Share via


루트 서명 사용

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

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

명령 목록 의미 체계

명령 목록의 맨 앞에는 루트 서명이 정의되어 있지 않습니다. 그래픽 셰이더에는 컴퓨팅 셰이더의 별도 루트 서명이 명령 목록에 별도로 할당되어 있습니다. 명령 목록 또는 번들에 설정된 루트 서명은 현재 그리기/디스패치에 설정된 PSO와도 일치해야 합니다. 그렇지 않으면 동작이 정의되지 않습니다. 호환되는 루트 서명으로 전환하기 전에 호환되지 않는 PSO를 설정하는 경우처럼 그리기/디스패치 전에 일시적으로 나타나는 루트 서명 불일치는 문제가 되지 않습니다(그리기/디스패이가 호출될 때 호환되면 문제가 되지 않음). PSO를 설정해도 루트 서명은 달라지지 않습니다. 애플리케이션은 루트 서명을 설정하기 위해 전용 API를 호출해야 합니다.

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

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

이 경우 그리기/디스패치를 실행하기 전에 애플리케이션은 애플리케이션이 현재 루트 서명으로 정의한 각 슬롯 [0..4]에 적절한 바인딩을 설정해야 합니다. instance 경우 슬롯 [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에서 그래픽 파이프라인 상태 관리그래픽 파이프라인 상태 상속 섹션을 참조하세요.

루트 서명