get rid of globals by removing the draw module

This commit is contained in:
jacekpoz 2024-09-26 23:29:30 +02:00
parent c205b50a7e
commit e25016f88b
Signed by: poz
SSH key fingerprint: SHA256:JyLeVWE4bF3tDnFeUpUaJsPsNlJyBldDGV/dIKSLyN8
5 changed files with 143 additions and 188 deletions

View file

@ -7,7 +7,6 @@
#include <ptk_vk/components.h>
#include <ptk_vk/device.h>
#include <ptk_vk/draw.h>
#include <ptk_vk/init.h>
#include <ptk_vk/utils.h>

View file

@ -1,109 +0,0 @@
// Copyright (jacekpoz 2024). Licensed under the EUPL-1.2 or later.
#include <ptk_vk/draw.h>
#include <ptk_vk/device.h>
#include <ptk_vk/init.h>
#include <ptk_vk/swapchain.h>
#include <ptk_vk/utils.h>
#include <ptk_log.h>
#include <stdint.h>
static bool m_framebuffer_resized = false;
static uint32_t m_current_frame = 0;
void vk_framebuffer_resized(GLFWwindow *window, int width, int height) {
(void)window; (void)width; (void)height;
m_framebuffer_resized = true;
}
uint32_t vk_current_frame(void) {
return m_current_frame;
}
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(g_window, g_dev, g_physical_dev, g_surface, g_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;
}
vk_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 (!vk_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 = &g_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(g_window, g_dev, g_physical_dev, g_surface, g_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) % g_max_frames_in_flight;
return true;
}

View file

@ -1,19 +0,0 @@
// Copyright (jacekpoz 2024). Licensed under the EUPL-1.2 or later.
#ifndef PTK_PTK_VK_DRAW_H_
#define PTK_PTK_VK_DRAW_H_
#include <stdbool.h>
#include <stdint.h>
#ifndef GLFW_INCLUDE_VULKAN
#define GLFW_INCLUDE_VULKAN
#endif
#include <GLFW/glfw3.h>
void vk_framebuffer_resized(GLFWwindow *window, int width, int height);
uint32_t vk_current_frame(void);
bool vk_draw_frame(void);
#endif // PTK_PTK_VK_DRAW_H_

View file

@ -7,7 +7,6 @@
#include <ptk_vk/components.h>
#include <ptk_vk/descriptors.h>
#include <ptk_vk/device.h>
#include <ptk_vk/draw.h>
#include <ptk_vk/instance.h>
#include <ptk_vk/physical_device.h>
#include <ptk_vk/pipeline.h>
@ -23,27 +22,25 @@
#include <stdio.h>
#include <string.h>
// TODO: clean up globals here
static VkInstance m_instance;
VkPhysicalDevice g_physical_dev;
static VkPhysicalDevice m_physical_dev;
GLFWwindow *g_window = NULL;
static GLFWwindow *m_window;
VkSurfaceKHR g_surface = VK_NULL_HANDLE;
static VkSurfaceKHR m_surface;
static VkDescriptorSetLayout m_descriptor_set_layout;
static VkPipelineLayout m_pipeline_layout;
static VkPipeline m_pipeline;
const size_t g_max_frames_in_flight = 2;
static const size_t m_max_frames_in_flight = 2;
static VkCommandPool m_command_pool;
PTK_LIST(VkCommandBuffer) g_command_buffers;
static PTK_LIST(VkCommandBuffer) m_command_buffers;
PTK_LIST(VkSemaphore) g_image_available_semaphores;
PTK_LIST(VkSemaphore) g_render_finished_semaphores;
PTK_LIST(VkFence) g_in_flight_fences;
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;
@ -56,7 +53,7 @@ static PTK_LIST(VkBuffer) m_uniform_buffers;
static PTK_LIST(VkDeviceMemory) m_uniform_buffer_memories;
static PTK_LIST(voidptr) m_uniform_buffers_mapped;
VkRenderPass g_render_pass;
static VkRenderPass m_render_pass;
static VkDescriptorPool m_descriptor_pool;
static PTK_LIST(VkDescriptorSet) m_descriptor_sets;
@ -79,7 +76,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(g_dev, g_physical_dev, m_command_pool, g_vertices.data, vertices_size, m_vertex_buffer, g_graphics_queue)) {
if (!transfer_to_buffer(g_dev, m_physical_dev, m_command_pool, g_vertices.data, vertices_size, m_vertex_buffer, g_graphics_queue)) {
PTK_ERR("failed transferring vertices");
return false;
}
@ -91,7 +88,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(g_dev, g_physical_dev, m_command_pool, g_indices.data, indices_size, m_index_buffer, g_graphics_queue)) {
if (!transfer_to_buffer(g_dev, m_physical_dev, m_command_pool, g_indices.data, indices_size, m_index_buffer, g_graphics_queue)) {
PTK_ERR("failed transferring indices");
return false;
}
@ -117,7 +114,7 @@ bool vk_record_command_buffer(const VkCommandBuffer command_buffer, const uint32
&(VkRenderPassBeginInfo){
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
.pNext = NULL,
.renderPass = g_render_pass,
.renderPass = m_render_pass,
.framebuffer = g_swapchain_framebuffers.data[image_index],
.renderArea = (VkRect2D){
.offset = (VkOffset2D){
@ -168,7 +165,7 @@ bool vk_update_uniform_buffer(const size_t current_frame) {
}
bool vk_init(GLFWwindow *window, const size_t width, const size_t height, const char *title, const PtkVersion version) {
g_window = window;
m_window = window;
m_uniform_buffer_object.initial_window_size.w = width;
m_uniform_buffer_object.initial_window_size.h = height;
@ -188,11 +185,11 @@ bool vk_init(GLFWwindow *window, const size_t width, const size_t height, const
return false;
}
g_physical_dev = physical_dev_opt.value;
m_physical_dev = physical_dev_opt.value;
VK_TRY(false, glfwCreateWindowSurface(m_instance, g_window, NULL, &g_surface));
VK_TRY(false, glfwCreateWindowSurface(m_instance, m_window, NULL, &m_surface));
PTK_OPTION(VkDevice) dev_opt = vk_create_logical_dev(g_physical_dev, g_surface, m_validation_layers);
PTK_OPTION(VkDevice) dev_opt = vk_create_logical_dev(m_physical_dev, m_surface, m_validation_layers);
if (!dev_opt.exists) {
PTK_ERR("failed creating logical device");
@ -201,7 +198,7 @@ bool vk_init(GLFWwindow *window, const size_t width, const size_t height, const
g_dev = dev_opt.value;
if (!vk_create_swapchain(g_window, g_dev, g_physical_dev, g_surface)) {
if (!vk_create_swapchain(m_window, g_dev, m_physical_dev, m_surface)) {
PTK_ERR("failed creating swapchain");
return false;
}
@ -218,7 +215,7 @@ bool vk_init(GLFWwindow *window, const size_t width, const size_t height, const
return false;
}
g_render_pass = render_pass_opt.value;
m_render_pass = render_pass_opt.value;
PTK_OPTION(VkDescriptorSetLayout) descriptor_set_layout_opt = vk_create_descriptor_set_layout(g_dev);
@ -229,7 +226,7 @@ bool vk_init(GLFWwindow *window, const size_t width, const size_t height, const
m_descriptor_set_layout = descriptor_set_layout_opt.value;
PTK_OPTION(PipelineStuff) pipeline_stuff_opt = vk_create_pipeline(g_dev, g_render_pass, m_descriptor_set_layout, g_swapchain_extent);
PTK_OPTION(PipelineStuff) pipeline_stuff_opt = vk_create_pipeline(g_dev, m_render_pass, m_descriptor_set_layout, g_swapchain_extent);
if (!pipeline_stuff_opt.exists) {
PTK_ERR("failed creating graphics pipeline");
@ -239,7 +236,7 @@ bool vk_init(GLFWwindow *window, const size_t width, const size_t height, const
m_pipeline = pipeline_stuff_opt.value.pipeline;
m_pipeline_layout = pipeline_stuff_opt.value.pipeline_layout;
if (!vk_create_framebuffers(g_dev, g_render_pass)) {
if (!vk_create_framebuffers(g_dev, m_render_pass)) {
PTK_ERR("failed creating framebuffers");
return false;
}
@ -257,7 +254,7 @@ bool vk_init(GLFWwindow *window, const size_t width, const size_t height, const
PTK_OPTION(BufferStuff) vertex_buffer_stuff_opt = create_buffer(
g_dev,
g_physical_dev,
m_physical_dev,
buffer_size,
VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
@ -273,7 +270,7 @@ bool vk_init(GLFWwindow *window, const size_t width, const size_t height, const
PTK_OPTION(BufferStuff) index_buffer_stuff_opt = create_buffer(
g_dev,
g_physical_dev,
m_physical_dev,
buffer_size,
VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
@ -287,7 +284,7 @@ bool vk_init(GLFWwindow *window, const size_t width, const size_t height, const
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(g_dev, g_physical_dev, g_max_frames_in_flight);
PTK_OPTION(UniformBufferStuff) uniform_buffer_stuff_opt = vk_create_uniform_buffers(g_dev, m_physical_dev, m_max_frames_in_flight);
if (!uniform_buffer_stuff_opt.exists) {
PTK_ERR("failed creating uniform buffers");
@ -298,7 +295,7 @@ bool vk_init(GLFWwindow *window, const size_t width, const size_t height, const
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(g_dev, g_max_frames_in_flight);
PTK_OPTION(VkDescriptorPool) descriptor_pool_opt = vk_create_descriptor_pool(g_dev, m_max_frames_in_flight);
if (!descriptor_pool_opt.exists) {
PTK_ERR("failed creating descriptor pool");
@ -307,7 +304,7 @@ bool vk_init(GLFWwindow *window, const size_t width, const size_t height, const
m_descriptor_pool = descriptor_pool_opt.value;
PTK_OPTION(VkDescriptorSetList) descriptor_sets_opt = vk_create_descriptor_sets(g_dev, m_descriptor_set_layout, m_descriptor_pool, m_uniform_buffers, g_max_frames_in_flight);
PTK_OPTION(VkDescriptorSetList) descriptor_sets_opt = vk_create_descriptor_sets(g_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");
@ -316,31 +313,128 @@ bool vk_init(GLFWwindow *window, const size_t width, const size_t height, const
m_descriptor_sets = descriptor_sets_opt.value;
PTK_OPTION(VkCommandBufferList) command_buffers_opt = vk_allocate_command_buffers(g_dev, m_command_pool, g_max_frames_in_flight);
PTK_OPTION(VkCommandBufferList) command_buffers_opt = vk_allocate_command_buffers(g_dev, m_command_pool, m_max_frames_in_flight);
if (!command_buffers_opt.exists) {
PTK_ERR("failed allocating command buffers");
return false;
}
g_command_buffers = command_buffers_opt.value;
m_command_buffers = command_buffers_opt.value;
PTK_OPTION(SyncObjects) sync_objects_opt = vk_create_sync_objects(g_dev, g_max_frames_in_flight);
PTK_OPTION(SyncObjects) sync_objects_opt = vk_create_sync_objects(g_dev, m_max_frames_in_flight);
if (!sync_objects_opt.exists) {
PTK_ERR("failed creating sync objects");
return false;
}
g_image_available_semaphores = sync_objects_opt.value.image_available_semaphores;
g_render_finished_semaphores = sync_objects_opt.value.render_finished_semaphores;
g_in_flight_fences = sync_objects_opt.value.in_flight_fences;
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(g_window);
return glfwWindowShouldClose(m_window);
}
static bool m_framebuffer_resized = false;
static uint32_t m_current_frame = 0;
void vk_framebuffer_resized(GLFWwindow *window, int width, int height) {
(void)window; (void)width; (void)height;
m_framebuffer_resized = true;
}
uint32_t vk_current_frame(void) {
return m_current_frame;
}
bool vk_draw_frame(void) {
vkWaitForFences(g_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(
g_dev,
g_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, g_dev, m_physical_dev, m_surface, 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;
}
vk_update_uniform_buffer(m_current_frame);
vkResetFences(g_dev, 1, &m_in_flight_fences.data[m_current_frame]);
vkResetCommandBuffer(m_command_buffers.data[m_current_frame], 0);
if (!vk_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(
g_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(g_present_queue, &(VkPresentInfoKHR){
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
.pNext = NULL,
.waitSemaphoreCount = 1,
.pWaitSemaphores = signal_semaphores,
.swapchainCount = 1,
.pSwapchains = &g_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, g_dev, m_physical_dev, m_surface, 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 vk_finish(void) {
@ -356,9 +450,9 @@ void vk_cleanup(void) {
vkDestroyPipeline(g_dev, m_pipeline, NULL);
vkDestroyPipelineLayout(g_dev, m_pipeline_layout, NULL);
vkDestroyRenderPass(g_dev, g_render_pass, NULL);
vkDestroyRenderPass(g_dev, m_render_pass, NULL);
for (size_t i = 0; i < g_max_frames_in_flight; ++i) {
for (size_t i = 0; i < m_max_frames_in_flight; ++i) {
vkDestroyBuffer(g_dev, m_uniform_buffers.data[i], NULL);
vkFreeMemory(g_dev, m_uniform_buffer_memories.data[i], NULL);
}
@ -376,20 +470,20 @@ void vk_cleanup(void) {
vkDestroyBuffer(g_dev, m_vertex_buffer, NULL);
vkFreeMemory(g_dev, m_vertex_buffer_memory, 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);
for (size_t i = 0; i < m_max_frames_in_flight; ++i) {
vkDestroySemaphore(g_dev, m_image_available_semaphores.data[i], NULL);
vkDestroySemaphore(g_dev, m_render_finished_semaphores.data[i], NULL);
vkDestroyFence(g_dev, m_in_flight_fences.data[i], NULL);
}
vkDestroyCommandPool(g_dev, m_command_pool, NULL);
vkDestroyDevice(g_dev, NULL);
vkDestroySurfaceKHR(m_instance, g_surface, NULL);
vkDestroySurfaceKHR(m_instance, m_surface, NULL);
vkDestroyInstance(m_instance, NULL);
glfwDestroyWindow(g_window);
glfwDestroyWindow(m_window);
glfwTerminate();
}

View file

@ -13,26 +13,16 @@
#include <ptk_vk/command_buffers.h>
#include <ptk_vk/sync_objects.h>
extern VkPhysicalDevice g_physical_dev;
extern GLFWwindow *g_window;
extern const size_t g_max_frames_in_flight;
extern PTK_LIST(VkCommandBuffer) g_command_buffers;
extern PTK_LIST(VkSemaphore) g_image_available_semaphores;
extern PTK_LIST(VkSemaphore) g_render_finished_semaphores;
extern PTK_LIST(VkFence) g_in_flight_fences;
extern VkSurfaceKHR g_surface;
extern VkRenderPass g_render_pass;
bool vk_init(GLFWwindow *window, const size_t width, const size_t height, const char *title, const PtkVersion version);
bool vk_is_done(void);
void vk_framebuffer_resized(GLFWwindow *window, int width, int height);
uint32_t vk_current_frame(void);
bool vk_draw_frame(void);
void vk_finish(void);
bool vk_transfer_vertex_data(void);