xref: /aosp_15_r20/external/skia/src/gpu/ganesh/vk/GrVkResourceProvider.h (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 #ifndef GrVkResourceProvider_DEFINED
9*c8dee2aaSAndroid Build Coastguard Worker #define GrVkResourceProvider_DEFINED
10*c8dee2aaSAndroid Build Coastguard Worker 
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkAssert.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTArray.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/gpu/vk/SkiaVulkan.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkChecksum.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkLRUCache.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkTDynamicHash.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrProgramDesc.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrResourceHandle.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrSamplerState.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrThreadSafePipelineBuilder.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/vk/GrVkDescriptorSetManager.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/vk/GrVkPipeline.h"
24*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/vk/GrVkRenderPass.h"
25*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/vk/GrVkSampler.h"
26*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/vk/GrVkSamplerYcbcrConversion.h"
27*c8dee2aaSAndroid Build Coastguard Worker 
28*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint>
29*c8dee2aaSAndroid Build Coastguard Worker #include <memory>
30*c8dee2aaSAndroid Build Coastguard Worker 
31*c8dee2aaSAndroid Build Coastguard Worker class GrProgramInfo;
32*c8dee2aaSAndroid Build Coastguard Worker class GrRenderTarget;
33*c8dee2aaSAndroid Build Coastguard Worker class GrVkCommandPool;
34*c8dee2aaSAndroid Build Coastguard Worker class GrVkDescriptorPool;
35*c8dee2aaSAndroid Build Coastguard Worker class GrVkDescriptorSet;
36*c8dee2aaSAndroid Build Coastguard Worker class GrVkGpu;
37*c8dee2aaSAndroid Build Coastguard Worker class GrVkPipelineState;
38*c8dee2aaSAndroid Build Coastguard Worker class GrVkRenderTarget;
39*c8dee2aaSAndroid Build Coastguard Worker class GrVkUniformHandler;
40*c8dee2aaSAndroid Build Coastguard Worker namespace skgpu {
41*c8dee2aaSAndroid Build Coastguard Worker class RefCntedCallback;
42*c8dee2aaSAndroid Build Coastguard Worker struct VulkanYcbcrConversionInfo;
43*c8dee2aaSAndroid Build Coastguard Worker }  // namespace skgpu
44*c8dee2aaSAndroid Build Coastguard Worker 
45*c8dee2aaSAndroid Build Coastguard Worker class GrVkResourceProvider {
46*c8dee2aaSAndroid Build Coastguard Worker public:
47*c8dee2aaSAndroid Build Coastguard Worker     GrVkResourceProvider(GrVkGpu* gpu);
48*c8dee2aaSAndroid Build Coastguard Worker     ~GrVkResourceProvider();
49*c8dee2aaSAndroid Build Coastguard Worker 
pipelineStateCache()50*c8dee2aaSAndroid Build Coastguard Worker     GrThreadSafePipelineBuilder* pipelineStateCache() {
51*c8dee2aaSAndroid Build Coastguard Worker         return fPipelineStateCache.get();
52*c8dee2aaSAndroid Build Coastguard Worker     }
53*c8dee2aaSAndroid Build Coastguard Worker 
refPipelineStateCache()54*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrThreadSafePipelineBuilder> refPipelineStateCache() {
55*c8dee2aaSAndroid Build Coastguard Worker         return fPipelineStateCache;
56*c8dee2aaSAndroid Build Coastguard Worker     }
57*c8dee2aaSAndroid Build Coastguard Worker 
58*c8dee2aaSAndroid Build Coastguard Worker     // Set up any initial vk objects
59*c8dee2aaSAndroid Build Coastguard Worker     void init();
60*c8dee2aaSAndroid Build Coastguard Worker 
61*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<const GrVkPipeline> makePipeline(const GrProgramInfo&,
62*c8dee2aaSAndroid Build Coastguard Worker                                            VkPipelineShaderStageCreateInfo* shaderStageInfo,
63*c8dee2aaSAndroid Build Coastguard Worker                                            int shaderStageCount,
64*c8dee2aaSAndroid Build Coastguard Worker                                            VkRenderPass compatibleRenderPass,
65*c8dee2aaSAndroid Build Coastguard Worker                                            VkPipelineLayout layout,
66*c8dee2aaSAndroid Build Coastguard Worker                                            uint32_t subpass);
67*c8dee2aaSAndroid Build Coastguard Worker 
68*c8dee2aaSAndroid Build Coastguard Worker     GR_DEFINE_RESOURCE_HANDLE_CLASS(CompatibleRPHandle)
69*c8dee2aaSAndroid Build Coastguard Worker 
70*c8dee2aaSAndroid Build Coastguard Worker     using SelfDependencyFlags = GrVkRenderPass::SelfDependencyFlags;
71*c8dee2aaSAndroid Build Coastguard Worker     using LoadFromResolve = GrVkRenderPass::LoadFromResolve;
72*c8dee2aaSAndroid Build Coastguard Worker 
73*c8dee2aaSAndroid Build Coastguard Worker     // Finds or creates a simple render pass that matches the target, increments the refcount,
74*c8dee2aaSAndroid Build Coastguard Worker     // and returns. The caller can optionally pass in a pointer to a CompatibleRPHandle. If this is
75*c8dee2aaSAndroid Build Coastguard Worker     // non null it will be set to a handle that can be used in the furutre to quickly return a
76*c8dee2aaSAndroid Build Coastguard Worker     // compatible GrVkRenderPasses without the need inspecting a GrVkRenderTarget.
77*c8dee2aaSAndroid Build Coastguard Worker     const GrVkRenderPass* findCompatibleRenderPass(GrVkRenderTarget* target,
78*c8dee2aaSAndroid Build Coastguard Worker                                                    CompatibleRPHandle* compatibleHandle,
79*c8dee2aaSAndroid Build Coastguard Worker                                                    bool withResolve,
80*c8dee2aaSAndroid Build Coastguard Worker                                                    bool withStencil,
81*c8dee2aaSAndroid Build Coastguard Worker                                                    SelfDependencyFlags selfDepFlags,
82*c8dee2aaSAndroid Build Coastguard Worker                                                    LoadFromResolve);
83*c8dee2aaSAndroid Build Coastguard Worker     const GrVkRenderPass* findCompatibleRenderPass(GrVkRenderPass::AttachmentsDescriptor*,
84*c8dee2aaSAndroid Build Coastguard Worker                                                    GrVkRenderPass::AttachmentFlags,
85*c8dee2aaSAndroid Build Coastguard Worker                                                    SelfDependencyFlags selfDepFlags,
86*c8dee2aaSAndroid Build Coastguard Worker                                                    LoadFromResolve,
87*c8dee2aaSAndroid Build Coastguard Worker                                                    CompatibleRPHandle* compatibleHandle = nullptr);
88*c8dee2aaSAndroid Build Coastguard Worker 
89*c8dee2aaSAndroid Build Coastguard Worker     const GrVkRenderPass* findCompatibleExternalRenderPass(VkRenderPass,
90*c8dee2aaSAndroid Build Coastguard Worker                                                            uint32_t colorAttachmentIndex);
91*c8dee2aaSAndroid Build Coastguard Worker 
92*c8dee2aaSAndroid Build Coastguard Worker 
93*c8dee2aaSAndroid Build Coastguard Worker     // Finds or creates a render pass that matches the target and LoadStoreOps, increments the
94*c8dee2aaSAndroid Build Coastguard Worker     // refcount, and returns. The caller can optionally pass in a pointer to a CompatibleRPHandle.
95*c8dee2aaSAndroid Build Coastguard Worker     // If this is non null it will be set to a handle that can be used in the future to quickly
96*c8dee2aaSAndroid Build Coastguard Worker     // return a GrVkRenderPass without the need to inspect a GrVkRenderTarget.
97*c8dee2aaSAndroid Build Coastguard Worker     // TODO: sk_sp?
98*c8dee2aaSAndroid Build Coastguard Worker     const GrVkRenderPass* findRenderPass(GrVkRenderTarget* target,
99*c8dee2aaSAndroid Build Coastguard Worker                                          const GrVkRenderPass::LoadStoreOps& colorOps,
100*c8dee2aaSAndroid Build Coastguard Worker                                          const GrVkRenderPass::LoadStoreOps& resolveOps,
101*c8dee2aaSAndroid Build Coastguard Worker                                          const GrVkRenderPass::LoadStoreOps& stencilOps,
102*c8dee2aaSAndroid Build Coastguard Worker                                          CompatibleRPHandle* compatibleHandle,
103*c8dee2aaSAndroid Build Coastguard Worker                                          bool withResolve,
104*c8dee2aaSAndroid Build Coastguard Worker                                          bool withStencil,
105*c8dee2aaSAndroid Build Coastguard Worker                                          SelfDependencyFlags selfDepFlags,
106*c8dee2aaSAndroid Build Coastguard Worker                                          LoadFromResolve);
107*c8dee2aaSAndroid Build Coastguard Worker 
108*c8dee2aaSAndroid Build Coastguard Worker     // The CompatibleRPHandle must be a valid handle previously set by a call to findRenderPass or
109*c8dee2aaSAndroid Build Coastguard Worker     // findCompatibleRenderPass.
110*c8dee2aaSAndroid Build Coastguard Worker     const GrVkRenderPass* findRenderPass(const CompatibleRPHandle& compatibleHandle,
111*c8dee2aaSAndroid Build Coastguard Worker                                          const GrVkRenderPass::LoadStoreOps& colorOps,
112*c8dee2aaSAndroid Build Coastguard Worker                                          const GrVkRenderPass::LoadStoreOps& resolveOps,
113*c8dee2aaSAndroid Build Coastguard Worker                                          const GrVkRenderPass::LoadStoreOps& stencilOps);
114*c8dee2aaSAndroid Build Coastguard Worker 
115*c8dee2aaSAndroid Build Coastguard Worker     GrVkCommandPool* findOrCreateCommandPool();
116*c8dee2aaSAndroid Build Coastguard Worker 
117*c8dee2aaSAndroid Build Coastguard Worker     void checkCommandBuffers();
118*c8dee2aaSAndroid Build Coastguard Worker 
119*c8dee2aaSAndroid Build Coastguard Worker     void forceSyncAllCommandBuffers();
120*c8dee2aaSAndroid Build Coastguard Worker 
121*c8dee2aaSAndroid Build Coastguard Worker     // We must add the finishedProc to all active command buffers since we may have flushed work
122*c8dee2aaSAndroid Build Coastguard Worker     // that the client cares about before they explicitly called flush and the GPU may reorder
123*c8dee2aaSAndroid Build Coastguard Worker     // command execution. So we make sure all previously submitted work finishes before we call the
124*c8dee2aaSAndroid Build Coastguard Worker     // finishedProc.
125*c8dee2aaSAndroid Build Coastguard Worker     void addFinishedProcToActiveCommandBuffers(sk_sp<skgpu::RefCntedCallback> finishedCallback);
126*c8dee2aaSAndroid Build Coastguard Worker 
127*c8dee2aaSAndroid Build Coastguard Worker     // Finds or creates a compatible GrVkDescriptorPool for the requested type and count.
128*c8dee2aaSAndroid Build Coastguard Worker     // The refcount is incremented and a pointer returned.
129*c8dee2aaSAndroid Build Coastguard Worker     // TODO: Currently this will just create a descriptor pool without holding onto a ref itself
130*c8dee2aaSAndroid Build Coastguard Worker     //       so we currently do not reuse them. Rquires knowing if another draw is currently using
131*c8dee2aaSAndroid Build Coastguard Worker     //       the GrVkDescriptorPool, the ability to reset pools, and the ability to purge pools out
132*c8dee2aaSAndroid Build Coastguard Worker     //       of our cache of GrVkDescriptorPools.
133*c8dee2aaSAndroid Build Coastguard Worker     GrVkDescriptorPool* findOrCreateCompatibleDescriptorPool(VkDescriptorType type, uint32_t count);
134*c8dee2aaSAndroid Build Coastguard Worker 
135*c8dee2aaSAndroid Build Coastguard Worker     // Finds or creates a compatible GrVkSampler based on the GrSamplerState and
136*c8dee2aaSAndroid Build Coastguard Worker     // skgpu::VulkanYcbcrConversionInfo. The refcount is incremented and a pointer returned.
137*c8dee2aaSAndroid Build Coastguard Worker     GrVkSampler* findOrCreateCompatibleSampler(GrSamplerState,
138*c8dee2aaSAndroid Build Coastguard Worker                                                const skgpu::VulkanYcbcrConversionInfo& ycbcrInfo);
139*c8dee2aaSAndroid Build Coastguard Worker 
140*c8dee2aaSAndroid Build Coastguard Worker     // Finds or creates a compatible GrVkSamplerYcbcrConversion based on the GrSamplerState and
141*c8dee2aaSAndroid Build Coastguard Worker     // skgpu::VulkanYcbcrConversionInfo. The refcount is incremented and a pointer returned.
142*c8dee2aaSAndroid Build Coastguard Worker     GrVkSamplerYcbcrConversion* findOrCreateCompatibleSamplerYcbcrConversion(
143*c8dee2aaSAndroid Build Coastguard Worker             const skgpu::VulkanYcbcrConversionInfo& ycbcrInfo);
144*c8dee2aaSAndroid Build Coastguard Worker 
145*c8dee2aaSAndroid Build Coastguard Worker     GrVkPipelineState* findOrCreateCompatiblePipelineState(
146*c8dee2aaSAndroid Build Coastguard Worker             GrRenderTarget*,
147*c8dee2aaSAndroid Build Coastguard Worker             const GrProgramInfo&,
148*c8dee2aaSAndroid Build Coastguard Worker             VkRenderPass compatibleRenderPass,
149*c8dee2aaSAndroid Build Coastguard Worker             bool overrideSubpassForResolveLoad);
150*c8dee2aaSAndroid Build Coastguard Worker 
151*c8dee2aaSAndroid Build Coastguard Worker     GrVkPipelineState* findOrCreateCompatiblePipelineState(
152*c8dee2aaSAndroid Build Coastguard Worker             const GrProgramDesc&,
153*c8dee2aaSAndroid Build Coastguard Worker             const GrProgramInfo&,
154*c8dee2aaSAndroid Build Coastguard Worker             VkRenderPass compatibleRenderPass,
155*c8dee2aaSAndroid Build Coastguard Worker             GrThreadSafePipelineBuilder::Stats::ProgramCacheResult* stat);
156*c8dee2aaSAndroid Build Coastguard Worker 
157*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<const GrVkPipeline> findOrCreateMSAALoadPipeline(
158*c8dee2aaSAndroid Build Coastguard Worker             const GrVkRenderPass& renderPass,
159*c8dee2aaSAndroid Build Coastguard Worker             int numSamples,
160*c8dee2aaSAndroid Build Coastguard Worker             VkPipelineShaderStageCreateInfo*,
161*c8dee2aaSAndroid Build Coastguard Worker             VkPipelineLayout);
162*c8dee2aaSAndroid Build Coastguard Worker 
163*c8dee2aaSAndroid Build Coastguard Worker     void getSamplerDescriptorSetHandle(VkDescriptorType type,
164*c8dee2aaSAndroid Build Coastguard Worker                                        const GrVkUniformHandler&,
165*c8dee2aaSAndroid Build Coastguard Worker                                        GrVkDescriptorSetManager::Handle* handle);
166*c8dee2aaSAndroid Build Coastguard Worker 
167*c8dee2aaSAndroid Build Coastguard Worker     // This is a convenience function to return a descriptor set for zero sammples. When making a
168*c8dee2aaSAndroid Build Coastguard Worker     // VkPipelineLayout we must pass in an array of valid descriptor set handles. However, we have
169*c8dee2aaSAndroid Build Coastguard Worker     // set up our system to have the descriptor sets be in the order uniform, sampler, input. So
170*c8dee2aaSAndroid Build Coastguard Worker     // if we have a uniform and input we will need to have a valid handle for the sampler as well.
171*c8dee2aaSAndroid Build Coastguard Worker     // When using the GrVkMSAALoadManager this is the case, but we also don't have a
172*c8dee2aaSAndroid Build Coastguard Worker     // GrVkUniformHandler to pass into the more general function. Thus we use this call instead.
173*c8dee2aaSAndroid Build Coastguard Worker     void getZeroSamplerDescriptorSetHandle(GrVkDescriptorSetManager::Handle* handle);
174*c8dee2aaSAndroid Build Coastguard Worker 
175*c8dee2aaSAndroid Build Coastguard Worker     // Returns the compatible VkDescriptorSetLayout to use for uniform buffers. The caller does not
176*c8dee2aaSAndroid Build Coastguard Worker     // own the VkDescriptorSetLayout and thus should not delete it. This function should be used
177*c8dee2aaSAndroid Build Coastguard Worker     // when the caller needs the layout to create a VkPipelineLayout.
178*c8dee2aaSAndroid Build Coastguard Worker     VkDescriptorSetLayout getUniformDSLayout() const;
179*c8dee2aaSAndroid Build Coastguard Worker 
180*c8dee2aaSAndroid Build Coastguard Worker     // Returns the compatible VkDescriptorSetLayout to use for input attachments. The caller does
181*c8dee2aaSAndroid Build Coastguard Worker     // not own the VkDescriptorSetLayout and thus should not delete it. This function should be used
182*c8dee2aaSAndroid Build Coastguard Worker     // when the caller needs the layout to create a VkPipelineLayout.
183*c8dee2aaSAndroid Build Coastguard Worker     VkDescriptorSetLayout getInputDSLayout() const;
184*c8dee2aaSAndroid Build Coastguard Worker 
185*c8dee2aaSAndroid Build Coastguard Worker     // Returns the compatible VkDescriptorSetLayout to use for a specific sampler handle. The caller
186*c8dee2aaSAndroid Build Coastguard Worker     // does not own the VkDescriptorSetLayout and thus should not delete it. This function should be
187*c8dee2aaSAndroid Build Coastguard Worker     // used when the caller needs the layout to create a VkPipelineLayout.
188*c8dee2aaSAndroid Build Coastguard Worker     VkDescriptorSetLayout getSamplerDSLayout(const GrVkDescriptorSetManager::Handle&) const;
189*c8dee2aaSAndroid Build Coastguard Worker 
190*c8dee2aaSAndroid Build Coastguard Worker     // Returns a GrVkDescriptorSet that can be used for uniform buffers. The GrVkDescriptorSet
191*c8dee2aaSAndroid Build Coastguard Worker     // is already reffed for the caller.
192*c8dee2aaSAndroid Build Coastguard Worker     const GrVkDescriptorSet* getUniformDescriptorSet();
193*c8dee2aaSAndroid Build Coastguard Worker 
194*c8dee2aaSAndroid Build Coastguard Worker     // Returns a GrVkDescriptorSet that can be used for sampler descriptors that are compatible with
195*c8dee2aaSAndroid Build Coastguard Worker     // the GrVkDescriptorSetManager::Handle passed in. The GrVkDescriptorSet is already reffed for
196*c8dee2aaSAndroid Build Coastguard Worker     // the caller.
197*c8dee2aaSAndroid Build Coastguard Worker     const GrVkDescriptorSet* getSamplerDescriptorSet(const GrVkDescriptorSetManager::Handle&);
198*c8dee2aaSAndroid Build Coastguard Worker 
199*c8dee2aaSAndroid Build Coastguard Worker     // Returns a GrVkDescriptorSet that can be used for input attachments. The GrVkDescriptorSet
200*c8dee2aaSAndroid Build Coastguard Worker     // is already reffed for the caller.
201*c8dee2aaSAndroid Build Coastguard Worker     const GrVkDescriptorSet* getInputDescriptorSet();
202*c8dee2aaSAndroid Build Coastguard Worker 
203*c8dee2aaSAndroid Build Coastguard Worker     // Signals that the descriptor set passed it, which is compatible with the passed in handle,
204*c8dee2aaSAndroid Build Coastguard Worker     // can be reused by the next allocation request.
205*c8dee2aaSAndroid Build Coastguard Worker     void recycleDescriptorSet(const GrVkDescriptorSet* descSet,
206*c8dee2aaSAndroid Build Coastguard Worker                               const GrVkDescriptorSetManager::Handle&);
207*c8dee2aaSAndroid Build Coastguard Worker 
208*c8dee2aaSAndroid Build Coastguard Worker     void storePipelineCacheData();
209*c8dee2aaSAndroid Build Coastguard Worker 
210*c8dee2aaSAndroid Build Coastguard Worker     // Destroy any cached resources. To be called before destroying the VkDevice.
211*c8dee2aaSAndroid Build Coastguard Worker     // The assumption is that all queues are idle and all command buffers are finished.
212*c8dee2aaSAndroid Build Coastguard Worker     // For resource tracing to work properly, this should be called after unrefing all other
213*c8dee2aaSAndroid Build Coastguard Worker     // resource usages.
214*c8dee2aaSAndroid Build Coastguard Worker     void destroyResources();
215*c8dee2aaSAndroid Build Coastguard Worker 
216*c8dee2aaSAndroid Build Coastguard Worker     // Currently we just release available command pools (which also releases their buffers). The
217*c8dee2aaSAndroid Build Coastguard Worker     // command buffers and pools take up the most memory. Other objects (e.g. samples,
218*c8dee2aaSAndroid Build Coastguard Worker     // ycbcr conversions, etc.) tend to be fairly light weight and not worth the effort to remove
219*c8dee2aaSAndroid Build Coastguard Worker     // them and then possibly remake them. Additionally many of those objects have refs/handles that
220*c8dee2aaSAndroid Build Coastguard Worker     // are held by other objects that aren't deleted here. Thus the memory wins for removing these
221*c8dee2aaSAndroid Build Coastguard Worker     // objects from the cache are probably not worth the complexity of safely releasing them.
222*c8dee2aaSAndroid Build Coastguard Worker     void releaseUnlockedBackendObjects();
223*c8dee2aaSAndroid Build Coastguard Worker 
224*c8dee2aaSAndroid Build Coastguard Worker #if defined(GPU_TEST_UTILS)
resetShaderCacheForTesting()225*c8dee2aaSAndroid Build Coastguard Worker     void resetShaderCacheForTesting() const { fPipelineStateCache->release(); }
226*c8dee2aaSAndroid Build Coastguard Worker #endif
227*c8dee2aaSAndroid Build Coastguard Worker 
228*c8dee2aaSAndroid Build Coastguard Worker private:
229*c8dee2aaSAndroid Build Coastguard Worker     class PipelineStateCache : public GrThreadSafePipelineBuilder {
230*c8dee2aaSAndroid Build Coastguard Worker     public:
231*c8dee2aaSAndroid Build Coastguard Worker         PipelineStateCache(GrVkGpu* gpu);
232*c8dee2aaSAndroid Build Coastguard Worker         ~PipelineStateCache() override;
233*c8dee2aaSAndroid Build Coastguard Worker 
234*c8dee2aaSAndroid Build Coastguard Worker         void release();
235*c8dee2aaSAndroid Build Coastguard Worker         GrVkPipelineState* findOrCreatePipelineState(GrRenderTarget*,
236*c8dee2aaSAndroid Build Coastguard Worker                                                      const GrProgramInfo&,
237*c8dee2aaSAndroid Build Coastguard Worker                                                      VkRenderPass compatibleRenderPass,
238*c8dee2aaSAndroid Build Coastguard Worker                                                      bool overrideSubpassForResolveLoad);
findOrCreatePipelineState(const GrProgramDesc & desc,const GrProgramInfo & programInfo,VkRenderPass compatibleRenderPass,Stats::ProgramCacheResult * stat)239*c8dee2aaSAndroid Build Coastguard Worker         GrVkPipelineState* findOrCreatePipelineState(const GrProgramDesc& desc,
240*c8dee2aaSAndroid Build Coastguard Worker                                                      const GrProgramInfo& programInfo,
241*c8dee2aaSAndroid Build Coastguard Worker                                                      VkRenderPass compatibleRenderPass,
242*c8dee2aaSAndroid Build Coastguard Worker                                                      Stats::ProgramCacheResult* stat) {
243*c8dee2aaSAndroid Build Coastguard Worker             return this->findOrCreatePipelineStateImpl(desc, programInfo, compatibleRenderPass,
244*c8dee2aaSAndroid Build Coastguard Worker                                                        false, stat);
245*c8dee2aaSAndroid Build Coastguard Worker         }
246*c8dee2aaSAndroid Build Coastguard Worker 
247*c8dee2aaSAndroid Build Coastguard Worker     private:
248*c8dee2aaSAndroid Build Coastguard Worker         struct Entry;
249*c8dee2aaSAndroid Build Coastguard Worker 
250*c8dee2aaSAndroid Build Coastguard Worker         GrVkPipelineState* findOrCreatePipelineStateImpl(const GrProgramDesc&,
251*c8dee2aaSAndroid Build Coastguard Worker                                                          const GrProgramInfo&,
252*c8dee2aaSAndroid Build Coastguard Worker                                                          VkRenderPass compatibleRenderPass,
253*c8dee2aaSAndroid Build Coastguard Worker                                                          bool overrideSubpassForResolveLoad,
254*c8dee2aaSAndroid Build Coastguard Worker                                                          Stats::ProgramCacheResult*);
255*c8dee2aaSAndroid Build Coastguard Worker 
256*c8dee2aaSAndroid Build Coastguard Worker         struct DescHash {
operatorDescHash257*c8dee2aaSAndroid Build Coastguard Worker             uint32_t operator()(const GrProgramDesc& desc) const {
258*c8dee2aaSAndroid Build Coastguard Worker                 return SkChecksum::Hash32(desc.asKey(), desc.keyLength());
259*c8dee2aaSAndroid Build Coastguard Worker             }
260*c8dee2aaSAndroid Build Coastguard Worker         };
261*c8dee2aaSAndroid Build Coastguard Worker 
262*c8dee2aaSAndroid Build Coastguard Worker         SkLRUCache<const GrProgramDesc, std::unique_ptr<Entry>, DescHash> fMap;
263*c8dee2aaSAndroid Build Coastguard Worker 
264*c8dee2aaSAndroid Build Coastguard Worker         GrVkGpu*                    fGpu;
265*c8dee2aaSAndroid Build Coastguard Worker     };
266*c8dee2aaSAndroid Build Coastguard Worker 
267*c8dee2aaSAndroid Build Coastguard Worker     class CompatibleRenderPassSet {
268*c8dee2aaSAndroid Build Coastguard Worker     public:
269*c8dee2aaSAndroid Build Coastguard Worker         // This will always construct the basic load store render pass (all attachments load and
270*c8dee2aaSAndroid Build Coastguard Worker         // store their data) so that there is at least one compatible VkRenderPass that can be used
271*c8dee2aaSAndroid Build Coastguard Worker         // with this set.
272*c8dee2aaSAndroid Build Coastguard Worker         CompatibleRenderPassSet(GrVkRenderPass* renderPass);
273*c8dee2aaSAndroid Build Coastguard Worker 
274*c8dee2aaSAndroid Build Coastguard Worker         bool isCompatible(const GrVkRenderPass::AttachmentsDescriptor&,
275*c8dee2aaSAndroid Build Coastguard Worker                           GrVkRenderPass::AttachmentFlags,
276*c8dee2aaSAndroid Build Coastguard Worker                           SelfDependencyFlags selfDepFlags,
277*c8dee2aaSAndroid Build Coastguard Worker                           LoadFromResolve) const;
278*c8dee2aaSAndroid Build Coastguard Worker 
getCompatibleRenderPass()279*c8dee2aaSAndroid Build Coastguard Worker         const GrVkRenderPass* getCompatibleRenderPass() const {
280*c8dee2aaSAndroid Build Coastguard Worker             // The first GrVkRenderpass should always exist since we create the basic load store
281*c8dee2aaSAndroid Build Coastguard Worker             // render pass on create
282*c8dee2aaSAndroid Build Coastguard Worker             SkASSERT(fRenderPasses[0]);
283*c8dee2aaSAndroid Build Coastguard Worker             return fRenderPasses[0];
284*c8dee2aaSAndroid Build Coastguard Worker         }
285*c8dee2aaSAndroid Build Coastguard Worker 
286*c8dee2aaSAndroid Build Coastguard Worker         GrVkRenderPass* getRenderPass(GrVkGpu* gpu,
287*c8dee2aaSAndroid Build Coastguard Worker                                       const GrVkRenderPass::LoadStoreOps& colorOps,
288*c8dee2aaSAndroid Build Coastguard Worker                                       const GrVkRenderPass::LoadStoreOps& resolveOps,
289*c8dee2aaSAndroid Build Coastguard Worker                                       const GrVkRenderPass::LoadStoreOps& stencilOps);
290*c8dee2aaSAndroid Build Coastguard Worker 
291*c8dee2aaSAndroid Build Coastguard Worker         void releaseResources();
292*c8dee2aaSAndroid Build Coastguard Worker 
293*c8dee2aaSAndroid Build Coastguard Worker     private:
294*c8dee2aaSAndroid Build Coastguard Worker         skia_private::STArray<4, GrVkRenderPass*> fRenderPasses;
295*c8dee2aaSAndroid Build Coastguard Worker         int                           fLastReturnedIndex;
296*c8dee2aaSAndroid Build Coastguard Worker     };
297*c8dee2aaSAndroid Build Coastguard Worker 
298*c8dee2aaSAndroid Build Coastguard Worker     VkPipelineCache pipelineCache();
299*c8dee2aaSAndroid Build Coastguard Worker 
300*c8dee2aaSAndroid Build Coastguard Worker     GrVkGpu* fGpu;
301*c8dee2aaSAndroid Build Coastguard Worker 
302*c8dee2aaSAndroid Build Coastguard Worker     // Central cache for creating pipelines
303*c8dee2aaSAndroid Build Coastguard Worker     VkPipelineCache fPipelineCache;
304*c8dee2aaSAndroid Build Coastguard Worker 
305*c8dee2aaSAndroid Build Coastguard Worker     struct MSAALoadPipeline {
306*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<const GrVkPipeline> fPipeline;
307*c8dee2aaSAndroid Build Coastguard Worker         const GrVkRenderPass* fRenderPass;
308*c8dee2aaSAndroid Build Coastguard Worker     };
309*c8dee2aaSAndroid Build Coastguard Worker 
310*c8dee2aaSAndroid Build Coastguard Worker     // Cache of previously created msaa load pipelines
311*c8dee2aaSAndroid Build Coastguard Worker     skia_private::TArray<MSAALoadPipeline> fMSAALoadPipelines;
312*c8dee2aaSAndroid Build Coastguard Worker 
313*c8dee2aaSAndroid Build Coastguard Worker     skia_private::STArray<4, CompatibleRenderPassSet> fRenderPassArray;
314*c8dee2aaSAndroid Build Coastguard Worker 
315*c8dee2aaSAndroid Build Coastguard Worker     skia_private::TArray<const GrVkRenderPass*> fExternalRenderPasses;
316*c8dee2aaSAndroid Build Coastguard Worker 
317*c8dee2aaSAndroid Build Coastguard Worker     // Array of command pools that we are waiting on
318*c8dee2aaSAndroid Build Coastguard Worker     skia_private::STArray<4, GrVkCommandPool*, true> fActiveCommandPools;
319*c8dee2aaSAndroid Build Coastguard Worker 
320*c8dee2aaSAndroid Build Coastguard Worker     // Array of available command pools that are not in flight
321*c8dee2aaSAndroid Build Coastguard Worker     skia_private::STArray<4, GrVkCommandPool*, true> fAvailableCommandPools;
322*c8dee2aaSAndroid Build Coastguard Worker 
323*c8dee2aaSAndroid Build Coastguard Worker     // Stores GrVkSampler objects that we've already created so we can reuse them across multiple
324*c8dee2aaSAndroid Build Coastguard Worker     // GrVkPipelineStates
325*c8dee2aaSAndroid Build Coastguard Worker     SkTDynamicHash<GrVkSampler, GrVkSampler::Key> fSamplers;
326*c8dee2aaSAndroid Build Coastguard Worker 
327*c8dee2aaSAndroid Build Coastguard Worker     // Stores GrVkSamplerYcbcrConversion objects that we've already created so we can reuse them.
328*c8dee2aaSAndroid Build Coastguard Worker     SkTDynamicHash<GrVkSamplerYcbcrConversion, GrVkSamplerYcbcrConversion::Key> fYcbcrConversions;
329*c8dee2aaSAndroid Build Coastguard Worker 
330*c8dee2aaSAndroid Build Coastguard Worker     // Cache of GrVkPipelineStates
331*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<PipelineStateCache> fPipelineStateCache;
332*c8dee2aaSAndroid Build Coastguard Worker 
333*c8dee2aaSAndroid Build Coastguard Worker     skia_private::STArray<4, std::unique_ptr<GrVkDescriptorSetManager>> fDescriptorSetManagers;
334*c8dee2aaSAndroid Build Coastguard Worker 
335*c8dee2aaSAndroid Build Coastguard Worker     GrVkDescriptorSetManager::Handle fUniformDSHandle;
336*c8dee2aaSAndroid Build Coastguard Worker     GrVkDescriptorSetManager::Handle fInputDSHandle;
337*c8dee2aaSAndroid Build Coastguard Worker };
338*c8dee2aaSAndroid Build Coastguard Worker 
339*c8dee2aaSAndroid Build Coastguard Worker #endif
340