diff options
author | kartofen <mladenovnasko0@gmail.com> | 2023-11-10 21:30:33 +0200 |
---|---|---|
committer | kartofen <mladenovnasko0@gmail.com> | 2023-11-10 21:30:33 +0200 |
commit | 2a733f3d513a7279c1df4efe88fc5386ced2ed14 (patch) | |
tree | 800bd6d5c63034b9408d38c7a2b6264297981fbd | |
parent | 4512fafc57d2ad95b83c8476781ce105a2cdc4e5 (diff) |
uniform buffer added
-rw-r--r-- | files/shaders/shader1.vert | 8 | ||||
-rw-r--r-- | src/graphics.c | 134 | ||||
-rw-r--r-- | src/graphics.h | 16 | ||||
-rw-r--r-- | src/main.c | 41 |
4 files changed, 179 insertions, 20 deletions
diff --git a/files/shaders/shader1.vert b/files/shaders/shader1.vert index 9f27f54..de25828 100644 --- a/files/shaders/shader1.vert +++ b/files/shaders/shader1.vert @@ -1,11 +1,17 @@ #version 450 +layout(binding = 0) uniform uniform_buffer { + mat4 model; + mat4 view; + mat4 proj; +} ubo; + layout(location = 0) in vec2 inPosition; layout(location = 1) in vec3 inColor; layout(location = 0) out vec3 fragColor; void main() { - gl_Position = vec4(inPosition, 0.0, 1.0); + gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition, 0.0, 1.0); fragColor = inColor; } diff --git a/src/graphics.c b/src/graphics.c index 95f6630..e722abf 100644 --- a/src/graphics.c +++ b/src/graphics.c @@ -1,6 +1,5 @@ #include <string.h> #include <errno.h> -#include <cglm/cglm.h> #include <vulkan/vulkan.h> #include "graphics.h" @@ -71,13 +70,16 @@ static int create_physical_device(graphics_t graphics, struct graphics_info *inf static int create_logical_device(graphics_t graphics, struct graphics_info *info); static int create_pipeline(graphics_t graphics, struct graphics_info *info); static int create_swap_chain(graphics_t graphics, struct graphics_info *info); -static int create_vertex_buffer(graphics_t graphics, struct graphics_info *info); static int create_command_pool(graphics_t graphics, struct graphics_info *info); +static int create_descriptor_pool(graphics_t graphics, struct graphics_info *info); +static int create_buffers(graphics_t graphics, struct graphics_info *info); +static int create_descriptors(graphics_t graphics, struct graphics_info *info); static int create_sync_objects(graphics_t graphics, struct graphics_info *info); static void destroy_pipeline(graphics_t graphics); static void destroy_swap_chain(graphics_t graphics); // static void destroy_command_pool(graphics_t graphics); +// static void destroy_descriptor_pool(graphics_t graphics); static void destroy_sync_objects(graphics_t graphics); static int buffer_create(graphics_t graphics, size_t size, VkBufferUsageFlags usageflg, @@ -106,10 +108,13 @@ static int swap_chain_get_extent(VkSurfaceCapabilitiesKHR capabilities, VkExtent #define CMND_TRNS graphics->command_transfer static int command_buffer_record(graphics_t graphics, u32 image_index); +#define UBOD graphics->ubo_descriptor + #define SYNC graphics->sync #define VBFF graphics->vertex_buffer #define IBFF graphics->index_buffer +#define UBO graphics->ubo static int graphics_buffer_create(graphics_t graphics, VkBufferUsageFlags flags, void *data, size_t size, buffer_t *buffer); static int vertex_populate_descriptions(VkVertexInputBindingDescription *binding_desc, VkVertexInputAttributeDescription *attribute_desc); @@ -175,8 +180,11 @@ graphics_t graphics_create(struct graphics_info *info) CCHECK(create_pipeline); CCHECK(create_swap_chain); CCHECK(create_command_pool); - CCHECK(create_vertex_buffer); + CCHECK(create_descriptor_pool); + CCHECK(create_buffers); + CCHECK(create_descriptors); CCHECK(create_sync_objects); + return graphics; fail: @@ -192,11 +200,14 @@ void graphics_destroy(graphics_t graphics) destroy_sync_objects(graphics); - vkDestroyCommandPool(graphics->logical_device, CMND.pool, NULL); - vkDestroyCommandPool(graphics->logical_device, CMND_TRNS.pool, NULL); - buffer_destroy(graphics, VBFF); buffer_destroy(graphics, IBFF); + // have to also unmap the memory? + buffer_destroy(graphics, UBO.buffer); + + vkDestroyDescriptorPool(graphics->logical_device, UBOD.pool, NULL); + vkDestroyCommandPool(graphics->logical_device, CMND.pool, NULL); + vkDestroyCommandPool(graphics->logical_device, CMND_TRNS.pool, NULL); destroy_swap_chain(graphics); destroy_pipeline(graphics); @@ -238,6 +249,8 @@ int graphics_draw_frame(graphics_t graphics) vkResetCommandBuffer(CMND.buffer, 0); command_buffer_record(graphics, image_index); + UBO.update_ubo(UBO.mapped_data); + // prepare the queue submit info VkSubmitInfo submit_info = {0}; submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; @@ -623,13 +636,12 @@ static int create_pipeline(graphics_t graphics, struct graphics_info *info) VkDynamicState dynamic_states[] = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; - // A Bunch of other things for the pipeline VkPipelineDynamicStateCreateInfo dynamic_state = {0}; dynamic_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; dynamic_state.dynamicStateCount = ARR_SIZE(dynamic_states); dynamic_state.pDynamicStates = dynamic_states; - // vertex things + // set up graphics pipeline stages VkVertexInputBindingDescription binding_description = {0}; VkVertexInputAttributeDescription attribute_description[2] = {0}; vertex_populate_descriptions(&binding_description, attribute_description); @@ -658,7 +670,7 @@ static int create_pipeline(graphics_t graphics, struct graphics_info *info) rasterizer.polygonMode = VK_POLYGON_MODE_FILL; rasterizer.lineWidth = 1.0f; rasterizer.cullMode = VK_CULL_MODE_BACK_BIT; - rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE; + rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; rasterizer.depthBiasEnable = VK_FALSE; rasterizer.depthBiasConstantFactor = 0.0f; // Optional @@ -695,11 +707,26 @@ static int create_pipeline(graphics_t graphics, struct graphics_info *info) color_blend.blendConstants[2] = 0.0f; // Optional color_blend.blendConstants[3] = 0.0f; // Optional + // Create UBO Descriptor + VkDescriptorSetLayoutBinding ubo_layout_binding = {0}; + ubo_layout_binding.binding = 0; + ubo_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + ubo_layout_binding.descriptorCount = 1; + ubo_layout_binding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; + ubo_layout_binding.pImmutableSamplers = NULL; + + VkDescriptorSetLayoutCreateInfo descriptor_set_layout_info = {0}; + descriptor_set_layout_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + descriptor_set_layout_info.bindingCount = 1; + descriptor_set_layout_info.pBindings = &ubo_layout_binding; + + VCHECK(vkCreateDescriptorSetLayout, graphics->logical_device, &descriptor_set_layout_info, NULL, &PPLN.descriptor_layout); + // Create Pipeline Layout VkPipelineLayoutCreateInfo pipeline_layout_info = {0}; pipeline_layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - pipeline_layout_info.setLayoutCount = 0; // Optional - pipeline_layout_info.pSetLayouts = NULL; // Optional + pipeline_layout_info.setLayoutCount = 1; + pipeline_layout_info.pSetLayouts = &PPLN.descriptor_layout; pipeline_layout_info.pushConstantRangeCount = 0; // Optional pipeline_layout_info.pPushConstantRanges = NULL; // Optional @@ -787,8 +814,9 @@ exit: static void destroy_pipeline(graphics_t graphics) { vkDestroyPipeline(graphics->logical_device, PPLN.pipeline, NULL); - vkDestroyPipelineLayout(graphics->logical_device, PPLN.layout, NULL); vkDestroyRenderPass(graphics->logical_device, PPLN.render_pass, NULL); + vkDestroyPipelineLayout(graphics->logical_device, PPLN.layout, NULL); + vkDestroyDescriptorSetLayout(graphics->logical_device, PPLN.descriptor_layout, NULL); } static int create_command_pool(graphics_t graphics, struct graphics_info *info) @@ -838,6 +866,29 @@ exit: return ret; } +static int create_descriptor_pool(graphics_t graphics, struct graphics_info *info) +{ + (void)info; + int ret = 1; + + VkDescriptorPoolSize pool_size = {0}; + pool_size.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + pool_size.descriptorCount = 1; + + VkDescriptorPoolCreateInfo pool_info = {0}; + pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + pool_info.poolSizeCount = 1; + pool_info.pPoolSizes = &pool_size; + pool_info.maxSets = 1; + + VCHECK(vkCreateDescriptorPool, graphics->logical_device, &pool_info, NULL, &UBOD.pool); + + ret = 0; +exit: + return ret; +} + + static int create_sync_objects(graphics_t graphics, struct graphics_info *info) { (void)info; @@ -866,12 +917,60 @@ static void destroy_sync_objects(graphics_t graphics) vkDestroyFence(graphics->logical_device, SYNC.fence_inflight, NULL); } -static int create_vertex_buffer(graphics_t graphics, struct graphics_info *info) +static int create_descriptors(graphics_t graphics, struct graphics_info *info) +{ + (void)info; + int ret = 1; + + // copying? + UBOD.layout = PPLN.descriptor_layout; + + VkDescriptorSetAllocateInfo alloc_info = {0}; + alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + alloc_info.descriptorPool = UBOD.pool; + alloc_info.descriptorSetCount = 1; + alloc_info.pSetLayouts = &UBOD.layout; + + VCHECK(vkAllocateDescriptorSets, graphics->logical_device, &alloc_info, &UBOD.set); + + VkDescriptorBufferInfo buffer_info = {0}; + buffer_info.buffer = UBO.buffer.buffer; + buffer_info.offset = 0; + buffer_info.range = VK_WHOLE_SIZE; + + VkWriteDescriptorSet descriptor_write = {0}; + descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descriptor_write.dstSet = UBOD.set; + descriptor_write.dstBinding = 0; + descriptor_write.dstArrayElement = 0; + + descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + descriptor_write.descriptorCount = 1; + descriptor_write.pBufferInfo = &buffer_info; + descriptor_write.pImageInfo = NULL; // Optional + descriptor_write.pTexelBufferView = NULL; // Optional + vkUpdateDescriptorSets(graphics->logical_device, 1, &descriptor_write, 0, NULL); + + ret = 0; +exit: + return ret; +} + +static int create_buffers(graphics_t graphics, struct graphics_info *info) { graphics_buffer_create(graphics, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, info->vertices, sizeof(*info->vertices) *info->nvertices, &VBFF); graphics_buffer_create(graphics, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, info->indices, sizeof(*info->indices) * info->nindices, &IBFF); + + + buffer_create(graphics, info->ubo_size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &UBO.buffer); + + vkMapMemory(graphics->logical_device, UBO.buffer.memory, 0, info->ubo_size, 0, &UBO.mapped_data); + + // copy the function pointer of updatign the ubo + UBO.update_ubo = info->update_ubo; + return 0; } @@ -1165,14 +1264,17 @@ static int command_buffer_record(graphics_t graphics, u32 image_index) viewport.height = (float)SWCH.extent.height; viewport.minDepth = 0.0f; viewport.maxDepth = 1.0f; - - vkCmdSetViewport(CMND.buffer, 0, 1, &viewport); - + VkRect2D scissor = {0}; scissor.offset = (VkOffset2D){0, 0}; scissor.extent = SWCH.extent; + + vkCmdSetViewport(CMND.buffer, 0, 1, &viewport); vkCmdSetScissor(CMND.buffer, 0, 1, &scissor); + vkCmdBindDescriptorSets(CMND.buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + PPLN.layout, 0, 1, &UBOD.set, 0, NULL); + // 3 is the number of vertices // TODO: fix this vkCmdDrawIndexed(CMND.buffer, 6, 1, 0, 0, 0); diff --git a/src/graphics.h b/src/graphics.h index 71a8889..ff03e12 100644 --- a/src/graphics.h +++ b/src/graphics.h @@ -39,6 +39,7 @@ typedef struct graphics { struct pipeline { VkRenderPass render_pass; + VkDescriptorSetLayout descriptor_layout; // VkDescriptorSetLayout *descriptor_layouts; VkPipelineLayout layout; VkPipeline pipeline; } pipeline; @@ -60,6 +61,12 @@ typedef struct graphics { VkCommandBuffer buffer; } command_graphics, command_transfer; + struct descriptor { + VkDescriptorPool pool; + VkDescriptorSetLayout layout; + VkDescriptorSet set; + } ubo_descriptor; + struct sync { VkSemaphore semph_image_available; VkSemaphore semph_render_finished; @@ -69,6 +76,12 @@ typedef struct graphics { buffer_t vertex_buffer; buffer_t index_buffer; + struct { + buffer_t buffer; + void *mapped_data; + int (*update_ubo)(void *ubo); + } ubo; + } * graphics_t; struct graphics_info { @@ -83,6 +96,9 @@ struct graphics_info { u32 *indices; size_t nindices; + size_t ubo_size; + int (*update_ubo)(void *ubo); + int (*surface_func)(VkInstance instance, VkSurfaceKHR *surface); }; @@ -1,14 +1,27 @@ #include <stdio.h> #include <stdlib.h> +#include <sys/times.h> +#include <cglm/cglm.h> +#include <cglm/struct.h> #include "graphics.h" #include "window.h" #include "common.h" +#define SW 640 +#define SH 480 + window_t window; graphics_t graphics; int _create_surface(VkInstance instance, VkSurfaceKHR *surface); +int update_ubo(void *uniform_buffer); + +struct ubo { + mat4 model; + mat4 view; + mat4 proj; +}; vertex_t vertices[] = { {{-0.5f, -0.5f}, {1.0f, 0.0f, 0.0f}}, @@ -33,9 +46,9 @@ int main(void) // populate window info struct window_info win_info = {0}; win_info.title = "Test App"; - win_info.flags = SDL_WINDOW_RESIZABLE; - win_info.w = 640; - win_info.h = 480; + // win_info.flags = SDL_WINDOW_RESIZABLE; + win_info.w = SW; + win_info.h = SH; // create window window = window_create(&win_info); @@ -64,6 +77,9 @@ int main(void) grph_info.indices = indices; grph_info.nindices = ARR_SIZE(indices); + grph_info.ubo_size = sizeof(struct ubo); + grph_info.update_ubo = update_ubo; + grph_info.surface_func = _create_surface; // create the device @@ -96,6 +112,25 @@ f2: SDL_Quit(); f1: return ret; } +int update_ubo(void *uniform_buffer) +{ + struct ubo *ubo = (struct ubo *)uniform_buffer; + + static float time = 1.0f; + time += 0.01f; + + memcpy(ubo->model, glms_mat4_identity().raw, sizeof(ubo->model)); + glm_rotate(&ubo->model, time * glm_rad(90.0f), + (vec3){0.0f, 0.0f, 1.0f}); + + glm_lookat((vec3){1.0f, 1.0f, 2.0f}, (vec3){0.0f, 0.0f, 0.0f}, (vec3){0.0f, 0.0f, 1.0f}, ubo->view); + + glm_perspective(glm_rad(45.0f), (float)SW/(float)SH, 0.1f, 10.0f, ubo->proj); + + ubo->proj[1][1] *= -1; + return 0; +} + int _create_surface(VkInstance instance, VkSurfaceKHR *surface) { return window_create_surface(window, instance, surface); |