diff options
| author | ladevieq <ladevie.quentin@gmail.com> | 2021-02-22 23:08:42 +0100 |
|---|---|---|
| committer | ladevieq <ladevie.quentin@gmail.com> | 2021-02-22 23:08:42 +0100 |
| commit | 769c8ef8aa429cf13bac920607690d104dd4d3ed (patch) | |
| tree | bdb02dfae5f673cbb8b874db3a9d016d5a7177d8 /src | |
| parent | 45783d96ec6f84893c85789ff5e5e2243e7f3db9 (diff) | |
Fix framebuffer validation errors
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.cpp | 7 | ||||
| -rw-r--r-- | src/vk-api.cpp | 46 | ||||
| -rw-r--r-- | src/vk-renderer.cpp | 108 |
3 files changed, 112 insertions, 49 deletions
diff --git a/src/main.cpp b/src/main.cpp index 120f8ed..5098f5d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,7 +4,6 @@ #include <cstdio> #include <cassert> -#include "imgui.h" #include "thirdparty/renderdoc.h" #include "vk-renderer.hpp" @@ -58,8 +57,6 @@ int main() { auto canRender = true; vkrenderer renderer { wnd, inputs }; - ImGui::Text("Hello, world %d", 123); - while(wnd.isOpen) { end = std::chrono::high_resolution_clock::now(); @@ -140,11 +137,11 @@ int main() { if (canRender) { renderer.begin_frame(); - // renderer.ui(); + renderer.ui(); if (((input_data*) renderer.compute_shader_buffer.mapped_ptr)->sample_index < samples_per_pixel) { bool clear = ((input_data*) renderer.compute_shader_buffer.mapped_ptr)->sample_index == 0; - renderer.compute(width, height, clear); + // renderer.compute(width, height, clear); ((input_data*) renderer.compute_shader_buffer.mapped_ptr)->sample_index++; } diff --git a/src/vk-api.cpp b/src/vk-api.cpp index eb5411a..6dd1f5b 100644 --- a/src/vk-api.cpp +++ b/src/vk-api.cpp @@ -46,9 +46,13 @@ vkapi::~vkapi() { } -Buffer vkapi::create_buffer(size_t data_size, VkBufferUsageFlags buffer_usage, VmaMemoryUsage mem_usage) { +Buffer vkapi::create_buffer(size_t data_size, VkBufferUsageFlags buffer_usage, VmaMemoryUsage mem_usage, void* ptr) { Buffer buffer = {}; + if (ptr) { + buffer.mapped_ptr = ptr; + } + VkBufferCreateInfo buffer_info = { }; buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; buffer_info.size = data_size; @@ -70,9 +74,13 @@ void vkapi::destroy_buffer(Buffer& buffer) { } -Image vkapi::create_image(VkExtent3D size, VkFormat format, VkImageUsageFlags usages) { +Image vkapi::create_image(VkExtent3D size, VkFormat format, VkImageUsageFlags usages, void* ptr) { Image image; + if (ptr) { + image.mapped_ptr = ptr; + } + image.size = size; image.subresource_range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; @@ -131,7 +139,7 @@ std::vector<Image> vkapi::create_images(VkExtent3D size, VkFormat format, VkImag std::vector<Image> images { image_count }; for (size_t image_index = 0; image_index < image_count; image_index++) { - images[image_index] = create_image(size, format, usages); + images[image_index] = create_image(size, format, usages, nullptr); } return std::move(images); @@ -242,14 +250,16 @@ VkRenderPass vkapi::create_render_pass(std::vector<VkFormat>& color_attachments_ attachment_description.samples = VK_SAMPLE_COUNT_1_BIT; attachment_description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; attachment_description.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attachment_description.initialLayout = VK_IMAGE_LAYOUT_GENERAL; // TODO: Change this - attachment_description.finalLayout = VK_IMAGE_LAYOUT_GENERAL; + attachment_description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attachment_description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + attachment_description.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; // TODO: Change this + attachment_description.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; attachments_description.push_back(attachment_description); VkAttachmentReference attachment_reference = {}; attachment_reference.attachment = attachment_index; - attachment_reference.layout = VK_IMAGE_LAYOUT_GENERAL; + attachment_reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; attachments_reference.push_back(attachment_reference); } @@ -260,6 +270,9 @@ VkRenderPass vkapi::create_render_pass(std::vector<VkFormat>& color_attachments_ subpass_description.colorAttachmentCount = attachments_reference.size(); subpass_description.pColorAttachments = attachments_reference.data(); subpass_description.pDepthStencilAttachment = VK_NULL_HANDLE; + subpass_description.pResolveAttachments = VK_NULL_HANDLE; + subpass_description.preserveAttachmentCount = 0; + subpass_description.pPreserveAttachments = VK_NULL_HANDLE; VkRenderPass render_pass; VkRenderPassCreateInfo create_info = {}; @@ -276,7 +289,7 @@ VkRenderPass vkapi::create_render_pass(std::vector<VkFormat>& color_attachments_ return render_pass; } -void vkapi::destroy_renderpass(VkRenderPass render_pass) { +void vkapi::destroy_render_pass(VkRenderPass render_pass) { vkDestroyRenderPass(context.device, render_pass, VK_NULL_HANDLE); } @@ -400,7 +413,7 @@ Pipeline vkapi::create_graphics_pipeline(const char* shader_name, std::vector<Vk std::vector<VkPipelineShaderStageCreateInfo> stages_create_info = {}; - for (VkShaderStageFlags stage_flag = VK_SHADER_STAGE_VERTEX_BIT; stage_flag <= VK_SHADER_STAGE_ALL_GRAPHICS; stage_flag >>= 2) { + for (VkShaderStageFlags stage_flag = VK_SHADER_STAGE_VERTEX_BIT; stage_flag <= VK_SHADER_STAGE_ALL_GRAPHICS; stage_flag <<= 2) { if (stage_flag & shader_stages) { VkShaderModule shader_module; @@ -426,7 +439,7 @@ Pipeline vkapi::create_graphics_pipeline(const char* shader_name, std::vector<Vk stage_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; stage_create_info.pNext = nullptr; stage_create_info.flags = 0; - stage_create_info.stage = VK_SHADER_STAGE_COMPUTE_BIT; + stage_create_info.stage = (VkShaderStageFlagBits)stage_flag; stage_create_info.module = shader_module; stage_create_info.pName = "main"; stage_create_info.pSpecializationInfo = nullptr; @@ -497,12 +510,13 @@ Pipeline vkapi::create_graphics_pipeline(const char* shader_name, std::vector<Vk rasterization_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; rasterization_state_create_info.pNext = nullptr; rasterization_state_create_info.flags = 0; - rasterization_state_create_info.depthClampEnable = VK_TRUE; + rasterization_state_create_info.depthClampEnable = VK_FALSE; rasterization_state_create_info.rasterizerDiscardEnable = VK_TRUE; rasterization_state_create_info.polygonMode = VK_POLYGON_MODE_FILL; rasterization_state_create_info.cullMode = VK_CULL_MODE_BACK_BIT; rasterization_state_create_info.frontFace = VK_FRONT_FACE_CLOCKWISE; rasterization_state_create_info.depthBiasEnable = VK_FALSE; + rasterization_state_create_info.lineWidth = 1.f; VkPipelineMultisampleStateCreateInfo multisample_state_create_info = {}; multisample_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; @@ -607,7 +621,7 @@ void vkapi::destroy_surface(VkSurfaceKHR surface) { } -Swapchain vkapi::create_swapchain(VkSurfaceKHR surface, size_t min_image_count, VkImageUsageFlags usages, std::optional<Swapchain> old_swapchain) { +Swapchain vkapi::create_swapchain(VkSurfaceKHR surface, size_t min_image_count, VkImageUsageFlags usages, std::optional<std::reference_wrapper<Swapchain>> old_swapchain) { Swapchain swapchain; VkBool32 queue_support_presentation = VK_FALSE; VKRESULT(vkGetPhysicalDeviceSurfaceSupportKHR(context.physical_device, context.queue_index, surface, &queue_support_presentation)) @@ -644,7 +658,7 @@ Swapchain vkapi::create_swapchain(VkSurfaceKHR surface, size_t min_image_count, VKRESULT(vkGetPhysicalDeviceSurfacePresentModesKHR(context.physical_device, surface, &supported_present_modes_count, supported_present_modes.data())) swapchain.surface_format = supported_formats[0]; - VkSwapchainKHR old_swapchain_handle = (old_swapchain != std::nullopt) ? old_swapchain.value().handle : VK_NULL_HANDLE; + VkSwapchainKHR old_swapchain_handle = (old_swapchain != std::nullopt) ? old_swapchain.value().get().handle : VK_NULL_HANDLE; VkSwapchainCreateInfoKHR create_info = {}; create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; @@ -719,7 +733,7 @@ Swapchain vkapi::create_swapchain(VkSurfaceKHR surface, size_t min_image_count, return std::move(swapchain); } -void vkapi::destroy_swapchain(Swapchain swapchain) { +void vkapi::destroy_swapchain(Swapchain& swapchain) { for(auto &image: swapchain.images) { vkDestroyImageView(context.device, image.view, nullptr); } @@ -739,8 +753,8 @@ void vkapi::update_descriptor_set_buffer(VkDescriptorSet set, VkDescriptorSetLay write_descriptor.dstSet = set; write_descriptor.dstBinding = binding.binding; write_descriptor.dstArrayElement = 0; - write_descriptor.descriptorCount = 1; - write_descriptor.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + write_descriptor.descriptorCount = binding.descriptorCount; + write_descriptor.descriptorType = binding.descriptorType; write_descriptor.pImageInfo = VK_NULL_HANDLE; write_descriptor.pBufferInfo = &descriptor_buffer_info; write_descriptor.pTexelBufferView = VK_NULL_HANDLE; @@ -865,7 +879,7 @@ VkResult vkapi::submit(VkCommandBuffer command_buffer, VkSemaphore wait_semaphor return vkQueueSubmit(context.queue, 1, &submit_info, submission_fence); } -VkResult vkapi::present(Swapchain swapchain, uint32_t image_index, VkSemaphore wait_semaphore) { +VkResult vkapi::present(Swapchain& swapchain, uint32_t image_index, VkSemaphore wait_semaphore) { VkPresentInfoKHR present_info = {}; present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; present_info.pNext = nullptr; diff --git a/src/vk-renderer.cpp b/src/vk-renderer.cpp index 21918cb..ae677a6 100644 --- a/src/vk-renderer.cpp +++ b/src/vk-renderer.cpp @@ -45,13 +45,11 @@ vkrenderer::vkrenderer(window& wnd, const input_data& inputs) { .pImmutableSamplers = VK_NULL_HANDLE, } }; - compute_pipeline = api.create_compute_pipeline("compute", bindings); + compute_shader_sets = api.create_descriptor_sets(compute_pipeline.descriptor_set_layout, swapchain.image_count); command_buffers = api.create_command_buffers(swapchain.image_count); - compute_shader_sets = api.create_descriptor_sets(compute_pipeline.descriptor_set_layout, swapchain.image_count); - VkExtent3D image_size = { .width = swapchain.extent.width, .height = swapchain.extent.height, @@ -63,32 +61,49 @@ vkrenderer::vkrenderer(window& wnd, const input_data& inputs) { execution_semaphores = api.create_semaphores(swapchain.image_count); acquire_semaphores = api.create_semaphores(swapchain.image_count); - // std::vector<VkFormat> attachments_format { swapchain.surface_format.format }; - // render_pass = api.create_render_pass(attachments_format); - - // std::vector<VkDescriptorSetLayoutBinding> ui_pipeline_bindings { - // { - // .binding = 0, - // .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - // .descriptorCount = 1, - // .stageFlags = VK_SHADER_STAGE_VERTEX_BIT, - // .pImmutableSamplers = VK_NULL_HANDLE, - // }, - // }; - // ui_pipeline = api.create_graphics_pipeline("ui", ui_pipeline_bindings, (VkShaderStageFlagBits)(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT), render_pass); - // ui_sets = api.create_descriptor_sets(ui_pipeline.descriptor_set_layout, swapchain.image_count); - - // for (auto& image : swapchain.images) { - // std::vector<Image> attachments { image }; - // framebuffers.push_back(api.create_framebuffer(render_pass, attachments, swapchain.extent)); - // } - - compute_shader_buffer = api.create_buffer(sizeof(inputs), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU); + compute_shader_buffer = api.create_buffer(sizeof(inputs), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU, nullptr); std::memcpy(compute_shader_buffer.mapped_ptr, &inputs, sizeof(inputs)); for (size_t index = 0; index < swapchain.image_count; index++) { api.update_descriptor_set_buffer(compute_shader_sets[index], bindings[0], compute_shader_buffer); } + + std::vector<VkFormat> attachments_format { swapchain.surface_format.format }; + render_pass = api.create_render_pass(attachments_format); + + for (auto& image : swapchain.images) { + std::vector<Image> attachments { image }; + framebuffers.push_back(api.create_framebuffer(render_pass, attachments, swapchain.extent)); + } + + std::vector<VkDescriptorSetLayoutBinding> ui_pipeline_bindings { + { + .binding = 0, + .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + .descriptorCount = 1, + .stageFlags = VK_SHADER_STAGE_VERTEX_BIT, + .pImmutableSamplers = VK_NULL_HANDLE, + }, + }; + ui_pipeline = api.create_graphics_pipeline("ui", ui_pipeline_bindings, (VkShaderStageFlagBits)(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT), render_pass); + ui_sets = api.create_descriptor_sets(ui_pipeline.descriptor_set_layout, swapchain.image_count); + + ImGui::CreateContext(); + auto io = ImGui::GetIO(); + + ImGui::StyleColorsDark(); + + uint8_t* pixels = nullptr; + int atlas_width, atlas_height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &atlas_width, &atlas_height); + + VkExtent3D atlas_size = { + .width = (uint32_t)atlas_width, + .height = (uint32_t)atlas_height, + .depth = 1, + }; + ui_texture = api.create_image(atlas_size, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, pixels); + io.Fonts->SetTexID((void*)&ui_texture); } vkrenderer::~vkrenderer() { @@ -102,8 +117,17 @@ vkrenderer::~vkrenderer() { api.destroy_descriptor_sets(compute_shader_sets); api.destroy_images(accumulation_images); + api.destroy_render_pass(render_pass); + + api.destroy_image(ui_texture); + + for (auto& framebuffer: framebuffers) { + api.destroy_framebuffer(framebuffer); + } + api.destroy_command_buffers(command_buffers); api.destroy_pipeline(compute_pipeline); + api.destroy_pipeline(ui_pipeline); api.destroy_swapchain(swapchain); api.destroy_surface(platform_surface); @@ -145,19 +169,31 @@ void vkrenderer::begin_frame() { } void vkrenderer::ui() { + ImGuiIO& io = ImGui::GetIO(); + io.DisplaySize.x = (float)swapchain.extent.width; + io.DisplaySize.y = (float)swapchain.extent.height; + io.DisplayFramebufferScale = { 1.f, 1.f }; + ImGui::NewFrame(); + + ImGui::Text("Hello, world!"); + + ImGui::EndFrame(); + ImGui::Render(); ImDrawData* draw_data = ImGui::GetDrawData(); + // TODO: Deallocate buffer when not used anymore + // Update descriptor with only the part of the buffer we are interested in for (size_t cmd_index = 0; cmd_index < draw_data->CmdListsCount; cmd_index++) { ImDrawList* draw_list = draw_data->CmdLists[cmd_index]; ImVector vertex_buffer = draw_list->VtxBuffer; ImVector index_buffer = draw_list->IdxBuffer; - auto vk_vtx_buf = api.create_buffer(vertex_buffer.Size * sizeof(vertex_buffer.Data[0]), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU); + auto vk_vtx_buf = api.create_buffer(vertex_buffer.Size * sizeof(vertex_buffer.Data[0]), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU, nullptr); std::memcpy(vk_vtx_buf.mapped_ptr, vertex_buffer.Data, vertex_buffer.Size * sizeof(vertex_buffer.Data[0])); - auto vk_idx_buf = api.create_buffer(index_buffer.Size * sizeof(index_buffer.Data[0]), VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU); + auto vk_idx_buf = api.create_buffer(index_buffer.Size * sizeof(index_buffer.Data[0]), VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU, nullptr); std::memcpy(vk_idx_buf.mapped_ptr, index_buffer.Data, index_buffer.Size * sizeof(index_buffer.Data[0])); ui_vertex_buffers.push_back(vk_vtx_buf); @@ -183,6 +219,7 @@ void vkrenderer::ui() { render_pass_begin_info.clearValueCount = 1; render_pass_begin_info.pClearValues = &clear_value; + api.image_barrier(cmd_buf, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, swapchain.images[swapchain_image_index]); vkCmdBeginRenderPass(cmd_buf, &render_pass_begin_info, VK_SUBPASS_CONTENTS_INLINE); vkCmdBindDescriptorSets(cmd_buf, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_pipeline.layout, 0, 1, &ui_sets[frame_index], 0, nullptr); @@ -200,7 +237,7 @@ void vkrenderer::ui() { for (size_t cmd_index = 0; cmd_index < draw_data->CmdListsCount; cmd_index++) { ImDrawList* draw_list = draw_data->CmdLists[cmd_index]; - api.update_descriptor_set_buffer(compute_shader_sets[frame_index], binding, ui_vertex_buffers[cmd_index]); + api.update_descriptor_set_buffer(ui_sets[frame_index], binding, ui_vertex_buffers[cmd_index]); vkCmdBindIndexBuffer(cmd_buf, ui_index_buffers[cmd_index].handle, 0, VK_INDEX_TYPE_UINT16); @@ -210,6 +247,8 @@ void vkrenderer::ui() { } vkCmdEndRenderPass(cmd_buf); + + api.image_barrier(cmd_buf, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, 0, swapchain.images[swapchain_image_index]); } void vkrenderer::compute(uint32_t width, uint32_t height, bool clear) { @@ -265,7 +304,7 @@ void vkrenderer::recreate_swapchain() { platform_surface, min_swapchain_image_count, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, - std::optional<Swapchain> { swapchain } + std::optional<std::reference_wrapper<Swapchain>> { swapchain } ); api.destroy_images(accumulation_images); @@ -275,6 +314,19 @@ void vkrenderer::recreate_swapchain() { .depth = 1, }; accumulation_images = api.create_images(image_size, swapchain.surface_format.format, VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, 2); + + for (auto& framebuffer: framebuffers) { + api.destroy_framebuffer(framebuffer); + } + framebuffers.clear(); + + std::vector<VkFormat> attachments_format { swapchain.surface_format.format }; + render_pass = api.create_render_pass(attachments_format); + + for (auto& image : swapchain.images) { + std::vector<Image> attachments { image }; + framebuffers.push_back(api.create_framebuffer(render_pass, attachments, swapchain.extent)); + } } void vkrenderer::handle_swapchain_result(VkResult function_result) { |
