Поделиться через


Метод 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 (означает, что для любого доступа к БПЛА может потребоваться барьер).
Когда ID3D12GraphicsCommandList::ResourceBarrier передается массив описаний барьеров ресурсов, API ведет себя так, как если бы он был вызван N раз (1 для каждого элемента массива) в указанном порядке. По возможности переходы следует объединять в один вызов API для оптимизации производительности.

Описание состояний использования, в которые может находиться подресурс, см. в перечислении 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.
Для барьеров псевдонимов среда выполнения проверит, что, если любой указатель ресурса не равен NULL, он ссылается на ресурс с плиткой.

Для барьеров 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

См. также раздел

ID3D12GraphicsCommandList

Использование барьеров ресурсов для синхронизации состояний ресурсов в Direct3D 12