다음을 통해 공유


명령 목록 실행 및 동기화

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 대한 호출을 삭제합니다. 다음과 같은 이유로 호출이 삭제됩니다.

여러 명령 큐에서 리소스 액세스

여러 명령 큐에서 리소스의 액세스를 제한하는 런타임에 의해 적용되는 몇 가지 규칙이 있습니다. 이러한 규칙은 다음과 같습니다.

  1. 리소스는 여러 명령 큐에서 동시에 쓸 수 없습니다. 리소스가 큐에서 쓰기 가능한 상태로 전환된 경우 해당 큐에서 단독으로 소유하는 것으로 간주되며 다른 큐에서 액세스하기 전에 읽기 또는 COMMON 상태(D3D12_RESOURCE_STATES참조)로 전환해야 합니다.

  2. 읽기 상태인 경우 리소스는 읽기 상태에 따라 프로세스 전반을 포함하여 여러 명령 큐에서 동시에 읽을 수 있습니다.

리소스 액세스 제한 및 리소스 장벽을 사용하여 리소스에 대한 액세스를 동기화하는 방법에 대한 자세한 내용은 리소스 장벽을 사용하여 리소스 상태동기화를 참조하세요.

명령 큐 펜스를 사용하여 명령 목록 실행 동기화

Direct3D 12에서 여러 병렬 명령 큐를 지원하면 GPU에서 비동기 작업의 우선 순위를 보다 유연하게 제어할 수 있습니다. 또한 이 디자인은 특히 한 큐의 명령 목록이 다른 명령 큐에서 작동하는 리소스에 따라 달라지는 경우 앱이 작업 동기화를 명시적으로 관리해야 한다는 것을 의미합니다. 이러한 몇 가지 예로는 결과가 3D 큐의 렌더링 작업에 사용될 수 있도록 컴퓨팅 큐의 작업이 완료될 때까지 대기하고, 컴퓨팅 큐의 작업이 쓰기 위해 리소스에 액세스할 수 있도록 3D 작업이 완료될 때까지 기다리는 것이 포함됩니다. 큐 간의 작업 동기화를 사용하도록 설정하기 위해 Direct3D 12는 ID3D12Fence 인터페이스로 API에 표시되는 펜스 개념을 사용합니다.

펜스는 처리 중인 작업의 현재 단위를 나타내는 정수입니다. 앱이 ID3D12CommandQueue::Signal호출하여 펜스를 진행하면 정수가 업데이트됩니다. 앱은 펜스 값을 확인하고 작업 단위가 완료되었는지 확인하여 후속 작업을 시작할 수 있는지 여부를 결정할 수 있습니다.

명령 큐에서 액세스하는 리소스 동기화

Direct3D 12에서는 일부 리소스의 상태 동기화가 리소스 장벽과 함께 구현됩니다. 각 리소스 장벽에서 앱은 리소스의 이전 및 이후 상태를 선언합니다. 일반적인 예는 리소스가 셰이더 리소스 뷰 간을 렌더링 대상 뷰로 전환하는 것입니다. 대부분의 경우 이러한 리소스 장벽은 명령 목록 내에서 관리됩니다. 디버그 계층을 사용하도록 설정하면 시스템은 모든 리소스의 이전 및 이후 상태가 일치하도록 적용하여 리소스가 장벽 전환 시 특정 작업에 대해 올바른 상태임을 보장합니다.

리소스 상태 동기화에 대한 자세한 내용은 리소스 장벽을 사용하여리소스 상태를 동기화하는 방법을 참조하세요.

타일형 리소스에 대한 명령 큐 지원

Direct3D 11의 ID3D11DeviceContext2 인터페이스를 통해 노출된 타일형 리소스를 관리하는 방법은 Direct3D 12의 ID3D12CommandQueue 인터페이스에서 제공됩니다. 이러한 메서드는 다음과 같습니다.

메서드 설명
CopyTileMappings 원본 타일식 리소스에서 대상 타일식 리소스로 매핑을 복사합니다.
UpdateTileMappings 타일식 리소스의 타일 위치 매핑을 리소스 힙의 메모리 위치로 업데이트합니다.

Direct3D 12 앱에서 타일식 리소스를 사용하는 방법에 대한 자세한 내용은 Direct3D11 타일식 리소스참조하세요.

Direct3D 12에서 작업 제출