diff --git a/src/main.c b/src/main.c index 984bcd6..f8c9e2f 100644 --- a/src/main.c +++ b/src/main.c @@ -364,33 +364,30 @@ typedef struct VulkanContextStruct { VkImageView depth_image_view; uint32_t max_frames_in_flight; + // Per frame objects VkCommandBuffer* swapchain_command_buffers; VkSemaphore* image_available_semaphores; VkSemaphore* render_finished_semaphores; VkFence* in_flight_fences; + VkPhysicalDeviceMemoryProperties memories; VkRenderPass render_pass; VkCommandPool graphics_command_pool; VkCommandPool transfer_command_pool; - VkDescriptorPool scene_pool; - VkDescriptorSetLayout scene_descriptor_layout; - VkDescriptorSet* scene_descriptors; - AllocatedBuffer* scene_ubos; - void** scene_ubo_ptrs; - - Mesh triangle_mesh; - Mesh triangle_mesh_textured; - Material simple_mesh_material; - Material texture_mesh_material; - Object triangle_object; - Object triangle_object_textured; - uint32_t current_frame; } VulkanContext; +typedef struct SceneContextStruct { + VkDescriptorPool pool; + VkDescriptorSetLayout descriptor_layout; + VkDescriptorSet* descriptors; + AllocatedBuffer* ubos; + void** ubo_ptrs; +} SceneContext; + struct TextureVertex { vec3 pos; vec3 color; @@ -587,31 +584,6 @@ VkDescriptorSet* create_descriptor_sets(VkDevice device, VkDescriptorSetLayout l return sets; } -VkDescriptorSetLayout create_descriptor_set_layout(VkDevice device, VkDescriptorSetLayoutBinding* bindings, uint32_t bindings_count) { - VkDescriptorSetLayoutCreateInfo layout_info = {}; - layout_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - layout_info.bindingCount = bindings_count; - layout_info.pBindings = bindings; - - VkDescriptorSetLayout layout; - VkResult result = vkCreateDescriptorSetLayout(device, &layout_info, 0, &layout); - if(result != VK_SUCCESS) { - return VK_NULL_HANDLE; - } - - return layout; -} - -VkSurfaceKHR create_surface_khr(VkInstance instance, GLFWwindow* window) { - VkSurfaceKHR surface; - VkResult result = glfwCreateWindowSurface(instance, window, 0, &surface); - if(result != VK_SUCCESS) { - return VK_NULL_HANDLE; - } - - return surface; -} - VkPhysicalDevice get_best_physical_device(VkInstance instance) { VkPhysicalDevice device = VK_NULL_HANDLE; @@ -750,22 +722,6 @@ VkDebugUtilsMessengerEXT create_debug_messenger(VkInstance instance) { return debug_messenger; } -VkDescriptorPool create_descriptor_pool(VkDevice device, VkDescriptorPoolSize* sizes, uint32_t num_sizes, uint32_t max_sets) { - VkDescriptorPoolCreateInfo pool_info = {}; - pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; - pool_info.poolSizeCount = num_sizes; - pool_info.pPoolSizes = sizes; - pool_info.maxSets = max_sets; - - VkDescriptorPool pool; - VkResult result = vkCreateDescriptorPool(device, &pool_info, 0, &pool); - if(result != VK_SUCCESS) { - return VK_NULL_HANDLE; - } - - return pool; -} - VkInstance create_instance() { VkInstance instance; @@ -1194,12 +1150,10 @@ VkRenderPass create_render_pass(VkDevice device, VkSurfaceFormatKHR format, VkFo return render_pass; } -uint32_t find_memory_type(VkPhysicalDevice physical_device, uint32_t type_filter, VkMemoryPropertyFlags properties) { - VkPhysicalDeviceMemoryProperties memory_properties; - vkGetPhysicalDeviceMemoryProperties(physical_device, &memory_properties); - - for(uint32_t i = 0; i < memory_properties.memoryTypeCount; i++) { - if ((type_filter & (1 << i)) && (memory_properties.memoryTypes[i].propertyFlags & properties) == properties) { +uint32_t pick_memory_type(VkPhysicalDeviceMemoryProperties memories, uint32_t filter, VkMemoryPropertyFlags flags) { + for(uint32_t i = 0; i < memories.memoryTypeCount; i++) { + if((filter & (1 << i)) + && ((memories.memoryTypes[i].propertyFlags & flags) == flags)) { return i; } } @@ -1207,7 +1161,7 @@ uint32_t find_memory_type(VkPhysicalDevice physical_device, uint32_t type_filter return 0xFFFFFFFF; } -AllocatedImage allocate_image(VkPhysicalDevice physical_device, VkDevice device, VkImageType type, VkFormat format, VkExtent3D size, VkImageUsageFlags usage, VkMemoryPropertyFlags properties) { +AllocatedImage allocate_image(VkPhysicalDeviceMemoryProperties memories, VkDevice device, VkImageType type, VkFormat format, VkExtent3D size, VkImageUsageFlags usage, VkMemoryPropertyFlags properties) { VkImageCreateInfo image_info = { .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, .imageType = type, @@ -1238,7 +1192,7 @@ AllocatedImage allocate_image(VkPhysicalDevice physical_device, VkDevice device, VkMemoryAllocateInfo memory_info = { .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, .allocationSize = memory_requirements.size, - .memoryTypeIndex = find_memory_type(physical_device, memory_requirements.memoryTypeBits, properties), + .memoryTypeIndex = pick_memory_type(memories, memory_requirements.memoryTypeBits, properties), }; result = vkAllocateMemory(device, &memory_info, 0, &allocated.memory); @@ -1261,7 +1215,7 @@ AllocatedImage allocate_image(VkPhysicalDevice physical_device, VkDevice device, return allocated; } -AllocatedBuffer allocate_buffer(VkPhysicalDevice physical_device, VkDevice device, VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties) { +AllocatedBuffer allocate_buffer(VkPhysicalDeviceMemoryProperties memories, VkDevice device, VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties) { AllocatedBuffer ret = {}; ret.memory = VK_NULL_HANDLE; ret.buffer = VK_NULL_HANDLE; @@ -1286,7 +1240,7 @@ AllocatedBuffer allocate_buffer(VkPhysicalDevice physical_device, VkDevice devic VkMemoryAllocateInfo alloc_info = {}; alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; alloc_info.allocationSize = memory_requirements.size; - alloc_info.memoryTypeIndex = find_memory_type(physical_device, memory_requirements.memoryTypeBits, properties); + alloc_info.memoryTypeIndex = pick_memory_type(memories, memory_requirements.memoryTypeBits, properties); result = vkAllocateMemory(device, &alloc_info, 0, &ret.memory); if(result != VK_SUCCESS) { @@ -1317,14 +1271,14 @@ void deallocate_image(VkDevice device, AllocatedImage image) { vkFreeMemory(device, image.memory, 0); }; -AllocatedBuffer* allocate_buffers(VkPhysicalDevice physical_device, VkDevice device, VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, uint32_t count) { +AllocatedBuffer* allocate_buffers(VkPhysicalDeviceMemoryProperties memories, VkDevice device, VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, uint32_t count) { AllocatedBuffer* buffers = malloc(sizeof(AllocatedBuffer)*count); if(buffers == 0) { return 0; } for(uint32_t i = 0; i < count; i++) { - buffers[i] = allocate_buffer(physical_device, device, size, usage, properties); + buffers[i] = allocate_buffer(memories, device, size, usage, properties); if(buffers[i].memory == VK_NULL_HANDLE) { for(uint32_t j = 0; j < i; j++) { deallocate_buffer(device, buffers[i]); @@ -1450,10 +1404,10 @@ VkResult command_copy_buffer_to_image(VkDevice device, VkCommandPool transfer_po return command_end_single(device, command_buffer, transfer_pool, transfer_queue); } -AllocatedBuffer create_populated_buffer(VkPhysicalDevice physical_device, VkDevice device, void* data, VkDeviceSize size, VkCommandPool transfer_pool, VkQueue transfer_queue, VkBufferUsageFlags usage) { +AllocatedBuffer create_populated_buffer(VkPhysicalDeviceMemoryProperties memories, VkDevice device, void* data, VkDeviceSize size, VkCommandPool transfer_pool, VkQueue transfer_queue, VkBufferUsageFlags usage) { AllocatedBuffer staging_buffer = {}; AllocatedBuffer vertex_buffer = {}; - staging_buffer = allocate_buffer(physical_device, device, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); + staging_buffer = allocate_buffer(memories, device, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); if(staging_buffer.memory == VK_NULL_HANDLE) { return vertex_buffer; } @@ -1470,7 +1424,7 @@ AllocatedBuffer create_populated_buffer(VkPhysicalDevice physical_device, VkDevi vkUnmapMemory(device, staging_buffer.memory); - vertex_buffer = allocate_buffer(physical_device, device, size, VK_BUFFER_USAGE_TRANSFER_DST_BIT | usage, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + vertex_buffer = allocate_buffer(memories, device, size, VK_BUFFER_USAGE_TRANSFER_DST_BIT | usage, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); if(vertex_buffer.memory == VK_NULL_HANDLE) { deallocate_buffer(device, staging_buffer); return vertex_buffer; @@ -1488,7 +1442,7 @@ AllocatedBuffer create_populated_buffer(VkPhysicalDevice physical_device, VkDevi return vertex_buffer; } -Texture load_texture(VkPhysicalDevice physical_device, VkDevice device, VkCommandPool transfer_pool, VkQueue transfer_queue, VkExtent2D size, uint32_t stride, VkFormat format, void* image_data){ +Texture load_texture(VkPhysicalDeviceMemoryProperties memories, VkDevice device, VkCommandPool transfer_pool, VkQueue transfer_queue, VkExtent2D size, uint32_t stride, VkFormat format, void* image_data){ Texture ret = { .image.image = VK_NULL_HANDLE, .image.memory = VK_NULL_HANDLE, @@ -1496,7 +1450,7 @@ Texture load_texture(VkPhysicalDevice physical_device, VkDevice device, VkComman }; uint32_t image_size = size.width * size.height * stride; - AllocatedBuffer staging = allocate_buffer(physical_device, device, image_size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); + AllocatedBuffer staging = allocate_buffer(memories, device, image_size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); if(staging.memory == VK_NULL_HANDLE) { return ret; } @@ -1517,7 +1471,7 @@ Texture load_texture(VkPhysicalDevice physical_device, VkDevice device, VkComman .height = size.height, .depth = 1, }; - AllocatedImage image = allocate_image(physical_device, device, VK_IMAGE_TYPE_2D, format, full_extent, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + AllocatedImage image = allocate_image(memories, device, VK_IMAGE_TYPE_2D, format, full_extent, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); if(image.memory == VK_NULL_HANDLE) { deallocate_buffer(device, staging); deallocate_image(device, image); @@ -1783,7 +1737,7 @@ VkResult recreate_swap_chain(VulkanContext* context) { .depth = 1, }; - AllocatedImage depth_image = allocate_image(context->physical_device, context->device, VK_IMAGE_TYPE_2D, context->depth_format, depth_extent, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + AllocatedImage depth_image = allocate_image(context->memories, context->device, VK_IMAGE_TYPE_2D, context->depth_format, depth_extent, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); if(depth_image.memory == VK_NULL_HANDLE) { return VK_ERROR_INITIALIZATION_FAILED; } else { @@ -2008,14 +1962,14 @@ VkFence* create_fences(VkDevice device, VkFenceCreateFlags flags, uint32_t count return fences; } -Mesh load_texture_mesh(VkPhysicalDevice physical_device, VkDevice device, struct TextureVertex* vertices, uint32_t vertex_count, uint16_t* indices, uint32_t index_count, VkCommandPool transfer_pool, VkQueue transfer_queue) { +Mesh load_texture_mesh(VkPhysicalDeviceMemoryProperties memories, VkDevice device, struct TextureVertex* vertices, uint32_t vertex_count, uint16_t* indices, uint32_t index_count, VkCommandPool transfer_pool, VkQueue transfer_queue) { Mesh mesh = {}; mesh.vertex_buffer.buffer = VK_NULL_HANDLE; mesh.vertex_buffer.memory = VK_NULL_HANDLE; mesh.index_buffer.buffer = VK_NULL_HANDLE; mesh.index_buffer.memory = VK_NULL_HANDLE; - AllocatedBuffer vertex_buffer = create_populated_buffer(physical_device, device, (void*)vertices, sizeof(struct TextureVertex) * vertex_count, transfer_pool, transfer_queue, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); + AllocatedBuffer vertex_buffer = create_populated_buffer(memories, device, (void*)vertices, sizeof(struct TextureVertex) * vertex_count, transfer_pool, transfer_queue, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); if(vertex_buffer.memory == VK_NULL_HANDLE) { return mesh; } @@ -2023,7 +1977,7 @@ Mesh load_texture_mesh(VkPhysicalDevice physical_device, VkDevice device, struct mesh.vertex_buffer = vertex_buffer; mesh.vertex_count = vertex_count; - AllocatedBuffer index_buffer = create_populated_buffer(physical_device, device, (void*)indices, sizeof(uint16_t) * index_count, transfer_pool, transfer_queue, VK_BUFFER_USAGE_INDEX_BUFFER_BIT); + AllocatedBuffer index_buffer = create_populated_buffer(memories, device, (void*)indices, sizeof(uint16_t) * index_count, transfer_pool, transfer_queue, VK_BUFFER_USAGE_INDEX_BUFFER_BIT); if(index_buffer.memory == VK_NULL_HANDLE) { deallocate_buffer(device, vertex_buffer); AllocatedBuffer tmp = { .memory = VK_NULL_HANDLE, .buffer = VK_NULL_HANDLE}; @@ -2117,14 +2071,14 @@ Object create_renderable(Mesh* mesh, Material* material, uint32_t descriptor_set return object; } -Mesh load_simple_mesh(VkPhysicalDevice physical_device, VkDevice device, struct Vertex* vertices, uint32_t vertex_count, uint16_t* indices, uint32_t index_count, VkCommandPool transfer_pool, VkQueue transfer_queue) { +Mesh load_simple_mesh(VkPhysicalDeviceMemoryProperties memories, VkDevice device, struct Vertex* vertices, uint32_t vertex_count, uint16_t* indices, uint32_t index_count, VkCommandPool transfer_pool, VkQueue transfer_queue) { Mesh mesh = {}; mesh.vertex_buffer.buffer = VK_NULL_HANDLE; mesh.vertex_buffer.memory = VK_NULL_HANDLE; mesh.index_buffer.buffer = VK_NULL_HANDLE; mesh.index_buffer.memory = VK_NULL_HANDLE; - AllocatedBuffer vertex_buffer = create_populated_buffer(physical_device, device, (void*)vertices, sizeof(struct Vertex) * vertex_count, transfer_pool, transfer_queue, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); + AllocatedBuffer vertex_buffer = create_populated_buffer(memories, device, (void*)vertices, sizeof(struct Vertex) * vertex_count, transfer_pool, transfer_queue, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); if(vertex_buffer.memory == VK_NULL_HANDLE) { return mesh; } @@ -2132,7 +2086,7 @@ Mesh load_simple_mesh(VkPhysicalDevice physical_device, VkDevice device, struct mesh.vertex_buffer = vertex_buffer; mesh.vertex_count = vertex_count; - AllocatedBuffer index_buffer = create_populated_buffer(physical_device, device, (void*)indices, sizeof(uint16_t) * index_count, transfer_pool, transfer_queue, VK_BUFFER_USAGE_INDEX_BUFFER_BIT); + AllocatedBuffer index_buffer = create_populated_buffer(memories, device, (void*)indices, sizeof(uint16_t) * index_count, transfer_pool, transfer_queue, VK_BUFFER_USAGE_INDEX_BUFFER_BIT); if(index_buffer.memory == VK_NULL_HANDLE) { deallocate_buffer(device, vertex_buffer); AllocatedBuffer tmp = { .memory = VK_NULL_HANDLE, .buffer = VK_NULL_HANDLE}; @@ -2501,8 +2455,11 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) { context->physical_device = physical_device; } - VkSurfaceKHR surface = create_surface_khr(context->instance, window); - if(surface == VK_NULL_HANDLE) { + vkGetPhysicalDeviceMemoryProperties(context->physical_device, &context->memories); + + VkSurfaceKHR surface; + VkResult result = glfwCreateWindowSurface(instance, window, 0, &surface); + if(result != VK_SUCCESS) { fprintf(stderr, "failed to create vulkan surface\n"); return 0; } else { @@ -2591,7 +2548,7 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) { .height = context->swapchain_extent.height, .depth = 1, }; - AllocatedImage depth_image = allocate_image(context->physical_device, context->device, VK_IMAGE_TYPE_2D, depth_format, depth_extent, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + AllocatedImage depth_image = allocate_image(context->memories, context->device, VK_IMAGE_TYPE_2D, depth_format, depth_extent, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); if(depth_image.memory == VK_NULL_HANDLE) { fprintf(stderr, "failed to create vulkan depth image\n"); return 0; @@ -2620,7 +2577,7 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) { }; VkImageView depth_image_view; - VkResult result = vkCreateImageView(context->device, &depth_view_info, 0, &depth_image_view); + result = vkCreateImageView(context->device, &depth_view_info, 0, &depth_image_view); if(result != VK_SUCCESS) { fprintf(stderr, "failed to create vulkan depth image view\n"); return 0; @@ -2686,421 +2643,181 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) { context->in_flight_fences = if_fences; } - VkDescriptorPoolSize scene_pool_sizes[] = { + return context; +} + +SceneContext create_scene_context(VkDevice device, VkPhysicalDeviceMemoryProperties memories, uint32_t max_frames_in_flight) { + SceneContext ret = { + .pool = VK_NULL_HANDLE, + .descriptor_layout = VK_NULL_HANDLE, + .descriptors = 0, + .ubos = 0, + .ubo_ptrs = 0, + }; + + VkDescriptorPoolSize pool_sizes[] = { { .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, .descriptorCount = max_frames_in_flight, } }; - VkDescriptorPool scene_pool = create_descriptor_pool(device, scene_pool_sizes, 1, max_frames_in_flight); - if(scene_pool == VK_NULL_HANDLE) { - fprintf(stderr, "failed to create vulkan scene descriptor pool\n"); - return 0; - } else { - context->scene_pool = scene_pool; - } - VkDescriptorSetLayoutBinding scene_ubo_layout_binding = { - .binding = 0, - .stageFlags = VK_SHADER_STAGE_VERTEX_BIT, - .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - .descriptorCount = 1, - .pImmutableSamplers = 0, + VkDescriptorPoolCreateInfo pool_info = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, + .poolSizeCount = 1, + .pPoolSizes = pool_sizes, + .maxSets = max_frames_in_flight, }; - VkDescriptorSetLayout scene_descriptor_layout = create_descriptor_set_layout(device, &scene_ubo_layout_binding, 1); - if(scene_descriptor_layout == VK_NULL_HANDLE) { - fprintf(stderr, "failed to create vulkan scene descriptor layout\n"); - return 0; - } else { - context->scene_descriptor_layout = scene_descriptor_layout; - } - - VkDescriptorSet* scene_descriptors = create_descriptor_sets(context->device, context->scene_descriptor_layout, context->scene_pool, max_frames_in_flight); - if(scene_descriptors == 0) { - fprintf(stderr, "failed to create vulkan scene descriptore\n"); - return 0; - } else { - 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); - if(scene_ubos == 0) { - fprintf(stderr, "failed to create vulkan scnene ubo buffers\n"); - return 0; - } else { - context->scene_ubos = scene_ubos; - } - - void** scene_ubo_ptrs = malloc(sizeof(void*)*max_frames_in_flight); - if(scene_ubo_ptrs == 0) { - return 0; - } else { - context->scene_ubo_ptrs = scene_ubo_ptrs; - } - - for(uint32_t i = 0; i < max_frames_in_flight; i++) { - VkResult result = vkMapMemory(device, context->scene_ubos[i].memory, 0, sizeof(struct SceneUBO), 0, &context->scene_ubo_ptrs[i]); - if(result != VK_SUCCESS) { - for(uint32_t j = 0; j < i; j++) { - vkUnmapMemory(device, context->scene_ubos[j].memory); - } - - fprintf(stderr, "failed to map vulkan buffers to pointers for scene ubos\n"); - return 0; - } - } - - for(uint32_t i = 0; i < max_frames_in_flight; i++) { - VkDescriptorBufferInfo buffer_info = {}; - buffer_info.buffer = context->scene_ubos[i].buffer; - buffer_info.offset = 0; - buffer_info.range = sizeof(struct SceneUBO); - - VkWriteDescriptorSet descriptor_write = {}; - descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - descriptor_write.dstSet = context->scene_descriptors[i]; - 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 = 0; - descriptor_write.pTexelBufferView = 0; - - vkUpdateDescriptorSets(device, 1, &descriptor_write, 0, 0); - } - - Material simple_mesh_material = create_simple_mesh_material(context->device, context->swapchain_extent, context->render_pass, context->scene_descriptor_layout, max_frames_in_flight); - if(simple_mesh_material.pipeline == VK_NULL_HANDLE) { - fprintf(stderr, "failed to create simple mesh material\n"); - return 0; - } else { - context->simple_mesh_material = simple_mesh_material; - } - - Mesh triangle_mesh = load_simple_mesh(context->physical_device, context->device, (struct Vertex*)vertices, 4, (uint16_t*)indices, 6, context->transfer_command_pool, context->queues.transfer); - if(triangle_mesh.vertex_buffer.buffer == VK_NULL_HANDLE) { - fprintf(stderr, "failed to load triangle mesh\n"); - return 0; - } else { - context->triangle_mesh = triangle_mesh; + VkDescriptorPool pool; + VkResult result = vkCreateDescriptorPool(device, &pool_info, 0, &pool); + if(result != VK_SUCCESS) { + return ret; } - VkDescriptorPoolSize simple_pool_sizes[] = { + VkDescriptorSetLayoutBinding layout_bindings[] = { { - .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - .descriptorCount = max_frames_in_flight, - }, + .binding = 0, + .stageFlags = VK_SHADER_STAGE_VERTEX_BIT, + .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + .descriptorCount = 1, + .pImmutableSamplers = 0, + } }; - VkDescriptorPoolCreateInfo simple_pool_info = { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, - .poolSizeCount = 1, - .pPoolSizes = simple_pool_sizes, - .maxSets = max_frames_in_flight, + VkDescriptorSetLayoutCreateInfo layout_info = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, + .bindingCount = 1, + .pBindings = layout_bindings, }; - VkDescriptorPool simple_pool; - result = vkCreateDescriptorPool(context->device, &simple_pool_info, 0, &simple_pool); + VkDescriptorSetLayout layout; + result = vkCreateDescriptorSetLayout(device, &layout_info, 0, &layout); if(result != VK_SUCCESS) { - fprintf(stderr, "failed to allocate simple_pool\n"); - return 0; + vkDestroyDescriptorPool(device, pool, 0); + return ret; } - 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; + VkDescriptorSetLayout* layouts = malloc(sizeof(VkDescriptorSetLayout)*max_frames_in_flight); + if(layouts == 0) { + vkDestroyDescriptorPool(device, pool, 0); + return ret; } for(uint32_t i = 0; i < max_frames_in_flight; i++) { - simple_set_layouts[i] = simple_mesh_material.object_set_layout; + layouts[i] = layout; } - VkDescriptorSetAllocateInfo simple_alloc_info = { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, - .pSetLayouts = simple_set_layouts, + VkDescriptorSet* sets = malloc(sizeof(VkDescriptorSet)*max_frames_in_flight); + if(sets == 0) { + free(layouts); + vkDestroyDescriptorPool(device, pool, 0); + return ret; + } + + VkDescriptorSetAllocateInfo set_alloc_info = { + .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, + .descriptorPool = pool, .descriptorSetCount = max_frames_in_flight, - .descriptorPool = simple_pool, + .pSetLayouts = layouts, }; - 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); + result = vkAllocateDescriptorSets(device, &set_alloc_info, 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; - } else { - context->triangle_object = triangle_object; + free(layouts); + free(sets); + vkDestroyDescriptorPool(device, pool, 0); + return ret; } - 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* ubos = allocate_buffers(memories, 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); + if(ubos == 0) { + free(layouts); + free(sets); + vkFreeDescriptorSets(device, pool, max_frames_in_flight, sets); + vkDestroyDescriptorPool(device, pool, 0); + return ret; } - 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; + void** ubo_ptrs = malloc(sizeof(void*)*max_frames_in_flight); + if(ubo_ptrs == 0) { + free(layouts); + free(sets); + vkFreeDescriptorSets(device, pool, max_frames_in_flight, sets); + vkDestroyDescriptorPool(device, pool, 0); + for(uint32_t i = 0; i < max_frames_in_flight; i++) { + deallocate_buffer(device, ubos[i]); + } + free(ubos); + return ret; } - 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]); + VkResult result = vkMapMemory(device, ubos[i].memory, 0, sizeof(struct SceneUBO), 0, &ubo_ptrs[i]); if(result != VK_SUCCESS) { - return 0; + for(uint32_t j = 0; j < i; j++) { + vkUnmapMemory(device, ubos[j].memory); + } + + free(layouts); + free(sets); + vkFreeDescriptorSets(device, pool, max_frames_in_flight, sets); + vkDestroyDescriptorPool(device, pool, 0); + for(uint32_t i = 0; i < max_frames_in_flight; i++) { + deallocate_buffer(device, ubos[i]); + } + free(ubos); + + return ret; } VkDescriptorBufferInfo buffer_info = { - .buffer = simple_position_buffers[i].buffer, + .buffer = ubos[i].buffer, .offset = 0, - .range = sizeof(struct ModelUBO), + .range = sizeof(struct SceneUBO), }; - - VkWriteDescriptorSet write_info = { + VkWriteDescriptorSet write = { .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .dstSet = simple_descriptor_sets[i], + .dstSet = sets[i], .dstBinding = 0, .dstArrayElement = 0, .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + .descriptorCount = 1, .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"); - return 0; - } else { - context->texture_mesh_material = texture_mesh_material; - } - - Mesh triangle_mesh_textured = load_texture_mesh(context->physical_device, context->device, (struct TextureVertex*)texture_vertices, 4, (uint16_t*)indices, 6, context->transfer_command_pool, context->queues.transfer); - if(triangle_mesh_textured.vertex_buffer.buffer == VK_NULL_HANDLE) { - fprintf(stderr, "failed to load textured triangle mesh\n"); - return 0; - } else { - context->triangle_mesh_textured = triangle_mesh_textured; + vkUpdateDescriptorSets(device, 1, &write, 0, 0); } - VkDescriptorPoolSize TODO_sizes[] = { - { - .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - .descriptorCount = max_frames_in_flight, - }, - { - .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - .descriptorCount = max_frames_in_flight, - }, - }; - - VkDescriptorPoolCreateInfo TODO_info = { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, - .poolSizeCount = sizeof(TODO_sizes)/sizeof(VkDescriptorPoolSize), - .maxSets = max_frames_in_flight, - .pPoolSizes = TODO_sizes, + SceneContext scene = { + .pool = pool, + .descriptor_layout = layout, + .descriptors = sets, + .ubos = ubos, + .ubo_ptrs = ubo_ptrs, }; - VkDescriptorPool TODO_pool; - result = vkCreateDescriptorPool(context->device, &TODO_info, 0, &TODO_pool); - if(result != VK_SUCCESS) { - fprintf(stderr, "failed to create temporary descriptor pool\n"); - return 0; - } + return scene; +} - VkDescriptorSetLayout* TODO_layouts = malloc(sizeof(VkDescriptorSetLayout)*max_frames_in_flight); - if(TODO_layouts == 0) { - fprintf(stderr, "failed to allocate temp buffer\n"); - return 0; - } - - for(uint32_t i = 0; i < max_frames_in_flight; i++) { - TODO_layouts[i] = texture_mesh_material.object_set_layout; - } - - VkDescriptorSetAllocateInfo TODO_alloc = { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, - .descriptorPool = TODO_pool, - .descriptorSetCount = max_frames_in_flight, - .pSetLayouts = TODO_layouts, - }; - - VkDescriptorSet* TODO_sets = malloc(sizeof(VkDescriptorSet)*max_frames_in_flight); - if(TODO_sets == 0) { - fprintf(stderr, "failed to allocate temp buffer\n"); - return 0; - } - - result = vkAllocateDescriptorSets(device, &TODO_alloc, TODO_sets); - if(result != VK_SUCCESS) { - fprintf(stderr, "failed to allocate TODO descriptors\n"); - return 0; - } - - 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; - } else { - context->triangle_object_textured = triangle_object_textured; - } - - Position* position = malloc(sizeof(Position)); - if(position == 0) { - return 0; - } - glm_quat_identity(position->rotation); - position->scale[0] = 1.f; - position->scale[1] = 1.f; - position->scale[2] = 1.f; - position->position[0] = 0.0f; - position->position[1] = 0.0f; - position->position[2] = 1.0f; - map_result = map_add(&triangle_object_textured.attributes, ATTRIBUTE_ID_POSITION, position); - if(map_result == 0) { - return 0; - } - - AllocatedBuffer* triangle_ubos = 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(triangle_ubos == 0) { - return 0; - } - - MaybeValue maybe_descriptors = map_lookup(triangle_object_textured.attributes, ATTRIBUTE_ID_DESCRIPTORS); - if(maybe_descriptors.has_value == false) { - return 0; - } - - 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(struct ModelUBO), 0, &descriptors[i][0]); - if(result != VK_SUCCESS) { - return 0; - } - - VkDescriptorBufferInfo buffer_info = { - .buffer = triangle_ubos[i].buffer, - .offset = 0, - .range = sizeof(struct ModelUBO), - }; - - VkWriteDescriptorSet write_info = { - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .dstSet = TODO_sets[i], - .dstBinding = 1, - .dstArrayElement = 0, - .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - .descriptorCount = 1, - .pBufferInfo = &buffer_info, - }; - - vkUpdateDescriptorSets(context->device, 1, &write_info, 0, 0); - } - - VkExtent2D texture_size = { - .width = 10, - .height = 10, - }; - struct __attribute__((__packed__)) texel { - uint8_t r; - uint8_t g; - uint8_t b; - uint8_t a; - }; - - struct texel WHT = {255, 255, 255, 255}; - struct texel BLK = {0, 0, 0, 255}; - struct texel RED = {255, 0, 0, 255}; - struct texel GRN = {0, 255, 0, 255}; - struct texel BLU = {0, 0, 255, 255}; - - struct texel texture_data[100] = { - RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, BLK, - RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, BLK, - RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, WHT, - RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, WHT, - RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, BLK, - RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, BLK, - RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, WHT, - RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, WHT, - RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, BLK, - RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, BLK, - }; - - Texture test_texture = load_texture(context->physical_device, context->device, context->transfer_command_pool, context->queues.transfer, texture_size, 4, VK_FORMAT_R8G8B8A8_SRGB, texture_data); - - for(uint32_t i = 0; i < max_frames_in_flight; i++) { - VkDescriptorImageInfo image_info = { - .sampler = test_texture.sampler, - .imageView = test_texture.view, - .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - }; - - VkWriteDescriptorSet descriptor_write = {}; - descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - descriptor_write.dstSet = TODO_sets[i]; - descriptor_write.dstBinding = 0; - descriptor_write.dstArrayElement = 0; - descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - descriptor_write.descriptorCount = 1; - descriptor_write.pBufferInfo = 0; - descriptor_write.pImageInfo = &image_info; - descriptor_write.pTexelBufferView = 0; - - vkUpdateDescriptorSets(device, 1, &descriptor_write, 0, 0); - } - - return context; -} - -struct { - bool forward; - bool backward; - bool left; - bool right; - bool up; - bool down; - bool turn_left; - bool turn_right; - bool turn_up; - bool turn_down; - bool roll_left; - bool roll_right; -} key_flags = { - .forward = false, - .backward = false, - .left = false, - .right = false, +struct { + bool forward; + bool backward; + bool left; + bool right; + bool up; + bool down; + bool turn_left; + bool turn_right; + bool turn_up; + bool turn_down; + bool roll_left; + bool roll_right; +} key_flags = { + .forward = false, + .backward = false, + .left = false, + .right = false, .turn_left = false, .turn_right = false, @@ -3304,8 +3021,8 @@ VkResult update_scene_descriptor(void** buffers, uint32_t frame_index, vec3 worl return VK_SUCCESS; } -VkResult draw_frame(VulkanContext* context) { - update_scene_descriptor(context->scene_ubo_ptrs, context->current_frame, world_position, world_rotation, (float)context->swapchain_extent.width/(float)context->swapchain_extent.height, 0.01); +VkResult draw_frame(VulkanContext* context, SceneContext* scene, uint32_t materials_count, Material* materials, uint32_t* objects_counts, Object** objects) { + update_scene_descriptor(scene->ubo_ptrs, context->current_frame, world_position, world_rotation, (float)context->swapchain_extent.width/(float)context->swapchain_extent.height, 0.01); VkResult result; result = vkWaitForFences(context->device, 1, &context->in_flight_fences[context->current_frame], VK_TRUE, UINT64_MAX); @@ -3329,10 +3046,7 @@ VkResult draw_frame(VulkanContext* context) { return result; } - 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); + result = command_draw_scene(materials_count, materials, objects_counts, objects, context->current_frame, 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; } @@ -3366,11 +3080,317 @@ VkResult draw_frame(VulkanContext* context) { } void main_loop(GLFWwindow* window, VulkanContext* context) { + SceneContext scene = create_scene_context(context->device, context->memories, context->max_frames_in_flight); + if(scene.pool == VK_NULL_HANDLE) { + return; + } + + Material simple_mesh_material = create_simple_mesh_material(context->device, context->swapchain_extent, context->render_pass, scene.descriptor_layout, context->max_frames_in_flight); + if(simple_mesh_material.pipeline == VK_NULL_HANDLE) { + fprintf(stderr, "failed to create simple mesh material\n"); + return; + } + + Mesh triangle_mesh = load_simple_mesh(context->memories, context->device, (struct Vertex*)vertices, 4, (uint16_t*)indices, 6, context->transfer_command_pool, context->queues.transfer); + if(triangle_mesh.vertex_buffer.buffer == VK_NULL_HANDLE) { + fprintf(stderr, "failed to load triangle mesh\n"); + return; + } + + VkDescriptorPoolSize simple_pool_sizes[] = { + { + .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + .descriptorCount = context->max_frames_in_flight, + }, + }; + + VkDescriptorPoolCreateInfo simple_pool_info = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, + .poolSizeCount = 1, + .pPoolSizes = simple_pool_sizes, + .maxSets = context->max_frames_in_flight, + }; + + VkDescriptorPool simple_pool; + VkResult result = vkCreateDescriptorPool(context->device, &simple_pool_info, 0, &simple_pool); + if(result != VK_SUCCESS) { + fprintf(stderr, "failed to allocate simple_pool\n"); + return; + } + + VkDescriptorSetLayout* simple_set_layouts = malloc(sizeof(VkDescriptorSetLayout)*context->max_frames_in_flight); + if(simple_set_layouts == 0) { + fprintf(stderr, "failed to allocate simple_set_layouts\n"); + return; + } + + for(uint32_t i = 0; i < context->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 = context->max_frames_in_flight, + .descriptorPool = simple_pool, + }; + + VkDescriptorSet* simple_descriptor_sets = malloc(sizeof(VkDescriptorSet)*context->max_frames_in_flight); + if(simple_descriptor_sets == 0) { + fprintf(stderr, "failed to allocate simple_descriptor_sets\n"); + return; + } + + 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; + } + + Object triangle_object = create_renderable(&triangle_mesh, &simple_mesh_material, 1, simple_descriptor_sets, context->max_frames_in_flight); + if(triangle_object.attributes.buckets == 0) { + fprintf(stderr, "failed to create renderable triangle object\n"); + return; + } + + Position* simple_position = malloc(sizeof(Position)); + if(simple_position == 0) { + fprintf(stderr, "failed to allocate simple_position\n"); + return; + } + 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; + } + + AllocatedBuffer* simple_position_buffers = allocate_buffers(context->memories, context->device, sizeof(struct ModelUBO), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, context->max_frames_in_flight); + if(simple_position_buffers == 0) { + fprintf(stderr, "failed to allocate simple_position_buffers\n"); + return; + } + + 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; + } + void*** simple_descriptors = maybe_simple_descriptors.value; + for(uint32_t i = 0; i < context->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; + } + + 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, scene.descriptor_layout, context->max_frames_in_flight); + if(texture_mesh_material.pipeline == VK_NULL_HANDLE) { + fprintf(stderr, "failed to create texture mesh material\n"); + return; + } + + Mesh triangle_mesh_textured = load_texture_mesh(context->memories, context->device, (struct TextureVertex*)texture_vertices, 4, (uint16_t*)indices, 6, context->transfer_command_pool, context->queues.transfer); + if(triangle_mesh_textured.vertex_buffer.buffer == VK_NULL_HANDLE) { + fprintf(stderr, "failed to load textured triangle mesh\n"); + return; + } + + VkDescriptorPoolSize TODO_sizes[] = { + { + .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + .descriptorCount = context->max_frames_in_flight, + }, + { + .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + .descriptorCount = context->max_frames_in_flight, + }, + }; + + VkDescriptorPoolCreateInfo TODO_info = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, + .poolSizeCount = sizeof(TODO_sizes)/sizeof(VkDescriptorPoolSize), + .maxSets = context->max_frames_in_flight, + .pPoolSizes = TODO_sizes, + }; + + VkDescriptorPool TODO_pool; + result = vkCreateDescriptorPool(context->device, &TODO_info, 0, &TODO_pool); + if(result != VK_SUCCESS) { + fprintf(stderr, "failed to create temporary descriptor pool\n"); + return; + } + + VkDescriptorSetLayout* TODO_layouts = malloc(sizeof(VkDescriptorSetLayout)*context->max_frames_in_flight); + if(TODO_layouts == 0) { + fprintf(stderr, "failed to allocate temp buffer\n"); + return; + } + + for(uint32_t i = 0; i < context->max_frames_in_flight; i++) { + TODO_layouts[i] = texture_mesh_material.object_set_layout; + } + + VkDescriptorSetAllocateInfo TODO_alloc = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, + .descriptorPool = TODO_pool, + .descriptorSetCount = context->max_frames_in_flight, + .pSetLayouts = TODO_layouts, + }; + + VkDescriptorSet* TODO_sets = malloc(sizeof(VkDescriptorSet)*context->max_frames_in_flight); + if(TODO_sets == 0) { + fprintf(stderr, "failed to allocate temp buffer\n"); + return; + } + + result = vkAllocateDescriptorSets(context->device, &TODO_alloc, TODO_sets); + if(result != VK_SUCCESS) { + fprintf(stderr, "failed to allocate TODO descriptors\n"); + return; + } + + Object triangle_object_textured = create_renderable(&triangle_mesh_textured, &texture_mesh_material, 1, TODO_sets, context->max_frames_in_flight); + if(triangle_object_textured.attributes.buckets == 0) { + fprintf(stderr, "failed to create renderable textured triangle object\n"); + return; + } + + Position* position = malloc(sizeof(Position)); + if(position == 0) { + return; + } + glm_quat_identity(position->rotation); + position->scale[0] = 1.f; + position->scale[1] = 1.f; + position->scale[2] = 1.f; + position->position[0] = 0.0f; + position->position[1] = 0.0f; + position->position[2] = 1.0f; + map_result = map_add(&triangle_object_textured.attributes, ATTRIBUTE_ID_POSITION, position); + if(map_result == 0) { + return; + } + + AllocatedBuffer* triangle_ubos = allocate_buffers(context->memories, context->device, sizeof(struct ModelUBO), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, context->max_frames_in_flight); + if(triangle_ubos == 0) { + return; + } + + MaybeValue maybe_descriptors = map_lookup(triangle_object_textured.attributes, ATTRIBUTE_ID_DESCRIPTORS); + if(maybe_descriptors.has_value == false) { + return; + } + + void*** descriptors = maybe_descriptors.value; + + for(uint32_t i = 0; i < context->max_frames_in_flight; i++) { + VkResult result = vkMapMemory(context->device, triangle_ubos[i].memory, 0, sizeof(struct ModelUBO), 0, &descriptors[i][0]); + if(result != VK_SUCCESS) { + return; + } + + VkDescriptorBufferInfo buffer_info = { + .buffer = triangle_ubos[i].buffer, + .offset = 0, + .range = sizeof(struct ModelUBO), + }; + + VkWriteDescriptorSet write_info = { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .dstSet = TODO_sets[i], + .dstBinding = 1, + .dstArrayElement = 0, + .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + .descriptorCount = 1, + .pBufferInfo = &buffer_info, + }; + + vkUpdateDescriptorSets(context->device, 1, &write_info, 0, 0); + } + + VkExtent2D texture_size = { + .width = 10, + .height = 10, + }; + struct __attribute__((__packed__)) texel { + uint8_t r; + uint8_t g; + uint8_t b; + uint8_t a; + }; + + struct texel WHT = {255, 255, 255, 255}; + struct texel BLK = {0, 0, 0, 255}; + struct texel RED = {255, 0, 0, 255}; + struct texel GRN = {0, 255, 0, 255}; + struct texel BLU = {0, 0, 255, 255}; + + struct texel texture_data[100] = { + RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, BLK, + RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, BLK, + RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, WHT, + RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, WHT, + RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, BLK, + RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, BLK, + RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, WHT, + RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, WHT, + RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, BLK, + RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, BLK, + }; + + Texture test_texture = load_texture(context->memories, context->device, context->transfer_command_pool, context->queues.transfer, texture_size, 4, VK_FORMAT_R8G8B8A8_SRGB, texture_data); + + for(uint32_t i = 0; i < context->max_frames_in_flight; i++) { + VkDescriptorImageInfo image_info = { + .sampler = test_texture.sampler, + .imageView = test_texture.view, + .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + }; + + VkWriteDescriptorSet descriptor_write = {}; + descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descriptor_write.dstSet = TODO_sets[i]; + descriptor_write.dstBinding = 0; + descriptor_write.dstArrayElement = 0; + descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + descriptor_write.descriptorCount = 1; + descriptor_write.pBufferInfo = 0; + descriptor_write.pImageInfo = &image_info; + descriptor_write.pTexelBufferView = 0; + + vkUpdateDescriptorSets(context->device, 1, &descriptor_write, 0, 0); + } + + Object* objects[] = {&triangle_object_textured, &triangle_object}; + Material materials[] = {texture_mesh_material, simple_mesh_material}; + uint32_t objects_counts[] = {1, 1}; + context->current_frame = 0; while(!glfwWindowShouldClose(window)) { glfwPollEvents(); - VkResult result = draw_frame(context); + VkResult result = draw_frame(context, &scene, 2, materials, objects_counts, objects); if(result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR) { recreate_swap_chain(context); } else if(result != VK_SUCCESS) {