diff --git a/examples/debugmarker/debugmarker.cpp b/examples/debugmarker/debugmarker.cpp index 227c0485..1ecc881b 100644 --- a/examples/debugmarker/debugmarker.cpp +++ b/examples/debugmarker/debugmarker.cpp @@ -1,7 +1,7 @@ /* * Vulkan Example - Example for VK_EXT_debug_marker extension. To be used in conjuction with a debugging app like RenderDoc (https://renderdoc.org) * -* Copyright (C) 2016 by Sascha Willems - www.saschawillems.de +* Copyright (C) by Sascha Willems - www.saschawillems.de * * This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) */ @@ -22,7 +22,6 @@ #include "VulkanBuffer.hpp" #include "VulkanModel.hpp" -#define VERTEX_BUFFER_BIND_ID 0 #define ENABLE_VALIDATION false // Offscreen properties @@ -164,7 +163,7 @@ struct Scene { void draw(VkCommandBuffer cmdBuffer) { VkDeviceSize offsets[1] = { 0 }; - vkCmdBindVertexBuffers(cmdBuffer, VERTEX_BUFFER_BIND_ID, 1, &model.vertices.buffer, offsets); + vkCmdBindVertexBuffers(cmdBuffer, 0, 1, &model.vertices.buffer, offsets); vkCmdBindIndexBuffer(cmdBuffer, model.indices.buffer, 0, VK_INDEX_TYPE_UINT32); for (auto i = 0; i < model.parts.size(); i++) { @@ -224,9 +223,6 @@ public: VkRenderPass renderPass; VkSampler sampler; VkDescriptorImageInfo descriptor; - VkCommandBuffer commandBuffer = VK_NULL_HANDLE; - // Semaphore used to synchronize between offscreen and final scene render pass - VkSemaphore semaphore = VK_NULL_HANDLE; } offscreenPass; // Random tag data @@ -236,13 +232,13 @@ public: VulkanExample() : VulkanExampleBase(ENABLE_VALIDATION) { - zoom = -8.5f; - zoomSpeed = 2.5f; - rotationSpeed = 0.5f; - rotation = { -4.35f, 16.25f, 0.0f }; - cameraPos = { 0.1f, 1.1f, 0.0f }; title = "Debugging with VK_EXT_debug_marker"; settings.overlay = true; + zoomSpeed = 2.5f; + rotationSpeed = 0.5f; + camera.setRotation(glm::vec3(-4.35f, 16.25f, 0.0f)); + camera.setPosition(glm::vec3(0.1f, 1.1f, -8.5f)); + camera.setPerspective(60.0f, (float)width / (float)height, 0.1f, 256.0f); } // Enable physical device features required for this example @@ -289,9 +285,6 @@ public: vkDestroyRenderPass(device, offscreenPass.renderPass, nullptr); vkDestroySampler(device, offscreenPass.sampler, nullptr); vkDestroyFramebuffer(device, offscreenPass.frameBuffer, nullptr); - - vkFreeCommandBuffers(device, cmdPool, 1, &offscreenPass.commandBuffer); - vkDestroySemaphore(device, offscreenPass.semaphore, nullptr); } // Prepare a texture target and framebuffer for offscreen rendering @@ -416,18 +409,18 @@ public: dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL; dependencies[0].dstSubpass = 0; - dependencies[0].srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; + dependencies[0].srcStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; dependencies[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - dependencies[0].srcAccessMask = VK_ACCESS_MEMORY_READ_BIT; - dependencies[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + dependencies[0].srcAccessMask = VK_ACCESS_SHADER_READ_BIT; + dependencies[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; dependencies[0].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT; dependencies[1].srcSubpass = 0; dependencies[1].dstSubpass = VK_SUBPASS_EXTERNAL; dependencies[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - dependencies[1].dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; - dependencies[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - dependencies[1].dstAccessMask = VK_ACCESS_MEMORY_READ_BIT; + dependencies[1].dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + dependencies[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + dependencies[1].dstAccessMask = VK_ACCESS_SHADER_READ_BIT; dependencies[1].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT; // Create the actual renderpass @@ -467,60 +460,6 @@ public: DebugMarker::setObjectName(device, (uint64_t)offscreenPass.sampler, VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT, "Off-screen framebuffer default sampler"); } - // Command buffer for rendering color only scene for glow - void buildOffscreenCommandBuffer() - { - if (offscreenPass.commandBuffer == VK_NULL_HANDLE) - { - offscreenPass.commandBuffer = VulkanExampleBase::createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, false); - } - if (offscreenPass.semaphore == VK_NULL_HANDLE) - { - // Create a semaphore used to synchronize offscreen rendering and usage - VkSemaphoreCreateInfo semaphoreCreateInfo = vks::initializers::semaphoreCreateInfo(); - VK_CHECK_RESULT(vkCreateSemaphore(device, &semaphoreCreateInfo, nullptr, &offscreenPass.semaphore)); - } - - VkCommandBufferBeginInfo cmdBufInfo = vks::initializers::commandBufferBeginInfo(); - - VkClearValue clearValues[2]; - clearValues[0].color = { { 0.0f, 0.0f, 0.0f, 0.0f } }; - clearValues[1].depthStencil = { 1.0f, 0 }; - - VkRenderPassBeginInfo renderPassBeginInfo = vks::initializers::renderPassBeginInfo(); - renderPassBeginInfo.renderPass = offscreenPass.renderPass; - renderPassBeginInfo.framebuffer = offscreenPass.frameBuffer; - renderPassBeginInfo.renderArea.extent.width = offscreenPass.width; - renderPassBeginInfo.renderArea.extent.height = offscreenPass.height; - renderPassBeginInfo.clearValueCount = 2; - renderPassBeginInfo.pClearValues = clearValues; - - VK_CHECK_RESULT(vkBeginCommandBuffer(offscreenPass.commandBuffer, &cmdBufInfo)); - - // Start a new debug marker region - DebugMarker::beginRegion(offscreenPass.commandBuffer, "Off-screen scene rendering", glm::vec4(1.0f, 0.78f, 0.05f, 1.0f)); - - VkViewport viewport = vks::initializers::viewport((float)offscreenPass.width, (float)offscreenPass.height, 0.0f, 1.0f); - vkCmdSetViewport(offscreenPass.commandBuffer, 0, 1, &viewport); - - VkRect2D scissor = vks::initializers::rect2D(offscreenPass.width, offscreenPass.height, 0, 0); - vkCmdSetScissor(offscreenPass.commandBuffer, 0, 1, &scissor); - - vkCmdBeginRenderPass(offscreenPass.commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); - - vkCmdBindDescriptorSets(offscreenPass.commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSets.scene, 0, NULL); - vkCmdBindPipeline(offscreenPass.commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.color); - - // Draw glow scene - sceneGlow.draw(offscreenPass.commandBuffer); - - vkCmdEndRenderPass(offscreenPass.commandBuffer); - - DebugMarker::endRegion(offscreenPass.commandBuffer); - - VK_CHECK_RESULT(vkEndCommandBuffer(offscreenPass.commandBuffer)); - } - void loadScene() { scene.loadFromFile(getAssetPath() + "models/treasure_smooth.dae", vulkanDevice, queue); @@ -544,102 +483,138 @@ public: DebugMarker::setObjectName(device, (uint64_t)sceneGlow.model.indices.buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, "Glow index buffer"); } - void reBuildCommandBuffers() - { - vkDeviceWaitIdle(device); - if (!checkCommandBuffers()) { - destroyCommandBuffers(); - createCommandBuffers(); - } - buildCommandBuffers(); - } - void buildCommandBuffers() { VkCommandBufferBeginInfo cmdBufInfo = vks::initializers::commandBufferBeginInfo(); - VkClearValue clearValues[2]; - clearValues[0].color = defaultClearColor; - clearValues[1].depthStencil = { 1.0f, 0 }; - - VkRenderPassBeginInfo renderPassBeginInfo = vks::initializers::renderPassBeginInfo(); - renderPassBeginInfo.renderPass = renderPass; - renderPassBeginInfo.renderArea.offset.x = 0; - renderPassBeginInfo.renderArea.offset.y = 0; - renderPassBeginInfo.renderArea.extent.width = width; - renderPassBeginInfo.renderArea.extent.height = height; - renderPassBeginInfo.clearValueCount = 2; - renderPassBeginInfo.pClearValues = clearValues; + VkViewport viewport; + VkRect2D scissor; + VkDeviceSize offsets[1] = { 0 }; for (int32_t i = 0; i < drawCmdBuffers.size(); ++i) { - // Set target frame buffer - renderPassBeginInfo.framebuffer = frameBuffers[i]; - VK_CHECK_RESULT(vkBeginCommandBuffer(drawCmdBuffers[i], &cmdBufInfo)); - // Start a new debug marker region - DebugMarker::beginRegion(drawCmdBuffers[i], "Render scene", glm::vec4(0.5f, 0.76f, 0.34f, 1.0f)); - - vkCmdBeginRenderPass(drawCmdBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); - - VkViewport viewport = vks::initializers::viewport((float)width, (float)height, 0.0f, 1.0f); - vkCmdSetViewport(drawCmdBuffers[i], 0, 1, &viewport); - - VkRect2D scissor = vks::initializers::rect2D(wireframe ? width / 2 : width, height, 0, 0); - vkCmdSetScissor(drawCmdBuffers[i], 0, 1, &scissor); - - vkCmdBindDescriptorSets(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSets.scene, 0, NULL); - - // Solid rendering - - // Start a new debug marker region - DebugMarker::beginRegion(drawCmdBuffers[i], "Toon shading draw", glm::vec4(0.78f, 0.74f, 0.9f, 1.0f)); - - vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.toonshading); - scene.draw(drawCmdBuffers[i]); - - DebugMarker::endRegion(drawCmdBuffers[i]); - - // Wireframe rendering - if (wireframe) + /* + First render pass: Offscreen rendering + */ + if (glow) { - // Insert debug marker - DebugMarker::beginRegion(drawCmdBuffers[i], "Wireframe draw", glm::vec4(0.53f, 0.78f, 0.91f, 1.0f)); + VkClearValue clearValues[2]; + clearValues[0].color = { { 0.0f, 0.0f, 0.0f, 0.0f } }; + clearValues[1].depthStencil = { 1.0f, 0 }; - scissor.offset.x = width / 2; + VkRenderPassBeginInfo renderPassBeginInfo = vks::initializers::renderPassBeginInfo(); + renderPassBeginInfo.renderPass = offscreenPass.renderPass; + renderPassBeginInfo.framebuffer = offscreenPass.frameBuffer; + renderPassBeginInfo.renderArea.extent.width = offscreenPass.width; + renderPassBeginInfo.renderArea.extent.height = offscreenPass.height; + renderPassBeginInfo.clearValueCount = 2; + renderPassBeginInfo.pClearValues = clearValues; + + // Start a new debug marker region + DebugMarker::beginRegion(drawCmdBuffers[i], "Off-screen scene rendering", glm::vec4(1.0f, 0.78f, 0.05f, 1.0f)); + + vkCmdBeginRenderPass(drawCmdBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); + + VkViewport viewport = vks::initializers::viewport((float)offscreenPass.width, (float)offscreenPass.height, 0.0f, 1.0f); + vkCmdSetViewport(drawCmdBuffers[i], 0, 1, &viewport); + + VkRect2D scissor = vks::initializers::rect2D(offscreenPass.width, offscreenPass.height, 0, 0); vkCmdSetScissor(drawCmdBuffers[i], 0, 1, &scissor); - vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.wireframe); + vkCmdBindDescriptorSets(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSets.scene, 0, NULL); + vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.color); + + sceneGlow.draw(drawCmdBuffers[i]); + + vkCmdEndRenderPass(drawCmdBuffers[i]); + + DebugMarker::endRegion(drawCmdBuffers[i]); + } + + /* + Note: Explicit synchronization is not required between the render pass, as this is done implicit via sub pass dependencies + */ + + /* + Second render pass: Scene rendering with applied bloom + */ + { + clearValues[0].color = defaultClearColor; + clearValues[1].depthStencil = { 1.0f, 0 }; + + VkRenderPassBeginInfo renderPassBeginInfo = vks::initializers::renderPassBeginInfo(); + renderPassBeginInfo.renderPass = renderPass; + renderPassBeginInfo.framebuffer = frameBuffers[i]; + renderPassBeginInfo.renderArea.extent.width = width; + renderPassBeginInfo.renderArea.extent.height = height; + renderPassBeginInfo.clearValueCount = 2; + renderPassBeginInfo.pClearValues = clearValues; + + // Start a new debug marker region + DebugMarker::beginRegion(drawCmdBuffers[i], "Render scene", glm::vec4(0.5f, 0.76f, 0.34f, 1.0f)); + + vkCmdBeginRenderPass(drawCmdBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); + + VkViewport viewport = vks::initializers::viewport((float)width, (float)height, 0.0f, 1.0f); + vkCmdSetViewport(drawCmdBuffers[i], 0, 1, &viewport); + + VkRect2D scissor = vks::initializers::rect2D(wireframe ? width / 2 : width, height, 0, 0); + vkCmdSetScissor(drawCmdBuffers[i], 0, 1, &scissor); + + vkCmdBindDescriptorSets(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSets.scene, 0, NULL); + + // Solid rendering + + // Start a new debug marker region + DebugMarker::beginRegion(drawCmdBuffers[i], "Toon shading draw", glm::vec4(0.78f, 0.74f, 0.9f, 1.0f)); + + vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.toonshading); scene.draw(drawCmdBuffers[i]); DebugMarker::endRegion(drawCmdBuffers[i]); - scissor.offset.x = 0; - scissor.extent.width = width; - vkCmdSetScissor(drawCmdBuffers[i], 0, 1, &scissor); + // Wireframe rendering + if (wireframe) + { + // Insert debug marker + DebugMarker::beginRegion(drawCmdBuffers[i], "Wireframe draw", glm::vec4(0.53f, 0.78f, 0.91f, 1.0f)); + + scissor.offset.x = width / 2; + vkCmdSetScissor(drawCmdBuffers[i], 0, 1, &scissor); + + vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.wireframe); + scene.draw(drawCmdBuffers[i]); + + DebugMarker::endRegion(drawCmdBuffers[i]); + + scissor.offset.x = 0; + scissor.extent.width = width; + vkCmdSetScissor(drawCmdBuffers[i], 0, 1, &scissor); + } + + // Post processing + if (glow) + { + DebugMarker::beginRegion(drawCmdBuffers[i], "Apply post processing", glm::vec4(0.93f, 0.89f, 0.69f, 1.0f)); + + vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.postprocess); + // Full screen quad is generated by the vertex shaders, so we reuse four vertices (for four invocations) from current vertex buffer + vkCmdDraw(drawCmdBuffers[i], 4, 1, 0, 0); + + DebugMarker::endRegion(drawCmdBuffers[i]); + } + + drawUI(drawCmdBuffers[i]); + + vkCmdEndRenderPass(drawCmdBuffers[i]); + + // End current debug marker region + DebugMarker::endRegion(drawCmdBuffers[i]); + } - // Post processing - if (glow) - { - DebugMarker::beginRegion(drawCmdBuffers[i], "Apply post processing", glm::vec4(0.93f, 0.89f, 0.69f, 1.0f)); - - vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.postprocess); - // Full screen quad is generated by the vertex shaders, so we reuse four vertices (for four invocations) from current vertex buffer - vkCmdDraw(drawCmdBuffers[i], 4, 1, 0, 0); - - DebugMarker::endRegion(drawCmdBuffers[i]); - } - - - drawUI(drawCmdBuffers[i]); - - vkCmdEndRenderPass(drawCmdBuffers[i]); - - // End current debug marker region - DebugMarker::endRegion(drawCmdBuffers[i]); - VK_CHECK_RESULT(vkEndCommandBuffer(drawCmdBuffers[i])); } } @@ -648,50 +623,27 @@ public: void setupDescriptorPool() { // Example uses one ubo and one combined image sampler - std::vector poolSizes = - { + std::vector poolSizes = { vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1), vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1), }; - - VkDescriptorPoolCreateInfo descriptorPoolInfo = - vks::initializers::descriptorPoolCreateInfo( - poolSizes.size(), - poolSizes.data(), - 1); - + VkDescriptorPoolCreateInfo descriptorPoolInfo = vks::initializers::descriptorPoolCreateInfo(poolSizes.size(), poolSizes.data(), 1); VK_CHECK_RESULT(vkCreateDescriptorPool(device, &descriptorPoolInfo, nullptr, &descriptorPool)); } void setupDescriptorSetLayout() { - std::vector setLayoutBindings = - { + std::vector setLayoutBindings = { // 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), // Binding 1 : Fragment shader combined sampler - vks::initializers::descriptorSetLayoutBinding( - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - VK_SHADER_STAGE_FRAGMENT_BIT, - 1), + vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT, 1), }; - - VkDescriptorSetLayoutCreateInfo descriptorLayout = - vks::initializers::descriptorSetLayoutCreateInfo( - setLayoutBindings.data(), - setLayoutBindings.size()); - + VkDescriptorSetLayoutCreateInfo descriptorLayout = vks::initializers::descriptorSetLayoutCreateInfo(setLayoutBindings.data(), setLayoutBindings.size()); VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorLayout, nullptr, &descriptorSetLayout)); - VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo = - vks::initializers::pipelineLayoutCreateInfo( - &descriptorSetLayout, - 1); - - VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pPipelineLayoutCreateInfo, nullptr, &pipelineLayout)); + VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = vks::initializers::pipelineLayoutCreateInfo(&descriptorSetLayout, 1); + VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pipelineLayoutCreateInfo, nullptr, &pipelineLayout)); // Name for debugging DebugMarker::setObjectName(device, (uint64_t)pipelineLayout, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT, "Shared pipeline layout"); @@ -700,113 +652,54 @@ public: void setupDescriptorSet() { - VkDescriptorSetAllocateInfo allocInfo = - vks::initializers::descriptorSetAllocateInfo( - descriptorPool, - &descriptorSetLayout, - 1); - + VkDescriptorSetAllocateInfo allocInfo = vks::initializers::descriptorSetAllocateInfo(descriptorPool, &descriptorSetLayout, 1); VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &descriptorSets.scene)); - std::vector writeDescriptorSets = - { + std::vector writeDescriptorSets = { // Binding 0 : Vertex shader uniform buffer - vks::initializers::writeDescriptorSet( - descriptorSets.scene, - VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - 0, - &uniformBuffer.descriptor), + vks::initializers::writeDescriptorSet(descriptorSets.scene, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &uniformBuffer.descriptor), // Binding 1 : Color map - vks::initializers::writeDescriptorSet( - descriptorSets.scene, - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - 1, - &offscreenPass.descriptor) + vks::initializers::writeDescriptorSet(descriptorSets.scene, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, &offscreenPass.descriptor) }; - vkUpdateDescriptorSets(device, writeDescriptorSets.size(), writeDescriptorSets.data(), 0, NULL); } void preparePipelines() { - 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_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(), - dynamicStateEnables.size(), - 0); - + 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_CLOCKWISE, 0); + VkPipelineColorBlendAttachmentState blendAttachmentState = vks::initializers::pipelineColorBlendAttachmentState(0xf, VK_FALSE); + VkPipelineColorBlendStateCreateInfo colorBlendStateCI = vks::initializers::pipelineColorBlendStateCreateInfo(1, &blendAttachmentState); + 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); + std::vector dynamicStateEnables = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; + VkPipelineDynamicStateCreateInfo dynamicStateCI = vks::initializers::pipelineDynamicStateCreateInfo(dynamicStateEnables.data(), dynamicStateEnables.size(), 0); std::array shaderStages; - VkGraphicsPipelineCreateInfo pipelineCreateInfo = - vks::initializers::pipelineCreateInfo( - pipelineLayout, - renderPass, - 0); - - pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState; - pipelineCreateInfo.pRasterizationState = &rasterizationState; - pipelineCreateInfo.pColorBlendState = &colorBlendState; - pipelineCreateInfo.pMultisampleState = &multisampleState; - pipelineCreateInfo.pViewportState = &viewportState; - pipelineCreateInfo.pDepthStencilState = &depthStencilState; - pipelineCreateInfo.pDynamicState = &dynamicState; - pipelineCreateInfo.stageCount = shaderStages.size(); - pipelineCreateInfo.pStages = shaderStages.data(); + VkGraphicsPipelineCreateInfo pipelineCI = vks::initializers::pipelineCreateInfo(pipelineLayout, renderPass); + pipelineCI.pInputAssemblyState = &inputAssemblyStateCI; + pipelineCI.pRasterizationState = &rasterizationStateCI; + pipelineCI.pColorBlendState = &colorBlendStateCI; + pipelineCI.pMultisampleState = &multisampleStateCI; + pipelineCI.pViewportState = &viewportStateCI; + pipelineCI.pDepthStencilState = &depthStencilStateCI; + pipelineCI.pDynamicState = &dynamicStateCI; + pipelineCI.stageCount = shaderStages.size(); + pipelineCI.pStages = shaderStages.data(); // Shared vertex inputs // Binding description - VkVertexInputBindingDescription vertexInputBinding = - vks::initializers::vertexInputBindingDescription(VERTEX_BUFFER_BIND_ID, vertexLayout.stride(), VK_VERTEX_INPUT_RATE_VERTEX); + VkVertexInputBindingDescription vertexInputBinding = { 0, vertexLayout.stride(), VK_VERTEX_INPUT_RATE_VERTEX }; // Attribute descriptions // Describes memory layout and shader positions std::vector vertexInputAttributes = { - vks::initializers::vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 0, VK_FORMAT_R32G32B32_SFLOAT, 0), // Location 0: Position - vks::initializers::vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 1, VK_FORMAT_R32G32B32_SFLOAT, sizeof(float) * 3), // Location 1: Normal - 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 + { 0, 0, VK_FORMAT_R32G32B32_SFLOAT, 0 }, // Location 0: Position + { 1, 0, VK_FORMAT_R32G32B32_SFLOAT, sizeof(float) * 3 }, // Location 1: Normal + { 2, 0, VK_FORMAT_R32G32_SFLOAT, sizeof(float) * 6 }, // Location 2: Texture coordinates + { 3, 0, VK_FORMAT_R32G32B32_SFLOAT, sizeof(float) * 8 }, // Location 3: Color }; VkPipelineVertexInputStateCreateInfo vertexInputState = vks::initializers::pipelineVertexInputStateCreateInfo(); @@ -815,34 +708,34 @@ public: vertexInputState.vertexAttributeDescriptionCount = static_cast(vertexInputAttributes.size()); vertexInputState.pVertexAttributeDescriptions = vertexInputAttributes.data(); - pipelineCreateInfo.pVertexInputState = &vertexInputState; + pipelineCI.pVertexInputState = &vertexInputState; // Toon shading pipeline shaderStages[0] = loadShader(getAssetPath() + "shaders/debugmarker/toon.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); shaderStages[1] = loadShader(getAssetPath() + "shaders/debugmarker/toon.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); - VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.toonshading)); + VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.toonshading)); // Color only pipeline shaderStages[0] = loadShader(getAssetPath() + "shaders/debugmarker/colorpass.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); shaderStages[1] = loadShader(getAssetPath() + "shaders/debugmarker/colorpass.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); - pipelineCreateInfo.renderPass = offscreenPass.renderPass; - VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.color)); + pipelineCI.renderPass = offscreenPass.renderPass; + VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.color)); // Wire frame rendering pipeline if (deviceFeatures.fillModeNonSolid) { - rasterizationState.polygonMode = VK_POLYGON_MODE_LINE; - pipelineCreateInfo.renderPass = renderPass; - VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.wireframe)); + rasterizationStateCI.polygonMode = VK_POLYGON_MODE_LINE; + pipelineCI.renderPass = renderPass; + VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.wireframe)); } // Post processing effect shaderStages[0] = loadShader(getAssetPath() + "shaders/debugmarker/postprocess.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); shaderStages[1] = loadShader(getAssetPath() + "shaders/debugmarker/postprocess.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); - depthStencilState.depthTestEnable = VK_FALSE; - depthStencilState.depthWriteEnable = VK_FALSE; - rasterizationState.polygonMode = VK_POLYGON_MODE_FILL; - rasterizationState.cullMode = VK_CULL_MODE_NONE; + depthStencilStateCI.depthTestEnable = VK_FALSE; + depthStencilStateCI.depthWriteEnable = VK_FALSE; + rasterizationStateCI.polygonMode = VK_POLYGON_MODE_FILL; + rasterizationStateCI.cullMode = VK_CULL_MODE_NONE; blendAttachmentState.colorWriteMask = 0xF; blendAttachmentState.blendEnable = VK_TRUE; blendAttachmentState.colorBlendOp = VK_BLEND_OP_ADD; @@ -851,7 +744,7 @@ public: blendAttachmentState.alphaBlendOp = VK_BLEND_OP_ADD; blendAttachmentState.srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; blendAttachmentState.dstAlphaBlendFactor = VK_BLEND_FACTOR_DST_ALPHA; - VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.postprocess)); + VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCI, nullptr, &pipelines.postprocess)); // Name shader moduels for debugging // Shader module count starts at 2 when UI overlay in base class is enabled @@ -899,48 +792,17 @@ public: void updateUniformBuffers() { - uboVS.projection = glm::perspective(glm::radians(60.0f), (float)width / (float)height, 0.1f, 256.0f); - glm::mat4 viewMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, zoom)); - - uboVS.model = viewMatrix * glm::translate(glm::mat4(1.0f), cameraPos); - uboVS.model = glm::rotate(uboVS.model, glm::radians(rotation.x), glm::vec3(1.0f, 0.0f, 0.0f)); - uboVS.model = glm::rotate(uboVS.model, glm::radians(rotation.y), glm::vec3(0.0f, 1.0f, 0.0f)); - uboVS.model = glm::rotate(uboVS.model, glm::radians(rotation.z), glm::vec3(0.0f, 0.0f, 1.0f)); - + uboVS.projection = camera.matrices.perspective; + uboVS.model = camera.matrices.view; memcpy(uniformBuffer.mapped, &uboVS, sizeof(uboVS)); } void draw() { VulkanExampleBase::prepareFrame(); - - // Offscreen rendering - if (glow) { - // Wait for swap chain presentation to finish - submitInfo.pWaitSemaphores = &semaphores.presentComplete; - // Signal ready with offscreen semaphore - submitInfo.pSignalSemaphores = &offscreenPass.semaphore; - - // Submit work - submitInfo.commandBufferCount = 1; - submitInfo.pCommandBuffers = &offscreenPass.commandBuffer; - VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE)); - - // Wait for offscreen semaphore - submitInfo.pWaitSemaphores = &offscreenPass.semaphore; - } - else { - submitInfo.pWaitSemaphores = &semaphores.presentComplete; - } - - // Scene rendering - // Signal ready with render complete semaphpre - submitInfo.pSignalSemaphores = &semaphores.renderComplete; - - // Submit work + submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = &drawCmdBuffers[currentBuffer]; VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE)); - VulkanExampleBase::submitFrame(); } @@ -956,7 +818,6 @@ public: setupDescriptorPool(); setupDescriptorSet(); buildCommandBuffers(); - buildOffscreenCommandBuffer(); prepared = true; } @@ -965,12 +826,10 @@ public: if (!prepared) return; draw(); + if (camera.updated) + updateUniformBuffers(); } - virtual void viewChanged() - { - updateUniformBuffers(); - } virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay) { @@ -979,11 +838,11 @@ public: } if (overlay->header("Settings")) { if (overlay->checkBox("Glow", &glow)) { - reBuildCommandBuffers(); + buildCommandBuffers(); } if (deviceFeatures.fillModeNonSolid) { if (overlay->checkBox("Wireframe", &wireframe)) { - reBuildCommandBuffers(); + buildCommandBuffers(); } } }