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 29namespace rr 30{ 31 32namespace 33{ 34 35struct NormalOrder 36{ 37 enum 38 { 39 T0 = 0, 40 T1 = 1, 41 T2 = 2, 42 T3 = 3, 43 }; 44}; 45 46struct BGRAOrder 47{ 48 enum 49 { 50 T0 = 2, 51 T1 = 1, 52 T2 = 0, 53 T3 = 3, 54 }; 55}; 56 57// readers 58 59template<typename SrcScalarType, typename DstScalarType, typename Order> 60inline 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 71template<typename SrcScalarType, typename Order> 72inline 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 85template<typename SrcScalarType> 86inline 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 100template<typename SrcScalarType> 101inline 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 115inline 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 126inline 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 137inline 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 148template <int integerLen> 149inline deInt32 extendSign (deUint32 integer) 150{ 151 return deUint32(0 - deInt32((integer & (1 << (integerLen - 1))) << 1)) | integer; 152} 153 154template<typename DstScalarType> 155inline 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 166template<typename DstScalarType> 167inline 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 178template<typename Order> 179inline 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 193template<typename Order> 194inline 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 209template<typename Order> 210inline 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 227template<typename SrcScalarType, typename DstScalarType> 228inline 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 233template<typename SrcScalarType> 234inline void readUnorm (tcu::Vec4& dst, const int size, const void* ptr) 235{ 236 readUnormOrder<SrcScalarType, NormalOrder>(dst, size, ptr); 237} 238 239template<typename SrcScalarType> 240inline void readUnormBGRA (tcu::Vec4& dst, const int size, const void* ptr) 241{ 242 readUnormOrder<SrcScalarType, BGRAOrder>(dst, size, ptr); 243} 244 245inline void readUnorm2101010Rev (tcu::Vec4& dst, const int size, const void* ptr) 246{ 247 readUnorm2101010RevOrder<NormalOrder>(dst, size, ptr); 248} 249 250inline void readUnorm2101010RevBGRA (tcu::Vec4& dst, const int size, const void* ptr) 251{ 252 readUnorm2101010RevOrder<BGRAOrder>(dst, size, ptr); 253} 254 255inline void readSnorm2101010RevClamp (tcu::Vec4& dst, const int size, const void* ptr) 256{ 257 readSnorm2101010RevClampOrder<NormalOrder>(dst, size, ptr); 258} 259 260inline void readSnorm2101010RevClampBGRA (tcu::Vec4& dst, const int size, const void* ptr) 261{ 262 readSnorm2101010RevClampOrder<BGRAOrder>(dst, size, ptr); 263} 264 265inline void readSnorm2101010RevScale (tcu::Vec4& dst, const int size, const void* ptr) 266{ 267 readSnorm2101010RevScaleOrder<NormalOrder>(dst, size, ptr); 268} 269 270inline void readSnorm2101010RevScaleBGRA (tcu::Vec4& dst, const int size, const void* ptr) 271{ 272 readSnorm2101010RevScaleOrder<BGRAOrder>(dst, size, ptr); 273} 274 275// utils 276 277void 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 318 default: 319 DE_ASSERT(false); 320 } 321} 322 323void 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_FATAL("Invalid read"); 363 364 default: 365 DE_ASSERT(false); 366 } 367} 368 369void 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_FATAL("Invalid read"); 409 410 default: 411 DE_ASSERT(false); 412 } 413} 414 415int 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 (int)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 (int)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 (int)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 (int)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 (int)sizeof(deUint32)/4; 442 case VERTEXATTRIBTYPE_NONPURE_INT_2_10_10_10_REV: return (int)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 (int)sizeof(deUint32)/4; 451 case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_CLAMP_BGRA: return (int)sizeof(deUint32)/4; 452 case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_SCALE_BGRA: return (int)sizeof(deUint32)/4; 453 default: 454 DE_ASSERT(false); 455 return 0; 456 } 457} 458 459} // anonymous 460 461bool 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 488void 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 508void 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 528void 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