MatrixAlignmentTest.azsl 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. /*
  9. This shader is used to graphically validate data offsets correctness when
  10. floatRxC matrices are followed by float or float2 variables
  11. in structs/classes/SRGs.
  12. This shader was created in response to the problem that DXC, when
  13. generating Spirv code, was not generating the expected data offsets
  14. with the command line argument -fvk-use-dx-layout.
  15. */
  16. #include <Atom/Features/SrgSemantics.azsli>
  17. // Defined in the supervariant.
  18. #ifndef NUM_FLOATS_AFTER_MATRIX
  19. #define NUM_FLOATS_AFTER_MATRIX 1
  20. #endif
  21. #define GET_COLOR_TEMPLATE(TheMatrix, r, g, b) \
  22. int row = 0; \
  23. int col = 0 ; \
  24. bool isBottomRightCorner = false; \
  25. if (GetMatrixLocationFromPixel(pixelCoord, row, col, isBottomRightCorner)) \
  26. { \
  27. float componentColor = TheMatrix[row][col]; \
  28. return float4(componentColor, componentColor, componentColor, 1.0); \
  29. } \
  30. if (isBottomRightCorner) \
  31. { \
  32. return float4(r, g, b, 1.0); \
  33. } \
  34. return defaultColor;
  35. ShaderResourceGroup AlignmentValidatorSrg : SRG_PerDraw
  36. {
  37. // Viewport resolution (in pixels).
  38. // .x,.y are width and height respectively.
  39. // .z,.w do not matter
  40. float4 m_resolution;
  41. // Based on the value of these two variables We pick which matrix
  42. // to use to generate the color grid.
  43. // For example:
  44. // If m_numRows == 3 && m_numColumns == 2
  45. // We draw a 3x2 grid where each cell gets a shade of gray color
  46. // as m_matrix32[r][c].
  47. // Another example:
  48. // If m_numRows == 2 && m_numColumns == 4
  49. // We draw a 2x4 grid where each cell gets a shade of gray color
  50. // as m_matrix24[r][c].
  51. int m_numRows;
  52. int m_numColumns;
  53. float4 __reserved; // Keep this here for alignment.
  54. // All RxC
  55. // 1xC
  56. float1x1 m_matrix11;
  57. #if NUM_FLOATS_AFTER_MATRIX == 1
  58. float m_fAfter11;
  59. #else
  60. float2 m_fAfter11;
  61. #endif
  62. float4 __reserved11; // Used to force 16 byte boundary
  63. float1x2 m_matrix12;
  64. #if NUM_FLOATS_AFTER_MATRIX == 1
  65. float m_fAfter12;
  66. #else
  67. float2 m_fAfter12;
  68. #endif
  69. float4 __reserved12; // Used to force 16 byte boundary
  70. float1x3 m_matrix13;
  71. #if NUM_FLOATS_AFTER_MATRIX == 1
  72. float m_fAfter13;
  73. #else
  74. float2 m_fAfter13;
  75. #endif
  76. float4 __reserved13; // Used to force 16 byte boundary
  77. float1x4 m_matrix14;
  78. #if NUM_FLOATS_AFTER_MATRIX == 1
  79. float m_fAfter14;
  80. #else
  81. float2 m_fAfter14;
  82. #endif
  83. float4 __reserved14; // Used to force 16 byte boundary
  84. // 2xC
  85. // AZSLc: PackAsVectorMatrix: row_major packing for 2x1, 3x1 and 4x1 matrix types is not allowed!
  86. // float2x1 m_matrix21;
  87. // float m_fAfter21;
  88. // float4 __reserved21; // Used to force 16 byte boundary
  89. float2x2 m_matrix22;
  90. // This case is broken in vulkan. Add float3 padding or use AZSLc 1.7.26+ for automatic float3 padding.
  91. float3 __padding22;
  92. #if NUM_FLOATS_AFTER_MATRIX == 1
  93. float m_fAfter22;
  94. #else
  95. float2 m_fAfter22;
  96. #endif
  97. float4 __reserved22; // Used to force 16 byte boundary
  98. // This case is broken in vulkan. Add float2 padding or use AZSLc 1.7.26+ for automatic float2 padding.
  99. float2x3 m_matrix23;
  100. #if NUM_FLOATS_AFTER_MATRIX == 1
  101. float2 __padding23;
  102. float m_fAfter23;
  103. #else
  104. float2 m_fAfter23;
  105. #endif
  106. float4 __reserved23; // Used to force 16 byte boundary
  107. float2x4 m_matrix24;
  108. #if NUM_FLOATS_AFTER_MATRIX == 1
  109. float m_fAfter24;
  110. #else
  111. float2 m_fAfter24;
  112. #endif
  113. float4 __reserved24; // Used to force 16 byte boundary
  114. // 3xC
  115. //AZSLc: PackAsVectorMatrix: row_major packing for 2x1, 3x1 and 4x1 matrix types is not allowed!
  116. //float3x1 m_matrix31;
  117. //float m_fAfter31;
  118. //float4 __reserved31; // Used to force 16 byte boundary
  119. float3x2 m_matrix32;
  120. // This case is broken in vulkan. Add float3 padding or use AZSLc 1.7.26+ for automatic float3 padding.
  121. float3 __padding32;
  122. #if NUM_FLOATS_AFTER_MATRIX == 1
  123. float m_fAfter32;
  124. #else
  125. float2 m_fAfter32;
  126. #endif
  127. float4 __reserved32; // Used to force 16 byte boundary
  128. float3x3 m_matrix33;
  129. #if NUM_FLOATS_AFTER_MATRIX == 1
  130. // This case is broken in vulkan. Add float2 padding or use AZSLc 1.7.26+ for automatic float2 padding.
  131. float2 __padding33;
  132. float m_fAfter33;
  133. #else
  134. float2 m_fAfter33;
  135. #endif
  136. float4 __reserved33; // Used to force 16 byte boundary
  137. float3x4 m_matrix34;
  138. #if NUM_FLOATS_AFTER_MATRIX == 1
  139. float m_fAfter34;
  140. #else
  141. float2 m_fAfter34;
  142. #endif
  143. float4 __reserved34; // Used to force 16 byte boundary
  144. // 4xC
  145. //AZSLc: PackAsVectorMatrix: row_major packing for 2x1, 3x1 and 4x1 matrix types is not allowed!
  146. //float4x1 m_matrix41;
  147. //float m_fAfter41;
  148. //float4 __reserved41; // Used to force 16 byte boundary
  149. float4x2 m_matrix42;
  150. // This case is broken in vulkan. Add float3 padding or use AZSLc 1.7.26+ for automatic float3 padding.
  151. float3 __padding42;
  152. #if NUM_FLOATS_AFTER_MATRIX == 1
  153. float m_fAfter42;
  154. #else
  155. float2 m_fAfter42;
  156. #endif
  157. float4 __reserved42; // Used to force 16 byte boundary
  158. // This case is broken in vulkan. Add float2 padding or use AZSLc 1.7.26+ for automatic float2 padding.
  159. float4x3 m_matrix43;
  160. #if NUM_FLOATS_AFTER_MATRIX == 1
  161. float2 __padding43;
  162. float m_fAfter43;
  163. #else
  164. float2 m_fAfter43;
  165. #endif
  166. float4 __reserved43; // Used to force 16 byte boundary
  167. float4x4 m_matrix44;
  168. #if NUM_FLOATS_AFTER_MATRIX == 1
  169. float m_fAfter44;
  170. #else
  171. float2 m_fAfter44;
  172. #endif
  173. float4 __reserved44; // Used to force 16 byte boundary
  174. // Returns true if the normalized pixel coordinate @pixelCoord falls inside a @row, @col cell whose coordinate is safe to use to fetch data from one of the @m_matrix<row><col> variables.
  175. // Otherwise returns false.
  176. // In addition when returning false, @isBottomRightCorner becomes true if the bottom right corner is being rendered.
  177. // In such case the respective float or float2 variable @m_fAfter should be used to pick the color of the
  178. // bottom right corner.
  179. bool GetMatrixLocationFromPixel(float2 pixelCoord, out int row, out int col, out bool isBottomRightCorner)
  180. {
  181. const int clampedRowSelection = clamp(m_numRows, 1, 4);
  182. const int clampedColSelection = clamp(m_numColumns, 1, 4);
  183. const float NumRows = clampedRowSelection + 1;
  184. const float NumColumns = clampedColSelection + 1;
  185. row = floor(NumRows * pixelCoord.y);
  186. col = floor(NumColumns * pixelCoord.x);
  187. isBottomRightCorner = false;
  188. if ((row < clampedRowSelection) && (col < clampedColSelection))
  189. {
  190. return true;
  191. }
  192. if ((row >= clampedRowSelection) && (col >= clampedColSelection))
  193. {
  194. isBottomRightCorner = true;
  195. }
  196. return false;
  197. }
  198. float4 GetColor11(float2 pixelCoord, float4 defaultColor)
  199. {
  200. #if NUM_FLOATS_AFTER_MATRIX == 1
  201. GET_COLOR_TEMPLATE(m_matrix11, m_fAfter11, m_fAfter11, m_fAfter11);
  202. #else
  203. GET_COLOR_TEMPLATE(m_matrix11, m_fAfter11.x, m_fAfter11.y, 0);
  204. #endif
  205. }
  206. float4 GetColor12(float2 pixelCoord, float4 defaultColor)
  207. {
  208. #if NUM_FLOATS_AFTER_MATRIX == 1
  209. GET_COLOR_TEMPLATE(m_matrix12, m_fAfter12, m_fAfter12, m_fAfter12);
  210. #else
  211. GET_COLOR_TEMPLATE(m_matrix12, m_fAfter12.x, m_fAfter12.y, 0);
  212. #endif
  213. }
  214. float4 GetColor13(float2 pixelCoord, float4 defaultColor)
  215. {
  216. #if NUM_FLOATS_AFTER_MATRIX == 1
  217. GET_COLOR_TEMPLATE(m_matrix13, m_fAfter13, m_fAfter13, m_fAfter13);
  218. #else
  219. GET_COLOR_TEMPLATE(m_matrix13, m_fAfter13.x, m_fAfter13.y, 0);
  220. #endif
  221. }
  222. float4 GetColor14(float2 pixelCoord, float4 defaultColor)
  223. {
  224. #if NUM_FLOATS_AFTER_MATRIX == 1
  225. GET_COLOR_TEMPLATE(m_matrix14, m_fAfter14, m_fAfter14, m_fAfter14);
  226. #else
  227. GET_COLOR_TEMPLATE(m_matrix14, m_fAfter14.x, m_fAfter14.y, 0);
  228. #endif
  229. }
  230. // Case not supported
  231. //float4 GetColor21(float2 pixelCoord, float4 defaultColor)
  232. //{
  233. // GET_COLOR_TEMPLATE(m_matrix21, m_fAfter21);
  234. //}
  235. float4 GetColor22(float2 pixelCoord, float4 defaultColor)
  236. {
  237. #if NUM_FLOATS_AFTER_MATRIX == 1
  238. GET_COLOR_TEMPLATE(m_matrix22, m_fAfter22, m_fAfter22, m_fAfter22);
  239. #else
  240. GET_COLOR_TEMPLATE(m_matrix22, m_fAfter22.x, m_fAfter22.y, 0);
  241. #endif
  242. }
  243. float4 GetColor23(float2 pixelCoord, float4 defaultColor)
  244. {
  245. #if NUM_FLOATS_AFTER_MATRIX == 1
  246. GET_COLOR_TEMPLATE(m_matrix23, m_fAfter23, m_fAfter23, m_fAfter23);
  247. #else
  248. GET_COLOR_TEMPLATE(m_matrix23, m_fAfter23.x, m_fAfter23.y, 0);
  249. #endif
  250. }
  251. float4 GetColor24(float2 pixelCoord, float4 defaultColor)
  252. {
  253. #if NUM_FLOATS_AFTER_MATRIX == 1
  254. GET_COLOR_TEMPLATE(m_matrix24, m_fAfter24, m_fAfter24, m_fAfter24);
  255. #else
  256. GET_COLOR_TEMPLATE(m_matrix24, m_fAfter24.x, m_fAfter24.y, 0);
  257. #endif
  258. }
  259. // Case not supported
  260. //float4 GetColor31(float2 pixelCoord, float4 defaultColor)
  261. //{
  262. // GET_COLOR_TEMPLATE(m_matrix31, m_fAfter31);
  263. //}
  264. float4 GetColor32(float2 pixelCoord, float4 defaultColor)
  265. {
  266. #if NUM_FLOATS_AFTER_MATRIX == 1
  267. GET_COLOR_TEMPLATE(m_matrix32, m_fAfter32, m_fAfter32, m_fAfter32);
  268. #else
  269. GET_COLOR_TEMPLATE(m_matrix32, m_fAfter32.x, m_fAfter32.y, 0);
  270. #endif
  271. }
  272. float4 GetColor33(float2 pixelCoord, float4 defaultColor)
  273. {
  274. #if NUM_FLOATS_AFTER_MATRIX == 1
  275. GET_COLOR_TEMPLATE(m_matrix33, m_fAfter33, m_fAfter33, m_fAfter33);
  276. #else
  277. GET_COLOR_TEMPLATE(m_matrix33, m_fAfter33.x, m_fAfter33.y, 0);
  278. #endif
  279. }
  280. float4 GetColor34(float2 pixelCoord, float4 defaultColor)
  281. {
  282. #if NUM_FLOATS_AFTER_MATRIX == 1
  283. GET_COLOR_TEMPLATE(m_matrix34, m_fAfter34, m_fAfter34, m_fAfter34);
  284. #else
  285. GET_COLOR_TEMPLATE(m_matrix34, m_fAfter34.x, m_fAfter34.y, 0);
  286. #endif
  287. }
  288. // Case not supported
  289. //float4 GetColor41(float2 pixelCoord, float4 defaultColor)
  290. //{
  291. // GET_COLOR_TEMPLATE(m_matrix41, m_fAfter41);
  292. //}
  293. float4 GetColor42(float2 pixelCoord, float4 defaultColor)
  294. {
  295. #if NUM_FLOATS_AFTER_MATRIX == 1
  296. GET_COLOR_TEMPLATE(m_matrix42, m_fAfter42, m_fAfter42, m_fAfter42);
  297. #else
  298. GET_COLOR_TEMPLATE(m_matrix42, m_fAfter42.x, m_fAfter42.y, 0);
  299. #endif
  300. }
  301. float4 GetColor43(float2 pixelCoord, float4 defaultColor)
  302. {
  303. #if NUM_FLOATS_AFTER_MATRIX == 1
  304. GET_COLOR_TEMPLATE(m_matrix43, m_fAfter43, m_fAfter43, m_fAfter43);
  305. #else
  306. GET_COLOR_TEMPLATE(m_matrix43, m_fAfter43.x, m_fAfter43.y, 0);
  307. #endif
  308. }
  309. float4 GetColor44(float2 pixelCoord, float4 defaultColor)
  310. {
  311. #if NUM_FLOATS_AFTER_MATRIX == 1
  312. GET_COLOR_TEMPLATE(m_matrix44, m_fAfter44, m_fAfter44, m_fAfter44);
  313. #else
  314. GET_COLOR_TEMPLATE(m_matrix44, m_fAfter44.x, m_fAfter44.y, 0);
  315. #endif
  316. }
  317. }
  318. struct VSInput
  319. {
  320. float3 m_position : POSITION;
  321. float4 m_color : COLOR0;
  322. };
  323. struct VSOutput
  324. {
  325. float4 m_position : SV_Position;
  326. float4 m_color : COLOR0;
  327. };
  328. VSOutput MainVS(VSInput vsInput)
  329. {
  330. VSOutput OUT;
  331. OUT.m_position = float4(vsInput.m_position, 1.0);
  332. OUT.m_color = vsInput.m_color;
  333. return OUT;
  334. }
  335. struct PSOutput
  336. {
  337. float4 m_color : SV_Target0;
  338. };
  339. PSOutput MainPS(VSOutput vsOutput)
  340. {
  341. PSOutput OUT;
  342. // Normalized pixel coordinates (from 0 to 1)
  343. float2 pixelCoord = vsOutput.m_position.xy / AlignmentValidatorSrg::m_resolution.xy;
  344. // The screen will be split in a grid where:
  345. // Number of rows is: m_numRows + 1;
  346. // Number of columns is: m_numColumns + 1;
  347. // The 0-indexed cells where Row < m_numRows & Col < m_numColumns
  348. // will take the color of float4(m_matrix<m_numRows><m_numRows>[row][col], ...)
  349. // The last cell will take the color (m_fAfter<m_numRows+1><m_numRows+1>, ...)
  350. float4 color = vsOutput.m_color.rgba;
  351. switch(AlignmentValidatorSrg::m_numRows)
  352. {
  353. case 1:
  354. switch(AlignmentValidatorSrg::m_numColumns)
  355. {
  356. case 1:
  357. color = AlignmentValidatorSrg::GetColor11(pixelCoord, color);
  358. break;
  359. case 2:
  360. color = AlignmentValidatorSrg::GetColor12(pixelCoord, color);
  361. break;
  362. case 3:
  363. color = AlignmentValidatorSrg::GetColor13(pixelCoord, color);
  364. break;
  365. case 4:
  366. color = AlignmentValidatorSrg::GetColor14(pixelCoord, color);
  367. break;
  368. default:
  369. break;
  370. }
  371. break;
  372. case 2:
  373. switch(AlignmentValidatorSrg::m_numColumns)
  374. {
  375. case 1:
  376. // color = AlignmentValidatorSrg::GetColor21(pixelCoord, color); // Not Supported
  377. break;
  378. case 2:
  379. color = AlignmentValidatorSrg::GetColor22(pixelCoord, color);
  380. break;
  381. case 3:
  382. color = AlignmentValidatorSrg::GetColor23(pixelCoord, color);
  383. break;
  384. case 4:
  385. color = AlignmentValidatorSrg::GetColor24(pixelCoord, color);
  386. break;
  387. default:
  388. break;
  389. }
  390. break;
  391. case 3:
  392. switch(AlignmentValidatorSrg::m_numColumns)
  393. {
  394. case 1:
  395. // color = AlignmentValidatorSrg::GetColor31(pixelCoord, color); // Not Supported
  396. break;
  397. case 2:
  398. color = AlignmentValidatorSrg::GetColor32(pixelCoord, color);
  399. break;
  400. case 3:
  401. color = AlignmentValidatorSrg::GetColor33(pixelCoord, color);
  402. break;
  403. case 4:
  404. color = AlignmentValidatorSrg::GetColor34(pixelCoord, color);
  405. break;
  406. default:
  407. break;
  408. }
  409. break;
  410. case 4:
  411. switch(AlignmentValidatorSrg::m_numColumns)
  412. {
  413. case 1:
  414. // color = AlignmentValidatorSrg::GetColor41(pixelCoord, color); // Not Supported
  415. break;
  416. case 2:
  417. color = AlignmentValidatorSrg::GetColor42(pixelCoord, color);
  418. break;
  419. case 3:
  420. color = AlignmentValidatorSrg::GetColor43(pixelCoord, color);
  421. break;
  422. case 4:
  423. color = AlignmentValidatorSrg::GetColor44(pixelCoord, color);
  424. break;
  425. default:
  426. break;
  427. }
  428. break;
  429. default:
  430. break;
  431. }
  432. OUT.m_color = color;
  433. return OUT;
  434. }