DxilRuntimeReflection.h 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709
  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. };
  132. struct RuntimeDataResourceInfo {
  133. uint32_t Class; // hlsl::DXIL::ResourceClass
  134. uint32_t Kind; // hlsl::DXIL::ResourceKind
  135. uint32_t ID; // id per class
  136. uint32_t Space;
  137. uint32_t LowerBound;
  138. uint32_t UpperBound;
  139. uint32_t Name; // resource name as an offset for string table
  140. uint32_t Flags; // hlsl::RDAT::DxilResourceFlag
  141. };
  142. struct RuntimeDataFunctionInfo {
  143. uint32_t Name; // offset for string table
  144. uint32_t UnmangledName; // offset for string table
  145. uint32_t Resources; // index to an index table
  146. uint32_t FunctionDependencies; // index to a list of functions that function
  147. // depends on
  148. uint32_t ShaderKind;
  149. uint32_t PayloadSizeInBytes; // 1) any/closest hit or miss shader: payload size
  150. // 2) call shader: parameter size
  151. uint32_t AttributeSizeInBytes; // attribute size for closest hit and any hit
  152. uint32_t FeatureInfo1; // first 32 bits of feature flag
  153. uint32_t FeatureInfo2; // second 32 bits of feature flag
  154. uint32_t ShaderStageFlag; // valid shader stage flag.
  155. uint32_t MinShaderTarget; // minimum shader target.
  156. };
  157. class RawBytesReader {
  158. const void *m_table;
  159. uint32_t m_size;
  160. public:
  161. RawBytesReader() : m_table(nullptr), m_size(0) {}
  162. RawBytesReader(const void *table, uint32_t size)
  163. : m_table(table), m_size(size) {}
  164. const void *Get(uint32_t offset) const {
  165. _Analysis_assume_(offset < m_size && m_table);
  166. (void)m_size; // avoid unused private warning if use above is ignored.
  167. return (const void*)(((const char*)m_table) + offset);
  168. }
  169. };
  170. struct RuntimeDataSubobjectInfo {
  171. uint32_t Kind;
  172. uint32_t Name;
  173. struct StateObjectConfig_t {
  174. uint32_t Flags;
  175. };
  176. struct RootSignature_t {
  177. uint32_t RawBytesOffset;
  178. uint32_t SizeInBytes;
  179. };
  180. struct SubobjectToExportsAssociation_t {
  181. uint32_t Subobject; // string table offset for name of subobject
  182. uint32_t Exports; // index table offset for array of string table offsets for export names
  183. };
  184. struct RaytracingShaderConfig_t {
  185. uint32_t MaxPayloadSizeInBytes;
  186. uint32_t MaxAttributeSizeInBytes;
  187. };
  188. struct RaytracingPipelineConfig_t {
  189. uint32_t MaxTraceRecursionDepth;
  190. };
  191. struct HitGroup_t {
  192. uint32_t Type;
  193. // each is a string table offset for the shader name
  194. // 0 points to empty name, indicating no shader.
  195. uint32_t AnyHit;
  196. uint32_t ClosestHit;
  197. uint32_t Intersection;
  198. };
  199. struct RaytracingPipelineConfig1_t {
  200. uint32_t MaxTraceRecursionDepth;
  201. uint32_t Flags;
  202. };
  203. union {
  204. StateObjectConfig_t StateObjectConfig;
  205. RootSignature_t RootSignature;
  206. SubobjectToExportsAssociation_t SubobjectToExportsAssociation;
  207. RaytracingShaderConfig_t RaytracingShaderConfig;
  208. RaytracingPipelineConfig_t RaytracingPipelineConfig;
  209. HitGroup_t HitGroup;
  210. RaytracingPipelineConfig1_t RaytracingPipelineConfig1;
  211. };
  212. };
  213. class ResourceTableReader;
  214. class FunctionTableReader;
  215. class SubobjectTableReader;
  216. struct RuntimeDataContext {
  217. StringTableReader *pStringTableReader;
  218. IndexTableReader *pIndexTableReader;
  219. RawBytesReader *pRawBytesReader;
  220. ResourceTableReader *pResourceTableReader;
  221. FunctionTableReader *pFunctionTableReader;
  222. SubobjectTableReader *pSubobjectTableReader;
  223. };
  224. class ResourceReader {
  225. private:
  226. const RuntimeDataResourceInfo *m_ResourceInfo;
  227. RuntimeDataContext *m_Context;
  228. public:
  229. ResourceReader(const RuntimeDataResourceInfo *resInfo,
  230. RuntimeDataContext *context)
  231. : m_ResourceInfo(resInfo), m_Context(context) {}
  232. hlsl::DXIL::ResourceClass GetResourceClass() const {
  233. return !m_ResourceInfo ? hlsl::DXIL::ResourceClass::Invalid
  234. : (hlsl::DXIL::ResourceClass)m_ResourceInfo->Class;
  235. }
  236. uint32_t GetSpace() const { return !m_ResourceInfo ? 0 : m_ResourceInfo->Space; }
  237. uint32_t GetLowerBound() const { return !m_ResourceInfo ? 0 : m_ResourceInfo->LowerBound; }
  238. uint32_t GetUpperBound() const { return !m_ResourceInfo ? 0 : m_ResourceInfo->UpperBound; }
  239. hlsl::DXIL::ResourceKind GetResourceKind() const {
  240. return !m_ResourceInfo ? hlsl::DXIL::ResourceKind::Invalid
  241. : (hlsl::DXIL::ResourceKind)m_ResourceInfo->Kind;
  242. }
  243. uint32_t GetID() const { return !m_ResourceInfo ? 0 : m_ResourceInfo->ID; }
  244. const char *GetName() const {
  245. return !m_ResourceInfo ? ""
  246. : m_Context->pStringTableReader->Get(m_ResourceInfo->Name);
  247. }
  248. uint32_t GetFlags() const { return !m_ResourceInfo ? 0 : m_ResourceInfo->Flags; }
  249. };
  250. class ResourceTableReader {
  251. private:
  252. TableReader m_Table;
  253. RuntimeDataContext *m_Context;
  254. uint32_t m_CBufferCount;
  255. uint32_t m_SamplerCount;
  256. uint32_t m_SRVCount;
  257. uint32_t m_UAVCount;
  258. public:
  259. ResourceTableReader()
  260. : m_Context(nullptr), m_CBufferCount(0),
  261. m_SamplerCount(0), m_SRVCount(0), m_UAVCount(0){};
  262. void SetResourceInfo(const char *ptr, uint32_t count, uint32_t recordStride) {
  263. m_Table.Init(ptr, count, recordStride);
  264. // Assuming that resources are in order of CBuffer, Sampler, SRV, and UAV,
  265. // count the number for each resource class
  266. m_CBufferCount = 0;
  267. m_SamplerCount = 0;
  268. m_SRVCount = 0;
  269. m_UAVCount = 0;
  270. for (uint32_t i = 0; i < count; ++i) {
  271. const RuntimeDataResourceInfo *curPtr =
  272. m_Table.Row<RuntimeDataResourceInfo>(i);
  273. if (curPtr->Class == (uint32_t)hlsl::DXIL::ResourceClass::CBuffer)
  274. m_CBufferCount++;
  275. else if (curPtr->Class == (uint32_t)hlsl::DXIL::ResourceClass::Sampler)
  276. m_SamplerCount++;
  277. else if (curPtr->Class == (uint32_t)hlsl::DXIL::ResourceClass::SRV)
  278. m_SRVCount++;
  279. else if (curPtr->Class == (uint32_t)hlsl::DXIL::ResourceClass::UAV)
  280. m_UAVCount++;
  281. }
  282. }
  283. void SetContext(RuntimeDataContext *context) { m_Context = context; }
  284. uint32_t GetNumResources() const {
  285. return m_CBufferCount + m_SamplerCount + m_SRVCount + m_UAVCount;
  286. }
  287. ResourceReader GetItem(uint32_t i) const {
  288. _Analysis_assume_(i < GetNumResources());
  289. return ResourceReader(m_Table.Row<RuntimeDataResourceInfo>(i), m_Context);
  290. }
  291. uint32_t GetNumCBuffers() const { return m_CBufferCount; }
  292. ResourceReader GetCBuffer(uint32_t i) {
  293. _Analysis_assume_(i < m_CBufferCount);
  294. return ResourceReader(m_Table.Row<RuntimeDataResourceInfo>(i), m_Context);
  295. }
  296. uint32_t GetNumSamplers() const { return m_SamplerCount; }
  297. ResourceReader GetSampler(uint32_t i) {
  298. _Analysis_assume_(i < m_SamplerCount);
  299. uint32_t offset = (m_CBufferCount + i);
  300. return ResourceReader(m_Table.Row<RuntimeDataResourceInfo>(offset), m_Context);
  301. }
  302. uint32_t GetNumSRVs() const { return m_SRVCount; }
  303. ResourceReader GetSRV(uint32_t i) {
  304. _Analysis_assume_(i < m_SRVCount);
  305. uint32_t offset = (m_CBufferCount + m_SamplerCount + i);
  306. return ResourceReader(m_Table.Row<RuntimeDataResourceInfo>(offset), m_Context);
  307. }
  308. uint32_t GetNumUAVs() const { return m_UAVCount; }
  309. ResourceReader GetUAV(uint32_t i) {
  310. _Analysis_assume_(i < m_UAVCount);
  311. uint32_t offset = (m_CBufferCount + m_SamplerCount + m_SRVCount + i);
  312. return ResourceReader(m_Table.Row<RuntimeDataResourceInfo>(offset), m_Context);
  313. }
  314. };
  315. class FunctionReader {
  316. private:
  317. const RuntimeDataFunctionInfo *m_RuntimeDataFunctionInfo;
  318. RuntimeDataContext *m_Context;
  319. public:
  320. FunctionReader() : m_RuntimeDataFunctionInfo(nullptr), m_Context(nullptr) {}
  321. FunctionReader(const RuntimeDataFunctionInfo *functionInfo,
  322. RuntimeDataContext *context)
  323. : m_RuntimeDataFunctionInfo(functionInfo), m_Context(context) {}
  324. const char *GetName() const {
  325. return !m_RuntimeDataFunctionInfo ? ""
  326. : m_Context->pStringTableReader->Get(m_RuntimeDataFunctionInfo->Name);
  327. }
  328. const char *GetUnmangledName() const {
  329. return !m_RuntimeDataFunctionInfo ? ""
  330. : m_Context->pStringTableReader->Get(
  331. m_RuntimeDataFunctionInfo->UnmangledName);
  332. }
  333. uint64_t GetFeatureFlag() const {
  334. return (static_cast<uint64_t>(GetFeatureInfo2()) << 32)
  335. | static_cast<uint64_t>(GetFeatureInfo1());
  336. }
  337. uint32_t GetFeatureInfo1() const {
  338. return !m_RuntimeDataFunctionInfo ? 0
  339. : m_RuntimeDataFunctionInfo->FeatureInfo1;
  340. }
  341. uint32_t GetFeatureInfo2() const {
  342. return !m_RuntimeDataFunctionInfo ? 0
  343. : m_RuntimeDataFunctionInfo->FeatureInfo2;
  344. }
  345. uint32_t GetShaderStageFlag() const {
  346. return !m_RuntimeDataFunctionInfo ? 0
  347. : m_RuntimeDataFunctionInfo->ShaderStageFlag;
  348. }
  349. uint32_t GetMinShaderTarget() const {
  350. return !m_RuntimeDataFunctionInfo ? 0
  351. : m_RuntimeDataFunctionInfo->MinShaderTarget;
  352. }
  353. uint32_t GetNumResources() const {
  354. if (!m_RuntimeDataFunctionInfo ||
  355. m_RuntimeDataFunctionInfo->Resources == UINT_MAX)
  356. return 0;
  357. return m_Context->pIndexTableReader->getRow(
  358. m_RuntimeDataFunctionInfo->Resources).Count();
  359. }
  360. ResourceReader GetResource(uint32_t i) const {
  361. if (!m_RuntimeDataFunctionInfo)
  362. return ResourceReader(nullptr, m_Context);
  363. uint32_t resIndex = m_Context->pIndexTableReader->getRow(
  364. m_RuntimeDataFunctionInfo->Resources).At(i);
  365. return m_Context->pResourceTableReader->GetItem(resIndex);
  366. }
  367. uint32_t GetNumDependencies() const {
  368. if (!m_RuntimeDataFunctionInfo ||
  369. m_RuntimeDataFunctionInfo->FunctionDependencies == UINT_MAX)
  370. return 0;
  371. return m_Context->pIndexTableReader->getRow(
  372. m_RuntimeDataFunctionInfo->FunctionDependencies).Count();
  373. }
  374. const char *GetDependency(uint32_t i) const {
  375. if (!m_RuntimeDataFunctionInfo)
  376. return "";
  377. uint32_t resIndex = m_Context->pIndexTableReader->getRow(
  378. m_RuntimeDataFunctionInfo->FunctionDependencies).At(i);
  379. return m_Context->pStringTableReader->Get(resIndex);
  380. }
  381. uint32_t GetPayloadSizeInBytes() const {
  382. return !m_RuntimeDataFunctionInfo ? 0
  383. : m_RuntimeDataFunctionInfo->PayloadSizeInBytes;
  384. }
  385. uint32_t GetAttributeSizeInBytes() const {
  386. return !m_RuntimeDataFunctionInfo ? 0
  387. : m_RuntimeDataFunctionInfo->AttributeSizeInBytes;
  388. }
  389. // payload (hit shaders) and parameters (call shaders) are mutually exclusive
  390. uint32_t GetParameterSizeInBytes() const {
  391. return !m_RuntimeDataFunctionInfo ? 0
  392. : m_RuntimeDataFunctionInfo->PayloadSizeInBytes;
  393. }
  394. hlsl::DXIL::ShaderKind GetShaderKind() const {
  395. return !m_RuntimeDataFunctionInfo ? hlsl::DXIL::ShaderKind::Invalid
  396. : (hlsl::DXIL::ShaderKind)m_RuntimeDataFunctionInfo->ShaderKind;
  397. }
  398. };
  399. class FunctionTableReader {
  400. private:
  401. TableReader m_Table;
  402. RuntimeDataContext *m_Context;
  403. public:
  404. FunctionTableReader() : m_Context(nullptr) {}
  405. FunctionReader GetItem(uint32_t i) const {
  406. return FunctionReader(m_Table.Row<RuntimeDataFunctionInfo>(i), m_Context);
  407. }
  408. uint32_t GetNumFunctions() const { return m_Table.Count(); }
  409. void SetFunctionInfo(const char *ptr, uint32_t count, uint32_t recordStride) {
  410. m_Table.Init(ptr, count, recordStride);
  411. }
  412. void SetContext(RuntimeDataContext *context) { m_Context = context; }
  413. };
  414. class SubobjectReader {
  415. private:
  416. const RuntimeDataSubobjectInfo *m_SubobjectInfo;
  417. RuntimeDataContext *m_Context;
  418. public:
  419. SubobjectReader(const RuntimeDataSubobjectInfo *info, RuntimeDataContext *context)
  420. : m_SubobjectInfo(info), m_Context(context) {}
  421. DXIL::SubobjectKind GetKind() const {
  422. return m_SubobjectInfo ? (DXIL::SubobjectKind)(m_SubobjectInfo->Kind) :
  423. (DXIL::SubobjectKind)(-1);
  424. }
  425. const char *GetName() const {
  426. return m_SubobjectInfo && m_SubobjectInfo->Name ?
  427. m_Context->pStringTableReader->Get(m_SubobjectInfo->Name) : "";
  428. }
  429. // StateObjectConfig
  430. uint32_t GetStateObjectConfig_Flags() const {
  431. return (GetKind() == DXIL::SubobjectKind::StateObjectConfig) ?
  432. m_SubobjectInfo->StateObjectConfig.Flags : (uint32_t)0;
  433. }
  434. // [Global|Local]RootSignature
  435. // returns true if valid non-zero-length buffer found and set to output params
  436. bool GetRootSignature(const void **ppOutBytes, uint32_t *pOutSizeInBytes) const {
  437. if (!ppOutBytes || !pOutSizeInBytes)
  438. return false;
  439. if (m_SubobjectInfo &&
  440. ( GetKind() == DXIL::SubobjectKind::GlobalRootSignature ||
  441. GetKind() == DXIL::SubobjectKind::LocalRootSignature ) &&
  442. m_SubobjectInfo->RootSignature.SizeInBytes > 0) {
  443. *ppOutBytes = m_Context->pRawBytesReader->Get(m_SubobjectInfo->RootSignature.RawBytesOffset);
  444. *pOutSizeInBytes = m_SubobjectInfo->RootSignature.SizeInBytes;
  445. return true;
  446. } else {
  447. *ppOutBytes = nullptr;
  448. *pOutSizeInBytes = 0;
  449. }
  450. return false;
  451. }
  452. // SubobjectToExportsAssociation
  453. const char *GetSubobjectToExportsAssociation_Subobject() const {
  454. return (GetKind() == DXIL::SubobjectKind::SubobjectToExportsAssociation) ?
  455. m_Context->pStringTableReader->Get(m_SubobjectInfo->SubobjectToExportsAssociation.Subobject) : "";
  456. }
  457. uint32_t GetSubobjectToExportsAssociation_NumExports() const {
  458. return (GetKind() == DXIL::SubobjectKind::SubobjectToExportsAssociation) ?
  459. m_Context->pIndexTableReader->getRow(m_SubobjectInfo->SubobjectToExportsAssociation.Exports).Count() : 0;
  460. }
  461. const char *GetSubobjectToExportsAssociation_Export(uint32_t index) const {
  462. if (!(GetKind() == DXIL::SubobjectKind::SubobjectToExportsAssociation))
  463. return "";
  464. auto row = m_Context->pIndexTableReader->getRow(
  465. m_SubobjectInfo->SubobjectToExportsAssociation.Exports);
  466. if (index >= row.Count())
  467. return "";
  468. return m_Context->pStringTableReader->Get(row.At(index));
  469. }
  470. // RaytracingShaderConfig
  471. uint32_t GetRaytracingShaderConfig_MaxPayloadSizeInBytes() const {
  472. return (GetKind() == DXIL::SubobjectKind::RaytracingShaderConfig) ?
  473. m_SubobjectInfo->RaytracingShaderConfig.MaxPayloadSizeInBytes : 0;
  474. }
  475. uint32_t GetRaytracingShaderConfig_MaxAttributeSizeInBytes() const {
  476. return (GetKind() == DXIL::SubobjectKind::RaytracingShaderConfig) ?
  477. m_SubobjectInfo->RaytracingShaderConfig.MaxAttributeSizeInBytes : 0;
  478. }
  479. // RaytracingPipelineConfig
  480. uint32_t GetRaytracingPipelineConfig_MaxTraceRecursionDepth() const {
  481. return (GetKind() == DXIL::SubobjectKind::RaytracingPipelineConfig) ?
  482. m_SubobjectInfo->RaytracingPipelineConfig.MaxTraceRecursionDepth : 0;
  483. }
  484. // RaytracingPipelineConfig1
  485. uint32_t GetRaytracingPipelineConfig1_MaxTraceRecursionDepth() const {
  486. return (GetKind() == DXIL::SubobjectKind::RaytracingPipelineConfig1) ?
  487. m_SubobjectInfo->RaytracingPipelineConfig1.MaxTraceRecursionDepth : 0;
  488. }
  489. uint32_t GetRaytracingPipelineConfig1_Flags() const {
  490. return (GetKind() == DXIL::SubobjectKind::RaytracingPipelineConfig1) ?
  491. m_SubobjectInfo->RaytracingPipelineConfig1.Flags : (uint32_t)0;
  492. }
  493. // HitGroup
  494. DXIL::HitGroupType GetHitGroup_Type() const {
  495. return (GetKind() == DXIL::SubobjectKind::HitGroup) ?
  496. (DXIL::HitGroupType)m_SubobjectInfo->HitGroup.Type : (DXIL::HitGroupType)(-1);
  497. }
  498. const char *GetHitGroup_Intersection() const {
  499. return (GetKind() == DXIL::SubobjectKind::HitGroup) ?
  500. m_Context->pStringTableReader->Get(m_SubobjectInfo->HitGroup.Intersection) : "";
  501. }
  502. const char *GetHitGroup_AnyHit() const {
  503. return (GetKind() == DXIL::SubobjectKind::HitGroup) ?
  504. m_Context->pStringTableReader->Get(m_SubobjectInfo->HitGroup.AnyHit) : "";
  505. }
  506. const char *GetHitGroup_ClosestHit() const {
  507. return (GetKind() == DXIL::SubobjectKind::HitGroup) ?
  508. m_Context->pStringTableReader->Get(m_SubobjectInfo->HitGroup.ClosestHit) : "";
  509. }
  510. };
  511. class SubobjectTableReader {
  512. private:
  513. TableReader m_Table;
  514. RuntimeDataContext *m_Context;
  515. public:
  516. SubobjectTableReader() : m_Context(nullptr) {}
  517. void SetContext(RuntimeDataContext *context) { m_Context = context; }
  518. void SetSubobjectInfo(const char *ptr, uint32_t count, uint32_t recordStride) {
  519. m_Table.Init(ptr, count, recordStride);
  520. }
  521. uint32_t GetCount() const { return m_Table.Count(); }
  522. SubobjectReader GetItem(uint32_t i) const {
  523. return SubobjectReader(m_Table.Row<RuntimeDataSubobjectInfo>(i), m_Context);
  524. }
  525. };
  526. class DxilRuntimeData {
  527. private:
  528. StringTableReader m_StringReader;
  529. IndexTableReader m_IndexTableReader;
  530. RawBytesReader m_RawBytesReader;
  531. ResourceTableReader m_ResourceTableReader;
  532. FunctionTableReader m_FunctionTableReader;
  533. SubobjectTableReader m_SubobjectTableReader;
  534. RuntimeDataContext m_Context;
  535. public:
  536. DxilRuntimeData();
  537. DxilRuntimeData(const void *ptr, size_t size);
  538. // initializing reader from RDAT. return true if no error has occured.
  539. bool InitFromRDAT(const void *pRDAT, size_t size);
  540. FunctionTableReader *GetFunctionTableReader();
  541. ResourceTableReader *GetResourceTableReader();
  542. SubobjectTableReader *GetSubobjectTableReader();
  543. };
  544. //////////////////////////////////
  545. /// structures for library runtime
  546. struct DxilResourceDesc {
  547. uint32_t Class; // hlsl::DXIL::ResourceClass
  548. uint32_t Kind; // hlsl::DXIL::ResourceKind
  549. uint32_t ID; // id per class
  550. uint32_t Space;
  551. uint32_t UpperBound;
  552. uint32_t LowerBound;
  553. LPCWSTR Name;
  554. uint32_t Flags; // hlsl::RDAT::DxilResourceFlag
  555. };
  556. struct DxilFunctionDesc {
  557. LPCWSTR Name;
  558. LPCWSTR UnmangledName;
  559. uint32_t NumResources;
  560. const DxilResourceDesc * const*Resources;
  561. uint32_t NumFunctionDependencies;
  562. const LPCWSTR *FunctionDependencies;
  563. uint32_t ShaderKind;
  564. uint32_t PayloadSizeInBytes; // 1) hit, miss, or closest shader: payload count
  565. // 2) call shader: parameter size
  566. uint32_t AttributeSizeInBytes; // attribute size for closest hit and any hit
  567. uint32_t FeatureInfo1; // first 32 bits of feature flag
  568. uint32_t FeatureInfo2; // second 32 bits of feature flag
  569. uint32_t ShaderStageFlag; // valid shader stage flag.
  570. uint32_t MinShaderTarget; // minimum shader target.
  571. };
  572. struct DxilSubobjectDesc {
  573. LPCWSTR Name;
  574. uint32_t Kind; // DXIL::SubobjectKind / D3D12_STATE_SUBOBJECT_TYPE
  575. struct StateObjectConfig_t {
  576. uint32_t Flags; // DXIL::StateObjectFlags / D3D12_STATE_OBJECT_FLAGS
  577. };
  578. struct RootSignature_t {
  579. LPCVOID pSerializedSignature;
  580. uint32_t SizeInBytes;
  581. }; // GlobalRootSignature or LocalRootSignature
  582. struct SubobjectToExportsAssociation_t {
  583. LPCWSTR Subobject;
  584. uint32_t NumExports;
  585. const LPCWSTR* Exports;
  586. };
  587. struct RaytracingShaderConfig_t {
  588. uint32_t MaxPayloadSizeInBytes;
  589. uint32_t MaxAttributeSizeInBytes;
  590. };
  591. struct RaytracingPipelineConfig_t {
  592. uint32_t MaxTraceRecursionDepth;
  593. };
  594. struct HitGroup_t {
  595. uint32_t Type; // DXIL::HitGroupType / D3D12_HIT_GROUP_TYPE
  596. LPCWSTR AnyHit;
  597. LPCWSTR ClosestHit;
  598. LPCWSTR Intersection;
  599. };
  600. struct RaytracingPipelineConfig1_t {
  601. uint32_t MaxTraceRecursionDepth;
  602. uint32_t Flags; // DXIL::RaytracingPipelineFlags / D3D12_RAYTRACING_PIPELINE_FLAGS
  603. };
  604. union {
  605. StateObjectConfig_t StateObjectConfig;
  606. RootSignature_t RootSignature; // GlobalRootSignature or LocalRootSignature
  607. SubobjectToExportsAssociation_t SubobjectToExportsAssociation;
  608. RaytracingShaderConfig_t RaytracingShaderConfig;
  609. RaytracingPipelineConfig_t RaytracingPipelineConfig;
  610. HitGroup_t HitGroup;
  611. RaytracingPipelineConfig1_t RaytracingPipelineConfig1;
  612. };
  613. };
  614. struct DxilLibraryDesc {
  615. uint32_t NumFunctions;
  616. DxilFunctionDesc *pFunction;
  617. uint32_t NumResources;
  618. DxilResourceDesc *pResource;
  619. uint32_t NumSubobjects;
  620. DxilSubobjectDesc *pSubobjects;
  621. };
  622. class DxilRuntimeReflection {
  623. public:
  624. virtual ~DxilRuntimeReflection() {}
  625. // This call will allocate memory for GetLibraryReflection call
  626. virtual bool InitFromRDAT(const void *pRDAT, size_t size) = 0;
  627. // DxilRuntimeReflection owns the memory pointed to by DxilLibraryDesc
  628. virtual const DxilLibraryDesc GetLibraryReflection() = 0;
  629. };
  630. DxilRuntimeReflection *CreateDxilRuntimeReflection();
  631. } // namespace RDAT
  632. } // namespace hlsl