From 14dabd5af0ea495c4dc11a7b48e205e6d0197d9c Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Tue, 4 Oct 2022 10:07:35 -0400 Subject: [PATCH] Add last bits for proper framebuffer creation, color clear now works --- src/pc/gfx/gfx_vulkan.cpp | 110 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 106 insertions(+), 4 deletions(-) diff --git a/src/pc/gfx/gfx_vulkan.cpp b/src/pc/gfx/gfx_vulkan.cpp index 387c511..42d0f52 100644 --- a/src/pc/gfx/gfx_vulkan.cpp +++ b/src/pc/gfx/gfx_vulkan.cpp @@ -22,6 +22,10 @@ static VkFormat surface_format; static std::vector swapchain_images; static std::vector swapchain_views; static VkRenderPass render_pass = VK_NULL_HANDLE; +static VkImage depth_image = VK_NULL_HANDLE; +static VkDeviceMemory depth_memory = VK_NULL_HANDLE; +static VkImageView depth_view = VK_NULL_HANDLE; +static std::vector swapchain_framebuffers; // TODO: removed hardcoded 3 frame queue, should be variable static std::array command_buffers; @@ -101,6 +105,21 @@ static void gfx_vulkan_renderer_set_use_alpha(bool use_alpha) { static void gfx_vulkan_renderer_draw_triangles(float buf_vbo[], size_t buf_vbo_len, size_t buf_vbo_num_tris) { } +static uint32_t gfx_vulkan_find_memory_type(uint32_t type_filter, VkMemoryPropertyFlags properties) { + VkPhysicalDeviceMemoryProperties memory_properties; + vkGetPhysicalDeviceMemoryProperties(physical_device, &memory_properties); + + for (uint32_t i = 0; i < memory_properties.memoryTypeCount; i++) { + if ((type_filter & (1 << i)) && + (memory_properties.memoryTypes[i].propertyFlags & properties) == + properties) { + return i; + } + } + + return -1; +} + static void gfx_vulkan_create_instance() { std::vector instance_extensions = {"VK_EXT_debug_utils"}; @@ -450,12 +469,75 @@ static void gfx_vulkan_create_sync() { } } +static void gfx_vulkan_create_depth() { + VkImageCreateInfo image_create_info = {}; + image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + image_create_info.imageType = VK_IMAGE_TYPE_2D; + image_create_info.extent.width = 640; + image_create_info.extent.height = 480; + image_create_info.extent.depth = 1; + image_create_info.mipLevels = 1; + image_create_info.arrayLayers = 1; + image_create_info.format = VK_FORMAT_D32_SFLOAT; + image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; + image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + image_create_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; + image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + + vkCreateImage(device, &image_create_info, nullptr, &depth_image); + + VkMemoryRequirements memory_requirements; + vkGetImageMemoryRequirements(device, depth_image, &memory_requirements); + + VkMemoryAllocateInfo allocate_info = {}; + allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + allocate_info.allocationSize = memory_requirements.size; + allocate_info.memoryTypeIndex = gfx_vulkan_find_memory_type(memory_requirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + + vkAllocateMemory(device, &allocate_info, nullptr, &depth_memory); + + vkBindImageMemory(device, depth_image, depth_memory, 0); + + VkImageViewCreateInfo view_create_info = {}; + view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + view_create_info.image = depth_image; + view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D; + view_create_info.format = VK_FORMAT_D32_SFLOAT; + view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; + view_create_info.subresourceRange.levelCount = 1; + view_create_info.subresourceRange.layerCount = 1; + + vkCreateImageView(device, &view_create_info, nullptr, &depth_view); +} + +static void gfx_vulkan_create_framebuffers() { + swapchain_framebuffers.resize(swapchain_views.size()); + + for (size_t i = 0; i < swapchain_framebuffers.size(); i++) { + std::array attachments = {swapchain_views[i], depth_view}; + + VkFramebufferCreateInfo create_info = {}; + create_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; + create_info.renderPass = render_pass; + create_info.attachmentCount = attachments.size(); + create_info.pAttachments = attachments.data(); + create_info.width = 640; + create_info.height = 480; + create_info.layers = 1; + + vkCreateFramebuffer(device, &create_info, nullptr, &swapchain_framebuffers[i]); + } +} + static void gfx_vulkan_renderer_init(void) { gfx_vulkan_create_instance(); gfx_vulkan_create_device(); gfx_vulkan_create_swapchain(); gfx_vulkan_create_render_pass(); gfx_vulkan_create_sync(); + gfx_vulkan_create_depth(); + gfx_vulkan_create_framebuffers(); } static void gfx_vulkan_renderer_on_resize(void) { @@ -482,14 +564,34 @@ static void gfx_vulkan_renderer_start_frame(void) { current_cmd = command_buffers[current_frame]; - VkCommandBufferBeginInfo beginInfo = {}; - beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - beginInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; + VkCommandBufferBeginInfo buffer_begin = {}; + buffer_begin.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + buffer_begin.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; - vkBeginCommandBuffer(current_cmd, &beginInfo); + vkBeginCommandBuffer(current_cmd, &buffer_begin); + + VkRenderPassBeginInfo render_pass_begin = {}; + render_pass_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + render_pass_begin.renderPass = render_pass; + render_pass_begin.framebuffer = swapchain_framebuffers[image_index]; + + std::array clear_values = {}; + clear_values[0].color.float32[0] = 0.8; + clear_values[0].color.float32[1] = 0.8; + clear_values[0].color.float32[2] = 0.8; + clear_values[0].color.float32[3] = 1.0; + clear_values[1].depthStencil = {1.0f, 0}; + + render_pass_begin.clearValueCount = clear_values.size(); + render_pass_begin.pClearValues = clear_values.data(); + render_pass_begin.renderArea.extent.width = 640; + render_pass_begin.renderArea.extent.height = 480; + + vkCmdBeginRenderPass(current_cmd, &render_pass_begin, VK_SUBPASS_CONTENTS_INLINE); } static void gfx_vulkan_renderer_end_frame(void) { + vkCmdEndRenderPass(current_cmd); vkEndCommandBuffer(current_cmd); }