DxilRootSignatureSerializer.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // //
  3. // DxilRootSignatureSerializer.cpp //
  4. // Copyright (C) Microsoft Corporation. All rights reserved. //
  5. // This file is distributed under the University of Illinois Open Source //
  6. // License. See LICENSE.TXT for details. //
  7. // //
  8. // Serializer for root signature structures. //
  9. // //
  10. ///////////////////////////////////////////////////////////////////////////////
  11. #include "dxc/DXIL/DxilConstants.h"
  12. #include "dxc/DxilRootSignature/DxilRootSignature.h"
  13. #include "dxc/Support/Global.h"
  14. #include "dxc/Support/WinIncludes.h"
  15. #include "dxc/Support/WinFunctions.h"
  16. #include "dxc/Support/FileIOHelper.h"
  17. #include "dxc/dxcapi.h"
  18. #include "llvm/Support/raw_ostream.h"
  19. #include "llvm/IR/DiagnosticPrinter.h"
  20. #include <string>
  21. #include <algorithm>
  22. #include <utility>
  23. #include <vector>
  24. #include <set>
  25. #include "DxilRootSignatureHelper.h"
  26. using namespace llvm;
  27. using std::string;
  28. namespace hlsl {
  29. using namespace root_sig_helper;
  30. //////////////////////////////////////////////////////////////////////////////
  31. // Simple serializer.
  32. class SimpleSerializer {
  33. struct Segment {
  34. void *pData;
  35. unsigned cbSize;
  36. bool bOwner;
  37. unsigned Offset;
  38. Segment *pNext;
  39. };
  40. public:
  41. SimpleSerializer();
  42. ~SimpleSerializer();
  43. HRESULT AddBlock(void *pData, unsigned cbSize, unsigned *pOffset);
  44. HRESULT ReserveBlock(void **ppData, unsigned cbSize, unsigned *pOffset);
  45. HRESULT Compact(_Out_writes_bytes_(cbSize) char *pData, unsigned cbSize);
  46. unsigned GetSize();
  47. protected:
  48. unsigned m_cbSegments;
  49. Segment *m_pSegment;
  50. Segment **m_ppSegment;
  51. };
  52. SimpleSerializer::SimpleSerializer() {
  53. m_cbSegments = 0;
  54. m_pSegment = nullptr;
  55. m_ppSegment = &m_pSegment;
  56. }
  57. SimpleSerializer::~SimpleSerializer() {
  58. while (m_pSegment) {
  59. Segment *pSegment = m_pSegment;
  60. m_pSegment = pSegment->pNext;
  61. if (pSegment->bOwner) {
  62. delete[] (char*)pSegment->pData;
  63. }
  64. delete pSegment;
  65. }
  66. }
  67. HRESULT SimpleSerializer::AddBlock(void *pData, unsigned cbSize,
  68. unsigned *pOffset) {
  69. Segment *pSegment = nullptr;
  70. IFRBOOL(!(cbSize != 0 && pData == nullptr), E_FAIL);
  71. IFROOM(pSegment = new (std::nothrow) Segment);
  72. pSegment->pData = pData;
  73. m_cbSegments = (m_cbSegments + 3) & ~3;
  74. pSegment->Offset = m_cbSegments;
  75. pSegment->cbSize = cbSize;
  76. pSegment->bOwner = false;
  77. pSegment->pNext = nullptr;
  78. m_cbSegments += pSegment->cbSize;
  79. *m_ppSegment = pSegment;
  80. m_ppSegment = &pSegment->pNext;
  81. if (pOffset != nullptr) {
  82. *pOffset = pSegment->Offset;
  83. }
  84. return S_OK;
  85. }
  86. HRESULT SimpleSerializer::ReserveBlock(void **ppData, unsigned cbSize,
  87. unsigned *pOffset) {
  88. HRESULT hr = S_OK;
  89. Segment *pSegment = nullptr;
  90. void *pClonedData = nullptr;
  91. IFCOOM(pSegment = new (std::nothrow) Segment);
  92. pSegment->pData = nullptr;
  93. IFCOOM(pClonedData = new (std::nothrow) char[cbSize]);
  94. pSegment->pData = pClonedData;
  95. m_cbSegments = (m_cbSegments + 3) & ~3;
  96. pSegment->Offset = m_cbSegments;
  97. pSegment->cbSize = cbSize;
  98. pSegment->bOwner = true;
  99. pSegment->pNext = nullptr;
  100. m_cbSegments += pSegment->cbSize;
  101. *m_ppSegment = pSegment;
  102. m_ppSegment = &pSegment->pNext;
  103. *ppData = pClonedData;
  104. if (pOffset) {
  105. *pOffset = pSegment->Offset;
  106. }
  107. Cleanup:
  108. if (FAILED(hr)) {
  109. delete[] (char*)pClonedData;
  110. delete pSegment;
  111. }
  112. return hr;
  113. }
  114. HRESULT SimpleSerializer::Compact(_Out_writes_bytes_(cbSize) char *pData,
  115. unsigned cbSize) {
  116. unsigned cb = GetSize();
  117. IFRBOOL(cb <= cbSize, E_FAIL);
  118. DXASSERT_NOMSG(cb <= UINT32_MAX / 2);
  119. char *p = (char *)pData;
  120. cb = 0;
  121. for (Segment *pSegment = m_pSegment; pSegment; pSegment = pSegment->pNext) {
  122. unsigned cbAlign = ((cb + 3) & ~3) - cb;
  123. _Analysis_assume_(p + cbAlign <= pData + cbSize);
  124. memset(p, 0xab, cbAlign);
  125. p += cbAlign;
  126. cb += cbAlign;
  127. _Analysis_assume_(p + pSegment->cbSize <= pData + cbSize);
  128. memcpy(p, pSegment->pData, pSegment->cbSize);
  129. p += pSegment->cbSize;
  130. cb += pSegment->cbSize;
  131. }
  132. // Trailing zeros
  133. _Analysis_assume_(p + cbSize - cb <= pData + cbSize);
  134. memset(p, 0xab, cbSize - cb);
  135. return S_OK;
  136. }
  137. unsigned SimpleSerializer::GetSize() {
  138. // Round up to 4==sizeof(unsigned).
  139. return ((m_cbSegments + 3) >> 2) * 4;
  140. }
  141. template<typename T_ROOT_SIGNATURE_DESC,
  142. typename T_ROOT_PARAMETER,
  143. typename T_ROOT_DESCRIPTOR_INTERNAL,
  144. typename T_DESCRIPTOR_RANGE_INTERNAL>
  145. void SerializeRootSignatureTemplate(_In_ const T_ROOT_SIGNATURE_DESC* pRootSignature,
  146. DxilRootSignatureVersion DescVersion,
  147. _COM_Outptr_ IDxcBlob** ppBlob,
  148. DiagnosticPrinter &DiagPrinter,
  149. _In_ bool bAllowReservedRegisterSpace) {
  150. DxilContainerRootSignatureDesc RS;
  151. uint32_t Offset;
  152. SimpleSerializer Serializer;
  153. IFT(Serializer.AddBlock(&RS, sizeof(RS), &Offset));
  154. IFTBOOL(Offset == 0, E_FAIL);
  155. const T_ROOT_SIGNATURE_DESC *pRS = pRootSignature;
  156. RS.Version = (uint32_t)DescVersion;
  157. RS.Flags = (uint32_t)pRS->Flags;
  158. RS.NumParameters = pRS->NumParameters;
  159. RS.NumStaticSamplers = pRS->NumStaticSamplers;
  160. DxilContainerRootParameter *pRP;
  161. IFT(Serializer.ReserveBlock((void**)&pRP,
  162. sizeof(DxilContainerRootParameter)*RS.NumParameters, &RS.RootParametersOffset));
  163. for (uint32_t iRP = 0; iRP < RS.NumParameters; iRP++) {
  164. const T_ROOT_PARAMETER *pInRP = &pRS->pParameters[iRP];
  165. DxilContainerRootParameter *pOutRP = &pRP[iRP];
  166. pOutRP->ParameterType = (uint32_t)pInRP->ParameterType;
  167. pOutRP->ShaderVisibility = (uint32_t)pInRP->ShaderVisibility;
  168. switch (pInRP->ParameterType) {
  169. case DxilRootParameterType::DescriptorTable: {
  170. DxilContainerRootDescriptorTable *p1;
  171. IFT(Serializer.ReserveBlock((void**)&p1,
  172. sizeof(DxilContainerRootDescriptorTable),
  173. &pOutRP->PayloadOffset));
  174. p1->NumDescriptorRanges = pInRP->DescriptorTable.NumDescriptorRanges;
  175. T_DESCRIPTOR_RANGE_INTERNAL *p2;
  176. IFT(Serializer.ReserveBlock((void**)&p2,
  177. sizeof(T_DESCRIPTOR_RANGE_INTERNAL)*p1->NumDescriptorRanges,
  178. &p1->DescriptorRangesOffset));
  179. for (uint32_t i = 0; i < p1->NumDescriptorRanges; i++) {
  180. p2[i].RangeType = (uint32_t)pInRP->DescriptorTable.pDescriptorRanges[i].RangeType;
  181. p2[i].NumDescriptors = pInRP->DescriptorTable.pDescriptorRanges[i].NumDescriptors;
  182. p2[i].BaseShaderRegister = pInRP->DescriptorTable.pDescriptorRanges[i].BaseShaderRegister;
  183. p2[i].RegisterSpace = pInRP->DescriptorTable.pDescriptorRanges[i].RegisterSpace;
  184. p2[i].OffsetInDescriptorsFromTableStart = pInRP->DescriptorTable.pDescriptorRanges[i].OffsetInDescriptorsFromTableStart;
  185. DxilDescriptorRangeFlags Flags = GetFlags(pInRP->DescriptorTable.pDescriptorRanges[i]);
  186. SetFlags(p2[i], Flags);
  187. }
  188. break;
  189. }
  190. case DxilRootParameterType::Constants32Bit: {
  191. DxilRootConstants *p;
  192. IFT(Serializer.ReserveBlock((void**)&p, sizeof(DxilRootConstants), &pOutRP->PayloadOffset));
  193. p->Num32BitValues = pInRP->Constants.Num32BitValues;
  194. p->ShaderRegister = pInRP->Constants.ShaderRegister;
  195. p->RegisterSpace = pInRP->Constants.RegisterSpace;
  196. break;
  197. }
  198. case DxilRootParameterType::CBV:
  199. case DxilRootParameterType::SRV:
  200. case DxilRootParameterType::UAV: {
  201. T_ROOT_DESCRIPTOR_INTERNAL *p;
  202. IFT(Serializer.ReserveBlock((void**)&p, sizeof(T_ROOT_DESCRIPTOR_INTERNAL), &pOutRP->PayloadOffset));
  203. p->ShaderRegister = pInRP->Descriptor.ShaderRegister;
  204. p->RegisterSpace = pInRP->Descriptor.RegisterSpace;
  205. DxilRootDescriptorFlags Flags = GetFlags(pInRP->Descriptor);
  206. SetFlags(*p, Flags);
  207. break;
  208. }
  209. default:
  210. EAT(DiagPrinter << "D3DSerializeRootSignature: unknown root parameter type ("
  211. << (uint32_t)pInRP->ParameterType << ")\n");
  212. }
  213. }
  214. DxilStaticSamplerDesc *pSS;
  215. unsigned StaticSamplerSize = sizeof(DxilStaticSamplerDesc)*RS.NumStaticSamplers;
  216. IFT(Serializer.ReserveBlock((void**)&pSS, StaticSamplerSize, &RS.StaticSamplersOffset));
  217. memcpy(pSS, pRS->pStaticSamplers, StaticSamplerSize);
  218. // Create the result blob.
  219. CDxcMallocHeapPtr<char> bytes(DxcGetThreadMallocNoRef());
  220. CComPtr<IDxcBlob> pBlob;
  221. unsigned cb = Serializer.GetSize();
  222. DXASSERT_NOMSG((cb & 0x3) == 0);
  223. IFTBOOL(bytes.Allocate(cb), E_OUTOFMEMORY);
  224. IFT(Serializer.Compact(bytes.m_pData, cb));
  225. IFT(DxcCreateBlobOnMalloc(bytes.m_pData, bytes.GetMallocNoRef(), cb, ppBlob));
  226. bytes.Detach(); // Ownership transfered to ppBlob.
  227. }
  228. _Use_decl_annotations_
  229. void SerializeRootSignature(const DxilVersionedRootSignatureDesc *pRootSignature,
  230. IDxcBlob **ppBlob, IDxcBlobEncoding **ppErrorBlob,
  231. bool bAllowReservedRegisterSpace) {
  232. DXASSERT_NOMSG(pRootSignature != nullptr);
  233. DXASSERT_NOMSG(ppBlob != nullptr);
  234. DXASSERT_NOMSG(ppErrorBlob != nullptr);
  235. *ppBlob = nullptr;
  236. *ppErrorBlob = nullptr;
  237. // TODO: change SerializeRootSignature to take raw_ostream&
  238. string DiagString;
  239. raw_string_ostream DiagStream(DiagString);
  240. DiagnosticPrinterRawOStream DiagPrinter(DiagStream);
  241. // Verify root signature.
  242. if (!VerifyRootSignature(pRootSignature, DiagStream,
  243. bAllowReservedRegisterSpace)) {
  244. DiagStream.flush();
  245. DxcCreateBlobWithEncodingOnHeapCopy(DiagString.c_str(), DiagString.size(), CP_UTF8, ppErrorBlob);
  246. return;
  247. }
  248. try {
  249. switch (pRootSignature->Version)
  250. {
  251. case DxilRootSignatureVersion::Version_1_0:
  252. SerializeRootSignatureTemplate<
  253. DxilRootSignatureDesc,
  254. DxilRootParameter,
  255. DxilRootDescriptor,
  256. DxilContainerDescriptorRange>(&pRootSignature->Desc_1_0,
  257. DxilRootSignatureVersion::Version_1_0,
  258. ppBlob, DiagPrinter,
  259. bAllowReservedRegisterSpace);
  260. break;
  261. case DxilRootSignatureVersion::Version_1_1:
  262. default:
  263. DXASSERT(pRootSignature->Version == DxilRootSignatureVersion::Version_1_1, "else VerifyRootSignature didn't validate");
  264. SerializeRootSignatureTemplate<
  265. DxilRootSignatureDesc1,
  266. DxilRootParameter1,
  267. DxilContainerRootDescriptor1,
  268. DxilContainerDescriptorRange1>(&pRootSignature->Desc_1_1,
  269. DxilRootSignatureVersion::Version_1_1,
  270. ppBlob, DiagPrinter,
  271. bAllowReservedRegisterSpace);
  272. break;
  273. }
  274. } catch (...) {
  275. DiagStream.flush();
  276. DxcCreateBlobWithEncodingOnHeapCopy(DiagString.c_str(), DiagString.size(), CP_UTF8, ppErrorBlob);
  277. }
  278. }
  279. //=============================================================================
  280. //
  281. // CVersionedRootSignatureDeserializer.
  282. //
  283. //=============================================================================
  284. class CVersionedRootSignatureDeserializer {
  285. protected:
  286. const DxilVersionedRootSignatureDesc *m_pRootSignature;
  287. const DxilVersionedRootSignatureDesc *m_pRootSignature10;
  288. const DxilVersionedRootSignatureDesc *m_pRootSignature11;
  289. public:
  290. CVersionedRootSignatureDeserializer();
  291. ~CVersionedRootSignatureDeserializer();
  292. void Initialize(_In_reads_bytes_(SrcDataSizeInBytes) const void *pSrcData,
  293. _In_ uint32_t SrcDataSizeInBytes);
  294. const DxilVersionedRootSignatureDesc *GetRootSignatureDescAtVersion(DxilRootSignatureVersion convertToVersion);
  295. const DxilVersionedRootSignatureDesc *GetUnconvertedRootSignatureDesc();
  296. };
  297. CVersionedRootSignatureDeserializer::CVersionedRootSignatureDeserializer()
  298. : m_pRootSignature(nullptr)
  299. , m_pRootSignature10(nullptr)
  300. , m_pRootSignature11(nullptr) {
  301. }
  302. CVersionedRootSignatureDeserializer::~CVersionedRootSignatureDeserializer() {
  303. DeleteRootSignature(m_pRootSignature10);
  304. DeleteRootSignature(m_pRootSignature11);
  305. }
  306. void CVersionedRootSignatureDeserializer::Initialize(_In_reads_bytes_(SrcDataSizeInBytes) const void *pSrcData,
  307. _In_ uint32_t SrcDataSizeInBytes) {
  308. const DxilVersionedRootSignatureDesc *pRootSignature = nullptr;
  309. DeserializeRootSignature(pSrcData, SrcDataSizeInBytes, &pRootSignature);
  310. switch (pRootSignature->Version) {
  311. case DxilRootSignatureVersion::Version_1_0:
  312. m_pRootSignature10 = pRootSignature;
  313. break;
  314. case DxilRootSignatureVersion::Version_1_1:
  315. m_pRootSignature11 = pRootSignature;
  316. break;
  317. default:
  318. DeleteRootSignature(pRootSignature);
  319. return;
  320. }
  321. m_pRootSignature = pRootSignature;
  322. }
  323. const DxilVersionedRootSignatureDesc *
  324. CVersionedRootSignatureDeserializer::GetUnconvertedRootSignatureDesc() {
  325. return m_pRootSignature;
  326. }
  327. const DxilVersionedRootSignatureDesc *
  328. CVersionedRootSignatureDeserializer::GetRootSignatureDescAtVersion(DxilRootSignatureVersion ConvertToVersion) {
  329. switch (ConvertToVersion) {
  330. case DxilRootSignatureVersion::Version_1_0:
  331. if (m_pRootSignature10 == nullptr) {
  332. ConvertRootSignature(m_pRootSignature,
  333. ConvertToVersion,
  334. (const DxilVersionedRootSignatureDesc **)&m_pRootSignature10);
  335. }
  336. return m_pRootSignature10;
  337. case DxilRootSignatureVersion::Version_1_1:
  338. if (m_pRootSignature11 == nullptr) {
  339. ConvertRootSignature(m_pRootSignature,
  340. ConvertToVersion,
  341. (const DxilVersionedRootSignatureDesc **)&m_pRootSignature11);
  342. }
  343. return m_pRootSignature11;
  344. default:
  345. IFTBOOL(false, E_FAIL);
  346. }
  347. return nullptr;
  348. }
  349. template<typename T_ROOT_SIGNATURE_DESC,
  350. typename T_ROOT_PARAMETER,
  351. typename T_ROOT_DESCRIPTOR,
  352. typename T_ROOT_DESCRIPTOR_INTERNAL,
  353. typename T_DESCRIPTOR_RANGE,
  354. typename T_DESCRIPTOR_RANGE_INTERNAL>
  355. void DeserializeRootSignatureTemplate(_In_reads_bytes_(SrcDataSizeInBytes) const void *pSrcData,
  356. _In_ uint32_t SrcDataSizeInBytes,
  357. DxilRootSignatureVersion DescVersion,
  358. T_ROOT_SIGNATURE_DESC &RootSignatureDesc) {
  359. // Note that in case of failure, outside code must deallocate memory.
  360. T_ROOT_SIGNATURE_DESC *pRootSignature = &RootSignatureDesc;
  361. const char *pData = (const char *)pSrcData;
  362. const char *pMaxPtr = pData + SrcDataSizeInBytes;
  363. UNREFERENCED_PARAMETER(DescVersion);
  364. DXASSERT_NOMSG(((const uint32_t*)pData)[0] == (uint32_t)DescVersion);
  365. // Root signature.
  366. IFTBOOL(pData + sizeof(DxilContainerRootSignatureDesc) <= pMaxPtr, E_FAIL);
  367. const DxilContainerRootSignatureDesc *pRS = (const DxilContainerRootSignatureDesc *)pData;
  368. pRootSignature->Flags = (DxilRootSignatureFlags)pRS->Flags;
  369. pRootSignature->NumParameters = pRS->NumParameters;
  370. pRootSignature->NumStaticSamplers = pRS->NumStaticSamplers;
  371. // Intialize all pointers early so that clean up works properly.
  372. pRootSignature->pParameters = nullptr;
  373. pRootSignature->pStaticSamplers = nullptr;
  374. size_t s = sizeof(DxilContainerRootParameter)*pRS->NumParameters;
  375. const DxilContainerRootParameter *pInRTS = (const DxilContainerRootParameter *)(pData + pRS->RootParametersOffset);
  376. IFTBOOL(((const char*)pInRTS) + s <= pMaxPtr, E_FAIL);
  377. if (pRootSignature->NumParameters) {
  378. pRootSignature->pParameters = new T_ROOT_PARAMETER[pRootSignature->NumParameters];
  379. }
  380. memset((void *)pRootSignature->pParameters, 0, s);
  381. for(unsigned iRP = 0; iRP < pRootSignature->NumParameters; iRP++) {
  382. DxilRootParameterType ParameterType = (DxilRootParameterType)pInRTS[iRP].ParameterType;
  383. T_ROOT_PARAMETER *pOutRTS = (T_ROOT_PARAMETER *)&pRootSignature->pParameters[iRP];
  384. pOutRTS->ParameterType = ParameterType;
  385. pOutRTS->ShaderVisibility = (DxilShaderVisibility)pInRTS[iRP].ShaderVisibility;
  386. switch(ParameterType) {
  387. case DxilRootParameterType::DescriptorTable: {
  388. const DxilContainerRootDescriptorTable *p1 = (const DxilContainerRootDescriptorTable*)(pData + pInRTS[iRP].PayloadOffset);
  389. IFTBOOL((const char*)p1 + sizeof(DxilContainerRootDescriptorTable) <= pMaxPtr, E_FAIL);
  390. pOutRTS->DescriptorTable.NumDescriptorRanges = p1->NumDescriptorRanges;
  391. pOutRTS->DescriptorTable.pDescriptorRanges = nullptr;
  392. const T_DESCRIPTOR_RANGE_INTERNAL *p2 = (const T_DESCRIPTOR_RANGE_INTERNAL*)(pData + p1->DescriptorRangesOffset);
  393. IFTBOOL((const char*)p2 + sizeof(T_DESCRIPTOR_RANGE_INTERNAL) <= pMaxPtr, E_FAIL);
  394. if (p1->NumDescriptorRanges) {
  395. pOutRTS->DescriptorTable.pDescriptorRanges = new T_DESCRIPTOR_RANGE[p1->NumDescriptorRanges];
  396. }
  397. for (unsigned i = 0; i < p1->NumDescriptorRanges; i++) {
  398. T_DESCRIPTOR_RANGE *p3 = (T_DESCRIPTOR_RANGE *)&pOutRTS->DescriptorTable.pDescriptorRanges[i];
  399. p3->RangeType = (DxilDescriptorRangeType)p2[i].RangeType;
  400. p3->NumDescriptors = p2[i].NumDescriptors;
  401. p3->BaseShaderRegister = p2[i].BaseShaderRegister;
  402. p3->RegisterSpace = p2[i].RegisterSpace;
  403. p3->OffsetInDescriptorsFromTableStart = p2[i].OffsetInDescriptorsFromTableStart;
  404. DxilDescriptorRangeFlags Flags = GetFlags(p2[i]);
  405. SetFlags(*p3, Flags);
  406. }
  407. break;
  408. }
  409. case DxilRootParameterType::Constants32Bit: {
  410. const DxilRootConstants *p = (const DxilRootConstants*)(pData + pInRTS[iRP].PayloadOffset);
  411. IFTBOOL((const char*)p + sizeof(DxilRootConstants) <= pMaxPtr, E_FAIL);
  412. pOutRTS->Constants.Num32BitValues = p->Num32BitValues;
  413. pOutRTS->Constants.ShaderRegister = p->ShaderRegister;
  414. pOutRTS->Constants.RegisterSpace = p->RegisterSpace;
  415. break;
  416. }
  417. case DxilRootParameterType::CBV:
  418. case DxilRootParameterType::SRV:
  419. case DxilRootParameterType::UAV: {
  420. const T_ROOT_DESCRIPTOR *p = (const T_ROOT_DESCRIPTOR *)(pData + pInRTS[iRP].PayloadOffset);
  421. IFTBOOL((const char*)p + sizeof(T_ROOT_DESCRIPTOR) <= pMaxPtr, E_FAIL);
  422. pOutRTS->Descriptor.ShaderRegister = p->ShaderRegister;
  423. pOutRTS->Descriptor.RegisterSpace = p->RegisterSpace;
  424. DxilRootDescriptorFlags Flags = GetFlags(*p);
  425. SetFlags(pOutRTS->Descriptor, Flags);
  426. break;
  427. }
  428. default:
  429. IFT(E_FAIL);
  430. }
  431. }
  432. s = sizeof(DxilStaticSamplerDesc)*pRS->NumStaticSamplers;
  433. const DxilStaticSamplerDesc *pInSS = (const DxilStaticSamplerDesc *)(pData + pRS->StaticSamplersOffset);
  434. IFTBOOL(((const char*)pInSS) + s <= pMaxPtr, E_FAIL);
  435. if (pRootSignature->NumStaticSamplers) {
  436. pRootSignature->pStaticSamplers = new DxilStaticSamplerDesc[pRootSignature->NumStaticSamplers];
  437. }
  438. memcpy((void*)pRootSignature->pStaticSamplers, pInSS, s);
  439. }
  440. _Use_decl_annotations_
  441. void DeserializeRootSignature(const void *pSrcData,
  442. uint32_t SrcDataSizeInBytes,
  443. const DxilVersionedRootSignatureDesc **ppRootSignature) {
  444. DxilVersionedRootSignatureDesc *pRootSignature = nullptr;
  445. IFTBOOL(pSrcData != nullptr && SrcDataSizeInBytes != 0 && ppRootSignature != nullptr, E_INVALIDARG);
  446. IFTBOOL(*ppRootSignature == nullptr, E_INVALIDARG);
  447. const char *pData = (const char *)pSrcData;
  448. IFTBOOL(pData + sizeof(uint32_t) < pData + SrcDataSizeInBytes, E_FAIL);
  449. DxilRootSignatureVersion Version = (const DxilRootSignatureVersion)((const uint32_t*)pData)[0];
  450. pRootSignature = new DxilVersionedRootSignatureDesc();
  451. try {
  452. switch (Version) {
  453. case DxilRootSignatureVersion::Version_1_0:
  454. pRootSignature->Version = DxilRootSignatureVersion::Version_1_0;
  455. DeserializeRootSignatureTemplate<
  456. DxilRootSignatureDesc,
  457. DxilRootParameter,
  458. DxilRootDescriptor,
  459. DxilRootDescriptor,
  460. DxilDescriptorRange,
  461. DxilContainerDescriptorRange>(pSrcData,
  462. SrcDataSizeInBytes,
  463. DxilRootSignatureVersion::Version_1_0,
  464. pRootSignature->Desc_1_0);
  465. break;
  466. case DxilRootSignatureVersion::Version_1_1:
  467. pRootSignature->Version = DxilRootSignatureVersion::Version_1_1;
  468. DeserializeRootSignatureTemplate<
  469. DxilRootSignatureDesc1,
  470. DxilRootParameter1,
  471. DxilRootDescriptor1,
  472. DxilContainerRootDescriptor1,
  473. DxilDescriptorRange1,
  474. DxilContainerDescriptorRange1>(pSrcData,
  475. SrcDataSizeInBytes,
  476. DxilRootSignatureVersion::Version_1_1,
  477. pRootSignature->Desc_1_1);
  478. break;
  479. default:
  480. IFT(E_FAIL);
  481. break;
  482. }
  483. } catch(...) {
  484. DeleteRootSignature(pRootSignature);
  485. throw;
  486. }
  487. *ppRootSignature = pRootSignature;
  488. }
  489. } // namespace hlsl