ID3D12GraphicsCommandList::ResourceBarrier 方法 (d3d12.h)
通知驅動程式需要同步處理資源的多個存取。
語法
void ResourceBarrier(
[in] UINT NumBarriers,
[in] const D3D12_RESOURCE_BARRIER *pBarriers
);
參數
[in] NumBarriers
類型: UINT
提交的屏障描述數目。
[in] pBarriers
類型:const D3D12_RESOURCE_BARRIER*
屏障描述陣列的指標。
傳回值
無
備註
注意
要用於 D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE 狀態的資源必須以該狀態建立,然後永遠不會從中轉換。 也不會有建立的資源未處於該狀態,而無法轉換成該資源。 如需詳細資訊,請參閱 GitHub 上 DirectX 光線追蹤 (DXR) 功能規格中的 加速結構記憶體限制 。
屏障描述有三種類型:
- D3D12_RESOURCE_TRANSITION_BARRIER - 轉換屏障表示一組子資源在不同的使用方式之間轉換。 呼叫端必須指定子資源使用前後的 。 D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES旗標可用來同時轉換資源中的所有子資源。
- D3D12_RESOURCE_ALIASING_BARRIER - 別名屏障表示兩個不同資源使用量之間的轉換,這些資源會對應到相同的堆積。 應用程式可以同時指定資源前後的 。 請注意,一或兩個資源可以是 Null (,表示任何磚資源都可能導致別名) 。
- D3D12_RESOURCE_UAV_BARRIER - 未排序的存取檢視屏障表示所有 UAV 存取 (讀取或寫入特定資源) 必須先完成, (才能開始讀取或寫入) 。 指定的資源可以是 Null。 不需要在兩個繪製或分派唯讀取 UAV 的呼叫之間插入 UAV 屏障。 此外,如果應用程式知道以任何循序執行 UAV 存取,則不需要在兩個繪製或分派呼叫之間插入 UAV 屏障,以寫入相同的 UAV。 資源可以是 Null (,表示任何 UAV 存取可能需要屏障) 。
如需子資源可以位於的使用狀態原因,請參閱 D3D12_RESOURCE_STATES 列舉和 使用資源屏障在 Direct3D 12 中同步處理資源狀態 一節。
呼叫 ID3D12GraphicsCommandList::D iscardResource 時,資源中的所有子資源都必須處於RENDER_TARGET狀態或DEPTH_WRITE狀態,才能分別轉譯目標/深度樣板資源。
出現後端緩衝區時,它必須處於D3D12_RESOURCE_STATE_PRESENT狀態。 如果在不在 PRESENT 狀態的資源上呼叫 IDXGISwapChain1::P resent1 ,將會發出偵錯層警告。
資源使用量位分為兩個類別:唯讀和讀取/寫入。
下列使用位是唯讀的:
- D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER
- D3D12_RESOURCE_STATE_INDEX_BUFFER
- D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE
- D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE
- D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT
- D3D12_RESOURCE_STATE_COPY_SOURCE
- D3D12_RESOURCE_STATE_DEPTH_READ
- D3D12_RESOURCE_STATE_UNORDERED_ACCESS
- D3D12_RESOURCE_STATE_DEPTH_WRITE
- D3D12_RESOURCE_STATE_COPY_DEST
- D3D12_RESOURCE_STATE_RENDER_TARGET
- D3D12_RESOURCE_STATE_STREAM_OUT
在任何指定的時間,子資源都只處於一種狀態, (由一組旗標所決定) 。 應用程式必須在進行一連串 的 ResourceBarrier 呼叫時,確保狀態相符。 換句話說, 連續呼叫 ResourceBarrier 的前後狀態必須同意。
若要轉換資源內的所有子資源,應用程式可以將子資源索引設定為 D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,這表示所有子資源都會變更。
為了提升效能,應用程式應該使用分割屏障 (參考 多引擎同步 處理) 。 您的應用程式也應該盡可能將多個轉換批次處理成單一呼叫。
執行時間驗證
執行時間會驗證屏障類型值是否為 D3D12_RESOURCE_BARRIER_TYPE 列舉的有效成員。此外,執行時間會檢查下列各項:
- 資源指標為非 Null。
- 子資源索引有效
- 資源 D3D12_RESOURCE_BINDING_TIER 和 D3D12_RESOURCE_FLAGS 旗標支援狀態前後的 。
- 未設定狀態遮罩中的保留位。
- 之前和之後的狀態不同。
- 狀態前後的位集合有效。
- 如果已設定D3D12_RESOURCE_STATE_RESOLVE_SOURCE位,則資源樣本計數必須大於 1。
- 如果已設定D3D12_RESOURCE_STATE_RESOLVE_DEST位,則資源範例計數必須等於 1。
針對 UAV 屏障,執行時間會驗證資源是否為非 Null,則資源已設定D3D12_RESOURCE_STATE_UNORDERED_ACCESS系結旗標。
驗證失敗會導致 ID3D12GraphicsCommandList::Close 傳回E_INVALIDARG。
偵錯層
偵錯層通常會發出運行時驗證失敗的錯誤:- 如果命令清單中的子資源轉換與相同命令清單中的先前轉換不一致。
- 如果使用資源而不先呼叫 ResourceBarrier ,將資源放入正確的狀態。
- 如果資源不合法地同時系結讀取和寫入。
- 如果傳遞至ResourceBarrier之前的狀態不符合先前呼叫ResourceBarrier的後置狀態,包括別名案例。
偵錯層會在下列情況下發出警告:
- 所有 D3D12 偵錯層都會發出 ID3D12GraphicsCommandList::ResourceBarrier的警告。
- 如果深度緩衝區用於非唯讀模式,而資源已設定D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE使用量位。
範例
D3D12HelloTriangle範例使用ID3D12GraphicsCommandList::ResourceBarrier,如下所示:
D3D12_VIEWPORT m_viewport;
D3D12_RECT m_scissorRect;
ComPtr<IDXGISwapChain3> m_swapChain;
ComPtr<ID3D12Device> m_device;
ComPtr<ID3D12Resource> m_renderTargets[FrameCount];
ComPtr<ID3D12CommandAllocator> m_commandAllocator;
ComPtr<ID3D12CommandQueue> m_commandQueue;
ComPtr<ID3D12RootSignature> m_rootSignature;
ComPtr<ID3D12DescriptorHeap> m_rtvHeap;
ComPtr<ID3D12PipelineState> m_pipelineState;
ComPtr<ID3D12GraphicsCommandList> m_commandList;
UINT m_rtvDescriptorSize;
void D3D12HelloTriangle::PopulateCommandList()
{
// Command list allocators can only be reset when the associated
// command lists have finished execution on the GPU; apps should use
// fences to determine GPU execution progress.
ThrowIfFailed(m_commandAllocator->Reset());
// However, when ExecuteCommandList() is called on a particular command
// list, that command list can then be reset at any time and must be before
// re-recording.
ThrowIfFailed(m_commandList->Reset(m_commandAllocator.Get(), m_pipelineState.Get()));
// Set necessary state.
m_commandList->SetGraphicsRootSignature(m_rootSignature.Get());
m_commandList->RSSetViewports(1, &m_viewport);
m_commandList->RSSetScissorRects(1, &m_scissorRect);
// Indicate that the back buffer will be used as a render target.
m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_renderTargets[m_frameIndex].Get(), D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET));
CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(m_rtvHeap->GetCPUDescriptorHandleForHeapStart(), m_frameIndex, m_rtvDescriptorSize);
m_commandList->OMSetRenderTargets(1, &rtvHandle, FALSE, nullptr);
// Record commands.
const float clearColor[] = { 0.0f, 0.2f, 0.4f, 1.0f };
m_commandList->ClearRenderTargetView(rtvHandle, clearColor, 0, nullptr);
m_commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
m_commandList->IASetVertexBuffers(0, 1, &m_vertexBufferView);
m_commandList->DrawInstanced(3, 1, 0, 0);
// Indicate that the back buffer will now be used to present.
m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_renderTargets[m_frameIndex].Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT));
ThrowIfFailed(m_commandList->Close());
}
請參閱 D3D12 參考中的範例程式碼。
需求
目標平台 | Windows |
標頭 | d3d12.h |
程式庫 | D3d12.lib |
Dll | D3d12.dll |