mirror of
https://github.com/love2d/love.git
synced 2026-08-20 04:30:09 +02:00
vulkan: optimize vkUpdateDescriptorSets calls
This commit is contained in:
@@ -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, ¤tDescriptorSet, 0, nullptr);
|
vkCmdBindDescriptorSets(commandBuffer, bindPoint, pipelineLayout, 0, 1, ¤tDescriptorSet, 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()
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user