ext_inst.glsl_test.cpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. // Copyright (c) 2015-2016 The Khronos Group 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 <algorithm>
  15. #include <string>
  16. #include <vector>
  17. #include "source/latest_version_glsl_std_450_header.h"
  18. #include "test/unit_spirv.h"
  19. namespace spvtools {
  20. namespace {
  21. /// Context for an extended instruction.
  22. ///
  23. /// Information about a GLSL extended instruction (including its opname, return
  24. /// type, etc.) and related instructions used to generate the return type and
  25. /// constant as the operands. Used in generating extended instruction tests.
  26. struct ExtInstContext {
  27. const char* extInstOpName;
  28. const char* extInstOperandVars;
  29. /// The following fields are used to check the SPIR-V binary representation
  30. /// of this instruction.
  31. uint32_t extInstOpcode; ///< Opcode value for this extended instruction.
  32. uint32_t extInstLength; ///< Wordcount of this extended instruction.
  33. std::vector<uint32_t> extInstOperandIds; ///< Ids for operands.
  34. };
  35. using ExtInstGLSLstd450RoundTripTest = ::testing::TestWithParam<ExtInstContext>;
  36. TEST_P(ExtInstGLSLstd450RoundTripTest, ParameterizedExtInst) {
  37. spv_context context = spvContextCreate(SPV_ENV_UNIVERSAL_1_0);
  38. const std::string spirv = R"(
  39. OpCapability Shader
  40. %1 = OpExtInstImport "GLSL.std.450"
  41. OpMemoryModel Logical Simple
  42. OpEntryPoint Vertex %2 "main"
  43. %3 = OpTypeVoid
  44. %4 = OpTypeFunction %3
  45. %2 = OpFunction %3 None %5
  46. %6 = OpLabel
  47. %8 = OpExtInst %7 %1 )" + std::string(GetParam().extInstOpName) +
  48. " " + GetParam().extInstOperandVars + R"(
  49. OpReturn
  50. OpFunctionEnd
  51. )";
  52. const std::string spirv_header =
  53. R"(; SPIR-V
  54. ; Version: 1.0
  55. ; Generator: Khronos SPIR-V Tools Assembler; 0
  56. ; Bound: 9
  57. ; Schema: 0)";
  58. spv_binary binary = nullptr;
  59. spv_diagnostic diagnostic;
  60. spv_result_t error = spvTextToBinary(context, spirv.c_str(), spirv.size(),
  61. &binary, &diagnostic);
  62. if (error) {
  63. spvDiagnosticPrint(diagnostic);
  64. spvDiagnosticDestroy(diagnostic);
  65. ASSERT_EQ(SPV_SUCCESS, error)
  66. << "Source was: " << std::endl
  67. << spirv << std::endl
  68. << "Test case for : " << GetParam().extInstOpName << std::endl;
  69. }
  70. // Check we do have the extended instruction's corresponding binary code in
  71. // the generated SPIR-V binary.
  72. std::vector<uint32_t> expected_contains(
  73. {12 /*OpExtInst*/ | GetParam().extInstLength << 16, 7 /*return type*/,
  74. 8 /*result id*/, 1 /*glsl450 import*/, GetParam().extInstOpcode});
  75. for (uint32_t operand : GetParam().extInstOperandIds) {
  76. expected_contains.push_back(operand);
  77. }
  78. EXPECT_NE(binary->code + binary->wordCount,
  79. std::search(binary->code, binary->code + binary->wordCount,
  80. expected_contains.begin(), expected_contains.end()))
  81. << "Cannot find\n"
  82. << spvtest::WordVector(expected_contains).str() << "in\n"
  83. << spvtest::WordVector(*binary).str();
  84. // Check round trip gives the same text.
  85. spv_text output_text = nullptr;
  86. error = spvBinaryToText(context, binary->code, binary->wordCount,
  87. SPV_BINARY_TO_TEXT_OPTION_NONE, &output_text,
  88. &diagnostic);
  89. if (error) {
  90. spvDiagnosticPrint(diagnostic);
  91. spvDiagnosticDestroy(diagnostic);
  92. ASSERT_EQ(SPV_SUCCESS, error);
  93. }
  94. EXPECT_EQ(spirv_header + spirv, output_text->str);
  95. spvTextDestroy(output_text);
  96. spvBinaryDestroy(binary);
  97. spvContextDestroy(context);
  98. }
  99. INSTANTIATE_TEST_SUITE_P(
  100. ExtInstParameters, ExtInstGLSLstd450RoundTripTest,
  101. ::testing::ValuesIn(std::vector<ExtInstContext>({
  102. // We are only testing the correctness of encoding and decoding here.
  103. // Semantic correctness should be the responsibility of validator. So
  104. // some of the instructions below have incorrect operand and/or return
  105. // types, e.g, Modf, ModfStruct, etc.
  106. {"Round", "%5", 1, 6, {5}},
  107. {"RoundEven", "%5", 2, 6, {5}},
  108. {"Trunc", "%5", 3, 6, {5}},
  109. {"FAbs", "%5", 4, 6, {5}},
  110. {"SAbs", "%5", 5, 6, {5}},
  111. {"FSign", "%5", 6, 6, {5}},
  112. {"SSign", "%5", 7, 6, {5}},
  113. {"Floor", "%5", 8, 6, {5}},
  114. {"Ceil", "%5", 9, 6, {5}},
  115. {"Fract", "%5", 10, 6, {5}},
  116. {"Radians", "%5", 11, 6, {5}},
  117. {"Degrees", "%5", 12, 6, {5}},
  118. {"Sin", "%5", 13, 6, {5}},
  119. {"Cos", "%5", 14, 6, {5}},
  120. {"Tan", "%5", 15, 6, {5}},
  121. {"Asin", "%5", 16, 6, {5}},
  122. {"Acos", "%5", 17, 6, {5}},
  123. {"Atan", "%5", 18, 6, {5}},
  124. {"Sinh", "%5", 19, 6, {5}},
  125. {"Cosh", "%5", 20, 6, {5}},
  126. {"Tanh", "%5", 21, 6, {5}},
  127. {"Asinh", "%5", 22, 6, {5}},
  128. {"Acosh", "%5", 23, 6, {5}},
  129. {"Atanh", "%5", 24, 6, {5}},
  130. {"Atan2", "%5 %5", 25, 7, {5, 5}},
  131. {"Pow", "%5 %5", 26, 7, {5, 5}},
  132. {"Exp", "%5", 27, 6, {5}},
  133. {"Log", "%5", 28, 6, {5}},
  134. {"Exp2", "%5", 29, 6, {5}},
  135. {"Log2", "%5", 30, 6, {5}},
  136. {"Sqrt", "%5", 31, 6, {5}},
  137. {"InverseSqrt", "%5", 32, 6, {5}},
  138. {"Determinant", "%5", 33, 6, {5}},
  139. {"MatrixInverse", "%5", 34, 6, {5}},
  140. {"Modf", "%5 %5", 35, 7, {5, 5}},
  141. {"ModfStruct", "%5", 36, 6, {5}},
  142. {"FMin", "%5 %5", 37, 7, {5, 5}},
  143. {"UMin", "%5 %5", 38, 7, {5, 5}},
  144. {"SMin", "%5 %5", 39, 7, {5, 5}},
  145. {"FMax", "%5 %5", 40, 7, {5, 5}},
  146. {"UMax", "%5 %5", 41, 7, {5, 5}},
  147. {"SMax", "%5 %5", 42, 7, {5, 5}},
  148. {"FClamp", "%5 %5 %5", 43, 8, {5, 5, 5}},
  149. {"UClamp", "%5 %5 %5", 44, 8, {5, 5, 5}},
  150. {"SClamp", "%5 %5 %5", 45, 8, {5, 5, 5}},
  151. {"FMix", "%5 %5 %5", 46, 8, {5, 5, 5}},
  152. {"IMix", "%5 %5 %5", 47, 8, {5, 5, 5}}, // Bug 15452. Reserved.
  153. {"Step", "%5 %5", 48, 7, {5, 5}},
  154. {"SmoothStep", "%5 %5 %5", 49, 8, {5, 5, 5}},
  155. {"Fma", "%5 %5 %5", 50, 8, {5, 5, 5}},
  156. {"Frexp", "%5 %5", 51, 7, {5, 5}},
  157. {"FrexpStruct", "%5", 52, 6, {5}},
  158. {"Ldexp", "%5 %5", 53, 7, {5, 5}},
  159. {"PackSnorm4x8", "%5", 54, 6, {5}},
  160. {"PackUnorm4x8", "%5", 55, 6, {5}},
  161. {"PackSnorm2x16", "%5", 56, 6, {5}},
  162. {"PackUnorm2x16", "%5", 57, 6, {5}},
  163. {"PackHalf2x16", "%5", 58, 6, {5}},
  164. {"PackDouble2x32", "%5", 59, 6, {5}},
  165. {"UnpackSnorm2x16", "%5", 60, 6, {5}},
  166. {"UnpackUnorm2x16", "%5", 61, 6, {5}},
  167. {"UnpackHalf2x16", "%5", 62, 6, {5}},
  168. {"UnpackSnorm4x8", "%5", 63, 6, {5}},
  169. {"UnpackUnorm4x8", "%5", 64, 6, {5}},
  170. {"UnpackDouble2x32", "%5", 65, 6, {5}},
  171. {"Length", "%5", 66, 6, {5}},
  172. {"Distance", "%5 %5", 67, 7, {5, 5}},
  173. {"Cross", "%5 %5", 68, 7, {5, 5}},
  174. {"Normalize", "%5", 69, 6, {5}},
  175. // clang-format off
  176. {"FaceForward", "%5 %5 %5", 70, 8, {5, 5, 5}},
  177. // clang-format on
  178. {"Reflect", "%5 %5", 71, 7, {5, 5}},
  179. {"Refract", "%5 %5 %5", 72, 8, {5, 5, 5}},
  180. {"FindILsb", "%5", 73, 6, {5}},
  181. {"FindSMsb", "%5", 74, 6, {5}},
  182. {"FindUMsb", "%5", 75, 6, {5}},
  183. {"InterpolateAtCentroid", "%5", 76, 6, {5}},
  184. // clang-format off
  185. {"InterpolateAtSample", "%5 %5", 77, 7, {5, 5}},
  186. {"InterpolateAtOffset", "%5 %5", 78, 7, {5, 5}},
  187. // clang-format on
  188. {"NMin", "%5 %5", 79, 7, {5, 5}},
  189. {"NMax", "%5 %5", 80, 7, {5, 5}},
  190. {"NClamp", "%5 %5 %5", 81, 8, {5, 5, 5}},
  191. })));
  192. } // namespace
  193. } // namespace spvtools