diff_test.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. // Copyright (c) 2022 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 "source/diff/diff.h"
  15. #include "diff_test_utils.h"
  16. #include "source/opt/build_module.h"
  17. #include "source/opt/ir_context.h"
  18. #include "source/spirv_constant.h"
  19. #include "spirv-tools/libspirv.hpp"
  20. #include "tools/io.h"
  21. #include "tools/util/cli_consumer.h"
  22. #include <fstream>
  23. #include <string>
  24. #include "gtest/gtest.h"
  25. namespace spvtools {
  26. namespace diff {
  27. namespace {
  28. constexpr auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_6;
  29. std::unique_ptr<spvtools::opt::IRContext> Assemble(const std::string& spirv) {
  30. spvtools::SpirvTools t(kDefaultEnvironment);
  31. t.SetMessageConsumer(spvtools::utils::CLIMessageConsumer);
  32. std::vector<uint32_t> binary;
  33. if (!t.Assemble(spirv, &binary,
  34. spvtools::SpirvTools::kDefaultAssembleOption |
  35. SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS))
  36. return nullptr;
  37. return spvtools::BuildModule(kDefaultEnvironment,
  38. spvtools::utils::CLIMessageConsumer,
  39. binary.data(), binary.size());
  40. }
  41. TEST(DiffIndentTest, Diff) {
  42. const std::string src = R"(OpCapability Shader
  43. %ext_inst = OpExtInstImport "GLSL.std.450"
  44. OpMemoryModel Logical GLSL450
  45. OpEntryPoint Fragment %main "main"
  46. OpExecutionMode %main OriginUpperLeft
  47. %void = OpTypeVoid
  48. %func = OpTypeFunction %void
  49. %main = OpFunction %void None %func
  50. %main_entry = OpLabel
  51. OpReturn
  52. OpFunctionEnd;)";
  53. const std::string dst = R"(OpCapability Shader
  54. OpMemoryModel Logical GLSL450
  55. OpEntryPoint Fragment %main "main"
  56. OpExecutionMode %main OriginUpperLeft
  57. %void = OpTypeVoid
  58. %func = OpTypeFunction %void
  59. %main = OpFunction %void None %func
  60. %main_entry = OpLabel
  61. OpReturn
  62. OpFunctionEnd;)";
  63. const std::string diff = R"( ; SPIR-V
  64. ; Version: 1.6
  65. ; Generator: Khronos SPIR-V Tools Assembler; 0
  66. ; Bound: 6
  67. ; Schema: 0
  68. OpCapability Shader
  69. - %1 = OpExtInstImport "GLSL.std.450"
  70. OpMemoryModel Logical GLSL450
  71. OpEntryPoint Fragment %2 "main"
  72. OpExecutionMode %2 OriginUpperLeft
  73. %3 = OpTypeVoid
  74. %4 = OpTypeFunction %3
  75. %2 = OpFunction %3 None %4
  76. %5 = OpLabel
  77. OpReturn
  78. OpFunctionEnd
  79. )";
  80. Options options;
  81. options.indent = true;
  82. DoStringDiffTest(src, dst, diff, options);
  83. }
  84. TEST(DiffNoHeaderTest, Diff) {
  85. const std::string src = R"(OpCapability Shader
  86. %ext_inst = OpExtInstImport "GLSL.std.450"
  87. OpMemoryModel Logical GLSL450
  88. OpEntryPoint Fragment %main "main"
  89. OpExecutionMode %main OriginUpperLeft
  90. %void = OpTypeVoid
  91. %func = OpTypeFunction %void
  92. %main = OpFunction %void None %func
  93. %main_entry = OpLabel
  94. OpReturn
  95. OpFunctionEnd;)";
  96. const std::string dst = R"(OpCapability Shader
  97. OpMemoryModel Logical GLSL450
  98. OpEntryPoint Fragment %main "main"
  99. OpExecutionMode %main OriginUpperLeft
  100. %void = OpTypeVoid
  101. %func = OpTypeFunction %void
  102. %main = OpFunction %void None %func
  103. %main_entry = OpLabel
  104. OpReturn
  105. OpFunctionEnd;)";
  106. const std::string diff = R"( OpCapability Shader
  107. -%1 = OpExtInstImport "GLSL.std.450"
  108. OpMemoryModel Logical GLSL450
  109. OpEntryPoint Fragment %2 "main"
  110. OpExecutionMode %2 OriginUpperLeft
  111. %3 = OpTypeVoid
  112. %4 = OpTypeFunction %3
  113. %2 = OpFunction %3 None %4
  114. %5 = OpLabel
  115. OpReturn
  116. OpFunctionEnd
  117. )";
  118. Options options;
  119. options.no_header = true;
  120. DoStringDiffTest(src, dst, diff, options);
  121. }
  122. TEST(DiffHeaderTest, Diff) {
  123. const std::string src_spirv = R"(OpCapability Shader
  124. %ext_inst = OpExtInstImport "GLSL.std.450"
  125. OpMemoryModel Logical GLSL450
  126. OpEntryPoint Fragment %main "main"
  127. OpExecutionMode %main OriginUpperLeft
  128. %void = OpTypeVoid
  129. %func = OpTypeFunction %void
  130. %main = OpFunction %void None %func
  131. %main_entry = OpLabel
  132. OpReturn
  133. OpFunctionEnd;)";
  134. const std::string dst_spirv = R"(OpCapability Shader
  135. OpMemoryModel Logical GLSL450
  136. OpEntryPoint Fragment %main "main"
  137. OpExecutionMode %main OriginUpperLeft
  138. %void = OpTypeVoid
  139. %func = OpTypeFunction %void
  140. %main = OpFunction %void None %func
  141. %main_entry = OpLabel
  142. OpReturn
  143. OpFunctionEnd;)";
  144. const std::string diff = R"( ; SPIR-V
  145. -; Version: 1.3
  146. +; Version: 1.2
  147. -; Generator: Khronos SPIR-V Tools Assembler; 3
  148. +; Generator: Khronos Glslang Reference Front End; 10
  149. ; Bound: 6
  150. ; Schema: 0
  151. OpCapability Shader
  152. -%1 = OpExtInstImport "GLSL.std.450"
  153. OpMemoryModel Logical GLSL450
  154. OpEntryPoint Fragment %2 "main"
  155. OpExecutionMode %2 OriginUpperLeft
  156. %3 = OpTypeVoid
  157. %4 = OpTypeFunction %3
  158. %2 = OpFunction %3 None %4
  159. %5 = OpLabel
  160. OpReturn
  161. OpFunctionEnd
  162. )";
  163. // Load the src and dst modules
  164. std::unique_ptr<spvtools::opt::IRContext> src = Assemble(src_spirv);
  165. ASSERT_TRUE(src);
  166. std::unique_ptr<spvtools::opt::IRContext> dst = Assemble(dst_spirv);
  167. ASSERT_TRUE(dst);
  168. // Differentiate them in the header.
  169. const spvtools::opt::ModuleHeader src_header = {
  170. SpvMagicNumber,
  171. SPV_SPIRV_VERSION_WORD(1, 3),
  172. SPV_GENERATOR_WORD(SPV_GENERATOR_KHRONOS_ASSEMBLER, 3),
  173. src->module()->IdBound(),
  174. src->module()->schema(),
  175. };
  176. const spvtools::opt::ModuleHeader dst_header = {
  177. SpvMagicNumber,
  178. SPV_SPIRV_VERSION_WORD(1, 2),
  179. SPV_GENERATOR_WORD(SPV_GENERATOR_KHRONOS_GLSLANG, 10),
  180. dst->module()->IdBound(),
  181. dst->module()->schema(),
  182. };
  183. src->module()->SetHeader(src_header);
  184. dst->module()->SetHeader(dst_header);
  185. // Take the diff
  186. Options options;
  187. std::ostringstream diff_result;
  188. spv_result_t result =
  189. spvtools::diff::Diff(src.get(), dst.get(), diff_result, options);
  190. ASSERT_EQ(result, SPV_SUCCESS);
  191. // Expect they match
  192. EXPECT_EQ(diff_result.str(), diff);
  193. }
  194. } // namespace
  195. } // namespace diff
  196. } // namespace spvtools