다음을 통해 공유


명령 목록 실행 및 동기화

Microsoft Direct3D 12에는 더 이상 이전 버전의 직접 실행 모드가 없습니다. 대신, 앱은 명령 목록과 번들을 만든 다음, GPU 명령 집합을 기록합니다. 명령 큐는 실행할 명령 목록을 제출하는 데 사용됩니다. 이 모델을 통해 개발자는 GPU(그래픽 처리 장치)와 CPU를 모두 효율적으로 사용할 수 있도록 자세히 제어할 수 있습니다.

명령 큐 개요

Direct3D 12 명령 큐는 이전에 개발자에게 공개되지 않은 직접 실행 모드 작업 제출의 런타임 및 드라이버 동기화를 명시적으로 동시성, 병렬 처리 및 동기화를 관리하는 API로 바꿉니다. 명령 큐에서 개발자에게 제공하는 향상된 기능은 다음과 같습니다.

  • 개발자가 예기치 않은 동기화로 인한 우발적인 비효율성을 방지할 수 있습니다.
  • 개발자가 필요한 동기화를 더 효율적이고 정확하게 확인할 수 있는 높은 수준에서 동기화를 도입할 수 있습니다. 즉, 런타임과 그래픽 드라이버에서 반응적인 엔지니어링 병렬 처리에 걸리는 시간을 줄일 수 있습니다.
  • 비용이 많이 드는 작업을 더 명확하게 만듭니다.

이러한 향상된 기능을 통해 사용하도록 설정하거나 향상시킬 수 있는 시나리오는 다음과 같습니다.

  • 병렬 처리 증가 - 별도의 포그라운드 작업 큐가 있는 경우 애플리케이션에서 비디오 디코딩과 같은 백그라운드 워크로드에 심층적인 큐를 사용할 수 있습니다.
  • 우선 순위가 낮은 비동기 GPU 작업 - 명령 큐 모델을 사용하면 우선 순위가 낮은 GPU 작업과 원자성 작업을 동시에 실행할 수 있으므로 하나의 GPU 스레드에서 동기화되지 않은 다른 스레드의 결과를 차단하지 않고 사용할 수 있도록 합니다.
  • 우선 순위가 높은 컴퓨팅 작업 - 이 디자인을 사용하면 3D 렌더링을 인터럽트해야 하는 시나리오에서 우선 순위가 높은 약간의 컴퓨팅 작업을 수행할 수 있으므로 CPU에서 추가로 처리하기 위한 결과를 일찍 얻을 수 있습니다.

명령 큐 초기화

명령 큐는 ID3D12Device::CreateCommandQueue를 호출하여 만들 수 있습니다. 이 메서드는 생성해야 하는 큐 유형과 해당 큐에 제출할 수 있는 명령 유형을 나타내는 D3D12_COMMAND_LIST_TYPE 사용합니다. 번들은 직접 명령 목록에서만 호출할 수 있으며 큐에 직접 제출할 수 없습니다. 지원되는 큐 유형은 다음과 같습니다.

일반적으로 DIRECT 큐 및 명령 목록은 임의의 명령을 허용하고, COMPUTE 큐 및 명령 목록은 컴퓨팅 및 복사 관련 명령을 허용하며, COPY 큐 및 명령 목록은 복사 명령만 허용합니다.

명령 목록 실행

명령 목록을 기록하고 기본 명령 큐를 검색하거나 새 명령 큐를 만든 후에는 ID3D12CommandQueue::ExecuteCommandLists를 호출하여 명령 목록을 실행합니다.

애플리케이션은 명령 목록을 여러 스레드에서 모든 명령 큐에 제출할 수 있습니다. 런타임은 이러한 요청을 제출 순서에 따라 직렬화하는 작업을 수행합니다.

런타임은 제출된 명령 목록의 유효성을 검사하고, 제한 사항 중 하나라도 위반하면 ExecuteCommandLists에 대한 호출을 삭제합니다. 호출이 삭제되는 이유는 다음과 같습니다.

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

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

  1. 여러 명령 큐에서 리소스를 동시에 쓸 수 없습니다. 리소스가 큐에서 쓰기 가능한 상태로 전환된 경우 해당 큐가 단독으로 소유한 것으로 간주되며 다른 큐에서 액세스하기 전에 읽기 또는 일반 상태( 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의 작업 제출