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