val_non_semantic_test.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. // Copyright (c) 2019 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. // Validation tests for non-semantic instructions
  15. #include <string>
  16. #include <vector>
  17. #include "gmock/gmock.h"
  18. #include "test/unit_spirv.h"
  19. #include "test/val/val_code_generator.h"
  20. #include "test/val/val_fixtures.h"
  21. namespace spvtools {
  22. namespace val {
  23. namespace {
  24. struct TestResult {
  25. TestResult(spv_result_t in_validation_result = SPV_SUCCESS,
  26. const char* in_error_str = nullptr,
  27. const char* in_error_str2 = nullptr)
  28. : validation_result(in_validation_result),
  29. error_str(in_error_str),
  30. error_str2(in_error_str2) {}
  31. spv_result_t validation_result;
  32. const char* error_str;
  33. const char* error_str2;
  34. };
  35. using ::testing::Combine;
  36. using ::testing::HasSubstr;
  37. using ::testing::Values;
  38. using ::testing::ValuesIn;
  39. using ValidateNonSemanticGenerated = spvtest::ValidateBase<
  40. std::tuple<bool, bool, const char*, const char*, TestResult>>;
  41. using ValidateNonSemanticString = spvtest::ValidateBase<bool>;
  42. CodeGenerator GetNonSemanticCodeGenerator(const bool declare_ext,
  43. const bool declare_extinst,
  44. const char* const global_extinsts,
  45. const char* const function_extinsts) {
  46. CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator();
  47. if (declare_ext) {
  48. generator.extensions_ += "OpExtension \"SPV_KHR_non_semantic_info\"\n";
  49. }
  50. if (declare_extinst) {
  51. generator.extensions_ +=
  52. "%extinst = OpExtInstImport \"NonSemantic.Testing.Set\"\n";
  53. }
  54. generator.after_types_ = global_extinsts;
  55. generator.before_types_ = "%decorate_group = OpDecorationGroup";
  56. EntryPoint entry_point;
  57. entry_point.name = "main";
  58. entry_point.execution_model = "Vertex";
  59. entry_point.body = R"(
  60. )";
  61. entry_point.body += function_extinsts;
  62. generator.entry_points_.push_back(std::move(entry_point));
  63. return generator;
  64. }
  65. TEST_P(ValidateNonSemanticGenerated, InTest) {
  66. const bool declare_ext = std::get<0>(GetParam());
  67. const bool declare_extinst = std::get<1>(GetParam());
  68. const char* const global_extinsts = std::get<2>(GetParam());
  69. const char* const function_extinsts = std::get<3>(GetParam());
  70. const TestResult& test_result = std::get<4>(GetParam());
  71. CodeGenerator generator = GetNonSemanticCodeGenerator(
  72. declare_ext, declare_extinst, global_extinsts, function_extinsts);
  73. CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0);
  74. ASSERT_EQ(test_result.validation_result,
  75. ValidateInstructions(SPV_ENV_VULKAN_1_0));
  76. if (test_result.error_str) {
  77. EXPECT_THAT(getDiagnosticString(),
  78. testing::ContainsRegex(test_result.error_str));
  79. }
  80. if (test_result.error_str2) {
  81. EXPECT_THAT(getDiagnosticString(),
  82. testing::ContainsRegex(test_result.error_str2));
  83. }
  84. }
  85. INSTANTIATE_TEST_SUITE_P(OnlyOpExtension, ValidateNonSemanticGenerated,
  86. Combine(Values(true), Values(false), Values(""),
  87. Values(""), Values(TestResult())));
  88. INSTANTIATE_TEST_SUITE_P(
  89. MissingOpExtensionPre1p6, ValidateNonSemanticGenerated,
  90. Combine(Values(false), Values(true), Values(""), Values(""),
  91. Values(TestResult(
  92. SPV_ERROR_INVALID_DATA,
  93. "NonSemantic extended instruction sets cannot be declared "
  94. "without SPV_KHR_non_semantic_info."))));
  95. INSTANTIATE_TEST_SUITE_P(NoExtInst, ValidateNonSemanticGenerated,
  96. Combine(Values(true), Values(true), Values(""),
  97. Values(""), Values(TestResult())));
  98. INSTANTIATE_TEST_SUITE_P(
  99. SimpleGlobalExtInst, ValidateNonSemanticGenerated,
  100. Combine(Values(true), Values(true),
  101. Values("%result = OpExtInst %void %extinst 123 %i32"), Values(""),
  102. Values(TestResult())));
  103. INSTANTIATE_TEST_SUITE_P(
  104. ComplexGlobalExtInst, ValidateNonSemanticGenerated,
  105. Combine(Values(true), Values(true),
  106. Values("%result = OpExtInst %void %extinst 123 %i32 %u32_2 "
  107. "%f32vec4_1234 %u32_0"),
  108. Values(""), Values(TestResult())));
  109. INSTANTIATE_TEST_SUITE_P(
  110. SimpleFunctionLevelExtInst, ValidateNonSemanticGenerated,
  111. Combine(Values(true), Values(true), Values(""),
  112. Values("%result = OpExtInst %void %extinst 123 %i32"),
  113. Values(TestResult())));
  114. INSTANTIATE_TEST_SUITE_P(
  115. FunctionTypeReference, ValidateNonSemanticGenerated,
  116. Combine(Values(true), Values(true),
  117. Values("%result = OpExtInst %void %extinst 123 %func"), Values(""),
  118. Values(TestResult())));
  119. INSTANTIATE_TEST_SUITE_P(
  120. EntryPointReference, ValidateNonSemanticGenerated,
  121. Combine(Values(true), Values(true), Values(""),
  122. Values("%result = OpExtInst %void %extinst 123 %main"),
  123. Values(TestResult())));
  124. INSTANTIATE_TEST_SUITE_P(
  125. DecorationGroupReference, ValidateNonSemanticGenerated,
  126. Combine(Values(true), Values(true), Values(""),
  127. Values("%result = OpExtInst %void %extinst 123 %decorate_group"),
  128. Values(TestResult())));
  129. INSTANTIATE_TEST_SUITE_P(
  130. UnknownIDReference, ValidateNonSemanticGenerated,
  131. Combine(Values(true), Values(true),
  132. Values("%result = OpExtInst %void %extinst 123 %undefined_id"),
  133. Values(""),
  134. Values(TestResult(SPV_ERROR_INVALID_ID,
  135. "ID .* has not been defined"))));
  136. INSTANTIATE_TEST_SUITE_P(
  137. NonSemanticUseInSemantic, ValidateNonSemanticGenerated,
  138. Combine(Values(true), Values(true),
  139. Values("%result = OpExtInst %f32 %extinst 123 %i32\n"
  140. "%invalid = OpConstantComposite %f32vec2 %f32_0 %result"),
  141. Values(""),
  142. Values(TestResult(SPV_ERROR_INVALID_ID,
  143. "in semantic instruction cannot be a "
  144. "non-semantic instruction"))));
  145. TEST_F(ValidateNonSemanticString, InvalidSectionOpExtInst) {
  146. const std::string spirv = R"(
  147. OpCapability Shader
  148. OpExtension "SPV_KHR_non_semantic_info"
  149. %extinst = OpExtInstImport "NonSemantic.Testing.Set"
  150. %test = OpExtInst %void %extinst 4 %void
  151. OpMemoryModel Logical GLSL450
  152. OpEntryPoint Vertex %main "main"
  153. )";
  154. CompileSuccessfully(spirv);
  155. EXPECT_THAT(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  156. // there's no specific error for using an OpExtInst too early, it requires a
  157. // type so by definition any use of a type in it will be an undefined ID
  158. EXPECT_THAT(getDiagnosticString(),
  159. HasSubstr("ID '2[%2]' has not been defined"));
  160. }
  161. TEST_F(ValidateNonSemanticString, MissingOpExtensionPost1p6) {
  162. const std::string spirv = R"(
  163. OpCapability Shader
  164. %extinst = OpExtInstImport "NonSemantic.Testing.Set"
  165. OpMemoryModel Logical GLSL450
  166. OpEntryPoint Fragment %main "main"
  167. OpExecutionMode %main OriginUpperLeft
  168. %void = OpTypeVoid
  169. %test = OpExtInst %void %extinst 3
  170. %void_fn = OpTypeFunction %void
  171. %main = OpFunction %void None %void_fn
  172. %entry = OpLabel
  173. OpReturn
  174. OpFunctionEnd
  175. )";
  176. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_6);
  177. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_6));
  178. }
  179. } // namespace
  180. } // namespace val
  181. } // namespace spvtools