Vulkan: depth buffer

This commit is contained in:
Attila Uygun 2021-01-26 23:07:29 +01:00
parent 744d4485eb
commit 68b6b1dfea
3 changed files with 180 additions and 20 deletions

View File

@ -533,6 +533,15 @@ void RendererVulkan::CreateShader(std::shared_ptr<void> impl_data,
color_blending.blendConstants[2] = 0.0f;
color_blending.blendConstants[3] = 0.0f;
VkPipelineDepthStencilStateCreateInfo depth_stencil{};
depth_stencil.sType =
VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
depth_stencil.depthTestEnable = VK_TRUE;
depth_stencil.depthWriteEnable = VK_TRUE;
depth_stencil.depthCompareOp = VK_COMPARE_OP_LESS;
depth_stencil.depthBoundsTestEnable = VK_FALSE;
depth_stencil.stencilTestEnable = VK_FALSE;
std::vector<VkDynamicState> dynamic_states;
dynamic_states.push_back(VK_DYNAMIC_STATE_VIEWPORT);
dynamic_states.push_back(VK_DYNAMIC_STATE_SCISSOR);
@ -555,6 +564,7 @@ void RendererVulkan::CreateShader(std::shared_ptr<void> impl_data,
pipeline_info.pRasterizationState = &rasterizer;
pipeline_info.pMultisampleState = &multisampling;
pipeline_info.pColorBlendState = &color_blending;
pipeline_info.pDepthStencilState = &depth_stencil;
pipeline_info.pDynamicState = &dynamic_state_create_info;
pipeline_info.layout = shader->pipeline_layout;
pipeline_info.renderPass = context_.GetRenderPass();
@ -1746,15 +1756,12 @@ void RendererVulkan::DrawListBegin() {
render_pass_begin.renderArea.offset.x = 0;
render_pass_begin.renderArea.offset.y = 0;
render_pass_begin.clearValueCount = 1;
std::array<VkClearValue, 2> clear_values;
clear_values[0].color = {{0.0f, 0.0f, 0.0f, 1.0f}};
clear_values[1].depthStencil = {1.0f, 0};
VkClearValue clear_value;
clear_value.color.float32[0] = 0;
clear_value.color.float32[1] = 0;
clear_value.color.float32[2] = 0;
clear_value.color.float32[3] = 1;
render_pass_begin.pClearValues = &clear_value;
render_pass_begin.clearValueCount = clear_values.size();
render_pass_begin.pClearValues = clear_values.data();
vkCmdBeginRenderPass(command_buffer, &render_pass_begin,
VK_SUBPASS_CONTENTS_INLINE);

View File

@ -1,6 +1,7 @@
#include "vulkan_context.h"
#include <string.h>
#include <array>
#include <limits>
#include <string>
@ -401,11 +402,13 @@ bool VulkanContext::CreatePhysicalDevice() {
if (instance_ == VK_NULL_HANDLE) {
VkResult err = vkCreateInstance(&inst_info, nullptr, &instance_);
if (err == VK_ERROR_INCOMPATIBLE_DRIVER) {
DLOG << "Cannot find a compatible Vulkan installable client driver (ICD).";
DLOG
<< "Cannot find a compatible Vulkan installable client driver (ICD).";
return false;
}
if (err == VK_ERROR_EXTENSION_NOT_PRESENT) {
DLOG << "Cannot find a specified extension library. Make sure your layers "
DLOG
<< "Cannot find a specified extension library. Make sure your layers "
"path is set appropriately. ";
return false;
}
@ -799,6 +802,13 @@ bool VulkanContext::CleanUpSwapChain(Window* window) {
vkDeviceWaitIdle(device_);
vkDestroyImageView(device_, window->depth_view, nullptr);
vkDestroyImage(device_, window->depth_image, nullptr);
vkFreeMemory(device_, window->depth_image_memory, nullptr);
window->depth_view = VK_NULL_HANDLE;
window->depth_image = VK_NULL_HANDLE;
window->depth_image_memory = VK_NULL_HANDLE;
DestroySwapchainKHR(device_, window->swapchain, nullptr);
window->swapchain = VK_NULL_HANDLE;
vkDestroyRenderPass(device_, window->render_pass, nullptr);
@ -1064,7 +1074,7 @@ bool VulkanContext::UpdateSwapChain(Window* window) {
// Framebuffer
{
const VkAttachmentDescription attachment = {
const VkAttachmentDescription color_attachment = {
/*flags*/ 0,
/*format*/ format_,
/*samples*/ VK_SAMPLE_COUNT_1_BIT,
@ -1081,6 +1091,23 @@ bool VulkanContext::UpdateSwapChain(Window* window) {
/*layout*/ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
};
const VkAttachmentDescription depth_attachment = {
/*flags*/ 0,
/*format*/ VK_FORMAT_D24_UNORM_S8_UINT,
/*samples*/ VK_SAMPLE_COUNT_1_BIT,
/*loadOp*/ VK_ATTACHMENT_LOAD_OP_CLEAR,
/*storeOp*/ VK_ATTACHMENT_STORE_OP_DONT_CARE,
/*stencilLoadOp*/ VK_ATTACHMENT_LOAD_OP_DONT_CARE,
/*stencilStoreOp*/ VK_ATTACHMENT_STORE_OP_DONT_CARE,
/*initialLayout*/ VK_IMAGE_LAYOUT_UNDEFINED,
/*finalLayout*/ VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
};
const VkAttachmentReference depth_reference = {
/*attachment*/ 1,
/*layout*/ VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
};
const VkSubpassDescription subpass = {
/*flags*/ 0,
/*pipelineBindPoint*/ VK_PIPELINE_BIND_POINT_GRAPHICS,
@ -1089,20 +1116,36 @@ bool VulkanContext::UpdateSwapChain(Window* window) {
/*colorAttachmentCount*/ 1,
/*pColorAttachments*/ &color_reference,
/*pResolveAttachments*/ nullptr,
/*pDepthStencilAttachment*/ nullptr,
/*pDepthStencilAttachment*/ &depth_reference,
/*preserveAttachmentCount*/ 0,
/*pPreserveAttachments*/ nullptr,
};
VkSubpassDependency dependency = {
/*srcSubpass*/ VK_SUBPASS_EXTERNAL,
/*dstSubpass*/ 0,
/*srcStageMask*/ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
/*dstStageMask*/ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
/*srcAccessMask*/ 0,
/*dstAccessMask*/ VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
/*dependencyFlags*/ 0,
};
std::array<VkAttachmentDescription, 2> attachments = {color_attachment,
depth_attachment};
const VkRenderPassCreateInfo rp_info = {
/*sTyp*/ VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
/*pNext*/ nullptr,
/*flags*/ 0,
/*attachmentCount*/ 1,
/*pAttachments*/ &attachment,
/*attachmentCount*/ attachments.size(),
/*pAttachments*/ attachments.data(),
/*subpassCount*/ 1,
/*pSubpasses*/ &subpass,
/*dependencyCount*/ 0,
/*pDependencies*/ nullptr,
/*dependencyCount*/ 1,
/*pDependencies*/ &dependency,
};
err = vkCreateRenderPass(device_, &rp_info, nullptr, &window->render_pass);
@ -1111,14 +1154,18 @@ bool VulkanContext::UpdateSwapChain(Window* window) {
return false;
}
CreateDepthImage(window);
for (uint32_t i = 0; i < swapchain_image_count_; i++) {
std::array<VkImageView, 2> attachments = {
window->swapchain_image_resources[i].view, window->depth_view};
const VkFramebufferCreateInfo fb_info = {
/*sType*/ VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
/*pNext*/ nullptr,
/*flags*/ 0,
/*renderPass*/ window->render_pass,
/*attachmentCount*/ 1,
/*pAttachments*/ &window->swapchain_image_resources[i].view,
/*attachmentCount*/ attachments.size(),
/*pAttachments*/ attachments.data(),
/*width*/ (uint32_t)window->width,
/*height*/ (uint32_t)window->height,
/*layers*/ 1,
@ -1212,6 +1259,108 @@ bool VulkanContext::UpdateSwapChain(Window* window) {
return true;
}
bool VulkanContext::CreateDepthImage(Window* window) {
VkImageCreateInfo depth_image_ci = {
/*sType*/ VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
/*pNext*/ nullptr,
/*flags*/ 0,
/*imageType*/ VK_IMAGE_TYPE_2D,
/*format*/ VK_FORMAT_D24_UNORM_S8_UINT,
/*extent*/
{
/*width*/ window->swapchain_extent.width,
/*height*/ window->swapchain_extent.height,
/*depth*/ 1,
},
/*mipLevels*/ 1,
/*arrayLayers*/ 1,
/*samples*/ VK_SAMPLE_COUNT_1_BIT,
/*tiling*/ VK_IMAGE_TILING_OPTIMAL,
/*usage*/ VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
/*sharingMode*/ VK_SHARING_MODE_EXCLUSIVE,
/*queueFamilyIndexCount*/ 0,
/*pQueueFamilyIndices*/ nullptr,
/*initialLayout*/ VK_IMAGE_LAYOUT_UNDEFINED,
};
VkResult err =
vkCreateImage(device_, &depth_image_ci, nullptr, &window->depth_image);
if (err) {
DLOG << "vkCreateImage failed. Error: " << err;
return false;
}
VkMemoryRequirements mem_requirements;
vkGetImageMemoryRequirements(device_, window->depth_image, &mem_requirements);
VkPhysicalDeviceMemoryProperties memProperties;
vkGetPhysicalDeviceMemoryProperties(gpu_, &memProperties);
uint32_t mti = 0;
for (; mti < memProperties.memoryTypeCount; mti++) {
if ((mem_requirements.memoryTypeBits & (1 << mti)) &&
(memProperties.memoryTypes[mti].propertyFlags &
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) ==
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) {
break;
}
}
if (mti == memProperties.memoryTypeCount) {
DLOG << "Memort type index not found.";
return false;
}
VkMemoryAllocateInfo alloc_info = {
/*sType*/ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
/*pNext*/ nullptr,
/*allocationSize*/ mem_requirements.size,
/*memoryTypeIndex*/ mti,
};
err = vkAllocateMemory(device_, &alloc_info, nullptr,
&window->depth_image_memory);
if (err) {
DLOG << "vkAllocateMemory failed. Error: " << err;
return false;
}
vkBindImageMemory(device_, window->depth_image, window->depth_image_memory,
0);
VkImageViewCreateInfo image_view_create_info = {
/*sType*/ VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
/*pNext*/ nullptr,
/*flags*/ 0,
/*image*/ window->depth_image,
/*viewType*/ VK_IMAGE_VIEW_TYPE_2D,
/*format*/ VK_FORMAT_D24_UNORM_S8_UINT,
/*components*/
{
/*r*/ VK_COMPONENT_SWIZZLE_R,
/*g*/ VK_COMPONENT_SWIZZLE_G,
/*b*/ VK_COMPONENT_SWIZZLE_B,
/*a*/ VK_COMPONENT_SWIZZLE_A,
},
/*subresourceRange*/
{
/*aspectMask*/ VK_IMAGE_ASPECT_DEPTH_BIT,
/*baseMipLevel*/ 0,
/*levelCount*/ 1,
/*baseArrayLayer*/ 0,
/*layerCount*/ 1,
},
};
err = vkCreateImageView(device_, &image_view_create_info, nullptr,
&window->depth_view);
if (err) {
vkDestroyImage(device_, window->depth_image, nullptr);
vkFreeMemory(device_, window->depth_image_memory, nullptr);
DLOG << "vkCreateImageView failed with error " << std::to_string(err);
return false;
}
return true;
}
void VulkanContext::AppendCommandBuffer(const VkCommandBuffer& command_buffer,
bool front) {
if (front)

View File

@ -81,6 +81,9 @@ class VulkanContext {
VkSurfaceKHR surface = VK_NULL_HANDLE;
VkSwapchainKHR swapchain = VK_NULL_HANDLE;
std::unique_ptr<SwapchainImageResources[]> swapchain_image_resources;
VkImage depth_image = VK_NULL_HANDLE;
VkDeviceMemory depth_image_memory = VK_NULL_HANDLE;
VkImageView depth_view = VK_NULL_HANDLE;
uint32_t current_buffer = 0;
int width = 0;
int height = 0;
@ -178,7 +181,8 @@ class VulkanContext {
bool UpdateSwapChain(Window* window);
bool CreateSwapChain();
bool CreateDepthImage(Window* window);
bool CreateSemaphores();
const char* GetPlatformSurfaceExtension() const;