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
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)
{
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())
{
auto usedStreamBufferMemory = currentUsedUniformStreamBuffersCount * uniformBufferSizeAligned;
@@ -397,6 +408,8 @@ void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBind
bufferInfo.offset = offset;
bufferInfo.range = localUniformData.size();
bufferInfos.push_back(bufferInfo);
VkWriteDescriptorSet uniformWrite{};
uniformWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
uniformWrite.dstSet = currentDescriptorSet;
@@ -404,9 +417,9 @@ void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBind
uniformWrite.dstArrayElement = 0;
uniformWrite.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
uniformWrite.descriptorCount = 1;
uniformWrite.pBufferInfo = &bufferInfo;
uniformWrite.pBufferInfo = &bufferInfos[bufferInfos.size() - 1];
vkUpdateDescriptorSets(device, 1, &uniformWrite, 0, nullptr);
descriptorWrites.push_back(uniformWrite);
currentUsedUniformStreamBuffersCount++;
}
@@ -422,8 +435,6 @@ void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBind
{
bool isSampler = info.baseType == UNIFORM_SAMPLER;
std::vector<VkDescriptorImageInfo> imageInfos;
for (int i = 0; i < info.count; i++)
{
auto vkTexture = dynamic_cast<Texture*>(info.textures[i]);
@@ -451,9 +462,9 @@ void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBind
else
write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
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)
{
@@ -465,8 +476,6 @@ void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBind
write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
write.descriptorCount = info.count;
std::vector<VkDescriptorBufferInfo> bufferInfos;
for (int i = 0; i < info.count; i++)
{
if (info.buffers[i] == nullptr)
@@ -480,9 +489,9 @@ void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBind
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)
{
@@ -494,8 +503,6 @@ void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBind
write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
write.descriptorCount = info.count;
std::vector<VkBufferView> bufferViews;
for (int i = 0; i < info.count; i++)
{
if (info.buffers[i] == nullptr)
@@ -504,20 +511,17 @@ void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBind
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);
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()
@@ -954,6 +958,32 @@ void Shader::compileShaders()
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()
+4 -2
View File
@@ -105,6 +105,10 @@ private:
VkPipeline computePipeline;
uint32_t numTextures;
uint32_t numBuffers;
uint32_t numBufferViews;
VkDescriptorSetLayout descriptorSetLayout;
VkPipelineLayout pipelineLayout;
std::vector<VkDescriptorPoolSize> descriptorPoolSizes;
@@ -134,8 +138,6 @@ private:
std::unordered_map<std::string, int> attributes;
VkDescriptorSet currentDescriptorSet;
uint32_t currentFrame;
uint32_t currentUsedUniformStreamBuffersCount;
uint32_t currentUsedDescriptorSetsCount;