You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
552 lines
22 KiB
552 lines
22 KiB
/*-------------------------------------------------------------------------
|
|
* drawElements Quality Program Reference Renderer
|
|
* -----------------------------------------------
|
|
*
|
|
* Copyright 2014 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*
|
|
*//*!
|
|
* \file
|
|
* \brief Vertex attribute fetch.
|
|
*//*--------------------------------------------------------------------*/
|
|
|
|
#include "rrVertexAttrib.hpp"
|
|
#include "tcuFloat.hpp"
|
|
#include "deInt32.h"
|
|
#include "deMemory.h"
|
|
|
|
namespace rr
|
|
{
|
|
|
|
namespace
|
|
{
|
|
|
|
struct NormalOrder
|
|
{
|
|
enum
|
|
{
|
|
T0 = 0,
|
|
T1 = 1,
|
|
T2 = 2,
|
|
T3 = 3,
|
|
};
|
|
};
|
|
|
|
struct BGRAOrder
|
|
{
|
|
enum
|
|
{
|
|
T0 = 2,
|
|
T1 = 1,
|
|
T2 = 0,
|
|
T3 = 3,
|
|
};
|
|
};
|
|
|
|
// readers
|
|
|
|
template<typename SrcScalarType, typename DstScalarType, typename Order>
|
|
inline void readOrder (typename tcu::Vector<DstScalarType, 4>& dst, const int size, const void* ptr)
|
|
{
|
|
SrcScalarType aligned[4];
|
|
deMemcpy(aligned, ptr, size * sizeof(SrcScalarType));
|
|
|
|
dst[Order::T0] = DstScalarType(aligned[0]);
|
|
if (size >= 2) dst[Order::T1] = DstScalarType(aligned[1]);
|
|
if (size >= 3) dst[Order::T2] = DstScalarType(aligned[2]);
|
|
if (size >= 4) dst[Order::T3] = DstScalarType(aligned[3]);
|
|
}
|
|
|
|
template<typename SrcScalarType, typename Order>
|
|
inline void readUnormOrder (tcu::Vec4& dst, const int size, const void* ptr)
|
|
{
|
|
const deUint32 range = (deUint32)((1ull << (sizeof(SrcScalarType)*8))-1);
|
|
|
|
SrcScalarType aligned[4];
|
|
deMemcpy(aligned, ptr, size * sizeof(SrcScalarType));
|
|
|
|
dst[Order::T0] = float(aligned[0]) / float(range);
|
|
if (size >= 2) dst[Order::T1] = float(aligned[1]) / float(range);
|
|
if (size >= 3) dst[Order::T2] = float(aligned[2]) / float(range);
|
|
if (size >= 4) dst[Order::T3] = float(aligned[3]) / float(range);
|
|
}
|
|
|
|
template<typename SrcScalarType>
|
|
inline void readSnormClamp (tcu::Vec4& dst, const int size, const void* ptr)
|
|
{
|
|
// Clamped formats, GLES3-style conversion: max{c / (2^(b-1) - 1), -1 }
|
|
const deUint32 range = (deUint32)((1ull << (sizeof(SrcScalarType)*8-1))-1);
|
|
|
|
SrcScalarType aligned[4];
|
|
deMemcpy(aligned, ptr, size * sizeof(SrcScalarType));
|
|
|
|
dst[0] = de::max(-1.0f, float(aligned[0]) / float(range));
|
|
if (size >= 2) dst[1] = de::max(-1.0f, float(aligned[1]) / float(range));
|
|
if (size >= 3) dst[2] = de::max(-1.0f, float(aligned[2]) / float(range));
|
|
if (size >= 4) dst[3] = de::max(-1.0f, float(aligned[3]) / float(range));
|
|
}
|
|
|
|
template<typename SrcScalarType>
|
|
inline void readSnormScale (tcu::Vec4& dst, const int size, const void* ptr)
|
|
{
|
|
// Scaled formats, GLES2-style conversion: (2c + 1) / (2^b - 1)
|
|
const deUint32 range = (deUint32)((1ull << (sizeof(SrcScalarType)*8))-1);
|
|
|
|
SrcScalarType aligned[4];
|
|
deMemcpy(aligned, ptr, size * sizeof(SrcScalarType));
|
|
|
|
dst[0] = (float(aligned[0]) * 2.0f + 1.0f) / float(range);
|
|
if (size >= 2) dst[1] = (float(aligned[1]) * 2.0f + 1.0f) / float(range);
|
|
if (size >= 3) dst[2] = (float(aligned[2]) * 2.0f + 1.0f) / float(range);
|
|
if (size >= 4) dst[3] = (float(aligned[3]) * 2.0f + 1.0f) / float(range);
|
|
}
|
|
|
|
inline void readHalf (tcu::Vec4& dst, const int size, const void* ptr)
|
|
{
|
|
deUint16 aligned[4];
|
|
deMemcpy(aligned, ptr, size * sizeof(deUint16));
|
|
|
|
dst[0] = tcu::Float16(aligned[0]).asFloat();
|
|
if (size >= 2) dst[1] = tcu::Float16(aligned[1]).asFloat();
|
|
if (size >= 3) dst[2] = tcu::Float16(aligned[2]).asFloat();
|
|
if (size >= 4) dst[3] = tcu::Float16(aligned[3]).asFloat();
|
|
}
|
|
|
|
inline void readFixed (tcu::Vec4& dst, const int size, const void* ptr)
|
|
{
|
|
deInt32 aligned[4];
|
|
deMemcpy(aligned, ptr, size * sizeof(deInt32));
|
|
|
|
dst[0] = float(aligned[0]) / float(1 << 16);
|
|
if (size >= 2) dst[1] = float(aligned[1]) / float(1 << 16);
|
|
if (size >= 3) dst[2] = float(aligned[2]) / float(1 << 16);
|
|
if (size >= 4) dst[3] = float(aligned[3]) / float(1 << 16);
|
|
}
|
|
|
|
inline void readDouble (tcu::Vec4& dst, const int size, const void* ptr)
|
|
{
|
|
double aligned[4];
|
|
deMemcpy(aligned, ptr, size * sizeof(double));
|
|
|
|
dst[0] = float(aligned[0]);
|
|
if (size >= 2) dst[1] = float(aligned[1]);
|
|
if (size >= 3) dst[2] = float(aligned[2]);
|
|
if (size >= 4) dst[3] = float(aligned[3]);
|
|
}
|
|
|
|
template <int integerLen>
|
|
inline deInt32 extendSign (deUint32 integer)
|
|
{
|
|
return deUint32(0 - deInt32((integer & (1 << (integerLen - 1))) << 1)) | integer;
|
|
}
|
|
|
|
template<typename DstScalarType>
|
|
inline void readUint2101010Rev (typename tcu::Vector<DstScalarType, 4>& dst, const int size, const void* ptr)
|
|
{
|
|
deUint32 aligned;
|
|
deMemcpy(&aligned, ptr, sizeof(deUint32));
|
|
|
|
dst[0] = DstScalarType((aligned >> 0) & ((1 << 10) - 1));
|
|
if (size >= 2) dst[1] = DstScalarType((aligned >> 10) & ((1 << 10) - 1));
|
|
if (size >= 3) dst[2] = DstScalarType((aligned >> 20) & ((1 << 10) - 1));
|
|
if (size >= 4) dst[3] = DstScalarType((aligned >> 30) & ((1 << 2) - 1));
|
|
}
|
|
|
|
template<typename DstScalarType>
|
|
inline void readInt2101010Rev (typename tcu::Vector<DstScalarType, 4>& dst, const int size, const void* ptr)
|
|
{
|
|
deUint32 aligned;
|
|
deMemcpy(&aligned, ptr, sizeof(deUint32));
|
|
|
|
dst[0] = (DstScalarType)extendSign<10>((aligned >> 0) & ((1 << 10) - 1));
|
|
if (size >= 2) dst[1] = (DstScalarType)extendSign<10>((aligned >> 10) & ((1 << 10) - 1));
|
|
if (size >= 3) dst[2] = (DstScalarType)extendSign<10>((aligned >> 20) & ((1 << 10) - 1));
|
|
if (size >= 4) dst[3] = (DstScalarType)extendSign< 2>((aligned >> 30) & ((1 << 2) - 1));
|
|
}
|
|
|
|
template<typename Order>
|
|
inline void readUnorm2101010RevOrder (tcu::Vec4& dst, const int size, const void* ptr)
|
|
{
|
|
const deUint32 range10 = (deUint32)((1ull << 10)-1);
|
|
const deUint32 range2 = (deUint32)((1ull << 2)-1);
|
|
|
|
deUint32 aligned;
|
|
deMemcpy(&aligned, ptr, sizeof(deUint32));
|
|
|
|
dst[Order::T0] = float((aligned >> 0) & ((1 << 10) - 1)) / float(range10);
|
|
if (size >= 2) dst[Order::T1] = float((aligned >> 10) & ((1 << 10) - 1)) / float(range10);
|
|
if (size >= 3) dst[Order::T2] = float((aligned >> 20) & ((1 << 10) - 1)) / float(range10);
|
|
if (size >= 4) dst[Order::T3] = float((aligned >> 30) & ((1 << 2) - 1)) / float(range2);
|
|
}
|
|
|
|
template<typename Order>
|
|
inline void readSnorm2101010RevClampOrder (tcu::Vec4& dst, const int size, const void* ptr)
|
|
{
|
|
// Clamped formats, GLES3-style conversion: max{c / (2^(b-1) - 1), -1 }
|
|
const deUint32 range10 = (deUint32)((1ull << (10-1))-1);
|
|
const deUint32 range2 = (deUint32)((1ull << ( 2-1))-1);
|
|
|
|
deUint32 aligned;
|
|
deMemcpy(&aligned, ptr, sizeof(deUint32));
|
|
|
|
dst[Order::T0] = de::max(-1.0f, float(extendSign<10>((aligned >> 0) & ((1 << 10) - 1))) / float(range10));
|
|
if (size >= 2) dst[Order::T1] = de::max(-1.0f, float(extendSign<10>((aligned >> 10) & ((1 << 10) - 1))) / float(range10));
|
|
if (size >= 3) dst[Order::T2] = de::max(-1.0f, float(extendSign<10>((aligned >> 20) & ((1 << 10) - 1))) / float(range10));
|
|
if (size >= 4) dst[Order::T3] = de::max(-1.0f, float(extendSign< 2>((aligned >> 30) & ((1 << 2) - 1))) / float(range2));
|
|
}
|
|
|
|
template<typename Order>
|
|
inline void readSnorm2101010RevScaleOrder (tcu::Vec4& dst, const int size, const void* ptr)
|
|
{
|
|
// Scaled formats, GLES2-style conversion: (2c + 1) / (2^b - 1)
|
|
const deUint32 range10 = (deUint32)((1ull << 10)-1);
|
|
const deUint32 range2 = (deUint32)((1ull << 2)-1);
|
|
|
|
deUint32 aligned;
|
|
deMemcpy(&aligned, ptr, sizeof(deUint32));
|
|
|
|
dst[Order::T0] = (float(extendSign<10>((aligned >> 0) & ((1 << 10) - 1))) * 2.0f + 1.0f) / float(range10);
|
|
if (size >= 2) dst[Order::T1] = (float(extendSign<10>((aligned >> 10) & ((1 << 10) - 1))) * 2.0f + 1.0f) / float(range10);
|
|
if (size >= 3) dst[Order::T2] = (float(extendSign<10>((aligned >> 20) & ((1 << 10) - 1))) * 2.0f + 1.0f) / float(range10);
|
|
if (size >= 4) dst[Order::T3] = (float(extendSign< 2>((aligned >> 30) & ((1 << 2) - 1))) * 2.0f + 1.0f) / float(range2);
|
|
}
|
|
|
|
// ordered readers
|
|
|
|
template<typename SrcScalarType, typename DstScalarType>
|
|
inline void read (typename tcu::Vector<DstScalarType, 4>& dst, const int size, const void* ptr)
|
|
{
|
|
readOrder<SrcScalarType, DstScalarType, NormalOrder>(dst, size, ptr);
|
|
}
|
|
|
|
template<typename SrcScalarType>
|
|
inline void readUnorm (tcu::Vec4& dst, const int size, const void* ptr)
|
|
{
|
|
readUnormOrder<SrcScalarType, NormalOrder>(dst, size, ptr);
|
|
}
|
|
|
|
template<typename SrcScalarType>
|
|
inline void readUnormBGRA (tcu::Vec4& dst, const int size, const void* ptr)
|
|
{
|
|
readUnormOrder<SrcScalarType, BGRAOrder>(dst, size, ptr);
|
|
}
|
|
|
|
inline void readUnorm2101010Rev (tcu::Vec4& dst, const int size, const void* ptr)
|
|
{
|
|
readUnorm2101010RevOrder<NormalOrder>(dst, size, ptr);
|
|
}
|
|
|
|
inline void readUnorm2101010RevBGRA (tcu::Vec4& dst, const int size, const void* ptr)
|
|
{
|
|
readUnorm2101010RevOrder<BGRAOrder>(dst, size, ptr);
|
|
}
|
|
|
|
inline void readSnorm2101010RevClamp (tcu::Vec4& dst, const int size, const void* ptr)
|
|
{
|
|
readSnorm2101010RevClampOrder<NormalOrder>(dst, size, ptr);
|
|
}
|
|
|
|
inline void readSnorm2101010RevClampBGRA (tcu::Vec4& dst, const int size, const void* ptr)
|
|
{
|
|
readSnorm2101010RevClampOrder<BGRAOrder>(dst, size, ptr);
|
|
}
|
|
|
|
inline void readSnorm2101010RevScale (tcu::Vec4& dst, const int size, const void* ptr)
|
|
{
|
|
readSnorm2101010RevScaleOrder<NormalOrder>(dst, size, ptr);
|
|
}
|
|
|
|
inline void readSnorm2101010RevScaleBGRA (tcu::Vec4& dst, const int size, const void* ptr)
|
|
{
|
|
readSnorm2101010RevScaleOrder<BGRAOrder>(dst, size, ptr);
|
|
}
|
|
|
|
// utils
|
|
|
|
void readFloat (tcu::Vec4& dst, const VertexAttribType type, const int size, const void* ptr)
|
|
{
|
|
switch (type)
|
|
{
|
|
case VERTEXATTRIBTYPE_FLOAT: read<float> (dst, size, ptr); break;
|
|
case VERTEXATTRIBTYPE_HALF: readHalf (dst, size, ptr); break;
|
|
case VERTEXATTRIBTYPE_FIXED: readFixed (dst, size, ptr); break;
|
|
case VERTEXATTRIBTYPE_DOUBLE: readDouble (dst, size, ptr); break;
|
|
case VERTEXATTRIBTYPE_NONPURE_UNORM8: readUnorm<deUint8> (dst, size, ptr); break;
|
|
case VERTEXATTRIBTYPE_NONPURE_UNORM16: readUnorm<deUint16> (dst, size, ptr); break;
|
|
case VERTEXATTRIBTYPE_NONPURE_UNORM32: readUnorm<deUint32> (dst, size, ptr); break;
|
|
case VERTEXATTRIBTYPE_NONPURE_UNORM_2_10_10_10_REV: readUnorm2101010Rev (dst, size, ptr); break;
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM8_CLAMP: readSnormClamp<deInt8> (dst, size, ptr); break;
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM16_CLAMP: readSnormClamp<deInt16> (dst, size, ptr); break;
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM32_CLAMP: readSnormClamp<deInt32> (dst, size, ptr); break;
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_CLAMP: readSnorm2101010RevClamp (dst, size, ptr); break;
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM8_SCALE: readSnormScale<deInt8> (dst, size, ptr); break;
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM16_SCALE: readSnormScale<deInt16> (dst, size, ptr); break;
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM32_SCALE: readSnormScale<deInt32> (dst, size, ptr); break;
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_SCALE: readSnorm2101010RevScale (dst, size, ptr); break;
|
|
case VERTEXATTRIBTYPE_NONPURE_UINT8: read<deUint8> (dst, size, ptr); break;
|
|
case VERTEXATTRIBTYPE_NONPURE_UINT16: read<deUint16> (dst, size, ptr); break;
|
|
case VERTEXATTRIBTYPE_NONPURE_UINT32: read<deUint32> (dst, size, ptr); break;
|
|
case VERTEXATTRIBTYPE_NONPURE_INT8: read<deInt8> (dst, size, ptr); break;
|
|
case VERTEXATTRIBTYPE_NONPURE_INT16: read<deInt16> (dst, size, ptr); break;
|
|
case VERTEXATTRIBTYPE_NONPURE_INT32: read<deInt32> (dst, size, ptr); break;
|
|
case VERTEXATTRIBTYPE_NONPURE_UINT_2_10_10_10_REV: readUint2101010Rev (dst, size, ptr); break;
|
|
case VERTEXATTRIBTYPE_NONPURE_INT_2_10_10_10_REV: readInt2101010Rev (dst, size, ptr); break;
|
|
case VERTEXATTRIBTYPE_NONPURE_UNORM8_BGRA: readUnormBGRA<deUint8> (dst, size, ptr); break;
|
|
case VERTEXATTRIBTYPE_NONPURE_UNORM_2_10_10_10_REV_BGRA: readUnorm2101010RevBGRA (dst, size, ptr); break;
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_CLAMP_BGRA: readSnorm2101010RevClampBGRA(dst, size, ptr); break;
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_SCALE_BGRA: readSnorm2101010RevScaleBGRA(dst, size, ptr); break;
|
|
|
|
case VERTEXATTRIBTYPE_PURE_UINT8:
|
|
case VERTEXATTRIBTYPE_PURE_UINT16:
|
|
case VERTEXATTRIBTYPE_PURE_UINT32:
|
|
case VERTEXATTRIBTYPE_PURE_INT8:
|
|
case VERTEXATTRIBTYPE_PURE_INT16:
|
|
case VERTEXATTRIBTYPE_PURE_INT32:
|
|
DE_FATAL("Invalid read");
|
|
break;
|
|
|
|
default:
|
|
DE_ASSERT(false);
|
|
}
|
|
}
|
|
|
|
void readInt (tcu::IVec4& dst, const VertexAttribType type, const int size, const void* ptr)
|
|
{
|
|
switch (type)
|
|
{
|
|
case VERTEXATTRIBTYPE_PURE_INT8: read<deInt8> (dst, size, ptr); break;
|
|
case VERTEXATTRIBTYPE_PURE_INT16: read<deInt16> (dst, size, ptr); break;
|
|
case VERTEXATTRIBTYPE_PURE_INT32: read<deInt32> (dst, size, ptr); break;
|
|
|
|
case VERTEXATTRIBTYPE_FLOAT:
|
|
case VERTEXATTRIBTYPE_HALF:
|
|
case VERTEXATTRIBTYPE_FIXED:
|
|
case VERTEXATTRIBTYPE_DOUBLE:
|
|
case VERTEXATTRIBTYPE_NONPURE_UNORM8:
|
|
case VERTEXATTRIBTYPE_NONPURE_UNORM16:
|
|
case VERTEXATTRIBTYPE_NONPURE_UNORM32:
|
|
case VERTEXATTRIBTYPE_NONPURE_UNORM_2_10_10_10_REV:
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM8_CLAMP:
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM16_CLAMP:
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM32_CLAMP:
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_CLAMP:
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM8_SCALE:
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM16_SCALE:
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM32_SCALE:
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_SCALE:
|
|
case VERTEXATTRIBTYPE_NONPURE_UINT8:
|
|
case VERTEXATTRIBTYPE_NONPURE_UINT16:
|
|
case VERTEXATTRIBTYPE_NONPURE_UINT32:
|
|
case VERTEXATTRIBTYPE_NONPURE_INT8:
|
|
case VERTEXATTRIBTYPE_NONPURE_INT16:
|
|
case VERTEXATTRIBTYPE_NONPURE_INT32:
|
|
case VERTEXATTRIBTYPE_NONPURE_UINT_2_10_10_10_REV:
|
|
case VERTEXATTRIBTYPE_NONPURE_INT_2_10_10_10_REV:
|
|
case VERTEXATTRIBTYPE_PURE_UINT8:
|
|
case VERTEXATTRIBTYPE_PURE_UINT16:
|
|
case VERTEXATTRIBTYPE_PURE_UINT32:
|
|
case VERTEXATTRIBTYPE_NONPURE_UNORM8_BGRA:
|
|
case VERTEXATTRIBTYPE_NONPURE_UNORM_2_10_10_10_REV_BGRA:
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_CLAMP_BGRA:
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_SCALE_BGRA:
|
|
DE_FATAL("Invalid read");
|
|
break;
|
|
|
|
default:
|
|
DE_ASSERT(false);
|
|
}
|
|
}
|
|
|
|
void readUint (tcu::UVec4& dst, const VertexAttribType type, const int size, const void* ptr)
|
|
{
|
|
switch (type)
|
|
{
|
|
case VERTEXATTRIBTYPE_PURE_UINT8: read<deUint8> (dst, size, ptr); break;
|
|
case VERTEXATTRIBTYPE_PURE_UINT16: read<deUint16> (dst, size, ptr); break;
|
|
case VERTEXATTRIBTYPE_PURE_UINT32: read<deUint32> (dst, size, ptr); break;
|
|
|
|
case VERTEXATTRIBTYPE_FLOAT:
|
|
case VERTEXATTRIBTYPE_HALF:
|
|
case VERTEXATTRIBTYPE_FIXED:
|
|
case VERTEXATTRIBTYPE_DOUBLE:
|
|
case VERTEXATTRIBTYPE_NONPURE_UNORM8:
|
|
case VERTEXATTRIBTYPE_NONPURE_UNORM16:
|
|
case VERTEXATTRIBTYPE_NONPURE_UNORM32:
|
|
case VERTEXATTRIBTYPE_NONPURE_UNORM_2_10_10_10_REV:
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM8_CLAMP:
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM16_CLAMP:
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM32_CLAMP:
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_CLAMP:
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM8_SCALE:
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM16_SCALE:
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM32_SCALE:
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_SCALE:
|
|
case VERTEXATTRIBTYPE_NONPURE_UINT8:
|
|
case VERTEXATTRIBTYPE_NONPURE_UINT16:
|
|
case VERTEXATTRIBTYPE_NONPURE_UINT32:
|
|
case VERTEXATTRIBTYPE_NONPURE_INT8:
|
|
case VERTEXATTRIBTYPE_NONPURE_INT16:
|
|
case VERTEXATTRIBTYPE_NONPURE_INT32:
|
|
case VERTEXATTRIBTYPE_NONPURE_UINT_2_10_10_10_REV:
|
|
case VERTEXATTRIBTYPE_NONPURE_INT_2_10_10_10_REV:
|
|
case VERTEXATTRIBTYPE_PURE_INT8:
|
|
case VERTEXATTRIBTYPE_PURE_INT16:
|
|
case VERTEXATTRIBTYPE_PURE_INT32:
|
|
case VERTEXATTRIBTYPE_NONPURE_UNORM8_BGRA:
|
|
case VERTEXATTRIBTYPE_NONPURE_UNORM_2_10_10_10_REV_BGRA:
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_CLAMP_BGRA:
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_SCALE_BGRA:
|
|
DE_FATAL("Invalid read");
|
|
break;
|
|
|
|
default:
|
|
DE_ASSERT(false);
|
|
}
|
|
}
|
|
|
|
int getComponentSize (const VertexAttribType type)
|
|
{
|
|
switch (type)
|
|
{
|
|
case VERTEXATTRIBTYPE_FLOAT: return 4;
|
|
case VERTEXATTRIBTYPE_HALF: return 2;
|
|
case VERTEXATTRIBTYPE_FIXED: return 4;
|
|
case VERTEXATTRIBTYPE_DOUBLE: return (int)sizeof(double);
|
|
case VERTEXATTRIBTYPE_NONPURE_UNORM8: return 1;
|
|
case VERTEXATTRIBTYPE_NONPURE_UNORM16: return 2;
|
|
case VERTEXATTRIBTYPE_NONPURE_UNORM32: return 4;
|
|
case VERTEXATTRIBTYPE_NONPURE_UNORM_2_10_10_10_REV: return (int)sizeof(deUint32)/4;
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM8_CLAMP: return 1;
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM16_CLAMP: return 2;
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM32_CLAMP: return 4;
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_CLAMP: return (int)sizeof(deUint32)/4;
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM8_SCALE: return 1;
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM16_SCALE: return 2;
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM32_SCALE: return 4;
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_SCALE: return (int)sizeof(deUint32)/4;
|
|
case VERTEXATTRIBTYPE_NONPURE_UINT8: return 1;
|
|
case VERTEXATTRIBTYPE_NONPURE_UINT16: return 2;
|
|
case VERTEXATTRIBTYPE_NONPURE_UINT32: return 4;
|
|
case VERTEXATTRIBTYPE_NONPURE_INT8: return 1;
|
|
case VERTEXATTRIBTYPE_NONPURE_INT16: return 2;
|
|
case VERTEXATTRIBTYPE_NONPURE_INT32: return 4;
|
|
case VERTEXATTRIBTYPE_NONPURE_UINT_2_10_10_10_REV: return (int)sizeof(deUint32)/4;
|
|
case VERTEXATTRIBTYPE_NONPURE_INT_2_10_10_10_REV: return (int)sizeof(deUint32)/4;
|
|
case VERTEXATTRIBTYPE_PURE_UINT8: return 1;
|
|
case VERTEXATTRIBTYPE_PURE_UINT16: return 2;
|
|
case VERTEXATTRIBTYPE_PURE_UINT32: return 4;
|
|
case VERTEXATTRIBTYPE_PURE_INT8: return 1;
|
|
case VERTEXATTRIBTYPE_PURE_INT16: return 2;
|
|
case VERTEXATTRIBTYPE_PURE_INT32: return 4;
|
|
case VERTEXATTRIBTYPE_NONPURE_UNORM8_BGRA: return 1;
|
|
case VERTEXATTRIBTYPE_NONPURE_UNORM_2_10_10_10_REV_BGRA: return (int)sizeof(deUint32)/4;
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_CLAMP_BGRA: return (int)sizeof(deUint32)/4;
|
|
case VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_SCALE_BGRA: return (int)sizeof(deUint32)/4;
|
|
default:
|
|
DE_ASSERT(false);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
} // anonymous
|
|
|
|
bool isValidVertexAttrib (const VertexAttrib& vertexAttrib)
|
|
{
|
|
// Trivial range checks.
|
|
if (!de::inBounds<int>(vertexAttrib.type, 0, VERTEXATTRIBTYPE_LAST) ||
|
|
!de::inRange(vertexAttrib.size, 0, 4) ||
|
|
vertexAttrib.instanceDivisor < 0)
|
|
return false;
|
|
|
|
// Generic attributes
|
|
if (!vertexAttrib.pointer && vertexAttrib.type != VERTEXATTRIBTYPE_DONT_CARE)
|
|
return false;
|
|
|
|
// Packed formats
|
|
if ((vertexAttrib.type == VERTEXATTRIBTYPE_NONPURE_INT_2_10_10_10_REV ||
|
|
vertexAttrib.type == VERTEXATTRIBTYPE_NONPURE_UINT_2_10_10_10_REV ||
|
|
vertexAttrib.type == VERTEXATTRIBTYPE_NONPURE_UNORM_2_10_10_10_REV ||
|
|
vertexAttrib.type == VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_CLAMP ||
|
|
vertexAttrib.type == VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_SCALE ||
|
|
vertexAttrib.type == VERTEXATTRIBTYPE_NONPURE_UNORM_2_10_10_10_REV_BGRA ||
|
|
vertexAttrib.type == VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_CLAMP_BGRA ||
|
|
vertexAttrib.type == VERTEXATTRIBTYPE_NONPURE_SNORM_2_10_10_10_REV_SCALE_BGRA) &&
|
|
vertexAttrib.size != 4)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
void readVertexAttrib (tcu::Vec4& dst, const VertexAttrib& vertexAttrib, const int instanceNdx, const int vertexNdx, const int baseInstanceNdx)
|
|
{
|
|
DE_ASSERT(isValidVertexAttrib(vertexAttrib));
|
|
|
|
if (vertexAttrib.pointer)
|
|
{
|
|
const int elementNdx = (vertexAttrib.instanceDivisor != 0) ? baseInstanceNdx + (instanceNdx / vertexAttrib.instanceDivisor) : vertexNdx;
|
|
const int compSize = getComponentSize(vertexAttrib.type);
|
|
const int stride = (vertexAttrib.stride != 0) ? (vertexAttrib.stride) : (vertexAttrib.size*compSize);
|
|
const int byteOffset = elementNdx*stride;
|
|
|
|
dst = tcu::Vec4(0, 0, 0, 1); // defaults
|
|
readFloat(dst, vertexAttrib.type, vertexAttrib.size, (const deUint8*)vertexAttrib.pointer + byteOffset);
|
|
}
|
|
else
|
|
{
|
|
dst = vertexAttrib.generic.get<float>();
|
|
}
|
|
}
|
|
|
|
void readVertexAttrib (tcu::IVec4& dst, const VertexAttrib& vertexAttrib, const int instanceNdx, const int vertexNdx, const int baseInstanceNdx)
|
|
{
|
|
DE_ASSERT(isValidVertexAttrib(vertexAttrib));
|
|
|
|
if (vertexAttrib.pointer)
|
|
{
|
|
const int elementNdx = (vertexAttrib.instanceDivisor != 0) ? baseInstanceNdx + (instanceNdx / vertexAttrib.instanceDivisor) : vertexNdx;
|
|
const int compSize = getComponentSize(vertexAttrib.type);
|
|
const int stride = (vertexAttrib.stride != 0) ? (vertexAttrib.stride) : (vertexAttrib.size*compSize);
|
|
const int byteOffset = elementNdx*stride;
|
|
|
|
dst = tcu::IVec4(0, 0, 0, 1); // defaults
|
|
readInt(dst, vertexAttrib.type, vertexAttrib.size, (const deUint8*)vertexAttrib.pointer + byteOffset);
|
|
}
|
|
else
|
|
{
|
|
dst = vertexAttrib.generic.get<deInt32>();
|
|
}
|
|
}
|
|
|
|
void readVertexAttrib (tcu::UVec4& dst, const VertexAttrib& vertexAttrib, const int instanceNdx, const int vertexNdx, const int baseInstanceNdx)
|
|
{
|
|
DE_ASSERT(isValidVertexAttrib(vertexAttrib));
|
|
|
|
if (vertexAttrib.pointer)
|
|
{
|
|
const int elementNdx = (vertexAttrib.instanceDivisor != 0) ? baseInstanceNdx + (instanceNdx / vertexAttrib.instanceDivisor) : vertexNdx;
|
|
const int compSize = getComponentSize(vertexAttrib.type);
|
|
const int stride = (vertexAttrib.stride != 0) ? (vertexAttrib.stride) : (vertexAttrib.size*compSize);
|
|
const int byteOffset = elementNdx*stride;
|
|
|
|
dst = tcu::UVec4(0, 0, 0, 1); // defaults
|
|
readUint(dst, vertexAttrib.type, vertexAttrib.size, (const deUint8*)vertexAttrib.pointer + byteOffset);
|
|
}
|
|
else
|
|
{
|
|
dst = vertexAttrib.generic.get<deUint32>();
|
|
}
|
|
}
|
|
|
|
} // rr
|