diff --git a/src/main.c b/src/main.c index 1359478..984bcd6 100644 --- a/src/main.c +++ b/src/main.c @@ -2081,14 +2081,14 @@ Object create_object(uint32_t max_frames_in_flight, uint32_t descriptor_count) { return ret; } -Object create_renderable(Mesh* mesh, Material* material, VkDescriptorSet* descriptor_sets, uint32_t max_frames_in_flight, uint32_t descriptor_count) { +Object create_renderable(Mesh* mesh, Material* material, uint32_t descriptor_sets_count, VkDescriptorSet* descriptor_sets, uint32_t max_frames_in_flight) { Object zero = { .attributes = { .buckets = 0, }, }; - Object object = create_object(max_frames_in_flight, descriptor_count); + Object object = create_object(max_frames_in_flight, descriptor_sets_count); if(object.attributes.buckets == 0) { return zero; } @@ -2327,16 +2327,45 @@ Material create_simple_mesh_material(VkDevice device, VkExtent2D extent, VkRende .attributes_count = sizeof(attributes)/sizeof(VkVertexInputAttributeDescription), }; - PipelineLayout simple_layout = { - + VkDescriptorSetLayoutBinding object_set_bindings[] = { + { + .binding = 0, + .descriptorCount = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + .pImmutableSamplers = 0, + .stageFlags = VK_SHADER_STAGE_VERTEX_BIT, + }, }; - Map empty_map = { - .buckets = 0, - .buckets_count = 0, + PipelineLayout simple_layout = { + .object_bindings = object_set_bindings, + .object_bindings_count = sizeof(object_set_bindings)/sizeof(*object_set_bindings), }; - return create_material(device, extent, render_pass, 2, shader_stages, scene_ubo_layout, simple_layout, simple_mesh_type, max_frames_in_flight, empty_map); + Map object_descriptor_mappings = map_create(8, 2); + if(object_descriptor_mappings.buckets == 0) { + Material tmp = {}; + return tmp; + } + + Mapping* position_mapping = malloc(sizeof(Mapping)); + if(position_mapping == 0) { + map_destroy(object_descriptor_mappings); + Material tmp = {}; + return tmp; + } + position_mapping->mapping_type = MAPPING_POSITION_TO_MATRIX; + position_mapping->index = 0; + + bool map_result = map_add(&object_descriptor_mappings, ATTRIBUTE_ID_POSITION, position_mapping); + if(map_result != true) { + map_destroy(object_descriptor_mappings); + free(position_mapping); + Material tmp = {}; + return tmp; + } + + return create_material(device, extent, render_pass, 2, shader_stages, scene_ubo_layout, simple_layout, simple_mesh_type, max_frames_in_flight, object_descriptor_mappings); } Material create_texture_mesh_material(VkDevice device, VkExtent2D extent, VkRenderPass render_pass, VkDescriptorSetLayout scene_ubo_layout, uint32_t max_frames_in_flight) { @@ -2758,7 +2787,57 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) { context->triangle_mesh = triangle_mesh; } - Object triangle_object = create_renderable(&context->triangle_mesh, &context->simple_mesh_material, 0, 2, 0); + VkDescriptorPoolSize simple_pool_sizes[] = { + { + .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + .descriptorCount = max_frames_in_flight, + }, + }; + + VkDescriptorPoolCreateInfo simple_pool_info = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, + .poolSizeCount = 1, + .pPoolSizes = simple_pool_sizes, + .maxSets = max_frames_in_flight, + }; + + VkDescriptorPool simple_pool; + result = vkCreateDescriptorPool(context->device, &simple_pool_info, 0, &simple_pool); + if(result != VK_SUCCESS) { + fprintf(stderr, "failed to allocate simple_pool\n"); + return 0; + } + + VkDescriptorSetLayout* simple_set_layouts = malloc(sizeof(VkDescriptorSetLayout)*max_frames_in_flight); + if(simple_set_layouts == 0) { + fprintf(stderr, "failed to allocate simple_set_layouts\n"); + return 0; + } + + for(uint32_t i = 0; i < max_frames_in_flight; i++) { + simple_set_layouts[i] = simple_mesh_material.object_set_layout; + } + + VkDescriptorSetAllocateInfo simple_alloc_info = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, + .pSetLayouts = simple_set_layouts, + .descriptorSetCount = max_frames_in_flight, + .descriptorPool = simple_pool, + }; + + VkDescriptorSet* simple_descriptor_sets = malloc(sizeof(VkDescriptorSet)*max_frames_in_flight); + if(simple_descriptor_sets == 0) { + fprintf(stderr, "failed to allocate simple_descriptor_sets\n"); + return 0; + } + + result = vkAllocateDescriptorSets(context->device, &simple_alloc_info, simple_descriptor_sets); + if(result != VK_SUCCESS) { + fprintf(stderr, "failed to allocate descriptor sets from simple_pool\n"); + return 0; + } + + Object triangle_object = create_renderable(&context->triangle_mesh, &context->simple_mesh_material, 1, simple_descriptor_sets, max_frames_in_flight); if(triangle_object.attributes.buckets == 0) { fprintf(stderr, "failed to create renderable triangle object\n"); return 0; @@ -2766,6 +2845,57 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) { context->triangle_object = triangle_object; } + Position* simple_position = malloc(sizeof(Position)); + if(simple_position == 0) { + fprintf(stderr, "failed to allocate simple_position\n"); + return 0; + } + glm_quat_identity(simple_position->rotation); + glm_vec3_adds(simple_position->scale, 1.0f, simple_position->scale); + simple_position->position[0] = 0.0f; + simple_position->position[1] = 0.0f; + simple_position->position[2] = 2.0f; + bool map_result = map_add(&triangle_object.attributes, ATTRIBUTE_ID_POSITION, simple_position); + if(map_result == 0) { + return 0; + } + + AllocatedBuffer* simple_position_buffers = allocate_buffers(context->physical_device, context->device, sizeof(struct ModelUBO), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, max_frames_in_flight); + if(simple_position_buffers == 0) { + fprintf(stderr, "failed to allocate simple_position_buffers\n"); + return 0; + } + + MaybeValue maybe_simple_descriptors = map_lookup(triangle_object.attributes, ATTRIBUTE_ID_DESCRIPTORS); + if(maybe_simple_descriptors.has_value == false) { + fprintf(stderr, "didn't find ATTRIBUTE_ID_DESCRIPTORS\n"); + return 0; + } + void*** simple_descriptors = maybe_simple_descriptors.value; + for(uint32_t i = 0; i < max_frames_in_flight; i++) { + VkResult result = vkMapMemory(context->device, simple_position_buffers[i].memory, 0, sizeof(struct ModelUBO), 0, &simple_descriptors[i][0]); + if(result != VK_SUCCESS) { + return 0; + } + + VkDescriptorBufferInfo buffer_info = { + .buffer = simple_position_buffers[i].buffer, + .offset = 0, + .range = sizeof(struct ModelUBO), + }; + + VkWriteDescriptorSet write_info = { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .dstSet = simple_descriptor_sets[i], + .dstBinding = 0, + .dstArrayElement = 0, + .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + .pBufferInfo = &buffer_info, + }; + + vkUpdateDescriptorSets(context->device, 1, &write_info, 0, 0); + } + Material texture_mesh_material = create_texture_mesh_material(context->device, context->swapchain_extent, context->render_pass, context->scene_descriptor_layout, max_frames_in_flight); if(texture_mesh_material.pipeline == VK_NULL_HANDLE) { fprintf(stderr, "failed to create texture mesh material\n"); @@ -2836,7 +2966,7 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) { return 0; } - Object triangle_object_textured = create_renderable(&context->triangle_mesh_textured, &context->texture_mesh_material, TODO_sets, max_frames_in_flight, 1); + Object triangle_object_textured = create_renderable(&context->triangle_mesh_textured, &context->texture_mesh_material, 1, TODO_sets, max_frames_in_flight); if(triangle_object_textured.attributes.buckets == 0) { fprintf(stderr, "failed to create renderable textured triangle object\n"); return 0; @@ -2855,7 +2985,7 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) { position->position[0] = 0.0f; position->position[1] = 0.0f; position->position[2] = 1.0f; - bool map_result = map_add(&triangle_object_textured.attributes, ATTRIBUTE_ID_POSITION, position); + map_result = map_add(&triangle_object_textured.attributes, ATTRIBUTE_ID_POSITION, position); if(map_result == 0) { return 0; } @@ -2873,7 +3003,7 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) { void*** descriptors = maybe_descriptors.value; for(uint32_t i = 0; i < max_frames_in_flight; i++) { - VkResult result = vkMapMemory(device, triangle_ubos[i].memory, 0, sizeof(Position), 0, &descriptors[i][0]); + VkResult result = vkMapMemory(device, triangle_ubos[i].memory, 0, sizeof(struct ModelUBO), 0, &descriptors[i][0]); if(result != VK_SUCCESS) { return 0; } @@ -3199,9 +3329,10 @@ VkResult draw_frame(VulkanContext* context) { return result; } - uint32_t mesh_counts[] = {1}; - Object* objects[] = {&context->triangle_object_textured}; - result = command_draw_scene(1, &context->texture_mesh_material, (uint32_t*)&mesh_counts, (Object**)objects, context->current_frame, context->scene_descriptors, context->swapchain_command_buffers[context->current_frame], context->render_pass, context->swapchain_framebuffers[image_index], context->swapchain_extent); + uint32_t mesh_counts[] = {1, 1}; + Object* objects[] = {&context->triangle_object_textured, &context->triangle_object}; + Material materials[] = {context->texture_mesh_material, context->simple_mesh_material}; + result = command_draw_scene(2, materials, mesh_counts, objects, context->current_frame, context->scene_descriptors, context->swapchain_command_buffers[context->current_frame], context->render_pass, context->swapchain_framebuffers[image_index], context->swapchain_extent); if(result != VK_SUCCESS) { return result; }