From 7935025c2d19354493e7d43b7696e581740aa2e1 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Mon, 1 Jan 2024 17:41:48 +0100 Subject: [PATCH] Code cleanup Comments --- .../conditionalrender/conditionalrender.cpp | 76 ++++---- .../conservativeraster/conservativeraster.cpp | 179 ++++++++---------- examples/debugprintf/debugprintf.cpp | 11 +- examples/debugutils/debugutils.cpp | 135 ++++++------- examples/meshshader/meshshader.cpp | 59 +++--- 5 files changed, 208 insertions(+), 252 deletions(-) diff --git a/examples/conditionalrender/conditionalrender.cpp b/examples/conditionalrender/conditionalrender.cpp index 3d256f83..625942df 100644 --- a/examples/conditionalrender/conditionalrender.cpp +++ b/examples/conditionalrender/conditionalrender.cpp @@ -23,21 +23,20 @@ public: vkglTF::Model scene; - struct { + struct UniformData { glm::mat4 projection; glm::mat4 view; glm::mat4 model; - } uboVS; - + } uniformData; vks::Buffer uniformBuffer; - std::vector conditionalVisibility; + std::vector conditionalVisibility{}; vks::Buffer conditionalBuffer; - VkPipelineLayout pipelineLayout; - VkPipeline pipeline; - VkDescriptorSetLayout descriptorSetLayout; - VkDescriptorSet descriptorSet; + VkPipelineLayout pipelineLayout{ VK_NULL_HANDLE }; + VkPipeline pipeline{ VK_NULL_HANDLE }; + VkDescriptorSetLayout descriptorSetLayout{ VK_NULL_HANDLE }; + VkDescriptorSet descriptorSet{ VK_NULL_HANDLE }; VulkanExample() : VulkanExampleBase() { @@ -57,11 +56,13 @@ public: ~VulkanExample() { - vkDestroyPipeline(device, pipeline, nullptr); - vkDestroyPipelineLayout(device, pipelineLayout, nullptr); - vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr); - uniformBuffer.destroy(); - conditionalBuffer.destroy(); + if (device) { + vkDestroyPipeline(device, pipeline, nullptr); + vkDestroyPipelineLayout(device, pipelineLayout, nullptr); + vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr); + uniformBuffer.destroy(); + conditionalBuffer.destroy(); + } } void renderNode(vkglTF::Node *node, VkCommandBuffer commandBuffer) { @@ -155,14 +156,16 @@ public: scene.loadFromFile(getAssetPath() + "models/gltf/glTF-Embedded/Buggy.gltf", vulkanDevice, queue); } - void setupDescriptorSets() + void setupDescriptors() { + // Pool std::vector poolSizes = { vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1), }; VkDescriptorPoolCreateInfo descriptorPoolCI = vks::initializers::descriptorPoolCreateInfo(poolSizes, 1); VK_CHECK_RESULT(vkCreateDescriptorPool(device, &descriptorPoolCI, nullptr, &descriptorPool)); + // Layouts std::vector setLayoutBindings = { vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT, 0), }; @@ -172,15 +175,7 @@ public: descriptorLayoutCI.pBindings = setLayoutBindings.data(); VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorLayoutCI, nullptr, &descriptorSetLayout)); - std::array setLayouts = { - descriptorSetLayout, vkglTF::descriptorSetLayoutUbo - }; - VkPipelineLayoutCreateInfo pipelineLayoutCI = vks::initializers::pipelineLayoutCreateInfo(setLayouts.data(), 2); - VkPushConstantRange pushConstantRange = vks::initializers::pushConstantRange(VK_SHADER_STAGE_VERTEX_BIT, sizeof(glm::vec4), 0); - pipelineLayoutCI.pushConstantRangeCount = 1; - pipelineLayoutCI.pPushConstantRanges = &pushConstantRange; - VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pipelineLayoutCI, nullptr, &pipelineLayout)); - + // Sets VkDescriptorSetAllocateInfo descriptorSetAllocateInfo = vks::initializers::descriptorSetAllocateInfo(descriptorPool, &descriptorSetLayout, 1); VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &descriptorSetAllocateInfo, &descriptorSet)); std::vector writeDescriptorSets = { @@ -191,8 +186,17 @@ public: void preparePipelines() { - const std::vector dynamicStateEnables = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; + // Layout + std::array setLayouts = { + descriptorSetLayout, vkglTF::descriptorSetLayoutUbo + }; + VkPipelineLayoutCreateInfo pipelineLayoutCI = vks::initializers::pipelineLayoutCreateInfo(setLayouts.data(), 2); + VkPushConstantRange pushConstantRange = vks::initializers::pushConstantRange(VK_SHADER_STAGE_VERTEX_BIT, sizeof(glm::vec4), 0); + pipelineLayoutCI.pushConstantRangeCount = 1; + pipelineLayoutCI.pPushConstantRanges = &pushConstantRange; + VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pipelineLayoutCI, nullptr, &pipelineLayout)); + // Pipeline VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCI = vks::initializers::pipelineInputAssemblyStateCreateInfo(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0, VK_FALSE); VkPipelineRasterizationStateCreateInfo rasterizationStateCI = vks::initializers::pipelineRasterizationStateCreateInfo(VK_POLYGON_MODE_FILL, VK_CULL_MODE_BACK_BIT, VK_FRONT_FACE_COUNTER_CLOCKWISE, 0); VkPipelineColorBlendAttachmentState blendAttachmentState = vks::initializers::pipelineColorBlendAttachmentState(0xf, VK_FALSE); @@ -200,7 +204,8 @@ public: VkPipelineDepthStencilStateCreateInfo depthStencilStateCI = vks::initializers::pipelineDepthStencilStateCreateInfo(VK_TRUE, VK_TRUE, VK_COMPARE_OP_LESS_OR_EQUAL); VkPipelineViewportStateCreateInfo viewportStateCI = vks::initializers::pipelineViewportStateCreateInfo(1, 1, 0); VkPipelineMultisampleStateCreateInfo multisampleStateCI = vks::initializers::pipelineMultisampleStateCreateInfo(VK_SAMPLE_COUNT_1_BIT, 0); - VkPipelineDynamicStateCreateInfo dynamicStateCI = vks::initializers::pipelineDynamicStateCreateInfo(dynamicStateEnables.data(), static_cast(dynamicStateEnables.size()), 0); + const std::vector dynamicStateEnables = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; + VkPipelineDynamicStateCreateInfo dynamicStateCI = vks::initializers::pipelineDynamicStateCreateInfo(dynamicStateEnables, 0); VkGraphicsPipelineCreateInfo pipelineCI = vks::initializers::pipelineCreateInfo(pipelineLayout, renderPass, 0); pipelineCI.pInputAssemblyState = &inputAssemblyStateCI; @@ -229,17 +234,17 @@ public: VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &uniformBuffer, - sizeof(uboVS))); + sizeof(UniformData))); VK_CHECK_RESULT(uniformBuffer.map()); updateUniformBuffers(); } void updateUniformBuffers() { - uboVS.projection = camera.matrices.perspective; - uboVS.view = glm::scale(camera.matrices.view, glm::vec3(0.1f , -0.1f, 0.1f)); - uboVS.model = glm::translate(glm::mat4(1.0f), scene.dimensions.min); - memcpy(uniformBuffer.mapped, &uboVS, sizeof(uboVS)); + uniformData.projection = camera.matrices.perspective; + uniformData.view = glm::scale(camera.matrices.view, glm::vec3(0.1f , -0.1f, 0.1f)); + uniformData.model = glm::translate(glm::mat4(1.0f), scene.dimensions.min); + memcpy(uniformBuffer.mapped, &uniformData, sizeof(UniformData)); } void updateConditionalBuffer() @@ -309,7 +314,7 @@ public: loadAssets(); prepareConditionalRendering(); prepareUniformBuffers(); - setupDescriptorSets(); + setupDescriptors(); preparePipelines(); buildCommandBuffers(); prepared = true; @@ -319,15 +324,8 @@ public: { if (!prepared) return; - draw(); - if (camera.updated) { - updateUniformBuffers(); - } - } - - virtual void viewChanged() - { updateUniformBuffers(); + draw(); } virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay) diff --git a/examples/conservativeraster/conservativeraster.cpp b/examples/conservativeraster/conservativeraster.cpp index 5b8d9515..d98a2262 100644 --- a/examples/conservativeraster/conservativeraster.cpp +++ b/examples/conservativeraster/conservativeraster.cpp @@ -5,17 +5,13 @@ * * Uses an offscreen buffer with lower resolution to demonstrate the effect of conservative rasterization * -* Copyright by Sascha Willems - www.saschawillems.de +* Copyright (C) 2016-2023 by Sascha Willems - www.saschawillems.de * * This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) */ #include "vulkanexamplebase.h" - -#define FB_COLOR_FORMAT VK_FORMAT_R8G8B8A8_UNORM -#define ZOOM_FACTOR 16 - class VulkanExample : public VulkanExampleBase { public: @@ -32,40 +28,35 @@ public: struct Triangle { vks::Buffer vertices; vks::Buffer indices; - uint32_t indexCount; + uint32_t indexCount{ 0 }; } triangle; - vks::Buffer uniformBuffer; - - struct UniformBuffers { - vks::Buffer scene; - } uniformBuffers; - - struct UboScene { + struct UniformData { glm::mat4 projection; glm::mat4 model; - } uboScene; + } uniformData; + vks::Buffer uniformBuffer; struct PipelineLayouts { - VkPipelineLayout scene; - VkPipelineLayout fullscreen; + VkPipelineLayout scene{ VK_NULL_HANDLE }; + VkPipelineLayout fullscreen{ VK_NULL_HANDLE }; } pipelineLayouts; struct Pipelines { - VkPipeline triangle; - VkPipeline triangleConservativeRaster; - VkPipeline triangleOverlay; - VkPipeline fullscreen; + VkPipeline triangle{ VK_NULL_HANDLE }; + VkPipeline triangleConservativeRaster{ VK_NULL_HANDLE }; + VkPipeline triangleOverlay{ VK_NULL_HANDLE }; + VkPipeline fullscreen{ VK_NULL_HANDLE }; } pipelines; struct DescriptorSetLayouts { - VkDescriptorSetLayout scene; - VkDescriptorSetLayout fullscreen; + VkDescriptorSetLayout scene{ VK_NULL_HANDLE }; + VkDescriptorSetLayout fullscreen{ VK_NULL_HANDLE }; } descriptorSetLayouts; struct DescriptorSets { - VkDescriptorSet scene; - VkDescriptorSet fullscreen; + VkDescriptorSet scene{ VK_NULL_HANDLE }; + VkDescriptorSet fullscreen{ VK_NULL_HANDLE }; } descriptorSets; // Framebuffer for offscreen rendering @@ -81,7 +72,7 @@ public: VkRenderPass renderPass; VkSampler sampler; VkDescriptorImageInfo descriptor; - } offscreenPass; + } offscreenPass{}; VulkanExample() : VulkanExampleBase() { @@ -101,33 +92,33 @@ public: ~VulkanExample() { - // Frame buffer + if (device) { + vkDestroyImageView(device, offscreenPass.color.view, nullptr); + vkDestroyImage(device, offscreenPass.color.image, nullptr); + vkFreeMemory(device, offscreenPass.color.mem, nullptr); + vkDestroyImageView(device, offscreenPass.depth.view, nullptr); + vkDestroyImage(device, offscreenPass.depth.image, nullptr); + vkFreeMemory(device, offscreenPass.depth.mem, nullptr); - vkDestroyImageView(device, offscreenPass.color.view, nullptr); - vkDestroyImage(device, offscreenPass.color.image, nullptr); - vkFreeMemory(device, offscreenPass.color.mem, nullptr); - vkDestroyImageView(device, offscreenPass.depth.view, nullptr); - vkDestroyImage(device, offscreenPass.depth.image, nullptr); - vkFreeMemory(device, offscreenPass.depth.mem, nullptr); + vkDestroyRenderPass(device, offscreenPass.renderPass, nullptr); + vkDestroySampler(device, offscreenPass.sampler, nullptr); + vkDestroyFramebuffer(device, offscreenPass.frameBuffer, nullptr); - vkDestroyRenderPass(device, offscreenPass.renderPass, nullptr); - vkDestroySampler(device, offscreenPass.sampler, nullptr); - vkDestroyFramebuffer(device, offscreenPass.frameBuffer, nullptr); + vkDestroyPipeline(device, pipelines.triangle, nullptr); + vkDestroyPipeline(device, pipelines.triangleOverlay, nullptr); + vkDestroyPipeline(device, pipelines.triangleConservativeRaster, nullptr); + vkDestroyPipeline(device, pipelines.fullscreen, nullptr); - vkDestroyPipeline(device, pipelines.triangle, nullptr); - vkDestroyPipeline(device, pipelines.triangleOverlay, nullptr); - vkDestroyPipeline(device, pipelines.triangleConservativeRaster, nullptr); - vkDestroyPipeline(device, pipelines.fullscreen, nullptr); + vkDestroyPipelineLayout(device, pipelineLayouts.fullscreen, nullptr); + vkDestroyPipelineLayout(device, pipelineLayouts.scene, nullptr); - vkDestroyPipelineLayout(device, pipelineLayouts.fullscreen, nullptr); - vkDestroyPipelineLayout(device, pipelineLayouts.scene, nullptr); + vkDestroyDescriptorSetLayout(device, descriptorSetLayouts.scene, nullptr); + vkDestroyDescriptorSetLayout(device, descriptorSetLayouts.fullscreen, nullptr); - vkDestroyDescriptorSetLayout(device, descriptorSetLayouts.scene, nullptr); - vkDestroyDescriptorSetLayout(device, descriptorSetLayouts.fullscreen, nullptr); - - uniformBuffers.scene.destroy(); - triangle.vertices.destroy(); - triangle.indices.destroy(); + uniformBuffer.destroy(); + triangle.vertices.destroy(); + triangle.indices.destroy(); + } } void getEnabledFeatures() @@ -141,8 +132,13 @@ public: */ void prepareOffscreen() { - offscreenPass.width = width / ZOOM_FACTOR; - offscreenPass.height = height / ZOOM_FACTOR; + // We "magnify" the offscreen rendered triangle so that the conservative rasterization feature is easier to see + const int32_t magnification = 16; + + offscreenPass.width = width / magnification; + offscreenPass.height = height / magnification; + + const VkFormat fbColorFormat = VK_FORMAT_R8G8B8A8_UNORM; // Find a suitable depth format VkFormat fbDepthFormat; @@ -152,7 +148,7 @@ public: // Color attachment VkImageCreateInfo image = vks::initializers::imageCreateInfo(); image.imageType = VK_IMAGE_TYPE_2D; - image.format = FB_COLOR_FORMAT; + image.format = fbColorFormat; image.extent.width = offscreenPass.width; image.extent.height = offscreenPass.height; image.extent.depth = 1; @@ -175,7 +171,7 @@ public: VkImageViewCreateInfo colorImageView = vks::initializers::imageViewCreateInfo(); colorImageView.viewType = VK_IMAGE_VIEW_TYPE_2D; - colorImageView.format = FB_COLOR_FORMAT; + colorImageView.format = fbColorFormat; colorImageView.subresourceRange = {}; colorImageView.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; colorImageView.subresourceRange.baseMipLevel = 0; @@ -228,7 +224,7 @@ public: std::array attchmentDescriptions = {}; // Color attachment - attchmentDescriptions[0].format = FB_COLOR_FORMAT; + attchmentDescriptions[0].format = fbColorFormat; attchmentDescriptions[0].samples = VK_SAMPLE_COUNT_1_BIT; attchmentDescriptions[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; attchmentDescriptions[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE; @@ -457,8 +453,9 @@ public: stagingBuffers.indices.destroy(); } - void setupDescriptorPool() + void setupDescriptors() { + // Pool std::vector poolSizes = { vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 3), vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2) @@ -466,13 +463,10 @@ public: VkDescriptorPoolCreateInfo descriptorPoolInfo = vks::initializers::descriptorPoolCreateInfo(poolSizes, 2); VK_CHECK_RESULT(vkCreateDescriptorPool(device, &descriptorPoolInfo, nullptr, &descriptorPool)); - } - void setupDescriptorSetLayout() - { + // Layouts std::vector setLayoutBindings; VkDescriptorSetLayoutCreateInfo descriptorLayout; - VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo; // Scene rendering setLayoutBindings = { @@ -480,8 +474,6 @@ public: }; descriptorLayout = vks::initializers::descriptorSetLayoutCreateInfo(setLayoutBindings.data(), static_cast(setLayoutBindings.size())); VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorLayout, nullptr, &descriptorSetLayouts.scene)); - pPipelineLayoutCreateInfo = vks::initializers::pipelineLayoutCreateInfo(&descriptorSetLayouts.scene, 1); - VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pPipelineLayoutCreateInfo, nullptr, &pipelineLayouts.scene)); // Fullscreen pass setLayoutBindings = { @@ -489,19 +481,15 @@ public: }; descriptorLayout = vks::initializers::descriptorSetLayoutCreateInfo(setLayoutBindings.data(), static_cast(setLayoutBindings.size())); VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorLayout, nullptr, &descriptorSetLayouts.fullscreen)); - pPipelineLayoutCreateInfo = vks::initializers::pipelineLayoutCreateInfo(&descriptorSetLayouts.fullscreen, 1); - VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pPipelineLayoutCreateInfo, nullptr, &pipelineLayouts.fullscreen)); - } - void setupDescriptorSet() - { + // Sets VkDescriptorSetAllocateInfo descriptorSetAllocInfo; // Scene rendering descriptorSetAllocInfo = vks::initializers::descriptorSetAllocateInfo(descriptorPool, &descriptorSetLayouts.scene, 1); VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &descriptorSetAllocInfo, &descriptorSets.scene)); std::vector offScreenWriteDescriptorSets = { - vks::initializers::writeDescriptorSet(descriptorSets.scene, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &uniformBuffers.scene.descriptor), + vks::initializers::writeDescriptorSet(descriptorSets.scene, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &uniformBuffer.descriptor), }; vkUpdateDescriptorSets(device, static_cast(offScreenWriteDescriptorSets.size()), offScreenWriteDescriptorSets.data(), 0, nullptr); @@ -516,38 +504,25 @@ public: void preparePipelines() { - VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCI = - vks::initializers::pipelineInputAssemblyStateCreateInfo(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0, VK_FALSE); + VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo; + pPipelineLayoutCreateInfo = vks::initializers::pipelineLayoutCreateInfo(&descriptorSetLayouts.scene, 1); + VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pPipelineLayoutCreateInfo, nullptr, &pipelineLayouts.scene)); - VkPipelineColorBlendAttachmentState blendAttachmentState = - vks::initializers::pipelineColorBlendAttachmentState(0xf, VK_FALSE); + pPipelineLayoutCreateInfo = vks::initializers::pipelineLayoutCreateInfo(&descriptorSetLayouts.fullscreen, 1); + VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pPipelineLayoutCreateInfo, nullptr, &pipelineLayouts.fullscreen)); - VkPipelineColorBlendStateCreateInfo colorBlendStateCI = - vks::initializers::pipelineColorBlendStateCreateInfo(1, &blendAttachmentState); - - VkPipelineDepthStencilStateCreateInfo depthStencilStateCI = - vks::initializers::pipelineDepthStencilStateCreateInfo(VK_FALSE, VK_FALSE, VK_COMPARE_OP_LESS_OR_EQUAL); - - VkPipelineViewportStateCreateInfo viewportStateCI = - vks::initializers::pipelineViewportStateCreateInfo(1, 1, 0); - - VkPipelineMultisampleStateCreateInfo multisampleStateCI = - vks::initializers::pipelineMultisampleStateCreateInfo(VK_SAMPLE_COUNT_1_BIT, 0); - - std::vector dynamicStateEnables = { - VK_DYNAMIC_STATE_VIEWPORT, - VK_DYNAMIC_STATE_SCISSOR, - }; - VkPipelineDynamicStateCreateInfo dynamicStateCI = - vks::initializers::pipelineDynamicStateCreateInfo(dynamicStateEnables); + VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCI = vks::initializers::pipelineInputAssemblyStateCreateInfo(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0, VK_FALSE); + VkPipelineColorBlendAttachmentState blendAttachmentState = vks::initializers::pipelineColorBlendAttachmentState(0xf, VK_FALSE); + VkPipelineColorBlendStateCreateInfo colorBlendStateCI = vks::initializers::pipelineColorBlendStateCreateInfo(1, &blendAttachmentState); + VkPipelineDepthStencilStateCreateInfo depthStencilStateCI = vks::initializers::pipelineDepthStencilStateCreateInfo(VK_FALSE, VK_FALSE, VK_COMPARE_OP_LESS_OR_EQUAL); + VkPipelineViewportStateCreateInfo viewportStateCI = vks::initializers::pipelineViewportStateCreateInfo(1, 1, 0); + VkPipelineMultisampleStateCreateInfo multisampleStateCI = vks::initializers::pipelineMultisampleStateCreateInfo(VK_SAMPLE_COUNT_1_BIT, 0); + std::vector dynamicStateEnables = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, }; + VkPipelineDynamicStateCreateInfo dynamicStateCI = vks::initializers::pipelineDynamicStateCreateInfo(dynamicStateEnables); std::array shaderStages; - VkGraphicsPipelineCreateInfo pipelineCreateInfo = - vks::initializers::pipelineCreateInfo(pipelineLayouts.fullscreen, renderPass, 0); - - VkPipelineRasterizationStateCreateInfo rasterizationStateCI = - vks::initializers::pipelineRasterizationStateCreateInfo(VK_POLYGON_MODE_FILL, VK_CULL_MODE_BACK_BIT, VK_FRONT_FACE_CLOCKWISE, 0); + VkPipelineRasterizationStateCreateInfo rasterizationStateCI = vks::initializers::pipelineRasterizationStateCreateInfo(VK_POLYGON_MODE_FILL, VK_CULL_MODE_BACK_BIT, VK_FRONT_FACE_CLOCKWISE, 0); /* Conservative rasterization setup @@ -579,6 +554,7 @@ public: vertexInputState.vertexAttributeDescriptionCount = static_cast(vertexInputAttributes.size()); vertexInputState.pVertexAttributeDescriptions = vertexInputAttributes.data(); + VkGraphicsPipelineCreateInfo pipelineCreateInfo = vks::initializers::pipelineCreateInfo(pipelineLayouts.fullscreen, renderPass, 0); pipelineCreateInfo.pInputAssemblyState = &inputAssemblyStateCI; pipelineCreateInfo.pRasterizationState = &rasterizationStateCI; pipelineCreateInfo.pColorBlendState = &colorBlendStateCI; @@ -643,17 +619,17 @@ public: VK_CHECK_RESULT(vulkanDevice->createBuffer( VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, - &uniformBuffers.scene, - sizeof(uboScene))); - VK_CHECK_RESULT(uniformBuffers.scene.map()); + &uniformBuffer, + sizeof(UniformData))); + VK_CHECK_RESULT(uniformBuffer.map()); updateUniformBuffersScene(); } void updateUniformBuffersScene() { - uboScene.projection = camera.matrices.perspective; - uboScene.model = camera.matrices.view; - memcpy(uniformBuffers.scene.mapped, &uboScene, sizeof(uboScene)); + uniformData.projection = camera.matrices.perspective; + uniformData.model = camera.matrices.view; + memcpy(uniformBuffer.mapped, &uniformData, sizeof(UniformData)); } void draw() @@ -671,10 +647,8 @@ public: loadAssets(); prepareOffscreen(); prepareUniformBuffers(); - setupDescriptorSetLayout(); + setupDescriptors(); preparePipelines(); - setupDescriptorPool(); - setupDescriptorSet(); buildCommandBuffers(); prepared = true; } @@ -683,9 +657,8 @@ public: { if (!prepared) return; + updateUniformBuffersScene(); draw(); - if (camera.updated) - updateUniformBuffersScene(); } virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay) diff --git a/examples/debugprintf/debugprintf.cpp b/examples/debugprintf/debugprintf.cpp index 0345836d..581c4e5b 100644 --- a/examples/debugprintf/debugprintf.cpp +++ b/examples/debugprintf/debugprintf.cpp @@ -49,11 +49,12 @@ public: ~VulkanExample() { - // Note : Inherited destructor cleans up resources stored in base class - vkDestroyPipeline(device, pipeline, nullptr); - vkDestroyPipelineLayout(device, pipelineLayout, nullptr); - vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr); - uniformBuffer.destroy(); + if (device) { + vkDestroyPipeline(device, pipeline, nullptr); + vkDestroyPipelineLayout(device, pipelineLayout, nullptr); + vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr); + uniformBuffer.destroy(); + } } void loadAssets() diff --git a/examples/debugutils/debugutils.cpp b/examples/debugutils/debugutils.cpp index e02fbc59..280c8fda 100644 --- a/examples/debugutils/debugutils.cpp +++ b/examples/debugutils/debugutils.cpp @@ -15,27 +15,16 @@ public: bool wireframe = true; bool glow = true; - struct Scene { - - vkglTF::Model model; - std::vector modelPartNames; - - void loadFromFile(std::string filename, vks::VulkanDevice* vulkanDevice, VkQueue queue) - { - const uint32_t glTFLoadingFlags = vkglTF::FileLoadingFlags::PreTransformVertices | vkglTF::FileLoadingFlags::PreMultiplyVertexColors | vkglTF::FileLoadingFlags::FlipY; - model.loadFromFile(filename, vulkanDevice, queue, glTFLoadingFlags); - } - }; - - Scene scene, sceneGlow; - - vks::Buffer uniformBuffer; + struct Models { + vkglTF::Model scene, sceneGlow; + } models; struct UBOVS { glm::mat4 projection; glm::mat4 model; glm::vec4 lightPos = glm::vec4(0.0f, 5.0f, 15.0f, 1.0f); - } uboVS; + } uniformData; + vks::Buffer uniformBuffer; struct Pipelines { VkPipeline toonshading; @@ -51,7 +40,7 @@ public: // Framebuffer for offscreen rendering struct FrameBufferAttachment { VkImage image; - VkDeviceMemory mem; + VkDeviceMemory memory; VkImageView view; }; struct OffscreenPass { @@ -98,34 +87,34 @@ public: ~VulkanExample() { - // Clean up used Vulkan resources - // Note : Inherited destructor cleans up resources stored in base class - vkDestroyPipeline(device, pipelines.toonshading, nullptr); - vkDestroyPipeline(device, pipelines.color, nullptr); - vkDestroyPipeline(device, pipelines.postprocess, nullptr); - if (pipelines.wireframe != VK_NULL_HANDLE) { - vkDestroyPipeline(device, pipelines.wireframe, nullptr); + if (device) { + vkDestroyPipeline(device, pipelines.toonshading, nullptr); + vkDestroyPipeline(device, pipelines.color, nullptr); + vkDestroyPipeline(device, pipelines.postprocess, nullptr); + if (pipelines.wireframe != VK_NULL_HANDLE) { + vkDestroyPipeline(device, pipelines.wireframe, nullptr); + } + + vkDestroyPipelineLayout(device, pipelineLayout, nullptr); + vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr); + + uniformBuffer.destroy(); + + // Offscreen + // Color attachment + vkDestroyImageView(device, offscreenPass.color.view, nullptr); + vkDestroyImage(device, offscreenPass.color.image, nullptr); + vkFreeMemory(device, offscreenPass.color.memory, nullptr); + + // Depth attachment + vkDestroyImageView(device, offscreenPass.depth.view, nullptr); + vkDestroyImage(device, offscreenPass.depth.image, nullptr); + vkFreeMemory(device, offscreenPass.depth.memory, nullptr); + + vkDestroyRenderPass(device, offscreenPass.renderPass, nullptr); + vkDestroySampler(device, offscreenPass.sampler, nullptr); + vkDestroyFramebuffer(device, offscreenPass.frameBuffer, nullptr); } - - vkDestroyPipelineLayout(device, pipelineLayout, nullptr); - vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr); - - uniformBuffer.destroy(); - - // Offscreen - // Color attachment - vkDestroyImageView(device, offscreenPass.color.view, nullptr); - vkDestroyImage(device, offscreenPass.color.image, nullptr); - vkFreeMemory(device, offscreenPass.color.mem, nullptr); - - // Depth attachment - vkDestroyImageView(device, offscreenPass.depth.view, nullptr); - vkDestroyImage(device, offscreenPass.depth.image, nullptr); - vkFreeMemory(device, offscreenPass.depth.mem, nullptr); - - vkDestroyRenderPass(device, offscreenPass.renderPass, nullptr); - vkDestroySampler(device, offscreenPass.sampler, nullptr); - vkDestroyFramebuffer(device, offscreenPass.frameBuffer, nullptr); } /* @@ -290,8 +279,8 @@ public: vkGetImageMemoryRequirements(device, offscreenPass.color.image, &memReqs); memAlloc.allocationSize = memReqs.size; memAlloc.memoryTypeIndex = vulkanDevice->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - VK_CHECK_RESULT(vkAllocateMemory(device, &memAlloc, nullptr, &offscreenPass.color.mem)); - VK_CHECK_RESULT(vkBindImageMemory(device, offscreenPass.color.image, offscreenPass.color.mem, 0)); + VK_CHECK_RESULT(vkAllocateMemory(device, &memAlloc, nullptr, &offscreenPass.color.memory)); + VK_CHECK_RESULT(vkBindImageMemory(device, offscreenPass.color.image, offscreenPass.color.memory, 0)); VkImageViewCreateInfo colorImageView = vks::initializers::imageViewCreateInfo(); colorImageView.viewType = VK_IMAGE_VIEW_TYPE_2D; @@ -328,8 +317,8 @@ public: vkGetImageMemoryRequirements(device, offscreenPass.depth.image, &memReqs); memAlloc.allocationSize = memReqs.size; memAlloc.memoryTypeIndex = vulkanDevice->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - VK_CHECK_RESULT(vkAllocateMemory(device, &memAlloc, nullptr, &offscreenPass.depth.mem)); - VK_CHECK_RESULT(vkBindImageMemory(device, offscreenPass.depth.image, offscreenPass.depth.mem, 0)); + VK_CHECK_RESULT(vkAllocateMemory(device, &memAlloc, nullptr, &offscreenPass.depth.memory)); + VK_CHECK_RESULT(vkBindImageMemory(device, offscreenPass.depth.image, offscreenPass.depth.memory, 0)); VkImageViewCreateInfo depthStencilView = vks::initializers::imageViewCreateInfo(); depthStencilView.viewType = VK_IMAGE_VIEW_TYPE_2D; @@ -428,18 +417,20 @@ public: void loadAssets() { - scene.loadFromFile(getAssetPath() + "models/treasure_smooth.gltf", vulkanDevice, queue); - sceneGlow.loadFromFile(getAssetPath() + "models/treasure_glow.gltf", vulkanDevice, queue); + const uint32_t glTFLoadingFlags = vkglTF::FileLoadingFlags::PreTransformVertices | vkglTF::FileLoadingFlags::PreMultiplyVertexColors | vkglTF::FileLoadingFlags::FlipY; + models.scene.loadFromFile(getAssetPath() + "models/treasure_smooth.gltf", vulkanDevice, queue, glTFLoadingFlags); + models.sceneGlow.loadFromFile(getAssetPath() + "models/treasure_glow.gltf", vulkanDevice, queue, glTFLoadingFlags); } - void drawScene(Scene& scene, VkCommandBuffer cmdBuffer) + // We use a custom draw function so we can insert debug labels with the names of the glTF nodes + void drawModel(vkglTF::Model &model, VkCommandBuffer cmdBuffer) { - scene.model.bindBuffers(cmdBuffer); - for (auto i = 0; i < scene.model.nodes.size(); i++) + model.bindBuffers(cmdBuffer); + for (auto i = 0; i < model.nodes.size(); i++) { // Insert a label for the current model's name - cmdInsertLabel(cmdBuffer, scene.model.nodes[i]->name.c_str(), { 0.0f, 0.0f, 0.0f, 0.0f }); - scene.model.drawNode(scene.model.nodes[i], cmdBuffer); + cmdInsertLabel(cmdBuffer, model.nodes[i]->name.c_str(), { 0.0f, 0.0f, 0.0f, 0.0f }); + model.drawNode(model.nodes[i], cmdBuffer); } } @@ -482,7 +473,7 @@ public: vkCmdBindDescriptorSets(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, nullptr); vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.color); - drawScene(sceneGlow, drawCmdBuffers[i]); + drawModel(models.sceneGlow, drawCmdBuffers[i]); vkCmdEndRenderPass(drawCmdBuffers[i]); @@ -525,7 +516,7 @@ public: cmdBeginLabel(drawCmdBuffers[i], "Toon shading draw", { 0.78f, 0.74f, 0.9f, 1.0f }); vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.toonshading); - drawScene(scene, drawCmdBuffers[i]); + drawModel(models.scene, drawCmdBuffers[i]); cmdEndLabel(drawCmdBuffers[i]); @@ -538,7 +529,7 @@ public: vkCmdSetScissor(drawCmdBuffers[i], 0, 1, &scissor); vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.wireframe); - drawScene(scene, drawCmdBuffers[i]); + drawModel(models.scene, drawCmdBuffers[i]); cmdEndLabel(drawCmdBuffers[i]); @@ -559,7 +550,9 @@ public: cmdEndLabel(drawCmdBuffers[i]); } + cmdBeginLabel(drawCmdBuffers[i], "UI overlay", { 0.23f, 0.65f, 0.28f, 1.0f }); drawUI(drawCmdBuffers[i]); + cmdEndLabel(drawCmdBuffers[i]); vkCmdEndRenderPass(drawCmdBuffers[i]); @@ -682,10 +675,10 @@ public: setObjectName(device, VK_OBJECT_TYPE_SAMPLER, (uint64_t)offscreenPass.sampler, "Off-screen framebuffer default sampler"); setObjectName(device, VK_OBJECT_TYPE_BUFFER, (uint64_t)uniformBuffer.buffer, "Scene uniform buffer block"); - setObjectName(device, VK_OBJECT_TYPE_BUFFER, (uint64_t)scene.model.vertices.buffer, "Scene vertex buffer"); - setObjectName(device, VK_OBJECT_TYPE_BUFFER, (uint64_t)scene.model.indices.buffer, "Scene index buffer"); - setObjectName(device, VK_OBJECT_TYPE_BUFFER, (uint64_t)sceneGlow.model.vertices.buffer, "Glow vertex buffer"); - setObjectName(device, VK_OBJECT_TYPE_BUFFER, (uint64_t)sceneGlow.model.indices.buffer, "Glow index buffer"); + setObjectName(device, VK_OBJECT_TYPE_BUFFER, (uint64_t)models.scene.vertices.buffer, "Scene vertex buffer"); + setObjectName(device, VK_OBJECT_TYPE_BUFFER, (uint64_t)models.scene.indices.buffer, "Scene index buffer"); + setObjectName(device, VK_OBJECT_TYPE_BUFFER, (uint64_t)models.sceneGlow.vertices.buffer, "Glow vertex buffer"); + setObjectName(device, VK_OBJECT_TYPE_BUFFER, (uint64_t)models.sceneGlow.indices.buffer, "Glow index buffer"); // Shader module count starts at 2 when UI overlay in base class is enabled uint32_t moduleIndex = settings.overlay ? 2 : 0; @@ -716,7 +709,7 @@ public: VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &uniformBuffer, - sizeof(uboVS))); + sizeof(uniformData))); // Map persistent VK_CHECK_RESULT(uniformBuffer.map()); @@ -726,9 +719,9 @@ public: void updateUniformBuffers() { - uboVS.projection = camera.matrices.perspective; - uboVS.model = camera.matrices.view; - memcpy(uniformBuffer.mapped, &uboVS, sizeof(uboVS)); + uniformData.projection = camera.matrices.perspective; + uniformData.model = camera.matrices.view; + memcpy(uniformBuffer.mapped, &uniformData, sizeof(uniformData)); } void draw() @@ -762,20 +755,14 @@ public: { if (!prepared) return; - draw(); - if (camera.updated) - updateUniformBuffers(); - } - - virtual void viewChanged() - { updateUniformBuffers(); + draw(); } virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay) { if (overlay->header("Info")) { - overlay->text("VK_EXT_debug_utils %s", (debugUtilsSupported? "active" : "not present")); + overlay->text("VK_EXT_debug_utils %s", (debugUtilsSupported? "supported" : "not supported")); } if (overlay->header("Settings")) { if (overlay->checkBox("Glow", &glow)) { diff --git a/examples/meshshader/meshshader.cpp b/examples/meshshader/meshshader.cpp index a9fdb95a..f3c944c9 100644 --- a/examples/meshshader/meshshader.cpp +++ b/examples/meshshader/meshshader.cpp @@ -1,7 +1,7 @@ /* - * Vulkan Example - Using mesh shaders + * Vulkan Example - Basic sample for using mesh and task shader to replace the traditional vertex pipeline * - * Copyright (C) 2022 by Sascha Willems - www.saschawillems.de + * Copyright (C) 2022-2023 by Sascha Willems - www.saschawillems.de * * This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) */ @@ -19,14 +19,14 @@ public: } uniformData; vks::Buffer uniformBuffer; - uint32_t indexCount; + uint32_t indexCount{ 0 }; - 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 }; - PFN_vkCmdDrawMeshTasksEXT vkCmdDrawMeshTasksEXT; + PFN_vkCmdDrawMeshTasksEXT vkCmdDrawMeshTasksEXT{ VK_NULL_HANDLE }; VkPhysicalDeviceMeshShaderFeaturesEXT enabledMeshShaderFeatures{}; @@ -39,7 +39,7 @@ public: camera.setRotation(glm::vec3(0.0f, 15.0f, 0.0f)); camera.setTranslation(glm::vec3(0.0f, 0.0f, -5.0f)); - // Extension require at least Vulkan 1.1 + // The mesh shader extension requires at least Vulkan Core 1.1 apiVersion = VK_API_VERSION_1_1; // Extensions required by mesh shading @@ -49,18 +49,8 @@ public: // Required by VK_KHR_spirv_1_4 enabledDeviceExtensions.push_back(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME); - } - ~VulkanExample() - { - vkDestroyPipeline(device, pipeline, nullptr); - vkDestroyPipelineLayout(device, pipelineLayout, nullptr); - vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr); - uniformBuffer.destroy(); - } - - void getEnabledFeatures() - { + // We need to enable the mesh and task shader feature using a new struct introduced with the extension enabledMeshShaderFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_EXT; enabledMeshShaderFeatures.meshShader = VK_TRUE; enabledMeshShaderFeatures.taskShader = VK_TRUE; @@ -68,6 +58,15 @@ public: deviceCreatepNextChain = &enabledMeshShaderFeatures; } + ~VulkanExample() + { + if (device) { + vkDestroyPipeline(device, pipeline, nullptr); + vkDestroyPipelineLayout(device, pipelineLayout, nullptr); + vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr); + uniformBuffer.destroy(); + } + } void buildCommandBuffers() { @@ -103,6 +102,8 @@ public: vkCmdBindDescriptorSets(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, NULL); vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); + + // Use mesh and task shader to draw the scene vkCmdDrawMeshTasksEXT(drawCmdBuffers[i], 1, 1, 1); drawUI(drawCmdBuffers[i]); @@ -158,10 +159,6 @@ public: VkGraphicsPipelineCreateInfo pipelineCI = vks::initializers::pipelineCreateInfo(pipelineLayout, renderPass, 0); - // Mesh shading doesn't require vertex input state - pipelineCI.pInputAssemblyState = nullptr; - pipelineCI.pVertexInputState = nullptr; - pipelineCI.pRasterizationState = &rasterizationState; pipelineCI.pColorBlendState = &colorBlendState; pipelineCI.pMultisampleState = &multisampleState; @@ -171,8 +168,14 @@ public: pipelineCI.stageCount = static_cast(shaderStages.size()); pipelineCI.pStages = shaderStages.data(); + // Not using a vertex shader, mesh shading doesn't require vertex input state + pipelineCI.pInputAssemblyState = nullptr; + pipelineCI.pVertexInputState = nullptr; + + // Instead of a vertex shader, we use a mesh and task shader shaderStages[0] = loadShader(getShadersPath() + "meshshader/meshshader.mesh.spv", VK_SHADER_STAGE_MESH_BIT_EXT); shaderStages[1] = loadShader(getShadersPath() + "meshshader/meshshader.task.spv", VK_SHADER_STAGE_TASK_BIT_EXT); + shaderStages[2] = loadShader(getShadersPath() + "meshshader/meshshader.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipeline)); } @@ -196,11 +199,9 @@ public: void draw() { VulkanExampleBase::prepareFrame(); - submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = &drawCmdBuffers[currentBuffer]; VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE)); - VulkanExampleBase::submitFrame(); } @@ -222,12 +223,8 @@ public: { if (!prepared) return; - draw(); - } - - virtual void viewChanged() - { updateUniformBuffers(); + draw(); } };