From cdf95d4aff11c198261f8a08a3c121de7d205233 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Wed, 24 Oct 2018 19:20:23 -0400 Subject: [PATCH] Add depth testing --- include/renderer.h | 11 ++++-- src/postpass.cpp | 2 +- src/renderer.cpp | 84 ++++++++++++++++++++++++++++++++++++++-------- src/worldpass.cpp | 38 ++++++++++++++++++--- 4 files changed, 112 insertions(+), 23 deletions(-) diff --git a/include/renderer.h b/include/renderer.h index fedbec4..b1edb3d 100644 --- a/include/renderer.h +++ b/include/renderer.h @@ -16,9 +16,14 @@ struct RenderTarget { VkImageView* swapchainImageViews = nullptr; VkFramebuffer* swapchainFramebuffers = nullptr; - VkImage* offscreenImages = nullptr; - VkDeviceMemory* offscreenMemory = nullptr; - VkImageView* offscreenImageViews = nullptr; + VkImage* offscreenColorImages = nullptr; + VkDeviceMemory* offscreenColorMemory = nullptr; + VkImageView* offscreenColorImageViews = nullptr; + + VkImage* offscreenDepthImages = nullptr; + VkDeviceMemory* offscreenDepthMemory = nullptr; + VkImageView* offscreenDepthImageViews = nullptr; + VkFramebuffer* offscreenFramebuffers = nullptr; VkCommandBuffer* commandBuffers = nullptr; diff --git a/src/postpass.cpp b/src/postpass.cpp index ef17f6b..010125d 100644 --- a/src/postpass.cpp +++ b/src/postpass.cpp @@ -46,7 +46,7 @@ void PostPass::createDescriptorSet(RenderTarget* target) { for(uint32_t i = 0; i < target->numImages; i++) { VkDescriptorImageInfo imageInfo = {}; imageInfo.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - imageInfo.imageView = target->offscreenImageViews[i]; + imageInfo.imageView = target->offscreenColorImageViews[i]; imageInfo.sampler = offscreenSampler_; VkWriteDescriptorSet descriptorWrite = {}; diff --git a/src/renderer.cpp b/src/renderer.cpp index 44772bd..80b478c 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -180,9 +180,12 @@ RenderTarget* Renderer::createSurfaceRenderTarget(VkSurfaceKHR surface, RenderTa // create frame resources target->swapchainImageViews = new VkImageView[swapchainImageCount]; target->swapchainFramebuffers = new VkFramebuffer[swapchainImageCount]; - target->offscreenImages = new VkImage[swapchainImageCount]; - target->offscreenMemory = new VkDeviceMemory[swapchainImageCount]; - target->offscreenImageViews = new VkImageView[swapchainImageCount]; + target->offscreenColorImages = new VkImage[swapchainImageCount]; + target->offscreenColorMemory = new VkDeviceMemory[swapchainImageCount]; + target->offscreenColorImageViews = new VkImageView[swapchainImageCount]; + target->offscreenDepthImages = new VkImage[swapchainImageCount]; + target->offscreenDepthMemory = new VkDeviceMemory[swapchainImageCount]; + target->offscreenDepthImageViews = new VkImageView[swapchainImageCount]; target->offscreenFramebuffers = new VkFramebuffer[swapchainImageCount]; for(uint32_t i = 0; i < swapchainImageCount; i++) { // swapchain image view @@ -228,41 +231,89 @@ RenderTarget* Renderer::createSurfaceRenderTarget(VkSurfaceKHR surface, RenderTa imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL; imageCreateInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; - vkCreateImage(device_, &imageCreateInfo, nullptr, &target->offscreenImages[i]); + vkCreateImage(device_, &imageCreateInfo, nullptr, &target->offscreenColorImages[i]); VkMemoryRequirements memoryRequirements = {}; - vkGetImageMemoryRequirements(device_, target->offscreenImages[i], &memoryRequirements); + vkGetImageMemoryRequirements(device_, target->offscreenColorImages[i], &memoryRequirements); VkMemoryAllocateInfo allocateInfo = {}; allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; allocateInfo.allocationSize = memoryRequirements.size; allocateInfo.memoryTypeIndex = findMemoryType(memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - vkAllocateMemory(device_, &allocateInfo, nullptr, &target->offscreenMemory[i]); - vkBindImageMemory(device_, target->offscreenImages[i], target->offscreenMemory[i], 0); + vkAllocateMemory(device_, &allocateInfo, nullptr, &target->offscreenColorMemory[i]); + vkBindImageMemory(device_, target->offscreenColorImages[i], target->offscreenColorMemory[i], 0); } // offscreen image view { VkImageViewCreateInfo createInfo = {}; createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - createInfo.image = target->offscreenImages[i]; + createInfo.image = target->offscreenColorImages[i]; createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; createInfo.format = VK_FORMAT_R32G32B32A32_SFLOAT; createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; createInfo.subresourceRange.levelCount = 1; createInfo.subresourceRange.layerCount = 1; - vkCreateImageView(device_, &createInfo, nullptr, &target->offscreenImageViews[i]); + vkCreateImageView(device_, &createInfo, nullptr, &target->offscreenColorImageViews[i]); + } + + // offscreen depth image + { + VkImageCreateInfo imageCreateInfo = {}; + imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + imageCreateInfo.imageType = VK_IMAGE_TYPE_2D; + imageCreateInfo.format = VK_FORMAT_D32_SFLOAT; + imageCreateInfo.extent.width = target->extent.width; + imageCreateInfo.extent.height = target->extent.height; + imageCreateInfo.extent.depth = 1; + imageCreateInfo.mipLevels = 1; + imageCreateInfo.arrayLayers = 1; + imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT; + imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL; + imageCreateInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + + vkCreateImage(device_, &imageCreateInfo, nullptr, &target->offscreenDepthImages[i]); + + VkMemoryRequirements memoryRequirements = {}; + vkGetImageMemoryRequirements(device_, target->offscreenDepthImages[i], &memoryRequirements); + + VkMemoryAllocateInfo allocateInfo = {}; + allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + allocateInfo.allocationSize = memoryRequirements.size; + allocateInfo.memoryTypeIndex = findMemoryType(memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + + vkAllocateMemory(device_, &allocateInfo, nullptr, &target->offscreenDepthMemory[i]); + vkBindImageMemory(device_, target->offscreenDepthImages[i], target->offscreenDepthMemory[i], 0); + } + + // offscreen depth image view + { + VkImageViewCreateInfo createInfo = {}; + createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + createInfo.image = target->offscreenDepthImages[i]; + createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; + createInfo.format = VK_FORMAT_D32_SFLOAT; + createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; + createInfo.subresourceRange.levelCount = 1; + createInfo.subresourceRange.layerCount = 1; + + vkCreateImageView(device_, &createInfo, nullptr, &target->offscreenDepthImageViews[i]); } // offscreen framebuffer { + const std::array attachments = { + target->offscreenColorImageViews[i], + target->offscreenDepthImageViews[i] + }; + VkFramebufferCreateInfo framebufferInfo = {}; framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; framebufferInfo.renderPass = worldPass_->getRenderPass(); - framebufferInfo.attachmentCount = 1; - framebufferInfo.pAttachments = &target->offscreenImageViews[i]; + framebufferInfo.attachmentCount = attachments.size(); + framebufferInfo.pAttachments = attachments.data(); framebufferInfo.width = target->extent.width; framebufferInfo.height = target->extent.height; framebufferInfo.layers = 1; @@ -320,9 +371,14 @@ void Renderer::destroyRenderTarget(RenderTarget* target) { for(uint32_t i = 0; i < target->numImages; i++) { vkDestroyFramebuffer(device_, target->offscreenFramebuffers[i], nullptr); - vkDestroyImageView(device_, target->offscreenImageViews[i], nullptr); - vkFreeMemory(device_, target->offscreenMemory[i], nullptr); - vkDestroyImage(device_, target->offscreenImages[i], nullptr); + + vkDestroyImageView(device_, target->offscreenDepthImageViews[i], nullptr); + vkFreeMemory(device_, target->offscreenDepthMemory[i], nullptr); + vkDestroyImage(device_, target->offscreenDepthImages[i], nullptr); + + vkDestroyImageView(device_, target->offscreenColorImageViews[i], nullptr); + vkFreeMemory(device_, target->offscreenColorMemory[i], nullptr); + vkDestroyImage(device_, target->offscreenColorImages[i], nullptr); vkDestroyFramebuffer(device_, target->swapchainFramebuffers[i], nullptr); vkDestroyImageView(device_, target->swapchainImageViews[i], nullptr); diff --git a/src/worldpass.cpp b/src/worldpass.cpp index c056a3f..3068be8 100644 --- a/src/worldpass.cpp +++ b/src/worldpass.cpp @@ -41,15 +41,16 @@ void WorldPass::render(VkCommandBuffer commandBuffer, World& world, RenderTarget vkUnmapMemory(renderer_.getDevice(), lightMemory_); - VkClearValue clearColor = {}; + std::array clearColor = {}; + clearColor[1].depthStencil.depth = 1.0f; VkRenderPassBeginInfo renderPassBeginInfo = {}; renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; renderPassBeginInfo.framebuffer = target->offscreenFramebuffers[target->currentImage]; renderPassBeginInfo.renderPass = renderPass_; renderPassBeginInfo.renderArea.extent = target->extent; - renderPassBeginInfo.clearValueCount = 1; - renderPassBeginInfo.pClearValues = &clearColor; + renderPassBeginInfo.clearValueCount = clearColor.size(); + renderPassBeginInfo.pClearValues = clearColor.data(); vkCmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); @@ -83,19 +84,39 @@ void WorldPass::createRenderPass() { colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; colorAttachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + + VkAttachmentDescription depthAttachment = {}; + depthAttachment.format = VK_FORMAT_D32_SFLOAT; + depthAttachment.samples = VK_SAMPLE_COUNT_1_BIT; + depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + depthAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + depthAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + depthAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + depthAttachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; VkAttachmentReference colorAttachmentRef = {}; colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + VkAttachmentReference depthAttachmentRef = {}; + depthAttachmentRef.attachment = 1; + depthAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + VkSubpassDescription subpass = {}; subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; subpass.colorAttachmentCount = 1; subpass.pColorAttachments = &colorAttachmentRef; + subpass.pDepthStencilAttachment = &depthAttachmentRef; + + const std::array attachments = { + colorAttachment, + depthAttachment + }; VkRenderPassCreateInfo renderPassInfo = {}; renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - renderPassInfo.attachmentCount = 1; - renderPassInfo.pAttachments = &colorAttachment; + renderPassInfo.attachmentCount = attachments.size(); + renderPassInfo.pAttachments = attachments.data(); renderPassInfo.subpassCount = 1; renderPassInfo.pSubpasses = &subpass; @@ -181,6 +202,12 @@ void WorldPass::createPipeline() { colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; colorBlendAttachment.blendEnable = VK_FALSE; + VkPipelineDepthStencilStateCreateInfo depthState = {}; + depthState.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; + depthState.depthTestEnable = true; + depthState.depthWriteEnable = true; + depthState.depthCompareOp = VK_COMPARE_OP_LESS; + VkPipelineColorBlendStateCreateInfo colorBlending = {}; colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; colorBlending.attachmentCount = 1; @@ -218,6 +245,7 @@ void WorldPass::createPipeline() { pipelineInfo.pViewportState = &viewportState; pipelineInfo.pRasterizationState = &rasterizer; pipelineInfo.pMultisampleState = &multisampling; + pipelineInfo.pDepthStencilState = &depthState; pipelineInfo.pColorBlendState = &colorBlending; pipelineInfo.pDynamicState = &dynamicState; pipelineInfo.layout = pipelineLayout_;