From 07104dfa13013a73a59a93cbd8d132254a5a171d Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jarkko=20P=C3=B6yry?= Date: Fri, 6 Mar 2015 17:04:33 -0800 Subject: [PATCH] Add UNORM_INT24 format. - New format is required to support separating combined texture stencil formats. Change-Id: I3cbc4f096cba6171850a9d980f01fb1c8b604a58 --- framework/common/tcuTexture.cpp | 132 +++++++++++++++++++++--------------- framework/common/tcuTexture.hpp | 1 + framework/common/tcuTextureUtil.cpp | 24 ++++++- 3 files changed, 103 insertions(+), 54 deletions(-) diff --git a/framework/common/tcuTexture.cpp b/framework/common/tcuTexture.cpp index ed11674..0d971e7 100644 --- a/framework/common/tcuTexture.cpp +++ b/framework/common/tcuTexture.cpp @@ -84,6 +84,32 @@ inline void writeRGB888Float (deUint8* ptr, const Vec4& val) ptr[2] = floatToU8(val[2]); } +inline void writeUint24 (deUint8* dst, deUint32 val) +{ +#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN) + dst[0] = (deUint8)((val & 0x0000FFu) >> 0u); + dst[1] = (deUint8)((val & 0x00FF00u) >> 8u); + dst[2] = (deUint8)((val & 0xFF0000u) >> 16u); +#else + dst[0] = (deUint8)((val & 0xFF0000u) >> 16u); + dst[1] = (deUint8)((val & 0x00FF00u) >> 8u); + dst[2] = (deUint8)((val & 0x0000FFu) >> 0u); +#endif +} + +inline deUint32 readUint24 (const deUint8* src) +{ +#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN) + return (((deUint32)src[0]) << 0u) | + (((deUint32)src[1]) << 8u) | + (((deUint32)src[2]) << 16u); +#else + return (((deUint32)src[0]) << 16u) | + (((deUint32)src[1]) << 8u) | + (((deUint32)src[2]) << 0u); +#endif +} + // \todo [2011-09-21 pyry] Move to tcutil? template inline T convertSatRte (float f) @@ -113,8 +139,18 @@ inline T convertSatRte (float f) return (T)intVal; } +inline deUint32 convertSatRteUint24 (float f) +{ + const deUint32 rounded = convertSatRte(f); + const deUint32 maxUint24 = 0xFFFFFFu; + return de::min(rounded, maxUint24); +} + int getChannelSize (TextureFormat::ChannelType type) { + // make sure this table is updated if format table is updated + DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 26); + switch (type) { case TextureFormat::SNORM_INT8: return 1; @@ -122,6 +158,7 @@ int getChannelSize (TextureFormat::ChannelType type) case TextureFormat::SNORM_INT32: return 4; case TextureFormat::UNORM_INT8: return 1; case TextureFormat::UNORM_INT16: return 2; + case TextureFormat::UNORM_INT24: return 3; case TextureFormat::UNORM_INT32: return 4; case TextureFormat::SIGNED_INT8: return 1; case TextureFormat::SIGNED_INT16: return 2; @@ -139,6 +176,9 @@ int getChannelSize (TextureFormat::ChannelType type) int getNumUsedChannels (TextureFormat::ChannelOrder order) { + // make sure this table is updated if type table is updated + DE_STATIC_ASSERT(TextureFormat::CHANNELORDER_LAST == 16); + switch (order) { case TextureFormat::R: return 1; @@ -165,6 +205,9 @@ int getNumUsedChannels (TextureFormat::ChannelOrder order) inline float channelToFloat (const deUint8* value, TextureFormat::ChannelType type) { + // make sure this table is updated if format table is updated + DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 26); + switch (type) { case TextureFormat::SNORM_INT8: return de::max(-1.0f, (float)*((const deInt8*)value) / 127.0f); @@ -172,6 +215,7 @@ inline float channelToFloat (const deUint8* value, TextureFormat::ChannelType ty case TextureFormat::SNORM_INT32: return de::max(-1.0f, (float)*((const deInt32*)value) / 2147483647.0f); case TextureFormat::UNORM_INT8: return (float)*((const deUint8*)value) / 255.0f; case TextureFormat::UNORM_INT16: return (float)*((const deUint16*)value) / 65535.0f; + case TextureFormat::UNORM_INT24: return (float)readUint24(value) / 16777215.0f; case TextureFormat::UNORM_INT32: return (float)*((const deUint32*)value) / 4294967295.0f; case TextureFormat::SIGNED_INT8: return (float)*((const deInt8*)value); case TextureFormat::SIGNED_INT16: return (float)*((const deInt16*)value); @@ -189,6 +233,9 @@ inline float channelToFloat (const deUint8* value, TextureFormat::ChannelType ty inline int channelToInt (const deUint8* value, TextureFormat::ChannelType type) { + // make sure this table is updated if format table is updated + DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 26); + switch (type) { case TextureFormat::SNORM_INT8: return (int)*((const deInt8*)value); @@ -196,6 +243,7 @@ inline int channelToInt (const deUint8* value, TextureFormat::ChannelType type) case TextureFormat::SNORM_INT32: return (int)*((const deInt32*)value); case TextureFormat::UNORM_INT8: return (int)*((const deUint8*)value); case TextureFormat::UNORM_INT16: return (int)*((const deUint16*)value); + case TextureFormat::UNORM_INT24: return (int)readUint24(value); case TextureFormat::UNORM_INT32: return (int)*((const deUint32*)value); case TextureFormat::SIGNED_INT8: return (int)*((const deInt8*)value); case TextureFormat::SIGNED_INT16: return (int)*((const deInt16*)value); @@ -213,6 +261,9 @@ inline int channelToInt (const deUint8* value, TextureFormat::ChannelType type) void floatToChannel (deUint8* dst, float src, TextureFormat::ChannelType type) { + // make sure this table is updated if format table is updated + DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 26); + switch (type) { case TextureFormat::SNORM_INT8: *((deInt8*)dst) = convertSatRte (src * 127.0f); break; @@ -220,6 +271,7 @@ void floatToChannel (deUint8* dst, float src, TextureFormat::ChannelType type) case TextureFormat::SNORM_INT32: *((deInt32*)dst) = convertSatRte (src * 2147483647.0f); break; case TextureFormat::UNORM_INT8: *((deUint8*)dst) = convertSatRte (src * 255.0f); break; case TextureFormat::UNORM_INT16: *((deUint16*)dst) = convertSatRte (src * 65535.0f); break; + case TextureFormat::UNORM_INT24: writeUint24(dst, convertSatRteUint24(src * 16777215.0f)); break; case TextureFormat::UNORM_INT32: *((deUint32*)dst) = convertSatRte (src * 4294967295.0f); break; case TextureFormat::SIGNED_INT8: *((deInt8*)dst) = convertSatRte (src); break; case TextureFormat::SIGNED_INT16: *((deInt16*)dst) = convertSatRte (src); break; @@ -248,14 +300,32 @@ static inline T convertSat (S src) return (T)src; } +template +static inline deUint32 convertSatUint24 (S src) +{ + S min = (S)0u; + S max = (S)0xFFFFFFu; + + if (src < min) + return (deUint32)min; + else if (src > max) + return (deUint32)max; + else + return (deUint32)src; +} + void intToChannel (deUint8* dst, int src, TextureFormat::ChannelType type) { + // make sure this table is updated if format table is updated + DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 26); + switch (type) { case TextureFormat::SNORM_INT8: *((deInt8*)dst) = convertSat (src); break; case TextureFormat::SNORM_INT16: *((deInt16*)dst) = convertSat (src); break; case TextureFormat::UNORM_INT8: *((deUint8*)dst) = convertSat (src); break; case TextureFormat::UNORM_INT16: *((deUint16*)dst) = convertSat (src); break; + case TextureFormat::UNORM_INT24: writeUint24(dst, convertSatUint24(src)); break; case TextureFormat::SIGNED_INT8: *((deInt8*)dst) = convertSat (src); break; case TextureFormat::SIGNED_INT16: *((deInt16*)dst) = convertSat (src); break; case TextureFormat::SIGNED_INT32: *((deInt32*)dst) = convertSat (src); break; @@ -447,52 +517,7 @@ int TextureFormat::getPixelSize (void) const return 8; } else - { - int numChannels = 0; - int channelSize = 0; - - switch (order) - { - case R: numChannels = 1; break; - case A: numChannels = 1; break; - case I: numChannels = 1; break; - case L: numChannels = 1; break; - case LA: numChannels = 2; break; - case RG: numChannels = 2; break; - case RA: numChannels = 2; break; - case RGB: numChannels = 3; break; - case RGBA: numChannels = 4; break; - case ARGB: numChannels = 4; break; - case BGRA: numChannels = 4; break; - case sRGB: numChannels = 3; break; - case sRGBA: numChannels = 4; break; - case D: numChannels = 1; break; - case S: numChannels = 1; break; - case DS: numChannels = 2; break; - default: DE_ASSERT(DE_FALSE); - } - - switch (type) - { - case SNORM_INT8: channelSize = 1; break; - case SNORM_INT16: channelSize = 2; break; - case SNORM_INT32: channelSize = 4; break; - case UNORM_INT8: channelSize = 1; break; - case UNORM_INT16: channelSize = 2; break; - case UNORM_INT32: channelSize = 4; break; - case SIGNED_INT8: channelSize = 1; break; - case SIGNED_INT16: channelSize = 2; break; - case SIGNED_INT32: channelSize = 4; break; - case UNSIGNED_INT8: channelSize = 1; break; - case UNSIGNED_INT16: channelSize = 2; break; - case UNSIGNED_INT32: channelSize = 4; break; - case HALF_FLOAT: channelSize = 2; break; - case FLOAT: channelSize = 4; break; - default: DE_ASSERT(DE_FALSE); - } - - return numChannels*channelSize; - } + return getNumUsedChannels(order) * getChannelSize(type); } ConstPixelBufferAccess::ConstPixelBufferAccess (void) @@ -677,8 +702,8 @@ IVec4 ConstPixelBufferAccess::getPixelInt (int x, int y, int z) const DE_ASSERT(de::inBounds(y, 0, m_size.y())); DE_ASSERT(de::inBounds(z, 0, m_size.z())); - const deUint8* pixelPtr = (const deUint8*)getDataPtr() + z*m_pitch.z() + y*m_pitch.y() + x*m_pitch.x(); - IVec4 result; + const deUint8* const pixelPtr = (const deUint8*)getDataPtr() + z*m_pitch.z() + y*m_pitch.y() + x*m_pitch.x(); + IVec4 result; // Optimized fomats. if (m_format.type == TextureFormat::UNORM_INT8) @@ -781,7 +806,7 @@ float ConstPixelBufferAccess::getPixDepth (int x, int y, int z) const DE_ASSERT(de::inBounds(y, 0, getHeight())); DE_ASSERT(de::inBounds(z, 0, getDepth())); - deUint8* pixelPtr = (deUint8*)getDataPtr() + z*m_pitch.z() + y*m_pitch.y() + x*m_pitch.x(); + const deUint8* const pixelPtr = (const deUint8*)getDataPtr() + z*m_pitch.z() + y*m_pitch.y() + x*m_pitch.x(); #define UB32(OFFS, COUNT) ((*((const deUint32*)pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1)) #define NB32(OFFS, COUNT) channelToNormFloat(UB32(OFFS, COUNT), (COUNT)) @@ -820,7 +845,7 @@ int ConstPixelBufferAccess::getPixStencil (int x, int y, int z) const DE_ASSERT(de::inBounds(y, 0, getHeight())); DE_ASSERT(de::inBounds(z, 0, getDepth())); - deUint8* pixelPtr = (deUint8*)getDataPtr() + z*m_pitch.z() + y*m_pitch.y() + x*m_pitch.x(); + const deUint8* const pixelPtr = (const deUint8*)getDataPtr() + z*m_pitch.z() + y*m_pitch.y() + x*m_pitch.x(); switch (m_format.type) { @@ -954,7 +979,7 @@ void PixelBufferAccess::setPixel (const IVec4& color, int x, int y, int z) const DE_ASSERT(de::inBounds(y, 0, getHeight())); DE_ASSERT(de::inBounds(z, 0, getDepth())); - deUint8* pixelPtr = (deUint8*)getDataPtr() + z*m_pitch.z() + y*m_pitch.y() + x*m_pitch.x(); + deUint8* const pixelPtr = (deUint8*)getDataPtr() + z*m_pitch.z() + y*m_pitch.y() + x*m_pitch.x(); // Optimized fomats. if (m_format.type == TextureFormat::UNORM_INT8) @@ -1017,7 +1042,7 @@ void PixelBufferAccess::setPixDepth (float depth, int x, int y, int z) const DE_ASSERT(de::inBounds(y, 0, getHeight())); DE_ASSERT(de::inBounds(z, 0, getDepth())); - deUint8* pixelPtr = (deUint8*)getDataPtr() + z*m_pitch.z() + y*m_pitch.y() + x*m_pitch.x(); + deUint8* const pixelPtr = (deUint8*)getDataPtr() + z*m_pitch.z() + y*m_pitch.y() + x*m_pitch.x(); #define PN(VAL, OFFS, BITS) (normFloatToChannel((VAL), (BITS)) << (OFFS)) @@ -1053,7 +1078,7 @@ void PixelBufferAccess::setPixStencil (int stencil, int x, int y, int z) const DE_ASSERT(de::inBounds(y, 0, getHeight())); DE_ASSERT(de::inBounds(z, 0, getDepth())); - deUint8* pixelPtr = (deUint8*)getDataPtr() + z*m_pitch.z() + y*m_pitch.y() + x*m_pitch.x(); + deUint8* const pixelPtr = (deUint8*)getDataPtr() + z*m_pitch.z() + y*m_pitch.y() + x*m_pitch.x(); #define PU(VAL, OFFS, BITS) (uintToChannel((deUint32)(VAL), (BITS)) << (OFFS)) @@ -3409,6 +3434,7 @@ std::ostream& operator<< (std::ostream& str, TextureFormat::ChannelType type) "SNORM_INT32", "UNORM_INT8", "UNORM_INT16", + "UNORM_INT24", "UNORM_INT32", "UNORM_SHORT_565", "UNORM_SHORT_555", diff --git a/framework/common/tcuTexture.hpp b/framework/common/tcuTexture.hpp index a0e2bb7..27db3ed 100644 --- a/framework/common/tcuTexture.hpp +++ b/framework/common/tcuTexture.hpp @@ -70,6 +70,7 @@ public: SNORM_INT32, UNORM_INT8, UNORM_INT16, + UNORM_INT24, UNORM_INT32, UNORM_SHORT_565, UNORM_SHORT_555, diff --git a/framework/common/tcuTextureUtil.cpp b/framework/common/tcuTextureUtil.cpp index abc4deb..73ebc0f 100644 --- a/framework/common/tcuTextureUtil.cpp +++ b/framework/common/tcuTextureUtil.cpp @@ -78,12 +78,18 @@ bool isSRGB (TextureFormat format) //! Get texture channel class for format TextureChannelClass getTextureChannelClass (TextureFormat::ChannelType channelType) { + // make sure this table is updated if format table is updated + DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 26); + switch (channelType) { case TextureFormat::SNORM_INT8: return TEXTURECHANNELCLASS_SIGNED_FIXED_POINT; case TextureFormat::SNORM_INT16: return TEXTURECHANNELCLASS_SIGNED_FIXED_POINT; + case TextureFormat::SNORM_INT32: return TEXTURECHANNELCLASS_SIGNED_FIXED_POINT; case TextureFormat::UNORM_INT8: return TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT; case TextureFormat::UNORM_INT16: return TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT; + case TextureFormat::UNORM_INT24: return TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT; + case TextureFormat::UNORM_INT32: return TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT; case TextureFormat::UNORM_SHORT_565: return TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT; case TextureFormat::UNORM_SHORT_555: return TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT; case TextureFormat::UNORM_SHORT_4444: return TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT; @@ -93,6 +99,7 @@ TextureChannelClass getTextureChannelClass (TextureFormat::ChannelType channelTy case TextureFormat::UNSIGNED_INT_1010102_REV: return TEXTURECHANNELCLASS_UNSIGNED_INTEGER; case TextureFormat::UNSIGNED_INT_11F_11F_10F_REV: return TEXTURECHANNELCLASS_FLOATING_POINT; case TextureFormat::UNSIGNED_INT_999_E5_REV: return TEXTURECHANNELCLASS_FLOATING_POINT; + case TextureFormat::UNSIGNED_INT_24_8: return TEXTURECHANNELCLASS_LAST; //!< packed unorm24-uint8 case TextureFormat::SIGNED_INT8: return TEXTURECHANNELCLASS_SIGNED_INTEGER; case TextureFormat::SIGNED_INT16: return TEXTURECHANNELCLASS_SIGNED_INTEGER; case TextureFormat::SIGNED_INT32: return TEXTURECHANNELCLASS_SIGNED_INTEGER; @@ -101,6 +108,7 @@ TextureChannelClass getTextureChannelClass (TextureFormat::ChannelType channelTy case TextureFormat::UNSIGNED_INT32: return TEXTURECHANNELCLASS_UNSIGNED_INTEGER; case TextureFormat::HALF_FLOAT: return TEXTURECHANNELCLASS_FLOATING_POINT; case TextureFormat::FLOAT: return TEXTURECHANNELCLASS_FLOATING_POINT; + case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV: return TEXTURECHANNELCLASS_LAST; //!< packed float32-pad24-uint8 default: return TEXTURECHANNELCLASS_LAST; } } @@ -215,6 +223,9 @@ ConstPixelBufferAccess flipYAccess (const ConstPixelBufferAccess& access) static Vec2 getChannelValueRange (TextureFormat::ChannelType channelType) { + // make sure this table is updated if format table is updated + DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 26); + float cMin = 0.0f; float cMax = 0.0f; @@ -222,11 +233,14 @@ static Vec2 getChannelValueRange (TextureFormat::ChannelType channelType) { // Signed normalized formats. case TextureFormat::SNORM_INT8: - case TextureFormat::SNORM_INT16: cMin = -1.0f; cMax = 1.0f; break; + case TextureFormat::SNORM_INT16: + case TextureFormat::SNORM_INT32: cMin = -1.0f; cMax = 1.0f; break; // Unsigned normalized formats. case TextureFormat::UNORM_INT8: case TextureFormat::UNORM_INT16: + case TextureFormat::UNORM_INT24: + case TextureFormat::UNORM_INT32: case TextureFormat::UNORM_SHORT_565: case TextureFormat::UNORM_SHORT_4444: case TextureFormat::UNORM_INT_101010: @@ -295,6 +309,9 @@ TextureFormatInfo getTextureFormatInfo (const TextureFormat& format) static IVec4 getChannelBitDepth (TextureFormat::ChannelType channelType) { + // make sure this table is updated if format table is updated + DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 26); + switch (channelType) { case TextureFormat::SNORM_INT8: return IVec4(8); @@ -302,6 +319,7 @@ static IVec4 getChannelBitDepth (TextureFormat::ChannelType channelType) case TextureFormat::SNORM_INT32: return IVec4(32); case TextureFormat::UNORM_INT8: return IVec4(8); case TextureFormat::UNORM_INT16: return IVec4(16); + case TextureFormat::UNORM_INT24: return IVec4(24); case TextureFormat::UNORM_INT32: return IVec4(32); case TextureFormat::UNORM_SHORT_565: return IVec4(5,6,5,0); case TextureFormat::UNORM_SHORT_4444: return IVec4(4); @@ -346,6 +364,9 @@ IVec4 getTextureFormatBitDepth (const TextureFormat& format) static IVec4 getChannelMantissaBitDepth (TextureFormat::ChannelType channelType) { + // make sure this table is updated if format table is updated + DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 26); + switch (channelType) { case TextureFormat::SNORM_INT8: @@ -353,6 +374,7 @@ static IVec4 getChannelMantissaBitDepth (TextureFormat::ChannelType channelType) case TextureFormat::SNORM_INT32: case TextureFormat::UNORM_INT8: case TextureFormat::UNORM_INT16: + case TextureFormat::UNORM_INT24: case TextureFormat::UNORM_INT32: case TextureFormat::UNORM_SHORT_565: case TextureFormat::UNORM_SHORT_4444: -- 2.7.4