Setup dependent external sources
[platform/upstream/VK-GL-CTS.git] / external / spirv-tools / src / test / text_to_binary.image_test.cpp
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
15 // Assembler tests for instructions in the "Image Instructions" section of
16 // the SPIR-V spec.
17
18 #include "unit_spirv.h"
19
20 #include "gmock/gmock.h"
21 #include "test_fixture.h"
22
23 namespace {
24
25 using spvtest::MakeInstruction;
26 using spvtest::TextToBinaryTest;
27 using ::testing::Eq;
28
29 // An example case for a mask value with operands.
30 struct ImageOperandsCase {
31   std::string image_operands;
32   // The expected mask, followed by its operands.
33   std::vector<uint32_t> expected_mask_and_operands;
34 };
35
36 // Test all kinds of image operands.
37
38 using ImageOperandsTest =
39     spvtest::TextToBinaryTestBase<::testing::TestWithParam<ImageOperandsCase>>;
40
41 TEST_P(ImageOperandsTest, Sample) {
42   const std::string input =
43       "%2 = OpImageFetch %1 %3 %4" + GetParam().image_operands + "\n";
44   EXPECT_THAT(CompiledInstructions(input),
45               Eq(MakeInstruction(SpvOpImageFetch, {1, 2, 3, 4},
46                                  GetParam().expected_mask_and_operands)));
47 }
48
49 #define MASK(NAME) SpvImageOperands##NAME##Mask
50 INSTANTIATE_TEST_CASE_P(
51     TextToBinaryImageOperandsAny, ImageOperandsTest,
52     ::testing::ValuesIn(std::vector<ImageOperandsCase>{
53         // TODO(dneto): Rev32 adds many more values, and rearranges their
54         // values.
55         // Image operands are optional.
56         {"", {}},
57         // Test each kind, alone.
58         {" Bias %5", {MASK(Bias), 5}},
59         {" Lod %5", {MASK(Lod), 5}},
60         {" Grad %5 %6", {MASK(Grad), 5, 6}},
61         {" ConstOffset %5", {MASK(ConstOffset), 5}},
62         {" Offset %5", {MASK(Offset), 5}},
63         {" ConstOffsets %5", {MASK(ConstOffsets), 5}},
64         {" Sample %5", {MASK(Sample), 5}},
65         {" MinLod %5", {MASK(MinLod), 5}},
66     }),);
67 #undef MASK
68 #define MASK(NAME) static_cast<uint32_t>(SpvImageOperands##NAME##Mask)
69 INSTANTIATE_TEST_CASE_P(
70     TextToBinaryImageOperandsCombination, ImageOperandsTest,
71     ::testing::ValuesIn(std::vector<ImageOperandsCase>{
72         // TODO(dneto): Rev32 adds many more values, and rearranges their
73         // values.
74         // Test adjacent pairs, so we can easily debug the values when it fails.
75         {" Bias|Lod %5 %6", {MASK(Bias) | MASK(Lod), 5, 6}},
76         {" Lod|Grad %5 %6 %7", {MASK(Lod) | MASK(Grad), 5, 6, 7}},
77         {" Grad|ConstOffset %5 %6 %7",
78          {MASK(Grad) | MASK(ConstOffset), 5, 6, 7}},
79         {" ConstOffset|Offset %5 %6",
80          {MASK(ConstOffset) | MASK(Offset), 5, 6}},
81         {" Offset|ConstOffsets %5 %6",
82          {MASK(Offset) | MASK(ConstOffsets), 5, 6}},
83         {" ConstOffsets|Sample %5 %6",
84          {MASK(ConstOffsets) | MASK(Sample), 5, 6}},
85         // Test all masks together.
86         {" Bias|Lod|Grad|ConstOffset|Offset|ConstOffsets|Sample"
87          " %5 %6 %7 %8 %9 %10 %11 %12",
88          {MASK(Bias) | MASK(Lod) | MASK(Grad) | MASK(ConstOffset) |
89               MASK(Offset) | MASK(ConstOffsets) | MASK(Sample),
90           5, 6, 7, 8, 9, 10, 11, 12}},
91         // The same, but with mask value names reversed.
92         {" Sample|ConstOffsets|Offset|ConstOffset|Grad|Lod|Bias"
93          " %5 %6 %7 %8 %9 %10 %11 %12",
94          {MASK(Bias) | MASK(Lod) | MASK(Grad) | MASK(ConstOffset) |
95               MASK(Offset) | MASK(ConstOffsets) | MASK(Sample),
96           5, 6, 7, 8, 9, 10, 11, 12}}}),);
97 #undef MASK
98
99 TEST_F(ImageOperandsTest, WrongOperand) {
100   EXPECT_THAT(CompileFailure("%r = OpImageFetch %t %i %c xxyyzz"),
101               Eq("Invalid image operand 'xxyyzz'."));
102 }
103
104 // Test OpImage
105
106 using OpImageTest = TextToBinaryTest;
107
108 TEST_F(OpImageTest, Valid) {
109   const std::string input = "%2 = OpImage %1 %3\n";
110   EXPECT_THAT(CompiledInstructions(input),
111               Eq(MakeInstruction(SpvOpImage, {1, 2, 3})));
112
113   // Test the disassembler.
114   EXPECT_THAT(EncodeAndDecodeSuccessfully(input), input);
115 }
116
117 TEST_F(OpImageTest, InvalidTypeOperand) {
118   EXPECT_THAT(CompileFailure("%2 = OpImage 42"),
119               Eq("Expected id to start with %."));
120 }
121
122 TEST_F(OpImageTest, MissingSampledImageOperand) {
123   EXPECT_THAT(CompileFailure("%2 = OpImage %1"),
124               Eq("Expected operand, found end of stream."));
125 }
126
127 TEST_F(OpImageTest, InvalidSampledImageOperand) {
128   EXPECT_THAT(CompileFailure("%2 = OpImage %1 1000"),
129               Eq("Expected id to start with %."));
130 }
131
132 TEST_F(OpImageTest, TooManyOperands) {
133   // We should improve this message, to say what instruction we're trying to
134   // parse.
135   EXPECT_THAT(CompileFailure("%2 = OpImage %1 %3 %4"), // an Id
136               Eq("Expected '=', found end of stream."));
137
138   EXPECT_THAT(CompileFailure("%2 = OpImage %1 %3 99"),  // a number
139               Eq("Expected <opcode> or <result-id> at the beginning of an "
140                  "instruction, found '99'."));
141   EXPECT_THAT(CompileFailure("%2 = OpImage %1 %3 \"abc\""),  // a string
142               Eq("Expected <opcode> or <result-id> at the beginning of an "
143                  "instruction, found '\"abc\"'."));
144 }
145
146 // Test OpImageSparseRead
147
148 using OpImageSparseReadTest = TextToBinaryTest;
149
150 TEST_F(OpImageSparseReadTest, OnlyRequiredOperands) {
151   const std::string input = "%2 = OpImageSparseRead %1 %3 %4\n";
152   EXPECT_THAT(CompiledInstructions(input),
153               Eq(MakeInstruction(SpvOpImageSparseRead, {1, 2, 3, 4})));
154   // Test the disassembler.
155   EXPECT_THAT(EncodeAndDecodeSuccessfully(input), input);
156 }
157
158 // Test all kinds of image operands on OpImageSparseRead
159
160 using ImageSparseReadImageOperandsTest =
161     spvtest::TextToBinaryTestBase<::testing::TestWithParam<ImageOperandsCase>>;
162
163 TEST_P(ImageSparseReadImageOperandsTest, Sample) {
164   const std::string input =
165       "%2 = OpImageSparseRead %1 %3 %4" + GetParam().image_operands + "\n";
166   EXPECT_THAT(CompiledInstructions(input),
167               Eq(MakeInstruction(SpvOpImageSparseRead, {1, 2, 3, 4},
168                                  GetParam().expected_mask_and_operands)));
169   // Test the disassembler.
170   EXPECT_THAT(EncodeAndDecodeSuccessfully(input), input);
171 }
172
173 #define MASK(NAME) SpvImageOperands##NAME##Mask
174 INSTANTIATE_TEST_CASE_P(ImageSparseReadImageOperandsAny,
175                         ImageSparseReadImageOperandsTest,
176                         ::testing::ValuesIn(std::vector<ImageOperandsCase>{
177                             // Image operands are optional.
178                             {"", {}},
179                             // Test each kind, alone.
180                             {" Bias %5", {MASK(Bias), 5}},
181                             {" Lod %5", {MASK(Lod), 5}},
182                             {" Grad %5 %6", {MASK(Grad), 5, 6}},
183                             {" ConstOffset %5", {MASK(ConstOffset), 5}},
184                             {" Offset %5", {MASK(Offset), 5}},
185                             {" ConstOffsets %5", {MASK(ConstOffsets), 5}},
186                             {" Sample %5", {MASK(Sample), 5}},
187                             {" MinLod %5", {MASK(MinLod), 5}},
188                         }),);
189 #undef MASK
190 #define MASK(NAME) static_cast<uint32_t>(SpvImageOperands##NAME##Mask)
191 INSTANTIATE_TEST_CASE_P(
192     ImageSparseReadImageOperandsCombination, ImageSparseReadImageOperandsTest,
193     ::testing::ValuesIn(std::vector<ImageOperandsCase>{
194         // values.
195         // Test adjacent pairs, so we can easily debug the values when it fails.
196         {" Bias|Lod %5 %6", {MASK(Bias) | MASK(Lod), 5, 6}},
197         {" Lod|Grad %5 %6 %7", {MASK(Lod) | MASK(Grad), 5, 6, 7}},
198         {" Grad|ConstOffset %5 %6 %7",
199          {MASK(Grad) | MASK(ConstOffset), 5, 6, 7}},
200         {" ConstOffset|Offset %5 %6", {MASK(ConstOffset) | MASK(Offset), 5, 6}},
201         {" Offset|ConstOffsets %5 %6",
202          {MASK(Offset) | MASK(ConstOffsets), 5, 6}},
203         {" ConstOffsets|Sample %5 %6",
204          {MASK(ConstOffsets) | MASK(Sample), 5, 6}},
205         // Test all masks together.
206         {" Bias|Lod|Grad|ConstOffset|Offset|ConstOffsets|Sample"
207          " %5 %6 %7 %8 %9 %10 %11 %12",
208          {MASK(Bias) | MASK(Lod) | MASK(Grad) | MASK(ConstOffset) |
209               MASK(Offset) | MASK(ConstOffsets) | MASK(Sample),
210           5, 6, 7, 8, 9, 10, 11, 12}},
211         // Don't try the masks reversed, since this is a round trip test,
212         // and the disassembler will sort them.
213     }),);
214 #undef MASK
215
216 TEST_F(OpImageSparseReadTest, InvalidTypeOperand) {
217   EXPECT_THAT(CompileFailure("%2 = OpImageSparseRead 42"),
218               Eq("Expected id to start with %."));
219 }
220
221 TEST_F(OpImageSparseReadTest, MissingImageOperand) {
222   EXPECT_THAT(CompileFailure("%2 = OpImageSparseRead %1"),
223               Eq("Expected operand, found end of stream."));
224 }
225
226 TEST_F(OpImageSparseReadTest, InvalidImageOperand) {
227   EXPECT_THAT(CompileFailure("%2 = OpImageSparseRead %1 1000"),
228               Eq("Expected id to start with %."));
229 }
230
231 TEST_F(OpImageSparseReadTest, MissingCoordinateOperand) {
232   EXPECT_THAT(CompileFailure("%2 = OpImageSparseRead %1 %2"),
233               Eq("Expected operand, found end of stream."));
234 }
235
236 TEST_F(OpImageSparseReadTest, InvalidCoordinateOperand) {
237   EXPECT_THAT(CompileFailure("%2 = OpImageSparseRead %1 %2 1000"),
238               Eq("Expected id to start with %."));
239 }
240
241 // TODO(dneto): OpSampledImage
242 // TODO(dneto): OpImageSampleImplicitLod
243 // TODO(dneto): OpImageSampleExplicitLod
244 // TODO(dneto): OpImageSampleDrefImplicitLod
245 // TODO(dneto): OpImageSampleDrefExplicitLod
246 // TODO(dneto): OpImageSampleProjImplicitLod
247 // TODO(dneto): OpImageSampleProjExplicitLod
248 // TODO(dneto): OpImageSampleProjDrefImplicitLod
249 // TODO(dneto): OpImageSampleProjDrefExplicitLod
250 // TODO(dneto): OpImageGather
251 // TODO(dneto): OpImageDrefGather
252 // TODO(dneto): OpImageRead
253 // TODO(dneto): OpImageWrite
254 // TODO(dneto): OpImageQueryFormat
255 // TODO(dneto): OpImageQueryOrder
256 // TODO(dneto): OpImageQuerySizeLod
257 // TODO(dneto): OpImageQuerySize
258 // TODO(dneto): OpImageQueryLod
259 // TODO(dneto): OpImageQueryLevels
260 // TODO(dneto): OpImageQuerySamples
261 // TODO(dneto): OpImageSparseSampleImplicitLod
262 // TODO(dneto): OpImageSparseSampleExplicitLod
263 // TODO(dneto): OpImageSparseSampleDrefImplicitLod
264 // TODO(dneto): OpImageSparseSampleDrefExplicitLod
265 // TODO(dneto): OpImageSparseSampleProjImplicitLod
266 // TODO(dneto): OpImageSparseSampleProjExplicitLod
267 // TODO(dneto): OpImageSparseSampleProjDrefImplicitLod
268 // TODO(dneto): OpImageSparseSampleProjDrefExplicitLod
269 // TODO(dneto): OpImageSparseFetch
270 // TODO(dneto): OpImageSparseDrefGather
271 // TODO(dneto): OpImageSparseTexelsResident
272
273 }  // anonymous namespace