struct_packing_test.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. // Copyright (c) 2024 Epic Games, Inc.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include <string>
  15. #include "gmock/gmock.h"
  16. #include "source/opt/struct_packing_pass.h"
  17. #include "test/opt/pass_fixture.h"
  18. #include "test/opt/pass_utils.h"
  19. namespace spvtools {
  20. namespace opt {
  21. namespace {
  22. using StructPackingTest = PassTest<::testing::Test>;
  23. TEST_F(StructPackingTest, PackSimpleStructStd140) {
  24. // #version 420
  25. //
  26. // layout(std140, binding = 0) uniform Globals {
  27. // layout(offset = 16) vec3 a_xyz;
  28. // float a_w;
  29. // layout(offset = 128) vec3 b_xyz;
  30. // int b_w;
  31. // };
  32. //
  33. // void main() {}
  34. const std::string spirv = R"(
  35. OpCapability Shader
  36. %1 = OpExtInstImport "GLSL.std.450"
  37. OpMemoryModel Logical GLSL450
  38. OpEntryPoint Fragment %main "main"
  39. OpExecutionMode %main OriginLowerLeft
  40. OpSource GLSL 420
  41. OpName %main "main"
  42. OpName %Globals "Globals"
  43. OpMemberName %Globals 0 "a_xyz"
  44. OpMemberName %Globals 1 "a_w"
  45. OpMemberName %Globals 2 "b_xyz"
  46. OpMemberName %Globals 3 "b_w"
  47. OpName %_ ""
  48. ; CHECK: OpMemberDecorate %Globals 0 Offset 0
  49. OpMemberDecorate %Globals 0 Offset 16
  50. ; CHECK: OpMemberDecorate %Globals 1 Offset 12
  51. OpMemberDecorate %Globals 1 Offset 28
  52. ; CHECK: OpMemberDecorate %Globals 2 Offset 16
  53. OpMemberDecorate %Globals 2 Offset 128
  54. ; CHECK: OpMemberDecorate %Globals 3 Offset 28
  55. OpMemberDecorate %Globals 3 Offset 140
  56. OpDecorate %Globals Block
  57. OpDecorate %_ DescriptorSet 0
  58. OpDecorate %_ Binding 0
  59. %void = OpTypeVoid
  60. %3 = OpTypeFunction %void
  61. %float = OpTypeFloat 32
  62. %v3float = OpTypeVector %float 3
  63. %int = OpTypeInt 32 1
  64. %Globals = OpTypeStruct %v3float %float %v3float %int
  65. %_ptr_Uniform_Globals = OpTypePointer Uniform %Globals
  66. %_ = OpVariable %_ptr_Uniform_Globals Uniform
  67. %main = OpFunction %void None %3
  68. %5 = OpLabel
  69. OpReturn
  70. OpFunctionEnd
  71. )";
  72. SinglePassRunAndMatch<StructPackingPass>(
  73. spirv, true, "Globals", StructPackingPass::PackingRules::Std140);
  74. }
  75. TEST_F(StructPackingTest, PackSimpleStructWithPaddingStd140) {
  76. // #version 420
  77. //
  78. // layout(std140, binding = 0) uniform Globals {
  79. // layout(offset = 16) vec3 a_xyz;
  80. // float a_w;
  81. // float b_x_padding_yzw;
  82. // layout(offset = 128) vec3 c_xyz;
  83. // int c_w;
  84. // };
  85. //
  86. // void main() {}
  87. const std::string spirv = R"(
  88. OpCapability Shader
  89. %1 = OpExtInstImport "GLSL.std.450"
  90. OpMemoryModel Logical GLSL450
  91. OpEntryPoint Fragment %main "main"
  92. OpExecutionMode %main OriginLowerLeft
  93. OpSource GLSL 420
  94. OpName %main "main"
  95. OpName %Globals "Globals"
  96. OpMemberName %Globals 0 "a_xyz"
  97. OpMemberName %Globals 1 "a_w"
  98. OpMemberName %Globals 2 "b_x_padding_yzw"
  99. OpMemberName %Globals 3 "c_xyz"
  100. OpMemberName %Globals 4 "c_w"
  101. OpName %_ ""
  102. ; CHECK: OpMemberDecorate %Globals 0 Offset 0
  103. OpMemberDecorate %Globals 0 Offset 16
  104. ; CHECK: OpMemberDecorate %Globals 1 Offset 12
  105. OpMemberDecorate %Globals 1 Offset 28
  106. ; CHECK: OpMemberDecorate %Globals 2 Offset 16
  107. OpMemberDecorate %Globals 2 Offset 32
  108. ; CHECK: OpMemberDecorate %Globals 3 Offset 32
  109. OpMemberDecorate %Globals 3 Offset 128
  110. ; CHECK: OpMemberDecorate %Globals 4 Offset 44
  111. OpMemberDecorate %Globals 4 Offset 140
  112. OpDecorate %Globals Block
  113. OpDecorate %_ DescriptorSet 0
  114. OpDecorate %_ Binding 0
  115. %void = OpTypeVoid
  116. %3 = OpTypeFunction %void
  117. %float = OpTypeFloat 32
  118. %v3float = OpTypeVector %float 3
  119. %int = OpTypeInt 32 1
  120. %Globals = OpTypeStruct %v3float %float %float %v3float %int
  121. %_ptr_Uniform_Globals = OpTypePointer Uniform %Globals
  122. %_ = OpVariable %_ptr_Uniform_Globals Uniform
  123. %main = OpFunction %void None %3
  124. %5 = OpLabel
  125. OpReturn
  126. OpFunctionEnd
  127. )";
  128. SinglePassRunAndMatch<StructPackingPass>(
  129. spirv, true, "Globals", StructPackingPass::PackingRules::Std140);
  130. }
  131. TEST_F(StructPackingTest, PackSimpleScalarArrayStd140) {
  132. // #version 420
  133. //
  134. // layout(std140, binding = 0) uniform Globals {
  135. // layout(offset = 16) float a[2];
  136. // layout(offset = 128) float b[2]; // Must become offset 32 with std140
  137. // };
  138. //
  139. // void main() {}
  140. const std::string spirv = R"(
  141. OpCapability Shader
  142. %1 = OpExtInstImport "GLSL.std.450"
  143. OpMemoryModel Logical GLSL450
  144. OpEntryPoint Fragment %main "main"
  145. OpExecutionMode %main OriginLowerLeft
  146. OpSource GLSL 420
  147. OpName %main "main"
  148. OpName %Globals "Globals"
  149. OpMemberName %Globals 0 "a"
  150. OpMemberName %Globals 1 "b"
  151. OpName %_ ""
  152. OpDecorate %_arr_float_uint_2 ArrayStride 16
  153. OpDecorate %_arr_float_uint_2_0 ArrayStride 16
  154. ; CHECK: OpMemberDecorate %Globals 0 Offset 0
  155. OpMemberDecorate %Globals 0 Offset 16
  156. ; CHECK: OpMemberDecorate %Globals 1 Offset 32
  157. OpMemberDecorate %Globals 1 Offset 128
  158. OpDecorate %Globals Block
  159. OpDecorate %_ DescriptorSet 0
  160. OpDecorate %_ Binding 0
  161. %void = OpTypeVoid
  162. %3 = OpTypeFunction %void
  163. %float = OpTypeFloat 32
  164. %uint = OpTypeInt 32 0
  165. %uint_2 = OpConstant %uint 2
  166. %_arr_float_uint_2 = OpTypeArray %float %uint_2
  167. %_arr_float_uint_2_0 = OpTypeArray %float %uint_2
  168. %Globals = OpTypeStruct %_arr_float_uint_2 %_arr_float_uint_2_0
  169. %_ptr_Uniform_Globals = OpTypePointer Uniform %Globals
  170. %_ = OpVariable %_ptr_Uniform_Globals Uniform
  171. %main = OpFunction %void None %3
  172. %5 = OpLabel
  173. OpReturn
  174. OpFunctionEnd
  175. )";
  176. SinglePassRunAndMatch<StructPackingPass>(
  177. spirv, true, "Globals", StructPackingPass::PackingRules::Std140);
  178. }
  179. TEST_F(StructPackingTest, PackSimpleScalarArrayStd430) {
  180. // #version 430
  181. //
  182. // layout(std430, binding = 0) buffer Globals {
  183. // layout(offset = 16) float a[2];
  184. // layout(offset = 128) float b[2]; // Must become offset 8 with std430
  185. // };
  186. //
  187. // void main() {}
  188. const std::string spirv = R"(
  189. OpCapability Shader
  190. %1 = OpExtInstImport "GLSL.std.450"
  191. OpMemoryModel Logical GLSL450
  192. OpEntryPoint Fragment %main "main"
  193. OpExecutionMode %main OriginLowerLeft
  194. OpSource GLSL 430
  195. OpName %main "main"
  196. OpName %Globals "Globals"
  197. OpMemberName %Globals 0 "a"
  198. OpMemberName %Globals 1 "b"
  199. OpName %_ ""
  200. OpDecorate %_arr_float_uint_2 ArrayStride 4
  201. OpDecorate %_arr_float_uint_2_0 ArrayStride 4
  202. ; CHECK: OpMemberDecorate %Globals 0 Offset 0
  203. OpMemberDecorate %Globals 0 Offset 16
  204. ; CHECK: OpMemberDecorate %Globals 1 Offset 8
  205. OpMemberDecorate %Globals 1 Offset 128
  206. OpDecorate %Globals BufferBlock
  207. OpDecorate %_ DescriptorSet 0
  208. OpDecorate %_ Binding 0
  209. %void = OpTypeVoid
  210. %3 = OpTypeFunction %void
  211. %float = OpTypeFloat 32
  212. %uint = OpTypeInt 32 0
  213. %uint_2 = OpConstant %uint 2
  214. %_arr_float_uint_2 = OpTypeArray %float %uint_2
  215. %_arr_float_uint_2_0 = OpTypeArray %float %uint_2
  216. %Globals = OpTypeStruct %_arr_float_uint_2 %_arr_float_uint_2_0
  217. %_ptr_Uniform_Globals = OpTypePointer Uniform %Globals
  218. %_ = OpVariable %_ptr_Uniform_Globals Uniform
  219. %main = OpFunction %void None %3
  220. %5 = OpLabel
  221. OpReturn
  222. OpFunctionEnd
  223. )";
  224. SinglePassRunAndMatch<StructPackingPass>(
  225. spirv, true, "Globals", StructPackingPass::PackingRules::Std430);
  226. }
  227. } // namespace
  228. } // namespace opt
  229. } // namespace spvtools