summaryrefslogtreecommitdiff
path: root/src/renderer/archive
diff options
context:
space:
mode:
Diffstat (limited to 'src/renderer/archive')
-rw-r--r--src/renderer/archive/old_backend_vulkan.c1990
-rw-r--r--src/renderer/archive/render.c413
-rw-r--r--src/renderer/archive/render.h46
-rw-r--r--src/renderer/archive/render_backend.h39
-rw-r--r--src/renderer/archive/render_types.h210
5 files changed, 0 insertions, 2698 deletions
diff --git a/src/renderer/archive/old_backend_vulkan.c b/src/renderer/archive/old_backend_vulkan.c
deleted file mode 100644
index 0dfba98..0000000
--- a/src/renderer/archive/old_backend_vulkan.c
+++ /dev/null
@@ -1,1990 +0,0 @@
-#define CDEBUG
-// #define CEL_REND_BACKEND_VULKAN 1
-#if CEL_REND_BACKEND_VULKAN
-#include "camera.h"
-#include "primitives.h"
-// ^ Temporary
-
-#include <assert.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <string.h>
-#include <vk_platform.h>
-#include <vulkan.h>
-#include <vulkan_core.h>
-#include "colours.h"
-#include "str.h"
-
-#include "darray.h"
-#include "defines.h"
-#include "file.h"
-#include "log.h"
-#include "maths.h"
-#include "maths_types.h"
-#include "render_backend.h"
-#include "render_types.h"
-// #include "vulkan_helpers.h"
-
-#include <stdlib.h>
-
-#define SCR_WIDTH 1000
-#define SCR_HEIGHT 1000
-
-#include <glad/glad.h>
-
-#include <glfw3.h>
-
-KITC_DECL_TYPED_ARRAY(VkLayerProperties)
-
-typedef struct vulkan_device {
- VkPhysicalDevice physical_device;
- VkDevice logical_device;
- vulkan_swapchain_support_info swapchain_support;
- i32 graphics_queue_index;
- i32 present_queue_index;
- i32 compute_queue_index;
- i32 transfer_queue_index;
- VkQueue graphics_queue;
- VkQueue present_queue;
- VkQueue compute_queue;
- VkQueue transfer_queue;
- VkCommandPool gfx_command_pool;
- VkPhysicalDeviceProperties properties;
- VkPhysicalDeviceFeatures features;
- VkPhysicalDeviceMemoryProperties memory;
- VkFormat depth_format;
-} vulkan_device;
-
-typedef struct vulkan_image {
- VkImage handle;
- VkDeviceMemory memory;
- VkImageView view;
- u32 width;
- u32 height;
-} vulkan_image;
-
-typedef struct vulkan_texture_data {
- vulkan_image image;
- VkSampler sampler;
-} vulkan_texture_data;
-
-typedef enum vulkan_renderpass_state {
- READY,
- RECORDING,
- IN_RENDER_PASS,
- RECORDING_ENDING,
- SUBMITTED,
- NOT_ALLOCATED
-} vulkan_renderpass_state;
-
-typedef struct vulkan_renderpass {
- VkRenderPass handle;
- vec4 render_area;
- vec4 clear_colour;
- f32 depth;
- u32 stencil;
- vulkan_renderpass_state state;
-} vulkan_renderpass;
-
-typedef struct vulkan_framebuffer {
- VkFramebuffer handle;
- u32 attachment_count;
- VkImageView* attachments;
- vulkan_renderpass* renderpass;
-} vulkan_framebuffer;
-
-KITC_DECL_TYPED_ARRAY(vulkan_framebuffer)
-
-typedef struct vulkan_swapchain {
- VkSurfaceFormatKHR image_format;
- u8 max_frames_in_flight;
- VkSwapchainKHR handle;
- u32 image_count;
- VkImage* images;
- VkImageView* views;
- vulkan_image depth_attachment;
- vulkan_framebuffer_darray* framebuffers;
-} vulkan_swapchain;
-
-// overengineered
-typedef enum vulkan_command_buffer_state {
- COMMAND_BUFFER_STATE_READY,
- COMMAND_BUFFER_STATE_IN_RENDER_PASS,
- COMMAND_BUFFER_STATE_RECORDING,
- COMMAND_BUFFER_STATE_RECORDING_ENDED,
- COMMAND_BUFFER_STATE_SUBMITTED,
- COMMAND_BUFFER_STATE_NOT_ALLOCATED,
-} vulkan_command_buffer_state;
-
-typedef struct vulkan_command_buffer {
- VkCommandBuffer handle;
- vulkan_command_buffer_state state;
-} vulkan_command_buffer;
-
-KITC_DECL_TYPED_ARRAY(vulkan_command_buffer)
-
-typedef struct vulkan_fence {
- VkFence handle;
- bool is_signaled;
-} vulkan_fence;
-
-typedef struct vulkan_shader_stage {
- VkShaderModuleCreateInfo create_info;
- VkShaderModule handle;
- VkPipelineShaderStageCreateInfo stage_create_info;
-} vulkan_shader_stage;
-
-typedef struct vulkan_pipeline {
- VkPipeline handle;
- VkPipelineLayout layout;
-} vulkan_pipeline;
-
-typedef struct global_object_uniform {
- mat4 projection; // 64 bytes
- mat4 view; // 64 bytes
- f32 padding[32];
-} global_object_uniform;
-
-typedef struct object_uniform {
- vec4 diffuse_colour;
- vec4 v_reserved0;
- vec4 v_reserved1;
- vec4 v_reserved2;
-} object_uniform;
-
-#define MAX_OBJECT_COUNT 1024
-#define VULKAN_OBJECT_SHADER_DESCRIPTOR_COUNT 1
-
-typedef struct geometry_render_data {
- u32 id;
- mat4 model;
- texture* textures[16];
-} geometry_render_data;
-
-typedef struct vulkan_buffer {
- u64 total_size;
- VkBuffer handle;
- VkBufferUsageFlagBits usage;
- bool is_locked;
- VkDeviceMemory memory;
- i32 memory_index;
- u32 memory_property_flags;
-} vulkan_buffer;
-
-#define SHADER_STAGE_COUNT 2
-
-typedef struct vulkan_shader {
- // vertex, fragment
- vulkan_shader_stage stages[SHADER_STAGE_COUNT];
- vulkan_pipeline pipeline;
-
- // descriptors
- VkDescriptorPool descriptor_pool;
- VkDescriptorSetLayout descriptor_set_layout;
- VkDescriptorSet descriptor_sets[3]; // one for each in-flight frame
-
- vulkan_buffer global_uniforms_buffer;
-
- // Data that's global for all objects drawn
- global_object_uniform global_ubo;
- object_uniform object_ubo;
- vulkan_texture_data* texture_data;
-} vulkan_shader;
-
-typedef struct vulkan_context {
- VkInstance instance;
- VkAllocationCallbacks* allocator;
- VkSurfaceKHR surface;
- vulkan_device device;
- u32 framebuffer_width;
- u32 framebuffer_height;
- vulkan_swapchain swapchain;
- vulkan_renderpass main_renderpass;
- vulkan_buffer object_vertex_buffer;
- vulkan_buffer object_index_buffer;
- u64 geometry_vertex_offset;
- u64 geometry_index_offset;
-
- vulkan_command_buffer_darray* gfx_command_buffers;
-
- VkSemaphore* image_available_semaphores;
- VkSemaphore* queue_complete_semaphores;
- u32 in_flight_fence_count;
- vulkan_fence* in_flight_fences;
- vulkan_fence** images_in_flight;
-
- u32 image_index;
- u32 current_frame;
-
- vulkan_shader object_shader;
-
- // TODO: swapchain recreation
-
-#if defined(DEBUG)
- VkDebugUtilsMessengerEXT vk_debugger;
-#endif
-} vulkan_context;
-
-static vulkan_context context;
-
-static i32 find_memory_index(vulkan_context* context, u32 type_filter, u32 property_flags) {
- VkPhysicalDeviceMemoryProperties memory_properties;
- vkGetPhysicalDeviceMemoryProperties(context->device.physical_device, &memory_properties);
-
- for (u32 i = 0; i < memory_properties.memoryTypeCount; ++i) {
- // Check each memory type to see if its bit is set to 1.
- if (type_filter & (1 << i) &&
- (memory_properties.memoryTypes[i].propertyFlags & property_flags) == property_flags) {
- return i;
- }
- }
-
- WARN("Unable to find suitable memory type!");
- return -1;
-}
-
-/** @brief Internal backend state */
-typedef struct vulkan_state {
-} vulkan_state;
-
-typedef struct vertex_pos {
- vec3 pos;
- vec3 normal;
-} vertex_pos;
-
-// pipeline stuff
-bool vulkan_graphics_pipeline_create(vulkan_context* context, vulkan_renderpass* renderpass,
- u32 attribute_count,
- VkVertexInputAttributeDescription* attributes,
- u32 descriptor_set_layout_count,
- VkDescriptorSetLayout* descriptor_set_layouts, u32 stage_count,
- VkPipelineShaderStageCreateInfo* stages, VkViewport viewport,
- VkRect2D scissor, bool is_wireframe,
- vulkan_pipeline* out_pipeline) {
- VkPipelineViewportStateCreateInfo viewport_state = {
- VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO
- };
- viewport_state.viewportCount = 1;
- viewport_state.pViewports = &viewport;
- viewport_state.scissorCount = 1;
- viewport_state.pScissors = &scissor;
-
- // Rasterizer
- VkPipelineRasterizationStateCreateInfo rasterizer_create_info = {
- VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO
- };
- rasterizer_create_info.depthClampEnable = VK_FALSE;
- rasterizer_create_info.rasterizerDiscardEnable = VK_FALSE;
- rasterizer_create_info.polygonMode = is_wireframe ? VK_POLYGON_MODE_LINE : VK_POLYGON_MODE_FILL;
- rasterizer_create_info.lineWidth = 1.0f;
- rasterizer_create_info.cullMode = VK_CULL_MODE_BACK_BIT;
- rasterizer_create_info.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
- rasterizer_create_info.depthBiasEnable = VK_FALSE;
- rasterizer_create_info.depthBiasConstantFactor = 0.0;
- rasterizer_create_info.depthBiasClamp = 0.0;
- rasterizer_create_info.depthBiasSlopeFactor = 0.0;
-
- // Multisampling
- VkPipelineMultisampleStateCreateInfo ms_create_info = {
- VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO
- };
- ms_create_info.sampleShadingEnable = VK_FALSE;
- ms_create_info.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
- ms_create_info.minSampleShading = 1.0;
- ms_create_info.pSampleMask = 0;
- ms_create_info.alphaToCoverageEnable = VK_FALSE;
- ms_create_info.alphaToOneEnable = VK_FALSE;
-
- // Depth and stencil testing
- VkPipelineDepthStencilStateCreateInfo depth_stencil = {
- VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO
- };
- depth_stencil.depthTestEnable = VK_TRUE;
- depth_stencil.depthWriteEnable = VK_TRUE;
- depth_stencil.depthCompareOp = VK_COMPARE_OP_LESS;
- depth_stencil.depthBoundsTestEnable = VK_FALSE;
- depth_stencil.stencilTestEnable = VK_FALSE;
- depth_stencil.pNext = 0;
-
- VkPipelineColorBlendAttachmentState color_blend_attachment_state;
- color_blend_attachment_state.blendEnable = VK_TRUE;
- color_blend_attachment_state.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
- color_blend_attachment_state.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
- color_blend_attachment_state.colorBlendOp = VK_BLEND_OP_ADD;
- color_blend_attachment_state.srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
- color_blend_attachment_state.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
- color_blend_attachment_state.alphaBlendOp = VK_BLEND_OP_ADD;
- color_blend_attachment_state.colorWriteMask = VK_COLOR_COMPONENT_R_BIT |
- VK_COLOR_COMPONENT_G_BIT |
- VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
-
- VkPipelineColorBlendStateCreateInfo color_blend = {
- VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO
- };
- color_blend.logicOpEnable = VK_FALSE;
- color_blend.logicOp = VK_LOGIC_OP_COPY;
- color_blend.attachmentCount = 1;
- color_blend.pAttachments = &color_blend_attachment_state;
-
- const u32 dynamic_state_count = 3;
- VkDynamicState dynamic_states[3] = {
- VK_DYNAMIC_STATE_VIEWPORT,
- VK_DYNAMIC_STATE_SCISSOR,
- VK_DYNAMIC_STATE_LINE_WIDTH,
- };
-
- VkPipelineDynamicStateCreateInfo dynamic_state = {
- VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO
- };
- dynamic_state.dynamicStateCount = dynamic_state_count;
- dynamic_state.pDynamicStates = dynamic_states;
-
- // Vertex input
- VkVertexInputBindingDescription binding_desc;
- binding_desc.binding = 0;
- binding_desc.stride = sizeof(vertex);
- binding_desc.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
-
- VkPipelineVertexInputStateCreateInfo vertex_input_info = {
- VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO
- };
- vertex_input_info.vertexBindingDescriptionCount = 1;
- vertex_input_info.pVertexBindingDescriptions = &binding_desc;
- vertex_input_info.vertexAttributeDescriptionCount = attribute_count;
- vertex_input_info.pVertexAttributeDescriptions = attributes;
-
- VkPipelineInputAssemblyStateCreateInfo input_assembly = {
- VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO
- };
- input_assembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
- input_assembly.primitiveRestartEnable = VK_FALSE;
-
- VkPipelineLayoutCreateInfo pipeline_layout_create_info = {
- VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO
- };
-
- // Pushconstants
- VkPushConstantRange push_constant;
- push_constant.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
- push_constant.offset = sizeof(mat4) * 0;
- push_constant.size = sizeof(mat4) * 2;
-
- pipeline_layout_create_info.pushConstantRangeCount = 1;
- pipeline_layout_create_info.pPushConstantRanges = &push_constant;
-
- pipeline_layout_create_info.setLayoutCount = descriptor_set_layout_count;
- pipeline_layout_create_info.pSetLayouts = descriptor_set_layouts;
-
- vkCreatePipelineLayout(context->device.logical_device, &pipeline_layout_create_info,
- context->allocator, &out_pipeline->layout);
-
- VkGraphicsPipelineCreateInfo pipeline_create_info = {
- VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO
- };
- pipeline_create_info.stageCount = stage_count;
- pipeline_create_info.pStages = stages;
- pipeline_create_info.pVertexInputState = &vertex_input_info;
- pipeline_create_info.pInputAssemblyState = &input_assembly;
-
- pipeline_create_info.pViewportState = &viewport_state;
- pipeline_create_info.pRasterizationState = &rasterizer_create_info;
- pipeline_create_info.pMultisampleState = &ms_create_info;
- pipeline_create_info.pDepthStencilState = &depth_stencil;
- pipeline_create_info.pColorBlendState = &color_blend;
- pipeline_create_info.pDynamicState = &dynamic_state;
- pipeline_create_info.pTessellationState = 0;
-
- pipeline_create_info.layout = out_pipeline->layout;
-
- pipeline_create_info.renderPass = renderpass->handle;
- pipeline_create_info.subpass = 0;
- pipeline_create_info.basePipelineHandle = VK_NULL_HANDLE;
- pipeline_create_info.basePipelineIndex = -1;
-
- VkResult result =
- vkCreateGraphicsPipelines(context->device.logical_device, VK_NULL_HANDLE, 1,
- &pipeline_create_info, context->allocator, &out_pipeline->handle);
- if (result != VK_SUCCESS) {
- FATAL("graphics pipeline creation failed. its fked mate");
- ERROR_EXIT("Doomed");
- }
-
- return true;
-}
-
-void vulkan_pipeline_bind(vulkan_command_buffer* command_buffer, VkPipelineBindPoint bind_point,
- vulkan_pipeline* pipeline) {
- vkCmdBindPipeline(command_buffer->handle, bind_point, pipeline->handle);
-}
-
-void vulkan_buffer_bind(vulkan_context* context, vulkan_buffer* buffer, u64 offset) {
- vkBindBufferMemory(context->device.logical_device, buffer->handle, buffer->memory, offset);
-}
-
-bool vulkan_buffer_create(vulkan_context* context, u64 size, VkBufferUsageFlagBits usage,
- u32 memory_property_flags, bool bind_on_create,
- vulkan_buffer* out_buffer) {
- memset(out_buffer, 0, sizeof(vulkan_buffer));
- out_buffer->total_size = size;
- out_buffer->usage = usage;
- out_buffer->memory_property_flags = memory_property_flags;
-
- VkBufferCreateInfo buffer_info = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
- buffer_info.size = size;
- buffer_info.usage = usage;
- buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
-
- vkCreateBuffer(context->device.logical_device, &buffer_info, context->allocator,
- &out_buffer->handle);
-
- VkMemoryRequirements requirements;
- vkGetBufferMemoryRequirements(context->device.logical_device, out_buffer->handle, &requirements);
- out_buffer->memory_index =
- find_memory_index(context, requirements.memoryTypeBits, out_buffer->memory_property_flags);
-
- // Allocate
- VkMemoryAllocateInfo allocate_info = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
- allocate_info.allocationSize = requirements.size;
- allocate_info.memoryTypeIndex = (u32)out_buffer->memory_index;
-
- vkAllocateMemory(context->device.logical_device, &allocate_info, context->allocator,
- &out_buffer->memory);
-
- if (bind_on_create) {
- vulkan_buffer_bind(context, out_buffer, 0);
- }
-
- DEBUG("Created buffer.");
-
- return true;
-}
-
-// lock and unlock?
-
-void* vulkan_buffer_lock_memory(vulkan_context* context, vulkan_buffer* buffer, u64 offset,
- u64 size, u32 flags) {
- void* data;
- vkMapMemory(context->device.logical_device, buffer->memory, offset, size, flags, &data);
- return data;
-}
-void* vulkan_buffer_unlock_memory(vulkan_context* context, vulkan_buffer* buffer) {
- vkUnmapMemory(context->device.logical_device, buffer->memory);
-}
-
-void vulkan_buffer_load_data(vulkan_context* context, vulkan_buffer* buffer, u64 offset, u64 size,
- u32 flags, const void* data) {
- void* data_ptr = 0;
- VK_CHECK(
- vkMapMemory(context->device.logical_device, buffer->memory, offset, size, flags, &data_ptr));
- memcpy(data_ptr, data, size);
- vkUnmapMemory(context->device.logical_device, buffer->memory);
-}
-
-// TODO: destroy
-
-bool create_shader_module(vulkan_context* context, const char* filename, const char* type_str,
- VkShaderStageFlagBits flag, u32 stage_index,
- vulkan_shader_stage* shader_stages) {
- memset(&shader_stages[stage_index].create_info, 0, sizeof(VkShaderModuleCreateInfo));
- memset(&shader_stages[stage_index].stage_create_info, 0, sizeof(VkPipelineShaderStageCreateInfo));
-
- shader_stages[stage_index].create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
-
- // todo: file input
- FileData file_contents = load_spv_file(filename);
-
- shader_stages[stage_index].create_info.codeSize = file_contents.size;
- shader_stages[stage_index].create_info.pCode = (u32*)file_contents.data;
-
- vkCreateShaderModule(context->device.logical_device, &shader_stages[stage_index].create_info,
- context->allocator, &shader_stages[stage_index].handle);
-
- shader_stages[stage_index].stage_create_info.sType =
- VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
- shader_stages[stage_index].stage_create_info.stage = flag;
- shader_stages[stage_index].stage_create_info.module = shader_stages[stage_index].handle;
- shader_stages[stage_index].stage_create_info.pName = "main";
-
- free(file_contents.data);
-
- // TODO: Descriptors
-
- return true;
-}
-
-bool vulkan_object_shader_create(vulkan_context* context, vulkan_shader* out_shader) {
- char stage_type_strs[SHADER_STAGE_COUNT][5] = { "vert", "frag" };
- char stage_filenames[SHADER_STAGE_COUNT][256] = { "build/linux/x86_64/debug/object.vert.spv",
- "build/linux/x86_64/debug/object.frag.spv" };
- VkShaderStageFlagBits stage_types[SHADER_STAGE_COUNT] = { VK_SHADER_STAGE_VERTEX_BIT,
- VK_SHADER_STAGE_FRAGMENT_BIT };
- for (u8 i = 0; i < SHADER_STAGE_COUNT; i++) {
- DEBUG("Loading %s", stage_filenames[i]);
- create_shader_module(context, stage_filenames[i], stage_type_strs[i], stage_types[i], i,
- out_shader->stages);
- }
-
- // descriptors
- VkDescriptorSetLayoutBinding global_ubo_layout_binding;
- global_ubo_layout_binding.binding = 0;
- global_ubo_layout_binding.descriptorCount = 1;
- global_ubo_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
- global_ubo_layout_binding.pImmutableSamplers = 0;
- global_ubo_layout_binding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
-
- VkDescriptorSetLayoutBinding sampler_layout_binding;
- sampler_layout_binding.binding = 1;
- sampler_layout_binding.descriptorCount = 1;
- sampler_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
- sampler_layout_binding.pImmutableSamplers = 0;
- sampler_layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
-
- VkDescriptorSetLayoutCreateInfo global_layout_info = {
- VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO
- };
-
- VkDescriptorSetLayoutBinding bindings[2] = { global_ubo_layout_binding, sampler_layout_binding };
-
- global_layout_info.bindingCount = 2;
- global_layout_info.pBindings = bindings;
-
- VK_CHECK(vkCreateDescriptorSetLayout(context->device.logical_device, &global_layout_info,
- context->allocator, &out_shader->descriptor_set_layout));
-
- VkDescriptorPoolSize global_pool_size;
- global_pool_size.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
- global_pool_size.descriptorCount = 3;
-
- VkDescriptorPoolSize sampler_pool_size;
- sampler_pool_size.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
- sampler_pool_size.descriptorCount = 3;
-
- VkDescriptorPoolSize pool_sizes[2] = { global_pool_size, sampler_pool_size };
-
- VkDescriptorPoolCreateInfo pool_info = { VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO };
- pool_info.poolSizeCount = 2;
- pool_info.pPoolSizes = pool_sizes;
- pool_info.maxSets = 3;
-
- VK_CHECK(vkCreateDescriptorPool(context->device.logical_device, &pool_info, context->allocator,
- &out_shader->descriptor_pool));
-
- // Pipeline creation
- VkViewport viewport;
- viewport.x = 0;
- viewport.y = 0;
- 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;
-
- // Attributes
- u32 offset = 0;
- const i32 attribute_count = 3;
- VkVertexInputAttributeDescription attribute_descs[3];
- // Position
- VkFormat formats[3] = { VK_FORMAT_R32G32B32_SFLOAT, VK_FORMAT_R32G32B32_SFLOAT,
- VK_FORMAT_R32G32_SFLOAT };
-
- u64 sizes[3] = { sizeof(vec3), sizeof(vec3), sizeof(vec2) };
-
- for (u32 i = 0; i < attribute_count; i++) {
- attribute_descs[i].binding = 0;
- attribute_descs[i].location = i;
- attribute_descs[i].format = formats[i];
- attribute_descs[i].offset = offset;
- offset += sizes[i];
- }
-
- // Descriptor set layouts
- VkDescriptorSetLayout layouts[1] = { out_shader->descriptor_set_layout };
-
- // Stages
- VkPipelineShaderStageCreateInfo stage_create_infos[SHADER_STAGE_COUNT];
- memset(stage_create_infos, 0, sizeof(stage_create_infos));
- for (u32 i = 0; i < SHADER_STAGE_COUNT; i++) {
- stage_create_infos[i].sType = out_shader->stages[i].stage_create_info.sType;
- stage_create_infos[i] = out_shader->stages[i].stage_create_info;
- }
-
- vulkan_graphics_pipeline_create(
- context, &context->main_renderpass, attribute_count, attribute_descs, 1, layouts,
- SHADER_STAGE_COUNT, stage_create_infos, viewport, scissor, false, &out_shader->pipeline);
- INFO("Graphics pipeline created!");
-
- // Uniform buffer
- if (!vulkan_buffer_create(context, sizeof(global_object_uniform),
- VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
- VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
- VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
- VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
- true, &out_shader->global_uniforms_buffer)) {
- ERROR("Couldnt create uniforms buffer");
- return false;
- }
-
- VkDescriptorSetLayout global_layouts[3] = {
- out_shader->descriptor_set_layout,
- out_shader->descriptor_set_layout,
- out_shader->descriptor_set_layout,
- };
-
- VkDescriptorSetAllocateInfo alloc_info = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO };
- alloc_info.descriptorPool = out_shader->descriptor_pool;
- alloc_info.descriptorSetCount = 3;
- alloc_info.pSetLayouts = global_layouts;
- VK_CHECK(vkAllocateDescriptorSets(context->device.logical_device, &alloc_info,
- out_shader->descriptor_sets));
-
- return true;
-}
-void vulkan_object_shader_destroy(vulkan_context* context, vulkan_shader* shader) {}
-void vulkan_object_shader_use(vulkan_context* context, vulkan_shader* shader) {
- u32 image_index = context->image_index;
- vulkan_pipeline_bind(&context->gfx_command_buffers->data[image_index],
- VK_PIPELINE_BIND_POINT_GRAPHICS, &shader->pipeline);
-}
-void vulkan_object_shader_update_global_state(vulkan_context* context, vulkan_shader* shader) {
- u32 image_index = context->image_index;
- VkCommandBuffer cmd_buffer = context->gfx_command_buffers->data[image_index].handle;
- VkDescriptorSet global_descriptors = shader->descriptor_sets[image_index];
-
- u32 range = sizeof(global_object_uniform);
- u64 offset = 0;
-
- // copy data to buffer
- vulkan_buffer_load_data(context, &shader->global_uniforms_buffer, offset, range, 0,
- &shader->global_ubo);
-
- VkDescriptorBufferInfo buffer_info;
- buffer_info.buffer = shader->global_uniforms_buffer.handle;
- buffer_info.offset = offset;
- buffer_info.range = range;
-
- VkDescriptorImageInfo image_info;
- image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
- image_info.imageView = shader->texture_data->image.view;
- image_info.sampler = shader->texture_data->sampler;
-
- VkWriteDescriptorSet uniform_write = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET };
- uniform_write.dstSet = shader->descriptor_sets[image_index];
- uniform_write.dstBinding = 0;
- uniform_write.dstArrayElement = 0;
- uniform_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
- uniform_write.descriptorCount = 1;
- uniform_write.pBufferInfo = &buffer_info;
-
- VkWriteDescriptorSet texture_write = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET };
- texture_write.dstSet = shader->descriptor_sets[image_index];
- texture_write.dstBinding = 1;
- texture_write.dstArrayElement = 0;
- texture_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
- texture_write.descriptorCount = 1;
- texture_write.pImageInfo = &image_info;
-
- VkWriteDescriptorSet writes[2] = { uniform_write, texture_write };
-
- vkUpdateDescriptorSets(context->device.logical_device, 2, writes, 0, 0);
-
- vkCmdBindDescriptorSets(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, shader->pipeline.layout, 0,
- 1, &global_descriptors, 0, 0);
-}
-
-void vulkan_object_shader_update_object(vulkan_context* context, vulkan_shader* shader,
- mat4 model) {
- u32 image_index = context->image_index;
- VkCommandBuffer cmd_buffer = context->gfx_command_buffers->data[image_index].handle;
- // vulkan_command_buffer* cmd_buffer = &context->gfx_command_buffers->data[context.image_index];
-
- vkCmdPushConstants(cmd_buffer, shader->pipeline.layout, VK_SHADER_STAGE_VERTEX_BIT, 0,
- sizeof(mat4), &model);
-
- // vulkan_object_shader_use(context, &context->object_shader);
- VkDeviceSize offsets[1] = { 0 };
- vkCmdBindVertexBuffers(cmd_buffer, 0, 1, &context->object_vertex_buffer.handle,
- (VkDeviceSize*)offsets);
-
- vkCmdBindIndexBuffer(cmd_buffer, context->object_index_buffer.handle, 0, VK_INDEX_TYPE_UINT32);
-
- vkCmdDrawIndexed(cmd_buffer, 36, 1, 0, 0, 0);
- // vkCmdDraw(cmd_buffer, 36, 1, 0, 0);
-}
-
-bool select_physical_device(vulkan_context* ctx) {
- u32 physical_device_count = 0;
- VK_CHECK(vkEnumeratePhysicalDevices(ctx->instance, &physical_device_count, 0));
- if (physical_device_count == 0) {
- FATAL("No devices that support vulkan were found");
- return false;
- }
- TRACE("Number of devices found %d", physical_device_count);
-
- VkPhysicalDevice physical_devices[physical_device_count];
- VK_CHECK(vkEnumeratePhysicalDevices(ctx->instance, &physical_device_count, physical_devices));
-
- for (u32 i = 0; i < physical_device_count; i++) {
- VkPhysicalDeviceProperties properties;
- vkGetPhysicalDeviceProperties(physical_devices[i], &properties);
-
- VkPhysicalDeviceFeatures features;
- vkGetPhysicalDeviceFeatures(physical_devices[i], &features);
-
- VkPhysicalDeviceMemoryProperties memory;
- vkGetPhysicalDeviceMemoryProperties(physical_devices[i], &memory);
-
- vulkan_physical_device_requirements requirements = {};
- requirements.graphics = true;
- requirements.present = true;
- requirements.compute = true;
- requirements.transfer = true;
-
- requirements.sampler_anistropy = true;
- requirements.discrete_gpu = true;
- requirements.device_ext_names[0] = str8lit(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
- requirements.device_ext_name_count = 1;
-
- vulkan_physical_device_queue_family_info queue_info = {};
-
- bool result = physical_device_meets_requirements(physical_devices[i], ctx->surface, &properties,
- &features, &requirements, &queue_info,
- &ctx->device.swapchain_support);
-
- if (result) {
- INFO("GPU Driver version: %d.%d.%d", VK_VERSION_MAJOR(properties.driverVersion),
- VK_VERSION_MINOR(properties.driverVersion), VK_VERSION_PATCH(properties.driverVersion));
-
- INFO("Vulkan API version: %d.%d.%d", VK_VERSION_MAJOR(properties.apiVersion),
- VK_VERSION_MINOR(properties.apiVersion), VK_VERSION_PATCH(properties.apiVersion));
-
- // TODO: print gpu memory information -
- // https://youtu.be/6Kj3O2Ov1RU?si=pXfP5NvXXcXjJsrG&t=2439
-
- ctx->device.physical_device = physical_devices[i];
- ctx->device.graphics_queue_index = queue_info.graphics_family_index;
- ctx->device.present_queue_index = queue_info.present_family_index;
- ctx->device.compute_queue_index = queue_info.compute_family_index;
- ctx->device.transfer_queue_index = queue_info.transfer_family_index;
- ctx->device.properties = properties;
- ctx->device.features = features;
- ctx->device.memory = memory;
- break;
- }
- }
-
- if (!ctx->device.physical_device) {
- ERROR("No suitable physical devices were found :(");
- return false;
- }
-
- INFO("Physical device selected: %s\n", ctx->device.properties.deviceName);
- return true;
-}
-
-bool vulkan_device_create(vulkan_context* context) {
- // Physical device - NOTE: mutates the context directly
- if (!select_physical_device(context)) {
- return false;
- }
-
-// Logical device - NOTE: mutates the context directly
-
-// queues
-#define VULKAN_QUEUES_COUNT 2
- const char* queue_names[VULKAN_QUEUES_COUNT] = {
- "GRAPHICS",
- "TRANSFER",
- };
- i32 indices[VULKAN_QUEUES_COUNT] = {
- context->device.graphics_queue_index,
- context->device.transfer_queue_index,
- };
- f32 prio_one = 1.0;
- VkDeviceQueueCreateInfo queue_create_info[2]; // HACK: make 2 queues, graphics and transfer
- // graphics
- queue_create_info[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
- queue_create_info[0].queueFamilyIndex = 0;
- queue_create_info[0].queueCount = 1;
- queue_create_info[0].flags = 0;
- queue_create_info[0].pNext = 0;
- queue_create_info[0].pQueuePriorities = &prio_one;
- // transfer
- queue_create_info[1].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
- queue_create_info[1].queueFamilyIndex = 1;
- queue_create_info[1].queueCount = 1;
- queue_create_info[1].flags = 0;
- queue_create_info[1].pNext = 0;
- queue_create_info[1].pQueuePriorities = &prio_one;
-
- // for (int i = 0; i < 2; i++) {
- // TRACE("Configure %s queue", queue_names[i]);
- // queue_create_info[i].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
- // queue_create_info[i].queueFamilyIndex = indices[i];
- // queue_create_info[i].queueCount = 1; // make just one of them
- // queue_create_info[i].flags = 0;
- // queue_create_info[i].pNext = 0;
- // f32 priority = 1.0;
- // queue_create_info[i].pQueuePriorities = &priority;
- // }
-
- // features
- VkPhysicalDeviceFeatures device_features = {};
- device_features.samplerAnisotropy = VK_TRUE; // request anistrophy
-
- // device itself
- VkDeviceCreateInfo device_create_info = { VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO };
- device_create_info.queueCreateInfoCount = VULKAN_QUEUES_COUNT;
- device_create_info.pQueueCreateInfos = queue_create_info;
- device_create_info.pEnabledFeatures = &device_features;
- device_create_info.enabledExtensionCount = 1;
- const char* extension_names = VK_KHR_SWAPCHAIN_EXTENSION_NAME;
- device_create_info.ppEnabledExtensionNames = &extension_names;
-
- // deprecated
- device_create_info.enabledLayerCount = 0;
- device_create_info.ppEnabledLayerNames = 0;
-
- VkResult result = vkCreateDevice(context->device.physical_device, &device_create_info,
- context->allocator, &context->device.logical_device);
- if (result != VK_SUCCESS) {
- printf("error creating logical device with status %u\n", result);
- ERROR_EXIT("Bye bye");
- }
- INFO("Logical device created");
-
- // get queues
- vkGetDeviceQueue(context->device.logical_device, context->device.graphics_queue_index, 0,
- &context->device.graphics_queue);
- // vkGetDeviceQueue(context->device.logical_device, context->device.present_queue_index, 0,
- // &context->device.present_queue);
- // vkGetDeviceQueue(context->device.logical_device, context->device.compute_queue_index, 0,
- // &context->device.compute_queue);
- vkGetDeviceQueue(context->device.logical_device, context->device.transfer_queue_index, 0,
- &context->device.transfer_queue);
-
- // create command pool for graphics queue
- VkCommandPoolCreateInfo pool_create_info = { VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO };
- pool_create_info.queueFamilyIndex = context->device.graphics_queue_index;
- pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
- vkCreateCommandPool(context->device.logical_device, &pool_create_info, context->allocator,
- &context->device.gfx_command_pool);
- INFO("Created Command Pool")
-
- return true;
-}
-void vulkan_device_destroy(vulkan_context* context) {
- context->device.physical_device = 0; // release
- // TODO: reset other memory
-}
-
-bool vulkan_device_detect_depth_format(vulkan_device* device) {
- const size_t n_candidates = 3;
- VkFormat candidates[3] = { VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT,
- VK_FORMAT_D24_UNORM_S8_UINT };
- u32 flags = VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT;
- for (u64 i = 0; i < n_candidates; i++) {
- VkFormatProperties properties;
- vkGetPhysicalDeviceFormatProperties(device->physical_device, candidates[i], &properties);
-
- if ((properties.linearTilingFeatures & flags) == flags) {
- device->depth_format = candidates[i];
- return true;
- }
- if ((properties.optimalTilingFeatures & flags) == flags) {
- device->depth_format = candidates[i];
- return true;
- }
- }
- return false;
-}
-
-void vulkan_image_view_create(vulkan_context* context, VkFormat format, vulkan_image* image,
- VkImageAspectFlags aspect_flags) {
- VkImageViewCreateInfo view_create_info = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO };
- view_create_info.image = image->handle;
- view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
- view_create_info.format = format;
- view_create_info.subresourceRange.aspectMask = aspect_flags;
-
- view_create_info.subresourceRange.baseMipLevel = 0;
- view_create_info.subresourceRange.levelCount = 1;
- view_create_info.subresourceRange.baseArrayLayer = 0;
- view_create_info.subresourceRange.layerCount = 1;
-
- vkCreateImageView(context->device.logical_device, &view_create_info, context->allocator,
- &image->view);
-}
-
-void vulkan_image_transition_layout(vulkan_context* context, vulkan_command_buffer* command_buffer,
- vulkan_image* image, VkFormat format, VkImageLayout old_layout,
- VkImageLayout new_layout) {
- VkImageMemoryBarrier barrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER };
- void vulkan_image_transition_layout(
- vulkan_context * context, vulkan_command_buffer * command_buffer, vulkan_image * image,
- VkFormat format, VkImageLayout old_layout, VkImageLayout new_layout) {
- VkImageMemoryBarrier barrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER };
- barrier.oldLayout = old_layout;
- barrier.newLayout = new_layout;
- barrier.srcQueueFamilyIndex = context->device.graphics_queue_index;
- barrier.dstQueueFamilyIndex = context->device.graphics_queue_index;
- barrier.image = image->handle;
- barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
- barrier.subresourceRange.baseMipLevel = 0;
- barrier.subresourceRange.levelCount = 1;
- barrier.subresourceRange.baseArrayLayer = 0;
- barrier.subresourceRange.layerCount = 1;
- barrier.srcAccessMask = 0;
- barrier.dstAccessMask = 0;
-
- VkPipelineStageFlags source_stage;
- VkPipelineStageFlags dest_stage;
-
- if (old_layout == VK_IMAGE_LAYOUT_UNDEFINED &&
- new_layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
- barrier.srcAccessMask = 0;
- barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
-
- source_stage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
- dest_stage = VK_PIPELINE_STAGE_TRANSFER_BIT;
-
- } else if (old_layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL &&
- new_layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
- barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
- barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
- source_stage = VK_PIPELINE_STAGE_TRANSFER_BIT;
- dest_stage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
- } else {
- FATAL("Unsupported image layout transition");
- return;
- }
-
- vkCmdPipelineBarrier(command_buffer->handle, source_stage, dest_stage, 0, 0, 0, 0, 0, 1,
- &barrier);
- }
-
- void vulkan_image_copy_from_buffer(vulkan_image * image, VkBuffer buffer,
- vulkan_command_buffer * command_buffer) {
- VkBufferImageCopy region;
- region.bufferOffset = 0;
- region.bufferRowLength = 0;
- region.bufferImageHeight = 0;
- region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
- region.imageSubresource.mipLevel = 0;
- region.imageSubresource.baseArrayLayer = 0;
- region.imageSubresource.layerCount = 1;
- printf("Image details width: %d height %d\n", image->width, image->height);
- region.imageOffset.x = 0;
- region.imageOffset.y = 0;
- region.imageOffset.z = 0;
- region.imageExtent.width = image->width;
- region.imageExtent.height = image->height;
- region.imageExtent.depth = 1;
-
- vkCmdCopyBufferToImage(command_buffer->handle, buffer, image->handle,
- VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
- }
-
- void vulkan_image_create(vulkan_context * context, VkImageType image_type, u32 width, u32 height,
- VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage,
- VkMemoryPropertyFlags memory_flags, bool create_view,
- VkImageAspectFlags aspect_flags, vulkan_image* out_image) {
- // copy params
- out_image->width = width;
- out_image->height = height;
-
- // create info
- VkImageCreateInfo image_create_info = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };
- image_create_info.imageType = image_type;
- image_create_info.extent.width = width;
- image_create_info.extent.height = height;
- image_create_info.extent.depth = 1;
- image_create_info.mipLevels = 1;
- image_create_info.arrayLayers = 1;
- image_create_info.format = format;
- image_create_info.tiling = tiling;
- image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
- image_create_info.usage = usage;
- image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
- image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
-
- VK_CHECK(vkCreateImage(context->device.logical_device, &image_create_info, context->allocator,
- &out_image->handle));
-
- VkMemoryRequirements memory_reqs;
- vkGetImageMemoryRequirements(context->device.logical_device, out_image->handle, &memory_reqs);
-
- i32 memory_type = -1;
- VkPhysicalDeviceMemoryProperties memory_properties;
- vkGetPhysicalDeviceMemoryProperties(context->device.physical_device, &memory_properties);
-
- for (u32 i = 0; i < memory_properties.memoryTypeCount; i++) {
- // typefilter = memoryTypeBits , prop filter = memory_flags
- if (memory_reqs.memoryTypeBits & (1 << i) &&
- (memory_properties.memoryTypes[i].propertyFlags & memory_flags)) {
- memory_type = i;
- break;
- }
- }
-
- if (memory_type < 0) {
- ERROR_EXIT("couldnt find a suitable memory type for the image");
- }
-
- // allocate memory
- VkMemoryAllocateInfo memory_allocate_info = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
- memory_allocate_info.allocationSize = memory_reqs.size;
- memory_allocate_info.memoryTypeIndex = memory_type;
- vkAllocateMemory(context->device.logical_device, &memory_allocate_info, context->allocator,
- &out_image->memory);
-
- // bind memory
- // TODO: maybe bind context->device.logical_device to device at the top of the functions?
- vkBindImageMemory(context->device.logical_device, out_image->handle, out_image->memory, 0);
-
- if (create_view) {
- out_image->view = 0;
- vulkan_image_view_create(context, format, out_image, aspect_flags);
- }
- }
-
- // TODO: vulkan_image_destroy
-
- void vulkan_framebuffer_create(vulkan_context * context, vulkan_renderpass * renderpass,
- u32 width, u32 height, u32 attachment_count,
- VkImageView * attachments, vulkan_framebuffer * out_framebuffer) {
- out_framebuffer->attachments = malloc(sizeof(VkImageView) * attachment_count);
- for (u32 i = 0; i < attachment_count; i++) {
- out_framebuffer->attachments[i] = attachments[i];
- }
- out_framebuffer->attachment_count = attachment_count;
- out_framebuffer->renderpass = renderpass;
-
- VkFramebufferCreateInfo framebuffer_create_info = {
- VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO
- }; // TODO
-
- framebuffer_create_info.renderPass = renderpass->handle;
- framebuffer_create_info.attachmentCount = attachment_count;
- framebuffer_create_info.pAttachments = out_framebuffer->attachments;
- framebuffer_create_info.width = width;
- framebuffer_create_info.height = height;
- framebuffer_create_info.layers = 1;
-
- vkCreateFramebuffer(context->device.logical_device, &framebuffer_create_info,
- context->allocator, &out_framebuffer->handle);
- }
-
- // TODO: vulkan_framebuffer_destroy
-
- void vulkan_command_buffer_allocate(vulkan_context * context, VkCommandPool pool, bool is_primary,
- vulkan_command_buffer* out_command_buffer) {
- VkCommandBufferAllocateInfo allocate_info = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO };
- allocate_info.commandPool = pool;
- allocate_info.level =
- is_primary ? VK_COMMAND_BUFFER_LEVEL_PRIMARY : VK_COMMAND_BUFFER_LEVEL_SECONDARY;
- allocate_info.commandBufferCount = 1;
- allocate_info.pNext = 0;
-
- out_command_buffer->state = COMMAND_BUFFER_STATE_NOT_ALLOCATED;
- vkAllocateCommandBuffers(context->device.logical_device, &allocate_info,
- &out_command_buffer->handle);
- out_command_buffer->state = COMMAND_BUFFER_STATE_READY;
- }
-
- void vulkan_command_buffer_free(vulkan_context * context, VkCommandPool pool,
- vulkan_command_buffer * out_command_buffer) {
- // TODO: implement freeing
- }
-
- void vulkan_command_buffer_begin(vulkan_command_buffer * command_buffer, bool is_single_use,
- bool is_renderpass_continue, bool is_simultaneous_use) {
- VkCommandBufferBeginInfo begin_info = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO };
- begin_info.flags = 0;
- if (is_single_use) {
- begin_info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
- }
- // TODO: RENDER_PASS_CONTINUE_BIT & SIMULTANEOUS_USE_BIT
-
- begin_info.pNext = 0;
- begin_info.pInheritanceInfo = 0;
- vkBeginCommandBuffer(command_buffer->handle, &begin_info);
-
- command_buffer->state = COMMAND_BUFFER_STATE_RECORDING;
- }
-
- void vulkan_command_buffer_end(vulkan_command_buffer * command_buffer) {
- VK_CHECK(vkEndCommandBuffer(command_buffer->handle));
- command_buffer->state = COMMAND_BUFFER_STATE_RECORDING_ENDED;
- }
- void vulkan_command_buffer_update_submitted(vulkan_command_buffer * command_buffer) {
- command_buffer->state = COMMAND_BUFFER_STATE_SUBMITTED;
- }
- void vulkan_command_buffer_reset(vulkan_command_buffer * command_buffer) {
- command_buffer->state = COMMAND_BUFFER_STATE_READY;
- }
-
- void vulkan_command_buffer_allocate_and_begin_oneshot(
- vulkan_context * context, VkCommandPool pool, vulkan_command_buffer * out_command_buffer) {
- vulkan_command_buffer_allocate(context, pool, true, out_command_buffer);
- vulkan_command_buffer_begin(out_command_buffer, true, false, false);
- }
-
- void vulkan_command_buffer_end_oneshot(vulkan_context * context, VkCommandPool pool,
- vulkan_command_buffer * command_buffer, VkQueue queue) {
- vulkan_command_buffer_end(command_buffer);
-
- // submit to queue
- VkSubmitInfo submit_info = { VK_STRUCTURE_TYPE_SUBMIT_INFO };
- submit_info.commandBufferCount = 1;
- submit_info.pCommandBuffers = &command_buffer->handle;
- VK_CHECK(vkQueueSubmit(queue, 1, &submit_info, 0));
- // wait for it to finish
- VK_CHECK(vkQueueWaitIdle(queue));
-
- vulkan_command_buffer_free(context, pool, command_buffer);
- }
-
- void vulkan_buffer_copy_to(vulkan_context * context, VkCommandPool pool, VkFence fence,
- VkQueue queue, VkBuffer source, u64 source_offset, VkBuffer dest,
- u64 dest_offset, u64 size) {
- vkQueueWaitIdle(queue);
-
- vulkan_command_buffer temp_cmd_buf;
- vulkan_command_buffer_allocate_and_begin_oneshot(context, pool, &temp_cmd_buf);
-
- VkBufferCopy copy_region;
- copy_region.srcOffset = source_offset;
- copy_region.dstOffset = dest_offset;
- copy_region.size = size;
-
- vkCmdCopyBuffer(temp_cmd_buf.handle, source, dest, 1, &copy_region);
-
- vulkan_command_buffer_end_oneshot(context, pool, &temp_cmd_buf, queue);
- }
-
- void vulkan_swapchain_create(vulkan_context * context, u32 width, u32 height,
- vulkan_swapchain * out_swapchain) {
- VkExtent2D swapchain_extent = { width, height };
- out_swapchain->max_frames_in_flight = 2; // support triple buffering
-
- // find a format
- bool found;
- for (u32 i = 0; i < context->device.swapchain_support.format_count; i++) {
- VkSurfaceFormatKHR format = context->device.swapchain_support.formats[i];
- if (format.format == VK_FORMAT_B8G8R8A8_UNORM &&
- format.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
- out_swapchain->image_format = format;
- found = true;
- break;
- }
- }
- if (!found) {
- out_swapchain->image_format = context->device.swapchain_support.formats[0];
- }
-
- VkPresentModeKHR present_mode = VK_PRESENT_MODE_FIFO_KHR; // guaranteed to be implemented
- // TODO: look for mailbox - https://youtu.be/jWKVb_QdSNM?si=bHcd3sEf-M0x3QwH&t=1687
-
- // TODO: requery swapchain support
-
- u32 image_count = context->device.swapchain_support.capabilities.minImageCount;
-
- VkSwapchainCreateInfoKHR swapchain_create_info = {
- VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR
- };
- swapchain_create_info.surface = context->surface;
- swapchain_create_info.minImageCount = image_count;
- swapchain_create_info.imageFormat = out_swapchain->image_format.format;
- swapchain_create_info.imageColorSpace = out_swapchain->image_format.colorSpace;
- DEBUG("Image extent %d %d\n", swapchain_extent.width, swapchain_extent.height);
- swapchain_create_info.imageExtent = swapchain_extent;
- swapchain_create_info.imageArrayLayers = 1;
- swapchain_create_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
- swapchain_create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
- swapchain_create_info.queueFamilyIndexCount = 0;
- swapchain_create_info.pQueueFamilyIndices = 0;
-
- swapchain_create_info.preTransform =
- context->device.swapchain_support.capabilities.currentTransform;
- swapchain_create_info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
- swapchain_create_info.presentMode = present_mode;
- swapchain_create_info.clipped = VK_TRUE;
- swapchain_create_info.oldSwapchain = 0;
-
- TRACE("Create swapchain");
- VK_CHECK(vkCreateSwapchainKHR(context->device.logical_device, &swapchain_create_info,
- context->allocator, &out_swapchain->handle));
-
- context->current_frame = 0;
-
- // images
- out_swapchain->image_count = 0;
- vkGetSwapchainImagesKHR(context->device.logical_device, out_swapchain->handle,
- &out_swapchain->image_count, 0);
-
- if (!out_swapchain->images) {
- out_swapchain->images = (VkImage*)malloc(sizeof(VkImage) * out_swapchain->image_count);
- }
- if (!out_swapchain->views) {
- out_swapchain->views = (VkImageView*)malloc(sizeof(VkImage) * out_swapchain->image_count);
- }
- VK_CHECK(vkGetSwapchainImagesKHR(context->device.logical_device, out_swapchain->handle,
- &out_swapchain->image_count, out_swapchain->images));
-
- // views
- for (int i = 0; i < out_swapchain->image_count; i++) {
- VkImageViewCreateInfo view_info = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO };
- view_info.image = out_swapchain->images[i];
- view_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
- view_info.format = out_swapchain->image_format.format;
- view_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
- view_info.subresourceRange.baseMipLevel = 0;
- view_info.subresourceRange.levelCount = 1;
- view_info.subresourceRange.baseArrayLayer = 0;
- view_info.subresourceRange.layerCount = 1;
-
- VK_CHECK(vkCreateImageView(context->device.logical_device, &view_info, context->allocator,
- &out_swapchain->views[i]));
- }
-
- // depth attachment
- if (!vulkan_device_detect_depth_format(&context->device)) {
- ERROR_EXIT("Failed to find a supported depth format");
- }
- vulkan_image_create(context, VK_IMAGE_TYPE_2D, swapchain_extent.width, swapchain_extent.height,
- context->device.depth_format, VK_IMAGE_TILING_OPTIMAL,
- VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
- VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, true, VK_IMAGE_ASPECT_DEPTH_BIT,
- &out_swapchain->depth_attachment);
- INFO("Depth attachment created");
-
- INFO("Swapchain created successfully");
- }
-
- // TODO: swapchain destroy
- void vulkan_swapchain_recreate(vulkan_context * context, u32 width, u32 height,
- vulkan_swapchain * swapchain) {
- // TODO
- }
- bool vulkan_swapchain_acquire_next_image_index(
- vulkan_context * context, vulkan_swapchain * swapchain, u64 timeout_ns,
- VkSemaphore image_available_semaphore, VkFence fence, u32 * out_image_index) {
- VkResult result =
- vkAcquireNextImageKHR(context->device.logical_device, swapchain->handle, timeout_ns,
- image_available_semaphore, fence, out_image_index);
-
- if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) {
- FATAL("Failed to acquire swapchain image");
- return false;
- }
-
- return true;
- }
-
- void vulkan_swapchain_present(vulkan_context * context, vulkan_swapchain * swapchain,
- VkQueue graphics_queue, VkQueue present_queue,
- VkSemaphore render_complete_semaphore, u32 present_image_index) {
- // return image to swapchain for presentation
- VkPresentInfoKHR present_info = { VK_STRUCTURE_TYPE_PRESENT_INFO_KHR };
- present_info.waitSemaphoreCount = 1;
- present_info.pWaitSemaphores = &render_complete_semaphore;
- present_info.swapchainCount = 1;
- present_info.pSwapchains = &swapchain->handle;
- present_info.pImageIndices = &present_image_index;
- present_info.pResults = 0;
-
- VkResult result = vkQueuePresentKHR(present_queue, &present_info);
- if (result != VK_SUCCESS) {
- if (result == VK_SUBOPTIMAL_KHR) {
- // WARN("Swapchain suboptimal - maybe resize needed?");
- } else {
- FATAL("Failed to present swapchain iamge");
- }
- }
-
- // advance the current frame
- context->current_frame = (context->current_frame + 1) % swapchain->max_frames_in_flight;
- }
-
- 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;
-
- // attachments
- u32 attachment_desc_count = 2;
- VkAttachmentDescription attachment_descriptions[2];
-
- // Colour attachment
- VkAttachmentDescription color_attachment;
- color_attachment.format = context->swapchain.image_format.format;
- color_attachment.samples = VK_SAMPLE_COUNT_1_BIT;
- color_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
- color_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
- color_attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
- color_attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
- color_attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
- color_attachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
- color_attachment.flags = 0;
-
- attachment_descriptions[0] = color_attachment;
-
- VkAttachmentReference color_attachment_reference;
- color_attachment_reference.attachment = 0;
- color_attachment_reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
-
- subpass.colorAttachmentCount = 1;
- subpass.pColorAttachments = &color_attachment_reference;
-
- // Depth attachment
- VkAttachmentDescription depth_attachment;
- depth_attachment.format = context->device.depth_format;
- depth_attachment.samples = VK_SAMPLE_COUNT_1_BIT;
- depth_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
- depth_attachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
- depth_attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
- depth_attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
- depth_attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
- depth_attachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
- depth_attachment.flags = 0;
-
- attachment_descriptions[1] = depth_attachment;
-
- VkAttachmentReference depth_attachment_reference;
- depth_attachment_reference.attachment = 1;
- depth_attachment_reference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
-
- subpass.pDepthStencilAttachment = &depth_attachment_reference;
-
- // TODO: other attachment styles
-
- subpass.inputAttachmentCount = 0;
- subpass.pInputAttachments = 0;
- subpass.pResolveAttachments = 0;
- subpass.preserveAttachmentCount = 0;
- subpass.preserveAttachmentCount = 0;
-
- // renderpass dependencies
- VkSubpassDependency dependency;
- dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
- dependency.dstSubpass = 0;
- dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
- dependency.srcAccessMask = 0;
- dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
- dependency.dstAccessMask =
- VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
- dependency.dependencyFlags = 0;
-
- VkRenderPassCreateInfo render_pass_create_info = { VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO };
- render_pass_create_info.attachmentCount = attachment_desc_count;
- render_pass_create_info.pAttachments = attachment_descriptions;
- render_pass_create_info.subpassCount = 1;
- render_pass_create_info.pSubpasses = &subpass;
- render_pass_create_info.dependencyCount = 1;
- render_pass_create_info.pDependencies = &dependency;
- render_pass_create_info.pNext = 0;
- render_pass_create_info.flags = 0;
-
- VK_CHECK(vkCreateRenderPass(context->device.logical_device, &render_pass_create_info,
- context->allocator, &out_renderpass->handle));
- }
-
- // TODO: renderpass destroy
-
- void vulkan_renderpass_begin(vulkan_command_buffer * command_buffer,
- vulkan_renderpass * renderpass, VkFramebuffer framebuffer) {
- VkRenderPassBeginInfo begin_info = { VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO };
- begin_info.renderPass = renderpass->handle;
- begin_info.framebuffer = framebuffer;
- begin_info.renderArea.offset.x = renderpass->render_area.x;
- begin_info.renderArea.offset.y = renderpass->render_area.y;
- begin_info.renderArea.extent.width = renderpass->render_area.z;
- begin_info.renderArea.extent.height = renderpass->render_area.w;
-
- VkClearValue clear_values[2];
- memset(&clear_values, 0, sizeof(VkClearValue) * 2);
- clear_values[0].color.float32[0] = renderpass->clear_colour.x;
- clear_values[0].color.float32[1] = renderpass->clear_colour.y;
- clear_values[0].color.float32[2] = renderpass->clear_colour.z;
- clear_values[0].color.float32[3] = renderpass->clear_colour.w;
- clear_values[1].depthStencil.depth = renderpass->depth;
- clear_values[1].depthStencil.stencil = renderpass->stencil;
-
- begin_info.clearValueCount = 2;
- begin_info.pClearValues = clear_values;
-
- vkCmdBeginRenderPass(command_buffer->handle, &begin_info, VK_SUBPASS_CONTENTS_INLINE);
- command_buffer->state = COMMAND_BUFFER_STATE_IN_RENDER_PASS;
- }
-
- void vulkan_renderpass_end(vulkan_command_buffer * command_buffer,
- vulkan_renderpass * renderpass) {
- vkCmdEndRenderPass(command_buffer->handle);
- command_buffer->state = COMMAND_BUFFER_STATE_RECORDING;
- }
-
- bool create_buffers(vulkan_context * context) {
- VkMemoryPropertyFlagBits mem_prop_flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
-
- const u64 vertex_buffer_size = sizeof(vertex_pos) * 1024 * 1024;
- if (!vulkan_buffer_create(context, vertex_buffer_size,
- VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
- VK_BUFFER_USAGE_TRANSFER_DST_BIT,
- mem_prop_flags, true, &context->object_vertex_buffer)) {
- ERROR("couldnt create vertex buffer");
- return false;
- }
-
- context->geometry_vertex_offset = 0;
-
- const u64 index1_buffer_size = sizeof(u32) * 1024 * 1024;
- if (!vulkan_buffer_create(context, index1_buffer_size,
- VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
- VK_BUFFER_USAGE_TRANSFER_DST_BIT,
- mem_prop_flags, true, &context->object_index_buffer)) {
- ERROR("couldnt create vertex buffer");
- return false;
- }
- context->geometry_index_offset = 0;
-
- return true;
- }
-
- void create_command_buffers(renderer * ren) {
- if (!context.gfx_command_buffers) {
- context.gfx_command_buffers = vulkan_command_buffer_darray_new(context.swapchain.image_count);
- }
-
- for (u32 i = 0; i < context.swapchain.image_count; i++) {
- vulkan_command_buffer_allocate(&context, context.device.gfx_command_pool, true,
- &context.gfx_command_buffers->data[i]);
- }
- }
-
- void upload_data_range(vulkan_context * context, VkCommandPool pool, VkFence fence, VkQueue queue,
- vulkan_buffer * buffer, u64 offset, u64 size, void* data) {
- VkBufferUsageFlags flags =
- VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
- vulkan_buffer staging;
- vulkan_buffer_create(context, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, flags, true, &staging);
- // load data into staging buffer
- printf("Size: %ld\n", size);
- vulkan_buffer_load_data(context, &staging, 0, size, 0, data);
-
- // copy
- vulkan_buffer_copy_to(context, pool, fence, queue, staging.handle, 0, buffer->handle, offset,
- size);
-
- vkDestroyBuffer(context->device.logical_device, staging.handle, context->allocator);
- }
-
- void regenerate_framebuffers(renderer * ren, vulkan_swapchain * swapchain,
- vulkan_renderpass * renderpass) {
- for (u32 i = 0; i < swapchain->image_count; i++) {
- u32 attachment_count = 2; // one for depth, one for colour
-
- VkImageView attachments[2] = { swapchain->views[i], swapchain->depth_attachment.view };
-
- vulkan_framebuffer_create(&context, renderpass, context.framebuffer_width,
- context.framebuffer_height, 2, attachments,
- &swapchain->framebuffers->data[i]);
- }
- }
-
- void vulkan_fence_create(vulkan_context * context, bool create_signaled,
- vulkan_fence* out_fence) {
- out_fence->is_signaled = create_signaled;
- VkFenceCreateInfo fence_create_info = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO };
- if (out_fence->is_signaled) {
- fence_create_info.flags = VK_FENCE_CREATE_SIGNALED_BIT;
- }
-
- vkCreateFence(context->device.logical_device, &fence_create_info, context->allocator,
- &out_fence->handle);
- }
-
- // TODO: vulkan_fence_destroy
-
- bool vulkan_fence_wait(vulkan_context * context, vulkan_fence * fence, u64 timeout_ns) {
- if (!fence->is_signaled) {
- VkResult result =
- vkWaitForFences(context->device.logical_device, 1, &fence->handle, true, timeout_ns);
- switch (result) {
- case VK_SUCCESS:
- fence->is_signaled = true;
- return true;
- case VK_TIMEOUT:
- WARN("vk_fence_wait - Timed out");
- break;
- default:
- ERROR("vk_fence_wait - Unhanlded error type");
- break;
- }
- } else {
- return true;
- }
-
- return false;
- }
- void vulkan_fence_reset(vulkan_context * context, vulkan_fence * fence) {
- if (fence->is_signaled) {
- vkResetFences(context->device.logical_device, 1, &fence->handle);
- fence->is_signaled = false;
- }
- }
-
- bool gfx_backend_init(renderer * ren) {
- INFO("loading Vulkan backend");
-
- vulkan_state* internal = malloc(sizeof(vulkan_state));
- ren->backend_state = (void*)internal;
-
- context.allocator = 0; // TODO: custom allocator
-
- context.framebuffer_width = SCR_WIDTH;
- context.framebuffer_height = SCR_HEIGHT;
-
- // Setup Vulkan instance
- VkApplicationInfo app_info = { VK_STRUCTURE_TYPE_APPLICATION_INFO };
- app_info.apiVersion = VK_API_VERSION_1_3;
- app_info.pApplicationName = ren->config.window_name;
- app_info.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
- app_info.pEngineName = "Celeritas Engine";
- app_info.engineVersion = VK_MAKE_VERSION(1, 0, 0);
-
- VkInstanceCreateInfo create_info = { VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO };
- create_info.pApplicationInfo = &app_info;
-
- cstr_darray* required_extensions = cstr_darray_new(2);
- cstr_darray_push(required_extensions, VK_KHR_SURFACE_EXTENSION_NAME);
-
- plat_get_required_extension_names(required_extensions);
-
-#if defined(CDEBUG)
- cstr_darray_push(required_extensions, VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
-
- DEBUG("Required extensions:");
- for (u32 i = 0; i < cstr_darray_len(required_extensions); i++) {
- DEBUG(" %s", required_extensions->data[i]);
- }
-#endif
-
- create_info.enabledExtensionCount = cstr_darray_len(required_extensions);
- create_info.ppEnabledExtensionNames = required_extensions->data;
-
- // Validation layers
- create_info.enabledLayerCount = 0;
- create_info.ppEnabledLayerNames = 0;
-#if defined(CDEBUG)
- INFO("Validation layers enabled");
- cstr_darray* desired_validation_layers = cstr_darray_new(1);
- cstr_darray_push(desired_validation_layers, "VK_LAYER_KHRONOS_validation");
-
- u32 n_available_layers = 0;
- VK_CHECK(vkEnumerateInstanceLayerProperties(&n_available_layers, 0));
- TRACE("%d available layers", n_available_layers);
- VkLayerProperties_darray* available_layers = VkLayerProperties_darray_new(n_available_layers);
- VK_CHECK(vkEnumerateInstanceLayerProperties(&n_available_layers, available_layers->data));
-
- for (int i = 0; i < cstr_darray_len(desired_validation_layers); i++) {
- // look through layers to make sure we can find the ones we want
- bool found = false;
- for (int j = 0; j < n_available_layers; j++) {
- if (str8_equals(str8_cstr_view(desired_validation_layers->data[i]),
- str8_cstr_view(available_layers->data[j].layerName))) {
- found = true;
- TRACE("Found layer %s", desired_validation_layers->data[i]);
- break;
- }
- }
-
- if (!found) {
- FATAL("Required validation is missing %s", desired_validation_layers->data[i]);
- return false;
- }
- }
- INFO("All validation layers are present");
- create_info.enabledLayerCount = cstr_darray_len(desired_validation_layers);
- create_info.ppEnabledLayerNames = desired_validation_layers->data;
-#endif
-
- VkResult result = vkCreateInstance(&create_info, NULL, &context.instance);
- if (result != VK_SUCCESS) {
- ERROR("vkCreateInstance failed with result: %u", result);
- return false;
- }
-
- // Debugger
-#if defined(CDEBUG)
- DEBUG("Creating Vulkan debugger")
- u32 log_severity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT |
- VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT;
- VkDebugUtilsMessengerCreateInfoEXT debug_create_info = {
- VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT
- };
- debug_create_info.messageSeverity = log_severity;
- debug_create_info.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
- VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT |
- VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT;
- debug_create_info.pfnUserCallback = vk_debug_callback;
-
- PFN_vkCreateDebugUtilsMessengerEXT func =
- (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(context.instance,
- "vkCreateDebugUtilsMessengerEXT");
- assert(func);
- VK_CHECK(func(context.instance, &debug_create_info, context.allocator, &context.vk_debugger));
- DEBUG("Vulkan debugger created");
-
-#endif
-
- // Surface creation
- DEBUG("Create SurfaceKHR")
- VkSurfaceKHR surface;
- VK_CHECK(glfwCreateWindowSurface(context.instance, ren->window, NULL, &surface));
- context.surface = surface;
- DEBUG("Vulkan surface created")
-
- // Device creation
- if (!vulkan_device_create(&context)) {
- FATAL("device creation failed");
- return false;
- }
-
- // Swapchain creation
- vulkan_swapchain_create(&context, SCR_WIDTH, SCR_HEIGHT, &context.swapchain);
-
- // Renderpass creation
- vulkan_renderpass_create(&context, &context.main_renderpass,
- vec4(0, 0, context.framebuffer_width, context.framebuffer_height),
- rgba_to_vec4(COLOUR_SEA_GREEN), 1.0, 0);
-
- // Framebiffers creation
- context.swapchain.framebuffers = vulkan_framebuffer_darray_new(context.swapchain.image_count);
- regenerate_framebuffers(ren, &context.swapchain, &context.main_renderpass);
- INFO("Framebuffers created");
-
- // Command buffers creation
- create_command_buffers(ren);
- INFO("Command buffers created");
-
- // Sync objects
- context.image_available_semaphores =
- calloc(context.swapchain.max_frames_in_flight, sizeof(VkSemaphore));
- context.queue_complete_semaphores =
- 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 };
- vkCreateSemaphore(context.device.logical_device, &semaphore_create_info, context.allocator,
- &context.image_available_semaphores[i]);
- vkCreateSemaphore(context.device.logical_device, &semaphore_create_info, context.allocator,
- &context.queue_complete_semaphores[i]);
-
- // create the fence in a signaled state
- vulkan_fence_create(&context, true, &context.in_flight_fences[i]);
- }
-
- context.images_in_flight =
- malloc(sizeof(vulkan_fence*) * context.swapchain.max_frames_in_flight);
- for (u8 i = 0; i < context.swapchain.max_frames_in_flight; i++) {
- context.images_in_flight[i] = 0;
- }
- INFO("Sync objects created");
-
- // Shader modules
- vulkan_object_shader_create(&context, &context.object_shader);
- INFO("Compiled shader modules")
-
- create_buffers(&context);
- INFO("Created buffers");
-
- // TODO: temporary test code
-
- mesh cube = prim_cube_mesh_create();
-
- vertex* verts = malloc(sizeof(vertex) * cube.vertices->len);
-
- f32 scale = 3.0;
- for (size_t i = 0; i < cube.vertices->len; i++) {
- verts[i].position = vec3_mult(cube.vertices->data[i].position, scale);
- verts[i].normal = cube.vertices->data[i].normal;
- verts[i].uv = cube.vertices->data[i].uv;
- }
-
- // const f32 s = 1.0;
- // const u32 vert_count = 4;
- // vertex_pos verts[4] = { 0 };
-
- // verts[0].pos.x = -0.5 * s;
- // verts[0].pos.y = -0.5 * s;
-
- // verts[1].pos.x = 0.5 * s;
- // verts[1].pos.y = 0.5 * s;
-
- // verts[2].pos.x = -0.5 * s;
- // verts[2].pos.y = 0.5 * s;
-
- // verts[3].pos.x = 0.5 * s;
- // verts[3].pos.y = -0.5 * s;
-
- // const u32 index_count = 6;
- // u32 indices[6] = { 0, 1, 2, 0, 3, 1 };
-
- upload_data_range(&context, context.device.gfx_command_pool, 0, context.device.graphics_queue,
- &context.object_vertex_buffer, 0, sizeof(vertex) * cube.vertices->len, verts);
- TRACE("Uploaded vertex data");
- upload_data_range(&context, context.device.gfx_command_pool, 0, context.device.graphics_queue,
- &context.object_index_buffer, 0, sizeof(u32) * cube.indices_len,
- cube.indices);
- TRACE("Uploaded index data");
- vertex_darray_free(cube.vertices);
- free(cube.indices);
-
- // upload texture
-
- // --- End test code
-
- INFO("Vulkan renderer initialisation succeeded");
- return true;
- }
-
- void gfx_backend_shutdown(renderer * ren) {
- DEBUG("Destroying Vulkan debugger");
- if (context.vk_debugger) {
- PFN_vkDestroyDebugUtilsMessengerEXT func =
- (PFN_vkDestroyDebugUtilsMessengerEXT)vkGetInstanceProcAddr(
- context.instance, "vkDestroyDebugUtilsMessengerEXT");
- func(context.instance, context.vk_debugger, context.allocator);
- }
-
- DEBUG("Destroying Vulkan instance...");
- 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 = 0;
- 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 texture_data_upload(texture * tex) {
- printf("Texture name %s\n", tex->name);
- tex->backend_data = malloc(sizeof(vulkan_texture_data));
- vulkan_texture_data* data = (vulkan_texture_data*)tex->backend_data;
- printf("Texture (%s) details: \n width %d\n height %d\n channel count %d\n", tex->name,
- tex->width, tex->height, tex->channel_count);
- VkDeviceSize image_size = tex->width * tex->height * max(tex->channel_count, 4);
-
- TRACE("Creating buffer of size %ld", image_size);
-
- VkFormat image_format = VK_FORMAT_R8G8B8A8_SRGB;
-
- VkBufferUsageFlags usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
- VkMemoryPropertyFlags memory_prop_flags =
- VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
- vulkan_buffer staging;
- vulkan_buffer_create(&context, image_size, usage, memory_prop_flags, true, &staging);
- DEBUG("Uploading image data");
- vulkan_buffer_load_data(&context, &staging, 0, image_size, 0, tex->image_data);
- INFO("Loaded iamge data!");
-
- vulkan_image_create(
- &context, VK_IMAGE_TYPE_2D, tex->width, tex->height, image_format, VK_IMAGE_TILING_OPTIMAL,
- VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
- VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
- VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, true, VK_IMAGE_ASPECT_COLOR_BIT, &data->image);
-
- vulkan_command_buffer temp_buffer;
- vulkan_command_buffer_allocate_and_begin_oneshot(&context, context.device.gfx_command_pool,
- &temp_buffer);
-
- vulkan_image_transition_layout(&context, &temp_buffer, &data->image, image_format,
- VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
-
- vulkan_image_copy_from_buffer(&data->image, staging.handle, &temp_buffer);
-
- vulkan_image_transition_layout(&context, &temp_buffer, &data->image, image_format,
- VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
- VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
-
- vulkan_command_buffer_end_oneshot(&context, context.device.gfx_command_pool, &temp_buffer,
- context.device.graphics_queue);
-
- VkSamplerCreateInfo sampler_info = { VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO };
- sampler_info.magFilter = VK_FILTER_LINEAR;
- sampler_info.minFilter = VK_FILTER_LINEAR;
- sampler_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
- sampler_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
- sampler_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
- sampler_info.anisotropyEnable = VK_TRUE;
- sampler_info.maxAnisotropy = 16;
- sampler_info.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
- sampler_info.unnormalizedCoordinates = VK_FALSE;
- sampler_info.compareEnable = VK_FALSE;
- sampler_info.compareOp = VK_COMPARE_OP_ALWAYS;
- sampler_info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
- sampler_info.mipLodBias = 0.0;
- sampler_info.minLod = 0.0;
- sampler_info.maxLod = 0.0;
-
- VkResult res = vkCreateSampler(context.device.logical_device, &sampler_info, context.allocator,
- &data->sampler);
- if (res != VK_SUCCESS) {
- ERROR("Error creating texture sampler for image %s", tex->name);
- return;
- }
-
- tex->image_data = (void*)data;
- }
-
- // TODO: destroy texture
-
- 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.graphics_queue,
- context.queue_complete_semaphores[context.current_frame], context.image_index);
- }
-
- void gfx_backend_draw_frame(renderer * ren, camera * cam, mat4 model, texture * tex) {
- backend_begin_frame(ren, 16.0);
-
- mat4 proj;
- mat4 view;
-
- camera_view_projection(cam, SCR_HEIGHT, SCR_WIDTH, &view, &proj);
-
- context.object_shader.texture_data = (vulkan_texture_data*)tex->image_data;
- gfx_backend_update_global_state(proj, view, cam->position, vec4(1.0, 1.0, 1.0, 1.0), 0);
-
- vulkan_object_shader_update_object(&context, &context.object_shader, model);
-
- backend_end_frame(ren, 16.0);
- }
-
- void gfx_backend_update_global_state(mat4 projection, mat4 view, vec3 view_pos,
- vec4 ambient_colour, i32 mode) {
- vulkan_object_shader_use(&context, &context.object_shader);
-
- vulkan_object_shader_update_global_state(&context, &context.object_shader);
- context.object_shader.global_ubo.projection = projection;
- context.object_shader.global_ubo.view = view;
- // TODO: other UBO properties
- }
-
- void clear_screen(vec3 colour) {}
-
- void bind_texture(shader s, texture * tex, u32 slot) {}
- void bind_mesh_vertex_buffer(void* backend, mesh* mesh) {}
- void draw_primitives(cel_primitive_topology primitive, u32 start_index, u32 count) {}
-
- shader shader_create_separate(const char* vert_shader, const char* frag_shader) {}
- void set_shader(shader s) {}
-
- void uniform_vec3f(u32 program_id, const char* uniform_name, vec3* value) {}
- void uniform_f32(u32 program_id, const char* uniform_name, f32 value) {}
- void uniform_i32(u32 program_id, const char* uniform_name, i32 value) {}
- void uniform_mat4f(u32 program_id, const char* uniform_name, mat4* value) {}
-
- VKAPI_ATTR VkBool32 VKAPI_CALL vk_debug_callback(
- VkDebugUtilsMessageSeverityFlagBitsEXT severity, VkDebugUtilsMessageTypeFlagsEXT flags,
- const VkDebugUtilsMessengerCallbackDataEXT* callback_data, void* user_data) {
- switch (severity) {
- default:
- case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT:
- ERROR("%s", callback_data->pMessage);
- break;
- case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT:
- WARN("%s", callback_data->pMessage);
- break;
- case VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT:
- INFO("%s", callback_data->pMessage);
- break;
- case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT:
- TRACE("%s", callback_data->pMessage);
- break;
- }
- return VK_FALSE;
- }
-
-#endif \ No newline at end of file
diff --git a/src/renderer/archive/render.c b/src/renderer/archive/render.c
deleted file mode 100644
index b1e2a46..0000000
--- a/src/renderer/archive/render.c
+++ /dev/null
@@ -1,413 +0,0 @@
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include "animation.h"
-#include "maths_types.h"
-#include "mem.h"
-#include "transform_hierarchy.h"
-#define STB_IMAGE_IMPLEMENTATION
-#include <stb_image.h>
-
-#define STB_TRUETYPE_IMPLEMENTATION
-#include <stb_truetype.h>
-
-#include "render.h"
-#include "render_types.h"
-
-#include <glad/glad.h>
-#include <glfw3.h>
-
-#include "defines.h"
-#include "log.h"
-#include "maths.h"
-#include "render_backend.h"
-
-// FIXME: get rid of these and store dynamic screen realestate
-// in renderer
-#define SCR_WIDTH 1000
-#define SCR_HEIGHT 1000
-
-material DEFAULT_MATERIAL = { 0 };
-
-bool renderer_init(renderer* ren) {
- INFO("Renderer init");
-
- // NOTE: all platforms use GLFW at the moment but thats subject to change
- glfwInit();
-
-#if defined(CEL_REND_BACKEND_OPENGL)
- glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
- glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
- glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
- glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
-#elif defined(CEL_REND_BACKEND_VULKAN)
- glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
-#endif
-
- // glfw window creation
- GLFWwindow* window = glfwCreateWindow(ren->config.scr_width, ren->config.scr_height,
- ren->config.window_name, NULL, NULL);
- if (window == NULL) {
- ERROR("Failed to create GLFW window\n");
- glfwTerminate();
- return false;
- }
- ren->window = window;
-
- glfwMakeContextCurrent(ren->window);
-
- DEBUG("init graphics api backend");
- if (!gfx_backend_init(ren)) {
- FATAL("Couldnt load graphics api backend");
- return false;
- }
-
- ren->blinn_phong =
- shader_create_separate("assets/shaders/blinn_phong.vert", "assets/shaders/blinn_phong.frag");
-
- ren->skinned =
- shader_create_separate("assets/shaders/skinned.vert", "assets/shaders/blinn_phong.frag");
-
- default_material_init();
-
- return true;
-}
-
-void renderer_shutdown(renderer* ren) {}
-
-void render_frame_begin(renderer* ren) {
- vec3 color = ren->config.clear_colour;
- clear_screen(color);
-}
-void render_frame_end(renderer* ren) {
- // present frame
- glfwSwapBuffers(ren->window);
- glfwPollEvents();
-}
-
-void default_material_init() {
- INFO("Load default material")
- DEFAULT_MATERIAL.ambient_colour = (vec3){ 0.5, 0.5, 0.5 };
- DEFAULT_MATERIAL.diffuse = (vec3){ 0.8, 0.8, 0.8 };
- DEFAULT_MATERIAL.specular = (vec3){ 1.0, 1.0, 1.0 };
- DEFAULT_MATERIAL.diffuse_texture = texture_data_load("assets/textures/white1x1.png", false);
- DEFAULT_MATERIAL.specular_texture = texture_data_load("assets/textures/black1x1.png", false);
- DEFAULT_MATERIAL.spec_exponent = 32.0;
- strcpy(DEFAULT_MATERIAL.name, "Default");
- texture_data_upload(&DEFAULT_MATERIAL.diffuse_texture);
- texture_data_upload(&DEFAULT_MATERIAL.specular_texture);
-}
-
-void model_destroy(model* model) {
- TRACE("Freeing all data for model %s", model->name);
- arena_free_all(&model->animation_data_arena);
- arena_free_storage(&model->animation_data_arena);
- mesh_darray_free(model->meshes);
- material_darray_free(model->materials);
- if (model->is_uploaded) {
- // Delete gpu buffer data
- for (u32 i = 0; i < mesh_darray_len(model->meshes); i++) {
- // FIXME: dont leak Opengl
- glDeleteBuffers(1, &model->meshes->data[i].vbo);
- glDeleteVertexArrays(1, &model->meshes->data[i].vao);
- }
- }
-}
-
-typedef struct draw_ctx {
- model_darray* models;
- renderer* ren;
- camera* cam;
- scene* scene;
-} draw_ctx;
-bool draw_scene_node(transform_node* node, void* ctx_data) {
- if (!node || !node->parent) return true;
- draw_ctx* ctx = ctx_data;
- model* m = &ctx->models->data[node->model.raw];
- draw_model(ctx->ren, ctx->cam, m, &node->world_matrix_tf, ctx->scene);
- return true;
-}
-
-void draw_scene(arena* frame, model_darray* models, renderer* ren, camera* camera,
- transform_hierarchy* tfh, scene* scene) {
- draw_ctx* ctx = arena_alloc(frame, sizeof(draw_ctx));
- ctx->models = models;
- ctx->ren = ren;
- ctx->cam = camera;
- ctx->scene = scene;
- transform_hierarchy_dfs(transform_hierarchy_root_node(tfh), draw_scene_node, true, ctx);
-}
-
-void draw_model(renderer* ren, camera* camera, model* model, mat4* model_tf, scene* scene) {
- // TRACE("Drawing model: %s", model->name);
- mat4 view;
- mat4 proj;
- camera_view_projection(camera, SCR_HEIGHT, SCR_WIDTH, &view, &proj);
-
- set_shader(ren->blinn_phong);
-
- // set camera uniform
- uniform_vec3f(ren->blinn_phong.program_id, "viewPos", &camera->position);
- // set light uniforms
- dir_light_upload_uniforms(ren->blinn_phong, &scene->dir_light);
- for (int i = 0; i < scene->n_point_lights; i++) {
- point_light_upload_uniforms(ren->blinn_phong, &scene->point_lights[i], '0' + i);
- }
-
- for (size_t i = 0; i < mesh_darray_len(model->meshes); i++) {
- mesh* m = &model->meshes->data[i];
- if (vertex_darray_len(m->vertices) == 0) {
- continue;
- }
- // TRACE("Drawing mesh %d", i);
- material* mat = &model->materials->data[m->material_index];
- draw_mesh(ren, m, model_tf, mat, &view, &proj);
- }
-}
-
-void draw_mesh(renderer* ren, mesh* mesh, mat4* model_tf, material* mat, mat4* view, mat4* proj) {
- shader lighting_shader = ren->blinn_phong;
-
- // bind buffer
- bind_mesh_vertex_buffer(ren->backend_state, mesh);
-
- // bind textures
- bind_texture(lighting_shader, &mat->diffuse_texture, 0); // bind to slot 0
- bind_texture(lighting_shader, &mat->specular_texture, 1); // bind to slot 1
- uniform_f32(lighting_shader.program_id, "material.shininess", 32.);
-
- // upload model, view, and projection matrices
- uniform_mat4f(lighting_shader.program_id, "model", model_tf);
- uniform_mat4f(lighting_shader.program_id, "view", view);
- uniform_mat4f(lighting_shader.program_id, "projection", proj);
-
- // draw triangles
- u32 num_vertices = vertex_darray_len(mesh->vertices);
- draw_primitives(CEL_PRIMITIVE_TOPOLOGY_TRIANGLE, 0, num_vertices);
-}
-
-void draw_skinned_mesh(renderer* ren, mesh* mesh, transform tf, material* mat, mat4* view,
- mat4* proj) {
- shader lighting_shader = ren->skinned;
-
- // bind buffer
- bind_mesh_vertex_buffer(ren->backend_state, mesh);
-
- // bind textures
- bind_texture(lighting_shader, &mat->diffuse_texture, 0); // bind to slot 0
- bind_texture(lighting_shader, &mat->specular_texture, 1); // bind to slot 1
-
- // Uniforms
- uniform_f32(lighting_shader.program_id, "material.shininess", 32.);
- mat4 trans = mat4_translation(tf.position);
- mat4 rot = mat4_rotation(tf.rotation);
- mat4 scale = mat4_scale(tf.scale);
- mat4 model_tf = mat4_mult(trans, mat4_mult(rot, scale));
- uniform_mat4f(lighting_shader.program_id, "model", &model_tf);
- uniform_mat4f(lighting_shader.program_id, "view", view);
- uniform_mat4f(lighting_shader.program_id, "projection", proj);
-
- // bone transforms
- size_t n_bones = mesh->bones->len;
-
- // for now assume correct ordering
- mat4* bone_transforms = malloc(n_bones * sizeof(mat4));
- mat4 parent = mat4_ident();
- for (int bone_i = 0; bone_i < n_bones; bone_i++) {
- joint j = mesh->bones->data[bone_i];
- transform tf = mesh->bones->data[bone_i].transform_components;
- tf.position.y = -tf.position.y;
- mat4 local = transform_to_mat(&tf);
- mat4 inverse = j.inverse_bind_matrix;
- inverse.data[13] = -inverse.data[13];
- mat4 intemediate = mat4_mult(local, inverse);
-
- bone_transforms[bone_i] = intemediate;
- parent = bone_transforms[bone_i];
- }
-
- // premultiply the inverses
- // for (int bone_i = 0; bone_i < n_bones; bone_i++) {
- // joint j = mesh->bones->data[bone_i];
- // // bone_transforms[bone_i] = mat4_mult(bone_transforms[bone_i], j.inverse_bind_matrix);
- // bone_transforms[bone_i] = mat4_mult(bone_transforms[bone_i], j.inverse_bind_matrix);
- // }
-
- glUniformMatrix4fv(glGetUniformLocation(lighting_shader.program_id, "boneMatrices"), n_bones,
- GL_FALSE, &bone_transforms->data[0]);
-
- free(bone_transforms);
-
- // draw triangles
- u32 num_vertices = vertex_darray_len(mesh->vertices);
- draw_primitives(CEL_PRIMITIVE_TOPOLOGY_TRIANGLE, 0, num_vertices);
-}
-
-void draw_skinned_model(renderer* ren, camera* cam, model* model, transform tf, scene* scene) {
- mat4 view;
- mat4 proj;
- camera_view_projection(cam, SCR_HEIGHT, SCR_WIDTH, &view, &proj);
-
- set_shader(ren->skinned);
-
- // set camera uniform
- uniform_vec3f(ren->skinned.program_id, "viewPos", &cam->position);
- // set light uniforms
- dir_light_upload_uniforms(ren->skinned, &scene->dir_light);
- for (int i = 0; i < scene->n_point_lights; i++) {
- point_light_upload_uniforms(ren->skinned, &scene->point_lights[i], '0' + i);
- }
-
- for (size_t i = 0; i < mesh_darray_len(model->meshes); i++) {
- mesh* m = &model->meshes->data[i];
- if (vertex_darray_len(m->vertices) == 0) {
- continue;
- }
- // material* mat = &model->materials->data[m->material_index];
- material* mat = &DEFAULT_MATERIAL;
- draw_skinned_mesh(ren, m, tf, mat, &view, &proj);
- }
-}
-
-void model_upload_meshes(renderer* ren, model* model) {
- INFO("Upload mesh vertex data to GPU for model %s", model->name);
-
- size_t num_meshes = mesh_darray_len(model->meshes);
- u32 VBOs[num_meshes];
- u32 VAOs[num_meshes];
- glGenBuffers(num_meshes, VBOs);
- glGenVertexArrays(num_meshes, VAOs);
-
- u64 total_verts = 0;
-
- TRACE("num meshes %d", num_meshes);
-
- // upload each mesh to the GPU
- for (int mesh_i = 0; mesh_i < num_meshes; mesh_i++) {
- mesh mesh = model->meshes->data[mesh_i];
- model->meshes->data[mesh_i].vao = VAOs[mesh_i];
- model->meshes->data[mesh_i].vbo = VBOs[mesh_i];
- // 3. bind buffers
- glBindBuffer(GL_ARRAY_BUFFER, VBOs[mesh_i]);
-
- size_t num_vertices = vertex_darray_len(model->meshes->data[mesh_i].vertices);
- // TRACE("Uploading vertex array data: %d verts", num_vertices);
- total_verts += num_vertices;
-
- size_t static_vertex_size = 2 * sizeof(vec3) + sizeof(vec2);
- size_t skinned_vertex_size = 2 * sizeof(vec3) + sizeof(vec2) + 4 * sizeof(u32) + sizeof(vec4);
- size_t vertex_size = mesh.is_skinned ? skinned_vertex_size : static_vertex_size;
-
- // TRACE("sizeof(vertex) -> %ld, vertex_size -> %ld\n", sizeof(vertex), vertex_size);
- if (mesh.is_skinned) {
- assert(vertex_size == (12 + 12 + 8 + 16 + 16));
- } else {
- assert(vertex_size == sizeof(vertex));
- assert(vertex_size == 8 * sizeof(float));
- }
-
- size_t buffer_size = vertex_size * num_vertices;
- u8* bytes = malloc(buffer_size);
-
- for (int i = 0; i < num_vertices; i++) {
- u8* p = bytes + vertex_size * i;
- memcpy(p, &mesh.vertices->data[i], static_vertex_size);
- if (mesh.is_skinned) {
- u8* bone_data_offset = p + static_vertex_size;
- memcpy(bone_data_offset, &mesh.vertex_bone_data->data[i], sizeof(vertex_bone_data));
- }
- }
-
- // 4. upload data
- glBufferData(GL_ARRAY_BUFFER, buffer_size, bytes, GL_STATIC_DRAW);
-
- // 5. cont. set mesh vertex layout
- glBindVertexArray(model->meshes->data[mesh_i].vao);
- // position attribute
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, vertex_size, (void*)0);
- glEnableVertexAttribArray(0);
- // normal vector attribute
- glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, vertex_size, (void*)(3 * sizeof(float)));
- glEnableVertexAttribArray(1);
- // tex coords
- glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, vertex_size, (void*)(6 * sizeof(float)));
- glEnableVertexAttribArray(2);
-
- // skinning (optional)
- if (mesh.is_skinned) {
- glEnableVertexAttribArray(3);
- glVertexAttribIPointer(3, 4, GL_INT, vertex_size, (void*)(8 * sizeof(float)));
-
- glEnableVertexAttribArray(4);
- glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, vertex_size, (void*)(12 * sizeof(float)));
- }
- }
-
- INFO("Uploaded %d submeshes with a total of %d vertices\n", num_meshes, total_verts);
-
- // 6. reset buffer
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-}
-
-texture texture_data_load(const char* path, bool invert_y) {
- TRACE("Load texture %s", path);
-
- // load the file data
- // texture loading
- int width, height, num_channels;
- stbi_set_flip_vertically_on_load(invert_y);
-
-#pragma GCC diagnostic ignored "-Wpointer-sign"
- char* data = stbi_load(path, &width, &height, &num_channels, 0); // STBI_rgb_alpha);
- if (data) {
- DEBUG("loaded texture: %s", path);
- } else {
- WARN("failed to load texture");
- }
-
- unsigned int channel_type;
- if (num_channels == 4) {
- channel_type = GL_RGBA;
- } else {
- channel_type = GL_RGB;
- }
-
- return (texture){ .texture_id = 0,
- .width = width,
- .height = height,
- .channel_count = num_channels,
- .channel_type = channel_type,
- .name = "TODO: Texture names",
- .image_data = data };
-}
-
-void dir_light_upload_uniforms(shader shader, directional_light* light) {
- uniform_vec3f(shader.program_id, "dirLight.direction", &light->direction);
- uniform_vec3f(shader.program_id, "dirLight.ambient", &light->ambient);
- uniform_vec3f(shader.program_id, "dirLight.diffuse", &light->diffuse);
- uniform_vec3f(shader.program_id, "dirLight.specular", &light->specular);
-}
-
-void point_light_upload_uniforms(shader shader, point_light* light, char index) {
- char position_str[] = "pointLights[x].position";
- position_str[12] = (char)index;
- char ambient_str[] = "pointLights[x].ambient";
- ambient_str[12] = (char)index;
- char diffuse_str[] = "pointLights[x].diffuse";
- diffuse_str[12] = (char)index;
- char specular_str[] = "pointLights[x].specular";
- specular_str[12] = (char)index;
- char constant_str[] = "pointLights[x].constant";
- constant_str[12] = (char)index;
- char linear_str[] = "pointLights[x].linear";
- linear_str[12] = (char)index;
- char quadratic_str[] = "pointLights[x].quadratic";
- quadratic_str[12] = (char)index;
- uniform_vec3f(shader.program_id, position_str, &light->position);
- uniform_vec3f(shader.program_id, ambient_str, &light->ambient);
- uniform_vec3f(shader.program_id, diffuse_str, &light->diffuse);
- uniform_vec3f(shader.program_id, specular_str, &light->specular);
- uniform_f32(shader.program_id, constant_str, light->constant);
- uniform_f32(shader.program_id, linear_str, light->linear);
- uniform_f32(shader.program_id, quadratic_str, light->quadratic);
-} \ No newline at end of file
diff --git a/src/renderer/archive/render.h b/src/renderer/archive/render.h
deleted file mode 100644
index 31cf3b0..0000000
--- a/src/renderer/archive/render.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * @file render.h
- * @author your name (you@domain.com)
- * @brief Renderer frontend
- * @version 0.1
- * @date 2024-03-21
- *
- * @copyright Copyright (c) 2024
- *
- */
-#pragma once
-
-#include "camera.h"
-#include "loaders.h"
-#include "render_types.h"
-#include "transform_hierarchy.h"
-
-// --- Lifecycle
-/** @brief initialise the render system frontend */
-bool renderer_init(renderer* ren);
-/** @brief shutdown the render system frontend */
-void renderer_shutdown(renderer* ren);
-
-void renderer_on_resize(renderer* ren);
-
-struct render_packet;
-
-// --- Frame
-
-void render_frame_begin(renderer* ren);
-void render_frame_end(renderer* ren);
-void render_frame_draw(renderer* ren);
-
-// --- models meshes
-void model_upload_meshes(renderer* ren, model* model);
-void draw_model(renderer* ren, camera* camera, model* model, mat4* tf, scene* scene);
-void draw_mesh(renderer* ren, mesh* mesh, mat4* tf, material* mat, mat4* view, mat4* proj);
-void draw_scene(arena* frame, model_darray* models, renderer* ren, camera* camera,
- transform_hierarchy* tfh, scene* scene);
-
-void draw_skinned_model(renderer* ren, camera* cam, model* model, transform tf, scene* scene);
-
-void model_destroy(model* model);
-
-// ---
-texture texture_data_load(const char* path, bool invert_y); // #frontend
diff --git a/src/renderer/archive/render_backend.h b/src/renderer/archive/render_backend.h
deleted file mode 100644
index 6df9c81..0000000
--- a/src/renderer/archive/render_backend.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * @brief Renderer backend
- */
-#pragma once
-
-#include "camera.h"
-#include "maths_types.h"
-#include "render_types.h"
-
-/// --- Lifecycle
-
-/** @brief Initialise the graphics API backend */
-bool gfx_backend_init(renderer* ren);
-void gfx_backend_shutdown(renderer* ren);
-
-void gfx_backend_draw_frame(renderer* ren, camera* camera, mat4 model, texture* tex);
-void gfx_backend_update_global_state(mat4 projection, mat4 view, vec3 view_pos, vec4 ambient_colour,
- i32 mode);
-
-void clear_screen(vec3 colour);
-
-void texture_data_upload(texture* tex);
-void bind_texture(shader s, texture* tex, u32 slot);
-void bind_mesh_vertex_buffer(void* backend, mesh* mesh);
-// void draw_primitives(cel_primitive_topology primitive, u32 start_index, u32 count);
-
-shader shader_create_separate(const char* vert_shader, const char* frag_shader);
-void set_shader(shader s);
-
-// --- Uniforms
-
-/** @brief upload a vec3 of f32 to a uniform */
-void uniform_vec3f(u32 program_id, const char* uniform_name, vec3* value);
-/** @brief upload a single f32 to a uniform */
-void uniform_f32(u32 program_id, const char* uniform_name, f32 value);
-/** @brief upload a integer to a uniform */
-void uniform_i32(u32 program_id, const char* uniform_name, i32 value);
-/** @brief upload a mat4 of f32 to a uniform */
-void uniform_mat4f(u32 program_id, const char* uniform_name, mat4* value); \ No newline at end of file
diff --git a/src/renderer/archive/render_types.h b/src/renderer/archive/render_types.h
deleted file mode 100644
index 5ee3316..0000000
--- a/src/renderer/archive/render_types.h
+++ /dev/null
@@ -1,210 +0,0 @@
-// /**
-// * @file render_types.h
-// * @author Omniscient
-// * @brief Type definitions for the majority of data required by the renderer system
-// * @date 2024-02-24
-// *
-// */
-// #pragma once
-
-#include "animation.h"
-#include "darray.h"
-#include "maths.h"
-#include "maths_types.h"
-#include "str.h"
-
-struct GLFWwindow;
-
-#define MAX_MATERIAL_NAME_LEN 256
-#define MAX_TEXTURE_NAME_LEN 256
-
-// #ifndef RESOURCE_HANDLE_DEFS
-// // CORE_DEFINE_HANDLE(model_handle);
-// #define ABSENT_MODEL_HANDLE 999999999
-// // CORE_DEFINE_HANDLE(texture_handle);
-// #define RESOURCE_HANDLE_DEFS
-// #endif
-
-/* @brief Opaque wrapper around a shader program */
-typedef struct shader {
- u32 program_id;
-} shader;
-
-/** @brief configuration passed to the renderer at init time */
-typedef struct renderer_config {
- char window_name[256];
- u32 scr_width, scr_height;
- vec3 clear_colour; /** colour that the screen gets cleared to every frame */
-} renderer_config;
-
-// typedef struct frame_stats {
-// u64 last_time;
-// } frame_stats;
-
-typedef struct renderer {
- struct GLFWwindow *window; /** Currently all platforms use GLFW*/
- void *backend_state; /** Graphics API-specific state */
- renderer_config config;
- // shaders
- shader blinn_phong;
- shader skinned;
-} renderer;
-
-// // --- Lighting & Materials
-
-typedef struct texture {
- u32 texture_id;
- char name[MAX_TEXTURE_NAME_LEN];
- void *image_data;
- void *backend_data;
- u32 width;
- u32 height;
- u8 channel_count;
- u32 channel_type;
-} texture;
-
-typedef struct blinn_phong_material {
- char name[MAX_MATERIAL_NAME_LEN];
- texture diffuse_texture;
- char diffuse_tex_path[256];
- texture specular_texture;
- char specular_tex_path[256];
- vec3 ambient_colour;
- vec3 diffuse;
- vec3 specular;
- f32 spec_exponent;
- bool is_loaded;
- bool is_uploaded;
-} blinn_phong_material;
-typedef blinn_phong_material material; // when we start using PBR, this will no longer be the
-// case
-
-// // the default blinn-phong material. MUST be initialised with the function below
-// extern material DEFAULT_MATERIAL;
-// void default_material_init();
-
-#ifndef TYPED_MATERIAL_ARRAY
-KITC_DECL_TYPED_ARRAY(material) // creates "material_darray"
-#define TYPED_MATERIAL_ARRAY
-#endif
-
-#ifndef TYPED_ANIMATION_CLIP_ARRAY
-KITC_DECL_TYPED_ARRAY(animation_clip) // creates "material_darray"
-#define TYPED_ANIMATION_CLIP_ARRAY
-#endif
-
-// // lights
-typedef struct point_light {
- vec3 position;
- f32 constant, linear, quadratic;
- vec3 ambient;
- vec3 diffuse;
- vec3 specular;
-} point_light;
-
-typedef struct directional_light {
- vec3 direction;
- vec3 ambient;
- vec3 diffuse;
- vec3 specular;
-} directional_light;
-
-// void point_light_upload_uniforms(shader shader, point_light *light, char index);
-// void dir_light_upload_uniforms(shader shader, directional_light *light);
-
-// // --- Models & Meshes
-
-// /** @brief Vertex format for a static mesh */
-typedef struct vertex {
- vec3 position;
- vec3 normal;
- vec2 uv;
-} vertex;
-
-typedef struct vertex_bone_data {
- vec4u joints; /** @brief 4 indices of joints that influence vectors position */
- vec4 weights; /** @brief weight (0,1) of each joint */
-} vertex_bone_data;
-
-#include "animation.h"
-#ifndef TYPED_VERTEX_ARRAY
-KITC_DECL_TYPED_ARRAY(vertex) // creates "vertex_darray"
-KITC_DECL_TYPED_ARRAY(vertex_bone_data) // creates "skinned_vertex_darray"
-KITC_DECL_TYPED_ARRAY(joint)
-#define TYPED_VERTEX_ARRAY
-#endif
-
-typedef struct mesh {
- vertex_darray *vertices;
- vertex_bone_data_darray *vertex_bone_data; // only used if model needs it
- joint_darray *bones;
- bool is_skinned;
- u32 vertex_size; /** size in bytes of each vertex including necessary padding */
- bool has_indices;
- u32 *indices;
- u32 indices_len;
- size_t material_index;
- u32 vbo, vao; /** OpenGL data. TODO: dont leak OpenGL details */
-} mesh;
-
-#ifndef TYPED_MESH_ARRAY
-KITC_DECL_TYPED_ARRAY(mesh) // creates "mesh_darray"
-#define TYPED_MESH_ARRAY
-#endif
-
-typedef struct model {
- str8 name;
- mesh_darray *meshes;
- aabb_3d bbox;
- material_darray *materials;
- animation_clip_darray *animations;
- arena animation_data_arena;
- bool is_loaded;
- bool is_uploaded;
-} model;
-
-// #ifndef TYPED_MODEL_ARRAY
-// KITC_DECL_TYPED_ARRAY(model) // creates "model_darray"
-// #define TYPED_MODEL_ARRAY
-// #endif
-
-// // --- Scene
-
-// // NOTE: This struct won't stay like this for a long time. It's somewhat temporary
-// // in order to get a basic scene working without putting burden on the caller of
-// // draw_model()
-// typedef struct scene {
-// directional_light dir_light;
-// point_light point_lights[4];
-// size_t n_point_lights;
-// } scene;
-
-// // --- Graphics API related
-
-// // typedef enum cel_primitive_topology {
-// // CEL_PRIMITIVE_TOPOLOGY_POINT,
-// // CEL_PRIMITIVE_TOPOLOGY_LINE,
-// // CEL_PRIMITIVE_TOPOLOGY_LINE_STRIP,
-// // CEL_PRIMITIVE_TOPOLOGY_TRIANGLE,
-// // CEL_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
-// // CEL_PRIMITIVE_TOPOLOGY_COUNT
-// // } cel_primitive_topology;
-
-// // typedef enum gpu_texture_type {
-// // TEXTURE_TYPE_2D,
-// // TEXTURE_TYPE_3D,
-// // TEXTURE_TYPE_2D_ARRAY,
-// // TEXTURE_TYPE_CUBE_MAP,
-// // TEXTURE_TYPE_COUNT
-// // } gpu_texture_type;
-
-// // typedef enum gpu_texture_format {
-// // TEXTURE_FORMAT_8_8_8_8_RGBA_UNORM,
-// // TEXTURE_FORMAT_DEPTH_DEFAULT,
-// // TEXTURE_FORMAT_COUNT
-// // } gpu_texture_format;
-
-// // typedef enum pipeline_kind {
-// // GRAPHICS,
-// // COMPUTE,
-// // } pipeline_kind;