Index: src/gpu/vk/GrVkProgram.cpp |
diff --git a/src/gpu/vk/GrVkProgram.cpp b/src/gpu/vk/GrVkProgram.cpp |
index 92adde86a991f0446de0b01ad6e8dd7a66f35b20..d9d4336057c7bbe4721f9b1a4c2744c8527f7ddb 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; |
+ } |
} |