src/core/VulkanDevice.cpp
VkResult VulkanDevice::createBuffer(VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags,
                                    Buffer *buffer, VkDeviceSize size, void *data) {
    buffer->device = logicalDevice;

    // Create the buffer handle
    VkBufferCreateInfo bufferCreateInfo = Populate::bufferCreateInfo(usageFlags, size);
    if (vkCreateBuffer(logicalDevice, &bufferCreateInfo, nullptr, &buffer->buffer) != VK_SUCCESS)
        throw std::runtime_error("Failed to create Buffer");

    // Create the memory backing up the buffer handle
    VkMemoryRequirements memReqs;
    VkMemoryAllocateInfo memAlloc = Populate::memoryAllocateInfo();
    vkGetBufferMemoryRequirements(logicalDevice, buffer->buffer, &memReqs);
    memAlloc.allocationSize = memReqs.size;
    // Find a memory type index that fits the properties of the buffer
    memAlloc.memoryTypeIndex = getMemoryType(memReqs.memoryTypeBits, memoryPropertyFlags);
    // If the buffer has VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT set we also need to enable the appropriate flag during allocation
    VkMemoryAllocateFlagsInfoKHR allocFlagsInfo{};
    if (usageFlags & VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT) {
        allocFlagsInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO_KHR;
        allocFlagsInfo.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR;
        memAlloc.pNext = &allocFlagsInfo;
    }
    if (vkAllocateMemory(logicalDevice, &memAlloc, nullptr, &buffer->memory) != VK_SUCCESS)
        throw std::runtime_error("Failed to allocate memory");

    buffer->alignment = memReqs.alignment;
    buffer->size = size;
    buffer->usageFlags = usageFlags;
    buffer->memoryPropertyFlags = memoryPropertyFlags;

    // If a pointer to the buffer data has been passed, map the buffer and copy over the data
    if (data != nullptr) {
        if (buffer->map() != VK_SUCCESS) throw std::runtime_error("Failed to map buffer");
        memcpy(buffer->mapped, data, size);
        if ((memoryPropertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) == 0)
            buffer->flush();

        buffer->unmap();
    }

    // Initialize a default descriptor that covers the whole buffer size
    buffer->setupDescriptor();

    // Attach the memory to the buffer object
    return buffer->bind();
}
/**
* Create a buffer on the device
*
* @param usageFlags Usage flag bit mask for the buffer (i.e. index, vertex, uniform buffer)
* @param memoryPropertyFlags Memory properties for this buffer (i.e. device local, host visible, coherent)
* @param buffer Pointer to a vk::Vulkan buffer object
* @param size Size of the buffer in bytes
* @param data Pointer to the data that should be copied to the buffer after creation (optional, if not set, no data is copied over)
*
* @return VK_SUCCESS if buffer handle and memory have been created and (optionally passed) data has been copied
*/
Create a buffer on the device
Create a buffer on the device
VkResult VulkanDevice::createBuffer(VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags,
                                    Buffer *buffer, VkDeviceSize size, void *data) {
    buffer->device = logicalDevice;
    VkBufferCreateInfo bufferCreateInfo = Populate::bufferCreateInfo(usageFlags, size);
    if (vkCreateBuffer(logicalDevice, &bufferCreateInfo, nullptr, &buffer->buffer) != VK_SUCCESS)
        throw std::runtime_error("Failed to create Buffer");
    VkMemoryRequirements memReqs;
    VkMemoryAllocateInfo memAlloc = Populate::memoryAllocateInfo();
    vkGetBufferMemoryRequirements(logicalDevice, buffer->buffer, &memReqs);
    memAlloc.allocationSize = memReqs.size;
    memAlloc.memoryTypeIndex = getMemoryType(memReqs.memoryTypeBits, memoryPropertyFlags);
    VkMemoryAllocateFlagsInfoKHR allocFlagsInfo{};
    if (usageFlags & VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT) {
        allocFlagsInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO_KHR;
        allocFlagsInfo.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR;
        memAlloc.pNext = &allocFlagsInfo;
    }
    if (vkAllocateMemory(logicalDevice, &memAlloc, nullptr, &buffer->memory) != VK_SUCCESS)
        throw std::runtime_error("Failed to allocate memory");
    buffer->alignment = memReqs.alignment;
    buffer->size = size;
    buffer->usageFlags = usageFlags;
    buffer->memoryPropertyFlags = memoryPropertyFlags;
    if (data != nullptr) {
        if (buffer->map() != VK_SUCCESS) throw std::runtime_error("Failed to map buffer");
        memcpy(buffer->mapped, data, size);
        if ((memoryPropertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) == 0)
            buffer->flush();
        buffer->unmap();
    }
    buffer->setupDescriptor();
    return buffer->bind();
}
VkResult VulkanDevice :: createBuffer ( VkBufferUsageFlags usageFlags , VkMemoryPropertyFlags memoryPropertyFlags , Buffer * buffer , VkDeviceSize size , void * data ) { buffer -> device = logicalDevice ; VkBufferCreateInfo bufferCreateInfo = Populate :: bufferCreateInfo ( usageFlags , size ) ; if ( vkCreateBuffer ( logicalDevice , & bufferCreateInfo , nullptr , & buffer -> buffer ) != VK_SUCCESS ) throw std :: runtime_error ( " " ) ; VkMemoryRequirements memReqs ; VkMemoryAllocateInfo memAlloc = Populate :: memoryAllocateInfo ( ) ; vkGetBufferMemoryRequirements ( logicalDevice , buffer -> buffer , & memReqs ) ; memAlloc . allocationSize = memReqs . size ; memAlloc . memoryTypeIndex = getMemoryType ( memReqs . memoryTypeBits , memoryPropertyFlags ) ; VkMemoryAllocateFlagsInfoKHR allocFlagsInfo { } ; if ( usageFlags & VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT ) { allocFlagsInfo . sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO_KHR ; allocFlagsInfo . flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR ; memAlloc . pNext = & allocFlagsInfo ; } if ( vkAllocateMemory ( logicalDevice , & memAlloc , nullptr , & buffer -> memory ) != VK_SUCCESS ) throw std :: runtime_error ( " " ) ; buffer -> alignment = memReqs . alignment ; buffer -> size = size ; buffer -> usageFlags = usageFlags ; buffer -> memoryPropertyFlags = memoryPropertyFlags ; if ( data != nullptr ) { if ( buffer -> map ( ) != VK_SUCCESS ) throw std :: runtime_error ( " " ) ; memcpy ( buffer -> mapped , data , size ) ; if ( ( memoryPropertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT ) == 0 ) buffer -> flush ( ) ; buffer -> unmap ( ) ; } buffer -> setupDescriptor ( ) ; return buffer -> bind ( ) ; }
Create a buffer on the device
Create a buffer on the device
// Create the buffer handle // Create the memory backing up the buffer handle // Find a memory type index that fits the properties of the buffer // If the buffer has VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT set we also need to enable the appropriate flag during allocation // If a pointer to the buffer data has been passed, map the buffer and copy over the data // Initialize a default descriptor that covers the whole buffer size // Attach the memory to the buffer object