egdaniel | 22281c1 | 2016-03-23 13:49:40 -0700 | [diff] [blame] | 1 | /* |
| 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 Daniel | 54bfb18 | 2018-11-20 17:12:36 -0500 | [diff] [blame] | 8 | |
Brian Osman | 172bb44 | 2019-09-06 10:16:02 -0400 | [diff] [blame] | 9 | #include "include/gpu/GrContextOptions.h" |
Adlai Holler | 3d0359a | 2020-07-09 15:35:55 -0400 | [diff] [blame] | 10 | #include "include/gpu/GrDirectContext.h" |
Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 11 | #include "src/core/SkOpts.h" |
Adlai Holler | a069304 | 2020-10-14 11:23:11 -0400 | [diff] [blame] | 12 | #include "src/gpu/GrDirectContextPriv.h" |
Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 13 | #include "src/gpu/GrProcessor.h" |
Brian Salomon | f7f5433 | 2020-07-28 09:23:35 -0400 | [diff] [blame] | 14 | #include "src/gpu/GrRenderTarget.h" |
Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 15 | #include "src/gpu/GrStencilSettings.h" |
| 16 | #include "src/gpu/glsl/GrGLSLFragmentProcessor.h" |
| 17 | #include "src/gpu/glsl/GrGLSLProgramDataManager.h" |
| 18 | #include "src/gpu/vk/GrVkGpu.h" |
| 19 | #include "src/gpu/vk/GrVkPipelineState.h" |
| 20 | #include "src/gpu/vk/GrVkPipelineStateBuilder.h" |
| 21 | #include "src/gpu/vk/GrVkResourceProvider.h" |
egdaniel | 22281c1 | 2016-03-23 13:49:40 -0700 | [diff] [blame] | 22 | |
Robert Phillips | f497c36 | 2020-05-12 10:35:18 -0400 | [diff] [blame] | 23 | #ifdef SK_DEBUG |
halcanary | 4e44efe | 2016-08-04 10:47:16 -0700 | [diff] [blame] | 24 | // Display pipeline state cache usage |
| 25 | static const bool c_DisplayVkPipelineCache{false}; |
egdaniel | 22281c1 | 2016-03-23 13:49:40 -0700 | [diff] [blame] | 26 | #endif |
| 27 | |
egdaniel | 22281c1 | 2016-03-23 13:49:40 -0700 | [diff] [blame] | 28 | struct GrVkResourceProvider::PipelineStateCache::Entry { |
Greg Daniel | 09eeefb | 2017-10-16 15:15:02 -0400 | [diff] [blame] | 29 | Entry(GrVkGpu* gpu, GrVkPipelineState* pipelineState) |
Ethan Nicholas | 87f340e | 2017-01-03 14:32:01 -0500 | [diff] [blame] | 30 | : fGpu(gpu) |
| 31 | , fPipelineState(pipelineState) {} |
egdaniel | 22281c1 | 2016-03-23 13:49:40 -0700 | [diff] [blame] | 32 | |
Ethan Nicholas | 87f340e | 2017-01-03 14:32:01 -0500 | [diff] [blame] | 33 | ~Entry() { |
| 34 | if (fPipelineState) { |
Greg Daniel | 9d02a4c | 2020-07-15 14:26:08 -0400 | [diff] [blame] | 35 | fPipelineState->freeGPUResources(fGpu); |
Ethan Nicholas | 87f340e | 2017-01-03 14:32:01 -0500 | [diff] [blame] | 36 | } |
egdaniel | 22281c1 | 2016-03-23 13:49:40 -0700 | [diff] [blame] | 37 | } |
| 38 | |
Ethan Nicholas | 87f340e | 2017-01-03 14:32:01 -0500 | [diff] [blame] | 39 | GrVkGpu* fGpu; |
Greg Daniel | 09eeefb | 2017-10-16 15:15:02 -0400 | [diff] [blame] | 40 | std::unique_ptr<GrVkPipelineState> fPipelineState; |
egdaniel | 22281c1 | 2016-03-23 13:49:40 -0700 | [diff] [blame] | 41 | }; |
| 42 | |
| 43 | GrVkResourceProvider::PipelineStateCache::PipelineStateCache(GrVkGpu* gpu) |
Brian Osman | 172bb44 | 2019-09-06 10:16:02 -0400 | [diff] [blame] | 44 | : fMap(gpu->getContext()->priv().options().fRuntimeProgramCacheSize) |
Robert Phillips | f497c36 | 2020-05-12 10:35:18 -0400 | [diff] [blame] | 45 | , fGpu(gpu) { |
| 46 | } |
egdaniel | 22281c1 | 2016-03-23 13:49:40 -0700 | [diff] [blame] | 47 | |
| 48 | GrVkResourceProvider::PipelineStateCache::~PipelineStateCache() { |
Ethan Nicholas | 87f340e | 2017-01-03 14:32:01 -0500 | [diff] [blame] | 49 | SkASSERT(0 == fMap.count()); |
egdaniel | 22281c1 | 2016-03-23 13:49:40 -0700 | [diff] [blame] | 50 | // dump stats |
Robert Phillips | f497c36 | 2020-05-12 10:35:18 -0400 | [diff] [blame] | 51 | #ifdef SK_DEBUG |
egdaniel | af13277 | 2016-03-28 12:39:29 -0700 | [diff] [blame] | 52 | if (c_DisplayVkPipelineCache) { |
Robert Phillips | ae67c52 | 2021-03-03 11:03:38 -0500 | [diff] [blame^] | 53 | using CacheResult = Stats::ProgramCacheResult; |
Robert Phillips | f497c36 | 2020-05-12 10:35:18 -0400 | [diff] [blame] | 54 | |
Robert Phillips | ae67c52 | 2021-03-03 11:03:38 -0500 | [diff] [blame^] | 55 | int misses = fStats.numInlineProgramCacheResult(CacheResult::kMiss) + |
| 56 | fStats.numPreProgramCacheResult(CacheResult::kMiss); |
Robert Phillips | f497c36 | 2020-05-12 10:35:18 -0400 | [diff] [blame] | 57 | |
Robert Phillips | ae67c52 | 2021-03-03 11:03:38 -0500 | [diff] [blame^] | 58 | int total = misses + fStats.numInlineProgramCacheResult(CacheResult::kHit) + |
| 59 | fStats.numPreProgramCacheResult(CacheResult::kHit); |
Robert Phillips | f497c36 | 2020-05-12 10:35:18 -0400 | [diff] [blame] | 60 | |
egdaniel | 22281c1 | 2016-03-23 13:49:40 -0700 | [diff] [blame] | 61 | SkDebugf("--- Pipeline State Cache ---\n"); |
Robert Phillips | f497c36 | 2020-05-12 10:35:18 -0400 | [diff] [blame] | 62 | SkDebugf("Total requests: %d\n", total); |
| 63 | SkDebugf("Cache misses: %d\n", misses); |
| 64 | SkDebugf("Cache miss %%: %f\n", (total > 0) ? 100.f * misses / total : 0.0f); |
egdaniel | 22281c1 | 2016-03-23 13:49:40 -0700 | [diff] [blame] | 65 | } |
| 66 | #endif |
| 67 | } |
| 68 | |
egdaniel | 22281c1 | 2016-03-23 13:49:40 -0700 | [diff] [blame] | 69 | void GrVkResourceProvider::PipelineStateCache::release() { |
Ethan Nicholas | 87f340e | 2017-01-03 14:32:01 -0500 | [diff] [blame] | 70 | fMap.reset(); |
egdaniel | 22281c1 | 2016-03-23 13:49:40 -0700 | [diff] [blame] | 71 | } |
| 72 | |
Stephen White | b185785 | 2020-02-07 15:33:23 +0000 | [diff] [blame] | 73 | GrVkPipelineState* GrVkResourceProvider::PipelineStateCache::findOrCreatePipelineState( |
Robert Phillips | d0fe875 | 2019-01-31 14:13:59 -0500 | [diff] [blame] | 74 | GrRenderTarget* renderTarget, |
Robert Phillips | 901aff0 | 2019-10-08 12:32:56 -0400 | [diff] [blame] | 75 | const GrProgramInfo& programInfo, |
Greg Daniel | 91b37b1 | 2021-01-05 15:40:54 -0500 | [diff] [blame] | 76 | VkRenderPass compatibleRenderPass, |
| 77 | bool overrideSubpassForResolveLoad) { |
Robert Phillips | a87c529 | 2019-11-12 10:12:42 -0500 | [diff] [blame] | 78 | #ifdef SK_DEBUG |
Chris Dalton | 1b6a43c | 2020-09-25 12:21:18 -0600 | [diff] [blame] | 79 | if (programInfo.isStencilEnabled()) { |
Brian Salomon | f7f5433 | 2020-07-28 09:23:35 -0400 | [diff] [blame] | 80 | SkASSERT(renderTarget->getStencilAttachment()); |
| 81 | SkASSERT(renderTarget->numStencilBits() == 8); |
| 82 | SkASSERT(renderTarget->getStencilAttachment()->numSamples() == |
Robert Phillips | f497c36 | 2020-05-12 10:35:18 -0400 | [diff] [blame] | 83 | programInfo.numStencilSamples()); |
Robert Phillips | 6c2aa7a | 2019-10-17 19:06:39 +0000 | [diff] [blame] | 84 | } |
Robert Phillips | a87c529 | 2019-11-12 10:12:42 -0500 | [diff] [blame] | 85 | #endif |
csmartdalton | c633abb | 2016-11-01 08:55:55 -0700 | [diff] [blame] | 86 | |
Greg Daniel | 91b37b1 | 2021-01-05 15:40:54 -0500 | [diff] [blame] | 87 | auto flags = overrideSubpassForResolveLoad |
| 88 | ? GrCaps::ProgramDescOverrideFlags::kVulkanHasResolveLoadSubpass |
| 89 | : GrCaps::ProgramDescOverrideFlags::kNone; |
| 90 | |
| 91 | GrProgramDesc desc = fGpu->caps()->makeDesc(renderTarget, programInfo, flags); |
Robert Phillips | 03e4c95 | 2019-11-26 16:20:22 -0500 | [diff] [blame] | 92 | if (!desc.isValid()) { |
egdaniel | 22281c1 | 2016-03-23 13:49:40 -0700 | [diff] [blame] | 93 | GrCapsDebugf(fGpu->caps(), "Failed to build vk program descriptor!\n"); |
egdaniel | dd97b85 | 2016-04-28 09:30:39 -0700 | [diff] [blame] | 94 | return nullptr; |
egdaniel | 22281c1 | 2016-03-23 13:49:40 -0700 | [diff] [blame] | 95 | } |
egdaniel | 22281c1 | 2016-03-23 13:49:40 -0700 | [diff] [blame] | 96 | |
Robert Phillips | ae67c52 | 2021-03-03 11:03:38 -0500 | [diff] [blame^] | 97 | Stats::ProgramCacheResult stat; |
Robert Phillips | f497c36 | 2020-05-12 10:35:18 -0400 | [diff] [blame] | 98 | auto tmp = this->findOrCreatePipelineState(renderTarget, desc, programInfo, |
Greg Daniel | 91b37b1 | 2021-01-05 15:40:54 -0500 | [diff] [blame] | 99 | compatibleRenderPass, overrideSubpassForResolveLoad, |
| 100 | &stat); |
Robert Phillips | f497c36 | 2020-05-12 10:35:18 -0400 | [diff] [blame] | 101 | if (!tmp) { |
Robert Phillips | ae67c52 | 2021-03-03 11:03:38 -0500 | [diff] [blame^] | 102 | fStats.incNumInlineCompilationFailures(); |
Robert Phillips | f497c36 | 2020-05-12 10:35:18 -0400 | [diff] [blame] | 103 | } else { |
Robert Phillips | ae67c52 | 2021-03-03 11:03:38 -0500 | [diff] [blame^] | 104 | fStats.incNumInlineProgramCacheResult(stat); |
Robert Phillips | f497c36 | 2020-05-12 10:35:18 -0400 | [diff] [blame] | 105 | } |
| 106 | |
| 107 | return tmp; |
Robert Phillips | 979b223 | 2020-02-20 10:47:29 -0500 | [diff] [blame] | 108 | } |
| 109 | |
Robert Phillips | f497c36 | 2020-05-12 10:35:18 -0400 | [diff] [blame] | 110 | GrVkPipelineState* GrVkResourceProvider::PipelineStateCache::findOrCreatePipelineState( |
Robert Phillips | 979b223 | 2020-02-20 10:47:29 -0500 | [diff] [blame] | 111 | GrRenderTarget* renderTarget, |
| 112 | const GrProgramDesc& desc, |
| 113 | const GrProgramInfo& programInfo, |
Robert Phillips | f497c36 | 2020-05-12 10:35:18 -0400 | [diff] [blame] | 114 | VkRenderPass compatibleRenderPass, |
Greg Daniel | 91b37b1 | 2021-01-05 15:40:54 -0500 | [diff] [blame] | 115 | bool overrideSubpassForResolveLoad, |
Robert Phillips | ae67c52 | 2021-03-03 11:03:38 -0500 | [diff] [blame^] | 116 | Stats::ProgramCacheResult* stat) { |
Robert Phillips | f497c36 | 2020-05-12 10:35:18 -0400 | [diff] [blame] | 117 | if (stat) { |
Robert Phillips | ae67c52 | 2021-03-03 11:03:38 -0500 | [diff] [blame^] | 118 | *stat = Stats::ProgramCacheResult::kHit; |
Robert Phillips | f497c36 | 2020-05-12 10:35:18 -0400 | [diff] [blame] | 119 | } |
| 120 | |
Ethan Nicholas | 87f340e | 2017-01-03 14:32:01 -0500 | [diff] [blame] | 121 | std::unique_ptr<Entry>* entry = fMap.find(desc); |
egdaniel | af13277 | 2016-03-28 12:39:29 -0700 | [diff] [blame] | 122 | if (!entry) { |
Robert Phillips | f497c36 | 2020-05-12 10:35:18 -0400 | [diff] [blame] | 123 | if (stat) { |
Robert Phillips | ae67c52 | 2021-03-03 11:03:38 -0500 | [diff] [blame^] | 124 | *stat = Stats::ProgramCacheResult::kMiss; |
Robert Phillips | f497c36 | 2020-05-12 10:35:18 -0400 | [diff] [blame] | 125 | } |
Brian Salomon | ff168d9 | 2018-06-23 15:17:27 -0400 | [diff] [blame] | 126 | GrVkPipelineState* pipelineState(GrVkPipelineStateBuilder::CreatePipelineState( |
Greg Daniel | 91b37b1 | 2021-01-05 15:40:54 -0500 | [diff] [blame] | 127 | fGpu, renderTarget, desc, programInfo, compatibleRenderPass, |
| 128 | overrideSubpassForResolveLoad)); |
Robert Phillips | 901aff0 | 2019-10-08 12:32:56 -0400 | [diff] [blame] | 129 | if (!pipelineState) { |
egdaniel | 22281c1 | 2016-03-23 13:49:40 -0700 | [diff] [blame] | 130 | return nullptr; |
| 131 | } |
John Stiles | fbd050b | 2020-08-03 13:21:46 -0400 | [diff] [blame] | 132 | entry = fMap.insert(desc, std::make_unique<Entry>(fGpu, pipelineState)); |
Greg Daniel | 09eeefb | 2017-10-16 15:15:02 -0400 | [diff] [blame] | 133 | return (*entry)->fPipelineState.get(); |
egdaniel | 22281c1 | 2016-03-23 13:49:40 -0700 | [diff] [blame] | 134 | } |
Greg Daniel | 09eeefb | 2017-10-16 15:15:02 -0400 | [diff] [blame] | 135 | return (*entry)->fPipelineState.get(); |
egdaniel | 22281c1 | 2016-03-23 13:49:40 -0700 | [diff] [blame] | 136 | } |