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] = 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 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_FATAL("Invalid read"); 317 break; 318 319 default: 320 DE_ASSERT(false); 321 } 322 } 323 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 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 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 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 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 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 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