DxilRuntimeReflection.h 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // //
  3. // DxilLibraryReflection.h //
  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. // Defines shader reflection for runtime usage. //
  9. // //
  10. ///////////////////////////////////////////////////////////////////////////////
  11. #pragma once
  12. #include "dxc/DXIL/DxilConstants.h"
  13. namespace hlsl {
  14. namespace RDAT {
  15. // Data Layout:
  16. // -start:
  17. // RuntimeDataHeader header;
  18. // uint32_t offsets[header.PartCount];
  19. // - for each i in header.PartCount:
  20. // - at &header + offsets[i]:
  21. // RuntimeDataPartHeader part;
  22. // - if part.Type is a Table (Function or Resource):
  23. // RuntimeDataTableHeader table;
  24. // byte TableData[table.RecordCount][table.RecordStride];
  25. // - else if part.Type is String:
  26. // byte UTF8Data[part.Size];
  27. // - else if part.Type is Index:
  28. // uint32_t IndexData[part.Size / 4];
  29. enum class RuntimeDataPartType : uint32_t {
  30. Invalid = 0,
  31. StringBuffer = 1,
  32. IndexArrays = 2,
  33. ResourceTable = 3,
  34. FunctionTable = 4,
  35. RawBytes = 5,
  36. SubobjectTable = 6,
  37. };
  38. enum RuntimeDataVersion {
  39. // Cannot be mistaken for part count from prerelease version
  40. RDAT_Version_10 = 0x10,
  41. };
  42. struct RuntimeDataHeader {
  43. uint32_t Version;
  44. uint32_t PartCount;
  45. // Followed by uint32_t array of offsets to parts
  46. // offsets are relative to the beginning of this header
  47. // offsets must be 4-byte aligned
  48. // uint32_t offsets[];
  49. };
  50. struct RuntimeDataPartHeader {
  51. RuntimeDataPartType Type;
  52. uint32_t Size; // Not including this header. Must be 4-byte aligned.
  53. // Followed by part data
  54. // byte Data[ALIGN4(Size)];
  55. };
  56. // For tables of records, such as Function and Resource tables
  57. // Stride allows for extending records, with forward and backward compatibility
  58. struct RuntimeDataTableHeader {
  59. uint32_t RecordCount;
  60. uint32_t RecordStride; // Must be 4-byte aligned.
  61. // Followed by recordCount records of recordStride size
  62. // byte TableData[RecordCount * RecordStride];
  63. };
  64. // General purpose strided table reader with casting Row() operation that
  65. // returns nullptr if stride is smaller than type, for record expansion.
  66. class TableReader {
  67. const char *m_table;
  68. uint32_t m_count;
  69. uint32_t m_stride;
  70. public:
  71. TableReader() : TableReader(nullptr, 0, 0) {}
  72. TableReader(const char *table, uint32_t count, uint32_t stride)
  73. : m_table(table), m_count(count), m_stride(stride) {}
  74. void Init(const char *table, uint32_t count, uint32_t stride) {
  75. m_table = table; m_count = count; m_stride = stride;
  76. }
  77. const char *Data() const { return m_table; }
  78. uint32_t Count() const { return m_count; }
  79. uint32_t Stride() const { return m_stride; }
  80. template<typename T>
  81. const T *Row(uint32_t index) const {
  82. if (index < m_count && sizeof(T) <= m_stride)
  83. return reinterpret_cast<const T*>(m_table + (m_stride * index));
  84. return nullptr;
  85. }
  86. };
  87. // Index table is a sequence of rows, where each row has a count as a first
  88. // element followed by the count number of elements pre computing values
  89. class IndexTableReader {
  90. private:
  91. const uint32_t *m_table;
  92. uint32_t m_size;
  93. public:
  94. class IndexRow {
  95. private:
  96. const uint32_t *m_values;
  97. const uint32_t m_count;
  98. public:
  99. IndexRow(const uint32_t *values, uint32_t count)
  100. : m_values(values), m_count(count) {}
  101. uint32_t Count() { return m_count; }
  102. uint32_t At(uint32_t i) { return m_values[i]; }
  103. };
  104. IndexTableReader() : m_table(nullptr), m_size(0) {}
  105. IndexTableReader(const uint32_t *table, uint32_t size)
  106. : m_table(table), m_size(size) {}
  107. void SetTable(const uint32_t *table) { m_table = table; }
  108. void SetSize(uint32_t size) { m_size = size; }
  109. IndexRow getRow(uint32_t i) { return IndexRow(&m_table[i] + 1, m_table[i]); }
  110. };
  111. class StringTableReader {
  112. const char *m_table;
  113. uint32_t m_size;
  114. public:
  115. StringTableReader() : m_table(nullptr), m_size(0) {}
  116. StringTableReader(const char *table, uint32_t size)
  117. : m_table(table), m_size(size) {}
  118. const char *Get(uint32_t offset) const {
  119. _Analysis_assume_(offset < m_size && m_table &&
  120. m_table[m_size - 1] == '\0');
  121. (void)m_size; // avoid unused private warning if use above is ignored.
  122. return m_table + offset;
  123. }
  124. };
  125. enum class DxilResourceFlag : uint32_t {
  126. None = 0,
  127. UAVGloballyCoherent = 1 << 0,
  128. UAVCounter = 1 << 1,
  129. UAVRasterizerOrderedView = 1 << 2,
  130. DynamicIndexing = 1 << 3,
  131. Atomics64Use = 1 << 4,
  132. };
  133. struct RuntimeDataResourceInfo {
  134. uint32_t Class; // hlsl::DXIL::ResourceClass
  135. uint32_t Kind; // hlsl::DXIL::ResourceKind
  136. uint32_t ID; // id per class
  137. uint32_t Space;
  138. uint32_t LowerBound;
  139. uint32_t UpperBound;
  140. uint32_t Name; // resource name as an offset for string table
  141. uint32_t Flags; // hlsl::RDAT::DxilResourceFlag
  142. };
  143. struct RuntimeDataFunctionInfo {
  144. uint32_t Name; // offset for string table
  145. uint32_t UnmangledName; // offset for string table
  146. uint32_t Resources; // index to an index table
  147. uint32_t FunctionDependencies; // index to a list of functions that function
  148. // depends on
  149. uint32_t ShaderKind;
  150. uint32_t PayloadSizeInBytes; // 1) any/closest hit or miss shader: payload size
  151. // 2) call shader: parameter size
  152. uint32_t AttributeSizeInBytes; // attribute size for closest hit and any hit
  153. uint32_t FeatureInfo1; // first 32 bits of feature flag
  154. uint32_t FeatureInfo2; // second 32 bits of feature flag
  155. uint32_t ShaderStageFlag; // valid shader stage flag.
  156. uint32_t MinShaderTarget; // minimum shader target.
  157. };
  158. class RawBytesReader {
  159. const void *m_table;
  160. uint32_t m_size;
  161. public:
  162. RawBytesReader() : m_table(nullptr), m_size(0) {}
  163. RawBytesReader(const void *table, uint32_t size)
  164. : m_table(table), m_size(size) {}
  165. const void *Get(uint32_t offset) const {
  166. _Analysis_assume_(offset < m_size && m_table);
  167. (void)m_size; // avoid unused private warning if use above is ignored.
  168. return (const void*)(((const char*)m_table) + offset);
  169. }
  170. };
  171. struct RuntimeDataSubobjectInfo {
  172. uint32_t Kind;
  173. uint32_t Name;
  174. struct StateObjectConfig_t {
  175. uint32_t Flags;
  176. };
  177. struct RootSignature_t {
  178. uint32_t RawBytesOffset;
  179. uint32_t SizeInBytes;
  180. };
  181. struct SubobjectToExportsAssociation_t {
  182. uint32_t Subobject; // string table offset for name of subobject
  183. uint32_t Exports; // index table offset for array of string table offsets for export names
  184. };
  185. struct RaytracingShaderConfig_t {
  186. uint32_t MaxPayloadSizeInBytes;
  187. uint32_t MaxAttributeSizeInBytes;
  188. };
  189. struct RaytracingPipelineConfig_t {
  190. uint32_t MaxTraceRecursionDepth;
  191. };
  192. struct HitGroup_t {
  193. uint32_t Type;
  194. // each is a string table offset for the shader name
  195. // 0 points to empty name, indicating no shader.
  196. uint32_t AnyHit;
  197. uint32_t ClosestHit;
  198. uint32_t Intersection;
  199. };
  200. struct RaytracingPipelineConfig1_t {
  201. uint32_t MaxTraceRecursionDepth;
  202. uint32_t Flags;
  203. };
  204. union {
  205. StateObjectConfig_t StateObjectConfig;
  206. RootSignature_t RootSignature;
  207. SubobjectToExportsAssociation_t SubobjectToExportsAssociation;
  208. RaytracingShaderConfig_t RaytracingShaderConfig;
  209. RaytracingPipelineConfig_t RaytracingPipelineConfig;
  210. HitGroup_t HitGroup;
  211. RaytracingPipelineConfig1_t RaytracingPipelineConfig1;
  212. };
  213. };
  214. class ResourceTableReader;
  215. class FunctionTableReader;
  216. class SubobjectTableReader;
  217. struct RuntimeDataContext {
  218. StringTableReader *pStringTableReader;
  219. IndexTableReader *pIndexTableReader;
  220. RawBytesReader *pRawBytesReader;
  221. ResourceTableReader *pResourceTableReader;
  222. FunctionTableReader *pFunctionTableReader;
  223. SubobjectTableReader *pSubobjectTableReader;
  224. };
  225. class ResourceReader {
  226. private:
  227. const RuntimeDataResourceInfo *m_ResourceInfo;
  228. RuntimeDataContext *m_Context;
  229. public:
  230. ResourceReader(const RuntimeDataResourceInfo *resInfo,
  231. RuntimeDataContext *context)
  232. : m_ResourceInfo(resInfo), m_Context(context) {}
  233. hlsl::DXIL::ResourceClass GetResourceClass() const {
  234. return !m_ResourceInfo ? hlsl::DXIL::ResourceClass::Invalid
  235. : (hlsl::DXIL::ResourceClass)m_ResourceInfo->Class;
  236. }
  237. uint32_t GetSpace() const { return !m_ResourceInfo ? 0 : m_ResourceInfo->Space; }
  238. uint32_t GetLowerBound() const { return !m_ResourceInfo ? 0 : m_ResourceInfo->LowerBound; }
  239. uint32_t GetUpperBound() const { return !m_ResourceInfo ? 0 : m_ResourceInfo->UpperBound; }
  240. hlsl::DXIL::ResourceKind GetResourceKind() const {
  241. return !m_ResourceInfo ? hlsl::DXIL::ResourceKind::Invalid
  242. : (hlsl::DXIL::ResourceKind)m_ResourceInfo->Kind;
  243. }
  244. uint32_t GetID() const { return !m_ResourceInfo ? 0 : m_ResourceInfo->ID; }
  245. const char *GetName() const {
  246. return !m_ResourceInfo ? ""
  247. : m_Context->pStringTableReader->Get(m_ResourceInfo->Name);
  248. }
  249. uint32_t GetFlags() const { return !m_ResourceInfo ? 0 : m_ResourceInfo->Flags; }
  250. };
  251. class ResourceTableReader {
  252. private:
  253. TableReader m_Table;
  254. RuntimeDataContext *m_Context;
  255. uint32_t m_CBufferCount;
  256. uint32_t m_SamplerCount;
  257. uint32_t m_SRVCount;
  258. uint32_t m_UAVCount;
  259. public:
  260. ResourceTableReader()
  261. : m_Context(nullptr), m_CBufferCount(0),
  262. m_SamplerCount(0), m_SRVCount(0), m_UAVCount(0){};
  263. void SetResourceInfo(const char *ptr, uint32_t count, uint32_t recordStride) {
  264. m_Table.Init(ptr, count, recordStride);
  265. // Assuming that resources are in order of CBuffer, Sampler, SRV, and UAV,
  266. // count the number for each resource class
  267. m_CBufferCount = 0;
  268. m_SamplerCount = 0;
  269. m_SRVCount = 0;
  270. m_UAVCount = 0;
  271. for (uint32_t i = 0; i < count; ++i) {
  272. const RuntimeDataResourceInfo *curPtr =
  273. m_Table.Row<RuntimeDataResourceInfo>(i);
  274. if (curPtr->Class == (uint32_t)hlsl::DXIL::ResourceClass::CBuffer)
  275. m_CBufferCount++;
  276. else if (curPtr->Class == (uint32_t)hlsl::DXIL::ResourceClass::Sampler)
  277. m_SamplerCount++;
  278. else if (curPtr->Class == (uint32_t)hlsl::DXIL::ResourceClass::SRV)
  279. m_SRVCount++;
  280. else if (curPtr->Class == (uint32_t)hlsl::DXIL::ResourceClass::UAV)
  281. m_UAVCount++;
  282. }
  283. }
  284. void SetContext(RuntimeDataContext *context) { m_Context = context; }
  285. uint32_t GetNumResources() const {
  286. return m_CBufferCount + m_SamplerCount + m_SRVCount + m_UAVCount;
  287. }
  288. ResourceReader GetItem(uint32_t i) const {
  289. _Analysis_assume_(i < GetNumResources());
  290. return ResourceReader(m_Table.Row<RuntimeDataResourceInfo>(i), m_Context);
  291. }
  292. uint32_t GetNumCBuffers() const { return m_CBufferCount; }
  293. ResourceReader GetCBuffer(uint32_t i) {
  294. _Analysis_assume_(i < m_CBufferCount);
  295. return ResourceReader(m_Table.Row<RuntimeDataResourceInfo>(i), m_Context);
  296. }
  297. uint32_t GetNumSamplers() const { return m_SamplerCount; }
  298. ResourceReader GetSampler(uint32_t i) {
  299. _Analysis_assume_(i < m_SamplerCount);
  300. uint32_t offset = (m_CBufferCount + i);
  301. return ResourceReader(m_Table.Row<RuntimeDataResourceInfo>(offset), m_Context);
  302. }
  303. uint32_t GetNumSRVs() const { return m_SRVCount; }
  304. ResourceReader GetSRV(uint32_t i) {
  305. _Analysis_assume_(i < m_SRVCount);
  306. uint32_t offset = (m_CBufferCount + m_SamplerCount + i);
  307. return ResourceReader(m_Table.Row<RuntimeDataResourceInfo>(offset), m_Context);
  308. }
  309. uint32_t GetNumUAVs() const { return m_UAVCount; }
  310. ResourceReader GetUAV(uint32_t i) {
  311. _Analysis_assume_(i < m_UAVCount);
  312. uint32_t offset = (m_CBufferCount + m_SamplerCount + m_SRVCount + i);
  313. return ResourceReader(m_Table.Row<RuntimeDataResourceInfo>(offset), m_Context);
  314. }
  315. };
  316. class FunctionReader {
  317. private:
  318. const RuntimeDataFunctionInfo *m_RuntimeDataFunctionInfo;
  319. RuntimeDataContext *m_Context;
  320. public:
  321. FunctionReader() : m_RuntimeDataFunctionInfo(nullptr), m_Context(nullptr) {}
  322. FunctionReader(const RuntimeDataFunctionInfo *functionInfo,
  323. RuntimeDataContext *context)
  324. : m_RuntimeDataFunctionInfo(functionInfo), m_Context(context) {}
  325. const char *GetName() const {
  326. return !m_RuntimeDataFunctionInfo ? ""
  327. : m_Context->pStringTableReader->Get(m_RuntimeDataFunctionInfo->Name);
  328. }
  329. const char *GetUnmangledName() const {
  330. return !m_RuntimeDataFunctionInfo ? ""
  331. : m_Context->pStringTableReader->Get(
  332. m_RuntimeDataFunctionInfo->UnmangledName);
  333. }
  334. uint64_t GetFeatureFlag() const {
  335. return (static_cast<uint64_t>(GetFeatureInfo2()) << 32)
  336. | static_cast<uint64_t>(GetFeatureInfo1());
  337. }
  338. uint32_t GetFeatureInfo1() const {
  339. return !m_RuntimeDataFunctionInfo ? 0
  340. : m_RuntimeDataFunctionInfo->FeatureInfo1;
  341. }
  342. uint32_t GetFeatureInfo2() const {
  343. return !m_RuntimeDataFunctionInfo ? 0
  344. : m_RuntimeDataFunctionInfo->FeatureInfo2;
  345. }
  346. uint32_t GetShaderStageFlag() const {
  347. return !m_RuntimeDataFunctionInfo ? 0
  348. : m_RuntimeDataFunctionInfo->ShaderStageFlag;
  349. }
  350. uint32_t GetMinShaderTarget() const {
  351. return !m_RuntimeDataFunctionInfo ? 0
  352. : m_RuntimeDataFunctionInfo->MinShaderTarget;
  353. }
  354. uint32_t GetNumResources() const {
  355. if (!m_RuntimeDataFunctionInfo ||
  356. m_RuntimeDataFunctionInfo->Resources == UINT_MAX)
  357. return 0;
  358. return m_Context->pIndexTableReader->getRow(
  359. m_RuntimeDataFunctionInfo->Resources).Count();
  360. }
  361. ResourceReader GetResource(uint32_t i) const {
  362. if (!m_RuntimeDataFunctionInfo)
  363. return ResourceReader(nullptr, m_Context);
  364. uint32_t resIndex = m_Context->pIndexTableReader->getRow(
  365. m_RuntimeDataFunctionInfo->Resources).At(i);
  366. return m_Context->pResourceTableReader->GetItem(resIndex);
  367. }
  368. uint32_t GetNumDependencies() const {
  369. if (!m_RuntimeDataFunctionInfo ||
  370. m_RuntimeDataFunctionInfo->FunctionDependencies == UINT_MAX)
  371. return 0;
  372. return m_Context->pIndexTableReader->getRow(
  373. m_RuntimeDataFunctionInfo->FunctionDependencies).Count();
  374. }
  375. const char *GetDependency(uint32_t i) const {
  376. if (!m_RuntimeDataFunctionInfo)
  377. return "";
  378. uint32_t resIndex = m_Context->pIndexTableReader->getRow(
  379. m_RuntimeDataFunctionInfo->FunctionDependencies).At(i);
  380. return m_Context->pStringTableReader->Get(resIndex);
  381. }
  382. uint32_t GetPayloadSizeInBytes() const {
  383. return !m_RuntimeDataFunctionInfo ? 0
  384. : m_RuntimeDataFunctionInfo->PayloadSizeInBytes;
  385. }
  386. uint32_t GetAttributeSizeInBytes() const {
  387. return !m_RuntimeDataFunctionInfo ? 0
  388. : m_RuntimeDataFunctionInfo->AttributeSizeInBytes;
  389. }
  390. // payload (hit shaders) and parameters (call shaders) are mutually exclusive
  391. uint32_t GetParameterSizeInBytes() const {
  392. return !m_RuntimeDataFunctionInfo ? 0
  393. : m_RuntimeDataFunctionInfo->PayloadSizeInBytes;
  394. }
  395. hlsl::DXIL::ShaderKind GetShaderKind() const {
  396. return !m_RuntimeDataFunctionInfo ? hlsl::DXIL::ShaderKind::Invalid
  397. : (hlsl::DXIL::ShaderKind)m_RuntimeDataFunctionInfo->ShaderKind;
  398. }
  399. };
  400. class FunctionTableReader {
  401. private:
  402. TableReader m_Table;
  403. RuntimeDataContext *m_Context;
  404. public:
  405. FunctionTableReader() : m_Context(nullptr) {}
  406. FunctionReader GetItem(uint32_t i) const {
  407. return FunctionReader(m_Table.Row<RuntimeDataFunctionInfo>(i), m_Context);
  408. }
  409. uint32_t GetNumFunctions() const { return m_Table.Count(); }
  410. void SetFunctionInfo(const char *ptr, uint32_t count, uint32_t recordStride) {
  411. m_Table.Init(ptr, count, recordStride);
  412. }
  413. void SetContext(RuntimeDataContext *context) { m_Context = context; }
  414. };
  415. class SubobjectReader {
  416. private:
  417. const RuntimeDataSubobjectInfo *m_SubobjectInfo;
  418. RuntimeDataContext *m_Context;
  419. public:
  420. SubobjectReader(const RuntimeDataSubobjectInfo *info, RuntimeDataContext *context)
  421. : m_SubobjectInfo(info), m_Context(context) {}
  422. DXIL::SubobjectKind GetKind() const {
  423. return m_SubobjectInfo ? (DXIL::SubobjectKind)(m_SubobjectInfo->Kind) :
  424. (DXIL::SubobjectKind)(-1);
  425. }
  426. const char *GetName() const {
  427. return m_SubobjectInfo && m_SubobjectInfo->Name ?
  428. m_Context->pStringTableReader->Get(m_SubobjectInfo->Name) : "";
  429. }
  430. // StateObjectConfig
  431. uint32_t GetStateObjectConfig_Flags() const {
  432. return (GetKind() == DXIL::SubobjectKind::StateObjectConfig) ?
  433. m_SubobjectInfo->StateObjectConfig.Flags : (uint32_t)0;
  434. }
  435. // [Global|Local]RootSignature
  436. // returns true if valid non-zero-length buffer found and set to output params
  437. bool GetRootSignature(const void **ppOutBytes, uint32_t *pOutSizeInBytes) const {
  438. if (!ppOutBytes || !pOutSizeInBytes)
  439. return false;
  440. if (m_SubobjectInfo &&
  441. ( GetKind() == DXIL::SubobjectKind::GlobalRootSignature ||
  442. GetKind() == DXIL::SubobjectKind::LocalRootSignature ) &&
  443. m_SubobjectInfo->RootSignature.SizeInBytes > 0) {
  444. *ppOutBytes = m_Context->pRawBytesReader->Get(m_SubobjectInfo->RootSignature.RawBytesOffset);
  445. *pOutSizeInBytes = m_SubobjectInfo->RootSignature.SizeInBytes;
  446. return true;
  447. } else {
  448. *ppOutBytes = nullptr;
  449. *pOutSizeInBytes = 0;
  450. }
  451. return false;
  452. }
  453. // SubobjectToExportsAssociation
  454. const char *GetSubobjectToExportsAssociation_Subobject() const {
  455. return (GetKind() == DXIL::SubobjectKind::SubobjectToExportsAssociation) ?
  456. m_Context->pStringTableReader->Get(m_SubobjectInfo->SubobjectToExportsAssociation.Subobject) : "";
  457. }
  458. uint32_t GetSubobjectToExportsAssociation_NumExports() const {
  459. return (GetKind() == DXIL::SubobjectKind::SubobjectToExportsAssociation) ?
  460. m_Context->pIndexTableReader->getRow(m_SubobjectInfo->SubobjectToExportsAssociation.Exports).Count() : 0;
  461. }
  462. const char *GetSubobjectToExportsAssociation_Export(uint32_t index) const {
  463. if (!(GetKind() == DXIL::SubobjectKind::SubobjectToExportsAssociation))
  464. return "";
  465. auto row = m_Context->pIndexTableReader->getRow(
  466. m_SubobjectInfo->SubobjectToExportsAssociation.Exports);
  467. if (index >= row.Count())
  468. return "";
  469. return m_Context->pStringTableReader->Get(row.At(index));
  470. }
  471. // RaytracingShaderConfig
  472. uint32_t GetRaytracingShaderConfig_MaxPayloadSizeInBytes() const {
  473. return (GetKind() == DXIL::SubobjectKind::RaytracingShaderConfig) ?
  474. m_SubobjectInfo->RaytracingShaderConfig.MaxPayloadSizeInBytes : 0;
  475. }
  476. uint32_t GetRaytracingShaderConfig_MaxAttributeSizeInBytes() const {
  477. return (GetKind() == DXIL::SubobjectKind::RaytracingShaderConfig) ?
  478. m_SubobjectInfo->RaytracingShaderConfig.MaxAttributeSizeInBytes : 0;
  479. }
  480. // RaytracingPipelineConfig
  481. uint32_t GetRaytracingPipelineConfig_MaxTraceRecursionDepth() const {
  482. return (GetKind() == DXIL::SubobjectKind::RaytracingPipelineConfig) ?
  483. m_SubobjectInfo->RaytracingPipelineConfig.MaxTraceRecursionDepth : 0;
  484. }
  485. // RaytracingPipelineConfig1
  486. uint32_t GetRaytracingPipelineConfig1_MaxTraceRecursionDepth() const {
  487. return (GetKind() == DXIL::SubobjectKind::RaytracingPipelineConfig1) ?
  488. m_SubobjectInfo->RaytracingPipelineConfig1.MaxTraceRecursionDepth : 0;
  489. }
  490. uint32_t GetRaytracingPipelineConfig1_Flags() const {
  491. return (GetKind() == DXIL::SubobjectKind::RaytracingPipelineConfig1) ?
  492. m_SubobjectInfo->RaytracingPipelineConfig1.Flags : (uint32_t)0;
  493. }
  494. // HitGroup
  495. DXIL::HitGroupType GetHitGroup_Type() const {
  496. return (GetKind() == DXIL::SubobjectKind::HitGroup) ?
  497. (DXIL::HitGroupType)m_SubobjectInfo->HitGroup.Type : (DXIL::HitGroupType)(-1);
  498. }
  499. const char *GetHitGroup_Intersection() const {
  500. return (GetKind() == DXIL::SubobjectKind::HitGroup) ?
  501. m_Context->pStringTableReader->Get(m_SubobjectInfo->HitGroup.Intersection) : "";
  502. }
  503. const char *GetHitGroup_AnyHit() const {
  504. return (GetKind() == DXIL::SubobjectKind::HitGroup) ?
  505. m_Context->pStringTableReader->Get(m_SubobjectInfo->HitGroup.AnyHit) : "";
  506. }
  507. const char *GetHitGroup_ClosestHit() const {
  508. return (GetKind() == DXIL::SubobjectKind::HitGroup) ?
  509. m_Context->pStringTableReader->Get(m_SubobjectInfo->HitGroup.ClosestHit) : "";
  510. }
  511. };
  512. class SubobjectTableReader {
  513. private:
  514. TableReader m_Table;
  515. RuntimeDataContext *m_Context;
  516. public:
  517. SubobjectTableReader() : m_Context(nullptr) {}
  518. void SetContext(RuntimeDataContext *context) { m_Context = context; }
  519. void SetSubobjectInfo(const char *ptr, uint32_t count, uint32_t recordStride) {
  520. m_Table.Init(ptr, count, recordStride);
  521. }
  522. uint32_t GetCount() const { return m_Table.Count(); }
  523. SubobjectReader GetItem(uint32_t i) const {
  524. return SubobjectReader(m_Table.Row<RuntimeDataSubobjectInfo>(i), m_Context);
  525. }
  526. };
  527. class DxilRuntimeData {
  528. private:
  529. StringTableReader m_StringReader;
  530. IndexTableReader m_IndexTableReader;
  531. RawBytesReader m_RawBytesReader;
  532. ResourceTableReader m_ResourceTableReader;
  533. FunctionTableReader m_FunctionTableReader;
  534. SubobjectTableReader m_SubobjectTableReader;
  535. RuntimeDataContext m_Context;
  536. public:
  537. DxilRuntimeData();
  538. DxilRuntimeData(const void *ptr, size_t size);
  539. // initializing reader from RDAT. return true if no error has occured.
  540. bool InitFromRDAT(const void *pRDAT, size_t size);
  541. FunctionTableReader *GetFunctionTableReader();
  542. ResourceTableReader *GetResourceTableReader();
  543. SubobjectTableReader *GetSubobjectTableReader();
  544. };
  545. //////////////////////////////////
  546. /// structures for library runtime
  547. struct DxilResourceDesc {
  548. uint32_t Class; // hlsl::DXIL::ResourceClass
  549. uint32_t Kind; // hlsl::DXIL::ResourceKind
  550. uint32_t ID; // id per class
  551. uint32_t Space;
  552. uint32_t UpperBound;
  553. uint32_t LowerBound;
  554. LPCWSTR Name;
  555. uint32_t Flags; // hlsl::RDAT::DxilResourceFlag
  556. };
  557. struct DxilFunctionDesc {
  558. LPCWSTR Name;
  559. LPCWSTR UnmangledName;
  560. uint32_t NumResources;
  561. const DxilResourceDesc * const*Resources;
  562. uint32_t NumFunctionDependencies;
  563. const LPCWSTR *FunctionDependencies;
  564. uint32_t ShaderKind;
  565. uint32_t PayloadSizeInBytes; // 1) hit, miss, or closest shader: payload count
  566. // 2) call shader: parameter size
  567. uint32_t AttributeSizeInBytes; // attribute size for closest hit and any hit
  568. uint32_t FeatureInfo1; // first 32 bits of feature flag
  569. uint32_t FeatureInfo2; // second 32 bits of feature flag
  570. uint32_t ShaderStageFlag; // valid shader stage flag.
  571. uint32_t MinShaderTarget; // minimum shader target.
  572. };
  573. struct DxilSubobjectDesc {
  574. LPCWSTR Name;
  575. uint32_t Kind; // DXIL::SubobjectKind / D3D12_STATE_SUBOBJECT_TYPE
  576. struct StateObjectConfig_t {
  577. uint32_t Flags; // DXIL::StateObjectFlags / D3D12_STATE_OBJECT_FLAGS
  578. };
  579. struct RootSignature_t {
  580. LPCVOID pSerializedSignature;
  581. uint32_t SizeInBytes;
  582. }; // GlobalRootSignature or LocalRootSignature
  583. struct SubobjectToExportsAssociation_t {
  584. LPCWSTR Subobject;
  585. uint32_t NumExports;
  586. const LPCWSTR* Exports;
  587. };
  588. struct RaytracingShaderConfig_t {
  589. uint32_t MaxPayloadSizeInBytes;
  590. uint32_t MaxAttributeSizeInBytes;
  591. };
  592. struct RaytracingPipelineConfig_t {
  593. uint32_t MaxTraceRecursionDepth;
  594. };
  595. struct HitGroup_t {
  596. uint32_t Type; // DXIL::HitGroupType / D3D12_HIT_GROUP_TYPE
  597. LPCWSTR AnyHit;
  598. LPCWSTR ClosestHit;
  599. LPCWSTR Intersection;
  600. };
  601. struct RaytracingPipelineConfig1_t {
  602. uint32_t MaxTraceRecursionDepth;
  603. uint32_t Flags; // DXIL::RaytracingPipelineFlags / D3D12_RAYTRACING_PIPELINE_FLAGS
  604. };
  605. union {
  606. StateObjectConfig_t StateObjectConfig;
  607. RootSignature_t RootSignature; // GlobalRootSignature or LocalRootSignature
  608. SubobjectToExportsAssociation_t SubobjectToExportsAssociation;
  609. RaytracingShaderConfig_t RaytracingShaderConfig;
  610. RaytracingPipelineConfig_t RaytracingPipelineConfig;
  611. HitGroup_t HitGroup;
  612. RaytracingPipelineConfig1_t RaytracingPipelineConfig1;
  613. };
  614. };
  615. struct DxilLibraryDesc {
  616. uint32_t NumFunctions;
  617. DxilFunctionDesc *pFunction;
  618. uint32_t NumResources;
  619. DxilResourceDesc *pResource;
  620. uint32_t NumSubobjects;
  621. DxilSubobjectDesc *pSubobjects;
  622. };
  623. class DxilRuntimeReflection {
  624. public:
  625. virtual ~DxilRuntimeReflection() {}
  626. // This call will allocate memory for GetLibraryReflection call
  627. virtual bool InitFromRDAT(const void *pRDAT, size_t size) = 0;
  628. // DxilRuntimeReflection owns the memory pointed to by DxilLibraryDesc
  629. virtual const DxilLibraryDesc GetLibraryReflection() = 0;
  630. };
  631. DxilRuntimeReflection *CreateDxilRuntimeReflection();
  632. } // namespace RDAT
  633. } // namespace hlsl