xref: /aosp_15_r20/external/skia/src/gpu/ganesh/vk/GrVkResourceProvider.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2016 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/vk/GrVkResourceProvider.h"
9*c8dee2aaSAndroid Build Coastguard Worker 
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkData.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkString.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrDirectContext.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrTypes.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkDebug.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/gpu/ganesh/GrTypesPriv.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkTaskGroup.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkTraceEvent.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/Blend.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/RefCntedCallback.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrDirectContextPriv.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrGeometryProcessor.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrSamplerState.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrStencilSettings.h"
24*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/vk/GrVkCommandBuffer.h"
25*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/vk/GrVkCommandPool.h"
26*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/vk/GrVkDescriptorPool.h"
27*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/vk/GrVkGpu.h"
28*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/vk/GrVkPipeline.h"
29*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/vk/GrVkRenderTarget.h"
30*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/vk/GrVkUtil.h"
31*c8dee2aaSAndroid Build Coastguard Worker 
32*c8dee2aaSAndroid Build Coastguard Worker #include <cstring>
33*c8dee2aaSAndroid Build Coastguard Worker 
34*c8dee2aaSAndroid Build Coastguard Worker class GrProgramInfo;
35*c8dee2aaSAndroid Build Coastguard Worker class GrRenderTarget;
36*c8dee2aaSAndroid Build Coastguard Worker class GrVkDescriptorSet;
37*c8dee2aaSAndroid Build Coastguard Worker 
GrVkResourceProvider(GrVkGpu * gpu)38*c8dee2aaSAndroid Build Coastguard Worker GrVkResourceProvider::GrVkResourceProvider(GrVkGpu* gpu)
39*c8dee2aaSAndroid Build Coastguard Worker     : fGpu(gpu)
40*c8dee2aaSAndroid Build Coastguard Worker     , fPipelineCache(VK_NULL_HANDLE) {
41*c8dee2aaSAndroid Build Coastguard Worker     fPipelineStateCache = sk_make_sp<PipelineStateCache>(gpu);
42*c8dee2aaSAndroid Build Coastguard Worker }
43*c8dee2aaSAndroid Build Coastguard Worker 
~GrVkResourceProvider()44*c8dee2aaSAndroid Build Coastguard Worker GrVkResourceProvider::~GrVkResourceProvider() {
45*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(fRenderPassArray.empty());
46*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(fExternalRenderPasses.empty());
47*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(fMSAALoadPipelines.empty());
48*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(VK_NULL_HANDLE == fPipelineCache);
49*c8dee2aaSAndroid Build Coastguard Worker }
50*c8dee2aaSAndroid Build Coastguard Worker 
pipelineCache()51*c8dee2aaSAndroid Build Coastguard Worker VkPipelineCache GrVkResourceProvider::pipelineCache() {
52*c8dee2aaSAndroid Build Coastguard Worker     if (fPipelineCache == VK_NULL_HANDLE) {
53*c8dee2aaSAndroid Build Coastguard Worker         TRACE_EVENT0("skia.shaders", "CreatePipelineCache-GrVkResourceProvider");
54*c8dee2aaSAndroid Build Coastguard Worker         VkPipelineCacheCreateInfo createInfo;
55*c8dee2aaSAndroid Build Coastguard Worker         memset(&createInfo, 0, sizeof(VkPipelineCacheCreateInfo));
56*c8dee2aaSAndroid Build Coastguard Worker         createInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
57*c8dee2aaSAndroid Build Coastguard Worker         createInfo.pNext = nullptr;
58*c8dee2aaSAndroid Build Coastguard Worker         createInfo.flags = 0;
59*c8dee2aaSAndroid Build Coastguard Worker 
60*c8dee2aaSAndroid Build Coastguard Worker         auto persistentCache = fGpu->getContext()->priv().getPersistentCache();
61*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<SkData> cached;
62*c8dee2aaSAndroid Build Coastguard Worker         if (persistentCache) {
63*c8dee2aaSAndroid Build Coastguard Worker             uint32_t key = GrVkGpu::kPipelineCache_PersistentCacheKeyType;
64*c8dee2aaSAndroid Build Coastguard Worker             sk_sp<SkData> keyData = SkData::MakeWithoutCopy(&key, sizeof(uint32_t));
65*c8dee2aaSAndroid Build Coastguard Worker             cached = persistentCache->load(*keyData);
66*c8dee2aaSAndroid Build Coastguard Worker         }
67*c8dee2aaSAndroid Build Coastguard Worker         bool usedCached = false;
68*c8dee2aaSAndroid Build Coastguard Worker         if (cached) {
69*c8dee2aaSAndroid Build Coastguard Worker             const uint32_t* cacheHeader = (const uint32_t*)cached->data();
70*c8dee2aaSAndroid Build Coastguard Worker             if (cacheHeader[1] == VK_PIPELINE_CACHE_HEADER_VERSION_ONE) {
71*c8dee2aaSAndroid Build Coastguard Worker                 // For version one of the header, the total header size is 16 bytes plus
72*c8dee2aaSAndroid Build Coastguard Worker                 // VK_UUID_SIZE bytes. See Section 9.6 (Pipeline Cache) in the vulkan spec to see
73*c8dee2aaSAndroid Build Coastguard Worker                 // the breakdown of these bytes.
74*c8dee2aaSAndroid Build Coastguard Worker                 SkASSERT(cacheHeader[0] == 16 + VK_UUID_SIZE);
75*c8dee2aaSAndroid Build Coastguard Worker                 const VkPhysicalDeviceProperties& devProps = fGpu->physicalDeviceProperties();
76*c8dee2aaSAndroid Build Coastguard Worker                 const uint8_t* supportedPipelineCacheUUID = devProps.pipelineCacheUUID;
77*c8dee2aaSAndroid Build Coastguard Worker                 if (cacheHeader[2] == devProps.vendorID && cacheHeader[3] == devProps.deviceID &&
78*c8dee2aaSAndroid Build Coastguard Worker                     !memcmp(&cacheHeader[4], supportedPipelineCacheUUID, VK_UUID_SIZE)) {
79*c8dee2aaSAndroid Build Coastguard Worker                     createInfo.initialDataSize = cached->size();
80*c8dee2aaSAndroid Build Coastguard Worker                     createInfo.pInitialData = cached->data();
81*c8dee2aaSAndroid Build Coastguard Worker                     usedCached = true;
82*c8dee2aaSAndroid Build Coastguard Worker                 }
83*c8dee2aaSAndroid Build Coastguard Worker             }
84*c8dee2aaSAndroid Build Coastguard Worker         }
85*c8dee2aaSAndroid Build Coastguard Worker         if (!usedCached) {
86*c8dee2aaSAndroid Build Coastguard Worker             createInfo.initialDataSize = 0;
87*c8dee2aaSAndroid Build Coastguard Worker             createInfo.pInitialData = nullptr;
88*c8dee2aaSAndroid Build Coastguard Worker         }
89*c8dee2aaSAndroid Build Coastguard Worker 
90*c8dee2aaSAndroid Build Coastguard Worker         VkResult result;
91*c8dee2aaSAndroid Build Coastguard Worker         GR_VK_CALL_RESULT(fGpu, result, CreatePipelineCache(fGpu->device(), &createInfo, nullptr,
92*c8dee2aaSAndroid Build Coastguard Worker                                                             &fPipelineCache));
93*c8dee2aaSAndroid Build Coastguard Worker         if (VK_SUCCESS != result) {
94*c8dee2aaSAndroid Build Coastguard Worker             fPipelineCache = VK_NULL_HANDLE;
95*c8dee2aaSAndroid Build Coastguard Worker         }
96*c8dee2aaSAndroid Build Coastguard Worker     }
97*c8dee2aaSAndroid Build Coastguard Worker     return fPipelineCache;
98*c8dee2aaSAndroid Build Coastguard Worker }
99*c8dee2aaSAndroid Build Coastguard Worker 
init()100*c8dee2aaSAndroid Build Coastguard Worker void GrVkResourceProvider::init() {
101*c8dee2aaSAndroid Build Coastguard Worker     // Init uniform descriptor objects
102*c8dee2aaSAndroid Build Coastguard Worker     GrVkDescriptorSetManager* dsm = GrVkDescriptorSetManager::CreateUniformManager(fGpu);
103*c8dee2aaSAndroid Build Coastguard Worker     fDescriptorSetManagers.emplace_back(dsm);
104*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(1 == fDescriptorSetManagers.size());
105*c8dee2aaSAndroid Build Coastguard Worker     fUniformDSHandle = GrVkDescriptorSetManager::Handle(0);
106*c8dee2aaSAndroid Build Coastguard Worker     dsm = GrVkDescriptorSetManager::CreateInputManager(fGpu);
107*c8dee2aaSAndroid Build Coastguard Worker     fDescriptorSetManagers.emplace_back(dsm);
108*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(2 == fDescriptorSetManagers.size());
109*c8dee2aaSAndroid Build Coastguard Worker     fInputDSHandle = GrVkDescriptorSetManager::Handle(1);
110*c8dee2aaSAndroid Build Coastguard Worker }
111*c8dee2aaSAndroid Build Coastguard Worker 
makePipeline(const GrProgramInfo & programInfo,VkPipelineShaderStageCreateInfo * shaderStageInfo,int shaderStageCount,VkRenderPass compatibleRenderPass,VkPipelineLayout layout,uint32_t subpass)112*c8dee2aaSAndroid Build Coastguard Worker sk_sp<const GrVkPipeline> GrVkResourceProvider::makePipeline(
113*c8dee2aaSAndroid Build Coastguard Worker         const GrProgramInfo& programInfo,
114*c8dee2aaSAndroid Build Coastguard Worker         VkPipelineShaderStageCreateInfo* shaderStageInfo,
115*c8dee2aaSAndroid Build Coastguard Worker         int shaderStageCount,
116*c8dee2aaSAndroid Build Coastguard Worker         VkRenderPass compatibleRenderPass,
117*c8dee2aaSAndroid Build Coastguard Worker         VkPipelineLayout layout,
118*c8dee2aaSAndroid Build Coastguard Worker         uint32_t subpass) {
119*c8dee2aaSAndroid Build Coastguard Worker     return GrVkPipeline::Make(fGpu, programInfo, shaderStageInfo, shaderStageCount,
120*c8dee2aaSAndroid Build Coastguard Worker                               compatibleRenderPass, layout, this->pipelineCache(), subpass);
121*c8dee2aaSAndroid Build Coastguard Worker }
122*c8dee2aaSAndroid Build Coastguard Worker 
123*c8dee2aaSAndroid Build Coastguard Worker // To create framebuffers, we first need to create a simple RenderPass that is
124*c8dee2aaSAndroid Build Coastguard Worker // only used for framebuffer creation. When we actually render we will create
125*c8dee2aaSAndroid Build Coastguard Worker // RenderPasses as needed that are compatible with the framebuffer.
126*c8dee2aaSAndroid Build Coastguard Worker const GrVkRenderPass*
findCompatibleRenderPass(GrVkRenderTarget * target,CompatibleRPHandle * compatibleHandle,bool withResolve,bool withStencil,SelfDependencyFlags selfDepFlags,LoadFromResolve loadFromResolve)127*c8dee2aaSAndroid Build Coastguard Worker GrVkResourceProvider::findCompatibleRenderPass(GrVkRenderTarget* target,
128*c8dee2aaSAndroid Build Coastguard Worker                                                CompatibleRPHandle* compatibleHandle,
129*c8dee2aaSAndroid Build Coastguard Worker                                                bool withResolve,
130*c8dee2aaSAndroid Build Coastguard Worker                                                bool withStencil,
131*c8dee2aaSAndroid Build Coastguard Worker                                                SelfDependencyFlags selfDepFlags,
132*c8dee2aaSAndroid Build Coastguard Worker                                                LoadFromResolve loadFromResolve) {
133*c8dee2aaSAndroid Build Coastguard Worker     // Get attachment information from render target. This includes which attachments the render
134*c8dee2aaSAndroid Build Coastguard Worker     // target has (color, stencil) and the attachments format and sample count.
135*c8dee2aaSAndroid Build Coastguard Worker     GrVkRenderPass::AttachmentFlags attachmentFlags;
136*c8dee2aaSAndroid Build Coastguard Worker     GrVkRenderPass::AttachmentsDescriptor attachmentsDesc;
137*c8dee2aaSAndroid Build Coastguard Worker     if (!target->getAttachmentsDescriptor(&attachmentsDesc, &attachmentFlags,
138*c8dee2aaSAndroid Build Coastguard Worker                                           withResolve, withStencil)) {
139*c8dee2aaSAndroid Build Coastguard Worker         return nullptr;
140*c8dee2aaSAndroid Build Coastguard Worker     }
141*c8dee2aaSAndroid Build Coastguard Worker 
142*c8dee2aaSAndroid Build Coastguard Worker     return this->findCompatibleRenderPass(&attachmentsDesc, attachmentFlags, selfDepFlags,
143*c8dee2aaSAndroid Build Coastguard Worker                                           loadFromResolve, compatibleHandle);
144*c8dee2aaSAndroid Build Coastguard Worker }
145*c8dee2aaSAndroid Build Coastguard Worker 
146*c8dee2aaSAndroid Build Coastguard Worker const GrVkRenderPass*
findCompatibleRenderPass(GrVkRenderPass::AttachmentsDescriptor * desc,GrVkRenderPass::AttachmentFlags attachmentFlags,SelfDependencyFlags selfDepFlags,LoadFromResolve loadFromResolve,CompatibleRPHandle * compatibleHandle)147*c8dee2aaSAndroid Build Coastguard Worker GrVkResourceProvider::findCompatibleRenderPass(GrVkRenderPass::AttachmentsDescriptor* desc,
148*c8dee2aaSAndroid Build Coastguard Worker                                                GrVkRenderPass::AttachmentFlags attachmentFlags,
149*c8dee2aaSAndroid Build Coastguard Worker                                                SelfDependencyFlags selfDepFlags,
150*c8dee2aaSAndroid Build Coastguard Worker                                                LoadFromResolve loadFromResolve,
151*c8dee2aaSAndroid Build Coastguard Worker                                                CompatibleRPHandle* compatibleHandle) {
152*c8dee2aaSAndroid Build Coastguard Worker     for (int i = 0; i < fRenderPassArray.size(); ++i) {
153*c8dee2aaSAndroid Build Coastguard Worker         if (fRenderPassArray[i].isCompatible(*desc, attachmentFlags, selfDepFlags,
154*c8dee2aaSAndroid Build Coastguard Worker                                              loadFromResolve)) {
155*c8dee2aaSAndroid Build Coastguard Worker             const GrVkRenderPass* renderPass = fRenderPassArray[i].getCompatibleRenderPass();
156*c8dee2aaSAndroid Build Coastguard Worker             renderPass->ref();
157*c8dee2aaSAndroid Build Coastguard Worker             if (compatibleHandle) {
158*c8dee2aaSAndroid Build Coastguard Worker                 *compatibleHandle = CompatibleRPHandle(i);
159*c8dee2aaSAndroid Build Coastguard Worker             }
160*c8dee2aaSAndroid Build Coastguard Worker             return renderPass;
161*c8dee2aaSAndroid Build Coastguard Worker         }
162*c8dee2aaSAndroid Build Coastguard Worker     }
163*c8dee2aaSAndroid Build Coastguard Worker 
164*c8dee2aaSAndroid Build Coastguard Worker     GrVkRenderPass* renderPass = GrVkRenderPass::CreateSimple(fGpu, desc, attachmentFlags,
165*c8dee2aaSAndroid Build Coastguard Worker                                                               selfDepFlags, loadFromResolve);
166*c8dee2aaSAndroid Build Coastguard Worker     if (!renderPass) {
167*c8dee2aaSAndroid Build Coastguard Worker         return nullptr;
168*c8dee2aaSAndroid Build Coastguard Worker     }
169*c8dee2aaSAndroid Build Coastguard Worker     fRenderPassArray.emplace_back(renderPass);
170*c8dee2aaSAndroid Build Coastguard Worker 
171*c8dee2aaSAndroid Build Coastguard Worker     if (compatibleHandle) {
172*c8dee2aaSAndroid Build Coastguard Worker         *compatibleHandle = CompatibleRPHandle(fRenderPassArray.size() - 1);
173*c8dee2aaSAndroid Build Coastguard Worker     }
174*c8dee2aaSAndroid Build Coastguard Worker     return renderPass;
175*c8dee2aaSAndroid Build Coastguard Worker }
176*c8dee2aaSAndroid Build Coastguard Worker 
findCompatibleExternalRenderPass(VkRenderPass renderPass,uint32_t colorAttachmentIndex)177*c8dee2aaSAndroid Build Coastguard Worker const GrVkRenderPass* GrVkResourceProvider::findCompatibleExternalRenderPass(
178*c8dee2aaSAndroid Build Coastguard Worker         VkRenderPass renderPass, uint32_t colorAttachmentIndex) {
179*c8dee2aaSAndroid Build Coastguard Worker     for (int i = 0; i < fExternalRenderPasses.size(); ++i) {
180*c8dee2aaSAndroid Build Coastguard Worker         if (fExternalRenderPasses[i]->isCompatibleExternalRP(renderPass)) {
181*c8dee2aaSAndroid Build Coastguard Worker             fExternalRenderPasses[i]->ref();
182*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_DEBUG
183*c8dee2aaSAndroid Build Coastguard Worker             uint32_t cachedColorIndex;
184*c8dee2aaSAndroid Build Coastguard Worker             SkASSERT(fExternalRenderPasses[i]->colorAttachmentIndex(&cachedColorIndex));
185*c8dee2aaSAndroid Build Coastguard Worker             SkASSERT(cachedColorIndex == colorAttachmentIndex);
186*c8dee2aaSAndroid Build Coastguard Worker #endif
187*c8dee2aaSAndroid Build Coastguard Worker             return fExternalRenderPasses[i];
188*c8dee2aaSAndroid Build Coastguard Worker         }
189*c8dee2aaSAndroid Build Coastguard Worker     }
190*c8dee2aaSAndroid Build Coastguard Worker 
191*c8dee2aaSAndroid Build Coastguard Worker     const GrVkRenderPass* newRenderPass = new GrVkRenderPass(fGpu, renderPass,
192*c8dee2aaSAndroid Build Coastguard Worker                                                              colorAttachmentIndex);
193*c8dee2aaSAndroid Build Coastguard Worker     fExternalRenderPasses.push_back(newRenderPass);
194*c8dee2aaSAndroid Build Coastguard Worker     newRenderPass->ref();
195*c8dee2aaSAndroid Build Coastguard Worker     return newRenderPass;
196*c8dee2aaSAndroid Build Coastguard Worker }
197*c8dee2aaSAndroid Build Coastguard Worker 
findRenderPass(GrVkRenderTarget * target,const GrVkRenderPass::LoadStoreOps & colorOps,const GrVkRenderPass::LoadStoreOps & resolveOps,const GrVkRenderPass::LoadStoreOps & stencilOps,CompatibleRPHandle * compatibleHandle,bool withResolve,bool withStencil,SelfDependencyFlags selfDepFlags,LoadFromResolve loadFromResolve)198*c8dee2aaSAndroid Build Coastguard Worker const GrVkRenderPass* GrVkResourceProvider::findRenderPass(
199*c8dee2aaSAndroid Build Coastguard Worker         GrVkRenderTarget* target,
200*c8dee2aaSAndroid Build Coastguard Worker         const GrVkRenderPass::LoadStoreOps& colorOps,
201*c8dee2aaSAndroid Build Coastguard Worker         const GrVkRenderPass::LoadStoreOps& resolveOps,
202*c8dee2aaSAndroid Build Coastguard Worker         const GrVkRenderPass::LoadStoreOps& stencilOps,
203*c8dee2aaSAndroid Build Coastguard Worker         CompatibleRPHandle* compatibleHandle,
204*c8dee2aaSAndroid Build Coastguard Worker         bool withResolve,
205*c8dee2aaSAndroid Build Coastguard Worker         bool withStencil,
206*c8dee2aaSAndroid Build Coastguard Worker         SelfDependencyFlags selfDepFlags,
207*c8dee2aaSAndroid Build Coastguard Worker         LoadFromResolve loadFromResolve) {
208*c8dee2aaSAndroid Build Coastguard Worker     GrVkResourceProvider::CompatibleRPHandle tempRPHandle;
209*c8dee2aaSAndroid Build Coastguard Worker     GrVkResourceProvider::CompatibleRPHandle* pRPHandle = compatibleHandle ? compatibleHandle
210*c8dee2aaSAndroid Build Coastguard Worker                                                                            : &tempRPHandle;
211*c8dee2aaSAndroid Build Coastguard Worker     *pRPHandle = target->compatibleRenderPassHandle(withResolve, withStencil, selfDepFlags,
212*c8dee2aaSAndroid Build Coastguard Worker                                                     loadFromResolve);
213*c8dee2aaSAndroid Build Coastguard Worker     if (!pRPHandle->isValid()) {
214*c8dee2aaSAndroid Build Coastguard Worker         return nullptr;
215*c8dee2aaSAndroid Build Coastguard Worker     }
216*c8dee2aaSAndroid Build Coastguard Worker 
217*c8dee2aaSAndroid Build Coastguard Worker     return this->findRenderPass(*pRPHandle, colorOps, resolveOps, stencilOps);
218*c8dee2aaSAndroid Build Coastguard Worker }
219*c8dee2aaSAndroid Build Coastguard Worker 
220*c8dee2aaSAndroid Build Coastguard Worker const GrVkRenderPass*
findRenderPass(const CompatibleRPHandle & compatibleHandle,const GrVkRenderPass::LoadStoreOps & colorOps,const GrVkRenderPass::LoadStoreOps & resolveOps,const GrVkRenderPass::LoadStoreOps & stencilOps)221*c8dee2aaSAndroid Build Coastguard Worker GrVkResourceProvider::findRenderPass(const CompatibleRPHandle& compatibleHandle,
222*c8dee2aaSAndroid Build Coastguard Worker                                      const GrVkRenderPass::LoadStoreOps& colorOps,
223*c8dee2aaSAndroid Build Coastguard Worker                                      const GrVkRenderPass::LoadStoreOps& resolveOps,
224*c8dee2aaSAndroid Build Coastguard Worker                                      const GrVkRenderPass::LoadStoreOps& stencilOps) {
225*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(compatibleHandle.isValid() && compatibleHandle.toIndex() < fRenderPassArray.size());
226*c8dee2aaSAndroid Build Coastguard Worker     CompatibleRenderPassSet& compatibleSet = fRenderPassArray[compatibleHandle.toIndex()];
227*c8dee2aaSAndroid Build Coastguard Worker     const GrVkRenderPass* renderPass = compatibleSet.getRenderPass(fGpu,
228*c8dee2aaSAndroid Build Coastguard Worker                                                                    colorOps,
229*c8dee2aaSAndroid Build Coastguard Worker                                                                    resolveOps,
230*c8dee2aaSAndroid Build Coastguard Worker                                                                    stencilOps);
231*c8dee2aaSAndroid Build Coastguard Worker     if (!renderPass) {
232*c8dee2aaSAndroid Build Coastguard Worker         return nullptr;
233*c8dee2aaSAndroid Build Coastguard Worker     }
234*c8dee2aaSAndroid Build Coastguard Worker     renderPass->ref();
235*c8dee2aaSAndroid Build Coastguard Worker     return renderPass;
236*c8dee2aaSAndroid Build Coastguard Worker }
237*c8dee2aaSAndroid Build Coastguard Worker 
findOrCreateCompatibleDescriptorPool(VkDescriptorType type,uint32_t count)238*c8dee2aaSAndroid Build Coastguard Worker GrVkDescriptorPool* GrVkResourceProvider::findOrCreateCompatibleDescriptorPool(
239*c8dee2aaSAndroid Build Coastguard Worker                                                             VkDescriptorType type, uint32_t count) {
240*c8dee2aaSAndroid Build Coastguard Worker     return GrVkDescriptorPool::Create(fGpu, type, count);
241*c8dee2aaSAndroid Build Coastguard Worker }
242*c8dee2aaSAndroid Build Coastguard Worker 
findOrCreateCompatibleSampler(GrSamplerState params,const skgpu::VulkanYcbcrConversionInfo & ycbcrInfo)243*c8dee2aaSAndroid Build Coastguard Worker GrVkSampler* GrVkResourceProvider::findOrCreateCompatibleSampler(
244*c8dee2aaSAndroid Build Coastguard Worker         GrSamplerState params, const skgpu::VulkanYcbcrConversionInfo& ycbcrInfo) {
245*c8dee2aaSAndroid Build Coastguard Worker     GrVkSampler* sampler = fSamplers.find(GrVkSampler::GenerateKey(params, ycbcrInfo));
246*c8dee2aaSAndroid Build Coastguard Worker     if (!sampler) {
247*c8dee2aaSAndroid Build Coastguard Worker         sampler = GrVkSampler::Create(fGpu, params, ycbcrInfo);
248*c8dee2aaSAndroid Build Coastguard Worker         if (!sampler) {
249*c8dee2aaSAndroid Build Coastguard Worker             return nullptr;
250*c8dee2aaSAndroid Build Coastguard Worker         }
251*c8dee2aaSAndroid Build Coastguard Worker         fSamplers.add(sampler);
252*c8dee2aaSAndroid Build Coastguard Worker     }
253*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(sampler);
254*c8dee2aaSAndroid Build Coastguard Worker     sampler->ref();
255*c8dee2aaSAndroid Build Coastguard Worker     return sampler;
256*c8dee2aaSAndroid Build Coastguard Worker }
257*c8dee2aaSAndroid Build Coastguard Worker 
findOrCreateCompatibleSamplerYcbcrConversion(const skgpu::VulkanYcbcrConversionInfo & ycbcrInfo)258*c8dee2aaSAndroid Build Coastguard Worker GrVkSamplerYcbcrConversion* GrVkResourceProvider::findOrCreateCompatibleSamplerYcbcrConversion(
259*c8dee2aaSAndroid Build Coastguard Worker         const skgpu::VulkanYcbcrConversionInfo& ycbcrInfo) {
260*c8dee2aaSAndroid Build Coastguard Worker     GrVkSamplerYcbcrConversion* ycbcrConversion =
261*c8dee2aaSAndroid Build Coastguard Worker             fYcbcrConversions.find(GrVkSamplerYcbcrConversion::GenerateKey(ycbcrInfo));
262*c8dee2aaSAndroid Build Coastguard Worker     if (!ycbcrConversion) {
263*c8dee2aaSAndroid Build Coastguard Worker         ycbcrConversion = GrVkSamplerYcbcrConversion::Create(fGpu, ycbcrInfo);
264*c8dee2aaSAndroid Build Coastguard Worker         if (!ycbcrConversion) {
265*c8dee2aaSAndroid Build Coastguard Worker             return nullptr;
266*c8dee2aaSAndroid Build Coastguard Worker         }
267*c8dee2aaSAndroid Build Coastguard Worker         fYcbcrConversions.add(ycbcrConversion);
268*c8dee2aaSAndroid Build Coastguard Worker     }
269*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(ycbcrConversion);
270*c8dee2aaSAndroid Build Coastguard Worker     ycbcrConversion->ref();
271*c8dee2aaSAndroid Build Coastguard Worker     return ycbcrConversion;
272*c8dee2aaSAndroid Build Coastguard Worker }
273*c8dee2aaSAndroid Build Coastguard Worker 
findOrCreateCompatiblePipelineState(GrRenderTarget * renderTarget,const GrProgramInfo & programInfo,VkRenderPass compatibleRenderPass,bool overrideSubpassForResolveLoad)274*c8dee2aaSAndroid Build Coastguard Worker GrVkPipelineState* GrVkResourceProvider::findOrCreateCompatiblePipelineState(
275*c8dee2aaSAndroid Build Coastguard Worker         GrRenderTarget* renderTarget,
276*c8dee2aaSAndroid Build Coastguard Worker         const GrProgramInfo& programInfo,
277*c8dee2aaSAndroid Build Coastguard Worker         VkRenderPass compatibleRenderPass,
278*c8dee2aaSAndroid Build Coastguard Worker         bool overrideSubpassForResolveLoad) {
279*c8dee2aaSAndroid Build Coastguard Worker     return fPipelineStateCache->findOrCreatePipelineState(renderTarget, programInfo,
280*c8dee2aaSAndroid Build Coastguard Worker                                                           compatibleRenderPass,
281*c8dee2aaSAndroid Build Coastguard Worker                                                           overrideSubpassForResolveLoad);
282*c8dee2aaSAndroid Build Coastguard Worker }
283*c8dee2aaSAndroid Build Coastguard Worker 
findOrCreateCompatiblePipelineState(const GrProgramDesc & desc,const GrProgramInfo & programInfo,VkRenderPass compatibleRenderPass,GrThreadSafePipelineBuilder::Stats::ProgramCacheResult * stat)284*c8dee2aaSAndroid Build Coastguard Worker GrVkPipelineState* GrVkResourceProvider::findOrCreateCompatiblePipelineState(
285*c8dee2aaSAndroid Build Coastguard Worker         const GrProgramDesc& desc,
286*c8dee2aaSAndroid Build Coastguard Worker         const GrProgramInfo& programInfo,
287*c8dee2aaSAndroid Build Coastguard Worker         VkRenderPass compatibleRenderPass,
288*c8dee2aaSAndroid Build Coastguard Worker         GrThreadSafePipelineBuilder::Stats::ProgramCacheResult* stat) {
289*c8dee2aaSAndroid Build Coastguard Worker 
290*c8dee2aaSAndroid Build Coastguard Worker     auto tmp =  fPipelineStateCache->findOrCreatePipelineState(desc, programInfo,
291*c8dee2aaSAndroid Build Coastguard Worker                                                                compatibleRenderPass, stat);
292*c8dee2aaSAndroid Build Coastguard Worker     if (!tmp) {
293*c8dee2aaSAndroid Build Coastguard Worker         fPipelineStateCache->stats()->incNumPreCompilationFailures();
294*c8dee2aaSAndroid Build Coastguard Worker     } else {
295*c8dee2aaSAndroid Build Coastguard Worker         fPipelineStateCache->stats()->incNumPreProgramCacheResult(*stat);
296*c8dee2aaSAndroid Build Coastguard Worker     }
297*c8dee2aaSAndroid Build Coastguard Worker 
298*c8dee2aaSAndroid Build Coastguard Worker     return tmp;
299*c8dee2aaSAndroid Build Coastguard Worker }
300*c8dee2aaSAndroid Build Coastguard Worker 
findOrCreateMSAALoadPipeline(const GrVkRenderPass & renderPass,int numSamples,VkPipelineShaderStageCreateInfo * shaderStageInfo,VkPipelineLayout pipelineLayout)301*c8dee2aaSAndroid Build Coastguard Worker sk_sp<const GrVkPipeline> GrVkResourceProvider::findOrCreateMSAALoadPipeline(
302*c8dee2aaSAndroid Build Coastguard Worker         const GrVkRenderPass& renderPass,
303*c8dee2aaSAndroid Build Coastguard Worker         int numSamples,
304*c8dee2aaSAndroid Build Coastguard Worker         VkPipelineShaderStageCreateInfo* shaderStageInfo,
305*c8dee2aaSAndroid Build Coastguard Worker         VkPipelineLayout pipelineLayout) {
306*c8dee2aaSAndroid Build Coastguard Worker     // Find or Create a compatible pipeline
307*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<const GrVkPipeline> pipeline;
308*c8dee2aaSAndroid Build Coastguard Worker     for (int i = 0; i < fMSAALoadPipelines.size() && !pipeline; ++i) {
309*c8dee2aaSAndroid Build Coastguard Worker         if (fMSAALoadPipelines[i].fRenderPass->isCompatible(renderPass)) {
310*c8dee2aaSAndroid Build Coastguard Worker             pipeline = fMSAALoadPipelines[i].fPipeline;
311*c8dee2aaSAndroid Build Coastguard Worker         }
312*c8dee2aaSAndroid Build Coastguard Worker     }
313*c8dee2aaSAndroid Build Coastguard Worker     if (!pipeline) {
314*c8dee2aaSAndroid Build Coastguard Worker         pipeline = GrVkPipeline::Make(
315*c8dee2aaSAndroid Build Coastguard Worker                 fGpu,
316*c8dee2aaSAndroid Build Coastguard Worker                 /*vertexAttribs=*/GrGeometryProcessor::AttributeSet(),
317*c8dee2aaSAndroid Build Coastguard Worker                 /*instanceAttribs=*/GrGeometryProcessor::AttributeSet(),
318*c8dee2aaSAndroid Build Coastguard Worker                 GrPrimitiveType::kTriangleStrip,
319*c8dee2aaSAndroid Build Coastguard Worker                 kTopLeft_GrSurfaceOrigin,
320*c8dee2aaSAndroid Build Coastguard Worker                 GrStencilSettings(),
321*c8dee2aaSAndroid Build Coastguard Worker                 numSamples,
322*c8dee2aaSAndroid Build Coastguard Worker                 /*isHWantialiasState=*/false,
323*c8dee2aaSAndroid Build Coastguard Worker                 skgpu::BlendInfo(),
324*c8dee2aaSAndroid Build Coastguard Worker                 /*isWireframe=*/false,
325*c8dee2aaSAndroid Build Coastguard Worker                 /*useConservativeRaster=*/false,
326*c8dee2aaSAndroid Build Coastguard Worker                 /*subpass=*/0,
327*c8dee2aaSAndroid Build Coastguard Worker                 shaderStageInfo,
328*c8dee2aaSAndroid Build Coastguard Worker                 /*shaderStageCount=*/2,
329*c8dee2aaSAndroid Build Coastguard Worker                 renderPass.vkRenderPass(),
330*c8dee2aaSAndroid Build Coastguard Worker                 pipelineLayout,
331*c8dee2aaSAndroid Build Coastguard Worker                 /*ownsLayout=*/false,
332*c8dee2aaSAndroid Build Coastguard Worker                 this->pipelineCache());
333*c8dee2aaSAndroid Build Coastguard Worker         if (!pipeline) {
334*c8dee2aaSAndroid Build Coastguard Worker             return nullptr;
335*c8dee2aaSAndroid Build Coastguard Worker         }
336*c8dee2aaSAndroid Build Coastguard Worker         fMSAALoadPipelines.push_back({pipeline, &renderPass});
337*c8dee2aaSAndroid Build Coastguard Worker     }
338*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(pipeline);
339*c8dee2aaSAndroid Build Coastguard Worker     return pipeline;
340*c8dee2aaSAndroid Build Coastguard Worker }
341*c8dee2aaSAndroid Build Coastguard Worker 
getZeroSamplerDescriptorSetHandle(GrVkDescriptorSetManager::Handle * handle)342*c8dee2aaSAndroid Build Coastguard Worker void GrVkResourceProvider::getZeroSamplerDescriptorSetHandle(
343*c8dee2aaSAndroid Build Coastguard Worker         GrVkDescriptorSetManager::Handle* handle) {
344*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(handle);
345*c8dee2aaSAndroid Build Coastguard Worker     for (int i = 0; i < fDescriptorSetManagers.size(); ++i) {
346*c8dee2aaSAndroid Build Coastguard Worker         if (fDescriptorSetManagers[i]->isZeroSampler()) {
347*c8dee2aaSAndroid Build Coastguard Worker             *handle = GrVkDescriptorSetManager::Handle(i);
348*c8dee2aaSAndroid Build Coastguard Worker             return;
349*c8dee2aaSAndroid Build Coastguard Worker         }
350*c8dee2aaSAndroid Build Coastguard Worker     }
351*c8dee2aaSAndroid Build Coastguard Worker 
352*c8dee2aaSAndroid Build Coastguard Worker     GrVkDescriptorSetManager* dsm =
353*c8dee2aaSAndroid Build Coastguard Worker             GrVkDescriptorSetManager::CreateZeroSamplerManager(fGpu);
354*c8dee2aaSAndroid Build Coastguard Worker     fDescriptorSetManagers.emplace_back(dsm);
355*c8dee2aaSAndroid Build Coastguard Worker     *handle = GrVkDescriptorSetManager::Handle(fDescriptorSetManagers.size() - 1);
356*c8dee2aaSAndroid Build Coastguard Worker }
357*c8dee2aaSAndroid Build Coastguard Worker 
getSamplerDescriptorSetHandle(VkDescriptorType type,const GrVkUniformHandler & uniformHandler,GrVkDescriptorSetManager::Handle * handle)358*c8dee2aaSAndroid Build Coastguard Worker void GrVkResourceProvider::getSamplerDescriptorSetHandle(VkDescriptorType type,
359*c8dee2aaSAndroid Build Coastguard Worker                                                          const GrVkUniformHandler& uniformHandler,
360*c8dee2aaSAndroid Build Coastguard Worker                                                          GrVkDescriptorSetManager::Handle* handle) {
361*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(handle);
362*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER == type ||
363*c8dee2aaSAndroid Build Coastguard Worker              VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER == type);
364*c8dee2aaSAndroid Build Coastguard Worker     for (int i = 0; i < fDescriptorSetManagers.size(); ++i) {
365*c8dee2aaSAndroid Build Coastguard Worker         if (fDescriptorSetManagers[i]->isCompatible(type, &uniformHandler)) {
366*c8dee2aaSAndroid Build Coastguard Worker            *handle = GrVkDescriptorSetManager::Handle(i);
367*c8dee2aaSAndroid Build Coastguard Worker            return;
368*c8dee2aaSAndroid Build Coastguard Worker         }
369*c8dee2aaSAndroid Build Coastguard Worker     }
370*c8dee2aaSAndroid Build Coastguard Worker 
371*c8dee2aaSAndroid Build Coastguard Worker     GrVkDescriptorSetManager* dsm = GrVkDescriptorSetManager::CreateSamplerManager(fGpu, type,
372*c8dee2aaSAndroid Build Coastguard Worker                                                                                    uniformHandler);
373*c8dee2aaSAndroid Build Coastguard Worker     fDescriptorSetManagers.emplace_back(dsm);
374*c8dee2aaSAndroid Build Coastguard Worker     *handle = GrVkDescriptorSetManager::Handle(fDescriptorSetManagers.size() - 1);
375*c8dee2aaSAndroid Build Coastguard Worker }
376*c8dee2aaSAndroid Build Coastguard Worker 
getUniformDSLayout() const377*c8dee2aaSAndroid Build Coastguard Worker VkDescriptorSetLayout GrVkResourceProvider::getUniformDSLayout() const {
378*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(fUniformDSHandle.isValid());
379*c8dee2aaSAndroid Build Coastguard Worker     return fDescriptorSetManagers[fUniformDSHandle.toIndex()]->layout();
380*c8dee2aaSAndroid Build Coastguard Worker }
381*c8dee2aaSAndroid Build Coastguard Worker 
getInputDSLayout() const382*c8dee2aaSAndroid Build Coastguard Worker VkDescriptorSetLayout GrVkResourceProvider::getInputDSLayout() const {
383*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(fInputDSHandle.isValid());
384*c8dee2aaSAndroid Build Coastguard Worker     return fDescriptorSetManagers[fInputDSHandle.toIndex()]->layout();
385*c8dee2aaSAndroid Build Coastguard Worker }
386*c8dee2aaSAndroid Build Coastguard Worker 
getSamplerDSLayout(const GrVkDescriptorSetManager::Handle & handle) const387*c8dee2aaSAndroid Build Coastguard Worker VkDescriptorSetLayout GrVkResourceProvider::getSamplerDSLayout(
388*c8dee2aaSAndroid Build Coastguard Worker         const GrVkDescriptorSetManager::Handle& handle) const {
389*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(handle.isValid());
390*c8dee2aaSAndroid Build Coastguard Worker     return fDescriptorSetManagers[handle.toIndex()]->layout();
391*c8dee2aaSAndroid Build Coastguard Worker }
392*c8dee2aaSAndroid Build Coastguard Worker 
getUniformDescriptorSet()393*c8dee2aaSAndroid Build Coastguard Worker const GrVkDescriptorSet* GrVkResourceProvider::getUniformDescriptorSet() {
394*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(fUniformDSHandle.isValid());
395*c8dee2aaSAndroid Build Coastguard Worker     return fDescriptorSetManagers[fUniformDSHandle.toIndex()]->getDescriptorSet(fGpu,
396*c8dee2aaSAndroid Build Coastguard Worker                                                                                 fUniformDSHandle);
397*c8dee2aaSAndroid Build Coastguard Worker }
398*c8dee2aaSAndroid Build Coastguard Worker 
getInputDescriptorSet()399*c8dee2aaSAndroid Build Coastguard Worker const GrVkDescriptorSet* GrVkResourceProvider::getInputDescriptorSet() {
400*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(fInputDSHandle.isValid());
401*c8dee2aaSAndroid Build Coastguard Worker     return fDescriptorSetManagers[fInputDSHandle.toIndex()]->getDescriptorSet(fGpu, fInputDSHandle);
402*c8dee2aaSAndroid Build Coastguard Worker }
403*c8dee2aaSAndroid Build Coastguard Worker 
getSamplerDescriptorSet(const GrVkDescriptorSetManager::Handle & handle)404*c8dee2aaSAndroid Build Coastguard Worker const GrVkDescriptorSet* GrVkResourceProvider::getSamplerDescriptorSet(
405*c8dee2aaSAndroid Build Coastguard Worker         const GrVkDescriptorSetManager::Handle& handle) {
406*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(handle.isValid());
407*c8dee2aaSAndroid Build Coastguard Worker     return fDescriptorSetManagers[handle.toIndex()]->getDescriptorSet(fGpu, handle);
408*c8dee2aaSAndroid Build Coastguard Worker }
409*c8dee2aaSAndroid Build Coastguard Worker 
recycleDescriptorSet(const GrVkDescriptorSet * descSet,const GrVkDescriptorSetManager::Handle & handle)410*c8dee2aaSAndroid Build Coastguard Worker void GrVkResourceProvider::recycleDescriptorSet(const GrVkDescriptorSet* descSet,
411*c8dee2aaSAndroid Build Coastguard Worker                                                 const GrVkDescriptorSetManager::Handle& handle) {
412*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(descSet);
413*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(handle.isValid());
414*c8dee2aaSAndroid Build Coastguard Worker     int managerIdx = handle.toIndex();
415*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(managerIdx < fDescriptorSetManagers.size());
416*c8dee2aaSAndroid Build Coastguard Worker     fDescriptorSetManagers[managerIdx]->recycleDescriptorSet(descSet);
417*c8dee2aaSAndroid Build Coastguard Worker }
418*c8dee2aaSAndroid Build Coastguard Worker 
findOrCreateCommandPool()419*c8dee2aaSAndroid Build Coastguard Worker GrVkCommandPool* GrVkResourceProvider::findOrCreateCommandPool() {
420*c8dee2aaSAndroid Build Coastguard Worker     GrVkCommandPool* result;
421*c8dee2aaSAndroid Build Coastguard Worker     if (!fAvailableCommandPools.empty()) {
422*c8dee2aaSAndroid Build Coastguard Worker         result = fAvailableCommandPools.back();
423*c8dee2aaSAndroid Build Coastguard Worker         fAvailableCommandPools.pop_back();
424*c8dee2aaSAndroid Build Coastguard Worker     } else {
425*c8dee2aaSAndroid Build Coastguard Worker         result = GrVkCommandPool::Create(fGpu);
426*c8dee2aaSAndroid Build Coastguard Worker         if (!result) {
427*c8dee2aaSAndroid Build Coastguard Worker             return nullptr;
428*c8dee2aaSAndroid Build Coastguard Worker         }
429*c8dee2aaSAndroid Build Coastguard Worker     }
430*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(result->unique());
431*c8dee2aaSAndroid Build Coastguard Worker     SkDEBUGCODE(
432*c8dee2aaSAndroid Build Coastguard Worker         for (const GrVkCommandPool* pool : fActiveCommandPools) {
433*c8dee2aaSAndroid Build Coastguard Worker             SkASSERT(pool != result);
434*c8dee2aaSAndroid Build Coastguard Worker         }
435*c8dee2aaSAndroid Build Coastguard Worker         for (const GrVkCommandPool* pool : fAvailableCommandPools) {
436*c8dee2aaSAndroid Build Coastguard Worker             SkASSERT(pool != result);
437*c8dee2aaSAndroid Build Coastguard Worker         }
438*c8dee2aaSAndroid Build Coastguard Worker     )
439*c8dee2aaSAndroid Build Coastguard Worker     fActiveCommandPools.push_back(result);
440*c8dee2aaSAndroid Build Coastguard Worker     result->ref();
441*c8dee2aaSAndroid Build Coastguard Worker     return result;
442*c8dee2aaSAndroid Build Coastguard Worker }
443*c8dee2aaSAndroid Build Coastguard Worker 
checkCommandBuffers()444*c8dee2aaSAndroid Build Coastguard Worker void GrVkResourceProvider::checkCommandBuffers() {
445*c8dee2aaSAndroid Build Coastguard Worker     // When resetting a command buffer it can trigger client provided procs (e.g. release or
446*c8dee2aaSAndroid Build Coastguard Worker     // finished) to be called. During these calls the client could trigger us to abandon the vk
447*c8dee2aaSAndroid Build Coastguard Worker     // context, e.g. if we are in a DEVICE_LOST state. When we abandon the vk context we will
448*c8dee2aaSAndroid Build Coastguard Worker     // unref all the fActiveCommandPools and reset the array. Since this can happen in the middle
449*c8dee2aaSAndroid Build Coastguard Worker     // of the loop here, we need to additionally check that fActiveCommandPools still has pools on
450*c8dee2aaSAndroid Build Coastguard Worker     // each iteration.
451*c8dee2aaSAndroid Build Coastguard Worker     //
452*c8dee2aaSAndroid Build Coastguard Worker     // TODO: We really need to have a more robust way to protect us from client proc calls that
453*c8dee2aaSAndroid Build Coastguard Worker     // happen in the middle of us doing work. This may be just one of many potential pitfalls that
454*c8dee2aaSAndroid Build Coastguard Worker     // could happen from the client triggering GrDirectContext changes during a proc call.
455*c8dee2aaSAndroid Build Coastguard Worker     for (int i = fActiveCommandPools.size() - 1; !fActiveCommandPools.empty() && i >= 0; --i) {
456*c8dee2aaSAndroid Build Coastguard Worker         GrVkCommandPool* pool = fActiveCommandPools[i];
457*c8dee2aaSAndroid Build Coastguard Worker         if (!pool->isOpen()) {
458*c8dee2aaSAndroid Build Coastguard Worker             GrVkPrimaryCommandBuffer* buffer = pool->getPrimaryCommandBuffer();
459*c8dee2aaSAndroid Build Coastguard Worker             if (buffer->finished(fGpu)) {
460*c8dee2aaSAndroid Build Coastguard Worker                 fActiveCommandPools.removeShuffle(i);
461*c8dee2aaSAndroid Build Coastguard Worker                 SkASSERT(pool->unique());
462*c8dee2aaSAndroid Build Coastguard Worker                 pool->reset(fGpu);
463*c8dee2aaSAndroid Build Coastguard Worker                 // After resetting the pool (specifically releasing the pool's resources) we may
464*c8dee2aaSAndroid Build Coastguard Worker                 // have called a client callback proc which may have disconnected the GrVkGpu. In
465*c8dee2aaSAndroid Build Coastguard Worker                 // that case we do not want to push the pool back onto the cache, but instead just
466*c8dee2aaSAndroid Build Coastguard Worker                 // drop the pool.
467*c8dee2aaSAndroid Build Coastguard Worker                 if (fGpu->disconnected()) {
468*c8dee2aaSAndroid Build Coastguard Worker                     pool->unref();
469*c8dee2aaSAndroid Build Coastguard Worker                     return;
470*c8dee2aaSAndroid Build Coastguard Worker                 }
471*c8dee2aaSAndroid Build Coastguard Worker                 fAvailableCommandPools.push_back(pool);
472*c8dee2aaSAndroid Build Coastguard Worker             }
473*c8dee2aaSAndroid Build Coastguard Worker         }
474*c8dee2aaSAndroid Build Coastguard Worker     }
475*c8dee2aaSAndroid Build Coastguard Worker }
476*c8dee2aaSAndroid Build Coastguard Worker 
forceSyncAllCommandBuffers()477*c8dee2aaSAndroid Build Coastguard Worker void GrVkResourceProvider::forceSyncAllCommandBuffers() {
478*c8dee2aaSAndroid Build Coastguard Worker     for (int i = fActiveCommandPools.size() - 1; !fActiveCommandPools.empty() && i >= 0; --i) {
479*c8dee2aaSAndroid Build Coastguard Worker         GrVkCommandPool* pool = fActiveCommandPools[i];
480*c8dee2aaSAndroid Build Coastguard Worker         if (!pool->isOpen()) {
481*c8dee2aaSAndroid Build Coastguard Worker             GrVkPrimaryCommandBuffer* buffer = pool->getPrimaryCommandBuffer();
482*c8dee2aaSAndroid Build Coastguard Worker             buffer->forceSync(fGpu);
483*c8dee2aaSAndroid Build Coastguard Worker         }
484*c8dee2aaSAndroid Build Coastguard Worker     }
485*c8dee2aaSAndroid Build Coastguard Worker }
486*c8dee2aaSAndroid Build Coastguard Worker 
addFinishedProcToActiveCommandBuffers(sk_sp<skgpu::RefCntedCallback> finishedCallback)487*c8dee2aaSAndroid Build Coastguard Worker void GrVkResourceProvider::addFinishedProcToActiveCommandBuffers(
488*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<skgpu::RefCntedCallback> finishedCallback) {
489*c8dee2aaSAndroid Build Coastguard Worker     for (int i = 0; i < fActiveCommandPools.size(); ++i) {
490*c8dee2aaSAndroid Build Coastguard Worker         GrVkCommandPool* pool = fActiveCommandPools[i];
491*c8dee2aaSAndroid Build Coastguard Worker         GrVkPrimaryCommandBuffer* buffer = pool->getPrimaryCommandBuffer();
492*c8dee2aaSAndroid Build Coastguard Worker         buffer->addFinishedProc(finishedCallback);
493*c8dee2aaSAndroid Build Coastguard Worker     }
494*c8dee2aaSAndroid Build Coastguard Worker }
495*c8dee2aaSAndroid Build Coastguard Worker 
destroyResources()496*c8dee2aaSAndroid Build Coastguard Worker void GrVkResourceProvider::destroyResources() {
497*c8dee2aaSAndroid Build Coastguard Worker     SkTaskGroup* taskGroup = fGpu->getContext()->priv().getTaskGroup();
498*c8dee2aaSAndroid Build Coastguard Worker     if (taskGroup) {
499*c8dee2aaSAndroid Build Coastguard Worker         taskGroup->wait();
500*c8dee2aaSAndroid Build Coastguard Worker     }
501*c8dee2aaSAndroid Build Coastguard Worker 
502*c8dee2aaSAndroid Build Coastguard Worker     // Release all msaa load pipelines
503*c8dee2aaSAndroid Build Coastguard Worker     fMSAALoadPipelines.clear();
504*c8dee2aaSAndroid Build Coastguard Worker 
505*c8dee2aaSAndroid Build Coastguard Worker     // loop over all render pass sets to make sure we destroy all the internal VkRenderPasses
506*c8dee2aaSAndroid Build Coastguard Worker     for (int i = 0; i < fRenderPassArray.size(); ++i) {
507*c8dee2aaSAndroid Build Coastguard Worker         fRenderPassArray[i].releaseResources();
508*c8dee2aaSAndroid Build Coastguard Worker     }
509*c8dee2aaSAndroid Build Coastguard Worker     fRenderPassArray.clear();
510*c8dee2aaSAndroid Build Coastguard Worker 
511*c8dee2aaSAndroid Build Coastguard Worker     for (int i = 0; i < fExternalRenderPasses.size(); ++i) {
512*c8dee2aaSAndroid Build Coastguard Worker         fExternalRenderPasses[i]->unref();
513*c8dee2aaSAndroid Build Coastguard Worker     }
514*c8dee2aaSAndroid Build Coastguard Worker     fExternalRenderPasses.clear();
515*c8dee2aaSAndroid Build Coastguard Worker 
516*c8dee2aaSAndroid Build Coastguard Worker     // Iterate through all store GrVkSamplers and unref them before resetting the hash table.
517*c8dee2aaSAndroid Build Coastguard Worker     fSamplers.foreach([&](auto* elt) { elt->unref(); });
518*c8dee2aaSAndroid Build Coastguard Worker     fSamplers.reset();
519*c8dee2aaSAndroid Build Coastguard Worker 
520*c8dee2aaSAndroid Build Coastguard Worker     fYcbcrConversions.foreach([&](auto* elt) { elt->unref(); });
521*c8dee2aaSAndroid Build Coastguard Worker     fYcbcrConversions.reset();
522*c8dee2aaSAndroid Build Coastguard Worker 
523*c8dee2aaSAndroid Build Coastguard Worker     fPipelineStateCache->release();
524*c8dee2aaSAndroid Build Coastguard Worker 
525*c8dee2aaSAndroid Build Coastguard Worker     GR_VK_CALL(fGpu->vkInterface(), DestroyPipelineCache(fGpu->device(), fPipelineCache, nullptr));
526*c8dee2aaSAndroid Build Coastguard Worker     fPipelineCache = VK_NULL_HANDLE;
527*c8dee2aaSAndroid Build Coastguard Worker 
528*c8dee2aaSAndroid Build Coastguard Worker     for (GrVkCommandPool* pool : fActiveCommandPools) {
529*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(pool->unique());
530*c8dee2aaSAndroid Build Coastguard Worker         pool->unref();
531*c8dee2aaSAndroid Build Coastguard Worker     }
532*c8dee2aaSAndroid Build Coastguard Worker     fActiveCommandPools.clear();
533*c8dee2aaSAndroid Build Coastguard Worker 
534*c8dee2aaSAndroid Build Coastguard Worker     for (GrVkCommandPool* pool : fAvailableCommandPools) {
535*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(pool->unique());
536*c8dee2aaSAndroid Build Coastguard Worker         pool->unref();
537*c8dee2aaSAndroid Build Coastguard Worker     }
538*c8dee2aaSAndroid Build Coastguard Worker     fAvailableCommandPools.clear();
539*c8dee2aaSAndroid Build Coastguard Worker 
540*c8dee2aaSAndroid Build Coastguard Worker     // We must release/destroy all command buffers and pipeline states before releasing the
541*c8dee2aaSAndroid Build Coastguard Worker     // GrVkDescriptorSetManagers. Additionally, we must release all uniform buffers since they hold
542*c8dee2aaSAndroid Build Coastguard Worker     // refs to GrVkDescriptorSets.
543*c8dee2aaSAndroid Build Coastguard Worker     for (int i = 0; i < fDescriptorSetManagers.size(); ++i) {
544*c8dee2aaSAndroid Build Coastguard Worker         fDescriptorSetManagers[i]->release(fGpu);
545*c8dee2aaSAndroid Build Coastguard Worker     }
546*c8dee2aaSAndroid Build Coastguard Worker     fDescriptorSetManagers.clear();
547*c8dee2aaSAndroid Build Coastguard Worker 
548*c8dee2aaSAndroid Build Coastguard Worker }
549*c8dee2aaSAndroid Build Coastguard Worker 
releaseUnlockedBackendObjects()550*c8dee2aaSAndroid Build Coastguard Worker void GrVkResourceProvider::releaseUnlockedBackendObjects() {
551*c8dee2aaSAndroid Build Coastguard Worker     for (GrVkCommandPool* pool : fAvailableCommandPools) {
552*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(pool->unique());
553*c8dee2aaSAndroid Build Coastguard Worker         pool->unref();
554*c8dee2aaSAndroid Build Coastguard Worker     }
555*c8dee2aaSAndroid Build Coastguard Worker     fAvailableCommandPools.clear();
556*c8dee2aaSAndroid Build Coastguard Worker }
557*c8dee2aaSAndroid Build Coastguard Worker 
storePipelineCacheData()558*c8dee2aaSAndroid Build Coastguard Worker void GrVkResourceProvider::storePipelineCacheData() {
559*c8dee2aaSAndroid Build Coastguard Worker     if (this->pipelineCache() == VK_NULL_HANDLE) {
560*c8dee2aaSAndroid Build Coastguard Worker         return;
561*c8dee2aaSAndroid Build Coastguard Worker     }
562*c8dee2aaSAndroid Build Coastguard Worker     size_t dataSize = 0;
563*c8dee2aaSAndroid Build Coastguard Worker     VkResult result;
564*c8dee2aaSAndroid Build Coastguard Worker     GR_VK_CALL_RESULT(fGpu, result, GetPipelineCacheData(fGpu->device(), this->pipelineCache(),
565*c8dee2aaSAndroid Build Coastguard Worker                                                          &dataSize, nullptr));
566*c8dee2aaSAndroid Build Coastguard Worker     if (result != VK_SUCCESS) {
567*c8dee2aaSAndroid Build Coastguard Worker         return;
568*c8dee2aaSAndroid Build Coastguard Worker     }
569*c8dee2aaSAndroid Build Coastguard Worker 
570*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<uint8_t[]> data(new uint8_t[dataSize]);
571*c8dee2aaSAndroid Build Coastguard Worker 
572*c8dee2aaSAndroid Build Coastguard Worker     GR_VK_CALL_RESULT(fGpu, result, GetPipelineCacheData(fGpu->device(), this->pipelineCache(),
573*c8dee2aaSAndroid Build Coastguard Worker                                                          &dataSize, (void*)data.get()));
574*c8dee2aaSAndroid Build Coastguard Worker     if (result != VK_SUCCESS) {
575*c8dee2aaSAndroid Build Coastguard Worker         return;
576*c8dee2aaSAndroid Build Coastguard Worker     }
577*c8dee2aaSAndroid Build Coastguard Worker 
578*c8dee2aaSAndroid Build Coastguard Worker     uint32_t key = GrVkGpu::kPipelineCache_PersistentCacheKeyType;
579*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkData> keyData = SkData::MakeWithoutCopy(&key, sizeof(uint32_t));
580*c8dee2aaSAndroid Build Coastguard Worker 
581*c8dee2aaSAndroid Build Coastguard Worker     fGpu->getContext()->priv().getPersistentCache()->store(
582*c8dee2aaSAndroid Build Coastguard Worker             *keyData, *SkData::MakeWithoutCopy(data.get(), dataSize), SkString("VkPipelineCache"));
583*c8dee2aaSAndroid Build Coastguard Worker }
584*c8dee2aaSAndroid Build Coastguard Worker 
585*c8dee2aaSAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
586*c8dee2aaSAndroid Build Coastguard Worker 
CompatibleRenderPassSet(GrVkRenderPass * renderPass)587*c8dee2aaSAndroid Build Coastguard Worker GrVkResourceProvider::CompatibleRenderPassSet::CompatibleRenderPassSet(GrVkRenderPass* renderPass)
588*c8dee2aaSAndroid Build Coastguard Worker         : fLastReturnedIndex(0) {
589*c8dee2aaSAndroid Build Coastguard Worker     renderPass->ref();
590*c8dee2aaSAndroid Build Coastguard Worker     fRenderPasses.push_back(renderPass);
591*c8dee2aaSAndroid Build Coastguard Worker }
592*c8dee2aaSAndroid Build Coastguard Worker 
isCompatible(const GrVkRenderPass::AttachmentsDescriptor & attachmentsDescriptor,GrVkRenderPass::AttachmentFlags attachmentFlags,SelfDependencyFlags selfDepFlags,LoadFromResolve loadFromResolve) const593*c8dee2aaSAndroid Build Coastguard Worker bool GrVkResourceProvider::CompatibleRenderPassSet::isCompatible(
594*c8dee2aaSAndroid Build Coastguard Worker         const GrVkRenderPass::AttachmentsDescriptor& attachmentsDescriptor,
595*c8dee2aaSAndroid Build Coastguard Worker         GrVkRenderPass::AttachmentFlags attachmentFlags,
596*c8dee2aaSAndroid Build Coastguard Worker         SelfDependencyFlags selfDepFlags,
597*c8dee2aaSAndroid Build Coastguard Worker         LoadFromResolve loadFromResolve) const {
598*c8dee2aaSAndroid Build Coastguard Worker     // The first GrVkRenderpass should always exists since we create the basic load store
599*c8dee2aaSAndroid Build Coastguard Worker     // render pass on create
600*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(fRenderPasses[0]);
601*c8dee2aaSAndroid Build Coastguard Worker     return fRenderPasses[0]->isCompatible(attachmentsDescriptor, attachmentFlags, selfDepFlags,
602*c8dee2aaSAndroid Build Coastguard Worker                                           loadFromResolve);
603*c8dee2aaSAndroid Build Coastguard Worker }
604*c8dee2aaSAndroid Build Coastguard Worker 
getRenderPass(GrVkGpu * gpu,const GrVkRenderPass::LoadStoreOps & colorOps,const GrVkRenderPass::LoadStoreOps & resolveOps,const GrVkRenderPass::LoadStoreOps & stencilOps)605*c8dee2aaSAndroid Build Coastguard Worker GrVkRenderPass* GrVkResourceProvider::CompatibleRenderPassSet::getRenderPass(
606*c8dee2aaSAndroid Build Coastguard Worker         GrVkGpu* gpu,
607*c8dee2aaSAndroid Build Coastguard Worker         const GrVkRenderPass::LoadStoreOps& colorOps,
608*c8dee2aaSAndroid Build Coastguard Worker         const GrVkRenderPass::LoadStoreOps& resolveOps,
609*c8dee2aaSAndroid Build Coastguard Worker         const GrVkRenderPass::LoadStoreOps& stencilOps) {
610*c8dee2aaSAndroid Build Coastguard Worker     for (int i = 0; i < fRenderPasses.size(); ++i) {
611*c8dee2aaSAndroid Build Coastguard Worker         int idx = (i + fLastReturnedIndex) % fRenderPasses.size();
612*c8dee2aaSAndroid Build Coastguard Worker         if (fRenderPasses[idx]->equalLoadStoreOps(colorOps, resolveOps, stencilOps)) {
613*c8dee2aaSAndroid Build Coastguard Worker             fLastReturnedIndex = idx;
614*c8dee2aaSAndroid Build Coastguard Worker             return fRenderPasses[idx];
615*c8dee2aaSAndroid Build Coastguard Worker         }
616*c8dee2aaSAndroid Build Coastguard Worker     }
617*c8dee2aaSAndroid Build Coastguard Worker     GrVkRenderPass* renderPass = GrVkRenderPass::Create(gpu, *this->getCompatibleRenderPass(),
618*c8dee2aaSAndroid Build Coastguard Worker                                                         colorOps, resolveOps, stencilOps);
619*c8dee2aaSAndroid Build Coastguard Worker     if (!renderPass) {
620*c8dee2aaSAndroid Build Coastguard Worker         return nullptr;
621*c8dee2aaSAndroid Build Coastguard Worker     }
622*c8dee2aaSAndroid Build Coastguard Worker     fRenderPasses.push_back(renderPass);
623*c8dee2aaSAndroid Build Coastguard Worker     fLastReturnedIndex = fRenderPasses.size() - 1;
624*c8dee2aaSAndroid Build Coastguard Worker     return renderPass;
625*c8dee2aaSAndroid Build Coastguard Worker }
626*c8dee2aaSAndroid Build Coastguard Worker 
releaseResources()627*c8dee2aaSAndroid Build Coastguard Worker void GrVkResourceProvider::CompatibleRenderPassSet::releaseResources() {
628*c8dee2aaSAndroid Build Coastguard Worker     for (int i = 0; i < fRenderPasses.size(); ++i) {
629*c8dee2aaSAndroid Build Coastguard Worker         if (fRenderPasses[i]) {
630*c8dee2aaSAndroid Build Coastguard Worker             fRenderPasses[i]->unref();
631*c8dee2aaSAndroid Build Coastguard Worker             fRenderPasses[i] = nullptr;
632*c8dee2aaSAndroid Build Coastguard Worker         }
633*c8dee2aaSAndroid Build Coastguard Worker     }
634*c8dee2aaSAndroid Build Coastguard Worker }
635*c8dee2aaSAndroid Build Coastguard Worker 
636