지원 명령 목록

이 섹션은 Windows 7 이상 및 Windows Server 2008 R2 이상 버전의 Windows에만 적용됩니다.

Direct3D 런타임은 명령 목록에 다음 Direct3D 11 DDI를 사용합니다.

드라이버의 CommandListExecute, CalcPrivateCommandListSize, CreateCommandListDestroyCommandList 함수에 대한 의미 체계는 다른 유사한 DDI 함수 및 해당 DDI에 대한 API 설명서를 기반으로 대부분 자체 설명입니다.

Direct3D 런타임이 pCreateCommandList 매개 변수가 가리키는 D3D11DDIARG_CREATECOMMANDLIST 구조의 hDeferredContext 멤버에 지정된 지연된 컨텍스트에서 드라이버의 CreateCommandList 또는 RecycleCreateCommandList 함수를 성공적으로 호출한 후 Direct3D 런타임은 지연된 컨텍스트에서 다음 소멸 시퀀스를 수행합니다.

  1. Direct3D 런타임은 열려 있는 모든 지연된 개체 핸들을 "닫습니다". 이러한 핸들은 지연된 컨텍스트에 바인딩된 것처럼 보일 수 있습니다.

  2. 런타임은 지연된 컨텍스트를 삭제합니다.

CreateCommandList 또는 RecycleCreateCommandList를 호출하는 동안 드라이버가 상태 새로 고침 DDI 콜백 함수에 대해 수행하는 모든 호출은 지연된 컨텍스트의 현재 상태를 계속 공개합니다. 그러나 지연된 컨텍스트를 "닫고" 소멸하는 동안 상태 새로 고침 DDI에 대한 모든 호출은 아무 것도 바인딩되지 않음을 반영합니다(즉, CreateCommandList 또는 RecycleCreateCommandList 호출 직후에 모든 항목이 암시적으로 바인딩되지 않음).

지연된 컨텍스트는 애플리케이션에서 명시적으로 중단하거나 API 또는 드라이버의 오류 조건으로 인해 중단될 수도 있습니다. 이러한 경우 Direct3D 런타임은 다음 시퀀스를 수행합니다.

  1. Direct3D 런타임은 드라이버의 AbandonCommandList 함수를 호출합니다.

  2. 런타임 바인딩 해제는 지연된 컨텍스트에서 하나씩 핸들을 처리합니다.

  3. 런타임은 열려 있는 모든 지연된 개체 핸들을 "닫습니다".

  4. 런타임은 지연된 컨텍스트를 취소하거나 삭제합니다.

앞의 시퀀스는 즉각적인 컨텍스트의 소멸 시퀀스와 유사합니다. 드라이버의 AbandonCommandList 함수를 호출하면 드라이버가 드라이버가 선호하는 모든 항목에 상태를 적용할 수 있습니다.

드라이버의 CommandListExecute 함수를 호출하는 동안 드라이버는 디바이스를 만들 때의 상태와 같도록 지연된 컨텍스트의 상태를 전환해야 합니다. 이 작업을 명확한 상태 작업이라고도 합니다. 그러나 드라이버의 CommandListExecute 함수를 호출하는 동안 드라이버가 상태 새로 고침 DDI 콜백 함수 에 대해 수행하는 모든 호출은 드라이버 함수에 대한 마지막 DDI 호출 중에 바인딩된 상태를 반영합니다. 드라이버 함수에 대한 다음 DDI 호출 중에 드라이버가 상태 새로 고침 DDI 콜백 함수에 대해 수행하는 모든 호출은 현재 상태를 완전히 비어 있는 것으로 표시하며 이는 CommandListExecute에서 암시적인 상태 전환을 반영합니다. 이 사실은 상태 새로 고침 DDI 콜백 함수의 일반적인 의미 체계 및 동작과 약간 다릅니다. 드라이버의 SetShader 함수 중 하나를 호출하는 동안 드라이버가 상태 새로 고침 DDI 콜백 함수를 호출한 경우 상태 새로 고침 DDI 콜백 함수는 바인딩되는 새 셰이더에 이미 바인딩된 것으로 표시됩니다. 이러한 상태 새로 고침 DDI 콜백 동작의 차이는 CommandListExecute 중에 이전 상태를 반영하도록 드라이버에 더 많은 유연성을 제공합니다.

Direct3D 버전 11 API는 명령 목록에 의해 쿼리가 조작되지 않았으며(즉, QueryBegin 또는 QueryEnd 가 호출됨) 명령 목록을 실행하려는 컨텍스트에서만 "시작"되었는지 확인합니다. 또한 API는 동적 리소스의 맵을 기록한 명령 목록이 현재 매핑된 동일한 리소스가 있는 컨텍스트에서 실행되지 않도록 합니다. FinishCommandList 함수를 호출하기 전에 Direct3D 런타임은 FinishCommandList가 쿼리 범위를 암시적으로 종료하고 매핑된 리소스의 매핑을 해제하기 때문에 시작된 쿼리 또는 매핑된 리소스가 열려 있는 모든 쿼리 또는 동적 리소스에서 드라이버의 QueryEndResourceUnmap DDI 함수를 호출합니다.

작은 명령 목록에 대한 최적화

메모리가 적은 명령 목록에 대한 메모리 재활용 최적화는 명령 목록 DDI 함수 호출 간의 경합을 줄이고 명령 목록에 필요한 호출 처리 오버헤드를 줄이는 데 중요할 수 있습니다. 각 명령 목록에서 일관되지 않은 처리 오버헤드는 중요합니다. 이 최적화는 명령 목록에 필요한 처리 오버헤드가 명령 목록에 필요한 CPU 시간 및 메모리 공간을 지배하는 명령 목록에 대한 것입니다. 작은 메모리 크기 명령 목록은 예를 들어 CopyResource와 같은 단일 그래픽 명령입니다. CopyResource에 필요한 메모리 양은 두 포인터입니다. 그러나 CopyResource에는 대용량 명령 목록과 동일한 양의 명령 목록 호출 처리가 여전히 필요합니다. 메모리 양이 적은 명령 목록이 높은 빈도로 생성되면 런타임에서 드라이버의 CreateCommandList, DestroyCommandList, CreateDeferredContextDestroyDevice(D3D10) 함수(지연된 컨텍스트의 경우)를 호출하는 데 필요한 처리 오버헤드가 점점 더 중요해지고 있습니다. 여기서 참조하는 메모리는 DDI 핸들에 대한 메모리를 포함하는 드라이버 데이터 구조를 보유하는 시스템 메모리입니다.

드라이버의 RecycleCommandList 함수는 드라이버 핸들이 사용되지 않지만 아직 삭제되지 않은 경우와 이전에 사용하지 않은 드라이버 핸들이 다시 사용되는 경우 드라이버에 알려야 합니다. 이 알림은 명령 목록 및 지연 컨텍스트 핸들 모두에 적용됩니다. 드라이버가 재활용해야 하는 유일한 메모리는 DDI 핸들이 가리키는 메모리입니다. RecycleCommandList의 목적은 핸들과 연결된 메모리를 재활용하는 것이지만 효율성을 위해 드라이버는 재활용할 메모리를 선택하고 선택할 수 있는 완전한 유연성을 제공합니다. 드라이버는 직접 컨텍스트 명령 목록이 지점을 처리하는 메모리 영역의 크기를 변경할 수 없습니다. 이 크기는 CalcPrivateCommandListSize의 반환 값입니다. 또한 드라이버는 컨텍스트 명령이 로컬 핸들 지점을 나열하는 메모리 영역의 크기를 변경할 수 없습니다. 이 크기는 CalcDeferredContextHandleSize의 반환 값입니다.

드라이버의 RecycleCreateCommandListRecycleCreateDeferredContext DDI 함수는 메모리 부족 오류 코드를 E_OUTOFMEMORY HRESULT 값으로 반환해야 합니다. 이러한 함수는 pfnSetErrorCb 함수에 대한 호출을 통해 이러한 오류 코드를 제공하지 않습니다. 이 드라이버 요구 사항은 런타임이 디바이스 전체 동기화를 사용하여 이러한 만들기 형식 드라이버 함수의 즉각적인 컨텍스트 오류를 watch 것을 방지합니다. 이러한 오류를 감시하는 것은 메모리 양이 적은 명령 목록에 치명적인 경합의 원천이 될 것입니다.

드라이버의 RecycleDestroyCommandList, RecycleCommandList 및 RecycleCreateCommandList 함수 간의 차이점이 중요합니다. 해당 기능에는 다음이 포함되었습니다.

RecycleDestroyCommandList

런타임은 드라이버의 RecycleDestroyCommandList 함수를 호출하여 경량 소멸이 필요하다는 것을 드라이버에 알립니다. 즉, 드라이버는 DDI 명령 목록 핸들에 대한 메모리를 아직 할당 해제하지 않아야 합니다. 드라이버의 RecycleDestroyCommandList 함수는 드라이버의 DestroyCommandList 함수와 마찬가지로 자유 스레드입니다.

RecycleCommandList

드라이버의 RecycleCommandList 함수는 런타임이 명령 목록 핸들을 지연된 컨텍스트 캐시에 다시 통합했음을 드라이버에 알릴 수 있습니다. 그런 다음 함수는 명령 목록과 연결된 메모리를 지연된 컨텍스트 캐시에 다시 통합할 수 있는 기회를 드라이버에 제공합니다. 런타임은 지연된 컨텍스트 스레드에서 드라이버의 RecycleCommandList 함수를 호출합니다. RecycleCommandList DDI 함수를 사용하면 드라이버가 자체 동기화를 수행할 필요가 줄어듭니다.

RecycleCreateCommandList

런타임은 드라이버의 RecycleCreateCommandList 함수를 호출하여 이전에 사용하지 않은 DDI 핸들을 완전히 다시 유효하게 만듭니다.

이러한 재활용 DDI 함수는 메모리 양이 적은 명령 목록에 대한 리소스를 재활용하는 데 도움이 되는 최적화 기회를 제공합니다. 다음 의사 코드는 API에서 DDI로 함수 호출의 흐름을 통해 런타임의 구현을 보여 줍니다.

::FinishCommandList()
{
  // Empty InterlockedSList, integrating into the cache
  Loop { DC::pfnRecycleCommandList }

  If (Previously Destroyed CommandList Available)
 { IC::pfnRecycleCreateCommandList }
 else
  {
    IC::pfnCalcPrivateCommandListSize
    IC::pfnCreateCommandList
    IC::pfnCalcDeferredContextHandleSize(D3D11DDI_HT_COMMANDLIST)
  }

  Loop { DC::pfnDestroy* (context-local handle destroy) }

  IC::pfnRecycleCreateDeferredContext
}
...
Sporadic: DC::pfnCreate* (context-local open during first-bind per CommandList)

CommandList::Destroy()
{
  // If DC still alive, almost always recycle:
  If (DC still alive)
 { IC::pfnRecycleDestroyCommandList }
  Else
 { IC::pfnDestroyCommandList }
  // Add to InterlockedSList
}

다음 상태 다이어그램은 직접 컨텍스트 DDI 명령 목록 핸들의 유효성을 보여 있습니다. 녹색 상태는 CommandListExecute와 함께 사용할 수 있는 핸들을 나타냅니다.

직접 컨텍스트 DDI 명령 목록 핸들의 유효성 상태를 보여 주는 다이어그램