topaz/rendering/vk/renderer.c

169 lines
4.9 KiB
C

/* SPDX-License-Identifier:BSD-3-Clause */
#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 "vk.h"
#include "../../core/log.h"
#include <stdlib.h>
#include <stdio.h>
#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;
}