/* SPDX-License-Identifier:BSD-3-Clause */ #include "vk.h" #include "../renderer.h" #include "instance.h" #include "physical_device.h" #include "device.h" #include "surface.h" #include "swapchain.h" #include "renderpass.h" #include "pipeline.h" #include "framebuffer.h" #include "command.h" #include "sync.h" #include "buffer.h" #include "../../core/log.h" #include #include #include "sync.h" struct renderer_context *renderer_context_init(RGFW_window *window) { struct renderer_context *context = (struct renderer_context *)malloc(sizeof(struct renderer_context)); context->window = window; vk_instance_init(context); vk_surface_init(context); vk_physical_device_pick(context); vk_physical_device_select_family_indices(context); vk_device_init(context); vk_swapchain_init(context); vk_renderpass_init(context); vk_pipeline_init(context); vk_framebuffers_init(context); vk_command_pool_init(context); vk_command_buffers_init(context); vk_sync_init(context); vk_quad_buffers_init(context); return context; } void renderer_context_deinit(struct renderer_context *context) { vkDeviceWaitIdle(context->device); vk_quad_buffers_deinit(context); vk_sync_deinit(context); free(context->command_buffers); vk_command_pool_deinit(context); vk_framebuffers_deinit(context); vk_pipeline_deinit(context); vk_renderpass_deinit(context); vk_swapchain_deinit(context); vk_surface_deinit(context); vk_device_deinit(context); vk_instance_deinit(context); free(context); } static void record_command_buffer(struct renderer_context *context, u32 image_index) { VkCommandBuffer cmd = context->command_buffers[context->current_frame]; VkCommandBufferBeginInfo begin_info = { .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO }; if (vkBeginCommandBuffer(cmd, &begin_info) != VK_SUCCESS) { fatal("Can't begin command buffer.\n"); } VkClearValue clear_color = { .color = { { 0.1f, 0.1f, 0.1f, 1.0f } } }; VkRenderPassBeginInfo render_pass_info = { .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, .renderPass = context->render_pass, .framebuffer = context->swapchain.framebuffers[image_index], .renderArea.offset = { 0, 0 }, .renderArea.extent = context->swapchain.extent, .clearValueCount = 1, .pClearValues = &clear_color }; vkCmdBeginRenderPass(cmd, &render_pass_info, VK_SUBPASS_CONTENTS_INLINE); vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, context->pipeline); VkBuffer vertex_buffers[] = { context->vertex_buffer }; VkDeviceSize offsets[] = { 0 }; vkCmdBindVertexBuffers(cmd, 0, 1, vertex_buffers, offsets); vkCmdBindIndexBuffer(cmd, context->index_buffer, 0, VK_INDEX_TYPE_UINT16); vkCmdDrawIndexed(cmd, 6, 1, 0, 0, 0); vkCmdEndRenderPass(cmd); if (vkEndCommandBuffer(cmd) != VK_SUCCESS) { fatal("Can't end command buffer.\n"); } } struct mesh *renderer_build_chunk_mesh(void) { return NULL; } void renderer_draw_mesh(struct renderer_context *context, struct mesh mesh) { (void)context; (void)mesh; } void renderer_draw_chunk(struct renderer_context *context, struct mesh mesh) { (void)mesh; (void)context; } void renderer_present(struct renderer_context *context) { vkWaitForFences(context->device, 1, &context->in_flight[context->current_frame], VK_TRUE, UINT64_MAX); u32 image_index; VkResult result = vkAcquireNextImageKHR(context->device, context->swapchain.handle, UINT64_MAX, context->image_available[context->current_frame], VK_NULL_HANDLE, &image_index); if (result == VK_ERROR_OUT_OF_DATE_KHR) { return; } vkResetFences(context->device, 1, &context->in_flight[context->current_frame]); vkResetCommandBuffer(context->command_buffers[context->current_frame], 0); record_command_buffer(context, image_index); VkSemaphore wait_semaphores[] = { context->image_available[context->current_frame] }; VkPipelineStageFlags wait_stages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT }; VkSemaphore signal_semaphores[] = { context->render_finished[image_index] }; VkSubmitInfo submit_info = { .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, .waitSemaphoreCount = 1, .pWaitSemaphores = wait_semaphores, .pWaitDstStageMask = wait_stages, .commandBufferCount = 1, .pCommandBuffers = &context->command_buffers[context->current_frame], .signalSemaphoreCount = 1, .pSignalSemaphores = signal_semaphores }; if (vkQueueSubmit(context->graphics_queue, 1, &submit_info, context->in_flight[context->current_frame]) != VK_SUCCESS) { fatal("Can't submit draw command buffer.\n"); } VkSwapchainKHR swapchains[] = { context->swapchain.handle }; VkPresentInfoKHR present_info = { .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, .waitSemaphoreCount = 1, .pWaitSemaphores = signal_semaphores, .swapchainCount = 1, .pSwapchains = swapchains, .pImageIndices = &image_index }; vkQueuePresentKHR(context->present_queue, &present_info); context->current_frame = (context->current_frame + 1) % MAX_FRAMES_IN_FLIGHT; }