2
0

strip_nonsemantic_info_test.cpp 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. // Copyright (c) 2018 Google LLC
  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 "spirv-tools/optimizer.hpp"
  17. #include "test/opt/pass_fixture.h"
  18. #include "test/opt/pass_utils.h"
  19. namespace spvtools {
  20. namespace opt {
  21. namespace {
  22. using StripNonSemanticInfoTest = PassTest<::testing::Test>;
  23. // This test acts as an end-to-end code example on how to strip
  24. // reflection info from a SPIR-V module. Use this code pattern
  25. // when you have compiled HLSL code with Glslang or DXC using
  26. // option -fhlsl_functionality1 to insert reflection information,
  27. // but then want to filter out the extra instructions before sending
  28. // it to a driver that does not implement VK_GOOGLE_hlsl_functionality1.
  29. TEST_F(StripNonSemanticInfoTest, StripReflectEnd2EndExample) {
  30. // This is a non-sensical example, but exercises the instructions.
  31. std::string before = R"(OpCapability Shader
  32. OpCapability Linkage
  33. OpExtension "SPV_GOOGLE_decorate_string"
  34. OpExtension "SPV_GOOGLE_hlsl_functionality1"
  35. OpMemoryModel Logical Simple
  36. OpDecorateStringGOOGLE %float HlslSemanticGOOGLE "foobar"
  37. OpDecorateStringGOOGLE %void HlslSemanticGOOGLE "my goodness"
  38. %void = OpTypeVoid
  39. %float = OpTypeFloat 32
  40. )";
  41. SpirvTools tools(SPV_ENV_UNIVERSAL_1_1);
  42. std::vector<uint32_t> binary_in;
  43. tools.Assemble(before, &binary_in);
  44. // Instantiate the optimizer, and run the strip-nonsemantic-info
  45. // pass over the |binary_in| module, and place the modified module
  46. // into |binary_out|.
  47. spvtools::Optimizer optimizer(SPV_ENV_UNIVERSAL_1_1);
  48. optimizer.RegisterPass(spvtools::CreateStripNonSemanticInfoPass());
  49. std::vector<uint32_t> binary_out;
  50. optimizer.Run(binary_in.data(), binary_in.size(), &binary_out);
  51. // Check results
  52. std::string disassembly;
  53. tools.Disassemble(binary_out.data(), binary_out.size(), &disassembly);
  54. std::string after = R"(OpCapability Shader
  55. OpCapability Linkage
  56. OpMemoryModel Logical Simple
  57. %void = OpTypeVoid
  58. %float = OpTypeFloat 32
  59. )";
  60. EXPECT_THAT(disassembly, testing::Eq(after));
  61. }
  62. // This test is functionally the same as the end-to-end test above,
  63. // but uses the test SinglePassRunAndCheck test fixture instead.
  64. TEST_F(StripNonSemanticInfoTest, StripHlslSemantic) {
  65. // This is a non-sensical example, but exercises the instructions.
  66. std::string before = R"(OpCapability Shader
  67. OpCapability Linkage
  68. OpExtension "SPV_GOOGLE_decorate_string"
  69. OpExtension "SPV_GOOGLE_hlsl_functionality1"
  70. OpMemoryModel Logical Simple
  71. OpDecorateStringGOOGLE %float HlslSemanticGOOGLE "foobar"
  72. OpDecorateStringGOOGLE %void HlslSemanticGOOGLE "my goodness"
  73. %void = OpTypeVoid
  74. %float = OpTypeFloat 32
  75. )";
  76. std::string after = R"(OpCapability Shader
  77. OpCapability Linkage
  78. OpMemoryModel Logical Simple
  79. %void = OpTypeVoid
  80. %float = OpTypeFloat 32
  81. )";
  82. SinglePassRunAndCheck<StripNonSemanticInfoPass>(before, after, false);
  83. }
  84. TEST_F(StripNonSemanticInfoTest, StripHlslCounterBuffer) {
  85. std::string before = R"(OpCapability Shader
  86. OpCapability Linkage
  87. OpExtension "SPV_GOOGLE_hlsl_functionality1"
  88. OpMemoryModel Logical Simple
  89. OpDecorateId %void HlslCounterBufferGOOGLE %float
  90. %void = OpTypeVoid
  91. %float = OpTypeFloat 32
  92. )";
  93. std::string after = R"(OpCapability Shader
  94. OpCapability Linkage
  95. OpMemoryModel Logical Simple
  96. %void = OpTypeVoid
  97. %float = OpTypeFloat 32
  98. )";
  99. SinglePassRunAndCheck<StripNonSemanticInfoPass>(before, after, false);
  100. }
  101. TEST_F(StripNonSemanticInfoTest, StripHlslSemanticOnMember) {
  102. // This is a non-sensical example, but exercises the instructions.
  103. std::string before = R"(OpCapability Shader
  104. OpCapability Linkage
  105. OpExtension "SPV_GOOGLE_decorate_string"
  106. OpExtension "SPV_GOOGLE_hlsl_functionality1"
  107. OpMemoryModel Logical Simple
  108. OpMemberDecorateStringGOOGLE %struct 0 HlslSemanticGOOGLE "foobar"
  109. %float = OpTypeFloat 32
  110. %_struct_3 = OpTypeStruct %float
  111. )";
  112. std::string after = R"(OpCapability Shader
  113. OpCapability Linkage
  114. OpMemoryModel Logical Simple
  115. %float = OpTypeFloat 32
  116. %_struct_3 = OpTypeStruct %float
  117. )";
  118. SinglePassRunAndCheck<StripNonSemanticInfoPass>(before, after, false);
  119. }
  120. TEST_F(StripNonSemanticInfoTest, StripNonSemanticImport) {
  121. std::string text = R"(
  122. ; CHECK-NOT: OpExtension "SPV_KHR_non_semantic_info"
  123. ; CHECK-NOT: OpExtInstImport
  124. OpCapability Shader
  125. OpCapability Linkage
  126. OpExtension "SPV_KHR_non_semantic_info"
  127. %ext = OpExtInstImport "NonSemantic.Test"
  128. OpMemoryModel Logical GLSL450
  129. )";
  130. SinglePassRunAndMatch<StripNonSemanticInfoPass>(text, true);
  131. }
  132. TEST_F(StripNonSemanticInfoTest, StripNonSemanticGlobal) {
  133. std::string text = R"(
  134. ; CHECK-NOT: OpExtInst
  135. OpCapability Shader
  136. OpCapability Linkage
  137. OpExtension "SPV_KHR_non_semantic_info"
  138. %ext = OpExtInstImport "NonSemantic.Test"
  139. OpMemoryModel Logical GLSL450
  140. %void = OpTypeVoid
  141. %1 = OpExtInst %void %ext 1
  142. )";
  143. SinglePassRunAndMatch<StripNonSemanticInfoPass>(text, true);
  144. }
  145. TEST_F(StripNonSemanticInfoTest, StripNonSemanticInFunction) {
  146. std::string text = R"(
  147. ; CHECK-NOT: OpExtInst
  148. OpCapability Shader
  149. OpCapability Linkage
  150. OpExtension "SPV_KHR_non_semantic_info"
  151. %ext = OpExtInstImport "NonSemantic.Test"
  152. OpMemoryModel Logical GLSL450
  153. %void = OpTypeVoid
  154. %void_fn = OpTypeFunction %void
  155. %foo = OpFunction %void None %void_fn
  156. %entry = OpLabel
  157. %1 = OpExtInst %void %ext 1 %foo
  158. OpReturn
  159. OpFunctionEnd
  160. )";
  161. SinglePassRunAndMatch<StripNonSemanticInfoPass>(text, true);
  162. }
  163. TEST_F(StripNonSemanticInfoTest, StripNonSemanticAfterFunction) {
  164. std::string text = R"(
  165. ; CHECK-NOT: OpExtInst
  166. OpCapability Shader
  167. OpCapability Linkage
  168. OpExtension "SPV_KHR_non_semantic_info"
  169. %ext = OpExtInstImport "NonSemantic.Test"
  170. OpMemoryModel Logical GLSL450
  171. %void = OpTypeVoid
  172. %void_fn = OpTypeFunction %void
  173. %foo = OpFunction %void None %void_fn
  174. %entry = OpLabel
  175. OpReturn
  176. OpFunctionEnd
  177. %1 = OpExtInst %void %ext 1 %foo
  178. )";
  179. SinglePassRunAndMatch<StripNonSemanticInfoPass>(text, true);
  180. }
  181. TEST_F(StripNonSemanticInfoTest, StripNonSemanticBetweenFunctions) {
  182. std::string text = R"(
  183. ; CHECK-NOT: OpExtInst
  184. OpCapability Shader
  185. OpCapability Linkage
  186. OpExtension "SPV_KHR_non_semantic_info"
  187. %ext = OpExtInstImport "NonSemantic.Test"
  188. OpMemoryModel Logical GLSL450
  189. %void = OpTypeVoid
  190. %void_fn = OpTypeFunction %void
  191. %foo = OpFunction %void None %void_fn
  192. %entry = OpLabel
  193. OpReturn
  194. OpFunctionEnd
  195. %1 = OpExtInst %void %ext 1 %foo
  196. %bar = OpFunction %void None %void_fn
  197. %bar_entry = OpLabel
  198. OpReturn
  199. OpFunctionEnd
  200. )";
  201. SinglePassRunAndMatch<StripNonSemanticInfoPass>(text, true);
  202. }
  203. // Make sure that strip reflect does not remove the debug info (OpString and
  204. // OpLine).
  205. TEST_F(StripNonSemanticInfoTest, DontStripDebug) {
  206. std::string text = R"(OpCapability Shader
  207. OpMemoryModel Logical Simple
  208. OpEntryPoint Fragment %1 "main"
  209. OpExecutionMode %1 OriginUpperLeft
  210. %2 = OpString "file"
  211. %void = OpTypeVoid
  212. %4 = OpTypeFunction %void
  213. %1 = OpFunction %void None %4
  214. %5 = OpLabel
  215. OpLine %2 1 1
  216. OpReturn
  217. OpFunctionEnd
  218. )";
  219. SinglePassRunAndCheck<StripNonSemanticInfoPass>(text, text, false);
  220. }
  221. TEST_F(StripNonSemanticInfoTest, RemovedNonSemanticDebugInfo) {
  222. const std::string text = R"(
  223. ;CHECK-NOT: OpExtension "SPV_KHR_non_semantic_info
  224. ;CHECK-NOT: OpExtInstImport "NonSemantic.Shader.DebugInfo.100
  225. ;CHECK-NOT: OpExtInst %void {{%\w+}} DebugSource
  226. ;CHECK-NOT: OpExtInst %void {{%\w+}} DebugLine
  227. OpCapability Shader
  228. OpExtension "SPV_KHR_non_semantic_info"
  229. %1 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
  230. OpMemoryModel Logical GLSL450
  231. OpEntryPoint Fragment %PSMain "PSMain" %in_var_COLOR %out_var_SV_TARGET
  232. OpExecutionMode %PSMain OriginUpperLeft
  233. %5 = OpString "t.hlsl"
  234. %6 = OpString "float"
  235. %7 = OpString "color"
  236. %8 = OpString "PSInput"
  237. %9 = OpString "PSMain"
  238. %10 = OpString ""
  239. %11 = OpString "input"
  240. OpName %in_var_COLOR "in.var.COLOR"
  241. OpName %out_var_SV_TARGET "out.var.SV_TARGET"
  242. OpName %PSMain "PSMain"
  243. OpDecorate %in_var_COLOR Location 0
  244. OpDecorate %out_var_SV_TARGET Location 0
  245. %uint = OpTypeInt 32 0
  246. %float = OpTypeFloat 32
  247. %v4float = OpTypeVector %float 4
  248. %_ptr_Input_v4float = OpTypePointer Input %v4float
  249. %_ptr_Output_v4float = OpTypePointer Output %v4float
  250. %void = OpTypeVoid
  251. %uint_1 = OpConstant %uint 1
  252. %uint_9 = OpConstant %uint 9
  253. %21 = OpTypeFunction %void
  254. %in_var_COLOR = OpVariable %_ptr_Input_v4float Input
  255. %out_var_SV_TARGET = OpVariable %_ptr_Output_v4float Output
  256. %13 = OpExtInst %void %1 DebugSource %5
  257. %PSMain = OpFunction %void None %21
  258. %22 = OpLabel
  259. %23 = OpLoad %v4float %in_var_COLOR
  260. OpStore %out_var_SV_TARGET %23
  261. %24 = OpExtInst %void %1 DebugLine %13 %uint_9 %uint_9 %uint_1 %uint_1
  262. OpReturn
  263. OpFunctionEnd
  264. )";
  265. SinglePassRunAndMatch<StripNonSemanticInfoPass>(text, true);
  266. }
  267. } // namespace
  268. } // namespace opt
  269. } // namespace spvtools