summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorOmniscient <17525998+omnisci3nce@users.noreply.github.com>2024-05-11 22:06:55 +1000
committerOmniscient <17525998+omnisci3nce@users.noreply.github.com>2024-05-11 22:06:55 +1000
commit677ab09b0dc3b6d9c872b732f8e31543fa2d11bb (patch)
treef8aa923eb9d97c561341579fa4e575e4804ad9f4 /src
parent08d7e23fd5ed95953822a72ba11d4b6cd96b2846 (diff)
WIP: shader data
Diffstat (limited to 'src')
-rw-r--r--src/renderer/backends/backend_vulkan.c116
-rw-r--r--src/renderer/backends/backend_vulkan.h21
-rw-r--r--src/renderer/ral.h13
-rw-r--r--src/renderer/ral_types.h15
-rw-r--r--src/renderer/render.h2
5 files changed, 165 insertions, 2 deletions
diff --git a/src/renderer/backends/backend_vulkan.c b/src/renderer/backends/backend_vulkan.c
index dbae96e..c145c1a 100644
--- a/src/renderer/backends/backend_vulkan.c
+++ b/src/renderer/backends/backend_vulkan.c
@@ -25,8 +25,9 @@
// TEMP
#define SCREEN_WIDTH 1000
#define SCREEN_HEIGHT 1000
-#define MAX_FRAMES_IN_FLIGHT 2
#define VULKAN_QUEUES_COUNT 2
+#define MAX_DESCRIPTOR_SETS 100
+
const char* queue_names[VULKAN_QUEUES_COUNT] = { "GRAPHICS", "TRANSFER" };
typedef struct vulkan_context {
@@ -78,6 +79,7 @@ queue_family_indices find_queue_families(VkPhysicalDevice device);
bool create_logical_device(gpu_device* out_device);
void create_swapchain_framebuffers();
void create_sync_objects();
+void create_descriptor_pools();
VkShaderModule create_shader_module(str8 spirv);
@@ -494,6 +496,83 @@ gpu_pipeline* gpu_graphics_pipeline_create(struct graphics_pipeline_desc descrip
dynamic_state.dynamicStateCount = DYNAMIC_STATE_COUNT;
dynamic_state.pDynamicStates = dynamic_states;
+ // Descriptor Set layouts
+
+ VkDescriptorSetLayout* desc_set_layouts =
+ malloc(description.data_layouts_count * sizeof(VkDescriptorSetLayout));
+ pipeline->desc_set_layouts = desc_set_layouts;
+ pipeline->desc_set_layouts_count = description.data_layouts_count;
+ pipeline->uniform_pointers =
+ malloc(description.data_layouts_count * sizeof(desc_set_uniform_buffer));
+
+ for (u32 i = 0; i < description.data_layouts_count; i++) {
+ shader_data_layout sdl = description.data_layouts[i].shader_data_get_layout(NULL);
+
+ // NOTE: is using VLA generally ok?
+ VkDescriptorSetLayoutBinding desc_set_bindings[description.data_layouts_count];
+
+ // Bindings
+ for (u32 j = 0; j < sdl.bindings_count; j++) {
+ desc_set_bindings[j].binding = j;
+ desc_set_bindings[j].descriptorCount = 1;
+ switch (sdl.bindings[j].type) {
+ case SHADER_BINDING_BUFFER:
+ case SHADER_BINDING_BYTES:
+ desc_set_bindings[j].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+
+ u64 buffer_size = sdl.bindings[j].data.bytes.size;
+ VkDeviceSize uniform_buf_size = buffer_size;
+ // TODO: Create backing buffer
+
+ VkBuffer buffers[MAX_FRAMES_IN_FLIGHT];
+ VkDeviceMemory uniform_buf_memorys[MAX_FRAMES_IN_FLIGHT];
+ void* uniform_buf_mem_mappings[MAX_FRAMES_IN_FLIGHT];
+ // void* s?
+ for (size_t frame_i = 0; frame_i < MAX_FRAMES_IN_FLIGHT; frame_i++) {
+ buffer_handle uniform_buf_handle =
+ gpu_buffer_create(buffer_size, CEL_BUFFER_UNIFORM, CEL_BUFFER_FLAG_CPU, NULL);
+ buffers[frame_i] = context.buffers[uniform_buf_handle.raw].handle;
+ vkMapMemory(context.device->logical_device, uniform_buf_memorys[frame_i], 0,
+ uniform_buf_size, 0, &uniform_buf_mem_mappings[frame_i]);
+ }
+
+ desc_set_uniform_buffer uniform_data;
+ memcpy(&uniform_data.buffers, &buffers, sizeof(buffers));
+ memcpy(&uniform_data.uniform_buf_memorys, &uniform_buf_memorys,
+ sizeof(uniform_buf_memorys));
+ memcpy(&uniform_data.uniform_buf_mem_mappings, &uniform_buf_mem_mappings,
+ sizeof(uniform_buf_mem_mappings));
+ uniform_data.size = buffer_size;
+
+ pipeline->uniform_pointers[j] = uniform_data;
+
+ break;
+ default:
+ ERROR_EXIT("Unimplemented binding type!! in backend_vulkan");
+ }
+ switch (sdl.bindings[j].vis) {
+ case VISIBILITY_VERTEX:
+ desc_set_bindings[j].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
+ break;
+ case VISIBILITY_FRAGMENT:
+ desc_set_bindings[j].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
+ break;
+ case VISIBILITY_COMPUTE:
+ WARN("Compute is not implemented yet");
+ break;
+ }
+ }
+
+ VkDescriptorSetLayoutCreateInfo desc_set_layout_info = {
+ VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO
+ };
+ desc_set_layout_info.bindingCount = sdl.bindings_count;
+ desc_set_layout_info.pBindings = desc_set_bindings;
+
+ VK_CHECK(vkCreateDescriptorSetLayout(context.device->logical_device, &desc_set_layout_info,
+ context.allocator, &desc_set_layouts[i]));
+ }
+
// Layout
VkPipelineLayoutCreateInfo pipeline_layout_create_info = {
VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO
@@ -652,6 +731,18 @@ gpu_cmd_encoder gpu_cmd_encoder_create() {
VK_CHECK(vkAllocateCommandBuffers(context.device->logical_device, &allocate_info,
&encoder.cmd_buffer););
+ VkDescriptorPoolSize uniform_pool_size;
+ uniform_pool_size.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+ uniform_pool_size.descriptorCount = MAX_FRAMES_IN_FLIGHT * MAX_DESCRIPTOR_SETS;
+
+ VkDescriptorPoolCreateInfo pool_info = { VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO };
+ pool_info.poolSizeCount = 1;
+ pool_info.pPoolSizes = &uniform_pool_size;
+ pool_info.maxSets = 10000;
+
+ VK_CHECK(vkCreateDescriptorPool(context.device->logical_device, &pool_info, context.allocator,
+ &encoder.descriptor_pool));
+
return encoder;
}
void gpu_cmd_encoder_destroy(gpu_cmd_encoder* encoder) {
@@ -698,7 +789,27 @@ gpu_cmd_buffer gpu_cmd_encoder_finish(gpu_cmd_encoder* encoder) {
// --- Binding
void encode_bind_pipeline(gpu_cmd_encoder* encoder, pipeline_kind kind, gpu_pipeline* pipeline) {
vkCmdBindPipeline(encoder->cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->handle);
+ encoder->pipeline = pipeline;
+}
+
+void encode_bind_shader_data(gpu_cmd_encoder* encoder, u32 group, shader_data* data) {
+ assert(data->data != NULL);
+
+ // Update the local buffer
+ desc_set_uniform_buffer ubo = encoder->pipeline->uniform_pointers[group];
+ memcpy(ubo.uniform_buf_mem_mappings[context.current_frame], data->data, ubo.size);
+
+ VkDescriptorSetAllocateInfo alloc_info = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO };
+ alloc_info.descriptorPool =encoder->descriptor_pool;
+ alloc_info.descriptorSetCount = 1;
+ alloc_info.pSetLayouts = &encoder->pipeline->desc_set_layouts[group];
+
+ VkDescriptorSet sets[1];
+ VK_CHECK(vkAllocateDescriptorSets(context.device->logical_device, &alloc_info,
+ sets));
+
}
+
void encode_set_vertex_buffer(gpu_cmd_encoder* encoder, buffer_handle buf) {
gpu_buffer buffer = context.buffers[buf.raw];
VkBuffer vbs[] = { buffer.handle };
@@ -970,6 +1081,9 @@ VkShaderModule create_shader_module(str8 spirv) {
return shader_module;
}
+
+void create_descriptor_pools() {}
+
void create_swapchain_framebuffers() {
WARN("Recreating framebuffers...");
u32 image_count = context.swapchain->image_count;
diff --git a/src/renderer/backends/backend_vulkan.h b/src/renderer/backends/backend_vulkan.h
index 0b0a492..7bdf821 100644
--- a/src/renderer/backends/backend_vulkan.h
+++ b/src/renderer/backends/backend_vulkan.h
@@ -7,6 +7,7 @@
#include "ral.h"
// #include "vulkan_helpers.h"
+#define MAX_FRAMES_IN_FLIGHT 2
#define GPU_SWAPCHAIN_IMG_COUNT 2
/*
@@ -59,9 +60,26 @@ typedef struct gpu_pipeline_layout {
VkPipelineLayout handle;
} gpu_pipeline_layout;
+typedef struct desc_set_uniform_buffer {
+ VkBuffer buffers[MAX_FRAMES_IN_FLIGHT];
+ VkDeviceMemory uniform_buf_memorys[MAX_FRAMES_IN_FLIGHT];
+ void* uniform_buf_mem_mappings[MAX_FRAMES_IN_FLIGHT];
+ size_t size;
+} desc_set_uniform_buffer;
+
typedef struct gpu_pipeline {
VkPipeline handle;
VkPipelineLayout layout_handle;
+
+ // Descriptor gubbins
+ shader_data data_layouts[MAX_SHADER_DATA_LAYOUTS];
+ u32 data_layouts_count;
+
+ VkDescriptorSetLayout* desc_set_layouts;
+ // Based on group, we know which data to load
+ desc_set_uniform_buffer* uniform_pointers;
+ u32 desc_set_layouts_count;
+
} gpu_pipeline;
typedef struct gpu_renderpass {
@@ -71,6 +89,8 @@ typedef struct gpu_renderpass {
typedef struct gpu_cmd_encoder {
VkCommandBuffer cmd_buffer;
+ VkDescriptorPool descriptor_pool;
+ gpu_pipeline* pipeline;
} gpu_cmd_encoder;
typedef struct gpu_cmd_buffer {
@@ -82,3 +102,4 @@ typedef struct gpu_buffer {
VkDeviceMemory memory;
u64 size;
} gpu_buffer;
+
diff --git a/src/renderer/ral.h b/src/renderer/ral.h
index 38a653d..0df23ea 100644
--- a/src/renderer/ral.h
+++ b/src/renderer/ral.h
@@ -30,6 +30,8 @@ typedef struct gpu_cmd_encoder gpu_cmd_encoder; // Recording
typedef struct gpu_cmd_buffer gpu_cmd_buffer; // Ready for submission
typedef struct gpu_buffer gpu_buffer;
+#define MAX_SHADER_DATA_LAYOUTS 5
+
/** @brief A*/
// typedef struct gpu_bind_group
@@ -54,6 +56,17 @@ struct graphics_pipeline_desc {
const char* debug_name;
shader_desc vs; /** @brief Vertex shader stage */
shader_desc fs; /** @brief Fragment shader stage */
+
+ /* shader_data_layout data_layouts[MAX_SHADER_DATA_LAYOUTS]; */
+ /* u32 data_layouts_count; */
+
+ // Roughly equivalent to a descriptor set layout each. each layout can have multiple bindings
+ // examples:
+ // - uniform buffer reprensenting view projection matrix
+ // - texture for shadow map ?
+ shader_data data_layouts[MAX_SHADER_DATA_LAYOUTS];
+ u32 data_layouts_count;
+
// gpu_pipeline_layout* layout;
gpu_renderpass* renderpass;
diff --git a/src/renderer/ral_types.h b/src/renderer/ral_types.h
index 230afc3..e7863a9 100644
--- a/src/renderer/ral_types.h
+++ b/src/renderer/ral_types.h
@@ -59,6 +59,7 @@ typedef enum gpu_buffer_type {
CEL_BUFFER_DEFAULT, // on Vulkan this would be a storage buffer?
CEL_BUFFER_VERTEX,
CEL_BUFFER_INDEX,
+ CEL_BUFFER_UNIFORM,
CEL_BUFFER_COUNT
} gpu_buffer_type;
@@ -75,6 +76,7 @@ typedef enum vertex_format {
VERTEX_SPRITE,
VERTEX_SKINNED,
VERTEX_COLOURED_STATIC_3D,
+ VERTEX_RAW_POS_COLOUR,
VERTEX_COUNT
} vertex_format;
@@ -106,6 +108,11 @@ typedef union vertex {
vec3 normal;
vec4 colour;
} coloured_static_3d; /** @brief vertex format used for debugging */
+
+ struct {
+ vec2 position;
+ vec3 colour;
+ } raw_pos_colour;
} vertex;
#ifndef TYPED_VERTEX_ARRAY
@@ -136,6 +143,12 @@ typedef enum vertex_attrib_type {
ATTR_I32x4,
} vertex_attrib_type;
+typedef enum shader_visibility {
+ VISIBILITY_VERTEX = 1 << 0,
+ VISIBILITY_FRAGMENT = 1 << 1 ,
+ VISIBILITY_COMPUTE = 1 << 2,
+} shader_visibility;
+
typedef enum shader_binding_type {
SHADER_BINDING_BUFFER,
SHADER_BINDING_TEXTURE,
@@ -146,6 +159,7 @@ typedef enum shader_binding_type {
typedef struct shader_binding {
const char* label;
shader_binding_type type;
+ shader_visibility vis;
bool stores_data; /** @brief if this is true then the shader binding has references to live data,
if false then its just being used to describe a layout and .data
should be zeroed */
@@ -168,6 +182,7 @@ typedef struct shader_binding {
typedef struct shader_data_layout {
char* name;
shader_binding bindings[MAX_LAYOUT_BINDINGS];
+ u32 bindings_count;
} shader_data_layout;
typedef struct shader_data {
diff --git a/src/renderer/render.h b/src/renderer/render.h
index e6dd8b8..c690e80 100644
--- a/src/renderer/render.h
+++ b/src/renderer/render.h
@@ -43,4 +43,4 @@ mesh mesh_create(geometry_data* geometry);
model_handle model_load(const char* debug_name, const char* filepath);
-void geo_set_vertex_colours(geometry_data* geo, vec4 colour); \ No newline at end of file
+void geo_set_vertex_colours(geometry_data* geo, vec4 colour);