Move back buffer rendering to a separate "present" command buffer
This commit is contained in:
parent
242efba6f7
commit
415a795b11
4 changed files with 38 additions and 13 deletions
|
@ -376,7 +376,7 @@ void VulkanQueueRunner::PreprocessSteps(std::vector<VKRStep *> &steps) {
|
|||
}
|
||||
}
|
||||
|
||||
void VulkanQueueRunner::RunSteps(VkCommandBuffer cmd, std::vector<VKRStep *> &steps, QueueProfileContext *profile) {
|
||||
void VulkanQueueRunner::RunSteps(VkCommandBuffer mainCmd, VkCommandBuffer presentCmd, bool *hasPresentCommands, std::vector<VKRStep *> &steps, QueueProfileContext *profile) {
|
||||
if (profile)
|
||||
profile->cpuStartTime = time_now_d();
|
||||
|
||||
|
@ -388,36 +388,47 @@ void VulkanQueueRunner::RunSteps(VkCommandBuffer cmd, std::vector<VKRStep *> &st
|
|||
if (emitLabels) {
|
||||
VkDebugUtilsLabelEXT labelInfo{ VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT };
|
||||
labelInfo.pLabelName = step.tag;
|
||||
vkCmdBeginDebugUtilsLabelEXT(cmd, &labelInfo);
|
||||
vkCmdBeginDebugUtilsLabelEXT(mainCmd, &labelInfo);
|
||||
}
|
||||
|
||||
switch (step.stepType) {
|
||||
case VKRStepType::RENDER:
|
||||
PerformRenderPass(step, cmd);
|
||||
if (!step.render.framebuffer) {
|
||||
_dbg_assert_(!*hasPresentCommands);
|
||||
if (!*hasPresentCommands) {
|
||||
*hasPresentCommands = true;
|
||||
VkCommandBufferBeginInfo begin{ VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO };
|
||||
begin.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
||||
vkBeginCommandBuffer(presentCmd, &begin);
|
||||
}
|
||||
PerformRenderPass(step, presentCmd);
|
||||
} else {
|
||||
PerformRenderPass(step, mainCmd);
|
||||
}
|
||||
break;
|
||||
case VKRStepType::COPY:
|
||||
PerformCopy(step, cmd);
|
||||
PerformCopy(step, mainCmd);
|
||||
break;
|
||||
case VKRStepType::BLIT:
|
||||
PerformBlit(step, cmd);
|
||||
PerformBlit(step, mainCmd);
|
||||
break;
|
||||
case VKRStepType::READBACK:
|
||||
PerformReadback(step, cmd);
|
||||
PerformReadback(step, mainCmd);
|
||||
break;
|
||||
case VKRStepType::READBACK_IMAGE:
|
||||
PerformReadbackImage(step, cmd);
|
||||
PerformReadbackImage(step, mainCmd);
|
||||
break;
|
||||
case VKRStepType::RENDER_SKIP:
|
||||
break;
|
||||
}
|
||||
|
||||
if (profile && profile->timestampDescriptions.size() + 1 < MAX_TIMESTAMP_QUERIES) {
|
||||
vkCmdWriteTimestamp(cmd, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, profile->queryPool, (uint32_t)profile->timestampDescriptions.size());
|
||||
vkCmdWriteTimestamp(mainCmd, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, profile->queryPool, (uint32_t)profile->timestampDescriptions.size());
|
||||
profile->timestampDescriptions.push_back(StepToString(step));
|
||||
}
|
||||
|
||||
if (emitLabels) {
|
||||
vkCmdEndDebugUtilsLabelEXT(cmd);
|
||||
vkCmdEndDebugUtilsLabelEXT(mainCmd);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -257,7 +257,7 @@ public:
|
|||
}
|
||||
|
||||
void PreprocessSteps(std::vector<VKRStep *> &steps);
|
||||
void RunSteps(VkCommandBuffer cmd, std::vector<VKRStep *> &steps, QueueProfileContext *profile);
|
||||
void RunSteps(VkCommandBuffer cmd, VkCommandBuffer presentCmd, bool *hasPresentCommands, std::vector<VKRStep *> &steps, QueueProfileContext *profile);
|
||||
void LogSteps(const std::vector<VKRStep *> &steps, bool verbose);
|
||||
|
||||
std::string StepToString(const VKRStep &step) const;
|
||||
|
|
|
@ -309,11 +309,11 @@ VulkanRenderManager::VulkanRenderManager(VulkanContext *vulkan) : vulkan_(vulkan
|
|||
cmd_alloc.commandPool = frameData_[i].cmdPoolInit;
|
||||
cmd_alloc.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||
cmd_alloc.commandBufferCount = 1;
|
||||
|
||||
res = vkAllocateCommandBuffers(vulkan_->GetDevice(), &cmd_alloc, &frameData_[i].initCmd);
|
||||
_dbg_assert_(res == VK_SUCCESS);
|
||||
cmd_alloc.commandPool = frameData_[i].cmdPoolMain;
|
||||
res = vkAllocateCommandBuffers(vulkan_->GetDevice(), &cmd_alloc, &frameData_[i].mainCmd);
|
||||
res = vkAllocateCommandBuffers(vulkan_->GetDevice(), &cmd_alloc, &frameData_[i].presentCmd);
|
||||
_dbg_assert_(res == VK_SUCCESS);
|
||||
|
||||
// Creating the frame fence with true so they can be instantly waited on the first frame
|
||||
|
@ -1481,14 +1481,22 @@ void VulkanRenderManager::Submit(int frame, bool triggerFrameFence) {
|
|||
VkResult res = vkEndCommandBuffer(frameData.mainCmd);
|
||||
_assert_msg_(res == VK_SUCCESS, "vkEndCommandBuffer failed (main)! result=%s", VulkanResultToString(res));
|
||||
|
||||
if (frameData.hasPresentCommands) {
|
||||
VkResult res = vkEndCommandBuffer(frameData.presentCmd);
|
||||
_assert_msg_(res == VK_SUCCESS, "vkEndCommandBuffer failed (present)! result=%s", VulkanResultToString(res));
|
||||
}
|
||||
|
||||
SubmitInitCommands(frame);
|
||||
|
||||
// Submit the main and final cmdbuf, ending by signalling the fence.
|
||||
|
||||
VkCommandBuffer cmdBufs[1];
|
||||
VkCommandBuffer cmdBufs[2];
|
||||
int numCmdBufs = 0;
|
||||
|
||||
cmdBufs[numCmdBufs++] = frameData.mainCmd;
|
||||
if (frameData.hasPresentCommands) {
|
||||
cmdBufs[numCmdBufs++] = frameData.presentCmd;
|
||||
}
|
||||
|
||||
VkSubmitInfo submit_info{ VK_STRUCTURE_TYPE_SUBMIT_INFO };
|
||||
VkPipelineStageFlags waitStage[1]{ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
|
||||
|
@ -1519,6 +1527,7 @@ void VulkanRenderManager::Submit(int frame, bool triggerFrameFence) {
|
|||
}
|
||||
|
||||
frameData.hasInitCommands = false;
|
||||
frameData.hasPresentCommands = false;
|
||||
}
|
||||
|
||||
void VulkanRenderManager::EndSubmitFrame(int frame) {
|
||||
|
@ -1564,7 +1573,7 @@ void VulkanRenderManager::Run(int frame) {
|
|||
VkCommandBuffer cmd = frameData.mainCmd;
|
||||
queueRunner_.PreprocessSteps(stepsOnThread);
|
||||
//queueRunner_.LogSteps(stepsOnThread, false);
|
||||
queueRunner_.RunSteps(cmd, stepsOnThread, frameData.profilingEnabled_ ? &frameData.profile : nullptr);
|
||||
queueRunner_.RunSteps(cmd, frameData.presentCmd, &frameData.hasPresentCommands, stepsOnThread, frameData.profilingEnabled_ ? &frameData.profile : nullptr);
|
||||
stepsOnThread.clear();
|
||||
|
||||
switch (frameData.type) {
|
||||
|
@ -1586,6 +1595,7 @@ void VulkanRenderManager::Run(int frame) {
|
|||
void VulkanRenderManager::EndSyncFrame(int frame) {
|
||||
FrameData &frameData = frameData_[frame];
|
||||
|
||||
_dbg_assert_(!frameData.hasPresentCommands);
|
||||
frameData.readbackFenceUsed = true;
|
||||
|
||||
// The submit will trigger the readbackFence.
|
||||
|
|
|
@ -507,10 +507,14 @@ private:
|
|||
// These are on different threads so need separate pools.
|
||||
VkCommandPool cmdPoolInit; // Written to from main thread
|
||||
VkCommandPool cmdPoolMain; // Written to from render thread, which also submits
|
||||
|
||||
VkCommandBuffer initCmd;
|
||||
VkCommandBuffer mainCmd;
|
||||
VkCommandBuffer presentCmd;
|
||||
|
||||
bool hasInitCommands = false;
|
||||
bool hasPresentCommands = false;
|
||||
|
||||
std::vector<VKRStep *> steps;
|
||||
|
||||
// Swapchain.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue