ANOTHER REFACTOR I'M GOING INSANE

THIS BASICALLY FULLY REVERTS THE OTHER REFACTOR I JUST DID

I THINK THE CODE IS BETTER NOW
This commit is contained in:
jacekpoz 2024-10-04 20:37:27 +02:00
parent 61308ed427
commit dbdbf09516
Signed by: poz
SSH key fingerprint: SHA256:JyLeVWE4bF3tDnFeUpUaJsPsNlJyBldDGV/dIKSLyN8
27 changed files with 752 additions and 800 deletions

View file

@ -4,8 +4,8 @@
#include "ptk_log.h" #include "ptk_log.h"
#include "ptk_option.h" #include "ptk_option.h"
#include "ptk_vk/backend.h"
#include "ptk_vk/components.h" #include "ptk_vk/components.h"
#include "ptk_vk/init.h"
#include <vulkan/vulkan_core.h> #include <vulkan/vulkan_core.h>
#ifndef GLFW_INCLUDE_VULKAN #ifndef GLFW_INCLUDE_VULKAN

346
src/ptk_vk/backend.c Normal file
View file

@ -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 <string.h>
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();
}

39
src/ptk_vk/backend.h Normal file
View file

@ -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 <GLFW/glfw3.h>
#include <stdbool.h>
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_

View file

@ -2,25 +2,30 @@
#include "ptk_vk/command_buffers.h" #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" #include "ptk_vk/utils.h"
PTK_OPTION(VkCommandBufferList) vk_allocate_command_buffers(VkDevice dev, VkCommandPool command_pool, uint32_t max_frames_in_flight) { PTK_LIST(VkCommandBuffer) g_command_buffers;
VkCommandBufferList ret = PTK_LIST_NEW(VkCommandBuffer, max_frames_in_flight);
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( vkAllocateCommandBuffers(
dev, g_dev,
&(VkCommandBufferAllocateInfo){ &(VkCommandBufferAllocateInfo){
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
.pNext = NULL, .pNext = NULL,
.commandPool = command_pool, .commandPool = g_command_pool,
.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, .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;
} }

View file

@ -4,14 +4,15 @@
#define PTK_PTK_VK_COMMAND_BUFFERS_H_ #define PTK_PTK_VK_COMMAND_BUFFERS_H_
#include "ptk_list.h" #include "ptk_list.h"
#include "ptk_option.h"
#include <vulkan/vulkan_core.h> #include <vulkan/vulkan_core.h>
PTK_LIST_DEFINE(VkCommandBuffer); #include <stdbool.h>
typedef PTK_LIST(VkCommandBuffer) VkCommandBufferList;
PTK_OPTION_DEFINE(VkCommandBufferList);
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_ #endif // PTK_PTK_VK_COMMAND_BUFFERS_H_

View file

@ -2,25 +2,25 @@
#include "ptk_vk/command_pool.h" #include "ptk_vk/command_pool.h"
#include "ptk_vk/device.h"
#include "ptk_vk/utils.h" #include "ptk_vk/utils.h"
PTK_OPTION(VkCommandPool) vk_create_command_pool(VkDevice dev, uint32_t graphics_queue_family_index) { VkCommandPool g_command_pool;
VkCommandPool ret;
VK_TRY(PTK_OPTION_NONE(VkCommandPool), bool vk_create_command_pool(void) {
VK_TRY(false,
vkCreateCommandPool( vkCreateCommandPool(
dev, g_dev,
&(VkCommandPoolCreateInfo){ &(VkCommandPoolCreateInfo){
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
.pNext = NULL, .pNext = NULL,
.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
.queueFamilyIndex = graphics_queue_family_index, .queueFamilyIndex = g_queue_family_indices.graphics.value,
}, },
NULL, NULL,
&ret &g_command_pool
) )
); );
return PTK_OPTION_SOME(VkCommandPool, ret); return true;
} }

View file

@ -3,12 +3,12 @@
#ifndef PTK_PTK_VK_COMMAND_POOL_H_ #ifndef PTK_PTK_VK_COMMAND_POOL_H_
#define PTK_PTK_VK_COMMAND_POOL_H_ #define PTK_PTK_VK_COMMAND_POOL_H_
#include "ptk_option.h"
#include <vulkan/vulkan_core.h> #include <vulkan/vulkan_core.h>
PTK_OPTION_DEFINE(VkCommandPool); #include <stdbool.h>
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_ #endif // PTK_PTK_VK_COMMAND_POOL_H_

View file

@ -2,14 +2,19 @@
#include "ptk_vk/descriptors.h" #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" #include "ptk_vk/utils.h"
PTK_OPTION(VkDescriptorSetLayout) vk_create_descriptor_set_layout(VkDevice dev) { VkDescriptorSetLayout g_descriptor_set_layout;
VkDescriptorSetLayout ret; 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( vkCreateDescriptorSetLayout(
dev, g_dev,
&(VkDescriptorSetLayoutCreateInfo){ &(VkDescriptorSetLayoutCreateInfo){
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.pNext = NULL, .pNext = NULL,
@ -24,77 +29,75 @@ PTK_OPTION(VkDescriptorSetLayout) vk_create_descriptor_set_layout(VkDevice dev)
}, },
}, },
NULL, 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) { bool vk_create_descriptor_pool(void) {
VkDescriptorPool ret; VK_TRY(false,
VK_TRY(PTK_OPTION_NONE(VkDescriptorPool),
vkCreateDescriptorPool( vkCreateDescriptorPool(
dev, g_dev,
&(VkDescriptorPoolCreateInfo){ &(VkDescriptorPoolCreateInfo){
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
.pNext = NULL, .pNext = NULL,
.flags = 0, .flags = 0,
.maxSets = max_frames_in_flight, .maxSets = g_max_frames_in_flight,
.poolSizeCount = 1, .poolSizeCount = 1,
.pPoolSizes = &(VkDescriptorPoolSize){ .pPoolSizes = &(VkDescriptorPoolSize){
.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.descriptorCount = max_frames_in_flight, .descriptorCount = g_max_frames_in_flight,
}, },
}, },
NULL, NULL,
&ret &g_descriptor_pool
) )
); );
return PTK_OPTION_SOME(VkDescriptorPool, ret); return true;
} }
PTK_LIST_DEFINE(VkDescriptorSetLayout); 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) { bool vk_create_descriptor_sets(void) {
PTK_LIST(VkDescriptorSetLayout) layouts = PTK_LIST_NEW(VkDescriptorSetLayout, max_frames_in_flight); PTK_LIST(VkDescriptorSetLayout) layouts = PTK_LIST_NEW(VkDescriptorSetLayout, 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_LIST_ADD(VkDescriptorSetLayout, layouts, descriptor_set_layout); 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( vkAllocateDescriptorSets(
dev, g_dev,
&(VkDescriptorSetAllocateInfo){ &(VkDescriptorSetAllocateInfo){
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
.pNext = NULL, .pNext = NULL,
.descriptorPool = descriptor_pool, .descriptorPool = g_descriptor_pool,
.descriptorSetCount = layouts.size, .descriptorSetCount = layouts.size,
.pSetLayouts = layouts.data, .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( vkUpdateDescriptorSets(
dev, g_dev,
1, 1,
&(VkWriteDescriptorSet){ &(VkWriteDescriptorSet){
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.pNext = NULL, .pNext = NULL,
.dstSet = ret.data[i], .dstSet = g_descriptor_sets.data[i],
.dstBinding = 0, .dstBinding = 0,
.dstArrayElement = 0, .dstArrayElement = 0,
.descriptorCount = 1, .descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.pImageInfo = NULL, .pImageInfo = NULL,
.pBufferInfo = &(VkDescriptorBufferInfo){ .pBufferInfo = &(VkDescriptorBufferInfo){
.buffer = uniform_buffers.data[i], .buffer = g_uniform_buffers.data[i],
.offset = 0, .offset = 0,
.range = sizeof(UniformBufferObject), .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;
} }

View file

@ -3,21 +3,18 @@
#ifndef PTK_PTK_VK_DESCRIPTORS_H_ #ifndef PTK_PTK_VK_DESCRIPTORS_H_
#define PTK_PTK_VK_DESCRIPTORS_H_ #define PTK_PTK_VK_DESCRIPTORS_H_
#include "ptk_vk/uniform_buffers.h"
#include "ptk_list.h" #include "ptk_list.h"
#include "ptk_option.h"
#include <vulkan/vulkan_core.h> #include <vulkan/vulkan_core.h>
PTK_OPTION_DEFINE(VkDescriptorSetLayout);
PTK_OPTION_DEFINE(VkDescriptorPool);
PTK_LIST_DEFINE(VkDescriptorSet); PTK_LIST_DEFINE(VkDescriptorSet);
typedef PTK_LIST(VkDescriptorSet) VkDescriptorSetList;
PTK_OPTION_DEFINE(VkDescriptorSetList);
PTK_OPTION(VkDescriptorSetLayout) vk_create_descriptor_set_layout(VkDevice dev); extern VkDescriptorSetLayout g_descriptor_set_layout;
PTK_OPTION(VkDescriptorPool) vk_create_descriptor_pool(VkDevice dev, uint32_t max_frames_in_flight); extern VkDescriptorPool g_descriptor_pool;
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 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_ #endif // PTK_PTK_VK_DESCRIPTORS_H_

View file

@ -2,6 +2,8 @@
#include "ptk_vk/device.h" #include "ptk_vk/device.h"
#include "ptk_vk/backend.h"
#include "ptk_vk/physical_device.h"
#include "ptk_vk/swapchain.h" #include "ptk_vk/swapchain.h"
#include "ptk_vk/utils.h" #include "ptk_vk/utils.h"
@ -13,10 +15,11 @@
#include <stdbool.h> #include <stdbool.h>
#include <string.h> #include <string.h>
VkDevice g_dev;
QueueFamilyIndices g_queue_family_indices;
VkQueue g_graphics_queue; VkQueue g_graphics_queue;
VkQueue g_present_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)); static const size_t m_queue_family_count = sizeof(QueueFamilyIndices) / sizeof(PTK_OPTION(uint32_t));
PTK_LIST_DEFINE(VkQueueFamilyProperties); 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); vkGetPhysicalDeviceQueueFamilyProperties(physical_dev, &queue_families.allocated, queue_families.data);
PTK_LIST_FILLED(queue_families); PTK_LIST_FILLED(queue_families);
m_queue_family_indices.graphics = PTK_OPTION_NONE(uint32_t); g_queue_family_indices.graphics = PTK_OPTION_NONE(uint32_t);
m_queue_family_indices.present = 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, { PTK_LIST_FOR_EACH_E(const VkQueueFamilyProperties, queue_families, i, queue_family, {
if (queue_family.queueFlags & VK_QUEUE_GRAPHICS_BIT) { 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; VkBool32 present_support = VK_FALSE;
vkGetPhysicalDeviceSurfaceSupportKHR(physical_dev, i, surface, &present_support); vkGetPhysicalDeviceSurfaceSupportKHR(physical_dev, i, surface, &present_support);
if (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 const bool indices_found = g_queue_family_indices.graphics.exists
&& m_queue_family_indices.present.exists; && g_queue_family_indices.present.exists;
const bool extensions_supported = are_extensions_supported(physical_dev); const bool extensions_supported = are_extensions_supported(physical_dev);
bool swapchain_adequate = false; 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; 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) { bool vk_create_logical_dev(void) {
if (!is_device_suitable(physical_dev, surface)) { if (!is_device_suitable(g_physical_dev, g_surface)) {
PTK_ERR("physical device isn't suitable"); 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]; VkDeviceQueueCreateInfo queue_create_infos[m_queue_family_count];
for (size_t i = 0; i < m_queue_family_count; ++i) { 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){ queue_create_infos[i] = (VkDeviceQueueCreateInfo){
.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, .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( vkCreateDevice(
physical_dev, g_physical_dev,
&(VkDeviceCreateInfo){ &(VkDeviceCreateInfo){
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
.pNext = NULL, .pNext = NULL,
.flags = 0, .flags = 0,
.queueCreateInfoCount = m_queue_family_count, .queueCreateInfoCount = m_queue_family_count,
.pQueueCreateInfos = queue_create_infos, .pQueueCreateInfos = queue_create_infos,
.enabledLayerCount = validation_layers.size, .enabledLayerCount = g_validation_layers.size,
.ppEnabledLayerNames = validation_layers.data, .ppEnabledLayerNames = g_validation_layers.data,
.enabledExtensionCount = m_device_extensions.size, .enabledExtensionCount = m_device_extensions.size,
.ppEnabledExtensionNames = m_device_extensions.data, .ppEnabledExtensionNames = m_device_extensions.data,
.pEnabledFeatures = &(VkPhysicalDeviceFeatures){0}, .pEnabledFeatures = &(VkPhysicalDeviceFeatures){0},
}, },
NULL, NULL,
&ret.dev &g_dev
) )
); );
vkGetDeviceQueue(ret.dev, m_queue_family_indices.graphics.value, 0, &ret.graphics_queue); vkGetDeviceQueue(g_dev, g_queue_family_indices.graphics.value, 0, &g_graphics_queue);
vkGetDeviceQueue(ret.dev, m_queue_family_indices.present.value, 0, &ret.present_queue); vkGetDeviceQueue(g_dev, g_queue_family_indices.present.value, 0, &g_present_queue);
return PTK_OPTION_SOME(DeviceStuff, ret); return true;
} }

View file

@ -3,10 +3,6 @@
#ifndef PTK_PTK_VK_DEVICE_H_ #ifndef PTK_PTK_VK_DEVICE_H_
#define 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 "ptk_option.h"
#include <vulkan/vulkan_core.h> #include <vulkan/vulkan_core.h>
@ -18,15 +14,11 @@ typedef struct {
PTK_OPTION(uint32_t) present; PTK_OPTION(uint32_t) present;
} QueueFamilyIndices; } QueueFamilyIndices;
typedef struct { extern VkDevice g_dev;
VkDevice dev; extern QueueFamilyIndices g_queue_family_indices;
QueueFamilyIndices queue_family_indices; extern VkQueue g_graphics_queue;
VkQueue graphics_queue; extern VkQueue g_present_queue;
VkQueue present_queue;
} DeviceStuff;
PTK_OPTION_DEFINE(DeviceStuff); bool vk_create_logical_dev(void);
PTK_OPTION(DeviceStuff) vk_create_logical_dev(VkPhysicalDevice physical_dev, VkSurfaceKHR surface, const PTK_ARRAY(constcharptr) validation_layers);
#endif // PTK_PTK_VK_DEVICE_H_ #endif // PTK_PTK_VK_DEVICE_H_

View file

@ -2,8 +2,8 @@
#include "ptk_vk/init.h" #include "ptk_vk/init.h"
#include "ptk_vk/backend.h"
#include "ptk_vk/buffer.h" #include "ptk_vk/buffer.h"
#include "ptk_vk/command_buffers.h"
#include "ptk_vk/command_pool.h" #include "ptk_vk/command_pool.h"
#include "ptk_vk/components.h" #include "ptk_vk/components.h"
#include "ptk_vk/descriptors.h" #include "ptk_vk/descriptors.h"
@ -15,68 +15,13 @@
#include "ptk_vk/swapchain.h" #include "ptk_vk/swapchain.h"
#include "ptk_vk/sync_objects.h" #include "ptk_vk/sync_objects.h"
#include "ptk_vk/uniform_buffers.h" #include "ptk_vk/uniform_buffers.h"
#include "ptk_vk/utils.h"
#include "ptk_array.h"
#include "ptk_list.h" #include "ptk_list.h"
#include "ptk_log.h" #include "ptk_log.h"
#include "ptk_option.h"
#include <stdio.h> #include <stdio.h>
#include <string.h>
#ifdef DEBUG UniformBufferObject g_uniform_buffer_object;
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;
bool vk_transfer_vertex_data(void) { bool vk_transfer_vertex_data(void) {
PTK_DEBUG("vertices updated!"); PTK_DEBUG("vertices updated!");
@ -88,7 +33,7 @@ bool vk_transfer_vertex_data(void) {
PTK_DEBUG("transferring vertices to gpu…"); PTK_DEBUG("transferring vertices to gpu…");
const size_t vertices_size = sizeof(g_vertices.data[0]) * g_vertices.size; 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"); PTK_ERR("failed transferring vertices");
return false; return false;
} }
@ -100,7 +45,7 @@ bool vk_transfer_vertex_data(void) {
PTK_DEBUG("transferring indices to gpu…"); PTK_DEBUG("transferring indices to gpu…");
const size_t indices_size = sizeof(g_indices.data[0]) * g_indices.size; 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"); PTK_ERR("failed transferring indices");
return false; return false;
} }
@ -108,402 +53,46 @@ bool vk_transfer_vertex_data(void) {
return true; return true;
} }
bool record_command_buffer(const VkCommandBuffer command_buffer, const uint32_t image_index) { void vk_cleanup(void) {
VK_TRY(false, vk_cleanup_swapchain();
vkBeginCommandBuffer(
command_buffer,
&(VkCommandBufferBeginInfo){
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
.pNext = NULL,
.flags = 0,
.pInheritanceInfo = NULL,
}
)
);
vkCmdBeginRenderPass( vkDestroyPipeline(g_dev, g_pipeline, NULL);
command_buffer, vkDestroyPipelineLayout(g_dev, g_pipeline_layout, NULL);
&(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
);
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}); for (size_t i = 0; i < g_max_frames_in_flight; ++i) {
vkDestroyBuffer(g_dev, g_uniform_buffers.data[i], NULL);
vkCmdBindIndexBuffer(command_buffer, m_index_buffer, 0, VK_INDEX_TYPE_UINT32); vkFreeMemory(g_dev, g_uniform_buffer_memories.data[i], NULL);
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;
} }
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); vkDestroyDescriptorSetLayout(g_dev, g_descriptor_set_layout, NULL);
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);
vkDestroyBuffer(m_dev, m_index_buffer, NULL); vkDestroyBuffer(g_dev, g_index_buffer, NULL);
vkFreeMemory(m_dev, m_index_buffer_memory, NULL); vkFreeMemory(g_dev, g_index_buffer_memory, NULL);
vkDestroyBuffer(m_dev, m_vertex_buffer, NULL); vkDestroyBuffer(g_dev, g_vertex_buffer, NULL);
vkFreeMemory(m_dev, m_vertex_buffer_memory, NULL); vkFreeMemory(g_dev, g_vertex_buffer_memory, NULL);
for (size_t i = 0; i < m_max_frames_in_flight; ++i) { for (size_t i = 0; i < g_max_frames_in_flight; ++i) {
vkDestroySemaphore(m_dev, m_image_available_semaphores.data[i], NULL); vkDestroySemaphore(g_dev, g_image_available_semaphores.data[i], NULL);
vkDestroySemaphore(m_dev, m_render_finished_semaphores.data[i], NULL); vkDestroySemaphore(g_dev, g_render_finished_semaphores.data[i], NULL);
vkDestroyFence(m_dev, m_in_flight_fences.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); vkDestroySurfaceKHR(g_instance, g_surface, NULL);
vkDestroyInstance(m_instance, NULL); vkDestroyInstance(g_instance, NULL);
glfwDestroyWindow(m_window); glfwDestroyWindow(g_window);
glfwTerminate(); glfwTerminate();
} }
void vk_finish(void) {
vkDeviceWaitIdle(m_dev);
cleanup();
vk_components_cleanup();
}

View file

@ -3,23 +3,14 @@
#ifndef PTK_PTK_VK_INIT_H_ #ifndef PTK_PTK_VK_INIT_H_
#define PTK_PTK_VK_INIT_H_ #define PTK_PTK_VK_INIT_H_
#include "ptk.h" #include "ptk_vk/uniform_buffers.h"
#ifndef GLFW_INCLUDE_VULKAN
#define GLFW_INCLUDE_VULKAN
#endif
#include <GLFW/glfw3.h>
#include <stdbool.h> #include <stdbool.h>
bool vk_init(GLFWwindow *window, const size_t width, const size_t height, const char *title, const PtkVersion version); extern UniformBufferObject g_uniform_buffer_object;
bool vk_is_done(void);
bool vk_draw_frame(void);
void vk_finish(void);
bool vk_transfer_vertex_data(void); bool vk_transfer_vertex_data(void);
void vk_cleanup(void);
#endif // PTK_PTK_VK_INIT_H_ #endif // PTK_PTK_VK_INIT_H_

View file

@ -2,6 +2,7 @@
#include "ptk_vk/instance.h" #include "ptk_vk/instance.h"
#include "ptk_vk/backend.h"
#include "ptk_vk/utils.h" #include "ptk_vk/utils.h"
#include "ptk_array.h" #include "ptk_array.h"
@ -46,20 +47,20 @@ bool check_validation_layers(const PTK_ARRAY(constcharptr) validation_layers) {
} }
#endif #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 #ifdef DEBUG
if (!check_validation_layers(validation_layers)) { if (!check_validation_layers(g_validation_layers)) {
PTK_ERR("couldn't find requested validation layer"); PTK_ERR("couldn't find requested validation layer");
return PTK_OPTION_NONE(VkInstance); return false;
} }
#endif #endif
PTK_ARRAY(constcharptr) extension_names = PTK_ARRAY_EMPTY(constcharptr); PTK_ARRAY(constcharptr) extension_names = PTK_ARRAY_EMPTY(constcharptr);
extension_names.data = glfwGetRequiredInstanceExtensions(&extension_names.size); extension_names.data = glfwGetRequiredInstanceExtensions(&extension_names.size);
VkInstance ret; VK_TRY(false,
VK_TRY(PTK_OPTION_NONE(VkInstance),
vkCreateInstance( vkCreateInstance(
&(VkInstanceCreateInfo){ &(VkInstanceCreateInfo){
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, .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), .engineVersion = VK_MAKE_API_VERSION(0, PTK_VERSION_MAJOR, PTK_VERSION_MINOR, PTK_VERSION_PATCH),
.apiVersion = VK_API_VERSION_1_3, .apiVersion = VK_API_VERSION_1_3,
}, },
.enabledLayerCount = validation_layers.size, .enabledLayerCount = g_validation_layers.size,
.ppEnabledLayerNames = validation_layers.data, .ppEnabledLayerNames = g_validation_layers.data,
.enabledExtensionCount = extension_names.size, .enabledExtensionCount = extension_names.size,
.ppEnabledExtensionNames = extension_names.data, .ppEnabledExtensionNames = extension_names.data,
}, },
NULL, NULL,
&ret &g_instance
) )
); );
return PTK_OPTION_SOME(VkInstance, ret); return true;
} }

View file

@ -4,15 +4,11 @@
#define PTK_PTK_VK_INSTANCE_H_ #define PTK_PTK_VK_INSTANCE_H_
#include "ptk.h" #include "ptk.h"
#include "ptk_array.h"
#include "ptk_option.h"
#include <vulkan/vulkan_core.h> #include <vulkan/vulkan_core.h>
PTK_OPTION_DEFINE(VkInstance); extern VkInstance g_instance;
typedef const char *constcharptr;
PTK_ARRAY_DEFINE(constcharptr);
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_ #endif // PTK_PTK_VK_INSTANCE_H_

View file

@ -2,19 +2,21 @@
#include "ptk_vk/physical_device.h" #include "ptk_vk/physical_device.h"
#include "ptk_vk/instance.h"
#include "ptk_log.h" #include "ptk_log.h"
#include <vulkan/vulkan.h> 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; uint32_t dev_count = 0;
vkEnumeratePhysicalDevices(instance, &dev_count, NULL); vkEnumeratePhysicalDevices(g_instance, &dev_count, NULL);
if (dev_count == 0) { if (dev_count == 0) {
PTK_ERR("failed to find GPU with vulkan support"); PTK_ERR("failed to find GPU with vulkan support");
return PTK_OPTION_NONE(VkPhysicalDevice); return false;
} }
VkPhysicalDevice devs[dev_count]; VkPhysicalDevice devs[dev_count];
vkEnumeratePhysicalDevices(instance, &dev_count, devs); vkEnumeratePhysicalDevices(g_instance, &dev_count, devs);
VkPhysicalDeviceProperties dev_props[dev_count]; VkPhysicalDeviceProperties dev_props[dev_count];
uint32_t dgpus[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]); 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;
} }

View file

@ -3,12 +3,12 @@
#ifndef PTK_PTK_VK_PHYSICAL_DEVICE_H_ #ifndef PTK_PTK_VK_PHYSICAL_DEVICE_H_
#define PTK_PTK_VK_PHYSICAL_DEVICE_H_ #define PTK_PTK_VK_PHYSICAL_DEVICE_H_
#include "ptk_option.h"
#include <vulkan/vulkan_core.h> #include <vulkan/vulkan_core.h>
PTK_OPTION_DEFINE(VkPhysicalDevice); #include <stdbool.h>
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_ #endif // PTK_PTK_VK_PHYSICAL_DEVICE_H_

View file

@ -3,14 +3,22 @@
#include "ptk_vk/pipeline.h" #include "ptk_vk/pipeline.h"
#include "ptk_vk/components.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_vk/utils.h"
#include "ptk_array.h" #include "ptk_array.h"
#include "ptk_option.h"
#include "ptk_log.h" #include "ptk_log.h"
#include "errno.h" #include "errno.h"
#include "stdio.h" #include "stdio.h"
VkPipeline g_pipeline;
VkPipelineLayout g_pipeline_layout;
PTK_OPTION_DEFINE(VkShaderModule); PTK_OPTION_DEFINE(VkShaderModule);
PTK_ARRAY_DEFINE(VkVertexInputAttributeDescription); 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); 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 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_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) { if (!vert_shader_module.exists) {
PTK_ERR("failed creating vert shader module"); 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) { if (!frag_shader_module.exists) {
PTK_ERR("failed creating frag shader module"); PTK_ERR("failed creating frag shader module");
return PTK_OPTION_NONE(PipelineStuff); return false;
} }
const VkSpecializationInfo spec_info = { const VkSpecializationInfo spec_info = {
@ -191,8 +199,8 @@ PTK_OPTION(PipelineStuff) vk_create_pipeline(VkDevice dev, VkRenderPass render_p
.pViewports = &(VkViewport){ .pViewports = &(VkViewport){
.x = 0.0f, .x = 0.0f,
.y = 0.0f, .y = 0.0f,
.width = (float) swapchain_extent.width, .width = (float) g_swapchain_extent.width,
.height = (float) swapchain_extent.height, .height = (float) g_swapchain_extent.height,
.minDepth = 0.0f, .minDepth = 0.0f,
.maxDepth = 1.0f, .maxDepth = 1.0f,
}, },
@ -202,7 +210,7 @@ PTK_OPTION(PipelineStuff) vk_create_pipeline(VkDevice dev, VkRenderPass render_p
.x = 0, .x = 0,
.y = 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, .blendConstants[3] = 0.0f,
}; };
PipelineStuff ret; VK_TRY(false,
VK_TRY(PTK_OPTION_NONE(PipelineStuff),
vkCreatePipelineLayout( vkCreatePipelineLayout(
dev, g_dev,
&(VkPipelineLayoutCreateInfo){ &(VkPipelineLayoutCreateInfo){
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
.pNext = NULL, .pNext = NULL,
.flags = 0, .flags = 0,
.setLayoutCount = 1, .setLayoutCount = 1,
.pSetLayouts = &descriptor_set_layout, .pSetLayouts = &g_descriptor_set_layout,
.pushConstantRangeCount = 0, .pushConstantRangeCount = 0,
.pPushConstantRanges = NULL, .pPushConstantRanges = NULL,
}, },
NULL, NULL,
&ret.pipeline_layout &g_pipeline_layout
) )
); );
VK_TRY(PTK_OPTION_NONE(PipelineStuff), VK_TRY(false,
vkCreateGraphicsPipelines( vkCreateGraphicsPipelines(
dev, g_dev,
VK_NULL_HANDLE, VK_NULL_HANDLE,
1, 1,
&(VkGraphicsPipelineCreateInfo){ &(VkGraphicsPipelineCreateInfo){
@ -298,19 +304,19 @@ PTK_OPTION(PipelineStuff) vk_create_pipeline(VkDevice dev, VkRenderPass render_p
.pDepthStencilState = NULL, .pDepthStencilState = NULL,
.pColorBlendState = &color_blending, .pColorBlendState = &color_blending,
.pDynamicState = &dynamic_state, .pDynamicState = &dynamic_state,
.layout = ret.pipeline_layout, .layout = g_pipeline_layout,
.renderPass = render_pass, .renderPass = g_render_pass,
.subpass = 0, .subpass = 0,
.basePipelineHandle = VK_NULL_HANDLE, .basePipelineHandle = VK_NULL_HANDLE,
.basePipelineIndex = -1, .basePipelineIndex = -1,
}, },
NULL, NULL,
&ret.pipeline &g_pipeline
) )
); );
vkDestroyShaderModule(dev, vert_shader_module.value, NULL); vkDestroyShaderModule(g_dev, vert_shader_module.value, NULL);
vkDestroyShaderModule(dev, frag_shader_module.value, NULL); vkDestroyShaderModule(g_dev, frag_shader_module.value, NULL);
return PTK_OPTION_SOME(PipelineStuff, ret); return true;
} }

View file

@ -3,17 +3,13 @@
#ifndef PTK_PTK_VK_PIPELINE_H_ #ifndef PTK_PTK_VK_PIPELINE_H_
#define PTK_PTK_VK_PIPELINE_H_ #define PTK_PTK_VK_PIPELINE_H_
#include "ptk_option.h"
#include <vulkan/vulkan_core.h> #include <vulkan/vulkan_core.h>
typedef struct { #include <stdbool.h>
VkPipeline pipeline;
VkPipelineLayout pipeline_layout;
} PipelineStuff;
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_ #endif // PTK_PTK_VK_PIPELINE_H_

View file

@ -2,14 +2,16 @@
#include "ptk_vk/render_pass.h" #include "ptk_vk/render_pass.h"
#include "ptk_vk/device.h"
#include "ptk_vk/swapchain.h"
#include "ptk_vk/utils.h" #include "ptk_vk/utils.h"
PTK_OPTION(VkRenderPass) vk_create_render_pass(VkDevice dev, VkFormat format) { VkRenderPass g_render_pass;
VkRenderPass ret;
VK_TRY(PTK_OPTION_NONE(VkRenderPass), bool vk_create_render_pass(void) {
VK_TRY(false,
vkCreateRenderPass( vkCreateRenderPass(
dev, g_dev,
&(VkRenderPassCreateInfo){ &(VkRenderPassCreateInfo){
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
.pNext = NULL, .pNext = NULL,
@ -17,7 +19,7 @@ PTK_OPTION(VkRenderPass) vk_create_render_pass(VkDevice dev, VkFormat format) {
.attachmentCount = 1, .attachmentCount = 1,
.pAttachments = &(VkAttachmentDescription){ .pAttachments = &(VkAttachmentDescription){
.flags = 0, .flags = 0,
.format = format, .format = g_swapchain_image_format,
.samples = VK_SAMPLE_COUNT_1_BIT, .samples = VK_SAMPLE_COUNT_1_BIT,
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
.storeOp = VK_ATTACHMENT_STORE_OP_STORE, .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
@ -54,9 +56,9 @@ PTK_OPTION(VkRenderPass) vk_create_render_pass(VkDevice dev, VkFormat format) {
}, },
}, },
NULL, NULL,
&ret &g_render_pass
) )
); );
return PTK_OPTION_SOME(VkRenderPass, ret); return true;
} }

View file

@ -3,14 +3,12 @@
#ifndef PTK_PTK_VK_RENDER_PASS_H_ #ifndef PTK_PTK_VK_RENDER_PASS_H_
#define PTK_PTK_VK_RENDER_PASS_H_ #define PTK_PTK_VK_RENDER_PASS_H_
#include "ptk_option.h"
#include <vulkan/vulkan.h> #include <vulkan/vulkan.h>
#include <stdbool.h> #include <stdbool.h>
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_ #endif // PTK_PTK_VK_RENDER_PASS_H_

View file

@ -2,6 +2,10 @@
#include "ptk_vk/swapchain.h" #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_vk/utils.h"
#include "ptk_list.h" #include "ptk_list.h"
@ -11,18 +15,16 @@
#endif #endif
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
static VkSwapchainKHR m_swapchain;
PTK_LIST_DEFINE(VkImage); PTK_LIST_DEFINE(VkImage);
PTK_LIST_DEFINE(VkImageView); PTK_LIST_DEFINE(VkImageView);
static PTK_LIST(VkImage) m_swapchain_images; static PTK_LIST(VkImage) m_swapchain_images;
static PTK_LIST(VkImageView) m_swapchain_image_views; static PTK_LIST(VkImageView) m_swapchain_image_views;
static VkFormat m_swapchain_image_format; VkSwapchainKHR g_swapchain;
static VkExtent2D m_swapchain_extent; VkFormat g_swapchain_image_format;
VkExtent2D g_swapchain_extent;
static PTK_LIST(VkFramebuffer) m_swapchain_framebuffers; PTK_LIST(VkFramebuffer) g_swapchain_framebuffers;
VkSurfaceFormatKHR select_swap_surface_format(const PTK_LIST(VkSurfaceFormatKHR) available_formats) { VkSurfaceFormatKHR select_swap_surface_format(const PTK_LIST(VkSurfaceFormatKHR) available_formats) {
PTK_LIST_FOR_EACH(const VkSurfaceFormatKHR, available_formats, current_format, { 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; 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); m_swapchain_image_views = PTK_LIST_NEW(VkImageView, m_swapchain_images.size);
PTK_LIST_FOR_EACH_E(VkImage, m_swapchain_images, i, swapchain_image, { PTK_LIST_FOR_EACH_E(VkImage, m_swapchain_images, i, swapchain_image, {
VK_TRY(false, VK_TRY(false,
vkCreateImageView( vkCreateImageView(
dev, g_dev,
&(VkImageViewCreateInfo){ &(VkImageViewCreateInfo){
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
.pNext = NULL, .pNext = NULL,
.flags = 0, .flags = 0,
.image = swapchain_image, .image = swapchain_image,
.viewType = VK_IMAGE_VIEW_TYPE_2D, .viewType = VK_IMAGE_VIEW_TYPE_2D,
.format = m_swapchain_image_format, .format = g_swapchain_image_format,
.components = (VkComponentMapping){ .components = (VkComponentMapping){
.r = VK_COMPONENT_SWIZZLE_IDENTITY, .r = VK_COMPONENT_SWIZZLE_IDENTITY,
.g = VK_COMPONENT_SWIZZLE_IDENTITY, .g = VK_COMPONENT_SWIZZLE_IDENTITY,
@ -146,115 +217,30 @@ bool vk_create_image_views(VkDevice dev) {
return true; return true;
} }
VkSwapchainKHR vk_current_swapchain(void) { bool vk_recreate_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) {
int width = 0, height = 0; int width = 0, height = 0;
glfwGetFramebufferSize(window, &width, &height); glfwGetFramebufferSize(g_window, &width, &height);
while (width == 0 || height == 0) { while (width == 0 || height == 0) {
glfwGetFramebufferSize(window, &width, &height); glfwGetFramebufferSize(g_window, &width, &height);
glfwWaitEvents(); 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"); PTK_ERR("failed creating new swapchain");
return false; return false;
} }
if (!vk_create_image_views(dev)) { if (!vk_create_image_views()) {
PTK_ERR("failed creating new image views"); PTK_ERR("failed creating new image views");
return false; return false;
} }
if (!vk_create_framebuffers(dev, render_pass)) { if (!vk_create_framebuffers()) {
PTK_ERR("failed creating new framebuffers"); PTK_ERR("failed creating new framebuffers");
return false; return false;
} }
@ -262,48 +248,48 @@ bool vk_recreate_swapchain(GLFWwindow *window, VkDevice dev, VkPhysicalDevice ph
return true; return true;
} }
bool vk_create_framebuffers(VkDevice dev, VkRenderPass render_pass) { bool vk_create_framebuffers(void) {
m_swapchain_framebuffers = PTK_LIST_NEW(VkFramebuffer, m_swapchain_image_views.size); g_swapchain_framebuffers = PTK_LIST_NEW(VkFramebuffer, m_swapchain_image_views.size);
VkFramebuffer fb; VkFramebuffer fb;
PTK_LIST_FOR_EACH(VkImageView, m_swapchain_image_views, swapchain_image_view, { PTK_LIST_FOR_EACH(VkImageView, m_swapchain_image_views, swapchain_image_view, {
VK_TRY(false, VK_TRY(false,
vkCreateFramebuffer( vkCreateFramebuffer(
dev, g_dev,
&(VkFramebufferCreateInfo){ &(VkFramebufferCreateInfo){
.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
.pNext = NULL, .pNext = NULL,
.flags = 0, .flags = 0,
.renderPass = render_pass, .renderPass = g_render_pass,
.attachmentCount = 1, .attachmentCount = 1,
.pAttachments = &swapchain_image_view, .pAttachments = &swapchain_image_view,
.width = m_swapchain_extent.width, .width = g_swapchain_extent.width,
.height = m_swapchain_extent.height, .height = g_swapchain_extent.height,
.layers = 1, .layers = 1,
}, },
NULL, NULL,
&fb &fb
) )
); );
PTK_LIST_ADD(VkFramebuffer, m_swapchain_framebuffers, fb); PTK_LIST_ADD(VkFramebuffer, g_swapchain_framebuffers, fb);
}) })
return true; return true;
} }
void vk_cleanup_swapchain(VkDevice dev) { void vk_cleanup_swapchain(void) {
PTK_LIST_FOR_EACH(VkFramebuffer, m_swapchain_framebuffers, fb, { PTK_LIST_FOR_EACH(VkFramebuffer, g_swapchain_framebuffers, fb, {
vkDestroyFramebuffer(dev, fb, NULL); 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_FREE(m_swapchain_images);
PTK_LIST_FOR_EACH(VkImageView, m_swapchain_image_views, iv, { 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); PTK_LIST_FREE(m_swapchain_image_views);
vkDestroySwapchainKHR(dev, m_swapchain, NULL); vkDestroySwapchainKHR(g_dev, g_swapchain, NULL);
} }

View file

@ -3,8 +3,6 @@
#ifndef PTK_PTK_VK_SWAPCHAIN_H_ #ifndef PTK_PTK_VK_SWAPCHAIN_H_
#define PTK_PTK_VK_SWAPCHAIN_H_ #define PTK_PTK_VK_SWAPCHAIN_H_
#include "ptk_vk/device.h"
#include "ptk_list.h" #include "ptk_list.h"
#include <vulkan/vulkan_core.h> #include <vulkan/vulkan_core.h>
@ -15,6 +13,11 @@ PTK_LIST_DEFINE(VkFramebuffer);
PTK_LIST_DEFINE(VkSurfaceFormatKHR); PTK_LIST_DEFINE(VkSurfaceFormatKHR);
PTK_LIST_DEFINE(VkPresentModeKHR); 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 { typedef struct {
VkSurfaceCapabilitiesKHR capabilities; VkSurfaceCapabilitiesKHR capabilities;
PTK_LIST(VkSurfaceFormatKHR) formats; PTK_LIST(VkSurfaceFormatKHR) formats;
@ -23,19 +26,14 @@ typedef struct {
SwapchainSupportInfo query_swapchain_support(const VkPhysicalDevice dev, const VkSurfaceKHR surface); SwapchainSupportInfo query_swapchain_support(const VkPhysicalDevice dev, const VkSurfaceKHR surface);
VkSwapchainKHR vk_current_swapchain(void); bool vk_create_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(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(void);
void vk_cleanup_swapchain(VkDevice dev);
#endif // PTK_PTK_VK_SWAPCHAIN_H_ #endif // PTK_PTK_VK_SWAPCHAIN_H_

View file

@ -2,14 +2,19 @@
#include "ptk_vk/sync_objects.h" #include "ptk_vk/sync_objects.h"
#include "ptk_vk/device.h"
#include "ptk_vk/utils.h" #include "ptk_vk/utils.h"
PTK_OPTION(SyncObjects) vk_create_sync_objects(VkDevice dev, uint32_t max_frames_in_flight) { PTK_LIST(VkSemaphore) g_image_available_semaphores;
SyncObjects ret = { PTK_LIST(VkSemaphore) g_render_finished_semaphores;
.image_available_semaphores = PTK_LIST_NEW(VkSemaphore, max_frames_in_flight), PTK_LIST(VkFence) g_in_flight_fences;
.render_finished_semaphores = PTK_LIST_NEW(VkSemaphore, max_frames_in_flight),
.in_flight_fences = PTK_LIST_NEW(VkFence, max_frames_in_flight), 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 = { const VkSemaphoreCreateInfo semaphore_info = {
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_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, .flags = 0,
}; };
for (size_t i = 0; i < max_frames_in_flight; ++i) { for (size_t i = 0; i < g_max_frames_in_flight; ++i) {
VK_TRY(PTK_OPTION_NONE(SyncObjects), VK_TRY(false,
vkCreateSemaphore(dev, &semaphore_info, NULL, &ret.image_available_semaphores.data[i]) vkCreateSemaphore(g_dev, &semaphore_info, NULL, &g_image_available_semaphores.data[i])
); );
VK_TRY(PTK_OPTION_NONE(SyncObjects), VK_TRY(false,
vkCreateSemaphore(dev, &semaphore_info, NULL, &ret.render_finished_semaphores.data[i]) vkCreateSemaphore(g_dev, &semaphore_info, NULL, &g_render_finished_semaphores.data[i])
); );
VK_TRY(PTK_OPTION_NONE(SyncObjects), VK_TRY(false,
vkCreateFence( vkCreateFence(
dev, g_dev,
&(VkFenceCreateInfo){ &(VkFenceCreateInfo){
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
.pNext = NULL, .pNext = NULL,
.flags = VK_FENCE_CREATE_SIGNALED_BIT, .flags = VK_FENCE_CREATE_SIGNALED_BIT,
}, },
NULL, NULL,
&ret.in_flight_fences.data[i] &g_in_flight_fences.data[i]
) )
); );
} }
return PTK_OPTION_SOME(SyncObjects, ret); return true;
} }

View file

@ -4,21 +4,18 @@
#define PTK_PTK_VK_SYNC_OBJECTS_H_ #define PTK_PTK_VK_SYNC_OBJECTS_H_
#include "ptk_list.h" #include "ptk_list.h"
#include "ptk_option.h"
#include <vulkan/vulkan_core.h> #include <vulkan/vulkan_core.h>
PTK_LIST_DEFINE(VkSemaphore); PTK_LIST_DEFINE(VkSemaphore);
PTK_LIST_DEFINE(VkFence); PTK_LIST_DEFINE(VkFence);
typedef struct { extern PTK_LIST(VkSemaphore) g_image_available_semaphores;
PTK_LIST(VkSemaphore) image_available_semaphores; extern PTK_LIST(VkSemaphore) g_render_finished_semaphores;
PTK_LIST(VkSemaphore) render_finished_semaphores; extern PTK_LIST(VkFence) g_in_flight_fences;
PTK_LIST(VkFence) in_flight_fences;
} SyncObjects;
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_ #endif // PTK_PTK_VK_SYNC_OBJECTS_H_

View file

@ -3,22 +3,27 @@
#include "ptk_vk/uniform_buffers.h" #include "ptk_vk/uniform_buffers.h"
#include "ptk_vk/buffer.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" #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); const VkDeviceSize buffer_size = sizeof(UniformBufferObject);
UniformBufferStuff ret = { g_uniform_buffers = PTK_LIST_NEW(VkBuffer, g_max_frames_in_flight);
.buffers = PTK_LIST_NEW(VkBuffer, max_frames_in_flight), g_uniform_buffer_memories = PTK_LIST_NEW(VkDeviceMemory, g_max_frames_in_flight);
.buffer_memories = PTK_LIST_NEW(VkDeviceMemory, max_frames_in_flight), g_uniform_buffers_mapped = PTK_LIST_NEW(voidptr, g_max_frames_in_flight);
.buffers_mapped = PTK_LIST_NEW(voidptr, 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( PTK_OPTION(BufferStuff) uniform_buffer_stuff_opt = create_buffer(
dev, g_dev,
physical_dev, g_physical_dev,
buffer_size, buffer_size,
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_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) { if (!uniform_buffer_stuff_opt.exists) {
PTK_ERR("failed creating index buffer"); PTK_ERR("failed creating index buffer");
return PTK_OPTION_NONE(UniformBufferStuff); return false;
} }
ret.buffers.data[i] = uniform_buffer_stuff_opt.value.buffer; g_uniform_buffers.data[i] = uniform_buffer_stuff_opt.value.buffer;
ret.buffer_memories.data[i] = uniform_buffer_stuff_opt.value.buffer_memory; 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;
} }

View file

@ -4,28 +4,24 @@
#define PTK_PTK_VK_UNIFORM_BUFFERS_H_ #define PTK_PTK_VK_UNIFORM_BUFFERS_H_
#include "ptk_list.h" #include "ptk_list.h"
#include "ptk_option.h"
#include "ptk_vec.h" #include "ptk_vec.h"
#include <vulkan/vulkan_core.h> #include <vulkan/vulkan_core.h>
PTK_LIST_DEFINE(VkBuffer);
PTK_LIST_DEFINE(VkDeviceMemory);
typedef void *voidptr;
PTK_LIST_DEFINE(voidptr);
typedef struct { typedef struct {
PtkSize initial_window_size; PtkSize initial_window_size;
PtkSize window_size; PtkSize window_size;
} UniformBufferObject; } UniformBufferObject;
typedef struct { PTK_LIST_DEFINE(VkBuffer);
PTK_LIST(VkBuffer) buffers; PTK_LIST_DEFINE(VkDeviceMemory);
PTK_LIST(VkDeviceMemory) buffer_memories; typedef void *voidptr;
PTK_LIST(voidptr) buffers_mapped; PTK_LIST_DEFINE(voidptr);
} UniformBufferStuff;
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_ #endif // PTK_PTK_VK_UNIFORM_BUFFERS_H_