blob: 6297ffc0e1d7a71326a50260d536c2f6946d4b78 [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
Robert Phillipsf497c362020-05-12 10:35:18 -040022#ifdef SK_DEBUG
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) {
Jim Van Verth5082df12020-03-11 16:14:51 -040034 fPipelineState->freeGPUResources();
Ethan Nicholas87f340e2017-01-03 14:32:01 -050035 }
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)
Robert Phillipsf497c362020-05-12 10:35:18 -040044 , fGpu(gpu) {
45}
egdaniel22281c12016-03-23 13:49:40 -070046
47GrVkResourceProvider::PipelineStateCache::~PipelineStateCache() {
Ethan Nicholas87f340e2017-01-03 14:32:01 -050048 SkASSERT(0 == fMap.count());
egdaniel22281c12016-03-23 13:49:40 -070049 // dump stats
Robert Phillipsf497c362020-05-12 10:35:18 -040050#ifdef SK_DEBUG
egdanielaf132772016-03-28 12:39:29 -070051 if (c_DisplayVkPipelineCache) {
Robert Phillipsf497c362020-05-12 10:35:18 -040052 using CacheResult = GrGpu::Stats::ProgramCacheResult;
53
54 int misses = fGpu->stats()->numInlineProgramCacheResult(CacheResult::kMiss) +
55 fGpu->stats()->numPreProgramCacheResult(CacheResult::kMiss);
56
57 int total = misses + fGpu->stats()->numInlineProgramCacheResult(CacheResult::kHit) +
58 fGpu->stats()->numPreProgramCacheResult(CacheResult::kHit);
59
egdaniel22281c12016-03-23 13:49:40 -070060 SkDebugf("--- Pipeline State Cache ---\n");
Robert Phillipsf497c362020-05-12 10:35:18 -040061 SkDebugf("Total requests: %d\n", total);
62 SkDebugf("Cache misses: %d\n", misses);
63 SkDebugf("Cache miss %%: %f\n", (total > 0) ? 100.f * misses / total : 0.0f);
egdaniel22281c12016-03-23 13:49:40 -070064 }
65#endif
66}
67
egdaniel22281c12016-03-23 13:49:40 -070068void GrVkResourceProvider::PipelineStateCache::release() {
Ethan Nicholas87f340e2017-01-03 14:32:01 -050069 fMap.reset();
egdaniel22281c12016-03-23 13:49:40 -070070}
71
Stephen Whiteb1857852020-02-07 15:33:23 +000072GrVkPipelineState* GrVkResourceProvider::PipelineStateCache::findOrCreatePipelineState(
Robert Phillipsd0fe8752019-01-31 14:13:59 -050073 GrRenderTarget* renderTarget,
Robert Phillips901aff02019-10-08 12:32:56 -040074 const GrProgramInfo& programInfo,
Greg Daniel99b88e02018-10-03 15:31:20 -040075 VkRenderPass compatibleRenderPass) {
Robert Phillipsa87c5292019-11-12 10:12:42 -050076#ifdef SK_DEBUG
Robert Phillips6c2aa7a2019-10-17 19:06:39 +000077 if (programInfo.pipeline().isStencilEnabled()) {
Robert Phillips6c2aa7a2019-10-17 19:06:39 +000078 SkASSERT(renderTarget->renderTargetPriv().getStencilAttachment());
Robert Phillipsa87c5292019-11-12 10:12:42 -050079 SkASSERT(renderTarget->renderTargetPriv().numStencilBits() == 8);
Robert Phillipsf497c362020-05-12 10:35:18 -040080 SkASSERT(renderTarget->renderTargetPriv().getStencilAttachment()->numSamples() ==
81 programInfo.numStencilSamples());
Robert Phillips6c2aa7a2019-10-17 19:06:39 +000082 }
Robert Phillipsa87c5292019-11-12 10:12:42 -050083#endif
csmartdaltonc633abb2016-11-01 08:55:55 -070084
Robert Phillips03e4c952019-11-26 16:20:22 -050085 GrProgramDesc desc = fGpu->caps()->makeDesc(renderTarget, programInfo);
86 if (!desc.isValid()) {
egdaniel22281c12016-03-23 13:49:40 -070087 GrCapsDebugf(fGpu->caps(), "Failed to build vk program descriptor!\n");
egdanieldd97b852016-04-28 09:30:39 -070088 return nullptr;
egdaniel22281c12016-03-23 13:49:40 -070089 }
egdaniel22281c12016-03-23 13:49:40 -070090
Robert Phillipsf497c362020-05-12 10:35:18 -040091 GrGpu::Stats::ProgramCacheResult stat;
92 auto tmp = this->findOrCreatePipelineState(renderTarget, desc, programInfo,
93 compatibleRenderPass, &stat);
94 if (!tmp) {
95 fGpu->stats()->incNumInlineCompilationFailures();
96 } else {
97 fGpu->stats()->incNumInlineProgramCacheResult(stat);
98 }
99
100 return tmp;
Robert Phillips979b2232020-02-20 10:47:29 -0500101}
102
Robert Phillipsf497c362020-05-12 10:35:18 -0400103GrVkPipelineState* GrVkResourceProvider::PipelineStateCache::findOrCreatePipelineState(
Robert Phillips979b2232020-02-20 10:47:29 -0500104 GrRenderTarget* renderTarget,
105 const GrProgramDesc& desc,
106 const GrProgramInfo& programInfo,
Robert Phillipsf497c362020-05-12 10:35:18 -0400107 VkRenderPass compatibleRenderPass,
108 GrGpu::Stats::ProgramCacheResult* stat) {
109 if (stat) {
110 *stat = GrGpu::Stats::ProgramCacheResult::kHit;
111 }
112
Ethan Nicholas87f340e2017-01-03 14:32:01 -0500113 std::unique_ptr<Entry>* entry = fMap.find(desc);
egdanielaf132772016-03-28 12:39:29 -0700114 if (!entry) {
Robert Phillipsf497c362020-05-12 10:35:18 -0400115 if (stat) {
116 *stat = GrGpu::Stats::ProgramCacheResult::kMiss;
117 }
Brian Salomonff168d92018-06-23 15:17:27 -0400118 GrVkPipelineState* pipelineState(GrVkPipelineStateBuilder::CreatePipelineState(
Stephen Whiteb1857852020-02-07 15:33:23 +0000119 fGpu, renderTarget, desc, programInfo, compatibleRenderPass));
Robert Phillips901aff02019-10-08 12:32:56 -0400120 if (!pipelineState) {
egdaniel22281c12016-03-23 13:49:40 -0700121 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}