DxilShaderModel.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // //
  3. // DxilShaderModel.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 <limits.h>
  10. #include "dxc/DXIL/DxilShaderModel.h"
  11. #include "dxc/DXIL/DxilSemantic.h"
  12. #include "dxc/Support/Global.h"
  13. #include <unordered_map>
  14. namespace hlsl {
  15. ShaderModel::ShaderModel(Kind Kind, unsigned Major, unsigned Minor, const char *pszName,
  16. unsigned NumInputRegs, unsigned NumOutputRegs,
  17. bool bUAVs, bool bTypedUavs, unsigned NumUAVRegs)
  18. : m_Kind(Kind)
  19. , m_Major(Major)
  20. , m_Minor(Minor)
  21. , m_pszName(pszName)
  22. , m_NumInputRegs(NumInputRegs)
  23. , m_NumOutputRegs(NumOutputRegs)
  24. , m_bTypedUavs(bTypedUavs)
  25. , m_NumUAVRegs(NumUAVRegs) {
  26. }
  27. bool ShaderModel::operator==(const ShaderModel &other) const {
  28. return m_Kind == other.m_Kind
  29. && m_Major == other.m_Major
  30. && m_Minor == other.m_Minor
  31. && strcmp(m_pszName, other.m_pszName) == 0
  32. && m_NumInputRegs == other.m_NumInputRegs
  33. && m_NumOutputRegs == other.m_NumOutputRegs
  34. && m_bTypedUavs == other.m_bTypedUavs
  35. && m_NumUAVRegs == other.m_NumUAVRegs;
  36. }
  37. bool ShaderModel::IsValid() const {
  38. DXASSERT(IsPS() || IsVS() || IsGS() || IsHS() || IsDS() || IsCS() ||
  39. IsLib() || IsMS() || IsAS() || m_Kind == Kind::Invalid,
  40. "invalid shader model");
  41. return m_Kind != Kind::Invalid;
  42. }
  43. bool ShaderModel::IsValidForDxil() const {
  44. if (!IsValid())
  45. return false;
  46. switch (m_Major) {
  47. case 6: {
  48. switch (m_Minor) {
  49. /* <py::lines('VALRULE-TEXT')>hctdb_instrhelp.get_is_valid_for_dxil()</py>*/
  50. // VALRULE-TEXT:BEGIN
  51. case 0:
  52. case 1:
  53. case 2:
  54. case 3:
  55. case 4:
  56. case 5:
  57. case 6:
  58. // VALRULE-TEXT:END
  59. return true;
  60. case kOfflineMinor:
  61. return m_Kind == Kind::Library;
  62. }
  63. }
  64. break;
  65. }
  66. return false;
  67. }
  68. bool ShaderModel::IsValidForModule() const {
  69. // Ray tracing shader model should only be used on functions in a lib
  70. return IsValid() && !IsRay();
  71. }
  72. const ShaderModel *ShaderModel::Get(Kind Kind, unsigned Major, unsigned Minor) {
  73. /* <py::lines('VALRULE-TEXT')>hctdb_instrhelp.get_shader_model_get()</py>*/
  74. // VALRULE-TEXT:BEGIN
  75. const static std::unordered_map<unsigned, unsigned> hashToIdxMap = {
  76. {1024,0}, //ps_4_0
  77. {1025,1}, //ps_4_1
  78. {1280,2}, //ps_5_0
  79. {1281,3}, //ps_5_1
  80. {1536,4}, //ps_6_0
  81. {1537,5}, //ps_6_1
  82. {1538,6}, //ps_6_2
  83. {1539,7}, //ps_6_3
  84. {1540,8}, //ps_6_4
  85. {1541,9}, //ps_6_5
  86. {1542,10}, //ps_6_6
  87. {66560,11}, //vs_4_0
  88. {66561,12}, //vs_4_1
  89. {66816,13}, //vs_5_0
  90. {66817,14}, //vs_5_1
  91. {67072,15}, //vs_6_0
  92. {67073,16}, //vs_6_1
  93. {67074,17}, //vs_6_2
  94. {67075,18}, //vs_6_3
  95. {67076,19}, //vs_6_4
  96. {67077,20}, //vs_6_5
  97. {67078,21}, //vs_6_6
  98. {132096,22}, //gs_4_0
  99. {132097,23}, //gs_4_1
  100. {132352,24}, //gs_5_0
  101. {132353,25}, //gs_5_1
  102. {132608,26}, //gs_6_0
  103. {132609,27}, //gs_6_1
  104. {132610,28}, //gs_6_2
  105. {132611,29}, //gs_6_3
  106. {132612,30}, //gs_6_4
  107. {132613,31}, //gs_6_5
  108. {132614,32}, //gs_6_6
  109. {197888,33}, //hs_5_0
  110. {197889,34}, //hs_5_1
  111. {198144,35}, //hs_6_0
  112. {198145,36}, //hs_6_1
  113. {198146,37}, //hs_6_2
  114. {198147,38}, //hs_6_3
  115. {198148,39}, //hs_6_4
  116. {198149,40}, //hs_6_5
  117. {198150,41}, //hs_6_6
  118. {263424,42}, //ds_5_0
  119. {263425,43}, //ds_5_1
  120. {263680,44}, //ds_6_0
  121. {263681,45}, //ds_6_1
  122. {263682,46}, //ds_6_2
  123. {263683,47}, //ds_6_3
  124. {263684,48}, //ds_6_4
  125. {263685,49}, //ds_6_5
  126. {263686,50}, //ds_6_6
  127. {328704,51}, //cs_4_0
  128. {328705,52}, //cs_4_1
  129. {328960,53}, //cs_5_0
  130. {328961,54}, //cs_5_1
  131. {329216,55}, //cs_6_0
  132. {329217,56}, //cs_6_1
  133. {329218,57}, //cs_6_2
  134. {329219,58}, //cs_6_3
  135. {329220,59}, //cs_6_4
  136. {329221,60}, //cs_6_5
  137. {329222,61}, //cs_6_6
  138. {394753,62}, //lib_6_1
  139. {394754,63}, //lib_6_2
  140. {394755,64}, //lib_6_3
  141. {394756,65}, //lib_6_4
  142. {394757,66}, //lib_6_5
  143. {394758,67}, //lib_6_6
  144. // lib_6_x is for offline linking only, and relaxes restrictions
  145. {394767,68},//lib_6_x
  146. {853509,69}, //ms_6_5
  147. {853510,70}, //ms_6_6
  148. {919045,71}, //as_6_5
  149. {919046,72}, //as_6_6
  150. };
  151. unsigned hash = (unsigned)Kind << 16 | Major << 8 | Minor;
  152. auto it = hashToIdxMap.find(hash);
  153. if (it == hashToIdxMap.end())
  154. return GetInvalid();
  155. return &ms_ShaderModels[it->second];
  156. // VALRULE-TEXT:END
  157. }
  158. const ShaderModel *ShaderModel::GetByName(const char *pszName) {
  159. // [ps|vs|gs|hs|ds|cs|ms|as]_[major]_[minor]
  160. Kind kind;
  161. switch (pszName[0]) {
  162. case 'p': kind = Kind::Pixel; break;
  163. case 'v': kind = Kind::Vertex; break;
  164. case 'g': kind = Kind::Geometry; break;
  165. case 'h': kind = Kind::Hull; break;
  166. case 'd': kind = Kind::Domain; break;
  167. case 'c': kind = Kind::Compute; break;
  168. case 'l': kind = Kind::Library; break;
  169. case 'm': kind = Kind::Mesh; break;
  170. case 'a': kind = Kind::Amplification; break;
  171. default: return GetInvalid();
  172. }
  173. unsigned Idx = 3;
  174. if (kind != Kind::Library) {
  175. if (pszName[1] != 's' || pszName[2] != '_')
  176. return GetInvalid();
  177. } else {
  178. if (pszName[1] != 'i' || pszName[2] != 'b' || pszName[3] != '_')
  179. return GetInvalid();
  180. Idx = 4;
  181. }
  182. unsigned Major;
  183. switch (pszName[Idx++]) {
  184. case '4': Major = 4; break;
  185. case '5': Major = 5; break;
  186. case '6': Major = 6; break;
  187. default: return GetInvalid();
  188. }
  189. if (pszName[Idx++] != '_')
  190. return GetInvalid();
  191. unsigned Minor;
  192. switch (pszName[Idx++]) {
  193. case '0': Minor = 0; break;
  194. case '1': Minor = 1; break;
  195. /* <py::lines('VALRULE-TEXT')>hctdb_instrhelp.get_shader_model_by_name()</py>*/
  196. // VALRULE-TEXT:BEGIN
  197. case '2':
  198. if (Major == 6) {
  199. Minor = 2;
  200. break;
  201. }
  202. else return GetInvalid();
  203. case '3':
  204. if (Major == 6) {
  205. Minor = 3;
  206. break;
  207. }
  208. else return GetInvalid();
  209. case '4':
  210. if (Major == 6) {
  211. Minor = 4;
  212. break;
  213. }
  214. else return GetInvalid();
  215. case '5':
  216. if (Major == 6) {
  217. Minor = 5;
  218. break;
  219. }
  220. else return GetInvalid();
  221. case '6':
  222. if (Major == 6) {
  223. Minor = 6;
  224. break;
  225. }
  226. else return GetInvalid();
  227. // VALRULE-TEXT:END
  228. case 'x':
  229. if (kind == Kind::Library && Major == 6) {
  230. Minor = kOfflineMinor;
  231. break;
  232. }
  233. else return GetInvalid();
  234. default: return GetInvalid();
  235. }
  236. if (pszName[Idx++] != 0)
  237. return GetInvalid();
  238. return Get(kind, Major, Minor);
  239. }
  240. void ShaderModel::GetDxilVersion(unsigned &DxilMajor, unsigned &DxilMinor) const {
  241. DXASSERT(IsValidForDxil(), "invalid shader model");
  242. DxilMajor = 1;
  243. switch (m_Minor) {
  244. /* <py::lines('VALRULE-TEXT')>hctdb_instrhelp.get_dxil_version()</py>*/
  245. // VALRULE-TEXT:BEGIN
  246. case 0:
  247. DxilMinor = 0;
  248. break;
  249. case 1:
  250. DxilMinor = 1;
  251. break;
  252. case 2:
  253. DxilMinor = 2;
  254. break;
  255. case 3:
  256. DxilMinor = 3;
  257. break;
  258. case 4:
  259. DxilMinor = 4;
  260. break;
  261. case 5:
  262. DxilMinor = 5;
  263. break;
  264. case 6:
  265. DxilMinor = 6;
  266. break;
  267. case kOfflineMinor: // Always update this to highest dxil version
  268. DxilMinor = 6;
  269. break;
  270. // VALRULE-TEXT:END
  271. default:
  272. DXASSERT(0, "IsValidForDxil() should have caught this.");
  273. break;
  274. }
  275. }
  276. void ShaderModel::GetMinValidatorVersion(unsigned &ValMajor, unsigned &ValMinor) const {
  277. DXASSERT(IsValidForDxil(), "invalid shader model");
  278. ValMajor = 1;
  279. switch (m_Minor) {
  280. /* <py::lines('VALRULE-TEXT')>hctdb_instrhelp.get_min_validator_version()</py>*/
  281. // VALRULE-TEXT:BEGIN
  282. case 0:
  283. ValMinor = 0;
  284. break;
  285. case 1:
  286. ValMinor = 1;
  287. break;
  288. case 2:
  289. ValMinor = 2;
  290. break;
  291. case 3:
  292. ValMinor = 3;
  293. break;
  294. case 4:
  295. ValMinor = 4;
  296. break;
  297. case 5:
  298. ValMinor = 5;
  299. break;
  300. case 6:
  301. ValMinor = 6;
  302. break;
  303. // VALRULE-TEXT:END
  304. case kOfflineMinor:
  305. ValMajor = 0;
  306. ValMinor = 0;
  307. break;
  308. default:
  309. DXASSERT(0, "IsValidForDxil() should have caught this.");
  310. break;
  311. }
  312. }
  313. static const char *ShaderModelKindNames[] = {
  314. "ps", "vs", "gs", "hs", "ds", "cs", "lib",
  315. "raygeneration", "intersection", "anyhit", "closesthit", "miss", "callable",
  316. "ms", "as", "invalid",
  317. };
  318. const char * ShaderModel::GetKindName() const {
  319. return GetKindName(m_Kind);
  320. }
  321. const char *ShaderModel::GetKindName(Kind kind) {
  322. static_assert(static_cast<unsigned>(Kind::Invalid) ==
  323. _countof(ShaderModelKindNames) - 1,
  324. "Invalid kinds or names");
  325. return ShaderModelKindNames[static_cast<unsigned int>(kind)];
  326. }
  327. const ShaderModel *ShaderModel::GetInvalid() {
  328. return &ms_ShaderModels[kNumShaderModels - 1];
  329. }
  330. typedef ShaderModel SM;
  331. typedef Semantic SE;
  332. const ShaderModel ShaderModel::ms_ShaderModels[kNumShaderModels] = {
  333. // IR OR UAV? TyUAV? UAV base
  334. /* <py::lines('VALRULE-TEXT')>hctdb_instrhelp.get_shader_models()</py>*/
  335. // VALRULE-TEXT:BEGIN
  336. SM(Kind::Pixel, 4, 0, "ps_4_0", 32, 8, false, false, 0),
  337. SM(Kind::Pixel, 4, 1, "ps_4_1", 32, 8, false, false, 0),
  338. SM(Kind::Pixel, 5, 0, "ps_5_0", 32, 8, true, true, 64),
  339. SM(Kind::Pixel, 5, 1, "ps_5_1", 32, 8, true, true, 64),
  340. SM(Kind::Pixel, 6, 0, "ps_6_0", 32, 8, true, true, UINT_MAX),
  341. SM(Kind::Pixel, 6, 1, "ps_6_1", 32, 8, true, true, UINT_MAX),
  342. SM(Kind::Pixel, 6, 2, "ps_6_2", 32, 8, true, true, UINT_MAX),
  343. SM(Kind::Pixel, 6, 3, "ps_6_3", 32, 8, true, true, UINT_MAX),
  344. SM(Kind::Pixel, 6, 4, "ps_6_4", 32, 8, true, true, UINT_MAX),
  345. SM(Kind::Pixel, 6, 5, "ps_6_5", 32, 8, true, true, UINT_MAX),
  346. SM(Kind::Pixel, 6, 6, "ps_6_6", 32, 8, true, true, UINT_MAX),
  347. SM(Kind::Vertex, 4, 0, "vs_4_0", 16, 16, false, false, 0),
  348. SM(Kind::Vertex, 4, 1, "vs_4_1", 32, 32, false, false, 0),
  349. SM(Kind::Vertex, 5, 0, "vs_5_0", 32, 32, true, true, 64),
  350. SM(Kind::Vertex, 5, 1, "vs_5_1", 32, 32, true, true, 64),
  351. SM(Kind::Vertex, 6, 0, "vs_6_0", 32, 32, true, true, UINT_MAX),
  352. SM(Kind::Vertex, 6, 1, "vs_6_1", 32, 32, true, true, UINT_MAX),
  353. SM(Kind::Vertex, 6, 2, "vs_6_2", 32, 32, true, true, UINT_MAX),
  354. SM(Kind::Vertex, 6, 3, "vs_6_3", 32, 32, true, true, UINT_MAX),
  355. SM(Kind::Vertex, 6, 4, "vs_6_4", 32, 32, true, true, UINT_MAX),
  356. SM(Kind::Vertex, 6, 5, "vs_6_5", 32, 32, true, true, UINT_MAX),
  357. SM(Kind::Vertex, 6, 6, "vs_6_6", 32, 32, true, true, UINT_MAX),
  358. SM(Kind::Geometry, 4, 0, "gs_4_0", 16, 32, false, false, 0),
  359. SM(Kind::Geometry, 4, 1, "gs_4_1", 32, 32, false, false, 0),
  360. SM(Kind::Geometry, 5, 0, "gs_5_0", 32, 32, true, true, 64),
  361. SM(Kind::Geometry, 5, 1, "gs_5_1", 32, 32, true, true, 64),
  362. SM(Kind::Geometry, 6, 0, "gs_6_0", 32, 32, true, true, UINT_MAX),
  363. SM(Kind::Geometry, 6, 1, "gs_6_1", 32, 32, true, true, UINT_MAX),
  364. SM(Kind::Geometry, 6, 2, "gs_6_2", 32, 32, true, true, UINT_MAX),
  365. SM(Kind::Geometry, 6, 3, "gs_6_3", 32, 32, true, true, UINT_MAX),
  366. SM(Kind::Geometry, 6, 4, "gs_6_4", 32, 32, true, true, UINT_MAX),
  367. SM(Kind::Geometry, 6, 5, "gs_6_5", 32, 32, true, true, UINT_MAX),
  368. SM(Kind::Geometry, 6, 6, "gs_6_6", 32, 32, true, true, UINT_MAX),
  369. SM(Kind::Hull, 5, 0, "hs_5_0", 32, 32, true, true, 64),
  370. SM(Kind::Hull, 5, 1, "hs_5_1", 32, 32, true, true, 64),
  371. SM(Kind::Hull, 6, 0, "hs_6_0", 32, 32, true, true, UINT_MAX),
  372. SM(Kind::Hull, 6, 1, "hs_6_1", 32, 32, true, true, UINT_MAX),
  373. SM(Kind::Hull, 6, 2, "hs_6_2", 32, 32, true, true, UINT_MAX),
  374. SM(Kind::Hull, 6, 3, "hs_6_3", 32, 32, true, true, UINT_MAX),
  375. SM(Kind::Hull, 6, 4, "hs_6_4", 32, 32, true, true, UINT_MAX),
  376. SM(Kind::Hull, 6, 5, "hs_6_5", 32, 32, true, true, UINT_MAX),
  377. SM(Kind::Hull, 6, 6, "hs_6_6", 32, 32, true, true, UINT_MAX),
  378. SM(Kind::Domain, 5, 0, "ds_5_0", 32, 32, true, true, 64),
  379. SM(Kind::Domain, 5, 1, "ds_5_1", 32, 32, true, true, 64),
  380. SM(Kind::Domain, 6, 0, "ds_6_0", 32, 32, true, true, UINT_MAX),
  381. SM(Kind::Domain, 6, 1, "ds_6_1", 32, 32, true, true, UINT_MAX),
  382. SM(Kind::Domain, 6, 2, "ds_6_2", 32, 32, true, true, UINT_MAX),
  383. SM(Kind::Domain, 6, 3, "ds_6_3", 32, 32, true, true, UINT_MAX),
  384. SM(Kind::Domain, 6, 4, "ds_6_4", 32, 32, true, true, UINT_MAX),
  385. SM(Kind::Domain, 6, 5, "ds_6_5", 32, 32, true, true, UINT_MAX),
  386. SM(Kind::Domain, 6, 6, "ds_6_6", 32, 32, true, true, UINT_MAX),
  387. SM(Kind::Compute, 4, 0, "cs_4_0", 0, 0, false, false, 0),
  388. SM(Kind::Compute, 4, 1, "cs_4_1", 0, 0, false, false, 0),
  389. SM(Kind::Compute, 5, 0, "cs_5_0", 0, 0, true, true, 64),
  390. SM(Kind::Compute, 5, 1, "cs_5_1", 0, 0, true, true, 64),
  391. SM(Kind::Compute, 6, 0, "cs_6_0", 0, 0, true, true, UINT_MAX),
  392. SM(Kind::Compute, 6, 1, "cs_6_1", 0, 0, true, true, UINT_MAX),
  393. SM(Kind::Compute, 6, 2, "cs_6_2", 0, 0, true, true, UINT_MAX),
  394. SM(Kind::Compute, 6, 3, "cs_6_3", 0, 0, true, true, UINT_MAX),
  395. SM(Kind::Compute, 6, 4, "cs_6_4", 0, 0, true, true, UINT_MAX),
  396. SM(Kind::Compute, 6, 5, "cs_6_5", 0, 0, true, true, UINT_MAX),
  397. SM(Kind::Compute, 6, 6, "cs_6_6", 0, 0, true, true, UINT_MAX),
  398. SM(Kind::Library, 6, 1, "lib_6_1", 32, 32, true, true, UINT_MAX),
  399. SM(Kind::Library, 6, 2, "lib_6_2", 32, 32, true, true, UINT_MAX),
  400. SM(Kind::Library, 6, 3, "lib_6_3", 32, 32, true, true, UINT_MAX),
  401. SM(Kind::Library, 6, 4, "lib_6_4", 32, 32, true, true, UINT_MAX),
  402. SM(Kind::Library, 6, 5, "lib_6_5", 32, 32, true, true, UINT_MAX),
  403. SM(Kind::Library, 6, 6, "lib_6_6", 32, 32, true, true, UINT_MAX),
  404. // lib_6_x is for offline linking only, and relaxes restrictions
  405. SM(Kind::Library, 6, kOfflineMinor, "lib_6_x", 32, 32, true, true, UINT_MAX),
  406. SM(Kind::Mesh, 6, 5, "ms_6_5", 0, 0, true, true, UINT_MAX),
  407. SM(Kind::Mesh, 6, 6, "ms_6_6", 0, 0, true, true, UINT_MAX),
  408. SM(Kind::Amplification, 6, 5, "as_6_5", 0, 0, true, true, UINT_MAX),
  409. SM(Kind::Amplification, 6, 6, "as_6_6", 0, 0, true, true, UINT_MAX),
  410. // Values before Invalid must remain sorted by Kind, then Major, then Minor.
  411. SM(Kind::Invalid, 0, 0, "invalid", 0, 0, false, false, 0),
  412. // VALRULE-TEXT:END
  413. };
  414. } // namespace hlsl