• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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