diff --git a/examples/dynamicuniformbuffer/dynamicuniformbuffer.cpp b/examples/dynamicuniformbuffer/dynamicuniformbuffer.cpp index 8695d733..83870995 100644 --- a/examples/dynamicuniformbuffer/dynamicuniformbuffer.cpp +++ b/examples/dynamicuniformbuffer/dynamicuniformbuffer.cpp @@ -1,7 +1,7 @@ /* * Vulkan Example - Dynamic uniform buffers * -* Copyright (C) 2016 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) * @@ -54,15 +54,9 @@ void alignedFree(void* data) class VulkanExample : public VulkanExampleBase { public: - struct { - VkPipelineVertexInputStateCreateInfo inputState; - std::vector bindingDescriptions; - std::vector attributeDescriptions; - } vertices; - vks::Buffer vertexBuffer; vks::Buffer indexBuffer; - uint32_t indexCount; + uint32_t indexCount{ 0 }; struct { vks::Buffer view; @@ -81,17 +75,17 @@ public: // One big uniform buffer that contains all matrices // Note that we need to manually allocate the data to cope for GPU-specific uniform buffer offset alignments struct UboDataDynamic { - glm::mat4 *model = nullptr; + glm::mat4* model{ nullptr }; } uboDataDynamic; - 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 }; - float animationTimer = 0.0f; + float animationTimer{ 0.0f }; - size_t dynamicAlignment; + size_t dynamicAlignment{ 0 }; VulkanExample() : VulkanExampleBase() { @@ -104,22 +98,18 @@ public: ~VulkanExample() { - if (uboDataDynamic.model) { - alignedFree(uboDataDynamic.model); + if (device) { + if (uboDataDynamic.model) { + alignedFree(uboDataDynamic.model); + } + vkDestroyPipeline(device, pipeline, nullptr); + vkDestroyPipelineLayout(device, pipelineLayout, nullptr); + vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr); + vertexBuffer.destroy(); + indexBuffer.destroy(); + uniformBuffers.view.destroy(); + uniformBuffers.dynamic.destroy(); } - - // Clean up used Vulkan resources - // Note : Inherited destructor cleans up resources stored in base class - vkDestroyPipeline(device, pipeline, nullptr); - - vkDestroyPipelineLayout(device, pipelineLayout, nullptr); - vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr); - - vertexBuffer.destroy(); - indexBuffer.destroy(); - - uniformBuffers.view.destroy(); - uniformBuffers.dynamic.destroy(); } void buildCommandBuffers() @@ -178,20 +168,6 @@ public: } } - void draw() - { - VulkanExampleBase::prepareFrame(); - - // Command buffer to be submitted to the queue - submitInfo.commandBufferCount = 1; - submitInfo.pCommandBuffers = &drawCmdBuffers[currentBuffer]; - - // Submit to queue - VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE)); - - VulkanExampleBase::submitFrame(); - } - void generateCube() { // Setup vertices indices for a colored cube @@ -229,150 +205,78 @@ public: indices.size() * sizeof(uint32_t), indices.data())); } - - void setupVertexDescriptions() + void setupDescriptors() { - // Binding description - vertices.bindingDescriptions = { - vks::initializers::vertexInputBindingDescription(VERTEX_BUFFER_BIND_ID, sizeof(Vertex), VK_VERTEX_INPUT_RATE_VERTEX), - }; - - // Attribute descriptions - vertices.attributeDescriptions = { - vks::initializers::vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(Vertex, pos)), // Location 0 : Position - vks::initializers::vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 1, VK_FORMAT_R32G32B32_SFLOAT, offsetof(Vertex, color)), // Location 1 : Color - }; - - vertices.inputState = vks::initializers::pipelineVertexInputStateCreateInfo(); - vertices.inputState.vertexBindingDescriptionCount = static_cast(vertices.bindingDescriptions.size()); - vertices.inputState.pVertexBindingDescriptions = vertices.bindingDescriptions.data(); - vertices.inputState.vertexAttributeDescriptionCount = static_cast(vertices.attributeDescriptions.size()); - vertices.inputState.pVertexAttributeDescriptions = vertices.attributeDescriptions.data(); - } - - void setupDescriptorPool() - { - // Example uses one ubo and one image sampler - std::vector poolSizes = - { + // Pool + std::vector poolSizes = { vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1), + // Dynamic uniform buffer vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1) }; - VkDescriptorPoolCreateInfo descriptorPoolInfo = - vks::initializers::descriptorPoolCreateInfo( - static_cast(poolSizes.size()), - poolSizes.data(), - 2); - + VkDescriptorPoolCreateInfo descriptorPoolInfo = vks::initializers::descriptorPoolCreateInfo(poolSizes, 2); VK_CHECK_RESULT(vkCreateDescriptorPool(device, &descriptorPoolInfo, nullptr, &descriptorPool)); - } - void setupDescriptorSetLayout() - { - std::vector setLayoutBindings = - { + // Layout + std::vector setLayoutBindings = { vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT, 0), + // Dynamic uniform buffer vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, VK_SHADER_STAGE_VERTEX_BIT, 1) }; - VkDescriptorSetLayoutCreateInfo descriptorLayout = - vks::initializers::descriptorSetLayoutCreateInfo( - setLayoutBindings.data(), - static_cast(setLayoutBindings.size())); - + VkDescriptorSetLayoutCreateInfo descriptorLayout = vks::initializers::descriptorSetLayoutCreateInfo(setLayoutBindings); VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorLayout, nullptr, &descriptorSetLayout)); - VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo = - vks::initializers::pipelineLayoutCreateInfo( - &descriptorSetLayout, - 1); - - VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pPipelineLayoutCreateInfo, nullptr, &pipelineLayout)); - } - - void setupDescriptorSet() - { - VkDescriptorSetAllocateInfo allocInfo = - vks::initializers::descriptorSetAllocateInfo( - descriptorPool, - &descriptorSetLayout, - 1); - + // Set + VkDescriptorSetAllocateInfo allocInfo = vks::initializers::descriptorSetAllocateInfo(descriptorPool, &descriptorSetLayout, 1); VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &descriptorSet)); std::vector writeDescriptorSets = { - // Binding 0 : Projection/View matrix uniform buffer + // Binding 0 : Projection/View matrix as uniform buffer vks::initializers::writeDescriptorSet(descriptorSet, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &uniformBuffers.view.descriptor), // Binding 1 : Instance matrix as dynamic uniform buffer vks::initializers::writeDescriptorSet(descriptorSet, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, &uniformBuffers.dynamic.descriptor), }; - - vkUpdateDescriptorSets(device, static_cast(writeDescriptorSets.size()), writeDescriptorSets.data(), 0, NULL); + vkUpdateDescriptorSets(device, static_cast(writeDescriptorSets.size()), writeDescriptorSets.data(), 0, nullptr); } void preparePipelines() { - VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = - vks::initializers::pipelineInputAssemblyStateCreateInfo( - VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, - 0, - VK_FALSE); + // Layout + VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = vks::initializers::pipelineLayoutCreateInfo(&descriptorSetLayout, 1); + VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pipelineLayoutCreateInfo, nullptr, &pipelineLayout)); - 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); - - VkPipelineColorBlendStateCreateInfo colorBlendState = - vks::initializers::pipelineColorBlendStateCreateInfo( - 1, - &blendAttachmentState); - - VkPipelineDepthStencilStateCreateInfo depthStencilState = - vks::initializers::pipelineDepthStencilStateCreateInfo( - VK_TRUE, - VK_TRUE, - VK_COMPARE_OP_LESS_OR_EQUAL); - - VkPipelineViewportStateCreateInfo viewportState = - vks::initializers::pipelineViewportStateCreateInfo(1, 1, 0); - - VkPipelineMultisampleStateCreateInfo multisampleState = - vks::initializers::pipelineMultisampleStateCreateInfo( - VK_SAMPLE_COUNT_1_BIT, - 0); - - std::vector dynamicStateEnables = { - VK_DYNAMIC_STATE_VIEWPORT, - VK_DYNAMIC_STATE_SCISSOR - }; - VkPipelineDynamicStateCreateInfo dynamicState = - vks::initializers::pipelineDynamicStateCreateInfo( - dynamicStateEnables.data(), - static_cast(dynamicStateEnables.size()), - 0); - - // Load shaders + // 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); + VkPipelineColorBlendStateCreateInfo colorBlendState = vks::initializers::pipelineColorBlendStateCreateInfo(1, &blendAttachmentState); + VkPipelineDepthStencilStateCreateInfo depthStencilState = vks::initializers::pipelineDepthStencilStateCreateInfo(VK_TRUE, VK_TRUE, VK_COMPARE_OP_LESS_OR_EQUAL); + VkPipelineViewportStateCreateInfo viewportState = vks::initializers::pipelineViewportStateCreateInfo(1, 1, 0); + VkPipelineMultisampleStateCreateInfo multisampleState = vks::initializers::pipelineMultisampleStateCreateInfo(VK_SAMPLE_COUNT_1_BIT, 0); + std::vector dynamicStateEnables = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; + VkPipelineDynamicStateCreateInfo dynamicState = vks::initializers::pipelineDynamicStateCreateInfo(dynamicStateEnables); std::array shaderStages; + // Vertex bindings and attributes + VkVertexInputBindingDescription vertexInputBinding = { + vks::initializers::vertexInputBindingDescription(VERTEX_BUFFER_BIND_ID, sizeof(Vertex), VK_VERTEX_INPUT_RATE_VERTEX) + }; + std::vector vertexInputAttributes = { + vks::initializers::vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(Vertex, pos)), // Location 0 : Position + vks::initializers::vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 1, VK_FORMAT_R32G32B32_SFLOAT, offsetof(Vertex, color)), // Location 1 : Color + }; + VkPipelineVertexInputStateCreateInfo vertexInputStateCI = vks::initializers::pipelineVertexInputStateCreateInfo(); + vertexInputStateCI.vertexBindingDescriptionCount = 1; + vertexInputStateCI.pVertexBindingDescriptions = &vertexInputBinding; + vertexInputStateCI.vertexAttributeDescriptionCount = static_cast(vertexInputAttributes.size()); + vertexInputStateCI.pVertexAttributeDescriptions = vertexInputAttributes.data(); + shaderStages[0] = loadShader(getShadersPath() + "dynamicuniformbuffer/base.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); shaderStages[1] = loadShader(getShadersPath() + "dynamicuniformbuffer/base.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); - VkGraphicsPipelineCreateInfo pipelineCreateInfo = - vks::initializers::pipelineCreateInfo( - pipelineLayout, - renderPass, - 0); - - pipelineCreateInfo.pVertexInputState = &vertices.inputState; + VkGraphicsPipelineCreateInfo pipelineCreateInfo = vks::initializers::pipelineCreateInfo(pipelineLayout, renderPass, 0); + pipelineCreateInfo.pVertexInputState = &vertexInputStateCI; pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState; pipelineCreateInfo.pRasterizationState = &rasterizationState; pipelineCreateInfo.pColorBlendState = &colorBlendState; @@ -382,7 +286,6 @@ public: pipelineCreateInfo.pDynamicState = &dynamicState; pipelineCreateInfo.stageCount = static_cast(shaderStages.size()); pipelineCreateInfo.pStages = shaderStages.data(); - VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipeline)); } @@ -439,7 +342,7 @@ public: } updateUniformBuffers(); - updateDynamicUniformBuffer(true); + updateDynamicUniformBuffer(); } void updateUniformBuffers() @@ -451,11 +354,11 @@ public: memcpy(uniformBuffers.view.mapped, &uboVS, sizeof(uboVS)); } - void updateDynamicUniformBuffer(bool force = false) + void updateDynamicUniformBuffer() { // Update at max. 60 fps - animationTimer += frameTimer; - if ((animationTimer <= 1.0f / 60.0f) && (!force)) { + animationTimer += frameTimer; + if (animationTimer <= 1.0f / 60.0f) { return; } @@ -501,28 +404,29 @@ public: { VulkanExampleBase::prepare(); generateCube(); - setupVertexDescriptions(); 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(); - if (!paused) - updateDynamicUniformBuffer(); - } - - virtual void viewChanged() - { updateUniformBuffers(); + updateDynamicUniformBuffer(); + draw(); } }; diff --git a/examples/inputattachments/inputattachments.cpp b/examples/inputattachments/inputattachments.cpp index ec651d3f..434db6a1 100644 --- a/examples/inputattachments/inputattachments.cpp +++ b/examples/inputattachments/inputattachments.cpp @@ -36,36 +36,36 @@ public: } uniformBuffers; struct { - VkPipeline attachmentWrite; - VkPipeline attachmentRead; + VkPipeline attachmentWrite{ VK_NULL_HANDLE }; + VkPipeline attachmentRead{ VK_NULL_HANDLE }; } pipelines; struct { - VkPipelineLayout attachmentWrite; - VkPipelineLayout attachmentRead; + VkPipelineLayout attachmentWrite{ VK_NULL_HANDLE }; + VkPipelineLayout attachmentRead{ VK_NULL_HANDLE }; } pipelineLayouts; struct { - VkDescriptorSet attachmentWrite; - std::vector attachmentRead; + VkDescriptorSet attachmentWrite{ VK_NULL_HANDLE }; + std::vector attachmentRead{ VK_NULL_HANDLE }; } descriptorSets; struct { - VkDescriptorSetLayout attachmentWrite; - VkDescriptorSetLayout attachmentRead; + VkDescriptorSetLayout attachmentWrite{ VK_NULL_HANDLE }; + VkDescriptorSetLayout attachmentRead{ VK_NULL_HANDLE }; } descriptorSetLayouts; struct FrameBufferAttachment { - VkImage image = VK_NULL_HANDLE; - VkDeviceMemory memory = VK_NULL_HANDLE; - VkImageView view = VK_NULL_HANDLE; + VkImage image{ VK_NULL_HANDLE }; + VkDeviceMemory memory{ VK_NULL_HANDLE }; + VkImageView view{ VK_NULL_HANDLE }; VkFormat format; }; struct Attachments { FrameBufferAttachment color, depth; }; std::vector attachments; - VkExtent2D attachmentSize; + VkExtent2D attachmentSize{}; const VkFormat colorFormat = VK_FORMAT_R8G8B8A8_UNORM; @@ -82,29 +82,28 @@ public: ~VulkanExample() { - // Clean up used Vulkan resources - // Note : Inherited destructor cleans up resources stored in base class + if (device) { + for (uint32_t i = 0; i < attachments.size(); i++) { + vkDestroyImageView(device, attachments[i].color.view, nullptr); + vkDestroyImage(device, attachments[i].color.image, nullptr); + vkFreeMemory(device, attachments[i].color.memory, nullptr); + vkDestroyImageView(device, attachments[i].depth.view, nullptr); + vkDestroyImage(device, attachments[i].depth.image, nullptr); + vkFreeMemory(device, attachments[i].depth.memory, nullptr); + } - for (uint32_t i = 0; i < attachments.size(); i++) { - vkDestroyImageView(device, attachments[i].color.view, nullptr); - vkDestroyImage(device, attachments[i].color.image, nullptr); - vkFreeMemory(device, attachments[i].color.memory, nullptr); - vkDestroyImageView(device, attachments[i].depth.view, nullptr); - vkDestroyImage(device, attachments[i].depth.image, nullptr); - vkFreeMemory(device, attachments[i].depth.memory, nullptr); + vkDestroyPipeline(device, pipelines.attachmentRead, nullptr); + vkDestroyPipeline(device, pipelines.attachmentWrite, nullptr); + + vkDestroyPipelineLayout(device, pipelineLayouts.attachmentWrite, nullptr); + vkDestroyPipelineLayout(device, pipelineLayouts.attachmentRead, nullptr); + + vkDestroyDescriptorSetLayout(device, descriptorSetLayouts.attachmentWrite, nullptr); + vkDestroyDescriptorSetLayout(device, descriptorSetLayouts.attachmentRead, nullptr); + + uniformBuffers.matrices.destroy(); + uniformBuffers.params.destroy(); } - - vkDestroyPipeline(device, pipelines.attachmentRead, nullptr); - vkDestroyPipeline(device, pipelines.attachmentWrite, nullptr); - - vkDestroyPipelineLayout(device, pipelineLayouts.attachmentWrite, nullptr); - vkDestroyPipelineLayout(device, pipelineLayouts.attachmentRead, nullptr); - - vkDestroyDescriptorSetLayout(device, descriptorSetLayouts.attachmentWrite, nullptr); - vkDestroyDescriptorSetLayout(device, descriptorSetLayouts.attachmentRead, nullptr); - - uniformBuffers.matrices.destroy(); - uniformBuffers.params.destroy(); } void clearAttachment(FrameBufferAttachment* attachment) @@ -596,15 +595,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/instancing/instancing.cpp b/examples/instancing/instancing.cpp index bb625688..bbdd41d1 100644 --- a/examples/instancing/instancing.cpp +++ b/examples/instancing/instancing.cpp @@ -24,51 +24,48 @@ public: struct { vks::Texture2DArray rocks; vks::Texture2D planet; - } textures; + } textures{}; struct { vkglTF::Model rock; vkglTF::Model planet; - } models; + } models{}; - // Per-instance data block + // We provide position, rotation and scale per mesh instance struct InstanceData { glm::vec3 pos; glm::vec3 rot; - float scale; - uint32_t texIndex; + float scale{ 0.0f }; + uint32_t texIndex{ 0 }; }; // Contains the instanced data struct InstanceBuffer { - VkBuffer buffer = VK_NULL_HANDLE; - VkDeviceMemory memory = VK_NULL_HANDLE; + VkBuffer buffer{ VK_NULL_HANDLE }; + VkDeviceMemory memory{ VK_NULL_HANDLE }; size_t size = 0; - VkDescriptorBufferInfo descriptor; + VkDescriptorBufferInfo descriptor{ VK_NULL_HANDLE }; } instanceBuffer; - struct UBOVS { + struct UniformData { glm::mat4 projection; glm::mat4 view; glm::vec4 lightPos = glm::vec4(0.0f, -5.0f, 0.0f, 1.0f); float locSpeed = 0.0f; float globSpeed = 0.0f; - } uboVS; + } uniformData; + vks::Buffer uniformBuffer; + VkPipelineLayout pipelineLayout{ VK_NULL_HANDLE }; struct { - vks::Buffer scene; - } uniformBuffers; - - VkPipelineLayout pipelineLayout; - struct { - VkPipeline instancedRocks; - VkPipeline planet; - VkPipeline starfield; + VkPipeline instancedRocks{ VK_NULL_HANDLE }; + VkPipeline planet{ VK_NULL_HANDLE }; + VkPipeline starfield{ VK_NULL_HANDLE }; } pipelines; - VkDescriptorSetLayout descriptorSetLayout; + VkDescriptorSetLayout descriptorSetLayout{ VK_NULL_HANDLE }; struct { - VkDescriptorSet instancedRocks; - VkDescriptorSet planet; + VkDescriptorSet instancedRocks{ VK_NULL_HANDLE }; + VkDescriptorSet planet{ VK_NULL_HANDLE }; } descriptorSets; VulkanExample() : VulkanExampleBase() @@ -82,16 +79,18 @@ public: ~VulkanExample() { - vkDestroyPipeline(device, pipelines.instancedRocks, nullptr); - vkDestroyPipeline(device, pipelines.planet, nullptr); - vkDestroyPipeline(device, pipelines.starfield, nullptr); - vkDestroyPipelineLayout(device, pipelineLayout, nullptr); - vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr); - vkDestroyBuffer(device, instanceBuffer.buffer, nullptr); - vkFreeMemory(device, instanceBuffer.memory, nullptr); - textures.rocks.destroy(); - textures.planet.destroy(); - uniformBuffers.scene.destroy(); + if (device) { + vkDestroyPipeline(device, pipelines.instancedRocks, nullptr); + vkDestroyPipeline(device, pipelines.planet, nullptr); + vkDestroyPipeline(device, pipelines.starfield, nullptr); + vkDestroyPipelineLayout(device, pipelineLayout, nullptr); + vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr); + vkDestroyBuffer(device, instanceBuffer.buffer, nullptr); + vkFreeMemory(device, instanceBuffer.memory, nullptr); + textures.rocks.destroy(); + textures.planet.destroy(); + uniformBuffer.destroy(); + } } // Enable physical device features required for this example @@ -176,62 +175,60 @@ public: textures.rocks.loadFromFile(getAssetPath() + "textures/texturearray_rocks_rgba.ktx", VK_FORMAT_R8G8B8A8_UNORM, vulkanDevice, queue); } - void setupDescriptorPool() + void setupDescriptors() { - // Example uses one ubo - std::vector poolSizes = - { + // Pool + std::vector poolSizes = { vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2), vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2), }; - VkDescriptorPoolCreateInfo descriptorPoolInfo = vks::initializers::descriptorPoolCreateInfo(poolSizes, 2); VK_CHECK_RESULT(vkCreateDescriptorPool(device, &descriptorPoolInfo, nullptr, &descriptorPool)); - } - void setupDescriptorSetLayout() - { + // Layout std::vector setLayoutBindings = { // Binding 0 : Vertex shader uniform buffer vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT, 0), // Binding 1 : Fragment shader combined sampler vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT, 1), }; - VkDescriptorSetLayoutCreateInfo descriptorLayout = - vks::initializers::descriptorSetLayoutCreateInfo(setLayoutBindings); + VkDescriptorSetLayoutCreateInfo descriptorLayout = vks::initializers::descriptorSetLayoutCreateInfo(setLayoutBindings); VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorLayout, nullptr, &descriptorSetLayout)); - VkPipelineLayoutCreateInfo pipelineLayoutCI = vks::initializers::pipelineLayoutCreateInfo(&descriptorSetLayout, 1); - VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pipelineLayoutCI, nullptr, &pipelineLayout)); - } - - void setupDescriptorSet() - { + // Sets VkDescriptorSetAllocateInfo descripotrSetAllocInfo; std::vector writeDescriptorSets; - descripotrSetAllocInfo = vks::initializers::descriptorSetAllocateInfo(descriptorPool, &descriptorSetLayout, 1);; + descripotrSetAllocInfo = vks::initializers::descriptorSetAllocateInfo(descriptorPool, &descriptorSetLayout, 1); // Instanced rocks + // Binding 0 : Vertex shader uniform buffer + // Binding 1 : Color map VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &descripotrSetAllocInfo, &descriptorSets.instancedRocks)); writeDescriptorSets = { - vks::initializers::writeDescriptorSet(descriptorSets.instancedRocks, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &uniformBuffers.scene.descriptor), // Binding 0 : Vertex shader uniform buffer - vks::initializers::writeDescriptorSet(descriptorSets.instancedRocks, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, &textures.rocks.descriptor) // Binding 1 : Color map + vks::initializers::writeDescriptorSet(descriptorSets.instancedRocks, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &uniformBuffer.descriptor), + vks::initializers::writeDescriptorSet(descriptorSets.instancedRocks, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, &textures.rocks.descriptor) }; vkUpdateDescriptorSets(device, static_cast(writeDescriptorSets.size()), writeDescriptorSets.data(), 0, nullptr); // Planet + // Binding 0 : Vertex shader uniform buffer + // Binding 1 : Color map VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &descripotrSetAllocInfo, &descriptorSets.planet)); writeDescriptorSets = { - vks::initializers::writeDescriptorSet(descriptorSets.planet, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &uniformBuffers.scene.descriptor), // Binding 0 : Vertex shader uniform buffer - vks::initializers::writeDescriptorSet(descriptorSets.planet, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, &textures.planet.descriptor) // Binding 1 : Color map + vks::initializers::writeDescriptorSet(descriptorSets.planet, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &uniformBuffer.descriptor), + vks::initializers::writeDescriptorSet(descriptorSets.planet, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, &textures.planet.descriptor) }; vkUpdateDescriptorSets(device, static_cast(writeDescriptorSets.size()), writeDescriptorSets.data(), 0, nullptr); - } void preparePipelines() { + // Layout + VkPipelineLayoutCreateInfo pipelineLayoutCI = vks::initializers::pipelineLayoutCreateInfo(&descriptorSetLayout, 1); + VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pipelineLayoutCI, nullptr, &pipelineLayout)); + + // Pipelines 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); VkPipelineColorBlendAttachmentState blendAttachmentState = vks::initializers::pipelineColorBlendAttachmentState(0xf, VK_FALSE); @@ -282,7 +279,7 @@ public: vks::initializers::vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 2, VK_FORMAT_R32G32_SFLOAT, sizeof(float) * 6), // Location 2: Texture coordinates vks::initializers::vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 3, VK_FORMAT_R32G32B32_SFLOAT, sizeof(float) * 8), // Location 3: Color // Per-Instance attributes - // These are fetched for each instance rendered + // These are advanced for each instance rendered vks::initializers::vertexInputAttributeDescription(INSTANCE_BUFFER_BIND_ID, 4, VK_FORMAT_R32G32B32_SFLOAT, 0), // Location 4: Position vks::initializers::vertexInputAttributeDescription(INSTANCE_BUFFER_BIND_ID, 5, VK_FORMAT_R32G32B32_SFLOAT, sizeof(float) * 3), // Location 5: Rotation vks::initializers::vertexInputAttributeDescription(INSTANCE_BUFFER_BIND_ID, 6, VK_FORMAT_R32_SFLOAT,sizeof(float) * 6), // Location 6: Scale @@ -320,6 +317,7 @@ public: VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.starfield)); } + // Create a buffer with per-instance data that is sourced in the shaders void prepareInstanceData() { std::vector instanceData; @@ -406,47 +404,23 @@ public: void prepareUniformBuffers() { - 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(uboVS))); + 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_CHECK_RESULT(uniformBuffer.map()); - // Map persistent - VK_CHECK_RESULT(uniformBuffers.scene.map()); - - updateUniformBuffer(true); + updateUniformBuffer(); } - void updateUniformBuffer(bool viewChanged) + void updateUniformBuffer() { - if (viewChanged) - { - uboVS.projection = camera.matrices.perspective; - uboVS.view = camera.matrices.view; + uniformData.projection = camera.matrices.perspective; + uniformData.view = camera.matrices.view; + + if (!paused) { + uniformData.locSpeed += frameTimer * 0.35f; + uniformData.globSpeed += frameTimer * 0.01f; } - if (!paused) - { - uboVS.locSpeed += frameTimer * 0.35f; - uboVS.globSpeed += frameTimer * 0.01f; - } - - memcpy(uniformBuffers.scene.mapped, &uboVS, sizeof(uboVS)); - } - - void draw() - { - VulkanExampleBase::prepareFrame(); - - // Command buffer to be sumitted to the queue - submitInfo.commandBufferCount = 1; - submitInfo.pCommandBuffers = &drawCmdBuffers[currentBuffer]; - - // Submit to queue - VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE)); - - VulkanExampleBase::submitFrame(); + memcpy(uniformBuffer.mapped, &uniformData, sizeof(uniformData)); } void prepare() @@ -455,30 +429,29 @@ public: loadAssets(); prepareInstanceData(); 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; } + updateUniformBuffer(); draw(); - if ((!paused) || (camera.updated)) - { - updateUniformBuffer(camera.updated); - } - } - - virtual void viewChanged() - { - updateUniformBuffer(true); } virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay) diff --git a/examples/multiview/multiview.cpp b/examples/multiview/multiview.cpp index 7b9fd6db..97cf6fcc 100644 --- a/examples/multiview/multiview.cpp +++ b/examples/multiview/multiview.cpp @@ -16,36 +16,35 @@ class VulkanExample : public VulkanExampleBase public: struct MultiviewPass { struct FrameBufferAttachment { - VkImage image; - VkDeviceMemory memory; - VkImageView view; + VkImage image{ VK_NULL_HANDLE }; + VkDeviceMemory memory{ VK_NULL_HANDLE }; + VkImageView view{ VK_NULL_HANDLE }; } color, depth; - VkFramebuffer frameBuffer; - VkRenderPass renderPass; - VkDescriptorImageInfo descriptor; - VkSampler sampler; - VkSemaphore semaphore; - std::vector commandBuffers; - std::vector waitFences; + VkFramebuffer frameBuffer{ VK_NULL_HANDLE }; + VkRenderPass renderPass{ VK_NULL_HANDLE }; + VkDescriptorImageInfo descriptor{ VK_NULL_HANDLE }; + VkSampler sampler{ VK_NULL_HANDLE }; + VkSemaphore semaphore{ VK_NULL_HANDLE }; + std::vector commandBuffers{}; + std::vector waitFences{}; } multiviewPass; vkglTF::Model scene; - struct UBO { + struct UniformData { glm::mat4 projection[2]; glm::mat4 modelview[2]; glm::vec4 lightPos = glm::vec4(-2.5f, -3.5f, 0.0f, 1.0f); float distortionAlpha = 0.2f; - } ubo; - + } 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 }; - VkPipeline viewDisplayPipelines[2]; + VkPipeline viewDisplayPipelines[2]{}; VkPhysicalDeviceMultiviewFeaturesKHR physicalDeviceMultiviewFeatures{}; @@ -78,35 +77,29 @@ public: ~VulkanExample() { - vkDestroyPipeline(device, pipeline, nullptr); - - vkDestroyPipelineLayout(device, pipelineLayout, nullptr); - vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr); - - // Multiview pass - - vkDestroyImageView(device, multiviewPass.color.view, nullptr); - vkDestroyImage(device, multiviewPass.color.image, nullptr); - vkFreeMemory(device, multiviewPass.color.memory, nullptr); - vkDestroyImageView(device, multiviewPass.depth.view, nullptr); - vkDestroyImage(device, multiviewPass.depth.image, nullptr); - vkFreeMemory(device, multiviewPass.depth.memory, nullptr); - - vkDestroyRenderPass(device, multiviewPass.renderPass, nullptr); - vkDestroySampler(device, multiviewPass.sampler, nullptr); - vkDestroyFramebuffer(device, multiviewPass.frameBuffer, nullptr); - - vkFreeCommandBuffers(device, cmdPool, static_cast(multiviewPass.commandBuffers.size()), multiviewPass.commandBuffers.data()); - vkDestroySemaphore(device, multiviewPass.semaphore, nullptr); - for (auto& fence : multiviewPass.waitFences) { - vkDestroyFence(device, fence, nullptr); - } - - for (auto& pipeline : viewDisplayPipelines) { + if (device) { vkDestroyPipeline(device, pipeline, nullptr); + vkDestroyPipelineLayout(device, pipelineLayout, nullptr); + vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr); + vkDestroyImageView(device, multiviewPass.color.view, nullptr); + vkDestroyImage(device, multiviewPass.color.image, nullptr); + vkFreeMemory(device, multiviewPass.color.memory, nullptr); + vkDestroyImageView(device, multiviewPass.depth.view, nullptr); + vkDestroyImage(device, multiviewPass.depth.image, nullptr); + vkFreeMemory(device, multiviewPass.depth.memory, nullptr); + vkDestroyRenderPass(device, multiviewPass.renderPass, nullptr); + vkDestroySampler(device, multiviewPass.sampler, nullptr); + vkDestroyFramebuffer(device, multiviewPass.frameBuffer, nullptr); + vkFreeCommandBuffers(device, cmdPool, static_cast(multiviewPass.commandBuffers.size()), multiviewPass.commandBuffers.data()); + vkDestroySemaphore(device, multiviewPass.semaphore, nullptr); + for (auto& fence : multiviewPass.waitFences) { + vkDestroyFence(device, fence, nullptr); + } + for (auto& pipeline : viewDisplayPipelines) { + vkDestroyPipeline(device, pipeline, nullptr); + } + uniformBuffer.destroy(); } - - uniformBuffer.destroy(); } /* @@ -150,8 +143,9 @@ public: depthStencilView.flags = 0; depthStencilView.subresourceRange = {}; depthStencilView.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; - if (depthFormat >= VK_FORMAT_D16_UNORM_S8_UINT) + if (depthFormat >= VK_FORMAT_D16_UNORM_S8_UINT) { depthStencilView.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT; + } depthStencilView.subresourceRange.baseMipLevel = 0; depthStencilView.subresourceRange.levelCount = 1; depthStencilView.subresourceRange.baseArrayLayer = 0; @@ -583,13 +577,8 @@ public: // Prepare and initialize uniform buffer containing shader uniforms void prepareUniformBuffers() { - 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(ubo))); + 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_CHECK_RESULT(uniformBuffer.map()); - updateUniformBuffers(); } void updateUniformBuffers() @@ -625,8 +614,8 @@ public: transM = glm::translate(glm::mat4(1.0f), camera.position - camRight * (eyeSeparation / 2.0f)); - ubo.projection[0] = glm::frustum(left, right, bottom, top, zNear, zFar); - ubo.modelview[0] = rotM * transM; + uniformData.projection[0] = glm::frustum(left, right, bottom, top, zNear, zFar); + uniformData.modelview[0] = rotM * transM; // Right eye left = -aspectRatio * wd2 + 0.5f * eyeSeparation * ndfl; @@ -634,35 +623,10 @@ public: transM = glm::translate(glm::mat4(1.0f), camera.position + camRight * (eyeSeparation / 2.0f)); - ubo.projection[1] = glm::frustum(left, right, bottom, top, zNear, zFar); - ubo.modelview[1] = rotM * transM; + uniformData.projection[1] = glm::frustum(left, right, bottom, top, zNear, zFar); + uniformData.modelview[1] = rotM * transM; - memcpy(uniformBuffer.mapped, &ubo, sizeof(ubo)); - } - - void draw() - { - VulkanExampleBase::prepareFrame(); - - // Multiview offscreen render - VK_CHECK_RESULT(vkWaitForFences(device, 1, &multiviewPass.waitFences[currentBuffer], VK_TRUE, UINT64_MAX)); - VK_CHECK_RESULT(vkResetFences(device, 1, &multiviewPass.waitFences[currentBuffer])); - submitInfo.pWaitSemaphores = &semaphores.presentComplete; - submitInfo.pSignalSemaphores = &multiviewPass.semaphore; - submitInfo.commandBufferCount = 1; - submitInfo.pCommandBuffers = &multiviewPass.commandBuffers[currentBuffer]; - VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, multiviewPass.waitFences[currentBuffer])); - - // View display - VK_CHECK_RESULT(vkWaitForFences(device, 1, &waitFences[currentBuffer], VK_TRUE, UINT64_MAX)); - VK_CHECK_RESULT(vkResetFences(device, 1, &waitFences[currentBuffer])); - submitInfo.pWaitSemaphores = &multiviewPass.semaphore; - submitInfo.pSignalSemaphores = &semaphores.renderComplete; - submitInfo.commandBufferCount = 1; - submitInfo.pCommandBuffers = &drawCmdBuffers[currentBuffer]; - VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, waitFences[currentBuffer])); - - VulkanExampleBase::submitFrame(); + memcpy(uniformBuffer.mapped, &uniformData, sizeof(UniformData)); } void prepare() @@ -728,19 +692,37 @@ public: } } + void draw() + { + VulkanExampleBase::prepareFrame(); + + // Multiview offscreen render + VK_CHECK_RESULT(vkWaitForFences(device, 1, &multiviewPass.waitFences[currentBuffer], VK_TRUE, UINT64_MAX)); + VK_CHECK_RESULT(vkResetFences(device, 1, &multiviewPass.waitFences[currentBuffer])); + submitInfo.pWaitSemaphores = &semaphores.presentComplete; + submitInfo.pSignalSemaphores = &multiviewPass.semaphore; + submitInfo.commandBufferCount = 1; + submitInfo.pCommandBuffers = &multiviewPass.commandBuffers[currentBuffer]; + VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, multiviewPass.waitFences[currentBuffer])); + + // View display + VK_CHECK_RESULT(vkWaitForFences(device, 1, &waitFences[currentBuffer], VK_TRUE, UINT64_MAX)); + VK_CHECK_RESULT(vkResetFences(device, 1, &waitFences[currentBuffer])); + submitInfo.pWaitSemaphores = &multiviewPass.semaphore; + submitInfo.pSignalSemaphores = &semaphores.renderComplete; + submitInfo.commandBufferCount = 1; + submitInfo.pCommandBuffers = &drawCmdBuffers[currentBuffer]; + VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, waitFences[currentBuffer])); + + VulkanExampleBase::submitFrame(); + } + virtual void render() { if (!prepared) return; - draw(); - if (camera.updated) { - updateUniformBuffers(); - } - } - - virtual void viewChanged() - { updateUniformBuffers(); + draw(); } virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay) @@ -749,7 +731,7 @@ public: if (overlay->sliderFloat("Eye separation", &eyeSeparation, -1.0f, 1.0f)) { updateUniformBuffers(); } - if (overlay->sliderFloat("Barrel distortion", &ubo.distortionAlpha, -0.6f, 0.6f)) { + if (overlay->sliderFloat("Barrel distortion", &uniformData.distortionAlpha, -0.6f, 0.6f)) { updateUniformBuffers(); } } diff --git a/examples/viewportarray/viewportarray.cpp b/examples/viewportarray/viewportarray.cpp index 4396d857..7c022ed1 100644 --- a/examples/viewportarray/viewportarray.cpp +++ b/examples/viewportarray/viewportarray.cpp @@ -1,7 +1,7 @@ /* * Vulkan Example - Viewport array with single pass rendering using geometry shaders * -* Copyright (C) 2017 by Sascha Willems - www.saschawillems.de +* Copyright (C) 2017-2023 by Sascha Willems - www.saschawillems.de * * This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) */ @@ -14,18 +14,17 @@ class VulkanExample : public VulkanExampleBase public: vkglTF::Model scene; - struct UBOGS { + struct UniformDataGS { glm::mat4 projection[2]; glm::mat4 modelview[2]; glm::vec4 lightPos = glm::vec4(-2.5f, -3.5f, 0.0f, 1.0f); - } uboGS; - + } uniformDataGS; vks::Buffer uniformBufferGS; - 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 }; // Camera and view properties float eyeSeparation = 0.08f; @@ -45,12 +44,12 @@ public: ~VulkanExample() { - vkDestroyPipeline(device, pipeline, nullptr); - - vkDestroyPipelineLayout(device, pipelineLayout, nullptr); - vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr); - - uniformBufferGS.destroy(); + if (device) { + vkDestroyPipeline(device, pipeline, nullptr); + vkDestroyPipelineLayout(device, pipelineLayout, nullptr); + vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr); + uniformBufferGS.destroy(); + } } // Enable physical device features required for this example @@ -98,12 +97,12 @@ public: vkCmdBeginRenderPass(drawCmdBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); - VkViewport viewports[2]; - // Right - viewports[0] = { (float)width / 2.0f, 0, (float)width / 2.0f, (float)height, 0.0, 1.0f }; - // Left - viewports[1] = { 0, 0, (float)width / 2.0f, (float)height, 0.0, 1.0f }; - + // We render to two viewports simultaneously, so we need to viewports and two scissor rectangles + // 0 = right, 1 = left + VkViewport viewports[2] = { + { (float)width / 2.0f, 0, (float)width / 2.0f, (float)height, 0.0, 1.0f }, + { 0, 0, (float)width / 2.0f, (float)height, 0.0, 1.0f }, + }; vkCmdSetViewport(drawCmdBuffers[i], 0, 2, viewports); VkRect2D scissorRects[2] = { @@ -131,55 +130,39 @@ public: scene.loadFromFile(getAssetPath() + "models/sampleroom.gltf", vulkanDevice, queue, vkglTF::FileLoadingFlags::PreTransformVertices | vkglTF::FileLoadingFlags::PreMultiplyVertexColors | vkglTF::FileLoadingFlags::FlipY); } - void setupDescriptorPool() + void setupDescriptors() { - // Example uses two ubos + // Pool std::vector poolSizes = { vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1), }; - - VkDescriptorPoolCreateInfo descriptorPoolInfo = - vks::initializers::descriptorPoolCreateInfo(static_cast(poolSizes.size()), poolSizes.data(), 1); - + VkDescriptorPoolCreateInfo descriptorPoolInfo = vks::initializers::descriptorPoolCreateInfo(static_cast(poolSizes.size()), poolSizes.data(), 1); VK_CHECK_RESULT(vkCreateDescriptorPool(device, &descriptorPoolInfo, nullptr, &descriptorPool)); - } - void setupDescriptorSetLayout() - { + // Layout std::vector setLayoutBindings = { vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_GEOMETRY_BIT, 0) // Binding 1: Geometry shader ubo }; - - VkDescriptorSetLayoutCreateInfo descriptorLayout = - vks::initializers::descriptorSetLayoutCreateInfo(setLayoutBindings); - + VkDescriptorSetLayoutCreateInfo descriptorLayout = vks::initializers::descriptorSetLayoutCreateInfo(setLayoutBindings); VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorLayout, nullptr, &descriptorSetLayout)); - - VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo = - vks::initializers::pipelineLayoutCreateInfo(&descriptorSetLayout, 1); - - VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pPipelineLayoutCreateInfo, nullptr, &pipelineLayout)); - } - - void setupDescriptorSet() - { - VkDescriptorSetAllocateInfo allocInfo = - vks::initializers::descriptorSetAllocateInfo( - descriptorPool, - &descriptorSetLayout, - 1); - + + // Set + VkDescriptorSetAllocateInfo allocInfo = vks::initializers::descriptorSetAllocateInfo(descriptorPool, &descriptorSetLayout, 1); VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &descriptorSet)); std::vector writeDescriptorSets = { vks::initializers::writeDescriptorSet(descriptorSet, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &uniformBufferGS.descriptor), // Binding 0 :Geometry shader ubo }; - vkUpdateDescriptorSets(device, static_cast(writeDescriptorSets.size()), writeDescriptorSets.data(), 0, nullptr); } void preparePipelines() { + // Layout + VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = vks::initializers::pipelineLayoutCreateInfo(&descriptorSetLayout, 1); + VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pipelineLayoutCreateInfo, 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_BACK_BIT, VK_FRONT_FACE_COUNTER_CLOCKWISE); VkPipelineColorBlendAttachmentState blendAttachmentState = vks::initializers::pipelineColorBlendAttachmentState(0xf, VK_FALSE); @@ -217,16 +200,9 @@ public: void prepareUniformBuffers() { // Geometry shader uniform buffer block - VK_CHECK_RESULT(vulkanDevice->createBuffer( - VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, - &uniformBufferGS, - sizeof(uboGS))); - + VK_CHECK_RESULT(vulkanDevice->createBuffer(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &uniformBufferGS, sizeof(UniformDataGS))); // Map persistent VK_CHECK_RESULT(uniformBufferGS.map()); - - updateUniformBuffers(); } void updateUniformBuffers() @@ -262,8 +238,8 @@ public: transM = glm::translate(glm::mat4(1.0f), camera.position - camRight * (eyeSeparation / 2.0f)); - uboGS.projection[0] = glm::frustum(left, right, bottom, top, zNear, zFar); - uboGS.modelview[0] = rotM * transM; + uniformDataGS.projection[0] = glm::frustum(left, right, bottom, top, zNear, zFar); + uniformDataGS.modelview[0] = rotM * transM; // Right eye left = -aspectRatio * wd2 - 0.5f * eyeSeparation * ndfl; @@ -271,10 +247,21 @@ public: transM = glm::translate(glm::mat4(1.0f), camera.position + camRight * (eyeSeparation / 2.0f)); - uboGS.projection[1] = glm::frustum(left, right, bottom, top, zNear, zFar); - uboGS.modelview[1] = rotM * transM; + uniformDataGS.projection[1] = glm::frustum(left, right, bottom, top, zNear, zFar); + uniformDataGS.modelview[1] = rotM * transM; - memcpy(uniformBufferGS.mapped, &uboGS, sizeof(uboGS)); + memcpy(uniformBufferGS.mapped, &uniformDataGS, sizeof(uniformDataGS)); + } + + void prepare() + { + VulkanExampleBase::prepare(); + loadAssets(); + prepareUniformBuffers(); + setupDescriptors(); + preparePipelines(); + buildCommandBuffers(); + prepared = true; } void draw() @@ -286,29 +273,12 @@ public: VulkanExampleBase::submitFrame(); } - void prepare() - { - VulkanExampleBase::prepare(); - loadAssets(); - prepareUniformBuffers(); - setupDescriptorSetLayout(); - preparePipelines(); - setupDescriptorPool(); - setupDescriptorSet(); - buildCommandBuffers(); - prepared = true; - } - virtual void render() { if (!prepared) return; - draw(); - } - - virtual void viewChanged() - { updateUniformBuffers(); + draw(); } virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay)