| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685 |
- ///////////////////////////////////////////////////////////////////////////////
- // //
- // DxilRootSignature.cpp //
- // Copyright (C) Microsoft Corporation. All rights reserved. //
- // This file is distributed under the University of Illinois Open Source //
- // License. See LICENSE.TXT for details. //
- // //
- // Provides support for manipulating root signature structures. //
- // //
- ///////////////////////////////////////////////////////////////////////////////
- #include "dxc/HLSL/DxilConstants.h"
- #include "dxc/HLSL/DxilRootSignature.h"
- #include "dxc/HLSL/DxilPipelineStateValidation.h"
- #include "dxc/Support/Global.h"
- #include "dxc/Support/WinIncludes.h"
- #include "dxc/Support/FileIOHelper.h"
- #include "dxc/dxcapi.h"
- #include "llvm/Support/raw_ostream.h"
- #include "llvm/IR/DiagnosticPrinter.h"
- #include <string>
- #include <algorithm>
- #include <utility>
- #include <vector>
- #include <set>
- using namespace llvm;
- using std::string;
- namespace hlsl {
- DEFINE_ENUM_FLAG_OPERATORS(DxilRootSignatureFlags)
- DEFINE_ENUM_FLAG_OPERATORS(DxilRootDescriptorFlags)
- DEFINE_ENUM_FLAG_OPERATORS(DxilDescriptorRangeType)
- DEFINE_ENUM_FLAG_OPERATORS(DxilDescriptorRangeFlags)
- // Execute (error) and throw.
- #define EAT(x) { (x); throw ::hlsl::Exception(E_FAIL); }
- //////////////////////////////////////////////////////////////////////////////
- // Root signature handler.
- RootSignatureHandle::RootSignatureHandle(RootSignatureHandle&& other) {
- m_pDesc = nullptr;
- m_pSerialized = nullptr;
- std::swap(m_pDesc, other.m_pDesc);
- std::swap(m_pSerialized, other.m_pSerialized);
- }
- void RootSignatureHandle::Assign(const DxilVersionedRootSignatureDesc *pDesc,
- IDxcBlob *pSerialized) {
- Clear();
- m_pDesc = pDesc;
- m_pSerialized = pSerialized;
- if (m_pSerialized)
- m_pSerialized->AddRef();
- }
- void RootSignatureHandle::Clear() {
- hlsl::DeleteRootSignature(m_pDesc);
- m_pDesc = nullptr;
- if (m_pSerialized != nullptr) {
- m_pSerialized->Release();
- m_pSerialized = nullptr;
- }
- }
- const uint8_t *RootSignatureHandle::GetSerializedBytes() const {
- DXASSERT_NOMSG(m_pSerialized != nullptr);
- return (uint8_t *)m_pSerialized->GetBufferPointer();
- }
- unsigned RootSignatureHandle::GetSerializedSize() const {
- DXASSERT_NOMSG(m_pSerialized != nullptr);
- return m_pSerialized->GetBufferSize();
- }
- void RootSignatureHandle::EnsureSerializedAvailable() {
- DXASSERT_NOMSG(!IsEmpty());
- if (m_pSerialized == nullptr) {
- CComPtr<IDxcBlob> pResult;
- hlsl::SerializeRootSignature(m_pDesc, &pResult, nullptr, false);
- IFTBOOL(pResult != nullptr, E_FAIL);
- m_pSerialized = pResult.Detach();
- }
- }
- void RootSignatureHandle::Deserialize() {
- DXASSERT_NOMSG(m_pSerialized && !m_pDesc);
- DeserializeRootSignature((uint8_t*)m_pSerialized->GetBufferPointer(), (uint32_t)m_pSerialized->GetBufferSize(), &m_pDesc);
- }
- void RootSignatureHandle::LoadSerialized(const uint8_t *pData,
- unsigned length) {
- DXASSERT_NOMSG(IsEmpty());
- IDxcBlobEncoding *pCreated;
- IFT(DxcCreateBlobWithEncodingOnHeapCopy(pData, length, CP_UTF8, &pCreated));
- m_pSerialized = pCreated;
- }
- //////////////////////////////////////////////////////////////////////////////
- // Simple serializer.
- class SimpleSerializer {
- struct Segment {
- void *pData;
- unsigned cbSize;
- bool bOwner;
- unsigned Offset;
- Segment *pNext;
- };
- public:
- SimpleSerializer();
- ~SimpleSerializer();
- HRESULT AddBlock(void *pData, unsigned cbSize, unsigned *pOffset);
- HRESULT ReserveBlock(void **ppData, unsigned cbSize, unsigned *pOffset);
- HRESULT Compact(_Out_writes_bytes_(cbSize) char *pData, unsigned cbSize);
- unsigned GetSize();
- protected:
- unsigned m_cbSegments;
- Segment *m_pSegment;
- Segment **m_ppSegment;
- };
- SimpleSerializer::SimpleSerializer() {
- m_cbSegments = 0;
- m_pSegment = nullptr;
- m_ppSegment = &m_pSegment;
- }
- SimpleSerializer::~SimpleSerializer() {
- while (m_pSegment) {
- Segment *pSegment = m_pSegment;
- m_pSegment = pSegment->pNext;
- if (pSegment->bOwner) {
- delete pSegment->pData;
- }
- delete pSegment;
- }
- }
- HRESULT SimpleSerializer::AddBlock(void *pData, unsigned cbSize,
- unsigned *pOffset) {
- Segment *pSegment = nullptr;
- IFRBOOL(!(cbSize != 0 && pData == nullptr), E_FAIL);
- IFROOM(pSegment = new (std::nothrow) Segment);
- pSegment->pData = pData;
- m_cbSegments = (m_cbSegments + 3) & ~3;
- pSegment->Offset = m_cbSegments;
- pSegment->cbSize = cbSize;
- pSegment->bOwner = false;
- pSegment->pNext = nullptr;
- m_cbSegments += pSegment->cbSize;
- *m_ppSegment = pSegment;
- m_ppSegment = &pSegment->pNext;
- if (pOffset != nullptr) {
- *pOffset = pSegment->Offset;
- }
- return S_OK;
- }
- HRESULT SimpleSerializer::ReserveBlock(void **ppData, unsigned cbSize,
- unsigned *pOffset) {
- HRESULT hr = S_OK;
- Segment *pSegment = nullptr;
- void *pClonedData = nullptr;
- IFCOOM(pSegment = new (std::nothrow) Segment);
- pSegment->pData = nullptr;
- IFCOOM(pClonedData = new (std::nothrow) char[cbSize]);
- pSegment->pData = pClonedData;
- m_cbSegments = (m_cbSegments + 3) & ~3;
- pSegment->Offset = m_cbSegments;
- pSegment->cbSize = cbSize;
- pSegment->bOwner = true;
- pSegment->pNext = nullptr;
- m_cbSegments += pSegment->cbSize;
- *m_ppSegment = pSegment;
- m_ppSegment = &pSegment->pNext;
- *ppData = pClonedData;
- if (pOffset) {
- *pOffset = pSegment->Offset;
- }
- Cleanup:
- if (FAILED(hr)) {
- delete[] pClonedData;
- delete pSegment;
- }
- return hr;
- }
- HRESULT SimpleSerializer::Compact(_Out_writes_bytes_(cbSize) char *pData,
- unsigned cbSize) {
- unsigned cb = GetSize();
- IFRBOOL(cb <= cbSize, E_FAIL);
- DXASSERT_NOMSG(cb <= UINT32_MAX / 2);
- char *p = (char *)pData;
- cb = 0;
- for (Segment *pSegment = m_pSegment; pSegment; pSegment = pSegment->pNext) {
- unsigned cbAlign = ((cb + 3) & ~3) - cb;
- _Analysis_assume_(p + cbAlign <= pData + cbSize);
- memset(p, 0xab, cbAlign);
- p += cbAlign;
- cb += cbAlign;
- _Analysis_assume_(p + pSegment->cbSize <= pData + cbSize);
- memcpy(p, pSegment->pData, pSegment->cbSize);
- p += pSegment->cbSize;
- cb += pSegment->cbSize;
- }
- // Trailing zeros
- _Analysis_assume_(p + cbSize - cb <= pData + cbSize);
- memset(p, 0xab, cbSize - cb);
- return S_OK;
- }
- unsigned SimpleSerializer::GetSize() {
- // Round up to 4==sizeof(unsigned).
- return ((m_cbSegments + 3) >> 2) * 4;
- }
- //////////////////////////////////////////////////////////////////////////////
- // Interval helper.
- template <typename T>
- class CIntervalCollection {
- private:
- std::set<T> m_set;
- public:
- const T* FindIntersectingInterval(const T &I) {
- auto it = m_set.find(I);
- if (it != m_set.end())
- return &*it;
- return nullptr;
- }
- void Insert(const T& value) {
- auto result = m_set.insert(value);
- UNREFERENCED_PARAMETER(result);
- #if DBG
- DXASSERT(result.second, "otherwise interval collides with existing in collection");
- #endif
- }
- };
- //////////////////////////////////////////////////////////////////////////////
- // Verifier classes.
- class DescriptorTableVerifier {
- public:
- void Verify(const DxilDescriptorRange1 *pRanges, unsigned NumRanges,
- unsigned iRTS, DiagnosticPrinter &DiagPrinter);
- };
- class StaticSamplerVerifier {
- public:
- void Verify(const DxilStaticSamplerDesc *pDesc, DiagnosticPrinter &DiagPrinter);
- };
- class RootSignatureVerifier {
- public:
- RootSignatureVerifier();
- ~RootSignatureVerifier();
- void AllowReservedRegisterSpace(bool bAllow);
- // Call this before calling VerifyShader, as it accumulates root signature state.
- void VerifyRootSignature(const DxilVersionedRootSignatureDesc *pRootSignature,
- DiagnosticPrinter &DiagPrinter);
- void VerifyShader(DxilShaderVisibility VisType,
- const void *pPSVData,
- uint32_t PSVSize,
- DiagnosticPrinter &DiagPrinter);
- typedef enum NODE_TYPE {
- DESCRIPTOR_TABLE_ENTRY,
- ROOT_DESCRIPTOR,
- ROOT_CONSTANT,
- STATIC_SAMPLER
- } NODE_TYPE;
- private:
- static const unsigned kMinVisType = (unsigned)DxilShaderVisibility::All;
- static const unsigned kMaxVisType = (unsigned)DxilShaderVisibility::Pixel;
- static const unsigned kMinDescType = (unsigned)DxilDescriptorRangeType::SRV;
- static const unsigned kMaxDescType = (unsigned)DxilDescriptorRangeType::Sampler;
- struct RegisterRange {
- NODE_TYPE nt;
- unsigned space;
- unsigned lb; // inclusive lower bound
- unsigned ub; // inclusive upper bound
- unsigned iRP;
- unsigned iDTS;
- // Sort by space, then lower bound.
- bool operator<(const RegisterRange& other) const {
- return space < other.space ||
- (space == other.space && ub < other.lb);
- }
- // Like a regular -1,0,1 comparison, but 0 indicates overlap.
- int overlap(const RegisterRange& other) const {
- if (space < other.space) return -1;
- if (space > other.space) return 1;
- if (ub < other.lb) return -1;
- if (lb > other.ub) return 1;
- return 0;
- }
- // Check containment.
- bool contains(const RegisterRange& other) const {
- return (space == other.space) && (lb <= other.lb && other.ub <= ub);
- }
- };
- typedef CIntervalCollection<RegisterRange> RegisterRanges;
- void AddRegisterRange(unsigned iRTS, NODE_TYPE nt, unsigned iDTS,
- DxilDescriptorRangeType DescType,
- DxilShaderVisibility VisType,
- unsigned NumRegisters, unsigned BaseRegister,
- unsigned RegisterSpace, DiagnosticPrinter &DiagPrinter);
- const RegisterRange *FindCoveringInterval(DxilDescriptorRangeType RangeType,
- DxilShaderVisibility VisType,
- unsigned Num,
- unsigned LB,
- unsigned Space);
- RegisterRanges &
- GetRanges(DxilShaderVisibility VisType, DxilDescriptorRangeType DescType) {
- return RangeKinds[(unsigned)VisType][(unsigned)DescType];
- }
- RegisterRanges RangeKinds[kMaxVisType + 1][kMaxDescType + 1];
- bool m_bAllowReservedRegisterSpace;
- DxilRootSignatureFlags m_RootSignatureFlags;
- };
- void DescriptorTableVerifier::Verify(const DxilDescriptorRange1 *pRanges,
- uint32_t NumRanges, uint32_t iRP,
- DiagnosticPrinter &DiagPrinter) {
- bool bHasSamplers = false;
- bool bHasResources = false;
- uint64_t iAppendStartSlot = 0;
- for (unsigned iDTS = 0; iDTS < NumRanges; iDTS++) {
- const DxilDescriptorRange1 *pRange = &pRanges[iDTS];
- switch (pRange->RangeType) {
- case DxilDescriptorRangeType::SRV:
- case DxilDescriptorRangeType::UAV:
- case DxilDescriptorRangeType::CBV:
- bHasResources = true;
- break;
- case DxilDescriptorRangeType::Sampler:
- bHasSamplers = true;
- break;
- default:
- EAT(DiagPrinter << "Unsupported RangeType value " << (uint32_t)pRange->RangeType
- << " (descriptor table slot [" << iDTS << "], root parameter [" << iRP << "]).\n");
- }
- // Samplers cannot be mixed with other resources.
- if (bHasResources && bHasSamplers) {
- EAT(DiagPrinter << "Samplers cannot be mixed with other "
- << "resource types in a descriptor table (root "
- << "parameter [" << iRP << "]).\n");
- }
- // NumDescriptors is not 0.
- if (pRange->NumDescriptors == 0) {
- EAT(DiagPrinter << "NumDescriptors cannot be 0 (descriptor "
- << "table slot [" << iDTS << "], root parameter [" << iRP << "]).\n");
- }
- // Range start.
- uint64_t iStartSlot = iAppendStartSlot;
- if (pRange->OffsetInDescriptorsFromTableStart != DxilDescriptorRangeOffsetAppend) {
- iStartSlot = pRange->OffsetInDescriptorsFromTableStart;
- }
- if (iStartSlot > UINT_MAX) {
- EAT(DiagPrinter << "Cannot append range with implicit lower "
- << "bound after an unbounded range (descriptor "
- << "table slot [" << iDTS << "], root parameter [" << iRP << "]).\n");
- }
- // Descriptor range and shader register range overlow.
- if (pRange->NumDescriptors != UINT_MAX) {
- // Bounded range.
- uint64_t ub1 = (uint64_t)pRange->BaseShaderRegister +
- (uint64_t)pRange->NumDescriptors - 1ull;
- if (ub1 > UINT_MAX) {
- EAT(DiagPrinter << "Overflow for shader register range: "
- << "BaseShaderRegister=" << pRange->BaseShaderRegister
- << ", NumDescriptor=" << pRange->NumDescriptors
- << "; (descriptor table slot [" << iDTS
- << "], root parameter [" << iRP << "]).\n");
- }
- uint64_t ub2 = (uint64_t)iStartSlot + (uint64_t)pRange->NumDescriptors - 1ull;
- if (ub2 > UINT_MAX) {
- EAT(DiagPrinter << "Overflow for descriptor range (descriptor "
- << "table slot [" << iDTS << "], root parameter [" << iRP << "])\n");
- }
- iAppendStartSlot = iStartSlot + (uint64_t)pRange->NumDescriptors;
- } else {
- // Unbounded range.
- iAppendStartSlot = 1ull + (uint64_t)UINT_MAX;
- }
- }
- }
- RootSignatureVerifier::RootSignatureVerifier() {
- m_RootSignatureFlags = DxilRootSignatureFlags::None;
- m_bAllowReservedRegisterSpace = false;
- }
- RootSignatureVerifier::~RootSignatureVerifier() {}
- void RootSignatureVerifier::AllowReservedRegisterSpace(bool bAllow) {
- m_bAllowReservedRegisterSpace = bAllow;
- }
- const char* RangeTypeString(DxilDescriptorRangeType rt)
- {
- static const char *RangeType[] = {"SRV", "UAV", "CBV", "SAMPLER"};
- return (rt <= DxilDescriptorRangeType::Sampler) ? RangeType[(unsigned)rt]
- : "unknown";
- }
- const char *VisTypeString(DxilShaderVisibility vis) {
- static const char *Vis[] = {"ALL", "VERTEX", "HULL",
- "DOMAIN", "GEOMETRY", "PIXEL"};
- unsigned idx = (unsigned)vis;
- return vis <= DxilShaderVisibility::Pixel ? Vis[idx] : "unknown";
- }
- static bool IsDxilShaderVisibility(DxilShaderVisibility v) {
- return v <= DxilShaderVisibility::Pixel;
- }
- void RootSignatureVerifier::AddRegisterRange(unsigned iRP,
- NODE_TYPE nt,
- unsigned iDTS,
- DxilDescriptorRangeType DescType,
- DxilShaderVisibility VisType,
- unsigned NumRegisters,
- unsigned BaseRegister,
- unsigned RegisterSpace,
- DiagnosticPrinter &DiagPrinter) {
- RegisterRange interval;
- interval.space = RegisterSpace;
- interval.lb = BaseRegister;
- interval.ub = (NumRegisters != UINT_MAX) ? BaseRegister + NumRegisters - 1 : UINT_MAX;
- interval.nt = nt;
- interval.iDTS = iDTS;
- interval.iRP = iRP;
- if (!m_bAllowReservedRegisterSpace &&
- (RegisterSpace >= DxilSystemReservedRegisterSpaceValuesStart) &&
- (RegisterSpace <= DxilSystemReservedRegisterSpaceValuesEnd)) {
- if (nt == DESCRIPTOR_TABLE_ENTRY) {
- EAT(DiagPrinter << "Root parameter [" << iRP << "] descriptor table entry [" << iDTS
- << "] specifies RegisterSpace=" << std::hex << RegisterSpace
- << ", which is invalid since RegisterSpace values in the range "
- << "[" << std::hex << DxilSystemReservedRegisterSpaceValuesStart
- << "," << std::hex << DxilSystemReservedRegisterSpaceValuesEnd
- << "] are reserved for system use.\n");
- }
- else {
- EAT(DiagPrinter << "Root parameter [" << iRP
- << "] specifies RegisterSpace=" << std::hex << RegisterSpace
- << ", which is invalid since RegisterSpace values in the range "
- << "[" << std::hex << DxilSystemReservedRegisterSpaceValuesStart
- << "," << std::hex << DxilSystemReservedRegisterSpaceValuesEnd
- << "] are reserved for system use.\n");
- }
- }
- const RegisterRange *pNode = nullptr;
- DxilShaderVisibility NodeVis = VisType;
- if (VisType == DxilShaderVisibility::All) {
- // Check for overlap with each visibility type.
- for (unsigned iVT = kMinVisType; iVT <= kMaxVisType; iVT++) {
- pNode = GetRanges((DxilShaderVisibility)iVT, DescType).FindIntersectingInterval(interval);
- if (pNode != nullptr)
- break;
- }
- } else {
- // Check for overlap with the same visibility.
- pNode = GetRanges(VisType, DescType).FindIntersectingInterval(interval);
- // Check for overlap with ALL visibility.
- if (pNode == nullptr) {
- pNode = GetRanges(DxilShaderVisibility::All, DescType).FindIntersectingInterval(interval);
- NodeVis = DxilShaderVisibility::All;
- }
- }
- if (pNode != nullptr) {
- const int strSize = 132;
- char testString[strSize];
- char nodeString[strSize];
- switch (nt) {
- case DESCRIPTOR_TABLE_ENTRY:
- StringCchPrintfA(testString, strSize, "(root parameter [%u], visibility %s, descriptor table slot [%u])",
- iRP, VisTypeString(VisType), iDTS);
- break;
- case ROOT_DESCRIPTOR:
- case ROOT_CONSTANT:
- StringCchPrintfA(testString, strSize, "(root parameter [%u], visibility %s)",
- iRP, VisTypeString(VisType));
- break;
- case STATIC_SAMPLER:
- StringCchPrintfA(testString, strSize, "(static sampler [%u], visibility %s)",
- iRP, VisTypeString(VisType));
- break;
- default:
- DXASSERT_NOMSG(false);
- break;
- }
- switch (pNode->nt)
- {
- case DESCRIPTOR_TABLE_ENTRY:
- StringCchPrintfA(nodeString, strSize, "(root parameter[%u], visibility %s, descriptor table slot [%u])",
- pNode->iRP, VisTypeString(NodeVis), pNode->iDTS);
- break;
- case ROOT_DESCRIPTOR:
- case ROOT_CONSTANT:
- StringCchPrintfA(nodeString, strSize, "(root parameter [%u], visibility %s)",
- pNode->iRP, VisTypeString(NodeVis));
- break;
- case STATIC_SAMPLER:
- StringCchPrintfA(nodeString, strSize, "(static sampler [%u], visibility %s)",
- pNode->iRP, VisTypeString(NodeVis));
- break;
- default:
- DXASSERT_NOMSG(false);
- break;
- }
- EAT(DiagPrinter << "Shader register range of type " << RangeTypeString(DescType)
- << " " << testString << " overlaps with another "
- << "shader register range " << nodeString << ".\n");
- }
- // Insert node.
- GetRanges(VisType, DescType).Insert(interval);
- }
- const RootSignatureVerifier::RegisterRange *
- RootSignatureVerifier::FindCoveringInterval(DxilDescriptorRangeType RangeType,
- DxilShaderVisibility VisType,
- unsigned Num,
- unsigned LB,
- unsigned Space) {
- RegisterRange RR;
- RR.space = Space;
- RR.lb = LB;
- RR.ub = LB + Num - 1;
- const RootSignatureVerifier::RegisterRange *pRange = GetRanges(DxilShaderVisibility::All, RangeType).FindIntersectingInterval(RR);
- if (!pRange && VisType != DxilShaderVisibility::All) {
- pRange = GetRanges(VisType, RangeType).FindIntersectingInterval(RR);
- }
- if (pRange && !pRange->contains(RR)) {
- pRange = nullptr;
- }
- return pRange;
- }
- static DxilDescriptorRangeType GetRangeType(DxilRootParameterType RPT) {
- switch (RPT) {
- case DxilRootParameterType::CBV: return DxilDescriptorRangeType::CBV;
- case DxilRootParameterType::SRV: return DxilDescriptorRangeType::SRV;
- case DxilRootParameterType::UAV: return DxilDescriptorRangeType::UAV;
- default:
- break;
- }
- DXASSERT_NOMSG(false);
- return DxilDescriptorRangeType::SRV;
- }
- void RootSignatureVerifier::VerifyRootSignature(
- const DxilVersionedRootSignatureDesc *pVersionedRootSignature,
- DiagnosticPrinter &DiagPrinter) {
- const DxilVersionedRootSignatureDesc *pUpconvertedRS = nullptr;
- // Up-convert root signature to the latest RS version.
- ConvertRootSignature(pVersionedRootSignature, DxilRootSignatureVersion::Version_1_1, &pUpconvertedRS);
- DXASSERT_NOMSG(pUpconvertedRS->Version == DxilRootSignatureVersion::Version_1_1);
- // Ensure this gets deleted as necessary.
- struct SigGuard {
- const DxilVersionedRootSignatureDesc *Orig, *Guard;
- SigGuard(const DxilVersionedRootSignatureDesc *pOrig, const DxilVersionedRootSignatureDesc *pGuard)
- : Orig(pOrig), Guard(pGuard) { }
- ~SigGuard() {
- if (Orig != Guard) {
- DeleteRootSignature(Guard);
- }
- }
- };
- SigGuard S(pVersionedRootSignature, pUpconvertedRS);
- const DxilRootSignatureDesc1 *pRootSignature = &pUpconvertedRS->Desc_1_1;
- // Flags (assume they are bits that can be combined with OR).
- if ((pRootSignature->Flags & ~DxilRootSignatureFlags::ValidFlags) != DxilRootSignatureFlags::None) {
- EAT(DiagPrinter << "Unsupported bit-flag set (root signature flags "
- << std::hex << (uint32_t)pRootSignature->Flags << ").\n");
- }
- m_RootSignatureFlags = pRootSignature->Flags;
- for (unsigned iRP = 0; iRP < pRootSignature->NumParameters; iRP++) {
- const DxilRootParameter1 *pSlot = &pRootSignature->pParameters[iRP];
- // Shader visibility.
- DxilShaderVisibility Visibility = pSlot->ShaderVisibility;
- if (!IsDxilShaderVisibility(Visibility)) {
- EAT(DiagPrinter << "Unsupported ShaderVisibility value " << (uint32_t)Visibility
- << " (root parameter [" << iRP << "]).\n");
- }
- DxilRootParameterType ParameterType = pSlot->ParameterType;
- switch (ParameterType) {
- case DxilRootParameterType::DescriptorTable: {
- DescriptorTableVerifier DTV;
- DTV.Verify(pSlot->DescriptorTable.pDescriptorRanges,
- pSlot->DescriptorTable.NumDescriptorRanges, iRP, DiagPrinter);
- for (unsigned iDTS = 0; iDTS < pSlot->DescriptorTable.NumDescriptorRanges; iDTS++) {
- const DxilDescriptorRange1 *pRange = &pSlot->DescriptorTable.pDescriptorRanges[iDTS];
- unsigned RangeFlags = (unsigned)pRange->Flags;
- // Verify range flags.
- if (RangeFlags & ~(unsigned)DxilDescriptorRangeFlags::ValidFlags) {
- EAT(DiagPrinter << "Unsupported bit-flag set (descriptor range flags "
- << (uint32_t)pRange->Flags << ").\n");
- }
- switch (pRange->RangeType) {
- case DxilDescriptorRangeType::Sampler: {
- if (RangeFlags & (unsigned)(DxilDescriptorRangeFlags::DataVolatile |
- DxilDescriptorRangeFlags::DataStatic |
- DxilDescriptorRangeFlags::DataStaticWhileSetAtExecute)) {
- EAT(DiagPrinter << "Sampler descriptor ranges can't specify DATA_* flags "
- << "since there is no data pointed to by samplers "
- << "(descriptor range flags " << (uint32_t)pRange->Flags << ").\n");
- }
- break;
- }
- default: {
- unsigned NumDataFlags = 0;
- if (RangeFlags & (unsigned)DxilDescriptorRangeFlags::DataVolatile) { NumDataFlags++; }
- if (RangeFlags & (unsigned)DxilDescriptorRangeFlags::DataStatic) { NumDataFlags++; }
- if (RangeFlags & (unsigned)DxilDescriptorRangeFlags::DataStaticWhileSetAtExecute) { NumDataFlags++; }
- if (NumDataFlags > 1) {
- EAT(DiagPrinter << "Descriptor range flags cannot specify more than one DATA_* flag "
- << "at a time (descriptor range flags " << (uint32_t)pRange->Flags << ").\n");
- }
- if ((RangeFlags & (unsigned)DxilDescriptorRangeFlags::DataStatic) &&
- (RangeFlags & (unsigned)DxilDescriptorRangeFlags::DescriptorsVolatile)) {
- EAT(DiagPrinter << "Descriptor range flags cannot specify DESCRIPTORS_VOLATILE with the DATA_STATIC flag at the same time (descriptor range flags " << (uint32_t)pRange->Flags << "). "
- << "DATA_STATIC_WHILE_SET_AT_EXECUTE is fine to combine with DESCRIPTORS_VOLATILE, since DESCRIPTORS_VOLATILE still requires descriptors don't change during execution. \n");
- }
- break;
- }
- }
- AddRegisterRange(iRP,
- DESCRIPTOR_TABLE_ENTRY,
- iDTS,
- pRange->RangeType,
- Visibility,
- pRange->NumDescriptors,
- pRange->BaseShaderRegister,
- pRange->RegisterSpace,
- DiagPrinter);
- }
- break;
- }
- case DxilRootParameterType::Constants32Bit:
- AddRegisterRange(iRP,
- ROOT_CONSTANT,
- (unsigned)-1,
- DxilDescriptorRangeType::CBV,
- Visibility,
- 1,
- pSlot->Constants.ShaderRegister,
- pSlot->Constants.RegisterSpace,
- DiagPrinter);
- break;
- case DxilRootParameterType::CBV:
- case DxilRootParameterType::SRV:
- case DxilRootParameterType::UAV: {
- // Verify root descriptor flags.
- unsigned Flags = (unsigned)pSlot->Descriptor.Flags;
- if (Flags & ~(unsigned)DxilRootDescriptorFlags::ValidFlags) {
- EAT(DiagPrinter << "Unsupported bit-flag set (root descriptor flags " << std::hex << Flags << ").\n");
- }
- unsigned NumDataFlags = 0;
- if (Flags & (unsigned)DxilRootDescriptorFlags::DataVolatile) { NumDataFlags++; }
- if (Flags & (unsigned)DxilRootDescriptorFlags::DataStatic) { NumDataFlags++; }
- if (Flags & (unsigned)DxilRootDescriptorFlags::DataStaticWhileSetAtExecute) { NumDataFlags++; }
- if (NumDataFlags > 1) {
- EAT(DiagPrinter << "Root descriptor flags cannot specify more "
- << "than one DATA_* flag at a time (root "
- << "descriptor flags " << NumDataFlags << ").\n");
- }
- AddRegisterRange(iRP, ROOT_DESCRIPTOR, (unsigned)-1,
- GetRangeType(ParameterType), Visibility, 1,
- pSlot->Descriptor.ShaderRegister,
- pSlot->Descriptor.RegisterSpace, DiagPrinter);
- break;
- }
- default:
- EAT(DiagPrinter << "Unsupported ParameterType value " << (uint32_t)ParameterType
- << " (root parameter " << iRP << ")\n");
- }
- }
- for (unsigned iSS = 0; iSS < pRootSignature->NumStaticSamplers; iSS++) {
- const DxilStaticSamplerDesc *pSS = &pRootSignature->pStaticSamplers[iSS];
- // Shader visibility.
- DxilShaderVisibility Visibility = pSS->ShaderVisibility;
- if (!IsDxilShaderVisibility(Visibility)) {
- EAT(DiagPrinter << "Unsupported ShaderVisibility value " << (uint32_t)Visibility
- << " (static sampler [" << iSS << "]).\n");
- }
- StaticSamplerVerifier SSV;
- SSV.Verify(pSS, DiagPrinter);
- AddRegisterRange(iSS, STATIC_SAMPLER, (unsigned)-1,
- DxilDescriptorRangeType::Sampler, Visibility, 1,
- pSS->ShaderRegister, pSS->RegisterSpace, DiagPrinter);
- }
- }
- void RootSignatureVerifier::VerifyShader(DxilShaderVisibility VisType,
- const void *pPSVData,
- uint32_t PSVSize,
- DiagnosticPrinter &DiagPrinter) {
- DxilPipelineStateValidation PSV;
- IFTBOOL(PSV.InitFromPSV0(pPSVData, PSVSize), E_INVALIDARG);
- bool bShaderDeniedByRootSig = false;
- switch (VisType) {
- case DxilShaderVisibility::Vertex:
- if ((m_RootSignatureFlags & DxilRootSignatureFlags::DenyVertexShaderRootAccess) != DxilRootSignatureFlags::None) {
- bShaderDeniedByRootSig = true;
- }
- break;
- case DxilShaderVisibility::Hull:
- if ((m_RootSignatureFlags & DxilRootSignatureFlags::DenyHullShaderRootAccess) != DxilRootSignatureFlags::None) {
- bShaderDeniedByRootSig = true;
- }
- break;
- case DxilShaderVisibility::Domain:
- if ((m_RootSignatureFlags & DxilRootSignatureFlags::DenyDomainShaderRootAccess) != DxilRootSignatureFlags::None) {
- bShaderDeniedByRootSig = true;
- }
- break;
- case DxilShaderVisibility::Geometry:
- if ((m_RootSignatureFlags & DxilRootSignatureFlags::DenyGeometryShaderRootAccess) != DxilRootSignatureFlags::None) {
- bShaderDeniedByRootSig = true;
- }
- break;
- case DxilShaderVisibility::Pixel:
- if ((m_RootSignatureFlags & DxilRootSignatureFlags::DenyPixelShaderRootAccess) != DxilRootSignatureFlags::None) {
- bShaderDeniedByRootSig = true;
- }
- break;
- default:
- break;
- }
- bool bShaderHasRootBindings = false;
- for (unsigned iResource = 0; iResource < PSV.GetBindCount(); iResource++) {
- const PSVResourceBindInfo0 *pBindInfo0 = PSV.GetPSVResourceBindInfo0(iResource);
- DXASSERT_NOMSG(pBindInfo0);
- unsigned Space = pBindInfo0->Space;
- unsigned LB = pBindInfo0->LowerBound;
- unsigned UB = pBindInfo0->UpperBound;
- unsigned Num = (UB != UINT_MAX) ? (UB - LB + 1) : 1;
- PSVResourceType ResType = (PSVResourceType)pBindInfo0->ResType;
- switch(ResType) {
- case PSVResourceType::Sampler: {
- bShaderHasRootBindings = true;
- auto pCoveringRange = FindCoveringInterval(DxilDescriptorRangeType::Sampler, VisType, Num, LB, Space);
- if(!pCoveringRange) {
- EAT(DiagPrinter << "Shader sampler descriptor range (RegisterSpace=" << Space
- << ", NumDescriptors=" << Num << ", BaseShaderRegister=" << LB
- << ") is not fully bound in root signature.\n");
- }
- break;
- }
- case PSVResourceType::SRVTyped:
- case PSVResourceType::SRVRaw:
- case PSVResourceType::SRVStructured: {
- bShaderHasRootBindings = true;
- auto pCoveringRange = FindCoveringInterval(DxilDescriptorRangeType::SRV, VisType, Num, LB, Space);
- if (pCoveringRange) {
- if(pCoveringRange->nt == ROOT_DESCRIPTOR && ResType == PSVResourceType::SRVTyped) {
- EAT(DiagPrinter << "A Shader is declaring a resource object as a texture using "
- << "a register mapped to a root descriptor SRV (RegisterSpace=" << Space
- << ", ShaderRegister=" << LB << "). "
- << "SRV or UAV root descriptors can only be Raw or Structured buffers.\n");
- }
- }
- else {
- EAT(DiagPrinter << "Shader SRV descriptor range (RegisterSpace=" << Space
- << ", NumDescriptors=" << Num << ", BaseShaderRegister=" << LB
- << ") is not fully bound in root signature.\n");
- }
- break;
- }
- case PSVResourceType::UAVTyped:
- case PSVResourceType::UAVRaw:
- case PSVResourceType::UAVStructured:
- case PSVResourceType::UAVStructuredWithCounter: {
- bShaderHasRootBindings = true;
- auto pCoveringRange = FindCoveringInterval(DxilDescriptorRangeType::UAV, VisType, Num, LB, Space);
- if (pCoveringRange) {
- if (pCoveringRange->nt == ROOT_DESCRIPTOR) {
- if (ResType == PSVResourceType::UAVTyped) {
- EAT(DiagPrinter << "A shader is declaring a typed UAV using a register mapped "
- << "to a root descriptor UAV (RegisterSpace=" << Space
- << ", ShaderRegister=" << LB << "). "
- << "SRV or UAV root descriptors can only be Raw or Structured buffers.\n");
- }
- if (ResType == PSVResourceType::UAVStructuredWithCounter) {
- EAT(DiagPrinter << "A Shader is declaring a structured UAV with counter using "
- << "a register mapped to a root descriptor UAV (RegisterSpace=" << Space
- << ", ShaderRegister=" << LB << "). "
- << "SRV or UAV root descriptors can only be Raw or Structured buffers.\n");
- }
- }
- }
- else {
- EAT(DiagPrinter << "Shader UAV descriptor range (RegisterSpace=" << Space
- << ", NumDescriptors=" << Num << ", BaseShaderRegister=" << LB
- << ") is not fully bound in root signature.\n");
- }
- break;
- }
- case PSVResourceType::CBV: {
- bShaderHasRootBindings = true;
- auto pCoveringRange = FindCoveringInterval(DxilDescriptorRangeType::CBV, VisType, Num, LB, Space);
- if (!pCoveringRange) {
- EAT(DiagPrinter << "Shader CBV descriptor range (RegisterSpace=" << Space
- << ", NumDescriptors=" << Num << ", BaseShaderRegister=" << LB
- << ") is not fully bound in root signature.\n");
- }
- break;
- }
- default:
- break;
- }
- }
- if (bShaderHasRootBindings && bShaderDeniedByRootSig) {
- EAT(DiagPrinter << "Shader has root bindings but root signature uses a DENY flag "
- << "to disallow root binding access to the shader stage.\n");
- }
- }
- BOOL isNaN(const float &a) {
- static const unsigned exponentMask = 0x7f800000;
- static const unsigned mantissaMask = 0x007fffff;
- unsigned u = *(const unsigned *)&a;
- return (((u & exponentMask) == exponentMask) && (u & mantissaMask)); // NaN
- }
- static bool IsDxilTextureAddressMode(DxilTextureAddressMode v) {
- return DxilTextureAddressMode::Wrap <= v &&
- v <= DxilTextureAddressMode::MirrorOnce;
- }
- static bool IsDxilComparisonFunc(DxilComparisonFunc v) {
- return DxilComparisonFunc::Never <= v && v <= DxilComparisonFunc::Always;
- }
- // This validation closely mirrors CCreateSamplerStateValidator's checks
- void StaticSamplerVerifier::Verify(const DxilStaticSamplerDesc* pDesc,
- DiagnosticPrinter &DiagPrinter) {
- if (!pDesc) {
- EAT(DiagPrinter << "Static sampler: A nullptr pSamplerDesc was specified.\n");
- }
- bool bIsComparison = false;
- switch (pDesc->Filter) {
- case DxilFilter::MINIMUM_MIN_MAG_MIP_POINT:
- case DxilFilter::MINIMUM_MIN_MAG_POINT_MIP_LINEAR:
- case DxilFilter::MINIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT:
- case DxilFilter::MINIMUM_MIN_POINT_MAG_MIP_LINEAR:
- case DxilFilter::MINIMUM_MIN_LINEAR_MAG_MIP_POINT:
- case DxilFilter::MINIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR:
- case DxilFilter::MINIMUM_MIN_MAG_LINEAR_MIP_POINT:
- case DxilFilter::MINIMUM_MIN_MAG_MIP_LINEAR:
- case DxilFilter::MINIMUM_ANISOTROPIC:
- case DxilFilter::MAXIMUM_MIN_MAG_MIP_POINT:
- case DxilFilter::MAXIMUM_MIN_MAG_POINT_MIP_LINEAR:
- case DxilFilter::MAXIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT:
- case DxilFilter::MAXIMUM_MIN_POINT_MAG_MIP_LINEAR:
- case DxilFilter::MAXIMUM_MIN_LINEAR_MAG_MIP_POINT:
- case DxilFilter::MAXIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR:
- case DxilFilter::MAXIMUM_MIN_MAG_LINEAR_MIP_POINT:
- case DxilFilter::MAXIMUM_MIN_MAG_MIP_LINEAR:
- case DxilFilter::MAXIMUM_ANISOTROPIC:
- break;
- case DxilFilter::MIN_MAG_MIP_POINT:
- case DxilFilter::MIN_MAG_POINT_MIP_LINEAR:
- case DxilFilter::MIN_POINT_MAG_LINEAR_MIP_POINT:
- case DxilFilter::MIN_POINT_MAG_MIP_LINEAR:
- case DxilFilter::MIN_LINEAR_MAG_MIP_POINT:
- case DxilFilter::MIN_LINEAR_MAG_POINT_MIP_LINEAR:
- case DxilFilter::MIN_MAG_LINEAR_MIP_POINT:
- case DxilFilter::MIN_MAG_MIP_LINEAR:
- case DxilFilter::ANISOTROPIC:
- break;
- case DxilFilter::COMPARISON_MIN_MAG_MIP_POINT:
- case DxilFilter::COMPARISON_MIN_MAG_POINT_MIP_LINEAR:
- case DxilFilter::COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT:
- case DxilFilter::COMPARISON_MIN_POINT_MAG_MIP_LINEAR:
- case DxilFilter::COMPARISON_MIN_LINEAR_MAG_MIP_POINT:
- case DxilFilter::COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR:
- case DxilFilter::COMPARISON_MIN_MAG_LINEAR_MIP_POINT:
- case DxilFilter::COMPARISON_MIN_MAG_MIP_LINEAR:
- case DxilFilter::COMPARISON_ANISOTROPIC:
- bIsComparison = true;
- break;
- default:
- EAT(DiagPrinter << "Static sampler: Filter unrecognized.\n");
- }
- if (!IsDxilTextureAddressMode(pDesc->AddressU)) {
- EAT(DiagPrinter << "Static sampler: AddressU unrecognized.\n");
- }
- if (!IsDxilTextureAddressMode(pDesc->AddressV)) {
- EAT(DiagPrinter << "Static sampler: AddressV unrecognized.\n");
- }
- if (!IsDxilTextureAddressMode(pDesc->AddressW)) {
- EAT(DiagPrinter << "Static sampler: AddressW unrecognized.\n");
- }
- if (isNaN(pDesc->MipLODBias) || (pDesc->MipLODBias < DxilMipLodBiaxMin) ||
- (pDesc->MipLODBias > DxilMipLodBiaxMax)) {
- EAT(DiagPrinter << "Static sampler: MipLODBias must be in the "
- << "range [" << DxilMipLodBiaxMin << " to " << DxilMipLodBiaxMax
- <<"]. " << pDesc->MipLODBias << "specified.\n");
- }
- if (pDesc->MaxAnisotropy > DxilMapAnisotropy) {
- EAT(DiagPrinter << "Static sampler: MaxAnisotropy must be in "
- << "the range [0 to " << DxilMapAnisotropy << "]. "
- << pDesc->MaxAnisotropy << " specified.\n");
- }
- if (bIsComparison && !IsDxilComparisonFunc(pDesc->ComparisonFunc)) {
- EAT(DiagPrinter << "Static sampler: ComparisonFunc unrecognized.");
- }
- if (isNaN(pDesc->MinLOD)) {
- EAT(DiagPrinter << "Static sampler: MinLOD be in the range [-INF to +INF]. "
- << pDesc->MinLOD << " specified.\n");
- }
- if (isNaN(pDesc->MaxLOD)) {
- EAT(DiagPrinter << "Static sampler: MaxLOD be in the range [-INF to +INF]. "
- << pDesc->MaxLOD << " specified.\n");
- }
- }
- //////////////////////////////////////////////////////////////////////////////
- template <typename T>
- void DeleteRootSignatureTemplate(const T &RS) {
- for (unsigned i = 0; i < RS.NumParameters; i++) {
- const auto &P = RS.pParameters[i];
- if (P.ParameterType == DxilRootParameterType::DescriptorTable) {
- delete[] P.DescriptorTable.pDescriptorRanges;
- }
- }
- delete[] RS.pParameters;
- delete[] RS.pStaticSamplers;
- }
- void DeleteRootSignature(const DxilVersionedRootSignatureDesc * pRootSignature)
- {
- if (pRootSignature == nullptr)
- return;
- switch (pRootSignature->Version)
- {
- case DxilRootSignatureVersion::Version_1_0:
- DeleteRootSignatureTemplate<DxilRootSignatureDesc>(pRootSignature->Desc_1_0);
- break;
- case DxilRootSignatureVersion::Version_1_1:
- default:
- DXASSERT(pRootSignature->Version == DxilRootSignatureVersion::Version_1_1, "else version is incorrect");
- DeleteRootSignatureTemplate<DxilRootSignatureDesc1>(pRootSignature->Desc_1_1);
- break;
- }
- delete pRootSignature;
- }
- // GetFlags/SetFlags overloads.
- static DxilRootDescriptorFlags GetFlags(const DxilRootDescriptor &)
- {
- // Upconvert root parameter flags to be volatile.
- return DxilRootDescriptorFlags::DataVolatile;
- }
- static void SetFlags(DxilRootDescriptor &, DxilRootDescriptorFlags)
- {
- // Drop the flags; none existed in rs_1_0.
- }
- static DxilRootDescriptorFlags GetFlags(const DxilRootDescriptor1 &D)
- {
- return D.Flags;
- }
- static void SetFlags(DxilRootDescriptor1 &D, DxilRootDescriptorFlags Flags)
- {
- D.Flags = Flags;
- }
- static DxilRootDescriptorFlags GetFlags(const DxilContainerRootDescriptor1 &D)
- {
- return (DxilRootDescriptorFlags)D.Flags;
- }
- static void SetFlags(DxilContainerRootDescriptor1 &D, DxilRootDescriptorFlags Flags)
- {
- D.Flags = (uint32_t)Flags;
- }
- static DxilDescriptorRangeFlags GetFlags(const DxilDescriptorRange &D)
- {
- // Upconvert range flags to be volatile.
- DxilDescriptorRangeFlags Flags = DxilDescriptorRangeFlags::DescriptorsVolatile;
- // Sampler does not have data.
- if (D.RangeType != DxilDescriptorRangeType::Sampler)
- Flags = (DxilDescriptorRangeFlags)((unsigned)Flags | (unsigned)DxilDescriptorRangeFlags::DataVolatile);
- return Flags;
- }
- static void SetFlags(DxilDescriptorRange &, DxilDescriptorRangeFlags)
- {
- }
- static DxilDescriptorRangeFlags GetFlags(const DxilContainerDescriptorRange &D)
- {
- // Upconvert range flags to be volatile.
- DxilDescriptorRangeFlags Flags = DxilDescriptorRangeFlags::DescriptorsVolatile;
- // Sampler does not have data.
- if (D.RangeType != (uint32_t)DxilDescriptorRangeType::Sampler)
- Flags |= DxilDescriptorRangeFlags::DataVolatile;
- return Flags;
- }
- static void SetFlags(DxilContainerDescriptorRange &, DxilDescriptorRangeFlags)
- {
- }
- static DxilDescriptorRangeFlags GetFlags(const DxilDescriptorRange1 &D)
- {
- return D.Flags;
- }
- static void SetFlags(DxilDescriptorRange1 &D, DxilDescriptorRangeFlags Flags)
- {
- D.Flags = Flags;
- }
- static DxilDescriptorRangeFlags GetFlags(const DxilContainerDescriptorRange1 &D)
- {
- return (DxilDescriptorRangeFlags)D.Flags;
- }
- static void SetFlags(DxilContainerDescriptorRange1 &D, DxilDescriptorRangeFlags Flags)
- {
- D.Flags = (uint32_t)Flags;
- }
- template<typename IN_DXIL_ROOT_SIGNATURE_DESC,
- typename OUT_DXIL_ROOT_SIGNATURE_DESC,
- typename OUT_DXIL_ROOT_PARAMETER,
- typename OUT_DXIL_ROOT_DESCRIPTOR,
- typename OUT_DXIL_DESCRIPTOR_RANGE>
- void ConvertRootSignatureTemplate(const IN_DXIL_ROOT_SIGNATURE_DESC &DescIn,
- DxilRootSignatureVersion DescVersionOut,
- OUT_DXIL_ROOT_SIGNATURE_DESC &DescOut)
- {
- const IN_DXIL_ROOT_SIGNATURE_DESC *pDescIn = &DescIn;
- OUT_DXIL_ROOT_SIGNATURE_DESC *pDescOut = &DescOut;
- // Root signature descriptor.
- pDescOut->Flags = pDescIn->Flags;
- pDescOut->NumParameters = 0;
- pDescOut->NumStaticSamplers = 0;
- // Intialize all pointers early so that clean up works properly.
- pDescOut->pParameters = nullptr;
- pDescOut->pStaticSamplers = nullptr;
- // Root signature parameters.
- if (pDescIn->NumParameters > 0) {
- pDescOut->pParameters = new OUT_DXIL_ROOT_PARAMETER[pDescIn->NumParameters];
- pDescOut->NumParameters = pDescIn->NumParameters;
- memset((void *)pDescOut->pParameters, 0, pDescOut->NumParameters*sizeof(OUT_DXIL_ROOT_PARAMETER));
- }
- for (unsigned iRP = 0; iRP < pDescIn->NumParameters; iRP++) {
- const auto &ParamIn = pDescIn->pParameters[iRP];
- OUT_DXIL_ROOT_PARAMETER &ParamOut = (OUT_DXIL_ROOT_PARAMETER &)pDescOut->pParameters[iRP];
- ParamOut.ParameterType = ParamIn.ParameterType;
- ParamOut.ShaderVisibility = ParamIn.ShaderVisibility;
- switch (ParamIn.ParameterType) {
- case DxilRootParameterType::DescriptorTable: {
- ParamOut.DescriptorTable.pDescriptorRanges = nullptr;
- unsigned NumRanges = ParamIn.DescriptorTable.NumDescriptorRanges;
- if (NumRanges > 0) {
- ParamOut.DescriptorTable.pDescriptorRanges = new OUT_DXIL_DESCRIPTOR_RANGE[NumRanges];
- ParamOut.DescriptorTable.NumDescriptorRanges = NumRanges;
- }
- for (unsigned i = 0; i < NumRanges; i++) {
- const auto &RangeIn = ParamIn.DescriptorTable.pDescriptorRanges[i];
- OUT_DXIL_DESCRIPTOR_RANGE &RangeOut = (OUT_DXIL_DESCRIPTOR_RANGE &)ParamOut.DescriptorTable.pDescriptorRanges[i];
- RangeOut.RangeType = RangeIn.RangeType;
- RangeOut.NumDescriptors = RangeIn.NumDescriptors;
- RangeOut.BaseShaderRegister = RangeIn.BaseShaderRegister;
- RangeOut.RegisterSpace = RangeIn.RegisterSpace;
- RangeOut.OffsetInDescriptorsFromTableStart = RangeIn.OffsetInDescriptorsFromTableStart;
- DxilDescriptorRangeFlags Flags = GetFlags(RangeIn);
- SetFlags(RangeOut, Flags);
- }
- break;
- }
- case DxilRootParameterType::Constants32Bit: {
- ParamOut.Constants.Num32BitValues = ParamIn.Constants.Num32BitValues;
- ParamOut.Constants.ShaderRegister = ParamIn.Constants.ShaderRegister;
- ParamOut.Constants.RegisterSpace = ParamIn.Constants.RegisterSpace;
- break;
- }
- case DxilRootParameterType::CBV:
- case DxilRootParameterType::SRV:
- case DxilRootParameterType::UAV: {
- ParamOut.Descriptor.ShaderRegister = ParamIn.Descriptor.ShaderRegister;
- ParamOut.Descriptor.RegisterSpace = ParamIn.Descriptor.RegisterSpace;
- DxilRootDescriptorFlags Flags = GetFlags(ParamIn.Descriptor);
- SetFlags(ParamOut.Descriptor, Flags);
- break;
- }
- default:
- IFT(E_FAIL);
- }
- }
- // Static samplers.
- if (pDescIn->NumStaticSamplers > 0) {
- pDescOut->pStaticSamplers = new DxilStaticSamplerDesc[pDescIn->NumStaticSamplers];
- pDescOut->NumStaticSamplers = pDescIn->NumStaticSamplers;
- memcpy((void*)pDescOut->pStaticSamplers, pDescIn->pStaticSamplers, pDescOut->NumStaticSamplers*sizeof(DxilStaticSamplerDesc));
- }
- }
- void ConvertRootSignature(const DxilVersionedRootSignatureDesc * pRootSignatureIn,
- DxilRootSignatureVersion RootSignatureVersionOut,
- const DxilVersionedRootSignatureDesc ** ppRootSignatureOut) {
- IFTBOOL(pRootSignatureIn != nullptr && ppRootSignatureOut != nullptr, E_INVALIDARG);
- *ppRootSignatureOut = nullptr;
- if (pRootSignatureIn->Version == RootSignatureVersionOut){
- // No conversion. Return the original root signature pointer; no cloning.
- *ppRootSignatureOut = pRootSignatureIn;
- return;
- }
- DxilVersionedRootSignatureDesc *pRootSignatureOut = nullptr;
- try {
- pRootSignatureOut = new DxilVersionedRootSignatureDesc();
- memset(pRootSignatureOut, 0, sizeof(*pRootSignatureOut));
- // Convert root signature.
- switch (RootSignatureVersionOut) {
- case DxilRootSignatureVersion::Version_1_0:
- switch (pRootSignatureIn->Version) {
- case DxilRootSignatureVersion::Version_1_1:
- pRootSignatureOut->Version = DxilRootSignatureVersion::Version_1_0;
- ConvertRootSignatureTemplate<
- DxilRootSignatureDesc1,
- DxilRootSignatureDesc,
- DxilRootParameter,
- DxilRootDescriptor,
- DxilDescriptorRange>(pRootSignatureIn->Desc_1_1,
- DxilRootSignatureVersion::Version_1_0,
- pRootSignatureOut->Desc_1_0);
- break;
- default:
- IFT(E_INVALIDARG);
- }
- break;
- case DxilRootSignatureVersion::Version_1_1:
- switch (pRootSignatureIn->Version) {
- case DxilRootSignatureVersion::Version_1_0:
- pRootSignatureOut->Version = DxilRootSignatureVersion::Version_1_1;
- ConvertRootSignatureTemplate<
- DxilRootSignatureDesc,
- DxilRootSignatureDesc1,
- DxilRootParameter1,
- DxilRootDescriptor1,
- DxilDescriptorRange1>(pRootSignatureIn->Desc_1_0,
- DxilRootSignatureVersion::Version_1_1,
- pRootSignatureOut->Desc_1_1);
- break;
- default:
- IFT(E_INVALIDARG);
- }
- break;
- default:
- IFT(E_INVALIDARG);
- break;
- }
- }
- catch (...) {
- DeleteRootSignature(pRootSignatureOut);
- throw;
- }
- *ppRootSignatureOut = pRootSignatureOut;
- }
- template<typename T_ROOT_SIGNATURE_DESC,
- typename T_ROOT_PARAMETER,
- typename T_ROOT_DESCRIPTOR_INTERNAL,
- typename T_DESCRIPTOR_RANGE_INTERNAL>
- void SerializeRootSignatureTemplate(_In_ const T_ROOT_SIGNATURE_DESC* pRootSignature,
- DxilRootSignatureVersion DescVersion,
- _COM_Outptr_ IDxcBlob** ppBlob,
- DiagnosticPrinter &DiagPrinter,
- _In_ bool bAllowReservedRegisterSpace) {
- DxilContainerRootSignatureDesc RS;
- uint32_t Offset;
- SimpleSerializer Serializer;
- IFT(Serializer.AddBlock(&RS, sizeof(RS), &Offset));
- IFTBOOL(Offset == 0, E_FAIL);
- const T_ROOT_SIGNATURE_DESC *pRS = pRootSignature;
- RS.Version = (uint32_t)DescVersion;
- RS.Flags = (uint32_t)pRS->Flags;
- RS.NumParameters = pRS->NumParameters;
- RS.NumStaticSamplers = pRS->NumStaticSamplers;
- DxilContainerRootParameter *pRP;
- IFT(Serializer.ReserveBlock((void**)&pRP,
- sizeof(DxilContainerRootParameter)*RS.NumParameters, &RS.RootParametersOffset));
- for (uint32_t iRP = 0; iRP < RS.NumParameters; iRP++) {
- const T_ROOT_PARAMETER *pInRP = &pRS->pParameters[iRP];
- DxilContainerRootParameter *pOutRP = &pRP[iRP];
- pOutRP->ParameterType = (uint32_t)pInRP->ParameterType;
- pOutRP->ShaderVisibility = (uint32_t)pInRP->ShaderVisibility;
- switch (pInRP->ParameterType) {
- case DxilRootParameterType::DescriptorTable: {
- DxilContainerRootDescriptorTable *p1;
- IFT(Serializer.ReserveBlock((void**)&p1,
- sizeof(DxilContainerRootDescriptorTable),
- &pOutRP->PayloadOffset));
- p1->NumDescriptorRanges = pInRP->DescriptorTable.NumDescriptorRanges;
- T_DESCRIPTOR_RANGE_INTERNAL *p2;
- IFT(Serializer.ReserveBlock((void**)&p2,
- sizeof(T_DESCRIPTOR_RANGE_INTERNAL)*p1->NumDescriptorRanges,
- &p1->DescriptorRangesOffset));
- for (uint32_t i = 0; i < p1->NumDescriptorRanges; i++) {
- p2[i].RangeType = (uint32_t)pInRP->DescriptorTable.pDescriptorRanges[i].RangeType;
- p2[i].NumDescriptors = pInRP->DescriptorTable.pDescriptorRanges[i].NumDescriptors;
- p2[i].BaseShaderRegister = pInRP->DescriptorTable.pDescriptorRanges[i].BaseShaderRegister;
- p2[i].RegisterSpace = pInRP->DescriptorTable.pDescriptorRanges[i].RegisterSpace;
- p2[i].OffsetInDescriptorsFromTableStart = pInRP->DescriptorTable.pDescriptorRanges[i].OffsetInDescriptorsFromTableStart;
- DxilDescriptorRangeFlags Flags = GetFlags(pInRP->DescriptorTable.pDescriptorRanges[i]);
- SetFlags(p2[i], Flags);
- }
- break;
- }
- case DxilRootParameterType::Constants32Bit: {
- DxilRootConstants *p;
- IFT(Serializer.ReserveBlock((void**)&p, sizeof(DxilRootConstants), &pOutRP->PayloadOffset));
- p->Num32BitValues = pInRP->Constants.Num32BitValues;
- p->ShaderRegister = pInRP->Constants.ShaderRegister;
- p->RegisterSpace = pInRP->Constants.RegisterSpace;
- break;
- }
- case DxilRootParameterType::CBV:
- case DxilRootParameterType::SRV:
- case DxilRootParameterType::UAV: {
- T_ROOT_DESCRIPTOR_INTERNAL *p;
- IFT(Serializer.ReserveBlock((void**)&p, sizeof(T_ROOT_DESCRIPTOR_INTERNAL), &pOutRP->PayloadOffset));
- p->ShaderRegister = pInRP->Descriptor.ShaderRegister;
- p->RegisterSpace = pInRP->Descriptor.RegisterSpace;
- DxilRootDescriptorFlags Flags = GetFlags(pInRP->Descriptor);
- SetFlags(*p, Flags);
- break;
- }
- default:
- EAT(DiagPrinter << "D3DSerializeRootSignature: unknown root parameter type ("
- << (uint32_t)pInRP->ParameterType << ")\n");
- }
- }
- DxilStaticSamplerDesc *pSS;
- unsigned StaticSamplerSize = sizeof(DxilStaticSamplerDesc)*RS.NumStaticSamplers;
- IFT(Serializer.ReserveBlock((void**)&pSS, StaticSamplerSize, &RS.StaticSamplersOffset));
- memcpy(pSS, pRS->pStaticSamplers, StaticSamplerSize);
- // Create the result blob.
- CDxcMallocHeapPtr<char> bytes(DxcGetThreadMallocNoRef());
- CComPtr<IDxcBlob> pBlob;
- unsigned cb = Serializer.GetSize();
- DXASSERT_NOMSG((cb & 0x3) == 0);
- IFTBOOL(bytes.Allocate(cb), E_OUTOFMEMORY);
- IFT(Serializer.Compact(bytes.m_pData, cb));
- IFT(DxcCreateBlobOnHeap(bytes.m_pData, cb, ppBlob));
- bytes.Detach(); // Ownership transfered to ppBlob.
- }
- _Use_decl_annotations_
- void SerializeRootSignature(const DxilVersionedRootSignatureDesc *pRootSignature,
- IDxcBlob **ppBlob, IDxcBlobEncoding **ppErrorBlob,
- bool bAllowReservedRegisterSpace) {
- DXASSERT_NOMSG(pRootSignature != nullptr);
- DXASSERT_NOMSG(ppBlob != nullptr);
- DXASSERT_NOMSG(ppErrorBlob != nullptr);
- *ppBlob = nullptr;
- *ppErrorBlob = nullptr;
- RootSignatureVerifier RSV;
- // TODO: change SerializeRootSignature to take raw_ostream&
- string DiagString;
- raw_string_ostream DiagStream(DiagString);
- DiagnosticPrinterRawOStream DiagPrinter(DiagStream);
- // Verify root signature.
- RSV.AllowReservedRegisterSpace(bAllowReservedRegisterSpace);
- try {
- RSV.VerifyRootSignature(pRootSignature, DiagPrinter);
- switch (pRootSignature->Version)
- {
- case DxilRootSignatureVersion::Version_1_0:
- SerializeRootSignatureTemplate<
- DxilRootSignatureDesc,
- DxilRootParameter,
- DxilRootDescriptor,
- DxilContainerDescriptorRange>(&pRootSignature->Desc_1_0,
- DxilRootSignatureVersion::Version_1_0,
- ppBlob, DiagPrinter,
- bAllowReservedRegisterSpace);
- break;
- case DxilRootSignatureVersion::Version_1_1:
- default:
- DXASSERT(pRootSignature->Version == DxilRootSignatureVersion::Version_1_1, "else VerifyRootSignature didn't validate");
- SerializeRootSignatureTemplate<
- DxilRootSignatureDesc1,
- DxilRootParameter1,
- DxilContainerRootDescriptor1,
- DxilContainerDescriptorRange1>(&pRootSignature->Desc_1_1,
- DxilRootSignatureVersion::Version_1_1,
- ppBlob, DiagPrinter,
- bAllowReservedRegisterSpace);
- break;
- }
- } catch (...) {
- DiagStream.flush();
- DxcCreateBlobWithEncodingOnHeapCopy(DiagString.c_str(), DiagString.size(), CP_UTF8, ppErrorBlob);
- }
- }
- //=============================================================================
- //
- // CVersionedRootSignatureDeserializer.
- //
- //=============================================================================
- class CVersionedRootSignatureDeserializer {
- protected:
- const DxilVersionedRootSignatureDesc *m_pRootSignature;
- const DxilVersionedRootSignatureDesc *m_pRootSignature10;
- const DxilVersionedRootSignatureDesc *m_pRootSignature11;
- public:
- CVersionedRootSignatureDeserializer();
- ~CVersionedRootSignatureDeserializer();
- void Initialize(_In_reads_bytes_(SrcDataSizeInBytes) const void *pSrcData,
- _In_ uint32_t SrcDataSizeInBytes);
- const DxilVersionedRootSignatureDesc *GetRootSignatureDescAtVersion(DxilRootSignatureVersion convertToVersion);
- const DxilVersionedRootSignatureDesc *GetUnconvertedRootSignatureDesc();
- };
- CVersionedRootSignatureDeserializer::CVersionedRootSignatureDeserializer()
- : m_pRootSignature(nullptr)
- , m_pRootSignature10(nullptr)
- , m_pRootSignature11(nullptr) {
- }
- CVersionedRootSignatureDeserializer::~CVersionedRootSignatureDeserializer() {
- DeleteRootSignature(m_pRootSignature10);
- DeleteRootSignature(m_pRootSignature11);
- }
- void CVersionedRootSignatureDeserializer::Initialize(_In_reads_bytes_(SrcDataSizeInBytes) const void *pSrcData,
- _In_ uint32_t SrcDataSizeInBytes) {
- const DxilVersionedRootSignatureDesc *pRootSignature = nullptr;
- DeserializeRootSignature(pSrcData, SrcDataSizeInBytes, &pRootSignature);
- switch (pRootSignature->Version) {
- case DxilRootSignatureVersion::Version_1_0:
- m_pRootSignature10 = pRootSignature;
- break;
- case DxilRootSignatureVersion::Version_1_1:
- m_pRootSignature11 = pRootSignature;
- break;
- default:
- DeleteRootSignature(pRootSignature);
- return;
- }
- m_pRootSignature = pRootSignature;
- }
- const DxilVersionedRootSignatureDesc *
- CVersionedRootSignatureDeserializer::GetUnconvertedRootSignatureDesc() {
- return m_pRootSignature;
- }
- const DxilVersionedRootSignatureDesc *
- CVersionedRootSignatureDeserializer::GetRootSignatureDescAtVersion(DxilRootSignatureVersion ConvertToVersion) {
- switch (ConvertToVersion) {
- case DxilRootSignatureVersion::Version_1_0:
- if (m_pRootSignature10 == nullptr) {
- ConvertRootSignature(m_pRootSignature,
- ConvertToVersion,
- (const DxilVersionedRootSignatureDesc **)&m_pRootSignature10);
- }
- return m_pRootSignature10;
- case DxilRootSignatureVersion::Version_1_1:
- if (m_pRootSignature11 == nullptr) {
- ConvertRootSignature(m_pRootSignature,
- ConvertToVersion,
- (const DxilVersionedRootSignatureDesc **)&m_pRootSignature11);
- }
- return m_pRootSignature11;
- default:
- IFTBOOL(false, E_FAIL);
- }
- return nullptr;
- }
- template<typename T_ROOT_SIGNATURE_DESC,
- typename T_ROOT_PARAMETER,
- typename T_ROOT_DESCRIPTOR,
- typename T_ROOT_DESCRIPTOR_INTERNAL,
- typename T_DESCRIPTOR_RANGE,
- typename T_DESCRIPTOR_RANGE_INTERNAL>
- void DeserializeRootSignatureTemplate(_In_reads_bytes_(SrcDataSizeInBytes) const void *pSrcData,
- _In_ uint32_t SrcDataSizeInBytes,
- DxilRootSignatureVersion DescVersion,
- T_ROOT_SIGNATURE_DESC &RootSignatureDesc) {
- // Note that in case of failure, outside code must deallocate memory.
- T_ROOT_SIGNATURE_DESC *pRootSignature = &RootSignatureDesc;
- const char *pData = (const char *)pSrcData;
- const char *pMaxPtr = pData + SrcDataSizeInBytes;
- UNREFERENCED_PARAMETER(DescVersion);
- DXASSERT_NOMSG(((uint32_t*)pData)[0] == (uint32_t)DescVersion);
- // Root signature.
- IFTBOOL(pData + sizeof(DxilContainerRootSignatureDesc) <= pMaxPtr, E_FAIL);
- DxilContainerRootSignatureDesc *pRS = (DxilContainerRootSignatureDesc *)pData;
- pRootSignature->Flags = (DxilRootSignatureFlags)pRS->Flags;
- pRootSignature->NumParameters = pRS->NumParameters;
- pRootSignature->NumStaticSamplers = pRS->NumStaticSamplers;
- // Intialize all pointers early so that clean up works properly.
- pRootSignature->pParameters = nullptr;
- pRootSignature->pStaticSamplers = nullptr;
- size_t s = sizeof(DxilContainerRootParameter)*pRS->NumParameters;
- DxilContainerRootParameter *pInRTS = (DxilContainerRootParameter *)(pData + pRS->RootParametersOffset);
- IFTBOOL(((char*)pInRTS) + s <= pMaxPtr, E_FAIL);
- if (pRootSignature->NumParameters) {
- pRootSignature->pParameters = new T_ROOT_PARAMETER[pRootSignature->NumParameters];
- }
- memset((void *)pRootSignature->pParameters, 0, s);
- for(unsigned iRP = 0; iRP < pRootSignature->NumParameters; iRP++) {
- DxilRootParameterType ParameterType = (DxilRootParameterType)pInRTS[iRP].ParameterType;
- T_ROOT_PARAMETER *pOutRTS = (T_ROOT_PARAMETER *)&pRootSignature->pParameters[iRP];
- pOutRTS->ParameterType = ParameterType;
- pOutRTS->ShaderVisibility = (DxilShaderVisibility)pInRTS[iRP].ShaderVisibility;
- switch(ParameterType) {
- case DxilRootParameterType::DescriptorTable: {
- DxilContainerRootDescriptorTable *p1 = (DxilContainerRootDescriptorTable*)(pData + pInRTS[iRP].PayloadOffset);
- IFTBOOL((char*)p1 + sizeof(DxilContainerRootDescriptorTable) <= pMaxPtr, E_FAIL);
- pOutRTS->DescriptorTable.NumDescriptorRanges = p1->NumDescriptorRanges;
- pOutRTS->DescriptorTable.pDescriptorRanges = nullptr;
- T_DESCRIPTOR_RANGE_INTERNAL *p2 = (T_DESCRIPTOR_RANGE_INTERNAL*)(pData + p1->DescriptorRangesOffset);
- IFTBOOL((char*)p2 + sizeof(T_DESCRIPTOR_RANGE_INTERNAL) <= pMaxPtr, E_FAIL);
- if (p1->NumDescriptorRanges) {
- pOutRTS->DescriptorTable.pDescriptorRanges = new T_DESCRIPTOR_RANGE[p1->NumDescriptorRanges];
- }
- for (unsigned i = 0; i < p1->NumDescriptorRanges; i++) {
- T_DESCRIPTOR_RANGE *p3 = (T_DESCRIPTOR_RANGE *)&pOutRTS->DescriptorTable.pDescriptorRanges[i];
- p3->RangeType = (DxilDescriptorRangeType)p2[i].RangeType;
- p3->NumDescriptors = p2[i].NumDescriptors;
- p3->BaseShaderRegister = p2[i].BaseShaderRegister;
- p3->RegisterSpace = p2[i].RegisterSpace;
- p3->OffsetInDescriptorsFromTableStart = p2[i].OffsetInDescriptorsFromTableStart;
- DxilDescriptorRangeFlags Flags = GetFlags(p2[i]);
- SetFlags(*p3, Flags);
- }
- break;
- }
- case DxilRootParameterType::Constants32Bit: {
- DxilRootConstants *p = (DxilRootConstants*)(pData + pInRTS[iRP].PayloadOffset);
- IFTBOOL((char*)p + sizeof(DxilRootConstants) <= pMaxPtr, E_FAIL);
- pOutRTS->Constants.Num32BitValues = p->Num32BitValues;
- pOutRTS->Constants.ShaderRegister = p->ShaderRegister;
- pOutRTS->Constants.RegisterSpace = p->RegisterSpace;
- break;
- }
- case DxilRootParameterType::CBV:
- case DxilRootParameterType::SRV:
- case DxilRootParameterType::UAV: {
- T_ROOT_DESCRIPTOR *p = (T_ROOT_DESCRIPTOR *)(pData + pInRTS[iRP].PayloadOffset);
- IFTBOOL((char*)p + sizeof(T_ROOT_DESCRIPTOR) <= pMaxPtr, E_FAIL);
- pOutRTS->Descriptor.ShaderRegister = p->ShaderRegister;
- pOutRTS->Descriptor.RegisterSpace = p->RegisterSpace;
- DxilRootDescriptorFlags Flags = GetFlags(*p);
- SetFlags(pOutRTS->Descriptor, Flags);
- break;
- }
- default:
- IFT(E_FAIL);
- }
- }
- s = sizeof(DxilStaticSamplerDesc)*pRS->NumStaticSamplers;
- DxilStaticSamplerDesc *pInSS = (DxilStaticSamplerDesc *)(pData + pRS->StaticSamplersOffset);
- IFTBOOL(((char*)pInSS) + s <= pMaxPtr, E_FAIL);
- if (pRootSignature->NumStaticSamplers) {
- pRootSignature->pStaticSamplers = new DxilStaticSamplerDesc[pRootSignature->NumStaticSamplers];
- }
- memcpy((void*)pRootSignature->pStaticSamplers, pInSS, s);
- }
- _Use_decl_annotations_
- void DeserializeRootSignature(const void *pSrcData,
- uint32_t SrcDataSizeInBytes,
- const DxilVersionedRootSignatureDesc **ppRootSignature) {
- DxilVersionedRootSignatureDesc *pRootSignature = nullptr;
- IFTBOOL(pSrcData != nullptr && SrcDataSizeInBytes != 0 && ppRootSignature != nullptr, E_INVALIDARG);
- IFTBOOL(*ppRootSignature == nullptr, E_INVALIDARG);
- const char *pData = (const char *)pSrcData;
- IFTBOOL(pData + sizeof(uint32_t) < pData + SrcDataSizeInBytes, E_FAIL);
- DxilRootSignatureVersion Version = (DxilRootSignatureVersion)((uint32_t*)pData)[0];
- pRootSignature = new DxilVersionedRootSignatureDesc();
- try {
- switch (Version) {
- case DxilRootSignatureVersion::Version_1_0:
- pRootSignature->Version = DxilRootSignatureVersion::Version_1_0;
- DeserializeRootSignatureTemplate<
- DxilRootSignatureDesc,
- DxilRootParameter,
- DxilRootDescriptor,
- DxilRootDescriptor,
- DxilDescriptorRange,
- DxilContainerDescriptorRange>(pSrcData,
- SrcDataSizeInBytes,
- DxilRootSignatureVersion::Version_1_0,
- pRootSignature->Desc_1_0);
- break;
- case DxilRootSignatureVersion::Version_1_1:
- pRootSignature->Version = DxilRootSignatureVersion::Version_1_1;
- DeserializeRootSignatureTemplate<
- DxilRootSignatureDesc1,
- DxilRootParameter1,
- DxilRootDescriptor1,
- DxilContainerRootDescriptor1,
- DxilDescriptorRange1,
- DxilContainerDescriptorRange1>(pSrcData,
- SrcDataSizeInBytes,
- DxilRootSignatureVersion::Version_1_1,
- pRootSignature->Desc_1_1);
- break;
- default:
- IFT(E_FAIL);
- break;
- }
- } catch(...) {
- DeleteRootSignature(pRootSignature);
- throw;
- }
- *ppRootSignature = pRootSignature;
- }
- static DxilShaderVisibility GetVisibilityType(DXIL::ShaderKind ShaderKind) {
- switch(ShaderKind) {
- case DXIL::ShaderKind::Pixel: return DxilShaderVisibility::Pixel;
- case DXIL::ShaderKind::Vertex: return DxilShaderVisibility::Vertex;
- case DXIL::ShaderKind::Geometry: return DxilShaderVisibility::Geometry;
- case DXIL::ShaderKind::Hull: return DxilShaderVisibility::Hull;
- case DXIL::ShaderKind::Domain: return DxilShaderVisibility::Domain;
- default: return DxilShaderVisibility::All;
- }
- }
- _Use_decl_annotations_
- bool VerifyRootSignatureWithShaderPSV(const DxilVersionedRootSignatureDesc *pDesc,
- DXIL::ShaderKind ShaderKind,
- const void *pPSVData,
- uint32_t PSVSize,
- llvm::raw_ostream &DiagStream) {
- try {
- RootSignatureVerifier RSV;
- DiagnosticPrinterRawOStream DiagPrinter(DiagStream);
- RSV.VerifyRootSignature(pDesc, DiagPrinter);
- RSV.VerifyShader(GetVisibilityType(ShaderKind), pPSVData, PSVSize, DiagPrinter);
- } catch (...) {
- return false;
- }
- return true;
- }
- } // namespace hlsl
|