|
|
|
@ -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;
|
|
|
|
|
}
|
|
|
|
|