blob: 4e7d3b169eb9308b995615253fb76367c1623411 [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
egdanielaf132772016-03-28 12:39:29 -070022#ifdef GR_PIPELINE_STATE_CACHE_STATS
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) {
34 fPipelineState->freeGPUResources(fGpu);
35 }
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)
egdaniel22281c12016-03-23 13:49:40 -070044 , fGpu(gpu)
egdanielaf132772016-03-28 12:39:29 -070045#ifdef GR_PIPELINE_STATE_CACHE_STATS
egdaniel22281c12016-03-23 13:49:40 -070046 , fTotalRequests(0)
47 , fCacheMisses(0)
egdaniel22281c12016-03-23 13:49:40 -070048#endif
egdanielaf132772016-03-28 12:39:29 -070049{}
egdaniel22281c12016-03-23 13:49:40 -070050
51GrVkResourceProvider::PipelineStateCache::~PipelineStateCache() {
Ethan Nicholas87f340e2017-01-03 14:32:01 -050052 SkASSERT(0 == fMap.count());
egdaniel22281c12016-03-23 13:49:40 -070053 // dump stats
egdanielaf132772016-03-28 12:39:29 -070054#ifdef GR_PIPELINE_STATE_CACHE_STATS
55 if (c_DisplayVkPipelineCache) {
egdaniel22281c12016-03-23 13:49:40 -070056 SkDebugf("--- Pipeline State Cache ---\n");
57 SkDebugf("Total requests: %d\n", fTotalRequests);
58 SkDebugf("Cache misses: %d\n", fCacheMisses);
59 SkDebugf("Cache miss %%: %f\n", (fTotalRequests > 0) ?
60 100.f * fCacheMisses / fTotalRequests :
61 0.f);
egdaniel22281c12016-03-23 13:49:40 -070062 SkDebugf("---------------------\n");
63 }
64#endif
65}
66
egdaniel22281c12016-03-23 13:49:40 -070067void GrVkResourceProvider::PipelineStateCache::abandon() {
Ethan Nicholas87f340e2017-01-03 14:32:01 -050068 fMap.foreach([](std::unique_ptr<Entry>* e) {
69 (*e)->fPipelineState->abandonGPUResources();
70 (*e)->fPipelineState = nullptr;
egdanielaf132772016-03-28 12:39:29 -070071 });
Ethan Nicholas87f340e2017-01-03 14:32:01 -050072 fMap.reset();
egdaniel22281c12016-03-23 13:49:40 -070073}
74
75void GrVkResourceProvider::PipelineStateCache::release() {
Ethan Nicholas87f340e2017-01-03 14:32:01 -050076 fMap.reset();
egdaniel22281c12016-03-23 13:49:40 -070077}
78
Greg Daniel09eeefb2017-10-16 15:15:02 -040079GrVkPipelineState* GrVkResourceProvider::PipelineStateCache::refPipelineState(
Robert Phillipsd0fe8752019-01-31 14:13:59 -050080 GrRenderTarget* renderTarget,
Robert Phillips901aff02019-10-08 12:32:56 -040081 const GrProgramInfo& programInfo,
Greg Daniel99b88e02018-10-03 15:31:20 -040082 VkRenderPass compatibleRenderPass) {
egdanielaf132772016-03-28 12:39:29 -070083#ifdef GR_PIPELINE_STATE_CACHE_STATS
egdaniel22281c12016-03-23 13:49:40 -070084 ++fTotalRequests;
85#endif
Robert Phillipsa87c5292019-11-12 10:12:42 -050086
87#ifdef SK_DEBUG
Robert Phillips6c2aa7a2019-10-17 19:06:39 +000088 if (programInfo.pipeline().isStencilEnabled()) {
Robert Phillips6c2aa7a2019-10-17 19:06:39 +000089 SkASSERT(renderTarget->renderTargetPriv().getStencilAttachment());
Robert Phillipsa87c5292019-11-12 10:12:42 -050090 SkASSERT(renderTarget->renderTargetPriv().numStencilBits() == 8);
Robert Phillips6c2aa7a2019-10-17 19:06:39 +000091 }
Robert Phillipsa87c5292019-11-12 10:12:42 -050092#endif
csmartdaltonc633abb2016-11-01 08:55:55 -070093
Robert Phillips2579de42019-10-09 09:51:59 -040094 // TODO: can this be unified between GL, Vk and Mtl?
egdaniel22281c12016-03-23 13:49:40 -070095 // Get GrVkProgramDesc
Brian Salomon1471df92018-06-08 10:49:00 -040096 GrVkPipelineStateBuilder::Desc desc;
Robert Phillipsa87c5292019-11-12 10:12:42 -050097 if (!GrVkPipelineStateBuilder::Desc::Build(&desc, renderTarget, programInfo, *fGpu->caps())) {
egdaniel22281c12016-03-23 13:49:40 -070098 GrCapsDebugf(fGpu->caps(), "Failed to build vk program descriptor!\n");
egdanieldd97b852016-04-28 09:30:39 -070099 return nullptr;
egdaniel22281c12016-03-23 13:49:40 -0700100 }
egdaniel22281c12016-03-23 13:49:40 -0700101
Ethan Nicholas87f340e2017-01-03 14:32:01 -0500102 std::unique_ptr<Entry>* entry = fMap.find(desc);
egdanielaf132772016-03-28 12:39:29 -0700103 if (!entry) {
104#ifdef GR_PIPELINE_STATE_CACHE_STATS
egdaniel22281c12016-03-23 13:49:40 -0700105 ++fCacheMisses;
106#endif
Brian Salomonff168d92018-06-23 15:17:27 -0400107 GrVkPipelineState* pipelineState(GrVkPipelineStateBuilder::CreatePipelineState(
Robert Phillipsa87c5292019-11-12 10:12:42 -0500108 fGpu, renderTarget, programInfo, &desc, compatibleRenderPass));
Robert Phillips901aff02019-10-08 12:32:56 -0400109 if (!pipelineState) {
egdaniel22281c12016-03-23 13:49:40 -0700110 return nullptr;
111 }
Greg Daniel09eeefb2017-10-16 15:15:02 -0400112 entry = fMap.insert(desc, std::unique_ptr<Entry>(new Entry(fGpu, pipelineState)));
113 return (*entry)->fPipelineState.get();
egdaniel22281c12016-03-23 13:49:40 -0700114 }
Greg Daniel09eeefb2017-10-16 15:15:02 -0400115 return (*entry)->fPipelineState.get();
egdaniel22281c12016-03-23 13:49:40 -0700116}