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