Fold attachment layout transitions into subpass (Refs #155)
This commit is contained in:
parent
a56f2b2c6f
commit
bc8cae9db7
2 changed files with 39 additions and 135 deletions
|
|
@ -85,16 +85,8 @@ bool VulkanExampleBase::checkCommandBuffers()
|
|||
|
||||
void VulkanExampleBase::createCommandBuffers()
|
||||
{
|
||||
// Create one command buffer per frame buffer
|
||||
// in the swap chain
|
||||
// Command buffers store a reference to the
|
||||
// frame buffer inside their render pass info
|
||||
// so for static usage withouth having to rebuild
|
||||
// them each frame, we use one per frame buffer
|
||||
|
||||
// Create one command buffer for each swap chain image and reuse for rendering
|
||||
drawCmdBuffers.resize(swapChain.imageCount);
|
||||
prePresentCmdBuffers.resize(swapChain.imageCount);
|
||||
postPresentCmdBuffers.resize(swapChain.imageCount);
|
||||
|
||||
VkCommandBufferAllocateInfo cmdBufAllocateInfo =
|
||||
vkTools::initializers::commandBufferAllocateInfo(
|
||||
|
|
@ -103,18 +95,11 @@ void VulkanExampleBase::createCommandBuffers()
|
|||
static_cast<uint32_t>(drawCmdBuffers.size()));
|
||||
|
||||
VK_CHECK_RESULT(vkAllocateCommandBuffers(device, &cmdBufAllocateInfo, drawCmdBuffers.data()));
|
||||
|
||||
// Command buffers for submitting present barriers
|
||||
// One pre and post present buffer per swap chain image
|
||||
VK_CHECK_RESULT(vkAllocateCommandBuffers(device, &cmdBufAllocateInfo, prePresentCmdBuffers.data()));
|
||||
VK_CHECK_RESULT(vkAllocateCommandBuffers(device, &cmdBufAllocateInfo, postPresentCmdBuffers.data()));
|
||||
}
|
||||
|
||||
void VulkanExampleBase::destroyCommandBuffers()
|
||||
{
|
||||
vkFreeCommandBuffers(device, cmdPool, static_cast<uint32_t>(drawCmdBuffers.size()), drawCmdBuffers.data());
|
||||
vkFreeCommandBuffers(device, cmdPool, static_cast<uint32_t>(drawCmdBuffers.size()), prePresentCmdBuffers.data());
|
||||
vkFreeCommandBuffers(device, cmdPool, static_cast<uint32_t>(drawCmdBuffers.size()), postPresentCmdBuffers.data());
|
||||
}
|
||||
|
||||
void VulkanExampleBase::createSetupCommandBuffer()
|
||||
|
|
@ -220,7 +205,6 @@ void VulkanExampleBase::prepare()
|
|||
createSetupCommandBuffer();
|
||||
setupSwapChain();
|
||||
createCommandBuffers();
|
||||
buildPresentCommandBuffers();
|
||||
setupDepthStencil();
|
||||
setupRenderPass();
|
||||
createPipelineCache();
|
||||
|
|
@ -625,12 +609,6 @@ void VulkanExampleBase::prepareFrame()
|
|||
{
|
||||
// Acquire the next image from the swap chaing
|
||||
VK_CHECK_RESULT(swapChain.acquireNextImage(semaphores.presentComplete, ¤tBuffer));
|
||||
|
||||
// Submit post present image barrier to transform the image back to a color attachment that our render pass can write to
|
||||
VkSubmitInfo submitInfo = vkTools::initializers::submitInfo();
|
||||
submitInfo.commandBufferCount = 1;
|
||||
submitInfo.pCommandBuffers = &postPresentCmdBuffers[currentBuffer];
|
||||
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE));
|
||||
}
|
||||
|
||||
void VulkanExampleBase::submitFrame()
|
||||
|
|
@ -667,12 +645,6 @@ void VulkanExampleBase::submitFrame()
|
|||
submitInfo.pSignalSemaphores = &semaphores.renderComplete;
|
||||
}
|
||||
|
||||
// Submit pre present image barrier to transform the image from color attachment to present(khr) for presenting to the swap chain
|
||||
VkSubmitInfo submitInfo = vkTools::initializers::submitInfo();
|
||||
submitInfo.commandBufferCount = 1;
|
||||
submitInfo.pCommandBuffers = &prePresentCmdBuffers[currentBuffer];
|
||||
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE));
|
||||
|
||||
VK_CHECK_RESULT(swapChain.queuePresent(queue, currentBuffer, submitTextOverlay ? semaphores.textOverlayComplete : semaphores.renderComplete));
|
||||
|
||||
VK_CHECK_RESULT(vkQueueWaitIdle(queue));
|
||||
|
|
@ -1472,72 +1444,6 @@ void VulkanExampleBase::buildCommandBuffers()
|
|||
// Can be overriden in derived class
|
||||
}
|
||||
|
||||
void VulkanExampleBase::buildPresentCommandBuffers()
|
||||
{
|
||||
VkCommandBufferBeginInfo cmdBufInfo = vkTools::initializers::commandBufferBeginInfo();
|
||||
|
||||
for (uint32_t i = 0; i < swapChain.imageCount; i++)
|
||||
{
|
||||
// Command buffer for post present barrier
|
||||
|
||||
// Insert a post present image barrier to transform the image back to a
|
||||
// color attachment that our render pass can write to
|
||||
// We always use undefined image layout as the source as it doesn't actually matter
|
||||
// what is done with the previous image contents
|
||||
|
||||
VK_CHECK_RESULT(vkBeginCommandBuffer(postPresentCmdBuffers[i], &cmdBufInfo));
|
||||
|
||||
VkImageMemoryBarrier postPresentBarrier = vkTools::initializers::imageMemoryBarrier();
|
||||
postPresentBarrier.srcAccessMask = 0;
|
||||
postPresentBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
postPresentBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
postPresentBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
postPresentBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
postPresentBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
postPresentBarrier.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
|
||||
postPresentBarrier.image = swapChain.buffers[i].image;
|
||||
|
||||
vkCmdPipelineBarrier(
|
||||
postPresentCmdBuffers[i],
|
||||
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
||||
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
|
||||
0,
|
||||
0, nullptr,
|
||||
0, nullptr,
|
||||
1, &postPresentBarrier);
|
||||
|
||||
VK_CHECK_RESULT(vkEndCommandBuffer(postPresentCmdBuffers[i]));
|
||||
|
||||
// Command buffers for pre present barrier
|
||||
|
||||
// Submit a pre present image barrier to the queue
|
||||
// Transforms the (framebuffer) image layout from color attachment to present(khr) for presenting to the swap chain
|
||||
|
||||
VK_CHECK_RESULT(vkBeginCommandBuffer(prePresentCmdBuffers[i], &cmdBufInfo));
|
||||
|
||||
VkImageMemoryBarrier prePresentBarrier = vkTools::initializers::imageMemoryBarrier();
|
||||
prePresentBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
prePresentBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
|
||||
prePresentBarrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
prePresentBarrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
prePresentBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
prePresentBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
prePresentBarrier.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
|
||||
prePresentBarrier.image = swapChain.buffers[i].image;
|
||||
|
||||
vkCmdPipelineBarrier(
|
||||
prePresentCmdBuffers[i],
|
||||
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
||||
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
|
||||
VK_FLAGS_NONE,
|
||||
0, nullptr, // No memory barriers,
|
||||
0, nullptr, // No buffer barriers,
|
||||
1, &prePresentBarrier);
|
||||
|
||||
VK_CHECK_RESULT(vkEndCommandBuffer(prePresentCmdBuffers[i]));
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanExampleBase::createCommandPool()
|
||||
{
|
||||
VkCommandPoolCreateInfo cmdPoolInfo = {};
|
||||
|
|
@ -1588,14 +1494,7 @@ void VulkanExampleBase::setupDepthStencil()
|
|||
mem_alloc.allocationSize = memReqs.size;
|
||||
mem_alloc.memoryTypeIndex = vulkanDevice->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||
VK_CHECK_RESULT(vkAllocateMemory(device, &mem_alloc, nullptr, &depthStencil.mem));
|
||||
|
||||
VK_CHECK_RESULT(vkBindImageMemory(device, depthStencil.image, depthStencil.mem, 0));
|
||||
vkTools::setImageLayout(
|
||||
setupCmdBuffer,
|
||||
depthStencil.image,
|
||||
VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT,
|
||||
VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||
|
||||
depthStencilView.image = depthStencil.image;
|
||||
VK_CHECK_RESULT(vkCreateImageView(device, &depthStencilView, nullptr, &depthStencil.view));
|
||||
|
|
@ -1629,8 +1528,7 @@ void VulkanExampleBase::setupFrameBuffer()
|
|||
|
||||
void VulkanExampleBase::setupRenderPass()
|
||||
{
|
||||
VkAttachmentDescription attachments[2] = {};
|
||||
|
||||
std::array<VkAttachmentDescription, 2> attachments = {};
|
||||
// Color attachment
|
||||
attachments[0].format = colorformat;
|
||||
attachments[0].samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
|
|
@ -1638,9 +1536,8 @@ void VulkanExampleBase::setupRenderPass()
|
|||
attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
attachments[0].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
attachments[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
|
||||
attachments[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
attachments[0].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
// Depth attachment
|
||||
attachments[1].format = depthFormat;
|
||||
attachments[1].samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
|
|
@ -1648,7 +1545,7 @@ void VulkanExampleBase::setupRenderPass()
|
|||
attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
attachments[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
attachments[1].initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
attachments[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
attachments[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
|
||||
VkAttachmentReference colorReference = {};
|
||||
|
|
@ -1659,27 +1556,44 @@ void VulkanExampleBase::setupRenderPass()
|
|||
depthReference.attachment = 1;
|
||||
depthReference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
|
||||
VkSubpassDescription subpass = {};
|
||||
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||
subpass.flags = 0;
|
||||
subpass.inputAttachmentCount = 0;
|
||||
subpass.pInputAttachments = NULL;
|
||||
subpass.colorAttachmentCount = 1;
|
||||
subpass.pColorAttachments = &colorReference;
|
||||
subpass.pResolveAttachments = NULL;
|
||||
subpass.pDepthStencilAttachment = &depthReference;
|
||||
subpass.preserveAttachmentCount = 0;
|
||||
subpass.pPreserveAttachments = NULL;
|
||||
VkSubpassDescription subpassDescription = {};
|
||||
subpassDescription.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||
subpassDescription.colorAttachmentCount = 1;
|
||||
subpassDescription.pColorAttachments = &colorReference;
|
||||
subpassDescription.pDepthStencilAttachment = &depthReference;
|
||||
subpassDescription.inputAttachmentCount = 0;
|
||||
subpassDescription.pInputAttachments = nullptr;
|
||||
subpassDescription.preserveAttachmentCount = 0;
|
||||
subpassDescription.pPreserveAttachments = nullptr;
|
||||
subpassDescription.pResolveAttachments = nullptr;
|
||||
|
||||
// Subpass dependencies for layout transitions
|
||||
std::array<VkSubpassDependency, 2> dependencies;
|
||||
|
||||
dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL;
|
||||
dependencies[0].dstSubpass = 0;
|
||||
dependencies[0].srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
|
||||
dependencies[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
dependencies[0].srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
|
||||
dependencies[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
dependencies[0].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
|
||||
|
||||
dependencies[1].srcSubpass = 0;
|
||||
dependencies[1].dstSubpass = VK_SUBPASS_EXTERNAL;
|
||||
dependencies[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
dependencies[1].dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
|
||||
dependencies[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
dependencies[1].dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
|
||||
dependencies[1].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
|
||||
|
||||
VkRenderPassCreateInfo renderPassInfo = {};
|
||||
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
||||
renderPassInfo.pNext = NULL;
|
||||
renderPassInfo.attachmentCount = 2;
|
||||
renderPassInfo.pAttachments = attachments;
|
||||
renderPassInfo.attachmentCount = static_cast<uint32_t>(attachments.size());
|
||||
renderPassInfo.pAttachments = attachments.data();
|
||||
renderPassInfo.subpassCount = 1;
|
||||
renderPassInfo.pSubpasses = &subpass;
|
||||
renderPassInfo.dependencyCount = 0;
|
||||
renderPassInfo.pDependencies = NULL;
|
||||
renderPassInfo.pSubpasses = &subpassDescription;
|
||||
renderPassInfo.dependencyCount = static_cast<uint32_t>(dependencies.size());
|
||||
renderPassInfo.pDependencies = dependencies.data();
|
||||
|
||||
VK_CHECK_RESULT(vkCreateRenderPass(device, &renderPassInfo, nullptr, &renderPass));
|
||||
}
|
||||
|
|
@ -1718,7 +1632,6 @@ void VulkanExampleBase::windowResize()
|
|||
destroyCommandBuffers();
|
||||
createCommandBuffers();
|
||||
buildCommandBuffers();
|
||||
buildPresentCommandBuffers();
|
||||
|
||||
vkQueueWaitIdle(queue);
|
||||
vkDeviceWaitIdle(device);
|
||||
|
|
|
|||
|
|
@ -104,10 +104,6 @@ protected:
|
|||
VkCommandPool cmdPool;
|
||||
// Command buffer used for setup
|
||||
VkCommandBuffer setupCmdBuffer = VK_NULL_HANDLE;
|
||||
// Command buffer for submitting a post present image barrier
|
||||
std::vector<VkCommandBuffer> postPresentCmdBuffers = { VK_NULL_HANDLE };
|
||||
// Command buffers for submitting a pre present image barrier
|
||||
std::vector<VkCommandBuffer> prePresentCmdBuffers = { VK_NULL_HANDLE };
|
||||
// Pipeline stage flags for the submit info structure
|
||||
VkPipelineStageFlags submitPipelineStages = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
|
||||
// Contains command buffers and semaphores to be presented to the queue
|
||||
|
|
@ -248,9 +244,6 @@ public:
|
|||
// all command buffers that may reference this
|
||||
virtual void buildCommandBuffers();
|
||||
|
||||
// Builds the command buffers used to submit the present barriers
|
||||
void buildPresentCommandBuffers();
|
||||
|
||||
// Creates a new (graphics) command pool object storing command buffers
|
||||
void createCommandPool();
|
||||
// Setup default depth and stencil views
|
||||
|
|
@ -358,13 +351,11 @@ public:
|
|||
|
||||
// Prepare the frame for workload submission
|
||||
// - Acquires the next image from the swap chain
|
||||
// - Submits a post present barrier
|
||||
// - Sets the default wait and signal semaphores
|
||||
void prepareFrame();
|
||||
|
||||
// Submit the frames' workload
|
||||
// - Submits the text overlay (if enabled)
|
||||
// -
|
||||
void submitFrame();
|
||||
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue