Метод ID3D12GraphicsCommandList::ResourceBarrier (d3d12.h)
Уведомляет драйвер о том, что ему необходимо синхронизировать несколько обращений к ресурсам.
Синтаксис
void ResourceBarrier(
[in] UINT NumBarriers,
[in] const D3D12_RESOURCE_BARRIER *pBarriers
);
Параметры
[in] NumBarriers
Тип: UINT
Количество отправленных описаний барьеров.
[in] pBarriers
Тип: const D3D12_RESOURCE_BARRIER*
Указатель на массив описаний барьеров.
Возвращаемое значение
None
Remarks
Примечание
Ресурс, используемый для D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE состояния, должен быть создан в этом состоянии, а затем никогда не переходить из него. В него также не может быть перенесен ресурс, который был создан не в этом состоянии. Дополнительные сведения см. в разделе Ограничения памяти структуры ускорения в функциональной спецификации DirectX raytracing (DXR) на сайте GitHub.
Существует три типа описаний барьеров:
- D3D12_RESOURCE_TRANSITION_BARRIER . Барьеры перехода указывают на переход набора подресурсов между различными способами использования. Вызывающий объект должен указать до и после использования вложенных ресурсов. Флаг D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES используется для одновременного переноса всех вложенных ресурсов в ресурсе.
- D3D12_RESOURCE_ALIASING_BARRIER . Барьеры псевдонимов указывают на переход между использованием двух разных ресурсов, которые имеют сопоставления в одной куче. Приложение может указать ресурс before и after. Обратите внимание, что один или оба ресурса могут иметь значение NULL (это означает, что любой ресурс с плитками может вызвать псевдоним).
- D3D12_RESOURCE_UAV_BARRIER . Барьеры представления неупорядоченного доступа указывают, что все операции доступа БПЛА (чтение или запись) к определенному ресурсу должны быть завершены до начала любых будущих операций доступа БПЛА (чтение или запись). Указанный ресурс может иметь значение NULL. Нет необходимости вставлять барьер БПЛА между двумя вызовами draw или dispatch, которые считывают только БПЛА. Кроме того, нет необходимости вставлять барьер БПЛА между двумя вызовами draw или dispatch, которые записывают данные в один и тот же БПЛА, если приложение знает, что безопасно выполнять доступ к БПЛА в любом порядке. Ресурс может иметь значение NULL (означает, что для любого доступа к БПЛА может потребоваться барьер).
Описание состояний использования, в которые может находиться подресурс, см. в перечислении D3D12_RESOURCE_STATES и в разделе Использование барьеров ресурсов для синхронизации состояний ресурсов в Direct3D 12 .
При вызове ID3D12GraphicsCommandList::D iscardResource все подресурсы в ресурсе должны находиться в состоянии RENDER_TARGET или DEPTH_WRITE состоянии соответственно.
При представлении заднего буфера он должен находиться в D3D12_RESOURCE_STATE_PRESENT состоянии. Если idXGISwapChain1::P resent1 вызывается для ресурса, который не находится в состоянии PRESENT, будет выдано предупреждение уровня отладки.
Биты использования ресурсов группируются в две категории: только для чтения и чтения и записи.
Следующие биты использования доступны только для чтения:
- 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 , чтобы поместить ресурс в правильное состояние.
- Если ресурс незаконно привязан для чтения и записи одновременно.
- Если состояния before , переданные 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 |
Header | d3d12.h |
Библиотека | D3d12.lib |
DLL | D3d12.dll |
См. также раздел
Использование барьеров ресурсов для синхронизации состояний ресурсов в Direct3D 12