1 /*
2 * Copyright 2022 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 "src/core/SkSLTypeShared.h"
9 #include "src/gpu/graphite/Uniform.h"
10 #include "src/gpu/graphite/UniformManager.h"
11 #include "tests/Test.h"
12
13 using namespace skgpu::graphite;
14
15 namespace {
16
17 // Used to test the exact alignment and size of an individual type. Returns the alignment and size
18 // as a pair.
19 struct AlignmentAndSize {
20 size_t alignment;
21 size_t size;
22 };
calculate_alignment_and_size(Layout layout,SkSLType type,size_t arrayCount=Uniform::kNonArray)23 static AlignmentAndSize calculate_alignment_and_size(Layout layout,
24 SkSLType type,
25 size_t arrayCount = Uniform::kNonArray) {
26 // Set the start offset at 1 to force alignment.
27 constexpr uint32_t kStart = 1;
28 UniformOffsetCalculator calc(layout, kStart);
29 size_t alignment = calc.advanceOffset(type, arrayCount);
30 return {alignment, calc.size() - alignment};
31 }
32
33 #define EXPECT(type, expectedAlignment, expectedSize) \
34 do { \
35 auto [alignment, size] = calculate_alignment_and_size(kLayout, type); \
36 REPORTER_ASSERT(r, \
37 alignment == expectedAlignment, \
38 "incorrect alignment for type '%s': expected %d, found %zu", \
39 SkSLTypeString(type), \
40 expectedAlignment, \
41 alignment); \
42 REPORTER_ASSERT(r, \
43 size == expectedSize, \
44 "incorrect size for type '%s': expected %d, found %zu", \
45 SkSLTypeString(type), \
46 expectedSize, \
47 size); \
48 } while (0)
49
50 #define EXPECT_ARRAY(type, expectedAlignment, expectedStride, expectedSize) \
51 do { \
52 auto [alignment, size] = calculate_alignment_and_size(kLayout, type, kCount); \
53 size_t stride = size / kCount; \
54 REPORTER_ASSERT(r, \
55 alignment == expectedAlignment, \
56 "incorrect alignment for type '%s': expected %d, found %zu", \
57 SkSLTypeString(type), \
58 expectedAlignment, \
59 alignment); \
60 REPORTER_ASSERT(r, \
61 size == expectedSize, \
62 "incorrect size for type '%s': expected %d, found %zu", \
63 SkSLTypeString(type), \
64 expectedSize, \
65 size); \
66 REPORTER_ASSERT(r, \
67 stride == expectedStride, \
68 "incorrect stride for type '%s': expected %d, found %zu", \
69 SkSLTypeString(type), \
70 expectedStride, \
71 stride); \
72 } while (0)
73
DEF_GRAPHITE_TEST(UniformOffsetCalculatorMetalBasicTypesTest,r,CtsEnforcement::kNextRelease)74 DEF_GRAPHITE_TEST(UniformOffsetCalculatorMetalBasicTypesTest, r, CtsEnforcement::kNextRelease) {
75 constexpr Layout kLayout = Layout::kMetal;
76
77 // scalars: int, float, half (unsigned types are disallowed)
78 EXPECT(SkSLType::kInt, /*alignment=*/4, /*size=*/4);
79 EXPECT(SkSLType::kFloat, /*alignment=*/4, /*size=*/4);
80 EXPECT(SkSLType::kHalf, /*alignment=*/2, /*size=*/2);
81
82 // int2, float2, half2
83 EXPECT(SkSLType::kInt2, /*alignment=*/8, /*size=*/8);
84 EXPECT(SkSLType::kFloat2, /*alignment=*/8, /*size=*/8);
85 EXPECT(SkSLType::kHalf2, /*alignment=*/4, /*size=*/4);
86
87 // int3, float3, half3 (unlike std430, size is also rounded up)
88 EXPECT(SkSLType::kInt3, /*alignment=*/16, /*size=*/16);
89 EXPECT(SkSLType::kFloat3, /*alignment=*/16, /*size=*/16);
90 EXPECT(SkSLType::kHalf3, /*alignment=*/8, /*size=*/8);
91
92 // int4, float4, half4
93 EXPECT(SkSLType::kInt4, /*alignment=*/16, /*size=*/16);
94 EXPECT(SkSLType::kFloat4, /*alignment=*/16, /*size=*/16);
95 EXPECT(SkSLType::kHalf4, /*alignment=*/8, /*size=*/8);
96
97 // float2x2, half2x2
98 EXPECT(SkSLType::kFloat2x2, /*alignment=*/8, /*size=*/16);
99 EXPECT(SkSLType::kHalf2x2, /*alignment=*/4, /*size=*/8);
100
101 // float3x3, half3x3
102 EXPECT(SkSLType::kFloat3x3, /*alignment=*/16, /*size=*/48);
103 EXPECT(SkSLType::kHalf3x3, /*alignment=*/8, /*size=*/24);
104
105 // float4x4, half4x4
106 EXPECT(SkSLType::kFloat4x4, /*alignment=*/16, /*size=*/64);
107 EXPECT(SkSLType::kHalf4x4, /*alignment=*/8, /*size=*/32);
108 }
109
DEF_GRAPHITE_TEST(UniformOffsetCalculatorMetalArrayTest,r,CtsEnforcement::kNextRelease)110 DEF_GRAPHITE_TEST(UniformOffsetCalculatorMetalArrayTest, r, CtsEnforcement::kNextRelease) {
111 constexpr Layout kLayout = Layout::kMetal;
112 constexpr size_t kCount = 3;
113
114 // int[3], float[3], half[3]
115 EXPECT_ARRAY(SkSLType::kInt, /*alignment=*/4, /*stride=*/4, /*size=*/12);
116 EXPECT_ARRAY(SkSLType::kFloat, /*alignment=*/4, /*stride=*/4, /*size=*/12);
117 EXPECT_ARRAY(SkSLType::kHalf, /*alignment=*/2, /*stride=*/2, /*size=*/6);
118
119 // int2[3], float2[3], half2[3]
120 EXPECT_ARRAY(SkSLType::kInt2, /*alignment=*/8, /*stride=*/8, /*size=*/24);
121 EXPECT_ARRAY(SkSLType::kFloat2, /*alignment=*/8, /*stride=*/8, /*size=*/24);
122 EXPECT_ARRAY(SkSLType::kHalf2, /*alignment=*/4, /*stride=*/4, /*size=*/12);
123
124 // int3[3], float3[3], half3[3]
125 EXPECT_ARRAY(SkSLType::kInt3, /*alignment=*/16, /*stride=*/16, /*size=*/48);
126 EXPECT_ARRAY(SkSLType::kFloat3, /*alignment=*/16, /*stride=*/16, /*size=*/48);
127 EXPECT_ARRAY(SkSLType::kHalf3, /*alignment=*/8, /*stride=*/8, /*size=*/24);
128
129 // int4[3], float4[3], half4[3]
130 EXPECT_ARRAY(SkSLType::kInt4, /*alignment=*/16, /*stride=*/16, /*size=*/48);
131 EXPECT_ARRAY(SkSLType::kFloat4, /*alignment=*/16, /*stride=*/16, /*size=*/48);
132 EXPECT_ARRAY(SkSLType::kHalf4, /*alignment=*/8, /*stride=*/8, /*size=*/24);
133
134 // float2x2[3], half2x2[3]
135 EXPECT_ARRAY(SkSLType::kFloat2x2, /*alignment=*/8, /*stride=*/16, /*size=*/48);
136 EXPECT_ARRAY(SkSLType::kHalf2x2, /*alignment=*/4, /*stride=*/8, /*size=*/24);
137
138 // float3x3[3], half3x3[3]
139 EXPECT_ARRAY(SkSLType::kFloat3x3, /*alignment=*/16, /*stride=*/48, /*size=*/144);
140 EXPECT_ARRAY(SkSLType::kHalf3x3, /*alignment=*/8, /*stride=*/24, /*size=*/72);
141
142 // float4x4[3], half4x4[3]
143 EXPECT_ARRAY(SkSLType::kFloat4x4, /*alignment=*/16, /*stride=*/64, /*size=*/192);
144 EXPECT_ARRAY(SkSLType::kHalf4x4, /*alignment=*/8, /*stride=*/32, /*size=*/96);
145 }
146
DEF_GRAPHITE_TEST(UniformOffsetCalculatorStd430BasicTypesTest,r,CtsEnforcement::kNextRelease)147 DEF_GRAPHITE_TEST(UniformOffsetCalculatorStd430BasicTypesTest, r, CtsEnforcement::kNextRelease) {
148 constexpr Layout kLayout = Layout::kStd430;
149
150 // scalars: int, float, half (unsigned types are disallowed)
151 EXPECT(SkSLType::kInt, /*alignment=*/4, /*size=*/4);
152 EXPECT(SkSLType::kFloat, /*alignment=*/4, /*size=*/4);
153 EXPECT(SkSLType::kHalf, /*alignment=*/4, /*size=*/4);
154
155 // int2, float2, half2
156 EXPECT(SkSLType::kInt2, /*alignment=*/8, /*size=*/8);
157 EXPECT(SkSLType::kFloat2, /*alignment=*/8, /*size=*/8);
158 EXPECT(SkSLType::kHalf2, /*alignment=*/8, /*size=*/8);
159
160 // int3, float3, half3 (size is not rounded up for non-arrays of vec3s)
161 EXPECT(SkSLType::kInt3, /*alignment=*/16, /*size=*/12);
162 EXPECT(SkSLType::kFloat3, /*alignment=*/16, /*size=*/12);
163 EXPECT(SkSLType::kHalf3, /*alignment=*/16, /*size=*/12);
164
165 // int4, float4, half4
166 EXPECT(SkSLType::kInt4, /*alignment=*/16, /*size=*/16);
167 EXPECT(SkSLType::kFloat4, /*alignment=*/16, /*size=*/16);
168 EXPECT(SkSLType::kHalf4, /*alignment=*/16, /*size=*/16);
169
170 // float2x2, half2x2
171 EXPECT(SkSLType::kFloat2x2, /*alignment=*/8, /*size=*/16);
172 EXPECT(SkSLType::kHalf2x2, /*alignment=*/8, /*size=*/16);
173
174 // float3x3, half3x3
175 EXPECT(SkSLType::kFloat3x3, /*alignment=*/16, /*size=*/48);
176 EXPECT(SkSLType::kHalf3x3, /*alignment=*/16, /*size=*/48);
177
178 // float4x4, half4x4
179 EXPECT(SkSLType::kFloat4x4, /*alignment=*/16, /*size=*/64);
180 EXPECT(SkSLType::kHalf4x4, /*alignment=*/16, /*size=*/64);
181 }
182
DEF_GRAPHITE_TEST(UniformOffsetCalculatorStd430ArrayTest,r,CtsEnforcement::kNextRelease)183 DEF_GRAPHITE_TEST(UniformOffsetCalculatorStd430ArrayTest, r, CtsEnforcement::kNextRelease) {
184 constexpr Layout kLayout = Layout::kStd430;
185 constexpr size_t kCount = 3;
186
187 // int[3], float[3], half[3]
188 EXPECT_ARRAY(SkSLType::kInt, /*alignment=*/4, /*stride=*/4, /*size=*/12);
189 EXPECT_ARRAY(SkSLType::kFloat, /*alignment=*/4, /*stride=*/4, /*size=*/12);
190 EXPECT_ARRAY(SkSLType::kHalf, /*alignment=*/4, /*stride=*/4, /*size=*/12);
191
192 // int2[3], float2[3], half2[3]
193 EXPECT_ARRAY(SkSLType::kInt2, /*alignment=*/8, /*stride=*/8, /*size=*/24);
194 EXPECT_ARRAY(SkSLType::kFloat2, /*alignment=*/8, /*stride=*/8, /*size=*/24);
195 EXPECT_ARRAY(SkSLType::kHalf2, /*alignment=*/8, /*stride=*/8, /*size=*/24);
196
197 // int3[3], float3[3], half3[3] (stride is rounded up in arrays)
198 EXPECT_ARRAY(SkSLType::kInt3, /*alignment=*/16, /*stride=*/16, /*size=*/48);
199 EXPECT_ARRAY(SkSLType::kFloat3, /*alignment=*/16, /*stride=*/16, /*size=*/48);
200 EXPECT_ARRAY(SkSLType::kHalf3, /*alignment=*/16, /*stride=*/16, /*size=*/48);
201
202 // int4[3], float4[3], half4[3]
203 EXPECT_ARRAY(SkSLType::kInt4, /*alignment=*/16, /*stride=*/16, /*size=*/48);
204 EXPECT_ARRAY(SkSLType::kFloat4, /*alignment=*/16, /*stride=*/16, /*size=*/48);
205 EXPECT_ARRAY(SkSLType::kHalf4, /*alignment=*/16, /*stride=*/16, /*size=*/48);
206
207 // float2x2[3], half2x2[3]
208 EXPECT_ARRAY(SkSLType::kFloat2x2, /*alignment=*/8, /*stride=*/16, /*size=*/48);
209 EXPECT_ARRAY(SkSLType::kHalf2x2, /*alignment=*/8, /*stride=*/16, /*size=*/48);
210
211 // float3x3[3], half3x3[3]
212 EXPECT_ARRAY(SkSLType::kFloat3x3, /*alignment=*/16, /*stride=*/48, /*size=*/144);
213 EXPECT_ARRAY(SkSLType::kHalf3x3, /*alignment=*/16, /*stride=*/48, /*size=*/144);
214
215 // float4x4[3], half4x4[3]
216 EXPECT_ARRAY(SkSLType::kFloat4x4, /*alignment=*/16, /*stride=*/64, /*size=*/192);
217 EXPECT_ARRAY(SkSLType::kHalf4x4, /*alignment=*/16, /*stride=*/64, /*size=*/192);
218 }
219
DEF_GRAPHITE_TEST(UniformOffsetCalculatorStd140BasicTypesTest,r,CtsEnforcement::kNextRelease)220 DEF_GRAPHITE_TEST(UniformOffsetCalculatorStd140BasicTypesTest, r, CtsEnforcement::kNextRelease) {
221 constexpr Layout kLayout = Layout::kStd140;
222
223 // scalars: int, float, half (unsigned types are disallowed)
224 EXPECT(SkSLType::kInt, /*alignment=*/4, /*size=*/4);
225 EXPECT(SkSLType::kFloat, /*alignment=*/4, /*size=*/4);
226 EXPECT(SkSLType::kHalf, /*alignment=*/4, /*size=*/4);
227
228 // int2, float2, half2
229 EXPECT(SkSLType::kInt2, /*alignment=*/8, /*size=*/8);
230 EXPECT(SkSLType::kFloat2, /*alignment=*/8, /*size=*/8);
231 EXPECT(SkSLType::kHalf2, /*alignment=*/8, /*size=*/8);
232
233 // int3, float3, half3 (size is not rounded up for non-arrays of vec3s)
234 EXPECT(SkSLType::kInt3, /*alignment=*/16, /*size=*/12);
235 EXPECT(SkSLType::kFloat3, /*alignment=*/16, /*size=*/12);
236 EXPECT(SkSLType::kHalf3, /*alignment=*/16, /*size=*/12);
237
238 // int4, float4, half4
239 EXPECT(SkSLType::kInt4, /*alignment=*/16, /*size=*/16);
240 EXPECT(SkSLType::kFloat4, /*alignment=*/16, /*size=*/16);
241 EXPECT(SkSLType::kHalf4, /*alignment=*/16, /*size=*/16);
242
243 // float2x2, half2x2
244 EXPECT(SkSLType::kFloat2x2, /*alignment=*/16, /*size=*/32);
245 EXPECT(SkSLType::kHalf2x2, /*alignment=*/16, /*size=*/32);
246
247 // float3x3, half3x3
248 EXPECT(SkSLType::kFloat3x3, /*alignment=*/16, /*size=*/48);
249 EXPECT(SkSLType::kHalf3x3, /*alignment=*/16, /*size=*/48);
250
251 // float4x4, half4x4
252 EXPECT(SkSLType::kFloat4x4, /*alignment=*/16, /*size=*/64);
253 EXPECT(SkSLType::kHalf4x4, /*alignment=*/16, /*size=*/64);
254 }
255
DEF_GRAPHITE_TEST(UniformOffsetCalculatorStd140ArrayTest,r,CtsEnforcement::kNextRelease)256 DEF_GRAPHITE_TEST(UniformOffsetCalculatorStd140ArrayTest, r, CtsEnforcement::kNextRelease) {
257 constexpr Layout kLayout = Layout::kStd140;
258 constexpr uint32_t kCount = 3;
259
260 // int[3], float[3], half[3]
261 EXPECT_ARRAY(SkSLType::kInt, /*alignment=*/16, /*stride=*/16, /*size=*/48);
262 EXPECT_ARRAY(SkSLType::kFloat, /*alignment=*/16, /*stride=*/16, /*size=*/48);
263 EXPECT_ARRAY(SkSLType::kHalf, /*alignment=*/16, /*stride=*/16, /*size=*/48);
264
265 // int2[3], float2[3], half2[3]
266 EXPECT_ARRAY(SkSLType::kInt2, /*alignment=*/16, /*stride=*/16, /*size=*/48);
267 EXPECT_ARRAY(SkSLType::kFloat2, /*alignment=*/16, /*stride=*/16, /*size=*/48);
268 EXPECT_ARRAY(SkSLType::kHalf2, /*alignment=*/16, /*stride=*/16, /*size=*/48);
269
270 // int3[3], float3[3], half3[3]
271 EXPECT_ARRAY(SkSLType::kInt3, /*alignment=*/16, /*stride=*/16, /*size=*/48);
272 EXPECT_ARRAY(SkSLType::kFloat3, /*alignment=*/16, /*stride=*/16, /*size=*/48);
273 EXPECT_ARRAY(SkSLType::kHalf3, /*alignment=*/16, /*stride=*/16, /*size=*/48);
274
275 // int4[3], float4[3], half4[3]
276 EXPECT_ARRAY(SkSLType::kInt4, /*alignment=*/16, /*stride=*/16, /*size=*/48);
277 EXPECT_ARRAY(SkSLType::kFloat4, /*alignment=*/16, /*stride=*/16, /*size=*/48);
278 EXPECT_ARRAY(SkSLType::kHalf4, /*alignment=*/16, /*stride=*/16, /*size=*/48);
279
280 // float2x2[3], half2x2[3]
281 EXPECT_ARRAY(SkSLType::kFloat2x2, /*alignment=*/16, /*stride=*/32, /*size=*/96);
282 EXPECT_ARRAY(SkSLType::kHalf2x2, /*alignment=*/16, /*stride=*/32, /*size=*/96);
283
284 // float3x3[3], half3x3[3]
285 EXPECT_ARRAY(SkSLType::kFloat3x3, /*alignment=*/16, /*stride=*/48, /*size=*/144);
286 EXPECT_ARRAY(SkSLType::kHalf3x3, /*alignment=*/16, /*stride=*/48, /*size=*/144);
287
288 // float4x4[3], half4x4[3]
289 EXPECT_ARRAY(SkSLType::kFloat4x4, /*alignment=*/16, /*stride=*/64, /*size=*/192);
290 EXPECT_ARRAY(SkSLType::kHalf4x4, /*alignment=*/16, /*stride=*/64, /*size=*/192);
291 }
292
293 } // namespace
294