blob: 78a515f91292a25d983f75641bfa4581ad1c46e3 [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"
Jim Van Verth3e192162020-03-10 16:23:16 -040016#include "src/gpu/GrManagedResource.h"
Robert Phillips03e4c952019-11-26 16:20:22 -050017#include "src/gpu/GrProgramDesc.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050018#include "src/gpu/GrResourceHandle.h"
19#include "src/gpu/vk/GrVkDescriptorPool.h"
20#include "src/gpu/vk/GrVkDescriptorSetManager.h"
21#include "src/gpu/vk/GrVkPipelineStateBuilder.h"
22#include "src/gpu/vk/GrVkRenderPass.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050023#include "src/gpu/vk/GrVkSampler.h"
24#include "src/gpu/vk/GrVkSamplerYcbcrConversion.h"
25#include "src/gpu/vk/GrVkUtil.h"
Greg Daniel164a9f02016-02-22 09:56:40 -050026
Ethan Nicholas8e265a72018-12-12 16:22:40 -050027#include <mutex>
28#include <thread>
29
30class GrVkCommandPool;
Greg Daniel164a9f02016-02-22 09:56:40 -050031class GrVkGpu;
32class GrVkPipeline;
Brian Salomon1471df92018-06-08 10:49:00 -040033class GrVkPipelineState;
jvanverth7ec92412016-07-06 09:24:57 -070034class GrVkPrimaryCommandBuffer;
Greg Daniel164a9f02016-02-22 09:56:40 -050035class GrVkRenderTarget;
jvanverth7ec92412016-07-06 09:24:57 -070036class GrVkSecondaryCommandBuffer;
egdaniel707bbd62016-07-26 07:19:47 -070037class GrVkUniformHandler;
Greg Daniel164a9f02016-02-22 09:56:40 -050038
39class GrVkResourceProvider {
40public:
41 GrVkResourceProvider(GrVkGpu* gpu);
42 ~GrVkResourceProvider();
43
jvanverth03509ea2016-03-02 13:19:47 -080044 // Set up any initial vk objects
45 void init();
46
Robert Phillips901aff02019-10-08 12:32:56 -040047 GrVkPipeline* createPipeline(const GrProgramInfo&,
Greg Daniel164a9f02016-02-22 09:56:40 -050048 VkPipelineShaderStageCreateInfo* shaderStageInfo,
49 int shaderStageCount,
Greg Daniel99b88e02018-10-03 15:31:20 -040050 VkRenderPass compatibleRenderPass,
Greg Daniel164a9f02016-02-22 09:56:40 -050051 VkPipelineLayout layout);
52
egdanield62e28b2016-06-07 08:43:30 -070053 GR_DEFINE_RESOURCE_HANDLE_CLASS(CompatibleRPHandle);
54
Greg Daniel164a9f02016-02-22 09:56:40 -050055 // Finds or creates a simple render pass that matches the target, increments the refcount,
egdanield62e28b2016-06-07 08:43:30 -070056 // and returns. The caller can optionally pass in a pointer to a CompatibleRPHandle. If this is
57 // non null it will be set to a handle that can be used in the furutre to quickly return a
58 // compatible GrVkRenderPasses without the need inspecting a GrVkRenderTarget.
59 const GrVkRenderPass* findCompatibleRenderPass(const GrVkRenderTarget& target,
60 CompatibleRPHandle* compatibleHandle = nullptr);
61 // The CompatibleRPHandle must be a valid handle previously set by a call to
62 // findCompatibleRenderPass(GrVkRenderTarget&, CompatibleRPHandle*).
63 const GrVkRenderPass* findCompatibleRenderPass(const CompatibleRPHandle& compatibleHandle);
64
Greg Danielb46add82019-01-02 14:51:29 -050065 const GrVkRenderPass* findCompatibleExternalRenderPass(VkRenderPass,
66 uint32_t colorAttachmentIndex);
67
egdaniel2feb0932016-06-08 06:48:09 -070068 // Finds or creates a render pass that matches the target and LoadStoreOps, increments the
69 // refcount, and returns. The caller can optionally pass in a pointer to a CompatibleRPHandle.
70 // If this is non null it will be set to a handle that can be used in the furutre to quickly
71 // return a GrVkRenderPasses without the need inspecting a GrVkRenderTarget.
Greg Danielfa3adf72019-11-07 09:53:41 -050072 const GrVkRenderPass* findRenderPass(GrVkRenderTarget* target,
egdaniel2feb0932016-06-08 06:48:09 -070073 const GrVkRenderPass::LoadStoreOps& colorOps,
egdaniel2feb0932016-06-08 06:48:09 -070074 const GrVkRenderPass::LoadStoreOps& stencilOps,
egdanield62e28b2016-06-07 08:43:30 -070075 CompatibleRPHandle* compatibleHandle = nullptr);
76
egdaniel2feb0932016-06-08 06:48:09 -070077 // The CompatibleRPHandle must be a valid handle previously set by a call to findRenderPass or
78 // findCompatibleRenderPass.
egdanield62e28b2016-06-07 08:43:30 -070079 const GrVkRenderPass* findRenderPass(const CompatibleRPHandle& compatibleHandle,
egdaniel2feb0932016-06-08 06:48:09 -070080 const GrVkRenderPass::LoadStoreOps& colorOps,
egdaniel2feb0932016-06-08 06:48:09 -070081 const GrVkRenderPass::LoadStoreOps& stencilOps);
82
Ethan Nicholas8e265a72018-12-12 16:22:40 -050083 GrVkCommandPool* findOrCreateCommandPool();
jvanverth7ec92412016-07-06 09:24:57 -070084
Ethan Nicholas8e265a72018-12-12 16:22:40 -050085 void checkCommandBuffers();
Ethan Nicholasbff4e072018-12-12 18:17:24 +000086
Greg Daniela3aa75a2019-04-12 14:24:55 -040087 // We must add the finishedProc to all active command buffers since we may have flushed work
88 // that the client cares about before they explicitly called flush and the GPU may reorder
89 // command execution. So we make sure all previously submitted work finishes before we call the
90 // finishedProc.
91 void addFinishedProcToActiveCommandBuffers(GrGpuFinishedProc finishedProc,
92 GrGpuFinishedContext finishedContext);
93
egdanielc2dc1b22016-03-18 13:18:23 -070094 // Finds or creates a compatible GrVkDescriptorPool for the requested type and count.
Greg Daniel164a9f02016-02-22 09:56:40 -050095 // The refcount is incremented and a pointer returned.
96 // TODO: Currently this will just create a descriptor pool without holding onto a ref itself
97 // so we currently do not reuse them. Rquires knowing if another draw is currently using
98 // the GrVkDescriptorPool, the ability to reset pools, and the ability to purge pools out
99 // of our cache of GrVkDescriptorPools.
egdanielc2dc1b22016-03-18 13:18:23 -0700100 GrVkDescriptorPool* findOrCreateCompatibleDescriptorPool(VkDescriptorType type, uint32_t count);
Greg Daniel164a9f02016-02-22 09:56:40 -0500101
Greg Daniel7e000222018-12-03 10:08:21 -0500102 // Finds or creates a compatible GrVkSampler based on the GrSamplerState and
103 // GrVkYcbcrConversionInfo. The refcount is incremented and a pointer returned.
Brian Salomonccb61422020-01-09 10:46:36 -0500104 GrVkSampler* findOrCreateCompatibleSampler(GrSamplerState,
Greg Daniel7e000222018-12-03 10:08:21 -0500105 const GrVkYcbcrConversionInfo& ycbcrInfo);
106
107 // Finds or creates a compatible GrVkSamplerYcbcrConversion based on the GrSamplerState and
108 // GrVkYcbcrConversionInfo. The refcount is incremented and a pointer returned.
109 GrVkSamplerYcbcrConversion* findOrCreateCompatibleSamplerYcbcrConversion(
110 const GrVkYcbcrConversionInfo& ycbcrInfo);
egdaniel8b6394c2016-03-04 07:35:10 -0800111
Greg Daniel9a51a862018-11-30 10:18:14 -0500112 GrVkPipelineState* findOrCreateCompatiblePipelineState(
Robert Phillips901aff02019-10-08 12:32:56 -0400113 GrRenderTarget*,
114 const GrProgramInfo&,
Greg Daniel9a51a862018-11-30 10:18:14 -0500115 VkRenderPass compatibleRenderPass);
egdaniel22281c12016-03-23 13:49:40 -0700116
Greg Daniela7543782017-05-02 14:01:43 -0400117 void getSamplerDescriptorSetHandle(VkDescriptorType type,
118 const GrVkUniformHandler&,
egdaniel707bbd62016-07-26 07:19:47 -0700119 GrVkDescriptorSetManager::Handle* handle);
Greg Daniela7543782017-05-02 14:01:43 -0400120 void getSamplerDescriptorSetHandle(VkDescriptorType type,
121 const SkTArray<uint32_t>& visibilities,
egdaniel4d866df2016-08-25 13:52:00 -0700122 GrVkDescriptorSetManager::Handle* handle);
egdaniel707bbd62016-07-26 07:19:47 -0700123
124 // Returns the compatible VkDescriptorSetLayout to use for uniform buffers. The caller does not
125 // own the VkDescriptorSetLayout and thus should not delete it. This function should be used
126 // when the caller needs the layout to create a VkPipelineLayout.
127 VkDescriptorSetLayout getUniformDSLayout() const;
128
129 // Returns the compatible VkDescriptorSetLayout to use for a specific sampler handle. The caller
130 // does not own the VkDescriptorSetLayout and thus should not delete it. This function should be
131 // used when the caller needs the layout to create a VkPipelineLayout.
132 VkDescriptorSetLayout getSamplerDSLayout(const GrVkDescriptorSetManager::Handle&) const;
egdaniela95220d2016-07-21 11:50:37 -0700133
134 // Returns a GrVkDescriptorSet that can be used for uniform buffers. The GrVkDescriptorSet
135 // is already reffed for the caller.
136 const GrVkDescriptorSet* getUniformDescriptorSet();
137
138 // Returns a GrVkDescriptorSet that can be used for sampler descriptors that are compatible with
egdaniel707bbd62016-07-26 07:19:47 -0700139 // the GrVkDescriptorSetManager::Handle passed in. The GrVkDescriptorSet is already reffed for
egdaniela95220d2016-07-21 11:50:37 -0700140 // the caller.
egdaniela95220d2016-07-21 11:50:37 -0700141 const GrVkDescriptorSet* getSamplerDescriptorSet(const GrVkDescriptorSetManager::Handle&);
egdaniel778555c2016-05-02 06:50:36 -0700142
egdaniel778555c2016-05-02 06:50:36 -0700143
egdaniela95220d2016-07-21 11:50:37 -0700144 // Signals that the descriptor set passed it, which is compatible with the passed in handle,
145 // can be reused by the next allocation request.
146 void recycleDescriptorSet(const GrVkDescriptorSet* descSet,
147 const GrVkDescriptorSetManager::Handle&);
148
jvanverth4c6e47a2016-07-22 10:34:52 -0700149 // Creates or finds free uniform buffer resources of size GrVkUniformBuffer::kStandardSize.
150 // Anything larger will need to be created and released by the client.
Jim Van Verth3e192162020-03-10 16:23:16 -0400151 const GrManagedResource* findOrCreateStandardUniformBufferResource();
jvanverth4c6e47a2016-07-22 10:34:52 -0700152
153 // Signals that the resource passed to it (which should be a uniform buffer resource)
154 // can be reused by the next uniform buffer resource request.
Jim Van Verth3e192162020-03-10 16:23:16 -0400155 void recycleStandardUniformBufferResource(const GrManagedResource*);
jvanverth4c6e47a2016-07-22 10:34:52 -0700156
Greg Daniela870b462019-01-08 15:49:46 -0500157 void storePipelineCacheData();
158
Greg Daniel164a9f02016-02-22 09:56:40 -0500159 // Destroy any cached resources. To be called before destroying the VkDevice.
160 // The assumption is that all queues are idle and all command buffers are finished.
161 // For resource tracing to work properly, this should be called after unrefing all other
162 // resource usages.
Jim Van Verth09557d72016-11-07 11:10:21 -0500163 // If deviceLost is true, then resources will not be checked to see if they've finished
164 // before deleting (see section 4.2.4 of the Vulkan spec).
165 void destroyResources(bool deviceLost);
Greg Daniel164a9f02016-02-22 09:56:40 -0500166
Ethan Nicholas8e265a72018-12-12 16:22:40 -0500167 void backgroundReset(GrVkCommandPool* pool);
168
169 void reset(GrVkCommandPool* pool);
170
Brian Osmanfd7657c2019-04-25 11:34:07 -0400171#if GR_TEST_UTILS
172 void resetShaderCacheForTesting() const { fPipelineStateCache->release(); }
173#endif
174
Greg Daniel164a9f02016-02-22 09:56:40 -0500175private:
Ethan Nicholas8e265a72018-12-12 16:22:40 -0500176
djsollenefe46d22016-04-29 06:41:35 -0700177#ifdef SK_DEBUG
egdanielaf132772016-03-28 12:39:29 -0700178#define GR_PIPELINE_STATE_CACHE_STATS
179#endif
180
egdaniel22281c12016-03-23 13:49:40 -0700181 class PipelineStateCache : public ::SkNoncopyable {
182 public:
183 PipelineStateCache(GrVkGpu* gpu);
184 ~PipelineStateCache();
185
egdaniel22281c12016-03-23 13:49:40 -0700186 void release();
Stephen Whiteb1857852020-02-07 15:33:23 +0000187 GrVkPipelineState* findOrCreatePipelineState(GrRenderTarget*,
188 const GrProgramInfo&,
189 VkRenderPass compatibleRenderPass);
egdaniel22281c12016-03-23 13:49:40 -0700190
191 private:
egdaniel22281c12016-03-23 13:49:40 -0700192 struct Entry;
193
Robert Phillips979b2232020-02-20 10:47:29 -0500194 GrVkPipelineState* findOrCreatePipeline(GrRenderTarget*,
195 const GrProgramDesc&,
196 const GrProgramInfo&,
197 VkRenderPass compatibleRenderPass);
198
Ethan Nicholas87f340e2017-01-03 14:32:01 -0500199 struct DescHash {
200 uint32_t operator()(const GrProgramDesc& desc) const {
201 return SkOpts::hash_fn(desc.asKey(), desc.keyLength(), 0);
202 }
203 };
egdaniel22281c12016-03-23 13:49:40 -0700204
Robert Phillips03e4c952019-11-26 16:20:22 -0500205 SkLRUCache<const GrProgramDesc, std::unique_ptr<Entry>, DescHash> fMap;
egdanielaf132772016-03-28 12:39:29 -0700206
egdaniel22281c12016-03-23 13:49:40 -0700207 GrVkGpu* fGpu;
egdanielaf132772016-03-28 12:39:29 -0700208
209#ifdef GR_PIPELINE_STATE_CACHE_STATS
egdaniel22281c12016-03-23 13:49:40 -0700210 int fTotalRequests;
211 int fCacheMisses;
egdaniel22281c12016-03-23 13:49:40 -0700212#endif
213 };
214
egdanield62e28b2016-06-07 08:43:30 -0700215 class CompatibleRenderPassSet {
216 public:
217 // This will always construct the basic load store render pass (all attachments load and
218 // store their data) so that there is at least one compatible VkRenderPass that can be used
219 // with this set.
Greg Danieled984762019-11-07 17:15:45 -0500220 CompatibleRenderPassSet(GrVkRenderPass* renderPass);
egdanield62e28b2016-06-07 08:43:30 -0700221
222 bool isCompatible(const GrVkRenderTarget& target) const;
223
224 GrVkRenderPass* getCompatibleRenderPass() const {
225 // The first GrVkRenderpass should always exist since we create the basic load store
226 // render pass on create
227 SkASSERT(fRenderPasses[0]);
228 return fRenderPasses[0];
229 }
230
Greg Daniele643da62019-11-05 12:36:42 -0500231 GrVkRenderPass* getRenderPass(GrVkGpu* gpu,
egdaniel2feb0932016-06-08 06:48:09 -0700232 const GrVkRenderPass::LoadStoreOps& colorOps,
egdaniel2feb0932016-06-08 06:48:09 -0700233 const GrVkRenderPass::LoadStoreOps& stencilOps);
234
Jim Van Verth5082df12020-03-11 16:14:51 -0400235 void releaseResources();
egdanield62e28b2016-06-07 08:43:30 -0700236
237 private:
238 SkSTArray<4, GrVkRenderPass*> fRenderPasses;
239 int fLastReturnedIndex;
240 };
241
Greg Daniela870b462019-01-08 15:49:46 -0500242 VkPipelineCache pipelineCache();
243
Greg Daniel164a9f02016-02-22 09:56:40 -0500244 GrVkGpu* fGpu;
245
jvanverth03509ea2016-03-02 13:19:47 -0800246 // Central cache for creating pipelines
247 VkPipelineCache fPipelineCache;
248
egdanield62e28b2016-06-07 08:43:30 -0700249 SkSTArray<4, CompatibleRenderPassSet> fRenderPassArray;
Greg Daniel164a9f02016-02-22 09:56:40 -0500250
Greg Danielb46add82019-01-02 14:51:29 -0500251 SkTArray<const GrVkRenderPass*> fExternalRenderPasses;
252
Ethan Nicholas8e265a72018-12-12 16:22:40 -0500253 // Array of command pools that we are waiting on
254 SkSTArray<4, GrVkCommandPool*, true> fActiveCommandPools;
jvanverth7ec92412016-07-06 09:24:57 -0700255
Ethan Nicholas8e265a72018-12-12 16:22:40 -0500256 // Array of available command pools that are not in flight
257 SkSTArray<4, GrVkCommandPool*, true> fAvailableCommandPools;
egdaniel8b6394c2016-03-04 07:35:10 -0800258
jvanverth4c6e47a2016-07-22 10:34:52 -0700259 // Array of available uniform buffer resources
Jim Van Verth3e192162020-03-10 16:23:16 -0400260 SkSTArray<16, const GrManagedResource*, true> fAvailableUniformBufferResources;
jvanverth4c6e47a2016-07-22 10:34:52 -0700261
egdaniel8b6394c2016-03-04 07:35:10 -0800262 // Stores GrVkSampler objects that we've already created so we can reuse them across multiple
egdaniel22281c12016-03-23 13:49:40 -0700263 // GrVkPipelineStates
Greg Daniel7e000222018-12-03 10:08:21 -0500264 SkTDynamicHash<GrVkSampler, GrVkSampler::Key> fSamplers;
265
266 // Stores GrVkSamplerYcbcrConversion objects that we've already created so we can reuse them.
267 SkTDynamicHash<GrVkSamplerYcbcrConversion, GrVkSamplerYcbcrConversion::Key> fYcbcrConversions;
egdaniel22281c12016-03-23 13:49:40 -0700268
269 // Cache of GrVkPipelineStates
270 PipelineStateCache* fPipelineStateCache;
egdaniel778555c2016-05-02 06:50:36 -0700271
Greg Daniel18f96022017-05-04 15:09:03 -0400272 SkSTArray<4, std::unique_ptr<GrVkDescriptorSetManager>> fDescriptorSetManagers;
egdaniela95220d2016-07-21 11:50:37 -0700273
egdaniel707bbd62016-07-26 07:19:47 -0700274 GrVkDescriptorSetManager::Handle fUniformDSHandle;
Ethan Nicholas8e265a72018-12-12 16:22:40 -0500275
276 std::recursive_mutex fBackgroundMutex;
Greg Daniel164a9f02016-02-22 09:56:40 -0500277};
278
279#endif