aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorladevieq <ladevie.quentin@gmail.com>2022-07-19 23:52:56 +0200
committerladevieq <ladevie.quentin@gmail.com>2022-07-19 23:52:56 +0200
commit9cf2e341adfdb389c0dd8eb9a621d83ccba78826 (patch)
tree0f54383d6f0c7a709cd98b02259b722c76baa4b8
parent715ab680e68f62a3a00777e81b18f8e64110058d (diff)
Fix window resize on windows
-rw-r--r--CMakeLists.txt3
-rw-r--r--include/primitive-renderpass.hpp2
-rw-r--r--include/vk-api.hpp2
-rw-r--r--include/vk-renderer.hpp2
-rw-r--r--include/window.hpp14
-rw-r--r--src/gltf.cpp6
-rw-r--r--src/main.cpp43
-rw-r--r--src/primitive-renderpass.cpp4
-rw-r--r--src/utils.cpp2
-rw-r--r--src/vk-api.cpp18
-rw-r--r--src/vk-renderer.cpp7
-rw-r--r--src/window.cpp132
12 files changed, 135 insertions, 100 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d9ddfe5..7fa8039 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -11,9 +11,10 @@ project(path-tracer VERSION 1.0 LANGUAGES CXX)
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
add_compile_options(
- -msse4.1
+ # -fsanitize=address TODO: Enable once compilation with the flag work on windows
-fcolor-diagnostics -fansi-escape-codes # colored output when using ninja
-ftime-trace
+ -msse4.1
# https://github.com/cpp-best-practices/cppbestpractices/blob/master/02-Use_the_Tools_Available.md#gcc--clang
-Wall
-Wextra
diff --git a/include/primitive-renderpass.hpp b/include/primitive-renderpass.hpp
index 2e0a77b..8dda772 100644
--- a/include/primitive-renderpass.hpp
+++ b/include/primitive-renderpass.hpp
@@ -64,7 +64,7 @@ class Primitive {
void set_constant(off_t offset, Buffer* buffer);
void set_constant(off_t offset, Sampler* sampler);
- void set_index_buffer(Buffer* index_buffer);
+ void set_index_buffer(Buffer* buffer);
void set_scissor(int32_t x, int32_t y, uint32_t width, uint32_t height);
diff --git a/include/vk-api.hpp b/include/vk-api.hpp
index 2c00b40..f4376cd 100644
--- a/include/vk-api.hpp
+++ b/include/vk-api.hpp
@@ -163,7 +163,7 @@ class vkapi {
void destroy_descriptor_sets(std::vector<VkDescriptorSet> &descriptor_sets);
- VkSurfaceKHR create_surface(window& wnd);
+ VkSurfaceKHR create_surface(window& wnd) const;
void destroy_surface(VkSurfaceKHR surface);
diff --git a/include/vk-renderer.hpp b/include/vk-renderer.hpp
index a6107cd..5efb7d6 100644
--- a/include/vk-renderer.hpp
+++ b/include/vk-renderer.hpp
@@ -39,6 +39,8 @@ class vkrenderer {
Texture* create_2d_texture(size_t width, size_t height, VkFormat format);
+ void destroy_2d_texture(Texture* texture);
+
Sampler* create_sampler(VkFilter filter, VkSamplerAddressMode address_mode);
ComputeRenderpass* create_compute_renderpass();
diff --git a/include/window.hpp b/include/window.hpp
index 3f0fa01..aeea39a 100644
--- a/include/window.hpp
+++ b/include/window.hpp
@@ -134,18 +134,22 @@ struct event {
class window {
public:
- window(uint32_t width, uint32_t height);
+ window(uint32_t desired_width, uint32_t desired_height);
~window();
void poll_events();
-
#if defined(WINDOWS)
+ void message_loop();
+
LRESULT message_handler(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam);
static LRESULT CALLBACK window_procedure(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam);
- HWND win_handle;
+ HWND window_handle {};
+ WNDCLASS window_class {};
+ LPVOID main_fiber;
+ LPVOID message_loop_fiber;
#elif defined(LINUX)
xcb_connection_t* connection;
xcb_window_t win;
@@ -164,8 +168,8 @@ class window {
bool isOpen;
- bool keyboard[KEYS::MAX_KEYS] = { false };
- bool mouse[BUTTONS::MAX_BUTTONS] = { false };
+ bool keyboard[KEYS::MAX_KEYS] { false };
+ bool mouse[BUTTONS::MAX_BUTTONS] { false };
};
#endif // !__WINDOW_HPP_
diff --git a/src/gltf.cpp b/src/gltf.cpp
index a044842..adb58d2 100644
--- a/src/gltf.cpp
+++ b/src/gltf.cpp
@@ -22,8 +22,8 @@ node gltf::load(std::filesystem::path &path, std::string &filename, vkrenderer &
auto buffers_content = std::vector<std::vector<uint8_t>>(buffers.size());
for (size_t buffer_index{0}; buffer_index < buffers.size(); buffer_index++) {
auto& buffer = buffers[buffer_index];
- auto buffer_path = (path / buffer["uri"].get<std::string>()).string();
- buffers_content[buffer_index] = read_file(buffer_path);
+ auto buffer_path = path / buffer["uri"].get<std::string>();
+ buffers_content[buffer_index] = read_file(buffer_path.string().c_str());
}
auto textures = load_textures(gltf_json, path, renderer);
@@ -40,6 +40,8 @@ node gltf::load(std::filesystem::path &path, std::string &filename, vkrenderer &
load_node(gltf_json, root_children[child_index].get<uint32_t>(), root_node.children[child_index], meshes);
}
+ f.close();
+
return root_node;
}
diff --git a/src/main.cpp b/src/main.cpp
index 045d1b7..1c83ce8 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -53,33 +53,31 @@ int main() {
#endif
#endif // ENABLE_RENDERDOC
- // Image dimensions
const float aspect_ratio = 16.0 / 9.0;
- uint32_t width = 400;
- uint32_t height = width / aspect_ratio;
+ const auto width = 400;
+ auto height = (uint32_t)(width / aspect_ratio);
- window wnd{width, height};
+ window wnd { width, height };
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();
- point3 position = {13.0, 2.0, -3.0};
- point3 target = {0.0, 0.0, 0.0};
- auto v_fov = 90;
- auto aperture = 0.1;
- auto focus_distance = 10;
- auto cam = camera(position, target, v_fov, (float)width / (float)height, aperture, focus_distance);
+ 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;
+ auto cam = camera(position, target, v_fov, aspect_ratio, aperture, focus_distance);
- vkrenderer renderer{wnd};
+ vkrenderer renderer { wnd };
ImGui::CreateContext();
ImGuiIO &io = ImGui::GetIO();
auto main_scene = scene(cam, width, height, renderer);
- std::string raytracing_shader_name = "compute";
auto *raytracing_pass = renderer.create_compute_renderpass();
raytracing_pass->set_pipeline(raytracing_shader_name);
@@ -91,6 +89,7 @@ int main() {
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);
uint8_t *pixels = nullptr;
int atlas_width, atlas_height;
@@ -127,17 +126,14 @@ int main() {
wnd.poll_events();
- for (auto event : wnd.events) {
+ for (auto &event : wnd.events) {
switch (event.type) {
case EVENT_TYPES::RESIZE: {
- width = event.width;
- height = event.height;
+ main_scene.meta.width = event.width;
+ main_scene.meta.height = event.height;
- main_scene.meta.width = width;
- main_scene.meta.height = height;
-
- io.DisplaySize.x = (float)width;
- io.DisplaySize.y = (float)height;
+ io.DisplaySize.x = (float)event.width;
+ io.DisplaySize.y = (float)event.height;
if (event.width == 0 && event.height == 0) {
can_render = false;
@@ -145,10 +141,11 @@ int main() {
can_render = true;
renderer.recreate_swapchain();
main_scene.meta.cam.set_aspect_ratio((float)event.width / (float)event.height);
- main_scene.meta.sample_index = 1;
- accumulation_texture = renderer.create_2d_texture(width, height, VK_FORMAT_R32G32B32A32_SFLOAT);
- output_texture = renderer.create_2d_texture(width, height, VK_FORMAT_R32G32B32A32_SFLOAT);
+ renderer.destroy_2d_texture(accumulation_texture);
+ renderer.destroy_2d_texture(output_texture);
+ accumulation_texture = renderer.create_2d_texture(event.width, event.height, VK_FORMAT_R32G32B32A32_SFLOAT);
+ output_texture = renderer.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);
}
diff --git a/src/primitive-renderpass.cpp b/src/primitive-renderpass.cpp
index 56b4771..72bcf19 100644
--- a/src/primitive-renderpass.cpp
+++ b/src/primitive-renderpass.cpp
@@ -36,8 +36,8 @@ void Primitive::set_constant(off_t offset, Sampler* sampler) {
memcpy(constants + offset, (void*)&device_sampler.bindless_index, sizeof(bindless_index));
}
-void Primitive::set_index_buffer(Buffer* index_buffer) {
- this->index_buffer = index_buffer;
+void Primitive::set_index_buffer(Buffer* buffer) {
+ this->index_buffer = buffer;
}
void Primitive::set_scissor(int32_t x, int32_t y, uint32_t width, uint32_t height) {
diff --git a/src/utils.cpp b/src/utils.cpp
index 48e9a5f..dc5791c 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -40,6 +40,8 @@ std::vector<uint8_t> read_file(const char* path) {
return {};
}
+ fclose(f);
+
return file_content;
}
diff --git a/src/vk-api.cpp b/src/vk-api.cpp
index 2ae57e2..9c5a5c5 100644
--- a/src/vk-api.cpp
+++ b/src/vk-api.cpp
@@ -821,7 +821,7 @@ void vkapi::destroy_descriptor_sets(std::vector<VkDescriptorSet> &descriptor_set
}
-VkSurfaceKHR vkapi::create_surface(window& wnd) {
+VkSurfaceKHR vkapi::create_surface(window& wnd) const {
VkSurfaceKHR surface;
#if defined(LINUX)
@@ -838,8 +838,8 @@ VkSurfaceKHR vkapi::create_surface(window& wnd) {
create_info.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
create_info.pNext = nullptr;
create_info.flags = 0;
- create_info.hinstance = GetModuleHandle(NULL);
- create_info.hwnd = wnd.win_handle;
+ create_info.hinstance = GetModuleHandle(nullptr);
+ create_info.hwnd = wnd.window_handle;
VKRESULT(vkCreateWin32SurfaceKHR(context.instance, &create_info, nullptr, &surface))
#elif defined(MACOS)
@@ -1166,7 +1166,7 @@ void vkapi::begin_render_pass(VkCommandBuffer command_buffer, VkRenderPass rende
attachment_begin_info.attachmentCount = attachments.size();
attachment_begin_info.pAttachments = attachments.data();
- VkClearValue clear_value { 0.f, 0.f, 0.f, 1.f };
+ VkClearValue clear_value { .color { .float32 { 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 = &attachment_begin_info;
@@ -1208,8 +1208,8 @@ void vkapi::draw(VkCommandBuffer command_buffer, pipeline& pipeline, handle inde
}
void vkapi::blit_full(VkCommandBuffer command_buffer, handle src, handle dst) {
- auto src_image = images[src];
- auto dst_image = images[dst];
+ auto *src_image = images[src];
+ auto *dst_image = images[dst];
VkImageSubresourceLayers images_subres_layers {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
@@ -1224,9 +1224,9 @@ void vkapi::blit_full(VkCommandBuffer command_buffer, handle src, handle dst) {
.z = 0,
};
VkOffset3D end_offset {
- .x = (int32_t)src_image->size.width,
- .y = (int32_t)src_image->size.height,
- .z = (int32_t)src_image->size.depth,
+ .x = (int32_t)dst_image->size.width,
+ .y = (int32_t)dst_image->size.height,
+ .z = (int32_t)dst_image->size.depth,
};
VkImageBlit blit_region {
diff --git a/src/vk-renderer.cpp b/src/vk-renderer.cpp
index e00e5f7..ed7129c 100644
--- a/src/vk-renderer.cpp
+++ b/src/vk-renderer.cpp
@@ -95,7 +95,7 @@ void vkrenderer::finish_frame() {
}
void vkrenderer::recreate_swapchain() {
- // VKRESULT(vkWaitForFences(context.device, submission_fences.size(), submission_fences.data(), VK_TRUE, UINT64_MAX))
+ VKRESULT(vkWaitForFences(context.device, vkrenderer::virtual_frames_count, submission_fences, VK_TRUE, UINT64_MAX))
auto swapchain_image_usages = api.get_image(swapchain.images[0]).usages;
struct swapchain old_swapchain = swapchain;
@@ -194,6 +194,11 @@ Texture* vkrenderer::create_2d_texture(size_t width, size_t height, VkFormat for
return texture;
}
+void vkrenderer::destroy_2d_texture(Texture* texture) {
+ api.destroy_image(texture->device_image);
+ delete texture;
+}
+
// TODO: Check if a similar sampler has been allocated
Sampler* vkrenderer::create_sampler(VkFilter filter, VkSamplerAddressMode address_mode) {
auto* sampler = new Sampler();
diff --git a/src/window.cpp b/src/window.cpp
index 65f8177..d57d44a 100644
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -1,11 +1,9 @@
#include "window.hpp"
-#include <iostream>
-
-#include "vk-renderer.hpp"
-#include "utils.hpp"
#ifdef LINUX
+#include <iostream>
+
#include <xkbcommon/xkbcommon-x11.h>
window::window(uint32_t width, uint32_t height)
@@ -172,85 +170,108 @@ void window::poll_events() {
}
#elif defined(WINDOWS)
-
#include <windowsx.h>
-#include <cctype>
+
+#include "utils.hpp"
LRESULT CALLBACK window::window_procedure(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam) {
window* win = nullptr;
if (umsg == WM_CREATE) {
- LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lparam;
+ auto *lpcs = (LPCREATESTRUCT)lparam;
win = (window*)lpcs->lpCreateParams;
- SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)win);
+ SetWindowLongPtrA(hwnd, GWLP_USERDATA, (LONG_PTR)win);
} else {
- win = (window*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
+ win = (window*)GetWindowLongPtrA(hwnd, GWLP_USERDATA);
return win->message_handler(hwnd, umsg, wparam, lparam);
}
return DefWindowProc(hwnd, umsg, wparam, lparam);
}
-window::window(uint32_t width, uint32_t height)
- :width(width), height(height) {
- auto process_handle = GetModuleHandle(NULL);
+void message_loop(void* wnd) {
+ ((window*)wnd)->message_loop();
+}
+
+window::window(uint32_t desired_width, uint32_t desired_height)
+ : width(desired_width), height(desired_height) {
+ auto *process_handle = GetModuleHandleA(nullptr);
+
+ window_class.style = 0;
+ window_class.lpfnWndProc = &window::window_procedure;
+ window_class.cbClsExtra = 0;
+ window_class.cbWndExtra = 0;
+ window_class.hInstance = process_handle;
+ window_class.hIcon = nullptr;
+ window_class.hCursor = nullptr;
+ window_class.hbrBackground = nullptr;
+ window_class.lpszMenuName = nullptr;
+ window_class.lpszClassName = "default-window";
+
+ RegisterClass(&window_class);
- WNDCLASS window_class = {};
- window_class.style = 0;
- window_class.lpfnWndProc = &window::window_procedure;
- window_class.cbClsExtra = 0;
- window_class.cbWndExtra = 0;
- window_class.hInstance = process_handle;
- window_class.hIcon = NULL;
- window_class.hCursor = NULL;
- window_class.hbrBackground = NULL;
- window_class.lpszMenuName = NULL;
- window_class.lpszClassName = "default-window";
+ RECT rect { 0, 0, (int32_t)desired_width, (int32_t)desired_height };
+ DWORD style = WS_OVERLAPPEDWINDOW;
- RegisterClass(&window_class);
+ if (FAILED(AdjustWindowRect(&rect, style, FALSE)))
+ log_last_error();
- win_handle = CreateWindow(
- "default-window",
- "path-tracer",
- WS_OVERLAPPEDWINDOW,
- 10,
- 10,
- width,
- height,
- NULL,
- NULL,
- process_handle,
- this
- );
+ main_fiber = ConvertThreadToFiber(nullptr);
+ message_loop_fiber = CreateFiber(0, &::message_loop, this);
+
+ window_handle = CreateWindowA(
+ "default-window",
+ "path-tracer",
+ style,
+ 10,
+ 10,
+ rect.right - rect.left,
+ rect.bottom - rect.top,
+ nullptr,
+ nullptr,
+ process_handle,
+ this
+ );
- ShowWindow(win_handle, SW_SHOW);
+ ShowWindow(window_handle, SW_SHOW);
- isOpen = true;
+ isOpen = true;
}
-window::~window() {}
+window::~window() {
+ DestroyWindow(window_handle);
+ UnregisterClassA(window_class.lpszClassName, GetModuleHandleA(nullptr));
+}
-void window::poll_events() {
- MSG msg = {};
+void window::message_loop() {
+ MSG msg {};
- // Generate keydown events pressed keys
- for (size_t virtual_key = KEYS::LSHIFT; virtual_key < KEYS::MAX_KEYS; virtual_key++) {
- if (keyboard[virtual_key]) {
- events.push_back({
- .key = (KEYS)virtual_key,
- .type = EVENT_TYPES::KEY_PRESS,
- });
+ while(true) {
+ // Generate keydown events pressed keys
+ for (size_t virtual_key { KEYS::LSHIFT }; virtual_key < KEYS::MAX_KEYS; virtual_key++) {
+ if (keyboard[virtual_key]) {
+ events.push_back({
+ .key = (KEYS)virtual_key,
+ .type = EVENT_TYPES::KEY_PRESS,
+ });
+ }
}
- }
- while (PeekMessage(&msg, win_handle, 0, 0, PM_REMOVE)) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
+ while (PeekMessageA(&msg, nullptr, 0, 0, PM_REMOVE) != 0) {
+ TranslateMessage(&msg);
+ DispatchMessageA(&msg);
+ }
+
+ SwitchToFiber(main_fiber);
}
}
+void window::poll_events() {
+ SwitchToFiber(message_loop_fiber);
+}
+
LRESULT window::message_handler(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam) {
switch(umsg) {
case WM_CLOSE:
@@ -346,13 +367,14 @@ LRESULT window::message_handler(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lpar
return DefWindowProc(hwnd, umsg, wparam, lparam);
}
}
+
+ SwitchToFiber(main_fiber);
+
return 0;
}
#elif defined(MACOS)
window::window(uint32_t width, uint32_t height) {
}
-window::~window() {};
-
void window::poll_events() {}
#endif