blob: 7b0f9f803846c0b5f18d3c2203e6cc09bc217212 [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#include "GrVkVulkan.h"
9
egdaniel22281c12016-03-23 13:49:40 -070010#include "GrProcessor.h"
Brian Salomon1471df92018-06-08 10:49:00 -040011#include "GrRenderTargetPriv.h" // TODO: remove once refPipelineState gets passed stencil settings.
12#include "GrStencilSettings.h"
13#include "GrVkGpu.h"
egdaniel22281c12016-03-23 13:49:40 -070014#include "GrVkPipelineState.h"
15#include "GrVkPipelineStateBuilder.h"
Brian Salomon1471df92018-06-08 10:49:00 -040016#include "GrVkResourceProvider.h"
mtklein4e976072016-08-08 09:06:27 -070017#include "SkOpts.h"
egdaniel22281c12016-03-23 13:49:40 -070018#include "glsl/GrGLSLFragmentProcessor.h"
19#include "glsl/GrGLSLProgramDataManager.h"
20
egdanielaf132772016-03-28 12:39:29 -070021#ifdef GR_PIPELINE_STATE_CACHE_STATS
halcanary4e44efe2016-08-04 10:47:16 -070022// Display pipeline state cache usage
23static const bool c_DisplayVkPipelineCache{false};
egdaniel22281c12016-03-23 13:49:40 -070024#endif
25
egdaniel22281c12016-03-23 13:49:40 -070026struct GrVkResourceProvider::PipelineStateCache::Entry {
Greg Daniel09eeefb2017-10-16 15:15:02 -040027 Entry(GrVkGpu* gpu, GrVkPipelineState* pipelineState)
Ethan Nicholas87f340e2017-01-03 14:32:01 -050028 : fGpu(gpu)
29 , fPipelineState(pipelineState) {}
egdaniel22281c12016-03-23 13:49:40 -070030
Ethan Nicholas87f340e2017-01-03 14:32:01 -050031 ~Entry() {
32 if (fPipelineState) {
33 fPipelineState->freeGPUResources(fGpu);
34 }
egdaniel22281c12016-03-23 13:49:40 -070035 }
36
Ethan Nicholas87f340e2017-01-03 14:32:01 -050037 GrVkGpu* fGpu;
Greg Daniel09eeefb2017-10-16 15:15:02 -040038 std::unique_ptr<GrVkPipelineState> fPipelineState;
egdaniel22281c12016-03-23 13:49:40 -070039};
40
41GrVkResourceProvider::PipelineStateCache::PipelineStateCache(GrVkGpu* gpu)
Ethan Nicholas87f340e2017-01-03 14:32:01 -050042 : fMap(kMaxEntries)
egdaniel22281c12016-03-23 13:49:40 -070043 , fGpu(gpu)
egdanielaf132772016-03-28 12:39:29 -070044#ifdef GR_PIPELINE_STATE_CACHE_STATS
egdaniel22281c12016-03-23 13:49:40 -070045 , fTotalRequests(0)
46 , fCacheMisses(0)
egdaniel22281c12016-03-23 13:49:40 -070047#endif
egdanielaf132772016-03-28 12:39:29 -070048{}
egdaniel22281c12016-03-23 13:49:40 -070049
50GrVkResourceProvider::PipelineStateCache::~PipelineStateCache() {
Ethan Nicholas87f340e2017-01-03 14:32:01 -050051 SkASSERT(0 == fMap.count());
egdaniel22281c12016-03-23 13:49:40 -070052 // dump stats
egdanielaf132772016-03-28 12:39:29 -070053#ifdef GR_PIPELINE_STATE_CACHE_STATS
54 if (c_DisplayVkPipelineCache) {
egdaniel22281c12016-03-23 13:49:40 -070055 SkDebugf("--- Pipeline State Cache ---\n");
56 SkDebugf("Total requests: %d\n", fTotalRequests);
57 SkDebugf("Cache misses: %d\n", fCacheMisses);
58 SkDebugf("Cache miss %%: %f\n", (fTotalRequests > 0) ?
59 100.f * fCacheMisses / fTotalRequests :
60 0.f);
egdaniel22281c12016-03-23 13:49:40 -070061 SkDebugf("---------------------\n");
62 }
63#endif
64}
65
egdaniel22281c12016-03-23 13:49:40 -070066void GrVkResourceProvider::PipelineStateCache::abandon() {
Ethan Nicholas87f340e2017-01-03 14:32:01 -050067 fMap.foreach([](std::unique_ptr<Entry>* e) {
68 (*e)->fPipelineState->abandonGPUResources();
69 (*e)->fPipelineState = nullptr;
egdanielaf132772016-03-28 12:39:29 -070070 });
Ethan Nicholas87f340e2017-01-03 14:32:01 -050071 fMap.reset();
egdaniel22281c12016-03-23 13:49:40 -070072}
73
74void GrVkResourceProvider::PipelineStateCache::release() {
Ethan Nicholas87f340e2017-01-03 14:32:01 -050075 fMap.reset();
egdaniel22281c12016-03-23 13:49:40 -070076}
77
Greg Daniel09eeefb2017-10-16 15:15:02 -040078GrVkPipelineState* GrVkResourceProvider::PipelineStateCache::refPipelineState(
Brian Salomonff168d92018-06-23 15:17:27 -040079 const GrPrimitiveProcessor& primProc,
Greg Daniel9a51a862018-11-30 10:18:14 -050080 const GrTextureProxy* const primProcProxies[],
Brian Salomonff168d92018-06-23 15:17:27 -040081 const GrPipeline& pipeline,
82 GrPrimitiveType primitiveType,
Greg Daniel99b88e02018-10-03 15:31:20 -040083 VkRenderPass compatibleRenderPass) {
egdanielaf132772016-03-28 12:39:29 -070084#ifdef GR_PIPELINE_STATE_CACHE_STATS
egdaniel22281c12016-03-23 13:49:40 -070085 ++fTotalRequests;
86#endif
csmartdaltonc633abb2016-11-01 08:55:55 -070087 GrStencilSettings stencil;
88 if (pipeline.isStencilEnabled()) {
Robert Phillips2890fbf2017-07-26 15:48:41 -040089 GrRenderTarget* rt = pipeline.renderTarget();
csmartdaltonc633abb2016-11-01 08:55:55 -070090 // TODO: attach stencil and create settings during render target flush.
91 SkASSERT(rt->renderTargetPriv().getStencilAttachment());
92 stencil.reset(*pipeline.getUserStencil(), pipeline.hasStencilClip(),
93 rt->renderTargetPriv().numStencilBits());
94 }
95
egdaniel22281c12016-03-23 13:49:40 -070096 // Get GrVkProgramDesc
Brian Salomon1471df92018-06-08 10:49:00 -040097 GrVkPipelineStateBuilder::Desc desc;
98 if (!GrVkPipelineStateBuilder::Desc::Build(&desc, primProc, pipeline, stencil, primitiveType,
Greg Daniel7a82edf2018-12-04 10:54:34 -050099 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 }
egdaniel720dc712016-09-07 11:56:59 -0700103 desc.finalize();
egdaniel22281c12016-03-23 13:49:40 -0700104
Ethan Nicholas87f340e2017-01-03 14:32:01 -0500105 std::unique_ptr<Entry>* entry = fMap.find(desc);
egdanielaf132772016-03-28 12:39:29 -0700106 if (!entry) {
Ethan Nicholas38657112017-02-09 17:01:22 -0500107 // Didn't find an origin-independent version, check with the specific origin
Robert Phillips2890fbf2017-07-26 15:48:41 -0400108 GrSurfaceOrigin origin = pipeline.proxy()->origin();
Robert Phillips7f861922018-01-30 13:13:42 +0000109 desc.setSurfaceOriginKey(GrGLSLFragmentShaderBuilder::KeyForSurfaceOrigin(origin));
Ethan Nicholas38657112017-02-09 17:01:22 -0500110 desc.finalize();
111 entry = fMap.find(desc);
112 }
113 if (!entry) {
egdanielaf132772016-03-28 12:39:29 -0700114#ifdef GR_PIPELINE_STATE_CACHE_STATS
egdaniel22281c12016-03-23 13:49:40 -0700115 ++fCacheMisses;
116#endif
Brian Salomonff168d92018-06-23 15:17:27 -0400117 GrVkPipelineState* pipelineState(GrVkPipelineStateBuilder::CreatePipelineState(
Greg Daniel9a51a862018-11-30 10:18:14 -0500118 fGpu, primProc, primProcProxies, pipeline, stencil, primitiveType, &desc,
119 compatibleRenderPass));
egdaniel22281c12016-03-23 13:49:40 -0700120 if (nullptr == pipelineState) {
121 return nullptr;
122 }
Greg Daniel09eeefb2017-10-16 15:15:02 -0400123 entry = fMap.insert(desc, std::unique_ptr<Entry>(new Entry(fGpu, pipelineState)));
124 return (*entry)->fPipelineState.get();
egdaniel22281c12016-03-23 13:49:40 -0700125 }
Greg Daniel09eeefb2017-10-16 15:15:02 -0400126 return (*entry)->fPipelineState.get();
egdaniel22281c12016-03-23 13:49:40 -0700127}