Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Aby odczytać dane z procesora GPU (na przykład w celu przechwycenia zrzutu ekranu), użyj sterty readback. Ta technika jest związana z przekazywanie danych tekstury za pośrednictwem buforu, z kilkoma różnicami.
- Aby odczytać dane z powrotem, należy utworzyć stertę z D3D12_HEAP_TYPE ustawioną na D3D12_HEAP_TYPE_READBACK, zamiast D3D12_HEAP_TYPE_UPLOAD.
- Zasób na stercie odczytu z powrotem musi zawsze być D3D12_RESOURCE_DIMENSION_BUFFER.
- Za pomocą ogrodzenia można wykryć, kiedy procesor GPU ukończy przetwarzanie ramki (po zakończeniu zapisywania danych w buforze wyjściowym). Jest to ważne, ponieważ metoda ID3D12Resource::Map nie synchronizuje się z procesorem GPU (z kolei równoważna Direct3D 11 wykonuje synchronizację). Wywołania map Map direct3D 12 zachowują się tak, jakby wywołano odpowiednik Direct3D 11 z flagą NO_OVERWRITE.
- Gdy dane będą gotowe (w tym wszelkie niezbędne bariery zasobów), wywołaj metodę ID3D12Resource::Map, aby dane odczytu zwrotnego widoczne dla procesora CPU.
Przykład kodu
Poniższy przykład kodu przedstawia ogólny zarys procesu odczytywania danych z procesora GPU do procesora CPU za pośrednictwem buforu.
// 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
);
Aby uzyskać pełną implementację procedury zrzutu ekranu, która odczytuje teksturę docelową renderowania i zapisuje ją na dysku jako plik, zobacz zestaw narzędzi DirectX dla zestawu narzędzi DX12ScreenGrab.
Tematy pokrewne
- podlokalizacja w buforu