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