diff options
-rw-r--r-- | src/gpu/vk/GrVkDescriptorPool.cpp | 54 | ||||
-rw-r--r-- | src/gpu/vk/GrVkDescriptorPool.h | 31 | ||||
-rw-r--r-- | src/gpu/vk/GrVkProgram.cpp | 139 | ||||
-rw-r--r-- | src/gpu/vk/GrVkProgram.h | 55 | ||||
-rw-r--r-- | src/gpu/vk/GrVkProgramBuilder.cpp | 23 | ||||
-rw-r--r-- | src/gpu/vk/GrVkResourceProvider.cpp | 4 | ||||
-rw-r--r-- | src/gpu/vk/GrVkResourceProvider.h | 5 |
7 files changed, 175 insertions, 136 deletions
diff --git a/src/gpu/vk/GrVkDescriptorPool.cpp b/src/gpu/vk/GrVkDescriptorPool.cpp index 48880b64db..43ffe951e2 100644 --- a/src/gpu/vk/GrVkDescriptorPool.cpp +++ b/src/gpu/vk/GrVkDescriptorPool.cpp @@ -11,29 +11,24 @@ #include "SkTemplates.h" -GrVkDescriptorPool::GrVkDescriptorPool(const GrVkGpu* gpu, const DescriptorTypeCounts& typeCounts) +GrVkDescriptorPool::GrVkDescriptorPool(const GrVkGpu* gpu, VkDescriptorType type, uint32_t count) : INHERITED() - , fTypeCounts(typeCounts) { - int numPools = fTypeCounts.numPoolSizes(); - SkAutoTDeleteArray<VkDescriptorPoolSize> poolSizes(new VkDescriptorPoolSize[numPools]); - int currentPool = 0; - for (int i = VK_DESCRIPTOR_TYPE_BEGIN_RANGE; i < VK_DESCRIPTOR_TYPE_END_RANGE; ++i) { - if (fTypeCounts.fDescriptorTypeCount[i]) { - VkDescriptorPoolSize& poolSize = poolSizes.get()[currentPool++]; - poolSize.type = (VkDescriptorType)i; - poolSize.descriptorCount = fTypeCounts.fDescriptorTypeCount[i]; - } - } - SkASSERT(currentPool == numPools); + , fType (type) + , fCount(count) { + VkDescriptorPoolSize poolSize; + memset(&poolSize, 0, sizeof(VkDescriptorPoolSize)); + poolSize.descriptorCount = count; + poolSize.type = type; VkDescriptorPoolCreateInfo createInfo; memset(&createInfo, 0, sizeof(VkDescriptorPoolCreateInfo)); createInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; createInfo.pNext = nullptr; createInfo.flags = 0; - createInfo.maxSets = 2; // Currently we allow one set for samplers and one set for uniforms - createInfo.poolSizeCount = numPools; - createInfo.pPoolSizes = poolSizes.get(); + // This is an over/conservative estimate since each set may contain more than count descriptors. + createInfo.maxSets = count; + createInfo.poolSizeCount = 1; + createInfo.pPoolSizes = &poolSize; GR_VK_CALL_ERRCHECK(gpu->vkInterface(), CreateDescriptorPool(gpu->device(), &createInfo, @@ -41,8 +36,8 @@ GrVkDescriptorPool::GrVkDescriptorPool(const GrVkGpu* gpu, const DescriptorTypeC &fDescPool)); } -bool GrVkDescriptorPool::isCompatible(const DescriptorTypeCounts& typeCounts) const { - return fTypeCounts.isSuperSet(typeCounts); +bool GrVkDescriptorPool::isCompatible(VkDescriptorType type, uint32_t count) const { + return fType == type && count <= fCount; } void GrVkDescriptorPool::reset(const GrVkGpu* gpu) { @@ -54,26 +49,3 @@ void GrVkDescriptorPool::freeGPUData(const GrVkGpu* gpu) const { // allocated from the pool. GR_VK_CALL(gpu->vkInterface(), DestroyDescriptorPool(gpu->device(), fDescPool, nullptr)); } - -/////////////////////////////////////////////////////////////////////////////// - -int GrVkDescriptorPool::DescriptorTypeCounts::numPoolSizes() const { - int count = 0; - for (int i = VK_DESCRIPTOR_TYPE_BEGIN_RANGE; i < VK_DESCRIPTOR_TYPE_END_RANGE; ++i) { - count += fDescriptorTypeCount[i] ? 1 : 0; - } - return count; -} - -bool GrVkDescriptorPool::DescriptorTypeCounts::isSuperSet(const DescriptorTypeCounts& that) const { - for (int i = VK_DESCRIPTOR_TYPE_BEGIN_RANGE; i < VK_DESCRIPTOR_TYPE_END_RANGE; ++i) { - if (that.fDescriptorTypeCount[i] > fDescriptorTypeCount[i]) { - return false; - } - } - return true; -} - -void GrVkDescriptorPool::DescriptorTypeCounts::setTypeCount(VkDescriptorType type, uint8_t count) { - fDescriptorTypeCount[type] = count; -} diff --git a/src/gpu/vk/GrVkDescriptorPool.h b/src/gpu/vk/GrVkDescriptorPool.h index b20b01827c..ad24453ef6 100644 --- a/src/gpu/vk/GrVkDescriptorPool.h +++ b/src/gpu/vk/GrVkDescriptorPool.h @@ -14,39 +14,28 @@ class GrVkGpu; +/** + * We require that all descriptor sets are of a single descriptor type. We also use a pool to only + * make one type of descriptor set. Thus a single VkDescriptorPool will only allocated space for + * for one type of descriptor. + */ class GrVkDescriptorPool : public GrVkResource { public: - class DescriptorTypeCounts { - public: - DescriptorTypeCounts() { - memset(fDescriptorTypeCount, 0, sizeof(fDescriptorTypeCount)); - } - - void setTypeCount(VkDescriptorType type, uint8_t count); - int numPoolSizes() const; - - // Determines if for each i, that.fDescriptorTypeCount[i] <= fDescriptorTypeCount[i]; - bool isSuperSet(const DescriptorTypeCounts& that) const; - private: - uint8_t fDescriptorTypeCount[VK_DESCRIPTOR_TYPE_RANGE_SIZE]; - - friend class GrVkDescriptorPool; - }; - - explicit GrVkDescriptorPool(const GrVkGpu* gpu, const DescriptorTypeCounts& typeCounts); + explicit GrVkDescriptorPool(const GrVkGpu* gpu, VkDescriptorType type, uint32_t count); VkDescriptorPool descPool() const { return fDescPool; } void reset(const GrVkGpu* gpu); // Returns whether or not this descriptor pool could be used, assuming it gets fully reset and - // not in use by another draw, to support the requested typeCounts. - bool isCompatible(const DescriptorTypeCounts& typeCounts) const; + // not in use by another draw, to support the requested type and count. + bool isCompatible(VkDescriptorType type, uint32_t count) const; private: void freeGPUData(const GrVkGpu* gpu) const override; - DescriptorTypeCounts fTypeCounts; + VkDescriptorType fType; + uint32_t fCount; VkDescriptorPool fDescPool; typedef GrVkResource INHERITED; diff --git a/src/gpu/vk/GrVkProgram.cpp b/src/gpu/vk/GrVkProgram.cpp index 92adde86a9..d9d4336057 100644 --- a/src/gpu/vk/GrVkProgram.cpp +++ b/src/gpu/vk/GrVkProgram.cpp @@ -25,8 +25,6 @@ GrVkProgram::GrVkProgram(GrVkGpu* gpu, GrVkPipeline* pipeline, VkPipelineLayout layout, VkDescriptorSetLayout dsLayout[2], - GrVkDescriptorPool* descriptorPool, - VkDescriptorSet descriptorSets[2], const BuiltinUniformHandles& builtinUniformHandles, const UniformInfoArray& uniforms, uint32_t vertexUniformSize, @@ -35,20 +33,31 @@ GrVkProgram::GrVkProgram(GrVkGpu* gpu, GrGLSLPrimitiveProcessor* geometryProcessor, GrGLSLXferProcessor* xferProcessor, const GrGLSLFragProcs& fragmentProcessors) - : fDescriptorPool(descriptorPool) - , fPipeline(pipeline) + : fPipeline(pipeline) , fPipelineLayout(layout) , fBuiltinUniformHandles(builtinUniformHandles) , fGeometryProcessor(geometryProcessor) , fXferProcessor(xferProcessor) , fFragmentProcessors(fragmentProcessors) - , fProgramDataManager(uniforms, vertexUniformSize, fragmentUniformSize) { + , fProgramDataManager(uniforms, vertexUniformSize, fragmentUniformSize) + , fSamplerPoolManager(dsLayout[GrVkUniformHandler::kSamplerDescSet], + VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, numSamplers, gpu) + , fUniformPoolManager(dsLayout[GrVkUniformHandler::kUniformBufferDescSet], + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2, gpu) { fSamplers.setReserve(numSamplers); fTextureViews.setReserve(numSamplers); fTextures.setReserve(numSamplers); - memcpy(fDSLayout, dsLayout, 2 * sizeof(VkDescriptorSetLayout)); - memcpy(fDescriptorSets, descriptorSets, 2 * sizeof(VkDescriptorSetLayout)); + fDescriptorSets[0] = VK_NULL_HANDLE; + fDescriptorSets[1] = VK_NULL_HANDLE; + + // Currently we are always binding a descriptor set for uniform buffers. + fStartDS = GrVkUniformHandler::kUniformBufferDescSet; + fDSCount = 1; + if (numSamplers) { + fDSCount++; + fStartDS = SkTMin(fStartDS, (int)GrVkUniformHandler::kSamplerDescSet); + } fVertexUniformBuffer.reset(GrVkUniformBuffer::Create(gpu, vertexUniformSize, true)); fFragmentUniformBuffer.reset(GrVkUniformBuffer::Create(gpu, fragmentUniformSize, true)); @@ -61,10 +70,7 @@ GrVkProgram::GrVkProgram(GrVkGpu* gpu, GrVkProgram::~GrVkProgram() { // Must of freed all GPU resources before this is destroyed SkASSERT(!fPipeline); - SkASSERT(!fDescriptorPool); SkASSERT(!fPipelineLayout); - SkASSERT(!fDSLayout[0]); - SkASSERT(!fDSLayout[1]); SkASSERT(!fSamplers.count()); SkASSERT(!fTextureViews.count()); SkASSERT(!fTextures.count()); @@ -92,10 +98,7 @@ void GrVkProgram::freeGPUResources(const GrVkGpu* gpu) { fPipeline->unref(gpu); fPipeline = nullptr; } - if (fDescriptorPool) { - fDescriptorPool->unref(gpu); - fDescriptorPool = nullptr; - } + if (fPipelineLayout) { GR_VK_CALL(gpu->vkInterface(), DestroyPipelineLayout(gpu->device(), fPipelineLayout, @@ -103,17 +106,6 @@ void GrVkProgram::freeGPUResources(const GrVkGpu* gpu) { fPipelineLayout = VK_NULL_HANDLE; } - if (fDSLayout[0]) { - GR_VK_CALL(gpu->vkInterface(), DestroyDescriptorSetLayout(gpu->device(), fDSLayout[0], - nullptr)); - fDSLayout[0] = VK_NULL_HANDLE; - } - if (fDSLayout[1]) { - GR_VK_CALL(gpu->vkInterface(), DestroyDescriptorSetLayout(gpu->device(), fDSLayout[1], - nullptr)); - fDSLayout[1] = VK_NULL_HANDLE; - } - if (fVertexUniformBuffer) { fVertexUniformBuffer->release(gpu); } @@ -121,17 +113,18 @@ void GrVkProgram::freeGPUResources(const GrVkGpu* gpu) { if (fFragmentUniformBuffer) { fFragmentUniformBuffer->release(gpu); } + + fSamplerPoolManager.freeGPUResources(gpu); + fUniformPoolManager.freeGPUResources(gpu); + this->freeTempResources(gpu); } void GrVkProgram::abandonGPUResources() { fPipeline->unrefAndAbandon(); fPipeline = nullptr; - fDescriptorPool->unrefAndAbandon(); - fDescriptorPool = nullptr; + fPipelineLayout = VK_NULL_HANDLE; - fDSLayout[0] = VK_NULL_HANDLE; - fDSLayout[1] = VK_NULL_HANDLE; fVertexUniformBuffer->abandon(); fFragmentUniformBuffer->abandon(); @@ -150,6 +143,9 @@ void GrVkProgram::abandonGPUResources() { fTextures[i]->unrefAndAbandon(); } fTextures.rewind(); + + fSamplerPoolManager.abandonGPUResources(); + fUniformPoolManager.abandonGPUResources(); } static void append_texture_bindings(const GrProcessor& processor, @@ -188,6 +184,14 @@ void GrVkProgram::setData(GrVkGpu* gpu, fXferProcessor->setData(fProgramDataManager, pipeline.getXferProcessor()); append_texture_bindings(pipeline.getXferProcessor(), &textureBindings); + // Get new descriptor sets + if (fNumSamplers) { + fSamplerPoolManager.getNewDescriptorSet(gpu, + &fDescriptorSets[GrVkUniformHandler::kSamplerDescSet]); + } + fUniformPoolManager.getNewDescriptorSet(gpu, + &fDescriptorSets[GrVkUniformHandler::kUniformBufferDescSet]); + this->writeUniformBuffers(gpu); this->writeSamplers(gpu, textureBindings); @@ -340,13 +344,21 @@ void GrVkProgram::setRenderTargetState(const GrPipeline& pipeline) { void GrVkProgram::bind(const GrVkGpu* gpu, GrVkCommandBuffer* commandBuffer) { commandBuffer->bindPipeline(gpu, fPipeline); - commandBuffer->bindDescriptorSets(gpu, this, fPipelineLayout, 0, 2, fDescriptorSets, 0, - nullptr); + + if (fDSCount) { + commandBuffer->bindDescriptorSets(gpu, this, fPipelineLayout, fStartDS, fDSCount, + &fDescriptorSets[fStartDS], 0, nullptr); + } } void GrVkProgram::addUniformResources(GrVkCommandBuffer& commandBuffer) { -#if 1 - commandBuffer.addResource(fDescriptorPool); + if (fSamplerPoolManager.fPool) { + commandBuffer.addResource(fSamplerPoolManager.fPool); + } + if (fUniformPoolManager.fPool) { + commandBuffer.addResource(fUniformPoolManager.fPool); + } + if (fVertexUniformBuffer.get()) { commandBuffer.addResource(fVertexUniformBuffer->resource()); } @@ -364,5 +376,64 @@ void GrVkProgram::addUniformResources(GrVkCommandBuffer& commandBuffer) { for (int i = 0; i < fTextures.count(); ++i) { commandBuffer.addResource(fTextures[i]); } -#endif +} + +//////////////////////////////////////////////////////////////////////////////// + +void GrVkProgram::DescriptorPoolManager::getNewPool(GrVkGpu* gpu) { + if (fPool) { + fPool->unref(gpu); + SkASSERT(fMaxDescriptorSets < (SK_MaxU32 >> 1)); + fMaxDescriptorSets = fMaxDescriptorSets << 1; + + } + if (fMaxDescriptorSets) { + fPool = gpu->resourceProvider().findOrCreateCompatibleDescriptorPool(fDescType, + fMaxDescriptorSets); + } + SkASSERT(fPool || !fMaxDescriptorSets); +} + +void GrVkProgram::DescriptorPoolManager::getNewDescriptorSet(GrVkGpu* gpu, VkDescriptorSet* ds) { + if (!fMaxDescriptorSets) { + return; + } + if (fCurrentDescriptorSet == fMaxDescriptorSets) { + this->getNewPool(gpu); + fCurrentDescriptorSet = 0; + } + fCurrentDescriptorSet++; + + VkDescriptorSetAllocateInfo dsAllocateInfo; + memset(&dsAllocateInfo, 0, sizeof(VkDescriptorSetAllocateInfo)); + dsAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + dsAllocateInfo.pNext = nullptr; + dsAllocateInfo.descriptorPool = fPool->descPool(); + dsAllocateInfo.descriptorSetCount = 1; + dsAllocateInfo.pSetLayouts = &fDescLayout; + + GR_VK_CALL_ERRCHECK(gpu->vkInterface(), AllocateDescriptorSets(gpu->device(), + &dsAllocateInfo, + ds)); +} + +void GrVkProgram::DescriptorPoolManager::freeGPUResources(const GrVkGpu* gpu) { + if (fDescLayout) { + GR_VK_CALL(gpu->vkInterface(), DestroyDescriptorSetLayout(gpu->device(), fDescLayout, + nullptr)); + fDescLayout = VK_NULL_HANDLE; + } + + if (fPool) { + fPool->unref(gpu); + fPool = nullptr; + } +} + +void GrVkProgram::DescriptorPoolManager::abandonGPUResources() { + fDescLayout = VK_NULL_HANDLE; + if (fPool) { + fPool->unrefAndAbandon(); + fPool = nullptr; + } } diff --git a/src/gpu/vk/GrVkProgram.h b/src/gpu/vk/GrVkProgram.h index 9b4eeb1e93..1a024f2f2a 100644 --- a/src/gpu/vk/GrVkProgram.h +++ b/src/gpu/vk/GrVkProgram.h @@ -55,8 +55,6 @@ private: GrVkPipeline* pipeline, VkPipelineLayout layout, VkDescriptorSetLayout dsLayout[2], - GrVkDescriptorPool* descriptorPool, - VkDescriptorSet descriptorSets[2], const BuiltinUniformHandles& builtinUniformHandles, const UniformInfoArray& uniforms, uint32_t vertexUniformSize, @@ -66,6 +64,40 @@ private: GrGLSLXferProcessor* xferProcessor, const GrGLSLFragProcs& fragmentProcessors); + // Each pool will manage one type of descriptor. Thus each descriptor set we use will all be of + // one VkDescriptorType. + struct DescriptorPoolManager { + DescriptorPoolManager(VkDescriptorSetLayout layout, VkDescriptorType type, + uint32_t descCount, GrVkGpu* gpu) + : fDescLayout(layout) + , fDescType(type) + , fCurrentDescriptorSet(0) + , fPool(nullptr) { + SkASSERT(descCount < (SK_MaxU32 >> 2)); + fMaxDescriptorSets = descCount << 2; + this->getNewPool(gpu); + } + + ~DescriptorPoolManager() { + SkASSERT(!fDescLayout); + SkASSERT(!fPool); + } + + void getNewDescriptorSet(GrVkGpu* gpu, VkDescriptorSet* ds); + + void freeGPUResources(const GrVkGpu* gpu); + void abandonGPUResources(); + + VkDescriptorSetLayout fDescLayout; + VkDescriptorType fDescType; + uint32_t fMaxDescriptorSets; + uint32_t fCurrentDescriptorSet; + GrVkDescriptorPool* fPool; + + private: + void getNewPool(GrVkGpu* gpu); + }; + void writeUniformBuffers(const GrVkGpu* gpu); void writeSamplers(GrVkGpu* gpu, const SkTArray<const GrTextureAccess*>& textureBindings); @@ -110,28 +142,24 @@ private: // Helper for setData() that sets the view matrix and loads the render target height uniform void setRenderTargetState(const GrPipeline&); -// GrVkGpu* fGpu; - // GrVkResources - GrVkDescriptorPool* fDescriptorPool; GrVkPipeline* fPipeline; // Used for binding DescriptorSets to the command buffer but does not need to survive during // command buffer execution. Thus this is not need to be a GrVkResource. VkPipelineLayout fPipelineLayout; - // The first set (index 0) will be used for samplers and the second set (index 1) will be - // used for uniform buffers. - // The DSLayouts only are needed for allocating the descriptor sets and must survive until after - // descriptor sets have been updated. Thus the lifetime of the layouts will just be the life of - //the GrVkProgram. - VkDescriptorSetLayout fDSLayout[2]; // The DescriptorSets need to survive until the gpu has finished all draws that use them. // However, they will only be freed by the descriptor pool. Thus by simply keeping the // descriptor pool alive through the draw, the descritor sets will also stay alive. Thus we do - // not need a GrVkResource versions of VkDescriptorSet. + // not need a GrVkResource versions of VkDescriptorSet. We hold on to these in the program since + // we update the descriptor sets and bind them at separate times; VkDescriptorSet fDescriptorSets[2]; + // Meta data so we know which descriptor sets we are using and need to bind. + int fStartDS; + int fDSCount; + SkAutoTDelete<GrVkUniformBuffer> fVertexUniformBuffer; SkAutoTDelete<GrVkUniformBuffer> fFragmentUniformBuffer; @@ -151,6 +179,9 @@ private: GrVkProgramDataManager fProgramDataManager; + DescriptorPoolManager fSamplerPoolManager; + DescriptorPoolManager fUniformPoolManager; + #ifdef SK_DEBUG int fNumSamplers; #endif diff --git a/src/gpu/vk/GrVkProgramBuilder.cpp b/src/gpu/vk/GrVkProgramBuilder.cpp index 1b56054d99..9dbbbb848c 100644 --- a/src/gpu/vk/GrVkProgramBuilder.cpp +++ b/src/gpu/vk/GrVkProgramBuilder.cpp @@ -272,33 +272,10 @@ GrVkProgram* GrVkProgramBuilder::finalize(GrPrimitiveType primitiveType, return nullptr; } - - GrVkDescriptorPool::DescriptorTypeCounts typeCounts; - typeCounts.setTypeCount(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2); - SkASSERT(numSamplers < 256); - typeCounts.setTypeCount(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, (uint8_t)numSamplers); - GrVkDescriptorPool* descriptorPool = - fGpu->resourceProvider().findOrCreateCompatibleDescriptorPool(typeCounts); - - VkDescriptorSetAllocateInfo dsAllocateInfo; - memset(&dsAllocateInfo, 0, sizeof(VkDescriptorSetAllocateInfo)); - dsAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; - dsAllocateInfo.pNext = nullptr; - dsAllocateInfo.descriptorPool = descriptorPool->descPool(); - dsAllocateInfo.descriptorSetCount = 2; - dsAllocateInfo.pSetLayouts = dsLayout; - - VkDescriptorSet descriptorSets[2]; - GR_VK_CALL_ERRCHECK(fGpu->vkInterface(), AllocateDescriptorSets(fGpu->device(), - &dsAllocateInfo, - descriptorSets)); - return new GrVkProgram(fGpu, pipeline, pipelineLayout, dsLayout, - descriptorPool, - descriptorSets, fUniformHandles, fUniformHandler.fUniforms, fUniformHandler.fCurrentVertexUBOOffset, diff --git a/src/gpu/vk/GrVkResourceProvider.cpp b/src/gpu/vk/GrVkResourceProvider.cpp index b273e3b65d..3e0dfa028d 100644 --- a/src/gpu/vk/GrVkResourceProvider.cpp +++ b/src/gpu/vk/GrVkResourceProvider.cpp @@ -79,8 +79,8 @@ GrVkResourceProvider::findOrCreateCompatibleRenderPass(const GrVkRenderTarget& t } GrVkDescriptorPool* GrVkResourceProvider::findOrCreateCompatibleDescriptorPool( - const GrVkDescriptorPool::DescriptorTypeCounts& typeCounts) { - return new GrVkDescriptorPool(fGpu, typeCounts); + VkDescriptorType type, uint32_t count) { + return new GrVkDescriptorPool(fGpu, type, count); } GrVkSampler* GrVkResourceProvider::findOrCreateCompatibleSampler(const GrTextureParams& params) { diff --git a/src/gpu/vk/GrVkResourceProvider.h b/src/gpu/vk/GrVkResourceProvider.h index a769a652d4..66a2556a93 100644 --- a/src/gpu/vk/GrVkResourceProvider.h +++ b/src/gpu/vk/GrVkResourceProvider.h @@ -49,14 +49,13 @@ public: GrVkCommandBuffer* createCommandBuffer(); void checkCommandBuffers(); - // Finds or creates a compatible GrVkDescriptorPool for the requested DescriptorTypeCount. + // Finds or creates a compatible GrVkDescriptorPool for the requested type and count. // The refcount is incremented and a pointer returned. // TODO: Currently this will just create a descriptor pool without holding onto a ref itself // so we currently do not reuse them. Rquires knowing if another draw is currently using // the GrVkDescriptorPool, the ability to reset pools, and the ability to purge pools out // of our cache of GrVkDescriptorPools. - GrVkDescriptorPool* findOrCreateCompatibleDescriptorPool( - const GrVkDescriptorPool::DescriptorTypeCounts& typeCounts); + GrVkDescriptorPool* findOrCreateCompatibleDescriptorPool(VkDescriptorType type, uint32_t count); // Finds or creates a compatible GrVkSampler based on the GrTextureParams. // The refcount is incremented and a pointer returned. |