xref: /aosp_15_r20/external/deqp/framework/referencerenderer/rrVertexAttrib.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program Reference Renderer
3  * -----------------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Vertex attribute fetch.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "rrVertexAttrib.hpp"
25 #include "tcuFloat.hpp"
26 #include "deInt32.h"
27 #include "deMemory.h"
28 
29 namespace rr
30 {
31 
32 namespace
33 {
34 
35 struct NormalOrder
36 {
37     enum
38     {
39         T0 = 0,
40         T1 = 1,
41         T2 = 2,
42         T3 = 3,
43     };
44 };
45 
46 struct BGRAOrder
47 {
48     enum
49     {
50         T0 = 2,
51         T1 = 1,
52         T2 = 0,
53         T3 = 3,
54     };
55 };
56 
57 // readers
58 
59 template <typename SrcScalarType, typename DstScalarType, typename Order>
readOrder(typename tcu::Vector<DstScalarType,4> & dst,const int size,const void * ptr)60 inline void readOrder(typename tcu::Vector<DstScalarType, 4> &dst, const int size, const void *ptr)
61 {
62     SrcScalarType aligned[4];
63     deMemcpy(aligned, ptr, size * sizeof(SrcScalarType));
64 
65     dst[Order::T0] = DstScalarType(aligned[0]);
66     if (size >= 2)
67         dst[Order::T1] = DstScalarType(aligned[1]);
68     if (size >= 3)
69         dst[Order::T2] = DstScalarType(aligned[2]);
70     if (size >= 4)
71         dst[Order::T3] = DstScalarType(aligned[3]);
72 }
73 
74 template <typename SrcScalarType, typename Order>
readUnormOrder(tcu::Vec4 & dst,const int size,const void * ptr)75 inline void readUnormOrder(tcu::Vec4 &dst, const int size, const void *ptr)
76 {
77     const uint32_t range = (uint32_t)((1ull << (sizeof(SrcScalarType) * 8)) - 1);
78 
79     SrcScalarType aligned[4];
80     deMemcpy(aligned, ptr, size * sizeof(SrcScalarType));
81 
82     dst[Order::T0] = float(aligned[0]) / float(range);
83     if (size >= 2)
84         dst[Order::T1] = float(aligned[1]) / float(range);
85     if (size >= 3)
86         dst[Order::T2] = float(aligned[2]) / float(range);
87     if (size >= 4)
88         dst[Order::T3] = float(aligned[3]) / float(range);
89 }
90 
91 template <typename SrcScalarType>
readSnormClamp(tcu::Vec4 & dst,const int size,const void * ptr)92 inline void readSnormClamp(tcu::Vec4 &dst, const int size, const void *ptr)
93 {
94     // Clamped formats, GLES3-style conversion: max{c / (2^(b-1) - 1), -1 }
95     const uint32_t range = (uint32_t)((1ull << (sizeof(SrcScalarType) * 8 - 1)) - 1);
96 
97     SrcScalarType aligned[4];
98     deMemcpy(aligned, ptr, size * sizeof(SrcScalarType));
99 
100     dst[0] = de::max(-1.0f, float(aligned[0]) / float(range));
101     if (size >= 2)
102         dst[1] = de::max(-1.0f, float(aligned[1]) / float(range));
103     if (size >= 3)
104         dst[2] = de::max(-1.0f, float(aligned[2]) / float(range));
105     if (size >= 4)
106         dst[3] = de::max(-1.0f, float(aligned[3]) / float(range));
107 }
108 
109 template <typename SrcScalarType>
readSnormScale(tcu::Vec4 & dst,const int size,const void * ptr)110 inline void readSnormScale(tcu::Vec4 &dst, const int size, const void *ptr)
111 {
112     // Scaled formats, GLES2-style conversion: (2c + 1) / (2^b - 1)
113     const uint32_t range = (uint32_t)((1ull << (sizeof(SrcScalarType) * 8)) - 1);
114 
115     SrcScalarType aligned[4];
116     deMemcpy(aligned, ptr, size * sizeof(SrcScalarType));
117 
118     dst[0] = (float(aligned[0]) * 2.0f + 1.0f) / float(range);
119     if (size >= 2)
120         dst[1] = (float(aligned[1]) * 2.0f + 1.0f) / float(range);
121     if (size >= 3)
122         dst[2] = (float(aligned[2]) * 2.0f + 1.0f) / float(range);
123     if (size >= 4)
124         dst[3] = (float(aligned[3]) * 2.0f + 1.0f) / float(range);
125 }
126 
readHalf(tcu::Vec4 & dst,const int size,const void * ptr)127 inline void readHalf(tcu::Vec4 &dst, const int size, const void *ptr)
128 {
129     uint16_t aligned[4];
130     deMemcpy(aligned, ptr, size * sizeof(uint16_t));
131 
132     dst[0] = tcu::Float16(aligned[0]).asFloat();
133     if (size >= 2)
134         dst[1] = tcu::Float16(aligned[1]).asFloat();
135     if (size >= 3)
136         dst[2] = tcu::Float16(aligned[2]).asFloat();
137     if (size >= 4)
138         dst[3] = tcu::Float16(aligned[3]).asFloat();
139 }
140 
readFixed(tcu::Vec4 & dst,const int size,const void * ptr)141 inline void readFixed(tcu::Vec4 &dst, const int size, const void *ptr)
142 {
143     int32_t aligned[4];
144     deMemcpy(aligned, ptr, size * sizeof(int32_t));
145 
146     dst[0] = float(aligned[0]) / float(1 << 16);
147     if (size >= 2)
148         dst[1] = float(aligned[1]) / float(1 << 16);
149     if (size >= 3)
150         dst[2] = float(aligned[2]) / float(1 << 16);
151     if (size >= 4)
152         dst[3] = float(aligned[3]) / float(1 << 16);
153 }
154 
readDouble(tcu::Vec4 & dst,const int size,const void * ptr)155 inline void readDouble(tcu::Vec4 &dst, const int size, const void *ptr)
156 {
157     double aligned[4];
158     deMemcpy(aligned, ptr, size * sizeof(double));
159 
160     dst[0] = float(aligned[0]);
161     if (size >= 2)
162         dst[1] = float(aligned[1]);
163     if (size >= 3)
164         dst[2] = float(aligned[2]);
165     if (size >= 4)
166         dst[3] = float(aligned[3]);
167 }
168 
169 template <int integerLen>
extendSign(uint32_t integer)170 inline int32_t extendSign(uint32_t integer)
171 {
172     return uint32_t(0 - int32_t((integer & (1 << (integerLen - 1))) << 1)) | integer;
173 }
174 
175 template <typename DstScalarType>
readUint2101010Rev(typename tcu::Vector<DstScalarType,4> & dst,const int size,const void * ptr)176 inline void readUint2101010Rev(typename tcu::Vector<DstScalarType, 4> &dst, const int size, const void *ptr)
177 {
178     uint32_t aligned;
179     deMemcpy(&aligned, ptr, sizeof(uint32_t));
180 
181     dst[0] = DstScalarType((aligned >> 0) & ((1 << 10) - 1));
182     if (size >= 2)
183         dst[1] = DstScalarType((aligned >> 10) & ((1 << 10) - 1));
184     if (size >= 3)
185         dst[2] = DstScalarType((aligned >> 20) & ((1 << 10) - 1));
186     if (size >= 4)
187         dst[3] = DstScalarType((aligned >> 30) & ((1 << 2) - 1));
188 }
189 
190 template <typename DstScalarType>
readInt2101010Rev(typename tcu::Vector<DstScalarType,4> & dst,const int size,const void * ptr)191 inline void readInt2101010Rev(typename tcu::Vector<DstScalarType, 4> &dst, const int size, const void *ptr)
192 {
193     uint32_t aligned;
194     deMemcpy(&aligned, ptr, sizeof(uint32_t));
195 
196     dst[0] = (DstScalarType)extendSign<10>((aligned >> 0) & ((1 << 10) - 1));
197     if (size >= 2)
198         dst[1] = (DstScalarType)extendSign<10>((aligned >> 10) & ((1 << 10) - 1));
199     if (size >= 3)
200         dst[2] = (DstScalarType)extendSign<10>((aligned >> 20) & ((1 << 10) - 1));
201     if (size >= 4)
202         dst[3] = (DstScalarType)extendSign<2>((aligned >> 30) & ((1 << 2) - 1));
203 }
204 
205 template <typename Order>
readUnorm2101010RevOrder(tcu::Vec4 & dst,const int size,const void * ptr)206 inline void readUnorm2101010RevOrder(tcu::Vec4 &dst, const int size, const void *ptr)
207 {
208     const uint32_t range10 = (uint32_t)((1ull << 10) - 1);
209     const uint32_t range2  = (uint32_t)((1ull << 2) - 1);
210 
211     uint32_t aligned;
212     deMemcpy(&aligned, ptr, sizeof(uint32_t));
213 
214     dst[Order::T0] = float((aligned >> 0) & ((1 << 10) - 1)) / float(range10);
215     if (size >= 2)
216         dst[Order::T1] = float((aligned >> 10) & ((1 << 10) - 1)) / float(range10);
217     if (size >= 3)
218         dst[Order::T2] = float((aligned >> 20) & ((1 << 10) - 1)) / float(range10);
219     if (size >= 4)
220         dst[Order::T3] = float((aligned >> 30) & ((1 << 2) - 1)) / float(range2);
221 }
222 
223 template <typename Order>
readSnorm2101010RevClampOrder(tcu::Vec4 & dst,const int size,const void * ptr)224 inline void readSnorm2101010RevClampOrder(tcu::Vec4 &dst, const int size, const void *ptr)
225 {
226     // Clamped formats, GLES3-style conversion: max{c / (2^(b-1) - 1), -1 }
227     const uint32_t range10 = (uint32_t)((1ull << (10 - 1)) - 1);
228     const uint32_t range2  = (uint32_t)((1ull << (2 - 1)) - 1);
229 
230     uint32_t aligned;
231     deMemcpy(&aligned, ptr, sizeof(uint32_t));
232 
233     dst[Order::T0] = de::max(-1.0f, float(extendSign<10>((aligned >> 0) & ((1 << 10) - 1))) / float(range10));
234     if (size >= 2)
235         dst[Order::T1] = de::max(-1.0f, float(extendSign<10>((aligned >> 10) & ((1 << 10) - 1))) / float(range10));
236     if (size >= 3)
237         dst[Order::T2] = de::max(-1.0f, float(extendSign<10>((aligned >> 20) & ((1 << 10) - 1))) / float(range10));
238     if (size >= 4)
239         dst[Order::T3] = de::max(-1.0f, float(extendSign<2>((aligned >> 30) & ((1 << 2) - 1))) / float(range2));
240 }
241 
242 template <typename Order>
readSnorm2101010RevScaleOrder(tcu::Vec4 & dst,const int size,const void * ptr)243 inline void readSnorm2101010RevScaleOrder(tcu::Vec4 &dst, const int size, const void *ptr)
244 {
245     // Scaled formats, GLES2-style conversion: (2c + 1) / (2^b - 1)
246     const uint32_t range10 = (uint32_t)((1ull << 10) - 1);
247     const uint32_t range2  = (uint32_t)((1ull << 2) - 1);
248 
249     uint32_t aligned;
250     deMemcpy(&aligned, ptr, sizeof(uint32_t));
251 
252     dst[Order::T0] = (float(extendSign<10>((aligned >> 0) & ((1 << 10) - 1))) * 2.0f + 1.0f) / float(range10);
253     if (size >= 2)
254         dst[Order::T1] = (float(extendSign<10>((aligned >> 10) & ((1 << 10) - 1))) * 2.0f + 1.0f) / float(range10);
255     if (size >= 3)
256         dst[Order::T2] = (float(extendSign<10>((aligned >> 20) & ((1 << 10) - 1))) * 2.0f + 1.0f) / float(range10);
257     if (size >= 4)
258         dst[Order::T3] = (float(extendSign<2>((aligned >> 30) & ((1 << 2) - 1))) * 2.0f + 1.0f) / float(range2);
259 }
260 
261 // ordered readers
262 
263 template <typename SrcScalarType, typename DstScalarType>
read(typename tcu::Vector<DstScalarType,4> & dst,const int size,const void * ptr)264 inline void read(typename tcu::Vector<DstScalarType, 4> &dst, const int size, const void *ptr)
265 {
266     readOrder<SrcScalarType, DstScalarType, NormalOrder>(dst, size, ptr);
267 }
268 
269 template <typename SrcScalarType>
readUnorm(tcu::Vec4 & dst,const int size,const void * ptr)270 inline void readUnorm(tcu::Vec4 &dst, const int size, const void *ptr)
271 {
272     readUnormOrder<SrcScalarType, NormalOrder>(dst, size, ptr);
273 }
274 
275 template <typename SrcScalarType>
readUnormBGRA(tcu::Vec4 & dst,const int size,const void * ptr)276 inline void readUnormBGRA(tcu::Vec4 &dst, const int size, const void *ptr)
277 {
278     readUnormOrder<SrcScalarType, BGRAOrder>(dst, size, ptr);
279 }
280 
readUnorm2101010Rev(tcu::Vec4 & dst,const int size,const void * ptr)281 inline void readUnorm2101010Rev(tcu::Vec4 &dst, const int size, const void *ptr)
282 {
283     readUnorm2101010RevOrder<NormalOrder>(dst, size, ptr);
284 }
285 
readUnorm2101010RevBGRA(tcu::Vec4 & dst,const int size,const void * ptr)286 inline void readUnorm2101010RevBGRA(tcu::Vec4 &dst, const int size, const void *ptr)
287 {
288     readUnorm2101010RevOrder<BGRAOrder>(dst, size, ptr);
289 }
290 
readSnorm2101010RevClamp(tcu::Vec4 & dst,const int size,const void * ptr)291 inline void readSnorm2101010RevClamp(tcu::Vec4 &dst, const int size, const void *ptr)
292 {
293     readSnorm2101010RevClampOrder<NormalOrder>(dst, size, ptr);
294 }
295 
readSnorm2101010RevClampBGRA(tcu::Vec4 & dst,const int size,const void * ptr)296 inline void readSnorm2101010RevClampBGRA(tcu::Vec4 &dst, const int size, const void *ptr)
297 {
298     readSnorm2101010RevClampOrder<BGRAOrder>(dst, size, ptr);
299 }
300 
readSnorm2101010RevScale(tcu::Vec4 & dst,const int size,const void * ptr)301 inline void readSnorm2101010RevScale(tcu::Vec4 &dst, const int size, const void *ptr)
302 {
303     readSnorm2101010RevScaleOrder<NormalOrder>(dst, size, ptr);
304 }
305 
readSnorm2101010RevScaleBGRA(tcu::Vec4 & dst,const int size,const void * ptr)306 inline void readSnorm2101010RevScaleBGRA(tcu::Vec4 &dst, const int size, const void *ptr)
307 {
308     readSnorm2101010RevScaleOrder<BGRAOrder>(dst, size, ptr);
309 }
310 
311 // utils
312 
readFloat(tcu::Vec4 & dst,const VertexAttribType type,const int size,const void * ptr)313 void readFloat(tcu::Vec4 &dst, const VertexAttribType type, const int size, const void *ptr)
314 {
315     switch (type)
316     {
317     case VERTEXATTRIBTYPE_FLOAT:
318         read<float>(dst, size, ptr);
319         break;
320     case VERTEXATTRIBTYPE_HALF:
321         readHalf(dst, size, ptr);
322         break;
323     case VERTEXATTRIBTYPE_FIXED:
324         readFixed(dst, size, ptr);
325         break;
326     case VERTEXATTRIBTYPE_DOUBLE:
327         readDouble(dst, size, ptr);
328         break;
329     case VERTEXATTRIBTYPE_NONPURE_UNORM8:
330         readUnorm<uint8_t>(dst, size, ptr);
331         break;
332     case VERTEXATTRIBTYPE_NONPURE_UNORM16:
333         readUnorm<uint16_t>(dst, size, ptr);
334         break;
335     case VERTEXATTRIBTYPE_NONPURE_UNORM32:
336         readUnorm<uint32_t>(dst, size, ptr);
337         break;
338     case VERTEXATTRIBTYPE_NONPURE_UNORM_2_10_10_10_REV:
339         readUnorm2101010Rev(dst, size, ptr);
340         break;
341     case VERTEXATTRIBTYPE_NONPURE_SNORM8_CLAMP:
342         readSnormClamp<int8_t>(dst, size, ptr);
343         break;
344     case VERTEXATTRIBTYPE_NONPURE_SNORM16_CLAMP:
345         readSnormClamp<int16_t>(dst, size, ptr);
346         break;
347     case VERTEXATTRIBTYPE_NONPURE_SNORM32_CLAMP:
348         readSnormClamp<int32_t>(dst, size, ptr);
349         break;
350     case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_CLAMP:
351         readSnorm2101010RevClamp(dst, size, ptr);
352         break;
353     case VERTEXATTRIBTYPE_NONPURE_SNORM8_SCALE:
354         readSnormScale<int8_t>(dst, size, ptr);
355         break;
356     case VERTEXATTRIBTYPE_NONPURE_SNORM16_SCALE:
357         readSnormScale<int16_t>(dst, size, ptr);
358         break;
359     case VERTEXATTRIBTYPE_NONPURE_SNORM32_SCALE:
360         readSnormScale<int32_t>(dst, size, ptr);
361         break;
362     case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_SCALE:
363         readSnorm2101010RevScale(dst, size, ptr);
364         break;
365     case VERTEXATTRIBTYPE_NONPURE_UINT8:
366         read<uint8_t>(dst, size, ptr);
367         break;
368     case VERTEXATTRIBTYPE_NONPURE_UINT16:
369         read<uint16_t>(dst, size, ptr);
370         break;
371     case VERTEXATTRIBTYPE_NONPURE_UINT32:
372         read<uint32_t>(dst, size, ptr);
373         break;
374     case VERTEXATTRIBTYPE_NONPURE_INT8:
375         read<int8_t>(dst, size, ptr);
376         break;
377     case VERTEXATTRIBTYPE_NONPURE_INT16:
378         read<int16_t>(dst, size, ptr);
379         break;
380     case VERTEXATTRIBTYPE_NONPURE_INT32:
381         read<int32_t>(dst, size, ptr);
382         break;
383     case VERTEXATTRIBTYPE_NONPURE_UINT_2_10_10_10_REV:
384         readUint2101010Rev(dst, size, ptr);
385         break;
386     case VERTEXATTRIBTYPE_NONPURE_INT_2_10_10_10_REV:
387         readInt2101010Rev(dst, size, ptr);
388         break;
389     case VERTEXATTRIBTYPE_NONPURE_UNORM8_BGRA:
390         readUnormBGRA<uint8_t>(dst, size, ptr);
391         break;
392     case VERTEXATTRIBTYPE_NONPURE_UNORM_2_10_10_10_REV_BGRA:
393         readUnorm2101010RevBGRA(dst, size, ptr);
394         break;
395     case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_CLAMP_BGRA:
396         readSnorm2101010RevClampBGRA(dst, size, ptr);
397         break;
398     case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_SCALE_BGRA:
399         readSnorm2101010RevScaleBGRA(dst, size, ptr);
400         break;
401 
402     case VERTEXATTRIBTYPE_PURE_UINT8:
403     case VERTEXATTRIBTYPE_PURE_UINT16:
404     case VERTEXATTRIBTYPE_PURE_UINT32:
405     case VERTEXATTRIBTYPE_PURE_INT8:
406     case VERTEXATTRIBTYPE_PURE_INT16:
407     case VERTEXATTRIBTYPE_PURE_INT32:
408         DE_FATAL("Invalid read");
409         break;
410 
411     default:
412         DE_ASSERT(false);
413     }
414 }
415 
readInt(tcu::IVec4 & dst,const VertexAttribType type,const int size,const void * ptr)416 void readInt(tcu::IVec4 &dst, const VertexAttribType type, const int size, const void *ptr)
417 {
418     switch (type)
419     {
420     case VERTEXATTRIBTYPE_PURE_INT8:
421         read<int8_t>(dst, size, ptr);
422         break;
423     case VERTEXATTRIBTYPE_PURE_INT16:
424         read<int16_t>(dst, size, ptr);
425         break;
426     case VERTEXATTRIBTYPE_PURE_INT32:
427         read<int32_t>(dst, size, ptr);
428         break;
429 
430     case VERTEXATTRIBTYPE_FLOAT:
431     case VERTEXATTRIBTYPE_HALF:
432     case VERTEXATTRIBTYPE_FIXED:
433     case VERTEXATTRIBTYPE_DOUBLE:
434     case VERTEXATTRIBTYPE_NONPURE_UNORM8:
435     case VERTEXATTRIBTYPE_NONPURE_UNORM16:
436     case VERTEXATTRIBTYPE_NONPURE_UNORM32:
437     case VERTEXATTRIBTYPE_NONPURE_UNORM_2_10_10_10_REV:
438     case VERTEXATTRIBTYPE_NONPURE_SNORM8_CLAMP:
439     case VERTEXATTRIBTYPE_NONPURE_SNORM16_CLAMP:
440     case VERTEXATTRIBTYPE_NONPURE_SNORM32_CLAMP:
441     case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_CLAMP:
442     case VERTEXATTRIBTYPE_NONPURE_SNORM8_SCALE:
443     case VERTEXATTRIBTYPE_NONPURE_SNORM16_SCALE:
444     case VERTEXATTRIBTYPE_NONPURE_SNORM32_SCALE:
445     case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_SCALE:
446     case VERTEXATTRIBTYPE_NONPURE_UINT8:
447     case VERTEXATTRIBTYPE_NONPURE_UINT16:
448     case VERTEXATTRIBTYPE_NONPURE_UINT32:
449     case VERTEXATTRIBTYPE_NONPURE_INT8:
450     case VERTEXATTRIBTYPE_NONPURE_INT16:
451     case VERTEXATTRIBTYPE_NONPURE_INT32:
452     case VERTEXATTRIBTYPE_NONPURE_UINT_2_10_10_10_REV:
453     case VERTEXATTRIBTYPE_NONPURE_INT_2_10_10_10_REV:
454     case VERTEXATTRIBTYPE_PURE_UINT8:
455     case VERTEXATTRIBTYPE_PURE_UINT16:
456     case VERTEXATTRIBTYPE_PURE_UINT32:
457     case VERTEXATTRIBTYPE_NONPURE_UNORM8_BGRA:
458     case VERTEXATTRIBTYPE_NONPURE_UNORM_2_10_10_10_REV_BGRA:
459     case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_CLAMP_BGRA:
460     case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_SCALE_BGRA:
461         DE_FATAL("Invalid read");
462         break;
463 
464     default:
465         DE_ASSERT(false);
466     }
467 }
468 
readUint(tcu::UVec4 & dst,const VertexAttribType type,const int size,const void * ptr)469 void readUint(tcu::UVec4 &dst, const VertexAttribType type, const int size, const void *ptr)
470 {
471     switch (type)
472     {
473     case VERTEXATTRIBTYPE_PURE_UINT8:
474         read<uint8_t>(dst, size, ptr);
475         break;
476     case VERTEXATTRIBTYPE_PURE_UINT16:
477         read<uint16_t>(dst, size, ptr);
478         break;
479     case VERTEXATTRIBTYPE_PURE_UINT32:
480         read<uint32_t>(dst, size, ptr);
481         break;
482 
483     case VERTEXATTRIBTYPE_FLOAT:
484     case VERTEXATTRIBTYPE_HALF:
485     case VERTEXATTRIBTYPE_FIXED:
486     case VERTEXATTRIBTYPE_DOUBLE:
487     case VERTEXATTRIBTYPE_NONPURE_UNORM8:
488     case VERTEXATTRIBTYPE_NONPURE_UNORM16:
489     case VERTEXATTRIBTYPE_NONPURE_UNORM32:
490     case VERTEXATTRIBTYPE_NONPURE_UNORM_2_10_10_10_REV:
491     case VERTEXATTRIBTYPE_NONPURE_SNORM8_CLAMP:
492     case VERTEXATTRIBTYPE_NONPURE_SNORM16_CLAMP:
493     case VERTEXATTRIBTYPE_NONPURE_SNORM32_CLAMP:
494     case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_CLAMP:
495     case VERTEXATTRIBTYPE_NONPURE_SNORM8_SCALE:
496     case VERTEXATTRIBTYPE_NONPURE_SNORM16_SCALE:
497     case VERTEXATTRIBTYPE_NONPURE_SNORM32_SCALE:
498     case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_SCALE:
499     case VERTEXATTRIBTYPE_NONPURE_UINT8:
500     case VERTEXATTRIBTYPE_NONPURE_UINT16:
501     case VERTEXATTRIBTYPE_NONPURE_UINT32:
502     case VERTEXATTRIBTYPE_NONPURE_INT8:
503     case VERTEXATTRIBTYPE_NONPURE_INT16:
504     case VERTEXATTRIBTYPE_NONPURE_INT32:
505     case VERTEXATTRIBTYPE_NONPURE_UINT_2_10_10_10_REV:
506     case VERTEXATTRIBTYPE_NONPURE_INT_2_10_10_10_REV:
507     case VERTEXATTRIBTYPE_PURE_INT8:
508     case VERTEXATTRIBTYPE_PURE_INT16:
509     case VERTEXATTRIBTYPE_PURE_INT32:
510     case VERTEXATTRIBTYPE_NONPURE_UNORM8_BGRA:
511     case VERTEXATTRIBTYPE_NONPURE_UNORM_2_10_10_10_REV_BGRA:
512     case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_CLAMP_BGRA:
513     case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_SCALE_BGRA:
514         DE_FATAL("Invalid read");
515         break;
516 
517     default:
518         DE_ASSERT(false);
519     }
520 }
521 
getComponentSize(const VertexAttribType type)522 int getComponentSize(const VertexAttribType type)
523 {
524     switch (type)
525     {
526     case VERTEXATTRIBTYPE_FLOAT:
527         return 4;
528     case VERTEXATTRIBTYPE_HALF:
529         return 2;
530     case VERTEXATTRIBTYPE_FIXED:
531         return 4;
532     case VERTEXATTRIBTYPE_DOUBLE:
533         return (int)sizeof(double);
534     case VERTEXATTRIBTYPE_NONPURE_UNORM8:
535         return 1;
536     case VERTEXATTRIBTYPE_NONPURE_UNORM16:
537         return 2;
538     case VERTEXATTRIBTYPE_NONPURE_UNORM32:
539         return 4;
540     case VERTEXATTRIBTYPE_NONPURE_UNORM_2_10_10_10_REV:
541         return (int)sizeof(uint32_t) / 4;
542     case VERTEXATTRIBTYPE_NONPURE_SNORM8_CLAMP:
543         return 1;
544     case VERTEXATTRIBTYPE_NONPURE_SNORM16_CLAMP:
545         return 2;
546     case VERTEXATTRIBTYPE_NONPURE_SNORM32_CLAMP:
547         return 4;
548     case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_CLAMP:
549         return (int)sizeof(uint32_t) / 4;
550     case VERTEXATTRIBTYPE_NONPURE_SNORM8_SCALE:
551         return 1;
552     case VERTEXATTRIBTYPE_NONPURE_SNORM16_SCALE:
553         return 2;
554     case VERTEXATTRIBTYPE_NONPURE_SNORM32_SCALE:
555         return 4;
556     case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_SCALE:
557         return (int)sizeof(uint32_t) / 4;
558     case VERTEXATTRIBTYPE_NONPURE_UINT8:
559         return 1;
560     case VERTEXATTRIBTYPE_NONPURE_UINT16:
561         return 2;
562     case VERTEXATTRIBTYPE_NONPURE_UINT32:
563         return 4;
564     case VERTEXATTRIBTYPE_NONPURE_INT8:
565         return 1;
566     case VERTEXATTRIBTYPE_NONPURE_INT16:
567         return 2;
568     case VERTEXATTRIBTYPE_NONPURE_INT32:
569         return 4;
570     case VERTEXATTRIBTYPE_NONPURE_UINT_2_10_10_10_REV:
571         return (int)sizeof(uint32_t) / 4;
572     case VERTEXATTRIBTYPE_NONPURE_INT_2_10_10_10_REV:
573         return (int)sizeof(uint32_t) / 4;
574     case VERTEXATTRIBTYPE_PURE_UINT8:
575         return 1;
576     case VERTEXATTRIBTYPE_PURE_UINT16:
577         return 2;
578     case VERTEXATTRIBTYPE_PURE_UINT32:
579         return 4;
580     case VERTEXATTRIBTYPE_PURE_INT8:
581         return 1;
582     case VERTEXATTRIBTYPE_PURE_INT16:
583         return 2;
584     case VERTEXATTRIBTYPE_PURE_INT32:
585         return 4;
586     case VERTEXATTRIBTYPE_NONPURE_UNORM8_BGRA:
587         return 1;
588     case VERTEXATTRIBTYPE_NONPURE_UNORM_2_10_10_10_REV_BGRA:
589         return (int)sizeof(uint32_t) / 4;
590     case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_CLAMP_BGRA:
591         return (int)sizeof(uint32_t) / 4;
592     case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_SCALE_BGRA:
593         return (int)sizeof(uint32_t) / 4;
594     default:
595         DE_ASSERT(false);
596         return 0;
597     }
598 }
599 
600 } // namespace
601 
isValidVertexAttrib(const VertexAttrib & vertexAttrib)602 bool isValidVertexAttrib(const VertexAttrib &vertexAttrib)
603 {
604     // Trivial range checks.
605     if (!de::inBounds<int>(vertexAttrib.type, 0, VERTEXATTRIBTYPE_LAST) || !de::inRange(vertexAttrib.size, 0, 4) ||
606         vertexAttrib.instanceDivisor < 0)
607         return false;
608 
609     // Generic attributes
610     if (!vertexAttrib.pointer && vertexAttrib.type != VERTEXATTRIBTYPE_DONT_CARE)
611         return false;
612 
613     // Packed formats
614     if ((vertexAttrib.type == VERTEXATTRIBTYPE_NONPURE_INT_2_10_10_10_REV ||
615          vertexAttrib.type == VERTEXATTRIBTYPE_NONPURE_UINT_2_10_10_10_REV ||
616          vertexAttrib.type == VERTEXATTRIBTYPE_NONPURE_UNORM_2_10_10_10_REV ||
617          vertexAttrib.type == VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_CLAMP ||
618          vertexAttrib.type == VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_SCALE ||
619          vertexAttrib.type == VERTEXATTRIBTYPE_NONPURE_UNORM_2_10_10_10_REV_BGRA ||
620          vertexAttrib.type == VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_CLAMP_BGRA ||
621          vertexAttrib.type == VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_SCALE_BGRA) &&
622         vertexAttrib.size != 4)
623         return false;
624 
625     return true;
626 }
627 
readVertexAttrib(tcu::Vec4 & dst,const VertexAttrib & vertexAttrib,const int instanceNdx,const int vertexNdx,const int baseInstanceNdx)628 void readVertexAttrib(tcu::Vec4 &dst, const VertexAttrib &vertexAttrib, const int instanceNdx, const int vertexNdx,
629                       const int baseInstanceNdx)
630 {
631     DE_ASSERT(isValidVertexAttrib(vertexAttrib));
632 
633     if (vertexAttrib.pointer)
634     {
635         const int elementNdx = (vertexAttrib.instanceDivisor != 0) ?
636                                    baseInstanceNdx + (instanceNdx / vertexAttrib.instanceDivisor) :
637                                    vertexNdx;
638         const int compSize   = getComponentSize(vertexAttrib.type);
639         const int stride     = (vertexAttrib.stride != 0) ? (vertexAttrib.stride) : (vertexAttrib.size * compSize);
640         const int byteOffset = elementNdx * stride;
641 
642         dst = tcu::Vec4(0, 0, 0, 1); // defaults
643         readFloat(dst, vertexAttrib.type, vertexAttrib.size, (const uint8_t *)vertexAttrib.pointer + byteOffset);
644     }
645     else
646     {
647         dst = vertexAttrib.generic.get<float>();
648     }
649 }
650 
readVertexAttrib(tcu::IVec4 & dst,const VertexAttrib & vertexAttrib,const int instanceNdx,const int vertexNdx,const int baseInstanceNdx)651 void readVertexAttrib(tcu::IVec4 &dst, const VertexAttrib &vertexAttrib, const int instanceNdx, const int vertexNdx,
652                       const int baseInstanceNdx)
653 {
654     DE_ASSERT(isValidVertexAttrib(vertexAttrib));
655 
656     if (vertexAttrib.pointer)
657     {
658         const int elementNdx = (vertexAttrib.instanceDivisor != 0) ?
659                                    baseInstanceNdx + (instanceNdx / vertexAttrib.instanceDivisor) :
660                                    vertexNdx;
661         const int compSize   = getComponentSize(vertexAttrib.type);
662         const int stride     = (vertexAttrib.stride != 0) ? (vertexAttrib.stride) : (vertexAttrib.size * compSize);
663         const int byteOffset = elementNdx * stride;
664 
665         dst = tcu::IVec4(0, 0, 0, 1); // defaults
666         readInt(dst, vertexAttrib.type, vertexAttrib.size, (const uint8_t *)vertexAttrib.pointer + byteOffset);
667     }
668     else
669     {
670         dst = vertexAttrib.generic.get<int32_t>();
671     }
672 }
673 
readVertexAttrib(tcu::UVec4 & dst,const VertexAttrib & vertexAttrib,const int instanceNdx,const int vertexNdx,const int baseInstanceNdx)674 void readVertexAttrib(tcu::UVec4 &dst, const VertexAttrib &vertexAttrib, const int instanceNdx, const int vertexNdx,
675                       const int baseInstanceNdx)
676 {
677     DE_ASSERT(isValidVertexAttrib(vertexAttrib));
678 
679     if (vertexAttrib.pointer)
680     {
681         const int elementNdx = (vertexAttrib.instanceDivisor != 0) ?
682                                    baseInstanceNdx + (instanceNdx / vertexAttrib.instanceDivisor) :
683                                    vertexNdx;
684         const int compSize   = getComponentSize(vertexAttrib.type);
685         const int stride     = (vertexAttrib.stride != 0) ? (vertexAttrib.stride) : (vertexAttrib.size * compSize);
686         const int byteOffset = elementNdx * stride;
687 
688         dst = tcu::UVec4(0, 0, 0, 1); // defaults
689         readUint(dst, vertexAttrib.type, vertexAttrib.size, (const uint8_t *)vertexAttrib.pointer + byteOffset);
690     }
691     else
692     {
693         dst = vertexAttrib.generic.get<uint32_t>();
694     }
695 }
696 
697 } // namespace rr
698