diff options
| author | ladevieq <ladevie.quentin@gmail.com> | 2022-02-07 21:53:14 +0100 |
|---|---|---|
| committer | ladevieq <ladevie.quentin@gmail.com> | 2022-02-07 21:53:14 +0100 |
| commit | 4ae9a520d97dcaf69f4a0cd044a4fc3fe689924d (patch) | |
| tree | b2bdcef4ff0bda3dca80b11da42c597ccc596a0b | |
| parent | ab39ab82b4dc60e4a181140dc91ee046e5daa6ea (diff) | |
Compute shader render pass api
| -rw-r--r-- | include/compute-renderpass.hpp | 57 | ||||
| -rw-r--r-- | include/scene.hpp | 2 | ||||
| -rw-r--r-- | include/vk-api.hpp | 2 | ||||
| -rw-r--r-- | include/vk-renderer.hpp | 27 | ||||
| -rw-r--r-- | shaders/compute.comp | 5 | ||||
| -rw-r--r-- | src/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/compute-renderpass.cpp | 32 | ||||
| -rw-r--r-- | src/main.cpp | 60 | ||||
| -rw-r--r-- | src/vk-api.cpp | 26 | ||||
| -rw-r--r-- | src/vk-renderer.cpp | 121 |
10 files changed, 230 insertions, 103 deletions
diff --git a/include/compute-renderpass.hpp b/include/compute-renderpass.hpp new file mode 100644 index 0000000..5393032 --- /dev/null +++ b/include/compute-renderpass.hpp @@ -0,0 +1,57 @@ +#pragma once
+
+#include "vk-api.hpp"
+#include <array>
+
+class Texture;
+class Renderpass {
+ public:
+
+ Renderpass(vkapi& api)
+ :api(api)
+ {};
+
+ virtual ~Renderpass() {
+ api.destroy_pipeline(pipeline);
+ }
+
+ void set_pipeline(pipeline pipeline) {
+ this->pipeline = pipeline;
+ }
+
+ // TODO: Do not use vulkan api type
+ virtual void execute(VkCommandBuffer command_buffer) = 0;
+
+ protected:
+ vkapi &api;
+
+ pipeline pipeline;
+};
+
+class ComputeRenderpass : public Renderpass {
+ public:
+
+ ComputeRenderpass(vkapi& api)
+ : Renderpass(api)
+ {}
+
+ void set_dispatch_size(size_t count_x, size_t count_y, size_t count_z);
+
+ void set_ouput_texture(Texture* ouput_texture);
+
+ void set_constant(off_t offset, uint64_t* constant);
+ void set_constant(off_t offset, Texture* texture);
+
+ // TODO: Do not use vulkan api type
+ void execute(VkCommandBuffer command_buffer) override final;
+
+ Texture* output_texture;
+
+ private:
+
+ std::array<uint8_t, 64> constants;
+
+ size_t group_count_x;
+ size_t group_count_y;
+ size_t group_count_z;
+};
diff --git a/include/scene.hpp b/include/scene.hpp index 0638387..e24e65f 100644 --- a/include/scene.hpp +++ b/include/scene.hpp @@ -23,7 +23,7 @@ class scene { uint32_t enable_dof = false;
uint32_t debug_bvh = false;
- int32_t downscale_factor = 4;
+ int32_t downscale_factor = 1;
metadata(camera cam, uint32_t width, uint32_t height)
: cam(cam), width(width), height(height) {}
diff --git a/include/vk-api.hpp b/include/vk-api.hpp index 864632e..9cc7707 100644 --- a/include/vk-api.hpp +++ b/include/vk-api.hpp @@ -3,6 +3,7 @@ #include <vector> #include <map> +#include <iostream> #include "vk-context.hpp" @@ -152,6 +153,7 @@ class vkapi { swapchain create_swapchain(VkSurfaceKHR surface, size_t min_image_count, VkImageUsageFlags usages, VkSwapchainKHR old_swapchain); void destroy_swapchain(swapchain& swapchain); + void update_descriptor_image(image &img, VkDescriptorType type); void update_descriptor_images(std::vector<image> &images, VkDescriptorType type); void update_descriptor_samplers(std::vector<sampler> &samplers); diff --git a/include/vk-renderer.hpp b/include/vk-renderer.hpp index 2ec9ef8..2666b64 100644 --- a/include/vk-renderer.hpp +++ b/include/vk-renderer.hpp @@ -6,9 +6,17 @@ #include "vk-api.hpp" #include "vulkan-loader.hpp" +#include "compute-renderpass.hpp" + class scene; class window; +class Texture { + public: + + image device_image; +}; + class vkrenderer { public: vkrenderer(window& wnd); @@ -17,8 +25,6 @@ class vkrenderer { void begin_frame(); - void reset_accumulation(); - void ui(); void compute(uint32_t width, uint32_t height); @@ -29,15 +35,15 @@ class vkrenderer { void update_image(image img, void* data, size_t size); + Texture* create_2d_texture(size_t width, size_t height); + + void new_renderpass(Renderpass* renderpass); + + void render(); + vkapi api; - VkDeviceAddress scene_buffer_addr; - VkDeviceAddress indices_buffer_addr; - VkDeviceAddress positions_buffer_addr; - VkDeviceAddress normals_buffer_addr; - VkDeviceAddress uvs_buffer_addr; - VkDeviceAddress bvh_buffer_addr; - VkDeviceAddress materials_buffer_addr; + std::vector<Renderpass*> renderpasses; private: @@ -48,14 +54,11 @@ class vkrenderer { uint32_t virtual_frame_index = 0; uint32_t swapchain_image_index = 0; - std::vector<image> accumulation_images; sampler ui_texture_sampler; image ui_texture; std::vector<VkCommandBuffer> command_buffers; - pipeline compute_pipeline; - buffer staging_buffer; diff --git a/shaders/compute.comp b/shaders/compute.comp index 6ca193e..83a8f0d 100644 --- a/shaders/compute.comp +++ b/shaders/compute.comp @@ -286,8 +286,9 @@ void main() { } float spp_scale = (1.0 / bufs.scene.sample_index); - vec3 acc_color = srgb_to_linear(imageLoad(images[nonuniformEXT(bufs.accumulation_image_index)], coords).xyz); - out_color = linear_to_srgb(mix(acc_color, out_color, spp_scale)); + // vec3 acc_color = srgb_to_linear(imageLoad(images[nonuniformEXT(bufs.accumulation_image_index)], coords).xyz); + // out_color = linear_to_srgb(mix(acc_color, out_color, spp_scale)); + out_color = linear_to_srgb(out_color); for (uint i = 0; i < bufs.scene.downscale_factor; i++) { for (uint j = 0; j < bufs.scene.downscale_factor; j++) { diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7bfeb1e..c91cb83 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -23,6 +23,7 @@ add_executable( window.cpp scene.cpp gltf.cpp + compute-renderpass.cpp ) if(UNIX AND NOT APPLE) diff --git a/src/compute-renderpass.cpp b/src/compute-renderpass.cpp new file mode 100644 index 0000000..fe772bf --- /dev/null +++ b/src/compute-renderpass.cpp @@ -0,0 +1,32 @@ +#include "compute-renderpass.hpp"
+
+#include "vk-api.hpp"
+
+#include "vk-renderer.hpp"
+
+void ComputeRenderpass::set_ouput_texture(Texture* output_texture) {
+ this->output_texture = output_texture;
+
+ // TODO: Remove hardcoded offset
+ memcpy(constants.data() + 56, &output_texture->device_image.bindless_storage_index, 4);
+}
+
+void ComputeRenderpass::set_dispatch_size(size_t count_x, size_t count_y, size_t count_z) {
+ group_count_x = count_x;
+ group_count_y = count_y;
+ group_count_z = count_z;
+}
+
+void ComputeRenderpass::set_constant(off_t offset, uint64_t* constant) {
+ memcpy(constants.data() + offset, constant, sizeof(uint64_t));
+}
+
+void ComputeRenderpass::set_constant(off_t offset, Texture* texture) {
+ memcpy(constants.data() + offset, (void*)&texture->device_image.bindless_sampled_index, 4);
+}
+
+void ComputeRenderpass::execute(VkCommandBuffer command_buffer) {
+ vkCmdPushConstants(command_buffer, api.bindless_descriptor.pipeline_layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, 64, (void*)&constants);
+
+ api.run_compute_pipeline(command_buffer, pipeline, group_count_x, group_count_y, group_count_z);
+}
diff --git a/src/main.cpp b/src/main.cpp index 06c351c..bd9c48c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,10 +4,12 @@ #include <cstdio> #include <cassert> +#include "compute-renderpass.hpp" #include "thirdparty/renderdoc.h" #include "imgui.h" #include "vk-renderer.hpp" +#include "vulkan-loader.hpp" #include "window.hpp" #include "scene.hpp" #include "defines.hpp" @@ -62,15 +64,24 @@ int main() { auto cam = camera(position, target, v_fov, (float)width / (float)height, aperture, focus_distance); vkrenderer renderer { wnd }; + auto main_scene = scene(cam, width, height, renderer); - renderer.scene_buffer_addr = main_scene.scene_buffer.device_address; - renderer.indices_buffer_addr = main_scene.indices_buffer.device_address; - renderer.positions_buffer_addr = main_scene.positions_buffer.device_address; - renderer.normals_buffer_addr = main_scene.normals_buffer.device_address; - renderer.uvs_buffer_addr = main_scene.uvs_buffer.device_address; - renderer.materials_buffer_addr = main_scene.materials_buffer.device_address; - renderer.bvh_buffer_addr = main_scene.bvh_buffer.device_address; + auto* raytracing_pass = new ComputeRenderpass(renderer.api); + raytracing_pass->set_pipeline(renderer.api.create_compute_pipeline("compute")); + + auto* accumulation_texture = renderer.create_2d_texture(width, height); + auto* output_texture = renderer.create_2d_texture(width, height); + raytracing_pass->set_constant(0, &main_scene.scene_buffer.device_address); + raytracing_pass->set_constant(8, &main_scene.bvh_buffer.device_address); + raytracing_pass->set_constant(16, &main_scene.indices_buffer.device_address); + raytracing_pass->set_constant(24, &main_scene.positions_buffer.device_address); + raytracing_pass->set_constant(32, &main_scene.normals_buffer.device_address); + raytracing_pass->set_constant(40, &main_scene.uvs_buffer.device_address); + raytracing_pass->set_constant(48, &main_scene.materials_buffer.device_address); + + renderer.new_renderpass(raytracing_pass); + auto can_render = true; @@ -111,6 +122,10 @@ int main() { renderer.recreate_swapchain(); ((scene*) main_scene.scene_buffer_ptr())->meta.cam.set_aspect_ratio((float)event.width / (float)event.height); ((scene*) main_scene.scene_buffer_ptr())->meta.sample_index = 0; + + accumulation_texture = renderer.create_2d_texture(width, height); + output_texture = renderer.create_2d_texture(width, height); + raytracing_pass->set_dispatch_size(event.width / 8 + 1, event.height / 8 + 1, 1); } reset_accumulation = true; @@ -239,22 +254,31 @@ int main() { // See the documentation below for a longer explanation // if(rdoc_api) rdoc_api->StartFrameCapture(NULL, NULL); - if (can_render) { - renderer.begin_frame(); + // if (can_render) { + // renderer.begin_frame(); - if (reset_accumulation) { - ((scene*) main_scene.scene_buffer_ptr())->meta.sample_index = 0; - renderer.reset_accumulation(); - } + // if (reset_accumulation) { + // ((scene*) main_scene.scene_buffer_ptr())->meta.sample_index = 0; + // renderer.reset_accumulation(); + // } + + // float scale = (float)((scene*) main_scene.scene_buffer_ptr())->meta.downscale_factor; + // renderer.compute(width / scale, height / scale); + + // ((scene*) main_scene.scene_buffer_ptr())->meta.sample_index++; - float scale = (float)((scene*) main_scene.scene_buffer_ptr())->meta.downscale_factor; - renderer.compute(width / scale, height / scale); + // renderer.ui(); - ((scene*) main_scene.scene_buffer_ptr())->meta.sample_index++; + // renderer.finish_frame(); + // } + + if (can_render) { + raytracing_pass->set_ouput_texture(output_texture); + raytracing_pass->set_constant(60, accumulation_texture); - renderer.ui(); + renderer.render(); - renderer.finish_frame(); + // std::swap(output_texture, accumulation_texture); } // stop the capture diff --git a/src/vk-api.cpp b/src/vk-api.cpp index 020efc6..a3c02de 100644 --- a/src/vk-api.cpp +++ b/src/vk-api.cpp @@ -3,6 +3,7 @@ #include <iostream> #include "vk-api.hpp" +#include "vulkan/vulkan_core.h" #include "window.hpp" #include "utils.hpp" @@ -472,6 +473,9 @@ VkRenderPass vkapi::create_render_pass(std::vector<VkFormat>& color_attachments_ create_info.pAttachments = attachments_description.data(); create_info.subpassCount = 1; create_info.pSubpasses = &subpass_description; + // TODO: Use this to chain renderpasses + create_info.dependencyCount = 0; + create_info.pDependencies = VK_NULL_HANDLE; VKRESULT(vkCreateRenderPass(context.device, &create_info, VK_NULL_HANDLE, &render_pass)) @@ -898,6 +902,28 @@ void vkapi::destroy_swapchain(swapchain& swapchain) { } +void vkapi::update_descriptor_image(image &img, VkDescriptorType type) { + VkDescriptorImageInfo descriptor_images_info; + VkWriteDescriptorSet writes_descriptor; + + descriptor_images_info.sampler = VK_NULL_HANDLE; + descriptor_images_info.imageView = img.view; + descriptor_images_info.imageLayout = VK_IMAGE_LAYOUT_GENERAL; + + writes_descriptor.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + writes_descriptor.pNext = nullptr; + writes_descriptor.dstSet = bindless_descriptor.set; + writes_descriptor.dstBinding = type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ? 2 : 1; + writes_descriptor.dstArrayElement = type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ? img.bindless_storage_index : img.bindless_sampled_index; + writes_descriptor.descriptorCount = 1; + writes_descriptor.descriptorType = type; + writes_descriptor.pImageInfo = &descriptor_images_info; + writes_descriptor.pBufferInfo = VK_NULL_HANDLE; + writes_descriptor.pTexelBufferView = VK_NULL_HANDLE; + + vkUpdateDescriptorSets(context.device, 1, &writes_descriptor, 0, nullptr); +} + void vkapi::update_descriptor_images(std::vector<image> &images, VkDescriptorType type) { std::vector<VkDescriptorImageInfo> descriptor_images_info { images.size() }; std::vector<VkWriteDescriptorSet> writes_descriptor { images.size() }; diff --git a/src/vk-renderer.cpp b/src/vk-renderer.cpp index 7dd566f..dd6fedc 100644 --- a/src/vk-renderer.cpp +++ b/src/vk-renderer.cpp @@ -2,12 +2,14 @@ #include <cstring> #include <cassert> +#include "compute-renderpass.hpp" #include "imgui.h" #include "vk-renderer.hpp" #include "thirdparty/vk_mem_alloc.h" #include "defines.hpp" #include "scene.hpp" +#include "vulkan/vulkan_core.h" #include "window.hpp" #ifdef _DEBUG @@ -39,18 +41,10 @@ vkrenderer::vkrenderer(window& wnd) { VK_NULL_HANDLE ); - compute_pipeline = api.create_compute_pipeline("compute"); tonemapping_pipeline = api.create_compute_pipeline("tonemapping"); command_buffers = api.create_command_buffers(virtual_frames_count); - VkExtent3D image_size = { - .width = swapchain.extent.width, - .height = swapchain.extent.height, - .depth = 1, - }; - accumulation_images = api.create_images(image_size, VK_FORMAT_R32G32B32A32_SFLOAT, VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, 2); - submission_fences = api.create_fences(virtual_frames_count); execution_semaphores = api.create_semaphores(virtual_frames_count); acquire_semaphores = api.create_semaphores(virtual_frames_count); @@ -95,9 +89,6 @@ vkrenderer::vkrenderer(window& wnd) { auto cmd_buf = command_buffers[virtual_frame_index]; api.start_record(cmd_buf); - api.image_barrier(cmd_buf, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, accumulation_images[0]); - api.image_barrier(cmd_buf, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, accumulation_images[1]); - api.image_barrier(cmd_buf, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_MEMORY_WRITE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, ui_texture); api.copy_buffer(cmd_buf, staging_buffer, ui_texture); @@ -112,9 +103,6 @@ vkrenderer::vkrenderer(window& wnd) { VKRESULT(vkWaitForFences(api.context.device, 1, &submission_fences[virtual_frame_index], VK_TRUE, UINT64_MAX)) std::vector<image> images = { - accumulation_images[0], - accumulation_images[1], - swapchain.images[0], swapchain.images[1], swapchain.images[2] @@ -143,6 +131,10 @@ vkrenderer::vkrenderer(window& wnd) { vkrenderer::~vkrenderer() { VKRESULT(vkWaitForFences(api.context.device, submission_fences.size(), submission_fences.data(), VK_TRUE, UINT64_MAX)) + for (auto& renderpass : renderpasses) { + delete renderpass; + } + api.destroy_fences(submission_fences); api.destroy_semaphores(execution_semaphores); api.destroy_semaphores(acquire_semaphores); @@ -157,7 +149,6 @@ vkrenderer::~vkrenderer() { api.destroy_command_buffers(command_buffers); - api.destroy_pipeline(compute_pipeline); api.destroy_pipeline(tonemapping_pipeline); api.destroy_pipeline(ui_pipeline); @@ -209,23 +200,6 @@ void vkrenderer::begin_frame() { } -void vkrenderer::reset_accumulation() { - auto cmd_buf = command_buffers[virtual_frame_index]; - VkClearColorValue clear_color = { 0.f, 0.f, 0.f, 1.f }; - - api.image_barrier(cmd_buf, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, VK_ACCESS_TRANSFER_WRITE_BIT, accumulation_images[0]); - - vkCmdClearColorImage(cmd_buf, accumulation_images[0].handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_color, 1, &accumulation_images[0].subresource_range); - - api.image_barrier(cmd_buf, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, accumulation_images[0]); - - api.image_barrier(cmd_buf, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, VK_ACCESS_TRANSFER_WRITE_BIT, accumulation_images[1]); - - vkCmdClearColorImage(cmd_buf, accumulation_images[1].handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_color, 1, &accumulation_images[1].subresource_range); - - api.image_barrier(cmd_buf, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, accumulation_images[1]); -} - void vkrenderer::ui() { ImDrawData* draw_data = ImGui::GetDrawData(); @@ -286,39 +260,17 @@ void vkrenderer::ui() { } void vkrenderer::compute(uint32_t width, uint32_t height) { - auto cmd_buf = command_buffers[virtual_frame_index]; - - api.image_barrier(cmd_buf, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, swapchain.images[swapchain_image_index]); - - api.image_barrier(cmd_buf, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, accumulation_images[1]); - - vkCmdPushConstants(cmd_buf, api.bindless_descriptor.pipeline_layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, 8, (void*)&scene_buffer_addr); - vkCmdPushConstants(cmd_buf, api.bindless_descriptor.pipeline_layout, VK_SHADER_STAGE_COMPUTE_BIT, 8, 8, (void*)&bvh_buffer_addr); - vkCmdPushConstants(cmd_buf, api.bindless_descriptor.pipeline_layout, VK_SHADER_STAGE_COMPUTE_BIT, 16, 8, (void*)&indices_buffer_addr); - vkCmdPushConstants(cmd_buf, api.bindless_descriptor.pipeline_layout, VK_SHADER_STAGE_COMPUTE_BIT, 24, 8, (void*)&positions_buffer_addr); - vkCmdPushConstants(cmd_buf, api.bindless_descriptor.pipeline_layout, VK_SHADER_STAGE_COMPUTE_BIT, 32, 8, (void*)&normals_buffer_addr); - vkCmdPushConstants(cmd_buf, api.bindless_descriptor.pipeline_layout, VK_SHADER_STAGE_COMPUTE_BIT, 40, 8, (void*)&uvs_buffer_addr); - vkCmdPushConstants(cmd_buf, api.bindless_descriptor.pipeline_layout, VK_SHADER_STAGE_COMPUTE_BIT, 48, 8, (void*)&materials_buffer_addr); - vkCmdPushConstants(cmd_buf, api.bindless_descriptor.pipeline_layout, VK_SHADER_STAGE_COMPUTE_BIT, 56, 4, (void*)&accumulation_images[0].bindless_storage_index); - vkCmdPushConstants(cmd_buf, api.bindless_descriptor.pipeline_layout, VK_SHADER_STAGE_COMPUTE_BIT, 60, 4, (void*)&accumulation_images[1].bindless_storage_index); - - api.run_compute_pipeline(cmd_buf, compute_pipeline, (width / 8) + 1, (height / 8) + 1, 1); - - api.image_barrier(cmd_buf, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, swapchain.images[swapchain_image_index]); - - api.image_barrier(cmd_buf, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, accumulation_images[0]); + // vkCmdPushConstants(cmd_buf, api.bindless_descriptor.pipeline_layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, 8, (void*)&scene_buffer_addr); + // vkCmdPushConstants(cmd_buf, api.bindless_descriptor.pipeline_layout, VK_SHADER_STAGE_COMPUTE_BIT, 56, 4, (void*)&swapchain.images[swapchain_image_index].bindless_storage_index); + // vkCmdPushConstants(cmd_buf, api.bindless_descriptor.pipeline_layout, VK_SHADER_STAGE_COMPUTE_BIT, 60, 4, (void*)&accumulation_images[0].bindless_storage_index); - vkCmdPushConstants(cmd_buf, api.bindless_descriptor.pipeline_layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, 8, (void*)&scene_buffer_addr); - vkCmdPushConstants(cmd_buf, api.bindless_descriptor.pipeline_layout, VK_SHADER_STAGE_COMPUTE_BIT, 56, 4, (void*)&swapchain.images[swapchain_image_index].bindless_storage_index); - vkCmdPushConstants(cmd_buf, api.bindless_descriptor.pipeline_layout, VK_SHADER_STAGE_COMPUTE_BIT, 60, 4, (void*)&accumulation_images[0].bindless_storage_index); - - api.run_compute_pipeline(cmd_buf, tonemapping_pipeline, (width / 8) + 1, (height / 8) + 1, 1); + // api.run_compute_pipeline(cmd_buf, tonemapping_pipeline, (width / 8) + 1, (height / 8) + 1, 1); } void vkrenderer::finish_frame() { auto cmd_buf = command_buffers[virtual_frame_index]; - api.image_barrier(cmd_buf, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_ACCESS_SHADER_WRITE_BIT, 0, swapchain.images[swapchain_image_index]); + // api.image_barrier(cmd_buf, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_ACCESS_SHADER_WRITE_BIT, 0, swapchain.images[swapchain_image_index]); api.end_record(cmd_buf); @@ -327,8 +279,6 @@ void vkrenderer::finish_frame() { auto present_result = api.present(swapchain, swapchain_image_index, execution_semaphores[virtual_frame_index]); handle_swapchain_result(present_result); - std::swap(accumulation_images[0], accumulation_images[1]); - virtual_frame_index = ++virtual_frame_index % virtual_frames_count; } @@ -345,21 +295,15 @@ void vkrenderer::recreate_swapchain() { api.destroy_swapchain(old_swapchain); - api.destroy_images(accumulation_images); VkExtent3D image_size = { .width = swapchain.extent.width, .height = swapchain.extent.height, .depth = 1, }; - accumulation_images = api.create_images(image_size, VK_FORMAT_R32G32B32A32_SFLOAT, VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, 2); - auto cmd_buf = command_buffers[virtual_frame_index]; api.start_record(cmd_buf); - api.image_barrier(cmd_buf, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, accumulation_images[0]); - api.image_barrier(cmd_buf, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, accumulation_images[1]); - api.end_record(cmd_buf); VKRESULT(vkResetFences(api.context.device, 1, &submission_fences[0])) @@ -369,9 +313,6 @@ void vkrenderer::recreate_swapchain() { VKRESULT(vkWaitForFences(api.context.device, 1, &submission_fences[0], VK_TRUE, UINT64_MAX)) std::vector<image> images = { - accumulation_images[0], - accumulation_images[1], - swapchain.images[0], swapchain.images[1], swapchain.images[2] @@ -430,3 +371,43 @@ void vkrenderer::update_image(image img, void* data, size_t size) { VKRESULT(vkWaitForFences(api.context.device, 1, &submission_fences[virtual_frame_index], VK_TRUE, UINT64_MAX)) } + +Texture* vkrenderer::create_2d_texture(size_t width, size_t height) { + auto texture = new Texture(); + texture->device_image = api.create_image( + { .width = (uint32_t)width, .height = (uint32_t)height, .depth = 1 }, + VK_FORMAT_R32G32B32A32_SFLOAT, + VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT + ); + + api.update_descriptor_image(texture->device_image, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE); + + return texture; +} + +void vkrenderer::new_renderpass(Renderpass* renderpass) { + renderpasses.push_back(renderpass); +} + +void vkrenderer::render() { + begin_frame(); + + auto cmd_buf = command_buffers[virtual_frame_index]; + + for (auto& renderpass: renderpasses) { + api.image_barrier(cmd_buf, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_ACCESS_SHADER_WRITE_BIT, ((ComputeRenderpass*)renderpass)->output_texture->device_image); + + renderpass->execute(cmd_buf); + + api.image_barrier(cmd_buf, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, ((ComputeRenderpass*)renderpass)->output_texture->device_image); + + + api.image_barrier(cmd_buf, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, VK_ACCESS_TRANSFER_WRITE_BIT, swapchain.images[swapchain_image_index]); + + api.blit_full(cmd_buf, ((ComputeRenderpass*)renderpass)->output_texture->device_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_BOTTOM_OF_PIPE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, 0, swapchain.images[swapchain_image_index]); + } + + finish_frame(); +} |
