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