1 // Copyright 2020 The Amber Authors.
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 parseried.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "gtest/gtest.h"
16 #include "src/amberscript/parser.h"
17
18 namespace amber {
19 namespace amberscript {
20
21 using AmberScriptParserTest = testing::Test;
22
TEST_F(AmberScriptParserTest,StencilAllValues)23 TEST_F(AmberScriptParserTest, StencilAllValues) {
24 std::string in = R"(
25 SHADER vertex my_shader PASSTHROUGH
26 SHADER fragment my_fragment GLSL
27 # GLSL Shader
28 END
29 BUFFER my_fb FORMAT R32G32B32A32_SFLOAT
30 BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT
31
32 PIPELINE graphics my_pipeline
33 ATTACH my_shader
34 ATTACH my_fragment
35 BIND BUFFER my_fb AS color LOCATION 0
36 BIND BUFFER my_ds AS depth_stencil
37
38 STENCIL front
39 TEST on
40 FAIL_OP increment_and_clamp
41 PASS_OP invert
42 DEPTH_FAIL_OP keep
43 COMPARE_OP equal
44 COMPARE_MASK 1
45 WRITE_MASK 2
46 REFERENCE 3
47 END
48 STENCIL back
49 TEST on
50 FAIL_OP zero
51 PASS_OP increment_and_wrap
52 DEPTH_FAIL_OP replace
53 COMPARE_OP greater
54 COMPARE_MASK 4
55 WRITE_MASK 5
56 REFERENCE 6
57 END
58 END)";
59
60 Parser parser;
61 Result r = parser.Parse(in);
62 ASSERT_TRUE(r.IsSuccess()) << r.Error();
63
64 auto script = parser.GetScript();
65 const auto& pipelines = script->GetPipelines();
66 ASSERT_EQ(1U, pipelines.size());
67
68 auto* pipeline = pipelines[0].get();
69 ASSERT_NE(nullptr, pipeline->GetDepthStencilBuffer().buffer);
70
71 ASSERT_TRUE(pipeline->GetPipelineData()->GetEnableStencilTest());
72 ASSERT_EQ(StencilOp::kIncrementAndClamp,
73 pipeline->GetPipelineData()->GetFrontFailOp());
74 ASSERT_EQ(StencilOp::kZero, pipeline->GetPipelineData()->GetBackFailOp());
75 ASSERT_EQ(StencilOp::kInvert, pipeline->GetPipelineData()->GetFrontPassOp());
76 ASSERT_EQ(StencilOp::kIncrementAndWrap,
77 pipeline->GetPipelineData()->GetBackPassOp());
78 ASSERT_EQ(StencilOp::kKeep,
79 pipeline->GetPipelineData()->GetFrontDepthFailOp());
80 ASSERT_EQ(StencilOp::kReplace,
81 pipeline->GetPipelineData()->GetBackDepthFailOp());
82 ASSERT_EQ(CompareOp::kEqual,
83 pipeline->GetPipelineData()->GetFrontCompareOp());
84 ASSERT_EQ(CompareOp::kGreater,
85 pipeline->GetPipelineData()->GetBackCompareOp());
86
87 ASSERT_EQ(1u, pipeline->GetPipelineData()->GetFrontCompareMask());
88 ASSERT_EQ(4u, pipeline->GetPipelineData()->GetBackCompareMask());
89 ASSERT_EQ(2u, pipeline->GetPipelineData()->GetFrontWriteMask());
90 ASSERT_EQ(5u, pipeline->GetPipelineData()->GetBackWriteMask());
91 ASSERT_EQ(3u, pipeline->GetPipelineData()->GetFrontReference());
92 ASSERT_EQ(6u, pipeline->GetPipelineData()->GetBackReference());
93 }
94
TEST_F(AmberScriptParserTest,StencilMissingFace)95 TEST_F(AmberScriptParserTest, StencilMissingFace) {
96 std::string in = R"(
97 SHADER vertex my_shader PASSTHROUGH
98 SHADER fragment my_fragment GLSL
99 # GLSL Shader
100 END
101 BUFFER my_fb FORMAT R32G32B32A32_SFLOAT
102 BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT
103
104 PIPELINE graphics my_pipeline
105 ATTACH my_shader
106 ATTACH my_fragment
107 BIND BUFFER my_fb AS color LOCATION 0
108 BIND BUFFER my_ds AS depth_stencil
109
110 STENCIL
111 TEST on
112 END
113 END)";
114
115 Parser parser;
116 Result r = parser.Parse(in);
117 ASSERT_FALSE(r.IsSuccess()) << r.Error();
118 EXPECT_EQ("16: STENCIL missing face", r.Error());
119 }
120
TEST_F(AmberScriptParserTest,StencilInvalidFaceValue)121 TEST_F(AmberScriptParserTest, StencilInvalidFaceValue) {
122 std::string in = R"(
123 SHADER vertex my_shader PASSTHROUGH
124 SHADER fragment my_fragment GLSL
125 # GLSL Shader
126 END
127 BUFFER my_fb FORMAT R32G32B32A32_SFLOAT
128 BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT
129
130 PIPELINE graphics my_pipeline
131 ATTACH my_shader
132 ATTACH my_fragment
133 BIND BUFFER my_fb AS color LOCATION 0
134 BIND BUFFER my_ds AS depth_stencil
135
136 STENCIL foo
137 TEST on
138 END
139 END)";
140
141 Parser parser;
142 Result r = parser.Parse(in);
143 ASSERT_FALSE(r.IsSuccess()) << r.Error();
144 EXPECT_EQ("15: STENCIL invalid face: foo", r.Error());
145 }
146
TEST_F(AmberScriptParserTest,StencilTestMissingValue)147 TEST_F(AmberScriptParserTest, StencilTestMissingValue) {
148 std::string in = R"(
149 SHADER vertex my_shader PASSTHROUGH
150 SHADER fragment my_fragment GLSL
151 # GLSL Shader
152 END
153 BUFFER my_fb FORMAT R32G32B32A32_SFLOAT
154 BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT
155
156 PIPELINE graphics my_pipeline
157 ATTACH my_shader
158 ATTACH my_fragment
159 BIND BUFFER my_fb AS color LOCATION 0
160 BIND BUFFER my_ds AS depth_stencil
161
162 STENCIL front
163 TEST
164 END
165 END)";
166
167 Parser parser;
168 Result r = parser.Parse(in);
169 ASSERT_FALSE(r.IsSuccess()) << r.Error();
170 EXPECT_EQ("17: STENCIL invalid value for TEST", r.Error());
171 }
172
TEST_F(AmberScriptParserTest,StencilTestInvalidValue)173 TEST_F(AmberScriptParserTest, StencilTestInvalidValue) {
174 std::string in = R"(
175 SHADER vertex my_shader PASSTHROUGH
176 SHADER fragment my_fragment GLSL
177 # GLSL Shader
178 END
179 BUFFER my_fb FORMAT R32G32B32A32_SFLOAT
180 BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT
181
182 PIPELINE graphics my_pipeline
183 ATTACH my_shader
184 ATTACH my_fragment
185 BIND BUFFER my_fb AS color LOCATION 0
186 BIND BUFFER my_ds AS depth_stencil
187
188 STENCIL front
189 TEST foo
190 END
191 END)";
192
193 Parser parser;
194 Result r = parser.Parse(in);
195 ASSERT_FALSE(r.IsSuccess()) << r.Error();
196 EXPECT_EQ("16: STENCIL invalid value for TEST: foo", r.Error());
197 }
198
TEST_F(AmberScriptParserTest,StencilFailMissingValue)199 TEST_F(AmberScriptParserTest, StencilFailMissingValue) {
200 std::string in = R"(
201 SHADER vertex my_shader PASSTHROUGH
202 SHADER fragment my_fragment GLSL
203 # GLSL Shader
204 END
205 BUFFER my_fb FORMAT R32G32B32A32_SFLOAT
206 BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT
207
208 PIPELINE graphics my_pipeline
209 ATTACH my_shader
210 ATTACH my_fragment
211 BIND BUFFER my_fb AS color LOCATION 0
212 BIND BUFFER my_ds AS depth_stencil
213
214 STENCIL front
215 TEST on
216 FAIL_OP
217 END
218 END)";
219
220 Parser parser;
221 Result r = parser.Parse(in);
222 ASSERT_FALSE(r.IsSuccess()) << r.Error();
223 EXPECT_EQ("18: STENCIL invalid value for FAIL_OP", r.Error());
224 }
225
TEST_F(AmberScriptParserTest,StencilFailInvalidValue)226 TEST_F(AmberScriptParserTest, StencilFailInvalidValue) {
227 std::string in = R"(
228 SHADER vertex my_shader PASSTHROUGH
229 SHADER fragment my_fragment GLSL
230 # GLSL Shader
231 END
232 BUFFER my_fb FORMAT R32G32B32A32_SFLOAT
233 BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT
234
235 PIPELINE graphics my_pipeline
236 ATTACH my_shader
237 ATTACH my_fragment
238 BIND BUFFER my_fb AS color LOCATION 0
239 BIND BUFFER my_ds AS depth_stencil
240
241 STENCIL front
242 TEST on
243 FAIL_OP foo
244 END
245 END)";
246
247 Parser parser;
248 Result r = parser.Parse(in);
249 ASSERT_FALSE(r.IsSuccess()) << r.Error();
250 EXPECT_EQ("17: STENCIL invalid value for FAIL_OP: foo", r.Error());
251 }
252
TEST_F(AmberScriptParserTest,StencilPassMissingValue)253 TEST_F(AmberScriptParserTest, StencilPassMissingValue) {
254 std::string in = R"(
255 SHADER vertex my_shader PASSTHROUGH
256 SHADER fragment my_fragment GLSL
257 # GLSL Shader
258 END
259 BUFFER my_fb FORMAT R32G32B32A32_SFLOAT
260 BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT
261
262 PIPELINE graphics my_pipeline
263 ATTACH my_shader
264 ATTACH my_fragment
265 BIND BUFFER my_fb AS color LOCATION 0
266 BIND BUFFER my_ds AS depth_stencil
267
268 STENCIL front
269 TEST on
270 PASS_OP
271 END
272 END)";
273
274 Parser parser;
275 Result r = parser.Parse(in);
276 ASSERT_FALSE(r.IsSuccess()) << r.Error();
277 EXPECT_EQ("18: STENCIL invalid value for PASS_OP", r.Error());
278 }
279
TEST_F(AmberScriptParserTest,StencilPassInvalidValue)280 TEST_F(AmberScriptParserTest, StencilPassInvalidValue) {
281 std::string in = R"(
282 SHADER vertex my_shader PASSTHROUGH
283 SHADER fragment my_fragment GLSL
284 # GLSL Shader
285 END
286 BUFFER my_fb FORMAT R32G32B32A32_SFLOAT
287 BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT
288
289 PIPELINE graphics my_pipeline
290 ATTACH my_shader
291 ATTACH my_fragment
292 BIND BUFFER my_fb AS color LOCATION 0
293 BIND BUFFER my_ds AS depth_stencil
294
295 STENCIL front
296 TEST on
297 PASS_OP foo
298 END
299 END)";
300
301 Parser parser;
302 Result r = parser.Parse(in);
303 ASSERT_FALSE(r.IsSuccess()) << r.Error();
304 EXPECT_EQ("17: STENCIL invalid value for PASS_OP: foo", r.Error());
305 }
306
TEST_F(AmberScriptParserTest,StencilDepthFailMissingValue)307 TEST_F(AmberScriptParserTest, StencilDepthFailMissingValue) {
308 std::string in = R"(
309 SHADER vertex my_shader PASSTHROUGH
310 SHADER fragment my_fragment GLSL
311 # GLSL Shader
312 END
313 BUFFER my_fb FORMAT R32G32B32A32_SFLOAT
314 BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT
315
316 PIPELINE graphics my_pipeline
317 ATTACH my_shader
318 ATTACH my_fragment
319 BIND BUFFER my_fb AS color LOCATION 0
320 BIND BUFFER my_ds AS depth_stencil
321
322 STENCIL front
323 TEST on
324 DEPTH_FAIL_OP
325 END
326 END)";
327
328 Parser parser;
329 Result r = parser.Parse(in);
330 ASSERT_FALSE(r.IsSuccess()) << r.Error();
331 EXPECT_EQ("18: STENCIL invalid value for DEPTH_FAIL_OP", r.Error());
332 }
333
TEST_F(AmberScriptParserTest,StencilDepthFailInvalidValue)334 TEST_F(AmberScriptParserTest, StencilDepthFailInvalidValue) {
335 std::string in = R"(
336 SHADER vertex my_shader PASSTHROUGH
337 SHADER fragment my_fragment GLSL
338 # GLSL Shader
339 END
340 BUFFER my_fb FORMAT R32G32B32A32_SFLOAT
341 BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT
342
343 PIPELINE graphics my_pipeline
344 ATTACH my_shader
345 ATTACH my_fragment
346 BIND BUFFER my_fb AS color LOCATION 0
347 BIND BUFFER my_ds AS depth_stencil
348
349 STENCIL front
350 TEST on
351 DEPTH_FAIL_OP foo
352 END
353 END)";
354
355 Parser parser;
356 Result r = parser.Parse(in);
357 ASSERT_FALSE(r.IsSuccess()) << r.Error();
358 EXPECT_EQ("17: STENCIL invalid value for DEPTH_FAIL_OP: foo", r.Error());
359 }
360
TEST_F(AmberScriptParserTest,StencilCompareMissingValue)361 TEST_F(AmberScriptParserTest, StencilCompareMissingValue) {
362 std::string in = R"(
363 SHADER vertex my_shader PASSTHROUGH
364 SHADER fragment my_fragment GLSL
365 # GLSL Shader
366 END
367 BUFFER my_fb FORMAT R32G32B32A32_SFLOAT
368 BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT
369
370 PIPELINE graphics my_pipeline
371 ATTACH my_shader
372 ATTACH my_fragment
373 BIND BUFFER my_fb AS color LOCATION 0
374 BIND BUFFER my_ds AS depth_stencil
375
376 STENCIL front
377 TEST on
378 COMPARE_OP
379 END
380 END)";
381
382 Parser parser;
383 Result r = parser.Parse(in);
384 ASSERT_FALSE(r.IsSuccess()) << r.Error();
385 EXPECT_EQ("18: STENCIL invalid value for COMPARE_OP", r.Error());
386 }
387
TEST_F(AmberScriptParserTest,StencilCompareInvalidValue)388 TEST_F(AmberScriptParserTest, StencilCompareInvalidValue) {
389 std::string in = R"(
390 SHADER vertex my_shader PASSTHROUGH
391 SHADER fragment my_fragment GLSL
392 # GLSL Shader
393 END
394 BUFFER my_fb FORMAT R32G32B32A32_SFLOAT
395 BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT
396
397 PIPELINE graphics my_pipeline
398 ATTACH my_shader
399 ATTACH my_fragment
400 BIND BUFFER my_fb AS color LOCATION 0
401 BIND BUFFER my_ds AS depth_stencil
402
403 STENCIL front
404 TEST on
405 COMPARE_OP foo
406 END
407 END)";
408
409 Parser parser;
410 Result r = parser.Parse(in);
411 ASSERT_FALSE(r.IsSuccess()) << r.Error();
412 EXPECT_EQ("17: STENCIL invalid value for COMPARE_OP: foo", r.Error());
413 }
414
TEST_F(AmberScriptParserTest,StencilCompareMaskMissingValue)415 TEST_F(AmberScriptParserTest, StencilCompareMaskMissingValue) {
416 std::string in = R"(
417 SHADER vertex my_shader PASSTHROUGH
418 SHADER fragment my_fragment GLSL
419 # GLSL Shader
420 END
421 BUFFER my_fb FORMAT R32G32B32A32_SFLOAT
422 BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT
423
424 PIPELINE graphics my_pipeline
425 ATTACH my_shader
426 ATTACH my_fragment
427 BIND BUFFER my_fb AS color LOCATION 0
428 BIND BUFFER my_ds AS depth_stencil
429
430 STENCIL front
431 TEST on
432 COMPARE_MASK
433 END
434 END)";
435
436 Parser parser;
437 Result r = parser.Parse(in);
438 ASSERT_FALSE(r.IsSuccess()) << r.Error();
439 EXPECT_EQ("18: STENCIL invalid value for COMPARE_MASK", r.Error());
440 }
441
TEST_F(AmberScriptParserTest,StencilCompareMaskInvalidValue)442 TEST_F(AmberScriptParserTest, StencilCompareMaskInvalidValue) {
443 std::string in = R"(
444 SHADER vertex my_shader PASSTHROUGH
445 SHADER fragment my_fragment GLSL
446 # GLSL Shader
447 END
448 BUFFER my_fb FORMAT R32G32B32A32_SFLOAT
449 BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT
450
451 PIPELINE graphics my_pipeline
452 ATTACH my_shader
453 ATTACH my_fragment
454 BIND BUFFER my_fb AS color LOCATION 0
455 BIND BUFFER my_ds AS depth_stencil
456
457 STENCIL front
458 TEST on
459 COMPARE_MASK foo
460 END
461 END)";
462
463 Parser parser;
464 Result r = parser.Parse(in);
465 ASSERT_FALSE(r.IsSuccess()) << r.Error();
466 EXPECT_EQ("17: STENCIL invalid value for COMPARE_MASK", r.Error());
467 }
468
TEST_F(AmberScriptParserTest,StencilWriteMaskMissingValue)469 TEST_F(AmberScriptParserTest, StencilWriteMaskMissingValue) {
470 std::string in = R"(
471 SHADER vertex my_shader PASSTHROUGH
472 SHADER fragment my_fragment GLSL
473 # GLSL Shader
474 END
475 BUFFER my_fb FORMAT R32G32B32A32_SFLOAT
476 BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT
477
478 PIPELINE graphics my_pipeline
479 ATTACH my_shader
480 ATTACH my_fragment
481 BIND BUFFER my_fb AS color LOCATION 0
482 BIND BUFFER my_ds AS depth_stencil
483
484 STENCIL front
485 TEST on
486 WRITE_MASK
487 END
488 END)";
489
490 Parser parser;
491 Result r = parser.Parse(in);
492 ASSERT_FALSE(r.IsSuccess()) << r.Error();
493 EXPECT_EQ("18: STENCIL invalid value for WRITE_MASK", r.Error());
494 }
495
TEST_F(AmberScriptParserTest,StencilWriteMaskInvalidValue)496 TEST_F(AmberScriptParserTest, StencilWriteMaskInvalidValue) {
497 std::string in = R"(
498 SHADER vertex my_shader PASSTHROUGH
499 SHADER fragment my_fragment GLSL
500 # GLSL Shader
501 END
502 BUFFER my_fb FORMAT R32G32B32A32_SFLOAT
503 BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT
504
505 PIPELINE graphics my_pipeline
506 ATTACH my_shader
507 ATTACH my_fragment
508 BIND BUFFER my_fb AS color LOCATION 0
509 BIND BUFFER my_ds AS depth_stencil
510
511 STENCIL front
512 TEST on
513 WRITE_MASK foo
514 END
515 END)";
516
517 Parser parser;
518 Result r = parser.Parse(in);
519 ASSERT_FALSE(r.IsSuccess()) << r.Error();
520 EXPECT_EQ("17: STENCIL invalid value for WRITE_MASK", r.Error());
521 }
522
TEST_F(AmberScriptParserTest,StencilReferenceMissingValue)523 TEST_F(AmberScriptParserTest, StencilReferenceMissingValue) {
524 std::string in = R"(
525 SHADER vertex my_shader PASSTHROUGH
526 SHADER fragment my_fragment GLSL
527 # GLSL Shader
528 END
529 BUFFER my_fb FORMAT R32G32B32A32_SFLOAT
530 BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT
531
532 PIPELINE graphics my_pipeline
533 ATTACH my_shader
534 ATTACH my_fragment
535 BIND BUFFER my_fb AS color LOCATION 0
536 BIND BUFFER my_ds AS depth_stencil
537
538 STENCIL front
539 TEST on
540 REFERENCE
541 END
542 END)";
543
544 Parser parser;
545 Result r = parser.Parse(in);
546 ASSERT_FALSE(r.IsSuccess()) << r.Error();
547 EXPECT_EQ("18: STENCIL invalid value for REFERENCE", r.Error());
548 }
549
TEST_F(AmberScriptParserTest,StencilReferenceInvalidValue)550 TEST_F(AmberScriptParserTest, StencilReferenceInvalidValue) {
551 std::string in = R"(
552 SHADER vertex my_shader PASSTHROUGH
553 SHADER fragment my_fragment GLSL
554 # GLSL Shader
555 END
556 BUFFER my_fb FORMAT R32G32B32A32_SFLOAT
557 BUFFER my_ds FORMAT D32_SFLOAT_S8_UINT
558
559 PIPELINE graphics my_pipeline
560 ATTACH my_shader
561 ATTACH my_fragment
562 BIND BUFFER my_fb AS color LOCATION 0
563 BIND BUFFER my_ds AS depth_stencil
564
565 STENCIL front
566 TEST on
567 REFERENCE foo
568 END
569 END)";
570
571 Parser parser;
572 Result r = parser.Parse(in);
573 ASSERT_FALSE(r.IsSuccess()) << r.Error();
574 EXPECT_EQ("17: STENCIL invalid value for REFERENCE", r.Error());
575 }
576
577 } // namespace amberscript
578 } // namespace amber
579