2 #include <kiba/renderer/poc.h>
5 #include <kiba/renderer/vulkan/command_buffer.h>
6 #include <kiba/renderer/vulkan/context.h>
7 #include <kiba/renderer/vulkan/depth.h>
8 #include <kiba/renderer/vulkan/device.h>
9 #include <kiba/renderer/vulkan/framebuffers.h>
10 #include <kiba/renderer/vulkan/image.h>
11 #include <kiba/renderer/vulkan/index_buffer.h>
12 #include <kiba/renderer/vulkan/instance.h>
13 #include <kiba/renderer/vulkan/logging.h>
14 #include <kiba/renderer/vulkan/pipeline.h>
15 #include <kiba/renderer/vulkan/renderpass.h>
16 #include <kiba/renderer/vulkan/surface.h>
17 #include <kiba/renderer/vulkan/swap_chain.h>
18 #include <kiba/renderer/vulkan/sync.h>
19 #include <kiba/renderer/vulkan/texture.h>
20 #include <kiba/renderer/vulkan/uniform.h>
21 #include <kiba/renderer/vulkan/vertex_buffer.h>
26 if (!vulkan_default_context_create(&context, window)) {
30 if (!vulkan_instance_create(&context)) {
35 if (!vulkan_debug_messenger_create(&context)) {
40 if (!vulkan_surface_create(&context)) {
44 if (!vulkan_device_create(&context)) {
48 if (!vulkan_renderpass_create(&context)) {
52 if (!vulkan_swap_chain_create(&context)) {
56 if (!vulkan_descriptor_set_layout_create(&context)) {
60 if (!vulkan_pipeline_create(&context)) {
64 if (!vulkan_depth_create(&context)) {
68 if (!vulkan_framebuffers_create(&context)) {
72 if (!vulkan_texture_create(&context)) {
76 if (!vulkan_vertex_buffer_create(&context)) {
80 if (!vulkan_index_buffer_create(&context)) {
84 if (!vulkan_uniform_buffers_create(&context)) {
88 if (!vulkan_descriptor_pool_create(&context)) {
92 if (!vulkan_descriptor_sets_create(&context)) {
96 if (!vulkan_sync_create(&context)) {
103 void vulkan_shutdown(
void) {
105 vkDeviceWaitIdle(context.device.logical);
107 vulkan_framebuffers_destroy(&context);
109 vulkan_depth_destroy(&context);
111 vulkan_swap_chain_destroy(&context);
113 vulkan_texture_destroy(&context);
115 vulkan_pipeline_destroy(&context);
117 vulkan_renderpass_destroy(&context);
119 vulkan_uniform_buffers_destroy(&context);
121 vulkan_descriptor_pool_destroy(&context);
123 vulkan_descriptor_set_layout_destroy(&context);
125 vulkan_index_buffer_destroy(&context);
127 vulkan_vertex_buffer_destroy(&context);
129 vulkan_sync_destroy(&context);
131 vulkan_device_destroy(&context);
133 vulkan_surface_destroy(&context);
135 #ifdef KB_DEBUG_BUILD
136 vulkan_debug_messenger_destroy(&context);
139 vulkan_instance_destroy(&context);
141 vulkan_context_destroy(&context);
144 void vulkan_draw_frame(
void) {
145 VK_CALL_ASSERT(vkWaitForFences(context.device.logical, 1, &context.sync.fc_in_flight, VK_TRUE, UINT64_MAX));
148 VkResult res = vkAcquireNextImageKHR(context.device.logical,
149 context.swap_chain.swap_chain,
151 context.sync.sp_image_available,
154 if (res == VK_ERROR_OUT_OF_DATE_KHR) {
155 vulkan_swap_chain_recreate(&context);
160 VK_CALL_ASSERT(vkResetFences(context.device.logical, 1, &context.sync.fc_in_flight));
162 static u32 init_counter = 0;
163 if (init_counter < 3) {
164 if (!vulkan_image_transition_layout_tmp(&context,
165 context.swap_chain.images[image_index],
166 VK_FORMAT_R8G8B8A8_SRGB,
167 VK_IMAGE_LAYOUT_UNDEFINED,
168 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)) {
169 KB_ERROR(
"failed to transition vulkan_image layout before rendering");
171 init_counter += (init_counter == image_index);
173 if (!vulkan_image_transition_layout_tmp(&context,
174 context.swap_chain.images[image_index],
175 VK_FORMAT_R8G8B8A8_SRGB,
176 VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
177 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)) {
178 KB_ERROR(
"failed to transition vulkan_image layout before rendering");
182 VK_CALL_ASSERT(vkResetCommandBuffer(context.device.graphics_queue.command_buffer, 0));
183 vulkan_command_buffer_record(&context, context.device.graphics_queue.command_buffer, image_index);
185 VkPipelineStageFlags wait_stages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
188 vulkan_uniform_buffers_update(&context, image_index);
190 VkSubmitInfo submit_info = {
191 .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
192 .waitSemaphoreCount = 1,
193 .pWaitSemaphores = &context.sync.sp_image_available,
194 .pWaitDstStageMask = wait_stages,
195 .commandBufferCount = 1,
196 .pCommandBuffers = &context.device.graphics_queue.command_buffer,
197 .signalSemaphoreCount = 1,
198 .pSignalSemaphores = &context.sync.sp_render_finished,
200 VK_CALL_ASSERT(vkQueueSubmit(context.device.graphics_queue.queue, 1, &submit_info, context.sync.fc_in_flight));
202 if (!vulkan_image_transition_layout_tmp(&context,
203 context.swap_chain.images[image_index],
204 VK_FORMAT_R8G8B8A8_SRGB,
205 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
206 VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)) {
207 KB_ERROR(
"failed to transition vulkan_image layout after rendering");
210 VkPresentInfoKHR present_info = {
211 .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
212 .waitSemaphoreCount = 1,
213 .pWaitSemaphores = &context.sync.sp_render_finished,
215 .pSwapchains = &context.swap_chain.swap_chain,
216 .pImageIndices = &image_index,
219 res = vkQueuePresentKHR(context.device.present_queue.queue, &present_info);
220 if (res == VK_ERROR_OUT_OF_DATE_KHR || res == VK_SUBOPTIMAL_KHR || context.swap_chain.recreate) {
221 context.swap_chain.recreate =
false;
222 vulkan_swap_chain_recreate(&context);
#define KB_ERROR(...)
Log entry with error log level.