diff --git a/src/main.c b/src/main.c index 1a9a773..36345ed 100644 --- a/src/main.c +++ b/src/main.c @@ -123,11 +123,11 @@ typedef struct PipelineLayoutStruct { } PipelineLayout; typedef struct MeshStruct { - uint32_t vertex_count; - AllocatedBuffer vertex_buffer; + uint32_t vertex_count; + VkBuffer vertex_buffer; - uint32_t index_count; - AllocatedBuffer index_buffer; + uint32_t index_count; + VkBuffer index_buffer; } Mesh; typedef struct MaterialStruct { @@ -1741,11 +1741,11 @@ void command_draw_object(Material material, Object object, uint32_t frame_num, V Mesh* mesh = maybe_mesh.value; - VkBuffer vertex_buffers[] = {mesh->vertex_buffer.buffer}; + VkBuffer vertex_buffers[] = {mesh->vertex_buffer}; VkDeviceSize offsets[] = {0}; vkCmdBindVertexBuffers(command_buffer, 0, 1, vertex_buffers, offsets); - vkCmdBindIndexBuffer(command_buffer, mesh->index_buffer.buffer, 0, VK_INDEX_TYPE_UINT16); + vkCmdBindIndexBuffer(command_buffer, mesh->index_buffer, 0, VK_INDEX_TYPE_UINT16); if(material.object_set_layout != VK_NULL_HANDLE) { MaybeValue maybe_descriptors = map_lookup(object.attributes, ATTRIBUTE_ID_DESCRIPTOR_SETS); @@ -1883,33 +1883,6 @@ VkFence* create_fences(VkDevice device, VkFenceCreateFlags flags, uint32_t count return fences; } -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) { - 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 0; - } - - 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); - return 0; - } - - Mesh* mesh = malloc(sizeof(Mesh)); - if(mesh == 0) { - deallocate_buffer(device, vertex_buffer); - deallocate_buffer(device, index_buffer); - return 0; - } - - mesh->vertex_buffer = vertex_buffer; - mesh->vertex_count = vertex_count; - mesh->index_buffer = index_buffer; - mesh->index_count = index_count; - - return mesh; -} - Object create_object(uint32_t max_frames_in_flight, uint32_t descriptor_count) { Object ret = { .attributes = { @@ -1990,33 +1963,6 @@ Object create_renderable(Mesh* mesh, Material* material, uint32_t descriptor_set return object; } -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) { - 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 0; - } - - 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); - return 0; - } - - Mesh* mesh = malloc(sizeof(Mesh)); - if(mesh == 0) { - deallocate_buffer(device, vertex_buffer); - deallocate_buffer(device, index_buffer); - return 0; - } - - mesh->vertex_buffer = vertex_buffer; - mesh->vertex_count = vertex_count; - mesh->index_buffer = index_buffer; - mesh->index_count = index_count; - - return mesh; -} - Material create_material( VkDevice device, VkExtent2D extent, @@ -2357,7 +2303,8 @@ Material create_texture_mesh_material(VkDevice device, VkExtent2D extent, VkRend typedef struct MemoryChunkStruct { VkDeviceMemory memory; - VkDeviceSize free; + VkDeviceSize used; + VkDeviceSize allocated; } MemoryChunk; VkResult allocate_memory_chunk(uint32_t memory_type, VkDevice device, VkDeviceSize size, MemoryChunk* allocated) { @@ -2376,7 +2323,8 @@ VkResult allocate_memory_chunk(uint32_t memory_type, VkDevice device, VkDeviceSi return result; } - allocated->free = size; + allocated->used = 0; + allocated->allocated = size; return VK_SUCCESS; } @@ -2420,19 +2368,23 @@ VkResult create_image(MemoryChunk* memory, VkDevice device, VkDeviceSize offset, VkMemoryRequirements memory_requirements; vkGetImageMemoryRequirements(device, *image, &memory_requirements); - memory->free -= memory_requirements.size; + memory->used += memory_requirements.size; return VK_SUCCESS; } -VkResult create_buffer(MemoryChunk* memory, VkDevice device, VkDeviceSize offset, VkDeviceSize size, VkBufferUsageFlags usage, VkBuffer* buffer) { +VkResult create_buffer(MemoryChunk* memory, VkDevice device, VkDeviceSize size, VkBufferUsageFlags usage, VkBuffer* buffer) { if(buffer == NULL) { + fprintf(stderr, "buffer is null\n"); return VK_ERROR_UNKNOWN; } else if (*buffer != VK_NULL_HANDLE) { + fprintf(stderr, "buffer has value\n"); return VK_ERROR_UNKNOWN; } else if (memory == NULL) { + fprintf(stderr, "memory is null\n"); return VK_ERROR_UNKNOWN; - } else if (memory->free < size) { + } else if ((memory->allocated - memory->used) < size) { + fprintf(stderr, "memory has not enough space\n"); return VK_ERROR_UNKNOWN; } @@ -2445,24 +2397,26 @@ VkResult create_buffer(MemoryChunk* memory, VkDevice device, VkDeviceSize offset VkResult result = vkCreateBuffer(device, &buffer_info, 0, buffer); if(result != VK_SUCCESS) { + fprintf(stderr, "vkCreateBuffer returned %d\n", result); return result; } VkMemoryRequirements memory_requirements; vkGetBufferMemoryRequirements(device, *buffer, &memory_requirements); - result = vkBindBufferMemory(device, *buffer, memory->memory, offset); + result = vkBindBufferMemory(device, *buffer, memory->memory, memory->used); if(result != VK_SUCCESS) { vkDestroyBuffer(device, *buffer, 0); *buffer = VK_NULL_HANDLE; + fprintf(stderr, "vkBindBufferMemory returned %d\n", result); return result; } - memory->free -= size; + memory->used += size; return VK_SUCCESS; } -VkResult create_buffers(MemoryChunk* memory, VkDevice device, VkDeviceSize offset, VkDeviceSize size, VkBufferUsageFlags usage, VkBuffer** buffers, uint32_t count) { +VkResult create_buffers(MemoryChunk* memory, VkDevice device, VkDeviceSize size, VkBufferUsageFlags usage, VkBuffer** buffers, uint32_t count) { if(buffers == NULL) { return VK_ERROR_UNKNOWN; } else if(*buffers == NULL) { @@ -2475,7 +2429,7 @@ VkResult create_buffers(MemoryChunk* memory, VkDevice device, VkDeviceSize offse } for(uint32_t i = 0; i < count; i++) { - VkResult result = create_buffer(memory, device, offset + (i*size), size, usage, &(*buffers)[i]); + VkResult result = create_buffer(memory, device, size, usage, &(*buffers)[i]); if(result != VK_SUCCESS) { for(uint32_t j = 0; j < i; j++) { vkDestroyBuffer(device, *buffers[j], 0); @@ -2560,10 +2514,50 @@ VkResult command_copy_to_buffer(VkDevice device, VkBuffer staging_buffer, VkDevi vkCmdCopyBuffer(command_buffer, staging_buffer, destination, 1, ®ion); result = command_end_single(device, command_buffer, pool, queue); - vkDestroyBuffer(device, staging_buffer, 0); return result; } +Mesh* load_mesh_to_buffer(VkDevice device, MemoryChunk* memory, VkBuffer staging_buffer, VkDeviceMemory staging_memory, uint32_t vertex_count, uint32_t vertex_stride, void* vertex_data, uint32_t index_count, uint32_t index_stride, void* index_data, VkCommandPool pool, VkQueue queue) { + VkBuffer vertex_buffer = VK_NULL_HANDLE; + VkBuffer index_buffer = VK_NULL_HANDLE; + + VkResult result = create_buffer(memory, device, vertex_count*vertex_stride, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, &vertex_buffer); + if(result != VK_SUCCESS) { + fprintf(stderr, "Failed to create vertex buffer\n"); + return NULL; + } + + result = create_buffer(memory, device, sizeof(uint16_t)*index_count, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, &index_buffer); + if(result != VK_SUCCESS) { + fprintf(stderr, "Failed to create index buffer\n"); + return NULL; + } + + result = command_copy_to_buffer(device, staging_buffer, staging_memory, vertex_buffer, vertex_data, vertex_count*vertex_stride, 0, pool, queue); + if(result != VK_SUCCESS) { + fprintf(stderr, "Failed to copy to vertex buffer\n"); + return NULL; + } + + result = command_copy_to_buffer(device, staging_buffer, staging_memory, index_buffer, index_data, index_stride*index_count, 0, pool, queue); + if(result != VK_SUCCESS) { + fprintf(stderr, "Failed to copy to index buffer\n"); + return NULL; + } + + Mesh* mesh = malloc(sizeof(Mesh)); + if(mesh == NULL) { + return NULL; + } + + mesh->vertex_buffer = vertex_buffer; + mesh->vertex_count = vertex_count; + mesh->index_buffer = index_buffer; + mesh->index_count = index_count; + + return mesh; +} + VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) { VulkanContext* context = (VulkanContext*)malloc(sizeof(VulkanContext)); @@ -3207,7 +3201,25 @@ VkResult draw_frame(VulkanContext* context, SceneContext* scene, uint32_t materi Object create_simple_mesh_object(Material* simple_mesh_material, VkPhysicalDeviceMemoryProperties memories, VkDevice device, VkCommandPool transfer_pool, VkQueue transfer_queue, uint32_t max_frames_in_flight, VkDescriptorPool pool) { Object zero = {}; - Mesh* mesh = load_simple_mesh(memories, device, (struct Vertex*)vertices, 4, (uint16*)indices, 6, transfer_pool, transfer_queue); + MemoryChunk mesh_memory = {0}; + VkResult result = allocate_memory_chunk(0, device, 10000, &mesh_memory); + if(result != VK_SUCCESS) { + return zero; + } + + MemoryChunk transfer_memory = {0}; + result = allocate_memory_chunk(2, device, 10000, &transfer_memory); + if(result != VK_SUCCESS) { + return zero; + } + + VkBuffer transfer_buffer = VK_NULL_HANDLE; + result = create_buffer(&transfer_memory, device, 10000, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, &transfer_buffer); + if(result != VK_SUCCESS) { + return zero; + } + + Mesh* mesh = load_mesh_to_buffer(device, &mesh_memory, transfer_buffer, transfer_memory.memory, 4, sizeof(struct Vertex), (void*)vertices, 6, sizeof(uint16_t), (void*)indices, transfer_pool, transfer_queue); if(mesh == 0) { return zero; } @@ -3233,7 +3245,7 @@ Object create_simple_mesh_object(Material* simple_mesh_material, VkPhysicalDevic return zero; } - VkResult result = vkAllocateDescriptorSets(device, &allocation_info, sets); + result = vkAllocateDescriptorSets(device, &allocation_info, sets); if(result != VK_SUCCESS) { return zero; } @@ -3301,7 +3313,25 @@ Object create_simple_mesh_object(Material* simple_mesh_material, VkPhysicalDevic Object create_texture_mesh_object(Material* texture_mesh_material, VkPhysicalDeviceMemoryProperties memories, VkDevice device, VkCommandPool transfer_pool, VkQueue transfer_queue, VkCommandPool graphics_pool, VkQueue graphics_queue, uint32_t max_frames_in_flight, VkDescriptorPool pool, uint32_t transfer_family, uint32_t graphics_family) { Object zero = {}; - Mesh* mesh = load_texture_mesh(memories, device, (struct TextureVertex*)texture_vertices, 4, (uint16_t*)indices, 6, transfer_pool, transfer_queue); + MemoryChunk mesh_memory = {0}; + VkResult result = allocate_memory_chunk(0, device, 10000, &mesh_memory); + if(result != VK_SUCCESS) { + return zero; + } + + MemoryChunk transfer_memory = {0}; + result = allocate_memory_chunk(2, device, 10000, &transfer_memory); + if(result != VK_SUCCESS) { + return zero; + } + + VkBuffer transfer_buffer = VK_NULL_HANDLE; + result = create_buffer(&transfer_memory, device, 10000, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, &transfer_buffer); + if(result != VK_SUCCESS) { + return zero; + } + + Mesh* mesh = load_mesh_to_buffer(device, &mesh_memory, transfer_buffer, transfer_memory.memory, 4, sizeof(struct TextureVertex), (void*)texture_vertices, 6, sizeof(uint16_t), (void*)indices, transfer_pool, transfer_queue); if(mesh == 0) { return zero; } @@ -3327,7 +3357,7 @@ Object create_texture_mesh_object(Material* texture_mesh_material, VkPhysicalDev return zero; } - VkResult result = vkAllocateDescriptorSets(device, &allocation_info, sets); + result = vkAllocateDescriptorSets(device, &allocation_info, sets); if(result != VK_SUCCESS) { return zero; }