[주의 사항] D3D12 학습 CPU / GPU 동기화

프로세서 (CPU 및 GPU) 개의 병렬로 실행하기 때문에 동기화 문제의 수.
우리는 R 상점에 우리가 그리려는 형상의 일부의 위치를 어떤 자원을 가지고 가정하자. 또한, 업데이트 된 위치 (P1)의 R, R 및 명령 큐에 기준 묘화 명령 C를 저장하기 위해 CPU로부터 데이터를 가정 목적은 위치 (P1)에서 그래픽을 그리는 것이다. CPU를 차단하지 않습니다 명령 대기열에 명령을 추가, CPU는 계속 실행됩니다. GPU 드로잉 명령 C, CPU를 실행하고, 커버가 오류 위치 (P2)에서 발생하는 새로운 데이터 R을 계속 저장 전 (아래 참조).

이 문제를 해결하는 한 가지 방법은, 처리 큐가 지정된 점 펜스 (울타리 포인트)까지 모든 명령을 GPU가 완료 될 때까지 기다립니다하기 위해 CPU를 강제하는 것입니다. 우리는 새로 고침 명령 큐 (명령 대기열 플러싱)로 전화하십시오. 우리는이 작업을 수행하기 위해 펜스 (울타리)를 사용할 수 있습니다. GPU를 상기 CPU를 동기화하기위한 인터페이스로 표시 ID3D12Fence 배리어. 울타리는 다음과 같은 방법을 사용하여 객체를 생성 할 수 있습니다 :

HRESULT ID3D12Device :: CreateFence ( 
  UINT64로 초기는, 
  플래그, D3D12_FENCE_FLAGS 
  REFIID의 riid, 
  무효 ** ppFence을); 
 
//  
ThrowIfFailed (md3dDevice-> CreateFence (
   0 , 
  D3D12_FENCE_FLAG_NONE, 
  IID_PPV_ARGS ( & mFence)));

UINT64 객체, 펜스 값은 단지 정수 유지 시간 울타리 포인트를 식별한다. 우리는 처음부터 우리는 새로운 울타리 지점을 표시 할 때마다 시작, 우리는 단지 정수를 증가. 이제 다음 코드 / 의견은 명령 대기열을 새로 울타리를 사용하는 방법을 보여줍니다.

UINT64 mCurrentFence = 0 ;
무효 D3DApp :: FlushCommandQueue을 () 
{ 
  // 이 울타리 지점까지 명령을 표시하는 울타리 값을 사전. 
  mCurrentFence ++ ; 
 
  // 새로운 울타리 점을 설정하기 위해 명령 대기열에 명령을 추가합니다.
  // 우리는 GPU의 타임 라인에 있기 때문에, 새로운 울타리 포인트가되지 않습니다 
   // GPU가 이전에 모든 명령 처리를 완료 할 때까지 설정 
   // 이 신호를 (). 
  ThrowIfFailed (mCommandQueue-> 신호 (mFence.Get () mCurrentFence)); 
 
  // GPU가이 울타리 지점까지 명령이 완료 될 때까지 기다립니다. 
  경우 (mFence-> GetCompletedValue () <mCurrentFence)는 
  { 
    eventHandle HANDLE = CreateEventEx (nullptr, 거짓 , 거짓 ), EVENT_ALL_ACCESS 단계; 
 
    // 화재 이벤트 GPU는 현재의 울타리를 때렸습니다. 
    ThrowIfFailed (mFence-> SetEventOnCompletion (mCurrentFence, eventHandle));
// GPU가 현재의 울타리 이벤트가 발생되는 돌 때까지 기다립니다. 
    의 WaitForSingleObject (eventHandle, INFINITE); 
    하여 CloseHandle (eventHandle); 
  } 
}

그림 4.8은 그래픽이 코드를 설명합니다.

4.8 그림. CPU가 막 (N + 울타리 ID3D12CommandQueue :: 호출 신호 중에이 스냅 샷에서, GPU는 xgpu까지 명령을 처리 한 1) 제조 방법. 이것은 본질적 끝에 추가 명령어 큐이고, 울타리의 값 n + 1 그러나 mFence-> GetCompletedValue을 변경 (), N 신호 명령 전에 큐에 모든 명령까지 처리 GPU를 리턴 할 것이다.

因此在前面的示例中,在CPU发出绘图命令C之后,它将在覆盖R的数据之前刷新命令队列以存储新位置p2。 这个解决方案并不理想,因为它意味着CPU在等待GPU完成时处于空闲状态,但它提供了一个简单的解决方案,我们将在第7章之前使用它。您几乎可以在任何时候刷新命令队列(每帧不一定只有一次); 比如如果您有一些初始化GPU命令,则可以在进入主渲染循环之前刷新命令队列以执行初始化。
请注意,刷新命令队列也可用于解决我们在上一节末尾提到的问题; 也就是说,我们可以刷新命令队列,以确保在重置命令分配器之前已经执行了所有GPU命令。

추천

출처www.cnblogs.com/heben/p/11324822.html