• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "include/private/SkSLModifiers.h"
9 #include "include/sksl/SkSLErrorReporter.h"
10 #include "include/sksl/SkSLPosition.h"
11 #include "src/sksl/SkSLBuiltinTypes.h"
12 #include "src/sksl/SkSLContext.h"
13 #include "src/sksl/SkSLMemoryLayout.h"
14 #include "src/sksl/SkSLUtil.h"
15 #include "src/sksl/ir/SkSLType.h"
16 #include "tests/Test.h"
17 
18 #include <memory>
19 #include <string>
20 #include <string_view>
21 #include <utility>
22 #include <vector>
23 
DEF_TEST(SkSLMemoryLayout140Test,r)24 DEF_TEST(SkSLMemoryLayout140Test, r) {
25     SkSL::TestingOnly_AbortErrorReporter errors;
26     SkSL::ShaderCaps caps;
27     SkSL::BuiltinTypes types;
28     SkSL::Context context(types, &caps, errors);
29     SkSL::MemoryLayout layout(SkSL::MemoryLayout::Standard::k140);
30 
31     // basic types
32     REPORTER_ASSERT(r,  4 == layout.size(*context.fTypes.fFloat));
33     REPORTER_ASSERT(r,  8 == layout.size(*context.fTypes.fFloat2));
34     REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fFloat3));
35     REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fFloat4));
36     REPORTER_ASSERT(r,  4 == layout.size(*context.fTypes.fInt));
37     REPORTER_ASSERT(r,  8 == layout.size(*context.fTypes.fInt2));
38     REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fInt3));
39     REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fInt4));
40     REPORTER_ASSERT(r,  1 == layout.size(*context.fTypes.fBool));
41     REPORTER_ASSERT(r,  2 == layout.size(*context.fTypes.fBool2));
42     REPORTER_ASSERT(r,  3 == layout.size(*context.fTypes.fBool3));
43     REPORTER_ASSERT(r,  4 == layout.size(*context.fTypes.fBool4));
44     REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fFloat2x2));
45     REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fFloat2x4));
46     REPORTER_ASSERT(r, 48 == layout.size(*context.fTypes.fFloat3x3));
47     REPORTER_ASSERT(r, 64 == layout.size(*context.fTypes.fFloat4x2));
48     REPORTER_ASSERT(r, 64 == layout.size(*context.fTypes.fFloat4x4));
49     REPORTER_ASSERT(r,  4 == layout.size(*context.fTypes.fAtomicUInt));
50     REPORTER_ASSERT(r,  4 == layout.alignment(*context.fTypes.fFloat));
51     REPORTER_ASSERT(r,  8 == layout.alignment(*context.fTypes.fFloat2));
52     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat3));
53     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat4));
54     REPORTER_ASSERT(r,  4 == layout.alignment(*context.fTypes.fInt));
55     REPORTER_ASSERT(r,  8 == layout.alignment(*context.fTypes.fInt2));
56     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fInt3));
57     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fInt4));
58     REPORTER_ASSERT(r,  1 == layout.alignment(*context.fTypes.fBool));
59     REPORTER_ASSERT(r,  2 == layout.alignment(*context.fTypes.fBool2));
60     REPORTER_ASSERT(r,  4 == layout.alignment(*context.fTypes.fBool3));
61     REPORTER_ASSERT(r,  4 == layout.alignment(*context.fTypes.fBool4));
62     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat2x2));
63     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat2x4));
64     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat3x3));
65     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat4x2));
66     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat4x4));
67     REPORTER_ASSERT(r,  4 == layout.alignment(*context.fTypes.fAtomicUInt));
68 
69     // struct 1
70     std::vector<SkSL::Type::Field> fields1;
71     fields1.emplace_back(SkSL::Position(), SkSL::Modifiers(), std::string_view("a"),
72             context.fTypes.fFloat3.get());
73     std::unique_ptr<SkSL::Type> s1 =
74             SkSL::Type::MakeStructType(context, SkSL::Position(), std::string("s1"), fields1);
75     REPORTER_ASSERT(r, 16 == layout.size(*s1));
76     REPORTER_ASSERT(r, 16 == layout.alignment(*s1));
77 
78     fields1.emplace_back(SkSL::Position(), SkSL::Modifiers(), std::string_view("b"),
79             context.fTypes.fFloat.get());
80     std::unique_ptr<SkSL::Type> s2 =
81             SkSL::Type::MakeStructType(context, SkSL::Position(), std::string("s2"), fields1);
82     REPORTER_ASSERT(r, 16 == layout.size(*s2));
83     REPORTER_ASSERT(r, 16 == layout.alignment(*s2));
84 
85     fields1.emplace_back(SkSL::Position(), SkSL::Modifiers(), std::string_view("c"),
86             context.fTypes.fBool.get());
87     std::unique_ptr<SkSL::Type> s3 =
88             SkSL::Type::MakeStructType(context, SkSL::Position(), std::string("s3"), fields1);
89     REPORTER_ASSERT(r, 32 == layout.size(*s3));
90     REPORTER_ASSERT(r, 16 == layout.alignment(*s3));
91 
92     // struct 2
93     std::vector<SkSL::Type::Field> fields2;
94     fields2.emplace_back(SkSL::Position(), SkSL::Modifiers(), std::string_view("a"),
95             context.fTypes.fInt.get());
96     std::unique_ptr<SkSL::Type> s4 =
97             SkSL::Type::MakeStructType(context, SkSL::Position(), std::string("s4"), fields2);
98     REPORTER_ASSERT(r, 16 == layout.size(*s4));
99     REPORTER_ASSERT(r, 16 == layout.alignment(*s4));
100 
101     fields2.emplace_back(SkSL::Position(), SkSL::Modifiers(), std::string_view("b"),
102             context.fTypes.fFloat3.get());
103     std::unique_ptr<SkSL::Type> s5 =
104             SkSL::Type::MakeStructType(context, SkSL::Position(), std::string("s5"), fields2);
105     REPORTER_ASSERT(r, 32 == layout.size(*s5));
106     REPORTER_ASSERT(r, 16 == layout.alignment(*s5));
107 
108     // arrays
109     std::unique_ptr<SkSL::Type> array1 =
110             SkSL::Type::MakeArrayType(std::string("float[4]"), *context.fTypes.fFloat, 4);
111     REPORTER_ASSERT(r, 64 == layout.size(*array1));
112     REPORTER_ASSERT(r, 16 == layout.alignment(*array1));
113     REPORTER_ASSERT(r, 16 == layout.stride(*array1));
114 
115     std::unique_ptr<SkSL::Type> array2 =
116             SkSL::Type::MakeArrayType(std::string("float4[4]"), *context.fTypes.fFloat4, 4);
117     REPORTER_ASSERT(r, 64 == layout.size(*array2));
118     REPORTER_ASSERT(r, 16 == layout.alignment(*array2));
119     REPORTER_ASSERT(r, 16 == layout.stride(*array2));
120 }
121 
DEF_TEST(SkSLMemoryLayout430Test,r)122 DEF_TEST(SkSLMemoryLayout430Test, r) {
123     SkSL::TestingOnly_AbortErrorReporter errors;
124     SkSL::ShaderCaps caps;
125     SkSL::BuiltinTypes types;
126     SkSL::Context context(types, &caps, errors);
127     SkSL::MemoryLayout layout(SkSL::MemoryLayout::Standard::k430);
128 
129     // basic types
130     REPORTER_ASSERT(r,  4 == layout.size(*context.fTypes.fFloat));
131     REPORTER_ASSERT(r,  8 == layout.size(*context.fTypes.fFloat2));
132     REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fFloat3));
133     REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fFloat4));
134     REPORTER_ASSERT(r,  4 == layout.size(*context.fTypes.fInt));
135     REPORTER_ASSERT(r,  8 == layout.size(*context.fTypes.fInt2));
136     REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fInt3));
137     REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fInt4));
138     REPORTER_ASSERT(r,  1 == layout.size(*context.fTypes.fBool));
139     REPORTER_ASSERT(r,  2 == layout.size(*context.fTypes.fBool2));
140     REPORTER_ASSERT(r,  3 == layout.size(*context.fTypes.fBool3));
141     REPORTER_ASSERT(r,  4 == layout.size(*context.fTypes.fBool4));
142     REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fFloat2x2));
143     REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fFloat2x4));
144     REPORTER_ASSERT(r, 48 == layout.size(*context.fTypes.fFloat3x3));
145     REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fFloat4x2));
146     REPORTER_ASSERT(r, 64 == layout.size(*context.fTypes.fFloat4x4));
147     REPORTER_ASSERT(r,  4 == layout.size(*context.fTypes.fAtomicUInt));
148     REPORTER_ASSERT(r,  4 == layout.alignment(*context.fTypes.fFloat));
149     REPORTER_ASSERT(r,  8 == layout.alignment(*context.fTypes.fFloat2));
150     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat3));
151     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat4));
152     REPORTER_ASSERT(r,  4 == layout.alignment(*context.fTypes.fInt));
153     REPORTER_ASSERT(r,  8 == layout.alignment(*context.fTypes.fInt2));
154     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fInt3));
155     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fInt4));
156     REPORTER_ASSERT(r,  1 == layout.alignment(*context.fTypes.fBool));
157     REPORTER_ASSERT(r,  2 == layout.alignment(*context.fTypes.fBool2));
158     REPORTER_ASSERT(r,  4 == layout.alignment(*context.fTypes.fBool3));
159     REPORTER_ASSERT(r,  4 == layout.alignment(*context.fTypes.fBool4));
160     REPORTER_ASSERT(r,  8 == layout.alignment(*context.fTypes.fFloat2x2));
161     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat2x4));
162     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat3x3));
163     REPORTER_ASSERT(r,  8 == layout.alignment(*context.fTypes.fFloat4x2));
164     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat4x4));
165     REPORTER_ASSERT(r,  4 == layout.alignment(*context.fTypes.fAtomicUInt));
166 
167     // struct 1
168     std::vector<SkSL::Type::Field> fields1;
169     fields1.emplace_back(SkSL::Position(), SkSL::Modifiers(), std::string_view("a"),
170                          context.fTypes.fFloat3.get());
171     std::unique_ptr<SkSL::Type> s1 =
172             SkSL::Type::MakeStructType(context, SkSL::Position(), std::string("s1"), fields1);
173     REPORTER_ASSERT(r, 16 == layout.size(*s1));
174     REPORTER_ASSERT(r, 16 == layout.alignment(*s1));
175 
176     fields1.emplace_back(SkSL::Position(), SkSL::Modifiers(), std::string_view("b"),
177             context.fTypes.fFloat.get());
178     std::unique_ptr<SkSL::Type> s2 =
179             SkSL::Type::MakeStructType(context, SkSL::Position(), std::string("s2"), fields1);
180     REPORTER_ASSERT(r, 16 == layout.size(*s2));
181     REPORTER_ASSERT(r, 16 == layout.alignment(*s2));
182 
183     fields1.emplace_back(SkSL::Position(), SkSL::Modifiers(), std::string_view("c"),
184             context.fTypes.fBool.get());
185     std::unique_ptr<SkSL::Type> s3 =
186             SkSL::Type::MakeStructType(context, SkSL::Position(), std::string("s3"), fields1);
187     REPORTER_ASSERT(r, 32 == layout.size(*s3));
188     REPORTER_ASSERT(r, 16 == layout.alignment(*s3));
189 
190     // struct 2
191     std::vector<SkSL::Type::Field> fields2;
192     fields2.emplace_back(SkSL::Position(), SkSL::Modifiers(), std::string_view("a"),
193             context.fTypes.fInt.get());
194     std::unique_ptr<SkSL::Type> s4 =
195             SkSL::Type::MakeStructType(context, SkSL::Position(), std::string("s4"), fields2);
196     REPORTER_ASSERT(r, 4 == layout.size(*s4));
197     REPORTER_ASSERT(r, 4 == layout.alignment(*s4));
198 
199     fields2.emplace_back(SkSL::Position(), SkSL::Modifiers(), std::string_view("b"),
200             context.fTypes.fFloat3.get());
201     std::unique_ptr<SkSL::Type> s5 =
202             SkSL::Type::MakeStructType(context, SkSL::Position(), std::string("s5"), fields2);
203     REPORTER_ASSERT(r, 32 == layout.size(*s5));
204     REPORTER_ASSERT(r, 16 == layout.alignment(*s5));
205 
206     // arrays
207     std::unique_ptr<SkSL::Type> array1 =
208             SkSL::Type::MakeArrayType(std::string("float[4]"), *context.fTypes.fFloat, 4);
209     REPORTER_ASSERT(r, 16 == layout.size(*array1));
210     REPORTER_ASSERT(r, 4 == layout.alignment(*array1));
211     REPORTER_ASSERT(r, 4 == layout.stride(*array1));
212 
213     std::unique_ptr<SkSL::Type> array2 =
214             SkSL::Type::MakeArrayType(std::string("float4[4]"), *context.fTypes.fFloat4, 4);
215     REPORTER_ASSERT(r, 64 == layout.size(*array2));
216     REPORTER_ASSERT(r, 16 == layout.alignment(*array2));
217     REPORTER_ASSERT(r, 16 == layout.stride(*array2));
218 }
219 
DEF_TEST(SkSLMemoryLayoutWGSLUniformTest,r)220 DEF_TEST(SkSLMemoryLayoutWGSLUniformTest, r) {
221     SkSL::TestingOnly_AbortErrorReporter errors;
222     SkSL::ShaderCaps caps;
223     SkSL::BuiltinTypes types;
224     SkSL::Context context(types, &caps, errors);
225     SkSL::MemoryLayout layout(SkSL::MemoryLayout::Standard::kWGSLUniform);
226 
227     // The values here are taken from https://www.w3.org/TR/WGSL/#alignment-and-size, table titled
228     // "Alignment and size for host-shareable types".
229 
230     // scalars (i32, u32, f32, f16)
231     REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fInt));
232     REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fUInt));
233     REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fFloat));
234     REPORTER_ASSERT(r, 2 == layout.size(*context.fTypes.fHalf));
235     REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fInt));
236     REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fUInt));
237     REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fFloat));
238     REPORTER_ASSERT(r, 2 == layout.alignment(*context.fTypes.fHalf));
239 
240     // vec2<T>, T: i32, u32, f32, f16
241     REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fInt2));
242     REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fUInt2));
243     REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fFloat2));
244     REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fHalf2));
245     REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fInt2));
246     REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fUInt2));
247     REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fFloat2));
248     REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fHalf2));
249 
250     // vec3<T>, T: i32, u32, f32, f16
251     REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fInt3));
252     REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fUInt3));
253     REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fFloat3));
254     REPORTER_ASSERT(r, 6 == layout.size(*context.fTypes.fHalf3));
255     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fInt3));
256     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fUInt3));
257     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat3));
258     REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf3));
259 
260     // vec4<T>, T: i32, u32, f32, f16
261     REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fInt4));
262     REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fUInt4));
263     REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fFloat4));
264     REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fHalf4));
265     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fInt4));
266     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fUInt4));
267     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat4));
268     REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf4));
269 
270     // mat2x2<f32>, mat2x2<f16>
271     REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fFloat2x2));
272     REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fHalf2x2));
273     REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fFloat2x2));
274     REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fHalf2x2));
275     REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fFloat2x2));
276     REPORTER_ASSERT(r, 4 == layout.stride(*context.fTypes.fHalf2x2));
277 
278     // mat3x2<f32>, mat3x2<f16>
279     REPORTER_ASSERT(r, 24 == layout.size(*context.fTypes.fFloat3x2));
280     REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fHalf3x2));
281     REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fFloat3x2));
282     REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fHalf3x2));
283     REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fFloat3x2));
284     REPORTER_ASSERT(r, 4 == layout.stride(*context.fTypes.fHalf3x2));
285 
286     // mat4x2<f32>, mat4x2<f16>
287     REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fFloat4x2));
288     REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fHalf4x2));
289     REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fFloat4x2));
290     REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fHalf4x2));
291     REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fFloat4x2));
292     REPORTER_ASSERT(r, 4 == layout.stride(*context.fTypes.fHalf4x2));
293 
294     // mat2x3<f32>, mat2x3<f16>
295     REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fFloat2x3));
296     REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fHalf2x3));
297     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat2x3));
298     REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf2x3));
299     REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fFloat2x3));
300     REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fHalf2x3));
301 
302     // mat3x3<f32>, mat3x3<f16>
303     REPORTER_ASSERT(r, 48 == layout.size(*context.fTypes.fFloat3x3));
304     REPORTER_ASSERT(r, 24 == layout.size(*context.fTypes.fHalf3x3));
305     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat3x3));
306     REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf3x3));
307     REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fFloat3x3));
308     REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fHalf3x3));
309 
310     // mat4x3<f32>, mat4x3<f16>
311     REPORTER_ASSERT(r, 64 == layout.size(*context.fTypes.fFloat4x3));
312     REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fHalf4x3));
313     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat4x3));
314     REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf4x3));
315     REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fFloat4x3));
316     REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fHalf4x3));
317 
318     // mat2x4<f32>, mat2x4<f16>
319     REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fFloat2x4));
320     REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fHalf2x4));
321     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat2x4));
322     REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf2x4));
323     REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fFloat2x4));
324     REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fHalf2x4));
325 
326     // mat3x4<f32>, mat3x4<f16>
327     REPORTER_ASSERT(r, 48 == layout.size(*context.fTypes.fFloat3x4));
328     REPORTER_ASSERT(r, 24 == layout.size(*context.fTypes.fHalf3x4));
329     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat3x4));
330     REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf3x4));
331     REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fFloat3x4));
332     REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fHalf3x4));
333 
334     // mat4x4<f32>, mat4x4<f16>
335     REPORTER_ASSERT(r, 64 == layout.size(*context.fTypes.fFloat4x4));
336     REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fHalf4x4));
337     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat4x4));
338     REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf4x4));
339     REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fFloat4x4));
340     REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fHalf4x4));
341 
342     // atomic<u32>
343     REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fAtomicUInt));
344     REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fAtomicUInt));
345 
346     // bool is not a host-shareable type and returns 0 for WGSL.
347     REPORTER_ASSERT(r, 0 == layout.size(*context.fTypes.fBool));
348     REPORTER_ASSERT(r, 0 == layout.size(*context.fTypes.fBool2));
349     REPORTER_ASSERT(r, 0 == layout.size(*context.fTypes.fBool3));
350     REPORTER_ASSERT(r, 0 == layout.size(*context.fTypes.fBool4));
351 
352     // Arrays
353     // array<f32, 4>
354     {
355         auto array = SkSL::Type::MakeArrayType("float[4]", *context.fTypes.fFloat, 4);
356         REPORTER_ASSERT(r, 64 == layout.size(*array));
357         REPORTER_ASSERT(r, 16 == layout.alignment(*array));
358         REPORTER_ASSERT(r, 16 == layout.stride(*array));
359     }
360     // array<f16, 4>
361     {
362         auto array = SkSL::Type::MakeArrayType("half[4]", *context.fTypes.fHalf, 4);
363         REPORTER_ASSERT(r, 64 == layout.size(*array));
364         REPORTER_ASSERT(r, 16 == layout.alignment(*array));
365         REPORTER_ASSERT(r, 16 == layout.stride(*array));
366     }
367     // array<vec2<f32>, 4>
368     {
369         auto array = SkSL::Type::MakeArrayType("float2[4]", *context.fTypes.fFloat2, 4);
370         REPORTER_ASSERT(r, 64 == layout.size(*array));
371         REPORTER_ASSERT(r, 16 == layout.alignment(*array));
372         REPORTER_ASSERT(r, 16 == layout.stride(*array));
373     }
374     // array<vec3<f32>, 4>
375     {
376         auto array = SkSL::Type::MakeArrayType("float3[4]", *context.fTypes.fFloat3, 4);
377         REPORTER_ASSERT(r, 64 == layout.size(*array));
378         REPORTER_ASSERT(r, 16 == layout.alignment(*array));
379         REPORTER_ASSERT(r, 16 == layout.stride(*array));
380     }
381     // array<vec4<f32>, 4>
382     {
383         auto array = SkSL::Type::MakeArrayType("float4[4]", *context.fTypes.fFloat4, 4);
384         REPORTER_ASSERT(r, 64 == layout.size(*array));
385         REPORTER_ASSERT(r, 16 == layout.alignment(*array));
386         REPORTER_ASSERT(r, 16 == layout.stride(*array));
387     }
388     // array<mat3x3<f32>, 4>
389     {
390         auto array = SkSL::Type::MakeArrayType("mat3[4]", *context.fTypes.fFloat3x3, 4);
391         REPORTER_ASSERT(r, 192 == layout.size(*array));
392         REPORTER_ASSERT(r, 16 == layout.alignment(*array));
393         REPORTER_ASSERT(r, 48 == layout.stride(*array));
394     }
395 
396     // Structs A and B from example in https://www.w3.org/TR/WGSL/#structure-member-layout, with
397     // offsets adjusted for uniform address space constraints.
398     //
399     // struct A {        //            align(roundUp(16, 8))  size(roundUp(16, 24))
400     //     u: f32,       // offset(0)  align(4)               size(4)
401     //     v: f32,       // offset(4)  align(4)               size(4)
402     //     w: vec2<f32>, // offset(8)  align(8)               size(8)
403     //     x: f32        // offset(16) align(4)               size(4)
404     //     // padding    // offset(20)                        size(12)
405     // }
406     std::vector<SkSL::Type::Field> fields;
407     fields.emplace_back(SkSL::Position(),
408                         SkSL::Modifiers(),
409                         std::string_view("u"),
410                         context.fTypes.fFloat.get());
411     fields.emplace_back(SkSL::Position(),
412                         SkSL::Modifiers(),
413                         std::string_view("v"),
414                         context.fTypes.fFloat.get());
415     fields.emplace_back(SkSL::Position(),
416                         SkSL::Modifiers(),
417                         std::string_view("v"),
418                         context.fTypes.fFloat2.get());
419     fields.emplace_back(SkSL::Position(),
420                         SkSL::Modifiers(),
421                         std::string_view("w"),
422                         context.fTypes.fFloat.get());
423     std::unique_ptr<SkSL::Type> structA = SkSL::Type::MakeStructType(
424             context, SkSL::Position(), std::string_view("A"), std::move(fields));
425     REPORTER_ASSERT(r, 32 == layout.size(*structA));
426     REPORTER_ASSERT(r, 16 == layout.alignment(*structA));
427     fields = {};
428 
429     // struct B {          //             align(16) size(208)
430     //     a: vec2<f32>,   // offset(0)   align(8)  size(8)
431     //     // padding      // offset(8)             size(8)
432     //     b: vec3<f32>,   // offset(16)  align(16) size(12)
433     //     c: f32,         // offset(28)  align(4)  size(4)
434     //     d: f32,         // offset(32)  align(4)  size(4)
435     //     // padding      // offset(36)            size(12)
436     //     e: A,           // offset(48)  align(16) size(32)
437     //     f: vec3<f32>,   // offset(80)  align(16) size(12)
438     //     // padding      // offset(92)            size(4)
439     //     g: array<A, 3>, // offset(96)  align(16) size(96)
440     //     h: i32          // offset(192) align(4)  size(4)
441     //     // padding      // offset(196)           size(12)
442     // }
443     fields.emplace_back(SkSL::Position(),
444                         SkSL::Modifiers(),
445                         std::string_view("a"),
446                         context.fTypes.fFloat2.get());
447     fields.emplace_back(SkSL::Position(),
448                         SkSL::Modifiers(),
449                         std::string_view("b"),
450                         context.fTypes.fFloat3.get());
451     fields.emplace_back(SkSL::Position(),
452                         SkSL::Modifiers(),
453                         std::string_view("c"),
454                         context.fTypes.fFloat.get());
455     fields.emplace_back(SkSL::Position(),
456                         SkSL::Modifiers(),
457                         std::string_view("d"),
458                         context.fTypes.fFloat.get());
459     fields.emplace_back(SkSL::Position(), SkSL::Modifiers(), std::string_view("e"), structA.get());
460     fields.emplace_back(SkSL::Position(),
461                         SkSL::Modifiers(),
462                         std::string_view("f"),
463                         context.fTypes.fFloat3.get());
464     auto array = SkSL::Type::MakeArrayType("A[3]", *structA, 3);
465     fields.emplace_back(SkSL::Position(), SkSL::Modifiers(), std::string_view("g"), array.get());
466     fields.emplace_back(
467             SkSL::Position(), SkSL::Modifiers(), std::string_view("h"), context.fTypes.fInt.get());
468     std::unique_ptr<SkSL::Type> structB = SkSL::Type::MakeStructType(
469             context, SkSL::Position(), std::string_view("B"), std::move(fields));
470     REPORTER_ASSERT(r, 208 == layout.size(*structB));
471     REPORTER_ASSERT(r, 16 == layout.alignment(*structB));
472 }
473 
DEF_TEST(SkSLMemoryLayoutWGSLStorageTest,r)474 DEF_TEST(SkSLMemoryLayoutWGSLStorageTest, r) {
475     SkSL::TestingOnly_AbortErrorReporter errors;
476     SkSL::ShaderCaps caps;
477     SkSL::BuiltinTypes types;
478     SkSL::Context context(types, &caps, errors);
479     SkSL::MemoryLayout layout(SkSL::MemoryLayout::Standard::kWGSLStorage);
480 
481     // The values here are taken from https://www.w3.org/TR/WGSL/#alignment-and-size, table titled
482     // "Alignment and size for host-shareable types".
483 
484     // scalars (i32, u32, f32, f16)
485     REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fInt));
486     REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fUInt));
487     REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fFloat));
488     REPORTER_ASSERT(r, 2 == layout.size(*context.fTypes.fHalf));
489     REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fInt));
490     REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fUInt));
491     REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fFloat));
492     REPORTER_ASSERT(r, 2 == layout.alignment(*context.fTypes.fHalf));
493 
494     // vec2<T>, T: i32, u32, f32, f16
495     REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fInt2));
496     REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fUInt2));
497     REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fFloat2));
498     REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fHalf2));
499     REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fInt2));
500     REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fUInt2));
501     REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fFloat2));
502     REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fHalf2));
503 
504     // vec3<T>, T: i32, u32, f32, f16
505     REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fInt3));
506     REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fUInt3));
507     REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fFloat3));
508     REPORTER_ASSERT(r, 6 == layout.size(*context.fTypes.fHalf3));
509     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fInt3));
510     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fUInt3));
511     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat3));
512     REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf3));
513 
514     // vec4<T>, T: i32, u32, f32, f16
515     REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fInt4));
516     REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fUInt4));
517     REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fFloat4));
518     REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fHalf4));
519     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fInt4));
520     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fUInt4));
521     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat4));
522     REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf4));
523 
524     // mat2x2<f32>, mat2x2<f16>
525     REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fFloat2x2));
526     REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fHalf2x2));
527     REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fFloat2x2));
528     REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fHalf2x2));
529     REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fFloat2x2));
530     REPORTER_ASSERT(r, 4 == layout.stride(*context.fTypes.fHalf2x2));
531 
532     // mat3x2<f32>, mat3x2<f16>
533     REPORTER_ASSERT(r, 24 == layout.size(*context.fTypes.fFloat3x2));
534     REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fHalf3x2));
535     REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fFloat3x2));
536     REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fHalf3x2));
537     REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fFloat3x2));
538     REPORTER_ASSERT(r, 4 == layout.stride(*context.fTypes.fHalf3x2));
539 
540     // mat4x2<f32>, mat4x2<f16>
541     REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fFloat4x2));
542     REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fHalf4x2));
543     REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fFloat4x2));
544     REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fHalf4x2));
545     REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fFloat4x2));
546     REPORTER_ASSERT(r, 4 == layout.stride(*context.fTypes.fHalf4x2));
547 
548     // mat2x3<f32>, mat2x3<f16>
549     REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fFloat2x3));
550     REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fHalf2x3));
551     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat2x3));
552     REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf2x3));
553     REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fFloat2x3));
554     REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fHalf2x3));
555 
556     // mat3x3<f32>, mat3x3<f16>
557     REPORTER_ASSERT(r, 48 == layout.size(*context.fTypes.fFloat3x3));
558     REPORTER_ASSERT(r, 24 == layout.size(*context.fTypes.fHalf3x3));
559     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat3x3));
560     REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf3x3));
561     REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fFloat3x3));
562     REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fHalf3x3));
563 
564     // mat4x3<f32>, mat4x3<f16>
565     REPORTER_ASSERT(r, 64 == layout.size(*context.fTypes.fFloat4x3));
566     REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fHalf4x3));
567     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat4x3));
568     REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf4x3));
569     REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fFloat4x3));
570     REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fHalf4x3));
571 
572     // mat2x4<f32>, mat2x4<f16>
573     REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fFloat2x4));
574     REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fHalf2x4));
575     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat2x4));
576     REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf2x4));
577     REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fFloat2x4));
578     REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fHalf2x4));
579 
580     // mat3x4<f32>, mat3x4<f16>
581     REPORTER_ASSERT(r, 48 == layout.size(*context.fTypes.fFloat3x4));
582     REPORTER_ASSERT(r, 24 == layout.size(*context.fTypes.fHalf3x4));
583     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat3x4));
584     REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf3x4));
585     REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fFloat3x4));
586     REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fHalf3x4));
587 
588     // mat4x4<f32>, mat4x4<f16>
589     REPORTER_ASSERT(r, 64 == layout.size(*context.fTypes.fFloat4x4));
590     REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fHalf4x4));
591     REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat4x4));
592     REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf4x4));
593     REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fFloat4x4));
594     REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fHalf4x4));
595 
596     // atomic<u32>
597     REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fAtomicUInt));
598     REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fAtomicUInt));
599 
600     // bool is not a host-shareable type and returns 0 for WGSL.
601     REPORTER_ASSERT(r, 0 == layout.size(*context.fTypes.fBool));
602     REPORTER_ASSERT(r, 0 == layout.size(*context.fTypes.fBool2));
603     REPORTER_ASSERT(r, 0 == layout.size(*context.fTypes.fBool3));
604     REPORTER_ASSERT(r, 0 == layout.size(*context.fTypes.fBool4));
605 
606     // Arrays
607     // array<f32, 4>
608     {
609         auto array = SkSL::Type::MakeArrayType("float[4]", *context.fTypes.fFloat, 4);
610         REPORTER_ASSERT(r, 16 == layout.size(*array));
611         REPORTER_ASSERT(r, 4 == layout.alignment(*array));
612         REPORTER_ASSERT(r, 4 == layout.stride(*array));
613     }
614     // array<f16, 4>
615     {
616         auto array = SkSL::Type::MakeArrayType("half[4]", *context.fTypes.fHalf, 4);
617         REPORTER_ASSERT(r, 8 == layout.size(*array));
618         REPORTER_ASSERT(r, 2 == layout.alignment(*array));
619         REPORTER_ASSERT(r, 2 == layout.stride(*array));
620     }
621     // array<vec2<f32>, 4>
622     {
623         auto array = SkSL::Type::MakeArrayType("float2[4]", *context.fTypes.fFloat2, 4);
624         REPORTER_ASSERT(r, 32 == layout.size(*array));
625         REPORTER_ASSERT(r, 8 == layout.alignment(*array));
626         REPORTER_ASSERT(r, 8 == layout.stride(*array));
627     }
628     // array<vec3<f32>, 4>
629     {
630         auto array = SkSL::Type::MakeArrayType("float3[4]", *context.fTypes.fFloat3, 4);
631         REPORTER_ASSERT(r, 64 == layout.size(*array));
632         REPORTER_ASSERT(r, 16 == layout.alignment(*array));
633         REPORTER_ASSERT(r, 16 == layout.stride(*array));
634     }
635     // array<vec4<f32>, 4>
636     {
637         auto array = SkSL::Type::MakeArrayType("float4[4]", *context.fTypes.fFloat4, 4);
638         REPORTER_ASSERT(r, 64 == layout.size(*array));
639         REPORTER_ASSERT(r, 16 == layout.alignment(*array));
640         REPORTER_ASSERT(r, 16 == layout.stride(*array));
641     }
642     // array<mat3x3<f32>, 4>
643     {
644         auto array = SkSL::Type::MakeArrayType("mat3[4]", *context.fTypes.fFloat3x3, 4);
645         REPORTER_ASSERT(r, 192 == layout.size(*array));
646         REPORTER_ASSERT(r, 16 == layout.alignment(*array));
647         REPORTER_ASSERT(r, 48 == layout.stride(*array));
648     }
649 
650     // Structs A and B from example in https://www.w3.org/TR/WGSL/#structure-member-layout
651     //
652     // struct A {        //            align(8)               size(24)
653     //     u: f32,       // offset(0)  align(4)               size(4)
654     //     v: f32,       // offset(4)  align(4)               size(4)
655     //     w: vec2<f32>, // offset(8)  align(8)               size(8)
656     //     x: f32        // offset(16) align(4)               size(4)
657     //     // padding    // offset(20)                        size(4)
658     // }
659     std::vector<SkSL::Type::Field> fields;
660     fields.emplace_back(SkSL::Position(),
661                         SkSL::Modifiers(),
662                         std::string_view("u"),
663                         context.fTypes.fFloat.get());
664     fields.emplace_back(SkSL::Position(),
665                         SkSL::Modifiers(),
666                         std::string_view("v"),
667                         context.fTypes.fFloat.get());
668     fields.emplace_back(SkSL::Position(),
669                         SkSL::Modifiers(),
670                         std::string_view("v"),
671                         context.fTypes.fFloat2.get());
672     fields.emplace_back(SkSL::Position(),
673                         SkSL::Modifiers(),
674                         std::string_view("w"),
675                         context.fTypes.fFloat.get());
676     std::unique_ptr<SkSL::Type> structA = SkSL::Type::MakeStructType(
677             context, SkSL::Position(), std::string_view("A"), std::move(fields));
678     REPORTER_ASSERT(r, 24 == layout.size(*structA));
679     REPORTER_ASSERT(r, 8 == layout.alignment(*structA));
680     fields = {};
681 
682     // struct B {          //             align(16) size(160)
683     //     a: vec2<f32>,   // offset(0)   align(8)  size(8)
684     //     // padding      // offset(8)             size(8)
685     //     b: vec3<f32>,   // offset(16)  align(16) size(12)
686     //     c: f32,         // offset(28)  align(4)  size(4)
687     //     d: f32,         // offset(32)  align(4)  size(4)
688     //     // padding      // offset(36)            size(4)
689     //     e: A,           // offset(40)  align(8)  size(24)
690     //     f: vec3<f32>,   // offset(64)  align(16) size(12)
691     //     // padding      // offset(76)            size(4)
692     //     g: array<A, 3>, // offset(80)  align(16) size(72)
693     //     h: i32          // offset(152) align(4)  size(4)
694     //     // padding      // offset(156)           size(4)
695     // }
696     fields.emplace_back(SkSL::Position(),
697                         SkSL::Modifiers(),
698                         std::string_view("a"),
699                         context.fTypes.fFloat2.get());
700     fields.emplace_back(SkSL::Position(),
701                         SkSL::Modifiers(),
702                         std::string_view("b"),
703                         context.fTypes.fFloat3.get());
704     fields.emplace_back(SkSL::Position(),
705                         SkSL::Modifiers(),
706                         std::string_view("c"),
707                         context.fTypes.fFloat.get());
708     fields.emplace_back(SkSL::Position(),
709                         SkSL::Modifiers(),
710                         std::string_view("d"),
711                         context.fTypes.fFloat.get());
712     fields.emplace_back(SkSL::Position(), SkSL::Modifiers(), std::string_view("e"), structA.get());
713     fields.emplace_back(SkSL::Position(),
714                         SkSL::Modifiers(),
715                         std::string_view("f"),
716                         context.fTypes.fFloat3.get());
717     auto array = SkSL::Type::MakeArrayType("A[3]", *structA, 3);
718     fields.emplace_back(SkSL::Position(), SkSL::Modifiers(), std::string_view("g"), array.get());
719     fields.emplace_back(
720             SkSL::Position(), SkSL::Modifiers(), std::string_view("h"), context.fTypes.fInt.get());
721     std::unique_ptr<SkSL::Type> structB = SkSL::Type::MakeStructType(
722             context, SkSL::Position(), std::string_view("B"), std::move(fields));
723     REPORTER_ASSERT(r, 160 == layout.size(*structB));
724     REPORTER_ASSERT(r, 16 == layout.alignment(*structB));
725 }
726 
DEF_TEST(SkSLMemoryLayoutWGSLUnsupportedTypesTest,r)727 DEF_TEST(SkSLMemoryLayoutWGSLUnsupportedTypesTest, r) {
728     SkSL::TestingOnly_AbortErrorReporter errors;
729     SkSL::ShaderCaps caps;
730     SkSL::BuiltinTypes types;
731     SkSL::Context context(types, &caps, errors);
732 
733     auto testArray = SkSL::Type::MakeArrayType("bool[3]", *context.fTypes.fBool, 3);
734 
735     std::vector<SkSL::Type::Field> fields;
736     fields.emplace_back(
737             SkSL::Position(), SkSL::Modifiers(), std::string_view("foo"), testArray.get());
738     auto testStruct = SkSL::Type::MakeStructType(
739             context, SkSL::Position(), std::string_view("Test"), std::move(fields));
740 
741     SkSL::MemoryLayout layout(SkSL::MemoryLayout::Standard::kWGSLUniform);
742     REPORTER_ASSERT(r, !layout.isSupported(*context.fTypes.fBool));
743     REPORTER_ASSERT(r, !layout.isSupported(*context.fTypes.fBool2));
744     REPORTER_ASSERT(r, !layout.isSupported(*context.fTypes.fBool3));
745     REPORTER_ASSERT(r, !layout.isSupported(*context.fTypes.fBool4));
746     REPORTER_ASSERT(r, !layout.isSupported(*context.fTypes.fShort));
747     REPORTER_ASSERT(r, !layout.isSupported(*context.fTypes.fShort2));
748     REPORTER_ASSERT(r, !layout.isSupported(*context.fTypes.fShort3));
749     REPORTER_ASSERT(r, !layout.isSupported(*context.fTypes.fShort4));
750     REPORTER_ASSERT(r, !layout.isSupported(*testArray));
751     REPORTER_ASSERT(r, !layout.isSupported(*testStruct));
752 }
753 
DEF_TEST(SkSLMemoryLayoutWGSLSupportedTypesTest,r)754 DEF_TEST(SkSLMemoryLayoutWGSLSupportedTypesTest, r) {
755     SkSL::TestingOnly_AbortErrorReporter errors;
756     SkSL::ShaderCaps caps;
757     SkSL::BuiltinTypes types;
758     SkSL::Context context(types, &caps, errors);
759 
760     auto testArray = SkSL::Type::MakeArrayType("float[3]", *context.fTypes.fFloat, 3);
761 
762     std::vector<SkSL::Type::Field> fields;
763     fields.emplace_back(
764             SkSL::Position(), SkSL::Modifiers(), std::string_view("foo"), testArray.get());
765     auto testStruct = SkSL::Type::MakeStructType(
766             context, SkSL::Position(), std::string_view("Test"), std::move(fields));
767 
768     SkSL::MemoryLayout layout(SkSL::MemoryLayout::Standard::kWGSLUniform);
769 
770     // scalars (i32, u32, f32, f16)
771     REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fInt));
772     REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fUInt));
773     REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fFloat));
774     REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fHalf));
775 
776     // vec2<T>, T: i32, u32, f32, f16
777     REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fInt2));
778     REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fUInt2));
779     REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fFloat2));
780     REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fHalf2));
781 
782     // vec3<T>, T: i32, u32, f32, f16
783     REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fInt3));
784     REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fUInt3));
785     REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fFloat3));
786     REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fHalf3));
787 
788     // vec4<T>, T: i32, u32, f32, f16
789     REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fInt4));
790     REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fUInt4));
791     REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fFloat4));
792     REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fHalf4));
793 
794     // mat2x2<f32>, mat2x2<f16>
795     REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fFloat2x2));
796     REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fHalf2x2));
797 
798     // mat3x2<f32>, mat3x2<f16>
799     REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fFloat3x2));
800     REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fHalf3x2));
801 
802     // mat4x2<f32>, mat4x2<f16>
803     REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fFloat4x2));
804     REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fHalf4x2));
805 
806     // mat2x3<f32>, mat2x3<f16>
807     REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fFloat2x3));
808     REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fHalf2x3));
809 
810     // mat3x3<f32>, mat3x3<f16>
811     REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fFloat3x3));
812     REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fHalf3x3));
813 
814     // mat4x3<f32>, mat4x3<f16>
815     REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fFloat4x3));
816     REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fHalf4x3));
817 
818     // mat2x4<f32>, mat2x4<f16>
819     REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fFloat2x4));
820     REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fHalf2x4));
821 
822     // mat3x4<f32>, mat3x4<f16>
823     REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fFloat3x4));
824     REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fHalf3x4));
825 
826     // mat4x4<f32>, mat4x4<f16>
827     REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fFloat4x4));
828     REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fHalf4x4));
829 
830     // atomic<u32>
831     REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fAtomicUInt));
832 
833     // arrays and structs
834     REPORTER_ASSERT(r, layout.isSupported(*testArray));
835     REPORTER_ASSERT(r, layout.isSupported(*testStruct));
836 }
837