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_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
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_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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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_
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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_
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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_
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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_
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
|
|
|
@ -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_
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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_
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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_
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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_
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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_
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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_
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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_
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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_
|
||||||
|
|
Loading…
Reference in a new issue