Corrected ui rendering order, refactored secondary command buffer generation

This commit is contained in:
saschawillems 2018-09-09 09:34:03 +02:00
parent e69090df78
commit 3b2e23ac49

View file

@ -67,7 +67,12 @@ public:
VkPipelineLayout pipelineLayout; VkPipelineLayout pipelineLayout;
VkCommandBuffer primaryCommandBuffer; VkCommandBuffer primaryCommandBuffer;
VkCommandBuffer secondaryCommandBuffer;
// Secondary scene command buffers used to store backgdrop and user interface
struct SecondaryCommandBuffers {
VkCommandBuffer background;
VkCommandBuffer ui;
} secondaryCommandBuffers;
// Number of animated objects to be renderer // Number of animated objects to be renderer
// by using threads and secondary command buffers // by using threads and secondary command buffers
@ -152,14 +157,10 @@ public:
vkDestroyPipelineLayout(device, pipelineLayout, nullptr); vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
vkFreeCommandBuffers(device, cmdPool, 1, &primaryCommandBuffer);
vkFreeCommandBuffers(device, cmdPool, 1, &secondaryCommandBuffer);
models.ufo.destroy(); models.ufo.destroy();
models.skysphere.destroy(); models.skysphere.destroy();
for (auto& thread : threadData) for (auto& thread : threadData) {
{
vkFreeCommandBuffers(device, thread.commandPool, thread.commandBuffer.size(), thread.commandBuffer.data()); vkFreeCommandBuffers(device, thread.commandPool, thread.commandBuffer.size(), thread.commandBuffer.data());
vkDestroyCommandPool(device, thread.commandPool, nullptr); vkDestroyCommandPool(device, thread.commandPool, nullptr);
} }
@ -186,9 +187,10 @@ public:
1); 1);
VK_CHECK_RESULT(vkAllocateCommandBuffers(device, &cmdBufAllocateInfo, &primaryCommandBuffer)); VK_CHECK_RESULT(vkAllocateCommandBuffers(device, &cmdBufAllocateInfo, &primaryCommandBuffer));
// Create a secondary command buffer for rendering the star sphere // Create additional secondary CBs for background and ui
cmdBufAllocateInfo.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY; cmdBufAllocateInfo.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
VK_CHECK_RESULT(vkAllocateCommandBuffers(device, &cmdBufAllocateInfo, &secondaryCommandBuffer)); VK_CHECK_RESULT(vkAllocateCommandBuffers(device, &cmdBufAllocateInfo, &secondaryCommandBuffers.background));
VK_CHECK_RESULT(vkAllocateCommandBuffers(device, &cmdBufAllocateInfo, &secondaryCommandBuffers.ui));
threadData.resize(numThreads); threadData.resize(numThreads);
@ -303,24 +305,26 @@ public:
VK_CHECK_RESULT(vkEndCommandBuffer(cmdBuffer)); VK_CHECK_RESULT(vkEndCommandBuffer(cmdBuffer));
} }
void updateSecondaryCommandBuffer(VkCommandBufferInheritanceInfo inheritanceInfo) void updateSecondaryCommandBuffers(VkCommandBufferInheritanceInfo inheritanceInfo)
{ {
// Secondary command buffer for the sky sphere // Secondary command buffer for the sky sphere
VkCommandBufferBeginInfo commandBufferBeginInfo = vks::initializers::commandBufferBeginInfo(); VkCommandBufferBeginInfo commandBufferBeginInfo = vks::initializers::commandBufferBeginInfo();
commandBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; commandBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
commandBufferBeginInfo.pInheritanceInfo = &inheritanceInfo; commandBufferBeginInfo.pInheritanceInfo = &inheritanceInfo;
VK_CHECK_RESULT(vkBeginCommandBuffer(secondaryCommandBuffer, &commandBufferBeginInfo));
VkViewport viewport = vks::initializers::viewport((float)width, (float)height, 0.0f, 1.0f); VkViewport viewport = vks::initializers::viewport((float)width, (float)height, 0.0f, 1.0f);
vkCmdSetViewport(secondaryCommandBuffer, 0, 1, &viewport);
VkRect2D scissor = vks::initializers::rect2D(width, height, 0, 0); VkRect2D scissor = vks::initializers::rect2D(width, height, 0, 0);
vkCmdSetScissor(secondaryCommandBuffer, 0, 1, &scissor);
vkCmdBindPipeline(secondaryCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.starsphere); /*
Background
*/
if (displaySkybox) { VK_CHECK_RESULT(vkBeginCommandBuffer(secondaryCommandBuffers.background, &commandBufferBeginInfo));
vkCmdSetViewport(secondaryCommandBuffers.background, 0, 1, &viewport);
vkCmdSetScissor(secondaryCommandBuffers.background, 0, 1, &scissor);
vkCmdBindPipeline(secondaryCommandBuffers.background, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.starsphere);
glm::mat4 view = glm::mat4(1.0f); glm::mat4 view = glm::mat4(1.0f);
view = glm::rotate(view, glm::radians(rotation.x), glm::vec3(1.0f, 0.0f, 0.0f)); view = glm::rotate(view, glm::radians(rotation.x), glm::vec3(1.0f, 0.0f, 0.0f));
@ -330,7 +334,7 @@ public:
glm::mat4 mvp = matrices.projection * view; glm::mat4 mvp = matrices.projection * view;
vkCmdPushConstants( vkCmdPushConstants(
secondaryCommandBuffer, secondaryCommandBuffers.background,
pipelineLayout, pipelineLayout,
VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_VERTEX_BIT,
0, 0,
@ -338,18 +342,31 @@ public:
&mvp); &mvp);
VkDeviceSize offsets[1] = { 0 }; VkDeviceSize offsets[1] = { 0 };
vkCmdBindVertexBuffers(secondaryCommandBuffer, 0, 1, &models.skysphere.vertices.buffer, offsets); vkCmdBindVertexBuffers(secondaryCommandBuffers.background, 0, 1, &models.skysphere.vertices.buffer, offsets);
vkCmdBindIndexBuffer(secondaryCommandBuffer, models.skysphere.indices.buffer, 0, VK_INDEX_TYPE_UINT32); vkCmdBindIndexBuffer(secondaryCommandBuffers.background, models.skysphere.indices.buffer, 0, VK_INDEX_TYPE_UINT32);
vkCmdDrawIndexed(secondaryCommandBuffer, models.skysphere.indexCount, 1, 0, 0, 0); vkCmdDrawIndexed(secondaryCommandBuffers.background, models.skysphere.indexCount, 1, 0, 0, 0);
}
VK_CHECK_RESULT(vkEndCommandBuffer(secondaryCommandBuffers.background));
/*
User interface
With VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS, the primary command buffer's content has to be defined
by secondary command buffers, which also applies to the UI overlay command buffer
*/
VK_CHECK_RESULT(vkBeginCommandBuffer(secondaryCommandBuffers.ui, &commandBufferBeginInfo));
vkCmdSetViewport(secondaryCommandBuffers.ui, 0, 1, &viewport);
vkCmdSetScissor(secondaryCommandBuffers.ui, 0, 1, &scissor);
vkCmdBindPipeline(secondaryCommandBuffers.ui, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.starsphere);
// With VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS, the primary command buffer's content has to be defined
// by secondary command buffers, which also applies to the UI overlay command buffer
if (settings.overlay) { if (settings.overlay) {
drawUI(secondaryCommandBuffer); drawUI(secondaryCommandBuffers.ui);
} }
VK_CHECK_RESULT(vkEndCommandBuffer(secondaryCommandBuffer)); VK_CHECK_RESULT(vkEndCommandBuffer(secondaryCommandBuffers.ui));
} }
// Updates the secondary command buffers using a thread pool // Updates the secondary command buffers using a thread pool
@ -357,6 +374,9 @@ public:
// lat submitted to the queue for rendering // lat submitted to the queue for rendering
void updateCommandBuffers(VkFramebuffer frameBuffer) void updateCommandBuffers(VkFramebuffer frameBuffer)
{ {
// Contains the list of secondary command buffers to be submitted
std::vector<VkCommandBuffer> commandBuffers;
VkCommandBufferBeginInfo cmdBufInfo = vks::initializers::commandBufferBeginInfo(); VkCommandBufferBeginInfo cmdBufInfo = vks::initializers::commandBufferBeginInfo();
VkClearValue clearValues[2]; VkClearValue clearValues[2];
@ -387,12 +407,12 @@ public:
// Secondary command buffer also use the currently active framebuffer // Secondary command buffer also use the currently active framebuffer
inheritanceInfo.framebuffer = frameBuffer; inheritanceInfo.framebuffer = frameBuffer;
// Contains the list of secondary command buffers to be executed // Update secondary sene command buffers
std::vector<VkCommandBuffer> commandBuffers; updateSecondaryCommandBuffers(inheritanceInfo);
// Secondary command buffer with star background sphere if (displaySkybox) {
updateSecondaryCommandBuffer(inheritanceInfo); commandBuffers.push_back(secondaryCommandBuffers.background);
commandBuffers.push_back(secondaryCommandBuffer); }
// Add a job to the thread's queue for each object to be rendered // Add a job to the thread's queue for each object to be rendered
for (uint32_t t = 0; t < numThreads; t++) for (uint32_t t = 0; t < numThreads; t++)
@ -417,12 +437,14 @@ public:
} }
} }
// Render ui last
if (UIOverlay.visible) {
commandBuffers.push_back(secondaryCommandBuffers.ui);
}
// Execute render commands from the secondary command buffer // Execute render commands from the secondary command buffer
vkCmdExecuteCommands(primaryCommandBuffer, commandBuffers.size(), commandBuffers.data()); vkCmdExecuteCommands(primaryCommandBuffer, commandBuffers.size(), commandBuffers.data());
// TODO: Can't call commands in this secondary buffer
// drawUI(primaryCommandBuffer);
vkCmdEndRenderPass(primaryCommandBuffer); vkCmdEndRenderPass(primaryCommandBuffer);
VK_CHECK_RESULT(vkEndCommandBuffer(primaryCommandBuffer)); VK_CHECK_RESULT(vkEndCommandBuffer(primaryCommandBuffer));