From 9025631231b119ad38d10d8407a6a0d755995cc5 Mon Sep 17 00:00:00 2001 From: niki Date: Fri, 9 Sep 2022 12:02:30 +0200 Subject: [PATCH] vulkan: modify descriptor set allocation Setting the size of each descriptor pool to one was a hack introduced to make the code work on android. Changing the code to now allocate all descriptor sets at once should fix the previous crash. Not tested yet. --- src/modules/graphics/vulkan/Shader.cpp | 53 +++++++++++++++----------- src/modules/graphics/vulkan/Shader.h | 3 +- 2 files changed, 32 insertions(+), 24 deletions(-) diff --git a/src/modules/graphics/vulkan/Shader.cpp b/src/modules/graphics/vulkan/Shader.cpp index 36af256fa..7c98f5743 100644 --- a/src/modules/graphics/vulkan/Shader.cpp +++ b/src/modules/graphics/vulkan/Shader.cpp @@ -118,7 +118,7 @@ static const TBuiltInResource defaultTBuiltInResource = { }; static const uint32_t STREAMBUFFER_DEFAULT_SIZE = 16; -static const uint32_t DESCRIPTOR_POOL_SIZE = 1; +static const uint32_t DESCRIPTOR_POOL_SIZE = 16; static VkShaderStageFlagBits getStageBit(ShaderStageType type) { switch (type) { @@ -174,7 +174,6 @@ bool Shader::loadVolatile() { currentFrame = 0; currentUsedUniformStreamBuffersCount = 0; currentUsedDescriptorSetsCount = 0; - currentAllocatedDescriptorSets = DESCRIPTOR_POOL_SIZE; return true; } @@ -197,11 +196,14 @@ void Shader::unloadVolatile() { if (computePipeline != VK_NULL_HANDLE) vkDestroyPipeline(device, computePipeline, nullptr); }); - for (const auto &streamBufferVector : streamBuffers) { - for (const auto streamBuffer : streamBufferVector) { + + while (!freeDescriptorSets.empty()) + freeDescriptorSets.pop(); + + for (const auto &streamBufferVector : streamBuffers) + for (const auto streamBuffer : streamBufferVector) delete streamBuffer; - } - } + shaderModules.clear(); shaderStages.clear(); streamBuffers.clear(); @@ -877,7 +879,7 @@ void Shader::setMainTex(graphics::Texture* texture) { } VkDescriptorSet Shader::allocateDescriptorSet() { - if (currentAllocatedDescriptorSets >= DESCRIPTOR_POOL_SIZE) { + if (freeDescriptorSets.empty()) { // fixme: we can optimize this, since sizes should never change for a given shader. std::vector sizes; @@ -910,24 +912,29 @@ VkDescriptorSet Shader::allocateDescriptorSet() { } descriptorPools.push_back(pool); - currentAllocatedDescriptorSets = 0; + std::vector layouts(DESCRIPTOR_POOL_SIZE, descriptorSetLayout); + + VkDescriptorSetAllocateInfo allocInfo{}; + allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + allocInfo.descriptorPool = descriptorPools.back(); + allocInfo.descriptorSetCount = DESCRIPTOR_POOL_SIZE; + allocInfo.pSetLayouts = layouts.data(); + + std::vector descriptorSet; + descriptorSet.resize(DESCRIPTOR_POOL_SIZE); + VkResult result = vkAllocateDescriptorSets(device, &allocInfo, descriptorSet.data()); + if (result != VK_SUCCESS) { + throw love::Exception("failed to allocate descriptor set"); + } + + for (const auto ds : descriptorSet) { + freeDescriptorSets.push(ds); + } } - VkDescriptorSetAllocateInfo allocInfo{}; - allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; - allocInfo.descriptorPool = descriptorPools.back(); - allocInfo.descriptorSetCount = 1; - allocInfo.pSetLayouts = &descriptorSetLayout; - - VkDescriptorSet descriptorSet; - VkResult result = vkAllocateDescriptorSets(device, &allocInfo, &descriptorSet); - if (result != VK_SUCCESS) { - throw love::Exception("failed to allocate descriptor set"); - } - - currentAllocatedDescriptorSets++; - - return descriptorSet; + auto ds = freeDescriptorSets.front(); + freeDescriptorSets.pop(); + return ds; } } // vulkan } // graphics diff --git a/src/modules/graphics/vulkan/Shader.h b/src/modules/graphics/vulkan/Shader.h index b7c89b0b0..e2f0566ab 100644 --- a/src/modules/graphics/vulkan/Shader.h +++ b/src/modules/graphics/vulkan/Shader.h @@ -12,6 +12,7 @@ #include #include #include +#include namespace love { @@ -88,7 +89,7 @@ private: // that gets dynamically increased if more memory is needed std::vector> streamBuffers; std::vector descriptorPools; - uint32_t currentAllocatedDescriptorSets; + std::queue freeDescriptorSets; std::vector> descriptorSetsVector; std::vector shaderStages;