From a04a5063536d2f2db8d99387d43a6bb1ecf68c17 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sat, 30 Dec 2023 12:03:46 +0100 Subject: [PATCH] Code cleanup, additional comments --- .../dynamicrendering/dynamicrendering.cpp | 101 ++++++++---------- 1 file changed, 45 insertions(+), 56 deletions(-) diff --git a/examples/dynamicrendering/dynamicrendering.cpp b/examples/dynamicrendering/dynamicrendering.cpp index 10b26995..f3ae6642 100644 --- a/examples/dynamicrendering/dynamicrendering.cpp +++ b/examples/dynamicrendering/dynamicrendering.cpp @@ -1,5 +1,5 @@ /* - * Vulkan Example - Using VK_KHR_dynamic_rendering for rendering without framebuffers and render passes (wip) + * Vulkan Example - Using VK_KHR_dynamic_rendering for rendering without framebuffers and render passes * * Copyright (C) 2022-2023 by Sascha Willems - www.saschawillems.de * @@ -14,10 +14,10 @@ class VulkanExample : public VulkanExampleBase { public: - PFN_vkCmdBeginRenderingKHR vkCmdBeginRenderingKHR; - PFN_vkCmdEndRenderingKHR vkCmdEndRenderingKHR; + PFN_vkCmdBeginRenderingKHR vkCmdBeginRenderingKHR{ VK_NULL_HANDLE }; + PFN_vkCmdEndRenderingKHR vkCmdEndRenderingKHR{ VK_NULL_HANDLE }; - VkPhysicalDeviceDynamicRenderingFeaturesKHR dynamicRenderingFeaturesKHR{}; + VkPhysicalDeviceDynamicRenderingFeaturesKHR enabledDynamicRenderingFeaturesKHR{}; vkglTF::Model model; @@ -28,10 +28,10 @@ public: } uniformData; vks::Buffer uniformBuffer; - VkPipeline pipeline; - VkPipelineLayout pipelineLayout; - VkDescriptorSet descriptorSet; - VkDescriptorSetLayout descriptorSetLayout; + VkPipeline pipeline{ VK_NULL_HANDLE }; + VkPipelineLayout pipelineLayout{ VK_NULL_HANDLE }; + VkDescriptorSet descriptorSet{ VK_NULL_HANDLE }; + VkDescriptorSetLayout descriptorSetLayout{ VK_NULL_HANDLE }; VulkanExample() : VulkanExampleBase(ENABLE_VALIDATION) { @@ -43,14 +43,18 @@ public: enabledInstanceExtensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); + // The sample uses the extension (instead of Vulkan 1.2, where dynamic rendering is core) enabledDeviceExtensions.push_back(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); - - // Since we are not requiring Vulkan 1.2, we need to enable some additional extensios as required per the spec enabledDeviceExtensions.push_back(VK_KHR_MAINTENANCE2_EXTENSION_NAME); enabledDeviceExtensions.push_back(VK_KHR_MULTIVIEW_EXTENSION_NAME); enabledDeviceExtensions.push_back(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); enabledDeviceExtensions.push_back(VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME); + // in addition to the extension, the feature needs to be explicitly enabled too by chaining the extension structure into device creation + enabledDynamicRenderingFeaturesKHR.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES_KHR; + enabledDynamicRenderingFeaturesKHR.dynamicRendering = VK_TRUE; + + deviceCreatepNextChain = &enabledDynamicRenderingFeaturesKHR; } ~VulkanExample() @@ -81,11 +85,6 @@ public: if (deviceFeatures.samplerAnisotropy) { enabledFeatures.samplerAnisotropy = VK_TRUE; }; - - dynamicRenderingFeaturesKHR.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES_KHR; - dynamicRenderingFeaturesKHR.dynamicRendering = VK_TRUE; - - deviceCreatepNextChain = &dynamicRenderingFeaturesKHR; } void loadAssets() @@ -102,7 +101,8 @@ public: { VK_CHECK_RESULT(vkBeginCommandBuffer(drawCmdBuffers[i], &cmdBufInfo)); - // Transition color and depth images for drawing + // With dynamic rendering there are no subpass dependencies, so we need to take care of proper layout transitions by using barriers + // This set of barriers prepares the color and depth images for output vks::tools::insertImageMemoryBarrier( drawCmdBuffers[i], swapChain.buffers[i].image, @@ -171,7 +171,7 @@ public: // End dynamic rendering vkCmdEndRenderingKHR(drawCmdBuffers[i]); - // Transition color image for presentation + // This set of barriers prepares the color image for presentation, we don't need to care for the depth image vks::tools::insertImageMemoryBarrier( drawCmdBuffers[i], swapChain.buffers[i].image, @@ -187,46 +187,22 @@ public: } } - void draw() - { - VulkanExampleBase::prepareFrame(); - submitInfo.commandBufferCount = 1; - submitInfo.pCommandBuffers = &drawCmdBuffers[currentBuffer]; - VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE)); - VulkanExampleBase::submitFrame(); - } - - void setupDescriptorPool() - { - // Example uses one ubo and one image sampler + void setupDescriptors() + { + // Pool std::vector poolSizes = { vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1), }; - VkDescriptorPoolCreateInfo descriptorPoolInfo = - vks::initializers::descriptorPoolCreateInfo(poolSizes, 1); + VkDescriptorPoolCreateInfo descriptorPoolInfo = vks::initializers::descriptorPoolCreateInfo(poolSizes, 1); VK_CHECK_RESULT(vkCreateDescriptorPool(device, &descriptorPoolInfo, nullptr, &descriptorPool)); - } - - void setupDescriptorSetLayout() - { + // Layout const std::vector setLayoutBindings = { // Binding 0 : Vertex shader uniform buffer vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT, 0), }; VkDescriptorSetLayoutCreateInfo descriptorLayout = vks::initializers::descriptorSetLayoutCreateInfo(setLayoutBindings); VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorLayout, nullptr, &descriptorSetLayout)); - - // Layout uses set 0 for passing vertex shader ubo and set 1 for fragment shader images (taken from glTF model) - const std::vector setLayouts = { - descriptorSetLayout, - vkglTF::descriptorSetLayoutImage, - }; - VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo = vks::initializers::pipelineLayoutCreateInfo(setLayouts.data(), 2); - VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pPipelineLayoutCreateInfo, nullptr, &pipelineLayout)); - } - - void setupDescriptorSet() - { + // Set VkDescriptorSetAllocateInfo allocInfo = vks::initializers::descriptorSetAllocateInfo(descriptorPool, &descriptorSetLayout, 1); VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &descriptorSet)); std::vector writeDescriptorSets = { @@ -238,6 +214,16 @@ public: void preparePipelines() { + // Layout + // Uses set 0 for passing vertex shader ubo and set 1 for fragment shader images (taken from glTF model) + const std::vector setLayouts = { + descriptorSetLayout, + vkglTF::descriptorSetLayoutImage, + }; + VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo = vks::initializers::pipelineLayoutCreateInfo(setLayouts.data(), 2); + VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pPipelineLayoutCreateInfo, nullptr, &pipelineLayout)); + + // Pipeline VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = vks::initializers::pipelineInputAssemblyStateCreateInfo(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0, VK_FALSE); VkPipelineRasterizationStateCreateInfo rasterizationState = vks::initializers::pipelineRasterizationStateCreateInfo(VK_POLYGON_MODE_FILL, VK_CULL_MODE_NONE, VK_FRONT_FACE_COUNTER_CLOCKWISE, 0); VkPipelineColorBlendAttachmentState blendAttachmentState = vks::initializers::pipelineColorBlendAttachmentState(0xf, VK_FALSE); @@ -283,7 +269,6 @@ public: { VK_CHECK_RESULT(vulkanDevice->createBuffer(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &uniformBuffer, sizeof(uniformData), &uniformData)); VK_CHECK_RESULT(uniformBuffer.map()); - updateUniformBuffers(); } @@ -299,29 +284,33 @@ public: { VulkanExampleBase::prepare(); + // Since we use an extension, we need to expliclity load the function pointers for extension related Vulkan commands vkCmdBeginRenderingKHR = reinterpret_cast(vkGetDeviceProcAddr(device, "vkCmdBeginRenderingKHR")); vkCmdEndRenderingKHR = reinterpret_cast(vkGetDeviceProcAddr(device, "vkCmdEndRenderingKHR")); loadAssets(); prepareUniformBuffers(); - setupDescriptorSetLayout(); + setupDescriptors(); preparePipelines(); - setupDescriptorPool(); - setupDescriptorSet(); buildCommandBuffers(); prepared = true; } + void draw() + { + VulkanExampleBase::prepareFrame(); + submitInfo.commandBufferCount = 1; + submitInfo.pCommandBuffers = &drawCmdBuffers[currentBuffer]; + VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE)); + VulkanExampleBase::submitFrame(); + } + virtual void render() { if (!prepared) return; - draw(); - } - - virtual void viewChanged() - { updateUniformBuffers(); + draw(); } };