다음을 통해 공유


루트 서명 사용

루트 서명은 설명자 테이블(레이아웃 포함), 루트 상수 및 루트 설명자의 임의로 정렬된 컬렉션의 정의입니다. 각 항목에는 최대 한도에 대한 비용이 있으므로 애플리케이션은 루트 서명에 포함될 각 항목 유형 간의 균형을 절상할 수 있습니다.

루트 서명은 API에서 수동 사양으로 만들 수 있는 개체입니다. PSO의 모든 셰이더는 PSO로 지정된 루트 레이아웃과 호환되어야 합니다. 그렇지 않으면 개별 셰이더에 서로 일치하는 포함된 루트 레이아웃이 포함되어야 합니다. 그렇지 않으면 PSO 만들기가 실패합니다. 루트 서명의 한 가지 속성은 작성할 때 셰이더에 대해 알 필요가 없다는 것입니다. 그러나 루트 서명은 원하는 경우 셰이더에서 직접 작성할 수도 있습니다. 기존 셰이더 자산은 루트 서명과 호환되도록 변경할 필요가 없습니다. 셰이더 모델 5.1은 추가적인 유연성(셰이더 내에서 설명자의 동적 인덱싱)을 제공하기 위해 도입되었으며, 원하는 대로 기존 셰이더 자산에서 시작하여 증분 방식으로 채택할 수 있습니다.

명령 목록 의미론

명령 목록의 시작 부분에서 루트 서명은 정의되지 않습니다. 그래픽 셰이더에는 각각 명령 목록에 독립적으로 할당된 컴퓨팅 셰이더와 별도의 루트 서명이 있습니다. 명령 목록 또는 번들에 설정된 루트 서명도 그리기/디스패치에서 현재 설정된 PSO와 일치해야 합니다. 그렇지 않으면 동작이 정의되지 않습니다. 그리기/디스패치 전에 일시적인 루트 서명 불일치는 괜찮습니다. 예를 들어 호환되는 루트 서명으로 전환하기 전에 호환되지 않는 PSO를 설정하는 것과 같습니다(그리기/디스패치가 호출되는 시간에 호환되는 한). PSO를 설정해도 루트 서명은 변경되지 않습니다. 애플리케이션은 루트 서명을 설정하기 위해 전용 API를 호출해야 합니다.

명령 목록에 루트 서명이 설정되면 레이아웃은 애플리케이션이 제공해야 하는 바인딩 집합과 다음 그리기/디스패치 호출에 사용할 수 있는 PSO(동일한 레이아웃으로 컴파일됨)를 정의합니다. 예를 들어 다음 항목을 포함하도록 애플리케이션에서 루트 서명을 정의할 수 있습니다. 각 항목을 "슬롯"이라고 합니다.

  • [0] CBV 설명자 인라인(루트 설명자)
  • [1] 설명자 테이블에는 SRV 2개, CBV 1개 및 UAV 1개가 포함되어 있습니다.
  • [2] 1개의 샘플러가 포함된 설명자 테이블
  • [3] 루트 상수의 4x32비트 컬렉션
  • [4] 지정되지 않은 수의 SRV가 포함된 설명자 테이블

이 경우 그리기/디스패치를 실행하기 전에 애플리케이션은 애플리케이션이 현재 루트 서명으로 정의한 각 슬롯 [0..4]에 적절한 바인딩을 설정해야 합니다. 예를 들어, 슬롯 [1]에서는 설명자 힙의 연속 영역에 있는 2개의 SRV, 1개의 CBV 및 1개의 UAV를 포함한 설명자 테이블이 바인딩되어야 합니다. 실행 시, 이러한 구성 요소는 힙에 포함되거나 포함될 예정입니다. 마찬가지로 설명자 테이블은 슬롯 [2] 및 [4]에서 설정해야 합니다.

애플리케이션은 루트 서명 바인딩의 일부를 한 번에 변경할 수 있습니다(나머지는 변경되지 않은 상태로 유지됨). 예를 들어, 그리기 사이에서 변경해야 하는 항목이 슬롯 [2]의 상수 중 하나뿐이라면, 애플리케이션은 그것만 다시 바인딩하면 됩니다. 앞에서 설명한 것처럼 드라이버/하드웨어는 자동으로 수정될 때 모든 루트 서명 바인딩 상태를 버전화합니다. 명령 목록에서 루트 서명이 변경되면 이전의 모든 루트 서명 바인딩이 부실해지고 새로 예상되는 모든 바인딩은 그리기/디스패치 전에 설정해야 합니다. 그렇지 않으면 동작이 정의되지 않습니다. 루트 서명이 현재 설정된 것과 동일한 서명으로 중복 설정되면 기존 루트 서명 바인딩이 부실해지지 않습니다.

번들 의미 체계

번들은 명령 목록의 루트 서명 바인딩(위 명령 목록 예제의 다양한 슬롯에 대한 바인딩)을 상속합니다. 번들이 상속된 루트 서명 바인딩 중 일부를 변경해야 하는 경우 먼저 루트 서명을 호출 명령 목록과 동일하게 설정해야 합니다(상속된 바인딩은 부실하지 않음). 번들이 루트 서명을 호출 명령 목록과 다르게 설정하면 위에서 설명한 명령 목록에서 루트 서명을 변경하는 것과 같은 효과가 있습니다. 이전의 모든 루트 서명 바인딩은 부실하며 새로 예상된 바인딩은 그리기/디스패치 전에 설정해야 합니다. 그렇지 않으면 동작이 정의되지 않습니다. 번들이 루트 서명 바인딩을 변경할 필요가 없는 경우 루트 서명을 설정할 필요가 없습니다.

다음 코드는 번들로의 호출 흐름 예제를 보여줍니다.

// Command List
...
pCmdList->SetGraphicsRootSignature(pRootSig); // new parameter space
MyEngine_SetTextures(); // bundle inherits descriptor table setting
MyEngine_SetAnimationFactor(fTime); // bundle inherits root constant
pCmdList->ExecuteBundle(...);
...
// Bundle
pBundle->SetGraphicsRootSignature(pRootSig); // same as caller, in order to inherits bindings
pBundle->SetPipelineState(pPS); 
pBundle->SetGraphicsRoot32BitConstant(drawConstantsSlot,0,drawIDOffset);
pBundle->Draw(...); // using inherited textures / animation factor
pBundle->SetGraphicsRoot32BitConstant(drawConstantsSlot,1,drawIDOffset);
pBundle->Draw(...);
...

번들에서 나오면 번들이 수행하는 루트 레이아웃 변경 및/또는 바인딩 변경 내용은 번들 실행이 완료되면 호출 명령 목록으로 다시 상속됩니다.

상속에 대한 자세한 내용은 Direct3D 12 그래픽 파이프라인 상태 관리의 그래픽 파이프라인 상태 상속 섹션을 참조하세요.

루트 서명