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> 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> 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> 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> 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 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 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] = aligned[0] / float(1 << 16); 132 if (size >= 2) dst[1] = aligned[1] / float(1 << 16); 133 if (size >= 3) dst[2] = aligned[2] / float(1 << 16); 134 if (size >= 4) dst[3] = aligned[3] / float(1 << 16); 135 } 136 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> 149 inline deInt32 extendSign (deUint32 integer) 150 { 151 return deUint32(0 - deInt32((integer & (1 << (integerLen - 1))) << 1)) | integer; 152 } 153 154 template<typename DstScalarType> 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> 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> 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> 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> 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> 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> 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> 240 inline void readUnormBGRA (tcu::Vec4& dst, const int size, const void* ptr) 241 { 242 readUnormOrder<SrcScalarType, BGRAOrder>(dst, size, ptr); 243 } 244 245 inline void readUnorm2101010Rev (tcu::Vec4& dst, const int size, const void* ptr) 246 { 247 readUnorm2101010RevOrder<NormalOrder>(dst, size, ptr); 248 } 249 250 inline void readUnorm2101010RevBGRA (tcu::Vec4& dst, const int size, const void* ptr) 251 { 252 readUnorm2101010RevOrder<BGRAOrder>(dst, size, ptr); 253 } 254 255 inline void readSnorm2101010RevClamp (tcu::Vec4& dst, const int size, const void* ptr) 256 { 257 readSnorm2101010RevClampOrder<NormalOrder>(dst, size, ptr); 258 } 259 260 inline void readSnorm2101010RevClampBGRA (tcu::Vec4& dst, const int size, const void* ptr) 261 { 262 readSnorm2101010RevClampOrder<BGRAOrder>(dst, size, ptr); 263 } 264 265 inline void readSnorm2101010RevScale (tcu::Vec4& dst, const int size, const void* ptr) 266 { 267 readSnorm2101010RevScaleOrder<NormalOrder>(dst, size, ptr); 268 } 269 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 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_ASSERT(!"Invalid read"); 317 318 default: 319 DE_ASSERT(false); 320 } 321 } 322 323 void readInt (tcu::IVec4& dst, const VertexAttribType type, const int size, const void* ptr) 324 { 325 switch (type) 326 { 327 case VERTEXATTRIBTYPE_PURE_INT8: read<deInt8> (dst, size, ptr); break; 328 case VERTEXATTRIBTYPE_PURE_INT16: read<deInt16> (dst, size, ptr); break; 329 case VERTEXATTRIBTYPE_PURE_INT32: read<deInt32> (dst, size, ptr); break; 330 331 case VERTEXATTRIBTYPE_FLOAT: 332 case VERTEXATTRIBTYPE_HALF: 333 case VERTEXATTRIBTYPE_FIXED: 334 case VERTEXATTRIBTYPE_DOUBLE: 335 case VERTEXATTRIBTYPE_NONPURE_UNORM8: 336 case VERTEXATTRIBTYPE_NONPURE_UNORM16: 337 case VERTEXATTRIBTYPE_NONPURE_UNORM32: 338 case VERTEXATTRIBTYPE_NONPURE_UNORM_2_10_10_10_REV: 339 case VERTEXATTRIBTYPE_NONPURE_SNORM8_CLAMP: 340 case VERTEXATTRIBTYPE_NONPURE_SNORM16_CLAMP: 341 case VERTEXATTRIBTYPE_NONPURE_SNORM32_CLAMP: 342 case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_CLAMP: 343 case VERTEXATTRIBTYPE_NONPURE_SNORM8_SCALE: 344 case VERTEXATTRIBTYPE_NONPURE_SNORM16_SCALE: 345 case VERTEXATTRIBTYPE_NONPURE_SNORM32_SCALE: 346 case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_SCALE: 347 case VERTEXATTRIBTYPE_NONPURE_UINT8: 348 case VERTEXATTRIBTYPE_NONPURE_UINT16: 349 case VERTEXATTRIBTYPE_NONPURE_UINT32: 350 case VERTEXATTRIBTYPE_NONPURE_INT8: 351 case VERTEXATTRIBTYPE_NONPURE_INT16: 352 case VERTEXATTRIBTYPE_NONPURE_INT32: 353 case VERTEXATTRIBTYPE_NONPURE_UINT_2_10_10_10_REV: 354 case VERTEXATTRIBTYPE_NONPURE_INT_2_10_10_10_REV: 355 case VERTEXATTRIBTYPE_PURE_UINT8: 356 case VERTEXATTRIBTYPE_PURE_UINT16: 357 case VERTEXATTRIBTYPE_PURE_UINT32: 358 case VERTEXATTRIBTYPE_NONPURE_UNORM8_BGRA: 359 case VERTEXATTRIBTYPE_NONPURE_UNORM_2_10_10_10_REV_BGRA: 360 case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_CLAMP_BGRA: 361 case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_SCALE_BGRA: 362 DE_ASSERT(!"Invalid read"); 363 364 default: 365 DE_ASSERT(false); 366 } 367 } 368 369 void readUint (tcu::UVec4& dst, const VertexAttribType type, const int size, const void* ptr) 370 { 371 switch (type) 372 { 373 case VERTEXATTRIBTYPE_PURE_UINT8: read<deUint8> (dst, size, ptr); break; 374 case VERTEXATTRIBTYPE_PURE_UINT16: read<deUint16> (dst, size, ptr); break; 375 case VERTEXATTRIBTYPE_PURE_UINT32: read<deUint32> (dst, size, ptr); break; 376 377 case VERTEXATTRIBTYPE_FLOAT: 378 case VERTEXATTRIBTYPE_HALF: 379 case VERTEXATTRIBTYPE_FIXED: 380 case VERTEXATTRIBTYPE_DOUBLE: 381 case VERTEXATTRIBTYPE_NONPURE_UNORM8: 382 case VERTEXATTRIBTYPE_NONPURE_UNORM16: 383 case VERTEXATTRIBTYPE_NONPURE_UNORM32: 384 case VERTEXATTRIBTYPE_NONPURE_UNORM_2_10_10_10_REV: 385 case VERTEXATTRIBTYPE_NONPURE_SNORM8_CLAMP: 386 case VERTEXATTRIBTYPE_NONPURE_SNORM16_CLAMP: 387 case VERTEXATTRIBTYPE_NONPURE_SNORM32_CLAMP: 388 case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_CLAMP: 389 case VERTEXATTRIBTYPE_NONPURE_SNORM8_SCALE: 390 case VERTEXATTRIBTYPE_NONPURE_SNORM16_SCALE: 391 case VERTEXATTRIBTYPE_NONPURE_SNORM32_SCALE: 392 case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_SCALE: 393 case VERTEXATTRIBTYPE_NONPURE_UINT8: 394 case VERTEXATTRIBTYPE_NONPURE_UINT16: 395 case VERTEXATTRIBTYPE_NONPURE_UINT32: 396 case VERTEXATTRIBTYPE_NONPURE_INT8: 397 case VERTEXATTRIBTYPE_NONPURE_INT16: 398 case VERTEXATTRIBTYPE_NONPURE_INT32: 399 case VERTEXATTRIBTYPE_NONPURE_UINT_2_10_10_10_REV: 400 case VERTEXATTRIBTYPE_NONPURE_INT_2_10_10_10_REV: 401 case VERTEXATTRIBTYPE_PURE_INT8: 402 case VERTEXATTRIBTYPE_PURE_INT16: 403 case VERTEXATTRIBTYPE_PURE_INT32: 404 case VERTEXATTRIBTYPE_NONPURE_UNORM8_BGRA: 405 case VERTEXATTRIBTYPE_NONPURE_UNORM_2_10_10_10_REV_BGRA: 406 case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_CLAMP_BGRA: 407 case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_SCALE_BGRA: 408 DE_ASSERT(!"Invalid read"); 409 410 default: 411 DE_ASSERT(false); 412 } 413 } 414 415 int getComponentSize (const VertexAttribType type) 416 { 417 switch (type) 418 { 419 case VERTEXATTRIBTYPE_FLOAT: return 4; 420 case VERTEXATTRIBTYPE_HALF: return 2; 421 case VERTEXATTRIBTYPE_FIXED: return 4; 422 case VERTEXATTRIBTYPE_DOUBLE: return sizeof(double); 423 case VERTEXATTRIBTYPE_NONPURE_UNORM8: return 1; 424 case VERTEXATTRIBTYPE_NONPURE_UNORM16: return 2; 425 case VERTEXATTRIBTYPE_NONPURE_UNORM32: return 4; 426 case VERTEXATTRIBTYPE_NONPURE_UNORM_2_10_10_10_REV: return sizeof(deUint32)/4; 427 case VERTEXATTRIBTYPE_NONPURE_SNORM8_CLAMP: return 1; 428 case VERTEXATTRIBTYPE_NONPURE_SNORM16_CLAMP: return 2; 429 case VERTEXATTRIBTYPE_NONPURE_SNORM32_CLAMP: return 4; 430 case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_CLAMP: return sizeof(deUint32)/4; 431 case VERTEXATTRIBTYPE_NONPURE_SNORM8_SCALE: return 1; 432 case VERTEXATTRIBTYPE_NONPURE_SNORM16_SCALE: return 2; 433 case VERTEXATTRIBTYPE_NONPURE_SNORM32_SCALE: return 4; 434 case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_SCALE: return sizeof(deUint32)/4; 435 case VERTEXATTRIBTYPE_NONPURE_UINT8: return 1; 436 case VERTEXATTRIBTYPE_NONPURE_UINT16: return 2; 437 case VERTEXATTRIBTYPE_NONPURE_UINT32: return 4; 438 case VERTEXATTRIBTYPE_NONPURE_INT8: return 1; 439 case VERTEXATTRIBTYPE_NONPURE_INT16: return 2; 440 case VERTEXATTRIBTYPE_NONPURE_INT32: return 4; 441 case VERTEXATTRIBTYPE_NONPURE_UINT_2_10_10_10_REV: return sizeof(deUint32)/4; 442 case VERTEXATTRIBTYPE_NONPURE_INT_2_10_10_10_REV: return sizeof(deUint32)/4; 443 case VERTEXATTRIBTYPE_PURE_UINT8: return 1; 444 case VERTEXATTRIBTYPE_PURE_UINT16: return 2; 445 case VERTEXATTRIBTYPE_PURE_UINT32: return 4; 446 case VERTEXATTRIBTYPE_PURE_INT8: return 1; 447 case VERTEXATTRIBTYPE_PURE_INT16: return 2; 448 case VERTEXATTRIBTYPE_PURE_INT32: return 4; 449 case VERTEXATTRIBTYPE_NONPURE_UNORM8_BGRA: return 1; 450 case VERTEXATTRIBTYPE_NONPURE_UNORM_2_10_10_10_REV_BGRA: return sizeof(deUint32)/4; 451 case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_CLAMP_BGRA: return sizeof(deUint32)/4; 452 case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_SCALE_BGRA: return sizeof(deUint32)/4; 453 default: 454 DE_ASSERT(false); 455 return 0; 456 } 457 } 458 459 } // anonymous 460 461 bool isValidVertexAttrib (const VertexAttrib& vertexAttrib) 462 { 463 // Trivial range checks. 464 if (!de::inBounds<int>(vertexAttrib.type, 0, VERTEXATTRIBTYPE_LAST) || 465 !de::inRange(vertexAttrib.size, 0, 4) || 466 vertexAttrib.instanceDivisor < 0) 467 return false; 468 469 // Generic attributes 470 if (!vertexAttrib.pointer && vertexAttrib.type != VERTEXATTRIBTYPE_DONT_CARE) 471 return false; 472 473 // Packed formats 474 if ((vertexAttrib.type == VERTEXATTRIBTYPE_NONPURE_INT_2_10_10_10_REV || 475 vertexAttrib.type == VERTEXATTRIBTYPE_NONPURE_UINT_2_10_10_10_REV || 476 vertexAttrib.type == VERTEXATTRIBTYPE_NONPURE_UNORM_2_10_10_10_REV || 477 vertexAttrib.type == VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_CLAMP || 478 vertexAttrib.type == VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_SCALE || 479 vertexAttrib.type == VERTEXATTRIBTYPE_NONPURE_UNORM_2_10_10_10_REV_BGRA || 480 vertexAttrib.type == VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_CLAMP_BGRA || 481 vertexAttrib.type == VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_SCALE_BGRA) && 482 vertexAttrib.size != 4) 483 return false; 484 485 return true; 486 } 487 488 void readVertexAttrib (tcu::Vec4& dst, const VertexAttrib& vertexAttrib, const int instanceNdx, const int vertexNdx) 489 { 490 DE_ASSERT(isValidVertexAttrib(vertexAttrib)); 491 492 if (vertexAttrib.pointer) 493 { 494 const int elementNdx = (vertexAttrib.instanceDivisor != 0) ? (instanceNdx / vertexAttrib.instanceDivisor) : vertexNdx; 495 const int compSize = getComponentSize(vertexAttrib.type); 496 const int stride = (vertexAttrib.stride != 0) ? (vertexAttrib.stride) : (vertexAttrib.size*compSize); 497 const int byteOffset = elementNdx*stride; 498 499 dst = tcu::Vec4(0, 0, 0, 1); // defaults 500 readFloat(dst, vertexAttrib.type, vertexAttrib.size, (const deUint8*)vertexAttrib.pointer + byteOffset); 501 } 502 else 503 { 504 dst = vertexAttrib.generic.get<float>(); 505 } 506 } 507 508 void readVertexAttrib (tcu::IVec4& dst, const VertexAttrib& vertexAttrib, const int instanceNdx, const int vertexNdx) 509 { 510 DE_ASSERT(isValidVertexAttrib(vertexAttrib)); 511 512 if (vertexAttrib.pointer) 513 { 514 const int elementNdx = (vertexAttrib.instanceDivisor != 0) ? (instanceNdx / vertexAttrib.instanceDivisor) : vertexNdx; 515 const int compSize = getComponentSize(vertexAttrib.type); 516 const int stride = (vertexAttrib.stride != 0) ? (vertexAttrib.stride) : (vertexAttrib.size*compSize); 517 const int byteOffset = elementNdx*stride; 518 519 dst = tcu::IVec4(0, 0, 0, 1); // defaults 520 readInt(dst, vertexAttrib.type, vertexAttrib.size, (const deUint8*)vertexAttrib.pointer + byteOffset); 521 } 522 else 523 { 524 dst = vertexAttrib.generic.get<deInt32>(); 525 } 526 } 527 528 void readVertexAttrib (tcu::UVec4& dst, const VertexAttrib& vertexAttrib, const int instanceNdx, const int vertexNdx) 529 { 530 DE_ASSERT(isValidVertexAttrib(vertexAttrib)); 531 532 if (vertexAttrib.pointer) 533 { 534 const int elementNdx = (vertexAttrib.instanceDivisor != 0) ? (instanceNdx / vertexAttrib.instanceDivisor) : vertexNdx; 535 const int compSize = getComponentSize(vertexAttrib.type); 536 const int stride = (vertexAttrib.stride != 0) ? (vertexAttrib.stride) : (vertexAttrib.size*compSize); 537 const int byteOffset = elementNdx*stride; 538 539 dst = tcu::UVec4(0, 0, 0, 1); // defaults 540 readUint(dst, vertexAttrib.type, vertexAttrib.size, (const deUint8*)vertexAttrib.pointer + byteOffset); 541 } 542 else 543 { 544 dst = vertexAttrib.generic.get<deUint32>(); 545 } 546 } 547 548 } // rr 549