blob: 902dece073f3356bac55a0bf75b8bb733c2cb8a5 [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
egdaniel22281c12016-03-23 13:49:40 -070011#include "GrGpu.h"
egdanield62e28b2016-06-07 08:43:30 -070012#include "GrResourceHandle.h"
Greg Daniel164a9f02016-02-22 09:56:40 -050013#include "GrVkDescriptorPool.h"
egdaniela95220d2016-07-21 11:50:37 -070014#include "GrVkDescriptorSetManager.h"
egdaniel22281c12016-03-23 13:49:40 -070015#include "GrVkPipelineState.h"
egdaniel2feb0932016-06-08 06:48:09 -070016#include "GrVkRenderPass.h"
Greg Daniel164a9f02016-02-22 09:56:40 -050017#include "GrVkResource.h"
18#include "GrVkUtil.h"
Ethan Nicholas87f340e2017-01-03 14:32:01 -050019#include "SkLRUCache.h"
Greg Daniel164a9f02016-02-22 09:56:40 -050020#include "SkTArray.h"
egdaniel8b6394c2016-03-04 07:35:10 -080021#include "SkTDynamicHash.h"
egdanielaf132772016-03-28 12:39:29 -070022#include "SkTInternalLList.h"
Greg Daniel164a9f02016-02-22 09:56:40 -050023
jvanverthe50f3e72016-03-28 07:03:06 -070024#include "vk/GrVkDefines.h"
Greg Daniel164a9f02016-02-22 09:56:40 -050025
26class GrPipeline;
27class GrPrimitiveProcessor;
Brian Salomon514baff2016-11-17 15:17:07 -050028class GrSamplerParams;
egdanielbc9b2962016-09-27 08:00:53 -070029class GrVkCopyPipeline;
Greg Daniel164a9f02016-02-22 09:56:40 -050030class GrVkGpu;
31class GrVkPipeline;
jvanverth7ec92412016-07-06 09:24:57 -070032class GrVkPrimaryCommandBuffer;
Greg Daniel164a9f02016-02-22 09:56:40 -050033class GrVkRenderTarget;
egdaniel8b6394c2016-03-04 07:35:10 -080034class GrVkSampler;
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
Greg Daniel164a9f02016-02-22 09:56:40 -050046 GrVkPipeline* createPipeline(const GrPipeline& pipeline,
csmartdaltonc633abb2016-11-01 08:55:55 -070047 const GrStencilSettings& stencil,
Greg Daniel164a9f02016-02-22 09:56:40 -050048 const GrPrimitiveProcessor& primProc,
49 VkPipelineShaderStageCreateInfo* shaderStageInfo,
50 int shaderStageCount,
51 GrPrimitiveType primitiveType,
52 const GrVkRenderPass& renderPass,
53 VkPipelineLayout layout);
54
egdanielbc9b2962016-09-27 08:00:53 -070055 GrVkCopyPipeline* findOrCreateCopyPipeline(const GrVkRenderTarget* dst,
56 VkPipelineShaderStageCreateInfo*,
57 VkPipelineLayout);
58
egdanield62e28b2016-06-07 08:43:30 -070059 GR_DEFINE_RESOURCE_HANDLE_CLASS(CompatibleRPHandle);
60
Greg Daniel164a9f02016-02-22 09:56:40 -050061 // Finds or creates a simple render pass that matches the target, increments the refcount,
egdanield62e28b2016-06-07 08:43:30 -070062 // and returns. The caller can optionally pass in a pointer to a CompatibleRPHandle. If this is
63 // non null it will be set to a handle that can be used in the furutre to quickly return a
64 // compatible GrVkRenderPasses without the need inspecting a GrVkRenderTarget.
65 const GrVkRenderPass* findCompatibleRenderPass(const GrVkRenderTarget& target,
66 CompatibleRPHandle* compatibleHandle = nullptr);
67 // The CompatibleRPHandle must be a valid handle previously set by a call to
68 // findCompatibleRenderPass(GrVkRenderTarget&, CompatibleRPHandle*).
69 const GrVkRenderPass* findCompatibleRenderPass(const CompatibleRPHandle& compatibleHandle);
70
egdaniel2feb0932016-06-08 06:48:09 -070071 // Finds or creates a render pass that matches the target and LoadStoreOps, increments the
72 // refcount, and returns. The caller can optionally pass in a pointer to a CompatibleRPHandle.
73 // If this is non null it will be set to a handle that can be used in the furutre to quickly
74 // return a GrVkRenderPasses without the need inspecting a GrVkRenderTarget.
egdanield62e28b2016-06-07 08:43:30 -070075 const GrVkRenderPass* findRenderPass(const GrVkRenderTarget& target,
egdaniel2feb0932016-06-08 06:48:09 -070076 const GrVkRenderPass::LoadStoreOps& colorOps,
egdaniel2feb0932016-06-08 06:48:09 -070077 const GrVkRenderPass::LoadStoreOps& stencilOps,
egdanield62e28b2016-06-07 08:43:30 -070078 CompatibleRPHandle* compatibleHandle = nullptr);
79
egdaniel2feb0932016-06-08 06:48:09 -070080 // The CompatibleRPHandle must be a valid handle previously set by a call to findRenderPass or
81 // findCompatibleRenderPass.
egdanield62e28b2016-06-07 08:43:30 -070082 const GrVkRenderPass* findRenderPass(const CompatibleRPHandle& compatibleHandle,
egdaniel2feb0932016-06-08 06:48:09 -070083 const GrVkRenderPass::LoadStoreOps& colorOps,
egdaniel2feb0932016-06-08 06:48:09 -070084 const GrVkRenderPass::LoadStoreOps& stencilOps);
85
jvanverth7ec92412016-07-06 09:24:57 -070086 GrVkPrimaryCommandBuffer* findOrCreatePrimaryCommandBuffer();
Greg Daniel164a9f02016-02-22 09:56:40 -050087 void checkCommandBuffers();
88
jvanverth7ec92412016-07-06 09:24:57 -070089 GrVkSecondaryCommandBuffer* findOrCreateSecondaryCommandBuffer();
90 void recycleSecondaryCommandBuffer(GrVkSecondaryCommandBuffer* cb);
91
egdanielc2dc1b22016-03-18 13:18:23 -070092 // Finds or creates a compatible GrVkDescriptorPool for the requested type and count.
Greg Daniel164a9f02016-02-22 09:56:40 -050093 // The refcount is incremented and a pointer returned.
94 // TODO: Currently this will just create a descriptor pool without holding onto a ref itself
95 // so we currently do not reuse them. Rquires knowing if another draw is currently using
96 // the GrVkDescriptorPool, the ability to reset pools, and the ability to purge pools out
97 // of our cache of GrVkDescriptorPools.
egdanielc2dc1b22016-03-18 13:18:23 -070098 GrVkDescriptorPool* findOrCreateCompatibleDescriptorPool(VkDescriptorType type, uint32_t count);
Greg Daniel164a9f02016-02-22 09:56:40 -050099
Brian Salomon514baff2016-11-17 15:17:07 -0500100 // Finds or creates a compatible GrVkSampler based on the GrSamplerParams.
egdaniel8b6394c2016-03-04 07:35:10 -0800101 // The refcount is incremented and a pointer returned.
Brian Salomon514baff2016-11-17 15:17:07 -0500102 GrVkSampler* findOrCreateCompatibleSampler(const GrSamplerParams&, uint32_t mipLevels);
egdaniel8b6394c2016-03-04 07:35:10 -0800103
egdanielaf132772016-03-28 12:39:29 -0700104 sk_sp<GrVkPipelineState> findOrCreateCompatiblePipelineState(const GrPipeline&,
105 const GrPrimitiveProcessor&,
106 GrPrimitiveType,
107 const GrVkRenderPass& renderPass);
egdaniel22281c12016-03-23 13:49:40 -0700108
Greg Daniela7543782017-05-02 14:01:43 -0400109 void getSamplerDescriptorSetHandle(VkDescriptorType type,
110 const GrVkUniformHandler&,
egdaniel707bbd62016-07-26 07:19:47 -0700111 GrVkDescriptorSetManager::Handle* handle);
Greg Daniela7543782017-05-02 14:01:43 -0400112 void getSamplerDescriptorSetHandle(VkDescriptorType type,
113 const SkTArray<uint32_t>& visibilities,
egdaniel4d866df2016-08-25 13:52:00 -0700114 GrVkDescriptorSetManager::Handle* handle);
egdaniel707bbd62016-07-26 07:19:47 -0700115
116 // Returns the compatible VkDescriptorSetLayout to use for uniform buffers. The caller does not
117 // own the VkDescriptorSetLayout and thus should not delete it. This function should be used
118 // when the caller needs the layout to create a VkPipelineLayout.
119 VkDescriptorSetLayout getUniformDSLayout() const;
120
121 // Returns the compatible VkDescriptorSetLayout to use for a specific sampler handle. The caller
122 // does not own the VkDescriptorSetLayout and thus should not delete it. This function should be
123 // used when the caller needs the layout to create a VkPipelineLayout.
124 VkDescriptorSetLayout getSamplerDSLayout(const GrVkDescriptorSetManager::Handle&) const;
egdaniela95220d2016-07-21 11:50:37 -0700125
126 // Returns a GrVkDescriptorSet that can be used for uniform buffers. The GrVkDescriptorSet
127 // is already reffed for the caller.
128 const GrVkDescriptorSet* getUniformDescriptorSet();
129
130 // Returns a GrVkDescriptorSet that can be used for sampler descriptors that are compatible with
egdaniel707bbd62016-07-26 07:19:47 -0700131 // the GrVkDescriptorSetManager::Handle passed in. The GrVkDescriptorSet is already reffed for
egdaniela95220d2016-07-21 11:50:37 -0700132 // the caller.
egdaniela95220d2016-07-21 11:50:37 -0700133 const GrVkDescriptorSet* getSamplerDescriptorSet(const GrVkDescriptorSetManager::Handle&);
egdaniel778555c2016-05-02 06:50:36 -0700134
egdaniel778555c2016-05-02 06:50:36 -0700135
egdaniela95220d2016-07-21 11:50:37 -0700136 // Signals that the descriptor set passed it, which is compatible with the passed in handle,
137 // can be reused by the next allocation request.
138 void recycleDescriptorSet(const GrVkDescriptorSet* descSet,
139 const GrVkDescriptorSetManager::Handle&);
140
jvanverth4c6e47a2016-07-22 10:34:52 -0700141 // Creates or finds free uniform buffer resources of size GrVkUniformBuffer::kStandardSize.
142 // Anything larger will need to be created and released by the client.
143 const GrVkResource* findOrCreateStandardUniformBufferResource();
144
145 // Signals that the resource passed to it (which should be a uniform buffer resource)
146 // can be reused by the next uniform buffer resource request.
147 void recycleStandardUniformBufferResource(const GrVkResource*);
148
Greg Daniel164a9f02016-02-22 09:56:40 -0500149 // Destroy any cached resources. To be called before destroying the VkDevice.
150 // The assumption is that all queues are idle and all command buffers are finished.
151 // For resource tracing to work properly, this should be called after unrefing all other
152 // resource usages.
Jim Van Verth09557d72016-11-07 11:10:21 -0500153 // If deviceLost is true, then resources will not be checked to see if they've finished
154 // before deleting (see section 4.2.4 of the Vulkan spec).
155 void destroyResources(bool deviceLost);
Greg Daniel164a9f02016-02-22 09:56:40 -0500156
157 // Abandon any cached resources. To be used when the context/VkDevice is lost.
158 // For resource tracing to work properly, this should be called after unrefing all other
159 // resource usages.
160 void abandonResources();
161
162private:
djsollenefe46d22016-04-29 06:41:35 -0700163#ifdef SK_DEBUG
egdanielaf132772016-03-28 12:39:29 -0700164#define GR_PIPELINE_STATE_CACHE_STATS
165#endif
166
egdaniel22281c12016-03-23 13:49:40 -0700167 class PipelineStateCache : public ::SkNoncopyable {
168 public:
169 PipelineStateCache(GrVkGpu* gpu);
170 ~PipelineStateCache();
171
172 void abandon();
173 void release();
egdanielaf132772016-03-28 12:39:29 -0700174 sk_sp<GrVkPipelineState> refPipelineState(const GrPipeline&,
175 const GrPrimitiveProcessor&,
176 GrPrimitiveType,
177 const GrVkRenderPass& renderPass);
egdaniel22281c12016-03-23 13:49:40 -0700178
179 private:
180 enum {
181 // We may actually have kMaxEntries+1 PipelineStates in context because we create a new
182 // PipelineState before evicting from the cache.
183 kMaxEntries = 128,
egdaniel22281c12016-03-23 13:49:40 -0700184 };
185
186 struct Entry;
187
Ethan Nicholas87f340e2017-01-03 14:32:01 -0500188 struct DescHash {
189 uint32_t operator()(const GrProgramDesc& desc) const {
190 return SkOpts::hash_fn(desc.asKey(), desc.keyLength(), 0);
191 }
192 };
egdaniel22281c12016-03-23 13:49:40 -0700193
Ethan Nicholas87f340e2017-01-03 14:32:01 -0500194 SkLRUCache<const GrVkPipelineState::Desc, std::unique_ptr<Entry>, DescHash> fMap;
egdanielaf132772016-03-28 12:39:29 -0700195
egdaniel22281c12016-03-23 13:49:40 -0700196 GrVkGpu* fGpu;
egdanielaf132772016-03-28 12:39:29 -0700197
198#ifdef GR_PIPELINE_STATE_CACHE_STATS
egdaniel22281c12016-03-23 13:49:40 -0700199 int fTotalRequests;
200 int fCacheMisses;
egdaniel22281c12016-03-23 13:49:40 -0700201#endif
202 };
203
egdanield62e28b2016-06-07 08:43:30 -0700204 class CompatibleRenderPassSet {
205 public:
206 // This will always construct the basic load store render pass (all attachments load and
207 // store their data) so that there is at least one compatible VkRenderPass that can be used
208 // with this set.
209 CompatibleRenderPassSet(const GrVkGpu* gpu, const GrVkRenderTarget& target);
210
211 bool isCompatible(const GrVkRenderTarget& target) const;
212
213 GrVkRenderPass* getCompatibleRenderPass() const {
214 // The first GrVkRenderpass should always exist since we create the basic load store
215 // render pass on create
216 SkASSERT(fRenderPasses[0]);
217 return fRenderPasses[0];
218 }
219
egdaniel2feb0932016-06-08 06:48:09 -0700220 GrVkRenderPass* getRenderPass(const GrVkGpu* gpu,
221 const GrVkRenderPass::LoadStoreOps& colorOps,
egdaniel2feb0932016-06-08 06:48:09 -0700222 const GrVkRenderPass::LoadStoreOps& stencilOps);
223
egdanield62e28b2016-06-07 08:43:30 -0700224 void releaseResources(const GrVkGpu* gpu);
225 void abandonResources();
226
227 private:
228 SkSTArray<4, GrVkRenderPass*> fRenderPasses;
229 int fLastReturnedIndex;
230 };
231
Greg Daniel164a9f02016-02-22 09:56:40 -0500232 GrVkGpu* fGpu;
233
jvanverth03509ea2016-03-02 13:19:47 -0800234 // Central cache for creating pipelines
235 VkPipelineCache fPipelineCache;
236
egdanielbc9b2962016-09-27 08:00:53 -0700237 // Cache of previously created copy pipelines
238 SkTArray<GrVkCopyPipeline*> fCopyPipelines;
239
egdanield62e28b2016-06-07 08:43:30 -0700240 SkSTArray<4, CompatibleRenderPassSet> fRenderPassArray;
Greg Daniel164a9f02016-02-22 09:56:40 -0500241
jvanverth7ec92412016-07-06 09:24:57 -0700242 // Array of PrimaryCommandBuffers that are currently in flight
egdaniel707bbd62016-07-26 07:19:47 -0700243 SkSTArray<4, GrVkPrimaryCommandBuffer*, true> fActiveCommandBuffers;
jvanverth7ec92412016-07-06 09:24:57 -0700244 // Array of available primary command buffers that are not in flight
egdaniel707bbd62016-07-26 07:19:47 -0700245 SkSTArray<4, GrVkPrimaryCommandBuffer*, true> fAvailableCommandBuffers;
jvanverth7ec92412016-07-06 09:24:57 -0700246
247 // Array of available secondary command buffers
egdaniel707bbd62016-07-26 07:19:47 -0700248 SkSTArray<16, GrVkSecondaryCommandBuffer*, true> fAvailableSecondaryCommandBuffers;
egdaniel8b6394c2016-03-04 07:35:10 -0800249
jvanverth4c6e47a2016-07-22 10:34:52 -0700250 // Array of available uniform buffer resources
egdaniel707bbd62016-07-26 07:19:47 -0700251 SkSTArray<16, const GrVkResource*, true> fAvailableUniformBufferResources;
jvanverth4c6e47a2016-07-22 10:34:52 -0700252
egdaniel8b6394c2016-03-04 07:35:10 -0800253 // Stores GrVkSampler objects that we've already created so we can reuse them across multiple
egdaniel22281c12016-03-23 13:49:40 -0700254 // GrVkPipelineStates
jvanverth62340062016-04-26 08:01:44 -0700255 SkTDynamicHash<GrVkSampler, uint16_t> fSamplers;
egdaniel22281c12016-03-23 13:49:40 -0700256
257 // Cache of GrVkPipelineStates
258 PipelineStateCache* fPipelineStateCache;
egdaniel778555c2016-05-02 06:50:36 -0700259
Greg Daniel18f96022017-05-04 15:09:03 -0400260 SkSTArray<4, std::unique_ptr<GrVkDescriptorSetManager>> fDescriptorSetManagers;
egdaniela95220d2016-07-21 11:50:37 -0700261
egdaniel707bbd62016-07-26 07:19:47 -0700262 GrVkDescriptorSetManager::Handle fUniformDSHandle;
Greg Daniel164a9f02016-02-22 09:56:40 -0500263};
264
265#endif