summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/main_loop/ex_main_loop.c3
-rw-r--r--src/colours.h2
-rw-r--r--src/renderer/backends/backend_vulkan.c101
-rw-r--r--src/renderer/render_backend.h2
4 files changed, 104 insertions, 4 deletions
diff --git a/examples/main_loop/ex_main_loop.c b/examples/main_loop/ex_main_loop.c
index 3b2354a..728290f 100644
--- a/examples/main_loop/ex_main_loop.c
+++ b/examples/main_loop/ex_main_loop.c
@@ -2,6 +2,7 @@
#include "core.h"
#include "render.h"
+#include "render_backend.h"
int main() {
core* core = core_bringup();
@@ -13,6 +14,8 @@ int main() {
render_frame_begin(&core->renderer);
+ gfx_backend_draw_frame(&core->renderer);
+
// insert work here
render_frame_end(&core->renderer);
diff --git a/src/colours.h b/src/colours.h
index bbd9476..fa5f54b 100644
--- a/src/colours.h
+++ b/src/colours.h
@@ -12,6 +12,8 @@ typedef struct rgba {
#define COLOUR_SEA_GREEN ((rgba){ 0.18, 0.77, 0.71, 1.0 })
#define COLOUR_WHITE ((rgba){ 1.0, 1.0, 1.0, 1.0 })
+#define rgba_to_vec4(color) (vec4(color.r, color.g, color.b, color.a))
+
// Thanks ChatGPT
#define STONE_50 ((rgba){ 0.980, 0.980, 0.976, 1.0 })
#define STONE_100 ((rgba){ 0.961, 0.961, 0.957, 1.0 })
diff --git a/src/renderer/backends/backend_vulkan.c b/src/renderer/backends/backend_vulkan.c
index 81a08e2..4b7314c 100644
--- a/src/renderer/backends/backend_vulkan.c
+++ b/src/renderer/backends/backend_vulkan.c
@@ -1,5 +1,7 @@
#include <stdbool.h>
+#include <stdint.h>
#include <string.h>
+#include "colours.h"
#define CEL_PLATFORM_LINUX
#include <assert.h>
#include <vulkan/vk_platform.h>
@@ -637,6 +639,11 @@ void vulkan_swapchain_present(vulkan_context* context, vulkan_swapchain* swapcha
void vulkan_renderpass_create(vulkan_context* context, vulkan_renderpass* out_renderpass,
vec4 render_area, vec4 clear_colour, f32 depth, u32 stencil) {
+ out_renderpass->render_area = render_area;
+ out_renderpass->clear_colour = clear_colour;
+ out_renderpass->depth = depth;
+ out_renderpass->stencil = stencil;
+
// main subpass
VkSubpassDescription subpass = {};
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
@@ -940,7 +947,7 @@ bool gfx_backend_init(renderer* ren) {
// Renderpass creation
vulkan_renderpass_create(&context, &context.main_renderpass,
vec4(0, 0, context.framebuffer_width, context.framebuffer_height),
- vec4(0.0, 0.0, 0.2, 1.0), 1.0, 0);
+ rgba_to_vec4(COLOUR_SEA_GREEN), 1.0, 0);
// Framebiffers creation
context.swapchain.framebuffers = vulkan_framebuffer_darray_new(context.swapchain.image_count);
@@ -953,10 +960,10 @@ bool gfx_backend_init(renderer* ren) {
// Sync objects
context.image_available_semaphores =
- malloc(sizeof(VkSemaphore) * context.swapchain.max_frames_in_flight);
+ calloc(context.swapchain.max_frames_in_flight, sizeof(VkSemaphore));
context.queue_complete_semaphores =
- malloc(sizeof(VkSemaphore) * context.swapchain.max_frames_in_flight);
- context.in_flight_fences = malloc(sizeof(vulkan_fence) * context.swapchain.max_frames_in_flight);
+ calloc(context.swapchain.max_frames_in_flight, sizeof(VkSemaphore));
+ context.in_flight_fences = calloc(context.swapchain.max_frames_in_flight, sizeof(vulkan_fence));
for (u8 i = 0; i < context.swapchain.max_frames_in_flight; i++) {
VkSemaphoreCreateInfo semaphore_create_info = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO };
@@ -993,6 +1000,92 @@ void gfx_backend_shutdown(renderer* ren) {
vkDestroyInstance(context.instance, context.allocator);
}
+void backend_begin_frame(renderer* ren, f32 delta_time) {
+ vulkan_device* device = &context.device;
+
+ // TODO: resize gubbins
+
+ if (!vulkan_fence_wait(&context, &context.in_flight_fences[context.current_frame], UINT64_MAX)) {
+ WARN("In-flight fence wait failure");
+ }
+
+ if (!vulkan_swapchain_acquire_next_image_index(
+ &context, &context.swapchain, UINT64_MAX,
+ context.image_available_semaphores[context.current_frame], 0, &context.image_index)) {
+ WARN("couldnt acquire swapchain next image");
+ }
+
+ vulkan_command_buffer* command_buffer = &context.gfx_command_buffers->data[context.image_index];
+ vulkan_command_buffer_reset(command_buffer);
+ vulkan_command_buffer_begin(command_buffer, false, false, false);
+
+ VkViewport viewport;
+ viewport.x = 0.0;
+ viewport.y = (f32)context.framebuffer_height;
+ viewport.width = (f32)context.framebuffer_width;
+ viewport.height = -(f32)context.framebuffer_height;
+ viewport.minDepth = 0.0;
+ viewport.maxDepth = 1.0;
+
+ VkRect2D scissor;
+ scissor.offset.x = scissor.offset.y = 0;
+ scissor.extent.width = context.framebuffer_width;
+ scissor.extent.height = context.framebuffer_height;
+
+ vkCmdSetViewport(command_buffer->handle, 0, 1, &viewport);
+ vkCmdSetScissor(command_buffer->handle, 0, 1, &scissor);
+
+ context.main_renderpass.render_area.z = context.framebuffer_width;
+ context.main_renderpass.render_area.w = context.framebuffer_height;
+
+ vulkan_renderpass_begin(command_buffer, &context.main_renderpass,
+ context.swapchain.framebuffers->data[context.image_index].handle);
+}
+
+void backend_end_frame(renderer* ren, f32 delta_time) {
+ vulkan_command_buffer* command_buffer = &context.gfx_command_buffers->data[context.image_index];
+
+ vulkan_renderpass_end(command_buffer, &context.main_renderpass);
+
+ vulkan_command_buffer_end(command_buffer);
+
+ // TODO: wait on fence - https://youtu.be/hRL71D1f3pU?si=nLJx-ZsemDBeQiQ1&t=1037
+
+ context.images_in_flight[context.image_index] = &context.in_flight_fences[context.current_frame];
+
+ vulkan_fence_reset(&context, &context.in_flight_fences[context.current_frame]);
+
+ VkSubmitInfo submit_info = { VK_STRUCTURE_TYPE_SUBMIT_INFO };
+ submit_info.commandBufferCount = 1;
+ submit_info.pCommandBuffers = &command_buffer->handle;
+ submit_info.signalSemaphoreCount = 1;
+ submit_info.pSignalSemaphores = &context.queue_complete_semaphores[context.current_frame];
+ submit_info.waitSemaphoreCount = 1;
+ submit_info.pWaitSemaphores = &context.image_available_semaphores[context.current_frame];
+
+ VkPipelineStageFlags flags[1] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
+ submit_info.pWaitDstStageMask = flags;
+
+ VkResult result = vkQueueSubmit(context.device.graphics_queue, 1, &submit_info,
+ context.in_flight_fences[context.current_frame].handle);
+
+ if (result != VK_SUCCESS) {
+ ERROR("queue submission failed. fark.");
+ }
+
+ vulkan_command_buffer_update_submitted(command_buffer);
+
+ vulkan_swapchain_present(
+ &context, &context.swapchain, context.device.graphics_queue, context.device.present_queue,
+ context.queue_complete_semaphores[context.current_frame], context.image_index);
+}
+
+void gfx_backend_draw_frame(renderer* ren) {
+ backend_begin_frame(ren, 16.0);
+
+ backend_end_frame(ren, 16.0);
+}
+
void clear_screen(vec3 colour) {}
void bind_texture(shader s, texture* tex, u32 slot) {}
diff --git a/src/renderer/render_backend.h b/src/renderer/render_backend.h
index 8c351c6..041f412 100644
--- a/src/renderer/render_backend.h
+++ b/src/renderer/render_backend.h
@@ -12,6 +12,8 @@
bool gfx_backend_init(renderer* ren);
void gfx_backend_shutdown(renderer* ren);
+void gfx_backend_draw_frame(renderer* ren);
+
void clear_screen(vec3 colour);
void bind_texture(shader s, texture* tex, u32 slot);