Lecture #16. Resource copying

Computer graphics in Game development

Ivan Belyavtsev

02.12.2022

Current version

THROW_IF_FAILED(device->CreateCommittedResource(
        &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
// ...
        IID_PPV_ARGS(&vertex_buffers[s])));

UINT8* vertex_data_begin;
CD3DX12_RANGE read_range(0, 0);
THROW_IF_FAILED(vertex_buffers[s]->Map(0, &read_range, reinterpret_cast<void **>(&vertex_data_begin)));
memcpy(vertex_data_begin, vertex_buffer_data->get_data(), vertex_buffer_size);
vertex_buffers[s]->Unmap(0, nullptr);

The issue

Upload heap type has CPU access optimized for uploading to the GPU, but does not experience the maximum amount of bandwidth for the GPU. Resources in this heap must be created with D3D12_RESOURCE_STATE_GENERIC_READ and cannot be changed away from this [1]

Solution

  1. Create a two resources: one on upload heap and one on default heap
  2. Use UpdateSubresources function to load data to the upload heap resource and then copy it to the default heap resource
  3. Insert a transition resource barrier to setup correct state for the default heap resource

Resource creation

THROW_IF_FAILED(device->CreateCommittedResource(
    &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
// ...
    D3D12_RESOURCE_STATE_GENERIC_READ, nullptr,
    IID_PPV_ARGS(&upload_vertex_buffer[s])));

THROW_IF_FAILED(device->CreateCommittedResource(
    &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
// ...
    D3D12_RESOURCE_STATE_COPY_DEST, nullptr,
    IID_PPV_ARGS(&vertex_buffer[s])));

UpdateSubresource

D3D12_SUBRESOURCE_DATA vertex_data{};
vertex_data.pData = vertex_buffer_data->get_data();
vertex_data.RowPitch = vertex_buffer_size;
vertex_data.SlicePitch = vertex_buffer_size;

UpdateSubresources(
    command_list.Get(), vertex_buffer[s].Get(),
    upload_vertex_buffer[s].Get(), 0, 0, 1, &vertex_data);

Resource barriers

command_list->ResourceBarrier(
    1, &CD3DX12_RESOURCE_BARRIER::Transition(
    vertex_buffer[s].Get(), D3D12_RESOURCE_STATE_COPY_DEST,
    D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER));
// Or D3D12_RESOURCE_STATE_INDEX_BUFFER for index buffers

Don’t forget about executing the command list before

References

1.
Satran M. et al. Direct3D 12 programming guide [Electronic resource]. 2019. URL: https://docs.microsoft.com/en-us/windows/win32/direct3d12/directx-12-programming-guide.