1 // Copyright 2019 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,RunCompute)23 TEST_F(AmberScriptParserTest, RunCompute) {
24 std::string in = R"(
25 SHADER compute my_shader GLSL
26 void main() {
27 gl_FragColor = vec3(2, 3, 4);
28 }
29 END
30
31 PIPELINE compute my_pipeline
32 ATTACH my_shader
33 END
34
35 RUN my_pipeline 2 4 5
36 )";
37
38 Parser parser;
39 Result r = parser.Parse(in);
40 ASSERT_TRUE(r.IsSuccess()) << r.Error();
41
42 auto script = parser.GetScript();
43 const auto& commands = script->GetCommands();
44 ASSERT_EQ(1U, commands.size());
45
46 auto* cmd = commands[0].get();
47 ASSERT_TRUE(cmd->IsCompute());
48 EXPECT_EQ(2U, cmd->AsCompute()->GetX());
49 EXPECT_EQ(4U, cmd->AsCompute()->GetY());
50 EXPECT_EQ(5U, cmd->AsCompute()->GetZ());
51 }
52
TEST_F(AmberScriptParserTest,RunWithoutPipeline)53 TEST_F(AmberScriptParserTest, RunWithoutPipeline) {
54 std::string in = R"(RUN 2 4 5)";
55
56 Parser parser;
57 Result r = parser.Parse(in);
58 ASSERT_FALSE(r.IsSuccess());
59 ASSERT_EQ("1: missing pipeline name for RUN command", r.Error());
60 }
61
TEST_F(AmberScriptParserTest,RunWithInvalidPipeline)62 TEST_F(AmberScriptParserTest, RunWithInvalidPipeline) {
63 std::string in = R"(RUN unknown_pipeline 2 4 5)";
64
65 Parser parser;
66 Result r = parser.Parse(in);
67 ASSERT_FALSE(r.IsSuccess());
68 ASSERT_EQ("1: unknown pipeline for RUN command: unknown_pipeline", r.Error());
69 }
70
TEST_F(AmberScriptParserTest,RunComputeWithGraphicsPipeline)71 TEST_F(AmberScriptParserTest, RunComputeWithGraphicsPipeline) {
72 std::string in = R"(
73 SHADER vertex my_shader PASSTHROUGH
74 SHADER fragment my_fragment GLSL
75 # GLSL Shader
76 END
77
78 PIPELINE graphics my_pipeline
79 ATTACH my_shader
80 ATTACH my_fragment
81 END
82
83 RUN my_pipeline 2 4 5)";
84
85 Parser parser;
86 Result r = parser.Parse(in);
87 ASSERT_FALSE(r.IsSuccess());
88 ASSERT_EQ("12: RUN command requires compute pipeline", r.Error());
89 }
90
TEST_F(AmberScriptParserTest,RunComputeMissingParams)91 TEST_F(AmberScriptParserTest, RunComputeMissingParams) {
92 std::string in = R"(
93 SHADER compute my_shader GLSL
94 void main() {
95 gl_FragColor = vec3(2, 3, 4);
96 }
97 END
98
99 PIPELINE compute my_pipeline
100 ATTACH my_shader
101 END
102
103 RUN my_pipeline)";
104
105 Parser parser;
106 Result r = parser.Parse(in);
107 ASSERT_FALSE(r.IsSuccess());
108 ASSERT_EQ("12: RUN command requires parameters", r.Error());
109 }
110
TEST_F(AmberScriptParserTest,RunComputeExtraParams)111 TEST_F(AmberScriptParserTest, RunComputeExtraParams) {
112 std::string in = R"(
113 SHADER compute my_shader GLSL
114 void main() {
115 gl_FragColor = vec3(2, 3, 4);
116 }
117 END
118
119 PIPELINE compute my_pipeline
120 ATTACH my_shader
121 END
122
123 RUN my_pipeline 2 4 5 EXTRA)";
124
125 Parser parser;
126 Result r = parser.Parse(in);
127 ASSERT_FALSE(r.IsSuccess());
128 ASSERT_EQ("12: extra parameters after RUN command", r.Error());
129 }
130
TEST_F(AmberScriptParserTest,RunComputeInvalidZ)131 TEST_F(AmberScriptParserTest, RunComputeInvalidZ) {
132 std::string in = R"(
133 SHADER compute my_shader GLSL
134 void main() {
135 gl_FragColor = vec3(2, 3, 4);
136 }
137 END
138
139 PIPELINE compute my_pipeline
140 ATTACH my_shader
141 END
142
143 RUN my_pipeline 2 4 INVALID)";
144
145 Parser parser;
146 Result r = parser.Parse(in);
147 ASSERT_FALSE(r.IsSuccess());
148 ASSERT_EQ("12: invalid parameter for RUN command: INVALID", r.Error());
149 }
150
TEST_F(AmberScriptParserTest,RunComputeInvalidY)151 TEST_F(AmberScriptParserTest, RunComputeInvalidY) {
152 std::string in = R"(
153 SHADER compute my_shader GLSL
154 void main() {
155 gl_FragColor = vec3(2, 3, 4);
156 }
157 END
158
159 PIPELINE compute my_pipeline
160 ATTACH my_shader
161 END
162
163 RUN my_pipeline 2 INVALID 5)";
164
165 Parser parser;
166 Result r = parser.Parse(in);
167 ASSERT_FALSE(r.IsSuccess());
168 ASSERT_EQ("12: invalid parameter for RUN command: INVALID", r.Error());
169 }
170
TEST_F(AmberScriptParserTest,RunComputeInvalidX)171 TEST_F(AmberScriptParserTest, RunComputeInvalidX) {
172 std::string in = R"(
173 SHADER compute my_shader GLSL
174 void main() {
175 gl_FragColor = vec3(2, 3, 4);
176 }
177 END
178
179 PIPELINE compute my_pipeline
180 ATTACH my_shader
181 END
182
183 RUN my_pipeline INVALID 4 5)";
184
185 Parser parser;
186 Result r = parser.Parse(in);
187 ASSERT_FALSE(r.IsSuccess());
188 ASSERT_EQ("12: invalid token in RUN command: INVALID", r.Error());
189 }
190
TEST_F(AmberScriptParserTest,RunDrawRect)191 TEST_F(AmberScriptParserTest, RunDrawRect) {
192 std::string in = R"(
193 SHADER vertex my_shader PASSTHROUGH
194 SHADER fragment my_fragment GLSL
195 # GLSL Shader
196 END
197
198 PIPELINE graphics my_pipeline
199 ATTACH my_shader
200 ATTACH my_fragment
201 END
202
203 RUN my_pipeline DRAW_RECT POS 2 4 SIZE 10 20)";
204
205 Parser parser;
206 Result r = parser.Parse(in);
207 ASSERT_TRUE(r.IsSuccess()) << r.Error();
208
209 auto script = parser.GetScript();
210 const auto& commands = script->GetCommands();
211 ASSERT_EQ(1U, commands.size());
212
213 auto* cmd = commands[0].get();
214 ASSERT_TRUE(cmd->IsDrawRect());
215 EXPECT_TRUE(cmd->AsDrawRect()->IsOrtho());
216 EXPECT_FALSE(cmd->AsDrawRect()->IsPatch());
217 EXPECT_FLOAT_EQ(2.f, cmd->AsDrawRect()->GetX());
218 EXPECT_FLOAT_EQ(4.f, cmd->AsDrawRect()->GetY());
219 EXPECT_FLOAT_EQ(10.f, cmd->AsDrawRect()->GetWidth());
220 EXPECT_FLOAT_EQ(20.f, cmd->AsDrawRect()->GetHeight());
221 }
222
TEST_F(AmberScriptParserTest,RunDrawRectWithComputePipelineInvalid)223 TEST_F(AmberScriptParserTest, RunDrawRectWithComputePipelineInvalid) {
224 std::string in = R"(
225 SHADER compute my_shader GLSL
226 void main() {
227 gl_FragColor = vec3(2, 3, 4);
228 }
229 END
230
231 PIPELINE compute my_pipeline
232 ATTACH my_shader
233 END
234
235 RUN my_pipeline DRAW_RECT POS 2 4 SIZE 10 20)";
236
237 Parser parser;
238 Result r = parser.Parse(in);
239 ASSERT_FALSE(r.IsSuccess());
240 ASSERT_EQ("12: RUN command requires graphics pipeline", r.Error());
241 }
242
TEST_F(AmberScriptParserTest,RunDrawRectWithMissingPipeline)243 TEST_F(AmberScriptParserTest, RunDrawRectWithMissingPipeline) {
244 std::string in = R"(RUN my_pipeline DRAW_RECT POS 2 4 SIZE 10 20)";
245
246 Parser parser;
247 Result r = parser.Parse(in);
248 ASSERT_FALSE(r.IsSuccess());
249 ASSERT_EQ("1: unknown pipeline for RUN command: my_pipeline", r.Error());
250 }
251
TEST_F(AmberScriptParserTest,RunDrawRectMissingValues)252 TEST_F(AmberScriptParserTest, RunDrawRectMissingValues) {
253 std::string in = R"(
254 SHADER vertex my_shader PASSTHROUGH
255 SHADER fragment my_fragment GLSL
256 # GLSL Shader
257 END
258
259 PIPELINE graphics my_pipeline
260 ATTACH my_shader
261 ATTACH my_fragment
262 END
263
264 RUN my_pipeline DRAW_RECT)";
265
266 Parser parser;
267 Result r = parser.Parse(in);
268 ASSERT_FALSE(r.IsSuccess());
269 ASSERT_EQ("12: RUN DRAW_RECT command requires parameters", r.Error());
270 }
271
TEST_F(AmberScriptParserTest,RunDrawRectMissingPOS)272 TEST_F(AmberScriptParserTest, RunDrawRectMissingPOS) {
273 std::string in = R"(
274 SHADER vertex my_shader PASSTHROUGH
275 SHADER fragment my_fragment GLSL
276 # GLSL Shader
277 END
278
279 PIPELINE graphics my_pipeline
280 ATTACH my_shader
281 ATTACH my_fragment
282 END
283
284 RUN my_pipeline DRAW_RECT 2 4 SIZE 10 20)";
285
286 Parser parser;
287 Result r = parser.Parse(in);
288 ASSERT_FALSE(r.IsSuccess());
289 ASSERT_EQ("12: invalid token in RUN command: 2; expected POS", r.Error());
290 }
291
TEST_F(AmberScriptParserTest,RunDrawRectPOSMissingValues)292 TEST_F(AmberScriptParserTest, RunDrawRectPOSMissingValues) {
293 std::string in = R"(
294 SHADER vertex my_shader PASSTHROUGH
295 SHADER fragment my_fragment GLSL
296 # GLSL Shader
297 END
298
299 PIPELINE graphics my_pipeline
300 ATTACH my_shader
301 ATTACH my_fragment
302 END
303
304 RUN my_pipeline DRAW_RECT POS SIZE 10 20)";
305
306 Parser parser;
307 Result r = parser.Parse(in);
308 ASSERT_FALSE(r.IsSuccess());
309 ASSERT_EQ("12: missing X position for RUN command", r.Error());
310 }
311
TEST_F(AmberScriptParserTest,RunDrawRectMissingPOSY)312 TEST_F(AmberScriptParserTest, RunDrawRectMissingPOSY) {
313 std::string in = R"(
314 SHADER vertex my_shader PASSTHROUGH
315 SHADER fragment my_fragment GLSL
316 # GLSL Shader
317 END
318
319 PIPELINE graphics my_pipeline
320 ATTACH my_shader
321 ATTACH my_fragment
322 END
323
324 RUN my_pipeline DRAW_RECT POS 2 SIZE 10 20)";
325
326 Parser parser;
327 Result r = parser.Parse(in);
328 ASSERT_FALSE(r.IsSuccess());
329 ASSERT_EQ("12: missing Y position for RUN command", r.Error());
330 }
331
TEST_F(AmberScriptParserTest,RunDrawRectInvalidPOSX)332 TEST_F(AmberScriptParserTest, RunDrawRectInvalidPOSX) {
333 std::string in = R"(
334 SHADER vertex my_shader PASSTHROUGH
335 SHADER fragment my_fragment GLSL
336 # GLSL Shader
337 END
338
339 PIPELINE graphics my_pipeline
340 ATTACH my_shader
341 ATTACH my_fragment
342 END
343
344 RUN my_pipeline DRAW_RECT POS INVALID 4 SIZE 10 20)";
345
346 Parser parser;
347 Result r = parser.Parse(in);
348 ASSERT_FALSE(r.IsSuccess());
349 ASSERT_EQ("12: missing X position for RUN command", r.Error());
350 }
351
TEST_F(AmberScriptParserTest,RunDrawRectInavlidPOSY)352 TEST_F(AmberScriptParserTest, RunDrawRectInavlidPOSY) {
353 std::string in = R"(
354 SHADER vertex my_shader PASSTHROUGH
355 SHADER fragment my_fragment GLSL
356 # GLSL Shader
357 END
358
359 PIPELINE graphics my_pipeline
360 ATTACH my_shader
361 ATTACH my_fragment
362 END
363
364 RUN my_pipeline DRAW_RECT POS 2 INVALID SIZE 10 20)";
365
366 Parser parser;
367 Result r = parser.Parse(in);
368 ASSERT_FALSE(r.IsSuccess());
369 ASSERT_EQ("12: missing Y position for RUN command", r.Error());
370 }
371
TEST_F(AmberScriptParserTest,RunDrawRectMissingSize)372 TEST_F(AmberScriptParserTest, RunDrawRectMissingSize) {
373 std::string in = R"(
374 SHADER vertex my_shader PASSTHROUGH
375 SHADER fragment my_fragment GLSL
376 # GLSL Shader
377 END
378
379 PIPELINE graphics my_pipeline
380 ATTACH my_shader
381 ATTACH my_fragment
382 END
383
384 RUN my_pipeline DRAW_RECT POS 2 4 10 20)";
385
386 Parser parser;
387 Result r = parser.Parse(in);
388 ASSERT_FALSE(r.IsSuccess());
389 ASSERT_EQ("12: invalid token in RUN command: 10; expected SIZE", r.Error());
390 }
391
TEST_F(AmberScriptParserTest,RunDrawRectMissingSizeValues)392 TEST_F(AmberScriptParserTest, RunDrawRectMissingSizeValues) {
393 std::string in = R"(
394 SHADER vertex my_shader PASSTHROUGH
395 SHADER fragment my_fragment GLSL
396 # GLSL Shader
397 END
398
399 PIPELINE graphics my_pipeline
400 ATTACH my_shader
401 ATTACH my_fragment
402 END
403
404 RUN my_pipeline DRAW_RECT POS 2 4 SIZE)";
405
406 Parser parser;
407 Result r = parser.Parse(in);
408 ASSERT_FALSE(r.IsSuccess());
409 ASSERT_EQ("12: missing width value for RUN command", r.Error());
410 }
411
TEST_F(AmberScriptParserTest,RunDrawRectMissingSizeHeight)412 TEST_F(AmberScriptParserTest, RunDrawRectMissingSizeHeight) {
413 std::string in = R"(
414 SHADER vertex my_shader PASSTHROUGH
415 SHADER fragment my_fragment GLSL
416 # GLSL Shader
417 END
418
419 PIPELINE graphics my_pipeline
420 ATTACH my_shader
421 ATTACH my_fragment
422 END
423
424 RUN my_pipeline DRAW_RECT POS 2 4 SIZE 10)";
425
426 Parser parser;
427 Result r = parser.Parse(in);
428 ASSERT_FALSE(r.IsSuccess());
429 ASSERT_EQ("12: missing height value for RUN command", r.Error());
430 }
431
TEST_F(AmberScriptParserTest,RunDrawRectInvalidSizeWidth)432 TEST_F(AmberScriptParserTest, RunDrawRectInvalidSizeWidth) {
433 std::string in = R"(
434 SHADER vertex my_shader PASSTHROUGH
435 SHADER fragment my_fragment GLSL
436 # GLSL Shader
437 END
438
439 PIPELINE graphics my_pipeline
440 ATTACH my_shader
441 ATTACH my_fragment
442 END
443
444 RUN my_pipeline DRAW_RECT POS 2 4 SIZE INVALID 20)";
445
446 Parser parser;
447 Result r = parser.Parse(in);
448 ASSERT_FALSE(r.IsSuccess());
449 ASSERT_EQ("12: missing width value for RUN command", r.Error());
450 }
451
TEST_F(AmberScriptParserTest,RunDrawRectInvalidSizeHeight)452 TEST_F(AmberScriptParserTest, RunDrawRectInvalidSizeHeight) {
453 std::string in = R"(
454 SHADER vertex my_shader PASSTHROUGH
455 SHADER fragment my_fragment GLSL
456 # GLSL Shader
457 END
458
459 PIPELINE graphics my_pipeline
460 ATTACH my_shader
461 ATTACH my_fragment
462 END
463
464 RUN my_pipeline DRAW_RECT POS 2 4 SIZE 10 INVALID)";
465
466 Parser parser;
467 Result r = parser.Parse(in);
468 ASSERT_FALSE(r.IsSuccess());
469 ASSERT_EQ("12: missing height value for RUN command", r.Error());
470 }
471
TEST_F(AmberScriptParserTest,RunDrawRectExtraCommands)472 TEST_F(AmberScriptParserTest, RunDrawRectExtraCommands) {
473 std::string in = R"(
474 SHADER vertex my_shader PASSTHROUGH
475 SHADER fragment my_fragment GLSL
476 # GLSL Shader
477 END
478
479 PIPELINE graphics my_pipeline
480 ATTACH my_shader
481 ATTACH my_fragment
482 END
483
484 RUN my_pipeline DRAW_RECT POS 2 4 SIZE 10 20 EXTRA)";
485
486 Parser parser;
487 Result r = parser.Parse(in);
488 ASSERT_FALSE(r.IsSuccess());
489 ASSERT_EQ("12: extra parameters after RUN command", r.Error());
490 }
491
TEST_F(AmberScriptParserTest,RunDrawArrays)492 TEST_F(AmberScriptParserTest, RunDrawArrays) {
493 std::string in = R"(
494 SHADER vertex my_shader PASSTHROUGH
495 SHADER fragment my_fragment GLSL
496 # GLSL Shader
497 END
498 BUFFER vtex_buf DATA_TYPE vec3<float> DATA
499 1 2 3
500 4 5 6
501 7 8 9
502 END
503
504 PIPELINE graphics my_pipeline
505 ATTACH my_shader
506 ATTACH my_fragment
507 VERTEX_DATA vtex_buf LOCATION 0
508 END
509
510 RUN my_pipeline DRAW_ARRAY AS TRIANGLE_LIST START_IDX 1 COUNT 2)";
511
512 Parser parser;
513 Result r = parser.Parse(in);
514 ASSERT_TRUE(r.IsSuccess()) << r.Error();
515
516 auto script = parser.GetScript();
517 const auto& commands = script->GetCommands();
518 ASSERT_EQ(1U, commands.size());
519
520 ASSERT_TRUE(commands[0]->IsDrawArrays());
521
522 auto* cmd = commands[0]->AsDrawArrays();
523 EXPECT_FALSE(cmd->IsIndexed());
524 EXPECT_FALSE(cmd->IsInstanced());
525 EXPECT_EQ(static_cast<uint32_t>(0U), cmd->GetInstanceCount());
526 EXPECT_EQ(Topology::kTriangleList, cmd->GetTopology());
527 EXPECT_EQ(1U, cmd->GetFirstVertexIndex());
528 EXPECT_EQ(2U, cmd->GetVertexCount());
529 }
530
TEST_F(AmberScriptParserTest,RunDrawArraysCountOmitted)531 TEST_F(AmberScriptParserTest, RunDrawArraysCountOmitted) {
532 std::string in = R"(
533 SHADER vertex my_shader PASSTHROUGH
534 SHADER fragment my_fragment GLSL
535 # GLSL Shader
536 END
537 BUFFER vtex_buf DATA_TYPE vec3<float> DATA
538 1 2 3
539 4 5 6
540 7 8 9
541 END
542
543 PIPELINE graphics my_pipeline
544 ATTACH my_shader
545 ATTACH my_fragment
546 VERTEX_DATA vtex_buf LOCATION 0
547 END
548
549 RUN my_pipeline DRAW_ARRAY AS TRIANGLE_LIST START_IDX 1)";
550
551 Parser parser;
552 Result r = parser.Parse(in);
553 ASSERT_TRUE(r.IsSuccess()) << r.Error();
554
555 auto script = parser.GetScript();
556 const auto& commands = script->GetCommands();
557 ASSERT_EQ(1U, commands.size());
558
559 ASSERT_TRUE(commands[0]->IsDrawArrays());
560
561 auto* cmd = commands[0]->AsDrawArrays();
562 EXPECT_FALSE(cmd->IsIndexed());
563 EXPECT_FALSE(cmd->IsInstanced());
564 EXPECT_EQ(static_cast<uint32_t>(0U), cmd->GetInstanceCount());
565 EXPECT_EQ(Topology::kTriangleList, cmd->GetTopology());
566 EXPECT_EQ(1U, cmd->GetFirstVertexIndex());
567 // There are 3 elements in the vertex buffer, but we start at element 1.
568 EXPECT_EQ(2U, cmd->GetVertexCount());
569 }
570
TEST_F(AmberScriptParserTest,RunDrawArraysStartIdxAndCountOmitted)571 TEST_F(AmberScriptParserTest, RunDrawArraysStartIdxAndCountOmitted) {
572 std::string in = R"(
573 SHADER vertex my_shader PASSTHROUGH
574 SHADER fragment my_fragment GLSL
575 # GLSL Shader
576 END
577 BUFFER vtex_buf DATA_TYPE vec3<float> DATA
578 1 2 3
579 4 5 6
580 7 8 9
581 END
582
583 PIPELINE graphics my_pipeline
584 ATTACH my_shader
585 ATTACH my_fragment
586 VERTEX_DATA vtex_buf LOCATION 0
587 END
588
589 RUN my_pipeline DRAW_ARRAY AS TRIANGLE_LIST)";
590
591 Parser parser;
592 Result r = parser.Parse(in);
593 ASSERT_TRUE(r.IsSuccess()) << r.Error();
594
595 auto script = parser.GetScript();
596 const auto& commands = script->GetCommands();
597 ASSERT_EQ(1U, commands.size());
598
599 ASSERT_TRUE(commands[0]->IsDrawArrays());
600
601 auto* cmd = commands[0]->AsDrawArrays();
602 EXPECT_FALSE(cmd->IsIndexed());
603 EXPECT_FALSE(cmd->IsInstanced());
604 EXPECT_EQ(static_cast<uint32_t>(0U), cmd->GetInstanceCount());
605 EXPECT_EQ(Topology::kTriangleList, cmd->GetTopology());
606 EXPECT_EQ(static_cast<uint32_t>(0U), cmd->GetFirstVertexIndex());
607 // There are 3 elements in the vertex buffer.
608 EXPECT_EQ(3U, cmd->GetVertexCount());
609 }
610
TEST_F(AmberScriptParserTest,RunDrawArraysIndexed)611 TEST_F(AmberScriptParserTest, RunDrawArraysIndexed) {
612 std::string in = R"(
613 SHADER vertex my_shader PASSTHROUGH
614 SHADER fragment my_fragment GLSL
615 # GLSL Shader
616 END
617 BUFFER vtex_buf DATA_TYPE vec3<float> DATA
618 1 2 3
619 4 5 6
620 7 8 9
621 END
622 BUFFER idx_buf DATA_TYPE vec3<float> DATA
623 9 8 7
624 6 5 4
625 3 2 1
626 END
627
628 PIPELINE graphics my_pipeline
629 ATTACH my_shader
630 ATTACH my_fragment
631 VERTEX_DATA vtex_buf LOCATION 0
632 INDEX_DATA idx_buf
633 END
634
635 RUN my_pipeline DRAW_ARRAY AS TRIANGLE_LIST INDEXED)";
636
637 Parser parser;
638 Result r = parser.Parse(in);
639 ASSERT_TRUE(r.IsSuccess()) << r.Error();
640
641 auto script = parser.GetScript();
642 const auto& commands = script->GetCommands();
643 ASSERT_EQ(1U, commands.size());
644
645 ASSERT_TRUE(commands[0]->IsDrawArrays());
646
647 auto* cmd = commands[0]->AsDrawArrays();
648 EXPECT_TRUE(cmd->IsIndexed());
649 EXPECT_FALSE(cmd->IsInstanced());
650 EXPECT_EQ(static_cast<uint32_t>(0U), cmd->GetInstanceCount());
651 EXPECT_EQ(Topology::kTriangleList, cmd->GetTopology());
652 EXPECT_EQ(static_cast<uint32_t>(0U), cmd->GetFirstVertexIndex());
653 // There are 3 elements in the vertex buffer.
654 EXPECT_EQ(3U, cmd->GetVertexCount());
655 }
656
TEST_F(AmberScriptParserTest,RunDrawArraysIndexedMissingIndexData)657 TEST_F(AmberScriptParserTest, RunDrawArraysIndexedMissingIndexData) {
658 std::string in = R"(
659 SHADER vertex my_shader PASSTHROUGH
660 SHADER fragment my_fragment GLSL
661 # GLSL Shader
662 END
663 BUFFER vtex_buf DATA_TYPE vec3<float> DATA
664 1 2 3
665 4 5 6
666 7 8 9
667 END
668
669 PIPELINE graphics my_pipeline
670 ATTACH my_shader
671 ATTACH my_fragment
672 VERTEX_DATA vtex_buf LOCATION 0
673 END
674
675 RUN my_pipeline DRAW_ARRAY AS TRIANGLE_LIST INDEXED)";
676
677 Parser parser;
678 Result r = parser.Parse(in);
679 ASSERT_FALSE(r.IsSuccess());
680
681 EXPECT_EQ("18: RUN DRAW_ARRAYS INDEXED requires attached index buffer",
682 r.Error());
683 }
684
TEST_F(AmberScriptParserTest,RunDrawArraysMissingVertexBuffer)685 TEST_F(AmberScriptParserTest, RunDrawArraysMissingVertexBuffer) {
686 std::string in = R"(
687 SHADER vertex my_shader PASSTHROUGH
688 SHADER fragment my_fragment GLSL
689 # GLSL Shader
690 END
691
692 PIPELINE graphics my_pipeline
693 ATTACH my_shader
694 ATTACH my_fragment
695 END
696
697 RUN my_pipeline DRAW_ARRAY TRIANGLE_LIST START_IDX 1 COUNT 2)";
698
699 Parser parser;
700 Result r = parser.Parse(in);
701 ASSERT_FALSE(r.IsSuccess());
702 EXPECT_EQ("12: RUN DRAW_ARRAY requires attached vertex buffer", r.Error());
703 }
704
TEST_F(AmberScriptParserTest,RunDrawArraysMissingAS)705 TEST_F(AmberScriptParserTest, RunDrawArraysMissingAS) {
706 std::string in = R"(
707 SHADER vertex my_shader PASSTHROUGH
708 SHADER fragment my_fragment GLSL
709 # GLSL Shader
710 END
711 BUFFER vtex_buf DATA_TYPE vec3<float> DATA
712 1 2 3
713 4 5 6
714 7 8 9
715 END
716
717 PIPELINE graphics my_pipeline
718 ATTACH my_shader
719 ATTACH my_fragment
720 VERTEX_DATA vtex_buf LOCATION 0
721 END
722
723 RUN my_pipeline DRAW_ARRAY TRIANGLE_LIST START_IDX 1 COUNT 2)";
724
725 Parser parser;
726 Result r = parser.Parse(in);
727 ASSERT_FALSE(r.IsSuccess());
728 EXPECT_EQ("18: missing AS for RUN command", r.Error());
729 }
730
TEST_F(AmberScriptParserTest,RunDrawArraysMissingTopology)731 TEST_F(AmberScriptParserTest, RunDrawArraysMissingTopology) {
732 std::string in = R"(
733 SHADER vertex my_shader PASSTHROUGH
734 SHADER fragment my_fragment GLSL
735 # GLSL Shader
736 END
737 BUFFER vtex_buf DATA_TYPE vec3<float> DATA
738 1 2 3
739 4 5 6
740 7 8 9
741 END
742
743 PIPELINE graphics my_pipeline
744 ATTACH my_shader
745 ATTACH my_fragment
746 VERTEX_DATA vtex_buf LOCATION 0
747 END
748
749 RUN my_pipeline DRAW_ARRAY AS START_IDX 1 COUNT 2)";
750
751 Parser parser;
752 Result r = parser.Parse(in);
753 ASSERT_FALSE(r.IsSuccess());
754 EXPECT_EQ("18: invalid topology for RUN command: START_IDX", r.Error());
755 }
756
TEST_F(AmberScriptParserTest,RunDrawArraysInvalidTopologyFormat)757 TEST_F(AmberScriptParserTest, RunDrawArraysInvalidTopologyFormat) {
758 std::string in = R"(
759 SHADER vertex my_shader PASSTHROUGH
760 SHADER fragment my_fragment GLSL
761 # GLSL Shader
762 END
763 BUFFER vtex_buf DATA_TYPE vec3<float> DATA
764 1 2 3
765 4 5 6
766 7 8 9
767 END
768
769 PIPELINE graphics my_pipeline
770 ATTACH my_shader
771 ATTACH my_fragment
772 VERTEX_DATA vtex_buf LOCATION 0
773 END
774
775 RUN my_pipeline DRAW_ARRAY AS 1234 START_IDX 1 COUNT 2)";
776
777 Parser parser;
778 Result r = parser.Parse(in);
779 ASSERT_FALSE(r.IsSuccess());
780 EXPECT_EQ("18: invalid topology for RUN command: 1234", r.Error());
781 }
782
TEST_F(AmberScriptParserTest,RunDrawArraysInvalidTopology)783 TEST_F(AmberScriptParserTest, RunDrawArraysInvalidTopology) {
784 std::string in = R"(
785 SHADER vertex my_shader PASSTHROUGH
786 SHADER fragment my_fragment GLSL
787 # GLSL Shader
788 END
789 BUFFER vtex_buf DATA_TYPE vec3<float> DATA
790 1 2 3
791 4 5 6
792 7 8 9
793 END
794
795 PIPELINE graphics my_pipeline
796 ATTACH my_shader
797 ATTACH my_fragment
798 VERTEX_DATA vtex_buf LOCATION 0
799 END
800
801 RUN my_pipeline DRAW_ARRAY AS INVALID_TOPOLOGY START_IDX 1 COUNT 2)";
802
803 Parser parser;
804 Result r = parser.Parse(in);
805 ASSERT_FALSE(r.IsSuccess());
806 EXPECT_EQ("18: invalid topology for RUN command: INVALID_TOPOLOGY",
807 r.Error());
808 }
809
TEST_F(AmberScriptParserTest,RunDrawArraysMissingStartIdx)810 TEST_F(AmberScriptParserTest, RunDrawArraysMissingStartIdx) {
811 std::string in = R"(
812 SHADER vertex my_shader PASSTHROUGH
813 SHADER fragment my_fragment GLSL
814 # GLSL Shader
815 END
816 BUFFER vtex_buf DATA_TYPE vec3<float> DATA
817 1 2 3
818 4 5 6
819 7 8 9
820 END
821
822 PIPELINE graphics my_pipeline
823 ATTACH my_shader
824 ATTACH my_fragment
825 VERTEX_DATA vtex_buf LOCATION 0
826 END
827
828 RUN my_pipeline DRAW_ARRAY AS TRIANGLE_LIST 1 COUNT 2)";
829
830 Parser parser;
831 Result r = parser.Parse(in);
832 ASSERT_FALSE(r.IsSuccess());
833 EXPECT_EQ("18: missing START_IDX for RUN command", r.Error());
834 }
835
TEST_F(AmberScriptParserTest,RunDrawArraysMissingStartIdxValue)836 TEST_F(AmberScriptParserTest, RunDrawArraysMissingStartIdxValue) {
837 std::string in = R"(
838 SHADER vertex my_shader PASSTHROUGH
839 SHADER fragment my_fragment GLSL
840 # GLSL Shader
841 END
842 BUFFER vtex_buf DATA_TYPE vec3<float> DATA
843 1 2 3
844 4 5 6
845 7 8 9
846 END
847
848 PIPELINE graphics my_pipeline
849 ATTACH my_shader
850 ATTACH my_fragment
851 VERTEX_DATA vtex_buf LOCATION 0
852 END
853
854 RUN my_pipeline DRAW_ARRAY AS TRIANGLE_LIST START_IDX COUNT 2)";
855
856 Parser parser;
857 Result r = parser.Parse(in);
858 ASSERT_FALSE(r.IsSuccess());
859 EXPECT_EQ("18: invalid START_IDX value for RUN command: COUNT", r.Error());
860 }
861
TEST_F(AmberScriptParserTest,RunDrawArraysInvalidStartIdxValueFormat)862 TEST_F(AmberScriptParserTest, RunDrawArraysInvalidStartIdxValueFormat) {
863 std::string in = R"(
864 SHADER vertex my_shader PASSTHROUGH
865 SHADER fragment my_fragment GLSL
866 # GLSL Shader
867 END
868 BUFFER vtex_buf DATA_TYPE vec3<float> DATA
869 1 2 3
870 4 5 6
871 7 8 9
872 END
873
874 PIPELINE graphics my_pipeline
875 ATTACH my_shader
876 ATTACH my_fragment
877 VERTEX_DATA vtex_buf LOCATION 0
878 END
879
880 RUN my_pipeline DRAW_ARRAY AS TRIANGLE_LIST START_IDX INVALID COUNT 2)";
881
882 Parser parser;
883 Result r = parser.Parse(in);
884 ASSERT_FALSE(r.IsSuccess());
885 EXPECT_EQ("18: invalid START_IDX value for RUN command: INVALID", r.Error());
886 }
887
TEST_F(AmberScriptParserTest,RunDrawArraysInvalidStartIdxValue)888 TEST_F(AmberScriptParserTest, RunDrawArraysInvalidStartIdxValue) {
889 std::string in = R"(
890 SHADER vertex my_shader PASSTHROUGH
891 SHADER fragment my_fragment GLSL
892 # GLSL Shader
893 END
894 BUFFER vtex_buf DATA_TYPE vec3<float> DATA
895 1 2 3
896 4 5 6
897 7 8 9
898 END
899
900 PIPELINE graphics my_pipeline
901 ATTACH my_shader
902 ATTACH my_fragment
903 VERTEX_DATA vtex_buf LOCATION 0
904 END
905
906 RUN my_pipeline DRAW_ARRAY AS TRIANGLE_LIST START_IDX 1.3 COUNT 2)";
907
908 Parser parser;
909 Result r = parser.Parse(in);
910 ASSERT_FALSE(r.IsSuccess());
911 EXPECT_EQ("18: invalid START_IDX value for RUN command: 1.3", r.Error());
912 }
913
TEST_F(AmberScriptParserTest,RunDrawArraysNegativeStartIdxValue)914 TEST_F(AmberScriptParserTest, RunDrawArraysNegativeStartIdxValue) {
915 std::string in = R"(
916 SHADER vertex my_shader PASSTHROUGH
917 SHADER fragment my_fragment GLSL
918 # GLSL Shader
919 END
920 BUFFER vtex_buf DATA_TYPE vec3<float> DATA
921 1 2 3
922 4 5 6
923 7 8 9
924 END
925
926 PIPELINE graphics my_pipeline
927 ATTACH my_shader
928 ATTACH my_fragment
929 VERTEX_DATA vtex_buf LOCATION 0
930 END
931
932 RUN my_pipeline DRAW_ARRAY AS TRIANGLE_LIST START_IDX -1 COUNT 2)";
933
934 Parser parser;
935 Result r = parser.Parse(in);
936 ASSERT_FALSE(r.IsSuccess());
937 EXPECT_EQ("18: START_IDX value must be >= 0 for RUN command", r.Error());
938 }
939
TEST_F(AmberScriptParserTest,RunDrawArraysMissingCount)940 TEST_F(AmberScriptParserTest, RunDrawArraysMissingCount) {
941 std::string in = R"(
942 SHADER vertex my_shader PASSTHROUGH
943 SHADER fragment my_fragment GLSL
944 # GLSL Shader
945 END
946 BUFFER vtex_buf DATA_TYPE vec3<float> DATA
947 1 2 3
948 4 5 6
949 7 8 9
950 END
951
952 PIPELINE graphics my_pipeline
953 ATTACH my_shader
954 ATTACH my_fragment
955 VERTEX_DATA vtex_buf LOCATION 0
956 END
957
958 RUN my_pipeline DRAW_ARRAY AS TRIANGLE_LIST START_IDX 1 2)";
959
960 Parser parser;
961 Result r = parser.Parse(in);
962 ASSERT_FALSE(r.IsSuccess());
963 EXPECT_EQ("18: missing COUNT for RUN command", r.Error());
964 }
965
TEST_F(AmberScriptParserTest,RunDrawArraysMissingCountValue)966 TEST_F(AmberScriptParserTest, RunDrawArraysMissingCountValue) {
967 std::string in = R"(
968 SHADER vertex my_shader PASSTHROUGH
969 SHADER fragment my_fragment GLSL
970 # GLSL Shader
971 END
972 BUFFER vtex_buf DATA_TYPE vec3<float> DATA
973 1 2 3
974 4 5 6
975 7 8 9
976 END
977
978 PIPELINE graphics my_pipeline
979 ATTACH my_shader
980 ATTACH my_fragment
981 VERTEX_DATA vtex_buf LOCATION 0
982 END
983
984 RUN my_pipeline DRAW_ARRAY AS TRIANGLE_LIST START_IDX 1 COUNT)";
985
986 Parser parser;
987 Result r = parser.Parse(in);
988 ASSERT_FALSE(r.IsSuccess());
989 EXPECT_EQ("18: invalid COUNT value for RUN command: ", r.Error());
990 }
991
TEST_F(AmberScriptParserTest,RunDrawArraysStartIdxTooLarge)992 TEST_F(AmberScriptParserTest, RunDrawArraysStartIdxTooLarge) {
993 std::string in = R"(
994 SHADER vertex my_shader PASSTHROUGH
995 SHADER fragment my_fragment GLSL
996 # GLSL Shader
997 END
998 BUFFER vtex_buf DATA_TYPE vec3<float> DATA
999 1 2 3
1000 4 5 6
1001 7 8 9
1002 END
1003
1004 PIPELINE graphics my_pipeline
1005 ATTACH my_shader
1006 ATTACH my_fragment
1007 VERTEX_DATA vtex_buf LOCATION 0
1008 END
1009
1010 RUN my_pipeline DRAW_ARRAY AS TRIANGLE_LIST START_IDX 9 COUNT 1)";
1011
1012 Parser parser;
1013 Result r = parser.Parse(in);
1014 ASSERT_FALSE(r.IsSuccess());
1015 EXPECT_EQ("18: START_IDX plus COUNT exceeds vertex buffer data size",
1016 r.Error());
1017 }
1018
TEST_F(AmberScriptParserTest,RunDrawArraysCountTooLarge)1019 TEST_F(AmberScriptParserTest, RunDrawArraysCountTooLarge) {
1020 std::string in = R"(
1021 SHADER vertex my_shader PASSTHROUGH
1022 SHADER fragment my_fragment GLSL
1023 # GLSL Shader
1024 END
1025 BUFFER vtex_buf DATA_TYPE vec3<float> DATA
1026 1 2 3
1027 4 5 6
1028 7 8 9
1029 END
1030
1031 PIPELINE graphics my_pipeline
1032 ATTACH my_shader
1033 ATTACH my_fragment
1034 VERTEX_DATA vtex_buf LOCATION 0
1035 END
1036
1037 RUN my_pipeline DRAW_ARRAY AS TRIANGLE_LIST START_IDX 1 COUNT 9)";
1038
1039 Parser parser;
1040 Result r = parser.Parse(in);
1041 ASSERT_FALSE(r.IsSuccess());
1042 EXPECT_EQ("18: START_IDX plus COUNT exceeds vertex buffer data size",
1043 r.Error());
1044 }
1045
TEST_F(AmberScriptParserTest,RunDrawArraysInvalidCountValueFormat)1046 TEST_F(AmberScriptParserTest, RunDrawArraysInvalidCountValueFormat) {
1047 std::string in = R"(
1048 SHADER vertex my_shader PASSTHROUGH
1049 SHADER fragment my_fragment GLSL
1050 # GLSL Shader
1051 END
1052 BUFFER vtex_buf DATA_TYPE vec3<float> DATA
1053 1 2 3
1054 4 5 6
1055 7 8 9
1056 END
1057
1058 PIPELINE graphics my_pipeline
1059 ATTACH my_shader
1060 ATTACH my_fragment
1061 VERTEX_DATA vtex_buf LOCATION 0
1062 END
1063
1064 RUN my_pipeline DRAW_ARRAY AS TRIANGLE_LIST START_IDX 1 COUNT INVALID)";
1065
1066 Parser parser;
1067 Result r = parser.Parse(in);
1068 ASSERT_FALSE(r.IsSuccess());
1069 EXPECT_EQ("18: invalid COUNT value for RUN command: INVALID", r.Error());
1070 }
1071
TEST_F(AmberScriptParserTest,RunDrawArraysInvalidCountValue)1072 TEST_F(AmberScriptParserTest, RunDrawArraysInvalidCountValue) {
1073 std::string in = R"(
1074 SHADER vertex my_shader PASSTHROUGH
1075 SHADER fragment my_fragment GLSL
1076 # GLSL Shader
1077 END
1078 BUFFER vtex_buf DATA_TYPE vec3<float> DATA
1079 1 2 3
1080 4 5 6
1081 7 8 9
1082 END
1083
1084 PIPELINE graphics my_pipeline
1085 ATTACH my_shader
1086 ATTACH my_fragment
1087 VERTEX_DATA vtex_buf LOCATION 0
1088 END
1089
1090 RUN my_pipeline DRAW_ARRAY AS TRIANGLE_LIST START_IDX 1 COUNT 2.4)";
1091
1092 Parser parser;
1093 Result r = parser.Parse(in);
1094 ASSERT_FALSE(r.IsSuccess());
1095 EXPECT_EQ("18: invalid COUNT value for RUN command: 2.4", r.Error());
1096 }
1097
TEST_F(AmberScriptParserTest,RunDrawArraysNegativeCountValue)1098 TEST_F(AmberScriptParserTest, RunDrawArraysNegativeCountValue) {
1099 std::string in = R"(
1100 SHADER vertex my_shader PASSTHROUGH
1101 SHADER fragment my_fragment GLSL
1102 # GLSL Shader
1103 END
1104 BUFFER vtex_buf DATA_TYPE vec3<float> DATA
1105 1 2 3
1106 4 5 6
1107 7 8 9
1108 END
1109
1110 PIPELINE graphics my_pipeline
1111 ATTACH my_shader
1112 ATTACH my_fragment
1113 VERTEX_DATA vtex_buf LOCATION 0
1114 END
1115
1116 RUN my_pipeline DRAW_ARRAY AS TRIANGLE_LIST START_IDX 1 COUNT -2)";
1117
1118 Parser parser;
1119 Result r = parser.Parse(in);
1120 ASSERT_FALSE(r.IsSuccess());
1121 EXPECT_EQ("18: COUNT value must be > 0 for RUN command", r.Error());
1122 }
1123
TEST_F(AmberScriptParserTest,RunDrawArraysZeroCountValue)1124 TEST_F(AmberScriptParserTest, RunDrawArraysZeroCountValue) {
1125 std::string in = R"(
1126 SHADER vertex my_shader PASSTHROUGH
1127 SHADER fragment my_fragment GLSL
1128 # GLSL Shader
1129 END
1130 BUFFER vtex_buf DATA_TYPE vec3<float> DATA
1131 1 2 3
1132 4 5 6
1133 7 8 9
1134 END
1135
1136 PIPELINE graphics my_pipeline
1137 ATTACH my_shader
1138 ATTACH my_fragment
1139 VERTEX_DATA vtex_buf LOCATION 0
1140 END
1141
1142 RUN my_pipeline DRAW_ARRAY AS TRIANGLE_LIST START_IDX 1 COUNT 0)";
1143
1144 Parser parser;
1145 Result r = parser.Parse(in);
1146 ASSERT_FALSE(r.IsSuccess());
1147 EXPECT_EQ("18: COUNT value must be > 0 for RUN command", r.Error());
1148 }
1149
1150 } // namespace amberscript
1151 } // namespace amber
1152