text_to_binary.mode_setting_test.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  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. // Assembler tests for instructions in the "Mode-Setting" section of the
  15. // SPIR-V spec.
  16. #include <string>
  17. #include <tuple>
  18. #include <vector>
  19. #include "gmock/gmock.h"
  20. #include "source/util/string_utils.h"
  21. #include "test/test_fixture.h"
  22. #include "test/unit_spirv.h"
  23. namespace spvtools {
  24. namespace {
  25. using spvtest::EnumCase;
  26. using spvtest::MakeInstruction;
  27. using utils::MakeVector;
  28. using ::testing::Combine;
  29. using ::testing::Eq;
  30. using ::testing::TestWithParam;
  31. using ::testing::Values;
  32. using ::testing::ValuesIn;
  33. // Test OpMemoryModel
  34. // An example case for OpMemoryModel
  35. struct MemoryModelCase {
  36. uint32_t get_addressing_value() const {
  37. return static_cast<uint32_t>(addressing_value);
  38. }
  39. uint32_t get_memory_value() const {
  40. return static_cast<uint32_t>(memory_value);
  41. }
  42. SpvAddressingModel addressing_value;
  43. std::string addressing_name;
  44. SpvMemoryModel memory_value;
  45. std::string memory_name;
  46. };
  47. using OpMemoryModelTest =
  48. spvtest::TextToBinaryTestBase<TestWithParam<MemoryModelCase>>;
  49. TEST_P(OpMemoryModelTest, AnyMemoryModelCase) {
  50. const std::string input = "OpMemoryModel " + GetParam().addressing_name +
  51. " " + GetParam().memory_name;
  52. EXPECT_THAT(
  53. CompiledInstructions(input),
  54. Eq(MakeInstruction(SpvOpMemoryModel, {GetParam().get_addressing_value(),
  55. GetParam().get_memory_value()})));
  56. }
  57. #define CASE(ADDRESSING, MEMORY) \
  58. { \
  59. SpvAddressingModel##ADDRESSING, #ADDRESSING, SpvMemoryModel##MEMORY, \
  60. #MEMORY \
  61. }
  62. // clang-format off
  63. INSTANTIATE_TEST_SUITE_P(TextToBinaryMemoryModel, OpMemoryModelTest,
  64. ValuesIn(std::vector<MemoryModelCase>{
  65. // These cases exercise each addressing model, and
  66. // each memory model, but not necessarily in
  67. // combination.
  68. CASE(Logical,Simple),
  69. CASE(Logical,GLSL450),
  70. CASE(Physical32,OpenCL),
  71. CASE(Physical64,OpenCL),
  72. }));
  73. #undef CASE
  74. // clang-format on
  75. TEST_F(OpMemoryModelTest, WrongModel) {
  76. EXPECT_THAT(CompileFailure("OpMemoryModel xxyyzz Simple"),
  77. Eq("Invalid addressing model 'xxyyzz'."));
  78. EXPECT_THAT(CompileFailure("OpMemoryModel Logical xxyyzz"),
  79. Eq("Invalid memory model 'xxyyzz'."));
  80. }
  81. // Test OpEntryPoint
  82. // An example case for OpEntryPoint
  83. struct EntryPointCase {
  84. uint32_t get_execution_value() const {
  85. return static_cast<uint32_t>(execution_value);
  86. }
  87. SpvExecutionModel execution_value;
  88. std::string execution_name;
  89. std::string entry_point_name;
  90. };
  91. using OpEntryPointTest =
  92. spvtest::TextToBinaryTestBase<TestWithParam<EntryPointCase>>;
  93. TEST_P(OpEntryPointTest, AnyEntryPointCase) {
  94. // TODO(dneto): utf-8, escaping, quoting cases for entry point name.
  95. const std::string input = "OpEntryPoint " + GetParam().execution_name +
  96. " %1 \"" + GetParam().entry_point_name + "\"";
  97. EXPECT_THAT(
  98. CompiledInstructions(input),
  99. Eq(MakeInstruction(SpvOpEntryPoint, {GetParam().get_execution_value(), 1},
  100. MakeVector(GetParam().entry_point_name))));
  101. }
  102. // clang-format off
  103. #define CASE(NAME) SpvExecutionModel##NAME, #NAME
  104. INSTANTIATE_TEST_SUITE_P(TextToBinaryEntryPoint, OpEntryPointTest,
  105. ValuesIn(std::vector<EntryPointCase>{
  106. { CASE(Vertex), "" },
  107. { CASE(TessellationControl), "my tess" },
  108. { CASE(TessellationEvaluation), "really fancy" },
  109. { CASE(Geometry), "Euclid" },
  110. { CASE(Fragment), "FAT32" },
  111. { CASE(GLCompute), "cubic" },
  112. { CASE(Kernel), "Sanders" },
  113. }));
  114. #undef CASE
  115. // clang-format on
  116. TEST_F(OpEntryPointTest, WrongModel) {
  117. EXPECT_THAT(CompileFailure("OpEntryPoint xxyyzz %1 \"fun\""),
  118. Eq("Invalid execution model 'xxyyzz'."));
  119. }
  120. // Test OpExecutionMode
  121. using OpExecutionModeTest = spvtest::TextToBinaryTestBase<
  122. TestWithParam<std::tuple<spv_target_env, EnumCase<SpvExecutionMode>>>>;
  123. TEST_P(OpExecutionModeTest, AnyExecutionMode) {
  124. // This string should assemble, but should not validate.
  125. std::stringstream input;
  126. input << "OpExecutionMode %1 " << std::get<1>(GetParam()).name();
  127. for (auto operand : std::get<1>(GetParam()).operands())
  128. input << " " << operand;
  129. EXPECT_THAT(CompiledInstructions(input.str(), std::get<0>(GetParam())),
  130. Eq(MakeInstruction(SpvOpExecutionMode,
  131. {1, std::get<1>(GetParam()).value()},
  132. std::get<1>(GetParam()).operands())));
  133. }
  134. #define CASE(NAME) SpvExecutionMode##NAME, #NAME
  135. INSTANTIATE_TEST_SUITE_P(
  136. TextToBinaryExecutionMode, OpExecutionModeTest,
  137. Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1),
  138. ValuesIn(std::vector<EnumCase<SpvExecutionMode>>{
  139. // The operand literal values are arbitrarily chosen,
  140. // but there are the right number of them.
  141. {CASE(Invocations), {101}},
  142. {CASE(SpacingEqual), {}},
  143. {CASE(SpacingFractionalEven), {}},
  144. {CASE(SpacingFractionalOdd), {}},
  145. {CASE(VertexOrderCw), {}},
  146. {CASE(VertexOrderCcw), {}},
  147. {CASE(PixelCenterInteger), {}},
  148. {CASE(OriginUpperLeft), {}},
  149. {CASE(OriginLowerLeft), {}},
  150. {CASE(EarlyFragmentTests), {}},
  151. {CASE(PointMode), {}},
  152. {CASE(Xfb), {}},
  153. {CASE(DepthReplacing), {}},
  154. {CASE(DepthGreater), {}},
  155. {CASE(DepthLess), {}},
  156. {CASE(DepthUnchanged), {}},
  157. {CASE(LocalSize), {64, 1, 2}},
  158. {CASE(LocalSizeHint), {8, 2, 4}},
  159. {CASE(InputPoints), {}},
  160. {CASE(InputLines), {}},
  161. {CASE(InputLinesAdjacency), {}},
  162. {CASE(Triangles), {}},
  163. {CASE(InputTrianglesAdjacency), {}},
  164. {CASE(Quads), {}},
  165. {CASE(Isolines), {}},
  166. {CASE(OutputVertices), {21}},
  167. {CASE(OutputPoints), {}},
  168. {CASE(OutputLineStrip), {}},
  169. {CASE(OutputTriangleStrip), {}},
  170. {CASE(VecTypeHint), {96}},
  171. {CASE(ContractionOff), {}},
  172. })));
  173. INSTANTIATE_TEST_SUITE_P(
  174. TextToBinaryExecutionModeV11, OpExecutionModeTest,
  175. Combine(Values(SPV_ENV_UNIVERSAL_1_1),
  176. ValuesIn(std::vector<EnumCase<SpvExecutionMode>>{
  177. {CASE(Initializer)},
  178. {CASE(Finalizer)},
  179. {CASE(SubgroupSize), {12}},
  180. {CASE(SubgroupsPerWorkgroup), {64}}})));
  181. #undef CASE
  182. TEST_F(OpExecutionModeTest, WrongMode) {
  183. EXPECT_THAT(CompileFailure("OpExecutionMode %1 xxyyzz"),
  184. Eq("Invalid execution mode 'xxyyzz'."));
  185. }
  186. TEST_F(OpExecutionModeTest, TooManyModes) {
  187. EXPECT_THAT(CompileFailure("OpExecutionMode %1 Xfb PointMode"),
  188. Eq("Expected <opcode> or <result-id> at the beginning of an "
  189. "instruction, found 'PointMode'."));
  190. }
  191. // Test OpCapability
  192. using OpCapabilityTest =
  193. spvtest::TextToBinaryTestBase<TestWithParam<EnumCase<SpvCapability>>>;
  194. TEST_P(OpCapabilityTest, AnyCapability) {
  195. const std::string input = "OpCapability " + GetParam().name();
  196. EXPECT_THAT(CompiledInstructions(input),
  197. Eq(MakeInstruction(SpvOpCapability, {GetParam().value()})));
  198. }
  199. // clang-format off
  200. #define CASE(NAME) { SpvCapability##NAME, #NAME }
  201. INSTANTIATE_TEST_SUITE_P(TextToBinaryCapability, OpCapabilityTest,
  202. ValuesIn(std::vector<EnumCase<SpvCapability>>{
  203. CASE(Matrix),
  204. CASE(Shader),
  205. CASE(Geometry),
  206. CASE(Tessellation),
  207. CASE(Addresses),
  208. CASE(Linkage),
  209. CASE(Kernel),
  210. CASE(Vector16),
  211. CASE(Float16Buffer),
  212. CASE(Float16),
  213. CASE(Float64),
  214. CASE(Int64),
  215. CASE(Int64Atomics),
  216. CASE(ImageBasic),
  217. CASE(ImageReadWrite),
  218. CASE(ImageMipmap),
  219. // Value 16 intentionally missing
  220. CASE(Pipes),
  221. CASE(Groups),
  222. CASE(DeviceEnqueue),
  223. CASE(LiteralSampler),
  224. CASE(AtomicStorage),
  225. CASE(Int16),
  226. CASE(TessellationPointSize),
  227. CASE(GeometryPointSize),
  228. CASE(ImageGatherExtended),
  229. // Value 26 intentionally missing
  230. CASE(StorageImageMultisample),
  231. CASE(UniformBufferArrayDynamicIndexing),
  232. CASE(SampledImageArrayDynamicIndexing),
  233. CASE(StorageBufferArrayDynamicIndexing),
  234. CASE(StorageImageArrayDynamicIndexing),
  235. CASE(ClipDistance),
  236. CASE(CullDistance),
  237. CASE(ImageCubeArray),
  238. CASE(SampleRateShading),
  239. CASE(ImageRect),
  240. CASE(SampledRect),
  241. CASE(GenericPointer),
  242. CASE(Int8),
  243. CASE(InputAttachment),
  244. CASE(SparseResidency),
  245. CASE(MinLod),
  246. CASE(Sampled1D),
  247. CASE(Image1D),
  248. CASE(SampledCubeArray),
  249. CASE(SampledBuffer),
  250. CASE(ImageBuffer),
  251. CASE(ImageMSArray),
  252. CASE(StorageImageExtendedFormats),
  253. CASE(ImageQuery),
  254. CASE(DerivativeControl),
  255. CASE(InterpolationFunction),
  256. CASE(TransformFeedback),
  257. }));
  258. #undef CASE
  259. // clang-format on
  260. using TextToBinaryCapability = spvtest::TextToBinaryTest;
  261. TEST_F(TextToBinaryCapability, BadMissingCapability) {
  262. EXPECT_THAT(CompileFailure("OpCapability"),
  263. Eq("Expected operand, found end of stream."));
  264. }
  265. TEST_F(TextToBinaryCapability, BadInvalidCapability) {
  266. EXPECT_THAT(CompileFailure("OpCapability 123"),
  267. Eq("Invalid capability '123'."));
  268. }
  269. // TODO(dneto): OpExecutionMode
  270. } // namespace
  271. } // namespace spvtools