Fix renderpass and framebuffer setup for ray tracing samples

Using the UI overlay triggered some validation errors due to a mismatch between render passes
This commit is contained in:
Sascha Willems 2024-03-16 15:35:39 +01:00
parent 055d70dc30
commit 642f481c21
2 changed files with 41 additions and 9 deletions

View file

@ -8,22 +8,31 @@
#include "VulkanRaytracingSample.h" #include "VulkanRaytracingSample.h"
void VulkanRaytracingSample::updateRenderPass() void VulkanRaytracingSample::setupRenderPass()
{ {
// Update the default render pass with different color attachment load ops to keep attachment contents // Update the default render pass with different color attachment load ops to keep attachment contents
// With this change, we can e.g. draw an UI on top of the ray traced scene // With this change, we can e.g. draw an UI on top of the ray traced scene
vkDestroyRenderPass(device, renderPass, nullptr); vkDestroyRenderPass(device, renderPass, nullptr);
VkAttachmentLoadOp colorLoadOp{ VK_ATTACHMENT_LOAD_OP_LOAD };
VkImageLayout colorInitialLayout{ VK_IMAGE_LAYOUT_PRESENT_SRC_KHR };
if (rayQueryOnly) {
// For samples that use ray queries with rasterization, we need to use a setup similar to the non-ray tracing samples
colorLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
colorInitialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
}
std::array<VkAttachmentDescription, 2> attachments = {}; std::array<VkAttachmentDescription, 2> attachments = {};
// Color attachment // Color attachment
attachments[0].format = swapChain.colorFormat; attachments[0].format = swapChain.colorFormat;
attachments[0].samples = VK_SAMPLE_COUNT_1_BIT; attachments[0].samples = VK_SAMPLE_COUNT_1_BIT;
attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; attachments[0].loadOp = colorLoadOp;
attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE; attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachments[0].initialLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; attachments[0].initialLayout = colorInitialLayout;
attachments[0].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; attachments[0].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
// Depth attachment // Depth attachment
attachments[1].format = depthFormat; attachments[1].format = depthFormat;
@ -55,7 +64,7 @@ void VulkanRaytracingSample::updateRenderPass()
subpassDescription.pResolveAttachments = nullptr; subpassDescription.pResolveAttachments = nullptr;
// Subpass dependencies for layout transitions // Subpass dependencies for layout transitions
std::array<VkSubpassDependency, 2> dependencies; std::array<VkSubpassDependency, 2> dependencies{};
dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL; dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL;
dependencies[0].dstSubpass = 0; dependencies[0].dstSubpass = 0;
@ -84,6 +93,32 @@ void VulkanRaytracingSample::updateRenderPass()
VK_CHECK_RESULT(vkCreateRenderPass(device, &renderPassInfo, nullptr, &renderPass)); VK_CHECK_RESULT(vkCreateRenderPass(device, &renderPassInfo, nullptr, &renderPass));
} }
void VulkanRaytracingSample::setupFrameBuffer()
{
VkImageView attachments[2];
// Depth/Stencil attachment is the same for all frame buffers
attachments[1] = depthStencil.view;
VkFramebufferCreateInfo frameBufferCreateInfo = {};
frameBufferCreateInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
frameBufferCreateInfo.pNext = NULL;
frameBufferCreateInfo.renderPass = renderPass;
frameBufferCreateInfo.attachmentCount = 2;
frameBufferCreateInfo.pAttachments = attachments;
frameBufferCreateInfo.width = width;
frameBufferCreateInfo.height = height;
frameBufferCreateInfo.layers = 1;
// Create frame buffers for every swap chain image
frameBuffers.resize(swapChain.imageCount);
for (uint32_t i = 0; i < frameBuffers.size(); i++)
{
attachments[0] = swapChain.buffers[i].view;
VK_CHECK_RESULT(vkCreateFramebuffer(device, &frameBufferCreateInfo, nullptr, &frameBuffers[i]));
}
}
void VulkanRaytracingSample::enableExtensions() void VulkanRaytracingSample::enableExtensions()
{ {
// Require Vulkan 1.1 // Require Vulkan 1.1
@ -277,10 +312,6 @@ void VulkanRaytracingSample::prepare()
vkCmdTraceRaysKHR = reinterpret_cast<PFN_vkCmdTraceRaysKHR>(vkGetDeviceProcAddr(device, "vkCmdTraceRaysKHR")); vkCmdTraceRaysKHR = reinterpret_cast<PFN_vkCmdTraceRaysKHR>(vkGetDeviceProcAddr(device, "vkCmdTraceRaysKHR"));
vkGetRayTracingShaderGroupHandlesKHR = reinterpret_cast<PFN_vkGetRayTracingShaderGroupHandlesKHR>(vkGetDeviceProcAddr(device, "vkGetRayTracingShaderGroupHandlesKHR")); vkGetRayTracingShaderGroupHandlesKHR = reinterpret_cast<PFN_vkGetRayTracingShaderGroupHandlesKHR>(vkGetDeviceProcAddr(device, "vkGetRayTracingShaderGroupHandlesKHR"));
vkCreateRayTracingPipelinesKHR = reinterpret_cast<PFN_vkCreateRayTracingPipelinesKHR>(vkGetDeviceProcAddr(device, "vkCreateRayTracingPipelinesKHR")); vkCreateRayTracingPipelinesKHR = reinterpret_cast<PFN_vkCreateRayTracingPipelinesKHR>(vkGetDeviceProcAddr(device, "vkCreateRayTracingPipelinesKHR"));
// Update the render pass to keep the color attachment contents, so we can draw the UI on top of the ray traced output
if (!rayQueryOnly) {
updateRenderPass();
}
} }
VkStridedDeviceAddressRegionKHR VulkanRaytracingSample::getSbtEntryStridedDeviceAddressRegion(VkBuffer buffer, uint32_t handleCount) VkStridedDeviceAddressRegionKHR VulkanRaytracingSample::getSbtEntryStridedDeviceAddressRegion(VkBuffer buffer, uint32_t handleCount)

View file

@ -17,7 +17,8 @@ class VulkanRaytracingSample : public VulkanExampleBase
{ {
protected: protected:
// Update the default render pass with different color attachment load ops // Update the default render pass with different color attachment load ops
virtual void updateRenderPass(); virtual void setupRenderPass();
virtual void setupFrameBuffer();
public: public:
// Function pointers for ray tracing related stuff // Function pointers for ray tracing related stuff
PFN_vkGetBufferDeviceAddressKHR vkGetBufferDeviceAddressKHR; PFN_vkGetBufferDeviceAddressKHR vkGetBufferDeviceAddressKHR;