DxilSubobject.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // //
  3. // DxilSubobject.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. ///////////////////////////////////////////////////////////////////////////////
  9. #include "dxc/Support/Global.h"
  10. #include "dxc/DXIL/DxilSubobject.h"
  11. #include "llvm/ADT/STLExtras.h"
  12. namespace hlsl {
  13. //------------------------------------------------------------------------------
  14. //
  15. // Subobject methods.
  16. //
  17. DxilSubobject::DxilSubobject(DxilSubobject &&other)
  18. : m_Owner(other.m_Owner),
  19. m_Kind(other.m_Kind),
  20. m_Name(m_Owner.InternString(other.m_Name)),
  21. m_Exports(std::move(other.m_Exports))
  22. {
  23. DXASSERT_NOMSG(DXIL::IsValidSubobjectKind(m_Kind));
  24. CopyUnionedContents(other);
  25. }
  26. DxilSubobject::DxilSubobject(DxilSubobjects &owner, Kind kind, llvm::StringRef name)
  27. : m_Owner(owner),
  28. m_Kind(kind),
  29. m_Name(m_Owner.InternString(name)),
  30. m_Exports()
  31. {
  32. DXASSERT_NOMSG(DXIL::IsValidSubobjectKind(m_Kind));
  33. }
  34. DxilSubobject::DxilSubobject(DxilSubobjects &owner, const DxilSubobject &other, llvm::StringRef name)
  35. : m_Owner(owner),
  36. m_Kind(other.m_Kind),
  37. m_Name(name),
  38. m_Exports(other.m_Exports.begin(), other.m_Exports.end())
  39. {
  40. DXASSERT_NOMSG(DXIL::IsValidSubobjectKind(m_Kind));
  41. CopyUnionedContents(other);
  42. if (&m_Owner != &other.m_Owner)
  43. InternStrings();
  44. }
  45. void DxilSubobject::CopyUnionedContents(const DxilSubobject &other) {
  46. switch (m_Kind) {
  47. case Kind::StateObjectConfig:
  48. StateObjectConfig.Flags = other.StateObjectConfig.Flags;
  49. break;
  50. case Kind::GlobalRootSignature:
  51. case Kind::LocalRootSignature:
  52. RootSignature.Size = other.RootSignature.Size;
  53. RootSignature.Data = other.RootSignature.Data;
  54. break;
  55. case Kind::SubobjectToExportsAssociation:
  56. SubobjectToExportsAssociation.Subobject = other.SubobjectToExportsAssociation.Subobject;
  57. break;
  58. case Kind::RaytracingShaderConfig:
  59. RaytracingShaderConfig.MaxPayloadSizeInBytes = other.RaytracingShaderConfig.MaxPayloadSizeInBytes;
  60. RaytracingShaderConfig.MaxAttributeSizeInBytes = other.RaytracingShaderConfig.MaxAttributeSizeInBytes;
  61. break;
  62. case Kind::RaytracingPipelineConfig:
  63. RaytracingPipelineConfig.MaxTraceRecursionDepth = other.RaytracingPipelineConfig.MaxTraceRecursionDepth;
  64. break;
  65. case Kind::HitGroup:
  66. HitGroup.Type = other.HitGroup.Type;
  67. HitGroup.AnyHit = other.HitGroup.AnyHit;
  68. HitGroup.ClosestHit = other.HitGroup.ClosestHit;
  69. HitGroup.Intersection = other.HitGroup.Intersection;
  70. break;
  71. default:
  72. DXASSERT(0, "invalid kind");
  73. break;
  74. }
  75. }
  76. void DxilSubobject::InternStrings() {
  77. // Transfer strings if necessary
  78. m_Name = m_Owner.InternString(m_Name).data();
  79. switch (m_Kind) {
  80. case Kind::SubobjectToExportsAssociation:
  81. SubobjectToExportsAssociation.Subobject = m_Owner.InternString(SubobjectToExportsAssociation.Subobject).data();
  82. for (auto &ptr : m_Exports)
  83. ptr = m_Owner.InternString(ptr).data();
  84. break;
  85. case Kind::HitGroup:
  86. HitGroup.AnyHit = m_Owner.InternString(HitGroup.AnyHit).data();
  87. HitGroup.ClosestHit = m_Owner.InternString(HitGroup.ClosestHit).data();
  88. HitGroup.Intersection = m_Owner.InternString(HitGroup.Intersection).data();
  89. break;
  90. default:
  91. break;
  92. }
  93. }
  94. DxilSubobject::~DxilSubobject() {
  95. }
  96. // StateObjectConfig
  97. bool DxilSubobject::GetStateObjectConfig(uint32_t &Flags) const {
  98. if (m_Kind == Kind::StateObjectConfig) {
  99. Flags = StateObjectConfig.Flags;
  100. return true;
  101. }
  102. return false;
  103. }
  104. // Local/Global RootSignature
  105. bool DxilSubobject::GetRootSignature(
  106. bool local, const void * &Data, uint32_t &Size, const char **pText) const {
  107. Kind expected = local ? Kind::LocalRootSignature : Kind::GlobalRootSignature;
  108. if (m_Kind == expected) {
  109. Data = RootSignature.Data;
  110. Size = RootSignature.Size;
  111. if (pText)
  112. *pText = RootSignature.Text;
  113. return true;
  114. }
  115. return false;
  116. }
  117. // SubobjectToExportsAssociation
  118. bool DxilSubobject::GetSubobjectToExportsAssociation(
  119. llvm::StringRef &Subobject,
  120. const char * const * &Exports,
  121. uint32_t &NumExports) const {
  122. if (m_Kind == Kind::SubobjectToExportsAssociation) {
  123. Subobject = SubobjectToExportsAssociation.Subobject;
  124. Exports = m_Exports.data();
  125. NumExports = (uint32_t)m_Exports.size();
  126. return true;
  127. }
  128. return false;
  129. }
  130. // RaytracingShaderConfig
  131. bool DxilSubobject::GetRaytracingShaderConfig(uint32_t &MaxPayloadSizeInBytes,
  132. uint32_t &MaxAttributeSizeInBytes) const {
  133. if (m_Kind == Kind::RaytracingShaderConfig) {
  134. MaxPayloadSizeInBytes = RaytracingShaderConfig.MaxPayloadSizeInBytes;
  135. MaxAttributeSizeInBytes = RaytracingShaderConfig.MaxAttributeSizeInBytes;
  136. return true;
  137. }
  138. return false;
  139. }
  140. // RaytracingPipelineConfig
  141. bool DxilSubobject::GetRaytracingPipelineConfig(
  142. uint32_t &MaxTraceRecursionDepth) const {
  143. if (m_Kind == Kind::RaytracingPipelineConfig) {
  144. MaxTraceRecursionDepth = RaytracingPipelineConfig.MaxTraceRecursionDepth;
  145. return true;
  146. }
  147. return false;
  148. }
  149. // HitGroup
  150. bool DxilSubobject::GetHitGroup(DXIL::HitGroupType &hitGroupType,
  151. llvm::StringRef &AnyHit,
  152. llvm::StringRef &ClosestHit,
  153. llvm::StringRef &Intersection) const {
  154. if (m_Kind == Kind::HitGroup) {
  155. hitGroupType = HitGroup.Type;
  156. AnyHit = HitGroup.AnyHit;
  157. ClosestHit = HitGroup.ClosestHit;
  158. Intersection = HitGroup.Intersection;
  159. return true;
  160. }
  161. return false;
  162. }
  163. DxilSubobjects::DxilSubobjects()
  164. : m_BytesStorage()
  165. , m_Subobjects()
  166. {}
  167. DxilSubobjects::DxilSubobjects(DxilSubobjects &&other)
  168. : m_BytesStorage(std::move(other.m_BytesStorage))
  169. , m_Subobjects(std::move(other.m_Subobjects))
  170. {}
  171. DxilSubobjects::~DxilSubobjects() {}
  172. llvm::StringRef DxilSubobjects::InternString(llvm::StringRef value) {
  173. auto it = m_BytesStorage.find(value);
  174. if (it != m_BytesStorage.end())
  175. return it->first;
  176. size_t size = value.size();
  177. StoredBytes stored(std::make_pair(std::unique_ptr<char[]>(new char[size + 1]), size + 1));
  178. memcpy(stored.first.get(), value.data(), size);
  179. stored.first[size] = 0;
  180. llvm::StringRef key(stored.first.get(), size);
  181. m_BytesStorage[key] = std::move(stored);
  182. return key;
  183. }
  184. const void *DxilSubobjects::InternRawBytes(const void *ptr, size_t size) {
  185. auto it = m_BytesStorage.find(llvm::StringRef((const char *)ptr, size));
  186. if (it != m_BytesStorage.end())
  187. return it->first.data();
  188. StoredBytes stored(std::make_pair(std::unique_ptr<char[]>(new char[size]), size));
  189. memcpy(stored.first.get(), ptr, size);
  190. llvm::StringRef key(stored.first.get(), size);
  191. m_BytesStorage[key] = std::move(stored);
  192. return key.data();
  193. }
  194. DxilSubobject *DxilSubobjects::FindSubobject(llvm::StringRef name) {
  195. auto it = m_Subobjects.find(name);
  196. if (it != m_Subobjects.end())
  197. return it->second.get();
  198. return nullptr;
  199. }
  200. void DxilSubobjects::RemoveSubobject(llvm::StringRef name) {
  201. auto it = m_Subobjects.find(name);
  202. if (it != m_Subobjects.end())
  203. m_Subobjects.erase(it);
  204. }
  205. DxilSubobject &DxilSubobjects::CloneSubobject(
  206. const DxilSubobject &Subobject, llvm::StringRef Name) {
  207. Name = InternString(Name);
  208. DXASSERT(FindSubobject(Name) == nullptr,
  209. "otherwise, name collision between subobjects");
  210. std::unique_ptr<DxilSubobject> ptr(new DxilSubobject(*this, Subobject, Name));
  211. DxilSubobject &ref = *ptr;
  212. m_Subobjects[Name] = std::move(ptr);
  213. return ref;
  214. }
  215. // Create DxilSubobjects
  216. DxilSubobject &DxilSubobjects::CreateStateObjectConfig(
  217. llvm::StringRef Name, uint32_t Flags) {
  218. DXASSERT_NOMSG(0 == ((~(uint32_t)DXIL::StateObjectFlags::ValidMask) & Flags));
  219. auto &obj = CreateSubobject(Kind::StateObjectConfig, Name);
  220. obj.StateObjectConfig.Flags = Flags;
  221. return obj;
  222. }
  223. DxilSubobject &DxilSubobjects::CreateRootSignature(
  224. llvm::StringRef Name, bool local, const void *Data, uint32_t Size, llvm::StringRef *pText /*= nullptr*/) {
  225. auto &obj = CreateSubobject(local ? Kind::LocalRootSignature : Kind::GlobalRootSignature, Name);
  226. obj.RootSignature.Data = InternRawBytes(Data, Size);
  227. obj.RootSignature.Size = Size;
  228. obj.RootSignature.Text = (pText ? InternString(*pText).data() : nullptr);
  229. return obj;
  230. }
  231. DxilSubobject &DxilSubobjects::CreateSubobjectToExportsAssociation(
  232. llvm::StringRef Name,
  233. llvm::StringRef Subobject,
  234. llvm::StringRef *Exports,
  235. uint32_t NumExports) {
  236. auto &obj = CreateSubobject(Kind::SubobjectToExportsAssociation, Name);
  237. Subobject = InternString(Subobject);
  238. obj.SubobjectToExportsAssociation.Subobject = Subobject.data();
  239. for (unsigned i = 0; i < NumExports; i++) {
  240. obj.m_Exports.emplace_back(InternString(Exports[i]).data());
  241. }
  242. return obj;
  243. }
  244. DxilSubobject &DxilSubobjects::CreateRaytracingShaderConfig(
  245. llvm::StringRef Name,
  246. uint32_t MaxPayloadSizeInBytes,
  247. uint32_t MaxAttributeSizeInBytes) {
  248. auto &obj = CreateSubobject(Kind::RaytracingShaderConfig, Name);
  249. obj.RaytracingShaderConfig.MaxPayloadSizeInBytes = MaxPayloadSizeInBytes;
  250. obj.RaytracingShaderConfig.MaxAttributeSizeInBytes = MaxAttributeSizeInBytes;
  251. return obj;
  252. }
  253. DxilSubobject &DxilSubobjects::CreateRaytracingPipelineConfig(
  254. llvm::StringRef Name,
  255. uint32_t MaxTraceRecursionDepth) {
  256. auto &obj = CreateSubobject(Kind::RaytracingPipelineConfig, Name);
  257. obj.RaytracingPipelineConfig.MaxTraceRecursionDepth = MaxTraceRecursionDepth;
  258. return obj;
  259. }
  260. DxilSubobject &DxilSubobjects::CreateHitGroup(llvm::StringRef Name,
  261. DXIL::HitGroupType hitGroupType,
  262. llvm::StringRef AnyHit,
  263. llvm::StringRef ClosestHit,
  264. llvm::StringRef Intersection) {
  265. auto &obj = CreateSubobject(Kind::HitGroup, Name);
  266. AnyHit = InternString(AnyHit);
  267. ClosestHit = InternString(ClosestHit);
  268. Intersection = InternString(Intersection);
  269. obj.HitGroup.Type = hitGroupType;
  270. obj.HitGroup.AnyHit = AnyHit.data();
  271. obj.HitGroup.ClosestHit = ClosestHit.data();
  272. obj.HitGroup.Intersection = Intersection.data();
  273. return obj;
  274. }
  275. DxilSubobject &DxilSubobjects::CreateSubobject(Kind kind, llvm::StringRef Name) {
  276. Name = InternString(Name);
  277. IFTBOOLMSG(FindSubobject(Name) == nullptr, DXC_E_GENERAL_INTERNAL_ERROR, "Subobject name collision");
  278. IFTBOOLMSG(!Name.empty(), DXC_E_GENERAL_INTERNAL_ERROR, "Empty Subobject name");
  279. std::unique_ptr<DxilSubobject> ptr(new DxilSubobject(*this, kind, Name));
  280. DxilSubobject &ref = *ptr;
  281. m_Subobjects[Name] = std::move(ptr);
  282. return ref;
  283. }
  284. } // namespace hlsl