Create buffers

In order to render meshes, we will also need to specify the vertex and index data. For this purpose, we need to create one or two buffers and index these buffers during rendering. We are creating this buffer on the host visible heap for simplicity. Ideally we would store the buffer on device-local memory, as this would provide more bandwidth, but we will use the host-visible heap in order to make the code a lot more simple.

result = vkCreateBuffer (
    renderer->device,
    &(VkBufferCreateInfo){
        .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
        .size  = renderer->scene->vertexDataSizeInBytes,
        .usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
    },
    NULL,
    &renderer->vertexBuffer
);
if ( result != VK_SUCCESS )
    RETURN_ERROR(-1, "vkCreateBuffer failed (0x%08X)", (uint32_t)result);

result = vkCreateBuffer (
    renderer->device,
    &(VkBufferCreateInfo){
        .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
        .size  = renderer->scene->indexDataSizeInBytes,
        .usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
    },
    NULL,
    &renderer->indexBuffer
);
if ( result != VK_SUCCESS )
    RETURN_ERROR(-1, "vkCreateBuffer failed (0x%08X)", (uint32_t)result);

VkMemoryRequirements vbMemoryRequirements, ibMemoryRequirements;
vkGetBufferMemoryRequirements ( renderer->device, renderer->vertexBuffer, &vbMemoryRequirements );
vkGetBufferMemoryRequirements ( renderer->device, renderer->indexBuffer, &ibMemoryRequirements );

uint32_t vbTypeIndex = 0xFFFFFFFF, ibTypeIndex = 0xFFFFFFFF;
for ( uint32_t i = 0; i < memoryProperties.memoryTypeCount; i++ )
{
    if ( vbMemoryRequirements.memoryTypeBits & (1 << i)
        && (memoryProperties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) )
    {
        vbTypeIndex = i;
        break;
    }
}
for ( uint32_t i = 0; i < memoryProperties.memoryTypeCount; i++ )
{
    if ( (ibMemoryRequirements.memoryTypeBits & (1 << i))
        && (memoryProperties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) )
    {
        ibTypeIndex = i;
        break;
    }
}
if ( vbTypeIndex == 0xFFFFFFFF || ibTypeIndex == 0xFFFFFFFF )
    RETURN_ERROR(-1, "No compatible memory type found for buffers");

VkDeviceMemory vbDeviceMemory, ibDeviceMemory;
result = vkAllocateMemory (
    renderer->device,
    &(VkMemoryAllocateInfo){
        .sType           = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
        .pNext           = NULL,
        .allocationSize  = vbMemoryRequirements.size,
        .memoryTypeIndex = vbTypeIndex,
    },
    NULL,
    &vbDeviceMemory
);
if ( result != VK_SUCCESS )
    RETURN_ERROR(-1, "vkAllocateMemory failed (0x%08X)", (uint32_t)result);

result = vkAllocateMemory (
    renderer->device,
    &(VkMemoryAllocateInfo){
        .sType           = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
        .pNext           = NULL,
        .allocationSize  = ibMemoryRequirements.size,
        .memoryTypeIndex = ibTypeIndex,
    },
    NULL,
    &ibDeviceMemory
);
if ( result != VK_SUCCESS )
    RETURN_ERROR(-1, "vkAllocateMemory failed (0x%08X)", (uint32_t)result);

result = vkBindBufferMemory (
    renderer->device,
    renderer->vertexBuffer,
    vbDeviceMemory,
    0
);
if ( result != VK_SUCCESS )
    RETURN_ERROR(-1, "vkBindBufferMemory failed (0x%08X)", (uint32_t)result);

result = vkBindBufferMemory (
    renderer->device,
    renderer->indexBuffer,
    ibDeviceMemory,
    0
);
if ( result != VK_SUCCESS )
    RETURN_ERROR(-1, "vkBindBufferMemory failed (0x%08X)", (uint32_t)result);

void* mappedData = NULL;
result = vkMapMemory (
    renderer->device,
    vbDeviceMemory,
    0,
    renderer->scene->vertexDataSizeInBytes,
    0,
    &mappedData
);
if ( result != VK_SUCCESS )
    RETURN_ERROR(-1, "vkMapMemory failed (0x%08X)", (uint32_t)result);
memcpy ( mappedData, renderer->scene->vertexData, renderer->scene->vertexDataSizeInBytes );
vkUnmapMemory ( renderer->device, vbDeviceMemory );

mappedData = NULL;
result = vkMapMemory (
    renderer->device,
    ibDeviceMemory,
    0,
    renderer->scene->indexDataSizeInBytes,
    0,
    &mappedData
);
if ( result != VK_SUCCESS )
    RETURN_ERROR(-1, "vkMapMemory failed (0x%08X)", (uint32_t)result);
memcpy ( mappedData, renderer->scene->indexData, renderer->scene->indexDataSizeInBytes );
vkUnmapMemory ( renderer->device, ibDeviceMemory );