inst_debug_printf_test.cpp 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. // Copyright (c) 2020-2022 Valve Corporation
  2. // Copyright (c) 2020-2022 LunarG Inc.
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. // Debug Printf Instrumentation Tests.
  16. #include <string>
  17. #include <vector>
  18. #include "test/opt/assembly_builder.h"
  19. #include "test/opt/pass_fixture.h"
  20. #include "test/opt/pass_utils.h"
  21. namespace spvtools {
  22. namespace opt {
  23. namespace {
  24. static const std::string kOutputDecorations = R"(
  25. ; CHECK: OpDecorate [[output_buffer_type:%inst_printf_OutputBuffer]] Block
  26. ; CHECK: OpMemberDecorate [[output_buffer_type]] 0 Offset 0
  27. ; CHECK: OpMemberDecorate [[output_buffer_type]] 1 Offset 4
  28. ; CHECK: OpMemberDecorate [[output_buffer_type]] 2 Offset 8
  29. ; CHECK: OpDecorate [[output_buffer_var:%\w+]] DescriptorSet 7
  30. ; CHECK: OpDecorate [[output_buffer_var]] Binding 3
  31. )";
  32. static const std::string kOutputGlobals = R"(
  33. ; CHECK: [[output_buffer_type]] = OpTypeStruct %uint %uint %_runtimearr_uint
  34. ; CHECK: [[output_ptr_type:%\w+]] = OpTypePointer StorageBuffer [[output_buffer_type]]
  35. ; CHECK: [[output_buffer_var]] = OpVariable [[output_ptr_type]] StorageBuffer
  36. )";
  37. using InstDebugPrintfTest = PassTest<::testing::Test>;
  38. TEST_F(InstDebugPrintfTest, V4Float32) {
  39. // SamplerState g_sDefault;
  40. // Texture2D g_tColor;
  41. //
  42. // struct PS_INPUT
  43. // {
  44. // float2 vBaseTexCoord : TEXCOORD0;
  45. // };
  46. //
  47. // struct PS_OUTPUT
  48. // {
  49. // float4 vDiffuse : SV_Target0;
  50. // };
  51. //
  52. // PS_OUTPUT MainPs(PS_INPUT i)
  53. // {
  54. // PS_OUTPUT o;
  55. //
  56. // o.vDiffuse.rgba = g_tColor.Sample(g_sDefault, (i.vBaseTexCoord.xy).xy);
  57. // debugPrintfEXT("diffuse: %v4f", o.vDiffuse.rgba);
  58. // return o;
  59. // }
  60. const std::string defs =
  61. R"(OpCapability Shader
  62. OpExtension "SPV_KHR_non_semantic_info"
  63. %1 = OpExtInstImport "NonSemantic.DebugPrintf"
  64. ; CHECK-NOT: OpExtension "SPV_KHR_non_semantic_info"
  65. ; CHECK-NOT: %1 = OpExtInstImport "NonSemantic.DebugPrintf"
  66. ; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
  67. OpMemoryModel Logical GLSL450
  68. OpEntryPoint Fragment %2 "MainPs" %3 %4
  69. ; CHECK: OpEntryPoint Fragment %2 "MainPs" %3 %4 %gl_FragCoord
  70. OpExecutionMode %2 OriginUpperLeft
  71. %5 = OpString "Color is %vn"
  72. )";
  73. // clang-format off
  74. const std::string decorates =
  75. R"(OpDecorate %6 DescriptorSet 0
  76. OpDecorate %6 Binding 1
  77. OpDecorate %7 DescriptorSet 0
  78. OpDecorate %7 Binding 0
  79. OpDecorate %3 Location 0
  80. OpDecorate %4 Location 0
  81. ; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
  82. )" + kOutputDecorations + R"(
  83. ; CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
  84. )";
  85. const std::string globals =
  86. R"(%void = OpTypeVoid
  87. %9 = OpTypeFunction %void
  88. %float = OpTypeFloat 32
  89. %v2float = OpTypeVector %float 2
  90. %v4float = OpTypeVector %float 4
  91. %13 = OpTypeImage %float 2D 0 0 0 1 Unknown
  92. %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
  93. %6 = OpVariable %_ptr_UniformConstant_13 UniformConstant
  94. %15 = OpTypeSampler
  95. %_ptr_UniformConstant_15 = OpTypePointer UniformConstant %15
  96. %7 = OpVariable %_ptr_UniformConstant_15 UniformConstant
  97. %17 = OpTypeSampledImage %13
  98. %_ptr_Input_v2float = OpTypePointer Input %v2float
  99. %3 = OpVariable %_ptr_Input_v2float Input
  100. %_ptr_Output_v4float = OpTypePointer Output %v4float
  101. %4 = OpVariable %_ptr_Output_v4float Output
  102. ; CHECK: %uint = OpTypeInt 32 0
  103. ; CHECK: [[func_type:%\w+]] = OpTypeFunction %void %uint %uint %uint %uint %uint %uint
  104. ; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint
  105. )" + kOutputGlobals + R"(
  106. ; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
  107. ; CHECK: %bool = OpTypeBool
  108. ; CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
  109. ; CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
  110. ; CHECK: %v4uint = OpTypeVector %uint 4
  111. )";
  112. // clang-format on
  113. const std::string main =
  114. R"(%2 = OpFunction %void None %9
  115. %20 = OpLabel
  116. %21 = OpLoad %v2float %3
  117. %22 = OpLoad %13 %6
  118. %23 = OpLoad %15 %7
  119. %24 = OpSampledImage %17 %22 %23
  120. %25 = OpImageSampleImplicitLod %v4float %24 %21
  121. %26 = OpExtInst %void %1 1 %5 %25
  122. ; CHECK-NOT: %26 = OpExtInst %void %1 1 %5 %25
  123. ; CHECK: %29 = OpCompositeExtract %float %25 0
  124. ; CHECK: %30 = OpBitcast %uint %29
  125. ; CHECK: %31 = OpCompositeExtract %float %25 1
  126. ; CHECK: %32 = OpBitcast %uint %31
  127. ; CHECK: %33 = OpCompositeExtract %float %25 2
  128. ; CHECK: %34 = OpBitcast %uint %33
  129. ; CHECK: %35 = OpCompositeExtract %float %25 3
  130. ; CHECK: %36 = OpBitcast %uint %35
  131. ; CHECK: %101 = OpFunctionCall %void %inst_printf_stream_write_6 %uint_36 %uint_5 %30 %32 %34 %36
  132. ; CHECK: OpBranch %102
  133. ; CHECK: %102 = OpLabel
  134. OpStore %4 %25
  135. OpReturn
  136. OpFunctionEnd
  137. )";
  138. const std::string output_func = R"(
  139. ; CHECK: %inst_printf_stream_write_6 = OpFunction %void None [[func_type]]
  140. ; CHECK: [[param_1:%\w+]] = OpFunctionParameter %uint
  141. ; CHECK: [[param_2:%\w+]] = OpFunctionParameter %uint
  142. ; CHECK: [[param_3:%\w+]] = OpFunctionParameter %uint
  143. ; CHECK: [[param_4:%\w+]] = OpFunctionParameter %uint
  144. ; CHECK: [[param_5:%\w+]] = OpFunctionParameter %uint
  145. ; CHECK: [[param_6:%\w+]] = OpFunctionParameter %uint
  146. ; CHECK: {{%\w+}} = OpLabel
  147. ; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint %inst_printf_output_buffer %uint_1
  148. ; CHECK: {{%\w+}} = OpAtomicIAdd %uint {{%\w+}} %uint_4 %uint_0 %uint_12
  149. ; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_12
  150. ; CHECK: {{%\w+}} = OpArrayLength %uint %inst_printf_output_buffer 2
  151. ; CHECK: {{%\w+}} = OpULessThanEqual %bool {{%\w+}} {{%\w+}}
  152. ; CHECK: OpSelectionMerge {{%\w+}} None
  153. ; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
  154. ; CHECK: {{%\w+}} = OpLabel
  155. ; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_0
  156. ; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint %inst_printf_output_buffer %uint_2 {{%\w+}}
  157. ; CHECK: OpStore {{%\w+}} %uint_12
  158. ; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_1
  159. ; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint %inst_printf_output_buffer %uint_2 {{%\w+}}
  160. ; CHECK: OpStore {{%\w+}} %uint_23
  161. ; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_2
  162. ; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint %inst_printf_output_buffer %uint_2 {{%\w+}}
  163. ; CHECK: OpStore {{%\w+}} [[param_1]]
  164. ; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_3
  165. ; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint %inst_printf_output_buffer %uint_2 {{%\w+}}
  166. ; CHECK: OpStore {{%\w+}} %uint_4
  167. ; CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord
  168. ; CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}}
  169. ; CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
  170. ; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_4
  171. ; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint %inst_printf_output_buffer %uint_2 {{%\w+}}
  172. ; CHECK: OpStore {{%\w+}} {{%\w+}}
  173. ; CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
  174. ; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_5
  175. ; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint %inst_printf_output_buffer %uint_2 {{%\w+}}
  176. ; CHECK: OpStore {{%\w+}} {{%\w+}}
  177. ; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_7
  178. ; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint %inst_printf_output_buffer %uint_2 {{%\w+}}
  179. ; CHECK: OpStore {{%\w+}} [[param_2]]
  180. ; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_8
  181. ; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint %inst_printf_output_buffer %uint_2 {{%\w+}}
  182. ; CHECK: OpStore {{%\w+}} [[param_3]]
  183. ; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_9
  184. ; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint %inst_printf_output_buffer %uint_2 {{%\w+}}
  185. ; CHECK: OpStore {{%\w+}} [[param_4]]
  186. ; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_10
  187. ; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint %inst_printf_output_buffer %uint_2 {{%\w+}}
  188. ; CHECK: OpStore {{%\w+}} [[param_5]]
  189. ; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_11
  190. ; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint %inst_printf_output_buffer %uint_2 {{%\w+}}
  191. ; CHECK: OpStore {{%\w+}} [[param_6]]
  192. ; CHECK: OpBranch {{%\w+}}
  193. ; CHECK: {{%\w+}} = OpLabel
  194. ; CHECK: OpReturn
  195. ; CHECK: OpFunctionEnd
  196. )";
  197. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  198. SinglePassRunAndMatch<InstDebugPrintfPass>(
  199. defs + decorates + globals + main + output_func, true);
  200. }
  201. // TODO(greg-lunarg): Add tests to verify handling of these cases:
  202. //
  203. // Compute shader
  204. // Geometry shader
  205. // Tessellation control shader
  206. // Tessellation eval shader
  207. // Vertex shader
  208. } // namespace
  209. } // namespace opt
  210. } // namespace spvtools