Browse Source

Use a staging buffer.

master
Amber 2 years ago
parent
commit
5bcd66fb6b
  1. 81
      src/main.c

81
src/main.c

@ -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, &copy);
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) {

Loading…
Cancel
Save