diff options
author | omniscient <17525998+omnisci3nce@users.noreply.github.com> | 2024-06-27 22:26:52 +1000 |
---|---|---|
committer | omniscient <17525998+omnisci3nce@users.noreply.github.com> | 2024-06-27 22:26:52 +1000 |
commit | d5f22a65ab12b289d80b035e45e6f1e9460b82d1 (patch) | |
tree | dde5033b0198ffd0b5997b1589b7b9c00662de9f /src | |
parent | 564a656b1e0bf2d2cec0f35898a860ace384f616 (diff) |
remove archived render code
Diffstat (limited to 'src')
-rw-r--r-- | src/renderer/archive/old_backend_vulkan.c | 1990 | ||||
-rw-r--r-- | src/renderer/archive/render.c | 413 | ||||
-rw-r--r-- | src/renderer/archive/render.h | 46 | ||||
-rw-r--r-- | src/renderer/archive/render_backend.h | 39 | ||||
-rw-r--r-- | src/renderer/archive/render_types.h | 210 |
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, ®ion); - } - - 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, ©_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; |