169 lines
4.9 KiB
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;
|
|
}
|