• 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 
23 class DummyDelegate : public amber::Delegate {
24  public:
25   DummyDelegate() = default;
26   ~DummyDelegate() override = default;
27 
Log(const std::string &)28   void Log(const std::string&) override {}
LogGraphicsCalls() const29   bool LogGraphicsCalls() const override { return false; }
SetLogGraphicsCalls(bool)30   void SetLogGraphicsCalls(bool) {}
LogExecuteCalls() const31   bool LogExecuteCalls() const override { return false; }
SetLogExecuteCalls(bool)32   void SetLogExecuteCalls(bool) {}
LogGraphicsCallsTime() const33   bool LogGraphicsCallsTime() const override { return false; }
34 
SetLogGraphicsCallsTime(bool)35   void SetLogGraphicsCallsTime(bool) {}
GetTimestampNs() const36   uint64_t GetTimestampNs() const override { return 0; }
SetScriptPath(std::string)37   void SetScriptPath(std::string) {}
38 
ReportExecutionTiming(double)39   void ReportExecutionTiming(double) override {}
LoadBufferData(const std::string,amber::BufferDataFileType type,amber::BufferInfo * buffer) const40   amber::Result LoadBufferData(const std::string,
41                                amber::BufferDataFileType type,
42                                amber::BufferInfo* buffer) const override {
43     amber::Value v;
44     v.SetIntValue(static_cast<uint64_t>(type));
45     buffer->values.push_back(v);
46     buffer->width = 1;
47     buffer->height = 1;
48 
49     return {};
50   }
51 
LoadFile(const std::string,std::vector<char> *) const52   amber::Result LoadFile(const std::string, std::vector<char>*) const override {
53     return Result("DummyDelegate::LoadFile not implemented");
54   }
55 };
56 
TEST_F(AmberScriptParserTest,BufferData)57 TEST_F(AmberScriptParserTest, BufferData) {
58   std::string in = R"(
59 BUFFER my_buffer DATA_TYPE uint32 DATA
60 1 2 3 4
61 55 99 1234
62 END)";
63 
64   Parser parser;
65   Result r = parser.Parse(in);
66   ASSERT_TRUE(r.IsSuccess()) << r.Error();
67 
68   auto script = parser.GetScript();
69   const auto& buffers = script->GetBuffers();
70   ASSERT_EQ(1U, buffers.size());
71 
72   ASSERT_TRUE(buffers[0] != nullptr);
73   EXPECT_EQ("my_buffer", buffers[0]->GetName());
74 
75   auto* buffer = buffers[0].get();
76   EXPECT_TRUE(buffer->GetFormat()->IsUint32());
77   EXPECT_EQ(Format::Layout::kStd430, buffer->GetFormat()->GetLayout());
78   EXPECT_EQ(7U, buffer->ElementCount());
79   EXPECT_EQ(7U, buffer->ValueCount());
80   EXPECT_EQ(7U * sizeof(uint32_t), buffer->GetSizeInBytes());
81 
82   std::vector<uint32_t> results = {1, 2, 3, 4, 55, 99, 1234};
83   const auto* data = buffer->GetValues<uint32_t>();
84   ASSERT_EQ(results.size(), buffer->ValueCount());
85   for (size_t i = 0; i < results.size(); ++i) {
86     EXPECT_EQ(results[i], data[i]);
87   }
88 }
89 
TEST_F(AmberScriptParserTest,BufferDataStd140)90 TEST_F(AmberScriptParserTest, BufferDataStd140) {
91   std::string in = R"(
92 BUFFER my_buffer DATA_TYPE uint32 STD140 DATA
93 1 2 3 4
94 55 99 1234
95 END)";
96 
97   Parser parser;
98   Result r = parser.Parse(in);
99   ASSERT_TRUE(r.IsSuccess()) << r.Error();
100 
101   auto script = parser.GetScript();
102   const auto& buffers = script->GetBuffers();
103   ASSERT_EQ(1U, buffers.size());
104 
105   ASSERT_TRUE(buffers[0] != nullptr);
106   EXPECT_EQ("my_buffer", buffers[0]->GetName());
107 
108   auto* buffer = buffers[0].get();
109   EXPECT_TRUE(buffer->GetFormat()->IsUint32());
110   EXPECT_EQ(Format::Layout::kStd140, buffer->GetFormat()->GetLayout());
111   EXPECT_EQ(7U, buffer->ElementCount());
112   EXPECT_EQ(7U, buffer->ValueCount());
113   EXPECT_EQ(7U * sizeof(uint32_t), buffer->GetSizeInBytes());
114 
115   std::vector<uint32_t> results = {1, 2, 3, 4, 55, 99, 1234};
116   const auto* data = buffer->GetValues<uint32_t>();
117   ASSERT_EQ(results.size(), buffer->ValueCount());
118   for (size_t i = 0; i < results.size(); ++i) {
119     EXPECT_EQ(results[i], data[i]);
120   }
121 }
122 
TEST_F(AmberScriptParserTest,BufferDataMatrixStd430)123 TEST_F(AmberScriptParserTest, BufferDataMatrixStd430) {
124   std::string in = R"(
125 BUFFER my_buffer DATA_TYPE mat2x2<float> STD430 DATA
126 1 2
127 3 4
128 END)";
129 
130   Parser parser;
131   Result r = parser.Parse(in);
132   ASSERT_TRUE(r.IsSuccess()) << r.Error();
133 
134   auto script = parser.GetScript();
135   const auto& buffers = script->GetBuffers();
136   ASSERT_EQ(1U, buffers.size());
137 
138   ASSERT_TRUE(buffers[0] != nullptr);
139   EXPECT_EQ("my_buffer", buffers[0]->GetName());
140 
141   auto* buffer = buffers[0].get();
142   EXPECT_TRUE(buffer->GetFormat()->IsFloat32());
143   EXPECT_EQ(Format::Layout::kStd430, buffer->GetFormat()->GetLayout());
144   EXPECT_EQ(1U, buffer->ElementCount());
145   EXPECT_EQ(4U, buffer->ValueCount());
146   EXPECT_EQ(4U * sizeof(float), buffer->GetSizeInBytes());
147 
148   std::vector<float> results = {1.f, 2.f, 3.f, 4.f};
149   const auto* data = buffer->GetValues<float>();
150   ASSERT_EQ(results.size(), buffer->ValueCount());
151   for (size_t i = 0; i < results.size(); ++i) {
152     EXPECT_FLOAT_EQ(results[i], data[i]);
153   }
154 }
155 
TEST_F(AmberScriptParserTest,BufferDataMatrixStd140)156 TEST_F(AmberScriptParserTest, BufferDataMatrixStd140) {
157   std::string in = R"(
158 BUFFER my_buffer DATA_TYPE mat2x2<float> STD140 DATA
159 1 2
160 3 4
161 END)";
162 
163   Parser parser;
164   Result r = parser.Parse(in);
165   ASSERT_TRUE(r.IsSuccess()) << r.Error();
166 
167   auto script = parser.GetScript();
168   const auto& buffers = script->GetBuffers();
169   ASSERT_EQ(1U, buffers.size());
170 
171   ASSERT_TRUE(buffers[0] != nullptr);
172   EXPECT_EQ("my_buffer", buffers[0]->GetName());
173 
174   auto* buffer = buffers[0].get();
175   EXPECT_TRUE(buffer->GetFormat()->IsFloat32());
176   EXPECT_EQ(Format::Layout::kStd140, buffer->GetFormat()->GetLayout());
177   EXPECT_EQ(1U, buffer->ElementCount());
178   EXPECT_EQ(4U, buffer->ValueCount());
179   EXPECT_EQ(8U * sizeof(float), buffer->GetSizeInBytes());
180 
181   std::vector<float> results = {1.f, 2.f, 0.f, 0.f, 3.f, 4.f, 0.f, 0.f};
182   const auto* data = buffer->GetValues<float>();
183   for (size_t i = 0; i < results.size(); ++i) {
184     EXPECT_FLOAT_EQ(results[i], data[i]);
185   }
186 }
187 
TEST_F(AmberScriptParserTest,BufferDataStd430)188 TEST_F(AmberScriptParserTest, BufferDataStd430) {
189   std::string in = R"(
190 BUFFER my_buffer DATA_TYPE uint32 STD430 DATA
191 1 2 3 4
192 55 99 1234
193 END)";
194 
195   Parser parser;
196   Result r = parser.Parse(in);
197   ASSERT_TRUE(r.IsSuccess()) << r.Error();
198 
199   auto script = parser.GetScript();
200   const auto& buffers = script->GetBuffers();
201   ASSERT_EQ(1U, buffers.size());
202 
203   ASSERT_TRUE(buffers[0] != nullptr);
204   EXPECT_EQ("my_buffer", buffers[0]->GetName());
205 
206   auto* buffer = buffers[0].get();
207   EXPECT_TRUE(buffer->GetFormat()->IsUint32());
208   EXPECT_EQ(Format::Layout::kStd430, buffer->GetFormat()->GetLayout());
209   EXPECT_EQ(7U, buffer->ElementCount());
210   EXPECT_EQ(7U, buffer->ValueCount());
211   EXPECT_EQ(7U * sizeof(uint32_t), buffer->GetSizeInBytes());
212 
213   std::vector<uint32_t> results = {1, 2, 3, 4, 55, 99, 1234};
214   const auto* data = buffer->GetValues<uint32_t>();
215   ASSERT_EQ(results.size(), buffer->ValueCount());
216   for (size_t i = 0; i < results.size(); ++i) {
217     EXPECT_EQ(results[i], data[i]);
218   }
219 }
220 
TEST_F(AmberScriptParserTest,BufferDataArrayStd140)221 TEST_F(AmberScriptParserTest, BufferDataArrayStd140) {
222   std::string in = R"(
223 BUFFER my_buffer DATA_TYPE uint32[] STD140 DATA
224 1 2 3 4
225 55 99 1234
226 END)";
227 
228   Parser parser;
229   Result r = parser.Parse(in);
230   ASSERT_TRUE(r.IsSuccess()) << r.Error();
231 
232   auto script = parser.GetScript();
233   const auto& buffers = script->GetBuffers();
234   ASSERT_EQ(1U, buffers.size());
235 
236   ASSERT_TRUE(buffers[0] != nullptr);
237   EXPECT_EQ("my_buffer", buffers[0]->GetName());
238 
239   auto* buffer = buffers[0].get();
240   EXPECT_TRUE(buffer->GetFormat()->IsUint32());
241   EXPECT_EQ(Format::Layout::kStd140, buffer->GetFormat()->GetLayout());
242   EXPECT_EQ(7U, buffer->ElementCount());
243   EXPECT_EQ(28U * sizeof(uint32_t), buffer->GetSizeInBytes());
244 
245   std::vector<uint32_t> results = {1,  0, 0, 0, 2,    0, 0,  0, 3, 0,
246                                    0,  0, 4, 0, 0,    0, 55, 0, 0, 0,
247                                    99, 0, 0, 0, 1234, 0, 0,  0};
248   const auto* data = buffer->GetValues<uint32_t>();
249   for (size_t i = 0; i < results.size(); ++i) {
250     EXPECT_EQ(results[i], data[i]);
251   }
252 }
253 
TEST_F(AmberScriptParserTest,BufferDataArrayStd430)254 TEST_F(AmberScriptParserTest, BufferDataArrayStd430) {
255   std::string in = R"(
256 BUFFER my_buffer DATA_TYPE uint32[] STD430 DATA
257 1 2 3 4
258 55 99 1234
259 END)";
260 
261   Parser parser;
262   Result r = parser.Parse(in);
263   ASSERT_TRUE(r.IsSuccess()) << r.Error();
264 
265   auto script = parser.GetScript();
266   const auto& buffers = script->GetBuffers();
267   ASSERT_EQ(1U, buffers.size());
268 
269   ASSERT_TRUE(buffers[0] != nullptr);
270   EXPECT_EQ("my_buffer", buffers[0]->GetName());
271 
272   auto* buffer = buffers[0].get();
273   EXPECT_TRUE(buffer->GetFormat()->IsUint32());
274   EXPECT_EQ(Format::Layout::kStd430, buffer->GetFormat()->GetLayout());
275   EXPECT_EQ(7U, buffer->ElementCount());
276   EXPECT_EQ(7U, buffer->ValueCount());
277   EXPECT_EQ(7U * sizeof(uint32_t), buffer->GetSizeInBytes());
278 
279   std::vector<uint32_t> results = {1, 2, 3, 4, 55, 99, 1234};
280   const auto* data = buffer->GetValues<uint32_t>();
281   ASSERT_EQ(results.size(), buffer->ValueCount());
282   for (size_t i = 0; i < results.size(); ++i) {
283     EXPECT_EQ(results[i], data[i]);
284   }
285 }
286 
TEST_F(AmberScriptParserTest,BufferDataOneLine)287 TEST_F(AmberScriptParserTest, BufferDataOneLine) {
288   std::string in = "BUFFER my_buffer DATA_TYPE uint32 DATA 1 2 3 4 END";
289 
290   Parser parser;
291   Result r = parser.Parse(in);
292   ASSERT_TRUE(r.IsSuccess()) << r.Error();
293 
294   auto script = parser.GetScript();
295   const auto& buffers = script->GetBuffers();
296   ASSERT_EQ(1U, buffers.size());
297 
298   ASSERT_TRUE(buffers[0] != nullptr);
299   EXPECT_EQ("my_buffer", buffers[0]->GetName());
300 
301   auto* buffer = buffers[0].get();
302   EXPECT_TRUE(buffer->GetFormat()->IsUint32());
303   EXPECT_EQ(Format::Layout::kStd430, buffer->GetFormat()->GetLayout());
304   EXPECT_EQ(4U, buffer->ElementCount());
305   EXPECT_EQ(4U, buffer->ValueCount());
306   EXPECT_EQ(4U * sizeof(uint32_t), buffer->GetSizeInBytes());
307 
308   std::vector<uint32_t> results = {1, 2, 3, 4};
309   const auto* data = buffer->GetValues<uint32_t>();
310   ASSERT_EQ(results.size(), buffer->ValueCount());
311   for (size_t i = 0; i < results.size(); ++i) {
312     EXPECT_EQ(results[i], data[i]);
313   }
314 }
315 
TEST_F(AmberScriptParserTest,BufferDataFloat)316 TEST_F(AmberScriptParserTest, BufferDataFloat) {
317   std::string in = "BUFFER my_buffer DATA_TYPE float DATA 1 2 3 4 END";
318 
319   Parser parser;
320   Result r = parser.Parse(in);
321   ASSERT_TRUE(r.IsSuccess()) << r.Error();
322 
323   auto script = parser.GetScript();
324   const auto& buffers = script->GetBuffers();
325   ASSERT_EQ(1U, buffers.size());
326 
327   ASSERT_TRUE(buffers[0] != nullptr);
328   EXPECT_EQ("my_buffer", buffers[0]->GetName());
329 
330   auto* buffer = buffers[0].get();
331   EXPECT_TRUE(buffer->GetFormat()->IsFloat32());
332   EXPECT_EQ(Format::Layout::kStd430, buffer->GetFormat()->GetLayout());
333   EXPECT_EQ(4U, buffer->ElementCount());
334   EXPECT_EQ(4U, buffer->ValueCount());
335   EXPECT_EQ(4U * sizeof(float), buffer->GetSizeInBytes());
336 
337   std::vector<float> results = {1, 2, 3, 4};
338   const auto* data = buffer->GetValues<float>();
339   ASSERT_EQ(results.size(), buffer->ValueCount());
340   for (size_t i = 0; i < results.size(); ++i) {
341     EXPECT_FLOAT_EQ(results[i], data[i]);
342   }
343 }
344 
TEST_F(AmberScriptParserTest,BufferFill)345 TEST_F(AmberScriptParserTest, BufferFill) {
346   std::string in = "BUFFER my_buffer DATA_TYPE uint8 SIZE 5 FILL 5";
347 
348   Parser parser;
349   Result r = parser.Parse(in);
350   ASSERT_TRUE(r.IsSuccess()) << r.Error();
351 
352   auto script = parser.GetScript();
353   const auto& buffers = script->GetBuffers();
354   ASSERT_EQ(1U, buffers.size());
355 
356   ASSERT_TRUE(buffers[0] != nullptr);
357 
358   auto* buffer = buffers[0].get();
359   EXPECT_EQ("my_buffer", buffer->GetName());
360   EXPECT_TRUE(buffer->GetFormat()->IsUint8());
361   EXPECT_EQ(Format::Layout::kStd430, buffer->GetFormat()->GetLayout());
362   EXPECT_EQ(5U, buffer->ElementCount());
363   EXPECT_EQ(5U, buffer->ValueCount());
364   EXPECT_EQ(5U * sizeof(uint8_t), buffer->GetSizeInBytes());
365 
366   std::vector<uint32_t> results = {5, 5, 5, 5, 5};
367   const auto* data = buffer->GetValues<uint8_t>();
368   ASSERT_EQ(results.size(), buffer->ValueCount());
369   for (size_t i = 0; i < results.size(); ++i) {
370     EXPECT_EQ(results[i], data[i]);
371   }
372 }
373 
TEST_F(AmberScriptParserTest,BufferFillFloat)374 TEST_F(AmberScriptParserTest, BufferFillFloat) {
375   std::string in = "BUFFER my_buffer DATA_TYPE float SIZE 5 FILL 5.2";
376 
377   Parser parser;
378   Result r = parser.Parse(in);
379   ASSERT_TRUE(r.IsSuccess()) << r.Error();
380 
381   auto script = parser.GetScript();
382   const auto& buffers = script->GetBuffers();
383   ASSERT_EQ(1U, buffers.size());
384 
385   ASSERT_TRUE(buffers[0] != nullptr);
386 
387   auto* buffer = buffers[0].get();
388   EXPECT_EQ("my_buffer", buffer->GetName());
389   EXPECT_TRUE(buffer->GetFormat()->IsFloat32());
390   EXPECT_EQ(Format::Layout::kStd430, buffer->GetFormat()->GetLayout());
391   EXPECT_EQ(5U, buffer->ElementCount());
392   EXPECT_EQ(5U, buffer->ValueCount());
393   EXPECT_EQ(5U * sizeof(float), buffer->GetSizeInBytes());
394 
395   std::vector<float> results = {5.2f, 5.2f, 5.2f, 5.2f, 5.2f};
396   const auto* data = buffer->GetValues<float>();
397   ASSERT_EQ(results.size(), buffer->ValueCount());
398   for (size_t i = 0; i < results.size(); ++i) {
399     EXPECT_FLOAT_EQ(results[i], data[i]);
400   }
401 }
402 
TEST_F(AmberScriptParserTest,BufferSeries)403 TEST_F(AmberScriptParserTest, BufferSeries) {
404   std::string in =
405       "BUFFER my_buffer DATA_TYPE uint8 SIZE 5 SERIES_FROM 2 INC_BY 1";
406 
407   Parser parser;
408   Result r = parser.Parse(in);
409   ASSERT_TRUE(r.IsSuccess()) << r.Error();
410 
411   auto script = parser.GetScript();
412   const auto& buffers = script->GetBuffers();
413   ASSERT_EQ(1U, buffers.size());
414 
415   ASSERT_TRUE(buffers[0] != nullptr);
416 
417   auto* buffer = buffers[0].get();
418   EXPECT_EQ("my_buffer", buffer->GetName());
419   EXPECT_TRUE(buffer->GetFormat()->IsUint8());
420   EXPECT_EQ(Format::Layout::kStd430, buffer->GetFormat()->GetLayout());
421   EXPECT_EQ(5U, buffer->ElementCount());
422   EXPECT_EQ(5U, buffer->ValueCount());
423   EXPECT_EQ(5U * sizeof(uint8_t), buffer->GetSizeInBytes());
424 
425   std::vector<uint8_t> results = {2, 3, 4, 5, 6};
426   const auto* data = buffer->GetValues<uint8_t>();
427   ASSERT_EQ(results.size(), buffer->ValueCount());
428   for (size_t i = 0; i < results.size(); ++i) {
429     EXPECT_EQ(results[i], data[i]);
430   }
431 }
432 
TEST_F(AmberScriptParserTest,BufferSeriesFloat)433 TEST_F(AmberScriptParserTest, BufferSeriesFloat) {
434   std::string in =
435       "BUFFER my_buffer DATA_TYPE float SIZE 5 SERIES_FROM 2.2 INC_BY "
436       "1.1";
437 
438   Parser parser;
439   Result r = parser.Parse(in);
440   ASSERT_TRUE(r.IsSuccess()) << r.Error();
441 
442   auto script = parser.GetScript();
443   const auto& buffers = script->GetBuffers();
444   ASSERT_EQ(1U, buffers.size());
445 
446   ASSERT_TRUE(buffers[0] != nullptr);
447 
448   auto* buffer = buffers[0].get();
449   EXPECT_EQ("my_buffer", buffer->GetName());
450   EXPECT_TRUE(buffer->GetFormat()->IsFloat32());
451   EXPECT_EQ(Format::Layout::kStd430, buffer->GetFormat()->GetLayout());
452   EXPECT_EQ(5U, buffer->ElementCount());
453   EXPECT_EQ(5U, buffer->ValueCount());
454   EXPECT_EQ(5U * sizeof(float), buffer->GetSizeInBytes());
455 
456   std::vector<float> results = {2.2f, 3.3f, 4.4f, 5.5f, 6.6f};
457   const auto* data = buffer->GetValues<float>();
458   ASSERT_EQ(results.size(), buffer->ValueCount());
459   for (size_t i = 0; i < results.size(); ++i) {
460     EXPECT_FLOAT_EQ(results[i], data[i]);
461   }
462 }
463 
TEST_F(AmberScriptParserTest,BufferMultipleBuffers)464 TEST_F(AmberScriptParserTest, BufferMultipleBuffers) {
465   std::string in = R"(
466 BUFFER color_buffer DATA_TYPE uint8 SIZE 5 FILL 5
467 BUFFER storage_buffer DATA_TYPE uint32 DATA
468 1 2 3 4
469 55 99 1234
470 END)";
471 
472   Parser parser;
473   Result r = parser.Parse(in);
474   ASSERT_TRUE(r.IsSuccess()) << r.Error();
475 
476   auto script = parser.GetScript();
477   const auto& buffers = script->GetBuffers();
478   ASSERT_EQ(2U, buffers.size());
479 
480   ASSERT_TRUE(buffers[0] != nullptr);
481 
482   auto* buffer = buffers[0].get();
483   EXPECT_EQ("color_buffer", buffer->GetName());
484   EXPECT_TRUE(buffer->GetFormat()->IsUint8());
485   EXPECT_EQ(Format::Layout::kStd430, buffer->GetFormat()->GetLayout());
486   EXPECT_EQ(5U, buffer->ElementCount());
487   EXPECT_EQ(5U, buffer->ValueCount());
488   EXPECT_EQ(5U * sizeof(uint8_t), buffer->GetSizeInBytes());
489 
490   std::vector<uint32_t> results0 = {5, 5, 5, 5, 5};
491   const auto* data0 = buffer->GetValues<uint8_t>();
492   ASSERT_EQ(results0.size(), buffer->ValueCount());
493   for (size_t i = 0; i < results0.size(); ++i) {
494     EXPECT_EQ(results0[i], data0[i]);
495   }
496 
497   ASSERT_TRUE(buffers[1] != nullptr);
498 
499   buffer = buffers[1].get();
500   EXPECT_EQ("storage_buffer", buffer->GetName());
501   EXPECT_TRUE(buffer->GetFormat()->IsUint32());
502   EXPECT_EQ(Format::Layout::kStd430, buffer->GetFormat()->GetLayout());
503   EXPECT_EQ(7U, buffer->ElementCount());
504   EXPECT_EQ(7U, buffer->ValueCount());
505   EXPECT_EQ(7U * sizeof(uint32_t), buffer->GetSizeInBytes());
506 
507   std::vector<uint32_t> results1 = {1, 2, 3, 4, 55, 99, 1234};
508   const auto* data1 = buffer->GetValues<uint32_t>();
509   ASSERT_EQ(results1.size(), buffer->ValueCount());
510   for (size_t i = 0; i < results1.size(); ++i) {
511     EXPECT_EQ(results1[i], data1[i]);
512   }
513 }
514 
TEST_F(AmberScriptParserTest,BufferFillMultiRow)515 TEST_F(AmberScriptParserTest, BufferFillMultiRow) {
516   std::string in = R"(
517 BUFFER my_index_buffer DATA_TYPE vec2<int32> SIZE 5 FILL 2)";
518 
519   Parser parser;
520   Result r = parser.Parse(in);
521   ASSERT_TRUE(r.IsSuccess()) << r.Error();
522 
523   auto script = parser.GetScript();
524   const auto& buffers = script->GetBuffers();
525   ASSERT_EQ(1U, buffers.size());
526 
527   ASSERT_TRUE(buffers[0] != nullptr);
528 
529   auto* buffer = buffers[0].get();
530   EXPECT_EQ("my_index_buffer", buffer->GetName());
531   EXPECT_TRUE(buffer->GetFormat()->IsInt32());
532   EXPECT_EQ(Format::Layout::kStd430, buffer->GetFormat()->GetLayout());
533   EXPECT_EQ(5U, buffer->ElementCount());
534   EXPECT_EQ(10U, buffer->ValueCount());
535   EXPECT_EQ(10U * sizeof(int32_t), buffer->GetSizeInBytes());
536 
537   std::vector<int32_t> results0 = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
538   const auto* data0 = buffer->GetValues<int32_t>();
539   for (size_t i = 0; i < results0.size(); ++i) {
540     EXPECT_EQ(results0[i], data0[i]);
541   }
542 }
543 
TEST_F(AmberScriptParserTest,BufferDataMultiRowStd430)544 TEST_F(AmberScriptParserTest, BufferDataMultiRowStd430) {
545   std::string in = R"(
546 BUFFER my_index_buffer DATA_TYPE vec2<int32> DATA
547 2 3
548 4 5
549 6 7
550 8 9
551 END
552 )";
553 
554   Parser parser;
555   Result r = parser.Parse(in);
556   ASSERT_TRUE(r.IsSuccess()) << r.Error();
557 
558   auto script = parser.GetScript();
559   const auto& buffers = script->GetBuffers();
560   ASSERT_EQ(1U, buffers.size());
561 
562   ASSERT_TRUE(buffers[0] != nullptr);
563 
564   auto* buffer = buffers[0].get();
565   EXPECT_EQ("my_index_buffer", buffer->GetName());
566   EXPECT_TRUE(buffer->GetFormat()->IsInt32());
567   EXPECT_EQ(Format::Layout::kStd430, buffer->GetFormat()->GetLayout());
568   EXPECT_EQ(4U, buffer->ElementCount());
569   EXPECT_EQ(8U, buffer->ValueCount());
570   EXPECT_EQ(8U * sizeof(int32_t), buffer->GetSizeInBytes());
571 
572   std::vector<int32_t> results0 = {2, 3, 4, 5, 6, 7, 8, 9};
573   const auto* data0 = buffer->GetValues<int32_t>();
574   for (size_t i = 0; i < results0.size(); ++i) {
575     EXPECT_EQ(results0[i], data0[i]);
576   }
577 }
578 
TEST_F(AmberScriptParserTest,BufferDataMultiRowStd140)579 TEST_F(AmberScriptParserTest, BufferDataMultiRowStd140) {
580   std::string in = R"(
581 BUFFER my_index_buffer DATA_TYPE vec2<int32> STD140 DATA
582 2 3
583 4 5
584 6 7
585 8 9
586 END
587 )";
588 
589   Parser parser;
590   Result r = parser.Parse(in);
591   ASSERT_TRUE(r.IsSuccess()) << r.Error();
592 
593   auto script = parser.GetScript();
594   const auto& buffers = script->GetBuffers();
595   ASSERT_EQ(1U, buffers.size());
596 
597   ASSERT_TRUE(buffers[0] != nullptr);
598 
599   auto* buffer = buffers[0].get();
600   EXPECT_EQ("my_index_buffer", buffer->GetName());
601   EXPECT_TRUE(buffer->GetFormat()->IsInt32());
602   EXPECT_EQ(Format::Layout::kStd140, buffer->GetFormat()->GetLayout());
603   EXPECT_EQ(4U, buffer->ElementCount());
604   EXPECT_EQ(8U, buffer->ValueCount());
605   EXPECT_EQ(8U * sizeof(int32_t), buffer->GetSizeInBytes());
606 
607   std::vector<int32_t> results0 = {2, 3, 4, 5, 6, 7, 8, 9};
608   const auto* data0 = buffer->GetValues<int32_t>();
609   for (size_t i = 0; i < results0.size(); ++i) {
610     EXPECT_EQ(results0[i], data0[i]);
611   }
612 }
613 
TEST_F(AmberScriptParserTest,BufferDataHex)614 TEST_F(AmberScriptParserTest, BufferDataHex) {
615   std::string in = R"(
616 BUFFER my_index_buffer DATA_TYPE uint32 DATA
617 0xff000000
618 0x00ff0000
619 0x0000ff00
620 0x000000ff
621 END
622 )";
623 
624   Parser parser;
625   Result r = parser.Parse(in);
626   ASSERT_TRUE(r.IsSuccess()) << r.Error();
627 
628   auto script = parser.GetScript();
629   const auto& buffers = script->GetBuffers();
630   ASSERT_EQ(1U, buffers.size());
631 
632   ASSERT_TRUE(buffers[0] != nullptr);
633 
634   auto* buffer = buffers[0].get();
635   EXPECT_EQ("my_index_buffer", buffer->GetName());
636   EXPECT_TRUE(buffer->GetFormat()->IsUint32());
637   EXPECT_EQ(Format::Layout::kStd430, buffer->GetFormat()->GetLayout());
638   EXPECT_EQ(4U, buffer->ElementCount());
639   EXPECT_EQ(4U, buffer->ValueCount());
640   EXPECT_EQ(4U * sizeof(uint32_t), buffer->GetSizeInBytes());
641 
642   std::vector<uint32_t> results0 = {4278190080, 16711680, 65280, 255};
643   const auto* data0 = buffer->GetValues<uint32_t>();
644   ASSERT_EQ(results0.size(), buffer->ValueCount());
645   for (size_t i = 0; i < results0.size(); ++i) {
646     EXPECT_EQ(results0[i], data0[i]);
647   }
648 }
649 
TEST_F(AmberScriptParserTest,BufferFormat)650 TEST_F(AmberScriptParserTest, BufferFormat) {
651   std::string in = "BUFFER my_buf FORMAT R32G32B32A32_SINT";
652 
653   Parser parser;
654   Result r = parser.Parse(in);
655   ASSERT_TRUE(r.IsSuccess()) << r.Error();
656 
657   auto script = parser.GetScript();
658   const auto& buffers = script->GetBuffers();
659   ASSERT_EQ(1U, buffers.size());
660 
661   ASSERT_TRUE(buffers[0] != nullptr);
662   auto* buffer = buffers[0].get();
663   EXPECT_EQ("my_buf", buffer->GetName());
664 
665   auto fmt = buffer->GetFormat();
666   EXPECT_EQ(FormatType::kR32G32B32A32_SINT, fmt->GetFormatType());
667   auto& segs = fmt->GetSegments();
668   ASSERT_EQ(4U, segs.size());
669 
670   for (size_t i = 0; i < 4; ++i) {
671     EXPECT_EQ(segs[i].GetNumBits(), 32u);
672     EXPECT_EQ(segs[i].GetFormatMode(), FormatMode::kSInt);
673     EXPECT_EQ(segs[i].GetName(), static_cast<FormatComponentType>(i));
674   }
675 }
676 
TEST_F(AmberScriptParserTest,BufferSamples)677 TEST_F(AmberScriptParserTest, BufferSamples) {
678   std::string in = "BUFFER my_buf FORMAT R8G8B8A8_UNORM SAMPLES 2";
679 
680   Parser parser;
681   Result r = parser.Parse(in);
682   ASSERT_TRUE(r.IsSuccess()) << r.Error();
683 
684   auto script = parser.GetScript();
685   const auto& buffers = script->GetBuffers();
686   ASSERT_EQ(1U, buffers.size());
687 
688   ASSERT_TRUE(buffers[0] != nullptr);
689   auto* buffer = buffers[0].get();
690   EXPECT_EQ("my_buf", buffer->GetName());
691   EXPECT_EQ(2u, buffer->GetSamples());
692 }
693 
694 struct BufferParseError {
695   const char* in;
696   const char* err;
697 };
698 using AmberScriptParserBufferParseErrorTest =
699     testing::TestWithParam<BufferParseError>;
TEST_P(AmberScriptParserBufferParseErrorTest,Test)700 TEST_P(AmberScriptParserBufferParseErrorTest, Test) {
701   auto test_data = GetParam();
702 
703   Parser parser;
704   Result r = parser.Parse(test_data.in);
705   ASSERT_FALSE(r.IsSuccess()) << test_data.in;
706   EXPECT_EQ(std::string(test_data.err), r.Error()) << test_data.in;
707 }
708 
709 INSTANTIATE_TEST_SUITE_P(
710     AmberScriptParserBufferParseErrorTest,
711     AmberScriptParserBufferParseErrorTest,
712     testing::Values(
713         BufferParseError{"BUFFER my_buf FORMAT 123",
714                          "1: BUFFER FORMAT must be an identifier"},
715         BufferParseError{"BUFFER my_buf FORMAT A23A32",
716                          "1: invalid BUFFER FORMAT"},
717         BufferParseError{"BUFFER my_buf FORMAT",
718                          "1: BUFFER FORMAT must be an identifier"},
719         BufferParseError{"BUFFER my_buffer FORMAT R32G32B32A32_SFLOAT EXTRA",
720                          "1: unknown token: EXTRA"},
721         BufferParseError{"BUFFER 1234 DATA_TYPE uint8 SIZE 5 FILL 5",
722                          "1: invalid BUFFER name provided"},
723         BufferParseError{"BUFFER DATA_TYPE uint8 SIZE 5 FILL 5",
724                          "1: missing BUFFER name"},
725 
726         BufferParseError{"BUFFER my_buf 1234",
727                          "1: invalid BUFFER command provided"},
728         BufferParseError{"BUFFER my_buf INVALID",
729                          "1: unknown BUFFER command provided: INVALID"},
730         BufferParseError{"BUFFER my_buf DATA_TYPE uint8 SIZE INVALID FILL 5",
731                          "1: BUFFER size invalid"},
732         BufferParseError{"BUFFER my_buf DATA_TYPE uint8 SIZE FILL 5",
733                          "1: BUFFER size invalid"},
734         BufferParseError{"BUFFER my_buf DATA_TYPE uint8 SIZE 5 FILL",
735                          "1: missing BUFFER fill value"},
736         BufferParseError{"BUFFER my_buf DATA_TYPE uint8 SIZE 5 FILL INVALID",
737                          "1: invalid BUFFER fill value"},
738         BufferParseError{"BUFFER my_buf DATA_TYPE uint8 SIZE 5 INVALID 5",
739                          "1: invalid BUFFER initializer provided"},
740         BufferParseError{"BUFFER my_buf DATA_TYPE uint8 SIZE 5 FILL INVALID",
741                          "1: invalid BUFFER fill value"},
742         BufferParseError{"BUFFER my_buf DATA_TYPE uint8 SIZE 5 FILL",
743                          "1: missing BUFFER fill value"},
744         BufferParseError{
745             "BUFFER my_buf DATA_TYPE uint8 SIZE 5 SERIES_FROM INC_BY 2",
746             "1: invalid BUFFER series_from value"},
747         BufferParseError{"BUFFER my_buf DATA_TYPE uint8 SIZE 5 SERIES_FROM 2",
748                          "1: missing BUFFER series_from inc_by"},
749         BufferParseError{
750             "BUFFER my_buf DATA_TYPE uint8 SIZE 5 SERIES_FROM 2 INC_BY",
751             "1: missing BUFFER series_from inc_by value"},
752         BufferParseError{"BUFFER my_buf DATA_TYPE uint8 SIZE 5 "
753                          "SERIES_FROM INVALID INC_BY 2",
754                          "1: invalid BUFFER series_from value"},
755         BufferParseError{"BUFFER my_buf DATA_TYPE uint8 SIZE 5 "
756                          "SERIES_FROM 1 INC_BY INVALID",
757                          "1: invalid BUFFER series_from inc_by value"},
758         BufferParseError{"BUFFER my_buf DATA_TYPE uint8 SIZE 5 "
759                          "SERIES_FROM 1 INVALID 2",
760                          "1: BUFFER series_from invalid command"},
761         BufferParseError{
762             "BUFFER my_index_buffer DATA_TYPE int32 DATA\n1.234\nEND",
763             "2: invalid BUFFER data value: 1.234"},
764         BufferParseError{
765             "BUFFER my_index_buffer DATA_TYPE int32 DATA\nINVALID\nEND",
766             "2: invalid BUFFER data value: INVALID"},
767         BufferParseError{
768             "BUFFER my_index_buffer DATA_TYPE int32 DATA INVALID\n123\nEND",
769             "1: invalid BUFFER data value: INVALID"},
770         BufferParseError{
771             "BUFFER my_index_buffer DATA_TYPE int32 SIZE 256 FILL "
772             "5 INVALID\n123\nEND",
773             "1: extra parameters after BUFFER fill command: INVALID"},
774         BufferParseError{
775             "BUFFER my_buffer DATA_TYPE int32 SIZE 256 SERIES_FROM 2 "
776             "INC_BY 5 "
777             "INVALID",
778             "1: extra parameters after BUFFER series_from command: INVALID"},
779         BufferParseError{"BUFFER my_buf DATA_TYPE int32 SIZE 5 FILL 5\nBUFFER "
780                          "my_buf DATA_TYPE int16 SIZE 5 FILL 2",
781                          // NOLINTNEXTLINE(whitespace/parens)
782                          "2: duplicate buffer name provided"},
783         BufferParseError{"BUFFER my_buf FORMAT R8G8B8A8_UNORM SAMPLES 9",
784                          "1: invalid sample count: 9"},
785         BufferParseError{"BUFFER my_buf FORMAT R8G8B8A8_UNORM SAMPLES foo",
786                          "1: expected integer value for SAMPLES"}));
787 
788 struct BufferData {
789   const char* name;
790   FormatMode type;
791   size_t num_bits;
792   size_t row_count;
793   size_t column_count;
794   bool is_array;
795 };
796 
797 using AmberScriptParserBufferDataTypeTest = testing::TestWithParam<BufferData>;
TEST_P(AmberScriptParserBufferDataTypeTest,BufferTypes)798 TEST_P(AmberScriptParserBufferDataTypeTest, BufferTypes) {
799   auto test_data = GetParam();
800 
801   std::string in = std::string("BUFFER my_buf DATA_TYPE ") + test_data.name +
802                    " SIZE 2 FILL 5";
803 
804   Parser parser;
805   Result r = parser.Parse(in);
806   ASSERT_TRUE(r.IsSuccess()) << test_data.name << " :" << r.Error();
807 
808   auto script = parser.GetScript();
809   const auto& buffers = script->GetBuffers();
810   ASSERT_EQ(1U, buffers.size());
811 
812   ASSERT_TRUE(buffers[0] != nullptr);
813 
814   auto* buffer = buffers[0].get();
815   auto fmt = buffer->GetFormat();
816   EXPECT_EQ(test_data.row_count, fmt->GetType()->RowCount());
817   EXPECT_EQ(test_data.column_count, fmt->GetType()->ColumnCount());
818 
819   auto& seg = fmt->GetSegments()[0];
820   EXPECT_EQ(test_data.type, seg.GetFormatMode());
821   EXPECT_EQ(test_data.num_bits, seg.GetNumBits());
822   EXPECT_EQ(test_data.is_array, fmt->GetType()->IsArray());
823 }
824 INSTANTIATE_TEST_SUITE_P(
825     AmberScriptParserTestsDataType,
826     AmberScriptParserBufferDataTypeTest,
827     testing::Values(
828         BufferData{"int8", FormatMode::kSInt, 8, 1, 1, false},
829         BufferData{"int16", FormatMode::kSInt, 16, 1, 1, false},
830         BufferData{"int32", FormatMode::kSInt, 32, 1, 1, false},
831         BufferData{"int64", FormatMode::kSInt, 64, 1, 1, false},
832         BufferData{"uint8", FormatMode::kUInt, 8, 1, 1, false},
833         BufferData{"uint16", FormatMode::kUInt, 16, 1, 1, false},
834         BufferData{"uint32", FormatMode::kUInt, 32, 1, 1, false},
835         BufferData{"uint64", FormatMode::kUInt, 64, 1, 1, false},
836         BufferData{"float", FormatMode::kSFloat, 32, 1, 1, false},
837         BufferData{"double", FormatMode::kSFloat, 64, 1, 1, false},
838         BufferData{"vec2<int8>", FormatMode::kSInt, 8, 2, 1, false},
839         BufferData{"vec3<float>", FormatMode::kSFloat, 32, 3, 1, false},
840         BufferData{"vec4<uint32>", FormatMode::kUInt, 32, 4, 1, false},
841         BufferData{"mat2x4<int32>", FormatMode::kSInt, 32, 4, 2, false},
842         BufferData{"mat3x3<float>", FormatMode::kSFloat, 32, 3, 3, false},
843         BufferData{"mat4x2<uint16>", FormatMode::kUInt, 16, 2, 4, false},
844         BufferData{"B8G8R8_UNORM", FormatMode::kUNorm, 8, 3, 1,
845                    false}));  // NOLINT(whitespace/parens)
846 
847 INSTANTIATE_TEST_SUITE_P(
848     AmberScriptParserTestsDataType2,
849     AmberScriptParserBufferDataTypeTest,
850     testing::Values(
851         BufferData{"int8[]", FormatMode::kSInt, 8, 1, 1, true},
852         BufferData{"int16[]", FormatMode::kSInt, 16, 1, 1, true},
853         BufferData{"int32[]", FormatMode::kSInt, 32, 1, 1, true},
854         BufferData{"int64[]", FormatMode::kSInt, 64, 1, 1, true},
855         BufferData{"uint8[]", FormatMode::kUInt, 8, 1, 1, true},
856         BufferData{"uint16[]", FormatMode::kUInt, 16, 1, 1, true},
857         BufferData{"uint32[]", FormatMode::kUInt, 32, 1, 1, true},
858         BufferData{"uint64[]", FormatMode::kUInt, 64, 1, 1, true},
859         BufferData{"float[]", FormatMode::kSFloat, 32, 1, 1, true},
860         BufferData{"double[]", FormatMode::kSFloat, 64, 1, 1, true},
861         BufferData{"vec2<int8>[]", FormatMode::kSInt, 8, 2, 1, true},
862         BufferData{"vec3<float>[]", FormatMode::kSFloat, 32, 3, 1, true},
863         BufferData{"vec4<uint32>[]", FormatMode::kUInt, 32, 4, 1, true},
864         BufferData{"mat2x4<int32>[]", FormatMode::kSInt, 32, 4, 2, true},
865         BufferData{"mat3x3<float>[]", FormatMode::kSFloat, 32, 3, 3, true},
866         BufferData{"mat4x2<uint16>[]", FormatMode::kUInt, 16, 2, 4,
867                    true}));  // NOLINT(whitespace/parens)
868 
869 struct NameData {
870   const char* name;
871 };
872 
873 using AmberScriptParserBufferDataTypeInvalidTest =
874     testing::TestWithParam<NameData>;
TEST_P(AmberScriptParserBufferDataTypeInvalidTest,BufferTypes)875 TEST_P(AmberScriptParserBufferDataTypeInvalidTest, BufferTypes) {
876   auto test_data = GetParam();
877 
878   std::string in = std::string("BUFFER my_buf DATA_TYPE ") + test_data.name +
879                    " SIZE 4 FILL 5";
880 
881   Parser parser;
882   Result r = parser.Parse(in);
883   ASSERT_FALSE(r.IsSuccess()) << test_data.name;
884   EXPECT_EQ(
885       std::string("1: invalid data type '") + test_data.name + "' provided",
886       r.Error())
887       << test_data.name;
888 }
889 INSTANTIATE_TEST_SUITE_P(
890     AmberScriptParserBufferDataTypeInvalidTestSamples,
891     AmberScriptParserBufferDataTypeInvalidTest,
892     testing::Values(NameData{"int17"},
893                     NameData{"int["},
894                     NameData{"int]"},
895                     NameData{"B8G8R8_UNORM[]"},
896                     NameData{"uintt0"},
897                     NameData{"vec7<uint8>"},
898                     NameData{"vec27<uint8>"},
899                     NameData{"vec2<vec2<float>>"},
900                     NameData{"vec2<mat2x2<float>>"},
901                     NameData{"vec2float>"},
902                     NameData{"vec2<uint32"},
903                     NameData{"vec2<uint4>"},
904                     NameData{"vec2<>"},
905                     NameData{"vec2"},
906                     NameData{"mat1x1<double>"},
907                     NameData{"mat5x2<double>"},
908                     NameData{"mat2x5<double>"},
909                     NameData{"mat22x22<double>"},
910                     NameData{"matx5<double>"},
911                     NameData{"mat2<double>"},
912                     NameData{"mat2x<double>"},
913                     NameData{"mat2x2<vec4<float>>"},
914                     NameData{"mat2x2<mat3x3<double>>"},
915                     NameData{"mat2x2<unit7>"},
916                     NameData{"mat2x2"},
917                     NameData{"mat2x2<>"}));  // NOLINT(whitespace/parens)
918 
TEST_F(AmberScriptParserTest,BufferWithStructStd140)919 TEST_F(AmberScriptParserTest, BufferWithStructStd140) {
920   std::string in = R"(
921 STRUCT s
922   uint32 d
923   uint32 e
924 END
925 
926 STRUCT my_data
927   float a
928   uint32 b
929   s c
930 END
931 
932 BUFFER my_buffer DATA_TYPE my_data STD140 DATA
933   1  # a
934  64  # b
935 128  # c.d
936 220  # c.e
937 END)";
938 
939   Parser parser;
940   Result r = parser.Parse(in);
941   ASSERT_TRUE(r.IsSuccess()) << r.Error();
942 
943   auto script = parser.GetScript();
944   const auto& buffers = script->GetBuffers();
945   ASSERT_EQ(1U, buffers.size());
946 
947   ASSERT_TRUE(buffers[0] != nullptr);
948   EXPECT_EQ("my_buffer", buffers[0]->GetName());
949 
950   auto* buffer = buffers[0].get();
951   EXPECT_TRUE(buffer->GetFormat()->GetType()->IsStruct());
952   EXPECT_EQ(Format::Layout::kStd140, buffer->GetFormat()->GetLayout());
953 
954   EXPECT_EQ(1U, buffer->ElementCount());
955   EXPECT_EQ(32U, buffer->GetSizeInBytes());
956 
957   const auto* data = buffer->GetValues<uint8_t>();
958   EXPECT_FLOAT_EQ(1.f, *reinterpret_cast<const float*>(data + 0));
959   EXPECT_EQ(64u,
960             *reinterpret_cast<const uint32_t*>(data + 4 /* sizeof(float) */));
961   EXPECT_EQ(128u,
962             *reinterpret_cast<const uint32_t*>(data + 16 /* 8 round -> 16 */));
963   EXPECT_EQ(220u, *reinterpret_cast<const uint32_t*>(
964                       data + 20 /* 8 round -> 16 + 4 */));
965 }
966 
TEST_F(AmberScriptParserTest,BufferWithStructStd430)967 TEST_F(AmberScriptParserTest, BufferWithStructStd430) {
968   std::string in = R"(
969 STRUCT s
970   uint32 d
971   uint32 e
972 END
973 
974 STRUCT my_data
975   float a
976   uint32 b
977   s c
978 END
979 
980 BUFFER my_buffer DATA_TYPE my_data STD430 DATA
981   1  # a
982  64  # b
983 128  # c.d
984 220  # c.e
985 END)";
986 
987   Parser parser;
988   Result r = parser.Parse(in);
989   ASSERT_TRUE(r.IsSuccess()) << r.Error();
990 
991   auto script = parser.GetScript();
992   const auto& buffers = script->GetBuffers();
993   ASSERT_EQ(1U, buffers.size());
994 
995   ASSERT_TRUE(buffers[0] != nullptr);
996   EXPECT_EQ("my_buffer", buffers[0]->GetName());
997 
998   auto* buffer = buffers[0].get();
999   EXPECT_TRUE(buffer->GetFormat()->GetType()->IsStruct());
1000   EXPECT_EQ(Format::Layout::kStd430, buffer->GetFormat()->GetLayout());
1001 
1002   EXPECT_EQ(1U, buffer->ElementCount());
1003   EXPECT_EQ(16U, buffer->GetSizeInBytes());
1004 
1005   const auto* data = buffer->GetValues<uint8_t>();
1006   EXPECT_FLOAT_EQ(1.f, *reinterpret_cast<const float*>(data + 0));
1007   EXPECT_EQ(64u, *reinterpret_cast<const uint32_t*>(data + 4));
1008   EXPECT_EQ(128u, *reinterpret_cast<const uint32_t*>(data + 8));
1009   EXPECT_EQ(220u, *reinterpret_cast<const uint32_t*>(data + 12));
1010 }
1011 
TEST_F(AmberScriptParserTest,BufferWithStructAndPaddingStd430)1012 TEST_F(AmberScriptParserTest, BufferWithStructAndPaddingStd430) {
1013   std::string in = R"(
1014 STRUCT s
1015   uint32 d OFFSET 8
1016   uint32 e OFFSET 16
1017 END
1018 
1019 STRUCT my_data
1020   float a OFFSET 8
1021   uint32 b OFFSET 16
1022   s c;
1023 END
1024 
1025 BUFFER my_buffer DATA_TYPE my_data STD430 DATA
1026   1  # a
1027  64  # b
1028 128  # c.d
1029 220  # c.e
1030 END)";
1031 
1032   Parser parser;
1033   Result r = parser.Parse(in);
1034   ASSERT_TRUE(r.IsSuccess()) << r.Error();
1035 
1036   auto script = parser.GetScript();
1037   const auto& buffers = script->GetBuffers();
1038   ASSERT_EQ(1U, buffers.size());
1039 
1040   ASSERT_TRUE(buffers[0] != nullptr);
1041   EXPECT_EQ("my_buffer", buffers[0]->GetName());
1042 
1043   auto* buffer = buffers[0].get();
1044   EXPECT_TRUE(buffer->GetFormat()->GetType()->IsStruct());
1045   EXPECT_EQ(Format::Layout::kStd430, buffer->GetFormat()->GetLayout());
1046 
1047   EXPECT_EQ(1U, buffer->ElementCount());
1048   EXPECT_EQ(40U, buffer->GetSizeInBytes());
1049 
1050   const auto* data = buffer->GetValues<uint8_t>();
1051   EXPECT_FLOAT_EQ(1.f, *reinterpret_cast<const float*>(data + 8));
1052   EXPECT_EQ(64u, *reinterpret_cast<const uint32_t*>(data + 16));
1053   EXPECT_EQ(128u, *reinterpret_cast<const uint32_t*>(data + 28));
1054   EXPECT_EQ(220u, *reinterpret_cast<const uint32_t*>(data + 36));
1055 }
1056 
TEST_F(AmberScriptParserTest,BufferWithStructPartialInitialization)1057 TEST_F(AmberScriptParserTest, BufferWithStructPartialInitialization) {
1058   std::string in = R"(
1059 STRUCT my_data
1060   uint32 a
1061   float b
1062   uint32 c
1063   uint32 d
1064 END
1065 
1066 BUFFER my_buffer DATA_TYPE my_data STD430 DATA
1067   1  # a
1068  64  # b
1069 END)";
1070 
1071   Parser parser;
1072   Result r = parser.Parse(in);
1073   ASSERT_FALSE(r.IsSuccess());
1074   EXPECT_EQ("12: Mismatched number of items in buffer", r.Error());
1075 }
1076 
TEST_F(AmberScriptParserTest,BufferWithStruct_vec_Std140)1077 TEST_F(AmberScriptParserTest, BufferWithStruct_vec_Std140) {
1078   std::string in = R"(
1079 
1080 STRUCT my_data
1081   float a
1082   vec3<float> b
1083 END
1084 
1085 BUFFER my_buffer DATA_TYPE my_data STD140 DATA
1086   1  # a
1087  64 128 220  # b
1088 END)";
1089 
1090   Parser parser;
1091   Result r = parser.Parse(in);
1092   ASSERT_TRUE(r.IsSuccess()) << r.Error();
1093 
1094   auto script = parser.GetScript();
1095   const auto& buffers = script->GetBuffers();
1096   ASSERT_EQ(1U, buffers.size());
1097 
1098   ASSERT_TRUE(buffers[0] != nullptr);
1099   EXPECT_EQ("my_buffer", buffers[0]->GetName());
1100 
1101   auto* buffer = buffers[0].get();
1102   EXPECT_TRUE(buffer->GetFormat()->GetType()->IsStruct());
1103   EXPECT_EQ(Format::Layout::kStd140, buffer->GetFormat()->GetLayout());
1104 
1105   EXPECT_EQ(1U, buffer->ElementCount());
1106   EXPECT_EQ(32U, buffer->GetSizeInBytes());
1107 
1108   const auto* data = buffer->GetValues<uint8_t>();
1109   EXPECT_FLOAT_EQ(1.f, *reinterpret_cast<const float*>(data + 0));
1110   EXPECT_FLOAT_EQ(64u, *reinterpret_cast<const float*>(data + 16));
1111   EXPECT_FLOAT_EQ(128u, *reinterpret_cast<const float*>(data + 20));
1112   EXPECT_FLOAT_EQ(220u, *reinterpret_cast<const float*>(data + 24));
1113 }
1114 
TEST_F(AmberScriptParserTest,InvalidBufferWidth)1115 TEST_F(AmberScriptParserTest, InvalidBufferWidth) {
1116   std::string in = R"(
1117 BUFFER buf DATA_TYPE vec4<float> WIDTH a
1118 )";
1119 
1120   Parser parser;
1121   Result r = parser.Parse(in);
1122   ASSERT_FALSE(r.IsSuccess());
1123   EXPECT_EQ("2: expected an integer for WIDTH", r.Error());
1124 }
1125 
TEST_F(AmberScriptParserTest,ZeroBufferWidth)1126 TEST_F(AmberScriptParserTest, ZeroBufferWidth) {
1127   std::string in = R"(
1128 BUFFER buf DATA_TYPE vec4<float> WIDTH 0
1129 )";
1130 
1131   Parser parser;
1132   Result r = parser.Parse(in);
1133   ASSERT_FALSE(r.IsSuccess());
1134   EXPECT_EQ("2: expected WIDTH to be positive", r.Error());
1135 }
1136 
TEST_F(AmberScriptParserTest,MissingBufferHeight)1137 TEST_F(AmberScriptParserTest, MissingBufferHeight) {
1138   std::string in = R"(
1139 BUFFER buf DATA_TYPE vec4<float> WIDTH 1
1140 )";
1141 
1142   Parser parser;
1143   Result r = parser.Parse(in);
1144   ASSERT_FALSE(r.IsSuccess());
1145   EXPECT_EQ("3: BUFFER HEIGHT missing", r.Error());
1146 }
1147 
TEST_F(AmberScriptParserTest,InvalidBufferHeight)1148 TEST_F(AmberScriptParserTest, InvalidBufferHeight) {
1149   std::string in = R"(
1150 BUFFER buf DATA_TYPE vec4<float> WIDTH 1 HEIGHT 1.0
1151 )";
1152 
1153   Parser parser;
1154   Result r = parser.Parse(in);
1155   ASSERT_FALSE(r.IsSuccess());
1156   EXPECT_EQ("2: expected an integer for HEIGHT", r.Error());
1157 }
1158 
TEST_F(AmberScriptParserTest,ZeroBufferHeight)1159 TEST_F(AmberScriptParserTest, ZeroBufferHeight) {
1160   std::string in = R"(
1161 BUFFER buf DATA_TYPE vec4<float> WIDTH 1 HEIGHT 0
1162 )";
1163 
1164   Parser parser;
1165   Result r = parser.Parse(in);
1166   ASSERT_FALSE(r.IsSuccess());
1167 
1168   EXPECT_EQ("2: expected HEIGHT to be positive", r.Error());
1169 }
1170 
TEST_F(AmberScriptParserTest,BufferWidthAndHeight)1171 TEST_F(AmberScriptParserTest, BufferWidthAndHeight) {
1172   std::string in = R"(
1173 BUFFER buf DATA_TYPE vec4<float> WIDTH 2 HEIGHT 3
1174 )";
1175 
1176   Parser parser;
1177   Result r = parser.Parse(in);
1178   ASSERT_TRUE(r.IsSuccess());
1179 
1180   auto script = parser.GetScript();
1181   const auto& buffers = script->GetBuffers();
1182   ASSERT_EQ(1U, buffers.size());
1183   ASSERT_TRUE(buffers[0] != nullptr);
1184   EXPECT_EQ("buf", buffers[0]->GetName());
1185 
1186   auto* buffer = buffers[0].get();
1187   EXPECT_EQ(2u, buffer->GetWidth());
1188   EXPECT_EQ(3u, buffer->GetHeight());
1189   EXPECT_EQ(6u, buffer->ElementCount());
1190 }
1191 
TEST_F(AmberScriptParserTest,BufferMipLevels)1192 TEST_F(AmberScriptParserTest, BufferMipLevels) {
1193   std::string in = "BUFFER my_buffer FORMAT R8G8B8A8_UNORM MIP_LEVELS 3";
1194 
1195   Parser parser;
1196   Result r = parser.Parse(in);
1197   ASSERT_TRUE(r.IsSuccess()) << r.Error();
1198 
1199   auto script = parser.GetScript();
1200   const auto& buffers = script->GetBuffers();
1201   ASSERT_EQ(1U, buffers.size());
1202 
1203   ASSERT_TRUE(buffers[0] != nullptr);
1204   EXPECT_EQ("my_buffer", buffers[0]->GetName());
1205 
1206   auto* buffer = buffers[0].get();
1207   EXPECT_EQ(3U, buffer->GetMipLevels());
1208 }
1209 
TEST_F(AmberScriptParserTest,BufferMissingMipLevels)1210 TEST_F(AmberScriptParserTest, BufferMissingMipLevels) {
1211   std::string in = "BUFFER my_buffer FORMAT R8G8B8A8_UNORM MIP_LEVELS";
1212 
1213   Parser parser;
1214   Result r = parser.Parse(in);
1215   ASSERT_FALSE(r.IsSuccess());
1216 
1217   EXPECT_EQ("1: invalid value for MIP_LEVELS", r.Error());
1218 }
1219 
TEST_F(AmberScriptParserTest,BufferMissingDataFile)1220 TEST_F(AmberScriptParserTest, BufferMissingDataFile) {
1221   std::string in = "BUFFER my_buffer FORMAT R8G8B8A8_UNORM FILE";
1222 
1223   Parser parser;
1224   Result r = parser.Parse(in);
1225   ASSERT_FALSE(r.IsSuccess());
1226 
1227   EXPECT_EQ("1: invalid value for FILE", r.Error());
1228 }
1229 
TEST_F(AmberScriptParserTest,BufferMissingDataFilePng)1230 TEST_F(AmberScriptParserTest, BufferMissingDataFilePng) {
1231   std::string in = "BUFFER my_buffer FORMAT R8G8B8A8_UNORM FILE PNG";
1232 
1233   Parser parser;
1234   Result r = parser.Parse(in);
1235   ASSERT_FALSE(r.IsSuccess());
1236 
1237   EXPECT_EQ("1: missing file name for FILE", r.Error());
1238 }
1239 
TEST_F(AmberScriptParserTest,BufferDataFilePng)1240 TEST_F(AmberScriptParserTest, BufferDataFilePng) {
1241   std::string in = "BUFFER my_buffer FORMAT R8G8B8A8_UNORM FILE PNG foo.png";
1242 
1243   DummyDelegate delegate;
1244   Parser parser(&delegate);
1245   Result r = parser.Parse(in);
1246   ASSERT_TRUE(r.IsSuccess());
1247   auto script = parser.GetScript();
1248   const auto& buffers = script->GetBuffers();
1249   ASSERT_EQ(1U, buffers.size());
1250   ASSERT_TRUE(buffers[0] != nullptr);
1251   ASSERT_EQ(static_cast<uint8_t>(amber::BufferDataFileType::kPng),
1252             buffers[0]->GetValues<uint8_t>()[0]);
1253 }
1254 
TEST_F(AmberScriptParserTest,BufferMissingDataFileBinary)1255 TEST_F(AmberScriptParserTest, BufferMissingDataFileBinary) {
1256   std::string in = "BUFFER my_buffer DATA_TYPE float SIZE 10 FILE BINARY";
1257 
1258   Parser parser;
1259   Result r = parser.Parse(in);
1260   ASSERT_FALSE(r.IsSuccess());
1261 
1262   EXPECT_EQ("1: missing file name for FILE", r.Error());
1263 }
1264 
TEST_F(AmberScriptParserTest,BufferDataFileBinary)1265 TEST_F(AmberScriptParserTest, BufferDataFileBinary) {
1266   std::string in =
1267       "BUFFER my_buffer DATA_TYPE int32 SIZE 10 FILE BINARY data.bin";
1268 
1269   DummyDelegate delegate;
1270   Parser parser(&delegate);
1271   Result r = parser.Parse(in);
1272   ASSERT_TRUE(r.IsSuccess());
1273   auto script = parser.GetScript();
1274   const auto& buffers = script->GetBuffers();
1275   ASSERT_EQ(1U, buffers.size());
1276   ASSERT_TRUE(buffers[0] != nullptr);
1277   ASSERT_EQ(static_cast<uint8_t>(amber::BufferDataFileType::kBinary),
1278             buffers[0]->GetValues<uint8_t>()[0]);
1279 }
1280 
TEST_F(AmberScriptParserTest,BufferMissingDataFileText)1281 TEST_F(AmberScriptParserTest, BufferMissingDataFileText) {
1282   std::string in = "BUFFER my_buffer DATA_TYPE float SIZE 10 FILE TEXT";
1283 
1284   Parser parser;
1285   Result r = parser.Parse(in);
1286   ASSERT_FALSE(r.IsSuccess());
1287 
1288   EXPECT_EQ("1: missing file name for FILE", r.Error());
1289 }
1290 
TEST_F(AmberScriptParserTest,BufferDataFileText)1291 TEST_F(AmberScriptParserTest, BufferDataFileText) {
1292   std::string in =
1293       "BUFFER my_buffer DATA_TYPE int32 SIZE 10 FILE TEXT data.txt";
1294 
1295   DummyDelegate delegate;
1296   Parser parser(&delegate);
1297   Result r = parser.Parse(in);
1298   ASSERT_TRUE(r.IsSuccess());
1299   auto script = parser.GetScript();
1300   const auto& buffers = script->GetBuffers();
1301   ASSERT_EQ(1U, buffers.size());
1302   ASSERT_TRUE(buffers[0] != nullptr);
1303   ASSERT_EQ(static_cast<uint8_t>(amber::BufferDataFileType::kText),
1304             buffers[0]->GetValues<uint8_t>()[0]);
1305 }
1306 
1307 }  // namespace amberscript
1308 }  // namespace amber
1309