Flutter Engine
The Flutter Engine
SkSLMemoryLayoutTest.cpp
Go to the documentation of this file.
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
15#include "src/sksl/SkSLUtil.h"
19#include "tests/Test.h"
20
21#include <memory>
22#include <string>
23#include <string_view>
24#include <utility>
25
26using namespace skia_private;
27
28DEF_TEST(SkSLMemoryLayoutTest_std140, r) {
31 SkSL::Context context(types, errors);
33 SkSL::ProgramConfig config = {};
34 context.fConfig = &config;
35
36 // basic types
37 REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fFloat));
38 REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fFloat2));
39 REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fFloat3));
40 REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fFloat4));
41 REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fInt));
42 REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fInt2));
43 REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fInt3));
44 REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fInt4));
45 REPORTER_ASSERT(r, 1 == layout.size(*context.fTypes.fBool));
46 REPORTER_ASSERT(r, 2 == layout.size(*context.fTypes.fBool2));
47 REPORTER_ASSERT(r, 3 == layout.size(*context.fTypes.fBool3));
48 REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fBool4));
49 REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fFloat2x2));
50 REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fFloat2x4));
51 REPORTER_ASSERT(r, 48 == layout.size(*context.fTypes.fFloat3x3));
52 REPORTER_ASSERT(r, 64 == layout.size(*context.fTypes.fFloat4x2));
53 REPORTER_ASSERT(r, 64 == layout.size(*context.fTypes.fFloat4x4));
54 REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fAtomicUInt));
55 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fFloat));
56 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fFloat2));
57 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat3));
58 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat4));
59 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fInt));
60 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fInt2));
61 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fInt3));
62 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fInt4));
63 REPORTER_ASSERT(r, 1 == layout.alignment(*context.fTypes.fBool));
64 REPORTER_ASSERT(r, 2 == layout.alignment(*context.fTypes.fBool2));
65 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fBool3));
66 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fBool4));
67 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat2x2));
68 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat2x4));
69 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat3x3));
70 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat4x2));
71 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat4x4));
72 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fAtomicUInt));
73
74 // struct 1
75 TArray<SkSL::Field> fields1;
77 std::string_view("a"), context.fTypes.fFloat3.get());
78 std::unique_ptr<SkSL::Type> s1 =
79 SkSL::Type::MakeStructType(context, SkSL::Position(), std::string("s1"), fields1);
80 REPORTER_ASSERT(r, 16 == layout.size(*s1));
81 REPORTER_ASSERT(r, 16 == layout.alignment(*s1));
82
84 std::string_view("b"), context.fTypes.fFloat.get());
85 std::unique_ptr<SkSL::Type> s2 =
86 SkSL::Type::MakeStructType(context, SkSL::Position(), std::string("s2"), fields1);
87 REPORTER_ASSERT(r, 16 == layout.size(*s2));
88 REPORTER_ASSERT(r, 16 == layout.alignment(*s2));
89
91 std::string_view("c"), context.fTypes.fBool.get());
92 std::unique_ptr<SkSL::Type> s3 =
93 SkSL::Type::MakeStructType(context, SkSL::Position(), std::string("s3"), fields1);
94 REPORTER_ASSERT(r, 32 == layout.size(*s3));
95 REPORTER_ASSERT(r, 16 == layout.alignment(*s3));
96
97 // struct 2
98 TArray<SkSL::Field> fields2;
100 std::string_view("a"), context.fTypes.fInt.get());
101 std::unique_ptr<SkSL::Type> s4 =
102 SkSL::Type::MakeStructType(context, SkSL::Position(), std::string("s4"), fields2);
103 REPORTER_ASSERT(r, 16 == layout.size(*s4));
104 REPORTER_ASSERT(r, 16 == layout.alignment(*s4));
105
107 std::string_view("b"), context.fTypes.fFloat3.get());
108 std::unique_ptr<SkSL::Type> s5 =
109 SkSL::Type::MakeStructType(context, SkSL::Position(), std::string("s5"), fields2);
110 REPORTER_ASSERT(r, 32 == layout.size(*s5));
111 REPORTER_ASSERT(r, 16 == layout.alignment(*s5));
112
113 // arrays
114 std::unique_ptr<SkSL::Type> array1 =
115 SkSL::Type::MakeArrayType(context, std::string("float[4]"), *context.fTypes.fFloat, 4);
116 REPORTER_ASSERT(r, 64 == layout.size(*array1));
117 REPORTER_ASSERT(r, 16 == layout.alignment(*array1));
118 REPORTER_ASSERT(r, 16 == layout.stride(*array1));
119
120 std::unique_ptr<SkSL::Type> array2 =
121 SkSL::Type::MakeArrayType(context, std::string("float4[4]"), *context.fTypes.fFloat4, 4);
122 REPORTER_ASSERT(r, 64 == layout.size(*array2));
123 REPORTER_ASSERT(r, 16 == layout.alignment(*array2));
124 REPORTER_ASSERT(r, 16 == layout.stride(*array2));
125}
126
127DEF_TEST(SkSLMemoryLayoutTest_std430, r) {
129 SkSL::BuiltinTypes types;
130 SkSL::Context context(types, errors);
132 SkSL::ProgramConfig config = {};
133 context.fConfig = &config;
134
135 // basic types
136 REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fFloat));
137 REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fFloat2));
138 REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fFloat3));
139 REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fFloat4));
140 REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fInt));
141 REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fInt2));
142 REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fInt3));
143 REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fInt4));
144 REPORTER_ASSERT(r, 1 == layout.size(*context.fTypes.fBool));
145 REPORTER_ASSERT(r, 2 == layout.size(*context.fTypes.fBool2));
146 REPORTER_ASSERT(r, 3 == layout.size(*context.fTypes.fBool3));
147 REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fBool4));
148 REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fFloat2x2));
149 REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fFloat2x4));
150 REPORTER_ASSERT(r, 48 == layout.size(*context.fTypes.fFloat3x3));
151 REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fFloat4x2));
152 REPORTER_ASSERT(r, 64 == layout.size(*context.fTypes.fFloat4x4));
153 REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fAtomicUInt));
154 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fFloat));
155 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fFloat2));
156 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat3));
157 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat4));
158 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fInt));
159 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fInt2));
160 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fInt3));
161 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fInt4));
162 REPORTER_ASSERT(r, 1 == layout.alignment(*context.fTypes.fBool));
163 REPORTER_ASSERT(r, 2 == layout.alignment(*context.fTypes.fBool2));
164 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fBool3));
165 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fBool4));
166 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fFloat2x2));
167 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat2x4));
168 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat3x3));
169 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fFloat4x2));
170 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat4x4));
171 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fAtomicUInt));
172
173 // struct 1
174 TArray<SkSL::Field> fields1;
176 std::string_view("a"), context.fTypes.fFloat3.get());
177 std::unique_ptr<SkSL::Type> s1 =
178 SkSL::Type::MakeStructType(context, SkSL::Position(), std::string("s1"), fields1);
179 REPORTER_ASSERT(r, 16 == layout.size(*s1));
180 REPORTER_ASSERT(r, 16 == layout.alignment(*s1));
181
183 std::string_view("b"), context.fTypes.fFloat.get());
184 std::unique_ptr<SkSL::Type> s2 =
185 SkSL::Type::MakeStructType(context, SkSL::Position(), std::string("s2"), fields1);
186 REPORTER_ASSERT(r, 16 == layout.size(*s2));
187 REPORTER_ASSERT(r, 16 == layout.alignment(*s2));
188
190 std::string_view("c"), context.fTypes.fBool.get());
191 std::unique_ptr<SkSL::Type> s3 =
192 SkSL::Type::MakeStructType(context, SkSL::Position(), std::string("s3"), fields1);
193 REPORTER_ASSERT(r, 32 == layout.size(*s3));
194 REPORTER_ASSERT(r, 16 == layout.alignment(*s3));
195
196 // struct 2
197 TArray<SkSL::Field> fields2;
199 std::string_view("a"), context.fTypes.fInt.get());
200 std::unique_ptr<SkSL::Type> s4 =
201 SkSL::Type::MakeStructType(context, SkSL::Position(), std::string("s4"), fields2);
202 REPORTER_ASSERT(r, 4 == layout.size(*s4));
203 REPORTER_ASSERT(r, 4 == layout.alignment(*s4));
204
206 std::string_view("b"), context.fTypes.fFloat3.get());
207 std::unique_ptr<SkSL::Type> s5 =
208 SkSL::Type::MakeStructType(context, SkSL::Position(), std::string("s5"), fields2);
209 REPORTER_ASSERT(r, 32 == layout.size(*s5));
210 REPORTER_ASSERT(r, 16 == layout.alignment(*s5));
211
212 // arrays
213 std::unique_ptr<SkSL::Type> array1 =
214 SkSL::Type::MakeArrayType(context, std::string("float[4]"), *context.fTypes.fFloat, 4);
215 REPORTER_ASSERT(r, 16 == layout.size(*array1));
216 REPORTER_ASSERT(r, 4 == layout.alignment(*array1));
217 REPORTER_ASSERT(r, 4 == layout.stride(*array1));
218
219 std::unique_ptr<SkSL::Type> array2 =
220 SkSL::Type::MakeArrayType(context, std::string("float4[4]"), *context.fTypes.fFloat4, 4);
221 REPORTER_ASSERT(r, 64 == layout.size(*array2));
222 REPORTER_ASSERT(r, 16 == layout.alignment(*array2));
223 REPORTER_ASSERT(r, 16 == layout.stride(*array2));
224}
225
226DEF_TEST(SkSLMemoryLayoutTest_WGSLUniform_Base, r) {
228 SkSL::BuiltinTypes types;
229 SkSL::Context context(types, errors);
231 SkSL::ProgramConfig config = {};
232 context.fConfig = &config;
233
234 // The values here are taken from https://www.w3.org/TR/WGSL/#alignment-and-size, table titled
235 // "Alignment and size for host-shareable types". WGSL does not have an i16 type, so short and
236 // unsigned-short integer types are treated as full-size integers in WGSL.
237
238 // scalars (i32, u32, f32, f16)
239 REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fInt));
240 REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fUInt));
241 REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fShort));
242 REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fUShort));
243 REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fFloat));
244 REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fHalf));
245 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fInt));
246 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fUInt));
247 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fShort));
248 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fUShort));
249 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fFloat));
250 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fHalf));
251
252 // vec2<T>, T: i32, u32, f32, f16
253 REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fInt2));
254 REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fUInt2));
255 REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fShort2));
256 REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fUShort2));
257 REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fFloat2));
258 REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fHalf2));
259 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fInt2));
260 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fUInt2));
261 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fShort2));
262 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fUShort2));
263 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fFloat2));
264 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf2));
265
266 // vec3<T>, T: i32, u32, f32, f16
267 REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fInt3));
268 REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fUInt3));
269 REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fShort3));
270 REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fUShort3));
271 REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fFloat3));
272 REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fHalf3));
273 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fInt3));
274 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fUInt3));
275 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fShort3));
276 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fUShort3));
277 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat3));
278 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fHalf3));
279
280 // vec4<T>, T: i32, u32, f32, f16
281 REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fInt4));
282 REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fUInt4));
283 REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fShort4));
284 REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fUShort4));
285 REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fFloat4));
286 REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fHalf4));
287 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fInt4));
288 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fUInt4));
289 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fShort4));
290 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fUShort4));
291 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat4));
292 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fHalf4));
293
294 // mat2x2<f32>, mat2x2<f16>
295 REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fFloat2x2));
296 REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fHalf2x2));
297 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fFloat2x2));
298 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf2x2));
299 REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fFloat2x2));
300 REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fHalf2x2));
301
302 // mat3x2<f32>, mat3x2<f16>
303 REPORTER_ASSERT(r, 24 == layout.size(*context.fTypes.fFloat3x2));
304 REPORTER_ASSERT(r, 24 == layout.size(*context.fTypes.fHalf3x2));
305 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fFloat3x2));
306 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf3x2));
307 REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fFloat3x2));
308 REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fHalf3x2));
309
310 // mat4x2<f32>, mat4x2<f16>
311 REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fFloat4x2));
312 REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fHalf4x2));
313 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fFloat4x2));
314 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf4x2));
315 REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fFloat4x2));
316 REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fHalf4x2));
317
318 // mat2x3<f32>, mat2x3<f16>
319 REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fFloat2x3));
320 REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fHalf2x3));
321 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat2x3));
322 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fHalf2x3));
323 REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fFloat2x3));
324 REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fHalf2x3));
325
326 // mat3x3<f32>, mat3x3<f16>
327 REPORTER_ASSERT(r, 48 == layout.size(*context.fTypes.fFloat3x3));
328 REPORTER_ASSERT(r, 48 == layout.size(*context.fTypes.fHalf3x3));
329 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat3x3));
330 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fHalf3x3));
331 REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fFloat3x3));
332 REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fHalf3x3));
333
334 // mat4x3<f32>, mat4x3<f16>
335 REPORTER_ASSERT(r, 64 == layout.size(*context.fTypes.fFloat4x3));
336 REPORTER_ASSERT(r, 64 == layout.size(*context.fTypes.fHalf4x3));
337 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat4x3));
338 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fHalf4x3));
339 REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fFloat4x3));
340 REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fHalf4x3));
341
342 // mat2x4<f32>, mat2x4<f16>
343 REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fFloat2x4));
344 REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fHalf2x4));
345 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat2x4));
346 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fHalf2x4));
347 REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fFloat2x4));
348 REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fHalf2x4));
349
350 // mat3x4<f32>, mat3x4<f16>
351 REPORTER_ASSERT(r, 48 == layout.size(*context.fTypes.fFloat3x4));
352 REPORTER_ASSERT(r, 48 == layout.size(*context.fTypes.fHalf3x4));
353 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat3x4));
354 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fHalf3x4));
355 REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fFloat3x4));
356 REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fHalf3x4));
357
358 // mat4x4<f32>, mat4x4<f16>
359 REPORTER_ASSERT(r, 64 == layout.size(*context.fTypes.fFloat4x4));
360 REPORTER_ASSERT(r, 64 == layout.size(*context.fTypes.fHalf4x4));
361 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat4x4));
362 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fHalf4x4));
363 REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fFloat4x4));
364 REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fHalf4x4));
365
366 // atomic<u32>
367 REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fAtomicUInt));
368 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fAtomicUInt));
369
370 // bool is not a host-shareable type and returns 0 for WGSL.
371 REPORTER_ASSERT(r, 0 == layout.size(*context.fTypes.fBool));
372 REPORTER_ASSERT(r, 0 == layout.size(*context.fTypes.fBool2));
373 REPORTER_ASSERT(r, 0 == layout.size(*context.fTypes.fBool3));
374 REPORTER_ASSERT(r, 0 == layout.size(*context.fTypes.fBool4));
375
376 // Arrays
377 // array<f32, 4>
378 {
379 auto array = SkSL::Type::MakeArrayType(context, "float[4]", *context.fTypes.fFloat, 4);
380 REPORTER_ASSERT(r, 64 == layout.size(*array));
381 REPORTER_ASSERT(r, 16 == layout.alignment(*array));
382 REPORTER_ASSERT(r, 16 == layout.stride(*array));
383 }
384 // array<f16, 4>
385 {
386 auto array = SkSL::Type::MakeArrayType(context, "half[4]", *context.fTypes.fHalf, 4);
387 REPORTER_ASSERT(r, 64 == layout.size(*array));
388 REPORTER_ASSERT(r, 16 == layout.alignment(*array));
389 REPORTER_ASSERT(r, 16 == layout.stride(*array));
390 }
391 // array<vec2<f32>, 4>
392 {
393 auto array = SkSL::Type::MakeArrayType(context, "float2[4]", *context.fTypes.fFloat2, 4);
394 REPORTER_ASSERT(r, 64 == layout.size(*array));
395 REPORTER_ASSERT(r, 16 == layout.alignment(*array));
396 REPORTER_ASSERT(r, 16 == layout.stride(*array));
397 }
398 // array<vec3<f32>, 4>
399 {
400 auto array = SkSL::Type::MakeArrayType(context, "float3[4]", *context.fTypes.fFloat3, 4);
401 REPORTER_ASSERT(r, 64 == layout.size(*array));
402 REPORTER_ASSERT(r, 16 == layout.alignment(*array));
403 REPORTER_ASSERT(r, 16 == layout.stride(*array));
404 }
405 // array<vec4<f32>, 4>
406 {
407 auto array = SkSL::Type::MakeArrayType(context, "float4[4]", *context.fTypes.fFloat4, 4);
408 REPORTER_ASSERT(r, 64 == layout.size(*array));
409 REPORTER_ASSERT(r, 16 == layout.alignment(*array));
410 REPORTER_ASSERT(r, 16 == layout.stride(*array));
411 }
412 // array<mat3x3<f32>, 4>
413 {
414 auto array = SkSL::Type::MakeArrayType(context, "mat3[4]", *context.fTypes.fFloat3x3, 4);
415 REPORTER_ASSERT(r, 192 == layout.size(*array));
416 REPORTER_ASSERT(r, 16 == layout.alignment(*array));
417 REPORTER_ASSERT(r, 48 == layout.stride(*array));
418 }
419
420 // Structs A and B from example in https://www.w3.org/TR/WGSL/#structure-member-layout, with
421 // offsets adjusted for uniform address space constraints.
422 //
423 // struct A { // align(roundUp(16, 8)) size(roundUp(16, 24))
424 // u: f32, // offset(0) align(4) size(4)
425 // v: f32, // offset(4) align(4) size(4)
426 // w: vec2<f32>, // offset(8) align(8) size(8)
427 // x: f32 // offset(16) align(4) size(4)
428 // // padding // offset(20) size(12)
429 // }
430 TArray<SkSL::Field> fields;
432 SkSL::Layout(),
434 std::string_view("u"),
435 context.fTypes.fFloat.get());
437 SkSL::Layout(),
439 std::string_view("v"),
440 context.fTypes.fFloat.get());
442 SkSL::Layout(),
444 std::string_view("w"),
445 context.fTypes.fFloat2.get());
447 SkSL::Layout(),
449 std::string_view("x"),
450 context.fTypes.fFloat.get());
451 std::unique_ptr<SkSL::Type> structA = SkSL::Type::MakeStructType(
452 context, SkSL::Position(), std::string_view("A"), std::move(fields));
453 REPORTER_ASSERT(r, 32 == layout.size(*structA));
454 REPORTER_ASSERT(r, 16 == layout.alignment(*structA));
455 fields = {};
456
457 // struct B { // align(16) size(208)
458 // a: vec2<f32>, // offset(0) align(8) size(8)
459 // // padding // offset(8) size(8)
460 // b: vec3<f32>, // offset(16) align(16) size(12)
461 // c: f32, // offset(28) align(4) size(4)
462 // d: f32, // offset(32) align(4) size(4)
463 // // padding // offset(36) size(12)
464 // e: A, // offset(48) align(16) size(32)
465 // f: vec3<f32>, // offset(80) align(16) size(12)
466 // // padding // offset(92) size(4)
467 // g: array<A, 3>, // offset(96) align(16) size(96)
468 // h: i32 // offset(192) align(4) size(4)
469 // // padding // offset(196) size(12)
470 // }
472 SkSL::Layout(),
474 std::string_view("a"),
475 context.fTypes.fFloat2.get());
477 SkSL::Layout(),
479 std::string_view("b"),
480 context.fTypes.fFloat3.get());
482 SkSL::Layout(),
484 std::string_view("c"),
485 context.fTypes.fFloat.get());
487 SkSL::Layout(),
489 std::string_view("d"),
490 context.fTypes.fFloat.get());
492 SkSL::Layout(),
494 std::string_view("e"),
495 structA.get());
497 SkSL::Layout(),
499 std::string_view("f"),
500 context.fTypes.fFloat3.get());
501 auto array = SkSL::Type::MakeArrayType(context, "A[3]", *structA, 3);
503 SkSL::Layout(),
505 std::string_view("g"),
506 array.get());
508 SkSL::Layout(),
510 std::string_view("h"),
511 context.fTypes.fInt.get());
512 std::unique_ptr<SkSL::Type> structB = SkSL::Type::MakeStructType(
513 context, SkSL::Position(), std::string_view("B"), std::move(fields));
514 REPORTER_ASSERT(r, 208 == layout.size(*structB));
515 REPORTER_ASSERT(r, 16 == layout.alignment(*structB));
516}
517
518DEF_TEST(SkSLMemoryLayoutTest_WGSLUniform_EnableF16, r) {
520 SkSL::BuiltinTypes types;
521 SkSL::Context context(types, errors);
523 SkSL::ProgramConfig config = {};
524 context.fConfig = &config;
525
526 // The values here are taken from https://www.w3.org/TR/WGSL/#alignment-and-size, table titled
527 // "Alignment and size for host-shareable types". WGSL does not have an i16 type, so short and
528 // unsigned-short integer types are treated as full-size integers in WGSL.
529
530 // scalars (i32, u32, f32, f16)
531 REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fInt));
532 REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fUInt));
533 REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fShort));
534 REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fUShort));
535 REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fFloat));
536 REPORTER_ASSERT(r, 2 == layout.size(*context.fTypes.fHalf));
537 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fInt));
538 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fUInt));
539 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fShort));
540 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fUShort));
541 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fFloat));
542 REPORTER_ASSERT(r, 2 == layout.alignment(*context.fTypes.fHalf));
543
544 // vec2<T>, T: i32, u32, f32, f16
545 REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fInt2));
546 REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fUInt2));
547 REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fShort2));
548 REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fUShort2));
549 REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fFloat2));
550 REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fHalf2));
551 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fInt2));
552 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fUInt2));
553 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fShort2));
554 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fUShort2));
555 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fFloat2));
556 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fHalf2));
557
558 // vec3<T>, T: i32, u32, f32, f16
559 REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fInt3));
560 REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fUInt3));
561 REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fShort3));
562 REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fUShort3));
563 REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fFloat3));
564 REPORTER_ASSERT(r, 6 == layout.size(*context.fTypes.fHalf3));
565 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fInt3));
566 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fUInt3));
567 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fShort3));
568 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fUShort3));
569 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat3));
570 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf3));
571
572 // vec4<T>, T: i32, u32, f32, f16
573 REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fInt4));
574 REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fUInt4));
575 REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fShort4));
576 REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fUShort4));
577 REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fFloat4));
578 REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fHalf4));
579 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fInt4));
580 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fUInt4));
581 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fShort4));
582 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fUShort4));
583 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat4));
584 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf4));
585
586 // mat2x2<f32>, mat2x2<f16>
587 REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fFloat2x2));
588 REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fHalf2x2));
589 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fFloat2x2));
590 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fHalf2x2));
591 REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fFloat2x2));
592 REPORTER_ASSERT(r, 4 == layout.stride(*context.fTypes.fHalf2x2));
593
594 // mat3x2<f32>, mat3x2<f16>
595 REPORTER_ASSERT(r, 24 == layout.size(*context.fTypes.fFloat3x2));
596 REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fHalf3x2));
597 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fFloat3x2));
598 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fHalf3x2));
599 REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fFloat3x2));
600 REPORTER_ASSERT(r, 4 == layout.stride(*context.fTypes.fHalf3x2));
601
602 // mat4x2<f32>, mat4x2<f16>
603 REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fFloat4x2));
604 REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fHalf4x2));
605 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fFloat4x2));
606 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fHalf4x2));
607 REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fFloat4x2));
608 REPORTER_ASSERT(r, 4 == layout.stride(*context.fTypes.fHalf4x2));
609
610 // mat2x3<f32>, mat2x3<f16>
611 REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fFloat2x3));
612 REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fHalf2x3));
613 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat2x3));
614 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf2x3));
615 REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fFloat2x3));
616 REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fHalf2x3));
617
618 // mat3x3<f32>, mat3x3<f16>
619 REPORTER_ASSERT(r, 48 == layout.size(*context.fTypes.fFloat3x3));
620 REPORTER_ASSERT(r, 24 == layout.size(*context.fTypes.fHalf3x3));
621 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat3x3));
622 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf3x3));
623 REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fFloat3x3));
624 REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fHalf3x3));
625
626 // mat4x3<f32>, mat4x3<f16>
627 REPORTER_ASSERT(r, 64 == layout.size(*context.fTypes.fFloat4x3));
628 REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fHalf4x3));
629 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat4x3));
630 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf4x3));
631 REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fFloat4x3));
632 REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fHalf4x3));
633
634 // mat2x4<f32>, mat2x4<f16>
635 REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fFloat2x4));
636 REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fHalf2x4));
637 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat2x4));
638 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf2x4));
639 REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fFloat2x4));
640 REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fHalf2x4));
641
642 // mat3x4<f32>, mat3x4<f16>
643 REPORTER_ASSERT(r, 48 == layout.size(*context.fTypes.fFloat3x4));
644 REPORTER_ASSERT(r, 24 == layout.size(*context.fTypes.fHalf3x4));
645 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat3x4));
646 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf3x4));
647 REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fFloat3x4));
648 REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fHalf3x4));
649
650 // mat4x4<f32>, mat4x4<f16>
651 REPORTER_ASSERT(r, 64 == layout.size(*context.fTypes.fFloat4x4));
652 REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fHalf4x4));
653 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat4x4));
654 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf4x4));
655 REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fFloat4x4));
656 REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fHalf4x4));
657
658 // atomic<u32>
659 REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fAtomicUInt));
660 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fAtomicUInt));
661
662 // bool is not a host-shareable type and returns 0 for WGSL.
663 REPORTER_ASSERT(r, 0 == layout.size(*context.fTypes.fBool));
664 REPORTER_ASSERT(r, 0 == layout.size(*context.fTypes.fBool2));
665 REPORTER_ASSERT(r, 0 == layout.size(*context.fTypes.fBool3));
666 REPORTER_ASSERT(r, 0 == layout.size(*context.fTypes.fBool4));
667
668 // Arrays
669 // array<f32, 4>
670 {
671 auto array = SkSL::Type::MakeArrayType(context, "float[4]", *context.fTypes.fFloat, 4);
672 REPORTER_ASSERT(r, 64 == layout.size(*array));
673 REPORTER_ASSERT(r, 16 == layout.alignment(*array));
674 REPORTER_ASSERT(r, 16 == layout.stride(*array));
675 }
676 // array<f16, 4>
677 {
678 auto array = SkSL::Type::MakeArrayType(context, "half[4]", *context.fTypes.fHalf, 4);
679 REPORTER_ASSERT(r, 64 == layout.size(*array));
680 REPORTER_ASSERT(r, 16 == layout.alignment(*array));
681 REPORTER_ASSERT(r, 16 == layout.stride(*array));
682 }
683 // array<vec2<f32>, 4>
684 {
685 auto array = SkSL::Type::MakeArrayType(context, "float2[4]", *context.fTypes.fFloat2, 4);
686 REPORTER_ASSERT(r, 64 == layout.size(*array));
687 REPORTER_ASSERT(r, 16 == layout.alignment(*array));
688 REPORTER_ASSERT(r, 16 == layout.stride(*array));
689 }
690 // array<vec3<f32>, 4>
691 {
692 auto array = SkSL::Type::MakeArrayType(context, "float3[4]", *context.fTypes.fFloat3, 4);
693 REPORTER_ASSERT(r, 64 == layout.size(*array));
694 REPORTER_ASSERT(r, 16 == layout.alignment(*array));
695 REPORTER_ASSERT(r, 16 == layout.stride(*array));
696 }
697 // array<vec4<f32>, 4>
698 {
699 auto array = SkSL::Type::MakeArrayType(context, "float4[4]", *context.fTypes.fFloat4, 4);
700 REPORTER_ASSERT(r, 64 == layout.size(*array));
701 REPORTER_ASSERT(r, 16 == layout.alignment(*array));
702 REPORTER_ASSERT(r, 16 == layout.stride(*array));
703 }
704 // array<mat3x3<f32>, 4>
705 {
706 auto array = SkSL::Type::MakeArrayType(context, "mat3[4]", *context.fTypes.fFloat3x3, 4);
707 REPORTER_ASSERT(r, 192 == layout.size(*array));
708 REPORTER_ASSERT(r, 16 == layout.alignment(*array));
709 REPORTER_ASSERT(r, 48 == layout.stride(*array));
710 }
711
712 // Structs A and B from example in https://www.w3.org/TR/WGSL/#structure-member-layout, with
713 // offsets adjusted for uniform address space constraints.
714 //
715 // struct A { // align(roundUp(16, 8)) size(roundUp(16, 24))
716 // u: f32, // offset(0) align(4) size(4)
717 // v: f32, // offset(4) align(4) size(4)
718 // w: vec2<f32>, // offset(8) align(8) size(8)
719 // x: f32 // offset(16) align(4) size(4)
720 // // padding // offset(20) size(12)
721 // }
722 TArray<SkSL::Field> fields;
724 SkSL::Layout(),
726 std::string_view("u"),
727 context.fTypes.fFloat.get());
729 SkSL::Layout(),
731 std::string_view("v"),
732 context.fTypes.fFloat.get());
734 SkSL::Layout(),
736 std::string_view("w"),
737 context.fTypes.fFloat2.get());
739 SkSL::Layout(),
741 std::string_view("x"),
742 context.fTypes.fFloat.get());
743 std::unique_ptr<SkSL::Type> structA = SkSL::Type::MakeStructType(
744 context, SkSL::Position(), std::string_view("A"), std::move(fields));
745 REPORTER_ASSERT(r, 32 == layout.size(*structA));
746 REPORTER_ASSERT(r, 16 == layout.alignment(*structA));
747 fields = {};
748
749 // struct B { // align(16) size(208)
750 // a: vec2<f32>, // offset(0) align(8) size(8)
751 // // padding // offset(8) size(8)
752 // b: vec3<f32>, // offset(16) align(16) size(12)
753 // c: f32, // offset(28) align(4) size(4)
754 // d: f32, // offset(32) align(4) size(4)
755 // // padding // offset(36) size(12)
756 // e: A, // offset(48) align(16) size(32)
757 // f: vec3<f32>, // offset(80) align(16) size(12)
758 // // padding // offset(92) size(4)
759 // g: array<A, 3>, // offset(96) align(16) size(96)
760 // h: i32 // offset(192) align(4) size(4)
761 // // padding // offset(196) size(12)
762 // }
764 SkSL::Layout(),
766 std::string_view("a"),
767 context.fTypes.fFloat2.get());
769 SkSL::Layout(),
771 std::string_view("b"),
772 context.fTypes.fFloat3.get());
774 SkSL::Layout(),
776 std::string_view("c"),
777 context.fTypes.fFloat.get());
779 SkSL::Layout(),
781 std::string_view("d"),
782 context.fTypes.fFloat.get());
784 SkSL::Layout(),
786 std::string_view("e"),
787 structA.get());
789 SkSL::Layout(),
791 std::string_view("f"),
792 context.fTypes.fFloat3.get());
793 auto array = SkSL::Type::MakeArrayType(context, "A[3]", *structA, 3);
795 SkSL::Layout(),
797 std::string_view("g"),
798 array.get());
800 SkSL::Layout(),
802 std::string_view("h"),
803 context.fTypes.fInt.get());
804 std::unique_ptr<SkSL::Type> structB = SkSL::Type::MakeStructType(
805 context, SkSL::Position(), std::string_view("B"), std::move(fields));
806 REPORTER_ASSERT(r, 208 == layout.size(*structB));
807 REPORTER_ASSERT(r, 16 == layout.alignment(*structB));
808}
809
810DEF_TEST(SkSLMemoryLayoutTest_WGSLStorage_Base, r) {
812 SkSL::BuiltinTypes types;
813 SkSL::Context context(types, errors);
815 SkSL::ProgramConfig config = {};
816 context.fConfig = &config;
817
818 // The values here are taken from https://www.w3.org/TR/WGSL/#alignment-and-size, table titled
819 // "Alignment and size for host-shareable types".
820
821 // scalars (i32, u32, f32, f16)
822 REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fInt));
823 REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fUInt));
824 REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fShort));
825 REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fUShort));
826 REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fFloat));
827 REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fHalf));
828 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fInt));
829 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fUInt));
830 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fShort));
831 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fUShort));
832 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fFloat));
833 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fHalf));
834
835 // vec2<T>, T: i32, u32, f32, f16
836 REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fInt2));
837 REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fUInt2));
838 REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fShort2));
839 REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fUShort2));
840 REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fFloat2));
841 REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fHalf2));
842 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fInt2));
843 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fUInt2));
844 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fShort2));
845 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fUShort2));
846 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fFloat2));
847 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf2));
848
849 // vec3<T>, T: i32, u32, f32, f16
850 REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fInt3));
851 REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fUInt3));
852 REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fShort3));
853 REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fUShort3));
854 REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fFloat3));
855 REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fHalf3));
856 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fInt3));
857 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fUInt3));
858 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fShort3));
859 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fUShort3));
860 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat3));
861 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fHalf3));
862
863 // vec4<T>, T: i32, u32, f32, f16
864 REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fInt4));
865 REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fUInt4));
866 REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fShort4));
867 REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fUShort4));
868 REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fFloat4));
869 REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fHalf4));
870 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fInt4));
871 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fUInt4));
872 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fShort4));
873 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fUShort4));
874 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat4));
875 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fHalf4));
876
877 // mat2x2<f32>, mat2x2<f16>
878 REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fFloat2x2));
879 REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fHalf2x2));
880 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fFloat2x2));
881 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf2x2));
882 REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fFloat2x2));
883 REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fHalf2x2));
884
885 // mat3x2<f32>, mat3x2<f16>
886 REPORTER_ASSERT(r, 24 == layout.size(*context.fTypes.fFloat3x2));
887 REPORTER_ASSERT(r, 24 == layout.size(*context.fTypes.fHalf3x2));
888 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fFloat3x2));
889 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf3x2));
890 REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fFloat3x2));
891 REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fHalf3x2));
892
893 // mat4x2<f32>, mat4x2<f16>
894 REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fFloat4x2));
895 REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fHalf4x2));
896 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fFloat4x2));
897 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf4x2));
898 REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fFloat4x2));
899 REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fHalf4x2));
900
901 // mat2x3<f32>, mat2x3<f16>
902 REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fFloat2x3));
903 REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fHalf2x3));
904 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat2x3));
905 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fHalf2x3));
906 REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fFloat2x3));
907 REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fHalf2x3));
908
909 // mat3x3<f32>, mat3x3<f16>
910 REPORTER_ASSERT(r, 48 == layout.size(*context.fTypes.fFloat3x3));
911 REPORTER_ASSERT(r, 48 == layout.size(*context.fTypes.fHalf3x3));
912 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat3x3));
913 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fHalf3x3));
914 REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fFloat3x3));
915 REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fHalf3x3));
916
917 // mat4x3<f32>, mat4x3<f16>
918 REPORTER_ASSERT(r, 64 == layout.size(*context.fTypes.fFloat4x3));
919 REPORTER_ASSERT(r, 64 == layout.size(*context.fTypes.fHalf4x3));
920 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat4x3));
921 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fHalf4x3));
922 REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fFloat4x3));
923 REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fHalf4x3));
924
925 // mat2x4<f32>, mat2x4<f16>
926 REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fFloat2x4));
927 REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fHalf2x4));
928 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat2x4));
929 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fHalf2x4));
930 REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fFloat2x4));
931 REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fHalf2x4));
932
933 // mat3x4<f32>, mat3x4<f16>
934 REPORTER_ASSERT(r, 48 == layout.size(*context.fTypes.fFloat3x4));
935 REPORTER_ASSERT(r, 48 == layout.size(*context.fTypes.fHalf3x4));
936 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat3x4));
937 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fHalf3x4));
938 REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fFloat3x4));
939 REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fHalf3x4));
940
941 // mat4x4<f32>, mat4x4<f16>
942 REPORTER_ASSERT(r, 64 == layout.size(*context.fTypes.fFloat4x4));
943 REPORTER_ASSERT(r, 64 == layout.size(*context.fTypes.fHalf4x4));
944 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat4x4));
945 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fHalf4x4));
946 REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fFloat4x4));
947 REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fHalf4x4));
948
949 // atomic<u32>
950 REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fAtomicUInt));
951 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fAtomicUInt));
952
953 // bool is not a host-shareable type and returns 0 for WGSL.
954 REPORTER_ASSERT(r, 0 == layout.size(*context.fTypes.fBool));
955 REPORTER_ASSERT(r, 0 == layout.size(*context.fTypes.fBool2));
956 REPORTER_ASSERT(r, 0 == layout.size(*context.fTypes.fBool3));
957 REPORTER_ASSERT(r, 0 == layout.size(*context.fTypes.fBool4));
958
959 // Arrays
960 // array<f32, 4>
961 {
962 auto array = SkSL::Type::MakeArrayType(context, "float[4]", *context.fTypes.fFloat, 4);
963 REPORTER_ASSERT(r, 16 == layout.size(*array));
964 REPORTER_ASSERT(r, 4 == layout.alignment(*array));
965 REPORTER_ASSERT(r, 4 == layout.stride(*array));
966 }
967 // array<f16, 4>
968 {
969 auto array = SkSL::Type::MakeArrayType(context, "half[4]", *context.fTypes.fHalf, 4);
970 REPORTER_ASSERT(r, 16 == layout.size(*array));
971 REPORTER_ASSERT(r, 4 == layout.alignment(*array));
972 REPORTER_ASSERT(r, 4 == layout.stride(*array));
973 }
974 // array<vec2<f32>, 4>
975 {
976 auto array = SkSL::Type::MakeArrayType(context, "float2[4]", *context.fTypes.fFloat2, 4);
977 REPORTER_ASSERT(r, 32 == layout.size(*array));
978 REPORTER_ASSERT(r, 8 == layout.alignment(*array));
979 REPORTER_ASSERT(r, 8 == layout.stride(*array));
980 }
981 // array<vec3<f32>, 4>
982 {
983 auto array = SkSL::Type::MakeArrayType(context, "float3[4]", *context.fTypes.fFloat3, 4);
984 REPORTER_ASSERT(r, 64 == layout.size(*array));
985 REPORTER_ASSERT(r, 16 == layout.alignment(*array));
986 REPORTER_ASSERT(r, 16 == layout.stride(*array));
987 }
988 // array<vec4<f32>, 4>
989 {
990 auto array = SkSL::Type::MakeArrayType(context, "float4[4]", *context.fTypes.fFloat4, 4);
991 REPORTER_ASSERT(r, 64 == layout.size(*array));
992 REPORTER_ASSERT(r, 16 == layout.alignment(*array));
993 REPORTER_ASSERT(r, 16 == layout.stride(*array));
994 }
995 // array<mat3x3<f32>, 4>
996 {
997 auto array = SkSL::Type::MakeArrayType(context, "mat3[4]", *context.fTypes.fFloat3x3, 4);
998 REPORTER_ASSERT(r, 192 == layout.size(*array));
999 REPORTER_ASSERT(r, 16 == layout.alignment(*array));
1000 REPORTER_ASSERT(r, 48 == layout.stride(*array));
1001 }
1002
1003 // Structs A and B from example in https://www.w3.org/TR/WGSL/#structure-member-layout
1004 //
1005 // struct A { // align(8) size(24)
1006 // u: f32, // offset(0) align(4) size(4)
1007 // v: f32, // offset(4) align(4) size(4)
1008 // w: vec2<f32>, // offset(8) align(8) size(8)
1009 // x: f32 // offset(16) align(4) size(4)
1010 // // padding // offset(20) size(4)
1011 // }
1012 TArray<SkSL::Field> fields;
1014 SkSL::Layout(),
1016 std::string_view("u"),
1017 context.fTypes.fFloat.get());
1019 SkSL::Layout(),
1021 std::string_view("v"),
1022 context.fTypes.fFloat.get());
1024 SkSL::Layout(),
1026 std::string_view("w"),
1027 context.fTypes.fFloat2.get());
1029 SkSL::Layout(),
1031 std::string_view("x"),
1032 context.fTypes.fFloat.get());
1033 std::unique_ptr<SkSL::Type> structA = SkSL::Type::MakeStructType(
1034 context, SkSL::Position(), std::string_view("A"), std::move(fields));
1035 REPORTER_ASSERT(r, 24 == layout.size(*structA));
1036 REPORTER_ASSERT(r, 8 == layout.alignment(*structA));
1037 fields = {};
1038
1039 // struct B { // align(16) size(160)
1040 // a: vec2<f32>, // offset(0) align(8) size(8)
1041 // // padding // offset(8) size(8)
1042 // b: vec3<f32>, // offset(16) align(16) size(12)
1043 // c: f32, // offset(28) align(4) size(4)
1044 // d: f32, // offset(32) align(4) size(4)
1045 // // padding // offset(36) size(4)
1046 // e: A, // offset(40) align(8) size(24)
1047 // f: vec3<f32>, // offset(64) align(16) size(12)
1048 // // padding // offset(76) size(4)
1049 // g: array<A, 3>, // offset(80) align(16) size(72)
1050 // h: i32 // offset(152) align(4) size(4)
1051 // // padding // offset(156) size(4)
1052 // }
1054 SkSL::Layout(),
1056 std::string_view("a"),
1057 context.fTypes.fFloat2.get());
1059 SkSL::Layout(),
1061 std::string_view("b"),
1062 context.fTypes.fFloat3.get());
1064 SkSL::Layout(),
1066 std::string_view("c"),
1067 context.fTypes.fFloat.get());
1069 SkSL::Layout(),
1071 std::string_view("d"),
1072 context.fTypes.fFloat.get());
1074 SkSL::Layout(),
1076 std::string_view("e"),
1077 structA.get());
1079 SkSL::Layout(),
1081 std::string_view("f"),
1082 context.fTypes.fFloat3.get());
1083 auto array = SkSL::Type::MakeArrayType(context, "A[3]", *structA, 3);
1085 SkSL::Layout(),
1087 std::string_view("g"),
1088 array.get());
1090 SkSL::Layout(),
1092 std::string_view("h"),
1093 context.fTypes.fInt.get());
1094 std::unique_ptr<SkSL::Type> structB = SkSL::Type::MakeStructType(
1095 context, SkSL::Position(), std::string_view("B"), std::move(fields));
1096 REPORTER_ASSERT(r, 160 == layout.size(*structB));
1097 REPORTER_ASSERT(r, 16 == layout.alignment(*structB));
1098}
1099
1100DEF_TEST(SkSLMemoryLayoutTest_WGSLStorage_EnableF16, r) {
1102 SkSL::BuiltinTypes types;
1103 SkSL::Context context(types, errors);
1105 SkSL::ProgramConfig config = {};
1106 context.fConfig = &config;
1107
1108 // The values here are taken from https://www.w3.org/TR/WGSL/#alignment-and-size, table titled
1109 // "Alignment and size for host-shareable types".
1110
1111 // scalars (i32, u32, f32, f16)
1112 REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fInt));
1113 REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fUInt));
1114 REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fShort));
1115 REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fUShort));
1116 REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fFloat));
1117 REPORTER_ASSERT(r, 2 == layout.size(*context.fTypes.fHalf));
1118 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fInt));
1119 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fUInt));
1120 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fShort));
1121 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fUShort));
1122 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fFloat));
1123 REPORTER_ASSERT(r, 2 == layout.alignment(*context.fTypes.fHalf));
1124
1125 // vec2<T>, T: i32, u32, f32, f16
1126 REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fInt2));
1127 REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fUInt2));
1128 REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fShort2));
1129 REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fUShort2));
1130 REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fFloat2));
1131 REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fHalf2));
1132 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fInt2));
1133 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fUInt2));
1134 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fShort2));
1135 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fUShort2));
1136 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fFloat2));
1137 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fHalf2));
1138
1139 // vec3<T>, T: i32, u32, f32, f16
1140 REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fInt3));
1141 REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fUInt3));
1142 REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fShort3));
1143 REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fUShort3));
1144 REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fFloat3));
1145 REPORTER_ASSERT(r, 6 == layout.size(*context.fTypes.fHalf3));
1146 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fInt3));
1147 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fUInt3));
1148 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fShort3));
1149 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fUShort3));
1150 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat3));
1151 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf3));
1152
1153 // vec4<T>, T: i32, u32, f32, f16
1154 REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fInt4));
1155 REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fUInt4));
1156 REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fShort4));
1157 REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fUShort4));
1158 REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fFloat4));
1159 REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fHalf4));
1160 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fInt4));
1161 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fUInt4));
1162 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fShort4));
1163 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fUShort4));
1164 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat4));
1165 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf4));
1166
1167 // mat2x2<f32>, mat2x2<f16>
1168 REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fFloat2x2));
1169 REPORTER_ASSERT(r, 8 == layout.size(*context.fTypes.fHalf2x2));
1170 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fFloat2x2));
1171 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fHalf2x2));
1172 REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fFloat2x2));
1173 REPORTER_ASSERT(r, 4 == layout.stride(*context.fTypes.fHalf2x2));
1174
1175 // mat3x2<f32>, mat3x2<f16>
1176 REPORTER_ASSERT(r, 24 == layout.size(*context.fTypes.fFloat3x2));
1177 REPORTER_ASSERT(r, 12 == layout.size(*context.fTypes.fHalf3x2));
1178 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fFloat3x2));
1179 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fHalf3x2));
1180 REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fFloat3x2));
1181 REPORTER_ASSERT(r, 4 == layout.stride(*context.fTypes.fHalf3x2));
1182
1183 // mat4x2<f32>, mat4x2<f16>
1184 REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fFloat4x2));
1185 REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fHalf4x2));
1186 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fFloat4x2));
1187 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fHalf4x2));
1188 REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fFloat4x2));
1189 REPORTER_ASSERT(r, 4 == layout.stride(*context.fTypes.fHalf4x2));
1190
1191 // mat2x3<f32>, mat2x3<f16>
1192 REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fFloat2x3));
1193 REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fHalf2x3));
1194 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat2x3));
1195 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf2x3));
1196 REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fFloat2x3));
1197 REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fHalf2x3));
1198
1199 // mat3x3<f32>, mat3x3<f16>
1200 REPORTER_ASSERT(r, 48 == layout.size(*context.fTypes.fFloat3x3));
1201 REPORTER_ASSERT(r, 24 == layout.size(*context.fTypes.fHalf3x3));
1202 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat3x3));
1203 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf3x3));
1204 REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fFloat3x3));
1205 REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fHalf3x3));
1206
1207 // mat4x3<f32>, mat4x3<f16>
1208 REPORTER_ASSERT(r, 64 == layout.size(*context.fTypes.fFloat4x3));
1209 REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fHalf4x3));
1210 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat4x3));
1211 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf4x3));
1212 REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fFloat4x3));
1213 REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fHalf4x3));
1214
1215 // mat2x4<f32>, mat2x4<f16>
1216 REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fFloat2x4));
1217 REPORTER_ASSERT(r, 16 == layout.size(*context.fTypes.fHalf2x4));
1218 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat2x4));
1219 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf2x4));
1220 REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fFloat2x4));
1221 REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fHalf2x4));
1222
1223 // mat3x4<f32>, mat3x4<f16>
1224 REPORTER_ASSERT(r, 48 == layout.size(*context.fTypes.fFloat3x4));
1225 REPORTER_ASSERT(r, 24 == layout.size(*context.fTypes.fHalf3x4));
1226 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat3x4));
1227 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf3x4));
1228 REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fFloat3x4));
1229 REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fHalf3x4));
1230
1231 // mat4x4<f32>, mat4x4<f16>
1232 REPORTER_ASSERT(r, 64 == layout.size(*context.fTypes.fFloat4x4));
1233 REPORTER_ASSERT(r, 32 == layout.size(*context.fTypes.fHalf4x4));
1234 REPORTER_ASSERT(r, 16 == layout.alignment(*context.fTypes.fFloat4x4));
1235 REPORTER_ASSERT(r, 8 == layout.alignment(*context.fTypes.fHalf4x4));
1236 REPORTER_ASSERT(r, 16 == layout.stride(*context.fTypes.fFloat4x4));
1237 REPORTER_ASSERT(r, 8 == layout.stride(*context.fTypes.fHalf4x4));
1238
1239 // atomic<u32>
1240 REPORTER_ASSERT(r, 4 == layout.size(*context.fTypes.fAtomicUInt));
1241 REPORTER_ASSERT(r, 4 == layout.alignment(*context.fTypes.fAtomicUInt));
1242
1243 // bool is not a host-shareable type and returns 0 for WGSL.
1244 REPORTER_ASSERT(r, 0 == layout.size(*context.fTypes.fBool));
1245 REPORTER_ASSERT(r, 0 == layout.size(*context.fTypes.fBool2));
1246 REPORTER_ASSERT(r, 0 == layout.size(*context.fTypes.fBool3));
1247 REPORTER_ASSERT(r, 0 == layout.size(*context.fTypes.fBool4));
1248
1249 // Arrays
1250 // array<f32, 4>
1251 {
1252 auto array = SkSL::Type::MakeArrayType(context, "float[4]", *context.fTypes.fFloat, 4);
1253 REPORTER_ASSERT(r, 16 == layout.size(*array));
1254 REPORTER_ASSERT(r, 4 == layout.alignment(*array));
1255 REPORTER_ASSERT(r, 4 == layout.stride(*array));
1256 }
1257 // array<f16, 4>
1258 {
1259 auto array = SkSL::Type::MakeArrayType(context, "half[4]", *context.fTypes.fHalf, 4);
1260 REPORTER_ASSERT(r, 8 == layout.size(*array));
1261 REPORTER_ASSERT(r, 2 == layout.alignment(*array));
1262 REPORTER_ASSERT(r, 2 == layout.stride(*array));
1263 }
1264 // array<vec2<f32>, 4>
1265 {
1266 auto array = SkSL::Type::MakeArrayType(context, "float2[4]", *context.fTypes.fFloat2, 4);
1267 REPORTER_ASSERT(r, 32 == layout.size(*array));
1268 REPORTER_ASSERT(r, 8 == layout.alignment(*array));
1269 REPORTER_ASSERT(r, 8 == layout.stride(*array));
1270 }
1271 // array<vec3<f32>, 4>
1272 {
1273 auto array = SkSL::Type::MakeArrayType(context, "float3[4]", *context.fTypes.fFloat3, 4);
1274 REPORTER_ASSERT(r, 64 == layout.size(*array));
1275 REPORTER_ASSERT(r, 16 == layout.alignment(*array));
1276 REPORTER_ASSERT(r, 16 == layout.stride(*array));
1277 }
1278 // array<vec4<f32>, 4>
1279 {
1280 auto array = SkSL::Type::MakeArrayType(context, "float4[4]", *context.fTypes.fFloat4, 4);
1281 REPORTER_ASSERT(r, 64 == layout.size(*array));
1282 REPORTER_ASSERT(r, 16 == layout.alignment(*array));
1283 REPORTER_ASSERT(r, 16 == layout.stride(*array));
1284 }
1285 // array<mat3x3<f32>, 4>
1286 {
1287 auto array = SkSL::Type::MakeArrayType(context, "mat3[4]", *context.fTypes.fFloat3x3, 4);
1288 REPORTER_ASSERT(r, 192 == layout.size(*array));
1289 REPORTER_ASSERT(r, 16 == layout.alignment(*array));
1290 REPORTER_ASSERT(r, 48 == layout.stride(*array));
1291 }
1292
1293 // Structs A and B from example in https://www.w3.org/TR/WGSL/#structure-member-layout
1294 //
1295 // struct A { // align(8) size(24)
1296 // u: f32, // offset(0) align(4) size(4)
1297 // v: f32, // offset(4) align(4) size(4)
1298 // w: vec2<f32>, // offset(8) align(8) size(8)
1299 // x: f32 // offset(16) align(4) size(4)
1300 // // padding // offset(20) size(4)
1301 // }
1302 TArray<SkSL::Field> fields;
1304 SkSL::Layout(),
1306 std::string_view("u"),
1307 context.fTypes.fFloat.get());
1309 SkSL::Layout(),
1311 std::string_view("v"),
1312 context.fTypes.fFloat.get());
1314 SkSL::Layout(),
1316 std::string_view("w"),
1317 context.fTypes.fFloat2.get());
1319 SkSL::Layout(),
1321 std::string_view("x"),
1322 context.fTypes.fFloat.get());
1323 std::unique_ptr<SkSL::Type> structA = SkSL::Type::MakeStructType(
1324 context, SkSL::Position(), std::string_view("A"), std::move(fields));
1325 REPORTER_ASSERT(r, 24 == layout.size(*structA));
1326 REPORTER_ASSERT(r, 8 == layout.alignment(*structA));
1327 fields = {};
1328
1329 // struct B { // align(16) size(160)
1330 // a: vec2<f32>, // offset(0) align(8) size(8)
1331 // // padding // offset(8) size(8)
1332 // b: vec3<f32>, // offset(16) align(16) size(12)
1333 // c: f32, // offset(28) align(4) size(4)
1334 // d: f32, // offset(32) align(4) size(4)
1335 // // padding // offset(36) size(4)
1336 // e: A, // offset(40) align(8) size(24)
1337 // f: vec3<f32>, // offset(64) align(16) size(12)
1338 // // padding // offset(76) size(4)
1339 // g: array<A, 3>, // offset(80) align(16) size(72)
1340 // h: i32 // offset(152) align(4) size(4)
1341 // // padding // offset(156) size(4)
1342 // }
1344 SkSL::Layout(),
1346 std::string_view("a"),
1347 context.fTypes.fFloat2.get());
1349 SkSL::Layout(),
1351 std::string_view("b"),
1352 context.fTypes.fFloat3.get());
1354 SkSL::Layout(),
1356 std::string_view("c"),
1357 context.fTypes.fFloat.get());
1359 SkSL::Layout(),
1361 std::string_view("d"),
1362 context.fTypes.fFloat.get());
1364 SkSL::Layout(),
1366 std::string_view("e"),
1367 structA.get());
1369 SkSL::Layout(),
1371 std::string_view("f"),
1372 context.fTypes.fFloat3.get());
1373 auto array = SkSL::Type::MakeArrayType(context, "A[3]", *structA, 3);
1375 SkSL::Layout(),
1377 std::string_view("g"),
1378 array.get());
1380 SkSL::Layout(),
1382 std::string_view("h"),
1383 context.fTypes.fInt.get());
1384 std::unique_ptr<SkSL::Type> structB = SkSL::Type::MakeStructType(
1385 context, SkSL::Position(), std::string_view("B"), std::move(fields));
1386 REPORTER_ASSERT(r, 160 == layout.size(*structB));
1387 REPORTER_ASSERT(r, 16 == layout.alignment(*structB));
1388}
1389
1390DEF_TEST(SkSLMemoryLayoutTest_WGSLUnsupportedTypes, r) {
1392 SkSL::BuiltinTypes types;
1393 SkSL::Context context(types, errors);
1394 SkSL::ProgramConfig config = {};
1395 context.fConfig = &config;
1396
1397 auto testArray = SkSL::Type::MakeArrayType(context, "bool[3]", *context.fTypes.fBool, 3);
1398
1399 TArray<SkSL::Field> fields;
1401 SkSL::Layout(),
1403 std::string_view("foo"),
1404 testArray.get());
1405 auto testStruct = SkSL::Type::MakeStructType(
1406 context, SkSL::Position(), std::string_view("Test"), std::move(fields));
1407
1409 REPORTER_ASSERT(r, !layout.isSupported(*context.fTypes.fBool));
1410 REPORTER_ASSERT(r, !layout.isSupported(*context.fTypes.fBool2));
1411 REPORTER_ASSERT(r, !layout.isSupported(*context.fTypes.fBool3));
1412 REPORTER_ASSERT(r, !layout.isSupported(*context.fTypes.fBool4));
1413 REPORTER_ASSERT(r, !layout.isSupported(*testArray));
1414 REPORTER_ASSERT(r, !layout.isSupported(*testStruct));
1415}
1416
1417DEF_TEST(SkSLMemoryLayoutTest_WGSLSupportedTypes, r) {
1419 SkSL::BuiltinTypes types;
1420 SkSL::Context context(types, errors);
1421 SkSL::ProgramConfig config = {};
1422 context.fConfig = &config;
1423
1424 auto testArray = SkSL::Type::MakeArrayType(context, "float[3]", *context.fTypes.fFloat, 3);
1425
1426 TArray<SkSL::Field> fields;
1428 SkSL::Layout(),
1430 std::string_view("foo"),
1431 testArray.get());
1432 auto testStruct = SkSL::Type::MakeStructType(
1433 context, SkSL::Position(), std::string_view("Test"), std::move(fields));
1434
1436
1437 // scalars (i32, u32, f32, f16)
1438 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fInt));
1439 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fUInt));
1440 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fShort));
1441 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fUShort));
1442 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fFloat));
1443 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fHalf));
1444
1445 // vec2<T>, T: i32, u32, f32, f16
1446 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fInt2));
1447 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fUInt2));
1448 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fShort2));
1449 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fUShort2));
1450 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fFloat2));
1451 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fHalf2));
1452
1453 // vec3<T>, T: i32, u32, f32, f16
1454 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fInt3));
1455 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fUInt3));
1456 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fShort3));
1457 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fUShort3));
1458 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fFloat3));
1459 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fHalf3));
1460
1461 // vec4<T>, T: i32, u32, f32, f16
1462 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fInt4));
1463 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fUInt4));
1464 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fFloat4));
1465 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fShort4));
1466 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fUShort4));
1467 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fHalf4));
1468
1469 // mat2x2<f32>, mat2x2<f16>
1470 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fFloat2x2));
1471 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fHalf2x2));
1472
1473 // mat3x2<f32>, mat3x2<f16>
1474 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fFloat3x2));
1475 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fHalf3x2));
1476
1477 // mat4x2<f32>, mat4x2<f16>
1478 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fFloat4x2));
1479 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fHalf4x2));
1480
1481 // mat2x3<f32>, mat2x3<f16>
1482 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fFloat2x3));
1483 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fHalf2x3));
1484
1485 // mat3x3<f32>, mat3x3<f16>
1486 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fFloat3x3));
1487 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fHalf3x3));
1488
1489 // mat4x3<f32>, mat4x3<f16>
1490 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fFloat4x3));
1491 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fHalf4x3));
1492
1493 // mat2x4<f32>, mat2x4<f16>
1494 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fFloat2x4));
1495 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fHalf2x4));
1496
1497 // mat3x4<f32>, mat3x4<f16>
1498 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fFloat3x4));
1499 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fHalf3x4));
1500
1501 // mat4x4<f32>, mat4x4<f16>
1502 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fFloat4x4));
1503 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fHalf4x4));
1504
1505 // atomic<u32>
1506 REPORTER_ASSERT(r, layout.isSupported(*context.fTypes.fAtomicUInt));
1507
1508 // arrays and structs
1509 REPORTER_ASSERT(r, layout.isSupported(*testArray));
1510 REPORTER_ASSERT(r, layout.isSupported(*testStruct));
1511}
DEF_TEST(SkSLMemoryLayoutTest_std140, r)
#define REPORTER_ASSERT(r, cond,...)
Definition: Test.h:286
const std::unique_ptr< Type > fFloat2
const std::unique_ptr< Type > fHalf4
const std::unique_ptr< Type > fFloat4x3
const std::unique_ptr< Type > fInt4
const std::unique_ptr< Type > fHalf2x3
const std::unique_ptr< Type > fHalf2x2
const std::unique_ptr< Type > fUInt2
const std::unique_ptr< Type > fShort3
const std::unique_ptr< Type > fInt2
const std::unique_ptr< Type > fUShort
const std::unique_ptr< Type > fInt
const std::unique_ptr< Type > fHalf4x3
const std::unique_ptr< Type > fFloat3x2
const std::unique_ptr< Type > fAtomicUInt
const std::unique_ptr< Type > fFloat2x2
const std::unique_ptr< Type > fFloat3x4
const std::unique_ptr< Type > fHalf3x4
const std::unique_ptr< Type > fFloat4x4
const std::unique_ptr< Type > fShort2
const std::unique_ptr< Type > fShort
const std::unique_ptr< Type > fInt3
const std::unique_ptr< Type > fHalf2x4
const std::unique_ptr< Type > fUInt3
const std::unique_ptr< Type > fUShort4
const std::unique_ptr< Type > fFloat4
const std::unique_ptr< Type > fHalf2
const std::unique_ptr< Type > fUInt4
const std::unique_ptr< Type > fHalf3x3
const std::unique_ptr< Type > fShort4
const std::unique_ptr< Type > fBool2
const std::unique_ptr< Type > fFloat3x3
const std::unique_ptr< Type > fUShort2
const std::unique_ptr< Type > fBool3
const std::unique_ptr< Type > fHalf4x2
const std::unique_ptr< Type > fUInt
const std::unique_ptr< Type > fFloat2x3
const std::unique_ptr< Type > fUShort3
const std::unique_ptr< Type > fBool
const std::unique_ptr< Type > fHalf3
const std::unique_ptr< Type > fFloat2x4
const std::unique_ptr< Type > fFloat
const std::unique_ptr< Type > fFloat3
const std::unique_ptr< Type > fHalf
const std::unique_ptr< Type > fHalf3x2
const std::unique_ptr< Type > fHalf4x4
const std::unique_ptr< Type > fFloat4x2
const std::unique_ptr< Type > fBool4
const BuiltinTypes & fTypes
Definition: SkSLContext.h:30
ProgramConfig * fConfig
Definition: SkSLContext.h:33
size_t size(const Type &type) const
size_t stride(const Type &type) const
size_t isSupported(const Type &type) const
size_t alignment(const Type &type) const
static std::unique_ptr< Type > MakeArrayType(const Context &context, std::string_view name, const Type &componentType, int columns)
static std::unique_ptr< Type > MakeStructType(const Context &context, Position pos, std::string_view name, skia_private::TArray< Field > fields, bool interfaceBlock=false)
T & emplace_back(Args &&... args)
Definition: SkTArray.h:248