|
|
|
@ -910,38 +910,93 @@ uint32_t find_memory_type (ApplicationState* state, uint32_t type_filter, VkMemo
@@ -910,38 +910,93 @@ uint32_t find_memory_type (ApplicationState* state, uint32_t type_filter, VkMemo
|
|
|
|
|
exit(1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void create_vertex_buffer(ApplicationState* state) { |
|
|
|
|
void create_buffer(ApplicationState* state, VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, |
|
|
|
|
VkBuffer* buffer, VkDeviceMemory* memory) { |
|
|
|
|
VkBufferCreateInfo buffer_info = {0}; |
|
|
|
|
buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; |
|
|
|
|
buffer_info.size = sizeof(Vertex) * ARRSIZE(vertices); |
|
|
|
|
buffer_info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; |
|
|
|
|
buffer_info.size = size; |
|
|
|
|
buffer_info.usage = usage; |
|
|
|
|
buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; |
|
|
|
|
|
|
|
|
|
if (vkCreateBuffer(state->device, &buffer_info, NULL, &state->vertex_buffer) != VK_SUCCESS) { |
|
|
|
|
printf("Failed to create vertex buffer\n"); |
|
|
|
|
if (vkCreateBuffer(state->device, &buffer_info, NULL, buffer) != VK_SUCCESS) { |
|
|
|
|
printf("Failed to create buffer\n"); |
|
|
|
|
exit(1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
VkMemoryRequirements mem_req; |
|
|
|
|
vkGetBufferMemoryRequirements(state->device, state->vertex_buffer, &mem_req); |
|
|
|
|
vkGetBufferMemoryRequirements(state->device, *buffer, &mem_req); |
|
|
|
|
|
|
|
|
|
VkMemoryAllocateInfo alloc_info = {0}; |
|
|
|
|
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; |
|
|
|
|
alloc_info.allocationSize = mem_req.size; |
|
|
|
|
alloc_info.memoryTypeIndex = find_memory_type(state, mem_req.memoryTypeBits, |
|
|
|
|
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); |
|
|
|
|
alloc_info.memoryTypeIndex = find_memory_type(state, mem_req.memoryTypeBits, properties); |
|
|
|
|
|
|
|
|
|
if (vkAllocateMemory(state->device, &alloc_info, NULL, &state->vertex_buffer_memory) != VK_SUCCESS) { |
|
|
|
|
if (vkAllocateMemory(state->device, &alloc_info, NULL, memory) != VK_SUCCESS) { |
|
|
|
|
printf("failed to allocate memory for buffer\n"); |
|
|
|
|
exit(1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
vkBindBufferMemory(state->device, state->vertex_buffer, state->vertex_buffer_memory, 0); |
|
|
|
|
vkBindBufferMemory(state->device, *buffer, *memory, 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void copy_buffer(ApplicationState* state, VkBuffer src, VkBuffer dst, VkDeviceSize size) { |
|
|
|
|
VkCommandBufferAllocateInfo command_buf_allocate_info = {0}; |
|
|
|
|
command_buf_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; |
|
|
|
|
command_buf_allocate_info.commandPool = state->commandPool; |
|
|
|
|
command_buf_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; |
|
|
|
|
command_buf_allocate_info.commandBufferCount = 1; |
|
|
|
|
|
|
|
|
|
VkCommandBuffer buffer; |
|
|
|
|
|
|
|
|
|
if (vkAllocateCommandBuffers(state->device, &command_buf_allocate_info, &buffer) != VK_SUCCESS) { |
|
|
|
|
printf("failed to allocated command buffer for transfer\n"); |
|
|
|
|
exit(1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
VkCommandBufferBeginInfo begin_info = {0}; |
|
|
|
|
begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; |
|
|
|
|
begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; |
|
|
|
|
|
|
|
|
|
vkBeginCommandBuffer(buffer, &begin_info); |
|
|
|
|
|
|
|
|
|
VkBufferCopy copy = {0}; |
|
|
|
|
copy.size = size; |
|
|
|
|
vkCmdCopyBuffer(buffer, src, dst, 1, ©); |
|
|
|
|
|
|
|
|
|
vkEndCommandBuffer(buffer); |
|
|
|
|
|
|
|
|
|
VkSubmitInfo submit_info = {0}; |
|
|
|
|
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; |
|
|
|
|
submit_info.commandBufferCount = 1; |
|
|
|
|
submit_info.pCommandBuffers = &buffer; |
|
|
|
|
|
|
|
|
|
vkQueueSubmit(state->graphics_queue, 1, &submit_info, VK_NULL_HANDLE); |
|
|
|
|
vkQueueWaitIdle(state->graphics_queue); |
|
|
|
|
|
|
|
|
|
vkFreeCommandBuffers(state->device, state->commandPool, 1, &buffer); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void create_vertex_buffer(ApplicationState* state) { |
|
|
|
|
VkDeviceSize buffer_size = sizeof(Vertex) * ARRSIZE(vertices); |
|
|
|
|
|
|
|
|
|
//we use a staging buffer for transferring data in order to use a more efficient memory type for the vertex buffer
|
|
|
|
|
VkBuffer staging_buffer; |
|
|
|
|
VkDeviceMemory staging_buffer_memory; |
|
|
|
|
create_buffer(state, buffer_size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, |
|
|
|
|
&staging_buffer, &staging_buffer_memory); |
|
|
|
|
|
|
|
|
|
void* data; |
|
|
|
|
vkMapMemory(state->device, state->vertex_buffer_memory, 0, buffer_info.size, 0, &data); |
|
|
|
|
memcpy(data, vertices, buffer_info.size); |
|
|
|
|
vkUnmapMemory(state->device, state->vertex_buffer_memory); |
|
|
|
|
vkMapMemory(state->device, staging_buffer_memory, 0, buffer_size, 0, &data); |
|
|
|
|
memcpy(data, vertices, buffer_size); |
|
|
|
|
vkUnmapMemory(state->device, staging_buffer_memory); |
|
|
|
|
|
|
|
|
|
create_buffer(state, buffer_size, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, |
|
|
|
|
&state->vertex_buffer, &state->vertex_buffer_memory); |
|
|
|
|
|
|
|
|
|
copy_buffer(state, staging_buffer, state->vertex_buffer, buffer_size); |
|
|
|
|
|
|
|
|
|
vkDestroyBuffer(state->device, staging_buffer, NULL); |
|
|
|
|
vkFreeMemory(state->device, staging_buffer_memory, NULL); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void create_command_buffer(ApplicationState* state) { |
|
|
|
|