blob: 0c25c6f4b1f27470c5599e66cc1ed51aff2a0ee7 [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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05009#include "src/core/SkOpts.h"
10#include "src/gpu/GrProcessor.h"
11#include "src/gpu/GrRenderTargetPriv.h"
12#include "src/gpu/GrStencilSettings.h"
13#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
14#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
15#include "src/gpu/vk/GrVkGpu.h"
16#include "src/gpu/vk/GrVkPipelineState.h"
17#include "src/gpu/vk/GrVkPipelineStateBuilder.h"
18#include "src/gpu/vk/GrVkResourceProvider.h"
egdaniel22281c12016-03-23 13:49:40 -070019
egdanielaf132772016-03-28 12:39:29 -070020#ifdef GR_PIPELINE_STATE_CACHE_STATS
halcanary4e44efe2016-08-04 10:47:16 -070021// Display pipeline state cache usage
22static const bool c_DisplayVkPipelineCache{false};
egdaniel22281c12016-03-23 13:49:40 -070023#endif
24
egdaniel22281c12016-03-23 13:49:40 -070025struct GrVkResourceProvider::PipelineStateCache::Entry {
Greg Daniel09eeefb2017-10-16 15:15:02 -040026 Entry(GrVkGpu* gpu, GrVkPipelineState* pipelineState)
Ethan Nicholas87f340e2017-01-03 14:32:01 -050027 : fGpu(gpu)
28 , fPipelineState(pipelineState) {}
egdaniel22281c12016-03-23 13:49:40 -070029
Ethan Nicholas87f340e2017-01-03 14:32:01 -050030 ~Entry() {
31 if (fPipelineState) {
32 fPipelineState->freeGPUResources(fGpu);
33 }
egdaniel22281c12016-03-23 13:49:40 -070034 }
35
Ethan Nicholas87f340e2017-01-03 14:32:01 -050036 GrVkGpu* fGpu;
Greg Daniel09eeefb2017-10-16 15:15:02 -040037 std::unique_ptr<GrVkPipelineState> fPipelineState;
egdaniel22281c12016-03-23 13:49:40 -070038};
39
40GrVkResourceProvider::PipelineStateCache::PipelineStateCache(GrVkGpu* gpu)
Ethan Nicholas87f340e2017-01-03 14:32:01 -050041 : fMap(kMaxEntries)
egdaniel22281c12016-03-23 13:49:40 -070042 , fGpu(gpu)
egdanielaf132772016-03-28 12:39:29 -070043#ifdef GR_PIPELINE_STATE_CACHE_STATS
egdaniel22281c12016-03-23 13:49:40 -070044 , fTotalRequests(0)
45 , fCacheMisses(0)
egdaniel22281c12016-03-23 13:49:40 -070046#endif
egdanielaf132772016-03-28 12:39:29 -070047{}
egdaniel22281c12016-03-23 13:49:40 -070048
49GrVkResourceProvider::PipelineStateCache::~PipelineStateCache() {
Ethan Nicholas87f340e2017-01-03 14:32:01 -050050 SkASSERT(0 == fMap.count());
egdaniel22281c12016-03-23 13:49:40 -070051 // dump stats
egdanielaf132772016-03-28 12:39:29 -070052#ifdef GR_PIPELINE_STATE_CACHE_STATS
53 if (c_DisplayVkPipelineCache) {
egdaniel22281c12016-03-23 13:49:40 -070054 SkDebugf("--- Pipeline State Cache ---\n");
55 SkDebugf("Total requests: %d\n", fTotalRequests);
56 SkDebugf("Cache misses: %d\n", fCacheMisses);
57 SkDebugf("Cache miss %%: %f\n", (fTotalRequests > 0) ?
58 100.f * fCacheMisses / fTotalRequests :
59 0.f);
egdaniel22281c12016-03-23 13:49:40 -070060 SkDebugf("---------------------\n");
61 }
62#endif
63}
64
egdaniel22281c12016-03-23 13:49:40 -070065void GrVkResourceProvider::PipelineStateCache::abandon() {
Ethan Nicholas87f340e2017-01-03 14:32:01 -050066 fMap.foreach([](std::unique_ptr<Entry>* e) {
67 (*e)->fPipelineState->abandonGPUResources();
68 (*e)->fPipelineState = nullptr;
egdanielaf132772016-03-28 12:39:29 -070069 });
Ethan Nicholas87f340e2017-01-03 14:32:01 -050070 fMap.reset();
egdaniel22281c12016-03-23 13:49:40 -070071}
72
73void GrVkResourceProvider::PipelineStateCache::release() {
Ethan Nicholas87f340e2017-01-03 14:32:01 -050074 fMap.reset();
egdaniel22281c12016-03-23 13:49:40 -070075}
76
Greg Daniel09eeefb2017-10-16 15:15:02 -040077GrVkPipelineState* GrVkResourceProvider::PipelineStateCache::refPipelineState(
Robert Phillipsd0fe8752019-01-31 14:13:59 -050078 GrRenderTarget* renderTarget,
79 GrSurfaceOrigin origin,
Brian Salomonff168d92018-06-23 15:17:27 -040080 const GrPrimitiveProcessor& primProc,
Greg Daniel9a51a862018-11-30 10:18:14 -050081 const GrTextureProxy* const primProcProxies[],
Brian Salomonff168d92018-06-23 15:17:27 -040082 const GrPipeline& pipeline,
83 GrPrimitiveType primitiveType,
Greg Daniel99b88e02018-10-03 15:31:20 -040084 VkRenderPass compatibleRenderPass) {
egdanielaf132772016-03-28 12:39:29 -070085#ifdef GR_PIPELINE_STATE_CACHE_STATS
egdaniel22281c12016-03-23 13:49:40 -070086 ++fTotalRequests;
87#endif
csmartdaltonc633abb2016-11-01 08:55:55 -070088 GrStencilSettings stencil;
89 if (pipeline.isStencilEnabled()) {
csmartdaltonc633abb2016-11-01 08:55:55 -070090 // TODO: attach stencil and create settings during render target flush.
Robert Phillipsd0fe8752019-01-31 14:13:59 -050091 SkASSERT(renderTarget->renderTargetPriv().getStencilAttachment());
csmartdaltonc633abb2016-11-01 08:55:55 -070092 stencil.reset(*pipeline.getUserStencil(), pipeline.hasStencilClip(),
Robert Phillipsd0fe8752019-01-31 14:13:59 -050093 renderTarget->renderTargetPriv().numStencilBits());
csmartdaltonc633abb2016-11-01 08:55:55 -070094 }
95
egdaniel22281c12016-03-23 13:49:40 -070096 // Get GrVkProgramDesc
Brian Salomon1471df92018-06-08 10:49:00 -040097 GrVkPipelineStateBuilder::Desc desc;
Robert Phillipsd0fe8752019-01-31 14:13:59 -050098 if (!GrVkPipelineStateBuilder::Desc::Build(&desc, renderTarget, primProc, pipeline, stencil,
99 primitiveType, fGpu)) {
egdaniel22281c12016-03-23 13:49:40 -0700100 GrCapsDebugf(fGpu->caps(), "Failed to build vk program descriptor!\n");
egdanieldd97b852016-04-28 09:30:39 -0700101 return nullptr;
egdaniel22281c12016-03-23 13:49:40 -0700102 }
Brian Osmane11dfd32019-07-23 10:29:41 -0400103 // If we knew the shader won't depend on origin, we could skip this (and use the same program
104 // for both origins). Instrumenting all fragment processors would be difficult and error prone.
105 desc.setSurfaceOriginKey(GrGLSLFragmentShaderBuilder::KeyForSurfaceOrigin(origin));
egdaniel22281c12016-03-23 13:49:40 -0700106
Ethan Nicholas87f340e2017-01-03 14:32:01 -0500107 std::unique_ptr<Entry>* entry = fMap.find(desc);
egdanielaf132772016-03-28 12:39:29 -0700108 if (!entry) {
109#ifdef GR_PIPELINE_STATE_CACHE_STATS
egdaniel22281c12016-03-23 13:49:40 -0700110 ++fCacheMisses;
111#endif
Brian Salomonff168d92018-06-23 15:17:27 -0400112 GrVkPipelineState* pipelineState(GrVkPipelineStateBuilder::CreatePipelineState(
Robert Phillipsd0fe8752019-01-31 14:13:59 -0500113 fGpu, renderTarget, origin, primProc, primProcProxies, pipeline, stencil,
114 primitiveType, &desc, compatibleRenderPass));
egdaniel22281c12016-03-23 13:49:40 -0700115 if (nullptr == pipelineState) {
116 return nullptr;
117 }
Greg Daniel09eeefb2017-10-16 15:15:02 -0400118 entry = fMap.insert(desc, std::unique_ptr<Entry>(new Entry(fGpu, pipelineState)));
119 return (*entry)->fPipelineState.get();
egdaniel22281c12016-03-23 13:49:40 -0700120 }
Greg Daniel09eeefb2017-10-16 15:15:02 -0400121 return (*entry)->fPipelineState.get();
egdaniel22281c12016-03-23 13:49:40 -0700122}