val_storage_test.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  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. // Validation tests for OpVariable storage class
  15. #include <sstream>
  16. #include <string>
  17. #include <tuple>
  18. #include "gmock/gmock.h"
  19. #include "test/val/val_fixtures.h"
  20. namespace spvtools {
  21. namespace val {
  22. namespace {
  23. using ::testing::HasSubstr;
  24. using ::testing::Values;
  25. using ValidateStorage = spvtest::ValidateBase<std::string>;
  26. using ValidateStorageClass =
  27. spvtest::ValidateBase<std::tuple<std::string, bool, bool, std::string>>;
  28. TEST_F(ValidateStorage, FunctionStorageInsideFunction) {
  29. char str[] = R"(
  30. OpCapability Shader
  31. OpCapability Linkage
  32. OpMemoryModel Logical GLSL450
  33. %intt = OpTypeInt 32 1
  34. %voidt = OpTypeVoid
  35. %vfunct = OpTypeFunction %voidt
  36. %ptrt = OpTypePointer Function %intt
  37. %func = OpFunction %voidt None %vfunct
  38. %funcl = OpLabel
  39. %var = OpVariable %ptrt Function
  40. OpReturn
  41. OpFunctionEnd
  42. )";
  43. CompileSuccessfully(str);
  44. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  45. }
  46. TEST_F(ValidateStorage, FunctionStorageOutsideFunction) {
  47. char str[] = R"(
  48. OpCapability Shader
  49. OpCapability Linkage
  50. OpMemoryModel Logical GLSL450
  51. %intt = OpTypeInt 32 1
  52. %voidt = OpTypeVoid
  53. %vfunct = OpTypeFunction %voidt
  54. %ptrt = OpTypePointer Function %intt
  55. %var = OpVariable %ptrt Function
  56. %func = OpFunction %voidt None %vfunct
  57. %funcl = OpLabel
  58. OpReturn
  59. OpFunctionEnd
  60. )";
  61. CompileSuccessfully(str);
  62. ASSERT_EQ(SPV_ERROR_INVALID_LAYOUT, ValidateInstructions());
  63. EXPECT_THAT(getDiagnosticString(),
  64. HasSubstr("Variables can not have a function[7] storage class "
  65. "outside of a function"));
  66. }
  67. TEST_F(ValidateStorage, OtherStorageOutsideFunction) {
  68. char str[] = R"(
  69. OpCapability Shader
  70. OpCapability Kernel
  71. OpCapability AtomicStorage
  72. OpCapability Linkage
  73. OpMemoryModel Logical GLSL450
  74. %intt = OpTypeInt 32 0
  75. %voidt = OpTypeVoid
  76. %vfunct = OpTypeFunction %voidt
  77. %uniconptrt = OpTypePointer UniformConstant %intt
  78. %unicon = OpVariable %uniconptrt UniformConstant
  79. %inputptrt = OpTypePointer Input %intt
  80. %input = OpVariable %inputptrt Input
  81. %unifptrt = OpTypePointer Uniform %intt
  82. %unif = OpVariable %unifptrt Uniform
  83. %outputptrt = OpTypePointer Output %intt
  84. %output = OpVariable %outputptrt Output
  85. %wgroupptrt = OpTypePointer Workgroup %intt
  86. %wgroup = OpVariable %wgroupptrt Workgroup
  87. %xwgrpptrt = OpTypePointer CrossWorkgroup %intt
  88. %xwgrp = OpVariable %xwgrpptrt CrossWorkgroup
  89. %privptrt = OpTypePointer Private %intt
  90. %priv = OpVariable %privptrt Private
  91. %pushcoptrt = OpTypePointer PushConstant %intt
  92. %pushco = OpVariable %pushcoptrt PushConstant
  93. %atomcptrt = OpTypePointer AtomicCounter %intt
  94. %atomct = OpVariable %atomcptrt AtomicCounter
  95. %imageptrt = OpTypePointer Image %intt
  96. %image = OpVariable %imageptrt Image
  97. %func = OpFunction %voidt None %vfunct
  98. %funcl = OpLabel
  99. OpReturn
  100. OpFunctionEnd
  101. )";
  102. CompileSuccessfully(str);
  103. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  104. }
  105. // clang-format off
  106. TEST_P(ValidateStorage, OtherStorageInsideFunction) {
  107. std::stringstream ss;
  108. ss << R"(
  109. OpCapability Shader
  110. OpCapability Kernel
  111. OpCapability AtomicStorage
  112. OpCapability Linkage
  113. OpMemoryModel Logical GLSL450
  114. %intt = OpTypeInt 32 0
  115. %voidt = OpTypeVoid
  116. %vfunct = OpTypeFunction %voidt
  117. %ptrt = OpTypePointer Function %intt
  118. %func = OpFunction %voidt None %vfunct
  119. %funcl = OpLabel
  120. %var = OpVariable %ptrt )" << GetParam() << R"(
  121. OpReturn
  122. OpFunctionEnd
  123. )";
  124. CompileSuccessfully(ss.str());
  125. ASSERT_EQ(SPV_ERROR_INVALID_LAYOUT, ValidateInstructions());
  126. EXPECT_THAT(getDiagnosticString(), HasSubstr(
  127. "Variables must have a function[7] storage class inside of a function"));
  128. }
  129. INSTANTIATE_TEST_SUITE_P(MatrixOp, ValidateStorage,
  130. ::testing::Values(
  131. "Input",
  132. "Uniform",
  133. "Output",
  134. "Workgroup",
  135. "CrossWorkgroup",
  136. "Private",
  137. "PushConstant",
  138. "AtomicCounter",
  139. "Image"));
  140. // clang-format on
  141. TEST_F(ValidateStorage, GenericVariableOutsideFunction) {
  142. const auto str = R"(
  143. OpCapability Kernel
  144. OpCapability Linkage
  145. OpCapability GenericPointer
  146. OpMemoryModel Logical OpenCL
  147. %intt = OpTypeInt 32 0
  148. %ptrt = OpTypePointer Function %intt
  149. %var = OpVariable %ptrt Generic
  150. )";
  151. CompileSuccessfully(str);
  152. ASSERT_EQ(SPV_ERROR_INVALID_BINARY, ValidateInstructions());
  153. EXPECT_THAT(getDiagnosticString(),
  154. HasSubstr("OpVariable storage class cannot be Generic"));
  155. }
  156. TEST_F(ValidateStorage, GenericVariableInsideFunction) {
  157. const auto str = R"(
  158. OpCapability Shader
  159. OpCapability Linkage
  160. OpCapability GenericPointer
  161. OpMemoryModel Logical GLSL450
  162. %intt = OpTypeInt 32 1
  163. %voidt = OpTypeVoid
  164. %vfunct = OpTypeFunction %voidt
  165. %ptrt = OpTypePointer Function %intt
  166. %func = OpFunction %voidt None %vfunct
  167. %funcl = OpLabel
  168. %var = OpVariable %ptrt Generic
  169. OpReturn
  170. OpFunctionEnd
  171. )";
  172. CompileSuccessfully(str);
  173. EXPECT_EQ(SPV_ERROR_INVALID_BINARY, ValidateInstructions());
  174. EXPECT_THAT(getDiagnosticString(),
  175. HasSubstr("OpVariable storage class cannot be Generic"));
  176. }
  177. TEST_F(ValidateStorage, RelaxedLogicalPointerFunctionParam) {
  178. const auto str = R"(
  179. OpCapability Shader
  180. OpCapability Linkage
  181. OpMemoryModel Logical GLSL450
  182. %intt = OpTypeInt 32 1
  183. %voidt = OpTypeVoid
  184. %ptrt = OpTypePointer Function %intt
  185. %vfunct = OpTypeFunction %voidt
  186. %vifunct = OpTypeFunction %voidt %ptrt
  187. %wgroupptrt = OpTypePointer Workgroup %intt
  188. %wgroup = OpVariable %wgroupptrt Workgroup
  189. %main = OpFunction %voidt None %vfunct
  190. %mainl = OpLabel
  191. %ret = OpFunctionCall %voidt %func %wgroup
  192. OpReturn
  193. OpFunctionEnd
  194. %func = OpFunction %voidt None %vifunct
  195. %arg = OpFunctionParameter %ptrt
  196. %funcl = OpLabel
  197. OpReturn
  198. OpFunctionEnd
  199. )";
  200. CompileSuccessfully(str);
  201. getValidatorOptions()->before_hlsl_legalization = true;
  202. ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
  203. }
  204. TEST_F(ValidateStorage, RelaxedLogicalPointerFunctionParamBad) {
  205. const auto str = R"(
  206. OpCapability Shader
  207. OpCapability Linkage
  208. OpMemoryModel Logical GLSL450
  209. %floatt = OpTypeFloat 32
  210. %intt = OpTypeInt 32 1
  211. %voidt = OpTypeVoid
  212. %ptrt = OpTypePointer Function %intt
  213. %vfunct = OpTypeFunction %voidt
  214. %vifunct = OpTypeFunction %voidt %ptrt
  215. %wgroupptrt = OpTypePointer Workgroup %floatt
  216. %wgroup = OpVariable %wgroupptrt Workgroup
  217. %main = OpFunction %voidt None %vfunct
  218. %mainl = OpLabel
  219. %ret = OpFunctionCall %voidt %func %wgroup
  220. OpReturn
  221. OpFunctionEnd
  222. %func = OpFunction %voidt None %vifunct
  223. %arg = OpFunctionParameter %ptrt
  224. %funcl = OpLabel
  225. OpReturn
  226. OpFunctionEnd
  227. )";
  228. CompileSuccessfully(str);
  229. getValidatorOptions()->relax_logical_pointer = true;
  230. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  231. EXPECT_THAT(getDiagnosticString(),
  232. HasSubstr("OpFunctionCall Argument <id> '"));
  233. }
  234. } // namespace
  235. } // namespace val
  236. } // namespace spvtools