blob: 3d3fb23bc00155c4702ed523bd65fdcbb620a4ff [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"
Adlai Holler3d0359a2020-07-09 15:35:55 -040010#include "include/gpu/GrDirectContext.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "src/core/SkOpts.h"
Adlai Hollera0693042020-10-14 11:23:11 -040012#include "src/gpu/GrDirectContextPriv.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050013#include "src/gpu/GrProcessor.h"
Brian Salomonf7f54332020-07-28 09:23:35 -040014#include "src/gpu/GrRenderTarget.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050015#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"
egdaniel22281c12016-03-23 13:49:40 -070022
Robert Phillipsf497c362020-05-12 10:35:18 -040023#ifdef SK_DEBUG
halcanary4e44efe2016-08-04 10:47:16 -070024// Display pipeline state cache usage
25static const bool c_DisplayVkPipelineCache{false};
egdaniel22281c12016-03-23 13:49:40 -070026#endif
27
egdaniel22281c12016-03-23 13:49:40 -070028struct GrVkResourceProvider::PipelineStateCache::Entry {
Greg Daniel09eeefb2017-10-16 15:15:02 -040029 Entry(GrVkGpu* gpu, GrVkPipelineState* pipelineState)
Ethan Nicholas87f340e2017-01-03 14:32:01 -050030 : fGpu(gpu)
31 , fPipelineState(pipelineState) {}
egdaniel22281c12016-03-23 13:49:40 -070032
Ethan Nicholas87f340e2017-01-03 14:32:01 -050033 ~Entry() {
34 if (fPipelineState) {
Greg Daniel9d02a4c2020-07-15 14:26:08 -040035 fPipelineState->freeGPUResources(fGpu);
Ethan Nicholas87f340e2017-01-03 14:32:01 -050036 }
egdaniel22281c12016-03-23 13:49:40 -070037 }
38
Ethan Nicholas87f340e2017-01-03 14:32:01 -050039 GrVkGpu* fGpu;
Greg Daniel09eeefb2017-10-16 15:15:02 -040040 std::unique_ptr<GrVkPipelineState> fPipelineState;
egdaniel22281c12016-03-23 13:49:40 -070041};
42
43GrVkResourceProvider::PipelineStateCache::PipelineStateCache(GrVkGpu* gpu)
Brian Osman172bb442019-09-06 10:16:02 -040044 : fMap(gpu->getContext()->priv().options().fRuntimeProgramCacheSize)
Robert Phillipsf497c362020-05-12 10:35:18 -040045 , fGpu(gpu) {
46}
egdaniel22281c12016-03-23 13:49:40 -070047
48GrVkResourceProvider::PipelineStateCache::~PipelineStateCache() {
Ethan Nicholas87f340e2017-01-03 14:32:01 -050049 SkASSERT(0 == fMap.count());
egdaniel22281c12016-03-23 13:49:40 -070050 // dump stats
Robert Phillipsf497c362020-05-12 10:35:18 -040051#ifdef SK_DEBUG
egdanielaf132772016-03-28 12:39:29 -070052 if (c_DisplayVkPipelineCache) {
Robert Phillipsae67c522021-03-03 11:03:38 -050053 using CacheResult = Stats::ProgramCacheResult;
Robert Phillipsf497c362020-05-12 10:35:18 -040054
Robert Phillipsae67c522021-03-03 11:03:38 -050055 int misses = fStats.numInlineProgramCacheResult(CacheResult::kMiss) +
56 fStats.numPreProgramCacheResult(CacheResult::kMiss);
Robert Phillipsf497c362020-05-12 10:35:18 -040057
Robert Phillipsae67c522021-03-03 11:03:38 -050058 int total = misses + fStats.numInlineProgramCacheResult(CacheResult::kHit) +
59 fStats.numPreProgramCacheResult(CacheResult::kHit);
Robert Phillipsf497c362020-05-12 10:35:18 -040060
egdaniel22281c12016-03-23 13:49:40 -070061 SkDebugf("--- Pipeline State Cache ---\n");
Robert Phillipsf497c362020-05-12 10:35:18 -040062 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);
egdaniel22281c12016-03-23 13:49:40 -070065 }
66#endif
67}
68
egdaniel22281c12016-03-23 13:49:40 -070069void GrVkResourceProvider::PipelineStateCache::release() {
Ethan Nicholas87f340e2017-01-03 14:32:01 -050070 fMap.reset();
egdaniel22281c12016-03-23 13:49:40 -070071}
72
Stephen Whiteb1857852020-02-07 15:33:23 +000073GrVkPipelineState* GrVkResourceProvider::PipelineStateCache::findOrCreatePipelineState(
Robert Phillipsd0fe8752019-01-31 14:13:59 -050074 GrRenderTarget* renderTarget,
Robert Phillips901aff02019-10-08 12:32:56 -040075 const GrProgramInfo& programInfo,
Greg Daniel91b37b12021-01-05 15:40:54 -050076 VkRenderPass compatibleRenderPass,
77 bool overrideSubpassForResolveLoad) {
Robert Phillipsa87c5292019-11-12 10:12:42 -050078#ifdef SK_DEBUG
Chris Dalton1b6a43c2020-09-25 12:21:18 -060079 if (programInfo.isStencilEnabled()) {
Brian Salomonf7f54332020-07-28 09:23:35 -040080 SkASSERT(renderTarget->getStencilAttachment());
81 SkASSERT(renderTarget->numStencilBits() == 8);
82 SkASSERT(renderTarget->getStencilAttachment()->numSamples() ==
Robert Phillipsf497c362020-05-12 10:35:18 -040083 programInfo.numStencilSamples());
Robert Phillips6c2aa7a2019-10-17 19:06:39 +000084 }
Robert Phillipsa87c5292019-11-12 10:12:42 -050085#endif
csmartdaltonc633abb2016-11-01 08:55:55 -070086
Greg Daniel91b37b12021-01-05 15:40:54 -050087 auto flags = overrideSubpassForResolveLoad
88 ? GrCaps::ProgramDescOverrideFlags::kVulkanHasResolveLoadSubpass
89 : GrCaps::ProgramDescOverrideFlags::kNone;
90
91 GrProgramDesc desc = fGpu->caps()->makeDesc(renderTarget, programInfo, flags);
Robert Phillips03e4c952019-11-26 16:20:22 -050092 if (!desc.isValid()) {
egdaniel22281c12016-03-23 13:49:40 -070093 GrCapsDebugf(fGpu->caps(), "Failed to build vk program descriptor!\n");
egdanieldd97b852016-04-28 09:30:39 -070094 return nullptr;
egdaniel22281c12016-03-23 13:49:40 -070095 }
egdaniel22281c12016-03-23 13:49:40 -070096
Robert Phillipsae67c522021-03-03 11:03:38 -050097 Stats::ProgramCacheResult stat;
Robert Phillipsf497c362020-05-12 10:35:18 -040098 auto tmp = this->findOrCreatePipelineState(renderTarget, desc, programInfo,
Greg Daniel91b37b12021-01-05 15:40:54 -050099 compatibleRenderPass, overrideSubpassForResolveLoad,
100 &stat);
Robert Phillipsf497c362020-05-12 10:35:18 -0400101 if (!tmp) {
Robert Phillipsae67c522021-03-03 11:03:38 -0500102 fStats.incNumInlineCompilationFailures();
Robert Phillipsf497c362020-05-12 10:35:18 -0400103 } else {
Robert Phillipsae67c522021-03-03 11:03:38 -0500104 fStats.incNumInlineProgramCacheResult(stat);
Robert Phillipsf497c362020-05-12 10:35:18 -0400105 }
106
107 return tmp;
Robert Phillips979b2232020-02-20 10:47:29 -0500108}
109
Robert Phillipsf497c362020-05-12 10:35:18 -0400110GrVkPipelineState* GrVkResourceProvider::PipelineStateCache::findOrCreatePipelineState(
Robert Phillips979b2232020-02-20 10:47:29 -0500111 GrRenderTarget* renderTarget,
112 const GrProgramDesc& desc,
113 const GrProgramInfo& programInfo,
Robert Phillipsf497c362020-05-12 10:35:18 -0400114 VkRenderPass compatibleRenderPass,
Greg Daniel91b37b12021-01-05 15:40:54 -0500115 bool overrideSubpassForResolveLoad,
Robert Phillipsae67c522021-03-03 11:03:38 -0500116 Stats::ProgramCacheResult* stat) {
Robert Phillipsf497c362020-05-12 10:35:18 -0400117 if (stat) {
Robert Phillipsae67c522021-03-03 11:03:38 -0500118 *stat = Stats::ProgramCacheResult::kHit;
Robert Phillipsf497c362020-05-12 10:35:18 -0400119 }
120
Ethan Nicholas87f340e2017-01-03 14:32:01 -0500121 std::unique_ptr<Entry>* entry = fMap.find(desc);
egdanielaf132772016-03-28 12:39:29 -0700122 if (!entry) {
Robert Phillipsf497c362020-05-12 10:35:18 -0400123 if (stat) {
Robert Phillipsae67c522021-03-03 11:03:38 -0500124 *stat = Stats::ProgramCacheResult::kMiss;
Robert Phillipsf497c362020-05-12 10:35:18 -0400125 }
Brian Salomonff168d92018-06-23 15:17:27 -0400126 GrVkPipelineState* pipelineState(GrVkPipelineStateBuilder::CreatePipelineState(
Greg Daniel91b37b12021-01-05 15:40:54 -0500127 fGpu, renderTarget, desc, programInfo, compatibleRenderPass,
128 overrideSubpassForResolveLoad));
Robert Phillips901aff02019-10-08 12:32:56 -0400129 if (!pipelineState) {
egdaniel22281c12016-03-23 13:49:40 -0700130 return nullptr;
131 }
John Stilesfbd050b2020-08-03 13:21:46 -0400132 entry = fMap.insert(desc, std::make_unique<Entry>(fGpu, pipelineState));
Greg Daniel09eeefb2017-10-16 15:15:02 -0400133 return (*entry)->fPipelineState.get();
egdaniel22281c12016-03-23 13:49:40 -0700134 }
Greg Daniel09eeefb2017-10-16 15:15:02 -0400135 return (*entry)->fPipelineState.get();
egdaniel22281c12016-03-23 13:49:40 -0700136}