aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/vk-api.hpp10
-rw-r--r--include/vk-renderer.hpp13
-rw-r--r--shaders/ui.frag5
-rw-r--r--shaders/ui.vert18
-rw-r--r--src/main.cpp5
-rw-r--r--src/vk-api.cpp100
-rw-r--r--src/vk-renderer.cpp114
7 files changed, 222 insertions, 43 deletions
diff --git a/include/vk-api.hpp b/include/vk-api.hpp
index 999b59e..4353064 100644
--- a/include/vk-api.hpp
+++ b/include/vk-api.hpp
@@ -69,12 +69,18 @@ class vkapi {
std::vector<VkCommandBuffer> create_command_buffers(size_t command_buffers_count);
void destroy_command_buffers(std::vector<VkCommandBuffer> &command_buffers);
- VkRenderPass create_render_pass(std::vector<VkFormat>& attachments_format);
+ VkRenderPass create_render_pass(std::vector<VkFormat>& color_attachments_format);
+ VkRenderPass create_render_pass(std::vector<VkFormat>& color_attachments_format, VkFormat depth_attachement_format);
void destroy_renderpass(VkRenderPass render_pass);
+ VkFramebuffer create_framebuffer(VkRenderPass render_pass, std::vector<Image>& images, VkExtent2D size);
+ std::vector<VkFramebuffer> create_framebuffers(VkRenderPass render_pass, std::vector<Image>& images, VkExtent2D size, uint32_t framebuffer_count);
+ void destroy_framebuffer(VkFramebuffer framebuffer);
+ void destroy_framebuffers(std::vector<VkFramebuffer>& framebuffers);
+
Pipeline create_compute_pipeline(const char* shader_name, std::vector<VkDescriptorSetLayoutBinding> bindings);
- Pipeline create_graphics_pipeline(const char* shader_name, VkShaderStageFlagBits shader_stages, std::vector<VkDescriptorSetLayoutBinding> bindings, VkRenderPass render_pass, uint32_t subpass);
+ Pipeline create_graphics_pipeline(const char* shader_name, std::vector<VkDescriptorSetLayoutBinding> bindings, VkShaderStageFlagBits shader_stages, VkRenderPass render_pass);
void destroy_pipeline(Pipeline &pipeline);
diff --git a/include/vk-renderer.hpp b/include/vk-renderer.hpp
index acbf0c9..a0edf39 100644
--- a/include/vk-renderer.hpp
+++ b/include/vk-renderer.hpp
@@ -15,10 +15,14 @@ class vkrenderer {
~vkrenderer();
+ void begin_frame();
+
void ui();
void compute(uint32_t width, uint32_t height, bool clear);
+ void finish_frame();
+
void recreate_swapchain();
Buffer compute_shader_buffer;
@@ -30,15 +34,22 @@ class vkrenderer {
vkapi api;
uint64_t frame_index = 0;
+ uint32_t swapchain_image_index = 0;
std::vector<Image> accumulation_images;
std::vector<VkCommandBuffer> command_buffers;
std::vector<VkDescriptorSet> compute_shader_sets;
-
Pipeline compute_pipeline;
+ std::vector<Buffer> ui_vertex_buffers;
+ std::vector<Buffer> ui_index_buffers;
+ std::vector<VkDescriptorSet> ui_sets;
+ Pipeline ui_pipeline;
+ VkRenderPass render_pass;
+ std::vector<VkFramebuffer> framebuffers;
+
std::vector<VkFence> submission_fences;
std::vector<VkSemaphore> execution_semaphores;
std::vector<VkSemaphore> acquire_semaphores;
diff --git a/shaders/ui.frag b/shaders/ui.frag
new file mode 100644
index 0000000..e5a6aa3
--- /dev/null
+++ b/shaders/ui.frag
@@ -0,0 +1,5 @@
+layout(location = 0) out vec4 o_Color;
+
+void main() {
+ o_Color = vec4(1.0, 0.0, 0.0, 1.0);
+}
diff --git a/shaders/ui.vert b/shaders/ui.vert
new file mode 100644
index 0000000..fc427d8
--- /dev/null
+++ b/shaders/ui.vert
@@ -0,0 +1,18 @@
+struct Vertex {
+ vec2 pos;
+ vec2 uv;
+ uint col;
+};
+
+layout(set = 0, binding = 0) uniform Vertices {
+ Vertex[10000] vertices;
+};
+
+out gl_PerVertex
+{
+ vec4 gl_Position;
+};
+
+void main() {
+ gl_Position = vec4(vertices[gl_VertexIndex].pos, 0.0, 1.0);
+}
diff --git a/src/main.cpp b/src/main.cpp
index 9736aaf..120f8ed 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -139,12 +139,17 @@ int main() {
if(rdoc_api) rdoc_api->StartFrameCapture(NULL, NULL);
if (canRender) {
+ renderer.begin_frame();
+ // 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);
((input_data*) renderer.compute_shader_buffer.mapped_ptr)->sample_index++;
}
+
+ renderer.finish_frame();
}
// stop the capture
diff --git a/src/vk-api.cpp b/src/vk-api.cpp
index b6070e5..eb5411a 100644
--- a/src/vk-api.cpp
+++ b/src/vk-api.cpp
@@ -230,10 +230,12 @@ void vkapi::destroy_command_buffers(std::vector<VkCommandBuffer> &command_buffer
// TODO: attachment structure
-VkRenderPass vkapi::create_render_pass(std::vector<VkFormat>& attachments_format) {
- std::vector<VkAttachmentDescription> attachments_description = {};
+VkRenderPass vkapi::create_render_pass(std::vector<VkFormat>& color_attachments_format) {
+ std::vector<VkAttachmentDescription> attachments_description = {};
+ std::vector<VkAttachmentReference> attachments_reference = {};
- for (auto& format: attachments_format) {
+ for (size_t attachment_index = 0; attachment_index < color_attachments_format.size(); attachment_index++) {
+ auto format = color_attachments_format[attachment_index];
VkAttachmentDescription attachment_description = {};
attachment_description.flags = 0;
attachment_description.format = format;
@@ -244,36 +246,30 @@ VkRenderPass vkapi::create_render_pass(std::vector<VkFormat>& attachments_format
attachment_description.finalLayout = VK_IMAGE_LAYOUT_GENERAL;
attachments_description.push_back(attachment_description);
- }
- std::vector<VkSubpassDescription> subpasses_description = {};
- VkSubpassDescription subpass_description = {};
- subpass_description.flags = 0;
- subpass_description.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
- subpass_description.inputAttachmentCount = 0;
- subpass_description.pInputAttachments = 0;
- subpass_description.colorAttachmentCount = 0;
- subpass_description.pColorAttachments = 0;
- subpass_description.pResolveAttachments = VK_NULL_HANDLE;
- subpass_description.pDepthStencilAttachment = VK_NULL_HANDLE;
- subpass_description.preserveAttachmentCount = 0;
- subpass_description.pPreserveAttachments = VK_NULL_HANDLE;
+ VkAttachmentReference attachment_reference = {};
+ attachment_reference.attachment = attachment_index;
+ attachment_reference.layout = VK_IMAGE_LAYOUT_GENERAL;
- subpasses_description.push_back(subpass_description);
+ attachments_reference.push_back(attachment_reference);
+ }
- std::vector<VkSubpassDependency> subpasses_dependency = {};
+ VkSubpassDescription subpass_description = {};
+ subpass_description.flags = 0;
+ subpass_description.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
+ subpass_description.colorAttachmentCount = attachments_reference.size();
+ subpass_description.pColorAttachments = attachments_reference.data();
+ subpass_description.pDepthStencilAttachment = VK_NULL_HANDLE;
VkRenderPass render_pass;
- VkRenderPassCreateInfo create_info = {};
- create_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
- create_info.pNext = VK_NULL_HANDLE;
- create_info.flags = 0;
- create_info.attachmentCount = attachments_description.size();
- create_info.pAttachments = attachments_description.data();
- create_info.subpassCount = subpasses_description.size();
- create_info.pSubpasses = subpasses_description.data();
- create_info.dependencyCount = subpasses_dependency.size();
- create_info.pDependencies = subpasses_dependency.data();
+ VkRenderPassCreateInfo create_info = {};
+ create_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
+ create_info.pNext = VK_NULL_HANDLE;
+ create_info.flags = 0;
+ create_info.attachmentCount = attachments_description.size();
+ create_info.pAttachments = attachments_description.data();
+ create_info.subpassCount = 1;
+ create_info.pSubpasses = &subpass_description;
VKRESULT(vkCreateRenderPass(context.device, &create_info, VK_NULL_HANDLE, &render_pass))
@@ -285,6 +281,50 @@ void vkapi::destroy_renderpass(VkRenderPass render_pass) {
}
+VkFramebuffer vkapi::create_framebuffer(VkRenderPass render_pass, std::vector<Image>& images, VkExtent2D size) {
+ VkFramebuffer framebuffer;
+ std::vector<VkImageView> attachements;
+ for (auto& image: images) {
+ attachements.push_back(image.view);
+ }
+
+ VkFramebufferCreateInfo create_info = {};
+ create_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
+ create_info.pNext = VK_NULL_HANDLE;
+ create_info.flags = 0;
+ create_info.renderPass = render_pass;
+ create_info.attachmentCount = attachements.size();
+ create_info.pAttachments = attachements.data();
+ create_info.width = size.width;
+ create_info.height = size.height;
+ create_info.layers = 1;
+
+ VKRESULT(vkCreateFramebuffer(context.device, &create_info, VK_NULL_HANDLE, &framebuffer))
+
+ return framebuffer;
+}
+
+std::vector<VkFramebuffer> vkapi::create_framebuffers(VkRenderPass render_pass, std::vector<Image>& images, VkExtent2D size, uint32_t framebuffer_count) {
+ std::vector<VkFramebuffer> framebuffers { framebuffer_count };
+
+ for (auto& framebuffer: framebuffers) {
+ framebuffer = create_framebuffer(render_pass, images, size);
+ }
+
+ return std::move(framebuffers);
+}
+
+void vkapi::destroy_framebuffer(VkFramebuffer framebuffer) {
+ vkDestroyFramebuffer(context.device, framebuffer, VK_NULL_HANDLE);
+}
+
+void vkapi::destroy_framebuffers(std::vector<VkFramebuffer>& framebuffers) {
+ for (auto& framebuffer: framebuffers) {
+ vkDestroyFramebuffer(context.device, framebuffer, VK_NULL_HANDLE);
+ }
+}
+
+
Pipeline vkapi::create_compute_pipeline(const char* shader_name, std::vector<VkDescriptorSetLayoutBinding> bindings) {
Pipeline pipeline;
@@ -355,7 +395,7 @@ Pipeline vkapi::create_compute_pipeline(const char* shader_name, std::vector<VkD
return std::move(pipeline);
}
-Pipeline vkapi::create_graphics_pipeline(const char* shader_name, VkShaderStageFlagBits shader_stages, std::vector<VkDescriptorSetLayoutBinding> bindings, VkRenderPass render_pass, uint32_t subpass) {
+Pipeline vkapi::create_graphics_pipeline(const char* shader_name, std::vector<VkDescriptorSetLayoutBinding> bindings, VkShaderStageFlagBits shader_stages, VkRenderPass render_pass) {
Pipeline pipeline;
std::vector<VkPipelineShaderStageCreateInfo> stages_create_info = {};
@@ -497,7 +537,7 @@ Pipeline vkapi::create_graphics_pipeline(const char* shader_name, VkShaderStageF
pipeline_create_info.pColorBlendState = &color_blend_state_create_info;
pipeline_create_info.layout = pipeline.layout;
pipeline_create_info.renderPass = render_pass;
- pipeline_create_info.subpass = subpass;
+ pipeline_create_info.subpass = 0;
VKRESULT(vkCreateGraphicsPipelines(context.device, VK_NULL_HANDLE, 1, &pipeline_create_info, VK_NULL_HANDLE, &pipeline.handle))
diff --git a/src/vk-renderer.cpp b/src/vk-renderer.cpp
index cffdaf2..21918cb 100644
--- a/src/vk-renderer.cpp
+++ b/src/vk-renderer.cpp
@@ -46,7 +46,7 @@ vkrenderer::vkrenderer(window& wnd, const input_data& inputs) {
}
};
- compute_pipeline = api.create_compute_pipeline("./shaders/compute", bindings);
+ compute_pipeline = api.create_compute_pipeline("compute", bindings);
command_buffers = api.create_command_buffers(swapchain.image_count);
@@ -63,6 +63,26 @@ 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);
std::memcpy(compute_shader_buffer.mapped_ptr, &inputs, sizeof(inputs));
@@ -89,20 +109,16 @@ vkrenderer::~vkrenderer() {
api.destroy_surface(platform_surface);
}
-void vkrenderer::ui() {
- ImGui::NewFrame();
- ImGui::Render();
- ImDrawData* draw_data = ImGui::GetDrawData();
-}
-
-void vkrenderer::compute(uint32_t width, uint32_t height, bool clear) {
+void vkrenderer::begin_frame() {
VKRESULT(vkWaitForFences(api.context.device, 1, &submission_fences[frame_index], VK_TRUE, UINT64_MAX))
VKRESULT(vkResetFences(api.context.device, 1, &submission_fences[frame_index]))
- uint32_t swapchain_image_index = 0;
+ swapchain_image_index = 0;
auto acquire_result = vkAcquireNextImageKHR(api.context.device, swapchain.handle, UINT64_MAX, acquire_semaphores[frame_index], VK_NULL_HANDLE, &swapchain_image_index);
handle_swapchain_result(acquire_result);
+ auto cmd_buf = command_buffers[frame_index];
+
auto output_image = accumulation_images[0];
auto accumulation_image = accumulation_images[1];
@@ -124,9 +140,83 @@ void vkrenderer::compute(uint32_t width, uint32_t height, bool clear) {
api.update_descriptor_set_image(compute_shader_sets[swapchain_image_index], images[0], output_image.view);
api.update_descriptor_set_image(compute_shader_sets[swapchain_image_index], images[1], accumulation_image.view);
+ api.start_record(cmd_buf);
+
+}
+
+void vkrenderer::ui() {
+ ImGui::NewFrame();
+ ImGui::Render();
+ ImDrawData* draw_data = ImGui::GetDrawData();
+
+ 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);
+ 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);
+ 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);
+ ui_index_buffers.push_back(vk_idx_buf);
+ }
+
auto cmd_buf = command_buffers[frame_index];
- api.start_record(cmd_buf);
+ VkRect2D render_area = {
+ {
+ 0,
+ 0,
+ },
+ swapchain.extent
+ };
+ VkClearValue clear_value = { 0.f, 0.f, 0.f, 1.f };
+ VkRenderPassBeginInfo render_pass_begin_info = {};
+ render_pass_begin_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
+ render_pass_begin_info.pNext = VK_NULL_HANDLE;
+ render_pass_begin_info.renderPass = render_pass;
+ render_pass_begin_info.framebuffer = framebuffers[swapchain_image_index];
+ render_pass_begin_info.renderArea = render_area;
+ render_pass_begin_info.clearValueCount = 1;
+ render_pass_begin_info.pClearValues = &clear_value;
+
+ 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);
+
+ vkCmdBindPipeline(cmd_buf, VK_PIPELINE_BIND_POINT_GRAPHICS, ui_pipeline.handle);
+
+ VkDescriptorSetLayoutBinding binding = {
+ .binding = 0,
+ .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
+ .descriptorCount = 1,
+ .stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
+ .pImmutableSamplers = VK_NULL_HANDLE,
+ };
+
+ 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]);
+
+ vkCmdBindIndexBuffer(cmd_buf, ui_index_buffers[cmd_index].handle, 0, VK_INDEX_TYPE_UINT16);
+
+ for (auto& draw_cmd: draw_list->CmdBuffer) {
+ vkCmdDrawIndexed(cmd_buf, draw_cmd.ElemCount, 1, draw_cmd.IdxOffset, draw_cmd.VtxOffset, 0);
+ }
+ }
+
+ vkCmdEndRenderPass(cmd_buf);
+}
+
+void vkrenderer::compute(uint32_t width, uint32_t height, bool clear) {
+ auto cmd_buf = command_buffers[frame_index];
+
+ auto output_image = accumulation_images[0];
+ auto accumulation_image = accumulation_images[1];
if (clear) {
api.image_barrier(cmd_buf, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, VK_ACCESS_TRANSFER_WRITE_BIT, accumulation_image);
@@ -151,6 +241,10 @@ void vkrenderer::compute(uint32_t width, uint32_t height, bool clear) {
api.blit_full(cmd_buf, output_image, swapchain.images[swapchain_image_index]);
api.image_barrier(cmd_buf, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, swapchain.images[swapchain_image_index]);
+}
+
+void vkrenderer::finish_frame() {
+ auto cmd_buf = command_buffers[frame_index];
api.end_record(cmd_buf);