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