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) dst[Order::T1] = DstScalarType(aligned[1]);
67 if (size >= 3) dst[Order::T2] = DstScalarType(aligned[2]);
68 if (size >= 4) dst[Order::T3] = DstScalarType(aligned[3]);
69 }
70
71 template<typename SrcScalarType, typename Order>
readUnormOrder(tcu::Vec4 & dst,const int size,const void * ptr)72 inline void readUnormOrder (tcu::Vec4& dst, const int size, const void* ptr)
73 {
74 const deUint32 range = (deUint32)((1ull << (sizeof(SrcScalarType)*8))-1);
75
76 SrcScalarType aligned[4];
77 deMemcpy(aligned, ptr, size * sizeof(SrcScalarType));
78
79 dst[Order::T0] = float(aligned[0]) / float(range);
80 if (size >= 2) dst[Order::T1] = float(aligned[1]) / float(range);
81 if (size >= 3) dst[Order::T2] = float(aligned[2]) / float(range);
82 if (size >= 4) dst[Order::T3] = float(aligned[3]) / float(range);
83 }
84
85 template<typename SrcScalarType>
readSnormClamp(tcu::Vec4 & dst,const int size,const void * ptr)86 inline void readSnormClamp (tcu::Vec4& dst, const int size, const void* ptr)
87 {
88 // Clamped formats, GLES3-style conversion: max{c / (2^(b-1) - 1), -1 }
89 const deUint32 range = (deUint32)((1ull << (sizeof(SrcScalarType)*8-1))-1);
90
91 SrcScalarType aligned[4];
92 deMemcpy(aligned, ptr, size * sizeof(SrcScalarType));
93
94 dst[0] = de::max(-1.0f, float(aligned[0]) / float(range));
95 if (size >= 2) dst[1] = de::max(-1.0f, float(aligned[1]) / float(range));
96 if (size >= 3) dst[2] = de::max(-1.0f, float(aligned[2]) / float(range));
97 if (size >= 4) dst[3] = de::max(-1.0f, float(aligned[3]) / float(range));
98 }
99
100 template<typename SrcScalarType>
readSnormScale(tcu::Vec4 & dst,const int size,const void * ptr)101 inline void readSnormScale (tcu::Vec4& dst, const int size, const void* ptr)
102 {
103 // Scaled formats, GLES2-style conversion: (2c + 1) / (2^b - 1)
104 const deUint32 range = (deUint32)((1ull << (sizeof(SrcScalarType)*8))-1);
105
106 SrcScalarType aligned[4];
107 deMemcpy(aligned, ptr, size * sizeof(SrcScalarType));
108
109 dst[0] = (float(aligned[0]) * 2.0f + 1.0f) / float(range);
110 if (size >= 2) dst[1] = (float(aligned[1]) * 2.0f + 1.0f) / float(range);
111 if (size >= 3) dst[2] = (float(aligned[2]) * 2.0f + 1.0f) / float(range);
112 if (size >= 4) dst[3] = (float(aligned[3]) * 2.0f + 1.0f) / float(range);
113 }
114
readHalf(tcu::Vec4 & dst,const int size,const void * ptr)115 inline void readHalf (tcu::Vec4& dst, const int size, const void* ptr)
116 {
117 deUint16 aligned[4];
118 deMemcpy(aligned, ptr, size * sizeof(deUint16));
119
120 dst[0] = tcu::Float16(aligned[0]).asFloat();
121 if (size >= 2) dst[1] = tcu::Float16(aligned[1]).asFloat();
122 if (size >= 3) dst[2] = tcu::Float16(aligned[2]).asFloat();
123 if (size >= 4) dst[3] = tcu::Float16(aligned[3]).asFloat();
124 }
125
readFixed(tcu::Vec4 & dst,const int size,const void * ptr)126 inline void readFixed (tcu::Vec4& dst, const int size, const void* ptr)
127 {
128 deInt32 aligned[4];
129 deMemcpy(aligned, ptr, size * sizeof(deInt32));
130
131 dst[0] = float(aligned[0]) / float(1 << 16);
132 if (size >= 2) dst[1] = float(aligned[1]) / float(1 << 16);
133 if (size >= 3) dst[2] = float(aligned[2]) / float(1 << 16);
134 if (size >= 4) dst[3] = float(aligned[3]) / float(1 << 16);
135 }
136
readDouble(tcu::Vec4 & dst,const int size,const void * ptr)137 inline void readDouble (tcu::Vec4& dst, const int size, const void* ptr)
138 {
139 double aligned[4];
140 deMemcpy(aligned, ptr, size * sizeof(double));
141
142 dst[0] = float(aligned[0]);
143 if (size >= 2) dst[1] = float(aligned[1]);
144 if (size >= 3) dst[2] = float(aligned[2]);
145 if (size >= 4) dst[3] = float(aligned[3]);
146 }
147
148 template <int integerLen>
extendSign(deUint32 integer)149 inline deInt32 extendSign (deUint32 integer)
150 {
151 return deUint32(0 - deInt32((integer & (1 << (integerLen - 1))) << 1)) | integer;
152 }
153
154 template<typename DstScalarType>
readUint2101010Rev(typename tcu::Vector<DstScalarType,4> & dst,const int size,const void * ptr)155 inline void readUint2101010Rev (typename tcu::Vector<DstScalarType, 4>& dst, const int size, const void* ptr)
156 {
157 deUint32 aligned;
158 deMemcpy(&aligned, ptr, sizeof(deUint32));
159
160 dst[0] = DstScalarType((aligned >> 0) & ((1 << 10) - 1));
161 if (size >= 2) dst[1] = DstScalarType((aligned >> 10) & ((1 << 10) - 1));
162 if (size >= 3) dst[2] = DstScalarType((aligned >> 20) & ((1 << 10) - 1));
163 if (size >= 4) dst[3] = DstScalarType((aligned >> 30) & ((1 << 2) - 1));
164 }
165
166 template<typename DstScalarType>
readInt2101010Rev(typename tcu::Vector<DstScalarType,4> & dst,const int size,const void * ptr)167 inline void readInt2101010Rev (typename tcu::Vector<DstScalarType, 4>& dst, const int size, const void* ptr)
168 {
169 deUint32 aligned;
170 deMemcpy(&aligned, ptr, sizeof(deUint32));
171
172 dst[0] = (DstScalarType)extendSign<10>((aligned >> 0) & ((1 << 10) - 1));
173 if (size >= 2) dst[1] = (DstScalarType)extendSign<10>((aligned >> 10) & ((1 << 10) - 1));
174 if (size >= 3) dst[2] = (DstScalarType)extendSign<10>((aligned >> 20) & ((1 << 10) - 1));
175 if (size >= 4) dst[3] = (DstScalarType)extendSign< 2>((aligned >> 30) & ((1 << 2) - 1));
176 }
177
178 template<typename Order>
readUnorm2101010RevOrder(tcu::Vec4 & dst,const int size,const void * ptr)179 inline void readUnorm2101010RevOrder (tcu::Vec4& dst, const int size, const void* ptr)
180 {
181 const deUint32 range10 = (deUint32)((1ull << 10)-1);
182 const deUint32 range2 = (deUint32)((1ull << 2)-1);
183
184 deUint32 aligned;
185 deMemcpy(&aligned, ptr, sizeof(deUint32));
186
187 dst[Order::T0] = float((aligned >> 0) & ((1 << 10) - 1)) / float(range10);
188 if (size >= 2) dst[Order::T1] = float((aligned >> 10) & ((1 << 10) - 1)) / float(range10);
189 if (size >= 3) dst[Order::T2] = float((aligned >> 20) & ((1 << 10) - 1)) / float(range10);
190 if (size >= 4) dst[Order::T3] = float((aligned >> 30) & ((1 << 2) - 1)) / float(range2);
191 }
192
193 template<typename Order>
readSnorm2101010RevClampOrder(tcu::Vec4 & dst,const int size,const void * ptr)194 inline void readSnorm2101010RevClampOrder (tcu::Vec4& dst, const int size, const void* ptr)
195 {
196 // Clamped formats, GLES3-style conversion: max{c / (2^(b-1) - 1), -1 }
197 const deUint32 range10 = (deUint32)((1ull << (10-1))-1);
198 const deUint32 range2 = (deUint32)((1ull << ( 2-1))-1);
199
200 deUint32 aligned;
201 deMemcpy(&aligned, ptr, sizeof(deUint32));
202
203 dst[Order::T0] = de::max(-1.0f, float(extendSign<10>((aligned >> 0) & ((1 << 10) - 1))) / float(range10));
204 if (size >= 2) dst[Order::T1] = de::max(-1.0f, float(extendSign<10>((aligned >> 10) & ((1 << 10) - 1))) / float(range10));
205 if (size >= 3) dst[Order::T2] = de::max(-1.0f, float(extendSign<10>((aligned >> 20) & ((1 << 10) - 1))) / float(range10));
206 if (size >= 4) dst[Order::T3] = de::max(-1.0f, float(extendSign< 2>((aligned >> 30) & ((1 << 2) - 1))) / float(range2));
207 }
208
209 template<typename Order>
readSnorm2101010RevScaleOrder(tcu::Vec4 & dst,const int size,const void * ptr)210 inline void readSnorm2101010RevScaleOrder (tcu::Vec4& dst, const int size, const void* ptr)
211 {
212 // Scaled formats, GLES2-style conversion: (2c + 1) / (2^b - 1)
213 const deUint32 range10 = (deUint32)((1ull << 10)-1);
214 const deUint32 range2 = (deUint32)((1ull << 2)-1);
215
216 deUint32 aligned;
217 deMemcpy(&aligned, ptr, sizeof(deUint32));
218
219 dst[Order::T0] = (float(extendSign<10>((aligned >> 0) & ((1 << 10) - 1))) * 2.0f + 1.0f) / float(range10);
220 if (size >= 2) dst[Order::T1] = (float(extendSign<10>((aligned >> 10) & ((1 << 10) - 1))) * 2.0f + 1.0f) / float(range10);
221 if (size >= 3) dst[Order::T2] = (float(extendSign<10>((aligned >> 20) & ((1 << 10) - 1))) * 2.0f + 1.0f) / float(range10);
222 if (size >= 4) dst[Order::T3] = (float(extendSign< 2>((aligned >> 30) & ((1 << 2) - 1))) * 2.0f + 1.0f) / float(range2);
223 }
224
225 // ordered readers
226
227 template<typename SrcScalarType, typename DstScalarType>
read(typename tcu::Vector<DstScalarType,4> & dst,const int size,const void * ptr)228 inline void read (typename tcu::Vector<DstScalarType, 4>& dst, const int size, const void* ptr)
229 {
230 readOrder<SrcScalarType, DstScalarType, NormalOrder>(dst, size, ptr);
231 }
232
233 template<typename SrcScalarType>
readUnorm(tcu::Vec4 & dst,const int size,const void * ptr)234 inline void readUnorm (tcu::Vec4& dst, const int size, const void* ptr)
235 {
236 readUnormOrder<SrcScalarType, NormalOrder>(dst, size, ptr);
237 }
238
239 template<typename SrcScalarType>
readUnormBGRA(tcu::Vec4 & dst,const int size,const void * ptr)240 inline void readUnormBGRA (tcu::Vec4& dst, const int size, const void* ptr)
241 {
242 readUnormOrder<SrcScalarType, BGRAOrder>(dst, size, ptr);
243 }
244
readUnorm2101010Rev(tcu::Vec4 & dst,const int size,const void * ptr)245 inline void readUnorm2101010Rev (tcu::Vec4& dst, const int size, const void* ptr)
246 {
247 readUnorm2101010RevOrder<NormalOrder>(dst, size, ptr);
248 }
249
readUnorm2101010RevBGRA(tcu::Vec4 & dst,const int size,const void * ptr)250 inline void readUnorm2101010RevBGRA (tcu::Vec4& dst, const int size, const void* ptr)
251 {
252 readUnorm2101010RevOrder<BGRAOrder>(dst, size, ptr);
253 }
254
readSnorm2101010RevClamp(tcu::Vec4 & dst,const int size,const void * ptr)255 inline void readSnorm2101010RevClamp (tcu::Vec4& dst, const int size, const void* ptr)
256 {
257 readSnorm2101010RevClampOrder<NormalOrder>(dst, size, ptr);
258 }
259
readSnorm2101010RevClampBGRA(tcu::Vec4 & dst,const int size,const void * ptr)260 inline void readSnorm2101010RevClampBGRA (tcu::Vec4& dst, const int size, const void* ptr)
261 {
262 readSnorm2101010RevClampOrder<BGRAOrder>(dst, size, ptr);
263 }
264
readSnorm2101010RevScale(tcu::Vec4 & dst,const int size,const void * ptr)265 inline void readSnorm2101010RevScale (tcu::Vec4& dst, const int size, const void* ptr)
266 {
267 readSnorm2101010RevScaleOrder<NormalOrder>(dst, size, ptr);
268 }
269
readSnorm2101010RevScaleBGRA(tcu::Vec4 & dst,const int size,const void * ptr)270 inline void readSnorm2101010RevScaleBGRA (tcu::Vec4& dst, const int size, const void* ptr)
271 {
272 readSnorm2101010RevScaleOrder<BGRAOrder>(dst, size, ptr);
273 }
274
275 // utils
276
readFloat(tcu::Vec4 & dst,const VertexAttribType type,const int size,const void * ptr)277 void readFloat (tcu::Vec4& dst, const VertexAttribType type, const int size, const void* ptr)
278 {
279 switch (type)
280 {
281 case VERTEXATTRIBTYPE_FLOAT: read<float> (dst, size, ptr); break;
282 case VERTEXATTRIBTYPE_HALF: readHalf (dst, size, ptr); break;
283 case VERTEXATTRIBTYPE_FIXED: readFixed (dst, size, ptr); break;
284 case VERTEXATTRIBTYPE_DOUBLE: readDouble (dst, size, ptr); break;
285 case VERTEXATTRIBTYPE_NONPURE_UNORM8: readUnorm<deUint8> (dst, size, ptr); break;
286 case VERTEXATTRIBTYPE_NONPURE_UNORM16: readUnorm<deUint16> (dst, size, ptr); break;
287 case VERTEXATTRIBTYPE_NONPURE_UNORM32: readUnorm<deUint32> (dst, size, ptr); break;
288 case VERTEXATTRIBTYPE_NONPURE_UNORM_2_10_10_10_REV: readUnorm2101010Rev (dst, size, ptr); break;
289 case VERTEXATTRIBTYPE_NONPURE_SNORM8_CLAMP: readSnormClamp<deInt8> (dst, size, ptr); break;
290 case VERTEXATTRIBTYPE_NONPURE_SNORM16_CLAMP: readSnormClamp<deInt16> (dst, size, ptr); break;
291 case VERTEXATTRIBTYPE_NONPURE_SNORM32_CLAMP: readSnormClamp<deInt32> (dst, size, ptr); break;
292 case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_CLAMP: readSnorm2101010RevClamp (dst, size, ptr); break;
293 case VERTEXATTRIBTYPE_NONPURE_SNORM8_SCALE: readSnormScale<deInt8> (dst, size, ptr); break;
294 case VERTEXATTRIBTYPE_NONPURE_SNORM16_SCALE: readSnormScale<deInt16> (dst, size, ptr); break;
295 case VERTEXATTRIBTYPE_NONPURE_SNORM32_SCALE: readSnormScale<deInt32> (dst, size, ptr); break;
296 case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_SCALE: readSnorm2101010RevScale (dst, size, ptr); break;
297 case VERTEXATTRIBTYPE_NONPURE_UINT8: read<deUint8> (dst, size, ptr); break;
298 case VERTEXATTRIBTYPE_NONPURE_UINT16: read<deUint16> (dst, size, ptr); break;
299 case VERTEXATTRIBTYPE_NONPURE_UINT32: read<deUint32> (dst, size, ptr); break;
300 case VERTEXATTRIBTYPE_NONPURE_INT8: read<deInt8> (dst, size, ptr); break;
301 case VERTEXATTRIBTYPE_NONPURE_INT16: read<deInt16> (dst, size, ptr); break;
302 case VERTEXATTRIBTYPE_NONPURE_INT32: read<deInt32> (dst, size, ptr); break;
303 case VERTEXATTRIBTYPE_NONPURE_UINT_2_10_10_10_REV: readUint2101010Rev (dst, size, ptr); break;
304 case VERTEXATTRIBTYPE_NONPURE_INT_2_10_10_10_REV: readInt2101010Rev (dst, size, ptr); break;
305 case VERTEXATTRIBTYPE_NONPURE_UNORM8_BGRA: readUnormBGRA<deUint8> (dst, size, ptr); break;
306 case VERTEXATTRIBTYPE_NONPURE_UNORM_2_10_10_10_REV_BGRA: readUnorm2101010RevBGRA (dst, size, ptr); break;
307 case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_CLAMP_BGRA: readSnorm2101010RevClampBGRA(dst, size, ptr); break;
308 case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_SCALE_BGRA: readSnorm2101010RevScaleBGRA(dst, size, ptr); break;
309
310 case VERTEXATTRIBTYPE_PURE_UINT8:
311 case VERTEXATTRIBTYPE_PURE_UINT16:
312 case VERTEXATTRIBTYPE_PURE_UINT32:
313 case VERTEXATTRIBTYPE_PURE_INT8:
314 case VERTEXATTRIBTYPE_PURE_INT16:
315 case VERTEXATTRIBTYPE_PURE_INT32:
316 DE_FATAL("Invalid read");
317 break;
318
319 default:
320 DE_ASSERT(false);
321 }
322 }
323
readInt(tcu::IVec4 & dst,const VertexAttribType type,const int size,const void * ptr)324 void readInt (tcu::IVec4& dst, const VertexAttribType type, const int size, const void* ptr)
325 {
326 switch (type)
327 {
328 case VERTEXATTRIBTYPE_PURE_INT8: read<deInt8> (dst, size, ptr); break;
329 case VERTEXATTRIBTYPE_PURE_INT16: read<deInt16> (dst, size, ptr); break;
330 case VERTEXATTRIBTYPE_PURE_INT32: read<deInt32> (dst, size, ptr); break;
331
332 case VERTEXATTRIBTYPE_FLOAT:
333 case VERTEXATTRIBTYPE_HALF:
334 case VERTEXATTRIBTYPE_FIXED:
335 case VERTEXATTRIBTYPE_DOUBLE:
336 case VERTEXATTRIBTYPE_NONPURE_UNORM8:
337 case VERTEXATTRIBTYPE_NONPURE_UNORM16:
338 case VERTEXATTRIBTYPE_NONPURE_UNORM32:
339 case VERTEXATTRIBTYPE_NONPURE_UNORM_2_10_10_10_REV:
340 case VERTEXATTRIBTYPE_NONPURE_SNORM8_CLAMP:
341 case VERTEXATTRIBTYPE_NONPURE_SNORM16_CLAMP:
342 case VERTEXATTRIBTYPE_NONPURE_SNORM32_CLAMP:
343 case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_CLAMP:
344 case VERTEXATTRIBTYPE_NONPURE_SNORM8_SCALE:
345 case VERTEXATTRIBTYPE_NONPURE_SNORM16_SCALE:
346 case VERTEXATTRIBTYPE_NONPURE_SNORM32_SCALE:
347 case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_SCALE:
348 case VERTEXATTRIBTYPE_NONPURE_UINT8:
349 case VERTEXATTRIBTYPE_NONPURE_UINT16:
350 case VERTEXATTRIBTYPE_NONPURE_UINT32:
351 case VERTEXATTRIBTYPE_NONPURE_INT8:
352 case VERTEXATTRIBTYPE_NONPURE_INT16:
353 case VERTEXATTRIBTYPE_NONPURE_INT32:
354 case VERTEXATTRIBTYPE_NONPURE_UINT_2_10_10_10_REV:
355 case VERTEXATTRIBTYPE_NONPURE_INT_2_10_10_10_REV:
356 case VERTEXATTRIBTYPE_PURE_UINT8:
357 case VERTEXATTRIBTYPE_PURE_UINT16:
358 case VERTEXATTRIBTYPE_PURE_UINT32:
359 case VERTEXATTRIBTYPE_NONPURE_UNORM8_BGRA:
360 case VERTEXATTRIBTYPE_NONPURE_UNORM_2_10_10_10_REV_BGRA:
361 case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_CLAMP_BGRA:
362 case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_SCALE_BGRA:
363 DE_FATAL("Invalid read");
364 break;
365
366 default:
367 DE_ASSERT(false);
368 }
369 }
370
readUint(tcu::UVec4 & dst,const VertexAttribType type,const int size,const void * ptr)371 void readUint (tcu::UVec4& dst, const VertexAttribType type, const int size, const void* ptr)
372 {
373 switch (type)
374 {
375 case VERTEXATTRIBTYPE_PURE_UINT8: read<deUint8> (dst, size, ptr); break;
376 case VERTEXATTRIBTYPE_PURE_UINT16: read<deUint16> (dst, size, ptr); break;
377 case VERTEXATTRIBTYPE_PURE_UINT32: read<deUint32> (dst, size, ptr); break;
378
379 case VERTEXATTRIBTYPE_FLOAT:
380 case VERTEXATTRIBTYPE_HALF:
381 case VERTEXATTRIBTYPE_FIXED:
382 case VERTEXATTRIBTYPE_DOUBLE:
383 case VERTEXATTRIBTYPE_NONPURE_UNORM8:
384 case VERTEXATTRIBTYPE_NONPURE_UNORM16:
385 case VERTEXATTRIBTYPE_NONPURE_UNORM32:
386 case VERTEXATTRIBTYPE_NONPURE_UNORM_2_10_10_10_REV:
387 case VERTEXATTRIBTYPE_NONPURE_SNORM8_CLAMP:
388 case VERTEXATTRIBTYPE_NONPURE_SNORM16_CLAMP:
389 case VERTEXATTRIBTYPE_NONPURE_SNORM32_CLAMP:
390 case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_CLAMP:
391 case VERTEXATTRIBTYPE_NONPURE_SNORM8_SCALE:
392 case VERTEXATTRIBTYPE_NONPURE_SNORM16_SCALE:
393 case VERTEXATTRIBTYPE_NONPURE_SNORM32_SCALE:
394 case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_SCALE:
395 case VERTEXATTRIBTYPE_NONPURE_UINT8:
396 case VERTEXATTRIBTYPE_NONPURE_UINT16:
397 case VERTEXATTRIBTYPE_NONPURE_UINT32:
398 case VERTEXATTRIBTYPE_NONPURE_INT8:
399 case VERTEXATTRIBTYPE_NONPURE_INT16:
400 case VERTEXATTRIBTYPE_NONPURE_INT32:
401 case VERTEXATTRIBTYPE_NONPURE_UINT_2_10_10_10_REV:
402 case VERTEXATTRIBTYPE_NONPURE_INT_2_10_10_10_REV:
403 case VERTEXATTRIBTYPE_PURE_INT8:
404 case VERTEXATTRIBTYPE_PURE_INT16:
405 case VERTEXATTRIBTYPE_PURE_INT32:
406 case VERTEXATTRIBTYPE_NONPURE_UNORM8_BGRA:
407 case VERTEXATTRIBTYPE_NONPURE_UNORM_2_10_10_10_REV_BGRA:
408 case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_CLAMP_BGRA:
409 case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_SCALE_BGRA:
410 DE_FATAL("Invalid read");
411 break;
412
413 default:
414 DE_ASSERT(false);
415 }
416 }
417
getComponentSize(const VertexAttribType type)418 int getComponentSize (const VertexAttribType type)
419 {
420 switch (type)
421 {
422 case VERTEXATTRIBTYPE_FLOAT: return 4;
423 case VERTEXATTRIBTYPE_HALF: return 2;
424 case VERTEXATTRIBTYPE_FIXED: return 4;
425 case VERTEXATTRIBTYPE_DOUBLE: return (int)sizeof(double);
426 case VERTEXATTRIBTYPE_NONPURE_UNORM8: return 1;
427 case VERTEXATTRIBTYPE_NONPURE_UNORM16: return 2;
428 case VERTEXATTRIBTYPE_NONPURE_UNORM32: return 4;
429 case VERTEXATTRIBTYPE_NONPURE_UNORM_2_10_10_10_REV: return (int)sizeof(deUint32)/4;
430 case VERTEXATTRIBTYPE_NONPURE_SNORM8_CLAMP: return 1;
431 case VERTEXATTRIBTYPE_NONPURE_SNORM16_CLAMP: return 2;
432 case VERTEXATTRIBTYPE_NONPURE_SNORM32_CLAMP: return 4;
433 case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_CLAMP: return (int)sizeof(deUint32)/4;
434 case VERTEXATTRIBTYPE_NONPURE_SNORM8_SCALE: return 1;
435 case VERTEXATTRIBTYPE_NONPURE_SNORM16_SCALE: return 2;
436 case VERTEXATTRIBTYPE_NONPURE_SNORM32_SCALE: return 4;
437 case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_SCALE: return (int)sizeof(deUint32)/4;
438 case VERTEXATTRIBTYPE_NONPURE_UINT8: return 1;
439 case VERTEXATTRIBTYPE_NONPURE_UINT16: return 2;
440 case VERTEXATTRIBTYPE_NONPURE_UINT32: return 4;
441 case VERTEXATTRIBTYPE_NONPURE_INT8: return 1;
442 case VERTEXATTRIBTYPE_NONPURE_INT16: return 2;
443 case VERTEXATTRIBTYPE_NONPURE_INT32: return 4;
444 case VERTEXATTRIBTYPE_NONPURE_UINT_2_10_10_10_REV: return (int)sizeof(deUint32)/4;
445 case VERTEXATTRIBTYPE_NONPURE_INT_2_10_10_10_REV: return (int)sizeof(deUint32)/4;
446 case VERTEXATTRIBTYPE_PURE_UINT8: return 1;
447 case VERTEXATTRIBTYPE_PURE_UINT16: return 2;
448 case VERTEXATTRIBTYPE_PURE_UINT32: return 4;
449 case VERTEXATTRIBTYPE_PURE_INT8: return 1;
450 case VERTEXATTRIBTYPE_PURE_INT16: return 2;
451 case VERTEXATTRIBTYPE_PURE_INT32: return 4;
452 case VERTEXATTRIBTYPE_NONPURE_UNORM8_BGRA: return 1;
453 case VERTEXATTRIBTYPE_NONPURE_UNORM_2_10_10_10_REV_BGRA: return (int)sizeof(deUint32)/4;
454 case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_CLAMP_BGRA: return (int)sizeof(deUint32)/4;
455 case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_SCALE_BGRA: return (int)sizeof(deUint32)/4;
456 default:
457 DE_ASSERT(false);
458 return 0;
459 }
460 }
461
462 } // anonymous
463
isValidVertexAttrib(const VertexAttrib & vertexAttrib)464 bool isValidVertexAttrib (const VertexAttrib& vertexAttrib)
465 {
466 // Trivial range checks.
467 if (!de::inBounds<int>(vertexAttrib.type, 0, VERTEXATTRIBTYPE_LAST) ||
468 !de::inRange(vertexAttrib.size, 0, 4) ||
469 vertexAttrib.instanceDivisor < 0)
470 return false;
471
472 // Generic attributes
473 if (!vertexAttrib.pointer && vertexAttrib.type != VERTEXATTRIBTYPE_DONT_CARE)
474 return false;
475
476 // Packed formats
477 if ((vertexAttrib.type == VERTEXATTRIBTYPE_NONPURE_INT_2_10_10_10_REV ||
478 vertexAttrib.type == VERTEXATTRIBTYPE_NONPURE_UINT_2_10_10_10_REV ||
479 vertexAttrib.type == VERTEXATTRIBTYPE_NONPURE_UNORM_2_10_10_10_REV ||
480 vertexAttrib.type == VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_CLAMP ||
481 vertexAttrib.type == VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_SCALE ||
482 vertexAttrib.type == VERTEXATTRIBTYPE_NONPURE_UNORM_2_10_10_10_REV_BGRA ||
483 vertexAttrib.type == VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_CLAMP_BGRA ||
484 vertexAttrib.type == VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_SCALE_BGRA) &&
485 vertexAttrib.size != 4)
486 return false;
487
488 return true;
489 }
490
readVertexAttrib(tcu::Vec4 & dst,const VertexAttrib & vertexAttrib,const int instanceNdx,const int vertexNdx,const int baseInstanceNdx)491 void readVertexAttrib (tcu::Vec4& dst, const VertexAttrib& vertexAttrib, const int instanceNdx, const int vertexNdx, const int baseInstanceNdx)
492 {
493 DE_ASSERT(isValidVertexAttrib(vertexAttrib));
494
495 if (vertexAttrib.pointer)
496 {
497 const int elementNdx = (vertexAttrib.instanceDivisor != 0) ? baseInstanceNdx + (instanceNdx / vertexAttrib.instanceDivisor) : vertexNdx;
498 const int compSize = getComponentSize(vertexAttrib.type);
499 const int stride = (vertexAttrib.stride != 0) ? (vertexAttrib.stride) : (vertexAttrib.size*compSize);
500 const int byteOffset = elementNdx*stride;
501
502 dst = tcu::Vec4(0, 0, 0, 1); // defaults
503 readFloat(dst, vertexAttrib.type, vertexAttrib.size, (const deUint8*)vertexAttrib.pointer + byteOffset);
504 }
505 else
506 {
507 dst = vertexAttrib.generic.get<float>();
508 }
509 }
510
readVertexAttrib(tcu::IVec4 & dst,const VertexAttrib & vertexAttrib,const int instanceNdx,const int vertexNdx,const int baseInstanceNdx)511 void readVertexAttrib (tcu::IVec4& dst, const VertexAttrib& vertexAttrib, const int instanceNdx, const int vertexNdx, const int baseInstanceNdx)
512 {
513 DE_ASSERT(isValidVertexAttrib(vertexAttrib));
514
515 if (vertexAttrib.pointer)
516 {
517 const int elementNdx = (vertexAttrib.instanceDivisor != 0) ? baseInstanceNdx + (instanceNdx / vertexAttrib.instanceDivisor) : vertexNdx;
518 const int compSize = getComponentSize(vertexAttrib.type);
519 const int stride = (vertexAttrib.stride != 0) ? (vertexAttrib.stride) : (vertexAttrib.size*compSize);
520 const int byteOffset = elementNdx*stride;
521
522 dst = tcu::IVec4(0, 0, 0, 1); // defaults
523 readInt(dst, vertexAttrib.type, vertexAttrib.size, (const deUint8*)vertexAttrib.pointer + byteOffset);
524 }
525 else
526 {
527 dst = vertexAttrib.generic.get<deInt32>();
528 }
529 }
530
readVertexAttrib(tcu::UVec4 & dst,const VertexAttrib & vertexAttrib,const int instanceNdx,const int vertexNdx,const int baseInstanceNdx)531 void readVertexAttrib (tcu::UVec4& dst, const VertexAttrib& vertexAttrib, const int instanceNdx, const int vertexNdx, const int baseInstanceNdx)
532 {
533 DE_ASSERT(isValidVertexAttrib(vertexAttrib));
534
535 if (vertexAttrib.pointer)
536 {
537 const int elementNdx = (vertexAttrib.instanceDivisor != 0) ? baseInstanceNdx + (instanceNdx / vertexAttrib.instanceDivisor) : vertexNdx;
538 const int compSize = getComponentSize(vertexAttrib.type);
539 const int stride = (vertexAttrib.stride != 0) ? (vertexAttrib.stride) : (vertexAttrib.size*compSize);
540 const int byteOffset = elementNdx*stride;
541
542 dst = tcu::UVec4(0, 0, 0, 1); // defaults
543 readUint(dst, vertexAttrib.type, vertexAttrib.size, (const deUint8*)vertexAttrib.pointer + byteOffset);
544 }
545 else
546 {
547 dst = vertexAttrib.generic.get<deUint32>();
548 }
549 }
550
551 } // rr
552