Code cleanup, comments

This commit is contained in:
Sascha Willems 2024-01-14 11:11:07 +01:00
parent 51618acc1f
commit 9023421b0e

View file

@ -1,5 +1,8 @@
/* /*
* Vulkan Example - Multisampling using resolve attachments * Vulkan Example - Multisampling using resolve attachments (MSAA)
*
* This sample shows how to do multisampled anti aliasing using built-in hardware via resolve attachments
* These are special attachments that a multi-sampled is resolved to using a fixed sample pattern
* *
* Copyright (C) 2016-2023 by Sascha Willems - www.saschawillems.de * Copyright (C) 2016-2023 by Sascha Willems - www.saschawillems.de
* *
@ -9,19 +12,6 @@
#include "vulkanexamplebase.h" #include "vulkanexamplebase.h"
#include "VulkanglTFModel.h" #include "VulkanglTFModel.h"
struct {
struct {
VkImage image;
VkImageView view;
VkDeviceMemory memory;
} color;
struct {
VkImage image;
VkImageView view;
VkDeviceMemory memory;
} depth;
} multisampleTarget;
class VulkanExample : public VulkanExampleBase class VulkanExample : public VulkanExampleBase
{ {
public: public:
@ -30,23 +20,36 @@ public:
vkglTF::Model model; vkglTF::Model model;
vks::Buffer uniformBuffer; struct UniformData {
struct UBOVS {
glm::mat4 projection; glm::mat4 projection;
glm::mat4 model; glm::mat4 model;
glm::vec4 lightPos = glm::vec4(5.0f, -5.0f, 5.0f, 1.0f); glm::vec4 lightPos = glm::vec4(5.0f, -5.0f, 5.0f, 1.0f);
} uboVS; } uniformData;
vks::Buffer uniformBuffer;
struct { struct {
VkPipeline MSAA; VkPipeline MSAA{ VK_NULL_HANDLE };
VkPipeline MSAASampleShading; VkPipeline MSAASampleShading{ VK_NULL_HANDLE };
} pipelines; } pipelines;
VkPipelineLayout pipelineLayout; VkPipelineLayout pipelineLayout{ VK_NULL_HANDLE };
VkDescriptorSet descriptorSet; VkDescriptorSet descriptorSet{ VK_NULL_HANDLE };
VkDescriptorSetLayout descriptorSetLayout; VkDescriptorSetLayout descriptorSetLayout{ VK_NULL_HANDLE };
VkExtent2D attachmentSize; VkExtent2D attachmentSize{};
// Holds the Vulkan resources required for the final multi sample output target
struct MultiSampleTarget {
struct {
VkImage image{ VK_NULL_HANDLE };
VkImageView view{ VK_NULL_HANDLE };
VkDeviceMemory memory{ VK_NULL_HANDLE };
} color;
struct {
VkImage image{ VK_NULL_HANDLE };
VkImageView view{ VK_NULL_HANDLE };
VkDeviceMemory memory{ VK_NULL_HANDLE };
} depth;
} multisampleTarget;
VulkanExample() : VulkanExampleBase() VulkanExample() : VulkanExampleBase()
{ {
@ -59,23 +62,23 @@ public:
~VulkanExample() ~VulkanExample()
{ {
// Clean up used Vulkan resources if (device) {
// Note : Inherited destructor cleans up resources stored in base class vkDestroyPipeline(device, pipelines.MSAA, nullptr);
vkDestroyPipeline(device, pipelines.MSAA, nullptr); vkDestroyPipeline(device, pipelines.MSAASampleShading, nullptr);
vkDestroyPipeline(device, pipelines.MSAASampleShading, nullptr);
vkDestroyPipelineLayout(device, pipelineLayout, nullptr); vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr); vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
// Destroy MSAA target // Destroy MSAA target
vkDestroyImage(device, multisampleTarget.color.image, nullptr); vkDestroyImage(device, multisampleTarget.color.image, nullptr);
vkDestroyImageView(device, multisampleTarget.color.view, nullptr); vkDestroyImageView(device, multisampleTarget.color.view, nullptr);
vkFreeMemory(device, multisampleTarget.color.memory, nullptr); vkFreeMemory(device, multisampleTarget.color.memory, nullptr);
vkDestroyImage(device, multisampleTarget.depth.image, nullptr); vkDestroyImage(device, multisampleTarget.depth.image, nullptr);
vkDestroyImageView(device, multisampleTarget.depth.view, nullptr); vkDestroyImageView(device, multisampleTarget.depth.view, nullptr);
vkFreeMemory(device, multisampleTarget.depth.memory, nullptr); vkFreeMemory(device, multisampleTarget.depth.memory, nullptr);
uniformBuffer.destroy(); uniformBuffer.destroy();
}
} }
// Enable physical device features required for this example // Enable physical device features required for this example
@ -384,21 +387,17 @@ public:
model.loadFromFile(getAssetPath() + "models/voyager.gltf", vulkanDevice, queue, vkglTF::FileLoadingFlags::PreTransformVertices | vkglTF::FileLoadingFlags::FlipY); model.loadFromFile(getAssetPath() + "models/voyager.gltf", vulkanDevice, queue, vkglTF::FileLoadingFlags::PreTransformVertices | vkglTF::FileLoadingFlags::FlipY);
} }
void setupDescriptorPool() void setupDescriptors()
{ {
// Example uses one ubo and one combined image sampler // Pool
std::vector<VkDescriptorPoolSize> poolSizes = std::vector<VkDescriptorPoolSize> poolSizes = {
{
vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1), vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1),
vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1), vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1),
}; };
VkDescriptorPoolCreateInfo descriptorPoolInfo = vks::initializers::descriptorPoolCreateInfo(poolSizes, 2); VkDescriptorPoolCreateInfo descriptorPoolInfo = vks::initializers::descriptorPoolCreateInfo(poolSizes, 2);
VK_CHECK_RESULT(vkCreateDescriptorPool(device, &descriptorPoolInfo, nullptr, &descriptorPool)); VK_CHECK_RESULT(vkCreateDescriptorPool(device, &descriptorPoolInfo, nullptr, &descriptorPool));
}
void setupDescriptorSetLayout() // Layout
{
const std::vector<VkDescriptorSetLayoutBinding> setLayoutBindings = { const std::vector<VkDescriptorSetLayoutBinding> setLayoutBindings = {
// Binding 0 : Vertex shader uniform buffer // Binding 0 : Vertex shader uniform buffer
vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT, 0), vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT, 0),
@ -406,17 +405,7 @@ public:
VkDescriptorSetLayoutCreateInfo descriptorLayout = vks::initializers::descriptorSetLayoutCreateInfo(setLayoutBindings); VkDescriptorSetLayoutCreateInfo descriptorLayout = vks::initializers::descriptorSetLayoutCreateInfo(setLayoutBindings);
VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorLayout, nullptr, &descriptorSetLayout)); 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) // Set
const std::vector<VkDescriptorSetLayout> setLayouts = {
descriptorSetLayout,
vkglTF::descriptorSetLayoutImage,
};
VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo = vks::initializers::pipelineLayoutCreateInfo(setLayouts.data(), 2);
VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pPipelineLayoutCreateInfo, nullptr, &pipelineLayout));
}
void setupDescriptorSet()
{
VkDescriptorSetAllocateInfo allocInfo = vks::initializers::descriptorSetAllocateInfo(descriptorPool, &descriptorSetLayout, 1); VkDescriptorSetAllocateInfo allocInfo = vks::initializers::descriptorSetAllocateInfo(descriptorPool, &descriptorSetLayout, 1);
VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &descriptorSet)); VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &descriptorSet));
std::vector<VkWriteDescriptorSet> writeDescriptorSets = { std::vector<VkWriteDescriptorSet> writeDescriptorSets = {
@ -428,6 +417,15 @@ public:
void preparePipelines() 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<VkDescriptorSetLayout> setLayouts = {
descriptorSetLayout,
vkglTF::descriptorSetLayoutImage,
};
VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = vks::initializers::pipelineLayoutCreateInfo(setLayouts.data(), 2);
VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pipelineLayoutCreateInfo, nullptr, &pipelineLayout));
// Pipeline
VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = vks::initializers::pipelineInputAssemblyStateCreateInfo(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0, VK_FALSE); 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_BACK_BIT, VK_FRONT_FACE_COUNTER_CLOCKWISE, 0); VkPipelineRasterizationStateCreateInfo rasterizationState = 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); VkPipelineColorBlendAttachmentState blendAttachmentState = vks::initializers::pipelineColorBlendAttachmentState(0xf, VK_FALSE);
@ -479,32 +477,16 @@ public:
void prepareUniformBuffers() void prepareUniformBuffers()
{ {
// Vertex shader uniform buffer block // Vertex shader uniform buffer block
VK_CHECK_RESULT(vulkanDevice->createBuffer( 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)));
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
&uniformBuffer,
sizeof(uboVS)));
// Map persistent // Map persistent
VK_CHECK_RESULT(uniformBuffer.map()); VK_CHECK_RESULT(uniformBuffer.map());
updateUniformBuffers();
} }
void updateUniformBuffers() void updateUniformBuffers()
{ {
uboVS.projection = camera.matrices.perspective; uniformData.projection = camera.matrices.perspective;
uboVS.model = camera.matrices.view; uniformData.model = camera.matrices.view;
memcpy(uniformBuffer.mapped, &uboVS, sizeof(uboVS)); memcpy(uniformBuffer.mapped, &uniformData, sizeof(UniformData));
}
void draw()
{
VulkanExampleBase::prepareFrame();
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &drawCmdBuffers[currentBuffer];
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE));
VulkanExampleBase::submitFrame();
} }
// Select the highest sample count usable by the platform // Select the highest sample count usable by the platform
@ -530,27 +512,27 @@ public:
VulkanExampleBase::prepare(); VulkanExampleBase::prepare();
loadAssets(); loadAssets();
prepareUniformBuffers(); prepareUniformBuffers();
setupDescriptorSetLayout(); setupDescriptors();
preparePipelines(); preparePipelines();
setupDescriptorPool();
setupDescriptorSet();
buildCommandBuffers(); buildCommandBuffers();
prepared = true; 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() virtual void render()
{ {
if (!prepared) if (!prepared)
return; return;
draw();
if (camera.updated) {
updateUniformBuffers();
}
}
virtual void viewChanged()
{
updateUniformBuffers(); updateUniformBuffers();
draw();
} }
virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay) virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay)