Have FrameData structs for each pipeline layout, instead of multiple arrays

This commit is contained in:
Henrik Rydgård 2023-10-09 23:08:19 +02:00
parent 397745ce14
commit 2b0192d818
3 changed files with 36 additions and 28 deletions

View File

@ -1199,7 +1199,7 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c
// The stencil ones are very commonly mostly redundant so let's eliminate them where possible.
// Might also want to consider scissor and viewport.
VkPipeline lastPipeline = VK_NULL_HANDLE;
VKRPipelineLayout *vkrPipelineLayout = nullptr;
FastVec<PendingDescSet> *descSets = nullptr;
VkPipelineLayout pipelineLayout = VK_NULL_HANDLE;
bool pipelineOK = false;
@ -1242,8 +1242,8 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c
if (pipeline != VK_NULL_HANDLE) {
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
vkrPipelineLayout = c.pipeline.pipelineLayout;
pipelineLayout = vkrPipelineLayout->pipelineLayout;
descSets = &c.pipeline.pipelineLayout->frameData[curFrame].descSets_;
pipelineLayout = c.pipeline.pipelineLayout->pipelineLayout;
lastGraphicsPipeline = graphicsPipeline;
pipelineOK = true;
} else {
@ -1338,7 +1338,7 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c
case VKRRenderCommand::DRAW_INDEXED:
if (pipelineOK) {
VkDescriptorSet set = vkrPipelineLayout->descSets_[curFrame][c.drawIndexed.descSetIndex].set;
VkDescriptorSet set = (*descSets)[c.drawIndexed.descSetIndex].set;
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &set, c.drawIndexed.numUboOffsets, c.drawIndexed.uboOffsets);
vkCmdBindIndexBuffer(cmd, c.drawIndexed.ibuffer, c.drawIndexed.ioffset, VK_INDEX_TYPE_UINT16);
VkDeviceSize voffset = c.drawIndexed.voffset;
@ -1349,7 +1349,7 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c
case VKRRenderCommand::DRAW:
if (pipelineOK) {
VkDescriptorSet set = vkrPipelineLayout->descSets_[curFrame][c.drawIndexed.descSetIndex].set;
VkDescriptorSet set = (*descSets)[c.drawIndexed.descSetIndex].set;
_dbg_assert_(set != VK_NULL_HANDLE);
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &set, c.draw.numUboOffsets, c.draw.uboOffsets);
if (c.draw.vbuffer) {

View File

@ -1647,8 +1647,8 @@ VKRPipelineLayout *VulkanRenderManager::CreatePipelineLayout(BindingType *bindin
vulkan_->SetDebugName(layout->pipelineLayout, VK_OBJECT_TYPE_PIPELINE_LAYOUT, tag);
for (int i = 0; i < VulkanContext::MAX_INFLIGHT_FRAMES; i++) {
layout->descPools[i].Create(vulkan_, bindingTypes, (uint32_t)bindingTypesCount, 512);
layout->descPools[i].Setup([]() {});
layout->frameData[i].pool.Create(vulkan_, bindingTypes, (uint32_t)bindingTypesCount, 512);
layout->frameData[i].pool.Setup([]() {});
}
pipelineLayouts_.push_back(layout);
@ -1657,7 +1657,7 @@ VKRPipelineLayout *VulkanRenderManager::CreatePipelineLayout(BindingType *bindin
void VulkanRenderManager::DestroyPipelineLayout(VKRPipelineLayout *layout) {
for (int i = 0; i < VulkanContext::MAX_INFLIGHT_FRAMES; i++) {
layout->descPools[i].Destroy();
layout->frameData[i].pool.Destroy();
}
vulkan_->Delete().QueueDeletePipelineLayout(layout->pipelineLayout);
@ -1678,18 +1678,22 @@ void VulkanRenderManager::FlushDescriptors(int frame) {
void VulkanRenderManager::ResetDescriptorLists(int frame) {
for (auto iter : pipelineLayouts_) {
iter->flushedDescriptors_[frame] = 0;
iter->descSets_[frame].clear();
iter->descData_[frame].clear();
VKRPipelineLayout::FrameData &data = iter->frameData[frame];
data.flushedDescriptors_ = 0;
data.descSets_.clear();
data.descData_.clear();
}
}
void VKRPipelineLayout::FlushDescSets(VulkanContext *vulkan, int frame, QueueProfileContext *profile) {
_dbg_assert_(frame < VulkanContext::MAX_INFLIGHT_FRAMES);
VulkanDescSetPool &pool = descPools[frame];
FastVec<PackedDescriptor> &descData = descData_[frame];
FastVec<PendingDescSet> &descSets = descSets_[frame];
FrameData &data = frameData[frame];
VulkanDescSetPool &pool = data.pool;
FastVec<PackedDescriptor> &descData = data.descData_;
FastVec<PendingDescSet> &descSets = data.descSets_;
pool.Reset();
@ -1702,7 +1706,7 @@ void VKRPipelineLayout::FlushDescSets(VulkanContext *vulkan, int frame, QueuePro
VkDescriptorImageInfo imageInfo[MAX_DESC_SET_BINDINGS]; // just picked a practical number
VkDescriptorBufferInfo bufferInfo[MAX_DESC_SET_BINDINGS];
size_t start = flushedDescriptors_[frame];
size_t start = data.flushedDescriptors_;
int writeCount = 0;
for (size_t index = start; index < descSets.size(); index++) {
@ -1788,6 +1792,6 @@ void VKRPipelineLayout::FlushDescSets(VulkanContext *vulkan, int frame, QueuePro
writeCount++;
}
flushedDescriptors_[frame] = (int)descSets.size();
data.flushedDescriptors_ = (int)descSets.size();
profile->descriptorsWritten += writeCount;
}

View File

@ -213,7 +213,7 @@ struct VKRPipelineLayout {
VKRPipelineLayout() {}
~VKRPipelineLayout() {
_assert_(!pipelineLayout && !descriptorSetLayout);
_assert_(descPools[0].IsDestroyed());
_assert_(frameData[0].pool.IsDestroyed());
}
enum { MAX_DESC_SET_BINDINGS = 10 };
BindingType bindingTypes[MAX_DESC_SET_BINDINGS];
@ -224,14 +224,16 @@ struct VKRPipelineLayout {
int pushConstSize = 0;
const char *tag = nullptr;
// The pipeline layout owns the descriptor set pools. Don't go create excessive layouts.
VulkanDescSetPool descPools[VulkanContext::MAX_INFLIGHT_FRAMES];
struct FrameData {
VulkanDescSetPool pool;
FastVec<PackedDescriptor> descData_;
FastVec<PendingDescSet> descSets_;
// TODO: We should be able to get away with a single descData_/descSets_ and then send it along,
// but it's easier to just segregate by frame id.
int flushedDescriptors_ = 0;
};
// TODO: We should be able to get away with a single descData_/descSets_ and then send it along,
// but it's easier to just segregate by frame id.
FastVec<PackedDescriptor> descData_[VulkanContext::MAX_INFLIGHT_FRAMES];
FastVec<PendingDescSet> descSets_[VulkanContext::MAX_INFLIGHT_FRAMES];
int flushedDescriptors_[VulkanContext::MAX_INFLIGHT_FRAMES]{};
FrameData frameData[VulkanContext::MAX_INFLIGHT_FRAMES];
void FlushDescSets(VulkanContext *vulkan, int frame, QueueProfileContext *profile);
};
@ -459,11 +461,13 @@ private:
int curFrame = vulkan_->GetCurFrame();
size_t offset = curPipelineLayout_->descData_[curFrame].size();
curPipelineLayout_->descData_[curFrame].extend(desc, count);
VKRPipelineLayout::FrameData &data = curPipelineLayout_->frameData[curFrame];
int setIndex = (int)curPipelineLayout_->descSets_[curFrame].size();
PendingDescSet &descSet = curPipelineLayout_->descSets_[curFrame].push_uninitialized();
size_t offset = data.descData_.size();
data.descData_.extend(desc, count);
int setIndex = (int)data.descSets_.size();
PendingDescSet &descSet = data.descSets_.push_uninitialized();
descSet.offset = (uint32_t)offset;
descSet.count = count;
// descSet.set = VK_NULL_HANDLE; // to be filled in