• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_TEST(UniformOffsetCalculatorMetalBasicTypesTest,r)74 DEF_TEST(UniformOffsetCalculatorMetalBasicTypesTest, r) {
75     constexpr Layout kLayout = Layout::kMetal;
76 
77     // scalars: int, float, short, half (unsigned types are disallowed)
78     EXPECT(SkSLType::kInt,    /*alignment=*/4, /*size=*/4);
79     EXPECT(SkSLType::kFloat,  /*alignment=*/4, /*size=*/4);
80     EXPECT(SkSLType::kShort,  /*alignment=*/2, /*size=*/2);
81     EXPECT(SkSLType::kHalf,   /*alignment=*/2, /*size=*/2);
82 
83     // int2, float2, short2, half2
84     EXPECT(SkSLType::kInt2,    /*alignment=*/8, /*size=*/8);
85     EXPECT(SkSLType::kFloat2,  /*alignment=*/8, /*size=*/8);
86     EXPECT(SkSLType::kShort2,  /*alignment=*/4, /*size=*/4);
87     EXPECT(SkSLType::kHalf2,   /*alignment=*/4, /*size=*/4);
88 
89     // int3, float3, short3, half3
90     EXPECT(SkSLType::kInt3,    /*alignment=*/16, /*size=*/16);
91     EXPECT(SkSLType::kFloat3,  /*alignment=*/16, /*size=*/16);
92     EXPECT(SkSLType::kShort3,  /*alignment=*/8,  /*size=*/8);
93     EXPECT(SkSLType::kHalf3,   /*alignment=*/8,  /*size=*/8);
94 
95     // int4, float4, short4, half4
96     EXPECT(SkSLType::kInt4,    /*alignment=*/16, /*size=*/16);
97     EXPECT(SkSLType::kFloat4,  /*alignment=*/16, /*size=*/16);
98     EXPECT(SkSLType::kShort4,  /*alignment=*/8,  /*size=*/8);
99     EXPECT(SkSLType::kHalf4,   /*alignment=*/8,  /*size=*/8);
100 
101     // float2x2, half2x2
102     EXPECT(SkSLType::kFloat2x2, /*alignment=*/8, /*size=*/16);
103     EXPECT(SkSLType::kHalf2x2,  /*alignment=*/4, /*size=*/8);
104 
105     // float3x3, half3x3
106     EXPECT(SkSLType::kFloat3x3, /*alignment=*/16, /*size=*/48);
107     EXPECT(SkSLType::kHalf3x3,  /*alignment=*/8,  /*size=*/24);
108 
109     // float4x4, half4x4
110     EXPECT(SkSLType::kFloat4x4, /*alignment=*/16, /*size=*/64);
111     EXPECT(SkSLType::kHalf4x4,  /*alignment=*/8,  /*size=*/32);
112 }
113 
DEF_TEST(UniformOffsetCalculatorMetalArrayTest,r)114 DEF_TEST(UniformOffsetCalculatorMetalArrayTest, r) {
115     constexpr Layout kLayout = Layout::kMetal;
116     constexpr size_t kCount = 3;
117 
118     // int[3], float[3], short[3], half[3]
119     EXPECT_ARRAY(SkSLType::kInt,   /*alignment=*/4, /*stride=*/4, /*size=*/12);
120     EXPECT_ARRAY(SkSLType::kFloat, /*alignment=*/4, /*stride=*/4, /*size=*/12);
121     EXPECT_ARRAY(SkSLType::kShort, /*alignment=*/2, /*stride=*/2, /*size=*/6);
122     EXPECT_ARRAY(SkSLType::kHalf,  /*alignment=*/2, /*stride=*/2, /*size=*/6);
123 
124     // int2[3], float2[3], short2[3], half2[3]
125     EXPECT_ARRAY(SkSLType::kInt2,   /*alignment=*/8, /*stride=*/8, /*size=*/24);
126     EXPECT_ARRAY(SkSLType::kFloat2, /*alignment=*/8, /*stride=*/8, /*size=*/24);
127     EXPECT_ARRAY(SkSLType::kShort2, /*alignment=*/4, /*stride=*/4, /*size=*/12);
128     EXPECT_ARRAY(SkSLType::kHalf2,  /*alignment=*/4, /*stride=*/4, /*size=*/12);
129 
130     // int3[3], float3[3], short3[3], half3[3]
131     EXPECT_ARRAY(SkSLType::kInt3,   /*alignment=*/16, /*stride=*/16, /*size=*/48);
132     EXPECT_ARRAY(SkSLType::kFloat3, /*alignment=*/16, /*stride=*/16, /*size=*/48);
133     EXPECT_ARRAY(SkSLType::kShort3, /*alignment=*/8,  /*stride=*/8,  /*size=*/24);
134     EXPECT_ARRAY(SkSLType::kHalf3,  /*alignment=*/8,  /*stride=*/8,  /*size=*/24);
135 
136     // int4[3], float4[3], short4[3], half4[3]
137     EXPECT_ARRAY(SkSLType::kInt4,   /*alignment=*/16, /*stride=*/16, /*size=*/48);
138     EXPECT_ARRAY(SkSLType::kFloat4, /*alignment=*/16, /*stride=*/16, /*size=*/48);
139     EXPECT_ARRAY(SkSLType::kShort4, /*alignment=*/8,  /*stride=*/8,  /*size=*/24);
140     EXPECT_ARRAY(SkSLType::kHalf4,  /*alignment=*/8,  /*stride=*/8,  /*size=*/24);
141 
142     // float2x2[3], half2x2[3]
143     EXPECT_ARRAY(SkSLType::kFloat2x2, /*alignment=*/8, /*stride=*/16, /*size=*/48);
144     EXPECT_ARRAY(SkSLType::kHalf2x2,  /*alignment=*/4, /*stride=*/8,  /*size=*/24);
145 
146     // float3x3[3], half3x3[3]
147     EXPECT_ARRAY(SkSLType::kFloat3x3, /*alignment=*/16, /*stride=*/48, /*size=*/144);
148     EXPECT_ARRAY(SkSLType::kHalf3x3,  /*alignment=*/8,  /*stride=*/24, /*size=*/72);
149 
150     // float4x4[3], half4x4[3]
151     EXPECT_ARRAY(SkSLType::kFloat4x4, /*alignment=*/16, /*stride=*/64, /*size=*/192);
152     EXPECT_ARRAY(SkSLType::kHalf4x4,  /*alignment=*/8,  /*stride=*/32, /*size=*/96);
153 }
154 
DEF_TEST(UniformOffsetCalculatorStd430BasicTypesTest,r)155 DEF_TEST(UniformOffsetCalculatorStd430BasicTypesTest, r) {
156     constexpr Layout kLayout = Layout::kStd430;
157 
158     // scalars: int, float, short, half (unsigned types are disallowed)
159     EXPECT(SkSLType::kInt,    /*alignment=*/4, /*size=*/4);
160     EXPECT(SkSLType::kFloat,  /*alignment=*/4, /*size=*/4);
161     EXPECT(SkSLType::kShort,  /*alignment=*/4, /*size=*/4);
162     EXPECT(SkSLType::kHalf,   /*alignment=*/4, /*size=*/4);
163 
164     // int2, float2, short2, half2
165     EXPECT(SkSLType::kInt2,    /*alignment=*/8, /*size=*/8);
166     EXPECT(SkSLType::kFloat2,  /*alignment=*/8, /*size=*/8);
167     EXPECT(SkSLType::kShort2,  /*alignment=*/8, /*size=*/8);
168     EXPECT(SkSLType::kHalf2,   /*alignment=*/8, /*size=*/8);
169 
170     // int3, float3, short3, half3
171     EXPECT(SkSLType::kInt3,    /*alignment=*/16, /*size=*/16);
172     EXPECT(SkSLType::kFloat3,  /*alignment=*/16, /*size=*/16);
173     EXPECT(SkSLType::kShort3,  /*alignment=*/16, /*size=*/16);
174     EXPECT(SkSLType::kHalf3,   /*alignment=*/16, /*size=*/16);
175 
176     // int4, float4, short4, half4
177     EXPECT(SkSLType::kInt4,    /*alignment=*/16, /*size=*/16);
178     EXPECT(SkSLType::kFloat4,  /*alignment=*/16, /*size=*/16);
179     EXPECT(SkSLType::kShort4,  /*alignment=*/16, /*size=*/16);
180     EXPECT(SkSLType::kHalf4,   /*alignment=*/16, /*size=*/16);
181 
182     // float2x2, half2x2
183     EXPECT(SkSLType::kFloat2x2, /*alignment=*/8, /*size=*/16);
184     EXPECT(SkSLType::kHalf2x2,  /*alignment=*/8, /*size=*/16);
185 
186     // float3x3, half3x3
187     EXPECT(SkSLType::kFloat3x3, /*alignment=*/16, /*size=*/48);
188     EXPECT(SkSLType::kHalf3x3,  /*alignment=*/16, /*size=*/48);
189 
190     // float4x4, half4x4
191     EXPECT(SkSLType::kFloat4x4, /*alignment=*/16, /*size=*/64);
192     EXPECT(SkSLType::kHalf4x4,  /*alignment=*/16, /*size=*/64);
193 }
194 
DEF_TEST(UniformOffsetCalculatorStd430ArrayTest,r)195 DEF_TEST(UniformOffsetCalculatorStd430ArrayTest, r) {
196     constexpr Layout kLayout = Layout::kStd430;
197     constexpr size_t kCount = 3;
198 
199     // int[3], float[3], short[3], half[3]
200     EXPECT_ARRAY(SkSLType::kInt,   /*alignment=*/4, /*stride=*/4, /*size=*/12);
201     EXPECT_ARRAY(SkSLType::kFloat, /*alignment=*/4, /*stride=*/4, /*size=*/12);
202     EXPECT_ARRAY(SkSLType::kShort, /*alignment=*/4, /*stride=*/4, /*size=*/12);
203     EXPECT_ARRAY(SkSLType::kHalf,  /*alignment=*/4, /*stride=*/4, /*size=*/12);
204 
205     // int2[3], float2[3], short2[3], half2[3]
206     EXPECT_ARRAY(SkSLType::kInt2,   /*alignment=*/8, /*stride=*/8, /*size=*/24);
207     EXPECT_ARRAY(SkSLType::kFloat2, /*alignment=*/8, /*stride=*/8, /*size=*/24);
208     EXPECT_ARRAY(SkSLType::kShort2, /*alignment=*/8, /*stride=*/8, /*size=*/24);
209     EXPECT_ARRAY(SkSLType::kHalf2,  /*alignment=*/8, /*stride=*/8, /*size=*/24);
210 
211     // int3[3], float3[3], short3[3], half3[3]
212     EXPECT_ARRAY(SkSLType::kInt3,   /*alignment=*/16, /*stride=*/16, /*size=*/48);
213     EXPECT_ARRAY(SkSLType::kFloat3, /*alignment=*/16, /*stride=*/16, /*size=*/48);
214     EXPECT_ARRAY(SkSLType::kShort3, /*alignment=*/16, /*stride=*/16, /*size=*/48);
215     EXPECT_ARRAY(SkSLType::kHalf3,  /*alignment=*/16, /*stride=*/16, /*size=*/48);
216 
217     // int4[3], float4[3], short4[3], half4[3]
218     EXPECT_ARRAY(SkSLType::kInt4,   /*alignment=*/16, /*stride=*/16, /*size=*/48);
219     EXPECT_ARRAY(SkSLType::kFloat4, /*alignment=*/16, /*stride=*/16, /*size=*/48);
220     EXPECT_ARRAY(SkSLType::kShort4, /*alignment=*/16, /*stride=*/16, /*size=*/48);
221     EXPECT_ARRAY(SkSLType::kHalf4,  /*alignment=*/16, /*stride=*/16, /*size=*/48);
222 
223     // float2x2[3], half2x2[3]
224     EXPECT_ARRAY(SkSLType::kFloat2x2, /*alignment=*/8, /*stride=*/16, /*size=*/48);
225     EXPECT_ARRAY(SkSLType::kHalf2x2,  /*alignment=*/8, /*stride=*/16, /*size=*/48);
226 
227     // float3x3[3], half3x3[3]
228     EXPECT_ARRAY(SkSLType::kFloat3x3, /*alignment=*/16, /*stride=*/48, /*size=*/144);
229     EXPECT_ARRAY(SkSLType::kHalf3x3,  /*alignment=*/16, /*stride=*/48, /*size=*/144);
230 
231     // float4x4[3], half4x4[3]
232     EXPECT_ARRAY(SkSLType::kFloat4x4, /*alignment=*/16, /*stride=*/64, /*size=*/192);
233     EXPECT_ARRAY(SkSLType::kHalf4x4,  /*alignment=*/16, /*stride=*/64, /*size=*/192);
234 }
235 
DEF_TEST(UniformOffsetCalculatorStd140BasicTypesTest,r)236 DEF_TEST(UniformOffsetCalculatorStd140BasicTypesTest, r) {
237     constexpr Layout kLayout = Layout::kStd140;
238 
239     // scalars: int, float, short, half (unsigned types are disallowed)
240     EXPECT(SkSLType::kInt,    /*alignment=*/4, /*size=*/4);
241     EXPECT(SkSLType::kFloat,  /*alignment=*/4, /*size=*/4);
242     EXPECT(SkSLType::kShort,  /*alignment=*/4, /*size=*/4);
243     EXPECT(SkSLType::kHalf,   /*alignment=*/4, /*size=*/4);
244 
245     // int2, float2, short2, half2
246     EXPECT(SkSLType::kInt2,    /*alignment=*/8, /*size=*/8);
247     EXPECT(SkSLType::kFloat2,  /*alignment=*/8, /*size=*/8);
248     EXPECT(SkSLType::kShort2,  /*alignment=*/8, /*size=*/8);
249     EXPECT(SkSLType::kHalf2,   /*alignment=*/8, /*size=*/8);
250 
251     // int3, float3, short3, half3
252     EXPECT(SkSLType::kInt3,    /*alignment=*/16, /*size=*/16);
253     EXPECT(SkSLType::kFloat3,  /*alignment=*/16, /*size=*/16);
254     EXPECT(SkSLType::kShort3,  /*alignment=*/16, /*size=*/16);
255     EXPECT(SkSLType::kHalf3,   /*alignment=*/16, /*size=*/16);
256 
257     // int4, float4, short4, half4
258     EXPECT(SkSLType::kInt4,    /*alignment=*/16, /*size=*/16);
259     EXPECT(SkSLType::kFloat4,  /*alignment=*/16, /*size=*/16);
260     EXPECT(SkSLType::kShort4,  /*alignment=*/16, /*size=*/16);
261     EXPECT(SkSLType::kHalf4,   /*alignment=*/16, /*size=*/16);
262 
263     // float2x2, half2x2
264     EXPECT(SkSLType::kFloat2x2, /*alignment=*/8, /*size=*/16);
265     EXPECT(SkSLType::kHalf2x2,  /*alignment=*/8, /*size=*/16);
266 
267     // float3x3, half3x3
268     EXPECT(SkSLType::kFloat3x3, /*alignment=*/16,  /*size=*/48);
269     EXPECT(SkSLType::kHalf3x3,  /*alignment=*/16,  /*size=*/48);
270 
271     // float4x4, half4x4
272     EXPECT(SkSLType::kFloat4x4, /*alignment=*/16, /*size=*/64);
273     EXPECT(SkSLType::kHalf4x4,  /*alignment=*/16, /*size=*/64);
274 }
275 
DEF_TEST(UniformOffsetCalculatorStd140ArrayTest,r)276 DEF_TEST(UniformOffsetCalculatorStd140ArrayTest, r) {
277     constexpr Layout kLayout = Layout::kStd140;
278     constexpr uint32_t kCount = 3;
279 
280     // int[3], float[3], short[3], half[3]
281     EXPECT_ARRAY(SkSLType::kInt,   /*alignment=*/16, /*stride=*/16, /*size=*/48);
282     EXPECT_ARRAY(SkSLType::kFloat, /*alignment=*/16, /*stride=*/16, /*size=*/48);
283     EXPECT_ARRAY(SkSLType::kShort, /*alignment=*/16, /*stride=*/16, /*size=*/48);
284     EXPECT_ARRAY(SkSLType::kHalf,  /*alignment=*/16, /*stride=*/16, /*size=*/48);
285 
286     // int2[3], float2[3], short2[3], half2[3]
287     EXPECT_ARRAY(SkSLType::kInt2,   /*alignment=*/16, /*stride=*/16, /*size=*/48);
288     EXPECT_ARRAY(SkSLType::kFloat2, /*alignment=*/16, /*stride=*/16, /*size=*/48);
289     EXPECT_ARRAY(SkSLType::kShort2, /*alignment=*/16, /*stride=*/16, /*size=*/48);
290     EXPECT_ARRAY(SkSLType::kHalf2,  /*alignment=*/16, /*stride=*/16, /*size=*/48);
291 
292     // int3[3], float3[3], short3[3], half3[3]
293     EXPECT_ARRAY(SkSLType::kInt3,   /*alignment=*/16, /*stride=*/16, /*size=*/48);
294     EXPECT_ARRAY(SkSLType::kFloat3, /*alignment=*/16, /*stride=*/16, /*size=*/48);
295     EXPECT_ARRAY(SkSLType::kShort3, /*alignment=*/16, /*stride=*/16, /*size=*/48);
296     EXPECT_ARRAY(SkSLType::kHalf3,  /*alignment=*/16, /*stride=*/16, /*size=*/48);
297 
298     // int4[3], float4[3], short4[3], half4[3]
299     EXPECT_ARRAY(SkSLType::kInt4,   /*alignment=*/16, /*stride=*/16, /*size=*/48);
300     EXPECT_ARRAY(SkSLType::kFloat4, /*alignment=*/16, /*stride=*/16, /*size=*/48);
301     EXPECT_ARRAY(SkSLType::kShort4, /*alignment=*/16, /*stride=*/16, /*size=*/48);
302     EXPECT_ARRAY(SkSLType::kHalf4,  /*alignment=*/16, /*stride=*/16, /*size=*/48);
303 
304     // float2x2[3], half2x2[3]
305     EXPECT_ARRAY(SkSLType::kFloat2x2, /*alignment=*/16, /*stride=*/16, /*size=*/48);
306     EXPECT_ARRAY(SkSLType::kHalf2x2,  /*alignment=*/16, /*stride=*/16, /*size=*/48);
307 
308     // float3x3[3], half3x3[3]
309     EXPECT_ARRAY(SkSLType::kFloat3x3, /*alignment=*/16, /*stride=*/48, /*size=*/144);
310     EXPECT_ARRAY(SkSLType::kHalf3x3,  /*alignment=*/16, /*stride=*/48, /*size=*/144);
311 
312     // float4x4[3], half4x4[3]
313     EXPECT_ARRAY(SkSLType::kFloat4x4, /*alignment=*/16, /*stride=*/64, /*size=*/192);
314     EXPECT_ARRAY(SkSLType::kHalf4x4,  /*alignment=*/16, /*stride=*/64, /*size=*/192);
315 }
316 
317 }  // namespace
318