Skip to content

Add multi-data staging to vk::buffer::transfer support #90

Description

@mrparmesan01

Task Brief

This issue is also a continuation for GitHub issue #43 .

Currently vk::buffer::transfer works well for single arbitrary of data transfers via a single std::span<T>. When needing to perform multiple transfer operations, this API does not handle those complex operations nicely.

Example of this can be noticeable with loading a 6-face skybox. Where we upload individual faces of a skybox or batching texture arrays.

We should extend our API to natively support multiple parts of transfers within a single map/unmap lifecycle.

Proposed Changes

Introducing an overloaded transfer function that accepts any std::ranges::forward_range, where elements can be viewed as a std::span.

Proposal Implementation Changes

template<typename Range> requires std::ranges::forward_range<Range>
void transfer(Range&& p_data, uint64_t p_offset = 0) {
    for(const auto& data : p_data){
        total_size += std::span{data}.size_bytes();
    }

    void* mapped=nullptr;
    vk_check(vkMapMemory(m_device, m_device_memory, total_size, 0, &mapped), "vkMapMemory");

    auto* mapped_bytes = static_cast<uint8_t*>(mapped);
    uint64_t current_offset = 0;
    for(const auto& data : p_data) {
        auto s = std::span{data};
        std::memcpy(mapped_bytes + current_offset, s.data(), s.size_bytes());
        current_offset += s.size_bytes();
    }

    vk_check(vkUnmapMemory(m_device, m_device_memory), "vkUnmapMemory");
}

Advantages

  • Minimize CPU-to-GPU data transfers under a single vkMapMemory/vkUnmapMemory lifecycle.
  • Eliminates manual offset arithmetic (mapped_bytes + offset) in user application logic
  • Using C++20 <ranges> to keep implementation type-safe and standard-container agnostic. (minimal data copying).

Task Completion Expectation

We should be able to perform skybox operations of uploading pixels for all 6 faces under a single vkMapMemory/vkUnmapMemory operation.

It should work as if we are doing the following:

std::array<std::span<const uint8_t>, 6> faces_pixels_data = m_skybox.data();

// write and manage all buffer offsets in one vkMapMemory/vkUnmapMemory lifecycle
staging_buffer.transfer(faces_pixels_data);

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions