Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Untuk membaca kembali data dari GPU (misalnya, untuk mengambil cuplikan layar), Anda menggunakan timbunan baca balik. Teknik ini terkait dengan Mengunggah data tekstur melalui buffer, dengan beberapa perbedaan.
- Untuk membaca kembali data, Anda membuat timbunan dengan D3D12_HEAP_TYPE diatur ke D3D12_HEAP_TYPE_READBACK, alih-alih D3D12_HEAP_TYPE_UPLOAD.
- Sumber daya pada timbunan read-back harus selalu menjadi D3D12_RESOURCE_DIMENSION_BUFFER.
- Anda menggunakan pagar untuk mendeteksi kapan GPU selesai memproses bingkai (ketika selesai menulis data ke dalam buffer output Anda). Ini penting, karena metode ID3D12Resource::Map tidak disinkronkan dengan GPU (sebaliknya, setara Direct3D 11 tidak disinkronkan). Panggilan Direct3D 12 Map berperilaku seolah-olah Anda memanggil Direct3D 11 yang setara dengan bendera NO_OVERWRITE.
- Setelah data siap (termasuk hambatan sumber daya yang diperlukan), panggil ID3D12Resource::Map untuk membuat data readback terlihat oleh CPU.
Contoh kode
Contoh kode di bawah ini menunjukkan kerangka umum proses membaca kembali data dari GPU ke CPU melalui buffer.
// The output buffer (created below) is on a default heap, so only the GPU can access it.
D3D12_HEAP_PROPERTIES defaultHeapProperties{ CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT) };
D3D12_RESOURCE_DESC outputBufferDesc{ CD3DX12_RESOURCE_DESC::Buffer(outputBufferSize, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS) };
winrt::com_ptr<::ID3D12Resource> outputBuffer;
winrt::check_hresult(d3d12Device->CreateCommittedResource(
&defaultHeapProperties,
D3D12_HEAP_FLAG_NONE,
&outputBufferDesc,
D3D12_RESOURCE_STATE_COPY_DEST,
nullptr,
__uuidof(outputBuffer),
outputBuffer.put_void()));
// The readback buffer (created below) is on a readback heap, so that the CPU can access it.
D3D12_HEAP_PROPERTIES readbackHeapProperties{ CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_READBACK) };
D3D12_RESOURCE_DESC readbackBufferDesc{ CD3DX12_RESOURCE_DESC::Buffer(outputBufferSize) };
winrt::com_ptr<::ID3D12Resource> readbackBuffer;
winrt::check_hresult(d3d12Device->CreateCommittedResource(
&readbackHeapProperties,
D3D12_HEAP_FLAG_NONE,
&readbackBufferDesc,
D3D12_RESOURCE_STATE_COPY_DEST,
nullptr,
__uuidof(readbackBuffer),
readbackBuffer.put_void()));
{
D3D12_RESOURCE_BARRIER outputBufferResourceBarrier
{
CD3DX12_RESOURCE_BARRIER::Transition(
outputBuffer.get(),
D3D12_RESOURCE_STATE_COPY_DEST,
D3D12_RESOURCE_STATE_COPY_SOURCE)
};
commandList->ResourceBarrier(1, &outputBufferResourceBarrier);
}
commandList->CopyResource(readbackBuffer.get(), outputBuffer.get());
// Code goes here to close, execute (and optionally reset) the command list, and also
// to use a fence to wait for the command queue.
// The code below assumes that the GPU wrote FLOATs to the buffer.
D3D12_RANGE readbackBufferRange{ 0, outputBufferSize };
FLOAT * pReadbackBufferData{};
winrt::check_hresult(
readbackBuffer->Map
(
0,
&readbackBufferRange,
reinterpret_cast<void**>(&pReadbackBufferData)
)
);
// Code goes here to access the data via pReadbackBufferData.
D3D12_RANGE emptyRange{ 0, 0 };
readbackBuffer->Unmap
(
0,
&emptyRange
);
Untuk implementasi lengkap rutinitas cuplikan layar yang membaca tekstur target render, dan menulisnya ke disk sebagai file, lihat DirectX Tool Kit untuk DX12ScreenGrab.
Topik terkait
- Suballocation dalam buffer