diff_test.cpp 6.3 KB

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