aboutsummaryrefslogtreecommitdiffstats
path: root/src/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp1053
1 files changed, 728 insertions, 325 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 1acf2fb..4d56a3c 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,437 +1,840 @@
-#include <chrono>
-#include <filesystem>
+// ===============
+// windows.h stuff
+// ===============
+#if defined(_WIN32)
+ #if defined(_M_AMD64)
+ #define _AMD64_
+ #endif
+ #include <basetsd.h>
+ #include <windef.h>
+ #include <winnt.h>
+ #include <winbase.h>
+ #include <winuser.h>
+ #include <winnls.h>
+ #include <fileapi.h>
+ #include <shlwapi.h>
+ #include <handleapi.h>
+ #include <errhandlingapi.h>
+#endif // _WIN32
-#include "imgui.h"
-#ifdef ENABLE_RENDERDOC
-#include <renderdoc.h>
-#endif
-#include "compute-renderpass.hpp"
-#include "primitive-renderpass.hpp"
-#include "scene.hpp"
-#include "vk-renderer.hpp"
-#include "window.hpp"
-#include "utils.hpp"
+// -------------------
+// thirdparties
+// -------------------
+#define IMGUI_DISABLE_WIN32_FUNCTIONS
+#include "imgui.cpp"
+#include "imgui_draw.cpp"
+#include "imgui_tables.cpp"
+#include "imgui_widgets.cpp"
+
+#define STB_IMAGE_IMPLEMENTATION
+#include <stb_image.h>
+
+#include <simdjson.h>
+#include "simdjson.cpp"
+
+#define ENABLE_RENDERDOC 1
+#if ENABLE_RENDERDOC
+#include <renderdoc_app.h>
-#if defined(LINUX)
-#include <dlfcn.h>
-#include <unistd.h>
-#elif defined(WINDOWS)
-#include <Windows.h>
+
+
+#define RD_START_CAPTURE if(rdoc_api != nullptr) rdoc_api->StartFrameCapture(nullptr, nullptr)
+#define RD_END_CAPTURE if(rdoc_api != nullptr) rdoc_api->EndFrameCapture(nullptr, nullptr)
+#else
+#define RD_START_CAPTURE
+#define RD_END_CAPTURE
+#endif // ENABLE_RENDERDOC
+
+#define VK 1
+#define DX12 0
+#if DX12
+#include "dx12-device.hpp"
+#include "dx12-command-buffer.hpp"
+#else
+#include "vulkan-loader.cpp"
+#include "vk-utils.cpp"
+#include "vk-device.cpp"
+#include "vk-bindless.cpp"
+#include "vk-command-buffer.cpp"
#endif
-struct VkVertex {
- float x, y;
- float u, v;
- uint32_t color;
- uint32_t padding[3];
-};
+#include "vec3.cpp"
+#include "utils.cpp"
+#include "window.cpp"
+#include "camera.cpp"
+#include "mesh.cpp"
+#include "gltf.cpp"
+#include "bvh.cpp"
+#include "scene.cpp"
+
+
+
+// -------------------
+// GLOBALS
+// -------------------
+LARGE_INTEGER freq;
+std::vector<handle<device_texture>> debug_texture_list;
+
+#if ENABLE_RENDERDOC
+RENDERDOC_API_1_6_0 *rdoc_api = nullptr;
+#endif // ENABLE_RENDERDOC
+
+void watch_func() {
+ printf("change");
+}
+
+void ui(scene* scene, float frame_time) {
+ static float max_fps = 0.f;
+ static float max_frame_time = 0.f;
+ float fps = 1000U / (frame_time > 0.001f ? frame_time : 0.001f);
+ if (fps > max_fps) {
+ max_fps = fps;
+ }
+ if (frame_time > max_frame_time) {
+ max_frame_time = frame_time;
+ }
-void update_ui(scene& main_scene, float delta_time) {
ImGui::NewFrame();
+ const ImGuiViewport* main_viewport = ImGui::GetMainViewport();
+ ImGuiWindowFlags wnd_flags = ImGuiWindowFlags_NoMove;
+ ImGui::SetNextWindowPos(ImVec2(main_viewport->WorkSize.x - 250, main_viewport->WorkPos.y), ImGuiCond_FirstUseEver);
+ ImGui::SetNextWindowSize(ImVec2(250, 720), ImGuiCond_FirstUseEver);
- ImGui::SetNextWindowPos({0.f, 0.f});
- ImGui::SetNextWindowSize({0.f, 0.f});
- ImGui::Begin("Debug", NULL, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoTitleBar);
+ ImGui::Begin("Debug", nullptr, wnd_flags);
+ if (ImGui::CollapsingHeader("Perfs")) {
+ ImGui::SeparatorText("Metrics");
+ ImGui::Text("FPS : %f\n", fps);
+ ImGui::Text("Max FPS : %f\n", max_fps);
+ ImGui::Text("frame_time : %f ms\n", frame_time);
+ ImGui::Text("max frame_time : %f ms\n", max_frame_time);
- ImGui::Text("frame per second %u\n", static_cast<uint32_t>(1000.f / delta_time));
- ImGui::Text("frame time %f ms\n", delta_time);
- ImGui::Text("frame count %u\n", main_scene.meta.sample_index);
+ ImGui::SeparatorText("Markers");
+ for (uint32_t index = 0U; index < marker_count; index++ ) {
+ uint64_t diff = marker_counter_end[index] - marker_counter_start[index];
+ uint64_t time = (diff * 1000000ULL) / freq.QuadPart;
- if (ImGui::Checkbox("depth of field", (bool*)&main_scene.meta.enable_dof)) {
- main_scene.meta.sample_index = 1;
+ ImGui::Text("%s time : %f ms\n", marker_names[index], static_cast<float>(time) / 1000U);
+ }
}
- ImGui::SliderInt("max bounces", (int32_t *)&main_scene.meta.max_bounce, 1, 250);
- ImGui::SliderInt("min bounces", (int32_t *)&main_scene.meta.min_bounce, 1, main_scene.meta.max_bounce);
- if (ImGui::SliderInt("downscale factor", (int32_t *)&main_scene.meta.downscale_factor, 1, 32)) {
- main_scene.meta.sample_index = 1;
+ if (ImGui::CollapsingHeader("Images")) {
+ for (const handle<device_texture>& handle : debug_texture_list) {
+ const device_texture& tex = vkdevice::get().get_texture(handle);
+ const char* name = tex.name;
+ ImGui::Text(name ? name : DUMMY_NAME);
+ ImGui::Image(tex.get_sampled_index(), ImVec2(128, 128));
+ }
}
- if (ImGui::Checkbox("debug bvh", (bool *)&main_scene.meta.debug_bvh)) {
- main_scene.meta.sample_index = 1;
+ if (ImGui::CollapsingHeader("Scene")) {
+ ImGui::SliderInt("Max bounce", reinterpret_cast<int*>(&scene->meta.max_bounce), 5, 100);
+ ImGui::SliderInt("Min bounce", reinterpret_cast<int*>(&scene->meta.min_bounce), 1, 5);
+
+ ImGui::Checkbox("DOF", reinterpret_cast<bool*>(&scene->meta.enable_dof));
+ ImGui::Checkbox("Debug BVH", reinterpret_cast<bool*>(&scene->meta.debug_bvh));
+ if (ImGui::SliderInt("Scale facotr", reinterpret_cast<int*>(&scene->meta.downscale_factor), 1, 20)) {
+ scene->meta.sample_index = 1U;
+ }
}
ImGui::End();
- bool open = true;
- ImGui::ShowDemoWindow(&open);
-
ImGui::EndFrame();
-
ImGui::Render();
}
-void render(scene& main_scene, vkrenderer& renderer) {
- // To start a frame capture, call StartFrameCapture.
- // You can specify NULL, NULL for the device to capture on if you have only
- // one device and either no windows at all or only one window, and it will
- // capture from that device. See the documentation below for a longer
- // explanation if(rdoc_api) rdoc_api->StartFrameCapture(NULL, NULL);
+int main() {
+ // From Microsoft doc
+ // https://learn.microsoft.com/en-us/windows/win32/api/profileapi/nf-profileapi-queryperformancefrequency
+ // The frequency of the performance counter is fixed at system boot and is
+ // consistent across all processors so you only need to query the frequency
+ // from QueryPerformanceFrequency as the application initializes,
+ // and then cache the result.
+ QueryPerformanceFrequency(&freq);
- main_scene.scene_buffer->write(&main_scene.meta, renderer.frame_index() * sizeof(main_scene.meta), sizeof(main_scene.meta));
+ BEGIN_MARKER(STARTUP);
+#if ENABLE_RENDERDOC
+ {
+ HMODULE mod = GetModuleHandleA("renderdoc.dll");
+ if (!mod) {
+ // https://github.com/baldurk/renderdoc/issues/1556
+ // If you load one copy of the dll yourself but a different copy of the dll is registered as a vulkan layer then both copies will be loaded because they're loaded from different paths.
+ // They'll be mutually incompatible (you can't use the API fetched from one to capture from another), and other things may break or cause crashes
+ mod = LoadLibraryA("C:/Program Files/RenderDoc/renderdoc.dll");
- // ImDrawData* draw_data = ImGui::GetDrawData();
+ }
- // ui_pass->set_viewport(0.f, 0.f, (float)draw_data->DisplaySize.x, (float)draw_data->DisplaySize.y);
+ if (mod) {
+ pRENDERDOC_GetAPI RENDERDOC_GetAPI = (pRENDERDOC_GetAPI)GetProcAddress(mod, "RENDERDOC_GetAPI");
+ int ret = RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_6_0, (void **)&rdoc_api);
+ assert(ret == 1);
+ (void)ret;
- // auto previous_size = ui_primitives.size();
- // auto commands_count = 0U;
+ rdoc_api->MaskOverlayBits(eRENDERDOC_Overlay_All, eRENDERDOC_Overlay_All);
- // for (int32_t draw_list_index = 0; draw_list_index < draw_data->CmdListsCount; draw_list_index++) {
- // commands_count += draw_data->CmdLists[draw_list_index]->CmdBuffer.size();
- // }
+ RENDERDOC_InputButton key = RENDERDOC_InputButton::eRENDERDOC_Key_F10;
+ rdoc_api->SetCaptureKeys(&key, 1U);
+ }
+ }
+#endif
- // if (ui_primitives.size() < commands_count) {
- // ui_primitives.resize(commands_count);
+ constexpr size_t window_width = 1280U;
+ constexpr size_t window_height = 720U;
+ window wnd { window_width, window_height };
- // for (size_t index = previous_size; index < ui_primitives.size(); index++) {
- // ui_primitives[index] = renderer.create_primitive(*ui_pass);
- // ui_primitives[index]->set_pipeline(ui_shader_name);
- // ui_primitives[index]->set_constant_offset(64);
- // ui_primitives[index]->set_constant(32, ui_texture);
- // ui_primitives[index]->set_constant(36, ui_texture_sampler);
- // }
- // }
+ ImGui::CreateContext();
+ ImGuiIO &io = ImGui::GetIO();
+ io.DisplaySize.x = window_width;
+ io.DisplaySize.y = window_height;
- // float scale[] {
- // 2.f / draw_data->DisplaySize.x,
- // 2.f / draw_data->DisplaySize.y,
- // };
- // float translate[] {
- // -1.f - draw_data->DisplayPos.x * (2.f / draw_data->DisplaySize.x),
- // -1.f - draw_data->DisplayPos.y * (2.f / draw_data->DisplaySize.y),
- // };
+ const float aspect_ratio = 16.f / 9.f;
- // if (!ui_vertex_buffer || ui_vertex_buffer->size < draw_data->TotalVtxCount * sizeof(VkVertex)) {
- // ui_vertex_buffer = renderer.create_buffer(draw_data->TotalVtxCount * sizeof(VkVertex), false);
+ point3 position { 13.f, 2.f, -3.f };
+ point3 target {};
+ const float v_fov = 90.f;
+ const float aperture = 0.1f;
+ const float focus_distance = 10.f;
- // for (auto& primitive : ui_primitives) {
- // primitive->set_constant(0, ui_vertex_buffer);
- // }
- // }
+#if VK
+ auto& device = vkdevice::get();
+#else
+ auto& device = dx12::device::get();
+#endif
+ device.init();
- // if (!ui_index_buffer || ui_index_buffer->size < draw_data->TotalIdxCount * sizeof(ImDrawIdx)) {
- // ui_index_buffer = renderer.create_index_buffer(draw_data->TotalIdxCount * sizeof(ImDrawIdx), false);
+ scene main_scene = scene(camera(position, target, v_fov, aspect_ratio, aperture, focus_distance), window_width, window_height);
- // for (auto& primitive : ui_primitives) {
- // primitive->set_index_buffer(ui_index_buffer);
- // }
- // }
+ handle<device_surface> surface_handle = device.create_surface({
+ .window_handle = wnd.handle,
+#if VK
+ .surface_format = {
+ .format = VK_FORMAT_B8G8R8A8_UNORM,
+ .colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR,
+ },
+ .present_mode = VK_PRESENT_MODE_IMMEDIATE_KHR,
+ .usages = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT,
+#else
+ .surface_format = DXGI_FORMAT_R16G16B16A16_FLOAT,
+ .present_mode = DXGI_SWAP_EFFECT_FLIP_DISCARD,
+ .usages = DXGI_USAGE_RENDER_TARGET_OUTPUT,
+#endif
+ .image_count = 2U,
+ });
+ const device_surface& surface = device.get_surface(surface_handle);
- // off_t vertex_buffer_offset = 0;
- // off_t index_buffer_offset = 0;
- // std::vector<VkVertex> vertices;
- // uint32_t draw_call_index = 0;
- // for (int32_t draw_list_index = 0; draw_list_index < draw_data->CmdListsCount; draw_list_index++) {
- // auto& vertex_buffer = draw_data->CmdLists[draw_list_index]->VtxBuffer;
- // auto& index_buffer = draw_data->CmdLists[draw_list_index]->IdxBuffer;
- // vertices.resize(vertex_buffer.size());
- // for (int32_t vert_index = 0; vert_index < vertex_buffer.Size; vert_index++) {
- // vertices[vert_index] = *((VkVertex*)&vertex_buffer[vert_index]);
- // }
+ // ==============
+ // create buffers
+ // ==============
+ const handle<device_buffer> staging_buffer_handle = device.create_buffer({
+ .size = 128 * MB,
+#if VK
+ .usages = VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
+ .memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
+ .memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
+#else
+ .map = true,
+ .states = D3D12_RESOURCE_STATE_COPY_SOURCE,
+ .usages = D3D12_RESOURCE_FLAG_NONE,
+ .heap_type = D3D12_HEAP_TYPE_UPLOAD,
+#endif
+ });
+ const device_buffer& staging_buffer = device.get_buffer(staging_buffer_handle);
- // renderer.update_buffer(ui_vertex_buffer, vertices.data(), vertex_buffer_offset * sizeof(VkVertex), vertices.size() * sizeof(VkVertex));
- // renderer.update_buffer(ui_index_buffer, index_buffer.Data, index_buffer_offset * sizeof(ImDrawIdx), index_buffer.size() * sizeof(ImDrawIdx));
+ const handle<device_buffer> vertex_buffer_handle = device.create_buffer({
+ .size = MB * sizeof(uint32_t),
+#if VK
+ .usages = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
+ .memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
+ .memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
+#else
+ #endif
+ });
- // ImDrawList* draw_list = draw_data->CmdLists[draw_list_index];
- // for (auto& draw_cmd: draw_list->CmdBuffer) {
- // auto& current_primitive = ui_primitives[draw_call_index];
- // current_primitive->set_constant(8, (uint64_t*)&scale);
- // current_primitive->set_constant(16, (uint64_t*)&translate);
+ const handle<device_buffer> index_buffer_handle = device.create_buffer({
+ .size = MB * sizeof(uint32_t),
+#if VK
+ .usages = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
+ .memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
+ .memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
+#else
+#endif
+ });
- // ImVec2 pos = draw_data->DisplayPos;
- // current_primitive->set_scissor(
- // (int32_t)draw_cmd.ClipRect.x - pos.x,
- // (int32_t)draw_cmd.ClipRect.y - pos.y,
- // (uint32_t)draw_cmd.ClipRect.z - pos.x,
- // (uint32_t)draw_cmd.ClipRect.w - pos.y
- // );
+ device_buffer vertex_buffer = device.get_buffer(vertex_buffer_handle);
+ device_buffer index_buffer = device.get_buffer(index_buffer_handle);
- // current_primitive->set_draw_info(
- // draw_cmd.ElemCount,
- // index_buffer_offset + draw_cmd.IdxOffset,
- // vertex_buffer_offset + draw_cmd.VtxOffset
- // );
- // ui_pass->add_primitive(current_primitive);
- // draw_call_index++;
- // }
+ // ================
+ // create pipelines
+ // ================
+#if VK
+ size_t code_size = 0U;
+ uint8_t* code = read_file("shaders/test.comp.spv", &code_size);
+ handle<device_pipeline> compute = device.create_compute_pipeline({
+ .cs_code = code,
+ .cs_code_size = code_size,
+ });
- // vertex_buffer_offset += vertex_buffer.Size;
- // index_buffer_offset += index_buffer.Size;
- // }
+ size_t rt_code_size = 0U;
+ uint8_t* rt_code = read_file("shaders/compute.comp.spv", &rt_code_size);
+ handle<device_pipeline> raytracing = device.create_compute_pipeline({
+ .cs_code = rt_code,
+ .cs_code_size = rt_code_size,
+ });
+ size_t tonemapping_code_size = 0U;
+ uint8_t* tonemapping_code = read_file("shaders/tonemapping.comp.spv", &tonemapping_code_size);
+ handle<device_pipeline> tonemapping = device.create_compute_pipeline({
+ .cs_code = tonemapping_code,
+ .cs_code_size = tonemapping_code_size,
+ });
- // ui_pass->set_color_attachment(0, renderer.back_buffer());
+ std::array<VkFormat, 1U> formats { surface.surface_format.format };
+ size_t vertex_code_size = 0U;
+ uint8_t* vertex_code = read_file("shaders/api-test-ui.vert.spv", &vertex_code_size);
+ size_t fragment_code_size = 0U;
+ uint8_t* fragment_code = read_file("shaders/api-test-ui.frag.spv", &fragment_code_size);
+ handle<device_pipeline> graphics = device.create_graphics_pipeline({
+ .vs_code = vertex_code,
+ .vs_code_size = vertex_code_size,
+ .fs_code = fragment_code,
+ .fs_code_size = fragment_code_size,
+ .color_attachments_format = formats
+ });
- renderer.render();
+ size_t transmittance_lut_code_size = 0U;
+ u8* transmittance_lut_code = read_file("shaders/transmittance_lut.comp.spv", &transmittance_lut_code_size);
+ handle<device_pipeline> transmittance_lut_compute = device.create_compute_pipeline({
+ .cs_code = transmittance_lut_code,
+ .cs_code_size = transmittance_lut_code_size,
+ .name = "transmittance_lut_comp",
+ });
+#endif
- main_scene.meta.sample_index++;
-}
+ // ==============
+ // Image loading
+ // ==============
+ int image_width;
+ int image_height;
+ int channels;
+ uint8_t* data = stbi_load("../models/sponza/466164707995436622.jpg", &image_width, &image_height, &channels, 4);
+ size_t size = static_cast<size_t>(image_width) * image_height * 4U;
+ memcpy(staging_buffer.mapped_ptr, data, size);
+ off_t buffer_offset = image_width * image_height * 4;
+ data = stbi_load("../models/sponza/715093869573992647.jpg", &image_width, &image_height, &channels, 4);
+ size = static_cast<size_t>(image_width) * image_height * 4U;
+ auto* addr = static_cast<void*>(static_cast<uint8_t*>(staging_buffer.mapped_ptr) + buffer_offset);
+ memcpy(addr, data, size);
-#if defined(ENABLE_RENDERDOC)
-RENDERDOC_API_1_1_2 enable_renderdoc() {
- RENDERDOC_API_1_1_2 *rdoc_api = nullptr;
+ u8 *pixels = nullptr;
+ int atlas_width;
+ int atlas_height;
+ io.Fonts->GetTexDataAsRGBA32(&pixels, &atlas_width, &atlas_height);
-#ifdef WINDOWS
- // At init, on windows
- if (HMODULE mod = GetModuleHandleA("renderdoc.dll")) {
- auto RENDERDOC_GetAPI =
- (pRENDERDOC_GetAPI)GetProcAddress(mod, "RENDERDOC_GetAPI");
- int ret =
- RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_1_2, (void **)&rdoc_api);
- assert(ret == 1);
- }
-#elif defined(LINUX)
- // At init, on linux/android.
- // For android replace librenderdoc.so with libVkLayer_GLES_RenderDoc.so
- if (void *mod = dlopen("librenderdoc.so", RTLD_NOW | RTLD_NOLOAD)) {
- pRENDERDOC_GetAPI RENDERDOC_GetAPI = (pRENDERDOC_GetAPI)dlsym(mod, "RENDERDOC_GetAPI");
- int ret = RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_1_2, (void **)&rdoc_api);
- assert(ret == 1);
- }
+ off_t ui_offset = 2L * buffer_offset;
+ size = static_cast<size_t>(atlas_width) * atlas_height * 4U;
+ addr = static_cast<void*>(static_cast<uint8_t*>(staging_buffer.mapped_ptr) + ui_offset);
+ memcpy(addr, pixels, size);
+
+
+ // ==============
+ // create texures
+ // ==============
+ const handle<device_texture> gpu_texture_handle = device.create_texture({
+ .width = static_cast<uint32_t>(image_width),
+ .height = static_cast<uint32_t>(image_height),
+#if VK
+ .usages = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
+ .format = VK_FORMAT_R8G8B8A8_UNORM,
+ .type = VK_IMAGE_TYPE_2D,
+#else
+ .states = D3D12_RESOURCE_STATE_COPY_DEST,
+ .usages = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS,
+ .format = DXGI_FORMAT_R8G8B8A8_UNORM,
+ .type = D3D12_RESOURCE_DIMENSION_TEXTURE2D,
#endif
+ });
- return rdoc_api;
-}
+ const handle<device_texture> second_texture = device.create_texture({
+ .width = static_cast<uint32_t>(image_width),
+ .height = static_cast<uint32_t>(image_height),
+#if VK
+ .usages = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_STORAGE_BIT,
+ .format = VK_FORMAT_R8G8B8A8_UNORM,
+ .type = VK_IMAGE_TYPE_2D,
+#else
+ .states = D3D12_RESOURCE_STATE_COPY_DEST,
+ .usages = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS,
+ .format = DXGI_FORMAT_R8G8B8A8_UNORM,
+ .type = D3D12_RESOURCE_DIMENSION_TEXTURE2D,
#endif
+ });
-int main() {
+ const handle<device_texture> output_texture_handle = device.create_texture({
+ .width = static_cast<uint32_t>(image_width),
+ .height = static_cast<uint32_t>(image_height),
+#if VK
+ .usages = VK_IMAGE_USAGE_STORAGE_BIT,
+ .format = VK_FORMAT_R8G8B8A8_UNORM,
+ .type = VK_IMAGE_TYPE_2D,
+#else
+ .usages = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS,
+ .format = DXGI_FORMAT_R8G8B8A8_UNORM,
+ .type = D3D12_RESOURCE_DIMENSION_TEXTURE2D,
+#endif
+ });
+
+ const handle<device_texture> ui_texture_handle = device.create_texture({
+ .width = static_cast<uint32_t>(atlas_width),
+ .height = static_cast<uint32_t>(atlas_height),
+#if VK
+ .usages = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
+ .format = VK_FORMAT_R8G8B8A8_UNORM,
+ .type = VK_IMAGE_TYPE_2D,
+#else
+ .states = D3D12_RESOURCE_STATE_COPY_DEST,
+ .usages = D3D12_RESOURCE_FLAG_NONE,
+ .format = DXGI_FORMAT_R8G8B8A8_UNORM,
+ .type = D3D12_RESOURCE_DIMENSION_TEXTURE2D,
+#endif
+ .name = "glyph atlas"
+ });
-#if defined(ENABLE_RENDERDOC)
- auto* rdoc_api = enable_renderdoc();
+ const handle<device_texture> acc_handle = device.create_texture({
+ .width = static_cast<uint32_t>(window_width),
+ .height = static_cast<uint32_t>(window_height),
+#if VK
+ .usages = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT,
+ .format = VK_FORMAT_R32G32B32A32_SFLOAT,
+ .type = VK_IMAGE_TYPE_2D,
+#else
+ .states = D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
+ .usages = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS,
+ .format = DXGI_FORMAT_R32G32B32A32_FLOAT,
+ .type = D3D12_RESOURCE_DIMENSION_TEXTURE2D,
#endif
+ .name = "accumulation texture"
+ });
- const float aspect_ratio = 16.0 / 9.0;
- const auto width = 400;
- auto height = (uint32_t)(width / aspect_ratio);
+ const handle<device_texture> result_handle = device.create_texture({
+ .width = static_cast<uint32_t>(window_width),
+ .height = static_cast<uint32_t>(window_height),
+#if VK
+ .usages = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT,
+ .format = VK_FORMAT_R32G32B32A32_SFLOAT,
+ .type = VK_IMAGE_TYPE_2D,
+#else
+ .states = D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
+ .usages = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS,
+ .format = DXGI_FORMAT_R32G32B32A32_FLOAT,
+ .type = D3D12_RESOURCE_DIMENSION_TEXTURE2D,
+#endif
+ .name = "output texture"
+ });
- window wnd { width, height };
+ const handle<device_texture> transmittance_lut_handle = device.create_texture({
+ .width = static_cast<uint32_t>(1024),
+ .height = static_cast<uint32_t>(1024),
+#if VK
+ .usages = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
+ .format = VK_FORMAT_R16G16B16A16_SFLOAT,
+ .type = VK_IMAGE_TYPE_2D,
+#else
+ .usages = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS,
+ .format = DXGI_FORMAT_R8G8B8A8_UNORM,
+ .type = D3D12_RESOURCE_DIMENSION_TEXTURE2D,
+#endif
+ .name = "transmittance_lut",
+ });
- float delta_time = 0.f;
- uint64_t frame_count = 0;
- auto start = std::chrono::high_resolution_clock::now();
- auto end = std::chrono::high_resolution_clock::now();
+#if VK
+ u32 acc_storage_index = device.get_texture(acc_handle).get_storage_index();
+ u32 result_storage_index = device.get_texture(result_handle).get_storage_index();
+#endif
- point3 position { 13.f, 2.f, -3.f };
- point3 target {};
- const auto v_fov = 90.f;
- const auto aperture = 0.1f;
- const auto focus_distance = 10.f;
+ const device_texture& ui_texture = device.get_texture(ui_texture_handle);
+ const device_texture& transmittance_lut = device.get_texture(transmittance_lut_handle);
+ debug_texture_list.push_back(transmittance_lut_handle);
- vkrenderer renderer { wnd };
+ io.Fonts->SetTexID(reinterpret_cast<void*>(static_cast<uintptr_t>(ui_texture.get_sampled_index())));
- ImGui::CreateContext();
- ImGuiIO &io = ImGui::GetIO();
- io.DisplaySize.x = (float)width;
- io.DisplaySize.y = (float)height;
- auto main_scene = scene(camera(position, target, v_fov, aspect_ratio, aperture, focus_distance), width, height);
+#if VK
+ std::array<graphics_command_buffer, 4U> graphics_command_buffers;
+ device.allocate_command_buffers(graphics_command_buffers.data(), graphics_command_buffers.size(), QueueType::GRAPHICS, "graphics_cmd_buf");
+#else
+ std::array<dx12::graphics_command_buffer, 4U> graphics_command_buffers;
+ device.allocate_command_buffers(graphics_command_buffers.data(), graphics_command_buffers.size(), dx12::QueueType::GRAPHICS);
+#endif
- auto *raytracing_pass = renderer.create_compute_renderpass();
- raytracing_pass->set_pipeline("compute");
- watcher::watch_file(std::filesystem::path("../shaders/compute.comp"), [&]() {
- LPCSTR app_name = "glslc.exe --target-env=vulkan1.2 -std=460 ../shaders/compute.comp -o shaders/compute.comp.spv -I \"../shaders/include\"\0";
- STARTUPINFO start_info {};
- PROCESS_INFORMATION proc_info {};
- if (FAILED(CreateProcessA(
- app_name,
- nullptr,
- nullptr,
- nullptr,
- FALSE,
- 0,
- nullptr,
- nullptr,
- &start_info,
- &proc_info
- )))
- log_last_error();
- WaitForSingleObject(proc_info.hProcess, INFINITE);
- CloseHandle(proc_info.hProcess);
- CloseHandle(proc_info.hThread);
+ // =============
+ // API test code
+ // =============
+ RD_START_CAPTURE;
+ graphics_command_buffers[0].start();
+
+#if VK
+ graphics_command_buffers[0].barrier(gpu_texture_handle, VK_PIPELINE_STAGE_2_TRANSFER_BIT, VK_ACCESS_2_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
+ graphics_command_buffers[0].barrier(second_texture, VK_PIPELINE_STAGE_2_TRANSFER_BIT, VK_ACCESS_2_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
+ graphics_command_buffers[0].barrier(ui_texture_handle, VK_PIPELINE_STAGE_2_TRANSFER_BIT, VK_ACCESS_2_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
+#endif
+
+ graphics_command_buffers[0].copy(staging_buffer_handle, gpu_texture_handle);
+ graphics_command_buffers[0].copy(staging_buffer_handle, second_texture, buffer_offset);
+ graphics_command_buffers[0].copy(staging_buffer_handle, ui_texture_handle, ui_offset);
+#if VK
+ graphics_command_buffers[0].barrier(gpu_texture_handle, VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, VK_ACCESS_2_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL);
+ graphics_command_buffers[0].barrier(second_texture, VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, VK_ACCESS_2_SHADER_READ_BIT, VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL);
- raytracing_pass->set_pipeline("compute");
- });
- auto *accumulation_texture = vkrenderer::create_2d_texture(width, height, VK_FORMAT_R32G32B32A32_SFLOAT);
- auto *output_texture = vkrenderer::create_2d_texture(width, height, VK_FORMAT_R32G32B32A32_SFLOAT);
- raytracing_pass->set_constant(0, main_scene.scene_buffer);
- raytracing_pass->set_constant(8, main_scene.bvh_buffer);
- raytracing_pass->set_constant(16, main_scene.indices_buffer);
- raytracing_pass->set_constant(24, main_scene.positions_buffer);
- raytracing_pass->set_constant(32, main_scene.normals_buffer);
- raytracing_pass->set_constant(40, main_scene.uvs_buffer);
- raytracing_pass->set_constant(48, main_scene.materials_buffer);
- raytracing_pass->set_dispatch_size(width / 8 + 1, height / 8 + 1, 1);
+ {
+ device_buffer& draws_uniform_buffer = device.get_bindingmodel().get_uniform_buffer(UniformTypes::DRAW);
+ {
+ struct params {
+ u32 input1;
+ u32 input2;
+ u32 output;
+ u32 pad;
+ } *params = draws_uniform_buffer.allocate<struct params>();
+ params->input1 = device.get_texture(second_texture).get_storage_index();
+ params->input2 = device.get_texture(gpu_texture_handle).get_storage_index();
+ params->output = device.get_texture(output_texture_handle).get_storage_index();
- // uint8_t *pixels = nullptr;
- // int atlas_width, atlas_height;
- // io.Fonts->GetTexDataAsRGBA32(&pixels, &atlas_width, &atlas_height);
- // auto *ui_texture = renderer.create_2d_texture(atlas_width, atlas_height, VK_FORMAT_R8G8B8A8_UNORM);
- // io.Fonts->SetTexID((void *)&ui_texture);
+ graphics_command_buffers[0].dispatch({
+ .pipeline = compute,
+ .group_size = { .vec = { static_cast<u32>(image_width), static_cast<u32>(image_height), 1U }},
+ .local_group_size = { .vec = { 8U, 8U, 1U }},
+ });
+ }
- // renderer.update_image(ui_texture, pixels);
- // auto ui_texture_sampler = renderer.create_sampler(VK_FILTER_LINEAR, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE);
+ {
+ struct params {
+ u32 lut_id;
+ u32 width;
+ u32 height;
+ u32 pad;
+ } *params = draws_uniform_buffer.allocate<struct params>();
+ params->lut_id = transmittance_lut.get_storage_index();
+ params->width = transmittance_lut.width;
+ params->height = transmittance_lut.height;
- // Buffer* ui_vertex_buffer = nullptr;
- // Buffer* ui_index_buffer = nullptr;
+ graphics_command_buffers[0].dispatch({
+ .pipeline = transmittance_lut_compute,
+ .group_size = { .vec = { 1024U, 1024U, 1U }},
+ .local_group_size = { .vec { 8U, 8U, 1U }},
+ });
+ }
+ }
- // const char* ui_shader_name = "ui";
- // std::vector<Primitive*> ui_primitives;
- // auto ui_pass = renderer.create_primitive_renderpass();
- // ui_pass->set_viewport(0.f, 0.f, (float)width, (float)height);
- // ui_pass->add_color_attachment(renderer.back_buffer_format());
- // ui_pass->finalize_render_pass();
+ graphics_command_buffers[0].barrier(gpu_texture_handle, VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+#endif
- auto can_render = true;
+ graphics_command_buffers[0].stop();
- while (wnd.isOpen) {
- end = std::chrono::high_resolution_clock::now();
+ device.submit(graphics_command_buffers.data(), 1);
+ device.wait();
- delta_time = std::chrono::duration<float, std::milli>(end - start).count();
+ RD_END_CAPTURE;
- start = std::chrono::high_resolution_clock::now();
+ END_MARKER(STARTUP);
- io.DeltaTime = delta_time;
+ watch_file("../shaders/compute.comp", watch_func);
- watcher::pull_changes();
+#if VK
+ std::array<handle<device_texture>, 1U> color_attachment {};
+ constexpr uint32_t virtual_frames_count = 2U;
+ float delta = 0.f; // milliseconds
+ u32 speed = 1U;
+ uint32_t frame_count = 0U;
+ while(wnd.isOpen) {
+ vec3 dir = { 0.f, 0.f, 0.f };
+ float rot = 0.f;
+ LARGE_INTEGER start_qpc;
+ QueryPerformanceCounter(&start_qpc);
wnd.poll_events();
- for (auto &event : wnd.events) {
- switch (event.type) {
- case EVENT_TYPES::RESIZE: {
- main_scene.meta.width = event.width;
- main_scene.meta.height = event.height;
+ pull_changes();
- io.DisplaySize.x = (float)event.width;
- io.DisplaySize.y = (float)event.height;
+ uint32_t virtual_frame_index = frame_count % virtual_frames_count;
+ auto command_buffer = graphics_command_buffers[2U + virtual_frame_index];
- if (event.width == 0 && event.height == 0) {
- can_render = false;
- } else {
- can_render = true;
- renderer.recreate_swapchain();
- main_scene.meta.cam.set_aspect_ratio((float)event.width / (float)event.height);
+ main_scene.meta.sample_index++;
- delete accumulation_texture;
- delete output_texture);
- accumulation_texture = vkrenderer::create_2d_texture(event.width, event.height, VK_FORMAT_R32G32B32A32_SFLOAT);
- output_texture = vkrenderer::create_2d_texture(event.width, event.height, VK_FORMAT_R32G32B32A32_SFLOAT);
- raytracing_pass->set_dispatch_size(event.width / 8 + 1, event.height / 8 + 1, 1);
+ //
+ // IOs
+ //
+ {
+ io.AddMouseButtonEvent(BUTTON::LEFT, wnd.mouse[BUTTON::LEFT]);
+ io.AddMouseButtonEvent(BUTTON::RIGHT, wnd.mouse[BUTTON::LEFT]);
+ io.AddMouseButtonEvent(BUTTON::MIDDLE, wnd.mouse[BUTTON::LEFT]);
+ for (event& event : wnd.events) {
+ if (event.type == EVENT_TYPE::MOUSE_MOVE) {
+ io.AddMousePosEvent(static_cast<float>(event.data.position.x), static_cast<float>(event.data.position.y));
+ } else if (event.type == EVENT_TYPE::MOUSE_WHEEL) {
+ io.AddMouseWheelEvent(static_cast<float>(event.data.delta.x), static_cast<float>(event.data.delta.y));
}
- main_scene.meta.sample_index = 1;
+ if (event.type == EVENT_TYPE::KEY_PRESS) {
+ if (event.data.key == KEY::F2) {
+#if ENABLE_RENDERDOC
+ if (!rdoc_api->IsTargetControlConnected()) {
+ rdoc_api->LaunchReplayUI(true, nullptr);
+ }
+#endif
+ }
+ }
- break;
+ if (event.type == EVENT_TYPE::KEY_DOWN) {
+ if (event.data.key == KEY::W) {
+ dir += main_scene.meta.cam.forward;
+ }
+ if (event.data.key == KEY::A) {
+ dir += -main_scene.meta.cam.right;
+ }
+ if (event.data.key == KEY::S) {
+ dir += -main_scene.meta.cam.forward;
+ }
+ if (event.data.key == KEY::D) {
+ dir += main_scene.meta.cam.right;
+ }
+ if (event.data.key == KEY::SPACE) {
+ dir += vec3 { 0.f, 1.f, 0.f };
+ }
+ if (event.data.key == KEY::LCTRL) {
+ dir += vec3 { 0.f, -1.f, 0.f };
+ }
+ if (event.data.key == KEY::E) {
+ rot += 0.001f;
+ }
+ if (event.data.key == KEY::Q) {
+ rot += -0.001f;
+ }
+ if (event.data.key == KEY::PAGE_UP) {
+ speed++;
+ }
+ if (event.data.key == KEY::PAGE_DOWN) {
+ if (speed > 1U) {
+ speed--;
+ }
+ }
+
+ }
}
- case EVENT_TYPES::KEY_PRESS: {
- auto move_speed = 1.f * delta_time;
- if (wnd.keyboard[KEYS::LSHIFT] || wnd.keyboard[KEYS::RSHIFT]) { move_speed *= 10.f; }
+ }
- vec3 move_vec{};
+ if (!dir.is_zero()) {
+ main_scene.meta.cam.move(dir.normalize() * delta * static_cast<float>(speed));
+ main_scene.meta.sample_index = 1U;
+ }
+ if (rot != 0.f) {
+ main_scene.meta.cam.rotate_y(rot * delta * static_cast<float>(speed));
+ main_scene.meta.sample_index = 1U;
+ }
- switch (event.key) {
- case KEYS::W: {
- move_vec = main_scene.meta.cam.forward * move_speed;
- break;
- }
+ ui(&main_scene, delta);
- case KEYS::S: {
- move_vec = -main_scene.meta.cam.forward * move_speed;
- break;
- }
- case KEYS::D: {
- move_vec = main_scene.meta.cam.right * move_speed;
- break;
- }
- case KEYS::A: {
- move_vec = -main_scene.meta.cam.right * move_speed;
- break;
- }
- case KEYS::E: {
- main_scene.meta.cam.rotate_y(0.001f * delta_time);
- main_scene.meta.sample_index = 1;
- break;
- }
- case KEYS::Q: {
- main_scene.meta.cam.rotate_y(-0.001f * delta_time);
- main_scene.meta.sample_index = 1;
- break;
- }
- case KEYS::SPACE: {
- move_vec = main_scene.meta.cam.up * move_speed;
- break;
- }
- case KEYS::LCTRL: {
- move_vec = -main_scene.meta.cam.up * move_speed;
- break;
- }
- default:
- break;
- }
+ ImGuiMouseCursor cursor_style = ImGui::GetMouseCursor();
+ window::set_cursor(static_cast<CURSOR_TYPE>(cursor_style));
- main_scene.meta.cam.move(move_vec);
+ // ==================
+ // copy ImGui buffers
+ // ==================
+ const ImDrawData* draw_data = ImGui::GetDrawData();
+ {
+ u32 vertex_offset = 0;
+ u32 index_offset = 0;
+ for (s32 index = 0U; index < draw_data->CmdListsCount; index++) {
+ ImDrawList* cmd_list = draw_data->CmdLists[index];
- if (!move_vec.near_zero()) { main_scene.meta.sample_index = 1; }
+ size_t vertex_bytes_size = sizeof(ImDrawVert) * cmd_list->VtxBuffer.size();
+ u8* vtx_ptr = static_cast<uint8_t*>(vertex_buffer.mapped_ptr) + vertex_offset;
+ memcpy(vtx_ptr, cmd_list->VtxBuffer.Data, vertex_bytes_size);
+ vertex_offset += static_cast<off_t>(vertex_bytes_size);
- break;
- }
- case EVENT_TYPES::BUTTON_PRESS: {
- if (event.button == BUTTONS::LEFT) { io.MouseDown[0] = true; }
- if (event.button == BUTTONS::RIGHT) { io.MouseDown[1] = true; }
- break;
+ size_t index_bytes_size = sizeof(ImDrawIdx) * cmd_list->IdxBuffer.size();
+ memcpy(static_cast<uint8_t*>(index_buffer.mapped_ptr) + index_offset, cmd_list->IdxBuffer.Data, index_bytes_size);
+ index_offset += static_cast<off_t>(index_bytes_size);
}
- case EVENT_TYPES::BUTTON_RELEASE: {
- if (event.button == BUTTONS::LEFT) { io.MouseDown[0] = false; }
- if (event.button == BUTTONS::RIGHT) { io.MouseDown[1] = false; }
- break;
+ }
+
+ // ======================
+ // global uniforms update
+ // ======================
+ {
+ metadata * const globals = vkdevice::get().get_bindingmodel().get_uniform_buffer(UniformTypes::GLOBAL).allocate<metadata>();
+ memcpy(static_cast<void*>(globals), &main_scene.meta, sizeof(main_scene.meta));
+ }
+
+ // TODO: Refactor backbuffer acquisition
+ auto backbuffer = surface.swapchain_images[device.acquire_image_index(surface_handle)];
+ color_attachment[0] = backbuffer;
+
+ // RD_START_CAPTURE;
+ command_buffer.start();
+
+ command_buffer.barrier(backbuffer, VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, VK_ACCESS_2_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
+
+ {
+ if (virtual_frame_index == 0) {
+ command_buffer.barrier(result_handle, VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, VK_ACCESS_2_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
+ command_buffer.barrier(acc_handle, VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, VK_ACCESS_2_SHADER_READ_BIT, VK_IMAGE_LAYOUT_GENERAL);
+ } else {
+ command_buffer.barrier(result_handle, VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, VK_ACCESS_2_SHADER_READ_BIT, VK_IMAGE_LAYOUT_GENERAL);
+ command_buffer.barrier(acc_handle, VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, VK_ACCESS_2_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
}
- case EVENT_TYPES::MOUSE_MOVE: {
- io.MousePos = ImVec2{(float)event.x, (float)event.y};
- break;
+
+ {
+ struct params {
+ uintptr_t bvh_buffer;
+ uintptr_t indices_buffer;
+ uintptr_t positions_buffer;
+ uintptr_t normals_buffer;
+ uintptr_t uvs_buffer;
+ uintptr_t materials_buffer;
+ u32 output_id;
+ u32 accumulation_id;
+ };
+ struct params* uniforms = device.get_bindingmodel().get_uniform_buffer(UniformTypes::DRAW).allocate<params>();
+ uniforms->bvh_buffer = main_scene.bvh_buffer_address();
+ uniforms->indices_buffer = main_scene.indices_buffer_address();
+ uniforms->positions_buffer = main_scene.positions_buffer_address();
+ uniforms->normals_buffer = main_scene.normals_buffer_address();
+ uniforms->uvs_buffer = main_scene.uvs_buffer_address();
+ uniforms->materials_buffer = main_scene.materials_buffer_address();
+ uniforms->output_id = (virtual_frame_index == 0U) ? result_storage_index : acc_storage_index;
+ uniforms->accumulation_id = (virtual_frame_index == 0U) ? acc_storage_index : result_storage_index;
+
+ command_buffer.dispatch({
+ .pipeline = raytracing,
+ .group_size = { .vec { window_width / main_scene.meta.downscale_factor, window_height / main_scene.meta.downscale_factor, 1U, } },
+ .local_group_size = { .vec { 8U, 8U, 1U, } },
+ });
}
- default:
- break;
+
+ {
+ struct params {
+ u32 output_id;
+ u32 accumulation_id;
+ } *uniforms = device.get_bindingmodel().get_uniform_buffer(UniformTypes::DRAW).allocate<params>();
+ // TODO: Refactor backbuffer acquisition
+ uniforms->output_id = device.get_texture(backbuffer).get_storage_index();
+ uniforms->accumulation_id = (virtual_frame_index == 0U) ? result_storage_index : acc_storage_index;
+
+ command_buffer.dispatch({
+ .pipeline = tonemapping,
+ .group_size = { .vec { window_width / main_scene.meta.downscale_factor, window_height / main_scene.meta.downscale_factor, 1U, } },
+ .local_group_size = { .vec { 8U, 8U, 1U, } },
+ });
}
}
- wnd.events.clear();
+ command_buffer.barrier(backbuffer, VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT, VK_ACCESS_2_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
- raytracing_pass->set_ouput_texture(output_texture);
- raytracing_pass->set_constant(60, accumulation_texture);
+ command_buffer.begin_renderpass({
+ .render_area = {
+ .x = static_cast<int32_t>(draw_data->DisplayPos.x),
+ .y = static_cast<int32_t>(draw_data->DisplayPos.y),
+ .width = static_cast<uint32_t>(draw_data->DisplaySize.x),
+ .height = static_cast<uint32_t>(draw_data->DisplaySize.y),
+ },
+ .color_attachments = color_attachment,
+ });
- renderer.begin_frame();
+ auto& draws_uniform_buffer = device.get_bindingmodel().get_uniform_buffer(UniformTypes::DRAW);
+ uint32_t vertex_offset = 0;
+ uint32_t index_offset = 0;
+ for (s32 index = 0U ; index < draw_data->CmdListsCount; index++) {
+ auto* cmd_list = draw_data->CmdLists[index];
- // update_ui(main_scene, delta_time);
-
- if (can_render) {
- render(main_scene, renderer);
+ for (auto& draw_command : cmd_list->CmdBuffer) {
+ ImTextureID texture_id = draw_command.TexRef.GetTexID();
+ {
+ struct ui_params {
+ u64 vertex_buffer;
+ float scale[2U];
+ float translate[2U];
+ uint32_t texture_index;
+ u32 padding;
+ };
+ struct ui_params* ui_param = draws_uniform_buffer.allocate<ui_params>();
+ *ui_param = ui_params{
+ .vertex_buffer = vertex_buffer.device_address,
+ .scale {
+ 2.f / draw_data->DisplaySize.x,
+ 2.f / draw_data->DisplaySize.y,
+ },
+ .translate {
+ -1.f - draw_data->DisplayPos.x * (2.f / draw_data->DisplaySize.x),
+ -1.f - draw_data->DisplayPos.y * (2.f / draw_data->DisplaySize.y),
+ },
+ .texture_index = *reinterpret_cast<uint32_t*>(&texture_id),
+ };
+ }
- std::swap(output_texture, accumulation_texture);
+ command_buffer.draw_indexed({
+ .pipeline = graphics,
+ .index_buffer = index_buffer_handle,
+ .vertex_count = draw_command.ElemCount,
+ .vertex_offset = draw_command.VtxOffset + vertex_offset,
+ .index_offset = draw_command.IdxOffset + index_offset,
+ .instance_count = 1U,
+ });
+ }
+ vertex_offset += cmd_list->VtxBuffer.size();
+ index_offset += cmd_list->IdxBuffer.size();
}
- renderer.finish_frame();
+ command_buffer.end_renderpass();
+ command_buffer.barrier(backbuffer, VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
+
+ command_buffer.stop();
+
+ device.submit_before_present(surface_handle, &command_buffer, 1U);
+ device.present(surface_handle);
+ // device.wait();
+ LARGE_INTEGER end_qpc;
+ QueryPerformanceCounter(&end_qpc);
+ LONGLONG diff_qpc = end_qpc.QuadPart - start_qpc.QuadPart;
+ delta = static_cast<float>(diff_qpc * 1000LL) / freq.QuadPart;
frame_count++;
+
+ // RD_END_CAPTURE;
}
- //-------------------------
- // Image exporter
- //-------------------------
- // PPM format header
- // std::cout << "P3\n" << width << '\n' << height << "\n255" << std::endl;
- // auto output_image = renderer.output_image();
- // for (size_t index = 0; index < height * width; index++) {
- // write_color(std::cout, output_image[index]);
- // }
+ device.wait();
+
+ main_scene.deinit();
+
+ device.destroy_surface(surface_handle);
+
+ device.destroy_pipeline(compute);
+ device.destroy_pipeline(graphics);
+ device.destroy_pipeline(raytracing);
+ device.destroy_pipeline(tonemapping);
+
+ device.destroy_pipeline(transmittance_lut_compute);
+ device.destroy_texture(transmittance_lut_handle);
+
+ device.destroy_texture(gpu_texture_handle);
+ device.destroy_texture(second_texture);
+ device.destroy_texture(output_texture_handle);
+ device.destroy_texture(ui_texture_handle);
+ device.destroy_texture(acc_handle);
+ device.destroy_texture(result_handle);
+
+ device.destroy_buffer(staging_buffer_handle);
+ device.destroy_buffer(vertex_buffer_handle);
+ device.destroy_buffer(index_buffer_handle);
+ device.deinit();
- // std::cerr << "Done !" << std::endl;
+ ImGui::DestroyContext();
+#endif // VK
return 0;
}