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의 DXR(DirectX 광선 추적) 기능 사양에서 가속 구조 메모리 제한을 참조하세요.

다음과 같은 세 가지 유형의 장벽 설명이 있습니다.

  • D3D12_RESOURCE_TRANSITION_BARRIER - 전환 장벽은 하위 리소스 집합이 서로 다른 사용량 간에 전환됨을 나타냅니다. 호출자는 하위 리소스의 사용전후를 지정해야 합니다. D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES 플래그는 리소스의 모든 하위 리소스를 동시에 전환하는 데 사용됩니다.
  • D3D12_RESOURCE_ALIASING_BARRIER - 별칭 장벽은 동일한 힙에 매핑된 두 개의 서로 다른 리소스 사용 간의 전환을 나타냅니다. 애플리케이션은 이전 및 후 리소스를 모두 지정할 수 있습니다. 하나 또는 두 개의 리소스가 NULL일 수 있습니다(타일식 리소스가 별칭을 일으킬 수 있음을 나타낸다).
  • D3D12_RESOURCE_UAV_BARRIER - 순서가 지정되지 않은 액세스 뷰 장벽은 향후 UAV 액세스(읽기 또는 쓰기)를 시작하기 전에 특정 리소스에 대한 모든 UAV 액세스(읽기 또는 쓰기)가 완료되어야 함을 나타냅니다. 지정된 리소스는 NULL일 수 있습니다. UAV만 읽는 두 그리기 또는 디스패치 호출 사이에 UAV 장벽을 삽입할 필요는 없습니다. 또한 애플리케이션이 UAV 액세스를 순서대로 실행하는 것이 안전하다는 것을 알고 있는 경우 동일한 UAV에 쓰는 두 그리기 또는 디스패치 호출 사이에 UAV 장벽을 삽입할 필요가 없습니다. 리소스는 NULL일 수 있습니다(UAV 액세스에 장벽이 필요할 수 있음을 나타낸다).
ID3D12GraphicsCommandList::ResourceBarrier가 리소스 장벽 설명 배열을 전달하면 API는 지정된 순서로 N번(각 배열 요소에 대해 1)이라고 하는 것처럼 동작합니다. 가능한 경우 성능 최적화를 위해 전환을 단일 API 호출로 일괄 처리해야 합니다.

하위 리소스가 있을 수 있는 사용 상태에 대한 설명은 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_TIERD3D12_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 를 호출하여 리소스를 올바른 상태로 전환합니다.
  • 리소스가 동시에 읽기 및 쓰기에 대해 불법으로 바인딩된 경우.
  • 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

추가 정보

ID3D12GraphicsCommandList

Direct3D 12에서 리소스 장벽을 사용하여 리소스 상태 동기화