• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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,BindColorBuffer)23 TEST_F(AmberScriptParserTest, BindColorBuffer) {
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 
31 PIPELINE graphics my_pipeline
32   ATTACH my_shader
33   ATTACH my_fragment
34 
35   BIND BUFFER my_fb AS color LOCATION 0
36 END)";
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& pipelines = script->GetPipelines();
44   ASSERT_EQ(1U, pipelines.size());
45 
46   const auto* pipeline = pipelines[0].get();
47   const auto& color_buffers = pipeline->GetColorAttachments();
48   ASSERT_EQ(1U, color_buffers.size());
49 
50   const auto& buf_info = color_buffers[0];
51   ASSERT_TRUE(buf_info.buffer != nullptr);
52   EXPECT_EQ(0u, buf_info.location);
53   EXPECT_EQ(250u * 250u, buf_info.buffer->ElementCount());
54   EXPECT_EQ(250u * 250u * 4u, buf_info.buffer->ValueCount());
55   EXPECT_EQ(250u * 250u * 4u * sizeof(float),
56             buf_info.buffer->GetSizeInBytes());
57 }
58 
TEST_F(AmberScriptParserTest,BindColorBufferTwice)59 TEST_F(AmberScriptParserTest, BindColorBufferTwice) {
60   std::string in = R"(
61 SHADER vertex my_shader PASSTHROUGH
62 SHADER fragment my_fragment GLSL
63 # GLSL Shader
64 END
65 BUFFER my_fb FORMAT R32G32B32A32_SFLOAT
66 
67 PIPELINE graphics my_pipeline
68   ATTACH my_shader
69   ATTACH my_fragment
70 
71   BIND BUFFER my_fb AS color LOCATION 0
72   BIND BUFFER my_fb AS color LOCATION 1
73 END)";
74 
75   Parser parser;
76   Result r = parser.Parse(in);
77   ASSERT_FALSE(r.IsSuccess());
78   EXPECT_EQ("13: color buffer may only be bound to a PIPELINE once", r.Error());
79 }
80 
TEST_F(AmberScriptParserTest,BindColorBufferMissingBuffer)81 TEST_F(AmberScriptParserTest, BindColorBufferMissingBuffer) {
82   std::string in = R"(
83 SHADER vertex my_shader PASSTHROUGH
84 SHADER fragment my_fragment GLSL
85 # GLSL Shader
86 END
87 BUFFER my_fb FORMAT R32G32B32A32_SFLOAT
88 
89 PIPELINE graphics my_pipeline
90   ATTACH my_shader
91   ATTACH my_fragment
92 
93   BIND BUFFER AS color LOCATION 0
94 END)";
95 
96   Parser parser;
97   Result r = parser.Parse(in);
98   ASSERT_FALSE(r.IsSuccess());
99   EXPECT_EQ("12: unknown buffer: AS", r.Error());
100 }
101 
TEST_F(AmberScriptParserTest,BindColorBufferNonDeclaredBuffer)102 TEST_F(AmberScriptParserTest, BindColorBufferNonDeclaredBuffer) {
103   std::string in = R"(
104 SHADER vertex my_shader PASSTHROUGH
105 SHADER fragment my_fragment GLSL
106 # GLSL Shader
107 END
108 
109 PIPELINE graphics my_pipeline
110   ATTACH my_shader
111   ATTACH my_fragment
112 
113   BIND BUFFER my_fb AS color LOCATION 0
114 END)";
115 
116   Parser parser;
117   Result r = parser.Parse(in);
118   ASSERT_FALSE(r.IsSuccess());
119   EXPECT_EQ("11: unknown buffer: my_fb", r.Error());
120 }
121 
TEST_F(AmberScriptParserTest,BindColorBufferMissingLocation)122 TEST_F(AmberScriptParserTest, BindColorBufferMissingLocation) {
123   std::string in = R"(
124 SHADER vertex my_shader PASSTHROUGH
125 SHADER fragment my_fragment GLSL
126 # GLSL Shader
127 END
128 BUFFER my_fb FORMAT R32G32B32A32_SFLOAT
129 
130 PIPELINE graphics my_pipeline
131   ATTACH my_shader
132   ATTACH my_fragment
133 
134   BIND BUFFER my_fb AS color
135 END)";
136 
137   Parser parser;
138   Result r = parser.Parse(in);
139   ASSERT_FALSE(r.IsSuccess());
140   EXPECT_EQ("13: BIND missing LOCATION", r.Error());
141 }
142 
TEST_F(AmberScriptParserTest,BindColorBufferMissingLocationIndex)143 TEST_F(AmberScriptParserTest, BindColorBufferMissingLocationIndex) {
144   std::string in = R"(
145 SHADER vertex my_shader PASSTHROUGH
146 SHADER fragment my_fragment GLSL
147 # GLSL Shader
148 END
149 BUFFER my_fb FORMAT R32G32B32A32_SFLOAT
150 
151 PIPELINE graphics my_pipeline
152   ATTACH my_shader
153   ATTACH my_fragment
154 
155   BIND BUFFER my_fb AS color LOCATION
156 END)";
157 
158   Parser parser;
159   Result r = parser.Parse(in);
160   ASSERT_FALSE(r.IsSuccess());
161   EXPECT_EQ("13: invalid value for BIND LOCATION", r.Error());
162 }
163 
TEST_F(AmberScriptParserTest,BindColorBufferInvalidLocationIndex)164 TEST_F(AmberScriptParserTest, BindColorBufferInvalidLocationIndex) {
165   std::string in = R"(
166 SHADER vertex my_shader PASSTHROUGH
167 SHADER fragment my_fragment GLSL
168 # GLSL Shader
169 END
170 BUFFER my_fb FORMAT R32G32B32A32_SFLOAT
171 
172 PIPELINE graphics my_pipeline
173   ATTACH my_shader
174   ATTACH my_fragment
175 
176   BIND BUFFER my_fb AS color LOCATION INVALID
177 END)";
178 
179   Parser parser;
180   Result r = parser.Parse(in);
181   ASSERT_FALSE(r.IsSuccess());
182   EXPECT_EQ("12: invalid value for BIND LOCATION", r.Error());
183 }
184 
TEST_F(AmberScriptParserTest,BindColorBufferExtraParams)185 TEST_F(AmberScriptParserTest, BindColorBufferExtraParams) {
186   std::string in = R"(
187 SHADER vertex my_shader PASSTHROUGH
188 SHADER fragment my_fragment GLSL
189 # GLSL Shader
190 END
191 BUFFER my_fb FORMAT R32G32B32A32_SFLOAT
192 
193 PIPELINE graphics my_pipeline
194   ATTACH my_shader
195   ATTACH my_fragment
196 
197   BIND BUFFER my_fb AS color LOCATION 0 EXTRA
198 END)";
199 
200   Parser parser;
201   Result r = parser.Parse(in);
202   ASSERT_FALSE(r.IsSuccess());
203   EXPECT_EQ("12: extra parameters after BIND command: EXTRA", r.Error());
204 }
205 
TEST_F(AmberScriptParserTest,BindColorBufferDuplicateLocation)206 TEST_F(AmberScriptParserTest, BindColorBufferDuplicateLocation) {
207   std::string in = R"(
208 SHADER vertex my_shader PASSTHROUGH
209 SHADER fragment my_fragment GLSL
210 # GLSL Shader
211 END
212 BUFFER my_fb FORMAT R32G32B32A32_SFLOAT
213 BUFFER sec_fb FORMAT R32G32B32A32_SFLOAT
214 
215 PIPELINE graphics my_pipeline
216   ATTACH my_shader
217   ATTACH my_fragment
218 
219   BIND BUFFER my_fb AS color LOCATION 0
220   BIND BUFFER sec_fb AS color LOCATION 0
221 END)";
222 
223   Parser parser;
224   Result r = parser.Parse(in);
225   ASSERT_FALSE(r.IsSuccess());
226   EXPECT_EQ("14: can not bind two color buffers to the same LOCATION",
227             r.Error());
228 }
229 
TEST_F(AmberScriptParserTest,BindColorToTwoPipelinesRequiresMatchingSize)230 TEST_F(AmberScriptParserTest, BindColorToTwoPipelinesRequiresMatchingSize) {
231   std::string in = R"(
232 SHADER vertex my_shader PASSTHROUGH
233 SHADER fragment my_fragment GLSL
234 # GLSL Shader
235 END
236 BUFFER my_fb FORMAT R32G32B32A32_SFLOAT
237 
238 PIPELINE graphics my_pipeline
239   ATTACH my_shader
240   ATTACH my_fragment
241 
242   BIND BUFFER my_fb AS color LOCATION 0
243 END
244 PIPELINE graphics second_pipeline
245   ATTACH my_shader
246   ATTACH my_fragment
247 
248   BIND BUFFER my_fb AS color LOCATION 0
249   FRAMEBUFFER_SIZE 256 300
250 END)";
251 
252   Parser parser;
253   Result r = parser.Parse(in);
254   ASSERT_FALSE(r.IsSuccess());
255   EXPECT_EQ("shared framebuffer must have same size over all PIPELINES",
256             r.Error());
257 }
258 
TEST_F(AmberScriptParserTest,BindColorTwoPipelines)259 TEST_F(AmberScriptParserTest, BindColorTwoPipelines) {
260   std::string in = R"(
261 SHADER vertex my_shader PASSTHROUGH
262 SHADER fragment my_fragment GLSL
263 # GLSL Shader
264 END
265 BUFFER my_fb FORMAT R32G32B32A32_SFLOAT
266 BUFFER second_fb FORMAT R8G8B8A8_UINT
267 BUFFER depth_1 FORMAT D32_SFLOAT_S8_UINT
268 BUFFER depth_2 FORMAT D32_SFLOAT_S8_UINT
269 
270 PIPELINE graphics my_pipeline
271   ATTACH my_shader
272   ATTACH my_fragment
273 
274   BIND BUFFER my_fb AS color LOCATION 0
275   BIND BUFFER depth_1 AS depth_stencil
276   FRAMEBUFFER_SIZE 90 180
277 END
278 PIPELINE graphics second_pipeline
279   ATTACH my_shader
280   ATTACH my_fragment
281 
282   BIND BUFFER second_fb AS color LOCATION 9
283   BIND BUFFER depth_2 AS depth_stencil
284   FRAMEBUFFER_SIZE 256 300
285 END)";
286 
287   Parser parser;
288   Result r = parser.Parse(in);
289   ASSERT_TRUE(r.IsSuccess()) << r.Error();
290 
291   auto script = parser.GetScript();
292   const auto& pipelines = script->GetPipelines();
293   ASSERT_EQ(2U, pipelines.size());
294 
295   const auto* pipeline = pipelines[0].get();
296   const auto& color_buffers1 = pipeline->GetColorAttachments();
297   ASSERT_EQ(1U, color_buffers1.size());
298 
299   const auto& buf1 = color_buffers1[0];
300   ASSERT_TRUE(buf1.buffer != nullptr);
301   EXPECT_EQ(0u, buf1.location);
302   EXPECT_EQ(90u * 180u, buf1.buffer->ElementCount());
303   EXPECT_EQ(90u * 180u * 4u, buf1.buffer->ValueCount());
304   EXPECT_EQ(90u * 180u * 4u * sizeof(float), buf1.buffer->GetSizeInBytes());
305 
306   pipeline = pipelines[1].get();
307   const auto& color_buffers2 = pipeline->GetColorAttachments();
308   const auto& buf2 = color_buffers2[0];
309   ASSERT_TRUE(buf2.buffer != nullptr);
310   EXPECT_EQ(9u, buf2.location);
311   EXPECT_EQ(256u * 300u, buf2.buffer->ElementCount());
312   EXPECT_EQ(256u * 300u * 4u, buf2.buffer->ValueCount());
313   EXPECT_EQ(256u * 300u * 4u * sizeof(uint8_t), buf2.buffer->GetSizeInBytes());
314 }
315 
TEST_F(AmberScriptParserTest,BindColorFBSizeSetBeforeBuffer)316 TEST_F(AmberScriptParserTest, BindColorFBSizeSetBeforeBuffer) {
317   std::string in = R"(
318 SHADER vertex my_shader PASSTHROUGH
319 SHADER fragment my_fragment GLSL
320 # GLSL Shader
321 END
322 BUFFER my_fb FORMAT R32G32B32A32_SFLOAT
323 
324 PIPELINE graphics my_pipeline
325   ATTACH my_shader
326   ATTACH my_fragment
327 
328   FRAMEBUFFER_SIZE 90 180
329   BIND BUFFER my_fb AS color LOCATION 0
330 END)";
331 
332   Parser parser;
333   Result r = parser.Parse(in);
334   ASSERT_TRUE(r.IsSuccess()) << r.Error();
335 
336   auto script = parser.GetScript();
337   const auto& pipelines = script->GetPipelines();
338   ASSERT_EQ(1U, pipelines.size());
339 
340   const auto* pipeline = pipelines[0].get();
341   const auto& color_buffers1 = pipeline->GetColorAttachments();
342   ASSERT_EQ(1U, color_buffers1.size());
343 
344   const auto& buf1 = color_buffers1[0];
345   ASSERT_TRUE(buf1.buffer != nullptr);
346   EXPECT_EQ(0u, buf1.location);
347   EXPECT_EQ(90u * 180u, buf1.buffer->ElementCount());
348   EXPECT_EQ(90u * 180u * 4u, buf1.buffer->ValueCount());
349   EXPECT_EQ(90u * 180u * 4u * sizeof(float), buf1.buffer->GetSizeInBytes());
350 }
351 
TEST_F(AmberScriptParserTest,BindColorFBSizeSetAfterBuffer)352 TEST_F(AmberScriptParserTest, BindColorFBSizeSetAfterBuffer) {
353   std::string in = R"(
354 SHADER vertex my_shader PASSTHROUGH
355 SHADER fragment my_fragment GLSL
356 # GLSL Shader
357 END
358 BUFFER my_fb FORMAT R32G32B32A32_SFLOAT
359 
360 PIPELINE graphics my_pipeline
361   ATTACH my_shader
362   ATTACH my_fragment
363 
364   BIND BUFFER my_fb AS color LOCATION 0
365   FRAMEBUFFER_SIZE 90 180
366 END)";
367 
368   Parser parser;
369   Result r = parser.Parse(in);
370   ASSERT_TRUE(r.IsSuccess()) << r.Error();
371 
372   auto script = parser.GetScript();
373   const auto& pipelines = script->GetPipelines();
374   ASSERT_EQ(1U, pipelines.size());
375 
376   const auto* pipeline = pipelines[0].get();
377   const auto& color_buffers1 = pipeline->GetColorAttachments();
378   ASSERT_EQ(1U, color_buffers1.size());
379 
380   const auto& buf1 = color_buffers1[0];
381   ASSERT_TRUE(buf1.buffer != nullptr);
382   EXPECT_EQ(0u, buf1.location);
383   EXPECT_EQ(90u * 180u, buf1.buffer->ElementCount());
384   EXPECT_EQ(90u * 180u * 4u, buf1.buffer->ValueCount());
385   EXPECT_EQ(90u * 180u * 4u * sizeof(float), buf1.buffer->GetSizeInBytes());
386 }
387 
TEST_F(AmberScriptParserTest,BindColorBaseMipLevel)388 TEST_F(AmberScriptParserTest, BindColorBaseMipLevel) {
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 MIP_LEVELS 2
395 
396 PIPELINE graphics my_pipeline
397   ATTACH my_shader
398   ATTACH my_fragment
399 
400   BIND BUFFER my_fb AS color LOCATION 0 BASE_MIP_LEVEL 1
401   FRAMEBUFFER_SIZE 90 180
402 END)";
403 
404   Parser parser;
405   Result r = parser.Parse(in);
406   ASSERT_TRUE(r.IsSuccess()) << r.Error();
407 
408   auto script = parser.GetScript();
409   const auto& pipelines = script->GetPipelines();
410   ASSERT_EQ(1U, pipelines.size());
411 
412   const auto* pipeline = pipelines[0].get();
413   const auto& color_buffers1 = pipeline->GetColorAttachments();
414   ASSERT_EQ(1U, color_buffers1.size());
415 
416   const auto& buf1 = color_buffers1[0];
417   ASSERT_TRUE(buf1.buffer != nullptr);
418   EXPECT_EQ(1u, buf1.base_mip_level);
419 }
420 
TEST_F(AmberScriptParserTest,BindColorMissingBaseMipLevel)421 TEST_F(AmberScriptParserTest, BindColorMissingBaseMipLevel) {
422   std::string in = R"(
423 SHADER vertex my_shader PASSTHROUGH
424 SHADER fragment my_fragment GLSL
425 # GLSL Shader
426 END
427 BUFFER my_fb FORMAT R32G32B32A32_SFLOAT MIP_LEVELS 2
428 
429 PIPELINE graphics my_pipeline
430   ATTACH my_shader
431   ATTACH my_fragment
432 
433   BIND BUFFER my_fb AS color LOCATION 0 BASE_MIP_LEVEL
434   FRAMEBUFFER_SIZE 90 180
435 END)";
436 
437   Parser parser;
438   Result r = parser.Parse(in);
439   ASSERT_FALSE(r.IsSuccess());
440   EXPECT_EQ("13: invalid value for BASE_MIP_LEVEL", r.Error());
441 }
442 
TEST_F(AmberScriptParserTest,BindColorBaseMipLevelTooLarge)443 TEST_F(AmberScriptParserTest, BindColorBaseMipLevelTooLarge) {
444   std::string in = R"(
445 SHADER vertex my_shader PASSTHROUGH
446 SHADER fragment my_fragment GLSL
447 # GLSL Shader
448 END
449 BUFFER my_fb FORMAT R32G32B32A32_SFLOAT MIP_LEVELS 2
450 
451 PIPELINE graphics my_pipeline
452   ATTACH my_shader
453   ATTACH my_fragment
454 
455   BIND BUFFER my_fb AS color LOCATION 0 BASE_MIP_LEVEL 2
456   FRAMEBUFFER_SIZE 90 180
457 END)";
458 
459   Parser parser;
460   Result r = parser.Parse(in);
461   ASSERT_FALSE(r.IsSuccess());
462   EXPECT_EQ(
463       "12: base mip level (now 2) needs to be larger than the number of buffer "
464       "mip maps (2)",
465       r.Error());
466 }
467 
TEST_F(AmberScriptParserTest,BindColorTooManyMipLevels)468 TEST_F(AmberScriptParserTest, BindColorTooManyMipLevels) {
469   std::string in = R"(
470 SHADER vertex my_shader PASSTHROUGH
471 SHADER fragment my_fragment GLSL
472 # GLSL Shader
473 END
474 BUFFER my_fb FORMAT R32G32B32A32_SFLOAT MIP_LEVELS 20
475 
476 PIPELINE graphics my_pipeline
477   ATTACH my_shader
478   ATTACH my_fragment
479 
480   BIND BUFFER my_fb AS color LOCATION 0
481   FRAMEBUFFER_SIZE 90 180
482 END)";
483 
484   Parser parser;
485   Result r = parser.Parse(in);
486   ASSERT_FALSE(r.IsSuccess());
487   EXPECT_EQ(
488       "color attachment with 20 mip levels would have zero width for level 7",
489       r.Error());
490 }
491 
TEST_F(AmberScriptParserTest,BindDepthBuffer)492 TEST_F(AmberScriptParserTest, BindDepthBuffer) {
493   std::string in = R"(
494 SHADER vertex my_shader PASSTHROUGH
495 SHADER fragment my_fragment GLSL
496 # GLSL Shader
497 END
498 BUFFER my_buf FORMAT R32G32B32A32_SFLOAT
499 
500 PIPELINE graphics my_pipeline
501   ATTACH my_shader
502   ATTACH my_fragment
503 
504   BIND BUFFER my_buf AS depth_stencil
505   FRAMEBUFFER_SIZE 90 180
506 END)";
507 
508   Parser parser;
509   Result r = parser.Parse(in);
510   ASSERT_TRUE(r.IsSuccess()) << r.Error();
511 
512   auto script = parser.GetScript();
513   const auto& pipelines = script->GetPipelines();
514   ASSERT_EQ(1U, pipelines.size());
515 
516   const auto* pipeline = pipelines[0].get();
517   const auto& buf = pipeline->GetDepthStencilBuffer();
518   ASSERT_TRUE(buf.buffer != nullptr);
519   EXPECT_EQ(90u * 180u, buf.buffer->ElementCount());
520   EXPECT_EQ(90u * 180u * 4u, buf.buffer->ValueCount());
521   EXPECT_EQ(90u * 180u * 4u * sizeof(float), buf.buffer->GetSizeInBytes());
522 }
523 
TEST_F(AmberScriptParserTest,BindDepthBufferExtraParams)524 TEST_F(AmberScriptParserTest, BindDepthBufferExtraParams) {
525   std::string in = R"(
526 SHADER vertex my_shader PASSTHROUGH
527 SHADER fragment my_fragment GLSL
528 # GLSL Shader
529 END
530 BUFFER my_buf FORMAT R32G32B32A32_SFLOAT
531 
532 PIPELINE graphics my_pipeline
533   ATTACH my_shader
534   ATTACH my_fragment
535 
536   BIND BUFFER my_buf AS depth_stencil EXTRA
537   FRAMEBUFFER_SIZE 90 180
538 END)";
539 
540   Parser parser;
541   Result r = parser.Parse(in);
542   ASSERT_FALSE(r.IsSuccess());
543   EXPECT_EQ("12: extra parameters after BIND command: EXTRA", r.Error());
544 }
545 
TEST_F(AmberScriptParserTest,BindBufferMissingBufferName)546 TEST_F(AmberScriptParserTest, BindBufferMissingBufferName) {
547   std::string in = R"(
548 SHADER vertex my_shader PASSTHROUGH
549 SHADER fragment my_fragment GLSL
550 # GLSL Shader
551 END
552 BUFFER my_buf FORMAT R32G32B32A32_SFLOAT
553 
554 PIPELINE graphics my_pipeline
555   ATTACH my_shader
556   ATTACH my_fragment
557 
558   BIND BUFFER AS depth_stencil
559   FRAMEBUFFER_SIZE 90 180
560 END)";
561 
562   Parser parser;
563   Result r = parser.Parse(in);
564   ASSERT_FALSE(r.IsSuccess());
565   EXPECT_EQ("12: unknown buffer: AS", r.Error());
566 }
567 
TEST_F(AmberScriptParserTest,BindBufferAsMissingType)568 TEST_F(AmberScriptParserTest, BindBufferAsMissingType) {
569   std::string in = R"(
570 SHADER vertex my_shader PASSTHROUGH
571 SHADER fragment my_fragment GLSL
572 # GLSL Shader
573 END
574 BUFFER my_buf FORMAT R32G32B32A32_SFLOAT
575 
576 PIPELINE graphics my_pipeline
577   ATTACH my_shader
578   ATTACH my_fragment
579 
580   BIND BUFFER my_buf AS
581   FRAMEBUFFER_SIZE 90 180
582 END)";
583 
584   Parser parser;
585   Result r = parser.Parse(in);
586   ASSERT_FALSE(r.IsSuccess());
587   EXPECT_EQ("13: invalid token for BUFFER type", r.Error());
588 }
589 
TEST_F(AmberScriptParserTest,BindBufferAsInvalidType)590 TEST_F(AmberScriptParserTest, BindBufferAsInvalidType) {
591   std::string in = R"(
592 SHADER vertex my_shader PASSTHROUGH
593 SHADER fragment my_fragment GLSL
594 # GLSL Shader
595 END
596 BUFFER my_buf FORMAT R32G32B32A32_SFLOAT
597 
598 PIPELINE graphics my_pipeline
599   ATTACH my_shader
600   ATTACH my_fragment
601 
602   BIND BUFFER my_buf AS
603   FRAMEBUFFER_SIZE 90 180
604 END)";
605 
606   Parser parser;
607   Result r = parser.Parse(in);
608   ASSERT_FALSE(r.IsSuccess());
609   EXPECT_EQ("13: invalid token for BUFFER type", r.Error());
610 }
611 
TEST_F(AmberScriptParserTest,BindDepthBufferUnknownBuffer)612 TEST_F(AmberScriptParserTest, BindDepthBufferUnknownBuffer) {
613   std::string in = R"(
614 SHADER vertex my_shader PASSTHROUGH
615 SHADER fragment my_fragment GLSL
616 # GLSL Shader
617 END
618 
619 PIPELINE graphics my_pipeline
620   ATTACH my_shader
621   ATTACH my_fragment
622 
623   BIND BUFFER my_buf AS depth_stencil
624   FRAMEBUFFER_SIZE 90 180
625 END)";
626 
627   Parser parser;
628   Result r = parser.Parse(in);
629   ASSERT_FALSE(r.IsSuccess());
630   EXPECT_EQ("11: unknown buffer: my_buf", r.Error());
631 }
632 
TEST_F(AmberScriptParserTest,BindBufferMultipleDepthBuffers)633 TEST_F(AmberScriptParserTest, BindBufferMultipleDepthBuffers) {
634   std::string in = R"(
635 SHADER vertex my_shader PASSTHROUGH
636 SHADER fragment my_fragment GLSL
637 # GLSL Shader
638 END
639 BUFFER my_buf FORMAT R32G32B32A32_SFLOAT
640 BUFFER my_buf2 FORMAT R32G32B32A32_SFLOAT
641 
642 PIPELINE graphics my_pipeline
643   ATTACH my_shader
644   ATTACH my_fragment
645 
646   BIND BUFFER my_buf AS depth_stencil
647   BIND BUFFER my_buf AS depth_stencil
648 END)";
649 
650   Parser parser;
651   Result r = parser.Parse(in);
652   ASSERT_FALSE(r.IsSuccess());
653   EXPECT_EQ("14: can only bind one depth/stencil buffer in a PIPELINE",
654             r.Error());
655 }
656 
TEST_F(AmberScriptParserTest,BindVertexData)657 TEST_F(AmberScriptParserTest, BindVertexData) {
658   std::string in = R"(
659 SHADER vertex my_shader PASSTHROUGH
660 SHADER fragment my_fragment GLSL
661 # GLSL Shader
662 END
663 BUFFER my_buf DATA_TYPE int8 SIZE 5 FILL 5
664 BUFFER my_buf2 DATA_TYPE int8 SIZE 5 FILL 5
665 
666 PIPELINE graphics my_pipeline
667   ATTACH my_shader
668   ATTACH my_fragment
669 
670   VERTEX_DATA my_buf LOCATION 0
671   VERTEX_DATA my_buf2 LOCATION 1
672 END)";
673 
674   Parser parser;
675   Result r = parser.Parse(in);
676   ASSERT_TRUE(r.IsSuccess()) << r.Error();
677 
678   auto script = parser.GetScript();
679   const auto& pipelines = script->GetPipelines();
680   ASSERT_EQ(1U, pipelines.size());
681 
682   const auto* pipeline = pipelines[0].get();
683   const auto& vertex_buffers = pipeline->GetVertexBuffers();
684   ASSERT_EQ(2u, vertex_buffers.size());
685 
686   const auto& info1 = vertex_buffers[0];
687   ASSERT_TRUE(info1.buffer != nullptr);
688   EXPECT_EQ(0u, info1.location);
689   EXPECT_EQ(InputRate::kVertex, info1.input_rate);
690 
691   const auto& info2 = vertex_buffers[1];
692   ASSERT_TRUE(info2.buffer != nullptr);
693   EXPECT_EQ(1u, info2.location);
694   EXPECT_EQ(InputRate::kVertex, info2.input_rate);
695 }
696 
TEST_F(AmberScriptParserTest,BindVertexDataDuplicateLocation)697 TEST_F(AmberScriptParserTest, BindVertexDataDuplicateLocation) {
698   std::string in = R"(
699 SHADER vertex my_shader PASSTHROUGH
700 SHADER fragment my_fragment GLSL
701 # GLSL Shader
702 END
703 BUFFER my_buf DATA_TYPE int8 SIZE 50 FILL 5
704 BUFFER my_buf2 DATA_TYPE int8 SIZE 50 FILL 5
705 
706 PIPELINE graphics my_pipeline
707   ATTACH my_shader
708   ATTACH my_fragment
709 
710   VERTEX_DATA my_buf LOCATION 0
711   VERTEX_DATA my_buf2 LOCATION 0
712 END)";
713 
714   Parser parser;
715   Result r = parser.Parse(in);
716   ASSERT_FALSE(r.IsSuccess());
717   EXPECT_EQ("14: can not bind two vertex buffers to the same LOCATION",
718             r.Error());
719 }
720 
TEST_F(AmberScriptParserTest,BindVertexDataDuplicateBinding)721 TEST_F(AmberScriptParserTest, BindVertexDataDuplicateBinding) {
722   std::string in = R"(
723 SHADER vertex my_shader PASSTHROUGH
724 SHADER fragment my_fragment GLSL
725 # GLSL Shader
726 END
727 BUFFER my_buf DATA_TYPE int8 SIZE 50 FILL 5
728 
729 PIPELINE graphics my_pipeline
730   ATTACH my_shader
731   ATTACH my_fragment
732 
733   VERTEX_DATA my_buf LOCATION 0
734   VERTEX_DATA my_buf LOCATION 1 OFFSET 10
735 END)";
736 
737   Parser parser;
738   Result r = parser.Parse(in);
739   ASSERT_TRUE(r.IsSuccess());
740 
741   auto script = parser.GetScript();
742   const auto& pipelines = script->GetPipelines();
743   ASSERT_EQ(1U, pipelines.size());
744 
745   const auto* pipeline = pipelines[0].get();
746   const auto& vertex_buffers = pipeline->GetVertexBuffers();
747   ASSERT_EQ(2u, vertex_buffers.size());
748 
749   const auto& info1 = vertex_buffers[0];
750   ASSERT_TRUE(info1.buffer != nullptr);
751   EXPECT_EQ(0u, info1.location);
752   EXPECT_EQ(0u, info1.offset);
753 
754   const auto& info2 = vertex_buffers[1];
755   ASSERT_TRUE(info2.buffer != nullptr);
756   EXPECT_EQ(1u, info2.location);
757   EXPECT_EQ(10u, info2.offset);
758 }
759 
TEST_F(AmberScriptParserTest,BindVertexDataMissingBuffer)760 TEST_F(AmberScriptParserTest, BindVertexDataMissingBuffer) {
761   std::string in = R"(
762 SHADER vertex my_shader PASSTHROUGH
763 SHADER fragment my_fragment GLSL
764 # GLSL Shader
765 END
766 BUFFER my_buf DATA_TYPE int8 SIZE 50 FILL 5
767 
768 PIPELINE graphics my_pipeline
769   ATTACH my_shader
770   ATTACH my_fragment
771 
772   VERTEX_DATA LOCATION 0
773 END)";
774 
775   Parser parser;
776   Result r = parser.Parse(in);
777   ASSERT_FALSE(r.IsSuccess());
778   EXPECT_EQ("12: unknown buffer: LOCATION", r.Error());
779 }
780 
TEST_F(AmberScriptParserTest,BindVertexDataUnknownBuffer)781 TEST_F(AmberScriptParserTest, BindVertexDataUnknownBuffer) {
782   std::string in = R"(
783 SHADER vertex my_shader PASSTHROUGH
784 SHADER fragment my_fragment GLSL
785 # GLSL Shader
786 END
787 
788 PIPELINE graphics my_pipeline
789   ATTACH my_shader
790   ATTACH my_fragment
791 
792   VERTEX_DATA my_buf LOCATION 0
793 END)";
794 
795   Parser parser;
796   Result r = parser.Parse(in);
797   ASSERT_FALSE(r.IsSuccess());
798   EXPECT_EQ("11: unknown buffer: my_buf", r.Error());
799 }
800 
TEST_F(AmberScriptParserTest,BindVertexDataMissingLocation)801 TEST_F(AmberScriptParserTest, BindVertexDataMissingLocation) {
802   std::string in = R"(
803 SHADER vertex my_shader PASSTHROUGH
804 SHADER fragment my_fragment GLSL
805 # GLSL Shader
806 END
807 BUFFER my_buf DATA_TYPE int8 SIZE 50 FILL 5
808 
809 PIPELINE graphics my_pipeline
810   ATTACH my_shader
811   ATTACH my_fragment
812 
813   VERTEX_DATA my_buf
814 END)";
815 
816   Parser parser;
817   Result r = parser.Parse(in);
818   ASSERT_FALSE(r.IsSuccess());
819   EXPECT_EQ("13: VERTEX_DATA missing LOCATION", r.Error());
820 }
821 
TEST_F(AmberScriptParserTest,BindVertexDataMissingLocationValue)822 TEST_F(AmberScriptParserTest, BindVertexDataMissingLocationValue) {
823   std::string in = R"(
824 SHADER vertex my_shader PASSTHROUGH
825 SHADER fragment my_fragment GLSL
826 # GLSL Shader
827 END
828 BUFFER my_buf DATA_TYPE int8 SIZE 50 FILL 5
829 
830 PIPELINE graphics my_pipeline
831   ATTACH my_shader
832   ATTACH my_fragment
833 
834   VERTEX_DATA my_buf LOCATION
835 END)";
836 
837   Parser parser;
838   Result r = parser.Parse(in);
839   ASSERT_FALSE(r.IsSuccess());
840   EXPECT_EQ("13: invalid value for VERTEX_DATA LOCATION", r.Error());
841 }
842 
TEST_F(AmberScriptParserTest,BindVertexDataExtraParameters)843 TEST_F(AmberScriptParserTest, BindVertexDataExtraParameters) {
844   std::string in = R"(
845 SHADER vertex my_shader PASSTHROUGH
846 SHADER fragment my_fragment GLSL
847 # GLSL Shader
848 END
849 BUFFER my_buf DATA_TYPE int8 SIZE 50 FILL 5
850 
851 PIPELINE graphics my_pipeline
852   ATTACH my_shader
853   ATTACH my_fragment
854 
855   VERTEX_DATA my_buf LOCATION 0 EXTRA
856 END)";
857 
858   Parser parser;
859   Result r = parser.Parse(in);
860   ASSERT_FALSE(r.IsSuccess());
861   EXPECT_EQ("12: unexpected identifier for VERTEX_DATA command: EXTRA",
862             r.Error());
863 }
864 
TEST_F(AmberScriptParserTest,BindVertexDataInputRate)865 TEST_F(AmberScriptParserTest, BindVertexDataInputRate) {
866   std::string in = R"(
867 SHADER vertex my_shader PASSTHROUGH
868 SHADER fragment my_fragment GLSL
869 # GLSL Shader
870 END
871 BUFFER my_buf DATA_TYPE int8 SIZE 5 FILL 5
872 BUFFER my_buf2 DATA_TYPE int8 SIZE 5 FILL 5
873 
874 PIPELINE graphics my_pipeline
875   ATTACH my_shader
876   ATTACH my_fragment
877 
878   VERTEX_DATA my_buf LOCATION 0 RATE vertex
879   VERTEX_DATA my_buf2 LOCATION 1 RATE instance
880 END)";
881 
882   Parser parser;
883   Result r = parser.Parse(in);
884   ASSERT_TRUE(r.IsSuccess()) << r.Error();
885 
886   auto script = parser.GetScript();
887   const auto& pipelines = script->GetPipelines();
888   ASSERT_EQ(1U, pipelines.size());
889 
890   const auto* pipeline = pipelines[0].get();
891   const auto& vertex_buffers = pipeline->GetVertexBuffers();
892   ASSERT_EQ(2u, vertex_buffers.size());
893 
894   const auto& info1 = vertex_buffers[0];
895   ASSERT_TRUE(info1.buffer != nullptr);
896   EXPECT_EQ(0u, info1.location);
897   EXPECT_EQ(InputRate::kVertex, info1.input_rate);
898 
899   const auto& info2 = vertex_buffers[1];
900   ASSERT_TRUE(info2.buffer != nullptr);
901   EXPECT_EQ(1u, info2.location);
902   EXPECT_EQ(InputRate::kInstance, info2.input_rate);
903 }
904 
TEST_F(AmberScriptParserTest,BindVertexDataInputRateMissingValue)905 TEST_F(AmberScriptParserTest, BindVertexDataInputRateMissingValue) {
906   std::string in = R"(
907 SHADER vertex my_shader PASSTHROUGH
908 SHADER fragment my_fragment GLSL
909 # GLSL Shader
910 END
911 BUFFER my_buf DATA_TYPE int8 SIZE 5 FILL 5
912 
913 PIPELINE graphics my_pipeline
914   ATTACH my_shader
915   ATTACH my_fragment
916 
917   VERTEX_DATA my_buf LOCATION 0 RATE
918 END)";
919 
920   Parser parser;
921   Result r = parser.Parse(in);
922   ASSERT_FALSE(r.IsSuccess());
923   EXPECT_EQ("13: missing input rate value for RATE", r.Error());
924 }
925 
TEST_F(AmberScriptParserTest,BindVertexDataInputRateInvalidValue)926 TEST_F(AmberScriptParserTest, BindVertexDataInputRateInvalidValue) {
927   std::string in = R"(
928 SHADER vertex my_shader PASSTHROUGH
929 SHADER fragment my_fragment GLSL
930 # GLSL Shader
931 END
932 BUFFER my_buf DATA_TYPE int8 SIZE 5 FILL 5
933 
934 PIPELINE graphics my_pipeline
935   ATTACH my_shader
936   ATTACH my_fragment
937 
938   VERTEX_DATA my_buf LOCATION 0 RATE foo
939 END)";
940 
941   Parser parser;
942   Result r = parser.Parse(in);
943   ASSERT_FALSE(r.IsSuccess());
944   EXPECT_EQ("12: expecting 'vertex' or 'instance' for RATE value", r.Error());
945 }
946 
TEST_F(AmberScriptParserTest,BindVertexDataOffset)947 TEST_F(AmberScriptParserTest, BindVertexDataOffset) {
948   std::string in = R"(
949 SHADER vertex my_shader PASSTHROUGH
950 SHADER fragment my_fragment GLSL
951 # GLSL Shader
952 END
953 BUFFER my_buf DATA_TYPE int8 SIZE 5 FILL 5
954 BUFFER my_buf2 DATA_TYPE int8 SIZE 5 FILL 5
955 
956 PIPELINE graphics my_pipeline
957   ATTACH my_shader
958   ATTACH my_fragment
959 
960   VERTEX_DATA my_buf LOCATION 0 OFFSET 5
961   VERTEX_DATA my_buf2 LOCATION 1 OFFSET 10
962 END)";
963 
964   Parser parser;
965   Result r = parser.Parse(in);
966   ASSERT_TRUE(r.IsSuccess()) << r.Error();
967 
968   auto script = parser.GetScript();
969   const auto& pipelines = script->GetPipelines();
970   ASSERT_EQ(1U, pipelines.size());
971 
972   const auto* pipeline = pipelines[0].get();
973   const auto& vertex_buffers = pipeline->GetVertexBuffers();
974   ASSERT_EQ(2u, vertex_buffers.size());
975 
976   const auto& info1 = vertex_buffers[0];
977   ASSERT_TRUE(info1.buffer != nullptr);
978   EXPECT_EQ(0u, info1.location);
979   EXPECT_EQ(5u, info1.offset);
980 
981   const auto& info2 = vertex_buffers[1];
982   ASSERT_TRUE(info2.buffer != nullptr);
983   EXPECT_EQ(1u, info2.location);
984   EXPECT_EQ(10u, info2.offset);
985 }
986 
TEST_F(AmberScriptParserTest,BindVertexDataOffsetMissingValue)987 TEST_F(AmberScriptParserTest, BindVertexDataOffsetMissingValue) {
988   std::string in = R"(
989 SHADER vertex my_shader PASSTHROUGH
990 SHADER fragment my_fragment GLSL
991 # GLSL Shader
992 END
993 BUFFER my_buf DATA_TYPE int8 SIZE 5 FILL 5
994 
995 PIPELINE graphics my_pipeline
996   ATTACH my_shader
997   ATTACH my_fragment
998 
999   VERTEX_DATA my_buf LOCATION 0 OFFSET
1000 END)";
1001 
1002   Parser parser;
1003   Result r = parser.Parse(in);
1004   ASSERT_FALSE(r.IsSuccess());
1005   EXPECT_EQ("13: expected unsigned integer for OFFSET", r.Error());
1006 }
1007 
TEST_F(AmberScriptParserTest,BindVertexDataOffsetIncorrectValue)1008 TEST_F(AmberScriptParserTest, BindVertexDataOffsetIncorrectValue) {
1009   std::string in = R"(
1010 SHADER vertex my_shader PASSTHROUGH
1011 SHADER fragment my_fragment GLSL
1012 # GLSL Shader
1013 END
1014 BUFFER my_buf DATA_TYPE int8 SIZE 5 FILL 5
1015 
1016 PIPELINE graphics my_pipeline
1017   ATTACH my_shader
1018   ATTACH my_fragment
1019 
1020   VERTEX_DATA my_buf LOCATION 0 OFFSET foo
1021 END)";
1022 
1023   Parser parser;
1024   Result r = parser.Parse(in);
1025   ASSERT_FALSE(r.IsSuccess());
1026   EXPECT_EQ("12: expected unsigned integer for OFFSET", r.Error());
1027 }
1028 
TEST_F(AmberScriptParserTest,BindVertexDataStride)1029 TEST_F(AmberScriptParserTest, BindVertexDataStride) {
1030   std::string in = R"(
1031 SHADER vertex my_shader PASSTHROUGH
1032 SHADER fragment my_fragment GLSL
1033 # GLSL Shader
1034 END
1035 BUFFER my_buf DATA_TYPE int8 SIZE 5 FILL 5
1036 BUFFER my_buf2 DATA_TYPE int8 SIZE 5 FILL 5
1037 
1038 PIPELINE graphics my_pipeline
1039   ATTACH my_shader
1040   ATTACH my_fragment
1041 
1042   VERTEX_DATA my_buf LOCATION 0 STRIDE 5
1043   VERTEX_DATA my_buf2 LOCATION 1 STRIDE 10
1044 END)";
1045 
1046   Parser parser;
1047   Result r = parser.Parse(in);
1048   ASSERT_TRUE(r.IsSuccess()) << r.Error();
1049 
1050   auto script = parser.GetScript();
1051   const auto& pipelines = script->GetPipelines();
1052   ASSERT_EQ(1U, pipelines.size());
1053 
1054   const auto* pipeline = pipelines[0].get();
1055   const auto& vertex_buffers = pipeline->GetVertexBuffers();
1056   ASSERT_EQ(2u, vertex_buffers.size());
1057 
1058   const auto& info1 = vertex_buffers[0];
1059   ASSERT_TRUE(info1.buffer != nullptr);
1060   EXPECT_EQ(0u, info1.location);
1061   EXPECT_EQ(5u, info1.stride);
1062 
1063   const auto& info2 = vertex_buffers[1];
1064   ASSERT_TRUE(info2.buffer != nullptr);
1065   EXPECT_EQ(1u, info2.location);
1066   EXPECT_EQ(10u, info2.stride);
1067 }
1068 
TEST_F(AmberScriptParserTest,BindVertexDataStrideFromFormat)1069 TEST_F(AmberScriptParserTest, BindVertexDataStrideFromFormat) {
1070   std::string in = R"(
1071 SHADER vertex my_shader PASSTHROUGH
1072 SHADER fragment my_fragment GLSL
1073 # GLSL Shader
1074 END
1075 BUFFER my_buf DATA_TYPE int8 SIZE 5 FILL 5
1076 BUFFER my_buf2 DATA_TYPE int8 SIZE 5 FILL 5
1077 
1078 PIPELINE graphics my_pipeline
1079   ATTACH my_shader
1080   ATTACH my_fragment
1081 
1082   VERTEX_DATA my_buf LOCATION 0
1083   VERTEX_DATA my_buf2 LOCATION 1 FORMAT R16_UINT
1084 END)";
1085 
1086   Parser parser;
1087   Result r = parser.Parse(in);
1088   ASSERT_TRUE(r.IsSuccess()) << r.Error();
1089 
1090   auto script = parser.GetScript();
1091   const auto& pipelines = script->GetPipelines();
1092   ASSERT_EQ(1U, pipelines.size());
1093 
1094   const auto* pipeline = pipelines[0].get();
1095   const auto& vertex_buffers = pipeline->GetVertexBuffers();
1096   ASSERT_EQ(2u, vertex_buffers.size());
1097 
1098   const auto& info1 = vertex_buffers[0];
1099   ASSERT_TRUE(info1.buffer != nullptr);
1100   EXPECT_EQ(0u, info1.location);
1101   EXPECT_EQ(1u, info1.stride);
1102 
1103   const auto& info2 = vertex_buffers[1];
1104   ASSERT_TRUE(info2.buffer != nullptr);
1105   EXPECT_EQ(1u, info2.location);
1106   EXPECT_EQ(2u, info2.stride);
1107 }
1108 
TEST_F(AmberScriptParserTest,BindVertexDataStrideMissingValue)1109 TEST_F(AmberScriptParserTest, BindVertexDataStrideMissingValue) {
1110   std::string in = R"(
1111 SHADER vertex my_shader PASSTHROUGH
1112 SHADER fragment my_fragment GLSL
1113 # GLSL Shader
1114 END
1115 BUFFER my_buf DATA_TYPE int8 SIZE 5 FILL 5
1116 
1117 PIPELINE graphics my_pipeline
1118   ATTACH my_shader
1119   ATTACH my_fragment
1120 
1121   VERTEX_DATA my_buf LOCATION 0 STRIDE
1122 END)";
1123 
1124   Parser parser;
1125   Result r = parser.Parse(in);
1126   ASSERT_FALSE(r.IsSuccess());
1127   EXPECT_EQ("13: expected unsigned integer for STRIDE", r.Error());
1128 }
1129 
TEST_F(AmberScriptParserTest,BindVertexDataStrideIncorrectValue)1130 TEST_F(AmberScriptParserTest, BindVertexDataStrideIncorrectValue) {
1131   std::string in = R"(
1132 SHADER vertex my_shader PASSTHROUGH
1133 SHADER fragment my_fragment GLSL
1134 # GLSL Shader
1135 END
1136 BUFFER my_buf DATA_TYPE int8 SIZE 5 FILL 5
1137 
1138 PIPELINE graphics my_pipeline
1139   ATTACH my_shader
1140   ATTACH my_fragment
1141 
1142   VERTEX_DATA my_buf LOCATION 0 STRIDE foo
1143 END)";
1144 
1145   Parser parser;
1146   Result r = parser.Parse(in);
1147   ASSERT_FALSE(r.IsSuccess());
1148   EXPECT_EQ("12: expected unsigned integer for STRIDE", r.Error());
1149 }
1150 
TEST_F(AmberScriptParserTest,BindVertexDataStrideZero)1151 TEST_F(AmberScriptParserTest, BindVertexDataStrideZero) {
1152   std::string in = R"(
1153 SHADER vertex my_shader PASSTHROUGH
1154 SHADER fragment my_fragment GLSL
1155 # GLSL Shader
1156 END
1157 BUFFER my_buf DATA_TYPE int8 SIZE 5 FILL 5
1158 
1159 PIPELINE graphics my_pipeline
1160   ATTACH my_shader
1161   ATTACH my_fragment
1162 
1163   VERTEX_DATA my_buf LOCATION 0 STRIDE 0
1164 END)";
1165 
1166   Parser parser;
1167   Result r = parser.Parse(in);
1168   ASSERT_FALSE(r.IsSuccess());
1169   EXPECT_EQ("12: STRIDE needs to be larger than zero", r.Error());
1170 }
1171 
TEST_F(AmberScriptParserTest,BindVertexDataFormat)1172 TEST_F(AmberScriptParserTest, BindVertexDataFormat) {
1173   std::string in = R"(
1174 SHADER vertex my_shader PASSTHROUGH
1175 SHADER fragment my_fragment GLSL
1176 # GLSL Shader
1177 END
1178 BUFFER my_buf DATA_TYPE int8 SIZE 5 FILL 5
1179 BUFFER my_buf2 DATA_TYPE int8 SIZE 5 FILL 5
1180 
1181 PIPELINE graphics my_pipeline
1182   ATTACH my_shader
1183   ATTACH my_fragment
1184 
1185   VERTEX_DATA my_buf LOCATION 0 FORMAT R8G8_UNORM
1186   VERTEX_DATA my_buf2 LOCATION 1 FORMAT R8_SRGB
1187 END)";
1188 
1189   Parser parser;
1190   Result r = parser.Parse(in);
1191   ASSERT_TRUE(r.IsSuccess()) << r.Error();
1192 
1193   auto script = parser.GetScript();
1194   const auto& pipelines = script->GetPipelines();
1195   ASSERT_EQ(1U, pipelines.size());
1196 
1197   const auto* pipeline = pipelines[0].get();
1198   const auto& vertex_buffers = pipeline->GetVertexBuffers();
1199   ASSERT_EQ(2u, vertex_buffers.size());
1200 
1201   const auto& info1 = vertex_buffers[0];
1202   ASSERT_TRUE(info1.buffer != nullptr);
1203   EXPECT_EQ(0u, info1.location);
1204   EXPECT_EQ(FormatType::kR8G8_UNORM, info1.format->GetFormatType());
1205 
1206   const auto& info2 = vertex_buffers[1];
1207   ASSERT_TRUE(info2.buffer != nullptr);
1208   EXPECT_EQ(1u, info2.location);
1209   EXPECT_EQ(FormatType::kR8_SRGB, info2.format->GetFormatType());
1210 }
1211 
TEST_F(AmberScriptParserTest,BindVertexDataFormatMissingValue)1212 TEST_F(AmberScriptParserTest, BindVertexDataFormatMissingValue) {
1213   std::string in = R"(
1214 SHADER vertex my_shader PASSTHROUGH
1215 SHADER fragment my_fragment GLSL
1216 # GLSL Shader
1217 END
1218 BUFFER my_buf DATA_TYPE int8 SIZE 5 FILL 5
1219 
1220 PIPELINE graphics my_pipeline
1221   ATTACH my_shader
1222   ATTACH my_fragment
1223 
1224   VERTEX_DATA my_buf LOCATION 0 FORMAT
1225 END)";
1226 
1227   Parser parser;
1228   Result r = parser.Parse(in);
1229   ASSERT_FALSE(r.IsSuccess());
1230   EXPECT_EQ("13: vertex data FORMAT must be an identifier", r.Error());
1231 }
1232 
TEST_F(AmberScriptParserTest,BindVertexDataFormatIncorrectValue)1233 TEST_F(AmberScriptParserTest, BindVertexDataFormatIncorrectValue) {
1234   std::string in = R"(
1235 SHADER vertex my_shader PASSTHROUGH
1236 SHADER fragment my_fragment GLSL
1237 # GLSL Shader
1238 END
1239 BUFFER my_buf DATA_TYPE int8 SIZE 5 FILL 5
1240 
1241 PIPELINE graphics my_pipeline
1242   ATTACH my_shader
1243   ATTACH my_fragment
1244 
1245   VERTEX_DATA my_buf LOCATION 0 FORMAT foo
1246 END)";
1247 
1248   Parser parser;
1249   Result r = parser.Parse(in);
1250   ASSERT_FALSE(r.IsSuccess());
1251   EXPECT_EQ("12: invalid vertex data FORMAT", r.Error());
1252 }
1253 
TEST_F(AmberScriptParserTest,BindIndexData)1254 TEST_F(AmberScriptParserTest, BindIndexData) {
1255   std::string in = R"(
1256 SHADER vertex my_shader PASSTHROUGH
1257 SHADER fragment my_fragment GLSL
1258 # GLSL Shader
1259 END
1260 BUFFER my_buf DATA_TYPE int8 SIZE 50 FILL 5
1261 
1262 PIPELINE graphics my_pipeline
1263   ATTACH my_shader
1264   ATTACH my_fragment
1265 
1266   INDEX_DATA my_buf
1267 END)";
1268 
1269   Parser parser;
1270   Result r = parser.Parse(in);
1271   ASSERT_TRUE(r.IsSuccess()) << r.Error();
1272 
1273   auto script = parser.GetScript();
1274   const auto& pipelines = script->GetPipelines();
1275   ASSERT_EQ(1U, pipelines.size());
1276 
1277   const auto* pipeline = pipelines[0].get();
1278   const auto* buf = pipeline->GetIndexBuffer();
1279   ASSERT_TRUE(buf != nullptr);
1280 }
1281 
TEST_F(AmberScriptParserTest,BindIndexataMissingBuffer)1282 TEST_F(AmberScriptParserTest, BindIndexataMissingBuffer) {
1283   std::string in = R"(
1284 SHADER vertex my_shader PASSTHROUGH
1285 SHADER fragment my_fragment GLSL
1286 # GLSL Shader
1287 END
1288 BUFFER my_buf FORMAT R32G32B32A32_SFLOAT
1289 
1290 PIPELINE graphics my_pipeline
1291   ATTACH my_shader
1292   ATTACH my_fragment
1293 
1294   INDEX_DATA
1295 END)";
1296 
1297   Parser parser;
1298   Result r = parser.Parse(in);
1299   ASSERT_FALSE(r.IsSuccess());
1300   EXPECT_EQ("13: missing buffer name in INDEX_DATA command", r.Error());
1301 }
1302 
TEST_F(AmberScriptParserTest,BindIndexDataUnknownBuffer)1303 TEST_F(AmberScriptParserTest, BindIndexDataUnknownBuffer) {
1304   std::string in = R"(
1305 SHADER vertex my_shader PASSTHROUGH
1306 SHADER fragment my_fragment GLSL
1307 # GLSL Shader
1308 END
1309 
1310 PIPELINE graphics my_pipeline
1311   ATTACH my_shader
1312   ATTACH my_fragment
1313 
1314   INDEX_DATA my_buf
1315 END)";
1316 
1317   Parser parser;
1318   Result r = parser.Parse(in);
1319   ASSERT_FALSE(r.IsSuccess());
1320   EXPECT_EQ("11: unknown buffer: my_buf", r.Error());
1321 }
1322 
TEST_F(AmberScriptParserTest,BindIndexDataExtraParameters)1323 TEST_F(AmberScriptParserTest, BindIndexDataExtraParameters) {
1324   std::string in = R"(
1325 SHADER vertex my_shader PASSTHROUGH
1326 SHADER fragment my_fragment GLSL
1327 # GLSL Shader
1328 END
1329 BUFFER my_buf FORMAT R32G32B32A32_SFLOAT
1330 
1331 PIPELINE graphics my_pipeline
1332   ATTACH my_shader
1333   ATTACH my_fragment
1334 
1335   INDEX_DATA my_buf EXTRA
1336 END)";
1337 
1338   Parser parser;
1339   Result r = parser.Parse(in);
1340   ASSERT_FALSE(r.IsSuccess());
1341   EXPECT_EQ("12: extra parameters after INDEX_DATA command: EXTRA", r.Error());
1342 }
1343 
TEST_F(AmberScriptParserTest,BindIndexDataMultiple)1344 TEST_F(AmberScriptParserTest, BindIndexDataMultiple) {
1345   std::string in = R"(
1346 SHADER vertex my_shader PASSTHROUGH
1347 SHADER fragment my_fragment GLSL
1348 # GLSL Shader
1349 END
1350 BUFFER my_buf FORMAT R32G32B32A32_SFLOAT
1351 
1352 PIPELINE graphics my_pipeline
1353   ATTACH my_shader
1354   ATTACH my_fragment
1355 
1356   INDEX_DATA my_buf
1357   INDEX_DATA my_buf
1358 END)";
1359 
1360   Parser parser;
1361   Result r = parser.Parse(in);
1362   ASSERT_FALSE(r.IsSuccess());
1363   EXPECT_EQ("13: can only bind one INDEX_DATA buffer in a pipeline", r.Error());
1364 }
1365 
TEST_F(AmberScriptParserTest,BindBuffer)1366 TEST_F(AmberScriptParserTest, BindBuffer) {
1367   std::string in = R"(
1368 SHADER vertex my_shader PASSTHROUGH
1369 SHADER fragment my_fragment GLSL
1370 # GLSL Shader
1371 END
1372 BUFFER my_buf FORMAT R32G32B32A32_SFLOAT
1373 
1374 PIPELINE graphics my_pipeline
1375   ATTACH my_shader
1376   ATTACH my_fragment
1377 
1378   BIND BUFFER my_buf AS uniform DESCRIPTOR_SET 1 BINDING 2
1379 END
1380 )";
1381 
1382   Parser parser;
1383   Result r = parser.Parse(in);
1384   ASSERT_TRUE(r.IsSuccess()) << r.Error();
1385 
1386   auto script = parser.GetScript();
1387   const auto& pipelines = script->GetPipelines();
1388   ASSERT_EQ(1U, pipelines.size());
1389 
1390   const auto* pipeline = pipelines[0].get();
1391   const auto& bufs = pipeline->GetBuffers();
1392   ASSERT_EQ(1U, bufs.size());
1393   EXPECT_EQ(BufferType::kUniform, bufs[0].type);
1394   EXPECT_EQ(1U, bufs[0].descriptor_set);
1395   EXPECT_EQ(2U, bufs[0].binding);
1396   EXPECT_EQ(static_cast<uint32_t>(0), bufs[0].location);
1397   EXPECT_EQ(FormatType::kR32G32B32A32_SFLOAT,
1398             bufs[0].buffer->GetFormat()->GetFormatType());
1399 }
1400 
TEST_F(AmberScriptParserTest,BindBufferMissingBindingValue)1401 TEST_F(AmberScriptParserTest, BindBufferMissingBindingValue) {
1402   std::string in = R"(
1403 SHADER vertex my_shader PASSTHROUGH
1404 SHADER fragment my_fragment GLSL
1405 # GLSL Shader
1406 END
1407 BUFFER my_buf FORMAT R32G32B32A32_SFLOAT
1408 
1409 PIPELINE graphics my_pipeline
1410   ATTACH my_shader
1411   ATTACH my_fragment
1412 
1413   BIND BUFFER my_buf AS uniform DESCRIPTOR_SET 1 BINDING
1414 END)";
1415 
1416   Parser parser;
1417   Result r = parser.Parse(in);
1418   ASSERT_FALSE(r.IsSuccess());
1419   EXPECT_EQ("13: invalid value for BINDING in BIND command", r.Error());
1420 }
1421 
TEST_F(AmberScriptParserTest,BindBufferMissingBinding)1422 TEST_F(AmberScriptParserTest, BindBufferMissingBinding) {
1423   std::string in = R"(
1424 SHADER vertex my_shader PASSTHROUGH
1425 SHADER fragment my_fragment GLSL
1426 # GLSL Shader
1427 END
1428 BUFFER my_buf FORMAT R32G32B32A32_SFLOAT
1429 
1430 PIPELINE graphics my_pipeline
1431   ATTACH my_shader
1432   ATTACH my_fragment
1433 
1434   BIND BUFFER my_buf AS uniform DESCRIPTOR_SET 1
1435 END)";
1436 
1437   Parser parser;
1438   Result r = parser.Parse(in);
1439   ASSERT_FALSE(r.IsSuccess());
1440   EXPECT_EQ("13: missing BINDING for BIND command", r.Error());
1441 }
1442 
TEST_F(AmberScriptParserTest,BindBufferMissingDescriptorSetValue)1443 TEST_F(AmberScriptParserTest, BindBufferMissingDescriptorSetValue) {
1444   std::string in = R"(
1445 SHADER vertex my_shader PASSTHROUGH
1446 SHADER fragment my_fragment GLSL
1447 # GLSL Shader
1448 END
1449 BUFFER my_buf FORMAT R32G32B32A32_SFLOAT
1450 
1451 PIPELINE graphics my_pipeline
1452   ATTACH my_shader
1453   ATTACH my_fragment
1454 
1455   BIND BUFFER my_buf AS uniform DESCRIPTOR_SET BINDING 2
1456 END)";
1457 
1458   Parser parser;
1459   Result r = parser.Parse(in);
1460   ASSERT_FALSE(r.IsSuccess());
1461   EXPECT_EQ("12: invalid value for DESCRIPTOR_SET in BIND command", r.Error());
1462 }
1463 
TEST_F(AmberScriptParserTest,BindBufferMissingDescriptorSet)1464 TEST_F(AmberScriptParserTest, BindBufferMissingDescriptorSet) {
1465   std::string in = R"(
1466 SHADER vertex my_shader PASSTHROUGH
1467 SHADER fragment my_fragment GLSL
1468 # GLSL Shader
1469 END
1470 BUFFER my_buf FORMAT R32G32B32A32_SFLOAT
1471 
1472 PIPELINE graphics my_pipeline
1473   ATTACH my_shader
1474   ATTACH my_fragment
1475 
1476   BIND BUFFER my_buf AS uniform BINDING 2
1477 END)";
1478 
1479   Parser parser;
1480   Result r = parser.Parse(in);
1481   ASSERT_FALSE(r.IsSuccess());
1482   EXPECT_EQ("12: missing DESCRIPTOR_SET or KERNEL for BIND command", r.Error());
1483 }
1484 
TEST_F(AmberScriptParserTest,BindingBufferExtraParams)1485 TEST_F(AmberScriptParserTest, BindingBufferExtraParams) {
1486   std::string in = R"(
1487 SHADER vertex my_shader PASSTHROUGH
1488 SHADER fragment my_fragment GLSL
1489 # GLSL Shader
1490 END
1491 BUFFER my_buf FORMAT R32G32B32A32_SFLOAT
1492 
1493 PIPELINE graphics my_pipeline
1494   ATTACH my_shader
1495   ATTACH my_fragment
1496 
1497   BIND BUFFER my_buf AS uniform DESCRIPTOR_SET 1 BINDING 2 EXTRA
1498 END)";
1499 
1500   Parser parser;
1501   Result r = parser.Parse(in);
1502   ASSERT_FALSE(r.IsSuccess());
1503   EXPECT_EQ("12: extra parameters after BIND command: EXTRA", r.Error());
1504 }
1505 
TEST_F(AmberScriptParserTest,BindingBufferInvalidBindingValue)1506 TEST_F(AmberScriptParserTest, BindingBufferInvalidBindingValue) {
1507   std::string in = R"(
1508 SHADER vertex my_shader PASSTHROUGH
1509 SHADER fragment my_fragment GLSL
1510 # GLSL Shader
1511 END
1512 BUFFER my_buf FORMAT R32G32B32A32_SFLOAT
1513 
1514 PIPELINE graphics my_pipeline
1515   ATTACH my_shader
1516   ATTACH my_fragment
1517 
1518   BIND BUFFER my_buf AS uniform DESCRIPTOR_SET 1 BINDING INVALID
1519 END)";
1520 
1521   Parser parser;
1522   Result r = parser.Parse(in);
1523   ASSERT_FALSE(r.IsSuccess());
1524   EXPECT_EQ("12: invalid value for BINDING in BIND command", r.Error());
1525 }
1526 
TEST_F(AmberScriptParserTest,BindingBufferInvalidDescriptorSetValue)1527 TEST_F(AmberScriptParserTest, BindingBufferInvalidDescriptorSetValue) {
1528   std::string in = R"(
1529 SHADER vertex my_shader PASSTHROUGH
1530 SHADER fragment my_fragment GLSL
1531 # GLSL Shader
1532 END
1533 BUFFER my_buf FORMAT R32G32B32A32_SFLOAT
1534 
1535 PIPELINE graphics my_pipeline
1536   ATTACH my_shader
1537   ATTACH my_fragment
1538 
1539   BIND BUFFER my_buf AS uniform DESCRIPTOR_SET INVALID BINDING 2
1540 END)";
1541 
1542   Parser parser;
1543   Result r = parser.Parse(in);
1544   ASSERT_FALSE(r.IsSuccess());
1545   EXPECT_EQ("12: invalid value for DESCRIPTOR_SET in BIND command", r.Error());
1546 }
1547 
TEST_F(AmberScriptParserTest,BindingBufferInvalidBufferType)1548 TEST_F(AmberScriptParserTest, BindingBufferInvalidBufferType) {
1549   std::string in = R"(
1550 SHADER vertex my_shader PASSTHROUGH
1551 SHADER fragment my_fragment GLSL
1552 # GLSL Shader
1553 END
1554 BUFFER my_buf FORMAT R32G32B32A32_SFLOAT
1555 
1556 PIPELINE graphics my_pipeline
1557   ATTACH my_shader
1558   ATTACH my_fragment
1559 
1560   BIND BUFFER my_buf AS INVALID DESCRIPTOR_SET 1 BINDING 2
1561 END)";
1562 
1563   Parser parser;
1564   Result r = parser.Parse(in);
1565   ASSERT_FALSE(r.IsSuccess());
1566   EXPECT_EQ("12: unknown buffer_type: INVALID", r.Error());
1567 }
1568 
1569 struct BufferTypeData {
1570   const char* name;
1571   BufferType type;
1572 };
1573 
1574 using AmberScriptParserBufferTypeTest = testing::TestWithParam<BufferTypeData>;
TEST_P(AmberScriptParserBufferTypeTest,BufferType)1575 TEST_P(AmberScriptParserBufferTypeTest, BufferType) {
1576   auto test_data = GetParam();
1577 
1578   std::string in = R"(
1579 SHADER vertex my_shader PASSTHROUGH
1580 SHADER fragment my_fragment GLSL
1581 # GLSL Shader
1582 END
1583 BUFFER my_buf FORMAT R32G32B32A32_SFLOAT
1584 
1585 PIPELINE graphics my_pipeline
1586   ATTACH my_shader
1587   ATTACH my_fragment
1588 
1589   BIND BUFFER my_buf AS )" +
1590                    std::string(test_data.name) +
1591                    " DESCRIPTOR_SET 0 BINDING 0\nEND";
1592 
1593   Parser parser;
1594   Result r = parser.Parse(in);
1595   ASSERT_TRUE(r.IsSuccess()) << r.Error();
1596 
1597   auto script = parser.GetScript();
1598   const auto& pipelines = script->GetPipelines();
1599   ASSERT_EQ(1U, pipelines.size());
1600 
1601   const auto* pipeline = pipelines[0].get();
1602   const auto& bufs = pipeline->GetBuffers();
1603   ASSERT_EQ(1U, bufs.size());
1604   EXPECT_EQ(test_data.type, bufs[0].type);
1605 }
1606 INSTANTIATE_TEST_SUITE_P(
1607     AmberScriptParserBufferTypeTestSamples,
1608     AmberScriptParserBufferTypeTest,
1609     testing::Values(BufferTypeData{"uniform", BufferType::kUniform},
1610                     BufferTypeData{
1611                         "storage",
1612                         BufferType::kStorage}));  // NOLINT(whitespace/parens)
1613 
TEST_F(AmberScriptParserTest,BindPushConstants)1614 TEST_F(AmberScriptParserTest, BindPushConstants) {
1615   std::string in = R"(
1616 SHADER vertex my_shader PASSTHROUGH
1617 SHADER fragment my_fragment GLSL
1618 # GLSL Shader
1619 END
1620 BUFFER my_buf DATA_TYPE float SIZE 20 FILL 5
1621 
1622 PIPELINE graphics my_pipeline
1623   ATTACH my_shader
1624   ATTACH my_fragment
1625 
1626   BIND BUFFER my_buf AS push_constant
1627 END)";
1628 
1629   Parser parser;
1630   Result r = parser.Parse(in);
1631   ASSERT_TRUE(r.IsSuccess()) << r.Error();
1632 
1633   auto script = parser.GetScript();
1634   const auto& pipelines = script->GetPipelines();
1635   ASSERT_EQ(1U, pipelines.size());
1636 
1637   const auto* pipeline = pipelines[0].get();
1638   const auto& buf = pipeline->GetPushConstantBuffer();
1639   ASSERT_TRUE(buf.buffer != nullptr);
1640   EXPECT_EQ(20u, buf.buffer->ElementCount());
1641   EXPECT_EQ(20u, buf.buffer->ValueCount());
1642   EXPECT_EQ(20u * sizeof(float), buf.buffer->GetSizeInBytes());
1643 }
1644 
TEST_F(AmberScriptParserTest,BindPushConstantsExtraParams)1645 TEST_F(AmberScriptParserTest, BindPushConstantsExtraParams) {
1646   std::string in = R"(
1647 SHADER vertex my_shader PASSTHROUGH
1648 SHADER fragment my_fragment GLSL
1649 # GLSL Shader
1650 END
1651 BUFFER my_buf DATA_TYPE float SIZE 20 FILL 5
1652 
1653 PIPELINE graphics my_pipeline
1654   ATTACH my_shader
1655   ATTACH my_fragment
1656 
1657   BIND BUFFER my_buf AS push_constant EXTRA
1658 END)";
1659 
1660   Parser parser;
1661   Result r = parser.Parse(in);
1662   ASSERT_FALSE(r.IsSuccess());
1663   EXPECT_EQ("12: extra parameters after BIND command: EXTRA", r.Error());
1664 }
1665 
TEST_F(AmberScriptParserTest,BindBufferOpenCLArgName)1666 TEST_F(AmberScriptParserTest, BindBufferOpenCLArgName) {
1667   std::string in = R"(
1668 SHADER compute my_shader OPENCL-C
1669 #shader
1670 END
1671 BUFFER my_buf DATA_TYPE uint32 DATA 1 END
1672 
1673 PIPELINE compute my_pipeline
1674   ATTACH my_shader
1675   BIND BUFFER my_buf AS storage KERNEL ARG_NAME arg
1676 END)";
1677 
1678   Parser parser;
1679   Result r = parser.Parse(in);
1680   ASSERT_TRUE(r.IsSuccess());
1681 }
1682 
TEST_F(AmberScriptParserTest,BindBufferOpenCLArgNumber)1683 TEST_F(AmberScriptParserTest, BindBufferOpenCLArgNumber) {
1684   std::string in = R"(
1685 SHADER compute my_shader OPENCL-C
1686 #shader
1687 END
1688 BUFFER my_buf DATA_TYPE uint32 DATA 1 END
1689 
1690 PIPELINE compute my_pipeline
1691   ATTACH my_shader
1692   BIND BUFFER my_buf AS storage KERNEL ARG_NUMBER 0
1693 END)";
1694 
1695   Parser parser;
1696   Result r = parser.Parse(in);
1697   ASSERT_TRUE(r.IsSuccess());
1698 }
1699 
TEST_F(AmberScriptParserTest,BindBufferOpenCLArgNameTypeless)1700 TEST_F(AmberScriptParserTest, BindBufferOpenCLArgNameTypeless) {
1701   std::string in = R"(
1702 SHADER compute my_shader OPENCL-C
1703 #shader
1704 END
1705 BUFFER my_buf DATA_TYPE uint32 DATA 1 END
1706 
1707 PIPELINE compute my_pipeline
1708   ATTACH my_shader
1709   BIND BUFFER my_buf KERNEL ARG_NAME arg
1710 END)";
1711 
1712   Parser parser;
1713   Result r = parser.Parse(in);
1714   ASSERT_TRUE(r.IsSuccess());
1715 }
1716 
TEST_F(AmberScriptParserTest,BindBufferOpenCLArgNumberTypeless)1717 TEST_F(AmberScriptParserTest, BindBufferOpenCLArgNumberTypeless) {
1718   std::string in = R"(
1719 SHADER compute my_shader OPENCL-C
1720 #shader
1721 END
1722 BUFFER my_buf DATA_TYPE uint32 DATA 1 END
1723 
1724 PIPELINE compute my_pipeline
1725   ATTACH my_shader
1726   BIND BUFFER my_buf KERNEL ARG_NUMBER 0
1727 END)";
1728 
1729   Parser parser;
1730   Result r = parser.Parse(in);
1731   ASSERT_TRUE(r.IsSuccess());
1732 }
1733 
TEST_F(AmberScriptParserTest,BindBufferOpenCLMissingKernel)1734 TEST_F(AmberScriptParserTest, BindBufferOpenCLMissingKernel) {
1735   std::string in = R"(
1736 SHADER compute my_shader OPENCL-C
1737 #shader
1738 END
1739 BUFFER my_buf DATA_TYPE uint32 DATA 1 END
1740 
1741 PIPELINE compute my_pipeline
1742   ATTACH my_shader
1743   BIND BUFFER my_buf AS storage ARG_NAME arg
1744 END)";
1745 
1746   Parser parser;
1747   Result r = parser.Parse(in);
1748   ASSERT_FALSE(r.IsSuccess());
1749   EXPECT_EQ("9: missing DESCRIPTOR_SET or KERNEL for BIND command", r.Error());
1750 }
1751 
TEST_F(AmberScriptParserTest,BindBufferOpenCLMissingArg)1752 TEST_F(AmberScriptParserTest, BindBufferOpenCLMissingArg) {
1753   std::string in = R"(
1754 SHADER compute my_shader OPENCL-C
1755 #shader
1756 END
1757 BUFFER my_buf DATA_TYPE uint32 DATA 1 END
1758 
1759 PIPELINE compute my_pipeline
1760   ATTACH my_shader
1761   BIND BUFFER my_buf AS storage KERNEL arg
1762 END)";
1763 
1764   Parser parser;
1765   Result r = parser.Parse(in);
1766   ASSERT_FALSE(r.IsSuccess());
1767   EXPECT_EQ("9: missing ARG_NAME or ARG_NUMBER keyword", r.Error());
1768 }
1769 
TEST_F(AmberScriptParserTest,BindBufferOpenCLMissingArgName)1770 TEST_F(AmberScriptParserTest, BindBufferOpenCLMissingArgName) {
1771   std::string in = R"(
1772 SHADER compute my_shader OPENCL-C
1773 #shader
1774 END
1775 BUFFER my_buf DATA_TYPE uint32 DATA 1 END
1776 
1777 PIPELINE compute my_pipeline
1778   ATTACH my_shader
1779   BIND BUFFER my_buf KERNEL ARG_NAME
1780 END)";
1781 
1782   Parser parser;
1783   Result r = parser.Parse(in);
1784   ASSERT_FALSE(r.IsSuccess());
1785   EXPECT_EQ("10: expected argument identifier", r.Error());
1786 }
1787 
TEST_F(AmberScriptParserTest,BindBufferOpenCLMissingArgNumber)1788 TEST_F(AmberScriptParserTest, BindBufferOpenCLMissingArgNumber) {
1789   std::string in = R"(
1790 SHADER compute my_shader OPENCL-C
1791 #shader
1792 END
1793 BUFFER my_buf DATA_TYPE uint32 DATA 1 END
1794 
1795 PIPELINE compute my_pipeline
1796   ATTACH my_shader
1797   BIND BUFFER my_buf AS storage KERNEL ARG_NUMBER
1798 END)";
1799 
1800   Parser parser;
1801   Result r = parser.Parse(in);
1802   ASSERT_FALSE(r.IsSuccess());
1803   EXPECT_EQ("10: expected argument number", r.Error());
1804 }
1805 
TEST_F(AmberScriptParserTest,BindBufferOpenCLArgNameNotString)1806 TEST_F(AmberScriptParserTest, BindBufferOpenCLArgNameNotString) {
1807   std::string in = R"(
1808 SHADER compute my_shader OPENCL-C
1809 #shader
1810 END
1811 BUFFER my_buf DATA_TYPE uint32 DATA 1 END
1812 
1813 PIPELINE compute my_pipeline
1814   ATTACH my_shader
1815   BIND BUFFER my_buf AS storage KERNEL ARG_NAME 0
1816 END)";
1817 
1818   Parser parser;
1819   Result r = parser.Parse(in);
1820   ASSERT_FALSE(r.IsSuccess());
1821   EXPECT_EQ("9: expected argument identifier", r.Error());
1822 }
1823 
TEST_F(AmberScriptParserTest,BindBufferOpenCLArgNumberNotInteger)1824 TEST_F(AmberScriptParserTest, BindBufferOpenCLArgNumberNotInteger) {
1825   std::string in = R"(
1826 SHADER compute my_shader OPENCL-C
1827 #shader
1828 END
1829 BUFFER my_buf DATA_TYPE uint32 DATA 1 END
1830 
1831 PIPELINE compute my_pipeline
1832   ATTACH my_shader
1833   BIND BUFFER my_buf KERNEL ARG_NUMBER in
1834 END)";
1835 
1836   Parser parser;
1837   Result r = parser.Parse(in);
1838   ASSERT_FALSE(r.IsSuccess());
1839   EXPECT_EQ("9: expected argument number", r.Error());
1840 }
1841 
TEST_F(AmberScriptParserTest,BindSamplerOpenCLMissingKernel)1842 TEST_F(AmberScriptParserTest, BindSamplerOpenCLMissingKernel) {
1843   std::string in = R"(
1844 SHADER compute my_shader OPENCL-C
1845 #shader
1846 END
1847 SAMPLER s
1848 
1849 PIPELINE compute my_pipeline
1850   ATTACH my_shader
1851   BIND SAMPLER s
1852 END
1853 )";
1854 
1855   Parser parser;
1856   Result r = parser.Parse(in);
1857   ASSERT_FALSE(r.IsSuccess());
1858   EXPECT_EQ("10: expected a string token for BIND command", r.Error());
1859 }
1860 
TEST_F(AmberScriptParserTest,BindSamplerOpenCLInvalidKernel)1861 TEST_F(AmberScriptParserTest, BindSamplerOpenCLInvalidKernel) {
1862   std::string in = R"(
1863 SHADER compute my_shader OPENCL-C
1864 #shader
1865 END
1866 SAMPLER s
1867 
1868 PIPELINE compute my_pipeline
1869   ATTACH my_shader
1870   BIND SAMPLER s INVALID
1871 END
1872 )";
1873 
1874   Parser parser;
1875   Result r = parser.Parse(in);
1876   ASSERT_FALSE(r.IsSuccess());
1877   EXPECT_EQ("9: missing DESCRIPTOR_SET or KERNEL for BIND command", r.Error());
1878 }
1879 
TEST_F(AmberScriptParserTest,BindSamplerOpenCLMissingArgument)1880 TEST_F(AmberScriptParserTest, BindSamplerOpenCLMissingArgument) {
1881   std::string in = R"(
1882 SHADER compute my_shader OPENCL-C
1883 #shader
1884 END
1885 SAMPLER s
1886 
1887 PIPELINE compute my_pipeline
1888   ATTACH my_shader
1889   BIND SAMPLER s KERNEL
1890 END
1891 )";
1892 
1893   Parser parser;
1894   Result r = parser.Parse(in);
1895   ASSERT_FALSE(r.IsSuccess());
1896   EXPECT_EQ("10: missing kernel arg identifier", r.Error());
1897 }
1898 
TEST_F(AmberScriptParserTest,BindSamplerOpenCLMissingArgumentName)1899 TEST_F(AmberScriptParserTest, BindSamplerOpenCLMissingArgumentName) {
1900   std::string in = R"(
1901 SHADER compute my_shader OPENCL-C
1902 #shader
1903 END
1904 SAMPLER s
1905 
1906 PIPELINE compute my_pipeline
1907   ATTACH my_shader
1908   BIND SAMPLER s KERNEL ARG_NAME
1909 END
1910 )";
1911 
1912   Parser parser;
1913   Result r = parser.Parse(in);
1914   ASSERT_FALSE(r.IsSuccess());
1915   EXPECT_EQ("10: expected argument identifier", r.Error());
1916 }
1917 
TEST_F(AmberScriptParserTest,BindSamplerOpenCLArgumentNameNotString)1918 TEST_F(AmberScriptParserTest, BindSamplerOpenCLArgumentNameNotString) {
1919   std::string in = R"(
1920 SHADER compute my_shader OPENCL-C
1921 #shader
1922 END
1923 SAMPLER s
1924 
1925 PIPELINE compute my_pipeline
1926   ATTACH my_shader
1927   BIND SAMPLER s KERNEL ARG_NAME 0
1928 END
1929 )";
1930 
1931   Parser parser;
1932   Result r = parser.Parse(in);
1933   ASSERT_FALSE(r.IsSuccess());
1934   EXPECT_EQ("9: expected argument identifier", r.Error());
1935 }
1936 
TEST_F(AmberScriptParserTest,BindSamplerOpenCLMissingArgumentNumber)1937 TEST_F(AmberScriptParserTest, BindSamplerOpenCLMissingArgumentNumber) {
1938   std::string in = R"(
1939 SHADER compute my_shader OPENCL-C
1940 #shader
1941 END
1942 SAMPLER s
1943 
1944 PIPELINE compute my_pipeline
1945   ATTACH my_shader
1946   BIND SAMPLER s KERNEL ARG_NUMBER
1947 END
1948 )";
1949 
1950   Parser parser;
1951   Result r = parser.Parse(in);
1952   ASSERT_FALSE(r.IsSuccess());
1953   EXPECT_EQ("10: expected argument number", r.Error());
1954 }
1955 
TEST_F(AmberScriptParserTest,BindSamplerOpenCLArgumentNumberNotInteger)1956 TEST_F(AmberScriptParserTest, BindSamplerOpenCLArgumentNumberNotInteger) {
1957   std::string in = R"(
1958 SHADER compute my_shader OPENCL-C
1959 #shader
1960 END
1961 SAMPLER s
1962 
1963 PIPELINE compute my_pipeline
1964   ATTACH my_shader
1965   BIND SAMPLER s KERNEL ARG_NUMBER a
1966 END
1967 )";
1968 
1969   Parser parser;
1970   Result r = parser.Parse(in);
1971   ASSERT_FALSE(r.IsSuccess());
1972   EXPECT_EQ("9: expected argument number", r.Error());
1973 }
1974 
TEST_F(AmberScriptParserTest,BindBufferStorageImageCompute)1975 TEST_F(AmberScriptParserTest, BindBufferStorageImageCompute) {
1976   std::string in = R"(
1977 SHADER compute compute_shader GLSL
1978 # GLSL Shader
1979 END
1980 
1981 BUFFER texture FORMAT R8G8B8A8_UNORM
1982 
1983 PIPELINE compute pipeline
1984   ATTACH compute_shader
1985   BIND BUFFER texture AS storage_image DESCRIPTOR_SET 0 BINDING 0
1986 END)";
1987 
1988   Parser parser;
1989   Result r = parser.Parse(in);
1990   ASSERT_TRUE(r.IsSuccess()) << r.Error();
1991 
1992   auto script = parser.GetScript();
1993   const auto& pipelines = script->GetPipelines();
1994   ASSERT_EQ(1U, pipelines.size());
1995 
1996   const auto* pipeline = pipelines[0].get();
1997   const auto& bufs = pipeline->GetBuffers();
1998   ASSERT_EQ(1U, bufs.size());
1999   EXPECT_EQ(BufferType::kStorageImage, bufs[0].type);
2000 }
2001 
TEST_F(AmberScriptParserTest,BindBufferStorageImageGraphics)2002 TEST_F(AmberScriptParserTest, BindBufferStorageImageGraphics) {
2003   std::string in = R"(
2004 SHADER vertex vert_shader PASSTHROUGH
2005 SHADER fragment frag_shader GLSL
2006 # GLSL Shader
2007 END
2008 
2009 BUFFER texture FORMAT R8G8B8A8_UNORM
2010 BUFFER framebuffer FORMAT R8G8B8A8_UNORM
2011 
2012 PIPELINE graphics pipeline
2013   ATTACH vert_shader
2014   ATTACH frag_shader
2015   BIND BUFFER texture AS storage_image DESCRIPTOR_SET 0 BINDING 0
2016   BIND BUFFER framebuffer AS color LOCATION 0
2017 END)";
2018 
2019   Parser parser;
2020   Result r = parser.Parse(in);
2021   ASSERT_TRUE(r.IsSuccess()) << r.Error();
2022 
2023   auto script = parser.GetScript();
2024   const auto& pipelines = script->GetPipelines();
2025   ASSERT_EQ(1U, pipelines.size());
2026 
2027   const auto* pipeline = pipelines[0].get();
2028   const auto& bufs = pipeline->GetBuffers();
2029   ASSERT_EQ(1U, bufs.size());
2030   EXPECT_EQ(BufferType::kStorageImage, bufs[0].type);
2031 }
2032 
TEST_F(AmberScriptParserTest,BindBufferStorageImageMissingDescriptorSetValue)2033 TEST_F(AmberScriptParserTest, BindBufferStorageImageMissingDescriptorSetValue) {
2034   std::string in = R"(
2035 SHADER compute compute_shader GLSL
2036 # GLSL Shader
2037 END
2038 
2039 BUFFER texture FORMAT R8G8B8A8_UNORM
2040 
2041 PIPELINE compute pipeline
2042   ATTACH compute_shader
2043   BIND BUFFER texture AS storage_image DESCRIPTOR_SET BINDING 0
2044 END)";
2045 
2046   Parser parser;
2047   Result r = parser.Parse(in);
2048   ASSERT_FALSE(r.IsSuccess());
2049   EXPECT_EQ("10: invalid value for DESCRIPTOR_SET in BIND command", r.Error());
2050 }
2051 
TEST_F(AmberScriptParserTest,BindBufferStorageImageMissingDescriptorSet)2052 TEST_F(AmberScriptParserTest, BindBufferStorageImageMissingDescriptorSet) {
2053   std::string in = R"(
2054 SHADER compute compute_shader GLSL
2055 # GLSL Shader
2056 END
2057 
2058 BUFFER texture FORMAT R8G8B8A8_UNORM
2059 
2060 PIPELINE compute pipeline
2061   ATTACH compute_shader
2062   BIND BUFFER texture AS storage_image BINDING 0
2063 END)";
2064 
2065   Parser parser;
2066   Result r = parser.Parse(in);
2067   ASSERT_FALSE(r.IsSuccess());
2068   EXPECT_EQ("10: missing DESCRIPTOR_SET or KERNEL for BIND command", r.Error());
2069 }
2070 
TEST_F(AmberScriptParserTest,BindBufferStorageImageMissingBindingValue)2071 TEST_F(AmberScriptParserTest, BindBufferStorageImageMissingBindingValue) {
2072   std::string in = R"(
2073 SHADER compute compute_shader GLSL
2074 # GLSL Shader
2075 END
2076 
2077 BUFFER texture FORMAT R8G8B8A8_UNORM
2078 
2079 PIPELINE compute pipeline
2080   ATTACH compute_shader
2081   BIND BUFFER texture AS storage_image DESCRIPTOR_SET 0 BINDING
2082 END)";
2083 
2084   Parser parser;
2085   Result r = parser.Parse(in);
2086   ASSERT_FALSE(r.IsSuccess());
2087   EXPECT_EQ("11: invalid value for BINDING in BIND command", r.Error());
2088 }
2089 
TEST_F(AmberScriptParserTest,BindBufferStorageImageMissingBinding)2090 TEST_F(AmberScriptParserTest, BindBufferStorageImageMissingBinding) {
2091   std::string in = R"(
2092 SHADER compute compute_shader GLSL
2093 # GLSL Shader
2094 END
2095 
2096 BUFFER texture FORMAT R8G8B8A8_UNORM
2097 
2098 PIPELINE compute pipeline
2099   ATTACH compute_shader
2100   BIND BUFFER texture AS storage_image DESCRIPTOR_SET 0
2101 END)";
2102 
2103   Parser parser;
2104   Result r = parser.Parse(in);
2105   ASSERT_FALSE(r.IsSuccess());
2106   EXPECT_EQ("11: missing BINDING for BIND command", r.Error());
2107 }
2108 
TEST_F(AmberScriptParserTest,BindBufferSampledImage)2109 TEST_F(AmberScriptParserTest, BindBufferSampledImage) {
2110   std::string in = R"(
2111 SHADER vertex vert_shader PASSTHROUGH
2112 SHADER fragment frag_shader GLSL
2113 # GLSL Shader
2114 END
2115 
2116 BUFFER texture FORMAT R8G8B8A8_UNORM
2117 BUFFER framebuffer FORMAT R8G8B8A8_UNORM
2118 
2119 PIPELINE graphics pipeline
2120   ATTACH vert_shader
2121   ATTACH frag_shader
2122   BIND BUFFER texture AS sampled_image DESCRIPTOR_SET 0 BINDING 0
2123   BIND BUFFER framebuffer AS color LOCATION 0
2124 END)";
2125 
2126   Parser parser;
2127   Result r = parser.Parse(in);
2128   ASSERT_TRUE(r.IsSuccess()) << r.Error();
2129 
2130   auto script = parser.GetScript();
2131   const auto& pipelines = script->GetPipelines();
2132   ASSERT_EQ(1U, pipelines.size());
2133 
2134   const auto* pipeline = pipelines[0].get();
2135   const auto& bufs = pipeline->GetBuffers();
2136   ASSERT_EQ(1U, bufs.size());
2137   EXPECT_EQ(BufferType::kSampledImage, bufs[0].type);
2138 }
2139 
TEST_F(AmberScriptParserTest,BindBufferSampledImageMissingDescriptorSetValue)2140 TEST_F(AmberScriptParserTest, BindBufferSampledImageMissingDescriptorSetValue) {
2141   std::string in = R"(
2142 SHADER vertex vert_shader PASSTHROUGH
2143 SHADER fragment frag_shader GLSL
2144 # GLSL Shader
2145 END
2146 
2147 BUFFER texture FORMAT R8G8B8A8_UNORM
2148 
2149 PIPELINE graphics pipeline
2150   ATTACH vert_shader
2151   ATTACH frag_shader
2152   BIND BUFFER texture AS sampled_image DESCRIPTOR_SET BINDING 0
2153 END)";
2154 
2155   Parser parser;
2156   Result r = parser.Parse(in);
2157   ASSERT_FALSE(r.IsSuccess());
2158   EXPECT_EQ("12: invalid value for DESCRIPTOR_SET in BIND command", r.Error());
2159 }
2160 
TEST_F(AmberScriptParserTest,BindBufferSampledImageMissingDescriptorSet)2161 TEST_F(AmberScriptParserTest, BindBufferSampledImageMissingDescriptorSet) {
2162   std::string in = R"(
2163 SHADER vertex vert_shader PASSTHROUGH
2164 SHADER fragment frag_shader GLSL
2165 # GLSL Shader
2166 END
2167 
2168 BUFFER texture FORMAT R8G8B8A8_UNORM
2169 
2170 PIPELINE graphics pipeline
2171   ATTACH vert_shader
2172   ATTACH frag_shader
2173   BIND BUFFER texture AS sampled_image BINDING 0
2174 END)";
2175 
2176   Parser parser;
2177   Result r = parser.Parse(in);
2178   ASSERT_FALSE(r.IsSuccess());
2179   EXPECT_EQ("12: missing DESCRIPTOR_SET or KERNEL for BIND command", r.Error());
2180 }
2181 
TEST_F(AmberScriptParserTest,BindBufferSampledImageMissingBindingValue)2182 TEST_F(AmberScriptParserTest, BindBufferSampledImageMissingBindingValue) {
2183   std::string in = R"(
2184 SHADER vertex vert_shader PASSTHROUGH
2185 SHADER fragment frag_shader GLSL
2186 # GLSL Shader
2187 END
2188 
2189 BUFFER texture FORMAT R8G8B8A8_UNORM
2190 
2191 PIPELINE graphics pipeline
2192   ATTACH vert_shader
2193   ATTACH frag_shader
2194   BIND BUFFER texture AS sampled_image DESCRIPTOR_SET 0 BINDING
2195 END)";
2196 
2197   Parser parser;
2198   Result r = parser.Parse(in);
2199   ASSERT_FALSE(r.IsSuccess());
2200   EXPECT_EQ("13: invalid value for BINDING in BIND command", r.Error());
2201 }
2202 
TEST_F(AmberScriptParserTest,BindBufferSampledImageMissingBinding)2203 TEST_F(AmberScriptParserTest, BindBufferSampledImageMissingBinding) {
2204   std::string in = R"(
2205 SHADER vertex vert_shader PASSTHROUGH
2206 SHADER fragment frag_shader GLSL
2207 # GLSL Shader
2208 END
2209 
2210 BUFFER texture FORMAT R8G8B8A8_UNORM
2211 
2212 PIPELINE graphics pipeline
2213   ATTACH vert_shader
2214   ATTACH frag_shader
2215   BIND BUFFER texture AS sampled_image DESCRIPTOR_SET 0
2216 END)";
2217 
2218   Parser parser;
2219   Result r = parser.Parse(in);
2220   ASSERT_FALSE(r.IsSuccess());
2221   EXPECT_EQ("13: missing BINDING for BIND command", r.Error());
2222 }
2223 
TEST_F(AmberScriptParserTest,BindBufferCombinedImageSampler)2224 TEST_F(AmberScriptParserTest, BindBufferCombinedImageSampler) {
2225   std::string in = R"(
2226 SHADER vertex vert_shader PASSTHROUGH
2227 SHADER fragment frag_shader GLSL
2228 # GLSL Shader
2229 END
2230 
2231 BUFFER texture FORMAT R8G8B8A8_UNORM
2232 BUFFER framebuffer FORMAT R8G8B8A8_UNORM
2233 SAMPLER sampler
2234 
2235 PIPELINE graphics pipeline
2236   ATTACH vert_shader
2237   ATTACH frag_shader
2238   BIND BUFFER texture AS combined_image_sampler SAMPLER sampler DESCRIPTOR_SET 0 BINDING 0
2239   BIND BUFFER framebuffer AS color LOCATION 0
2240 END)";
2241 
2242   Parser parser;
2243   Result r = parser.Parse(in);
2244   ASSERT_TRUE(r.IsSuccess()) << r.Error();
2245 
2246   auto script = parser.GetScript();
2247   const auto& pipelines = script->GetPipelines();
2248   ASSERT_EQ(1U, pipelines.size());
2249 
2250   const auto* pipeline = pipelines[0].get();
2251   const auto& bufs = pipeline->GetBuffers();
2252   ASSERT_EQ(1U, bufs.size());
2253   EXPECT_EQ(BufferType::kCombinedImageSampler, bufs[0].type);
2254 }
2255 
TEST_F(AmberScriptParserTest,BindBufferCombinedImageSamplerMissingDescriptorSetValue)2256 TEST_F(AmberScriptParserTest,
2257        BindBufferCombinedImageSamplerMissingDescriptorSetValue) {
2258   std::string in = R"(
2259 SHADER vertex vert_shader PASSTHROUGH
2260 SHADER fragment frag_shader GLSL
2261 # GLSL Shader
2262 END
2263 
2264 BUFFER texture FORMAT R8G8B8A8_UNORM
2265 SAMPLER sampler
2266 
2267 PIPELINE graphics pipeline
2268   ATTACH vert_shader
2269   ATTACH frag_shader
2270   BIND BUFFER texture AS combined_image_sampler SAMPLER sampler DESCRIPTOR_SET BINDING 0
2271 END)";
2272 
2273   Parser parser;
2274   Result r = parser.Parse(in);
2275   ASSERT_FALSE(r.IsSuccess());
2276   EXPECT_EQ("13: invalid value for DESCRIPTOR_SET in BIND command", r.Error());
2277 }
2278 
TEST_F(AmberScriptParserTest,BindBufferCombinedImageSamplerMissingDescriptorSet)2279 TEST_F(AmberScriptParserTest,
2280        BindBufferCombinedImageSamplerMissingDescriptorSet) {
2281   std::string in = R"(
2282 SHADER vertex vert_shader PASSTHROUGH
2283 SHADER fragment frag_shader GLSL
2284 # GLSL Shader
2285 END
2286 
2287 BUFFER texture FORMAT R8G8B8A8_UNORM
2288 SAMPLER sampler
2289 
2290 PIPELINE graphics pipeline
2291   ATTACH vert_shader
2292   ATTACH frag_shader
2293   BIND BUFFER texture AS combined_image_sampler SAMPLER sampler BINDING 0
2294 END)";
2295 
2296   Parser parser;
2297   Result r = parser.Parse(in);
2298   ASSERT_FALSE(r.IsSuccess());
2299   EXPECT_EQ("13: missing DESCRIPTOR_SET or KERNEL for BIND command", r.Error());
2300 }
2301 
TEST_F(AmberScriptParserTest,BindBufferCombinedImageSamplerMissingBindingValue)2302 TEST_F(AmberScriptParserTest,
2303        BindBufferCombinedImageSamplerMissingBindingValue) {
2304   std::string in = R"(
2305 SHADER vertex vert_shader PASSTHROUGH
2306 SHADER fragment frag_shader GLSL
2307 # GLSL Shader
2308 END
2309 
2310 BUFFER texture FORMAT R8G8B8A8_UNORM
2311 SAMPLER sampler
2312 
2313 PIPELINE graphics pipeline
2314   ATTACH vert_shader
2315   ATTACH frag_shader
2316   BIND BUFFER texture AS combined_image_sampler SAMPLER sampler DESCRIPTOR_SET 0 BINDING
2317 END)";
2318 
2319   Parser parser;
2320   Result r = parser.Parse(in);
2321   ASSERT_FALSE(r.IsSuccess());
2322   EXPECT_EQ("14: invalid value for BINDING in BIND command", r.Error());
2323 }
2324 
TEST_F(AmberScriptParserTest,BindBufferCombinedImageSamplerMissingBinding)2325 TEST_F(AmberScriptParserTest, BindBufferCombinedImageSamplerMissingBinding) {
2326   std::string in = R"(
2327 SHADER vertex vert_shader PASSTHROUGH
2328 SHADER fragment frag_shader GLSL
2329 # GLSL Shader
2330 END
2331 
2332 BUFFER texture FORMAT R8G8B8A8_UNORM
2333 SAMPLER sampler
2334 
2335 PIPELINE graphics pipeline
2336   ATTACH vert_shader
2337   ATTACH frag_shader
2338   BIND BUFFER texture AS combined_image_sampler SAMPLER sampler DESCRIPTOR_SET 0
2339 END)";
2340 
2341   Parser parser;
2342   Result r = parser.Parse(in);
2343   ASSERT_FALSE(r.IsSuccess());
2344   EXPECT_EQ("14: missing BINDING for BIND command", r.Error());
2345 }
2346 
TEST_F(AmberScriptParserTest,BindBufferCombinedImageSamplerMissingSampler)2347 TEST_F(AmberScriptParserTest, BindBufferCombinedImageSamplerMissingSampler) {
2348   std::string in = R"(
2349 SHADER vertex vert_shader PASSTHROUGH
2350 SHADER fragment frag_shader GLSL
2351 # GLSL Shader
2352 END
2353 
2354 BUFFER texture FORMAT R8G8B8A8_UNORM
2355 
2356 PIPELINE graphics pipeline
2357   ATTACH vert_shader
2358   ATTACH frag_shader
2359   BIND BUFFER texture AS combined_image_sampler DESCRIPTOR_SET 0 BINDING 0
2360 END)";
2361 
2362   Parser parser;
2363   Result r = parser.Parse(in);
2364   ASSERT_FALSE(r.IsSuccess());
2365   EXPECT_EQ("12: expecting SAMPLER for combined image sampler", r.Error());
2366 }
2367 
TEST_F(AmberScriptParserTest,BindBufferCombinedImageSamplerUnknownSampler)2368 TEST_F(AmberScriptParserTest, BindBufferCombinedImageSamplerUnknownSampler) {
2369   std::string in = R"(
2370 SHADER vertex vert_shader PASSTHROUGH
2371 SHADER fragment frag_shader GLSL
2372 # GLSL Shader
2373 END
2374 
2375 BUFFER texture FORMAT R8G8B8A8_UNORM
2376 
2377 PIPELINE graphics pipeline
2378   ATTACH vert_shader
2379   ATTACH frag_shader
2380   BIND BUFFER texture AS combined_image_sampler SAMPLER foo DESCRIPTOR_SET 0 BINDING 0
2381 END)";
2382 
2383   Parser parser;
2384   Result r = parser.Parse(in);
2385   ASSERT_FALSE(r.IsSuccess());
2386   EXPECT_EQ("12: unknown sampler: foo", r.Error());
2387 }
2388 
TEST_F(AmberScriptParserTest,BindBufferCombinedImageSamplerBaseMipLevel)2389 TEST_F(AmberScriptParserTest, BindBufferCombinedImageSamplerBaseMipLevel) {
2390   std::string in = R"(
2391 SHADER vertex vert_shader PASSTHROUGH
2392 SHADER fragment frag_shader GLSL
2393 # GLSL Shader
2394 END
2395 
2396 BUFFER texture FORMAT R8G8B8A8_UNORM MIP_LEVELS 4
2397 BUFFER framebuffer FORMAT R8G8B8A8_UNORM
2398 SAMPLER sampler MAX_LOD 4.0
2399 
2400 PIPELINE graphics pipeline
2401   ATTACH vert_shader
2402   ATTACH frag_shader
2403   BIND BUFFER texture AS combined_image_sampler SAMPLER sampler DESCRIPTOR_SET 0 BINDING 0 BASE_MIP_LEVEL 2
2404   BIND BUFFER framebuffer AS color LOCATION 0
2405 END)";
2406 
2407   Parser parser;
2408   Result r = parser.Parse(in);
2409   ASSERT_TRUE(r.IsSuccess()) << r.Error();
2410 
2411   auto script = parser.GetScript();
2412   const auto& pipelines = script->GetPipelines();
2413   ASSERT_EQ(1U, pipelines.size());
2414 
2415   const auto* pipeline = pipelines[0].get();
2416   const auto& bufs = pipeline->GetBuffers();
2417   ASSERT_EQ(1U, bufs.size());
2418   EXPECT_EQ(2U, bufs[0].base_mip_level);
2419 }
2420 
TEST_F(AmberScriptParserTest,BindBufferCombinedImageSamplerMissingBaseMipLevel)2421 TEST_F(AmberScriptParserTest,
2422        BindBufferCombinedImageSamplerMissingBaseMipLevel) {
2423   std::string in = R"(
2424 SHADER vertex vert_shader PASSTHROUGH
2425 SHADER fragment frag_shader GLSL
2426 # GLSL Shader
2427 END
2428 
2429 BUFFER texture FORMAT R8G8B8A8_UNORM MIP_LEVELS 4
2430 BUFFER framebuffer FORMAT R8G8B8A8_UNORM
2431 SAMPLER sampler MAX_LOD 4.0
2432 
2433 PIPELINE graphics pipeline
2434   ATTACH vert_shader
2435   ATTACH frag_shader
2436   BIND BUFFER texture AS combined_image_sampler SAMPLER sampler DESCRIPTOR_SET 0 BINDING 0 BASE_MIP_LEVEL
2437   BIND BUFFER framebuffer AS color LOCATION 0
2438 END)";
2439 
2440   Parser parser;
2441   Result r = parser.Parse(in);
2442 
2443   ASSERT_FALSE(r.IsSuccess());
2444   EXPECT_EQ("15: invalid value for BASE_MIP_LEVEL", r.Error());
2445 }
2446 
TEST_F(AmberScriptParserTest,BindBufferCombinedImageSamplerBaseMipLevelTooLarge)2447 TEST_F(AmberScriptParserTest,
2448        BindBufferCombinedImageSamplerBaseMipLevelTooLarge) {
2449   std::string in = R"(
2450 SHADER vertex vert_shader PASSTHROUGH
2451 SHADER fragment frag_shader GLSL
2452 # GLSL Shader
2453 END
2454 
2455 BUFFER texture FORMAT R8G8B8A8_UNORM MIP_LEVELS 2
2456 BUFFER framebuffer FORMAT R8G8B8A8_UNORM
2457 SAMPLER sampler MAX_LOD 2.0
2458 
2459 PIPELINE graphics pipeline
2460   ATTACH vert_shader
2461   ATTACH frag_shader
2462   BIND BUFFER texture AS combined_image_sampler SAMPLER sampler DESCRIPTOR_SET 0 BINDING 0 BASE_MIP_LEVEL 3
2463   BIND BUFFER framebuffer AS color LOCATION 0
2464 END)";
2465 
2466   Parser parser;
2467   Result r = parser.Parse(in);
2468 
2469   ASSERT_FALSE(r.IsSuccess());
2470   EXPECT_EQ(
2471       "14: base mip level (now 3) needs to be larger than the number of buffer "
2472       "mip maps (2)",
2473       r.Error());
2474 }
2475 
TEST_F(AmberScriptParserTest,BindBufferUniformTexelBufferCompute)2476 TEST_F(AmberScriptParserTest, BindBufferUniformTexelBufferCompute) {
2477   std::string in = R"(
2478 SHADER compute compute_shader GLSL
2479 # GLSL Shader
2480 END
2481 
2482 BUFFER texture FORMAT R8G8B8A8_UNORM
2483 
2484 PIPELINE compute pipeline
2485   ATTACH compute_shader
2486   BIND BUFFER texture AS uniform_texel_buffer DESCRIPTOR_SET 0 BINDING 0
2487 END)";
2488 
2489   Parser parser;
2490   Result r = parser.Parse(in);
2491   ASSERT_TRUE(r.IsSuccess()) << r.Error();
2492 
2493   auto script = parser.GetScript();
2494   const auto& pipelines = script->GetPipelines();
2495   ASSERT_EQ(1U, pipelines.size());
2496 
2497   const auto* pipeline = pipelines[0].get();
2498   const auto& bufs = pipeline->GetBuffers();
2499   ASSERT_EQ(1U, bufs.size());
2500   EXPECT_EQ(BufferType::kUniformTexelBuffer, bufs[0].type);
2501 }
2502 
TEST_F(AmberScriptParserTest,BindBufferUniformTexelBufferGraphics)2503 TEST_F(AmberScriptParserTest, BindBufferUniformTexelBufferGraphics) {
2504   std::string in = R"(
2505 SHADER vertex vert_shader PASSTHROUGH
2506 SHADER fragment frag_shader GLSL
2507 # GLSL Shader
2508 END
2509 
2510 BUFFER texture FORMAT R8G8B8A8_UNORM
2511 BUFFER framebuffer FORMAT R8G8B8A8_UNORM
2512 
2513 PIPELINE graphics pipeline
2514   ATTACH vert_shader
2515   ATTACH frag_shader
2516   BIND BUFFER texture AS uniform_texel_buffer DESCRIPTOR_SET 0 BINDING 0
2517   BIND BUFFER framebuffer AS color LOCATION 0
2518 END)";
2519 
2520   Parser parser;
2521   Result r = parser.Parse(in);
2522   ASSERT_TRUE(r.IsSuccess()) << r.Error();
2523 
2524   auto script = parser.GetScript();
2525   const auto& pipelines = script->GetPipelines();
2526   ASSERT_EQ(1U, pipelines.size());
2527 
2528   const auto* pipeline = pipelines[0].get();
2529   const auto& bufs = pipeline->GetBuffers();
2530   ASSERT_EQ(1U, bufs.size());
2531   EXPECT_EQ(BufferType::kUniformTexelBuffer, bufs[0].type);
2532 }
2533 
TEST_F(AmberScriptParserTest,BindBufferUniformTexelBufferMissingDescriptorSetValue)2534 TEST_F(AmberScriptParserTest,
2535        BindBufferUniformTexelBufferMissingDescriptorSetValue) {
2536   std::string in = R"(
2537 SHADER compute compute_shader GLSL
2538 # GLSL Shader
2539 END
2540 
2541 BUFFER texture FORMAT R8G8B8A8_UNORM
2542 
2543 PIPELINE compute pipeline
2544   ATTACH compute_shader
2545   BIND BUFFER texture AS uniform_texel_buffer DESCRIPTOR_SET BINDING 0
2546 END)";
2547 
2548   Parser parser;
2549   Result r = parser.Parse(in);
2550   ASSERT_FALSE(r.IsSuccess());
2551   EXPECT_EQ("10: invalid value for DESCRIPTOR_SET in BIND command", r.Error());
2552 }
2553 
TEST_F(AmberScriptParserTest,BindBufferUniformTexelBufferMissingDescriptorSet)2554 TEST_F(AmberScriptParserTest,
2555        BindBufferUniformTexelBufferMissingDescriptorSet) {
2556   std::string in = R"(
2557 SHADER compute compute_shader GLSL
2558 # GLSL Shader
2559 END
2560 
2561 BUFFER texture FORMAT R8G8B8A8_UNORM
2562 
2563 PIPELINE compute pipeline
2564   ATTACH compute_shader
2565   BIND BUFFER texture AS uniform_texel_buffer BINDING 0
2566 END)";
2567 
2568   Parser parser;
2569   Result r = parser.Parse(in);
2570   ASSERT_FALSE(r.IsSuccess());
2571   EXPECT_EQ("10: missing DESCRIPTOR_SET or KERNEL for BIND command", r.Error());
2572 }
2573 
TEST_F(AmberScriptParserTest,BindBufferUniformTexelBufferMissingBindingValue)2574 TEST_F(AmberScriptParserTest, BindBufferUniformTexelBufferMissingBindingValue) {
2575   std::string in = R"(
2576 SHADER compute compute_shader GLSL
2577 # GLSL Shader
2578 END
2579 
2580 BUFFER texture FORMAT R8G8B8A8_UNORM
2581 
2582 PIPELINE compute pipeline
2583   ATTACH compute_shader
2584   BIND BUFFER texture AS uniform_texel_buffer DESCRIPTOR_SET 0 BINDING
2585 END)";
2586 
2587   Parser parser;
2588   Result r = parser.Parse(in);
2589   ASSERT_FALSE(r.IsSuccess());
2590   EXPECT_EQ("11: invalid value for BINDING in BIND command", r.Error());
2591 }
2592 
TEST_F(AmberScriptParserTest,BindBufferUniformTexelBufferMissingBinding)2593 TEST_F(AmberScriptParserTest, BindBufferUniformTexelBufferMissingBinding) {
2594   std::string in = R"(
2595 SHADER compute compute_shader GLSL
2596 # GLSL Shader
2597 END
2598 
2599 BUFFER texture FORMAT R8G8B8A8_UNORM
2600 
2601 PIPELINE compute pipeline
2602   ATTACH compute_shader
2603   BIND BUFFER texture AS uniform_texel_buffer DESCRIPTOR_SET 0
2604 END)";
2605 
2606   Parser parser;
2607   Result r = parser.Parse(in);
2608   ASSERT_FALSE(r.IsSuccess());
2609   EXPECT_EQ("11: missing BINDING for BIND command", r.Error());
2610 }
2611 
TEST_F(AmberScriptParserTest,BindBufferStorageTexelBufferCompute)2612 TEST_F(AmberScriptParserTest, BindBufferStorageTexelBufferCompute) {
2613   std::string in = R"(
2614 SHADER compute compute_shader GLSL
2615 # GLSL Shader
2616 END
2617 
2618 BUFFER texture FORMAT R8G8B8A8_UNORM
2619 
2620 PIPELINE compute pipeline
2621   ATTACH compute_shader
2622   BIND BUFFER texture AS storage_texel_buffer DESCRIPTOR_SET 0 BINDING 0
2623 END)";
2624 
2625   Parser parser;
2626   Result r = parser.Parse(in);
2627   ASSERT_TRUE(r.IsSuccess()) << r.Error();
2628 
2629   auto script = parser.GetScript();
2630   const auto& pipelines = script->GetPipelines();
2631   ASSERT_EQ(1U, pipelines.size());
2632 
2633   const auto* pipeline = pipelines[0].get();
2634   const auto& bufs = pipeline->GetBuffers();
2635   ASSERT_EQ(1U, bufs.size());
2636   EXPECT_EQ(BufferType::kStorageTexelBuffer, bufs[0].type);
2637 }
2638 
TEST_F(AmberScriptParserTest,BindBufferStorageTexelBufferGraphics)2639 TEST_F(AmberScriptParserTest, BindBufferStorageTexelBufferGraphics) {
2640   std::string in = R"(
2641 SHADER vertex vert_shader PASSTHROUGH
2642 SHADER fragment frag_shader GLSL
2643 # GLSL Shader
2644 END
2645 
2646 BUFFER texture FORMAT R8G8B8A8_UNORM
2647 BUFFER framebuffer FORMAT R8G8B8A8_UNORM
2648 
2649 PIPELINE graphics pipeline
2650   ATTACH vert_shader
2651   ATTACH frag_shader
2652   BIND BUFFER texture AS storage_texel_buffer DESCRIPTOR_SET 0 BINDING 0
2653   BIND BUFFER framebuffer AS color LOCATION 0
2654 END)";
2655 
2656   Parser parser;
2657   Result r = parser.Parse(in);
2658   ASSERT_TRUE(r.IsSuccess()) << r.Error();
2659 
2660   auto script = parser.GetScript();
2661   const auto& pipelines = script->GetPipelines();
2662   ASSERT_EQ(1U, pipelines.size());
2663 
2664   const auto* pipeline = pipelines[0].get();
2665   const auto& bufs = pipeline->GetBuffers();
2666   ASSERT_EQ(1U, bufs.size());
2667   EXPECT_EQ(BufferType::kStorageTexelBuffer, bufs[0].type);
2668 }
2669 
TEST_F(AmberScriptParserTest,BindBufferStorageTexelBufferMissingDescriptorSetValue)2670 TEST_F(AmberScriptParserTest,
2671        BindBufferStorageTexelBufferMissingDescriptorSetValue) {
2672   std::string in = R"(
2673 SHADER compute compute_shader GLSL
2674 # GLSL Shader
2675 END
2676 
2677 BUFFER texture FORMAT R8G8B8A8_UNORM
2678 
2679 PIPELINE compute pipeline
2680   ATTACH compute_shader
2681   BIND BUFFER texture AS storage_texel_buffer DESCRIPTOR_SET BINDING 0
2682 END)";
2683 
2684   Parser parser;
2685   Result r = parser.Parse(in);
2686   ASSERT_FALSE(r.IsSuccess());
2687   EXPECT_EQ("10: invalid value for DESCRIPTOR_SET in BIND command", r.Error());
2688 }
2689 
TEST_F(AmberScriptParserTest,BindBufferStorageTexelBufferMissingDescriptorSet)2690 TEST_F(AmberScriptParserTest,
2691        BindBufferStorageTexelBufferMissingDescriptorSet) {
2692   std::string in = R"(
2693 SHADER compute compute_shader GLSL
2694 # GLSL Shader
2695 END
2696 
2697 BUFFER texture FORMAT R8G8B8A8_UNORM
2698 
2699 PIPELINE compute pipeline
2700   ATTACH compute_shader
2701   BIND BUFFER texture AS storage_texel_buffer BINDING 0
2702 END)";
2703 
2704   Parser parser;
2705   Result r = parser.Parse(in);
2706   ASSERT_FALSE(r.IsSuccess());
2707   EXPECT_EQ("10: missing DESCRIPTOR_SET or KERNEL for BIND command", r.Error());
2708 }
2709 
TEST_F(AmberScriptParserTest,BindBufferStorageTexelBufferMissingBindingValue)2710 TEST_F(AmberScriptParserTest, BindBufferStorageTexelBufferMissingBindingValue) {
2711   std::string in = R"(
2712 SHADER compute compute_shader GLSL
2713 # GLSL Shader
2714 END
2715 
2716 BUFFER texture FORMAT R8G8B8A8_UNORM
2717 
2718 PIPELINE compute pipeline
2719   ATTACH compute_shader
2720   BIND BUFFER texture AS storage_texel_buffer DESCRIPTOR_SET 0 BINDING
2721 END)";
2722 
2723   Parser parser;
2724   Result r = parser.Parse(in);
2725   ASSERT_FALSE(r.IsSuccess());
2726   EXPECT_EQ("11: invalid value for BINDING in BIND command", r.Error());
2727 }
2728 
TEST_F(AmberScriptParserTest,BindBufferStorageTexelBufferMissingBinding)2729 TEST_F(AmberScriptParserTest, BindBufferStorageTexelBufferMissingBinding) {
2730   std::string in = R"(
2731 SHADER compute compute_shader GLSL
2732 # GLSL Shader
2733 END
2734 
2735 BUFFER texture FORMAT R8G8B8A8_UNORM
2736 
2737 PIPELINE compute pipeline
2738   ATTACH compute_shader
2739   BIND BUFFER texture AS storage_texel_buffer DESCRIPTOR_SET 0
2740 END)";
2741 
2742   Parser parser;
2743   Result r = parser.Parse(in);
2744   ASSERT_FALSE(r.IsSuccess());
2745   EXPECT_EQ("11: missing BINDING for BIND command", r.Error());
2746 }
2747 
TEST_F(AmberScriptParserTest,BindSampler)2748 TEST_F(AmberScriptParserTest, BindSampler) {
2749   std::string in = R"(
2750 SHADER vertex vert_shader PASSTHROUGH
2751 SHADER fragment frag_shader GLSL
2752 # GLSL Shader
2753 END
2754 
2755 SAMPLER sampler
2756 BUFFER framebuffer FORMAT R8G8B8A8_UNORM
2757 
2758 PIPELINE graphics pipeline
2759   ATTACH vert_shader
2760   ATTACH frag_shader
2761   BIND SAMPLER sampler DESCRIPTOR_SET 0 BINDING 0
2762   BIND BUFFER framebuffer AS color LOCATION 0
2763 END)";
2764 
2765   Parser parser;
2766   Result r = parser.Parse(in);
2767   ASSERT_TRUE(r.IsSuccess()) << r.Error();
2768 
2769   auto script = parser.GetScript();
2770   const auto& pipelines = script->GetPipelines();
2771   ASSERT_EQ(1U, pipelines.size());
2772 
2773   const auto* pipeline = pipelines[0].get();
2774   const auto& samplers = pipeline->GetSamplers();
2775   ASSERT_EQ(1U, samplers.size());
2776 }
2777 
TEST_F(AmberScriptParserTest,BindSamplerMissingDescriptorSetValue)2778 TEST_F(AmberScriptParserTest, BindSamplerMissingDescriptorSetValue) {
2779   std::string in = R"(
2780 SHADER vertex vert_shader PASSTHROUGH
2781 SHADER fragment frag_shader GLSL
2782 # GLSL Shader
2783 END
2784 
2785 SAMPLER sampler
2786 
2787 PIPELINE graphics pipeline
2788   ATTACH vert_shader
2789   ATTACH frag_shader
2790   BIND SAMPLER sampler DESCRIPTOR_SET BINDING 0
2791 END)";
2792 
2793   Parser parser;
2794   Result r = parser.Parse(in);
2795   ASSERT_FALSE(r.IsSuccess());
2796   EXPECT_EQ("12: invalid value for DESCRIPTOR_SET in BIND command", r.Error());
2797 }
2798 
TEST_F(AmberScriptParserTest,BindSamplerMissingDescriptorSet)2799 TEST_F(AmberScriptParserTest, BindSamplerMissingDescriptorSet) {
2800   std::string in = R"(
2801 SHADER vertex vert_shader PASSTHROUGH
2802 SHADER fragment frag_shader GLSL
2803 # GLSL Shader
2804 END
2805 
2806 SAMPLER sampler
2807 
2808 PIPELINE graphics pipeline
2809   ATTACH vert_shader
2810   ATTACH frag_shader
2811   BIND SAMPLER sampler BINDING 0
2812 END)";
2813 
2814   Parser parser;
2815   Result r = parser.Parse(in);
2816   ASSERT_FALSE(r.IsSuccess());
2817   EXPECT_EQ("12: missing DESCRIPTOR_SET or KERNEL for BIND command", r.Error());
2818 }
2819 
TEST_F(AmberScriptParserTest,BindSamplerMissingBindingValue)2820 TEST_F(AmberScriptParserTest, BindSamplerMissingBindingValue) {
2821   std::string in = R"(
2822 SHADER vertex vert_shader PASSTHROUGH
2823 SHADER fragment frag_shader GLSL
2824 # GLSL Shader
2825 END
2826 
2827 SAMPLER sampler
2828 
2829 PIPELINE graphics pipeline
2830   ATTACH vert_shader
2831   ATTACH frag_shader
2832   BIND SAMPLER sampler DESCRIPTOR_SET 0 BINDING
2833 END)";
2834 
2835   Parser parser;
2836   Result r = parser.Parse(in);
2837   ASSERT_FALSE(r.IsSuccess());
2838   EXPECT_EQ("13: invalid value for BINDING in BIND command", r.Error());
2839 }
2840 
TEST_F(AmberScriptParserTest,BindSamplerMissingBinding)2841 TEST_F(AmberScriptParserTest, BindSamplerMissingBinding) {
2842   std::string in = R"(
2843 SHADER vertex vert_shader PASSTHROUGH
2844 SHADER fragment frag_shader GLSL
2845 # GLSL Shader
2846 END
2847 
2848 SAMPLER sampler
2849 
2850 PIPELINE graphics pipeline
2851   ATTACH vert_shader
2852   ATTACH frag_shader
2853   BIND SAMPLER sampler DESCRIPTOR_SET 0
2854 END)";
2855 
2856   Parser parser;
2857   Result r = parser.Parse(in);
2858   ASSERT_FALSE(r.IsSuccess());
2859   EXPECT_EQ("13: missing BINDING for BIND command", r.Error());
2860 }
2861 
TEST_F(AmberScriptParserTest,BindBufferArray)2862 TEST_F(AmberScriptParserTest, BindBufferArray) {
2863   std::string in = R"(
2864 SHADER vertex my_shader PASSTHROUGH
2865 SHADER fragment my_fragment GLSL
2866 # GLSL Shader
2867 END
2868 BUFFER my_buf1 FORMAT R32G32B32A32_SFLOAT
2869 BUFFER my_buf2 FORMAT R32G32B32A32_SFLOAT
2870 
2871 PIPELINE graphics my_pipeline
2872   ATTACH my_shader
2873   ATTACH my_fragment
2874 
2875   BIND BUFFER_ARRAY my_buf1 my_buf2 AS uniform DESCRIPTOR_SET 1 BINDING 2
2876 END
2877 )";
2878 
2879   Parser parser;
2880   Result r = parser.Parse(in);
2881   ASSERT_TRUE(r.IsSuccess()) << r.Error();
2882 
2883   auto script = parser.GetScript();
2884   const auto& pipelines = script->GetPipelines();
2885   ASSERT_EQ(1U, pipelines.size());
2886 
2887   const auto* pipeline = pipelines[0].get();
2888   const auto& bufs = pipeline->GetBuffers();
2889   ASSERT_EQ(2U, bufs.size());
2890   for (size_t i = 0; i < 2; i++) {
2891     EXPECT_EQ(BufferType::kUniform, bufs[i].type);
2892     EXPECT_EQ(1U, bufs[i].descriptor_set);
2893     EXPECT_EQ(2U, bufs[i].binding);
2894     EXPECT_EQ(static_cast<uint32_t>(0), bufs[i].location);
2895     EXPECT_EQ(FormatType::kR32G32B32A32_SFLOAT,
2896               bufs[i].buffer->GetFormat()->GetFormatType());
2897   }
2898 }
2899 
TEST_F(AmberScriptParserTest,BindBufferArrayOnlyOneBuffer)2900 TEST_F(AmberScriptParserTest, BindBufferArrayOnlyOneBuffer) {
2901   std::string in = R"(
2902 SHADER vertex my_shader PASSTHROUGH
2903 SHADER fragment my_fragment GLSL
2904 # GLSL Shader
2905 END
2906 BUFFER my_buf FORMAT R32G32B32A32_SFLOAT
2907 
2908 PIPELINE graphics my_pipeline
2909   ATTACH my_shader
2910   ATTACH my_fragment
2911 
2912   BIND BUFFER_ARRAY my_buf AS uniform DESCRIPTOR_SET 1 BINDING 2
2913 END
2914 )";
2915 
2916   Parser parser;
2917   Result r = parser.Parse(in);
2918 
2919   ASSERT_FALSE(r.IsSuccess());
2920   EXPECT_EQ("12: expecting multiple buffer names for BUFFER_ARRAY", r.Error());
2921 }
2922 
TEST_F(AmberScriptParserTest,BindSamplerArray)2923 TEST_F(AmberScriptParserTest, BindSamplerArray) {
2924   std::string in = R"(
2925 SHADER vertex vert_shader PASSTHROUGH
2926 SHADER fragment frag_shader GLSL
2927 # GLSL Shader
2928 END
2929 
2930 SAMPLER sampler1
2931 SAMPLER sampler2
2932 BUFFER framebuffer FORMAT R8G8B8A8_UNORM
2933 
2934 PIPELINE graphics pipeline
2935   ATTACH vert_shader
2936   ATTACH frag_shader
2937   BIND SAMPLER_ARRAY sampler1 sampler2 DESCRIPTOR_SET 0 BINDING 0
2938   BIND BUFFER framebuffer AS color LOCATION 0
2939 END)";
2940 
2941   Parser parser;
2942   Result r = parser.Parse(in);
2943   ASSERT_TRUE(r.IsSuccess()) << r.Error();
2944 
2945   auto script = parser.GetScript();
2946   const auto& pipelines = script->GetPipelines();
2947   ASSERT_EQ(1U, pipelines.size());
2948 
2949   const auto* pipeline = pipelines[0].get();
2950   const auto& samplers = pipeline->GetSamplers();
2951   ASSERT_EQ(2U, samplers.size());
2952 }
2953 
TEST_F(AmberScriptParserTest,BindSamplerArrayOnlyOneSampler)2954 TEST_F(AmberScriptParserTest, BindSamplerArrayOnlyOneSampler) {
2955   std::string in = R"(
2956 SHADER vertex my_shader PASSTHROUGH
2957 SHADER fragment my_fragment GLSL
2958 # GLSL Shader
2959 END
2960 SAMPLER sampler
2961 
2962 PIPELINE graphics my_pipeline
2963   ATTACH my_shader
2964   ATTACH my_fragment
2965 
2966   BIND SAMPLER_ARRAY sampler DESCRIPTOR_SET 1 BINDING 2
2967 END
2968 )";
2969 
2970   Parser parser;
2971   Result r = parser.Parse(in);
2972 
2973   ASSERT_FALSE(r.IsSuccess());
2974   EXPECT_EQ("12: expecting multiple sampler names for SAMPLER_ARRAY",
2975             r.Error());
2976 }
2977 
TEST_F(AmberScriptParserTest,BindUniformBufferDynamic)2978 TEST_F(AmberScriptParserTest, BindUniformBufferDynamic) {
2979   std::string in = R"(
2980 SHADER vertex my_shader PASSTHROUGH
2981 SHADER fragment my_fragment GLSL
2982 # GLSL Shader
2983 END
2984 BUFFER my_buf FORMAT R32G32B32A32_SFLOAT
2985 
2986 PIPELINE graphics my_pipeline
2987   ATTACH my_shader
2988   ATTACH my_fragment
2989 
2990   BIND BUFFER my_buf AS uniform_dynamic DESCRIPTOR_SET 1 BINDING 2 OFFSET 8
2991 END
2992 )";
2993 
2994   Parser parser;
2995   Result r = parser.Parse(in);
2996   ASSERT_TRUE(r.IsSuccess()) << r.Error();
2997 
2998   auto script = parser.GetScript();
2999   const auto& pipelines = script->GetPipelines();
3000   ASSERT_EQ(1U, pipelines.size());
3001 
3002   const auto* pipeline = pipelines[0].get();
3003   const auto& bufs = pipeline->GetBuffers();
3004   ASSERT_EQ(1U, bufs.size());
3005   EXPECT_EQ(BufferType::kUniformDynamic, bufs[0].type);
3006   EXPECT_EQ(1U, bufs[0].descriptor_set);
3007   EXPECT_EQ(2U, bufs[0].binding);
3008   EXPECT_EQ(8u, bufs[0].dynamic_offset);
3009   EXPECT_EQ(static_cast<uint32_t>(0), bufs[0].location);
3010   EXPECT_EQ(FormatType::kR32G32B32A32_SFLOAT,
3011             bufs[0].buffer->GetFormat()->GetFormatType());
3012 }
3013 
TEST_F(AmberScriptParserTest,BindUniformBufferArrayDynamic)3014 TEST_F(AmberScriptParserTest, BindUniformBufferArrayDynamic) {
3015   std::string in = R"(
3016 SHADER vertex my_shader PASSTHROUGH
3017 SHADER fragment my_fragment GLSL
3018 # GLSL Shader
3019 END
3020 BUFFER buf0 FORMAT R32G32B32A32_SFLOAT
3021 BUFFER buf1 FORMAT R32G32B32A32_SFLOAT
3022 
3023 PIPELINE graphics my_pipeline
3024   ATTACH my_shader
3025   ATTACH my_fragment
3026 
3027   BIND BUFFER_ARRAY buf0 buf1 AS uniform_dynamic DESCRIPTOR_SET 1 BINDING 2 OFFSET 8 16
3028 END
3029 )";
3030 
3031   Parser parser;
3032   Result r = parser.Parse(in);
3033   ASSERT_TRUE(r.IsSuccess()) << r.Error();
3034 
3035   auto script = parser.GetScript();
3036   const auto& pipelines = script->GetPipelines();
3037   ASSERT_EQ(1U, pipelines.size());
3038 
3039   const auto* pipeline = pipelines[0].get();
3040   const auto& bufs = pipeline->GetBuffers();
3041   ASSERT_EQ(2U, bufs.size());
3042   EXPECT_EQ(BufferType::kUniformDynamic, bufs[0].type);
3043   EXPECT_EQ(1U, bufs[0].descriptor_set);
3044   EXPECT_EQ(2U, bufs[0].binding);
3045   EXPECT_EQ(8u, bufs[0].dynamic_offset);
3046   EXPECT_EQ(static_cast<uint32_t>(0), bufs[0].location);
3047   EXPECT_EQ(FormatType::kR32G32B32A32_SFLOAT,
3048             bufs[0].buffer->GetFormat()->GetFormatType());
3049   EXPECT_EQ(1U, bufs[1].descriptor_set);
3050   EXPECT_EQ(2U, bufs[1].binding);
3051   EXPECT_EQ(16u, bufs[1].dynamic_offset);
3052   EXPECT_EQ(static_cast<uint32_t>(0), bufs[1].location);
3053   EXPECT_EQ(FormatType::kR32G32B32A32_SFLOAT,
3054             bufs[1].buffer->GetFormat()->GetFormatType());
3055 }
3056 
TEST_F(AmberScriptParserTest,BindUniformBufferDynamicMissingOffset)3057 TEST_F(AmberScriptParserTest, BindUniformBufferDynamicMissingOffset) {
3058   std::string in = R"(
3059 BUFFER my_buf FORMAT R32G32B32A32_SFLOAT
3060 PIPELINE graphics my_pipeline
3061   BIND BUFFER my_buf AS uniform_dynamic DESCRIPTOR_SET 1 BINDING 2
3062 END
3063 )";
3064 
3065   Parser parser;
3066   Result r = parser.Parse(in);
3067   ASSERT_FALSE(r.IsSuccess());
3068   EXPECT_EQ("5: expecting an OFFSET for dynamic buffer type", r.Error());
3069 }
3070 
TEST_F(AmberScriptParserTest,BindUniformBufferDynamicEmptyOffset)3071 TEST_F(AmberScriptParserTest, BindUniformBufferDynamicEmptyOffset) {
3072   std::string in = R"(
3073 BUFFER my_buf FORMAT R32G32B32A32_SFLOAT
3074 PIPELINE graphics my_pipeline
3075   BIND BUFFER my_buf AS uniform_dynamic DESCRIPTOR_SET 1 BINDING 2 OFFSET
3076 END
3077 )";
3078 
3079   Parser parser;
3080   Result r = parser.Parse(in);
3081   ASSERT_FALSE(r.IsSuccess());
3082   EXPECT_EQ("5: expecting an integer value for OFFSET", r.Error());
3083 }
3084 
TEST_F(AmberScriptParserTest,BindUniformBufferDynamicInvalidOffset)3085 TEST_F(AmberScriptParserTest, BindUniformBufferDynamicInvalidOffset) {
3086   std::string in = R"(
3087 BUFFER my_buf FORMAT R32G32B32A32_SFLOAT
3088 PIPELINE graphics my_pipeline
3089   BIND BUFFER my_buf AS uniform_dynamic DESCRIPTOR_SET 1 BINDING 2 OFFSET foo
3090 END
3091 )";
3092 
3093   Parser parser;
3094   Result r = parser.Parse(in);
3095   ASSERT_FALSE(r.IsSuccess());
3096   EXPECT_EQ("4: expecting an integer value for OFFSET", r.Error());
3097 }
3098 
TEST_F(AmberScriptParserTest,BindUniformBufferArrayDynamicNotEnoughOffsets)3099 TEST_F(AmberScriptParserTest, BindUniformBufferArrayDynamicNotEnoughOffsets) {
3100   std::string in = R"(
3101 BUFFER buf0 FORMAT R32G32B32A32_SFLOAT
3102 BUFFER buf1 FORMAT R32G32B32A32_SFLOAT
3103 
3104 PIPELINE graphics my_pipeline
3105   BIND BUFFER_ARRAY buf0 buf1 AS uniform_dynamic DESCRIPTOR_SET 1 BINDING 2 OFFSET 8
3106 END
3107 )";
3108 
3109   Parser parser;
3110   Result r = parser.Parse(in);
3111   ASSERT_FALSE(r.IsSuccess());
3112   EXPECT_EQ("7: expecting an OFFSET value for each buffer in the array",
3113             r.Error());
3114 }
3115 
TEST_F(AmberScriptParserTest,BindStorageBufferDynamic)3116 TEST_F(AmberScriptParserTest, BindStorageBufferDynamic) {
3117   std::string in = R"(
3118 SHADER vertex my_shader PASSTHROUGH
3119 SHADER fragment my_fragment GLSL
3120 # GLSL Shader
3121 END
3122 BUFFER my_buf FORMAT R32G32B32A32_SFLOAT
3123 
3124 PIPELINE graphics my_pipeline
3125   ATTACH my_shader
3126   ATTACH my_fragment
3127 
3128   BIND BUFFER my_buf AS storage_dynamic DESCRIPTOR_SET 1 BINDING 2 OFFSET 8
3129 END
3130 )";
3131 
3132   Parser parser;
3133   Result r = parser.Parse(in);
3134   ASSERT_TRUE(r.IsSuccess()) << r.Error();
3135 
3136   auto script = parser.GetScript();
3137   const auto& pipelines = script->GetPipelines();
3138   ASSERT_EQ(1U, pipelines.size());
3139 
3140   const auto* pipeline = pipelines[0].get();
3141   const auto& bufs = pipeline->GetBuffers();
3142   ASSERT_EQ(1U, bufs.size());
3143   EXPECT_EQ(BufferType::kStorageDynamic, bufs[0].type);
3144   EXPECT_EQ(1U, bufs[0].descriptor_set);
3145   EXPECT_EQ(2U, bufs[0].binding);
3146   EXPECT_EQ(8u, bufs[0].dynamic_offset);
3147   EXPECT_EQ(static_cast<uint32_t>(0), bufs[0].location);
3148   EXPECT_EQ(FormatType::kR32G32B32A32_SFLOAT,
3149             bufs[0].buffer->GetFormat()->GetFormatType());
3150 }
3151 
TEST_F(AmberScriptParserTest,BindStorageBufferArrayDynamic)3152 TEST_F(AmberScriptParserTest, BindStorageBufferArrayDynamic) {
3153   std::string in = R"(
3154 SHADER vertex my_shader PASSTHROUGH
3155 SHADER fragment my_fragment GLSL
3156 # GLSL Shader
3157 END
3158 BUFFER buf0 FORMAT R32G32B32A32_SFLOAT
3159 BUFFER buf1 FORMAT R32G32B32A32_SFLOAT
3160 
3161 PIPELINE graphics my_pipeline
3162   ATTACH my_shader
3163   ATTACH my_fragment
3164 
3165   BIND BUFFER_ARRAY buf0 buf1 AS storage_dynamic DESCRIPTOR_SET 1 BINDING 2 OFFSET 8 16
3166 END
3167 )";
3168 
3169   Parser parser;
3170   Result r = parser.Parse(in);
3171   ASSERT_TRUE(r.IsSuccess()) << r.Error();
3172 
3173   auto script = parser.GetScript();
3174   const auto& pipelines = script->GetPipelines();
3175   ASSERT_EQ(1U, pipelines.size());
3176 
3177   const auto* pipeline = pipelines[0].get();
3178   const auto& bufs = pipeline->GetBuffers();
3179   ASSERT_EQ(2U, bufs.size());
3180   EXPECT_EQ(BufferType::kStorageDynamic, bufs[0].type);
3181   EXPECT_EQ(1U, bufs[0].descriptor_set);
3182   EXPECT_EQ(2U, bufs[0].binding);
3183   EXPECT_EQ(8u, bufs[0].dynamic_offset);
3184   EXPECT_EQ(static_cast<uint32_t>(0), bufs[0].location);
3185   EXPECT_EQ(FormatType::kR32G32B32A32_SFLOAT,
3186             bufs[0].buffer->GetFormat()->GetFormatType());
3187   EXPECT_EQ(1U, bufs[1].descriptor_set);
3188   EXPECT_EQ(2U, bufs[1].binding);
3189   EXPECT_EQ(16u, bufs[1].dynamic_offset);
3190   EXPECT_EQ(static_cast<uint32_t>(0), bufs[1].location);
3191   EXPECT_EQ(FormatType::kR32G32B32A32_SFLOAT,
3192             bufs[1].buffer->GetFormat()->GetFormatType());
3193 }
3194 
TEST_F(AmberScriptParserTest,BindStorageBufferDynamicMissingOffset)3195 TEST_F(AmberScriptParserTest, BindStorageBufferDynamicMissingOffset) {
3196   std::string in = R"(
3197 BUFFER my_buf FORMAT R32G32B32A32_SFLOAT
3198 PIPELINE graphics my_pipeline
3199   BIND BUFFER my_buf AS storage_dynamic DESCRIPTOR_SET 1 BINDING 2
3200 END
3201 )";
3202 
3203   Parser parser;
3204   Result r = parser.Parse(in);
3205   ASSERT_FALSE(r.IsSuccess());
3206   EXPECT_EQ("5: expecting an OFFSET for dynamic buffer type", r.Error());
3207 }
3208 
TEST_F(AmberScriptParserTest,BindStorageBufferDynamicEmptyOffset)3209 TEST_F(AmberScriptParserTest, BindStorageBufferDynamicEmptyOffset) {
3210   std::string in = R"(
3211 BUFFER my_buf FORMAT R32G32B32A32_SFLOAT
3212 PIPELINE graphics my_pipeline
3213   BIND BUFFER my_buf AS storage_dynamic DESCRIPTOR_SET 1 BINDING 2 OFFSET
3214 END
3215 )";
3216 
3217   Parser parser;
3218   Result r = parser.Parse(in);
3219   ASSERT_FALSE(r.IsSuccess());
3220   EXPECT_EQ("5: expecting an integer value for OFFSET", r.Error());
3221 }
3222 
TEST_F(AmberScriptParserTest,BindStorageBufferDynamicInvalidOffset)3223 TEST_F(AmberScriptParserTest, BindStorageBufferDynamicInvalidOffset) {
3224   std::string in = R"(
3225 BUFFER my_buf FORMAT R32G32B32A32_SFLOAT
3226 PIPELINE graphics my_pipeline
3227   BIND BUFFER my_buf AS storage_dynamic DESCRIPTOR_SET 1 BINDING 2 OFFSET foo
3228 END
3229 )";
3230 
3231   Parser parser;
3232   Result r = parser.Parse(in);
3233   ASSERT_FALSE(r.IsSuccess());
3234   EXPECT_EQ("4: expecting an integer value for OFFSET", r.Error());
3235 }
3236 
TEST_F(AmberScriptParserTest,BindStorageBufferArrayDynamicNotEnoughOffsets)3237 TEST_F(AmberScriptParserTest, BindStorageBufferArrayDynamicNotEnoughOffsets) {
3238   std::string in = R"(
3239 BUFFER buf0 FORMAT R32G32B32A32_SFLOAT
3240 BUFFER buf1 FORMAT R32G32B32A32_SFLOAT
3241 
3242 PIPELINE graphics my_pipeline
3243   BIND BUFFER_ARRAY buf0 buf1 AS storage_dynamic DESCRIPTOR_SET 1 BINDING 2 OFFSET 8
3244 END
3245 )";
3246 
3247   Parser parser;
3248   Result r = parser.Parse(in);
3249   ASSERT_FALSE(r.IsSuccess());
3250   EXPECT_EQ("7: expecting an OFFSET value for each buffer in the array",
3251             r.Error());
3252 }
3253 
3254 }  // namespace amberscript
3255 }  // namespace amber
3256