blob: a0f5ff47ebd337ff4a28a4731afedcf569e1d810 [file] [log] [blame]
egdaniel22281c12016-03-23 13:49:40 -07001/*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
Greg Daniel54bfb182018-11-20 17:12:36 -05008
Brian Osman172bb442019-09-06 10:16:02 -04009#include "include/gpu/GrContextOptions.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "src/core/SkOpts.h"
Brian Osman172bb442019-09-06 10:16:02 -040011#include "src/gpu/GrContextPriv.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050012#include "src/gpu/GrProcessor.h"
13#include "src/gpu/GrRenderTargetPriv.h"
14#include "src/gpu/GrStencilSettings.h"
15#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
16#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
17#include "src/gpu/vk/GrVkGpu.h"
18#include "src/gpu/vk/GrVkPipelineState.h"
19#include "src/gpu/vk/GrVkPipelineStateBuilder.h"
20#include "src/gpu/vk/GrVkResourceProvider.h"
egdaniel22281c12016-03-23 13:49:40 -070021
egdanielaf132772016-03-28 12:39:29 -070022#ifdef GR_PIPELINE_STATE_CACHE_STATS
halcanary4e44efe2016-08-04 10:47:16 -070023// Display pipeline state cache usage
24static const bool c_DisplayVkPipelineCache{false};
egdaniel22281c12016-03-23 13:49:40 -070025#endif
26
egdaniel22281c12016-03-23 13:49:40 -070027struct GrVkResourceProvider::PipelineStateCache::Entry {
Greg Daniel09eeefb2017-10-16 15:15:02 -040028 Entry(GrVkGpu* gpu, GrVkPipelineState* pipelineState)
Ethan Nicholas87f340e2017-01-03 14:32:01 -050029 : fGpu(gpu)
30 , fPipelineState(pipelineState) {}
egdaniel22281c12016-03-23 13:49:40 -070031
Ethan Nicholas87f340e2017-01-03 14:32:01 -050032 ~Entry() {
33 if (fPipelineState) {
34 fPipelineState->freeGPUResources(fGpu);
35 }
egdaniel22281c12016-03-23 13:49:40 -070036 }
37
Ethan Nicholas87f340e2017-01-03 14:32:01 -050038 GrVkGpu* fGpu;
Greg Daniel09eeefb2017-10-16 15:15:02 -040039 std::unique_ptr<GrVkPipelineState> fPipelineState;
egdaniel22281c12016-03-23 13:49:40 -070040};
41
42GrVkResourceProvider::PipelineStateCache::PipelineStateCache(GrVkGpu* gpu)
Brian Osman172bb442019-09-06 10:16:02 -040043 : fMap(gpu->getContext()->priv().options().fRuntimeProgramCacheSize)
egdaniel22281c12016-03-23 13:49:40 -070044 , fGpu(gpu)
egdanielaf132772016-03-28 12:39:29 -070045#ifdef GR_PIPELINE_STATE_CACHE_STATS
egdaniel22281c12016-03-23 13:49:40 -070046 , fTotalRequests(0)
47 , fCacheMisses(0)
egdaniel22281c12016-03-23 13:49:40 -070048#endif
egdanielaf132772016-03-28 12:39:29 -070049{}
egdaniel22281c12016-03-23 13:49:40 -070050
51GrVkResourceProvider::PipelineStateCache::~PipelineStateCache() {
Ethan Nicholas87f340e2017-01-03 14:32:01 -050052 SkASSERT(0 == fMap.count());
egdaniel22281c12016-03-23 13:49:40 -070053 // dump stats
egdanielaf132772016-03-28 12:39:29 -070054#ifdef GR_PIPELINE_STATE_CACHE_STATS
55 if (c_DisplayVkPipelineCache) {
egdaniel22281c12016-03-23 13:49:40 -070056 SkDebugf("--- Pipeline State Cache ---\n");
57 SkDebugf("Total requests: %d\n", fTotalRequests);
58 SkDebugf("Cache misses: %d\n", fCacheMisses);
59 SkDebugf("Cache miss %%: %f\n", (fTotalRequests > 0) ?
60 100.f * fCacheMisses / fTotalRequests :
61 0.f);
egdaniel22281c12016-03-23 13:49:40 -070062 SkDebugf("---------------------\n");
63 }
64#endif
65}
66
egdaniel22281c12016-03-23 13:49:40 -070067void GrVkResourceProvider::PipelineStateCache::release() {
Ethan Nicholas87f340e2017-01-03 14:32:01 -050068 fMap.reset();
egdaniel22281c12016-03-23 13:49:40 -070069}
70
Stephen Whiteb1857852020-02-07 15:33:23 +000071GrVkPipelineState* GrVkResourceProvider::PipelineStateCache::findOrCreatePipelineState(
Robert Phillipsd0fe8752019-01-31 14:13:59 -050072 GrRenderTarget* renderTarget,
Robert Phillips901aff02019-10-08 12:32:56 -040073 const GrProgramInfo& programInfo,
Greg Daniel99b88e02018-10-03 15:31:20 -040074 VkRenderPass compatibleRenderPass) {
egdanielaf132772016-03-28 12:39:29 -070075#ifdef GR_PIPELINE_STATE_CACHE_STATS
egdaniel22281c12016-03-23 13:49:40 -070076 ++fTotalRequests;
77#endif
Robert Phillipsa87c5292019-11-12 10:12:42 -050078
79#ifdef SK_DEBUG
Robert Phillips6c2aa7a2019-10-17 19:06:39 +000080 if (programInfo.pipeline().isStencilEnabled()) {
Robert Phillips6c2aa7a2019-10-17 19:06:39 +000081 SkASSERT(renderTarget->renderTargetPriv().getStencilAttachment());
Robert Phillipsa87c5292019-11-12 10:12:42 -050082 SkASSERT(renderTarget->renderTargetPriv().numStencilBits() == 8);
Robert Phillips6c2aa7a2019-10-17 19:06:39 +000083 }
Robert Phillipsa87c5292019-11-12 10:12:42 -050084#endif
csmartdaltonc633abb2016-11-01 08:55:55 -070085
Robert Phillips03e4c952019-11-26 16:20:22 -050086 GrProgramDesc desc = fGpu->caps()->makeDesc(renderTarget, programInfo);
87 if (!desc.isValid()) {
egdaniel22281c12016-03-23 13:49:40 -070088 GrCapsDebugf(fGpu->caps(), "Failed to build vk program descriptor!\n");
egdanieldd97b852016-04-28 09:30:39 -070089 return nullptr;
egdaniel22281c12016-03-23 13:49:40 -070090 }
egdaniel22281c12016-03-23 13:49:40 -070091
Ethan Nicholas87f340e2017-01-03 14:32:01 -050092 std::unique_ptr<Entry>* entry = fMap.find(desc);
egdanielaf132772016-03-28 12:39:29 -070093 if (!entry) {
94#ifdef GR_PIPELINE_STATE_CACHE_STATS
egdaniel22281c12016-03-23 13:49:40 -070095 ++fCacheMisses;
96#endif
Brian Salomonff168d92018-06-23 15:17:27 -040097 GrVkPipelineState* pipelineState(GrVkPipelineStateBuilder::CreatePipelineState(
Stephen Whiteb1857852020-02-07 15:33:23 +000098 fGpu, renderTarget, desc, programInfo, compatibleRenderPass));
Robert Phillips901aff02019-10-08 12:32:56 -040099 if (!pipelineState) {
egdaniel22281c12016-03-23 13:49:40 -0700100 return nullptr;
101 }
Greg Daniel09eeefb2017-10-16 15:15:02 -0400102 entry = fMap.insert(desc, std::unique_ptr<Entry>(new Entry(fGpu, pipelineState)));
103 return (*entry)->fPipelineState.get();
egdaniel22281c12016-03-23 13:49:40 -0700104 }
Greg Daniel09eeefb2017-10-16 15:15:02 -0400105 return (*entry)->fPipelineState.get();
egdaniel22281c12016-03-23 13:49:40 -0700106}