Microsoft Direct3D 12에서는 이전 버전의 직접 실행 모드가 더 이상 존재하지 않습니다. 대신 앱은 명령 목록과 번들을 만든 다음 GPU 명령 집합을 기록합니다. 명령 큐는 실행할 명령 목록을 제출하는 데 사용됩니다. 이 모델을 사용하면 개발자가 GPU(그래픽 처리 장치)와 CPU의 효율적인 사용을 더 효율적으로 제어할 수 있습니다.
- 명령 큐 개요
- 명령 큐 초기화
- 실행 명령 목록
- 여러 명령 큐에서 리소스를 액세스하기
- 명령 큐 펜스를 사용하여 명령 목록 실행을 동기화하는
- 명령 큐에서 액세스하는 리소스 동기화
- 타일형 리소스 대한 명령 큐 지원
- 관련 항목
명령 큐 개요
Direct3D 12 명령 큐는 이전에 개발자에게 노출되지 않았던 즉시 모드 작업 제출의 런타임 및 드라이버 동기화를 동시성, 병렬 처리 및 동기화를 명시적으로 관리하기 위한 API로 바꿉니다. 명령 큐는 개발자에게 다음과 같은 개선 사항을 제공합니다.
- 개발자는 예기치 않은 동기화로 인한 우발적인 비효율성을 방지할 수 있습니다.
- 개발자는 필요한 동기화를 보다 효율적이고 정확하게 확인할 수 있는 더 높은 수준에서 동기화를 도입할 수 있습니다. 즉, 런타임과 그래픽 드라이버는 병렬 처리를 사후적으로 엔지니어링하는 데 더 적은 시간을 소비합니다.
- 비용이 많이 드는 작업을 보다 명시적으로 만듭니다.
이러한 향상된 기능은 다음 시나리오를 사용하거나 향상시킵니다.
- 병렬 처리 증가 - 애플리케이션은 포그라운드 작업을 위해 별도의 큐가 있는 경우 비디오 디코딩과 같은 백그라운드 워크로드에 더 깊은 큐를 사용할 수 있습니다.
- 비동기 및 우선 순위가 낮은 GPU 작업 - 명령 큐 모델을 사용하면 우선 순위가 낮은 GPU 작업과 원자성 작업을 동시에 실행할 수 있으므로 한 GPU 스레드가 차단 없이 다른 비동기 스레드의 결과를 사용할 수 있습니다.
- 우선 순위가 높은 컴퓨팅 작업 - 이 설계를 사용하면 CPU에서 추가 처리를 위해 결과를 조기에 얻을 수 있도록 3D 렌더링을 중단해야 하는 시나리오에서 우선 순위가 높은 컴퓨팅 작업을 소량 수행할 수 있습니다.
명령 큐 초기화
ID3D12Device::CreateCommandQueue호출하여 명령 큐를 만들 수 있습니다. 이 메서드는 생성해야 하는 큐 유형과 해당 큐에 제출할 수 있는 명령 유형을 나타내는 D3D12_COMMAND_LIST_TYPE 사용합니다. 번들은 직접 명령 목록에서만 호출할 수 있으며 큐에 직접 제출할 수 없습니다. 지원되는 큐 유형은 다음과 같습니다.
일반적으로 DIRECT 큐 및 명령 목록은 모든 명령을 허용하고, COMPUTE 큐 및 명령 목록은 컴퓨팅 및 복사 관련 명령을 허용하며, COPY 큐 및 명령 목록은 복사 명령만 허용합니다.
명령 목록 실행
명령 목록을 기록하고 기본 명령 큐를 검색하거나 새 명령 큐를 만든 후에는 ID3D12CommandQueue::ExecuteCommandLists호출하여 명령 목록을 실행합니다.
애플리케이션은 여러 스레드의 명령 큐에 명령 목록을 제출할 수 있습니다. 런타임은 제출 순서대로 이러한 요청을 serialize하는 작업을 수행합니다.
런타임은 제출된 명령 목록의 유효성을 검사하고 제한 사항이 위반된 경우 ExecuteCommandLists 대한 호출을 삭제합니다. 다음과 같은 이유로 호출이 삭제됩니다.
- 제공된 명령 목록은 직접 명령 목록이 아닌 번들입니다.
- ID3D12GraphicsCommandList::Close 제공된 명령 목록에서 호출되어 기록을 완료하지 못했습니다.
- ID3D12CommandAllocator::Reset 기록된 이후 명령 목록과 연결된 명령 할당자에서 호출되었습니다. 명령 할당자에 대한 자세한 내용은 만들기 및 기록 명령 목록 및 번들참조하세요.
- 명령 큐 펜스는 명령 목록의 이전 실행이 아직 완료되지 않았다는 것을 나타냅니다. 명령 큐 펜스는 아래에서 자세히 설명합니다.
- ID3D12GraphicsCommandList::BeginQuery 및 ID3D12GraphicsCommandList::EndQuery호출로 설정된 쿼리의 이전 및 이후 상태는 제대로 일치하지 않습니다.
- 리소스 전환 장벽의 전후 상태가 제대로 일치하지 않습니다. 자세한 내용은 리소스 장벽을 사용하여 리소스 상태를 동기화하는참조하세요.
여러 명령 큐에서 리소스 액세스
여러 명령 큐에서 리소스의 액세스를 제한하는 런타임에 의해 적용되는 몇 가지 규칙이 있습니다. 이러한 규칙은 다음과 같습니다.
리소스는 여러 명령 큐에서 동시에 쓸 수 없습니다. 리소스가 큐에서 쓰기 가능한 상태로 전환된 경우 해당 큐에서 단독으로 소유하는 것으로 간주되며 다른 큐에서 액세스하기 전에 읽기 또는 COMMON 상태(D3D12_RESOURCE_STATES참조)로 전환해야 합니다.
읽기 상태인 경우 리소스는 읽기 상태에 따라 프로세스 전반을 포함하여 여러 명령 큐에서 동시에 읽을 수 있습니다.
리소스 액세스 제한 및 리소스 장벽을 사용하여 리소스에 대한 액세스를 동기화하는 방법에 대한 자세한 내용은 리소스 장벽을 사용하여 리소스 상태동기화를 참조하세요.
명령 큐 펜스를 사용하여 명령 목록 실행 동기화
Direct3D 12에서 여러 병렬 명령 큐를 지원하면 GPU에서 비동기 작업의 우선 순위를 보다 유연하게 제어할 수 있습니다. 또한 이 디자인은 특히 한 큐의 명령 목록이 다른 명령 큐에서 작동하는 리소스에 따라 달라지는 경우 앱이 작업 동기화를 명시적으로 관리해야 한다는 것을 의미합니다. 이러한 몇 가지 예로는 결과가 3D 큐의 렌더링 작업에 사용될 수 있도록 컴퓨팅 큐의 작업이 완료될 때까지 대기하고, 컴퓨팅 큐의 작업이 쓰기 위해 리소스에 액세스할 수 있도록 3D 작업이 완료될 때까지 기다리는 것이 포함됩니다. 큐 간의 작업 동기화를 사용하도록 설정하기 위해 Direct3D 12는 ID3D12Fence 인터페이스로 API에 표시되는 펜스 개념을 사용합니다.
펜스는 처리 중인 작업의 현재 단위를 나타내는 정수입니다. 앱이 ID3D12CommandQueue::Signal호출하여 펜스를 진행하면 정수가 업데이트됩니다. 앱은 펜스 값을 확인하고 작업 단위가 완료되었는지 확인하여 후속 작업을 시작할 수 있는지 여부를 결정할 수 있습니다.
명령 큐에서 액세스하는 리소스 동기화
Direct3D 12에서는 일부 리소스의 상태 동기화가 리소스 장벽과 함께 구현됩니다. 각 리소스 장벽에서 앱은 리소스의 이전 및 이후 상태를 선언합니다. 일반적인 예는 리소스가 셰이더 리소스 뷰 간을 렌더링 대상 뷰로 전환하는 것입니다. 대부분의 경우 이러한 리소스 장벽은 명령 목록 내에서 관리됩니다. 디버그 계층을 사용하도록 설정하면 시스템은 모든 리소스의 이전 및 이후 상태가 일치하도록 적용하여 리소스가 장벽 전환 시 특정 작업에 대해 올바른 상태임을 보장합니다.
리소스 상태 동기화에 대한 자세한 내용은 리소스 장벽을 사용하여리소스 상태를 동기화하는 방법을 참조하세요.
타일형 리소스에 대한 명령 큐 지원
Direct3D 11의 ID3D11DeviceContext2 인터페이스를 통해 노출된 타일형 리소스를 관리하는 방법은 Direct3D 12의 ID3D12CommandQueue 인터페이스에서 제공됩니다. 이러한 메서드는 다음과 같습니다.
| 메서드 | 설명 |
|---|---|
| CopyTileMappings | 원본 타일식 리소스에서 대상 타일식 리소스로 매핑을 복사합니다. |
| UpdateTileMappings | 타일식 리소스의 타일 위치 매핑을 리소스 힙의 메모리 위치로 업데이트합니다. |
Direct3D 12 앱에서 타일식 리소스를 사용하는 방법에 대한 자세한 내용은 Direct3D11 타일식 리소스참조하세요.