Skip to content

Removing VkPhysicalDeviceMemoryProperties as a dependency of object construction #57

Description

@mrparmesan01

When creating any Vulkan handles for buffers and images. Where it was a requirement to pass the VkPhysicalDeviceMemoryProperties struct for each construction parameter.

This task is to remove all of the need of passing that particular struct and instead pass two parameters for allocation size and the memory index.

API Previously

These API's have to perform redundant calculation everytime to when configured. Which is something that I would like to alleviate to not be needed to do.

Buffer Usage for VkPhysicalDeviceMemoryProperties

For buffer handles, these are the logic

buffer_parameters staging_buffer_params = {
    .physical_memory_properties =p_vertex_info.phsyical_memory_properties, // Removing this
    .property_flags = static_cast<memory_property>(memory_property::host_visible_bit | memory_property::host_cached_bit),
    .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
};

// which under the hood in vk::buffer_streams would contain this logic for every creation
VkMemoryRequirements memory_requirements = {};
vkGetBufferMemoryRequirements(p_device, m_handle, &memory_requirements);

// 3. selects the required memory requirements for this specific
// buffer allocations
uint32_t memory_index = select_memory_requirements(p_params.physical_memory_properties,
                                          memory_requirements,
                                          p_params.property_flags);

// 4. allocatring the necessary memory based on memory
// requirements for the buffer handles
VkMemoryAllocateInfo memory_alloc_info = {
    .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
    .allocationSize = memory_requirements.size,
    .memoryTypeIndex = memory_index
};

Image Usage for VkPhysicalDeviceMemoryProperties

vk::image_params swapchain_image_config = {
    .extent = {
        .width = swapchain_extent.width,
        .height = swapchain_extent.height
    },
    .format = surface_properties.format.format,
    .aspect = vk::image_aspect_flags::color_bit,
    .usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
    .mip_levels = 1,
    .layer_count = 1,
    .phsyical_memory_properties = physical_device.memory_properties(), // Removing this!
};

VkMemoryRequirements memory_requirements;
vkGetImageMemoryRequirements(p_device, m_image, &memory_requirements);

uint32_t memory_index = select_memory_requirements(p_image_properties.phsyical_memory_properties,
                                          memory_requirements,
                                          p_image_properties.property);

VkMemoryAllocateInfo memory_alloc_info = {
    .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
    .pNext = nullptr,
    .allocationSize = memory_requirements.size,
    .memoryTypeIndex = memory_index
};

New API Proposal

These only needed to be created once beforehand. This then can just be passed or rely on the vk::device to provide external information on how it may need to be allocated for that specific handles.

const auto property_flags = static_cast<memory_property>(memory_property::host_visible_bit | memory_property::host_cached_bit);

// Used by buffer handles
vk::allocation_params buffer_allocation_params = logical_device.buffer_memory_properties(property_flags);

// Used by image handles
vk::allocation_params image_allocation_params = logical_device.image_memory_properties(property_flags);

Buffer Handle Newer API Configurations

buffer_parameters staging_buffer_params = {
    // .physical_memory_properties =p_vertex_info.phsyical_memory_properties, // Removing this
    .allocation_size = buffer_allocation_params.size,
    .memory_index = buffer_allocation_params.memory_index,
    .property_flags = static_cast<memory_property>(memory_property::host_visible_bit | memory_property::host_cached_bit),
    .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
};

Image Handle Newer API Configurations

vk::image_params swapchain_image_config = {
    .extent = {
        .width = swapchain_extent.width,
        .height = swapchain_extent.height
    },
    .format = surface_properties.format.format,
    .aspect = vk::image_aspect_flags::color_bit,
    .usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
    .mip_levels = 1,
    .layer_count = 1,
    // .phsyical_memory_properties = physical_device.memory_properties(), // Removing this!
    .allocation_size = image_allocation_params.size,
    .memory_index = image_allocation_params.memory_index,
};

What does task completion look like?

To get this task completion working. I should be able to see a single source for performing the operation to getting the memory properties from the logical device. Specifically from vk::device as shown in the newer API's section.

Which should be able to be passed to other buffer/image handles correctly. The behavior of configuring those handles should still work the same they have been. The only changes is removing the memory_properties parameter to be replaced.

Metadata

Metadata

Assignees

No one assigned

    Labels

    💠coreCritical tasks are reserved for maintainers during fundamental architectural changes.💳 Tech DebtTasks that have some kind of user API tech debt

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions