vulkan: optimize vkUpdateDescriptorSets calls

This commit is contained in:
niki
2023-07-25 21:39:28 +02:00
parent af717c8cab
commit 9d9e2da763
2 changed files with 58 additions and 26 deletions
+54 -24
View File
@@ -360,15 +360,26 @@ void Shader::newFrame()
} }
else else
streamBuffers.at(0)->nextFrame(); streamBuffers.at(0)->nextFrame();
if (descriptorSetsVector.at(currentFrame).size() == 0)
descriptorSetsVector.at(currentFrame).push_back(allocateDescriptorSet());
currentDescriptorSet = descriptorSetsVector.at(currentFrame).at(0);
} }
void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBindPoint bindPoint) void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBindPoint bindPoint)
{ {
if (currentUsedDescriptorSetsCount >= static_cast<uint32_t>(descriptorSetsVector.at(currentFrame).size()))
descriptorSetsVector.at(currentFrame).push_back(allocateDescriptorSet());
VkDescriptorSet currentDescriptorSet = descriptorSetsVector.at(currentFrame).at(currentUsedDescriptorSetsCount);
std::vector<VkDescriptorBufferInfo> bufferInfos{};
bufferInfos.reserve(numBuffers);
std::vector<VkDescriptorImageInfo> imageInfos{};
imageInfos.reserve(numTextures);
std::vector<VkBufferView> bufferViews;
bufferViews.reserve(numBufferViews);
std::vector<VkWriteDescriptorSet> descriptorWrites;
if (!localUniformData.empty()) if (!localUniformData.empty())
{ {
auto usedStreamBufferMemory = currentUsedUniformStreamBuffersCount * uniformBufferSizeAligned; auto usedStreamBufferMemory = currentUsedUniformStreamBuffersCount * uniformBufferSizeAligned;
@@ -397,6 +408,8 @@ void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBind
bufferInfo.offset = offset; bufferInfo.offset = offset;
bufferInfo.range = localUniformData.size(); bufferInfo.range = localUniformData.size();
bufferInfos.push_back(bufferInfo);
VkWriteDescriptorSet uniformWrite{}; VkWriteDescriptorSet uniformWrite{};
uniformWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; uniformWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
uniformWrite.dstSet = currentDescriptorSet; uniformWrite.dstSet = currentDescriptorSet;
@@ -404,9 +417,9 @@ void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBind
uniformWrite.dstArrayElement = 0; uniformWrite.dstArrayElement = 0;
uniformWrite.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; uniformWrite.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
uniformWrite.descriptorCount = 1; uniformWrite.descriptorCount = 1;
uniformWrite.pBufferInfo = &bufferInfo; uniformWrite.pBufferInfo = &bufferInfos[bufferInfos.size() - 1];
vkUpdateDescriptorSets(device, 1, &uniformWrite, 0, nullptr); descriptorWrites.push_back(uniformWrite);
currentUsedUniformStreamBuffersCount++; currentUsedUniformStreamBuffersCount++;
} }
@@ -422,8 +435,6 @@ void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBind
{ {
bool isSampler = info.baseType == UNIFORM_SAMPLER; bool isSampler = info.baseType == UNIFORM_SAMPLER;
std::vector<VkDescriptorImageInfo> imageInfos;
for (int i = 0; i < info.count; i++) for (int i = 0; i < info.count; i++)
{ {
auto vkTexture = dynamic_cast<Texture*>(info.textures[i]); auto vkTexture = dynamic_cast<Texture*>(info.textures[i]);
@@ -451,9 +462,9 @@ void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBind
else else
write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
write.descriptorCount = static_cast<uint32_t>(info.count); write.descriptorCount = static_cast<uint32_t>(info.count);
write.pImageInfo = imageInfos.data(); write.pImageInfo = &imageInfos[imageInfos.size() - info.count];
vkUpdateDescriptorSets(device, 1, &write, 0, nullptr); descriptorWrites.push_back(write);
} }
if (info.baseType == UNIFORM_STORAGEBUFFER) if (info.baseType == UNIFORM_STORAGEBUFFER)
{ {
@@ -465,8 +476,6 @@ void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBind
write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
write.descriptorCount = info.count; write.descriptorCount = info.count;
std::vector<VkDescriptorBufferInfo> bufferInfos;
for (int i = 0; i < info.count; i++) for (int i = 0; i < info.count; i++)
{ {
if (info.buffers[i] == nullptr) if (info.buffers[i] == nullptr)
@@ -480,9 +489,9 @@ void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBind
bufferInfos.push_back(bufferInfo); bufferInfos.push_back(bufferInfo);
} }
write.pBufferInfo = bufferInfos.data(); write.pBufferInfo = &bufferInfos[bufferInfos.size() - info.count];
vkUpdateDescriptorSets(device, 1, &write, 0, nullptr); descriptorWrites.push_back(write);
} }
if (info.baseType == UNIFORM_TEXELBUFFER) if (info.baseType == UNIFORM_TEXELBUFFER)
{ {
@@ -494,8 +503,6 @@ void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBind
write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
write.descriptorCount = info.count; write.descriptorCount = info.count;
std::vector<VkBufferView> bufferViews;
for (int i = 0; i < info.count; i++) for (int i = 0; i < info.count; i++)
{ {
if (info.buffers[i] == nullptr) if (info.buffers[i] == nullptr)
@@ -504,20 +511,17 @@ void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBind
bufferViews.push_back((VkBufferView)info.buffers[i]->getTexelBufferHandle()); bufferViews.push_back((VkBufferView)info.buffers[i]->getTexelBufferHandle());
} }
write.pTexelBufferView = bufferViews.data(); write.pTexelBufferView = &bufferViews[bufferViews.size() - info.count];
vkUpdateDescriptorSets(device, 1, &write, 0, nullptr); descriptorWrites.push_back(write);
} }
} }
vkUpdateDescriptorSets(device, descriptorWrites.size(), descriptorWrites.data(), 0, nullptr);
vkCmdBindDescriptorSets(commandBuffer, bindPoint, pipelineLayout, 0, 1, &currentDescriptorSet, 0, nullptr); vkCmdBindDescriptorSets(commandBuffer, bindPoint, pipelineLayout, 0, 1, &currentDescriptorSet, 0, nullptr);
currentUsedDescriptorSetsCount++; currentUsedDescriptorSetsCount++;
if (currentUsedDescriptorSetsCount >= static_cast<uint32_t>(descriptorSetsVector.at(currentFrame).size()))
descriptorSetsVector.at(currentFrame).push_back(allocateDescriptorSet());
currentDescriptorSet = descriptorSetsVector.at(currentFrame).at(currentUsedDescriptorSetsCount);
} }
Shader::~Shader() Shader::~Shader()
@@ -954,6 +958,32 @@ void Shader::compileShaders()
shaderStages.push_back(shaderStageInfo); shaderStages.push_back(shaderStageInfo);
} }
numBuffers = 0;
numTextures = 0;
numBufferViews = 0;
if (localUniformData.size() > 0)
numBuffers++;
for (const auto &u : uniformInfos)
{
switch (u.second.baseType)
{
case UNIFORM_SAMPLER:
case UNIFORM_STORAGETEXTURE:
numTextures++;
break;
case UNIFORM_STORAGEBUFFER:
numBuffers++;
break;
case UNIFORM_TEXELBUFFER:
numBufferViews++;
break;
default:
continue;
}
}
} }
void Shader::createDescriptorSetLayout() void Shader::createDescriptorSetLayout()
+4 -2
View File
@@ -105,6 +105,10 @@ private:
VkPipeline computePipeline; VkPipeline computePipeline;
uint32_t numTextures;
uint32_t numBuffers;
uint32_t numBufferViews;
VkDescriptorSetLayout descriptorSetLayout; VkDescriptorSetLayout descriptorSetLayout;
VkPipelineLayout pipelineLayout; VkPipelineLayout pipelineLayout;
std::vector<VkDescriptorPoolSize> descriptorPoolSizes; std::vector<VkDescriptorPoolSize> descriptorPoolSizes;
@@ -134,8 +138,6 @@ private:
std::unordered_map<std::string, int> attributes; std::unordered_map<std::string, int> attributes;
VkDescriptorSet currentDescriptorSet;
uint32_t currentFrame; uint32_t currentFrame;
uint32_t currentUsedUniformStreamBuffersCount; uint32_t currentUsedUniformStreamBuffersCount;
uint32_t currentUsedDescriptorSetsCount; uint32_t currentUsedDescriptorSetsCount;