blob: fff410ed0d16d05d48b68e9023ad17c27b372dc1 [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
egdaniel22281c12016-03-23 13:49:40 -07009#include "GrProcessor.h"
Brian Salomon1471df92018-06-08 10:49:00 -040010#include "GrRenderTargetPriv.h" // TODO: remove once refPipelineState gets passed stencil settings.
11#include "GrStencilSettings.h"
12#include "GrVkGpu.h"
egdaniel22281c12016-03-23 13:49:40 -070013#include "GrVkPipelineState.h"
14#include "GrVkPipelineStateBuilder.h"
Brian Salomon1471df92018-06-08 10:49:00 -040015#include "GrVkResourceProvider.h"
mtklein4e976072016-08-08 09:06:27 -070016#include "SkOpts.h"
egdaniel22281c12016-03-23 13:49:40 -070017#include "glsl/GrGLSLFragmentProcessor.h"
18#include "glsl/GrGLSLProgramDataManager.h"
19
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 }
egdaniel22281c12016-03-23 13:49:40 -0700103
Ethan Nicholas87f340e2017-01-03 14:32:01 -0500104 std::unique_ptr<Entry>* entry = fMap.find(desc);
egdanielaf132772016-03-28 12:39:29 -0700105 if (!entry) {
Ethan Nicholas38657112017-02-09 17:01:22 -0500106 // Didn't find an origin-independent version, check with the specific origin
Robert Phillips7f861922018-01-30 13:13:42 +0000107 desc.setSurfaceOriginKey(GrGLSLFragmentShaderBuilder::KeyForSurfaceOrigin(origin));
Ethan Nicholas38657112017-02-09 17:01:22 -0500108 entry = fMap.find(desc);
109 }
110 if (!entry) {
egdanielaf132772016-03-28 12:39:29 -0700111#ifdef GR_PIPELINE_STATE_CACHE_STATS
egdaniel22281c12016-03-23 13:49:40 -0700112 ++fCacheMisses;
113#endif
Brian Salomonff168d92018-06-23 15:17:27 -0400114 GrVkPipelineState* pipelineState(GrVkPipelineStateBuilder::CreatePipelineState(
Robert Phillipsd0fe8752019-01-31 14:13:59 -0500115 fGpu, renderTarget, origin, primProc, primProcProxies, pipeline, stencil,
116 primitiveType, &desc, compatibleRenderPass));
egdaniel22281c12016-03-23 13:49:40 -0700117 if (nullptr == pipelineState) {
118 return nullptr;
119 }
Greg Daniel09eeefb2017-10-16 15:15:02 -0400120 entry = fMap.insert(desc, std::unique_ptr<Entry>(new Entry(fGpu, pipelineState)));
121 return (*entry)->fPipelineState.get();
egdaniel22281c12016-03-23 13:49:40 -0700122 }
Greg Daniel09eeefb2017-10-16 15:15:02 -0400123 return (*entry)->fPipelineState.get();
egdaniel22281c12016-03-23 13:49:40 -0700124}