Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Pour lire des données à partir du GPU (par exemple, pour capturer une capture d’écran), vous utilisez un tas de lecture différé. Cette technique est liée à chargement de données de texture via unde mémoire tampon, avec quelques différences.
- Pour lire les données de retour, vous créez un tas avec le D3D12_HEAP_TYPE défini sur D3D12_HEAP_TYPE_READBACK, au lieu de D3D12_HEAP_TYPE_UPLOAD.
- La ressource sur le tas en lecture-arrière doit toujours être une D3D12_RESOURCE_DIMENSION_BUFFER.
- Vous utilisez une clôture pour détecter quand le GPU termine le traitement d’une trame (lorsqu’il est terminé d’écrire des données dans votre mémoire tampon de sortie). Cela est important, car la méthode ID3D12Resource ::Map ne se synchronise pas avec le GPU (à l’inverse, l’équivalent Direct3D 11 ne se synchronise). Direct3D 12 Mapper les appels se comportent comme si vous avez appelé l’équivalent Direct3D 11 avec l’indicateur NO_OVERWRITE.
- Une fois les données prêtes (y compris toute barrière de ressource nécessaire), appelez ID3D12Resource ::Map pour rendre les données de lecture visibles par l’UC.
Exemple de code
L’exemple de code ci-dessous montre le plan général du processus de lecture des données du GPU vers l’UC via une mémoire tampon.
// 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
);
Pour une implémentation complète d’une routine de capture d’écran qui lit la texture cible de rendu et l’écrit sur le disque en tant que fichier, consultez Kit d’outils DirectX pour DX12's ScreenGrab.
Rubriques connexes
- sous-allocation dans un de mémoire tampon