diff --git a/src/ptk.c b/src/ptk.c index 368199f..2eeb8a9 100644 --- a/src/ptk.c +++ b/src/ptk.c @@ -4,8 +4,8 @@ #include "ptk_log.h" #include "ptk_option.h" +#include "ptk_vk/backend.h" #include "ptk_vk/components.h" -#include "ptk_vk/init.h" #include #ifndef GLFW_INCLUDE_VULKAN diff --git a/src/ptk_vk/backend.c b/src/ptk_vk/backend.c new file mode 100644 index 0000000..46bf5e7 --- /dev/null +++ b/src/ptk_vk/backend.c @@ -0,0 +1,346 @@ +// Copyright (jacekpoz 2024). Licensed under the EUPL-1.2 or later. + +#include "ptk_vk/backend.h" + +#include "ptk_vk/buffer.h" +#include "ptk_vk/command_buffers.h" +#include "ptk_vk/command_pool.h" +#include "ptk_vk/components.h" +#include "ptk_vk/descriptors.h" +#include "ptk_vk/device.h" +#include "ptk_vk/init.h" +#include "ptk_vk/instance.h" +#include "ptk_vk/physical_device.h" + +#include "ptk_log.h" +#include "ptk_vk/pipeline.h" +#include "ptk_vk/render_pass.h" +#include "ptk_vk/swapchain.h" +#include "ptk_vk/sync_objects.h" +#include "ptk_vk/uniform_buffers.h" +#include "ptk_vk/utils.h" + +#include + +bool g_framebuffer_resized = false; + +GLFWwindow *g_window; +VkSurfaceKHR g_surface; + +VkBuffer g_vertex_buffer; +VkDeviceMemory g_vertex_buffer_memory; +VkBuffer g_index_buffer; +VkDeviceMemory g_index_buffer_memory; + +#ifdef DEBUG +const PTK_ARRAY(constcharptr) g_validation_layers = PTK_ARRAY_NEW(constcharptr, { + "VK_LAYER_KHRONOS_validation" +}); +#else +const PTK_ARRAY(constcharptr) g_validation_layers = PTK_ARRAY_EMPTY(constcharptr); +#endif + +static uint32_t m_current_frame = 0; + +static void mouse_button_callback(GLFWwindow *window, int button, int action, int mods) { + double x, y; + glfwGetCursorPos(window, &x, &y); + vk_handle_mouse_button_input((PtkPos){ .x = x, .y = y }, button, action, mods); +} + +static void framebuffer_resized(GLFWwindow *window, int width, int height) { + (void)window; (void)width; (void)height; + g_framebuffer_resized = true; +} + +bool record_command_buffer(const VkCommandBuffer command_buffer, const uint32_t image_index) { + VK_TRY(false, + vkBeginCommandBuffer( + command_buffer, + &(VkCommandBufferBeginInfo){ + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, + .pNext = NULL, + .flags = 0, + .pInheritanceInfo = NULL, + } + ) + ); + + vkCmdBeginRenderPass( + command_buffer, + &(VkRenderPassBeginInfo){ + .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, + .pNext = NULL, + .renderPass = g_render_pass, + .framebuffer = g_swapchain_framebuffers.data[image_index], + .renderArea = (VkRect2D){ + .offset = (VkOffset2D){ + .x = 0, + .y = 0, + }, + .extent = g_swapchain_extent, + }, + .clearValueCount = 1, + .pClearValues = &(VkClearValue){ + .color = (VkClearColorValue){ + .float32[0] = 0.0f, + .float32[1] = 0.0f, + .float32[2] = 0.0f, + .float32[3] = 1.0f, + }, + }, + }, + VK_SUBPASS_CONTENTS_INLINE + ); + + vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipeline); + + vkCmdBindVertexBuffers(command_buffer, 0, 1, (VkBuffer []){g_vertex_buffer}, (VkDeviceSize []){0}); + + vkCmdBindIndexBuffer(command_buffer, g_index_buffer, 0, VK_INDEX_TYPE_UINT32); + + vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipeline_layout, 0, 1, &g_descriptor_sets.data[m_current_frame], 0, NULL); + + vkCmdDrawIndexed(command_buffer, g_indices.size, 1, 0, 0, 0); + + vkCmdEndRenderPass(command_buffer); + + VK_TRY(false, + vkEndCommandBuffer(command_buffer) + ); + + return true; +} + +bool vk_init(GLFWwindow *window, const size_t width, const size_t height, const char *title, const PtkVersion version) { + g_window = window; + g_uniform_buffer_object.initial_window_size.w = width; + g_uniform_buffer_object.initial_window_size.h = height; + + vk_init_vertices(); + + glfwSetFramebufferSizeCallback(window, framebuffer_resized); + glfwSetMouseButtonCallback(window, mouse_button_callback); + + if (!vk_instance_create(title, version)) { + PTK_ERR("failed creating VkInstance"); + return false; + } + + if (!vk_select_physical_dev()) { + PTK_ERR("failed selecting physical device"); + return false; + } + + VK_TRY(false, glfwCreateWindowSurface(g_instance, g_window, NULL, &g_surface)); + + if (!vk_create_logical_dev()) { + PTK_ERR("failed creating logical device"); + return false; + } + + if (!vk_create_swapchain()) { + PTK_ERR("failed creating swapchain"); + return false; + } + + if (!vk_create_image_views()) { + PTK_ERR("failed creating image views"); + return false; + } + + if (!vk_create_render_pass()) { + PTK_ERR("failed creating render pass"); + return false; + } + + if (!vk_create_descriptor_set_layout()) { + PTK_ERR("failed creating descriptor set layout"); + return false; + } + + if (!vk_create_pipeline()) { + PTK_ERR("failed creating graphics pipeline"); + return false; + } + + if (!vk_create_framebuffers()) { + PTK_ERR("failed creating framebuffers"); + return false; + } + + if (!vk_create_command_pool()) { + PTK_ERR("failed creating command pool"); + return false; + } + + const VkDeviceSize buffer_size = 65536; + + PTK_OPTION(BufferStuff) vertex_buffer_stuff_opt = create_buffer( + g_dev, + g_physical_dev, + buffer_size, + VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT + ); + + if (!vertex_buffer_stuff_opt.exists) { + PTK_ERR("failed creating vertex buffer"); + return false; + } + + g_vertex_buffer = vertex_buffer_stuff_opt.value.buffer; + g_vertex_buffer_memory = vertex_buffer_stuff_opt.value.buffer_memory; + + PTK_OPTION(BufferStuff) index_buffer_stuff_opt = create_buffer( + g_dev, + g_physical_dev, + buffer_size, + VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT + ); + + if (!index_buffer_stuff_opt.exists) { + PTK_ERR("failed creating index buffer"); + return false; + } + + g_index_buffer = index_buffer_stuff_opt.value.buffer; + g_index_buffer_memory = index_buffer_stuff_opt.value.buffer_memory; + + if (!vk_create_uniform_buffers()) { + PTK_ERR("failed creating uniform buffers"); + return false; + } + + if (!vk_create_descriptor_pool()) { + PTK_ERR("failed creating descriptor pool"); + return false; + } + + if (!vk_create_descriptor_sets()) { + PTK_ERR("failed creating descriptor sets"); + return false; + } + + if (!vk_allocate_command_buffers()) { + PTK_ERR("failed allocating command buffers"); + return false; + } + + if (!vk_create_sync_objects()) { + PTK_ERR("failed creating sync objects"); + return false; + } + + return true; +} + +bool vk_is_done(void) { + return glfwWindowShouldClose(g_window); +} + +bool update_uniform_buffer(const size_t current_frame) { + g_uniform_buffer_object.window_size.w = g_swapchain_extent.width; + g_uniform_buffer_object.window_size.h = g_swapchain_extent.height; + + memcpy(g_uniform_buffers_mapped.data[current_frame], &g_uniform_buffer_object, sizeof(g_uniform_buffer_object)); + + return true; +} + +bool vk_draw_frame(void) { + vkWaitForFences(g_dev, 1, &g_in_flight_fences.data[m_current_frame], VK_TRUE, UINT64_MAX); + + uint32_t image_index; + const VkResult acquire_next_image_result = vkAcquireNextImageKHR( + g_dev, + g_swapchain, + UINT64_MAX, + g_image_available_semaphores.data[m_current_frame], + VK_NULL_HANDLE, + &image_index + ); + + if (acquire_next_image_result == VK_ERROR_OUT_OF_DATE_KHR) { + if (!vk_recreate_swapchain()) { + return false; + } + return true; + } else if (acquire_next_image_result != VK_SUCCESS && acquire_next_image_result != VK_SUBOPTIMAL_KHR) { + PTK_ERR("%s", vk_result_string(acquire_next_image_result)); + return false; + } + + update_uniform_buffer(m_current_frame); + + vkResetFences(g_dev, 1, &g_in_flight_fences.data[m_current_frame]); + + vkResetCommandBuffer(g_command_buffers.data[m_current_frame], 0); + if (!record_command_buffer(g_command_buffers.data[m_current_frame], image_index)) { + PTK_ERR("failed recording command buffer"); + return false; + } + + const VkSemaphore signal_semaphores[] = {g_render_finished_semaphores.data[m_current_frame]}; + + VK_TRY(false, + vkQueueSubmit( + g_graphics_queue, + 1, + &(VkSubmitInfo){ + .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, + .pNext = NULL, + .waitSemaphoreCount = 1, + .pWaitSemaphores = &g_image_available_semaphores.data[m_current_frame], + .pWaitDstStageMask = &(VkPipelineStageFlags){VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}, + .commandBufferCount = 1, + .pCommandBuffers = &g_command_buffers.data[m_current_frame], + .signalSemaphoreCount = 1, + .pSignalSemaphores = signal_semaphores, + }, + g_in_flight_fences.data[m_current_frame] + ) + ); + + const VkResult queue_present_result = vkQueuePresentKHR( + g_present_queue, + &(VkPresentInfoKHR){ + .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, + .pNext = NULL, + .waitSemaphoreCount = 1, + .pWaitSemaphores = signal_semaphores, + .swapchainCount = 1, + .pSwapchains = &(VkSwapchainKHR){g_swapchain}, + .pImageIndices = &image_index, + .pResults = NULL, + } + ); + + if ( + queue_present_result == VK_ERROR_OUT_OF_DATE_KHR || + queue_present_result == VK_SUBOPTIMAL_KHR || + g_framebuffer_resized + ) { + g_framebuffer_resized = false; + if (!vk_recreate_swapchain()) { + return false; + } + PTK_TRACE("recreated swapchain"); + } else if (queue_present_result != VK_SUCCESS) { + PTK_ERR("%s", vk_result_string(queue_present_result)); + return false; + } + + m_current_frame = (m_current_frame + 1) % g_max_frames_in_flight; + + return true; +} + + +void vk_finish(void) { + vkDeviceWaitIdle(g_dev); + + vk_cleanup(); + vk_components_cleanup(); +} diff --git a/src/ptk_vk/backend.h b/src/ptk_vk/backend.h new file mode 100644 index 0000000..8197b99 --- /dev/null +++ b/src/ptk_vk/backend.h @@ -0,0 +1,39 @@ +// Copyright (jacekpoz 2024). Licensed under the EUPL-1.2 or later. + +#ifndef PTK_PTK_VK_BACKEND_H_ +#define PTK_PTK_VK_BACKEND_H_ + +#include "ptk.h" +#include "ptk_array.h" + +#ifndef GLFW_INCLUDE_VULKAN +#define GLFW_INCLUDE_VULKAN +#endif +#include + +#include + +extern bool g_framebuffer_resized; + +extern GLFWwindow *g_window; +extern VkSurfaceKHR g_surface; + +extern VkBuffer g_vertex_buffer; +extern VkDeviceMemory g_vertex_buffer_memory; +extern VkBuffer g_index_buffer; +extern VkDeviceMemory g_index_buffer_memory; + +typedef const char *constcharptr; +PTK_ARRAY_DEFINE(constcharptr); + +extern const PTK_ARRAY(constcharptr) g_validation_layers; + +bool vk_init(GLFWwindow *window, const size_t width, const size_t height, const char *title, const PtkVersion version); + +bool vk_is_done(void); + +bool vk_draw_frame(void); + +void vk_finish(void); + +#endif // PTK_PTK_VK_BACKEND_H_ diff --git a/src/ptk_vk/command_buffers.c b/src/ptk_vk/command_buffers.c index 937570f..51a77ba 100644 --- a/src/ptk_vk/command_buffers.c +++ b/src/ptk_vk/command_buffers.c @@ -2,25 +2,30 @@ #include "ptk_vk/command_buffers.h" +#include "ptk_vk/command_pool.h" +#include "ptk_vk/device.h" +#include "ptk_vk/sync_objects.h" #include "ptk_vk/utils.h" -PTK_OPTION(VkCommandBufferList) vk_allocate_command_buffers(VkDevice dev, VkCommandPool command_pool, uint32_t max_frames_in_flight) { - VkCommandBufferList ret = PTK_LIST_NEW(VkCommandBuffer, max_frames_in_flight); +PTK_LIST(VkCommandBuffer) g_command_buffers; - VK_TRY(PTK_OPTION_NONE(VkCommandBufferList), +bool vk_allocate_command_buffers(void) { + g_command_buffers = PTK_LIST_NEW(VkCommandBuffer, g_max_frames_in_flight); + + VK_TRY(false, vkAllocateCommandBuffers( - dev, + g_dev, &(VkCommandBufferAllocateInfo){ .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, .pNext = NULL, - .commandPool = command_pool, + .commandPool = g_command_pool, .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, - .commandBufferCount = ret.allocated, + .commandBufferCount = g_command_buffers.allocated, }, - ret.data + g_command_buffers.data ) ); - PTK_LIST_FILLED(ret); + PTK_LIST_FILLED(g_command_buffers); - return PTK_OPTION_SOME(VkCommandBufferList, ret); + return true; } diff --git a/src/ptk_vk/command_buffers.h b/src/ptk_vk/command_buffers.h index c05341c..6b9a61d 100644 --- a/src/ptk_vk/command_buffers.h +++ b/src/ptk_vk/command_buffers.h @@ -4,14 +4,15 @@ #define PTK_PTK_VK_COMMAND_BUFFERS_H_ #include "ptk_list.h" -#include "ptk_option.h" #include -PTK_LIST_DEFINE(VkCommandBuffer); -typedef PTK_LIST(VkCommandBuffer) VkCommandBufferList; -PTK_OPTION_DEFINE(VkCommandBufferList); +#include -PTK_OPTION(VkCommandBufferList) vk_allocate_command_buffers(VkDevice dev, VkCommandPool command_pool, uint32_t max_frames_in_flight); +PTK_LIST_DEFINE(VkCommandBuffer); + +extern PTK_LIST(VkCommandBuffer) g_command_buffers; + +bool vk_allocate_command_buffers(void); #endif // PTK_PTK_VK_COMMAND_BUFFERS_H_ diff --git a/src/ptk_vk/command_pool.c b/src/ptk_vk/command_pool.c index 7e8dc87..71e2ea1 100644 --- a/src/ptk_vk/command_pool.c +++ b/src/ptk_vk/command_pool.c @@ -2,25 +2,25 @@ #include "ptk_vk/command_pool.h" +#include "ptk_vk/device.h" #include "ptk_vk/utils.h" -PTK_OPTION(VkCommandPool) vk_create_command_pool(VkDevice dev, uint32_t graphics_queue_family_index) { - VkCommandPool ret; +VkCommandPool g_command_pool; - VK_TRY(PTK_OPTION_NONE(VkCommandPool), +bool vk_create_command_pool(void) { + VK_TRY(false, vkCreateCommandPool( - dev, + g_dev, &(VkCommandPoolCreateInfo){ .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, .pNext = NULL, .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, - .queueFamilyIndex = graphics_queue_family_index, + .queueFamilyIndex = g_queue_family_indices.graphics.value, }, NULL, - &ret + &g_command_pool ) ); - return PTK_OPTION_SOME(VkCommandPool, ret); + return true; } - diff --git a/src/ptk_vk/command_pool.h b/src/ptk_vk/command_pool.h index 8744a36..067b853 100644 --- a/src/ptk_vk/command_pool.h +++ b/src/ptk_vk/command_pool.h @@ -3,12 +3,12 @@ #ifndef PTK_PTK_VK_COMMAND_POOL_H_ #define PTK_PTK_VK_COMMAND_POOL_H_ -#include "ptk_option.h" - #include -PTK_OPTION_DEFINE(VkCommandPool); +#include -PTK_OPTION(VkCommandPool) vk_create_command_pool(VkDevice dev, uint32_t graphics_queue_family_index); +extern VkCommandPool g_command_pool; + +bool vk_create_command_pool(void); #endif // PTK_PTK_VK_COMMAND_POOL_H_ diff --git a/src/ptk_vk/descriptors.c b/src/ptk_vk/descriptors.c index 9d94b6e..f22a63d 100644 --- a/src/ptk_vk/descriptors.c +++ b/src/ptk_vk/descriptors.c @@ -2,14 +2,19 @@ #include "ptk_vk/descriptors.h" +#include "ptk_vk/device.h" +#include "ptk_vk/sync_objects.h" +#include "ptk_vk/uniform_buffers.h" #include "ptk_vk/utils.h" -PTK_OPTION(VkDescriptorSetLayout) vk_create_descriptor_set_layout(VkDevice dev) { - VkDescriptorSetLayout ret; +VkDescriptorSetLayout g_descriptor_set_layout; +VkDescriptorPool g_descriptor_pool; +PTK_LIST(VkDescriptorSet) g_descriptor_sets; - VK_TRY(PTK_OPTION_NONE(VkDescriptorSetLayout), +bool vk_create_descriptor_set_layout(void) { + VK_TRY(false, vkCreateDescriptorSetLayout( - dev, + g_dev, &(VkDescriptorSetLayoutCreateInfo){ .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, .pNext = NULL, @@ -24,77 +29,75 @@ PTK_OPTION(VkDescriptorSetLayout) vk_create_descriptor_set_layout(VkDevice dev) }, }, NULL, - &ret + &g_descriptor_set_layout ) ); - return PTK_OPTION_SOME(VkDescriptorSetLayout, ret); + return true; } -PTK_OPTION(VkDescriptorPool) vk_create_descriptor_pool(VkDevice dev, uint32_t max_frames_in_flight) { - VkDescriptorPool ret; - - VK_TRY(PTK_OPTION_NONE(VkDescriptorPool), +bool vk_create_descriptor_pool(void) { + VK_TRY(false, vkCreateDescriptorPool( - dev, + g_dev, &(VkDescriptorPoolCreateInfo){ .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, .pNext = NULL, .flags = 0, - .maxSets = max_frames_in_flight, + .maxSets = g_max_frames_in_flight, .poolSizeCount = 1, .pPoolSizes = &(VkDescriptorPoolSize){ .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - .descriptorCount = max_frames_in_flight, + .descriptorCount = g_max_frames_in_flight, }, }, NULL, - &ret + &g_descriptor_pool ) ); - return PTK_OPTION_SOME(VkDescriptorPool, ret); + return true; } PTK_LIST_DEFINE(VkDescriptorSetLayout); -PTK_OPTION(VkDescriptorSetList) vk_create_descriptor_sets(VkDevice dev, VkDescriptorSetLayout descriptor_set_layout, VkDescriptorPool descriptor_pool, PTK_LIST(VkBuffer) uniform_buffers, uint32_t max_frames_in_flight) { - PTK_LIST(VkDescriptorSetLayout) layouts = PTK_LIST_NEW(VkDescriptorSetLayout, max_frames_in_flight); - for (size_t i = 0; i < max_frames_in_flight; ++i) { - PTK_LIST_ADD(VkDescriptorSetLayout, layouts, descriptor_set_layout); +bool vk_create_descriptor_sets(void) { + PTK_LIST(VkDescriptorSetLayout) layouts = PTK_LIST_NEW(VkDescriptorSetLayout, g_max_frames_in_flight); + for (size_t i = 0; i < g_max_frames_in_flight; ++i) { + PTK_LIST_ADD(VkDescriptorSetLayout, layouts, g_descriptor_set_layout); } - VkDescriptorSetList ret = PTK_LIST_NEW(VkDescriptorSet, max_frames_in_flight); + g_descriptor_sets = PTK_LIST_NEW(VkDescriptorSet, g_max_frames_in_flight); - VK_TRY(PTK_OPTION_NONE(VkDescriptorSetList), + VK_TRY(false, vkAllocateDescriptorSets( - dev, + g_dev, &(VkDescriptorSetAllocateInfo){ .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, .pNext = NULL, - .descriptorPool = descriptor_pool, + .descriptorPool = g_descriptor_pool, .descriptorSetCount = layouts.size, .pSetLayouts = layouts.data, }, - ret.data + g_descriptor_sets.data ) ); - for (size_t i = 0; i < max_frames_in_flight; ++i) { + for (size_t i = 0; i < g_max_frames_in_flight; ++i) { vkUpdateDescriptorSets( - dev, + g_dev, 1, &(VkWriteDescriptorSet){ .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, .pNext = NULL, - .dstSet = ret.data[i], + .dstSet = g_descriptor_sets.data[i], .dstBinding = 0, .dstArrayElement = 0, .descriptorCount = 1, .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, .pImageInfo = NULL, .pBufferInfo = &(VkDescriptorBufferInfo){ - .buffer = uniform_buffers.data[i], + .buffer = g_uniform_buffers.data[i], .offset = 0, .range = sizeof(UniformBufferObject), }, @@ -105,5 +108,5 @@ PTK_OPTION(VkDescriptorSetList) vk_create_descriptor_sets(VkDevice dev, VkDescri ); } - return PTK_OPTION_SOME(VkDescriptorSetList, ret); + return true; } diff --git a/src/ptk_vk/descriptors.h b/src/ptk_vk/descriptors.h index faf9b6e..a873431 100644 --- a/src/ptk_vk/descriptors.h +++ b/src/ptk_vk/descriptors.h @@ -3,21 +3,18 @@ #ifndef PTK_PTK_VK_DESCRIPTORS_H_ #define PTK_PTK_VK_DESCRIPTORS_H_ -#include "ptk_vk/uniform_buffers.h" - #include "ptk_list.h" -#include "ptk_option.h" #include -PTK_OPTION_DEFINE(VkDescriptorSetLayout); -PTK_OPTION_DEFINE(VkDescriptorPool); PTK_LIST_DEFINE(VkDescriptorSet); -typedef PTK_LIST(VkDescriptorSet) VkDescriptorSetList; -PTK_OPTION_DEFINE(VkDescriptorSetList); -PTK_OPTION(VkDescriptorSetLayout) vk_create_descriptor_set_layout(VkDevice dev); -PTK_OPTION(VkDescriptorPool) vk_create_descriptor_pool(VkDevice dev, uint32_t max_frames_in_flight); -PTK_OPTION(VkDescriptorSetList) vk_create_descriptor_sets(VkDevice dev, VkDescriptorSetLayout descriptor_set_layout, VkDescriptorPool descriptor_pool, PTK_LIST(VkBuffer) uniform_buffers, uint32_t max_frames_in_flight); +extern VkDescriptorSetLayout g_descriptor_set_layout; +extern VkDescriptorPool g_descriptor_pool; +extern PTK_LIST(VkDescriptorSet) g_descriptor_sets; + +bool vk_create_descriptor_set_layout(void); +bool vk_create_descriptor_pool(void); +bool vk_create_descriptor_sets(void); #endif // PTK_PTK_VK_DESCRIPTORS_H_ diff --git a/src/ptk_vk/device.c b/src/ptk_vk/device.c index d384531..c53e894 100644 --- a/src/ptk_vk/device.c +++ b/src/ptk_vk/device.c @@ -2,6 +2,8 @@ #include "ptk_vk/device.h" +#include "ptk_vk/backend.h" +#include "ptk_vk/physical_device.h" #include "ptk_vk/swapchain.h" #include "ptk_vk/utils.h" @@ -13,10 +15,11 @@ #include #include +VkDevice g_dev; +QueueFamilyIndices g_queue_family_indices; VkQueue g_graphics_queue; VkQueue g_present_queue; -static QueueFamilyIndices m_queue_family_indices = {0}; static const size_t m_queue_family_count = sizeof(QueueFamilyIndices) / sizeof(PTK_OPTION(uint32_t)); PTK_LIST_DEFINE(VkQueueFamilyProperties); @@ -57,22 +60,22 @@ static bool is_device_suitable(const VkPhysicalDevice physical_dev, const VkSurf vkGetPhysicalDeviceQueueFamilyProperties(physical_dev, &queue_families.allocated, queue_families.data); PTK_LIST_FILLED(queue_families); - m_queue_family_indices.graphics = PTK_OPTION_NONE(uint32_t); - m_queue_family_indices.present = PTK_OPTION_NONE(uint32_t); + g_queue_family_indices.graphics = PTK_OPTION_NONE(uint32_t); + g_queue_family_indices.present = PTK_OPTION_NONE(uint32_t); PTK_LIST_FOR_EACH_E(const VkQueueFamilyProperties, queue_families, i, queue_family, { if (queue_family.queueFlags & VK_QUEUE_GRAPHICS_BIT) { - m_queue_family_indices.graphics = PTK_OPTION_SOME(uint32_t, i); + g_queue_family_indices.graphics = PTK_OPTION_SOME(uint32_t, i); } VkBool32 present_support = VK_FALSE; vkGetPhysicalDeviceSurfaceSupportKHR(physical_dev, i, surface, &present_support); if (present_support) { - m_queue_family_indices.present = PTK_OPTION_SOME(uint32_t, i); + g_queue_family_indices.present = PTK_OPTION_SOME(uint32_t, i); } }) - const bool indices_found = m_queue_family_indices.graphics.exists - && m_queue_family_indices.present.exists; + const bool indices_found = g_queue_family_indices.graphics.exists + && g_queue_family_indices.present.exists; const bool extensions_supported = are_extensions_supported(physical_dev); bool swapchain_adequate = false; @@ -89,20 +92,16 @@ static bool is_device_suitable(const VkPhysicalDevice physical_dev, const VkSurf return indices_found && extensions_supported && swapchain_adequate; } -PTK_OPTION(DeviceStuff) vk_create_logical_dev(VkPhysicalDevice physical_dev, VkSurfaceKHR surface, const PTK_ARRAY(constcharptr) validation_layers) { - if (!is_device_suitable(physical_dev, surface)) { +bool vk_create_logical_dev(void) { + if (!is_device_suitable(g_physical_dev, g_surface)) { PTK_ERR("physical device isn't suitable"); - return PTK_OPTION_NONE(DeviceStuff); + return false; } - DeviceStuff ret = { - .queue_family_indices = m_queue_family_indices, - }; - VkDeviceQueueCreateInfo queue_create_infos[m_queue_family_count]; for (size_t i = 0; i < m_queue_family_count; ++i) { - const PTK_OPTION(uint32_t) index = *(((PTK_OPTION(uint32_t) *)&m_queue_family_indices) + i); + const PTK_OPTION(uint32_t) index = *(((PTK_OPTION(uint32_t) *)&g_queue_family_indices) + i); queue_create_infos[i] = (VkDeviceQueueCreateInfo){ .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, @@ -114,28 +113,28 @@ PTK_OPTION(DeviceStuff) vk_create_logical_dev(VkPhysicalDevice physical_dev, VkS }; } - VK_TRY(PTK_OPTION_NONE(DeviceStuff), + VK_TRY(false, vkCreateDevice( - physical_dev, + g_physical_dev, &(VkDeviceCreateInfo){ .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, .pNext = NULL, .flags = 0, .queueCreateInfoCount = m_queue_family_count, .pQueueCreateInfos = queue_create_infos, - .enabledLayerCount = validation_layers.size, - .ppEnabledLayerNames = validation_layers.data, + .enabledLayerCount = g_validation_layers.size, + .ppEnabledLayerNames = g_validation_layers.data, .enabledExtensionCount = m_device_extensions.size, .ppEnabledExtensionNames = m_device_extensions.data, .pEnabledFeatures = &(VkPhysicalDeviceFeatures){0}, }, NULL, - &ret.dev + &g_dev ) ); - vkGetDeviceQueue(ret.dev, m_queue_family_indices.graphics.value, 0, &ret.graphics_queue); - vkGetDeviceQueue(ret.dev, m_queue_family_indices.present.value, 0, &ret.present_queue); + vkGetDeviceQueue(g_dev, g_queue_family_indices.graphics.value, 0, &g_graphics_queue); + vkGetDeviceQueue(g_dev, g_queue_family_indices.present.value, 0, &g_present_queue); - return PTK_OPTION_SOME(DeviceStuff, ret); + return true; } diff --git a/src/ptk_vk/device.h b/src/ptk_vk/device.h index ff3b89a..a7195a6 100644 --- a/src/ptk_vk/device.h +++ b/src/ptk_vk/device.h @@ -3,10 +3,6 @@ #ifndef PTK_PTK_VK_DEVICE_H_ #define PTK_PTK_VK_DEVICE_H_ -// for PTK_ARRAY(constcharptr) -#include "ptk_vk/instance.h" - -#include "ptk_array.h" #include "ptk_option.h" #include @@ -18,15 +14,11 @@ typedef struct { PTK_OPTION(uint32_t) present; } QueueFamilyIndices; -typedef struct { - VkDevice dev; - QueueFamilyIndices queue_family_indices; - VkQueue graphics_queue; - VkQueue present_queue; -} DeviceStuff; +extern VkDevice g_dev; +extern QueueFamilyIndices g_queue_family_indices; +extern VkQueue g_graphics_queue; +extern VkQueue g_present_queue; -PTK_OPTION_DEFINE(DeviceStuff); - -PTK_OPTION(DeviceStuff) vk_create_logical_dev(VkPhysicalDevice physical_dev, VkSurfaceKHR surface, const PTK_ARRAY(constcharptr) validation_layers); +bool vk_create_logical_dev(void); #endif // PTK_PTK_VK_DEVICE_H_ diff --git a/src/ptk_vk/init.c b/src/ptk_vk/init.c index 3389df2..32da48f 100644 --- a/src/ptk_vk/init.c +++ b/src/ptk_vk/init.c @@ -2,8 +2,8 @@ #include "ptk_vk/init.h" +#include "ptk_vk/backend.h" #include "ptk_vk/buffer.h" -#include "ptk_vk/command_buffers.h" #include "ptk_vk/command_pool.h" #include "ptk_vk/components.h" #include "ptk_vk/descriptors.h" @@ -15,68 +15,13 @@ #include "ptk_vk/swapchain.h" #include "ptk_vk/sync_objects.h" #include "ptk_vk/uniform_buffers.h" -#include "ptk_vk/utils.h" -#include "ptk_array.h" #include "ptk_list.h" #include "ptk_log.h" -#include "ptk_option.h" #include -#include -#ifdef DEBUG -static const PTK_ARRAY(constcharptr) m_validation_layers = PTK_ARRAY_NEW(constcharptr, { - "VK_LAYER_KHRONOS_validation" -}); -#else -static const PTK_ARRAY(constcharptr) m_validation_layers = PTK_ARRAY_EMPTY(constcharptr); -#endif - -static VkInstance m_instance; -static VkDevice m_dev; -static VkPhysicalDevice m_physical_dev; - -static QueueFamilyIndices m_queue_family_indices; - -static VkQueue m_graphics_queue; -static VkQueue m_present_queue; - -static GLFWwindow *m_window; - -static VkSurfaceKHR m_surface; - -static VkDescriptorSetLayout m_descriptor_set_layout; -static VkPipelineLayout m_pipeline_layout; -static VkPipeline m_pipeline; - -static const size_t m_max_frames_in_flight = 2; - -static VkCommandPool m_command_pool; -static PTK_LIST(VkCommandBuffer) m_command_buffers; - -static PTK_LIST(VkSemaphore) m_image_available_semaphores; -static PTK_LIST(VkSemaphore) m_render_finished_semaphores; -static PTK_LIST(VkFence) m_in_flight_fences; - -static VkBuffer m_vertex_buffer; -static VkDeviceMemory m_vertex_buffer_memory; -static VkBuffer m_index_buffer; -static VkDeviceMemory m_index_buffer_memory; - -static UniformBufferObject m_uniform_buffer_object; - -static PTK_LIST(VkBuffer) m_uniform_buffers; -static PTK_LIST(VkDeviceMemory) m_uniform_buffer_memories; -static PTK_LIST(voidptr) m_uniform_buffers_mapped; - -static VkRenderPass m_render_pass; - -static VkDescriptorPool m_descriptor_pool; -static PTK_LIST(VkDescriptorSet) m_descriptor_sets; - -static bool m_framebuffer_resized = false; -static uint32_t m_current_frame = 0; +UniformBufferObject g_uniform_buffer_object; bool vk_transfer_vertex_data(void) { PTK_DEBUG("vertices updated!"); @@ -88,7 +33,7 @@ bool vk_transfer_vertex_data(void) { PTK_DEBUG("transferring vertices to gpu…"); const size_t vertices_size = sizeof(g_vertices.data[0]) * g_vertices.size; - if (!transfer_to_buffer(m_dev, m_physical_dev, m_command_pool, g_vertices.data, vertices_size, m_vertex_buffer, m_graphics_queue)) { + if (!transfer_to_buffer(g_dev, g_physical_dev, g_command_pool, g_vertices.data, vertices_size, g_vertex_buffer, g_graphics_queue)) { PTK_ERR("failed transferring vertices"); return false; } @@ -100,7 +45,7 @@ bool vk_transfer_vertex_data(void) { PTK_DEBUG("transferring indices to gpu…"); const size_t indices_size = sizeof(g_indices.data[0]) * g_indices.size; - if (!transfer_to_buffer(m_dev, m_physical_dev, m_command_pool, g_indices.data, indices_size, m_index_buffer, m_graphics_queue)) { + if (!transfer_to_buffer(g_dev, g_physical_dev, g_command_pool, g_indices.data, indices_size, g_index_buffer, g_graphics_queue)) { PTK_ERR("failed transferring indices"); return false; } @@ -108,402 +53,46 @@ bool vk_transfer_vertex_data(void) { return true; } -bool record_command_buffer(const VkCommandBuffer command_buffer, const uint32_t image_index) { - VK_TRY(false, - vkBeginCommandBuffer( - command_buffer, - &(VkCommandBufferBeginInfo){ - .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, - .pNext = NULL, - .flags = 0, - .pInheritanceInfo = NULL, - } - ) - ); +void vk_cleanup(void) { + vk_cleanup_swapchain(); - vkCmdBeginRenderPass( - command_buffer, - &(VkRenderPassBeginInfo){ - .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, - .pNext = NULL, - .renderPass = m_render_pass, - .framebuffer = vk_current_swapchain_framebuffers().data[image_index], - .renderArea = (VkRect2D){ - .offset = (VkOffset2D){ - .x = 0, - .y = 0, - }, - .extent = vk_current_swapchain_extent(), - }, - .clearValueCount = 1, - .pClearValues = &(VkClearValue){ - .color = (VkClearColorValue){ - .float32[0] = 0.0f, - .float32[1] = 0.0f, - .float32[2] = 0.0f, - .float32[3] = 1.0f, - }, - }, - }, - VK_SUBPASS_CONTENTS_INLINE - ); + vkDestroyPipeline(g_dev, g_pipeline, NULL); + vkDestroyPipelineLayout(g_dev, g_pipeline_layout, NULL); - vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline); + vkDestroyRenderPass(g_dev, g_render_pass, NULL); - vkCmdBindVertexBuffers(command_buffer, 0, 1, (VkBuffer []){m_vertex_buffer}, (VkDeviceSize []){0}); - - vkCmdBindIndexBuffer(command_buffer, m_index_buffer, 0, VK_INDEX_TYPE_UINT32); - - vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_layout, 0, 1, &m_descriptor_sets.data[m_current_frame], 0, NULL); - - vkCmdDrawIndexed(command_buffer, g_indices.size, 1, 0, 0, 0); - - vkCmdEndRenderPass(command_buffer); - - VK_TRY(false, - vkEndCommandBuffer(command_buffer) - ); - - return true; -} - -bool update_uniform_buffer(const size_t current_frame) { - const VkExtent2D current_extent = vk_current_swapchain_extent(); - m_uniform_buffer_object.window_size.w = current_extent.width; - m_uniform_buffer_object.window_size.h = current_extent.height; - - memcpy(m_uniform_buffers_mapped.data[current_frame], &m_uniform_buffer_object, sizeof(m_uniform_buffer_object)); - - return true; -} - -static void mouse_button_callback(GLFWwindow *window, int button, int action, int mods) { - double x, y; - glfwGetCursorPos(window, &x, &y); - vk_handle_mouse_button_input((PtkPos){ .x = x, .y = y }, button, action, mods); -} - -static void framebuffer_resized(GLFWwindow *window, int width, int height) { - (void)window; (void)width; (void)height; - m_framebuffer_resized = true; -} - -bool vk_init(GLFWwindow *window, const size_t width, const size_t height, const char *title, const PtkVersion version) { - m_window = window; - m_uniform_buffer_object.initial_window_size.w = width; - m_uniform_buffer_object.initial_window_size.h = height; - - vk_init_vertices(); - - glfwSetFramebufferSizeCallback(window, framebuffer_resized); - glfwSetMouseButtonCallback(window, mouse_button_callback); - - PTK_OPTION(VkInstance) instance_opt = vk_instance_create(title, version, m_validation_layers); - - if (!instance_opt.exists) { - PTK_ERR("failed creating VkInstance"); - return false; + for (size_t i = 0; i < g_max_frames_in_flight; ++i) { + vkDestroyBuffer(g_dev, g_uniform_buffers.data[i], NULL); + vkFreeMemory(g_dev, g_uniform_buffer_memories.data[i], NULL); } + PTK_LIST_FREE(g_uniform_buffers); + PTK_LIST_FREE(g_uniform_buffer_memories); + PTK_LIST_FREE(g_uniform_buffers_mapped); - m_instance = instance_opt.value; + vkDestroyDescriptorPool(g_dev, g_descriptor_pool, NULL); - PTK_OPTION(VkPhysicalDevice) physical_dev_opt = vk_select_physical_dev(m_instance); - - if (!physical_dev_opt.exists) { - PTK_ERR("failed selecting physical device"); - return false; - } - - m_physical_dev = physical_dev_opt.value; - - VK_TRY(false, glfwCreateWindowSurface(m_instance, m_window, NULL, &m_surface)); - - PTK_OPTION(DeviceStuff) dev_stuff_opt = vk_create_logical_dev(m_physical_dev, m_surface, m_validation_layers); - - if (!dev_stuff_opt.exists) { - PTK_ERR("failed creating logical device"); - return false; - } - - m_dev = dev_stuff_opt.value.dev; - m_queue_family_indices = dev_stuff_opt.value.queue_family_indices; - m_graphics_queue = dev_stuff_opt.value.graphics_queue; - m_present_queue = dev_stuff_opt.value.present_queue; - - if (!vk_create_swapchain(m_window, m_dev, m_physical_dev, m_surface, m_queue_family_indices)) { - PTK_ERR("failed creating swapchain"); - return false; - } - - if (!vk_create_image_views(m_dev)) { - PTK_ERR("failed creating image views"); - return false; - } - - PTK_OPTION(VkRenderPass) render_pass_opt = vk_create_render_pass(m_dev, vk_current_swapchain_image_format()); - - if (!render_pass_opt.exists) { - PTK_ERR("failed creating render pass"); - return false; - } - - m_render_pass = render_pass_opt.value; - - PTK_OPTION(VkDescriptorSetLayout) descriptor_set_layout_opt = vk_create_descriptor_set_layout(m_dev); - - if (!descriptor_set_layout_opt.exists) { - PTK_ERR("failed creating descriptor set layout"); - return false; - } - - m_descriptor_set_layout = descriptor_set_layout_opt.value; - - PTK_OPTION(PipelineStuff) pipeline_stuff_opt = vk_create_pipeline(m_dev, m_render_pass, m_descriptor_set_layout, vk_current_swapchain_extent()); - - if (!pipeline_stuff_opt.exists) { - PTK_ERR("failed creating graphics pipeline"); - return false; - } - - m_pipeline = pipeline_stuff_opt.value.pipeline; - m_pipeline_layout = pipeline_stuff_opt.value.pipeline_layout; - - if (!vk_create_framebuffers(m_dev, m_render_pass)) { - PTK_ERR("failed creating framebuffers"); - return false; - } - - PTK_OPTION(VkCommandPool) command_pool_opt = vk_create_command_pool(m_dev, m_queue_family_indices.graphics.value); - - if (!command_pool_opt.exists) { - PTK_ERR("failed creating command pool"); - return false; - } - - m_command_pool = command_pool_opt.value; - - const VkDeviceSize buffer_size = 65536; - - PTK_OPTION(BufferStuff) vertex_buffer_stuff_opt = create_buffer( - m_dev, - m_physical_dev, - buffer_size, - VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, - VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT - ); - - if (!vertex_buffer_stuff_opt.exists) { - PTK_ERR("failed creating vertex buffer"); - return false; - } - - m_vertex_buffer = vertex_buffer_stuff_opt.value.buffer; - m_vertex_buffer_memory = vertex_buffer_stuff_opt.value.buffer_memory; - - PTK_OPTION(BufferStuff) index_buffer_stuff_opt = create_buffer( - m_dev, - m_physical_dev, - buffer_size, - VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, - VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT - ); - - if (!index_buffer_stuff_opt.exists) { - PTK_ERR("failed creating index buffer"); - return false; - } - - m_index_buffer = index_buffer_stuff_opt.value.buffer; - m_index_buffer_memory = index_buffer_stuff_opt.value.buffer_memory; - - PTK_OPTION(UniformBufferStuff) uniform_buffer_stuff_opt = vk_create_uniform_buffers(m_dev, m_physical_dev, m_max_frames_in_flight); - - if (!uniform_buffer_stuff_opt.exists) { - PTK_ERR("failed creating uniform buffers"); - return false; - } - - m_uniform_buffers = uniform_buffer_stuff_opt.value.buffers; - m_uniform_buffer_memories = uniform_buffer_stuff_opt.value.buffer_memories; - m_uniform_buffers_mapped = uniform_buffer_stuff_opt.value.buffers_mapped; - - PTK_OPTION(VkDescriptorPool) descriptor_pool_opt = vk_create_descriptor_pool(m_dev, m_max_frames_in_flight); - - if (!descriptor_pool_opt.exists) { - PTK_ERR("failed creating descriptor pool"); - return false; - } - - m_descriptor_pool = descriptor_pool_opt.value; - - PTK_OPTION(VkDescriptorSetList) descriptor_sets_opt = vk_create_descriptor_sets(m_dev, m_descriptor_set_layout, m_descriptor_pool, m_uniform_buffers, m_max_frames_in_flight); - - if (!descriptor_sets_opt.exists) { - PTK_ERR("failed creating descriptor sets"); - return false; - } - - m_descriptor_sets = descriptor_sets_opt.value; - - PTK_OPTION(VkCommandBufferList) command_buffers_opt = vk_allocate_command_buffers(m_dev, m_command_pool, m_max_frames_in_flight); - - if (!command_buffers_opt.exists) { - PTK_ERR("failed allocating command buffers"); - return false; - } - - m_command_buffers = command_buffers_opt.value; - - PTK_OPTION(SyncObjects) sync_objects_opt = vk_create_sync_objects(m_dev, m_max_frames_in_flight); - - if (!sync_objects_opt.exists) { - PTK_ERR("failed creating sync objects"); - return false; - } - - m_image_available_semaphores = sync_objects_opt.value.image_available_semaphores; - m_render_finished_semaphores = sync_objects_opt.value.render_finished_semaphores; - m_in_flight_fences = sync_objects_opt.value.in_flight_fences; - - return true; -} - -bool vk_is_done(void) { - return glfwWindowShouldClose(m_window); -} - -bool vk_draw_frame(void) { - vkWaitForFences(m_dev, 1, &m_in_flight_fences.data[m_current_frame], VK_TRUE, UINT64_MAX); - - uint32_t image_index; - const VkResult acquire_next_image_result = vkAcquireNextImageKHR( - m_dev, - vk_current_swapchain(), - UINT64_MAX, - m_image_available_semaphores.data[m_current_frame], - VK_NULL_HANDLE, - &image_index - ); - - if (acquire_next_image_result == VK_ERROR_OUT_OF_DATE_KHR) { - if (!vk_recreate_swapchain(m_window, m_dev, m_physical_dev, m_surface, m_queue_family_indices, m_render_pass)) { - return false; - } - return true; - } else if (acquire_next_image_result != VK_SUCCESS && acquire_next_image_result != VK_SUBOPTIMAL_KHR) { - PTK_ERR("%s", vk_result_string(acquire_next_image_result)); - return false; - } - - update_uniform_buffer(m_current_frame); - - vkResetFences(m_dev, 1, &m_in_flight_fences.data[m_current_frame]); - - vkResetCommandBuffer(m_command_buffers.data[m_current_frame], 0); - if (!record_command_buffer(m_command_buffers.data[m_current_frame], image_index)) { - PTK_ERR("failed recording command buffer"); - return false; - } - - const VkSemaphore signal_semaphores[] = {m_render_finished_semaphores.data[m_current_frame]}; - - VK_TRY(false, - vkQueueSubmit( - m_graphics_queue, - 1, - &(VkSubmitInfo){ - .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, - .pNext = NULL, - .waitSemaphoreCount = 1, - .pWaitSemaphores = &m_image_available_semaphores.data[m_current_frame], - .pWaitDstStageMask = &(VkPipelineStageFlags){VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}, - .commandBufferCount = 1, - .pCommandBuffers = &m_command_buffers.data[m_current_frame], - .signalSemaphoreCount = 1, - .pSignalSemaphores = signal_semaphores, - }, - m_in_flight_fences.data[m_current_frame] - ) - ); - - const VkResult queue_present_result = vkQueuePresentKHR(m_present_queue, &(VkPresentInfoKHR){ - .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, - .pNext = NULL, - .waitSemaphoreCount = 1, - .pWaitSemaphores = signal_semaphores, - .swapchainCount = 1, - .pSwapchains = &(VkSwapchainKHR){vk_current_swapchain()}, - .pImageIndices = &image_index, - .pResults = NULL, - }); - - if ( - queue_present_result == VK_ERROR_OUT_OF_DATE_KHR || - queue_present_result == VK_SUBOPTIMAL_KHR || - m_framebuffer_resized - ) { - m_framebuffer_resized = false; - if (!vk_recreate_swapchain(m_window, m_dev, m_physical_dev, m_surface, m_queue_family_indices, m_render_pass)) { - return false; - } - PTK_TRACE("recreated swapchain"); - } else if (queue_present_result != VK_SUCCESS) { - PTK_ERR("%s", vk_result_string(queue_present_result)); - return false; - } - - m_current_frame = (m_current_frame + 1) % m_max_frames_in_flight; - - return true; -} - -void cleanup(void) { - vk_cleanup_swapchain(m_dev); - - vkDestroyPipeline(m_dev, m_pipeline, NULL); - vkDestroyPipelineLayout(m_dev, m_pipeline_layout, NULL); - - vkDestroyRenderPass(m_dev, m_render_pass, NULL); - - for (size_t i = 0; i < m_max_frames_in_flight; ++i) { - vkDestroyBuffer(m_dev, m_uniform_buffers.data[i], NULL); - vkFreeMemory(m_dev, m_uniform_buffer_memories.data[i], NULL); - } - PTK_LIST_FREE(m_uniform_buffers); - PTK_LIST_FREE(m_uniform_buffer_memories); - PTK_LIST_FREE(m_uniform_buffers_mapped); - - vkDestroyDescriptorPool(m_dev, m_descriptor_pool, NULL); - - vkDestroyDescriptorSetLayout(m_dev, m_descriptor_set_layout, NULL); + vkDestroyDescriptorSetLayout(g_dev, g_descriptor_set_layout, NULL); - vkDestroyBuffer(m_dev, m_index_buffer, NULL); - vkFreeMemory(m_dev, m_index_buffer_memory, NULL); + vkDestroyBuffer(g_dev, g_index_buffer, NULL); + vkFreeMemory(g_dev, g_index_buffer_memory, NULL); - vkDestroyBuffer(m_dev, m_vertex_buffer, NULL); - vkFreeMemory(m_dev, m_vertex_buffer_memory, NULL); + vkDestroyBuffer(g_dev, g_vertex_buffer, NULL); + vkFreeMemory(g_dev, g_vertex_buffer_memory, NULL); - for (size_t i = 0; i < m_max_frames_in_flight; ++i) { - vkDestroySemaphore(m_dev, m_image_available_semaphores.data[i], NULL); - vkDestroySemaphore(m_dev, m_render_finished_semaphores.data[i], NULL); - vkDestroyFence(m_dev, m_in_flight_fences.data[i], NULL); + for (size_t i = 0; i < g_max_frames_in_flight; ++i) { + vkDestroySemaphore(g_dev, g_image_available_semaphores.data[i], NULL); + vkDestroySemaphore(g_dev, g_render_finished_semaphores.data[i], NULL); + vkDestroyFence(g_dev, g_in_flight_fences.data[i], NULL); } - vkDestroyCommandPool(m_dev, m_command_pool, NULL); + vkDestroyCommandPool(g_dev, g_command_pool, NULL); - vkDestroyDevice(m_dev, NULL); + vkDestroyDevice(g_dev, NULL); - vkDestroySurfaceKHR(m_instance, m_surface, NULL); - vkDestroyInstance(m_instance, NULL); + vkDestroySurfaceKHR(g_instance, g_surface, NULL); + vkDestroyInstance(g_instance, NULL); - glfwDestroyWindow(m_window); + glfwDestroyWindow(g_window); glfwTerminate(); } - -void vk_finish(void) { - vkDeviceWaitIdle(m_dev); - - cleanup(); - vk_components_cleanup(); -} diff --git a/src/ptk_vk/init.h b/src/ptk_vk/init.h index e5f1350..0b19147 100644 --- a/src/ptk_vk/init.h +++ b/src/ptk_vk/init.h @@ -3,23 +3,14 @@ #ifndef PTK_PTK_VK_INIT_H_ #define PTK_PTK_VK_INIT_H_ -#include "ptk.h" - -#ifndef GLFW_INCLUDE_VULKAN -#define GLFW_INCLUDE_VULKAN -#endif -#include +#include "ptk_vk/uniform_buffers.h" #include -bool vk_init(GLFWwindow *window, const size_t width, const size_t height, const char *title, const PtkVersion version); - -bool vk_is_done(void); - -bool vk_draw_frame(void); - -void vk_finish(void); +extern UniformBufferObject g_uniform_buffer_object; bool vk_transfer_vertex_data(void); +void vk_cleanup(void); + #endif // PTK_PTK_VK_INIT_H_ diff --git a/src/ptk_vk/instance.c b/src/ptk_vk/instance.c index b164191..ddff035 100644 --- a/src/ptk_vk/instance.c +++ b/src/ptk_vk/instance.c @@ -2,6 +2,7 @@ #include "ptk_vk/instance.h" +#include "ptk_vk/backend.h" #include "ptk_vk/utils.h" #include "ptk_array.h" @@ -46,20 +47,20 @@ bool check_validation_layers(const PTK_ARRAY(constcharptr) validation_layers) { } #endif -PTK_OPTION(VkInstance) vk_instance_create(const char *title, const PtkVersion version, const PTK_ARRAY(constcharptr) validation_layers) { +VkInstance g_instance; + +bool vk_instance_create(const char *title, const PtkVersion version) { #ifdef DEBUG - if (!check_validation_layers(validation_layers)) { + if (!check_validation_layers(g_validation_layers)) { PTK_ERR("couldn't find requested validation layer"); - return PTK_OPTION_NONE(VkInstance); + return false; } #endif PTK_ARRAY(constcharptr) extension_names = PTK_ARRAY_EMPTY(constcharptr); extension_names.data = glfwGetRequiredInstanceExtensions(&extension_names.size); - VkInstance ret; - - VK_TRY(PTK_OPTION_NONE(VkInstance), + VK_TRY(false, vkCreateInstance( &(VkInstanceCreateInfo){ .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, @@ -74,15 +75,15 @@ PTK_OPTION(VkInstance) vk_instance_create(const char *title, const PtkVersion ve .engineVersion = VK_MAKE_API_VERSION(0, PTK_VERSION_MAJOR, PTK_VERSION_MINOR, PTK_VERSION_PATCH), .apiVersion = VK_API_VERSION_1_3, }, - .enabledLayerCount = validation_layers.size, - .ppEnabledLayerNames = validation_layers.data, + .enabledLayerCount = g_validation_layers.size, + .ppEnabledLayerNames = g_validation_layers.data, .enabledExtensionCount = extension_names.size, .ppEnabledExtensionNames = extension_names.data, }, NULL, - &ret + &g_instance ) ); - return PTK_OPTION_SOME(VkInstance, ret); + return true; } diff --git a/src/ptk_vk/instance.h b/src/ptk_vk/instance.h index 6c22dd4..c7b6f6d 100644 --- a/src/ptk_vk/instance.h +++ b/src/ptk_vk/instance.h @@ -4,15 +4,11 @@ #define PTK_PTK_VK_INSTANCE_H_ #include "ptk.h" -#include "ptk_array.h" -#include "ptk_option.h" #include -PTK_OPTION_DEFINE(VkInstance); -typedef const char *constcharptr; -PTK_ARRAY_DEFINE(constcharptr); +extern VkInstance g_instance; -PTK_OPTION(VkInstance) vk_instance_create(const char *title, const PtkVersion version, const PTK_ARRAY(constcharptr) validation_layers); +bool vk_instance_create(const char *title, const PtkVersion version); #endif // PTK_PTK_VK_INSTANCE_H_ diff --git a/src/ptk_vk/physical_device.c b/src/ptk_vk/physical_device.c index b32d429..d340736 100644 --- a/src/ptk_vk/physical_device.c +++ b/src/ptk_vk/physical_device.c @@ -2,19 +2,21 @@ #include "ptk_vk/physical_device.h" +#include "ptk_vk/instance.h" + #include "ptk_log.h" -#include +VkPhysicalDevice g_physical_dev; -PTK_OPTION(VkPhysicalDevice) vk_select_physical_dev(const VkInstance instance) { +bool vk_select_physical_dev(void) { uint32_t dev_count = 0; - vkEnumeratePhysicalDevices(instance, &dev_count, NULL); + vkEnumeratePhysicalDevices(g_instance, &dev_count, NULL); if (dev_count == 0) { PTK_ERR("failed to find GPU with vulkan support"); - return PTK_OPTION_NONE(VkPhysicalDevice); + return false; } VkPhysicalDevice devs[dev_count]; - vkEnumeratePhysicalDevices(instance, &dev_count, devs); + vkEnumeratePhysicalDevices(g_instance, &dev_count, devs); VkPhysicalDeviceProperties dev_props[dev_count]; uint32_t dgpus[dev_count]; @@ -73,5 +75,7 @@ PTK_OPTION(VkPhysicalDevice) vk_select_physical_dev(const VkInstance instance) { PTK_DEBUG("total memory: %lu", dev_mem_totals[dev_best_index]); - return PTK_OPTION_SOME(VkPhysicalDevice, devs[dev_best_index]); + g_physical_dev = devs[dev_best_index]; + + return true; } diff --git a/src/ptk_vk/physical_device.h b/src/ptk_vk/physical_device.h index f6751ef..2e1fb25 100644 --- a/src/ptk_vk/physical_device.h +++ b/src/ptk_vk/physical_device.h @@ -3,12 +3,12 @@ #ifndef PTK_PTK_VK_PHYSICAL_DEVICE_H_ #define PTK_PTK_VK_PHYSICAL_DEVICE_H_ -#include "ptk_option.h" - #include -PTK_OPTION_DEFINE(VkPhysicalDevice); +#include -PTK_OPTION(VkPhysicalDevice) vk_select_physical_dev(const VkInstance instance); +extern VkPhysicalDevice g_physical_dev; + +bool vk_select_physical_dev(void); #endif // PTK_PTK_VK_PHYSICAL_DEVICE_H_ diff --git a/src/ptk_vk/pipeline.c b/src/ptk_vk/pipeline.c index c5f4581..6cb702e 100644 --- a/src/ptk_vk/pipeline.c +++ b/src/ptk_vk/pipeline.c @@ -3,14 +3,22 @@ #include "ptk_vk/pipeline.h" #include "ptk_vk/components.h" +#include "ptk_vk/descriptors.h" +#include "ptk_vk/device.h" +#include "ptk_vk/render_pass.h" +#include "ptk_vk/swapchain.h" #include "ptk_vk/utils.h" #include "ptk_array.h" +#include "ptk_option.h" #include "ptk_log.h" #include "errno.h" #include "stdio.h" +VkPipeline g_pipeline; +VkPipelineLayout g_pipeline_layout; + PTK_OPTION_DEFINE(VkShaderModule); PTK_ARRAY_DEFINE(VkVertexInputAttributeDescription); @@ -107,22 +115,22 @@ PTK_OPTION(VkShaderModule) create_shader_module(VkDevice dev, const PTK_STRING c return PTK_OPTION_SOME(VkShaderModule, shader_module); } -PTK_OPTION(PipelineStuff) vk_create_pipeline(VkDevice dev, VkRenderPass render_pass, VkDescriptorSetLayout descriptor_set_layout, VkExtent2D swapchain_extent) { +bool vk_create_pipeline(void) { const PTK_STRING vert_shader_code = read_spv("target/shaders/shader.vert.spv"); const PTK_STRING frag_shader_code = read_spv("target/shaders/shader.frag.spv"); - const PTK_OPTION(VkShaderModule) vert_shader_module = create_shader_module(dev, vert_shader_code); + const PTK_OPTION(VkShaderModule) vert_shader_module = create_shader_module(g_dev, vert_shader_code); if (!vert_shader_module.exists) { PTK_ERR("failed creating vert shader module"); - return PTK_OPTION_NONE(PipelineStuff); + return false; } - const PTK_OPTION(VkShaderModule) frag_shader_module = create_shader_module(dev, frag_shader_code); + const PTK_OPTION(VkShaderModule) frag_shader_module = create_shader_module(g_dev, frag_shader_code); if (!frag_shader_module.exists) { PTK_ERR("failed creating frag shader module"); - return PTK_OPTION_NONE(PipelineStuff); + return false; } const VkSpecializationInfo spec_info = { @@ -191,8 +199,8 @@ PTK_OPTION(PipelineStuff) vk_create_pipeline(VkDevice dev, VkRenderPass render_p .pViewports = &(VkViewport){ .x = 0.0f, .y = 0.0f, - .width = (float) swapchain_extent.width, - .height = (float) swapchain_extent.height, + .width = (float) g_swapchain_extent.width, + .height = (float) g_swapchain_extent.height, .minDepth = 0.0f, .maxDepth = 1.0f, }, @@ -202,7 +210,7 @@ PTK_OPTION(PipelineStuff) vk_create_pipeline(VkDevice dev, VkRenderPass render_p .x = 0, .y = 0, }, - .extent = swapchain_extent, + .extent = g_swapchain_extent, }, }; @@ -259,28 +267,26 @@ PTK_OPTION(PipelineStuff) vk_create_pipeline(VkDevice dev, VkRenderPass render_p .blendConstants[3] = 0.0f, }; - PipelineStuff ret; - - VK_TRY(PTK_OPTION_NONE(PipelineStuff), + VK_TRY(false, vkCreatePipelineLayout( - dev, + g_dev, &(VkPipelineLayoutCreateInfo){ .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, .pNext = NULL, .flags = 0, .setLayoutCount = 1, - .pSetLayouts = &descriptor_set_layout, + .pSetLayouts = &g_descriptor_set_layout, .pushConstantRangeCount = 0, .pPushConstantRanges = NULL, }, NULL, - &ret.pipeline_layout + &g_pipeline_layout ) ); - VK_TRY(PTK_OPTION_NONE(PipelineStuff), + VK_TRY(false, vkCreateGraphicsPipelines( - dev, + g_dev, VK_NULL_HANDLE, 1, &(VkGraphicsPipelineCreateInfo){ @@ -298,19 +304,19 @@ PTK_OPTION(PipelineStuff) vk_create_pipeline(VkDevice dev, VkRenderPass render_p .pDepthStencilState = NULL, .pColorBlendState = &color_blending, .pDynamicState = &dynamic_state, - .layout = ret.pipeline_layout, - .renderPass = render_pass, + .layout = g_pipeline_layout, + .renderPass = g_render_pass, .subpass = 0, .basePipelineHandle = VK_NULL_HANDLE, .basePipelineIndex = -1, }, NULL, - &ret.pipeline + &g_pipeline ) ); - vkDestroyShaderModule(dev, vert_shader_module.value, NULL); - vkDestroyShaderModule(dev, frag_shader_module.value, NULL); + vkDestroyShaderModule(g_dev, vert_shader_module.value, NULL); + vkDestroyShaderModule(g_dev, frag_shader_module.value, NULL); - return PTK_OPTION_SOME(PipelineStuff, ret); + return true; } diff --git a/src/ptk_vk/pipeline.h b/src/ptk_vk/pipeline.h index c38ace9..e3b9441 100644 --- a/src/ptk_vk/pipeline.h +++ b/src/ptk_vk/pipeline.h @@ -3,17 +3,13 @@ #ifndef PTK_PTK_VK_PIPELINE_H_ #define PTK_PTK_VK_PIPELINE_H_ -#include "ptk_option.h" - #include -typedef struct { - VkPipeline pipeline; - VkPipelineLayout pipeline_layout; -} PipelineStuff; +#include -PTK_OPTION_DEFINE(PipelineStuff); +extern VkPipeline g_pipeline; +extern VkPipelineLayout g_pipeline_layout; -PTK_OPTION(PipelineStuff) vk_create_pipeline(VkDevice dev, VkRenderPass render_pass, VkDescriptorSetLayout descriptor_set_layout, VkExtent2D swapchain_extent); +bool vk_create_pipeline(void); #endif // PTK_PTK_VK_PIPELINE_H_ diff --git a/src/ptk_vk/render_pass.c b/src/ptk_vk/render_pass.c index b6310b4..dfa848c 100644 --- a/src/ptk_vk/render_pass.c +++ b/src/ptk_vk/render_pass.c @@ -2,14 +2,16 @@ #include "ptk_vk/render_pass.h" +#include "ptk_vk/device.h" +#include "ptk_vk/swapchain.h" #include "ptk_vk/utils.h" -PTK_OPTION(VkRenderPass) vk_create_render_pass(VkDevice dev, VkFormat format) { - VkRenderPass ret; +VkRenderPass g_render_pass; - VK_TRY(PTK_OPTION_NONE(VkRenderPass), +bool vk_create_render_pass(void) { + VK_TRY(false, vkCreateRenderPass( - dev, + g_dev, &(VkRenderPassCreateInfo){ .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, .pNext = NULL, @@ -17,7 +19,7 @@ PTK_OPTION(VkRenderPass) vk_create_render_pass(VkDevice dev, VkFormat format) { .attachmentCount = 1, .pAttachments = &(VkAttachmentDescription){ .flags = 0, - .format = format, + .format = g_swapchain_image_format, .samples = VK_SAMPLE_COUNT_1_BIT, .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, .storeOp = VK_ATTACHMENT_STORE_OP_STORE, @@ -54,9 +56,9 @@ PTK_OPTION(VkRenderPass) vk_create_render_pass(VkDevice dev, VkFormat format) { }, }, NULL, - &ret + &g_render_pass ) ); - return PTK_OPTION_SOME(VkRenderPass, ret); + return true; } diff --git a/src/ptk_vk/render_pass.h b/src/ptk_vk/render_pass.h index e2bafe5..d811129 100644 --- a/src/ptk_vk/render_pass.h +++ b/src/ptk_vk/render_pass.h @@ -3,14 +3,12 @@ #ifndef PTK_PTK_VK_RENDER_PASS_H_ #define PTK_PTK_VK_RENDER_PASS_H_ -#include "ptk_option.h" - #include #include -PTK_OPTION_DEFINE(VkRenderPass); +extern VkRenderPass g_render_pass; -PTK_OPTION(VkRenderPass) vk_create_render_pass(VkDevice dev, VkFormat format); +bool vk_create_render_pass(void); #endif // PTK_PTK_VK_RENDER_PASS_H_ diff --git a/src/ptk_vk/swapchain.c b/src/ptk_vk/swapchain.c index d09715c..0208f1f 100644 --- a/src/ptk_vk/swapchain.c +++ b/src/ptk_vk/swapchain.c @@ -2,6 +2,10 @@ #include "ptk_vk/swapchain.h" +#include "ptk_vk/backend.h" +#include "ptk_vk/device.h" +#include "ptk_vk/physical_device.h" +#include "ptk_vk/render_pass.h" #include "ptk_vk/utils.h" #include "ptk_list.h" @@ -11,18 +15,16 @@ #endif #include -static VkSwapchainKHR m_swapchain; - PTK_LIST_DEFINE(VkImage); PTK_LIST_DEFINE(VkImageView); static PTK_LIST(VkImage) m_swapchain_images; static PTK_LIST(VkImageView) m_swapchain_image_views; -static VkFormat m_swapchain_image_format; -static VkExtent2D m_swapchain_extent; - -static PTK_LIST(VkFramebuffer) m_swapchain_framebuffers; +VkSwapchainKHR g_swapchain; +VkFormat g_swapchain_image_format; +VkExtent2D g_swapchain_extent; +PTK_LIST(VkFramebuffer) g_swapchain_framebuffers; VkSurfaceFormatKHR select_swap_surface_format(const PTK_LIST(VkSurfaceFormatKHR) available_formats) { PTK_LIST_FOR_EACH(const VkSurfaceFormatKHR, available_formats, current_format, { @@ -108,20 +110,89 @@ SwapchainSupportInfo query_swapchain_support(const VkPhysicalDevice dev, const V return info; } -bool vk_create_image_views(VkDevice dev) { +bool vk_create_swapchain(void) { + const SwapchainSupportInfo swapchain_support = query_swapchain_support(g_physical_dev, g_surface); + + const VkSurfaceFormatKHR surface_format = select_swap_surface_format(swapchain_support.formats); + const VkPresentModeKHR present_mode = select_swap_present_mode(swapchain_support.present_modes); + const VkExtent2D extent = select_swap_extent(swapchain_support.capabilities, g_window); + + uint32_t image_count = swapchain_support.capabilities.minImageCount + 1; + + if (swapchain_support.capabilities.maxImageCount > 0 && image_count > swapchain_support.capabilities.maxImageCount) { + image_count = swapchain_support.capabilities.maxImageCount; + } + + const bool queue_families_differ = g_queue_family_indices.graphics.value != g_queue_family_indices.present.value; + + VK_TRY(false, + vkCreateSwapchainKHR( + g_dev, + &(VkSwapchainCreateInfoKHR){ + .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, + .pNext = NULL, + .flags = 0, + .surface = g_surface, + .minImageCount = image_count, + .imageFormat = surface_format.format, + .imageColorSpace = surface_format.colorSpace, + .imageExtent = extent, + .imageArrayLayers = 1, + .imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, + .imageSharingMode = + queue_families_differ + ? VK_SHARING_MODE_CONCURRENT + : VK_SHARING_MODE_EXCLUSIVE, + .queueFamilyIndexCount = + queue_families_differ + ? 2 + : 0, + .pQueueFamilyIndices = + queue_families_differ + ? (const uint32_t []){ + g_queue_family_indices.graphics.value, + g_queue_family_indices.present.value + } + : NULL, + .preTransform = swapchain_support.capabilities.currentTransform, + .compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, + .presentMode = present_mode, + .clipped = VK_TRUE, + .oldSwapchain = VK_NULL_HANDLE, + }, + NULL, + &g_swapchain + ) + ); + + vkGetSwapchainImagesKHR(g_dev, g_swapchain, &m_swapchain_images.allocated, NULL); + m_swapchain_images = PTK_LIST_NEW(VkImage, m_swapchain_images.allocated); + vkGetSwapchainImagesKHR(g_dev, g_swapchain, &m_swapchain_images.allocated, m_swapchain_images.data); + PTK_LIST_FILLED(m_swapchain_images); + + g_swapchain_image_format = surface_format.format; + g_swapchain_extent = extent; + + PTK_LIST_FREE(swapchain_support.formats); + PTK_LIST_FREE(swapchain_support.present_modes); + + return true; +} + +bool vk_create_image_views(void) { m_swapchain_image_views = PTK_LIST_NEW(VkImageView, m_swapchain_images.size); PTK_LIST_FOR_EACH_E(VkImage, m_swapchain_images, i, swapchain_image, { VK_TRY(false, vkCreateImageView( - dev, + g_dev, &(VkImageViewCreateInfo){ .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, .pNext = NULL, .flags = 0, .image = swapchain_image, .viewType = VK_IMAGE_VIEW_TYPE_2D, - .format = m_swapchain_image_format, + .format = g_swapchain_image_format, .components = (VkComponentMapping){ .r = VK_COMPONENT_SWIZZLE_IDENTITY, .g = VK_COMPONENT_SWIZZLE_IDENTITY, @@ -146,115 +217,30 @@ bool vk_create_image_views(VkDevice dev) { return true; } -VkSwapchainKHR vk_current_swapchain(void) { - return m_swapchain; -} - -VkFormat vk_current_swapchain_image_format(void) { - return m_swapchain_image_format; -} - -VkExtent2D vk_current_swapchain_extent(void) { - return m_swapchain_extent; -} - -PTK_LIST(VkFramebuffer) vk_current_swapchain_framebuffers(void) { - return m_swapchain_framebuffers; -} - -bool vk_create_swapchain(GLFWwindow *window, VkDevice dev, VkPhysicalDevice physical_dev, VkSurfaceKHR surface, QueueFamilyIndices queue_family_indices) { - const SwapchainSupportInfo swapchain_support = query_swapchain_support(physical_dev, surface); - - const VkSurfaceFormatKHR surface_format = select_swap_surface_format(swapchain_support.formats); - const VkPresentModeKHR present_mode = select_swap_present_mode(swapchain_support.present_modes); - const VkExtent2D extent = select_swap_extent(swapchain_support.capabilities, window); - - uint32_t image_count = swapchain_support.capabilities.minImageCount + 1; - - if (swapchain_support.capabilities.maxImageCount > 0 && image_count > swapchain_support.capabilities.maxImageCount) { - image_count = swapchain_support.capabilities.maxImageCount; - } - - const bool queue_families_differ = queue_family_indices.graphics.value != queue_family_indices.present.value; - - VK_TRY(false, - vkCreateSwapchainKHR( - dev, - &(VkSwapchainCreateInfoKHR){ - .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, - .pNext = NULL, - .flags = 0, - .surface = surface, - .minImageCount = image_count, - .imageFormat = surface_format.format, - .imageColorSpace = surface_format.colorSpace, - .imageExtent = extent, - .imageArrayLayers = 1, - .imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, - .imageSharingMode = - queue_families_differ - ? VK_SHARING_MODE_CONCURRENT - : VK_SHARING_MODE_EXCLUSIVE, - .queueFamilyIndexCount = - queue_families_differ - ? 2 - : 0, - .pQueueFamilyIndices = - queue_families_differ - ? (const uint32_t []){ - queue_family_indices.graphics.value, - queue_family_indices.present.value - } - : NULL, - .preTransform = swapchain_support.capabilities.currentTransform, - .compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, - .presentMode = present_mode, - .clipped = VK_TRUE, - .oldSwapchain = VK_NULL_HANDLE, - }, - NULL, - &m_swapchain - ) - ); - - vkGetSwapchainImagesKHR(dev, m_swapchain, &m_swapchain_images.allocated, NULL); - m_swapchain_images = PTK_LIST_NEW(VkImage, m_swapchain_images.allocated); - vkGetSwapchainImagesKHR(dev, m_swapchain, &m_swapchain_images.allocated, m_swapchain_images.data); - PTK_LIST_FILLED(m_swapchain_images); - - m_swapchain_image_format = surface_format.format; - m_swapchain_extent = extent; - - PTK_LIST_FREE(swapchain_support.formats); - PTK_LIST_FREE(swapchain_support.present_modes); - - return true; -} - -bool vk_recreate_swapchain(GLFWwindow *window, VkDevice dev, VkPhysicalDevice physical_dev, VkSurfaceKHR surface, QueueFamilyIndices queue_family_indices, VkRenderPass render_pass) { +bool vk_recreate_swapchain(void) { int width = 0, height = 0; - glfwGetFramebufferSize(window, &width, &height); + glfwGetFramebufferSize(g_window, &width, &height); while (width == 0 || height == 0) { - glfwGetFramebufferSize(window, &width, &height); + glfwGetFramebufferSize(g_window, &width, &height); glfwWaitEvents(); } - vkDeviceWaitIdle(dev); + vkDeviceWaitIdle(g_dev); - vk_cleanup_swapchain(dev); + vk_cleanup_swapchain(); - if (!vk_create_swapchain(window, dev, physical_dev, surface, queue_family_indices)) { + if (!vk_create_swapchain()) { PTK_ERR("failed creating new swapchain"); return false; } - if (!vk_create_image_views(dev)) { + if (!vk_create_image_views()) { PTK_ERR("failed creating new image views"); return false; } - if (!vk_create_framebuffers(dev, render_pass)) { + if (!vk_create_framebuffers()) { PTK_ERR("failed creating new framebuffers"); return false; } @@ -262,48 +248,48 @@ bool vk_recreate_swapchain(GLFWwindow *window, VkDevice dev, VkPhysicalDevice ph return true; } -bool vk_create_framebuffers(VkDevice dev, VkRenderPass render_pass) { - m_swapchain_framebuffers = PTK_LIST_NEW(VkFramebuffer, m_swapchain_image_views.size); +bool vk_create_framebuffers(void) { + g_swapchain_framebuffers = PTK_LIST_NEW(VkFramebuffer, m_swapchain_image_views.size); VkFramebuffer fb; PTK_LIST_FOR_EACH(VkImageView, m_swapchain_image_views, swapchain_image_view, { VK_TRY(false, vkCreateFramebuffer( - dev, + g_dev, &(VkFramebufferCreateInfo){ .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, .pNext = NULL, .flags = 0, - .renderPass = render_pass, + .renderPass = g_render_pass, .attachmentCount = 1, .pAttachments = &swapchain_image_view, - .width = m_swapchain_extent.width, - .height = m_swapchain_extent.height, + .width = g_swapchain_extent.width, + .height = g_swapchain_extent.height, .layers = 1, }, NULL, &fb ) ); - PTK_LIST_ADD(VkFramebuffer, m_swapchain_framebuffers, fb); + PTK_LIST_ADD(VkFramebuffer, g_swapchain_framebuffers, fb); }) return true; } -void vk_cleanup_swapchain(VkDevice dev) { - PTK_LIST_FOR_EACH(VkFramebuffer, m_swapchain_framebuffers, fb, { - vkDestroyFramebuffer(dev, fb, NULL); +void vk_cleanup_swapchain(void) { + PTK_LIST_FOR_EACH(VkFramebuffer, g_swapchain_framebuffers, fb, { + vkDestroyFramebuffer(g_dev, fb, NULL); }) - PTK_LIST_FREE(m_swapchain_framebuffers); + PTK_LIST_FREE(g_swapchain_framebuffers); PTK_LIST_FREE(m_swapchain_images); PTK_LIST_FOR_EACH(VkImageView, m_swapchain_image_views, iv, { - vkDestroyImageView(dev, iv, NULL); + vkDestroyImageView(g_dev, iv, NULL); }) PTK_LIST_FREE(m_swapchain_image_views); - vkDestroySwapchainKHR(dev, m_swapchain, NULL); + vkDestroySwapchainKHR(g_dev, g_swapchain, NULL); } diff --git a/src/ptk_vk/swapchain.h b/src/ptk_vk/swapchain.h index 4ab7197..43286f1 100644 --- a/src/ptk_vk/swapchain.h +++ b/src/ptk_vk/swapchain.h @@ -3,8 +3,6 @@ #ifndef PTK_PTK_VK_SWAPCHAIN_H_ #define PTK_PTK_VK_SWAPCHAIN_H_ -#include "ptk_vk/device.h" - #include "ptk_list.h" #include @@ -15,6 +13,11 @@ PTK_LIST_DEFINE(VkFramebuffer); PTK_LIST_DEFINE(VkSurfaceFormatKHR); PTK_LIST_DEFINE(VkPresentModeKHR); +extern VkSwapchainKHR g_swapchain; +extern VkFormat g_swapchain_image_format; +extern VkExtent2D g_swapchain_extent; +extern PTK_LIST(VkFramebuffer) g_swapchain_framebuffers; + typedef struct { VkSurfaceCapabilitiesKHR capabilities; PTK_LIST(VkSurfaceFormatKHR) formats; @@ -23,19 +26,14 @@ typedef struct { SwapchainSupportInfo query_swapchain_support(const VkPhysicalDevice dev, const VkSurfaceKHR surface); -VkSwapchainKHR vk_current_swapchain(void); -VkFormat vk_current_swapchain_image_format(void); -VkExtent2D vk_current_swapchain_extent(void); -PTK_LIST(VkFramebuffer) vk_current_swapchain_framebuffers(void); +bool vk_create_swapchain(void); -bool vk_create_swapchain(GLFWwindow *window, VkDevice dev, VkPhysicalDevice physical_dev, VkSurfaceKHR surface, QueueFamilyIndices queue_family_indices); +bool vk_create_image_views(void); -bool vk_create_image_views(VkDevice dev); +bool vk_recreate_swapchain(void); -bool vk_recreate_swapchain(GLFWwindow *window, VkDevice dev, VkPhysicalDevice physical_dev, VkSurfaceKHR surface, QueueFamilyIndices queue_family_indices, VkRenderPass render_pass); +bool vk_create_framebuffers(void); -bool vk_create_framebuffers(VkDevice dev, VkRenderPass render_pass); - -void vk_cleanup_swapchain(VkDevice dev); +void vk_cleanup_swapchain(void); #endif // PTK_PTK_VK_SWAPCHAIN_H_ diff --git a/src/ptk_vk/sync_objects.c b/src/ptk_vk/sync_objects.c index 9cddaa0..4c21942 100644 --- a/src/ptk_vk/sync_objects.c +++ b/src/ptk_vk/sync_objects.c @@ -2,14 +2,19 @@ #include "ptk_vk/sync_objects.h" +#include "ptk_vk/device.h" #include "ptk_vk/utils.h" -PTK_OPTION(SyncObjects) vk_create_sync_objects(VkDevice dev, uint32_t max_frames_in_flight) { - SyncObjects ret = { - .image_available_semaphores = PTK_LIST_NEW(VkSemaphore, max_frames_in_flight), - .render_finished_semaphores = PTK_LIST_NEW(VkSemaphore, max_frames_in_flight), - .in_flight_fences = PTK_LIST_NEW(VkFence, max_frames_in_flight), - }; +PTK_LIST(VkSemaphore) g_image_available_semaphores; +PTK_LIST(VkSemaphore) g_render_finished_semaphores; +PTK_LIST(VkFence) g_in_flight_fences; + +const size_t g_max_frames_in_flight = 2; + +bool vk_create_sync_objects(void) { + g_image_available_semaphores = PTK_LIST_NEW(VkSemaphore, g_max_frames_in_flight); + g_render_finished_semaphores = PTK_LIST_NEW(VkSemaphore, g_max_frames_in_flight); + g_in_flight_fences = PTK_LIST_NEW(VkFence, g_max_frames_in_flight); const VkSemaphoreCreateInfo semaphore_info = { .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, @@ -17,28 +22,28 @@ PTK_OPTION(SyncObjects) vk_create_sync_objects(VkDevice dev, uint32_t max_frames .flags = 0, }; - for (size_t i = 0; i < max_frames_in_flight; ++i) { - VK_TRY(PTK_OPTION_NONE(SyncObjects), - vkCreateSemaphore(dev, &semaphore_info, NULL, &ret.image_available_semaphores.data[i]) + for (size_t i = 0; i < g_max_frames_in_flight; ++i) { + VK_TRY(false, + vkCreateSemaphore(g_dev, &semaphore_info, NULL, &g_image_available_semaphores.data[i]) ); - VK_TRY(PTK_OPTION_NONE(SyncObjects), - vkCreateSemaphore(dev, &semaphore_info, NULL, &ret.render_finished_semaphores.data[i]) + VK_TRY(false, + vkCreateSemaphore(g_dev, &semaphore_info, NULL, &g_render_finished_semaphores.data[i]) ); - VK_TRY(PTK_OPTION_NONE(SyncObjects), + VK_TRY(false, vkCreateFence( - dev, + g_dev, &(VkFenceCreateInfo){ .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, .pNext = NULL, .flags = VK_FENCE_CREATE_SIGNALED_BIT, }, NULL, - &ret.in_flight_fences.data[i] + &g_in_flight_fences.data[i] ) ); } - return PTK_OPTION_SOME(SyncObjects, ret); + return true; } diff --git a/src/ptk_vk/sync_objects.h b/src/ptk_vk/sync_objects.h index d6c1a3d..1c38d79 100644 --- a/src/ptk_vk/sync_objects.h +++ b/src/ptk_vk/sync_objects.h @@ -4,21 +4,18 @@ #define PTK_PTK_VK_SYNC_OBJECTS_H_ #include "ptk_list.h" -#include "ptk_option.h" #include PTK_LIST_DEFINE(VkSemaphore); PTK_LIST_DEFINE(VkFence); -typedef struct { - PTK_LIST(VkSemaphore) image_available_semaphores; - PTK_LIST(VkSemaphore) render_finished_semaphores; - PTK_LIST(VkFence) in_flight_fences; -} SyncObjects; +extern PTK_LIST(VkSemaphore) g_image_available_semaphores; +extern PTK_LIST(VkSemaphore) g_render_finished_semaphores; +extern PTK_LIST(VkFence) g_in_flight_fences; -PTK_OPTION_DEFINE(SyncObjects); +extern const size_t g_max_frames_in_flight; -PTK_OPTION(SyncObjects) vk_create_sync_objects(VkDevice dev, uint32_t max_frames_in_flight); +bool vk_create_sync_objects(void); #endif // PTK_PTK_VK_SYNC_OBJECTS_H_ diff --git a/src/ptk_vk/uniform_buffers.c b/src/ptk_vk/uniform_buffers.c index 179af81..c7915db 100644 --- a/src/ptk_vk/uniform_buffers.c +++ b/src/ptk_vk/uniform_buffers.c @@ -3,22 +3,27 @@ #include "ptk_vk/uniform_buffers.h" #include "ptk_vk/buffer.h" +#include "ptk_vk/device.h" +#include "ptk_vk/physical_device.h" +#include "ptk_vk/sync_objects.h" #include "ptk_log.h" -PTK_OPTION(UniformBufferStuff) vk_create_uniform_buffers(VkDevice dev, VkPhysicalDevice physical_dev, uint32_t max_frames_in_flight) { +PTK_LIST(VkBuffer) g_uniform_buffers; +PTK_LIST(VkDeviceMemory) g_uniform_buffer_memories; +PTK_LIST(voidptr) g_uniform_buffers_mapped; + +bool vk_create_uniform_buffers(void) { const VkDeviceSize buffer_size = sizeof(UniformBufferObject); - UniformBufferStuff ret = { - .buffers = PTK_LIST_NEW(VkBuffer, max_frames_in_flight), - .buffer_memories = PTK_LIST_NEW(VkDeviceMemory, max_frames_in_flight), - .buffers_mapped = PTK_LIST_NEW(voidptr, max_frames_in_flight), - }; + g_uniform_buffers = PTK_LIST_NEW(VkBuffer, g_max_frames_in_flight); + g_uniform_buffer_memories = PTK_LIST_NEW(VkDeviceMemory, g_max_frames_in_flight); + g_uniform_buffers_mapped = PTK_LIST_NEW(voidptr, g_max_frames_in_flight); - for (size_t i = 0; i < max_frames_in_flight; ++i) { + for (size_t i = 0; i < g_max_frames_in_flight; ++i) { PTK_OPTION(BufferStuff) uniform_buffer_stuff_opt = create_buffer( - dev, - physical_dev, + g_dev, + g_physical_dev, buffer_size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT @@ -26,14 +31,14 @@ PTK_OPTION(UniformBufferStuff) vk_create_uniform_buffers(VkDevice dev, VkPhysica if (!uniform_buffer_stuff_opt.exists) { PTK_ERR("failed creating index buffer"); - return PTK_OPTION_NONE(UniformBufferStuff); + return false; } - ret.buffers.data[i] = uniform_buffer_stuff_opt.value.buffer; - ret.buffer_memories.data[i] = uniform_buffer_stuff_opt.value.buffer_memory; + g_uniform_buffers.data[i] = uniform_buffer_stuff_opt.value.buffer; + g_uniform_buffer_memories.data[i] = uniform_buffer_stuff_opt.value.buffer_memory; - vkMapMemory(dev, ret.buffer_memories.data[i], 0, buffer_size, 0, &ret.buffers_mapped.data[i]); + vkMapMemory(g_dev, g_uniform_buffer_memories.data[i], 0, buffer_size, 0, &g_uniform_buffers_mapped.data[i]); } - return PTK_OPTION_SOME(UniformBufferStuff, ret); + return true; } diff --git a/src/ptk_vk/uniform_buffers.h b/src/ptk_vk/uniform_buffers.h index 194f005..cae2f8d 100644 --- a/src/ptk_vk/uniform_buffers.h +++ b/src/ptk_vk/uniform_buffers.h @@ -4,28 +4,24 @@ #define PTK_PTK_VK_UNIFORM_BUFFERS_H_ #include "ptk_list.h" -#include "ptk_option.h" #include "ptk_vec.h" #include -PTK_LIST_DEFINE(VkBuffer); -PTK_LIST_DEFINE(VkDeviceMemory); -typedef void *voidptr; -PTK_LIST_DEFINE(voidptr); - typedef struct { PtkSize initial_window_size; PtkSize window_size; } UniformBufferObject; -typedef struct { - PTK_LIST(VkBuffer) buffers; - PTK_LIST(VkDeviceMemory) buffer_memories; - PTK_LIST(voidptr) buffers_mapped; -} UniformBufferStuff; +PTK_LIST_DEFINE(VkBuffer); +PTK_LIST_DEFINE(VkDeviceMemory); +typedef void *voidptr; +PTK_LIST_DEFINE(voidptr); -PTK_OPTION_DEFINE(UniformBufferStuff); +extern PTK_LIST(VkBuffer) g_uniform_buffers; +extern PTK_LIST(VkDeviceMemory) g_uniform_buffer_memories; +extern PTK_LIST(voidptr) g_uniform_buffers_mapped; + +bool vk_create_uniform_buffers(void); -PTK_OPTION(UniformBufferStuff) vk_create_uniform_buffers(VkDevice dev, VkPhysicalDevice physical_dev, uint32_t max_frames_in_flight); #endif // PTK_PTK_VK_UNIFORM_BUFFERS_H_