다음을 통해 공유


D3D12 향상된 장벽

향상된 장벽을 위한 DDI 인터페이스는 Windows 11 버전 22H2 WDK(WDDM 3.0)에서 사용할 수 있습니다. 22H2(또는 이전 OS 릴리스)에서 향상된 장벽을 사용하려면 1.706.4 미리 보기 Agility SDK를 설치해야 합니다.

D3D12 향상된 장벽을 통해 개발자는 GPU 작업 동기화, 텍스처 레이아웃 전환 및 캐시 플러시("리소스 메모리 액세스")를 독립적으로 제어할 수 있습니다. 이 기능은 개발자가 GPU 작업 동기화, 텍스처 레이아웃 전환 및 캐시 플러시(리소스 메모리 액세스)를 독립적으로 제어할 수 있는 Direct3D API 및 DDI 집합을 제공합니다.

향상된 장벽은 레거시 리소스 장벽을 더 표현적인 장벽 유형으로 대체합니다. 기능에는 다음이 포함되어 있습니다.

  • 동기화 대기 시간이 줄어듭니다.
  • 과도한 캐시 플러시 감소
  • 신비한 승진과 부패 규칙이 없습니다.
  • 빠르고 유연한 리소스 별칭(다양한 별칭 토폴로지).
  • 장벽 전환 중에 삭제합니다.
  • 동일한 리소스 복사본(자체 복사)을 포함하여 동시 읽기/쓰기를 지원합니다.
  • 비동기 삭제, 복사, 해결 및 지우기 명령을 지원합니다.

향상된 장벽은 레거시 리소스 장벽보다 간단하지는 않지만 훨씬 덜 모호하므로 개발자가 사용하기가 더 쉽습니다.

향상된 장벽 지원 보고

향상된 장벽 기능은 현재 하드웨어 또는 드라이버 요구 사항이 아닙니다. 드라이버는 D3D12DDI_D3D12_OPTIONS_DATA_0089 EnhancedBarriersSupported 멤버를 TRUE로 설정하여 지원을 나타냅니다.

  • D3D12DDI_FEATURE_VERSION_VIDEO_0088_0 Windows 11에 도입된 D3D12 향상된 장벽 마일스톤의 예비 구현을 정의하는 버전 번호입니다.

D3D12 향상된 장벽 콜백 함수

향상된 장벽에 대한 지원을 나타내는 드라이버는 다음 콜백 함수를 구현합니다.

디자인 세부 정보

드라이버는 일반적으로 세 가지 개별 작업을 사용하여 레거시 리소스 장벽을 처리합니다.

  1. GPU 작업을 동기화합니다.
  2. 필요한 캐시 플러시 작업을 수행합니다.
  3. 필요한 레이아웃 변경 작업을 수행합니다.

향상된 장벽을 통해 개발자는 이러한 각 작업을 개별적으로 제어할 수 있습니다.

향상된 장벽 유형

세 가지 유형의 향상된 장벽이 있습니다.

범위가 지정한 장벽은 레거시 리소스 장벽을 대체 합니다. 성능 저하 없이 레거시 리소스 장벽을 완전히 구현할 수 있도록 범위가 지정된 장벽이 제공됩니다.

  • 모든 장벽 유형은 GPU 작업 동기화를 제어하고 장벽 전후에 읽기 또는 쓰기 액세스 유형을 제어합니다.

  • 텍스처 장벽은 텍스처 하위 리소스의 레이아웃을 추가로 관리합니다. 하위 리소스 선택은 레거시 리소스 장벽에서 사용되는 친숙한 일체형 옵션 외에도 밉, 배열 및 평면 조각의 범위로 표현될 수 있습니다.

  • 버퍼 장벽 및 전역 장벽은 동기화 및 리소스 액세스만 제어하며 리소스 레이아웃에 영향을 주지 않습니다(버퍼에는 레이아웃이 없음). 전역 장벽은 캐시된 모든 메모리에 영향을 주므로 비용이 많이 들 수 있으며 범위가 더 지정된 장벽이 부족한 경우에만 사용해야 합니다.

텍스처 장벽

  • 텍스처 하위 리소스에 대한 캐시 플러시, 메모리 레이아웃 및 동기화를 제어합니다.
  • 텍스처 리소스에만 사용해야 합니다.
  • 단일 하위 리소스, 모든 하위 리소스 또는 일관된 하위 리소스 범위(즉, 밉 범위 및 배열 범위)를 선택할 수 있습니다.
  • 유효한 NULL이 아닌 리소스 포인터를 제공해야 합니다.

버퍼 장벽

  • 버퍼 리소스에 대한 캐시 플러시 및 동기화를 제어합니다.
  • 버퍼 리소스에만 사용해야 합니다.
  • 텍스처와 달리 버퍼에는 단일 하위 리소스만 있으며 전환할 수 있는 레이아웃이 없습니다.
  • 유효한 NULL이 아닌 리소스 포인터를 제공해야 합니다.

글로벌 장벽

  • 단일 명령 큐에서 표시된 모든 리소스 액세스 유형에 대한 캐시 플러시 및 동기화를 제어합니다.
  • 텍스처 레이아웃에는 영향을 주지 않습니다.
  • 레거시 NULL UAV 장벽 및 NULL/NULL 별칭 장벽과 유사한 기능을 제공하는 데 필요합니다.

전역 장벽은 텍스처 레이아웃을 전환하지 않으므로, 그렇지 않으면 레이아웃 변경이 필요한 전환에 전역 장벽을 사용할 수 없습니다. 예를 들어 D3D12DDI_BARRIER_LAYOUT_RENDER_TARGET D3D12DDI_BARRIER_LAYOUT_SHADER_RESOURCE 변경해야 하므로 글로벌 장벽을 사용하여 비동기 액세스 텍스처를 D3D12DDI_BARRIER_ACCESS_RENDER_TARGET D3D12DDI_BARRIER_ACCESS_SHADER_RESOURCE 전환할 수 없습니다.

동기화

그래픽 프로세서는 가능한 한 많은 작업을 병렬로 실행하도록 설계되었습니다. 종속 데이터에 액세스하기 전에 이전 GPU 작업에 종속된 모든 GPU 작업을 동기화해야 합니다.

향상된 장벽 인터페이스는 명시적 SyncBeforeSyncAfter 값을 논리 비트 필드 마스크로 사용합니다. 장벽은 장벽을 실행하기 전에 이전의 모든 명령 SyncBefore 범위가 완료되기를 기다려야 합니다. 마찬가지로 장벽은 장벽이 완료될 때까지 모든 후속 SyncAfter 범위를 차단해야 합니다. D3D12DDI_BARRIER_SYNC 장벽과 관련하여 GPU 작업의 동기화 범위를 지정합니다.

자세한 내용은 향상된 장벽 사양을 참조 하세요.

레이아웃 전환

텍스처 하위 리소스는 다양한 액세스 방법에 대해 다양한 레이아웃을 사용할 수 있습니다. 예를 들어 텍스처는 렌더링 대상 또는 깊이 스텐실로 사용될 때 압축되는 경우가 많으며 셰이더 읽기 또는 복사 명령에 대해 압축되지 않는 경우가 많습니다. 텍스처 장벽은 LayoutBeforeLayoutAfter D3D12DDI_BARRIER_LAYOUT 값을 사용하여 레이아웃 전환을 설명합니다.

레이아웃 전환은 텍스처에만 필요하므로 D3D12DDI_TEXTURE_BARRIER 데이터 구조에서만 표현됩니다.

LayoutBeforeLayoutAfter는 모두 장벽을 수행하는 큐 유형과 호환되어야 합니다. 예를 들어 컴퓨팅 큐는 하위 리소스를 D3D12DDI_BARRIER_LAYOUT_RENDER_TARGET 또는 외부로 전환할 수 없습니다.

잘 정의된 장벽 순서를 제공하기 위해 일련의 장벽을 완료한 후 하위 리소스의 레이아웃은 시퀀스의 최종 LayoutAfter 입니다.

액세스 전환

많은 GPU 쓰기 작업이 캐시되므로 쓰기 액세스에서 다른 쓰기 액세스 또는 읽기 전용 액세스에 대한 장벽에는 캐시 플러시가 필요할 수 있습니다. 향상된 장벽 API의 액세스 전환은 특정 새 액세스 유형에 대해 하위 리소스의 메모리를 표시해야 함을 나타냅니다. 레이아웃 전환과 마찬가지로 연결된 하위 리소스의 메모리가 원하는 용도로 이미 액세스할 수 있는 것으로 알려진 경우 일부 액세스 전환이 필요하지 않을 수 있습니다.

액세스 전환은 다음과 같이 표시됩니다.

  • 텍스처의 경우 D3D12DDI_TEXTURE_BARRIER 구조체의 일부로 사용합니다.
  • 버퍼의 경우 D3D12DDI_BUFFER_BARRIER 구조체의 일부로 사용합니다.

액세스 전환은 동기화를 수행하지 않습니다. 종속 액세스 간의 동기화는 장벽에서 적절한 SyncBeforeSyncAfter 값을 사용하여 처리될 것으로 예상됩니다.

지정된 AccessAfter에 표시되는 AccessBefore는 리소스 메모리가 다른 액세스 형식에도 표시되도록 보장하지 않습니다. 예시:

MyTexBarrier.AccessBefore=D3D12DDI_BARRIER_ACCESS_UNORDERED_ACCESS;
MyTexBarrier.AccessAfter=D3D12DDI_BARRIER_ACCESS_SHADER_RESOURCE;

이 액세스 전환은 후속 셰이더 읽기 액세스가 이전 순서가 지정되지 않은 액세스-쓰기에 따라 달라지게 됨을 나타냅니다. 그러나 하드웨어가 UAV 캐시에서 직접 셰이더 리소스를 읽을 수 있는 경우 드라이버는 실제로 UAV 캐시를 플러시하지 않을 수 있습니다.

D3D12DDI_BARRIER_ACCESS_COMMON

D3D12DDI_BARRIER_ACCESS_COMMON 레이아웃 호환 액세스를 나타내는 특수 액세스 형식입니다. D3D12DDI_BARRIER_ACCESS_COMMON 전환하면 하위 리소스 데이터를 장벽 이후 레이아웃 호환 액세스에 사용할 수 있어야 합니다. 버퍼에는 레이아웃 이 없으므로 D3D12DDI_BARRIER_ACCESS_COMMON 단순히 버퍼 호환 액세스를 의미합니다.

장벽에서 D3D12DDI_BARRIER_ACCESS_COMMON AccessBefore지정하면 모든 쓰기 액세스 형식 집합이 의미합니다. D3D12DDI_BARRIER_ACCESS_COMMON AccessBefore사용하면 비용이 많이 들고 의도하지 않은 캐시 플러시가 발생할 수 있으므로 권장되지 않습니다. 대신, 개발자는 장벽 오버헤드를 적절하게 제한하기 위해 가장 좁게 필요한 쓰기 액세스 비트만 사용하는 것이 좋습니다. AccessBefore가 D3D12DDI_BARRIER_ACCESS_COMMON 설정되면 디버그 계층 경고가 발생합니다.

단일 큐 동시 액세스

향상된 장벽을 사용하면 동일한 명령 큐의 동일한 버퍼 또는 동시 액세스 텍스처에서 동시 읽기/쓰기 작업을 수행할 수 있습니다.

버퍼 및 동시 액세스 리소스는 하나 이상의 다른 큐에서 동시에 종속되지 않은 읽기 액세스가 있는 한 큐에서 쓰기 액세스를 항상 지원합니다. 이러한 지원은 읽기가 동시 쓰기에 의존해서는 안 되므로 이러한 리소스는 항상 COMMON 레이아웃을 사용하고 읽기/쓰기 위험이 없기 때문입니다. (레거시 리소스 장벽 규칙은 쓰기 상태 비트를 다른 상태 비트와 결합하는 것을 허용하지 않습니다. 따라서 레거시 리소스 장벽을 사용하여 동일한 큐에서 리소스를 동시에 읽고 쓸 수 없습니다.)

겹치지 않는 것처럼 보이는 두 개의 쓰기 영역에는 여전히 겹치는 캐시 줄이 있을 수 있기 때문에 한 번에 한 명의 작성자 정책이 적용됩니다.

하위 리소스 범위

개발자는 일반적으로 다양한 하위 리소스를 전환하려고 합니다. 예를 들어 지정된 텍스처 배열에 대해 전체 밉 체인을 전환하거나 모든 배열 조각에 대해 단일 밉 수준을 전환합니다. 향상된 장벽을 통해 개발자는 D3D12DDI_BARRIER_SUBRESOURCE_RANGE 구조를 사용하여 논리적으로 인접한 하위 리소스 범위를 전환할 수 있습니다. (레거시 리소스 상태 전환 장벽은 개발자에게 모든 하위 리소스 상태 또는 단일 하위 리소스 상태를 원자성으로 전환할 수 있는 옵션만 제공합니다.)

컴퓨팅 및 직접 큐 레이아웃

다음과 같은 향상된 장벽 레이아웃 은 직접 큐와 컴퓨팅 큐 모두에서 동일하게 보장됩니다.

  • D3D12DDI_BARRIER_LAYOUT_GENERIC_READ
  • D3D12DDI_BARRIER_LAYOUT_UNORDERED_ACCESS
  • D3D12DDI_BARRIER_LAYOUT_SHADER_RESOURCE
  • D3D12DDI_BARRIER_LAYOUT_COPY_SOURCE
  • D3D12DDI_BARRIER_LAYOUT_COPY_DEST

이러한 레이아웃 중 하나의 하위 리소스는 레이아웃 전환 없이 직접 큐 또는 컴퓨팅 큐에서 사용할 수 있습니다.

일부 하드웨어에서는 이전 또는 후속 액세스가 모두 직접 큐에 있는 경우 직접 큐의 레이아웃 전환 장벽이 훨씬 더 빨라질 수 있습니다. 직접 큐의 리소스에 액세스하려면 다음 레이아웃을 사용하는 것이 좋습니다.

  • D3D12DDI_BARRIER_LAYOUT_DIRECT_QUEUE_GENERIC_READ
  • D3D12DDI_BARRIER_LAYOUT_DIRECT_QUEUE_UNORDERED_ACCESS
  • D3D12DDI_BARRIER_LAYOUT_DIRECT_QUEUE_SHADER_RESOURCE
  • D3D12DDI_BARRIER_LAYOUT_DIRECT_QUEUE_COPY_SOURCE
  • D3D12DDI_BARRIER_LAYOUT_DIRECT_QUEUE_COPY_DEST

DIRECT_QUEUE 레이아웃 변형은 컴퓨팅 큐와 호환되지 않으며 컴퓨팅 명령 목록 장벽에서 사용할 수 없습니다. 그러나 직접 큐의 컴퓨팅 작업과 호환됩니다.

장벽 없는 액세스

ExecuteCommandList 경계 간에 보류 중인 명령 또는 캐시 플러시 작업이 없어야 하므로 버퍼는 처음에 장벽 없이 ExecuteCommandLists 범위에서 액세스할 수 있습니다. 마찬가지로, 텍스처 하위 리소스는 다음과 같은 조건에서 장벽 없이 처음에 액세스할 수도 있습니다.

  • 하위 리소스 레이아웃은 액세스 형식과 호환됩니다.
  • 필요한 압축 메타데이터가 초기화되었습니다.

잠재적으로 미해결 읽기 또는 쓰기 작업이 없는 레이아웃 D3D12DDI_BARRIER_LAYOUT_COMMON(또는 D3D12DDI_BARRIER_LAYOUT_DIRECT_QUEUE_COMMON 같은 큐별 일반 레이아웃)의 텍스처 하위 리소스는 다음 액세스 형식을 사용하는 장벽 없이 ExecuteCommandLists 명령 스트림에서 액세스할 수 있습니다.

  • D3D12DDI_BARRIER_ACCESS_SHADER_RESOURCE
  • D3D12DDI_BARRIER_ACCESS_COPY_SOURCE
  • D3D12DDI_BARRIER_ACCESS_COPY_DEST

또한 큐별 공통 레이아웃을 사용하는 버퍼 또는 텍스처는 장벽 없이 D3D12DDI_BARRIER_ACCESS_UNORDERED_ACCESS 사용할 수 있습니다.

버퍼 및 동시 액세스 텍스처(D3D12DDI_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS 플래그를 사용하여 만든 텍스처)는 다음 액세스 형식을 사용하는 장벽 없이 ExecuteCommandLists 명령 스트림에서 처음에 액세스할 수 있습니다.

  • D3D12DDI_BARRIER_ACCESS_VERTEX_BUFFER
  • D3D12DDI_BARRIER_ACCESS_CONSTANT_BUFFER
  • D3D12DDI_BARRIER_ACCESS_INDEX_BUFFER
  • D3D12DDI_BARRIER_ACCESS_RENDER_TARGET
  • D3D12DDI_BARRIER_ACCESS_UNORDERED_ACCESS
  • D3D12DDI_BARRIER_ACCESS_SHADER_RESOURCE
  • D3D12DDI_BARRIER_ACCESS_STREAM_OUTPUT
  • D3D12DDI_BARRIER_ACCESS_INDIRECT_ARGUMENT
  • D3D12DDI_BARRIER_ACCESS_COPY_DEST
  • D3D12DDI_BARRIER_ACCESS_COPY_SOURCE
  • D3D12DDI_BARRIER_ACCESS_RESOLVE_DEST
  • D3D12DDI_BARRIER_ACCESS_RESOLVE_SOURCE
  • D3D12DDI_BARRIER_ACCESS_PREDICATION

후속 액세스는 둘 이상의 쓰기 액세스 유형이 없는 장벽 없이 수행할 수도 있습니다. 그러나 D3D12DDI_BARRIER_ACCESS_RENDER_TARGET 경우를 제외하고 장벽을 사용하여 동일한 리소스에 순차 쓰기를 플러시해야 합니다.

자체 리소스 복사

향상된 장벽과는 관련이 없지만 하위 리소스의 한 지역에서 다른 교차하지 않는 지역으로의 복사본을 허용하는 기능은 매우 요청이 많은 기능입니다. 향상된 장벽을 사용하면 공통 레이아웃이 있는 하위 리소스를 동일한 CopyBufferRegion 또는 CopyTextureRegion 호출에서 원본 및 대상으로 모두 사용할 수 있습니다. 교차하는 원본과 대상 메모리 영역 간의 복사본은 정의되지 않은 결과를 생성합니다. 디버그 계층은 이러한 결과에 대해 유효성을 검사해야 합니다. (레거시 리소스 장벽 디자인에서는 하위 리소스가 동시에 D3D12DDI_RESOURCE_STATE_COPY_SOURCE 및 D3D12DDI_RESOURCE_STATE_COPY_DEST 상태에 있을 수 없으므로 자체에 복사할 수 없습니다.)

배치된 리소스 메타데이터 초기화

레거시 리소스 장벽 설계에서는 새로 배치되고 활성화된 별칭이 지정된 텍스처 리소스를 Clear, Copy 또는 Discard로 초기화한 후 렌더링 대상 또는 깊이 스텐실 리소스로 사용해야 합니다. 이 요구 사항은 렌더링 대상 및 깊이 스텐실 리소스는 일반적으로 데이터가 유효하도록 초기화해야 하는 압축 메타데이터를 사용하기 때문입니다. 새로 업데이트된 타일 매핑을 사용하는 예약된 텍스처도 마찬가지입니다.

향상된 장벽은 장벽의 일부로 삭제하는 옵션을 지원합니다. D3D12DDI_BARRIER_LAYOUT_UNDEFINED 잠재적으로 압축된 레이아웃(예: D3D12DDI_BARRIER_LAYOUT_RENDER_TARGET, D3D12DDI_BARRIER_LAYOUT_DEPTH_STENCIL, D3D12DDI_BARRIER_LAYOUT_UNORDERED_ACCESS)으로의 장벽 레이아웃 전환은 D3D12DDI_TEXTURE_BARRIER_FLAG_DISCARD D3D12DDI_TEXTURE_BARRIER::Flags 멤버에 있을 때 압축 메타데이터를 초기화해야 합니다.

렌더링 대상 및 깊이/스텐실 리소스 외에도 레거시 장벽 모델이 지원하지 않는 유사한 UAV 텍스처 압축 최적화가 있습니다.

장벽 순서 지정

장벽은 정방향 순서로 큐에 대기합니다(API 호출 순서, barrier-group-index, barrier-array-index). 동일한 하위 리소스의 여러 장벽은 장벽이 대기 중인 순서로 완료되는 것처럼 작동해야 합니다.

동일한 메모리에 쓸 수 있는 SyncAfter 범위가 일치하는 큐에 대기 중인 장벽은 모든 쓰기를 큐에 대기된 순서로 완료해야 합니다. 이 요구 사항은 리소스 별칭을 지원하는 장벽에서 데이터 경합을 방지합니다. 예를 들어 리소스를 '비활성화'하는 장벽은 '동일한 메모리에서 다른 리소스를 활성화하고 메타데이터를 지울 수 있는 다른 장벽 앞에 캐시를 플러시해야 합니다.