aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorladevieq <ladevie.quentin@gmail.com>2022-02-07 21:53:14 +0100
committerladevieq <ladevie.quentin@gmail.com>2022-02-07 21:53:14 +0100
commit4ae9a520d97dcaf69f4a0cd044a4fc3fe689924d (patch)
treeb2bdcef4ff0bda3dca80b11da42c597ccc596a0b
parentab39ab82b4dc60e4a181140dc91ee046e5daa6ea (diff)
Compute shader render pass api
-rw-r--r--include/compute-renderpass.hpp57
-rw-r--r--include/scene.hpp2
-rw-r--r--include/vk-api.hpp2
-rw-r--r--include/vk-renderer.hpp27
-rw-r--r--shaders/compute.comp5
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/compute-renderpass.cpp32
-rw-r--r--src/main.cpp60
-rw-r--r--src/vk-api.cpp26
-rw-r--r--src/vk-renderer.cpp121
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();
+}