blob: 9cd457ed2986673dcf6216718452ff5ad3c3c864 [file] [log] [blame]
Greg Daniel164a9f02016-02-22 09:56:40 -05001/*
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
8#ifndef GrVkResourceProvider_DEFINED
9#define GrVkResourceProvider_DEFINED
10
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "include/gpu/vk/GrVkTypes.h"
12#include "include/private/SkTArray.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050013#include "src/core/SkLRUCache.h"
14#include "src/core/SkTDynamicHash.h"
Ben Wagner729a23f2019-05-17 16:29:34 -040015#include "src/core/SkTInternalLList.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050016#include "src/gpu/GrResourceHandle.h"
17#include "src/gpu/vk/GrVkDescriptorPool.h"
18#include "src/gpu/vk/GrVkDescriptorSetManager.h"
19#include "src/gpu/vk/GrVkPipelineStateBuilder.h"
20#include "src/gpu/vk/GrVkRenderPass.h"
21#include "src/gpu/vk/GrVkResource.h"
22#include "src/gpu/vk/GrVkSampler.h"
23#include "src/gpu/vk/GrVkSamplerYcbcrConversion.h"
24#include "src/gpu/vk/GrVkUtil.h"
Greg Daniel164a9f02016-02-22 09:56:40 -050025
Ethan Nicholas8e265a72018-12-12 16:22:40 -050026#include <mutex>
27#include <thread>
28
29class GrVkCommandPool;
Greg Daniel164a9f02016-02-22 09:56:40 -050030class GrVkGpu;
31class GrVkPipeline;
Brian Salomon1471df92018-06-08 10:49:00 -040032class GrVkPipelineState;
jvanverth7ec92412016-07-06 09:24:57 -070033class GrVkPrimaryCommandBuffer;
Greg Daniel164a9f02016-02-22 09:56:40 -050034class GrVkRenderTarget;
jvanverth7ec92412016-07-06 09:24:57 -070035class GrVkSecondaryCommandBuffer;
egdaniel707bbd62016-07-26 07:19:47 -070036class GrVkUniformHandler;
Greg Daniel164a9f02016-02-22 09:56:40 -050037
38class GrVkResourceProvider {
39public:
40 GrVkResourceProvider(GrVkGpu* gpu);
41 ~GrVkResourceProvider();
42
jvanverth03509ea2016-03-02 13:19:47 -080043 // Set up any initial vk objects
44 void init();
45
Robert Phillipsd0fe8752019-01-31 14:13:59 -050046 GrVkPipeline* createPipeline(int numColorSamples,
47 const GrPrimitiveProcessor& primProc,
Brian Salomonff168d92018-06-23 15:17:27 -040048 const GrPipeline& pipeline,
csmartdaltonc633abb2016-11-01 08:55:55 -070049 const GrStencilSettings& stencil,
Chris Dalton71713f62019-04-18 12:41:03 -060050 GrSurfaceOrigin,
Greg Daniel164a9f02016-02-22 09:56:40 -050051 VkPipelineShaderStageCreateInfo* shaderStageInfo,
52 int shaderStageCount,
53 GrPrimitiveType primitiveType,
Greg Daniel99b88e02018-10-03 15:31:20 -040054 VkRenderPass compatibleRenderPass,
Greg Daniel164a9f02016-02-22 09:56:40 -050055 VkPipelineLayout layout);
56
egdanield62e28b2016-06-07 08:43:30 -070057 GR_DEFINE_RESOURCE_HANDLE_CLASS(CompatibleRPHandle);
58
Greg Daniel164a9f02016-02-22 09:56:40 -050059 // Finds or creates a simple render pass that matches the target, increments the refcount,
egdanield62e28b2016-06-07 08:43:30 -070060 // and returns. The caller can optionally pass in a pointer to a CompatibleRPHandle. If this is
61 // non null it will be set to a handle that can be used in the furutre to quickly return a
62 // compatible GrVkRenderPasses without the need inspecting a GrVkRenderTarget.
63 const GrVkRenderPass* findCompatibleRenderPass(const GrVkRenderTarget& target,
64 CompatibleRPHandle* compatibleHandle = nullptr);
65 // The CompatibleRPHandle must be a valid handle previously set by a call to
66 // findCompatibleRenderPass(GrVkRenderTarget&, CompatibleRPHandle*).
67 const GrVkRenderPass* findCompatibleRenderPass(const CompatibleRPHandle& compatibleHandle);
68
Greg Danielb46add82019-01-02 14:51:29 -050069 const GrVkRenderPass* findCompatibleExternalRenderPass(VkRenderPass,
70 uint32_t colorAttachmentIndex);
71
egdaniel2feb0932016-06-08 06:48:09 -070072 // Finds or creates a render pass that matches the target and LoadStoreOps, increments the
73 // refcount, and returns. The caller can optionally pass in a pointer to a CompatibleRPHandle.
74 // If this is non null it will be set to a handle that can be used in the furutre to quickly
75 // return a GrVkRenderPasses without the need inspecting a GrVkRenderTarget.
egdanield62e28b2016-06-07 08:43:30 -070076 const GrVkRenderPass* findRenderPass(const GrVkRenderTarget& target,
egdaniel2feb0932016-06-08 06:48:09 -070077 const GrVkRenderPass::LoadStoreOps& colorOps,
egdaniel2feb0932016-06-08 06:48:09 -070078 const GrVkRenderPass::LoadStoreOps& stencilOps,
egdanield62e28b2016-06-07 08:43:30 -070079 CompatibleRPHandle* compatibleHandle = nullptr);
80
egdaniel2feb0932016-06-08 06:48:09 -070081 // The CompatibleRPHandle must be a valid handle previously set by a call to findRenderPass or
82 // findCompatibleRenderPass.
egdanield62e28b2016-06-07 08:43:30 -070083 const GrVkRenderPass* findRenderPass(const CompatibleRPHandle& compatibleHandle,
egdaniel2feb0932016-06-08 06:48:09 -070084 const GrVkRenderPass::LoadStoreOps& colorOps,
egdaniel2feb0932016-06-08 06:48:09 -070085 const GrVkRenderPass::LoadStoreOps& stencilOps);
86
Ethan Nicholas8e265a72018-12-12 16:22:40 -050087 GrVkCommandPool* findOrCreateCommandPool();
jvanverth7ec92412016-07-06 09:24:57 -070088
Ethan Nicholas8e265a72018-12-12 16:22:40 -050089 void checkCommandBuffers();
Ethan Nicholasbff4e072018-12-12 18:17:24 +000090
Greg Daniela3aa75a2019-04-12 14:24:55 -040091 // We must add the finishedProc to all active command buffers since we may have flushed work
92 // that the client cares about before they explicitly called flush and the GPU may reorder
93 // command execution. So we make sure all previously submitted work finishes before we call the
94 // finishedProc.
95 void addFinishedProcToActiveCommandBuffers(GrGpuFinishedProc finishedProc,
96 GrGpuFinishedContext finishedContext);
97
egdanielc2dc1b22016-03-18 13:18:23 -070098 // Finds or creates a compatible GrVkDescriptorPool for the requested type and count.
Greg Daniel164a9f02016-02-22 09:56:40 -050099 // The refcount is incremented and a pointer returned.
100 // TODO: Currently this will just create a descriptor pool without holding onto a ref itself
101 // so we currently do not reuse them. Rquires knowing if another draw is currently using
102 // the GrVkDescriptorPool, the ability to reset pools, and the ability to purge pools out
103 // of our cache of GrVkDescriptorPools.
egdanielc2dc1b22016-03-18 13:18:23 -0700104 GrVkDescriptorPool* findOrCreateCompatibleDescriptorPool(VkDescriptorType type, uint32_t count);
Greg Daniel164a9f02016-02-22 09:56:40 -0500105
Greg Daniel7e000222018-12-03 10:08:21 -0500106 // Finds or creates a compatible GrVkSampler based on the GrSamplerState and
107 // GrVkYcbcrConversionInfo. The refcount is incremented and a pointer returned.
108 GrVkSampler* findOrCreateCompatibleSampler(const GrSamplerState&,
109 const GrVkYcbcrConversionInfo& ycbcrInfo);
110
111 // Finds or creates a compatible GrVkSamplerYcbcrConversion based on the GrSamplerState and
112 // GrVkYcbcrConversionInfo. The refcount is incremented and a pointer returned.
113 GrVkSamplerYcbcrConversion* findOrCreateCompatibleSamplerYcbcrConversion(
114 const GrVkYcbcrConversionInfo& ycbcrInfo);
egdaniel8b6394c2016-03-04 07:35:10 -0800115
Greg Daniel9a51a862018-11-30 10:18:14 -0500116 GrVkPipelineState* findOrCreateCompatiblePipelineState(
Robert Phillipsd0fe8752019-01-31 14:13:59 -0500117 GrRenderTarget*, GrSurfaceOrigin,
Greg Daniel9a51a862018-11-30 10:18:14 -0500118 const GrPipeline&,
119 const GrPrimitiveProcessor&,
120 const GrTextureProxy* const primProcProxies[],
121 GrPrimitiveType,
122 VkRenderPass compatibleRenderPass);
egdaniel22281c12016-03-23 13:49:40 -0700123
Greg Daniela7543782017-05-02 14:01:43 -0400124 void getSamplerDescriptorSetHandle(VkDescriptorType type,
125 const GrVkUniformHandler&,
egdaniel707bbd62016-07-26 07:19:47 -0700126 GrVkDescriptorSetManager::Handle* handle);
Greg Daniela7543782017-05-02 14:01:43 -0400127 void getSamplerDescriptorSetHandle(VkDescriptorType type,
128 const SkTArray<uint32_t>& visibilities,
egdaniel4d866df2016-08-25 13:52:00 -0700129 GrVkDescriptorSetManager::Handle* handle);
egdaniel707bbd62016-07-26 07:19:47 -0700130
131 // Returns the compatible VkDescriptorSetLayout to use for uniform buffers. The caller does not
132 // own the VkDescriptorSetLayout and thus should not delete it. This function should be used
133 // when the caller needs the layout to create a VkPipelineLayout.
134 VkDescriptorSetLayout getUniformDSLayout() const;
135
136 // Returns the compatible VkDescriptorSetLayout to use for a specific sampler handle. The caller
137 // does not own the VkDescriptorSetLayout and thus should not delete it. This function should be
138 // used when the caller needs the layout to create a VkPipelineLayout.
139 VkDescriptorSetLayout getSamplerDSLayout(const GrVkDescriptorSetManager::Handle&) const;
egdaniela95220d2016-07-21 11:50:37 -0700140
141 // Returns a GrVkDescriptorSet that can be used for uniform buffers. The GrVkDescriptorSet
142 // is already reffed for the caller.
143 const GrVkDescriptorSet* getUniformDescriptorSet();
144
145 // Returns a GrVkDescriptorSet that can be used for sampler descriptors that are compatible with
egdaniel707bbd62016-07-26 07:19:47 -0700146 // the GrVkDescriptorSetManager::Handle passed in. The GrVkDescriptorSet is already reffed for
egdaniela95220d2016-07-21 11:50:37 -0700147 // the caller.
egdaniela95220d2016-07-21 11:50:37 -0700148 const GrVkDescriptorSet* getSamplerDescriptorSet(const GrVkDescriptorSetManager::Handle&);
egdaniel778555c2016-05-02 06:50:36 -0700149
egdaniel778555c2016-05-02 06:50:36 -0700150
egdaniela95220d2016-07-21 11:50:37 -0700151 // Signals that the descriptor set passed it, which is compatible with the passed in handle,
152 // can be reused by the next allocation request.
153 void recycleDescriptorSet(const GrVkDescriptorSet* descSet,
154 const GrVkDescriptorSetManager::Handle&);
155
jvanverth4c6e47a2016-07-22 10:34:52 -0700156 // Creates or finds free uniform buffer resources of size GrVkUniformBuffer::kStandardSize.
157 // Anything larger will need to be created and released by the client.
158 const GrVkResource* findOrCreateStandardUniformBufferResource();
159
160 // Signals that the resource passed to it (which should be a uniform buffer resource)
161 // can be reused by the next uniform buffer resource request.
162 void recycleStandardUniformBufferResource(const GrVkResource*);
163
Greg Daniela870b462019-01-08 15:49:46 -0500164 void storePipelineCacheData();
165
Greg Daniel164a9f02016-02-22 09:56:40 -0500166 // Destroy any cached resources. To be called before destroying the VkDevice.
167 // The assumption is that all queues are idle and all command buffers are finished.
168 // For resource tracing to work properly, this should be called after unrefing all other
169 // resource usages.
Jim Van Verth09557d72016-11-07 11:10:21 -0500170 // If deviceLost is true, then resources will not be checked to see if they've finished
171 // before deleting (see section 4.2.4 of the Vulkan spec).
172 void destroyResources(bool deviceLost);
Greg Daniel164a9f02016-02-22 09:56:40 -0500173
174 // Abandon any cached resources. To be used when the context/VkDevice is lost.
175 // For resource tracing to work properly, this should be called after unrefing all other
176 // resource usages.
177 void abandonResources();
178
Ethan Nicholas8e265a72018-12-12 16:22:40 -0500179 void backgroundReset(GrVkCommandPool* pool);
180
181 void reset(GrVkCommandPool* pool);
182
Brian Osmanfd7657c2019-04-25 11:34:07 -0400183#if GR_TEST_UTILS
184 void resetShaderCacheForTesting() const { fPipelineStateCache->release(); }
185#endif
186
Greg Daniel164a9f02016-02-22 09:56:40 -0500187private:
Ethan Nicholas8e265a72018-12-12 16:22:40 -0500188
djsollenefe46d22016-04-29 06:41:35 -0700189#ifdef SK_DEBUG
egdanielaf132772016-03-28 12:39:29 -0700190#define GR_PIPELINE_STATE_CACHE_STATS
191#endif
192
egdaniel22281c12016-03-23 13:49:40 -0700193 class PipelineStateCache : public ::SkNoncopyable {
194 public:
195 PipelineStateCache(GrVkGpu* gpu);
196 ~PipelineStateCache();
197
198 void abandon();
199 void release();
Robert Phillipsd0fe8752019-01-31 14:13:59 -0500200 GrVkPipelineState* refPipelineState(GrRenderTarget*, GrSurfaceOrigin,
201 const GrPrimitiveProcessor&,
Greg Daniel9a51a862018-11-30 10:18:14 -0500202 const GrTextureProxy* const primProcProxies[],
Brian Salomonff168d92018-06-23 15:17:27 -0400203 const GrPipeline&,
Greg Daniel09eeefb2017-10-16 15:15:02 -0400204 GrPrimitiveType,
Greg Daniel99b88e02018-10-03 15:31:20 -0400205 VkRenderPass compatibleRenderPass);
egdaniel22281c12016-03-23 13:49:40 -0700206
207 private:
egdaniel22281c12016-03-23 13:49:40 -0700208 struct Entry;
209
Ethan Nicholas87f340e2017-01-03 14:32:01 -0500210 struct DescHash {
211 uint32_t operator()(const GrProgramDesc& desc) const {
212 return SkOpts::hash_fn(desc.asKey(), desc.keyLength(), 0);
213 }
214 };
egdaniel22281c12016-03-23 13:49:40 -0700215
Brian Salomon1471df92018-06-08 10:49:00 -0400216 SkLRUCache<const GrVkPipelineStateBuilder::Desc, std::unique_ptr<Entry>, DescHash> fMap;
egdanielaf132772016-03-28 12:39:29 -0700217
egdaniel22281c12016-03-23 13:49:40 -0700218 GrVkGpu* fGpu;
egdanielaf132772016-03-28 12:39:29 -0700219
220#ifdef GR_PIPELINE_STATE_CACHE_STATS
egdaniel22281c12016-03-23 13:49:40 -0700221 int fTotalRequests;
222 int fCacheMisses;
egdaniel22281c12016-03-23 13:49:40 -0700223#endif
224 };
225
egdanield62e28b2016-06-07 08:43:30 -0700226 class CompatibleRenderPassSet {
227 public:
228 // This will always construct the basic load store render pass (all attachments load and
229 // store their data) so that there is at least one compatible VkRenderPass that can be used
230 // with this set.
231 CompatibleRenderPassSet(const GrVkGpu* gpu, const GrVkRenderTarget& target);
232
233 bool isCompatible(const GrVkRenderTarget& target) const;
234
235 GrVkRenderPass* getCompatibleRenderPass() const {
236 // The first GrVkRenderpass should always exist since we create the basic load store
237 // render pass on create
238 SkASSERT(fRenderPasses[0]);
239 return fRenderPasses[0];
240 }
241
egdaniel2feb0932016-06-08 06:48:09 -0700242 GrVkRenderPass* getRenderPass(const GrVkGpu* gpu,
243 const GrVkRenderPass::LoadStoreOps& colorOps,
egdaniel2feb0932016-06-08 06:48:09 -0700244 const GrVkRenderPass::LoadStoreOps& stencilOps);
245
Ethan Nicholas8e265a72018-12-12 16:22:40 -0500246 void releaseResources(GrVkGpu* gpu);
egdanield62e28b2016-06-07 08:43:30 -0700247 void abandonResources();
248
249 private:
250 SkSTArray<4, GrVkRenderPass*> fRenderPasses;
251 int fLastReturnedIndex;
252 };
253
Greg Daniela870b462019-01-08 15:49:46 -0500254 VkPipelineCache pipelineCache();
255
Greg Daniel164a9f02016-02-22 09:56:40 -0500256 GrVkGpu* fGpu;
257
jvanverth03509ea2016-03-02 13:19:47 -0800258 // Central cache for creating pipelines
259 VkPipelineCache fPipelineCache;
260
egdanield62e28b2016-06-07 08:43:30 -0700261 SkSTArray<4, CompatibleRenderPassSet> fRenderPassArray;
Greg Daniel164a9f02016-02-22 09:56:40 -0500262
Greg Danielb46add82019-01-02 14:51:29 -0500263 SkTArray<const GrVkRenderPass*> fExternalRenderPasses;
264
Ethan Nicholas8e265a72018-12-12 16:22:40 -0500265 // Array of command pools that we are waiting on
266 SkSTArray<4, GrVkCommandPool*, true> fActiveCommandPools;
jvanverth7ec92412016-07-06 09:24:57 -0700267
Ethan Nicholas8e265a72018-12-12 16:22:40 -0500268 // Array of available command pools that are not in flight
269 SkSTArray<4, GrVkCommandPool*, true> fAvailableCommandPools;
egdaniel8b6394c2016-03-04 07:35:10 -0800270
jvanverth4c6e47a2016-07-22 10:34:52 -0700271 // Array of available uniform buffer resources
egdaniel707bbd62016-07-26 07:19:47 -0700272 SkSTArray<16, const GrVkResource*, true> fAvailableUniformBufferResources;
jvanverth4c6e47a2016-07-22 10:34:52 -0700273
egdaniel8b6394c2016-03-04 07:35:10 -0800274 // Stores GrVkSampler objects that we've already created so we can reuse them across multiple
egdaniel22281c12016-03-23 13:49:40 -0700275 // GrVkPipelineStates
Greg Daniel7e000222018-12-03 10:08:21 -0500276 SkTDynamicHash<GrVkSampler, GrVkSampler::Key> fSamplers;
277
278 // Stores GrVkSamplerYcbcrConversion objects that we've already created so we can reuse them.
279 SkTDynamicHash<GrVkSamplerYcbcrConversion, GrVkSamplerYcbcrConversion::Key> fYcbcrConversions;
egdaniel22281c12016-03-23 13:49:40 -0700280
281 // Cache of GrVkPipelineStates
282 PipelineStateCache* fPipelineStateCache;
egdaniel778555c2016-05-02 06:50:36 -0700283
Greg Daniel18f96022017-05-04 15:09:03 -0400284 SkSTArray<4, std::unique_ptr<GrVkDescriptorSetManager>> fDescriptorSetManagers;
egdaniela95220d2016-07-21 11:50:37 -0700285
egdaniel707bbd62016-07-26 07:19:47 -0700286 GrVkDescriptorSetManager::Handle fUniformDSHandle;
Ethan Nicholas8e265a72018-12-12 16:22:40 -0500287
288 std::recursive_mutex fBackgroundMutex;
Greg Daniel164a9f02016-02-22 09:56:40 -0500289};
290
291#endif