blob: 29170c188d822b0836b9930c0ea04c292a5c3a49 [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
egdanield62e28b2016-06-07 08:43:30 -070011#include "GrResourceHandle.h"
Greg Daniel164a9f02016-02-22 09:56:40 -050012#include "GrVkDescriptorPool.h"
egdaniela95220d2016-07-21 11:50:37 -070013#include "GrVkDescriptorSetManager.h"
Brian Salomon1471df92018-06-08 10:49:00 -040014#include "GrVkPipelineStateBuilder.h"
egdaniel2feb0932016-06-08 06:48:09 -070015#include "GrVkRenderPass.h"
Greg Daniel164a9f02016-02-22 09:56:40 -050016#include "GrVkResource.h"
Greg Daniel7e000222018-12-03 10:08:21 -050017#include "GrVkSampler.h"
18#include "GrVkSamplerYcbcrConversion.h"
Greg Daniel164a9f02016-02-22 09:56:40 -050019#include "GrVkUtil.h"
Ethan Nicholas87f340e2017-01-03 14:32:01 -050020#include "SkLRUCache.h"
Greg Daniel164a9f02016-02-22 09:56:40 -050021#include "SkTArray.h"
egdaniel8b6394c2016-03-04 07:35:10 -080022#include "SkTDynamicHash.h"
egdanielaf132772016-03-28 12:39:29 -070023#include "SkTInternalLList.h"
Greg Daniel487132b2018-12-20 14:09:36 -050024#include "vk/GrVkTypes.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;
egdanielbc9b2962016-09-27 08:00:53 -070030class GrVkCopyPipeline;
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 Phillipsd0fe8752019-01-31 14:13:59 -050047 GrVkPipeline* createPipeline(int numColorSamples,
48 const GrPrimitiveProcessor& primProc,
Brian Salomonff168d92018-06-23 15:17:27 -040049 const GrPipeline& pipeline,
csmartdaltonc633abb2016-11-01 08:55:55 -070050 const GrStencilSettings& stencil,
Chris Dalton71713f62019-04-18 12:41:03 -060051 GrSurfaceOrigin,
Greg Daniel164a9f02016-02-22 09:56:40 -050052 VkPipelineShaderStageCreateInfo* shaderStageInfo,
53 int shaderStageCount,
54 GrPrimitiveType primitiveType,
Greg Daniel99b88e02018-10-03 15:31:20 -040055 VkRenderPass compatibleRenderPass,
Greg Daniel164a9f02016-02-22 09:56:40 -050056 VkPipelineLayout layout);
57
egdanielbc9b2962016-09-27 08:00:53 -070058 GrVkCopyPipeline* findOrCreateCopyPipeline(const GrVkRenderTarget* dst,
59 VkPipelineShaderStageCreateInfo*,
60 VkPipelineLayout);
61
egdanield62e28b2016-06-07 08:43:30 -070062 GR_DEFINE_RESOURCE_HANDLE_CLASS(CompatibleRPHandle);
63
Greg Daniel164a9f02016-02-22 09:56:40 -050064 // Finds or creates a simple render pass that matches the target, increments the refcount,
egdanield62e28b2016-06-07 08:43:30 -070065 // and returns. The caller can optionally pass in a pointer to a CompatibleRPHandle. If this is
66 // non null it will be set to a handle that can be used in the furutre to quickly return a
67 // compatible GrVkRenderPasses without the need inspecting a GrVkRenderTarget.
68 const GrVkRenderPass* findCompatibleRenderPass(const GrVkRenderTarget& target,
69 CompatibleRPHandle* compatibleHandle = nullptr);
70 // The CompatibleRPHandle must be a valid handle previously set by a call to
71 // findCompatibleRenderPass(GrVkRenderTarget&, CompatibleRPHandle*).
72 const GrVkRenderPass* findCompatibleRenderPass(const CompatibleRPHandle& compatibleHandle);
73
Greg Danielb46add82019-01-02 14:51:29 -050074 const GrVkRenderPass* findCompatibleExternalRenderPass(VkRenderPass,
75 uint32_t colorAttachmentIndex);
76
egdaniel2feb0932016-06-08 06:48:09 -070077 // Finds or creates a render pass that matches the target and LoadStoreOps, increments the
78 // refcount, and returns. The caller can optionally pass in a pointer to a CompatibleRPHandle.
79 // If this is non null it will be set to a handle that can be used in the furutre to quickly
80 // return a GrVkRenderPasses without the need inspecting a GrVkRenderTarget.
egdanield62e28b2016-06-07 08:43:30 -070081 const GrVkRenderPass* findRenderPass(const GrVkRenderTarget& target,
egdaniel2feb0932016-06-08 06:48:09 -070082 const GrVkRenderPass::LoadStoreOps& colorOps,
egdaniel2feb0932016-06-08 06:48:09 -070083 const GrVkRenderPass::LoadStoreOps& stencilOps,
egdanield62e28b2016-06-07 08:43:30 -070084 CompatibleRPHandle* compatibleHandle = nullptr);
85
egdaniel2feb0932016-06-08 06:48:09 -070086 // The CompatibleRPHandle must be a valid handle previously set by a call to findRenderPass or
87 // findCompatibleRenderPass.
egdanield62e28b2016-06-07 08:43:30 -070088 const GrVkRenderPass* findRenderPass(const CompatibleRPHandle& compatibleHandle,
egdaniel2feb0932016-06-08 06:48:09 -070089 const GrVkRenderPass::LoadStoreOps& colorOps,
egdaniel2feb0932016-06-08 06:48:09 -070090 const GrVkRenderPass::LoadStoreOps& stencilOps);
91
Ethan Nicholas8e265a72018-12-12 16:22:40 -050092 GrVkCommandPool* findOrCreateCommandPool();
jvanverth7ec92412016-07-06 09:24:57 -070093
Ethan Nicholas8e265a72018-12-12 16:22:40 -050094 void checkCommandBuffers();
Ethan Nicholasbff4e072018-12-12 18:17:24 +000095
Greg Daniela3aa75a2019-04-12 14:24:55 -040096 // We must add the finishedProc to all active command buffers since we may have flushed work
97 // that the client cares about before they explicitly called flush and the GPU may reorder
98 // command execution. So we make sure all previously submitted work finishes before we call the
99 // finishedProc.
100 void addFinishedProcToActiveCommandBuffers(GrGpuFinishedProc finishedProc,
101 GrGpuFinishedContext finishedContext);
102
egdanielc2dc1b22016-03-18 13:18:23 -0700103 // Finds or creates a compatible GrVkDescriptorPool for the requested type and count.
Greg Daniel164a9f02016-02-22 09:56:40 -0500104 // The refcount is incremented and a pointer returned.
105 // TODO: Currently this will just create a descriptor pool without holding onto a ref itself
106 // so we currently do not reuse them. Rquires knowing if another draw is currently using
107 // the GrVkDescriptorPool, the ability to reset pools, and the ability to purge pools out
108 // of our cache of GrVkDescriptorPools.
egdanielc2dc1b22016-03-18 13:18:23 -0700109 GrVkDescriptorPool* findOrCreateCompatibleDescriptorPool(VkDescriptorType type, uint32_t count);
Greg Daniel164a9f02016-02-22 09:56:40 -0500110
Greg Daniel7e000222018-12-03 10:08:21 -0500111 // Finds or creates a compatible GrVkSampler based on the GrSamplerState and
112 // GrVkYcbcrConversionInfo. The refcount is incremented and a pointer returned.
113 GrVkSampler* findOrCreateCompatibleSampler(const GrSamplerState&,
114 const GrVkYcbcrConversionInfo& ycbcrInfo);
115
116 // Finds or creates a compatible GrVkSamplerYcbcrConversion based on the GrSamplerState and
117 // GrVkYcbcrConversionInfo. The refcount is incremented and a pointer returned.
118 GrVkSamplerYcbcrConversion* findOrCreateCompatibleSamplerYcbcrConversion(
119 const GrVkYcbcrConversionInfo& ycbcrInfo);
egdaniel8b6394c2016-03-04 07:35:10 -0800120
Greg Daniel9a51a862018-11-30 10:18:14 -0500121 GrVkPipelineState* findOrCreateCompatiblePipelineState(
Robert Phillipsd0fe8752019-01-31 14:13:59 -0500122 GrRenderTarget*, GrSurfaceOrigin,
Greg Daniel9a51a862018-11-30 10:18:14 -0500123 const GrPipeline&,
124 const GrPrimitiveProcessor&,
125 const GrTextureProxy* const primProcProxies[],
126 GrPrimitiveType,
127 VkRenderPass compatibleRenderPass);
egdaniel22281c12016-03-23 13:49:40 -0700128
Greg Daniela7543782017-05-02 14:01:43 -0400129 void getSamplerDescriptorSetHandle(VkDescriptorType type,
130 const GrVkUniformHandler&,
egdaniel707bbd62016-07-26 07:19:47 -0700131 GrVkDescriptorSetManager::Handle* handle);
Greg Daniela7543782017-05-02 14:01:43 -0400132 void getSamplerDescriptorSetHandle(VkDescriptorType type,
133 const SkTArray<uint32_t>& visibilities,
egdaniel4d866df2016-08-25 13:52:00 -0700134 GrVkDescriptorSetManager::Handle* handle);
egdaniel707bbd62016-07-26 07:19:47 -0700135
136 // Returns the compatible VkDescriptorSetLayout to use for uniform buffers. The caller does not
137 // own the VkDescriptorSetLayout and thus should not delete it. This function should be used
138 // when the caller needs the layout to create a VkPipelineLayout.
139 VkDescriptorSetLayout getUniformDSLayout() const;
140
141 // Returns the compatible VkDescriptorSetLayout to use for a specific sampler handle. The caller
142 // does not own the VkDescriptorSetLayout and thus should not delete it. This function should be
143 // used when the caller needs the layout to create a VkPipelineLayout.
144 VkDescriptorSetLayout getSamplerDSLayout(const GrVkDescriptorSetManager::Handle&) const;
egdaniela95220d2016-07-21 11:50:37 -0700145
146 // Returns a GrVkDescriptorSet that can be used for uniform buffers. The GrVkDescriptorSet
147 // is already reffed for the caller.
148 const GrVkDescriptorSet* getUniformDescriptorSet();
149
150 // Returns a GrVkDescriptorSet that can be used for sampler descriptors that are compatible with
egdaniel707bbd62016-07-26 07:19:47 -0700151 // the GrVkDescriptorSetManager::Handle passed in. The GrVkDescriptorSet is already reffed for
egdaniela95220d2016-07-21 11:50:37 -0700152 // the caller.
egdaniela95220d2016-07-21 11:50:37 -0700153 const GrVkDescriptorSet* getSamplerDescriptorSet(const GrVkDescriptorSetManager::Handle&);
egdaniel778555c2016-05-02 06:50:36 -0700154
egdaniel778555c2016-05-02 06:50:36 -0700155
egdaniela95220d2016-07-21 11:50:37 -0700156 // Signals that the descriptor set passed it, which is compatible with the passed in handle,
157 // can be reused by the next allocation request.
158 void recycleDescriptorSet(const GrVkDescriptorSet* descSet,
159 const GrVkDescriptorSetManager::Handle&);
160
jvanverth4c6e47a2016-07-22 10:34:52 -0700161 // Creates or finds free uniform buffer resources of size GrVkUniformBuffer::kStandardSize.
162 // Anything larger will need to be created and released by the client.
163 const GrVkResource* findOrCreateStandardUniformBufferResource();
164
165 // Signals that the resource passed to it (which should be a uniform buffer resource)
166 // can be reused by the next uniform buffer resource request.
167 void recycleStandardUniformBufferResource(const GrVkResource*);
168
Greg Daniela870b462019-01-08 15:49:46 -0500169 void storePipelineCacheData();
170
Greg Daniel164a9f02016-02-22 09:56:40 -0500171 // Destroy any cached resources. To be called before destroying the VkDevice.
172 // The assumption is that all queues are idle and all command buffers are finished.
173 // For resource tracing to work properly, this should be called after unrefing all other
174 // resource usages.
Jim Van Verth09557d72016-11-07 11:10:21 -0500175 // If deviceLost is true, then resources will not be checked to see if they've finished
176 // before deleting (see section 4.2.4 of the Vulkan spec).
177 void destroyResources(bool deviceLost);
Greg Daniel164a9f02016-02-22 09:56:40 -0500178
179 // Abandon any cached resources. To be used when the context/VkDevice is lost.
180 // For resource tracing to work properly, this should be called after unrefing all other
181 // resource usages.
182 void abandonResources();
183
Ethan Nicholas8e265a72018-12-12 16:22:40 -0500184 void backgroundReset(GrVkCommandPool* pool);
185
186 void reset(GrVkCommandPool* pool);
187
Greg Daniel164a9f02016-02-22 09:56:40 -0500188private:
Ethan Nicholas8e265a72018-12-12 16:22:40 -0500189
djsollenefe46d22016-04-29 06:41:35 -0700190#ifdef SK_DEBUG
egdanielaf132772016-03-28 12:39:29 -0700191#define GR_PIPELINE_STATE_CACHE_STATS
192#endif
193
egdaniel22281c12016-03-23 13:49:40 -0700194 class PipelineStateCache : public ::SkNoncopyable {
195 public:
196 PipelineStateCache(GrVkGpu* gpu);
197 ~PipelineStateCache();
198
199 void abandon();
200 void release();
Robert Phillipsd0fe8752019-01-31 14:13:59 -0500201 GrVkPipelineState* refPipelineState(GrRenderTarget*, GrSurfaceOrigin,
202 const GrPrimitiveProcessor&,
Greg Daniel9a51a862018-11-30 10:18:14 -0500203 const GrTextureProxy* const primProcProxies[],
Brian Salomonff168d92018-06-23 15:17:27 -0400204 const GrPipeline&,
Greg Daniel09eeefb2017-10-16 15:15:02 -0400205 GrPrimitiveType,
Greg Daniel99b88e02018-10-03 15:31:20 -0400206 VkRenderPass compatibleRenderPass);
egdaniel22281c12016-03-23 13:49:40 -0700207
208 private:
209 enum {
210 // We may actually have kMaxEntries+1 PipelineStates in context because we create a new
211 // PipelineState before evicting from the cache.
212 kMaxEntries = 128,
egdaniel22281c12016-03-23 13:49:40 -0700213 };
214
215 struct Entry;
216
Ethan Nicholas87f340e2017-01-03 14:32:01 -0500217 struct DescHash {
218 uint32_t operator()(const GrProgramDesc& desc) const {
219 return SkOpts::hash_fn(desc.asKey(), desc.keyLength(), 0);
220 }
221 };
egdaniel22281c12016-03-23 13:49:40 -0700222
Brian Salomon1471df92018-06-08 10:49:00 -0400223 SkLRUCache<const GrVkPipelineStateBuilder::Desc, std::unique_ptr<Entry>, DescHash> fMap;
egdanielaf132772016-03-28 12:39:29 -0700224
egdaniel22281c12016-03-23 13:49:40 -0700225 GrVkGpu* fGpu;
egdanielaf132772016-03-28 12:39:29 -0700226
227#ifdef GR_PIPELINE_STATE_CACHE_STATS
egdaniel22281c12016-03-23 13:49:40 -0700228 int fTotalRequests;
229 int fCacheMisses;
egdaniel22281c12016-03-23 13:49:40 -0700230#endif
231 };
232
egdanield62e28b2016-06-07 08:43:30 -0700233 class CompatibleRenderPassSet {
234 public:
235 // This will always construct the basic load store render pass (all attachments load and
236 // store their data) so that there is at least one compatible VkRenderPass that can be used
237 // with this set.
238 CompatibleRenderPassSet(const GrVkGpu* gpu, const GrVkRenderTarget& target);
239
240 bool isCompatible(const GrVkRenderTarget& target) const;
241
242 GrVkRenderPass* getCompatibleRenderPass() const {
243 // The first GrVkRenderpass should always exist since we create the basic load store
244 // render pass on create
245 SkASSERT(fRenderPasses[0]);
246 return fRenderPasses[0];
247 }
248
egdaniel2feb0932016-06-08 06:48:09 -0700249 GrVkRenderPass* getRenderPass(const GrVkGpu* gpu,
250 const GrVkRenderPass::LoadStoreOps& colorOps,
egdaniel2feb0932016-06-08 06:48:09 -0700251 const GrVkRenderPass::LoadStoreOps& stencilOps);
252
Ethan Nicholas8e265a72018-12-12 16:22:40 -0500253 void releaseResources(GrVkGpu* gpu);
egdanield62e28b2016-06-07 08:43:30 -0700254 void abandonResources();
255
256 private:
257 SkSTArray<4, GrVkRenderPass*> fRenderPasses;
258 int fLastReturnedIndex;
259 };
260
Greg Daniela870b462019-01-08 15:49:46 -0500261 VkPipelineCache pipelineCache();
262
Greg Daniel164a9f02016-02-22 09:56:40 -0500263 GrVkGpu* fGpu;
264
jvanverth03509ea2016-03-02 13:19:47 -0800265 // Central cache for creating pipelines
266 VkPipelineCache fPipelineCache;
267
egdanielbc9b2962016-09-27 08:00:53 -0700268 // Cache of previously created copy pipelines
269 SkTArray<GrVkCopyPipeline*> fCopyPipelines;
270
egdanield62e28b2016-06-07 08:43:30 -0700271 SkSTArray<4, CompatibleRenderPassSet> fRenderPassArray;
Greg Daniel164a9f02016-02-22 09:56:40 -0500272
Greg Danielb46add82019-01-02 14:51:29 -0500273 SkTArray<const GrVkRenderPass*> fExternalRenderPasses;
274
Ethan Nicholas8e265a72018-12-12 16:22:40 -0500275 // Array of command pools that we are waiting on
276 SkSTArray<4, GrVkCommandPool*, true> fActiveCommandPools;
jvanverth7ec92412016-07-06 09:24:57 -0700277
Ethan Nicholas8e265a72018-12-12 16:22:40 -0500278 // Array of available command pools that are not in flight
279 SkSTArray<4, GrVkCommandPool*, true> fAvailableCommandPools;
egdaniel8b6394c2016-03-04 07:35:10 -0800280
jvanverth4c6e47a2016-07-22 10:34:52 -0700281 // Array of available uniform buffer resources
egdaniel707bbd62016-07-26 07:19:47 -0700282 SkSTArray<16, const GrVkResource*, true> fAvailableUniformBufferResources;
jvanverth4c6e47a2016-07-22 10:34:52 -0700283
egdaniel8b6394c2016-03-04 07:35:10 -0800284 // Stores GrVkSampler objects that we've already created so we can reuse them across multiple
egdaniel22281c12016-03-23 13:49:40 -0700285 // GrVkPipelineStates
Greg Daniel7e000222018-12-03 10:08:21 -0500286 SkTDynamicHash<GrVkSampler, GrVkSampler::Key> fSamplers;
287
288 // Stores GrVkSamplerYcbcrConversion objects that we've already created so we can reuse them.
289 SkTDynamicHash<GrVkSamplerYcbcrConversion, GrVkSamplerYcbcrConversion::Key> fYcbcrConversions;
egdaniel22281c12016-03-23 13:49:40 -0700290
291 // Cache of GrVkPipelineStates
292 PipelineStateCache* fPipelineStateCache;
egdaniel778555c2016-05-02 06:50:36 -0700293
Greg Daniel18f96022017-05-04 15:09:03 -0400294 SkSTArray<4, std::unique_ptr<GrVkDescriptorSetManager>> fDescriptorSetManagers;
egdaniela95220d2016-07-21 11:50:37 -0700295
egdaniel707bbd62016-07-26 07:19:47 -0700296 GrVkDescriptorSetManager::Handle fUniformDSHandle;
Ethan Nicholas8e265a72018-12-12 16:22:40 -0500297
298 std::recursive_mutex fBackgroundMutex;
Greg Daniel164a9f02016-02-22 09:56:40 -0500299};
300
301#endif