DxilRootSignatureSerializer.cpp 21 KB

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