From ee57d5bc81e180c9370f323f71414b8242ade478 Mon Sep 17 00:00:00 2001 From: Noah Metz Date: Tue, 9 Jan 2024 20:41:31 -0700 Subject: [PATCH] Added Map struct and methods to create/destroy/use it --- src/main.c | 197 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 167 insertions(+), 30 deletions(-) diff --git a/src/main.c b/src/main.c index 62f0f7f..6f84693 100644 --- a/src/main.c +++ b/src/main.c @@ -64,6 +64,153 @@ typedef struct TextureStruct { VkSampler sampler; } Texture; +typedef struct EntryStruct { + uint32_t key; + void* value; +} Entry; + +typedef struct MapStruct { + uint32_t buckets_count; + Entry** buckets; + uint32_t* bucket_sizes; + uint32_t* bucket_usage; +} Map; + +Map map_create(uint32_t buckets_count, uint32_t initial_bucket_size) { + Map zero = {}; + + Entry** buckets = malloc(sizeof(Entry*)*buckets_count); + if(buckets == 0) { + return zero; + } + + uint32_t* bucket_sizes = malloc(sizeof(uint32_t)*buckets_count); + if(bucket_sizes == 0) { + free(buckets); + return zero; + } + + uint32_t* bucket_usage = malloc(sizeof(uint32_t)*buckets_count); + if(bucket_usage == 0) { + free(bucket_usage); + free(buckets); + return zero; + } + + for(uint32_t i = 0; i < buckets_count; i++) { + Entry* bucket = malloc(sizeof(Entry)*initial_bucket_size); + if(bucket == 0) { + for(uint32_t j = 0; j < i; j++) { + free(buckets[j]); + } + free(bucket_sizes); + free(buckets); + return zero; + } + buckets[i] = bucket; + bucket_sizes[i] = initial_bucket_size; + bucket_usage[i] = 0; + } + + Map ret = { + .buckets_count = buckets_count, + .bucket_sizes = bucket_sizes, + .bucket_usage = bucket_usage, + .buckets = buckets, + }; + + return ret; +} + +typedef struct MaybeValueStruct { + bool has_value; + void* value; +} MaybeValue; + +MaybeValue map_lookup(Map map, uint32_t key) { + MaybeValue ret = { + .has_value = false, + .value = 0, + }; + + uint32_t bucket_index = key % map.buckets_count; + for(uint32_t i = 0; i < map.bucket_usage[bucket_index]; i++) { + if(map.buckets[bucket_index][i].key == key) { + ret.has_value = true; + ret.value = map.buckets[bucket_index][i].value; + } + } + + return ret; +} + +bool map_add(Map* map, uint32_t key, void* value) { + uint32_t bucket_index = key % map->buckets_count; + + for(uint32_t i = 0; i < map->bucket_usage[bucket_index]; i++) { + if(map->buckets[bucket_index][i].key == key) { + map->buckets[bucket_index][i].value = value; + return true; + } + } + + if(map->bucket_usage[bucket_index] < map->bucket_sizes[bucket_index]) { + map->buckets[bucket_index][map->bucket_usage[bucket_index]].key = key; + map->buckets[bucket_index][map->bucket_usage[bucket_index]].value = value; + map->bucket_usage[bucket_index] += 1; + return true; + } + + Entry* new_bucket = realloc(map->buckets[bucket_index], 2*map->bucket_sizes[bucket_index]); + if(new_bucket == 0) { + return false; + } + + map->bucket_usage[bucket_index] += 1; + map->bucket_sizes[bucket_index] *= 2; + map->buckets[bucket_index] = new_bucket; + map->buckets[bucket_index][map->bucket_usage[bucket_index]].key = key; + map->buckets[bucket_index][map->bucket_usage[bucket_index]].value = value; + + return true; +} + +MaybeValue map_del(Map* map, uint32_t key) { + MaybeValue ret = { + .has_value = false, + .value = 0, + }; + + uint32_t bucket_index = key % map->buckets_count; + for(uint32_t i = 0; i < map->bucket_usage[bucket_index]; i++) { + if(map->buckets[bucket_index][i].key == key) { + ret.value = map->buckets[bucket_index][i].value; + ret.has_value = true; + + if(map->bucket_usage[bucket_index] > 1) { + map->buckets[bucket_index][i] = map->buckets[bucket_index][map->bucket_usage[bucket_index]-1]; + } + map->bucket_usage[bucket_index] -= 1; + break; + } + } + + return ret; +} + +void map_destroy(Map map) { + for(uint32_t i = 0; i < map.buckets_count; i++) { + free(map.buckets[i]); + } + free(map.buckets); + free(map.bucket_sizes); + free(map.bucket_usage); +} + +typedef struct ObjectStruct { + Map attributes; +} Object; + // Defines how a mesh is read from a buffer into a graphics pipeline typedef struct MeshTypeStruct { uint32_t bindings_count; @@ -157,7 +304,7 @@ typedef struct VulkanContextStruct { VkDescriptorPool scene_ubo_pool; VkDescriptorSetLayout scene_ubo_layout; - VkDescriptorSet* scene_ubo_descriptors; + VkDescriptorSet* scene_descriptors; AllocatedBuffer* scene_ubos; void** scene_ubo_ptrs; @@ -1056,24 +1203,6 @@ VkRenderPass create_render_pass(VkDevice device, VkSurfaceFormatKHR format, VkFo return render_pass; } -VkPipelineLayout create_pipeline_layout(VkDevice device, uint32_t set_count, VkDescriptorSetLayout* sets, uint32_t pcr_count, VkPushConstantRange* pcrs) { - VkPipelineLayout layout; - VkPipelineLayoutCreateInfo layout_info = {}; - layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - layout_info.setLayoutCount = set_count; - layout_info.pSetLayouts = sets; - layout_info.pushConstantRangeCount = pcr_count; - layout_info.pPushConstantRanges = pcrs; - - VkResult result; - result = vkCreatePipelineLayout(device, &layout_info, 0, &layout); - if(result != VK_SUCCESS) { - return VK_NULL_HANDLE; - } - - return layout; -} - uint32_t find_memory_type(VkPhysicalDevice physical_device, uint32_t type_filter, VkMemoryPropertyFlags properties) { VkPhysicalDeviceMemoryProperties memory_properties; vkGetPhysicalDeviceMemoryProperties(physical_device, &memory_properties); @@ -1700,15 +1829,15 @@ void record_command_buffer_mesh(Mesh mesh, VkCommandBuffer command_buffer) { vkCmdDrawIndexed(command_buffer, mesh.index_count, 1, 0, 0, 0); } -void record_command_buffer_material(Material material, uint32_t mesh_count, Mesh* meshes, VkDescriptorSet scene_ubo_descriptor, VkCommandBuffer command_buffer) { +void record_command_buffer_material(Material material, uint32_t mesh_count, Mesh* meshes, VkDescriptorSet scene_descriptor, VkCommandBuffer command_buffer) { vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, material.pipeline); - vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, material.layout, 0, 1, &scene_ubo_descriptor, 0, 0); + vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, material.layout, 0, 1, &scene_descriptor, 0, 0); for(uint32_t i = 0; i < mesh_count; i++) { record_command_buffer_mesh(meshes[i], command_buffer); } } -VkResult record_command_buffer_scene(uint32_t materials_count, Material* materials, uint32_t* mesh_counts, Mesh** meshes, VkDescriptorSet scene_ubo_descriptor, VkCommandBuffer command_buffer, VkRenderPass render_pass, VkFramebuffer framebuffer, VkExtent2D extent) { +VkResult record_command_buffer_scene(uint32_t materials_count, Material* materials, uint32_t* mesh_counts, Mesh** meshes, VkDescriptorSet scene_descriptor, VkCommandBuffer command_buffer, VkRenderPass render_pass, VkFramebuffer framebuffer, VkExtent2D extent) { VkCommandBufferBeginInfo begin_info = {}; begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; begin_info.flags = 0; @@ -1757,7 +1886,7 @@ VkResult record_command_buffer_scene(uint32_t materials_count, Material* materia vkCmdSetScissor(command_buffer, 0, 1, &scissor); for(uint i = 0; i < materials_count; i++) { - record_command_buffer_material(materials[i], mesh_counts[i], meshes[i], scene_ubo_descriptor, command_buffer); + record_command_buffer_material(materials[i], mesh_counts[i], meshes[i], scene_descriptor, command_buffer); } vkCmdEndRenderPass(command_buffer); @@ -1936,9 +2065,17 @@ Material create_material( num_layouts += 1; } + VkPipelineLayout layout; + + VkPipelineLayoutCreateInfo layout_info = {}; + layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + layout_info.setLayoutCount = num_layouts; + layout_info.pSetLayouts = all_layouts; + layout_info.pushConstantRangeCount = 0; // TODO + layout_info.pPushConstantRanges = 0; // TODO - VkPipelineLayout layout = create_pipeline_layout(device, num_layouts, all_layouts, 0, 0); - if(layout == VK_NULL_HANDLE) { + VkResult result = vkCreatePipelineLayout(device, &layout_info, 0, &layout); + if(result != VK_SUCCESS) { return zero_material; } @@ -2327,12 +2464,12 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) { context->scene_ubo_layout = scene_ubo_layout; } - VkDescriptorSet* scene_ubo_descriptors = create_descriptor_sets(context->device, context->scene_ubo_layout, context->scene_ubo_pool, max_frames_in_flight); - if(scene_ubo_descriptors == 0) { + VkDescriptorSet* scene_descriptors = create_descriptor_sets(context->device, context->scene_ubo_layout, context->scene_ubo_pool, max_frames_in_flight); + if(scene_descriptors == 0) { fprintf(stderr, "failed to create vulkan scene descriptore\n"); return 0; } else { - context->scene_ubo_descriptors = scene_ubo_descriptors; + context->scene_descriptors = scene_descriptors; } AllocatedBuffer* scene_ubos = allocate_buffers(context->physical_device, context->device, sizeof(struct SceneUBO), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, max_frames_in_flight); @@ -2370,7 +2507,7 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) { VkWriteDescriptorSet descriptor_write = {}; descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - descriptor_write.dstSet = context->scene_ubo_descriptors[i]; + descriptor_write.dstSet = context->scene_descriptors[i]; descriptor_write.dstBinding = 0; descriptor_write.dstArrayElement = 0; descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; @@ -2665,7 +2802,7 @@ VkResult draw_frame(VulkanContext* context) { uint32_t mesh_counts[] = {1}; Mesh* meshes[] = {&context->triangle_mesh_textured}; - result = record_command_buffer_scene(1, &context->texture_mesh_material, (uint32_t*)&mesh_counts, (Mesh**)meshes, context->scene_ubo_descriptors[context->current_frame], context->swapchain_command_buffers[context->current_frame], context->render_pass, context->swapchain_framebuffers[image_index], context->swapchain_extent); + result = record_command_buffer_scene(1, &context->texture_mesh_material, (uint32_t*)&mesh_counts, (Mesh**)meshes, context->scene_descriptors[context->current_frame], context->swapchain_command_buffers[context->current_frame], context->render_pass, context->swapchain_framebuffers[image_index], context->swapchain_extent); if(result != VK_SUCCESS) { return result; }