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 implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "src/format.h"
16 
17 #include "gtest/gtest.h"
18 #include "src/make_unique.h"
19 #include "src/type_parser.h"
20 
21 namespace amber {
22 
23 using FormatTest = testing::Test;
24 
TEST_F(FormatTest,DefaultToStd430)25 TEST_F(FormatTest, DefaultToStd430) {
26   auto f32 = type::Number::Float(32);
27   Format fmt(f32.get());
28   EXPECT_EQ(Format::Layout::kStd430, fmt.GetLayout());
29 }
30 
TEST_F(FormatTest,SizeInBytesVector_Std430)31 TEST_F(FormatTest, SizeInBytesVector_Std430) {
32   TypeParser parser;
33   auto type = parser.Parse("R32G32B32_SFLOAT");
34   ASSERT_TRUE(type != nullptr);
35 
36   Format fmt(type.get());
37   EXPECT_EQ(3U, fmt.InputNeededPerElement());
38   EXPECT_EQ(16U, fmt.SizeInBytes());
39 }
40 
TEST_F(FormatTest,SizeInBytesMatrix_Std430)41 TEST_F(FormatTest, SizeInBytesMatrix_Std430) {
42   TypeParser parser;
43   auto type = parser.Parse("R32G32B32_SFLOAT");
44   ASSERT_TRUE(type != nullptr);
45   type->SetColumnCount(3);
46 
47   Format fmt(type.get());
48   EXPECT_EQ(9U, fmt.InputNeededPerElement());
49   EXPECT_EQ(48U, fmt.SizeInBytes());
50 }
51 
TEST_F(FormatTest,SizeInBytesMatrix_Std140)52 TEST_F(FormatTest, SizeInBytesMatrix_Std140) {
53   TypeParser parser;
54   auto type = parser.Parse("R32G32_SFLOAT");
55   ASSERT_TRUE(type != nullptr);
56   type->SetColumnCount(2);
57 
58   Format fmt(type.get());
59   fmt.SetLayout(Format::Format::Layout::kStd140);
60   EXPECT_EQ(32U, fmt.SizeInBytes());
61 }
62 
63 struct StdData {
64   const char* name;
65   const char* fmt;
66   uint32_t column_count;
67   bool is_std140;
68   uint32_t size_in_bytes;
69 };
70 using FormatStdTest = testing::TestWithParam<StdData>;
TEST_P(FormatStdTest,Test)71 TEST_P(FormatStdTest, Test) {
72   auto test_data = GetParam();
73 
74   TypeParser parser;
75   auto type = parser.Parse(test_data.fmt);
76   ASSERT_TRUE(type != nullptr) << test_data.name;
77 
78   type->SetColumnCount(test_data.column_count);
79 
80   Format fmt(type.get());
81   if (test_data.is_std140)
82     fmt.SetLayout(Format::Format::Layout::kStd140);
83 
84   EXPECT_EQ(test_data.size_in_bytes, fmt.SizeInBytes()) << test_data.name;
85 }
86 
87 INSTANTIATE_TEST_SUITE_P(
88     FormatStdTestSamples,
89     FormatStdTest,
90     testing::Values(
91         StdData{"mat2x2-std140", "R32G32_SFLOAT", 2, true, 32U},
92         StdData{"mat2x3-std140", "R32G32B32_SFLOAT", 2, true, 32U},
93         StdData{"mat2x4-std140", "R32G32B32A32_SFLOAT", 2, true, 32U},
94         StdData{"mat3x2-std140", "R32G32_SFLOAT", 3, true, 48U},
95         StdData{"mat3x3-std140", "R32G32B32_SFLOAT", 3, true, 48U},
96         StdData{"mat3x4-std140", "R32G32B32A32_SFLOAT", 3, true, 48U},
97         StdData{"mat4x2-std140", "R32G32_SFLOAT", 4, true, 64U},
98         StdData{"mat4x3-std140", "R32G32B32_SFLOAT", 4, true, 64U},
99         StdData{"mat4x4-std140", "R32G32B32A32_SFLOAT", 4, true, 64U},
100         StdData{"mat2x2-std430", "R32G32_SFLOAT", 2, false, 16U},
101         StdData{"mat2x3-std430", "R32G32B32_SFLOAT", 2, false, 32U},
102         StdData{"mat2x4-std430", "R32G32B32A32_SFLOAT", 2, false, 32U},
103         StdData{"mat3x2-std430", "R32G32_SFLOAT", 3, false, 24U},
104         StdData{"mat3x3-std430", "R32G32B32_SFLOAT", 3, false, 48U},
105         StdData{"mat3x4-std430", "R32G32B32A32_SFLOAT", 3, false, 48U},
106         StdData{"mat4x2-std430", "R32G32_SFLOAT", 4, false, 32U},
107         StdData{"mat4x3-std430", "R32G32B32_SFLOAT", 4, false, 64U},
108         StdData{"mat4x4-std430", "R32G32B32A32_SFLOAT", 4, false, 64U},
109         StdData{"float-std140", "R32_SFLOAT", 1, true, 4U},
110         StdData{"float-std430", "R32_SFLOAT", 1, false,
111                 4U}));  // NOLINT(whitespace/parens)
112 
113 struct Name {
114   const char* name;
115 };
116 using FormatNameTest = testing::TestWithParam<Name>;
117 
TEST_P(FormatNameTest,Test)118 TEST_P(FormatNameTest, Test) {
119   auto test_data = GetParam();
120 
121   TypeParser parser;
122   auto type = parser.Parse(test_data.name);
123   ASSERT_TRUE(type != nullptr) << test_data.name;
124 
125   Format fmt(type.get());
126   EXPECT_EQ(test_data.name, fmt.GenerateNameForTesting());
127 }
128 INSTANTIATE_TEST_SUITE_P(
129     FormatNameGenerateTest,
130     FormatNameTest,
131     testing::Values(Name{"A1R5G5B5_UNORM_PACK16"},
132                     Name{"A2B10G10R10_SINT_PACK32"},
133                     Name{"A2B10G10R10_SNORM_PACK32"},
134                     Name{"A2B10G10R10_SSCALED_PACK32"},
135                     Name{"A2B10G10R10_UINT_PACK32"},
136                     Name{"A2B10G10R10_UNORM_PACK32"},
137                     Name{"A2B10G10R10_USCALED_PACK32"},
138                     Name{"A2R10G10B10_SINT_PACK32"},
139                     Name{"A2R10G10B10_SNORM_PACK32"},
140                     Name{"A2R10G10B10_SSCALED_PACK32"},
141                     Name{"A2R10G10B10_UINT_PACK32"},
142                     Name{"A2R10G10B10_UNORM_PACK32"},
143                     Name{"A2R10G10B10_USCALED_PACK32"},
144                     Name{"A8B8G8R8_SINT_PACK32"},
145                     Name{"A8B8G8R8_SNORM_PACK32"},
146                     Name{"A8B8G8R8_SRGB_PACK32"},
147                     Name{"A8B8G8R8_SSCALED_PACK32"},
148                     Name{"A8B8G8R8_UINT_PACK32"},
149                     Name{"A8B8G8R8_UNORM_PACK32"},
150                     Name{"A8B8G8R8_USCALED_PACK32"},
151                     Name{"B10G11R11_UFLOAT_PACK32"},
152                     Name{"B4G4R4A4_UNORM_PACK16"},
153                     Name{"B5G5R5A1_UNORM_PACK16"},
154                     Name{"B5G6R5_UNORM_PACK16"},
155                     Name{"B8G8R8A8_SINT"},
156                     Name{"B8G8R8A8_SNORM"},
157                     Name{"B8G8R8A8_SRGB"},
158                     Name{"B8G8R8A8_SSCALED"},
159                     Name{"B8G8R8A8_UINT"},
160                     Name{"B8G8R8A8_UNORM"},
161                     Name{"B8G8R8A8_USCALED"},
162                     Name{"B8G8R8_SINT"},
163                     Name{"B8G8R8_SNORM"},
164                     Name{"B8G8R8_SRGB"},
165                     Name{"B8G8R8_SSCALED"},
166                     Name{"B8G8R8_UINT"},
167                     Name{"B8G8R8_UNORM"},
168                     Name{"B8G8R8_USCALED"},
169                     Name{"D16_UNORM"},
170                     Name{"D16_UNORM_S8_UINT"},
171                     Name{"D24_UNORM_S8_UINT"},
172                     Name{"D32_SFLOAT"},
173                     Name{"D32_SFLOAT_S8_UINT"},
174                     Name{"R16G16B16A16_SFLOAT"},
175                     Name{"R16G16B16A16_SINT"},
176                     Name{"R16G16B16A16_SNORM"},
177                     Name{"R16G16B16A16_SSCALED"},
178                     Name{"R16G16B16A16_UINT"},
179                     Name{"R16G16B16A16_UNORM"},
180                     Name{"R16G16B16A16_USCALED"},
181                     Name{"R16G16B16_SFLOAT"},
182                     Name{"R16G16B16_SINT"},
183                     Name{"R16G16B16_SNORM"},
184                     Name{"R16G16B16_SSCALED"},
185                     Name{"R16G16B16_UINT"},
186                     Name{"R16G16B16_UNORM"},
187                     Name{"R16G16B16_USCALED"},
188                     Name{"R16G16_SFLOAT"},
189                     Name{"R16G16_SINT"},
190                     Name{"R16G16_SNORM"},
191                     Name{"R16G16_SSCALED"},
192                     Name{"R16G16_UINT"},
193                     Name{"R16G16_UNORM"},
194                     Name{"R16G16_USCALED"},
195                     Name{"R16_SFLOAT"},
196                     Name{"R16_SINT"},
197                     Name{"R16_SNORM"},
198                     Name{"R16_SSCALED"},
199                     Name{"R16_UINT"},
200                     Name{"R16_UNORM"},
201                     Name{"R16_USCALED"},
202                     Name{"R32G32B32A32_SFLOAT"},
203                     Name{"R32G32B32A32_SINT"},
204                     Name{"R32G32B32A32_UINT"},
205                     Name{"R32G32B32_SFLOAT"},
206                     Name{"R32G32B32_SINT"},
207                     Name{"R32G32B32_UINT"},
208                     Name{"R32G32_SFLOAT"},
209                     Name{"R32G32_SINT"},
210                     Name{"R32G32_UINT"},
211                     Name{"R32_SFLOAT"},
212                     Name{"R32_SINT"},
213                     Name{"R32_UINT"},
214                     Name{"R4G4B4A4_UNORM_PACK16"},
215                     Name{"R4G4_UNORM_PACK8"},
216                     Name{"R5G5B5A1_UNORM_PACK16"},
217                     Name{"R5G6B5_UNORM_PACK16"},
218                     Name{"R64G64B64A64_SFLOAT"},
219                     Name{"R64G64B64A64_SINT"},
220                     Name{"R64G64B64A64_UINT"},
221                     Name{"R64G64B64_SFLOAT"},
222                     Name{"R64G64B64_SINT"},
223                     Name{"R64G64B64_UINT"},
224                     Name{"R64G64_SFLOAT"},
225                     Name{"R64G64_SINT"},
226                     Name{"R64G64_UINT"},
227                     Name{"R64_SFLOAT"},
228                     Name{"R64_SINT"},
229                     Name{"R64_UINT"},
230                     Name{"R8G8B8A8_SINT"},
231                     Name{"R8G8B8A8_SNORM"},
232                     Name{"R8G8B8A8_SRGB"},
233                     Name{"R8G8B8A8_SSCALED"},
234                     Name{"R8G8B8A8_UINT"},
235                     Name{"R8G8B8A8_UNORM"},
236                     Name{"R8G8B8A8_USCALED"},
237                     Name{"R8G8B8_SINT"},
238                     Name{"R8G8B8_SNORM"},
239                     Name{"R8G8B8_SRGB"},
240                     Name{"R8G8B8_SSCALED"},
241                     Name{"R8G8B8_UINT"},
242                     Name{"R8G8B8_UNORM"},
243                     Name{"R8G8B8_USCALED"},
244                     Name{"R8G8_SINT"},
245                     Name{"R8G8_SNORM"},
246                     Name{"R8G8_SRGB"},
247                     Name{"R8G8_SSCALED"},
248                     Name{"R8G8_UINT"},
249                     Name{"R8G8_UNORM"},
250                     Name{"R8G8_USCALED"},
251                     Name{"R8_SINT"},
252                     Name{"R8_SNORM"},
253                     Name{"R8_SRGB"},
254                     Name{"R8_SSCALED"},
255                     Name{"R8_UINT"},
256                     Name{"R8_UNORM"},
257                     Name{"R8_USCALED"},
258                     Name{"S8_UINT"},
259                     Name{"X8_D24_UNORM_PACK32"}));  // NOLINT(whitespace/parens)
260 
TEST_F(FormatTest,SegmentPackedList_Std430)261 TEST_F(FormatTest, SegmentPackedList_Std430) {
262   TypeParser parser;
263   auto type = parser.Parse("A8B8G8R8_SINT_PACK32");
264 
265   Format fmt(type.get());
266   EXPECT_EQ(4u, fmt.SizeInBytes());
267 
268   const auto& segs = fmt.GetSegments();
269   ASSERT_EQ(1U, segs.size());
270   // Always packs into a unsigned ...
271   EXPECT_EQ(FormatMode::kUInt, segs[0].GetFormatMode());
272   EXPECT_EQ(4u, segs[0].SizeInBytes());
273 }
274 
TEST_F(FormatTest,SegmentListR32G32_Std140)275 TEST_F(FormatTest, SegmentListR32G32_Std140) {
276   TypeParser parser;
277   auto type = parser.Parse("R32G32_UINT");
278 
279   Format fmt(type.get());
280   fmt.SetLayout(Format::Layout::kStd140);
281   EXPECT_EQ(8u, fmt.SizeInBytes());
282 
283   const auto& segs = fmt.GetSegments();
284   ASSERT_EQ(2U, segs.size());
285   EXPECT_EQ(FormatMode::kUInt, segs[0].GetFormatMode());
286   EXPECT_EQ(4u, segs[0].SizeInBytes());
287   EXPECT_EQ(FormatMode::kUInt, segs[1].GetFormatMode());
288   EXPECT_EQ(4u, segs[1].SizeInBytes());
289 }
290 
TEST_F(FormatTest,SegmentListR32G32B32_Std140)291 TEST_F(FormatTest, SegmentListR32G32B32_Std140) {
292   TypeParser parser;
293   auto type = parser.Parse("R32G32B32_UINT");
294 
295   Format fmt(type.get());
296   fmt.SetLayout(Format::Layout::kStd140);
297   EXPECT_EQ(16u, fmt.SizeInBytes());
298 
299   const auto& segs = fmt.GetSegments();
300   ASSERT_EQ(4U, segs.size());
301   EXPECT_EQ(FormatMode::kUInt, segs[0].GetFormatMode());
302   EXPECT_EQ(4u, segs[0].SizeInBytes());
303   EXPECT_EQ(FormatMode::kUInt, segs[1].GetFormatMode());
304   EXPECT_EQ(4u, segs[1].SizeInBytes());
305   EXPECT_EQ(FormatMode::kUInt, segs[2].GetFormatMode());
306   EXPECT_EQ(4u, segs[2].SizeInBytes());
307   EXPECT_TRUE(segs[3].IsPadding());
308   EXPECT_EQ(4u, segs[3].SizeInBytes());
309 }
310 
TEST_F(FormatTest,SegmentListR32G32B32_Std430)311 TEST_F(FormatTest, SegmentListR32G32B32_Std430) {
312   TypeParser parser;
313   auto type = parser.Parse("R32G32B32_UINT");
314 
315   Format fmt(type.get());
316   fmt.SetLayout(Format::Format::Layout::kStd430);
317   EXPECT_EQ(16u, fmt.SizeInBytes());
318 
319   const auto& segs = fmt.GetSegments();
320   ASSERT_EQ(4U, segs.size());
321   EXPECT_EQ(FormatMode::kUInt, segs[0].GetFormatMode());
322   EXPECT_EQ(4u, segs[0].SizeInBytes());
323   EXPECT_EQ(FormatMode::kUInt, segs[1].GetFormatMode());
324   EXPECT_EQ(4u, segs[1].SizeInBytes());
325   EXPECT_EQ(FormatMode::kUInt, segs[2].GetFormatMode());
326   EXPECT_EQ(4u, segs[2].SizeInBytes());
327   EXPECT_TRUE(segs[3].IsPadding());
328   EXPECT_EQ(4u, segs[3].SizeInBytes());
329 }
330 
TEST_F(FormatTest,SegmentMat2x2_Std140)331 TEST_F(FormatTest, SegmentMat2x2_Std140) {
332   TypeParser parser;
333   auto type = parser.Parse("R32G32_SFLOAT");
334   type->SetColumnCount(2);
335 
336   Format fmt(type.get());
337   fmt.SetLayout(Format::Format::Layout::kStd140);
338   EXPECT_EQ(32u, fmt.SizeInBytes());
339 
340   const auto& segs = fmt.GetSegments();
341   ASSERT_EQ(6U, segs.size());
342   EXPECT_EQ(FormatMode::kSFloat, segs[0].GetFormatMode());
343   EXPECT_EQ(4u, segs[0].SizeInBytes());
344   EXPECT_EQ(FormatMode::kSFloat, segs[1].GetFormatMode());
345   EXPECT_EQ(4u, segs[1].SizeInBytes());
346   EXPECT_TRUE(segs[2].IsPadding());
347   EXPECT_EQ(8u, segs[2].SizeInBytes());
348 
349   EXPECT_EQ(FormatMode::kSFloat, segs[3].GetFormatMode());
350   EXPECT_EQ(4u, segs[3].SizeInBytes());
351   EXPECT_EQ(FormatMode::kSFloat, segs[4].GetFormatMode());
352   EXPECT_EQ(4u, segs[4].SizeInBytes());
353   EXPECT_TRUE(segs[5].IsPadding());
354   EXPECT_EQ(8u, segs[5].SizeInBytes());
355 }
356 
TEST_F(FormatTest,SegmentMat2x2_Std430)357 TEST_F(FormatTest, SegmentMat2x2_Std430) {
358   TypeParser parser;
359   auto type = parser.Parse("R32G32_SFLOAT");
360   type->SetColumnCount(2);
361 
362   Format fmt(type.get());
363   fmt.SetLayout(Format::Layout::kStd430);
364   EXPECT_EQ(16u, fmt.SizeInBytes());
365 
366   const auto& segs = fmt.GetSegments();
367   ASSERT_EQ(4U, segs.size());
368   EXPECT_EQ(FormatMode::kSFloat, segs[0].GetFormatMode());
369   EXPECT_EQ(4u, segs[0].SizeInBytes());
370   EXPECT_EQ(FormatMode::kSFloat, segs[1].GetFormatMode());
371   EXPECT_EQ(4u, segs[1].SizeInBytes());
372 
373   EXPECT_EQ(FormatMode::kSFloat, segs[2].GetFormatMode());
374   EXPECT_EQ(4u, segs[2].SizeInBytes());
375   EXPECT_EQ(FormatMode::kSFloat, segs[3].GetFormatMode());
376   EXPECT_EQ(4u, segs[3].SizeInBytes());
377 }
378 
TEST_F(FormatTest,SegmentMat2x3_Std430)379 TEST_F(FormatTest, SegmentMat2x3_Std430) {
380   TypeParser parser;
381   auto type = parser.Parse("R32G32B32_SFLOAT");
382   type->SetColumnCount(2);
383 
384   Format fmt(type.get());
385   fmt.SetLayout(Format::Layout::kStd430);
386   EXPECT_EQ(32u, fmt.SizeInBytes());
387 
388   const auto& segs = fmt.GetSegments();
389   ASSERT_EQ(8U, segs.size());
390   EXPECT_EQ(FormatMode::kSFloat, segs[0].GetFormatMode());
391   EXPECT_EQ(4u, segs[0].SizeInBytes());
392   EXPECT_EQ(FormatMode::kSFloat, segs[1].GetFormatMode());
393   EXPECT_EQ(4u, segs[1].SizeInBytes());
394   EXPECT_EQ(FormatMode::kSFloat, segs[2].GetFormatMode());
395   EXPECT_EQ(4u, segs[2].SizeInBytes());
396   EXPECT_TRUE(segs[3].IsPadding());
397   EXPECT_EQ(4u, segs[3].SizeInBytes());
398 
399   EXPECT_EQ(FormatMode::kSFloat, segs[4].GetFormatMode());
400   EXPECT_EQ(4u, segs[4].SizeInBytes());
401   EXPECT_EQ(FormatMode::kSFloat, segs[5].GetFormatMode());
402   EXPECT_EQ(4u, segs[5].SizeInBytes());
403   EXPECT_EQ(FormatMode::kSFloat, segs[6].GetFormatMode());
404   EXPECT_EQ(4u, segs[6].SizeInBytes());
405   EXPECT_TRUE(segs[7].IsPadding());
406   EXPECT_EQ(4u, segs[7].SizeInBytes());
407 }
408 
TEST_F(FormatTest,SegmentRuntimeArray_Std140)409 TEST_F(FormatTest, SegmentRuntimeArray_Std140) {
410   TypeParser parser;
411   auto type = parser.Parse("R32_SFLOAT");
412   type->SetIsRuntimeArray();
413 
414   Format fmt(type.get());
415   fmt.SetLayout(Format::Format::Layout::kStd140);
416   EXPECT_EQ(16u, fmt.SizeInBytes());
417 
418   const auto& segs = fmt.GetSegments();
419   ASSERT_EQ(2U, segs.size());
420   EXPECT_EQ(FormatMode::kSFloat, segs[0].GetFormatMode());
421   EXPECT_EQ(4u, segs[0].SizeInBytes());
422   EXPECT_TRUE(segs[1].IsPadding());
423   EXPECT_EQ(12u, segs[1].SizeInBytes());
424 }
425 
TEST_F(FormatTest,SegmentRuntimeArray_Std430)426 TEST_F(FormatTest, SegmentRuntimeArray_Std430) {
427   TypeParser parser;
428   auto type = parser.Parse("R32_SFLOAT");
429   type->SetIsRuntimeArray();
430 
431   Format fmt(type.get());
432   fmt.SetLayout(Format::Layout::kStd430);
433   EXPECT_EQ(4u, fmt.SizeInBytes());
434 
435   const auto& segs = fmt.GetSegments();
436   ASSERT_EQ(1U, segs.size());
437   EXPECT_EQ(FormatMode::kSFloat, segs[0].GetFormatMode());
438   EXPECT_EQ(4u, segs[0].SizeInBytes());
439 }
440 
441 // struct {
442 //  float x;
443 //  int32 y;
444 // }
TEST_F(FormatTest,SegmentStruct_Std140)445 TEST_F(FormatTest, SegmentStruct_Std140) {
446   auto s = MakeUnique<type::Struct>();
447   auto f32 = type::Number::Float(32);
448   auto u32 = type::Number::Uint(32);
449   s->AddMember(f32.get());
450   s->AddMember(u32.get());
451 
452   Format fmt(s.get());
453   fmt.SetLayout(Format::Layout::kStd140);
454   EXPECT_EQ(16u, fmt.SizeInBytes());
455 
456   const auto& segs = fmt.GetSegments();
457   ASSERT_EQ(3u, segs.size());
458   EXPECT_EQ(FormatMode::kSFloat, segs[0].GetFormatMode());
459   EXPECT_EQ(4u, segs[0].SizeInBytes());
460   EXPECT_EQ(FormatMode::kUInt, segs[1].GetFormatMode());
461   EXPECT_EQ(4u, segs[1].SizeInBytes());
462   EXPECT_TRUE(segs[2].IsPadding());
463   EXPECT_EQ(8u, segs[2].SizeInBytes());
464 }
TEST_F(FormatTest,SegmentStruct_Std430)465 TEST_F(FormatTest, SegmentStruct_Std430) {
466   auto s = MakeUnique<type::Struct>();
467   auto f32 = type::Number::Float(32);
468   auto u32 = type::Number::Uint(32);
469   s->AddMember(f32.get());
470   s->AddMember(u32.get());
471 
472   Format fmt(s.get());
473   fmt.SetLayout(Format::Layout::kStd430);
474   EXPECT_EQ(8u, fmt.SizeInBytes());
475 
476   const auto& segs = fmt.GetSegments();
477   ASSERT_EQ(2U, segs.size());
478   EXPECT_EQ(FormatMode::kSFloat, segs[0].GetFormatMode());
479   EXPECT_EQ(4u, segs[0].SizeInBytes());
480   EXPECT_EQ(FormatMode::kUInt, segs[1].GetFormatMode());
481   EXPECT_EQ(4u, segs[1].SizeInBytes());
482 }
483 
484 // struct STRIDE 20 {
485 //  float x;
486 //  int32 y;
487 // }
488 // Note, the STRIDE is the stride over the entire structure.
TEST_F(FormatTest,SegmentStructWithStride_Std140)489 TEST_F(FormatTest, SegmentStructWithStride_Std140) {
490   auto s = MakeUnique<type::Struct>();
491   auto f32 = type::Number::Float(32);
492   auto u32 = type::Number::Uint(32);
493   s->AddMember(f32.get());
494   s->AddMember(u32.get());
495   s->SetStrideInBytes(20);
496 
497   Format fmt(s.get());
498   fmt.SetLayout(Format::Layout::kStd140);
499   EXPECT_EQ(20u, fmt.SizeInBytes());
500 
501   const auto& segs = fmt.GetSegments();
502   ASSERT_EQ(3U, segs.size());
503   EXPECT_EQ(FormatMode::kSFloat, segs[0].GetFormatMode());
504   EXPECT_EQ(4u, segs[0].SizeInBytes());
505   EXPECT_EQ(FormatMode::kUInt, segs[1].GetFormatMode());
506   EXPECT_EQ(4u, segs[1].SizeInBytes());
507   EXPECT_TRUE(segs[2].IsPadding());
508   EXPECT_EQ((20u - sizeof(float) - sizeof(uint32_t)), segs[2].SizeInBytes());
509 }
TEST_F(FormatTest,SegmentStructWithStride_Std430)510 TEST_F(FormatTest, SegmentStructWithStride_Std430) {
511   auto s = MakeUnique<type::Struct>();
512   auto f32 = type::Number::Float(32);
513   auto u32 = type::Number::Uint(32);
514   s->AddMember(f32.get());
515   s->AddMember(u32.get());
516   s->SetStrideInBytes(20);
517 
518   Format fmt(s.get());
519   fmt.SetLayout(Format::Layout::kStd430);
520   EXPECT_EQ(20u, fmt.SizeInBytes());
521 
522   const auto& segs = fmt.GetSegments();
523   ASSERT_EQ(3U, segs.size());
524   EXPECT_EQ(FormatMode::kSFloat, segs[0].GetFormatMode());
525   EXPECT_EQ(32U, segs[0].GetNumBits());
526   EXPECT_EQ(FormatMode::kUInt, segs[1].GetFormatMode());
527   EXPECT_EQ(32U, segs[1].GetNumBits());
528   EXPECT_TRUE(segs[2].IsPadding());
529   EXPECT_EQ((20u - sizeof(float) - sizeof(uint32_t)) * 8, segs[2].GetNumBits());
530 }
531 
532 // struct {
533 //  float x OFFSET 4;
534 //  int32 y;
535 // }
TEST_F(FormatTest,SegmentStructWithMemberOffset_Std140)536 TEST_F(FormatTest, SegmentStructWithMemberOffset_Std140) {
537   auto s = MakeUnique<type::Struct>();
538   auto f32 = type::Number::Float(32);
539   auto u32 = type::Number::Uint(32);
540 
541   auto m = s->AddMember(f32.get());
542   m->offset_in_bytes = 4;
543 
544   s->AddMember(u32.get());
545 
546   Format fmt(s.get());
547   fmt.SetLayout(Format::Layout::kStd140);
548   EXPECT_EQ(16u, fmt.SizeInBytes());
549 
550   const auto& segs = fmt.GetSegments();
551   ASSERT_EQ(4U, segs.size());
552   EXPECT_TRUE(segs[0].IsPadding());
553   EXPECT_EQ(4u, segs[0].SizeInBytes());
554   EXPECT_EQ(FormatMode::kSFloat, segs[1].GetFormatMode());
555   EXPECT_EQ(4u, segs[1].SizeInBytes());
556   EXPECT_EQ(FormatMode::kUInt, segs[2].GetFormatMode());
557   EXPECT_EQ(4u, segs[2].SizeInBytes());
558   EXPECT_TRUE(segs[3].IsPadding());
559   EXPECT_EQ(4u, segs[3].SizeInBytes());
560 }
TEST_F(FormatTest,SegmentStructWithMemberOffset_Std430)561 TEST_F(FormatTest, SegmentStructWithMemberOffset_Std430) {
562   auto s = MakeUnique<type::Struct>();
563   auto f32 = type::Number::Float(32);
564   auto u32 = type::Number::Uint(32);
565 
566   auto m = s->AddMember(f32.get());
567   m->offset_in_bytes = 4;
568 
569   s->AddMember(u32.get());
570 
571   Format fmt(s.get());
572   fmt.SetLayout(Format::Layout::kStd430);
573   EXPECT_EQ(12, fmt.SizeInBytes());
574 
575   const auto& segs = fmt.GetSegments();
576   ASSERT_EQ(3U, segs.size());
577   EXPECT_TRUE(segs[0].IsPadding());
578   EXPECT_EQ(4u, segs[0].SizeInBytes());
579   EXPECT_EQ(FormatMode::kSFloat, segs[1].GetFormatMode());
580   EXPECT_EQ(4u, segs[1].SizeInBytes());
581   EXPECT_EQ(FormatMode::kUInt, segs[2].GetFormatMode());
582   EXPECT_EQ(4u, segs[2].SizeInBytes());
583 }
584 
585 // struct {
586 //   struct {
587 //     int32 a;
588 //     float b;
589 //   } x;
590 //   float y;
591 // }
TEST_F(FormatTest,SegmentStructWithStruct_Std140)592 TEST_F(FormatTest, SegmentStructWithStruct_Std140) {
593   auto x = MakeUnique<type::Struct>();
594   auto f32 = type::Number::Float(32);
595   auto i32 = type::Number::Int(32);
596   x->AddMember(i32.get());
597   x->AddMember(f32.get());
598 
599   auto s = MakeUnique<type::Struct>();
600   s->AddMember(x.get());
601   s->AddMember(f32.get());
602 
603   Format fmt(s.get());
604   fmt.SetLayout(Format::Layout::kStd140);
605   EXPECT_EQ(32u, fmt.SizeInBytes());
606 
607   const auto& segs = fmt.GetSegments();
608   ASSERT_EQ(5U, segs.size());
609   EXPECT_EQ(FormatMode::kSInt, segs[0].GetFormatMode());
610   EXPECT_EQ(4u, segs[0].SizeInBytes());
611   EXPECT_EQ(FormatMode::kSFloat, segs[1].GetFormatMode());
612   EXPECT_EQ(4u, segs[1].SizeInBytes());
613   EXPECT_TRUE(segs[2].IsPadding());
614   EXPECT_EQ(8u, segs[2].SizeInBytes());
615   EXPECT_EQ(FormatMode::kSFloat, segs[3].GetFormatMode());
616   EXPECT_EQ(4u, segs[3].SizeInBytes());
617   EXPECT_TRUE(segs[4].IsPadding());
618   EXPECT_EQ(12u, segs[4].SizeInBytes());
619 }
TEST_F(FormatTest,SegmentStructWithStruct_Std430)620 TEST_F(FormatTest, SegmentStructWithStruct_Std430) {
621   auto x = MakeUnique<type::Struct>();
622   auto f32 = type::Number::Float(32);
623   auto i32 = type::Number::Int(32);
624   x->AddMember(i32.get());
625   x->AddMember(f32.get());
626 
627   auto s = MakeUnique<type::Struct>();
628   s->AddMember(x.get());
629   s->AddMember(f32.get());
630 
631   Format fmt(s.get());
632   fmt.SetLayout(Format::Layout::kStd430);
633   EXPECT_EQ(12u, fmt.SizeInBytes());
634 
635   const auto& segs = fmt.GetSegments();
636   ASSERT_EQ(3U, segs.size());
637   EXPECT_EQ(FormatMode::kSInt, segs[0].GetFormatMode());
638   EXPECT_EQ(4u, segs[0].SizeInBytes());
639   EXPECT_EQ(FormatMode::kSFloat, segs[1].GetFormatMode());
640   EXPECT_EQ(4u, segs[1].SizeInBytes());
641   EXPECT_EQ(FormatMode::kSFloat, segs[2].GetFormatMode());
642   EXPECT_EQ(4u, segs[2].SizeInBytes());
643 }
644 
645 // struct {
646 //   int32 w;
647 //   vec2<float> x;
648 //   float y;
649 // }
TEST_F(FormatTest,SegmentStructWithVec2_Std140)650 TEST_F(FormatTest, SegmentStructWithVec2_Std140) {
651   auto s = MakeUnique<type::Struct>();
652   auto f32 = type::Number::Float(32);
653   auto i32 = type::Number::Int(32);
654   auto vec2 = type::Number::Float(32);
655   vec2->SetRowCount(2);
656 
657   s->AddMember(i32.get());
658   s->AddMember(vec2.get());
659   s->AddMember(f32.get());
660 
661   Format fmt(s.get());
662   fmt.SetLayout(Format::Layout::kStd140);
663   EXPECT_EQ(32u, fmt.SizeInBytes());
664 
665   const auto& segs = fmt.GetSegments();
666   ASSERT_EQ(6U, segs.size());
667   /* w */
668   EXPECT_EQ(FormatMode::kSInt, segs[0].GetFormatMode());
669   EXPECT_EQ(4u, segs[0].SizeInBytes());
670   /* pad */
671   EXPECT_TRUE(segs[1].IsPadding());
672   EXPECT_EQ(4u, segs[1].SizeInBytes());
673   /* vec2 */
674   EXPECT_EQ(FormatMode::kSFloat, segs[2].GetFormatMode());
675   EXPECT_EQ(4u, segs[2].SizeInBytes());
676   EXPECT_EQ(FormatMode::kSFloat, segs[3].GetFormatMode());
677   EXPECT_EQ(4u, segs[3].SizeInBytes());
678   /* y */
679   EXPECT_EQ(FormatMode::kSFloat, segs[4].GetFormatMode());
680   EXPECT_EQ(4u, segs[4].SizeInBytes());
681   /* pad */
682   EXPECT_TRUE(segs[5].IsPadding());
683   EXPECT_EQ(12u, segs[5].SizeInBytes());
684 }
TEST_F(FormatTest,SegmentStructWithVec2_Std430)685 TEST_F(FormatTest, SegmentStructWithVec2_Std430) {
686   auto s = MakeUnique<type::Struct>();
687   auto f32 = type::Number::Float(32);
688   auto i32 = type::Number::Int(32);
689   auto vec2 = type::Number::Float(32);
690   vec2->SetRowCount(2);
691 
692   s->AddMember(i32.get());
693   s->AddMember(vec2.get());
694   s->AddMember(f32.get());
695 
696   Format fmt(s.get());
697   fmt.SetLayout(Format::Layout::kStd430);
698   EXPECT_EQ(24u, fmt.SizeInBytes());
699 
700   const auto& segs = fmt.GetSegments();
701   ASSERT_EQ(6U, segs.size());
702   /* w */
703   EXPECT_EQ(FormatMode::kSInt, segs[0].GetFormatMode());
704   EXPECT_EQ(4u, segs[0].SizeInBytes());
705   /* pad */
706   EXPECT_TRUE(segs[1].IsPadding());
707   EXPECT_EQ(4u, segs[1].SizeInBytes());
708   /* vec2 */
709   EXPECT_EQ(FormatMode::kSFloat, segs[2].GetFormatMode());
710   EXPECT_EQ(4u, segs[2].SizeInBytes());
711   EXPECT_EQ(FormatMode::kSFloat, segs[3].GetFormatMode());
712   EXPECT_EQ(4u, segs[3].SizeInBytes());
713   /* y */
714   EXPECT_EQ(FormatMode::kSFloat, segs[4].GetFormatMode());
715   EXPECT_EQ(4u, segs[4].SizeInBytes());
716   /* pad */
717   EXPECT_TRUE(segs[5].IsPadding());
718   EXPECT_EQ(4u, segs[5].SizeInBytes());
719 }
720 
721 // struct {
722 //   int32 w;
723 //   vec3<float> x;
724 //   float y;
725 // }
TEST_F(FormatTest,SegmentStructWithFloatPackedToVec_Std140)726 TEST_F(FormatTest, SegmentStructWithFloatPackedToVec_Std140) {
727   auto s = MakeUnique<type::Struct>();
728   auto f32 = type::Number::Float(32);
729   auto i32 = type::Number::Int(32);
730   auto vec3 = type::Number::Float(32);
731   vec3->SetRowCount(3);
732 
733   s->AddMember(i32.get());
734   s->AddMember(vec3.get());
735   s->AddMember(f32.get());
736 
737   Format fmt(s.get());
738   fmt.SetLayout(Format::Layout::kStd140);
739   EXPECT_EQ(32u, fmt.SizeInBytes());
740 
741   const auto& segs = fmt.GetSegments();
742   ASSERT_EQ(6U, segs.size());
743   /* w */
744   EXPECT_EQ(FormatMode::kSInt, segs[0].GetFormatMode());
745   EXPECT_EQ(4u, segs[0].SizeInBytes());
746   /* pad */
747   EXPECT_TRUE(segs[1].IsPadding());
748   EXPECT_EQ(12u, segs[1].SizeInBytes());
749   /* vec2 */
750   EXPECT_EQ(FormatMode::kSFloat, segs[2].GetFormatMode());
751   EXPECT_EQ(4u, segs[2].SizeInBytes());
752   EXPECT_EQ(FormatMode::kSFloat, segs[3].GetFormatMode());
753   EXPECT_EQ(4u, segs[3].SizeInBytes());
754   EXPECT_EQ(FormatMode::kSFloat, segs[4].GetFormatMode());
755   EXPECT_EQ(4u, segs[4].SizeInBytes());
756   /* y */
757   EXPECT_EQ(FormatMode::kSFloat, segs[5].GetFormatMode());
758   EXPECT_EQ(4u, segs[5].SizeInBytes());
759 }
TEST_F(FormatTest,SegmentStructWithFloatPackedToVec_Std430)760 TEST_F(FormatTest, SegmentStructWithFloatPackedToVec_Std430) {
761   auto s = MakeUnique<type::Struct>();
762   auto f32 = type::Number::Float(32);
763   auto i32 = type::Number::Int(32);
764   auto vec3 = type::Number::Float(32);
765   vec3->SetRowCount(3);
766 
767   s->AddMember(i32.get());
768   s->AddMember(vec3.get());
769   s->AddMember(f32.get());
770 
771   Format fmt(s.get());
772   fmt.SetLayout(Format::Layout::kStd430);
773   EXPECT_EQ(32u, fmt.SizeInBytes());
774 
775   const auto& segs = fmt.GetSegments();
776   ASSERT_EQ(6U, segs.size());
777   /* w */
778   EXPECT_EQ(FormatMode::kSInt, segs[0].GetFormatMode());
779   EXPECT_EQ(4u, segs[0].SizeInBytes());
780   /* pad */
781   EXPECT_TRUE(segs[1].IsPadding());
782   EXPECT_EQ(12u, segs[1].SizeInBytes());
783   /* vec2 */
784   EXPECT_EQ(FormatMode::kSFloat, segs[2].GetFormatMode());
785   EXPECT_EQ(4u, segs[2].SizeInBytes());
786   EXPECT_EQ(FormatMode::kSFloat, segs[3].GetFormatMode());
787   EXPECT_EQ(4u, segs[3].SizeInBytes());
788   EXPECT_EQ(FormatMode::kSFloat, segs[4].GetFormatMode());
789   EXPECT_EQ(4u, segs[4].SizeInBytes());
790   /* y */
791   EXPECT_EQ(FormatMode::kSFloat, segs[5].GetFormatMode());
792   EXPECT_EQ(4u, segs[5].SizeInBytes());
793 }
794 
795 // struct {
796 //   int32 w;
797 //   vec3<float> x;
798 //   vec2<float> y;
799 // }
TEST_F(FormatTest,SegmentStructVec3Vec2_Std140)800 TEST_F(FormatTest, SegmentStructVec3Vec2_Std140) {
801   auto s = MakeUnique<type::Struct>();
802   auto i32 = type::Number::Int(32);
803   auto vec3 = type::Number::Float(32);
804   vec3->SetRowCount(3);
805   auto vec2 = type::Number::Float(32);
806   vec2->SetRowCount(2);
807 
808   s->AddMember(i32.get());
809   s->AddMember(vec3.get());
810   s->AddMember(vec2.get());
811 
812   Format fmt(s.get());
813   fmt.SetLayout(Format::Layout::kStd140);
814   EXPECT_EQ(48u, fmt.SizeInBytes());
815 
816   const auto& segs = fmt.GetSegments();
817   ASSERT_EQ(9U, segs.size());
818   /* w */
819   EXPECT_EQ(FormatMode::kSInt, segs[0].GetFormatMode());
820   EXPECT_EQ(4u, segs[0].SizeInBytes());
821   /* pad */
822   EXPECT_TRUE(segs[1].IsPadding());
823   EXPECT_EQ(12u, segs[1].SizeInBytes());
824   /* vec3 */
825   EXPECT_EQ(FormatMode::kSFloat, segs[2].GetFormatMode());
826   EXPECT_EQ(4u, segs[2].SizeInBytes());
827   EXPECT_EQ(FormatMode::kSFloat, segs[3].GetFormatMode());
828   EXPECT_EQ(4u, segs[3].SizeInBytes());
829   EXPECT_EQ(FormatMode::kSFloat, segs[4].GetFormatMode());
830   EXPECT_EQ(4u, segs[4].SizeInBytes());
831   /* pad */
832   EXPECT_TRUE(segs[5].IsPadding());
833   EXPECT_EQ(4u, segs[5].SizeInBytes());
834   /* vec2 */
835   EXPECT_EQ(FormatMode::kSFloat, segs[6].GetFormatMode());
836   EXPECT_EQ(4u, segs[6].SizeInBytes());
837   EXPECT_EQ(FormatMode::kSFloat, segs[7].GetFormatMode());
838   EXPECT_EQ(4u, segs[7].SizeInBytes());
839   /* pad */
840   EXPECT_TRUE(segs[8].IsPadding());
841   EXPECT_EQ(8u, segs[8].SizeInBytes());
842 }
TEST_F(FormatTest,SegmentStructVec3Vec2_Std430)843 TEST_F(FormatTest, SegmentStructVec3Vec2_Std430) {
844   auto s = MakeUnique<type::Struct>();
845   auto i32 = type::Number::Int(32);
846   auto vec3 = type::Number::Float(32);
847   vec3->SetRowCount(3);
848   auto vec2 = type::Number::Float(32);
849   vec2->SetRowCount(2);
850 
851   s->AddMember(i32.get());
852   s->AddMember(vec3.get());
853   s->AddMember(vec2.get());
854 
855   Format fmt(s.get());
856   fmt.SetLayout(Format::Layout::kStd430);
857   EXPECT_EQ(48u, fmt.SizeInBytes());
858 
859   const auto& segs = fmt.GetSegments();
860   ASSERT_EQ(9U, segs.size());
861   /* w */
862   EXPECT_EQ(FormatMode::kSInt, segs[0].GetFormatMode());
863   EXPECT_EQ(4u, segs[0].SizeInBytes());
864   /* pad */
865   EXPECT_TRUE(segs[1].IsPadding());
866   EXPECT_EQ(12u, segs[1].SizeInBytes());
867   /* vec3 */
868   EXPECT_EQ(FormatMode::kSFloat, segs[2].GetFormatMode());
869   EXPECT_EQ(4u, segs[2].SizeInBytes());
870   EXPECT_EQ(FormatMode::kSFloat, segs[3].GetFormatMode());
871   EXPECT_EQ(4u, segs[3].SizeInBytes());
872   EXPECT_EQ(FormatMode::kSFloat, segs[4].GetFormatMode());
873   EXPECT_EQ(4u, segs[4].SizeInBytes());
874   /* pad */
875   EXPECT_TRUE(segs[5].IsPadding());
876   EXPECT_EQ(4u, segs[5].SizeInBytes());
877   /* vec2 */
878   EXPECT_EQ(FormatMode::kSFloat, segs[6].GetFormatMode());
879   EXPECT_EQ(4u, segs[6].SizeInBytes());
880   EXPECT_EQ(FormatMode::kSFloat, segs[7].GetFormatMode());
881   EXPECT_EQ(4u, segs[7].SizeInBytes());
882   /* pad */
883   EXPECT_TRUE(segs[8].IsPadding());
884   EXPECT_EQ(8u, segs[8].SizeInBytes());
885 }
886 
887 // struct {
888 //   int32 w;
889 //   mat2x2<float> x;
890 //   float y;
891 // }
TEST_F(FormatTest,SegmentStructMat2x2_Std140)892 TEST_F(FormatTest, SegmentStructMat2x2_Std140) {
893   auto s = MakeUnique<type::Struct>();
894   auto f32 = type::Number::Float(32);
895   auto i32 = type::Number::Int(32);
896   auto mat2x2 = type::Number::Float(32);
897   mat2x2->SetRowCount(2);
898   mat2x2->SetColumnCount(2);
899 
900   s->AddMember(i32.get());
901   s->AddMember(mat2x2.get());
902   s->AddMember(f32.get());
903 
904   Format fmt(s.get());
905   fmt.SetLayout(Format::Layout::kStd140);
906   EXPECT_EQ(64u, fmt.SizeInBytes());
907 
908   const auto& segs = fmt.GetSegments();
909   ASSERT_EQ(10U, segs.size());
910   /* w */
911   EXPECT_EQ(FormatMode::kSInt, segs[0].GetFormatMode());
912   EXPECT_EQ(4u, segs[0].SizeInBytes());
913   /* pad */
914   EXPECT_TRUE(segs[1].IsPadding());
915   EXPECT_EQ(12u, segs[1].SizeInBytes());
916   /* column 1 */
917   EXPECT_EQ(FormatMode::kSFloat, segs[2].GetFormatMode());
918   EXPECT_EQ(4u, segs[2].SizeInBytes());
919   EXPECT_EQ(FormatMode::kSFloat, segs[3].GetFormatMode());
920   EXPECT_EQ(4u, segs[3].SizeInBytes());
921   EXPECT_TRUE(segs[4].IsPadding());
922   EXPECT_EQ(8u, segs[4].SizeInBytes());
923   /* column 2 */
924   EXPECT_EQ(FormatMode::kSFloat, segs[5].GetFormatMode());
925   EXPECT_EQ(4u, segs[5].SizeInBytes());
926   EXPECT_EQ(FormatMode::kSFloat, segs[6].GetFormatMode());
927   EXPECT_EQ(4u, segs[6].SizeInBytes());
928   EXPECT_TRUE(segs[7].IsPadding());
929   EXPECT_EQ(8u, segs[7].SizeInBytes());
930   /* y */
931   EXPECT_EQ(FormatMode::kSFloat, segs[8].GetFormatMode());
932   EXPECT_EQ(4u, segs[8].SizeInBytes());
933   /* pad */
934   EXPECT_TRUE(segs[9].IsPadding());
935   EXPECT_EQ(12u, segs[9].SizeInBytes());
936 }
TEST_F(FormatTest,SegmentStructMat2x2_Std430)937 TEST_F(FormatTest, SegmentStructMat2x2_Std430) {
938   auto s = MakeUnique<type::Struct>();
939   auto f32 = type::Number::Float(32);
940   auto i32 = type::Number::Int(32);
941   auto mat2x2 = type::Number::Float(32);
942   mat2x2->SetRowCount(2);
943   mat2x2->SetColumnCount(2);
944 
945   s->AddMember(i32.get());
946   s->AddMember(mat2x2.get());
947   s->AddMember(f32.get());
948 
949   Format fmt(s.get());
950   fmt.SetLayout(Format::Layout::kStd430);
951   EXPECT_EQ(32u, fmt.SizeInBytes());
952 
953   const auto& segs = fmt.GetSegments();
954   ASSERT_EQ(8U, segs.size());
955   /* w */
956   EXPECT_EQ(FormatMode::kSInt, segs[0].GetFormatMode());
957   EXPECT_EQ(4u, segs[0].SizeInBytes());
958   /* pad */
959   EXPECT_TRUE(segs[1].IsPadding());
960   EXPECT_EQ(4u, segs[1].SizeInBytes());
961   /* column 1 */
962   EXPECT_EQ(FormatMode::kSFloat, segs[2].GetFormatMode());
963   EXPECT_EQ(4u, segs[2].SizeInBytes());
964   EXPECT_EQ(FormatMode::kSFloat, segs[3].GetFormatMode());
965   EXPECT_EQ(4u, segs[3].SizeInBytes());
966   /* column 2 */
967   EXPECT_EQ(FormatMode::kSFloat, segs[4].GetFormatMode());
968   EXPECT_EQ(4u, segs[4].SizeInBytes());
969   EXPECT_EQ(FormatMode::kSFloat, segs[5].GetFormatMode());
970   EXPECT_EQ(4u, segs[5].SizeInBytes());
971   /* y */
972   EXPECT_EQ(FormatMode::kSFloat, segs[6].GetFormatMode());
973   EXPECT_EQ(4u, segs[6].SizeInBytes());
974   /* pad */
975   EXPECT_TRUE(segs[7].IsPadding());
976   EXPECT_EQ(4u, segs[7].SizeInBytes());
977 }
978 
979 // struct {
980 //   int32 w;
981 //   struct {
982 //     int32 a;
983 //     int32 b;
984 //     float c;
985 //   } x;
986 //   float y;
987 // }
TEST_F(FormatTest,SegmentStructWithStructNoPack_Std140)988 TEST_F(FormatTest, SegmentStructWithStructNoPack_Std140) {
989   auto s = MakeUnique<type::Struct>();
990   auto f32 = type::Number::Float(32);
991   auto i32 = type::Number::Int(32);
992   auto x = MakeUnique<type::Struct>();
993   x->AddMember(i32.get());
994   x->AddMember(i32.get());
995   x->AddMember(f32.get());
996 
997   s->AddMember(i32.get());
998   s->AddMember(x.get());
999   s->AddMember(f32.get());
1000 
1001   Format fmt(s.get());
1002   fmt.SetLayout(Format::Layout::kStd140);
1003   EXPECT_EQ(48u, fmt.SizeInBytes());
1004 
1005   const auto& segs = fmt.GetSegments();
1006   ASSERT_EQ(8U, segs.size());
1007   /* w */
1008   EXPECT_EQ(FormatMode::kSInt, segs[0].GetFormatMode());
1009   EXPECT_EQ(4u, segs[0].SizeInBytes());
1010   /* pad */
1011   EXPECT_TRUE(segs[1].IsPadding());
1012   EXPECT_EQ(12u, segs[1].SizeInBytes());
1013   /* a */
1014   EXPECT_EQ(FormatMode::kSInt, segs[2].GetFormatMode());
1015   EXPECT_EQ(4u, segs[2].SizeInBytes());
1016   /* b */
1017   EXPECT_EQ(FormatMode::kSInt, segs[3].GetFormatMode());
1018   EXPECT_EQ(4u, segs[3].SizeInBytes());
1019   /* c */
1020   EXPECT_EQ(FormatMode::kSFloat, segs[4].GetFormatMode());
1021   EXPECT_EQ(4u, segs[4].SizeInBytes());
1022   /* pad */
1023   EXPECT_TRUE(segs[5].IsPadding());
1024   EXPECT_EQ(4u, segs[5].SizeInBytes());
1025   /* y */
1026   EXPECT_EQ(FormatMode::kSFloat, segs[6].GetFormatMode());
1027   EXPECT_EQ(4u, segs[6].SizeInBytes());
1028   /* pad */
1029   EXPECT_TRUE(segs[7].IsPadding());
1030   EXPECT_EQ(12u, segs[7].SizeInBytes());
1031 }
TEST_F(FormatTest,SegmentStructWithStructNoPack_Std430)1032 TEST_F(FormatTest, SegmentStructWithStructNoPack_Std430) {
1033   auto s = MakeUnique<type::Struct>();
1034   auto f32 = type::Number::Float(32);
1035   auto i32 = type::Number::Int(32);
1036   auto x = MakeUnique<type::Struct>();
1037   x->AddMember(i32.get());
1038   x->AddMember(i32.get());
1039   x->AddMember(f32.get());
1040 
1041   s->AddMember(i32.get());
1042   s->AddMember(x.get());
1043   s->AddMember(f32.get());
1044 
1045   Format fmt(s.get());
1046   fmt.SetLayout(Format::Layout::kStd430);
1047   EXPECT_EQ(20u, fmt.SizeInBytes());
1048 
1049   const auto& segs = fmt.GetSegments();
1050   ASSERT_EQ(5U, segs.size());
1051   /* w */
1052   EXPECT_EQ(FormatMode::kSInt, segs[0].GetFormatMode());
1053   EXPECT_EQ(4u, segs[0].SizeInBytes());
1054   /* a */
1055   EXPECT_EQ(FormatMode::kSInt, segs[1].GetFormatMode());
1056   EXPECT_EQ(4u, segs[1].SizeInBytes());
1057   /* b */
1058   EXPECT_EQ(FormatMode::kSInt, segs[2].GetFormatMode());
1059   EXPECT_EQ(4u, segs[2].SizeInBytes());
1060   /* c */
1061   EXPECT_EQ(FormatMode::kSFloat, segs[3].GetFormatMode());
1062   EXPECT_EQ(4u, segs[3].SizeInBytes());
1063   /* y */
1064   EXPECT_EQ(FormatMode::kSFloat, segs[4].GetFormatMode());
1065   EXPECT_EQ(4u, segs[4].SizeInBytes());
1066 }
1067 
1068 // struct {
1069 //   int32 w;
1070 //   struct {
1071 //     int32 a;
1072 //     int32 b;
1073 //     float c[3];
1074 //   } x;
1075 //   float y;
1076 // }
TEST_F(FormatTest,SegmentStructWithStructArray_Std140)1077 TEST_F(FormatTest, SegmentStructWithStructArray_Std140) {
1078   auto s = MakeUnique<type::Struct>();
1079   auto f32 = type::Number::Float(32);
1080   auto i32 = type::Number::Int(32);
1081   auto f32_ary = type::Number::Float(32);
1082   f32_ary->SetIsSizedArray(3);
1083 
1084   auto x = MakeUnique<type::Struct>();
1085   x->AddMember(i32.get());
1086   x->AddMember(i32.get());
1087   x->AddMember(f32_ary.get());
1088 
1089   s->AddMember(i32.get());
1090   s->AddMember(x.get());
1091   s->AddMember(f32.get());
1092 
1093   Format fmt(s.get());
1094   fmt.SetLayout(Format::Layout::kStd140);
1095   EXPECT_EQ(96u, fmt.SizeInBytes());
1096 
1097   const auto& segs = fmt.GetSegments();
1098   ASSERT_EQ(13U, segs.size());
1099   /* w */
1100   EXPECT_EQ(FormatMode::kSInt, segs[0].GetFormatMode());
1101   EXPECT_EQ(4u, segs[0].SizeInBytes());
1102   /* pad */
1103   EXPECT_TRUE(segs[1].IsPadding());
1104   EXPECT_EQ(12u, segs[1].SizeInBytes());
1105   /* a */
1106   EXPECT_EQ(FormatMode::kSInt, segs[2].GetFormatMode());
1107   EXPECT_EQ(4u, segs[2].SizeInBytes());
1108   /* b */
1109   EXPECT_EQ(FormatMode::kSInt, segs[3].GetFormatMode());
1110   EXPECT_EQ(4u, segs[3].SizeInBytes());
1111   /* pad */
1112   EXPECT_TRUE(segs[4].IsPadding());
1113   EXPECT_EQ(8u, segs[4].SizeInBytes());
1114   /* c[0] */
1115   EXPECT_EQ(FormatMode::kSFloat, segs[5].GetFormatMode());
1116   EXPECT_EQ(4u, segs[5].SizeInBytes());
1117   /* pad */
1118   EXPECT_TRUE(segs[6].IsPadding());
1119   EXPECT_EQ(12u, segs[6].SizeInBytes());
1120   /* c[1] */
1121   EXPECT_EQ(FormatMode::kSFloat, segs[7].GetFormatMode());
1122   EXPECT_EQ(4u, segs[7].SizeInBytes());
1123   /* pad */
1124   EXPECT_TRUE(segs[8].IsPadding());
1125   EXPECT_EQ(12u, segs[8].SizeInBytes());
1126   /* c[2] */
1127   EXPECT_EQ(FormatMode::kSFloat, segs[9].GetFormatMode());
1128   EXPECT_EQ(4u, segs[9].SizeInBytes());
1129   /* pad */
1130   EXPECT_TRUE(segs[10].IsPadding());
1131   EXPECT_EQ(12u, segs[10].SizeInBytes());
1132   /* y */
1133   EXPECT_EQ(FormatMode::kSFloat, segs[11].GetFormatMode());
1134   EXPECT_EQ(4u, segs[11].SizeInBytes());
1135   /* pad */
1136   EXPECT_TRUE(segs[12].IsPadding());
1137   EXPECT_EQ(12u, segs[12].SizeInBytes());
1138 }
TEST_F(FormatTest,SegmentStructWithStructArray_Std430)1139 TEST_F(FormatTest, SegmentStructWithStructArray_Std430) {
1140   auto s = MakeUnique<type::Struct>();
1141   auto f32 = type::Number::Float(32);
1142   auto i32 = type::Number::Int(32);
1143   auto f32_ary = type::Number::Float(32);
1144   f32_ary->SetIsSizedArray(3);
1145   auto x = MakeUnique<type::Struct>();
1146   x->AddMember(i32.get());
1147   x->AddMember(i32.get());
1148   x->AddMember(f32_ary.get());
1149 
1150   s->AddMember(i32.get());
1151   s->AddMember(x.get());
1152   s->AddMember(f32.get());
1153 
1154   Format fmt(s.get());
1155   fmt.SetLayout(Format::Layout::kStd430);
1156   EXPECT_EQ(28u, fmt.SizeInBytes());
1157 
1158   const auto& segs = fmt.GetSegments();
1159   ASSERT_EQ(7U, segs.size());
1160   /* w */
1161   EXPECT_EQ(FormatMode::kSInt, segs[0].GetFormatMode());
1162   EXPECT_EQ(4u, segs[0].SizeInBytes());
1163   /* a */
1164   EXPECT_EQ(FormatMode::kSInt, segs[1].GetFormatMode());
1165   EXPECT_EQ(4u, segs[1].SizeInBytes());
1166   /* b */
1167   EXPECT_EQ(FormatMode::kSInt, segs[2].GetFormatMode());
1168   EXPECT_EQ(4u, segs[2].SizeInBytes());
1169   /* c[0] */
1170   EXPECT_EQ(FormatMode::kSFloat, segs[3].GetFormatMode());
1171   EXPECT_EQ(4u, segs[3].SizeInBytes());
1172   /* c[1] */
1173   EXPECT_EQ(FormatMode::kSFloat, segs[4].GetFormatMode());
1174   EXPECT_EQ(4u, segs[4].SizeInBytes());
1175   /* c[2] */
1176   EXPECT_EQ(FormatMode::kSFloat, segs[5].GetFormatMode());
1177   EXPECT_EQ(4u, segs[5].SizeInBytes());
1178   /* y */
1179   EXPECT_EQ(FormatMode::kSFloat, segs[6].GetFormatMode());
1180   EXPECT_EQ(4u, segs[6].SizeInBytes());
1181 }
1182 
1183 }  // namespace amber
1184