1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * drawElements Quality Program Tester Core 3e5c31af7Sopenharmony_ci * ---------------------------------------- 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright 2014 The Android Open Source Project 6e5c31af7Sopenharmony_ci * 7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 10e5c31af7Sopenharmony_ci * 11e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 12e5c31af7Sopenharmony_ci * 13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 17e5c31af7Sopenharmony_ci * limitations under the License. 18e5c31af7Sopenharmony_ci * 19e5c31af7Sopenharmony_ci *//*! 20e5c31af7Sopenharmony_ci * \file 21e5c31af7Sopenharmony_ci * \brief Reference Texture Implementation. 22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci#include "tcuTexture.hpp" 25e5c31af7Sopenharmony_ci#include "deInt32.h" 26e5c31af7Sopenharmony_ci#include "deFloat16.h" 27e5c31af7Sopenharmony_ci#include "deMath.h" 28e5c31af7Sopenharmony_ci#include "deMemory.h" 29e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp" 30e5c31af7Sopenharmony_ci#include "tcuSurface.hpp" 31e5c31af7Sopenharmony_ci#include "tcuFloat.hpp" 32e5c31af7Sopenharmony_ci#include "tcuTextureUtil.hpp" 33e5c31af7Sopenharmony_ci#include "deStringUtil.hpp" 34e5c31af7Sopenharmony_ci#include "deArrayUtil.hpp" 35e5c31af7Sopenharmony_ci#include "tcuMatrix.hpp" 36e5c31af7Sopenharmony_ci 37e5c31af7Sopenharmony_ci#include <limits> 38e5c31af7Sopenharmony_ci 39e5c31af7Sopenharmony_cinamespace tcu 40e5c31af7Sopenharmony_ci{ 41e5c31af7Sopenharmony_ci 42e5c31af7Sopenharmony_ci// \note No sign. Denorms are supported. 43e5c31af7Sopenharmony_citypedef Float<deUint32, 5, 6, 15, FLOAT_SUPPORT_DENORM> Float11; 44e5c31af7Sopenharmony_citypedef Float<deUint32, 5, 5, 15, FLOAT_SUPPORT_DENORM> Float10; 45e5c31af7Sopenharmony_ci 46e5c31af7Sopenharmony_cinamespace 47e5c31af7Sopenharmony_ci{ 48e5c31af7Sopenharmony_ci 49e5c31af7Sopenharmony_ci// Optimized getters for common formats. 50e5c31af7Sopenharmony_ci// \todo [2012-11-14 pyry] Use intrinsics if available. 51e5c31af7Sopenharmony_ci 52e5c31af7Sopenharmony_ciinline Vec4 readRGBA8888Float (const deUint8* ptr) { return Vec4(ptr[0]/255.0f, ptr[1]/255.0f, ptr[2]/255.0f, ptr[3]/255.0f); } 53e5c31af7Sopenharmony_ciinline Vec4 readRGB888Float (const deUint8* ptr) { return Vec4(ptr[0]/255.0f, ptr[1]/255.0f, ptr[2]/255.0f, 1.0f); } 54e5c31af7Sopenharmony_ciinline IVec4 readRGBA8888Int (const deUint8* ptr) { return IVec4(ptr[0], ptr[1], ptr[2], ptr[3]); } 55e5c31af7Sopenharmony_ciinline IVec4 readRGB888Int (const deUint8* ptr) { return IVec4(ptr[0], ptr[1], ptr[2], 1); } 56e5c31af7Sopenharmony_ci 57e5c31af7Sopenharmony_ci// Optimized setters. 58e5c31af7Sopenharmony_ci 59e5c31af7Sopenharmony_ciinline void writeRGBA8888Int (deUint8* ptr, const IVec4& val) 60e5c31af7Sopenharmony_ci{ 61e5c31af7Sopenharmony_ci ptr[0] = (deUint8)de::clamp(val[0], 0, 255); 62e5c31af7Sopenharmony_ci ptr[1] = (deUint8)de::clamp(val[1], 0, 255); 63e5c31af7Sopenharmony_ci ptr[2] = (deUint8)de::clamp(val[2], 0, 255); 64e5c31af7Sopenharmony_ci ptr[3] = (deUint8)de::clamp(val[3], 0, 255); 65e5c31af7Sopenharmony_ci} 66e5c31af7Sopenharmony_ci 67e5c31af7Sopenharmony_ciinline void writeRGB888Int (deUint8* ptr, const IVec4& val) 68e5c31af7Sopenharmony_ci{ 69e5c31af7Sopenharmony_ci ptr[0] = (deUint8)de::clamp(val[0], 0, 255); 70e5c31af7Sopenharmony_ci ptr[1] = (deUint8)de::clamp(val[1], 0, 255); 71e5c31af7Sopenharmony_ci ptr[2] = (deUint8)de::clamp(val[2], 0, 255); 72e5c31af7Sopenharmony_ci} 73e5c31af7Sopenharmony_ci 74e5c31af7Sopenharmony_ciinline void writeRGBA8888Float (deUint8* ptr, const Vec4& val) 75e5c31af7Sopenharmony_ci{ 76e5c31af7Sopenharmony_ci ptr[0] = floatToU8(val[0]); 77e5c31af7Sopenharmony_ci ptr[1] = floatToU8(val[1]); 78e5c31af7Sopenharmony_ci ptr[2] = floatToU8(val[2]); 79e5c31af7Sopenharmony_ci ptr[3] = floatToU8(val[3]); 80e5c31af7Sopenharmony_ci} 81e5c31af7Sopenharmony_ci 82e5c31af7Sopenharmony_ciinline void writeRGB888Float (deUint8* ptr, const Vec4& val) 83e5c31af7Sopenharmony_ci{ 84e5c31af7Sopenharmony_ci ptr[0] = floatToU8(val[0]); 85e5c31af7Sopenharmony_ci ptr[1] = floatToU8(val[1]); 86e5c31af7Sopenharmony_ci ptr[2] = floatToU8(val[2]); 87e5c31af7Sopenharmony_ci} 88e5c31af7Sopenharmony_ci 89e5c31af7Sopenharmony_ciinline void writeUint24 (deUint8* dst, deUint32 val) 90e5c31af7Sopenharmony_ci{ 91e5c31af7Sopenharmony_ci#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN) 92e5c31af7Sopenharmony_ci dst[0] = (deUint8)((val & 0x0000FFu) >> 0u); 93e5c31af7Sopenharmony_ci dst[1] = (deUint8)((val & 0x00FF00u) >> 8u); 94e5c31af7Sopenharmony_ci dst[2] = (deUint8)((val & 0xFF0000u) >> 16u); 95e5c31af7Sopenharmony_ci#else 96e5c31af7Sopenharmony_ci dst[0] = (deUint8)((val & 0xFF0000u) >> 16u); 97e5c31af7Sopenharmony_ci dst[1] = (deUint8)((val & 0x00FF00u) >> 8u); 98e5c31af7Sopenharmony_ci dst[2] = (deUint8)((val & 0x0000FFu) >> 0u); 99e5c31af7Sopenharmony_ci#endif 100e5c31af7Sopenharmony_ci} 101e5c31af7Sopenharmony_ci 102e5c31af7Sopenharmony_ciinline deUint32 readUint24 (const deUint8* src) 103e5c31af7Sopenharmony_ci{ 104e5c31af7Sopenharmony_ci#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN) 105e5c31af7Sopenharmony_ci return (((deUint32)src[0]) << 0u) | 106e5c31af7Sopenharmony_ci (((deUint32)src[1]) << 8u) | 107e5c31af7Sopenharmony_ci (((deUint32)src[2]) << 16u); 108e5c31af7Sopenharmony_ci#else 109e5c31af7Sopenharmony_ci return (((deUint32)src[0]) << 16u) | 110e5c31af7Sopenharmony_ci (((deUint32)src[1]) << 8u) | 111e5c31af7Sopenharmony_ci (((deUint32)src[2]) << 0u); 112e5c31af7Sopenharmony_ci#endif 113e5c31af7Sopenharmony_ci} 114e5c31af7Sopenharmony_ci 115e5c31af7Sopenharmony_ciinline deUint8 readUint32Low8 (const deUint8* src) 116e5c31af7Sopenharmony_ci{ 117e5c31af7Sopenharmony_ci#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN) 118e5c31af7Sopenharmony_ci const deUint32 uint32ByteOffsetBits0To8 = 0; //!< least significant byte in the lowest address 119e5c31af7Sopenharmony_ci#else 120e5c31af7Sopenharmony_ci const deUint32 uint32ByteOffsetBits0To8 = 3; //!< least significant byte in the highest address 121e5c31af7Sopenharmony_ci#endif 122e5c31af7Sopenharmony_ci 123e5c31af7Sopenharmony_ci return src[uint32ByteOffsetBits0To8]; 124e5c31af7Sopenharmony_ci} 125e5c31af7Sopenharmony_ci 126e5c31af7Sopenharmony_ciinline deUint8 readUint32High8 (const deUint8* src) 127e5c31af7Sopenharmony_ci{ 128e5c31af7Sopenharmony_ci#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN) 129e5c31af7Sopenharmony_ci const deUint32 uint32ByteOffsetBits24To32 = 3; 130e5c31af7Sopenharmony_ci#else 131e5c31af7Sopenharmony_ci const deUint32 uint32ByteOffsetBits24To32 = 0; 132e5c31af7Sopenharmony_ci#endif 133e5c31af7Sopenharmony_ci 134e5c31af7Sopenharmony_ci return src[uint32ByteOffsetBits24To32]; 135e5c31af7Sopenharmony_ci} 136e5c31af7Sopenharmony_ci 137e5c31af7Sopenharmony_ciinline void writeUint32Low8 (deUint8* dst, deUint8 val) 138e5c31af7Sopenharmony_ci{ 139e5c31af7Sopenharmony_ci#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN) 140e5c31af7Sopenharmony_ci const deUint32 uint32ByteOffsetBits0To8 = 0; //!< least significant byte in the lowest address 141e5c31af7Sopenharmony_ci#else 142e5c31af7Sopenharmony_ci const deUint32 uint32ByteOffsetBits0To8 = 3; //!< least significant byte in the highest address 143e5c31af7Sopenharmony_ci#endif 144e5c31af7Sopenharmony_ci 145e5c31af7Sopenharmony_ci dst[uint32ByteOffsetBits0To8] = val; 146e5c31af7Sopenharmony_ci} 147e5c31af7Sopenharmony_ci 148e5c31af7Sopenharmony_ciinline void writeUint32High8 (deUint8* dst, deUint8 val) 149e5c31af7Sopenharmony_ci{ 150e5c31af7Sopenharmony_ci#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN) 151e5c31af7Sopenharmony_ci const deUint32 uint32ByteOffsetBits24To32 = 3; 152e5c31af7Sopenharmony_ci#else 153e5c31af7Sopenharmony_ci const deUint32 uint32ByteOffsetBits24To32 = 0; 154e5c31af7Sopenharmony_ci#endif 155e5c31af7Sopenharmony_ci 156e5c31af7Sopenharmony_ci dst[uint32ByteOffsetBits24To32] = val; 157e5c31af7Sopenharmony_ci} 158e5c31af7Sopenharmony_ci 159e5c31af7Sopenharmony_ciinline deUint32 readUint32High16 (const deUint8* src) 160e5c31af7Sopenharmony_ci{ 161e5c31af7Sopenharmony_ci#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN) 162e5c31af7Sopenharmony_ci const deUint32 uint32ByteOffset16To32 = 2; 163e5c31af7Sopenharmony_ci#else 164e5c31af7Sopenharmony_ci const deUint32 uint32ByteOffset16To32 = 0; 165e5c31af7Sopenharmony_ci#endif 166e5c31af7Sopenharmony_ci 167e5c31af7Sopenharmony_ci return *(const deUint16*)(src + uint32ByteOffset16To32); 168e5c31af7Sopenharmony_ci} 169e5c31af7Sopenharmony_ci 170e5c31af7Sopenharmony_ciinline void writeUint32High16 (deUint8* dst, deUint16 val) 171e5c31af7Sopenharmony_ci{ 172e5c31af7Sopenharmony_ci#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN) 173e5c31af7Sopenharmony_ci const deUint32 uint32ByteOffset16To32 = 2; 174e5c31af7Sopenharmony_ci#else 175e5c31af7Sopenharmony_ci const deUint32 uint32ByteOffset16To32 = 0; 176e5c31af7Sopenharmony_ci#endif 177e5c31af7Sopenharmony_ci 178e5c31af7Sopenharmony_ci *(deUint16*)(dst + uint32ByteOffset16To32) = val; 179e5c31af7Sopenharmony_ci} 180e5c31af7Sopenharmony_ci 181e5c31af7Sopenharmony_ciinline deUint32 readUint32Low24 (const deUint8* src) 182e5c31af7Sopenharmony_ci{ 183e5c31af7Sopenharmony_ci#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN) 184e5c31af7Sopenharmony_ci const deUint32 uint32ByteOffset0To24 = 0; 185e5c31af7Sopenharmony_ci#else 186e5c31af7Sopenharmony_ci const deUint32 uint32ByteOffset0To24 = 1; 187e5c31af7Sopenharmony_ci#endif 188e5c31af7Sopenharmony_ci 189e5c31af7Sopenharmony_ci return readUint24(src + uint32ByteOffset0To24); 190e5c31af7Sopenharmony_ci} 191e5c31af7Sopenharmony_ci 192e5c31af7Sopenharmony_ciinline deUint32 readUint32High24 (const deUint8* src) 193e5c31af7Sopenharmony_ci{ 194e5c31af7Sopenharmony_ci#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN) 195e5c31af7Sopenharmony_ci const deUint32 uint32ByteOffset8To32 = 1; 196e5c31af7Sopenharmony_ci#else 197e5c31af7Sopenharmony_ci const deUint32 uint32ByteOffset8To32 = 0; 198e5c31af7Sopenharmony_ci#endif 199e5c31af7Sopenharmony_ci 200e5c31af7Sopenharmony_ci return readUint24(src + uint32ByteOffset8To32); 201e5c31af7Sopenharmony_ci} 202e5c31af7Sopenharmony_ci 203e5c31af7Sopenharmony_ciinline void writeUint32Low24 (deUint8* dst, deUint32 val) 204e5c31af7Sopenharmony_ci{ 205e5c31af7Sopenharmony_ci#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN) 206e5c31af7Sopenharmony_ci const deUint32 uint32ByteOffset0To24 = 0; 207e5c31af7Sopenharmony_ci#else 208e5c31af7Sopenharmony_ci const deUint32 uint32ByteOffset0To24 = 1; 209e5c31af7Sopenharmony_ci#endif 210e5c31af7Sopenharmony_ci 211e5c31af7Sopenharmony_ci writeUint24(dst + uint32ByteOffset0To24, val); 212e5c31af7Sopenharmony_ci} 213e5c31af7Sopenharmony_ci 214e5c31af7Sopenharmony_ciinline void writeUint32High24 (deUint8* dst, deUint32 val) 215e5c31af7Sopenharmony_ci{ 216e5c31af7Sopenharmony_ci#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN) 217e5c31af7Sopenharmony_ci const deUint32 uint32ByteOffset8To32 = 1; 218e5c31af7Sopenharmony_ci#else 219e5c31af7Sopenharmony_ci const deUint32 uint32ByteOffset8To32 = 0; 220e5c31af7Sopenharmony_ci#endif 221e5c31af7Sopenharmony_ci 222e5c31af7Sopenharmony_ci writeUint24(dst + uint32ByteOffset8To32, val); 223e5c31af7Sopenharmony_ci} 224e5c31af7Sopenharmony_ci 225e5c31af7Sopenharmony_ci// \todo [2011-09-21 pyry] Move to tcutil? 226e5c31af7Sopenharmony_citemplate <typename T> 227e5c31af7Sopenharmony_ciinline T convertSatRte (float f) 228e5c31af7Sopenharmony_ci{ 229e5c31af7Sopenharmony_ci // \note Doesn't work for 64-bit types 230e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(sizeof(T) < sizeof(deUint64)); 231e5c31af7Sopenharmony_ci DE_STATIC_ASSERT((-3 % 2 != 0) && (-4 % 2 == 0)); 232e5c31af7Sopenharmony_ci 233e5c31af7Sopenharmony_ci deInt64 minVal = std::numeric_limits<T>::min(); 234e5c31af7Sopenharmony_ci deInt64 maxVal = std::numeric_limits<T>::max(); 235e5c31af7Sopenharmony_ci float q = deFloatFrac(f); 236e5c31af7Sopenharmony_ci deInt64 intVal = (deInt64)(f-q); 237e5c31af7Sopenharmony_ci 238e5c31af7Sopenharmony_ci // Rounding. 239e5c31af7Sopenharmony_ci if (q == 0.5f) 240e5c31af7Sopenharmony_ci { 241e5c31af7Sopenharmony_ci if (intVal % 2 != 0) 242e5c31af7Sopenharmony_ci intVal++; 243e5c31af7Sopenharmony_ci } 244e5c31af7Sopenharmony_ci else if (q > 0.5f) 245e5c31af7Sopenharmony_ci intVal++; 246e5c31af7Sopenharmony_ci // else Don't add anything 247e5c31af7Sopenharmony_ci 248e5c31af7Sopenharmony_ci // Saturate. 249e5c31af7Sopenharmony_ci intVal = de::max(minVal, de::min(maxVal, intVal)); 250e5c31af7Sopenharmony_ci 251e5c31af7Sopenharmony_ci return (T)intVal; 252e5c31af7Sopenharmony_ci} 253e5c31af7Sopenharmony_ci 254e5c31af7Sopenharmony_ciinline deUint32 convertSatRteUint24 (float f) 255e5c31af7Sopenharmony_ci{ 256e5c31af7Sopenharmony_ci const deUint32 rounded = convertSatRte<deUint32>(f); 257e5c31af7Sopenharmony_ci const deUint32 maxUint24 = 0xFFFFFFu; 258e5c31af7Sopenharmony_ci return de::min(rounded, maxUint24); 259e5c31af7Sopenharmony_ci} 260e5c31af7Sopenharmony_ci 261e5c31af7Sopenharmony_ciinline deUint16 convertSatRteUint10 (float f) 262e5c31af7Sopenharmony_ci{ 263e5c31af7Sopenharmony_ci const deUint16 rounded = convertSatRte<deUint16>(f); 264e5c31af7Sopenharmony_ci const deUint16 maxUint10 = 0x3FFu; 265e5c31af7Sopenharmony_ci return de::min(rounded, maxUint10); 266e5c31af7Sopenharmony_ci} 267e5c31af7Sopenharmony_ci 268e5c31af7Sopenharmony_ciinline deUint16 convertSatRteUint12 (float f) 269e5c31af7Sopenharmony_ci{ 270e5c31af7Sopenharmony_ci const deUint16 rounded = convertSatRte<deUint16>(f); 271e5c31af7Sopenharmony_ci const deUint16 maxUint12 = 0xFFFu; 272e5c31af7Sopenharmony_ci return de::min(rounded, maxUint12); 273e5c31af7Sopenharmony_ci} 274e5c31af7Sopenharmony_ci 275e5c31af7Sopenharmony_ciinline float channelToFloat (const deUint8* value, TextureFormat::ChannelType type) 276e5c31af7Sopenharmony_ci{ 277e5c31af7Sopenharmony_ci // make sure this table is updated if format table is updated 278e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 48); 279e5c31af7Sopenharmony_ci 280e5c31af7Sopenharmony_ci switch (type) 281e5c31af7Sopenharmony_ci { 282e5c31af7Sopenharmony_ci case TextureFormat::SNORM_INT8: return de::max(-1.0f, (float)*((const deInt8*)value) / 127.0f); 283e5c31af7Sopenharmony_ci case TextureFormat::SNORM_INT16: return de::max(-1.0f, (float)*((const deInt16*)value) / 32767.0f); 284e5c31af7Sopenharmony_ci case TextureFormat::SNORM_INT32: return de::max(-1.0f, (float)*((const deInt32*)value) / 2147483647.0f); 285e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT8: return (float)*((const deUint8*)value) / 255.0f; 286e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT16: return (float)*((const deUint16*)value) / 65535.0f; 287e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT24: return (float)readUint24(value) / 16777215.0f; 288e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT32: return (float)*((const deUint32*)value) / 4294967295.0f; 289e5c31af7Sopenharmony_ci case TextureFormat::SIGNED_INT8: return (float)*((const deInt8*)value); 290e5c31af7Sopenharmony_ci case TextureFormat::SIGNED_INT16: return (float)*((const deInt16*)value); 291e5c31af7Sopenharmony_ci case TextureFormat::SIGNED_INT32: return (float)*((const deInt32*)value); 292e5c31af7Sopenharmony_ci case TextureFormat::SIGNED_INT64: return (float)*((const deInt64*)value); 293e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT8: return (float)*((const deUint8*)value); 294e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT16: return (float)*((const deUint16*)value); 295e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT24: return (float)readUint24(value); 296e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT32: return (float)*((const deUint32*)value); 297e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT64: return (float)*((const deUint64*)value); 298e5c31af7Sopenharmony_ci case TextureFormat::HALF_FLOAT: return deFloat16To32(*(const deFloat16*)value); 299e5c31af7Sopenharmony_ci case TextureFormat::FLOAT: return *((const float*)value); 300e5c31af7Sopenharmony_ci case TextureFormat::FLOAT64: return (float)*((const double*)value); 301e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_10: return (float)((*((const deUint16*)value)) >> 6u) / 1023.0f; 302e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_12: return (float)((*((const deUint16*)value)) >> 4u) / 4095.0f; 303e5c31af7Sopenharmony_ci case TextureFormat::USCALED_INT8: return (float)*((const deUint8*)value); 304e5c31af7Sopenharmony_ci case TextureFormat::USCALED_INT16: return (float)*((const deUint16*)value); 305e5c31af7Sopenharmony_ci case TextureFormat::SSCALED_INT8: return (float)*((const deInt8*)value); 306e5c31af7Sopenharmony_ci case TextureFormat::SSCALED_INT16: return (float)*((const deInt16*)value); 307e5c31af7Sopenharmony_ci default: 308e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 309e5c31af7Sopenharmony_ci return 0.0f; 310e5c31af7Sopenharmony_ci } 311e5c31af7Sopenharmony_ci} 312e5c31af7Sopenharmony_ci 313e5c31af7Sopenharmony_citemplate <class T> 314e5c31af7Sopenharmony_ciinline T channelToIntType (const deUint8* value, TextureFormat::ChannelType type) 315e5c31af7Sopenharmony_ci{ 316e5c31af7Sopenharmony_ci // make sure this table is updated if format table is updated 317e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 48); 318e5c31af7Sopenharmony_ci 319e5c31af7Sopenharmony_ci switch (type) 320e5c31af7Sopenharmony_ci { 321e5c31af7Sopenharmony_ci case TextureFormat::SNORM_INT8: return (T)*((const deInt8*)value); 322e5c31af7Sopenharmony_ci case TextureFormat::SNORM_INT16: return (T)*((const deInt16*)value); 323e5c31af7Sopenharmony_ci case TextureFormat::SNORM_INT32: return (T)*((const deInt32*)value); 324e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT8: return (T)*((const deUint8*)value); 325e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT16: return (T)*((const deUint16*)value); 326e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT24: return (T)readUint24(value); 327e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT32: return (T)*((const deUint32*)value); 328e5c31af7Sopenharmony_ci case TextureFormat::SIGNED_INT8: return (T)*((const deInt8*)value); 329e5c31af7Sopenharmony_ci case TextureFormat::SIGNED_INT16: return (T)*((const deInt16*)value); 330e5c31af7Sopenharmony_ci case TextureFormat::SIGNED_INT32: return (T)*((const deInt32*)value); 331e5c31af7Sopenharmony_ci case TextureFormat::SIGNED_INT64: return (T)*((const deInt64*)value); 332e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT8: return (T)*((const deUint8*)value); 333e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT16: return (T)*((const deUint16*)value); 334e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT24: return (T)readUint24(value); 335e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT32: return (T)*((const deUint32*)value); 336e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT64: return (T)*((const deUint64*)value); 337e5c31af7Sopenharmony_ci case TextureFormat::HALF_FLOAT: return (T)deFloat16To32(*(const deFloat16*)value); 338e5c31af7Sopenharmony_ci case TextureFormat::FLOAT: return (T)*((const float*)value); 339e5c31af7Sopenharmony_ci case TextureFormat::FLOAT64: return (T)*((const double*)value); 340e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_10: return (T)((*(((const deUint16*)value))) >> 6u); 341e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_12: return (T)((*(((const deUint16*)value))) >> 4u); 342e5c31af7Sopenharmony_ci case TextureFormat::USCALED_INT8: return (T)*((const deUint8*)value); 343e5c31af7Sopenharmony_ci case TextureFormat::USCALED_INT16: return (T)*((const deUint16*)value); 344e5c31af7Sopenharmony_ci case TextureFormat::SSCALED_INT8: return (T)*((const deInt8*)value); 345e5c31af7Sopenharmony_ci case TextureFormat::SSCALED_INT16: return (T)*((const deInt16*)value); 346e5c31af7Sopenharmony_ci default: 347e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 348e5c31af7Sopenharmony_ci return 0; 349e5c31af7Sopenharmony_ci } 350e5c31af7Sopenharmony_ci} 351e5c31af7Sopenharmony_ci 352e5c31af7Sopenharmony_ciinline uint64_t retrieveChannelBitsAsUint64 (const deUint8* value, TextureFormat::ChannelType type) 353e5c31af7Sopenharmony_ci{ 354e5c31af7Sopenharmony_ci // make sure this table is updated if format table is updated 355e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 48); 356e5c31af7Sopenharmony_ci 357e5c31af7Sopenharmony_ci switch (type) 358e5c31af7Sopenharmony_ci { 359e5c31af7Sopenharmony_ci case TextureFormat::SNORM_INT8: return (uint64_t)*((const uint8_t*)value); 360e5c31af7Sopenharmony_ci case TextureFormat::SNORM_INT16: return (uint64_t)*((const uint16_t*)value); 361e5c31af7Sopenharmony_ci case TextureFormat::SNORM_INT32: return (uint64_t)*((const uint32_t*)value); 362e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT8: return (uint64_t)*((const uint8_t*)value); 363e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT16: return (uint64_t)*((const uint16_t*)value); 364e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT24: return (uint64_t)readUint24(value); 365e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT32: return (uint64_t)*((const uint32_t*)value); 366e5c31af7Sopenharmony_ci case TextureFormat::SIGNED_INT8: return (uint64_t)*((const uint8_t*)value); 367e5c31af7Sopenharmony_ci case TextureFormat::SIGNED_INT16: return (uint64_t)*((const uint16_t*)value); 368e5c31af7Sopenharmony_ci case TextureFormat::SIGNED_INT32: return (uint64_t)*((const uint32_t*)value); 369e5c31af7Sopenharmony_ci case TextureFormat::SIGNED_INT64: return (uint64_t)*((const uint64_t*)value); 370e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT8: return (uint64_t)*((const uint8_t*)value); 371e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT16: return (uint64_t)*((const uint16_t*)value); 372e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT24: return (uint64_t)readUint24(value); 373e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT32: return (uint64_t)*((const uint32_t*)value); 374e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT64: return (uint64_t)*((const uint64_t*)value); 375e5c31af7Sopenharmony_ci case TextureFormat::HALF_FLOAT: return (uint64_t)*((const uint16_t*)value); 376e5c31af7Sopenharmony_ci case TextureFormat::FLOAT: return (uint64_t)*((const uint32_t*)value); 377e5c31af7Sopenharmony_ci case TextureFormat::FLOAT64: return (uint64_t)*((const uint64_t*)value); 378e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_10: return (uint64_t)((*((const uint16_t*)value)) >> 6u); 379e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_12: return (uint64_t)((*((const uint16_t*)value)) >> 4u); 380e5c31af7Sopenharmony_ci case TextureFormat::USCALED_INT8: return (uint64_t)*((const uint8_t*)value); 381e5c31af7Sopenharmony_ci case TextureFormat::USCALED_INT16: return (uint64_t)*((const uint16_t*)value); 382e5c31af7Sopenharmony_ci case TextureFormat::SSCALED_INT8: return (uint64_t)*((const uint8_t*)value); 383e5c31af7Sopenharmony_ci case TextureFormat::SSCALED_INT16: return (uint64_t)*((const uint16_t*)value); 384e5c31af7Sopenharmony_ci default: 385e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 386e5c31af7Sopenharmony_ci return 0; 387e5c31af7Sopenharmony_ci } 388e5c31af7Sopenharmony_ci} 389e5c31af7Sopenharmony_ci 390e5c31af7Sopenharmony_ciinline int channelToInt (const deUint8* value, TextureFormat::ChannelType type) 391e5c31af7Sopenharmony_ci{ 392e5c31af7Sopenharmony_ci return channelToIntType<int>(value, type); 393e5c31af7Sopenharmony_ci} 394e5c31af7Sopenharmony_ci 395e5c31af7Sopenharmony_civoid floatToChannel (deUint8* dst, float src, TextureFormat::ChannelType type) 396e5c31af7Sopenharmony_ci{ 397e5c31af7Sopenharmony_ci // make sure this table is updated if format table is updated 398e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 48); 399e5c31af7Sopenharmony_ci 400e5c31af7Sopenharmony_ci switch (type) 401e5c31af7Sopenharmony_ci { 402e5c31af7Sopenharmony_ci case TextureFormat::SNORM_INT8: *((deInt8*)dst) = convertSatRte<deInt8> (src * 127.0f); break; 403e5c31af7Sopenharmony_ci case TextureFormat::SNORM_INT16: *((deInt16*)dst) = convertSatRte<deInt16> (src * 32767.0f); break; 404e5c31af7Sopenharmony_ci case TextureFormat::SNORM_INT32: *((deInt32*)dst) = convertSatRte<deInt32> (src * 2147483647.0f); break; 405e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT8: *((deUint8*)dst) = convertSatRte<deUint8> (src * 255.0f); break; 406e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT16: *((deUint16*)dst) = convertSatRte<deUint16> (src * 65535.0f); break; 407e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT24: writeUint24(dst, convertSatRteUint24 (src * 16777215.0f)); break; 408e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT32: *((deUint32*)dst) = convertSatRte<deUint32> (src * 4294967295.0f); break; 409e5c31af7Sopenharmony_ci case TextureFormat::SIGNED_INT8: *((deInt8*)dst) = convertSatRte<deInt8> (src); break; 410e5c31af7Sopenharmony_ci case TextureFormat::SIGNED_INT16: *((deInt16*)dst) = convertSatRte<deInt16> (src); break; 411e5c31af7Sopenharmony_ci case TextureFormat::SIGNED_INT32: *((deInt32*)dst) = convertSatRte<deInt32> (src); break; 412e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT8: *((deUint8*)dst) = convertSatRte<deUint8> (src); break; 413e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT16: *((deUint16*)dst) = convertSatRte<deUint16> (src); break; 414e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT24: writeUint24(dst, convertSatRteUint24 (src)); break; 415e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT32: *((deUint32*)dst) = convertSatRte<deUint32> (src); break; 416e5c31af7Sopenharmony_ci case TextureFormat::HALF_FLOAT: *((deFloat16*)dst) = deFloat32To16 (src); break; 417e5c31af7Sopenharmony_ci case TextureFormat::FLOAT: *((float*)dst) = src; break; 418e5c31af7Sopenharmony_ci case TextureFormat::FLOAT64: *((double*)dst) = (double)src; break; 419e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_10: *((deUint16*)dst) = (deUint16)(convertSatRteUint10(src * 1023.0f) << 6u); break; 420e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_12: *((deUint16*)dst) = (deUint16)(convertSatRteUint12(src * 4095.0f) << 4u); break; 421e5c31af7Sopenharmony_ci case TextureFormat::USCALED_INT8: *((deUint8*)dst) = convertSatRte<deUint8> (src); break; 422e5c31af7Sopenharmony_ci case TextureFormat::USCALED_INT16: *((deUint16*)dst) = convertSatRte<deUint16> (src); break; 423e5c31af7Sopenharmony_ci case TextureFormat::SSCALED_INT8: *((deInt8*)dst) = convertSatRte<deInt8> (src); break; 424e5c31af7Sopenharmony_ci case TextureFormat::SSCALED_INT16: *((deInt16*)dst) = convertSatRte<deInt16> (src); break; 425e5c31af7Sopenharmony_ci default: 426e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 427e5c31af7Sopenharmony_ci } 428e5c31af7Sopenharmony_ci} 429e5c31af7Sopenharmony_ci 430e5c31af7Sopenharmony_citemplate <typename T, typename S> 431e5c31af7Sopenharmony_cistatic inline T convertSat (S src) 432e5c31af7Sopenharmony_ci{ 433e5c31af7Sopenharmony_ci S min = (S)std::numeric_limits<T>::min(); 434e5c31af7Sopenharmony_ci S max = (S)std::numeric_limits<T>::max(); 435e5c31af7Sopenharmony_ci 436e5c31af7Sopenharmony_ci if (src < min) 437e5c31af7Sopenharmony_ci return (T)min; 438e5c31af7Sopenharmony_ci else if (src > max) 439e5c31af7Sopenharmony_ci return (T)max; 440e5c31af7Sopenharmony_ci else 441e5c31af7Sopenharmony_ci return (T)src; 442e5c31af7Sopenharmony_ci} 443e5c31af7Sopenharmony_ci 444e5c31af7Sopenharmony_citemplate <typename S> 445e5c31af7Sopenharmony_cistatic inline deUint32 convertSatUint24 (S src) 446e5c31af7Sopenharmony_ci{ 447e5c31af7Sopenharmony_ci S min = (S)0u; 448e5c31af7Sopenharmony_ci S max = (S)0xFFFFFFu; 449e5c31af7Sopenharmony_ci 450e5c31af7Sopenharmony_ci if (src < min) 451e5c31af7Sopenharmony_ci return (deUint32)min; 452e5c31af7Sopenharmony_ci else if (src > max) 453e5c31af7Sopenharmony_ci return (deUint32)max; 454e5c31af7Sopenharmony_ci else 455e5c31af7Sopenharmony_ci return (deUint32)src; 456e5c31af7Sopenharmony_ci} 457e5c31af7Sopenharmony_ci 458e5c31af7Sopenharmony_citemplate <typename S> 459e5c31af7Sopenharmony_cistatic inline deUint16 convertSatUint10 (S src) 460e5c31af7Sopenharmony_ci{ 461e5c31af7Sopenharmony_ci S min = (S)0u; 462e5c31af7Sopenharmony_ci S max = (S)0x3FFu; 463e5c31af7Sopenharmony_ci 464e5c31af7Sopenharmony_ci if (src < min) 465e5c31af7Sopenharmony_ci return (deUint16)min; 466e5c31af7Sopenharmony_ci else if (src > max) 467e5c31af7Sopenharmony_ci return (deUint16)max; 468e5c31af7Sopenharmony_ci else 469e5c31af7Sopenharmony_ci return (deUint16)src; 470e5c31af7Sopenharmony_ci} 471e5c31af7Sopenharmony_ci 472e5c31af7Sopenharmony_citemplate <typename S> 473e5c31af7Sopenharmony_cistatic inline deUint16 convertSatUint12 (S src) 474e5c31af7Sopenharmony_ci{ 475e5c31af7Sopenharmony_ci S min = (S)0u; 476e5c31af7Sopenharmony_ci S max = (S)0xFFFu; 477e5c31af7Sopenharmony_ci 478e5c31af7Sopenharmony_ci if (src < min) 479e5c31af7Sopenharmony_ci return (deUint16)min; 480e5c31af7Sopenharmony_ci else if (src > max) 481e5c31af7Sopenharmony_ci return (deUint16)max; 482e5c31af7Sopenharmony_ci else 483e5c31af7Sopenharmony_ci return (deUint16)src; 484e5c31af7Sopenharmony_ci} 485e5c31af7Sopenharmony_ci 486e5c31af7Sopenharmony_civoid intToChannel (deUint8* dst, int src, TextureFormat::ChannelType type) 487e5c31af7Sopenharmony_ci{ 488e5c31af7Sopenharmony_ci // make sure this table is updated if format table is updated 489e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 48); 490e5c31af7Sopenharmony_ci 491e5c31af7Sopenharmony_ci switch (type) 492e5c31af7Sopenharmony_ci { 493e5c31af7Sopenharmony_ci case TextureFormat::SNORM_INT8: *((deInt8*)dst) = convertSat<deInt8> (src); break; 494e5c31af7Sopenharmony_ci case TextureFormat::SNORM_INT16: *((deInt16*)dst) = convertSat<deInt16> (src); break; 495e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT8: *((deUint8*)dst) = convertSat<deUint8> (src); break; 496e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT16: *((deUint16*)dst) = convertSat<deUint16> (src); break; 497e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT24: writeUint24(dst, convertSatUint24 (src)); break; 498e5c31af7Sopenharmony_ci case TextureFormat::SIGNED_INT8: *((deInt8*)dst) = convertSat<deInt8> (src); break; 499e5c31af7Sopenharmony_ci case TextureFormat::SIGNED_INT16: *((deInt16*)dst) = convertSat<deInt16> (src); break; 500e5c31af7Sopenharmony_ci case TextureFormat::SIGNED_INT32: *((deInt32*)dst) = convertSat<deInt32> (src); break; 501e5c31af7Sopenharmony_ci case TextureFormat::SIGNED_INT64: *((deInt64*)dst) = convertSat<deInt64> ((deInt64)src); break; 502e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT8: *((deUint8*)dst) = convertSat<deUint8> ((deUint32)src); break; 503e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT16: *((deUint16*)dst) = convertSat<deUint16> ((deUint32)src); break; 504e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT24: writeUint24(dst, convertSatUint24 ((deUint32)src)); break; 505e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT32: *((deUint32*)dst) = convertSat<deUint32> ((deUint32)src); break; 506e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT64: *((deUint64*)dst) = convertSat<deUint64> ((deUint64)src); break; 507e5c31af7Sopenharmony_ci case TextureFormat::HALF_FLOAT: *((deFloat16*)dst) = deFloat32To16((float)src); break; 508e5c31af7Sopenharmony_ci case TextureFormat::FLOAT: *((float*)dst) = (float)src; break; 509e5c31af7Sopenharmony_ci case TextureFormat::FLOAT64: *((double*)dst) = (double)src; break; 510e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_10: *((deUint16*)dst) = (deUint16)(convertSatUint10(src) << 6u); break; 511e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_12: *((deUint16*)dst) = (deUint16)(convertSatUint12(src) << 4u); break; 512e5c31af7Sopenharmony_ci case TextureFormat::USCALED_INT8: *((deUint8*)dst) = convertSat<deUint8> ((deUint32)src); break; 513e5c31af7Sopenharmony_ci case TextureFormat::USCALED_INT16: *((deUint16*)dst) = convertSat<deUint16> ((deUint32)src); break; 514e5c31af7Sopenharmony_ci case TextureFormat::SSCALED_INT8: *((deInt8*)dst) = convertSat<deInt8> (src); break; 515e5c31af7Sopenharmony_ci case TextureFormat::SSCALED_INT16: *((deInt16*)dst) = convertSat<deInt16> (src); break; 516e5c31af7Sopenharmony_ci default: 517e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 518e5c31af7Sopenharmony_ci } 519e5c31af7Sopenharmony_ci} 520e5c31af7Sopenharmony_ci 521e5c31af7Sopenharmony_ciinline float channelToUnormFloat (deUint32 src, int bits) 522e5c31af7Sopenharmony_ci{ 523e5c31af7Sopenharmony_ci const deUint32 maxVal = (1u << bits) - 1; 524e5c31af7Sopenharmony_ci 525e5c31af7Sopenharmony_ci // \note Will lose precision if bits > 23 526e5c31af7Sopenharmony_ci return (float)src / (float)maxVal; 527e5c31af7Sopenharmony_ci} 528e5c31af7Sopenharmony_ci 529e5c31af7Sopenharmony_ci//! Extend < 32b signed integer to 32b 530e5c31af7Sopenharmony_ciinline deInt32 signExtend (deUint32 src, int bits) 531e5c31af7Sopenharmony_ci{ 532e5c31af7Sopenharmony_ci const deUint32 signBit = 1u << (bits-1); 533e5c31af7Sopenharmony_ci 534e5c31af7Sopenharmony_ci src |= ~((src & signBit) - 1); 535e5c31af7Sopenharmony_ci 536e5c31af7Sopenharmony_ci return (deInt32)src; 537e5c31af7Sopenharmony_ci} 538e5c31af7Sopenharmony_ci 539e5c31af7Sopenharmony_ciinline float channelToSnormFloat (deUint32 src, int bits) 540e5c31af7Sopenharmony_ci{ 541e5c31af7Sopenharmony_ci const deUint32 range = (1u << (bits-1)) - 1; 542e5c31af7Sopenharmony_ci 543e5c31af7Sopenharmony_ci // \note Will lose precision if bits > 24 544e5c31af7Sopenharmony_ci return de::max(-1.0f, (float)signExtend(src, bits) / (float)range); 545e5c31af7Sopenharmony_ci} 546e5c31af7Sopenharmony_ci 547e5c31af7Sopenharmony_ciinline deUint32 unormFloatToChannel (float src, int bits) 548e5c31af7Sopenharmony_ci{ 549e5c31af7Sopenharmony_ci const deUint32 maxVal = (1u << bits) - 1; 550e5c31af7Sopenharmony_ci const deUint32 intVal = convertSatRte<deUint32>(src * (float)maxVal); 551e5c31af7Sopenharmony_ci 552e5c31af7Sopenharmony_ci return de::min(intVal, maxVal); 553e5c31af7Sopenharmony_ci} 554e5c31af7Sopenharmony_ci 555e5c31af7Sopenharmony_ciinline deUint32 snormFloatToChannel (float src, int bits) 556e5c31af7Sopenharmony_ci{ 557e5c31af7Sopenharmony_ci const deInt32 range = (deInt32)((1u << (bits-1)) - 1u); 558e5c31af7Sopenharmony_ci const deUint32 mask = (1u << bits) - 1; 559e5c31af7Sopenharmony_ci const deInt32 intVal = convertSatRte<deInt32>(src * (float)range); 560e5c31af7Sopenharmony_ci 561e5c31af7Sopenharmony_ci return (deUint32)de::clamp(intVal, -range, range) & mask; 562e5c31af7Sopenharmony_ci} 563e5c31af7Sopenharmony_ci 564e5c31af7Sopenharmony_ciinline deUint32 uintToChannel (deUint32 src, int bits) 565e5c31af7Sopenharmony_ci{ 566e5c31af7Sopenharmony_ci const deUint32 maxVal = (1u << bits) - 1; 567e5c31af7Sopenharmony_ci return de::min(src, maxVal); 568e5c31af7Sopenharmony_ci} 569e5c31af7Sopenharmony_ci 570e5c31af7Sopenharmony_ciinline deUint32 intToChannel (deInt32 src, int bits) 571e5c31af7Sopenharmony_ci{ 572e5c31af7Sopenharmony_ci const deInt32 minVal = -(deInt32)(1u << (bits-1)); 573e5c31af7Sopenharmony_ci const deInt32 maxVal = (deInt32)((1u << (bits-1)) - 1u); 574e5c31af7Sopenharmony_ci const deUint32 mask = (1u << bits) - 1; 575e5c31af7Sopenharmony_ci 576e5c31af7Sopenharmony_ci return (deUint32)de::clamp(src, minVal, maxVal) & mask; 577e5c31af7Sopenharmony_ci} 578e5c31af7Sopenharmony_ci 579e5c31af7Sopenharmony_citcu::Vec4 unpackRGB999E5 (deUint32 color) 580e5c31af7Sopenharmony_ci{ 581e5c31af7Sopenharmony_ci const int mBits = 9; 582e5c31af7Sopenharmony_ci const int eBias = 15; 583e5c31af7Sopenharmony_ci 584e5c31af7Sopenharmony_ci deUint32 exp = color >> 27; 585e5c31af7Sopenharmony_ci deUint32 bs = (color >> 18) & ((1<<9)-1); 586e5c31af7Sopenharmony_ci deUint32 gs = (color >> 9) & ((1<<9)-1); 587e5c31af7Sopenharmony_ci deUint32 rs = color & ((1<<9)-1); 588e5c31af7Sopenharmony_ci 589e5c31af7Sopenharmony_ci float e = deFloatPow(2.0f, (float)((int)exp - eBias - mBits)); 590e5c31af7Sopenharmony_ci float r = (float)rs * e; 591e5c31af7Sopenharmony_ci float g = (float)gs * e; 592e5c31af7Sopenharmony_ci float b = (float)bs * e; 593e5c31af7Sopenharmony_ci 594e5c31af7Sopenharmony_ci return tcu::Vec4(r, g, b, 1.0f); 595e5c31af7Sopenharmony_ci} 596e5c31af7Sopenharmony_ci 597e5c31af7Sopenharmony_cibool isColorOrder (TextureFormat::ChannelOrder order) 598e5c31af7Sopenharmony_ci{ 599e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(TextureFormat::CHANNELORDER_LAST == 22); 600e5c31af7Sopenharmony_ci 601e5c31af7Sopenharmony_ci switch (order) 602e5c31af7Sopenharmony_ci { 603e5c31af7Sopenharmony_ci case TextureFormat::R: 604e5c31af7Sopenharmony_ci case TextureFormat::A: 605e5c31af7Sopenharmony_ci case TextureFormat::I: 606e5c31af7Sopenharmony_ci case TextureFormat::L: 607e5c31af7Sopenharmony_ci case TextureFormat::LA: 608e5c31af7Sopenharmony_ci case TextureFormat::RG: 609e5c31af7Sopenharmony_ci case TextureFormat::RA: 610e5c31af7Sopenharmony_ci case TextureFormat::RGB: 611e5c31af7Sopenharmony_ci case TextureFormat::RGBA: 612e5c31af7Sopenharmony_ci case TextureFormat::ARGB: 613e5c31af7Sopenharmony_ci case TextureFormat::ABGR: 614e5c31af7Sopenharmony_ci case TextureFormat::BGR: 615e5c31af7Sopenharmony_ci case TextureFormat::BGRA: 616e5c31af7Sopenharmony_ci case TextureFormat::sR: 617e5c31af7Sopenharmony_ci case TextureFormat::sRG: 618e5c31af7Sopenharmony_ci case TextureFormat::sRGB: 619e5c31af7Sopenharmony_ci case TextureFormat::sRGBA: 620e5c31af7Sopenharmony_ci case TextureFormat::sBGR: 621e5c31af7Sopenharmony_ci case TextureFormat::sBGRA: 622e5c31af7Sopenharmony_ci return true; 623e5c31af7Sopenharmony_ci 624e5c31af7Sopenharmony_ci default: 625e5c31af7Sopenharmony_ci return false; 626e5c31af7Sopenharmony_ci } 627e5c31af7Sopenharmony_ci} 628e5c31af7Sopenharmony_ci 629e5c31af7Sopenharmony_cifloat getImageViewMinLod(ImageViewMinLod& l) 630e5c31af7Sopenharmony_ci{ 631e5c31af7Sopenharmony_ci return (l.mode == IMAGEVIEWMINLODMODE_PREFERRED) ? l.value : deFloatFloor(l.value); 632e5c31af7Sopenharmony_ci} 633e5c31af7Sopenharmony_ci 634e5c31af7Sopenharmony_ci} // anonymous 635e5c31af7Sopenharmony_ci 636e5c31af7Sopenharmony_cibool isValid (TextureFormat format) 637e5c31af7Sopenharmony_ci{ 638e5c31af7Sopenharmony_ci const bool isColor = isColorOrder(format.order); 639e5c31af7Sopenharmony_ci 640e5c31af7Sopenharmony_ci switch (format.type) 641e5c31af7Sopenharmony_ci { 642e5c31af7Sopenharmony_ci case TextureFormat::SNORM_INT8: 643e5c31af7Sopenharmony_ci case TextureFormat::SNORM_INT16: 644e5c31af7Sopenharmony_ci case TextureFormat::SNORM_INT32: 645e5c31af7Sopenharmony_ci return isColor; 646e5c31af7Sopenharmony_ci 647e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT8: 648e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT16: 649e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT24: 650e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT32: 651e5c31af7Sopenharmony_ci return isColor || format.order == TextureFormat::D; 652e5c31af7Sopenharmony_ci 653e5c31af7Sopenharmony_ci case TextureFormat::UNORM_BYTE_44: 654e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_BYTE_44: 655e5c31af7Sopenharmony_ci return format.order == TextureFormat::RG; 656e5c31af7Sopenharmony_ci 657e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_565: 658e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_555: 659e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_SHORT_565: 660e5c31af7Sopenharmony_ci return format.order == TextureFormat::RGB || format.order == TextureFormat::BGR; 661e5c31af7Sopenharmony_ci 662e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_4444: 663e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_5551: 664e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_SHORT_4444: 665e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_SHORT_5551: 666e5c31af7Sopenharmony_ci return format.order == TextureFormat::RGBA || format.order == TextureFormat::BGRA 667e5c31af7Sopenharmony_ci || format.order == TextureFormat::ARGB || format.order == TextureFormat::ABGR; 668e5c31af7Sopenharmony_ci 669e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_1555: 670e5c31af7Sopenharmony_ci return format.order == TextureFormat::ARGB || format.order == TextureFormat::ABGR; 671e5c31af7Sopenharmony_ci 672e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT_101010: 673e5c31af7Sopenharmony_ci return format.order == TextureFormat::RGB; 674e5c31af7Sopenharmony_ci 675e5c31af7Sopenharmony_ci case TextureFormat::SNORM_INT_1010102_REV: 676e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT_1010102_REV: 677e5c31af7Sopenharmony_ci case TextureFormat::SIGNED_INT_1010102_REV: 678e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT_1010102_REV: 679e5c31af7Sopenharmony_ci case TextureFormat::USCALED_INT_1010102_REV: 680e5c31af7Sopenharmony_ci case TextureFormat::SSCALED_INT_1010102_REV: 681e5c31af7Sopenharmony_ci return format.order == TextureFormat::RGBA || format.order == TextureFormat::BGRA; 682e5c31af7Sopenharmony_ci 683e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT_11F_11F_10F_REV: 684e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT_999_E5_REV: 685e5c31af7Sopenharmony_ci return format.order == TextureFormat::RGB; 686e5c31af7Sopenharmony_ci 687e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT_16_8_8: 688e5c31af7Sopenharmony_ci return format.order == TextureFormat::DS; 689e5c31af7Sopenharmony_ci 690e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT_24_8: 691e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT_24_8_REV: 692e5c31af7Sopenharmony_ci return format.order == TextureFormat::D || format.order == TextureFormat::DS; 693e5c31af7Sopenharmony_ci 694e5c31af7Sopenharmony_ci case TextureFormat::SIGNED_INT8: 695e5c31af7Sopenharmony_ci case TextureFormat::SIGNED_INT16: 696e5c31af7Sopenharmony_ci case TextureFormat::SIGNED_INT32: 697e5c31af7Sopenharmony_ci case TextureFormat::SSCALED_INT8: 698e5c31af7Sopenharmony_ci case TextureFormat::SSCALED_INT16: 699e5c31af7Sopenharmony_ci case TextureFormat::SIGNED_INT64: 700e5c31af7Sopenharmony_ci return isColor; 701e5c31af7Sopenharmony_ci 702e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT8: 703e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT16: 704e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT24: 705e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT32: 706e5c31af7Sopenharmony_ci case TextureFormat::USCALED_INT8: 707e5c31af7Sopenharmony_ci case TextureFormat::USCALED_INT16: 708e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT64: 709e5c31af7Sopenharmony_ci return isColor || format.order == TextureFormat::S; 710e5c31af7Sopenharmony_ci 711e5c31af7Sopenharmony_ci case TextureFormat::HALF_FLOAT: 712e5c31af7Sopenharmony_ci case TextureFormat::FLOAT: 713e5c31af7Sopenharmony_ci case TextureFormat::FLOAT64: 714e5c31af7Sopenharmony_ci return isColor || format.order == TextureFormat::D; 715e5c31af7Sopenharmony_ci 716e5c31af7Sopenharmony_ci case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV: 717e5c31af7Sopenharmony_ci return format.order == TextureFormat::DS; 718e5c31af7Sopenharmony_ci 719e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_10: 720e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_12: 721e5c31af7Sopenharmony_ci return isColor; 722e5c31af7Sopenharmony_ci 723e5c31af7Sopenharmony_ci default: 724e5c31af7Sopenharmony_ci DE_FATAL("Unknown format"); 725e5c31af7Sopenharmony_ci return 0u; 726e5c31af7Sopenharmony_ci } 727e5c31af7Sopenharmony_ci 728e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 48); 729e5c31af7Sopenharmony_ci} 730e5c31af7Sopenharmony_ci 731e5c31af7Sopenharmony_ciint getNumUsedChannels (TextureFormat::ChannelOrder order) 732e5c31af7Sopenharmony_ci{ 733e5c31af7Sopenharmony_ci // make sure this table is updated if type table is updated 734e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(TextureFormat::CHANNELORDER_LAST == 22); 735e5c31af7Sopenharmony_ci 736e5c31af7Sopenharmony_ci switch (order) 737e5c31af7Sopenharmony_ci { 738e5c31af7Sopenharmony_ci case TextureFormat::R: return 1; 739e5c31af7Sopenharmony_ci case TextureFormat::A: return 1; 740e5c31af7Sopenharmony_ci case TextureFormat::I: return 1; 741e5c31af7Sopenharmony_ci case TextureFormat::L: return 1; 742e5c31af7Sopenharmony_ci case TextureFormat::LA: return 2; 743e5c31af7Sopenharmony_ci case TextureFormat::RG: return 2; 744e5c31af7Sopenharmony_ci case TextureFormat::RA: return 2; 745e5c31af7Sopenharmony_ci case TextureFormat::RGB: return 3; 746e5c31af7Sopenharmony_ci case TextureFormat::RGBA: return 4; 747e5c31af7Sopenharmony_ci case TextureFormat::ARGB: return 4; 748e5c31af7Sopenharmony_ci case TextureFormat::ABGR: return 4; 749e5c31af7Sopenharmony_ci case TextureFormat::BGR: return 3; 750e5c31af7Sopenharmony_ci case TextureFormat::BGRA: return 4; 751e5c31af7Sopenharmony_ci case TextureFormat::sR: return 1; 752e5c31af7Sopenharmony_ci case TextureFormat::sRG: return 2; 753e5c31af7Sopenharmony_ci case TextureFormat::sRGB: return 3; 754e5c31af7Sopenharmony_ci case TextureFormat::sRGBA: return 4; 755e5c31af7Sopenharmony_ci case TextureFormat::sBGR: return 3; 756e5c31af7Sopenharmony_ci case TextureFormat::sBGRA: return 4; 757e5c31af7Sopenharmony_ci case TextureFormat::D: return 1; 758e5c31af7Sopenharmony_ci case TextureFormat::S: return 1; 759e5c31af7Sopenharmony_ci case TextureFormat::DS: return 2; 760e5c31af7Sopenharmony_ci default: 761e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 762e5c31af7Sopenharmony_ci return 0; 763e5c31af7Sopenharmony_ci } 764e5c31af7Sopenharmony_ci} 765e5c31af7Sopenharmony_ci 766e5c31af7Sopenharmony_ciint getChannelSize (TextureFormat::ChannelType type) 767e5c31af7Sopenharmony_ci{ 768e5c31af7Sopenharmony_ci // make sure this table is updated if format table is updated 769e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 48); 770e5c31af7Sopenharmony_ci 771e5c31af7Sopenharmony_ci switch (type) 772e5c31af7Sopenharmony_ci { 773e5c31af7Sopenharmony_ci case TextureFormat::SNORM_INT8: return 1; 774e5c31af7Sopenharmony_ci case TextureFormat::SNORM_INT16: return 2; 775e5c31af7Sopenharmony_ci case TextureFormat::SNORM_INT32: return 4; 776e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT8: return 1; 777e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT16: return 2; 778e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT24: return 3; 779e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT32: return 4; 780e5c31af7Sopenharmony_ci case TextureFormat::SIGNED_INT8: return 1; 781e5c31af7Sopenharmony_ci case TextureFormat::SIGNED_INT16: return 2; 782e5c31af7Sopenharmony_ci case TextureFormat::SIGNED_INT32: return 4; 783e5c31af7Sopenharmony_ci case TextureFormat::SIGNED_INT64: return 8; 784e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT8: return 1; 785e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT16: return 2; 786e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT24: return 3; 787e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT32: return 4; 788e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT64: return 8; 789e5c31af7Sopenharmony_ci case TextureFormat::HALF_FLOAT: return 2; 790e5c31af7Sopenharmony_ci case TextureFormat::FLOAT: return 4; 791e5c31af7Sopenharmony_ci case TextureFormat::FLOAT64: return 8; 792e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_10: return 2; 793e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_12: return 2; 794e5c31af7Sopenharmony_ci case TextureFormat::USCALED_INT8: return 1; 795e5c31af7Sopenharmony_ci case TextureFormat::USCALED_INT16: return 2; 796e5c31af7Sopenharmony_ci case TextureFormat::SSCALED_INT8: return 1; 797e5c31af7Sopenharmony_ci case TextureFormat::SSCALED_INT16: return 2; 798e5c31af7Sopenharmony_ci default: 799e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 800e5c31af7Sopenharmony_ci return 0; 801e5c31af7Sopenharmony_ci } 802e5c31af7Sopenharmony_ci} 803e5c31af7Sopenharmony_ci 804e5c31af7Sopenharmony_ci/** Get pixel size in bytes. */ 805e5c31af7Sopenharmony_ciint getPixelSize (TextureFormat format) 806e5c31af7Sopenharmony_ci{ 807e5c31af7Sopenharmony_ci const TextureFormat::ChannelOrder order = format.order; 808e5c31af7Sopenharmony_ci const TextureFormat::ChannelType type = format.type; 809e5c31af7Sopenharmony_ci 810e5c31af7Sopenharmony_ci DE_ASSERT(isValid(format)); 811e5c31af7Sopenharmony_ci 812e5c31af7Sopenharmony_ci // make sure this table is updated if format table is updated 813e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 48); 814e5c31af7Sopenharmony_ci 815e5c31af7Sopenharmony_ci switch (type) 816e5c31af7Sopenharmony_ci { 817e5c31af7Sopenharmony_ci case TextureFormat::UNORM_BYTE_44: 818e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_BYTE_44: 819e5c31af7Sopenharmony_ci return 1; 820e5c31af7Sopenharmony_ci 821e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_565: 822e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_555: 823e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_4444: 824e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_5551: 825e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_1555: 826e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_SHORT_565: 827e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_SHORT_4444: 828e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_SHORT_5551: 829e5c31af7Sopenharmony_ci return 2; 830e5c31af7Sopenharmony_ci 831e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT_101010: 832e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT_999_E5_REV: 833e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT_11F_11F_10F_REV: 834e5c31af7Sopenharmony_ci case TextureFormat::SNORM_INT_1010102_REV: 835e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT_1010102_REV: 836e5c31af7Sopenharmony_ci case TextureFormat::SIGNED_INT_1010102_REV: 837e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT_1010102_REV: 838e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT_24_8: 839e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT_24_8_REV: 840e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT_16_8_8: 841e5c31af7Sopenharmony_ci case TextureFormat::USCALED_INT_1010102_REV: 842e5c31af7Sopenharmony_ci case TextureFormat::SSCALED_INT_1010102_REV: 843e5c31af7Sopenharmony_ci return 4; 844e5c31af7Sopenharmony_ci 845e5c31af7Sopenharmony_ci case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV: 846e5c31af7Sopenharmony_ci return 8; 847e5c31af7Sopenharmony_ci 848e5c31af7Sopenharmony_ci default: 849e5c31af7Sopenharmony_ci return getNumUsedChannels(order) * getChannelSize(type); 850e5c31af7Sopenharmony_ci } 851e5c31af7Sopenharmony_ci} 852e5c31af7Sopenharmony_ci 853e5c31af7Sopenharmony_ciint TextureFormat::getPixelSize (void) const 854e5c31af7Sopenharmony_ci{ 855e5c31af7Sopenharmony_ci return ::tcu::getPixelSize(*this); 856e5c31af7Sopenharmony_ci} 857e5c31af7Sopenharmony_ci 858e5c31af7Sopenharmony_ciconst TextureSwizzle& getChannelReadSwizzle (TextureFormat::ChannelOrder order) 859e5c31af7Sopenharmony_ci{ 860e5c31af7Sopenharmony_ci // make sure to update these tables when channel orders are updated 861e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(TextureFormat::CHANNELORDER_LAST == 22); 862e5c31af7Sopenharmony_ci 863e5c31af7Sopenharmony_ci static const TextureSwizzle INV = {{ TextureSwizzle::CHANNEL_ZERO, TextureSwizzle::CHANNEL_ZERO, TextureSwizzle::CHANNEL_ZERO, TextureSwizzle::CHANNEL_ONE }}; 864e5c31af7Sopenharmony_ci static const TextureSwizzle R = {{ TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_ZERO, TextureSwizzle::CHANNEL_ZERO, TextureSwizzle::CHANNEL_ONE }}; 865e5c31af7Sopenharmony_ci static const TextureSwizzle A = {{ TextureSwizzle::CHANNEL_ZERO, TextureSwizzle::CHANNEL_ZERO, TextureSwizzle::CHANNEL_ZERO, TextureSwizzle::CHANNEL_0 }}; 866e5c31af7Sopenharmony_ci static const TextureSwizzle I = {{ TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_0 }}; 867e5c31af7Sopenharmony_ci static const TextureSwizzle L = {{ TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_ONE }}; 868e5c31af7Sopenharmony_ci static const TextureSwizzle LA = {{ TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_1 }}; 869e5c31af7Sopenharmony_ci static const TextureSwizzle RG = {{ TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_1, TextureSwizzle::CHANNEL_ZERO, TextureSwizzle::CHANNEL_ONE }}; 870e5c31af7Sopenharmony_ci static const TextureSwizzle RA = {{ TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_ZERO, TextureSwizzle::CHANNEL_ZERO, TextureSwizzle::CHANNEL_1 }}; 871e5c31af7Sopenharmony_ci static const TextureSwizzle RGB = {{ TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_1, TextureSwizzle::CHANNEL_2, TextureSwizzle::CHANNEL_ONE }}; 872e5c31af7Sopenharmony_ci static const TextureSwizzle RGBA = {{ TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_1, TextureSwizzle::CHANNEL_2, TextureSwizzle::CHANNEL_3 }}; 873e5c31af7Sopenharmony_ci static const TextureSwizzle BGR = {{ TextureSwizzle::CHANNEL_2, TextureSwizzle::CHANNEL_1, TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_ONE }}; 874e5c31af7Sopenharmony_ci static const TextureSwizzle BGRA = {{ TextureSwizzle::CHANNEL_2, TextureSwizzle::CHANNEL_1, TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3 }}; 875e5c31af7Sopenharmony_ci static const TextureSwizzle ARGB = {{ TextureSwizzle::CHANNEL_1, TextureSwizzle::CHANNEL_2, TextureSwizzle::CHANNEL_3, TextureSwizzle::CHANNEL_0 }}; 876e5c31af7Sopenharmony_ci static const TextureSwizzle ABGR = {{ TextureSwizzle::CHANNEL_3, TextureSwizzle::CHANNEL_2, TextureSwizzle::CHANNEL_1, TextureSwizzle::CHANNEL_0 }}; 877e5c31af7Sopenharmony_ci static const TextureSwizzle D = {{ TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_ZERO, TextureSwizzle::CHANNEL_ZERO, TextureSwizzle::CHANNEL_ONE }}; 878e5c31af7Sopenharmony_ci static const TextureSwizzle S = {{ TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_ZERO, TextureSwizzle::CHANNEL_ZERO, TextureSwizzle::CHANNEL_ONE }}; 879e5c31af7Sopenharmony_ci static const TextureSwizzle DS = {{ TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_1, TextureSwizzle::CHANNEL_ZERO, TextureSwizzle::CHANNEL_ONE }}; 880e5c31af7Sopenharmony_ci 881e5c31af7Sopenharmony_ci switch (order) 882e5c31af7Sopenharmony_ci { 883e5c31af7Sopenharmony_ci case TextureFormat::R: return R; 884e5c31af7Sopenharmony_ci case TextureFormat::A: return A; 885e5c31af7Sopenharmony_ci case TextureFormat::I: return I; 886e5c31af7Sopenharmony_ci case TextureFormat::L: return L; 887e5c31af7Sopenharmony_ci case TextureFormat::LA: return LA; 888e5c31af7Sopenharmony_ci case TextureFormat::RG: return RG; 889e5c31af7Sopenharmony_ci case TextureFormat::RA: return RA; 890e5c31af7Sopenharmony_ci case TextureFormat::RGB: return RGB; 891e5c31af7Sopenharmony_ci case TextureFormat::RGBA: return RGBA; 892e5c31af7Sopenharmony_ci case TextureFormat::ARGB: return ARGB; 893e5c31af7Sopenharmony_ci case TextureFormat::ABGR: return ABGR; 894e5c31af7Sopenharmony_ci case TextureFormat::BGR: return BGR; 895e5c31af7Sopenharmony_ci case TextureFormat::BGRA: return BGRA; 896e5c31af7Sopenharmony_ci case TextureFormat::sR: return R; 897e5c31af7Sopenharmony_ci case TextureFormat::sRG: return RG; 898e5c31af7Sopenharmony_ci case TextureFormat::sRGB: return RGB; 899e5c31af7Sopenharmony_ci case TextureFormat::sRGBA: return RGBA; 900e5c31af7Sopenharmony_ci case TextureFormat::sBGR: return BGR; 901e5c31af7Sopenharmony_ci case TextureFormat::sBGRA: return BGRA; 902e5c31af7Sopenharmony_ci case TextureFormat::D: return D; 903e5c31af7Sopenharmony_ci case TextureFormat::S: return S; 904e5c31af7Sopenharmony_ci case TextureFormat::DS: return DS; 905e5c31af7Sopenharmony_ci 906e5c31af7Sopenharmony_ci default: 907e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 908e5c31af7Sopenharmony_ci return INV; 909e5c31af7Sopenharmony_ci } 910e5c31af7Sopenharmony_ci} 911e5c31af7Sopenharmony_ci 912e5c31af7Sopenharmony_ciconst TextureSwizzle& getChannelWriteSwizzle (TextureFormat::ChannelOrder order) 913e5c31af7Sopenharmony_ci{ 914e5c31af7Sopenharmony_ci // make sure to update these tables when channel orders are updated 915e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(TextureFormat::CHANNELORDER_LAST == 22); 916e5c31af7Sopenharmony_ci 917e5c31af7Sopenharmony_ci static const TextureSwizzle INV = {{ TextureSwizzle::CHANNEL_LAST, TextureSwizzle::CHANNEL_LAST, TextureSwizzle::CHANNEL_LAST, TextureSwizzle::CHANNEL_LAST }}; 918e5c31af7Sopenharmony_ci static const TextureSwizzle R = {{ TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_LAST, TextureSwizzle::CHANNEL_LAST, TextureSwizzle::CHANNEL_LAST }}; 919e5c31af7Sopenharmony_ci static const TextureSwizzle A = {{ TextureSwizzle::CHANNEL_3, TextureSwizzle::CHANNEL_LAST, TextureSwizzle::CHANNEL_LAST, TextureSwizzle::CHANNEL_LAST }}; 920e5c31af7Sopenharmony_ci static const TextureSwizzle I = {{ TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_LAST, TextureSwizzle::CHANNEL_LAST, TextureSwizzle::CHANNEL_LAST }}; 921e5c31af7Sopenharmony_ci static const TextureSwizzle L = {{ TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_LAST, TextureSwizzle::CHANNEL_LAST, TextureSwizzle::CHANNEL_LAST }}; 922e5c31af7Sopenharmony_ci static const TextureSwizzle LA = {{ TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3, TextureSwizzle::CHANNEL_LAST, TextureSwizzle::CHANNEL_LAST }}; 923e5c31af7Sopenharmony_ci static const TextureSwizzle RG = {{ TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_1, TextureSwizzle::CHANNEL_LAST, TextureSwizzle::CHANNEL_LAST }}; 924e5c31af7Sopenharmony_ci static const TextureSwizzle RA = {{ TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3, TextureSwizzle::CHANNEL_LAST, TextureSwizzle::CHANNEL_LAST }}; 925e5c31af7Sopenharmony_ci static const TextureSwizzle RGB = {{ TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_1, TextureSwizzle::CHANNEL_2, TextureSwizzle::CHANNEL_LAST }}; 926e5c31af7Sopenharmony_ci static const TextureSwizzle RGBA = {{ TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_1, TextureSwizzle::CHANNEL_2, TextureSwizzle::CHANNEL_3 }}; 927e5c31af7Sopenharmony_ci static const TextureSwizzle BGR = {{ TextureSwizzle::CHANNEL_2, TextureSwizzle::CHANNEL_1, TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_LAST }}; 928e5c31af7Sopenharmony_ci static const TextureSwizzle BGRA = {{ TextureSwizzle::CHANNEL_2, TextureSwizzle::CHANNEL_1, TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3 }}; 929e5c31af7Sopenharmony_ci static const TextureSwizzle ARGB = {{ TextureSwizzle::CHANNEL_3, TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_1, TextureSwizzle::CHANNEL_2 }}; 930e5c31af7Sopenharmony_ci static const TextureSwizzle ABGR = {{ TextureSwizzle::CHANNEL_3, TextureSwizzle::CHANNEL_2, TextureSwizzle::CHANNEL_1, TextureSwizzle::CHANNEL_0 }}; 931e5c31af7Sopenharmony_ci static const TextureSwizzle D = {{ TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_LAST, TextureSwizzle::CHANNEL_LAST, TextureSwizzle::CHANNEL_LAST }}; 932e5c31af7Sopenharmony_ci static const TextureSwizzle S = {{ TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_LAST, TextureSwizzle::CHANNEL_LAST, TextureSwizzle::CHANNEL_LAST }}; 933e5c31af7Sopenharmony_ci 934e5c31af7Sopenharmony_ci switch (order) 935e5c31af7Sopenharmony_ci { 936e5c31af7Sopenharmony_ci case TextureFormat::R: return R; 937e5c31af7Sopenharmony_ci case TextureFormat::A: return A; 938e5c31af7Sopenharmony_ci case TextureFormat::I: return I; 939e5c31af7Sopenharmony_ci case TextureFormat::L: return L; 940e5c31af7Sopenharmony_ci case TextureFormat::LA: return LA; 941e5c31af7Sopenharmony_ci case TextureFormat::RG: return RG; 942e5c31af7Sopenharmony_ci case TextureFormat::RA: return RA; 943e5c31af7Sopenharmony_ci case TextureFormat::RGB: return RGB; 944e5c31af7Sopenharmony_ci case TextureFormat::RGBA: return RGBA; 945e5c31af7Sopenharmony_ci case TextureFormat::ARGB: return ARGB; 946e5c31af7Sopenharmony_ci case TextureFormat::ABGR: return ABGR; 947e5c31af7Sopenharmony_ci case TextureFormat::BGR: return BGR; 948e5c31af7Sopenharmony_ci case TextureFormat::BGRA: return BGRA; 949e5c31af7Sopenharmony_ci case TextureFormat::sR: return R; 950e5c31af7Sopenharmony_ci case TextureFormat::sRG: return RG; 951e5c31af7Sopenharmony_ci case TextureFormat::sRGB: return RGB; 952e5c31af7Sopenharmony_ci case TextureFormat::sRGBA: return RGBA; 953e5c31af7Sopenharmony_ci case TextureFormat::sBGR: return BGR; 954e5c31af7Sopenharmony_ci case TextureFormat::sBGRA: return BGRA; 955e5c31af7Sopenharmony_ci case TextureFormat::D: return D; 956e5c31af7Sopenharmony_ci case TextureFormat::S: return S; 957e5c31af7Sopenharmony_ci 958e5c31af7Sopenharmony_ci case TextureFormat::DS: 959e5c31af7Sopenharmony_ci DE_ASSERT(false); // combined formats cannot be written to 960e5c31af7Sopenharmony_ci return INV; 961e5c31af7Sopenharmony_ci 962e5c31af7Sopenharmony_ci default: 963e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 964e5c31af7Sopenharmony_ci return INV; 965e5c31af7Sopenharmony_ci } 966e5c31af7Sopenharmony_ci} 967e5c31af7Sopenharmony_ci 968e5c31af7Sopenharmony_ciIVec3 calculatePackedPitch (const TextureFormat& format, const IVec3& size) 969e5c31af7Sopenharmony_ci{ 970e5c31af7Sopenharmony_ci const int pixelSize = format.getPixelSize(); 971e5c31af7Sopenharmony_ci const int rowPitch = pixelSize * size.x(); 972e5c31af7Sopenharmony_ci const int slicePitch = rowPitch * size.y(); 973e5c31af7Sopenharmony_ci 974e5c31af7Sopenharmony_ci return IVec3(pixelSize, rowPitch, slicePitch); 975e5c31af7Sopenharmony_ci} 976e5c31af7Sopenharmony_ci 977e5c31af7Sopenharmony_ciConstPixelBufferAccess::ConstPixelBufferAccess (void) 978e5c31af7Sopenharmony_ci : m_size (0) 979e5c31af7Sopenharmony_ci , m_pitch (0) 980e5c31af7Sopenharmony_ci , m_divider (1,1,1) 981e5c31af7Sopenharmony_ci , m_data (DE_NULL) 982e5c31af7Sopenharmony_ci{ 983e5c31af7Sopenharmony_ci} 984e5c31af7Sopenharmony_ci 985e5c31af7Sopenharmony_ciConstPixelBufferAccess::ConstPixelBufferAccess (const TextureFormat& format, int width, int height, int depth, const void* data) 986e5c31af7Sopenharmony_ci : m_format (format) 987e5c31af7Sopenharmony_ci , m_size (width, height, depth) 988e5c31af7Sopenharmony_ci , m_pitch (calculatePackedPitch(m_format, m_size)) 989e5c31af7Sopenharmony_ci , m_divider (1,1,1) 990e5c31af7Sopenharmony_ci , m_data ((void*)data) 991e5c31af7Sopenharmony_ci{ 992e5c31af7Sopenharmony_ci DE_ASSERT(isValid(format)); 993e5c31af7Sopenharmony_ci} 994e5c31af7Sopenharmony_ci 995e5c31af7Sopenharmony_ciConstPixelBufferAccess::ConstPixelBufferAccess (const TextureFormat& format, const IVec3& size, const void* data) 996e5c31af7Sopenharmony_ci : m_format (format) 997e5c31af7Sopenharmony_ci , m_size (size) 998e5c31af7Sopenharmony_ci , m_pitch (calculatePackedPitch(m_format, m_size)) 999e5c31af7Sopenharmony_ci , m_divider (1,1,1) 1000e5c31af7Sopenharmony_ci , m_data ((void*)data) 1001e5c31af7Sopenharmony_ci{ 1002e5c31af7Sopenharmony_ci DE_ASSERT(isValid(format)); 1003e5c31af7Sopenharmony_ci} 1004e5c31af7Sopenharmony_ci 1005e5c31af7Sopenharmony_ciConstPixelBufferAccess::ConstPixelBufferAccess (const TextureFormat& format, int width, int height, int depth, int rowPitch, int slicePitch, const void* data) 1006e5c31af7Sopenharmony_ci : m_format (format) 1007e5c31af7Sopenharmony_ci , m_size (width, height, depth) 1008e5c31af7Sopenharmony_ci , m_pitch (format.getPixelSize(), rowPitch, slicePitch) 1009e5c31af7Sopenharmony_ci , m_divider (1,1,1) 1010e5c31af7Sopenharmony_ci , m_data ((void*)data) 1011e5c31af7Sopenharmony_ci{ 1012e5c31af7Sopenharmony_ci DE_ASSERT(isValid(format)); 1013e5c31af7Sopenharmony_ci} 1014e5c31af7Sopenharmony_ci 1015e5c31af7Sopenharmony_ciConstPixelBufferAccess::ConstPixelBufferAccess (const TextureFormat& format, const IVec3& size, const IVec3& pitch, const void* data) 1016e5c31af7Sopenharmony_ci : m_format (format) 1017e5c31af7Sopenharmony_ci , m_size (size) 1018e5c31af7Sopenharmony_ci , m_pitch (pitch) 1019e5c31af7Sopenharmony_ci , m_divider (1,1,1) 1020e5c31af7Sopenharmony_ci , m_data ((void*)data) 1021e5c31af7Sopenharmony_ci{ 1022e5c31af7Sopenharmony_ci DE_ASSERT(isValid(format)); 1023e5c31af7Sopenharmony_ci DE_ASSERT(m_format.getPixelSize() <= m_pitch.x()); 1024e5c31af7Sopenharmony_ci} 1025e5c31af7Sopenharmony_ci 1026e5c31af7Sopenharmony_ciConstPixelBufferAccess::ConstPixelBufferAccess(const TextureFormat& format, const IVec3& size, const IVec3& pitch, const IVec3& block, const void* data) 1027e5c31af7Sopenharmony_ci : m_format (format) 1028e5c31af7Sopenharmony_ci , m_size (size) 1029e5c31af7Sopenharmony_ci , m_pitch (pitch) 1030e5c31af7Sopenharmony_ci , m_divider (block) 1031e5c31af7Sopenharmony_ci , m_data ((void*)data) 1032e5c31af7Sopenharmony_ci{ 1033e5c31af7Sopenharmony_ci DE_ASSERT(isValid(format)); 1034e5c31af7Sopenharmony_ci DE_ASSERT(m_format.getPixelSize() <= m_pitch.x()); 1035e5c31af7Sopenharmony_ci} 1036e5c31af7Sopenharmony_ci 1037e5c31af7Sopenharmony_ciConstPixelBufferAccess::ConstPixelBufferAccess (const TextureLevel& level) 1038e5c31af7Sopenharmony_ci : m_format (level.getFormat()) 1039e5c31af7Sopenharmony_ci , m_size (level.getSize()) 1040e5c31af7Sopenharmony_ci , m_pitch (calculatePackedPitch(m_format, m_size)) 1041e5c31af7Sopenharmony_ci , m_divider (1,1,1) 1042e5c31af7Sopenharmony_ci , m_data ((void*)level.getPtr()) 1043e5c31af7Sopenharmony_ci{ 1044e5c31af7Sopenharmony_ci} 1045e5c31af7Sopenharmony_ci 1046e5c31af7Sopenharmony_ciPixelBufferAccess::PixelBufferAccess (const TextureFormat& format, int width, int height, int depth, void* data) 1047e5c31af7Sopenharmony_ci : ConstPixelBufferAccess(format, width, height, depth, data) 1048e5c31af7Sopenharmony_ci{ 1049e5c31af7Sopenharmony_ci} 1050e5c31af7Sopenharmony_ci 1051e5c31af7Sopenharmony_ciPixelBufferAccess::PixelBufferAccess (const TextureFormat& format, const IVec3& size, void* data) 1052e5c31af7Sopenharmony_ci : ConstPixelBufferAccess(format, size, data) 1053e5c31af7Sopenharmony_ci{ 1054e5c31af7Sopenharmony_ci} 1055e5c31af7Sopenharmony_ci 1056e5c31af7Sopenharmony_ciPixelBufferAccess::PixelBufferAccess (const TextureFormat& format, int width, int height, int depth, int rowPitch, int slicePitch, void* data) 1057e5c31af7Sopenharmony_ci : ConstPixelBufferAccess(format, width, height, depth, rowPitch, slicePitch, data) 1058e5c31af7Sopenharmony_ci{ 1059e5c31af7Sopenharmony_ci} 1060e5c31af7Sopenharmony_ci 1061e5c31af7Sopenharmony_ciPixelBufferAccess::PixelBufferAccess (const TextureFormat& format, const IVec3& size, const IVec3& pitch, void* data) 1062e5c31af7Sopenharmony_ci : ConstPixelBufferAccess(format, size, pitch, data) 1063e5c31af7Sopenharmony_ci{ 1064e5c31af7Sopenharmony_ci} 1065e5c31af7Sopenharmony_ci 1066e5c31af7Sopenharmony_ciPixelBufferAccess::PixelBufferAccess(const TextureFormat& format, const IVec3& size, const IVec3& pitch, const IVec3& block, void* data) 1067e5c31af7Sopenharmony_ci : ConstPixelBufferAccess(format, size, pitch, block, data) 1068e5c31af7Sopenharmony_ci{ 1069e5c31af7Sopenharmony_ci} 1070e5c31af7Sopenharmony_ci 1071e5c31af7Sopenharmony_ci 1072e5c31af7Sopenharmony_ciPixelBufferAccess::PixelBufferAccess (TextureLevel& level) 1073e5c31af7Sopenharmony_ci : ConstPixelBufferAccess(level) 1074e5c31af7Sopenharmony_ci{ 1075e5c31af7Sopenharmony_ci} 1076e5c31af7Sopenharmony_ci 1077e5c31af7Sopenharmony_ci//! Swizzle generally based on channel order. 1078e5c31af7Sopenharmony_citemplate<typename T> 1079e5c31af7Sopenharmony_ciVector<T, 4> swizzleGe (const Vector<T, 4>& v, TextureFormat::ChannelOrder src, TextureFormat::ChannelOrder dst) 1080e5c31af7Sopenharmony_ci{ 1081e5c31af7Sopenharmony_ci if (src == dst) 1082e5c31af7Sopenharmony_ci return v; 1083e5c31af7Sopenharmony_ci else 1084e5c31af7Sopenharmony_ci { 1085e5c31af7Sopenharmony_ci if ((src == TextureFormat::RGBA && dst == TextureFormat::ARGB) || 1086e5c31af7Sopenharmony_ci (src == TextureFormat::BGRA && dst == TextureFormat::ABGR)) 1087e5c31af7Sopenharmony_ci return v.swizzle(3, 0, 1, 2); 1088e5c31af7Sopenharmony_ci 1089e5c31af7Sopenharmony_ci if ((src == TextureFormat::ARGB && dst == TextureFormat::RGBA) || 1090e5c31af7Sopenharmony_ci (src == TextureFormat::ABGR && dst == TextureFormat::BGRA)) 1091e5c31af7Sopenharmony_ci return v.swizzle(1, 2, 3, 0); 1092e5c31af7Sopenharmony_ci 1093e5c31af7Sopenharmony_ci if ((src == TextureFormat::BGRA && dst == TextureFormat::ARGB) || 1094e5c31af7Sopenharmony_ci (src == TextureFormat::ABGR && dst == TextureFormat::RGBA) || 1095e5c31af7Sopenharmony_ci (src == TextureFormat::RGBA && dst == TextureFormat::ABGR) || 1096e5c31af7Sopenharmony_ci (src == TextureFormat::ARGB && dst == TextureFormat::BGRA)) 1097e5c31af7Sopenharmony_ci return v.swizzle(3, 2, 1, 0); 1098e5c31af7Sopenharmony_ci 1099e5c31af7Sopenharmony_ci if ((src == TextureFormat::RGB && dst == TextureFormat::BGR) || 1100e5c31af7Sopenharmony_ci (src == TextureFormat::BGR && dst == TextureFormat::RGB) || 1101e5c31af7Sopenharmony_ci (src == TextureFormat::RGBA && dst == TextureFormat::BGRA) || 1102e5c31af7Sopenharmony_ci (src == TextureFormat::BGRA && dst == TextureFormat::RGBA)) 1103e5c31af7Sopenharmony_ci return v.swizzle(2,1,0,3); 1104e5c31af7Sopenharmony_ci 1105e5c31af7Sopenharmony_ci DE_ASSERT(false); 1106e5c31af7Sopenharmony_ci return v; 1107e5c31af7Sopenharmony_ci } 1108e5c31af7Sopenharmony_ci} 1109e5c31af7Sopenharmony_ci 1110e5c31af7Sopenharmony_ciVec4 ConstPixelBufferAccess::getPixel (int x, int y, int z) const 1111e5c31af7Sopenharmony_ci{ 1112e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(x, 0, m_size.x())); 1113e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(y, 0, m_size.y())); 1114e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(z, 0, m_size.z())); 1115e5c31af7Sopenharmony_ci DE_ASSERT(!isCombinedDepthStencilType(m_format.type)); // combined types cannot be accessed directly 1116e5c31af7Sopenharmony_ci DE_ASSERT(m_format.order != TextureFormat::DS); // combined formats cannot be accessed directly 1117e5c31af7Sopenharmony_ci 1118e5c31af7Sopenharmony_ci const deUint8* pixelPtr = (const deUint8*)getPixelPtr(x, y, z); 1119e5c31af7Sopenharmony_ci 1120e5c31af7Sopenharmony_ci // Optimized fomats. 1121e5c31af7Sopenharmony_ci if (m_format.type == TextureFormat::UNORM_INT8) 1122e5c31af7Sopenharmony_ci { 1123e5c31af7Sopenharmony_ci if (m_format.order == TextureFormat::RGBA || m_format.order == TextureFormat::sRGBA) 1124e5c31af7Sopenharmony_ci return readRGBA8888Float(pixelPtr); 1125e5c31af7Sopenharmony_ci else if (m_format.order == TextureFormat::RGB || m_format.order == TextureFormat::sRGB) 1126e5c31af7Sopenharmony_ci return readRGB888Float(pixelPtr); 1127e5c31af7Sopenharmony_ci } 1128e5c31af7Sopenharmony_ci 1129e5c31af7Sopenharmony_ci#define UI8(OFFS, COUNT) ((*((const deUint8*)pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1)) 1130e5c31af7Sopenharmony_ci#define UI16(OFFS, COUNT) ((*((const deUint16*)pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1)) 1131e5c31af7Sopenharmony_ci#define UI32(OFFS, COUNT) ((*((const deUint32*)pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1)) 1132e5c31af7Sopenharmony_ci#define SI32(OFFS, COUNT) signExtend(UI32(OFFS, COUNT), (COUNT)) 1133e5c31af7Sopenharmony_ci#define UN8(OFFS, COUNT) channelToUnormFloat(UI8 (OFFS, COUNT), (COUNT)) 1134e5c31af7Sopenharmony_ci#define UN16(OFFS, COUNT) channelToUnormFloat(UI16(OFFS, COUNT), (COUNT)) 1135e5c31af7Sopenharmony_ci#define UN32(OFFS, COUNT) channelToUnormFloat(UI32(OFFS, COUNT), (COUNT)) 1136e5c31af7Sopenharmony_ci#define SN32(OFFS, COUNT) channelToSnormFloat(UI32(OFFS, COUNT), (COUNT)) 1137e5c31af7Sopenharmony_ci 1138e5c31af7Sopenharmony_ci // Packed formats. 1139e5c31af7Sopenharmony_ci switch (m_format.type) 1140e5c31af7Sopenharmony_ci { 1141e5c31af7Sopenharmony_ci case TextureFormat::UNORM_BYTE_44: return Vec4(UN8 (4, 4), UN8 ( 0, 4), 0.0f, 1.0f); 1142e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_BYTE_44: return UVec4(UI8 (4, 4), UI8 ( 0, 4), 0u, 1u).cast<float>(); 1143e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_565: return swizzleGe( Vec4(UN16(11, 5), UN16( 5, 6), UN16( 0, 5), 1.0f), m_format.order, TextureFormat::RGB); 1144e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_SHORT_565: return swizzleGe(UVec4(UI16(11, 5), UI16( 5, 6), UI16( 0, 5), 1u), m_format.order, TextureFormat::RGB).cast<float>(); 1145e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_555: return swizzleGe( Vec4(UN16(10, 5), UN16( 5, 5), UN16( 0, 5), 1.0f), m_format.order, TextureFormat::RGB); 1146e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_4444: return swizzleGe( Vec4(UN16(12, 4), UN16( 8, 4), UN16( 4, 4), UN16( 0, 4)), m_format.order, TextureFormat::RGBA); 1147e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_SHORT_4444: return swizzleGe(UVec4(UI16(12, 4), UI16( 8, 4), UI16( 4, 4), UI16( 0, 4)), m_format.order, TextureFormat::RGBA).cast<float>(); 1148e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_5551: return swizzleGe( Vec4(UN16(11, 5), UN16( 6, 5), UN16( 1, 5), UN16( 0, 1)), m_format.order, TextureFormat::RGBA); 1149e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_SHORT_5551: return swizzleGe(UVec4(UI16(11, 5), UI16( 6, 5), UI16( 1, 5), UI16( 0, 1)), m_format.order, TextureFormat::RGBA).cast<float>(); 1150e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_1555: return swizzleGe( Vec4(UN16(15, 1), UN16(10, 5), UN16( 5, 5), UN16( 0, 5)), m_format.order, TextureFormat::RGBA); 1151e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT_101010: return Vec4(UN32(22, 10), UN32(12, 10), UN32( 2, 10), 1.0f); 1152e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT_1010102_REV: return swizzleGe( Vec4(UN32( 0, 10), UN32(10, 10), UN32(20, 10), UN32(30, 2)), m_format.order, TextureFormat::RGBA); 1153e5c31af7Sopenharmony_ci case TextureFormat::SNORM_INT_1010102_REV: return swizzleGe( Vec4(SN32( 0, 10), SN32(10, 10), SN32(20, 10), SN32(30, 2)), m_format.order, TextureFormat::RGBA); 1154e5c31af7Sopenharmony_ci case TextureFormat::USCALED_INT_1010102_REV: 1155e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT_1010102_REV: return swizzleGe( UVec4(UI32(0, 10), UI32(10, 10), UI32(20, 10), UI32(30, 2)), m_format.order, TextureFormat::RGBA).cast<float>(); 1156e5c31af7Sopenharmony_ci case TextureFormat::SSCALED_INT_1010102_REV: 1157e5c31af7Sopenharmony_ci case TextureFormat::SIGNED_INT_1010102_REV: return swizzleGe( UVec4(SI32(0, 10), SI32(10, 10), SI32(20, 10), SI32(30, 2)), m_format.order, TextureFormat::RGBA).cast<float>(); 1158e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT_999_E5_REV: return unpackRGB999E5(*((const deUint32*)pixelPtr)); 1159e5c31af7Sopenharmony_ci 1160e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT_11F_11F_10F_REV: 1161e5c31af7Sopenharmony_ci return Vec4(Float11(UI32(0, 11)).asFloat(), Float11(UI32(11, 11)).asFloat(), Float10(UI32(22, 10)).asFloat(), 1.0f); 1162e5c31af7Sopenharmony_ci 1163e5c31af7Sopenharmony_ci default: 1164e5c31af7Sopenharmony_ci break; 1165e5c31af7Sopenharmony_ci } 1166e5c31af7Sopenharmony_ci 1167e5c31af7Sopenharmony_ci#undef UN8 1168e5c31af7Sopenharmony_ci#undef UN16 1169e5c31af7Sopenharmony_ci#undef UN32 1170e5c31af7Sopenharmony_ci#undef SN32 1171e5c31af7Sopenharmony_ci#undef SI32 1172e5c31af7Sopenharmony_ci#undef UI8 1173e5c31af7Sopenharmony_ci#undef UI16 1174e5c31af7Sopenharmony_ci#undef UI32 1175e5c31af7Sopenharmony_ci 1176e5c31af7Sopenharmony_ci // Generic path. 1177e5c31af7Sopenharmony_ci Vec4 result; 1178e5c31af7Sopenharmony_ci const TextureSwizzle::Channel* channelMap = getChannelReadSwizzle(m_format.order).components; 1179e5c31af7Sopenharmony_ci int channelSize = getChannelSize(m_format.type); 1180e5c31af7Sopenharmony_ci 1181e5c31af7Sopenharmony_ci for (int c = 0; c < 4; c++) 1182e5c31af7Sopenharmony_ci { 1183e5c31af7Sopenharmony_ci switch (channelMap[c]) 1184e5c31af7Sopenharmony_ci { 1185e5c31af7Sopenharmony_ci case TextureSwizzle::CHANNEL_0: 1186e5c31af7Sopenharmony_ci case TextureSwizzle::CHANNEL_1: 1187e5c31af7Sopenharmony_ci case TextureSwizzle::CHANNEL_2: 1188e5c31af7Sopenharmony_ci case TextureSwizzle::CHANNEL_3: 1189e5c31af7Sopenharmony_ci result[c] = channelToFloat(pixelPtr + channelSize*((int)channelMap[c]), m_format.type); 1190e5c31af7Sopenharmony_ci break; 1191e5c31af7Sopenharmony_ci 1192e5c31af7Sopenharmony_ci case TextureSwizzle::CHANNEL_ZERO: 1193e5c31af7Sopenharmony_ci result[c] = 0.0f; 1194e5c31af7Sopenharmony_ci break; 1195e5c31af7Sopenharmony_ci 1196e5c31af7Sopenharmony_ci case TextureSwizzle::CHANNEL_ONE: 1197e5c31af7Sopenharmony_ci result[c] = 1.0f; 1198e5c31af7Sopenharmony_ci break; 1199e5c31af7Sopenharmony_ci 1200e5c31af7Sopenharmony_ci default: 1201e5c31af7Sopenharmony_ci DE_ASSERT(false); 1202e5c31af7Sopenharmony_ci } 1203e5c31af7Sopenharmony_ci } 1204e5c31af7Sopenharmony_ci 1205e5c31af7Sopenharmony_ci return result; 1206e5c31af7Sopenharmony_ci} 1207e5c31af7Sopenharmony_ci 1208e5c31af7Sopenharmony_citemplate <typename T> 1209e5c31af7Sopenharmony_cistatic tcu::Vector<T, 4> getPixelIntGeneric (const deUint8* pixelPtr, const tcu::TextureFormat& format) 1210e5c31af7Sopenharmony_ci{ 1211e5c31af7Sopenharmony_ci tcu::Vector<T, 4> result; 1212e5c31af7Sopenharmony_ci 1213e5c31af7Sopenharmony_ci // Generic path. 1214e5c31af7Sopenharmony_ci const TextureSwizzle::Channel* channelMap = getChannelReadSwizzle(format.order).components; 1215e5c31af7Sopenharmony_ci int channelSize = getChannelSize(format.type); 1216e5c31af7Sopenharmony_ci 1217e5c31af7Sopenharmony_ci for (int c = 0; c < 4; c++) 1218e5c31af7Sopenharmony_ci { 1219e5c31af7Sopenharmony_ci switch (channelMap[c]) 1220e5c31af7Sopenharmony_ci { 1221e5c31af7Sopenharmony_ci case TextureSwizzle::CHANNEL_0: 1222e5c31af7Sopenharmony_ci case TextureSwizzle::CHANNEL_1: 1223e5c31af7Sopenharmony_ci case TextureSwizzle::CHANNEL_2: 1224e5c31af7Sopenharmony_ci case TextureSwizzle::CHANNEL_3: 1225e5c31af7Sopenharmony_ci result[c] = channelToIntType<T>(pixelPtr + channelSize*((int)channelMap[c]), format.type); 1226e5c31af7Sopenharmony_ci break; 1227e5c31af7Sopenharmony_ci 1228e5c31af7Sopenharmony_ci case TextureSwizzle::CHANNEL_ZERO: 1229e5c31af7Sopenharmony_ci result[c] = 0; 1230e5c31af7Sopenharmony_ci break; 1231e5c31af7Sopenharmony_ci 1232e5c31af7Sopenharmony_ci case TextureSwizzle::CHANNEL_ONE: 1233e5c31af7Sopenharmony_ci result[c] = 1; 1234e5c31af7Sopenharmony_ci break; 1235e5c31af7Sopenharmony_ci 1236e5c31af7Sopenharmony_ci default: 1237e5c31af7Sopenharmony_ci DE_ASSERT(false); 1238e5c31af7Sopenharmony_ci } 1239e5c31af7Sopenharmony_ci } 1240e5c31af7Sopenharmony_ci 1241e5c31af7Sopenharmony_ci return result; 1242e5c31af7Sopenharmony_ci} 1243e5c31af7Sopenharmony_ci 1244e5c31af7Sopenharmony_cistatic U64Vec4 getPixelAsBitsUint64 (const deUint8* pixelPtr, const tcu::TextureFormat& format) 1245e5c31af7Sopenharmony_ci{ 1246e5c31af7Sopenharmony_ci U64Vec4 result; 1247e5c31af7Sopenharmony_ci 1248e5c31af7Sopenharmony_ci // Generic path. 1249e5c31af7Sopenharmony_ci const TextureSwizzle::Channel* channelMap = getChannelReadSwizzle(format.order).components; 1250e5c31af7Sopenharmony_ci int channelSize = getChannelSize(format.type); 1251e5c31af7Sopenharmony_ci 1252e5c31af7Sopenharmony_ci for (int c = 0; c < 4; c++) 1253e5c31af7Sopenharmony_ci { 1254e5c31af7Sopenharmony_ci switch (channelMap[c]) 1255e5c31af7Sopenharmony_ci { 1256e5c31af7Sopenharmony_ci case TextureSwizzle::CHANNEL_0: 1257e5c31af7Sopenharmony_ci case TextureSwizzle::CHANNEL_1: 1258e5c31af7Sopenharmony_ci case TextureSwizzle::CHANNEL_2: 1259e5c31af7Sopenharmony_ci case TextureSwizzle::CHANNEL_3: 1260e5c31af7Sopenharmony_ci result[c] = retrieveChannelBitsAsUint64(pixelPtr + channelSize*((int)channelMap[c]), format.type); 1261e5c31af7Sopenharmony_ci break; 1262e5c31af7Sopenharmony_ci 1263e5c31af7Sopenharmony_ci case TextureSwizzle::CHANNEL_ZERO: 1264e5c31af7Sopenharmony_ci result[c] = 0; 1265e5c31af7Sopenharmony_ci break; 1266e5c31af7Sopenharmony_ci 1267e5c31af7Sopenharmony_ci case TextureSwizzle::CHANNEL_ONE: 1268e5c31af7Sopenharmony_ci result[c] = 1; 1269e5c31af7Sopenharmony_ci break; 1270e5c31af7Sopenharmony_ci 1271e5c31af7Sopenharmony_ci default: 1272e5c31af7Sopenharmony_ci DE_ASSERT(false); 1273e5c31af7Sopenharmony_ci } 1274e5c31af7Sopenharmony_ci } 1275e5c31af7Sopenharmony_ci 1276e5c31af7Sopenharmony_ci return result; 1277e5c31af7Sopenharmony_ci} 1278e5c31af7Sopenharmony_ci 1279e5c31af7Sopenharmony_ciIVec4 ConstPixelBufferAccess::getPixelInt (int x, int y, int z) const 1280e5c31af7Sopenharmony_ci{ 1281e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(x, 0, m_size.x())); 1282e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(y, 0, m_size.y())); 1283e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(z, 0, m_size.z())); 1284e5c31af7Sopenharmony_ci DE_ASSERT(!isCombinedDepthStencilType(m_format.type)); // combined types cannot be accessed directly 1285e5c31af7Sopenharmony_ci DE_ASSERT(m_format.order != TextureFormat::DS); // combined formats cannot be accessed directly 1286e5c31af7Sopenharmony_ci 1287e5c31af7Sopenharmony_ci const deUint8* const pixelPtr = (const deUint8*)getPixelPtr(x, y, z); 1288e5c31af7Sopenharmony_ci 1289e5c31af7Sopenharmony_ci // Optimized fomats. 1290e5c31af7Sopenharmony_ci if (m_format.type == TextureFormat::UNORM_INT8) 1291e5c31af7Sopenharmony_ci { 1292e5c31af7Sopenharmony_ci if (m_format.order == TextureFormat::RGBA || m_format.order == TextureFormat::sRGBA) 1293e5c31af7Sopenharmony_ci return readRGBA8888Int(pixelPtr); 1294e5c31af7Sopenharmony_ci else if (m_format.order == TextureFormat::RGB || m_format.order == TextureFormat::sRGB) 1295e5c31af7Sopenharmony_ci return readRGB888Int(pixelPtr); 1296e5c31af7Sopenharmony_ci } 1297e5c31af7Sopenharmony_ci 1298e5c31af7Sopenharmony_ci#define U8(OFFS, COUNT) ((*((const deUint8* )pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1)) 1299e5c31af7Sopenharmony_ci#define U16(OFFS, COUNT) ((*((const deUint16*)pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1)) 1300e5c31af7Sopenharmony_ci#define U32(OFFS, COUNT) ((*((const deUint32*)pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1)) 1301e5c31af7Sopenharmony_ci#define S32(OFFS, COUNT) signExtend(U32(OFFS, COUNT), (COUNT)) 1302e5c31af7Sopenharmony_ci 1303e5c31af7Sopenharmony_ci switch (m_format.type) 1304e5c31af7Sopenharmony_ci { 1305e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_BYTE_44: // Fall-through 1306e5c31af7Sopenharmony_ci case TextureFormat::UNORM_BYTE_44: return UVec4(U8 ( 4, 4), U8 ( 0, 4), 0u, 1u).cast<int>(); 1307e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_SHORT_565: // Fall-through 1308e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_565: return swizzleGe(UVec4(U16(11, 5), U16( 5, 6), U16( 0, 5), 1).cast<int>(), m_format.order, TextureFormat::RGB); 1309e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_555: return swizzleGe(UVec4(U16(10, 5), U16( 5, 5), U16( 0, 5), 1).cast<int>(), m_format.order, TextureFormat::RGB); 1310e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_SHORT_4444: // Fall-through 1311e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_4444: return swizzleGe(UVec4(U16(12, 4), U16( 8, 4), U16( 4, 4), U16( 0, 4)).cast<int>(), m_format.order, TextureFormat::RGBA); 1312e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_SHORT_5551: // Fall-through 1313e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_5551: return swizzleGe(UVec4(U16(11, 5), U16( 6, 5), U16( 1, 5), U16( 0, 1)).cast<int>(), m_format.order, TextureFormat::RGBA); 1314e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_1555: return swizzleGe(UVec4(U16(15, 1), U16(10, 5), U16( 5, 5), U16( 0, 5)).cast<int>(), m_format.order, TextureFormat::RGBA); 1315e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT_101010: return UVec4(U32(22, 10), U32(12, 10), U32( 2, 10), 1).cast<int>(); 1316e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT_1010102_REV: // Fall-through 1317e5c31af7Sopenharmony_ci case TextureFormat::USCALED_INT_1010102_REV: // Fall-through 1318e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT_1010102_REV: return swizzleGe(UVec4(U32( 0, 10), U32(10, 10), U32(20, 10), U32(30, 2)), m_format.order, TextureFormat::RGBA).cast<int>(); 1319e5c31af7Sopenharmony_ci case TextureFormat::SNORM_INT_1010102_REV: // Fall-through 1320e5c31af7Sopenharmony_ci case TextureFormat::SSCALED_INT_1010102_REV: // Fall-through 1321e5c31af7Sopenharmony_ci case TextureFormat::SIGNED_INT_1010102_REV: return swizzleGe(IVec4(S32( 0, 10), S32(10, 10), S32(20, 10), S32(30, 2)), m_format.order, TextureFormat::RGBA); 1322e5c31af7Sopenharmony_ci 1323e5c31af7Sopenharmony_ci default: 1324e5c31af7Sopenharmony_ci break; // To generic path. 1325e5c31af7Sopenharmony_ci } 1326e5c31af7Sopenharmony_ci 1327e5c31af7Sopenharmony_ci#undef U8 1328e5c31af7Sopenharmony_ci#undef U16 1329e5c31af7Sopenharmony_ci#undef U32 1330e5c31af7Sopenharmony_ci#undef S32 1331e5c31af7Sopenharmony_ci 1332e5c31af7Sopenharmony_ci // Generic path. 1333e5c31af7Sopenharmony_ci return getPixelIntGeneric<int>(pixelPtr, m_format); 1334e5c31af7Sopenharmony_ci} 1335e5c31af7Sopenharmony_ci 1336e5c31af7Sopenharmony_ciI64Vec4 ConstPixelBufferAccess::getPixelInt64 (int x, int y, int z) const 1337e5c31af7Sopenharmony_ci{ 1338e5c31af7Sopenharmony_ci // Rely on getPixelInt() for some formats. 1339e5c31af7Sopenharmony_ci if (m_format.type == TextureFormat::UNORM_INT8 && 1340e5c31af7Sopenharmony_ci (m_format.order == TextureFormat::RGBA || m_format.order == TextureFormat::sRGBA || 1341e5c31af7Sopenharmony_ci m_format.order == TextureFormat::RGB || m_format.order == TextureFormat::sRGB)) 1342e5c31af7Sopenharmony_ci { 1343e5c31af7Sopenharmony_ci return getPixelInt(x, y, z).cast<deInt64>(); 1344e5c31af7Sopenharmony_ci } 1345e5c31af7Sopenharmony_ci 1346e5c31af7Sopenharmony_ci switch (m_format.type) 1347e5c31af7Sopenharmony_ci { 1348e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_BYTE_44: 1349e5c31af7Sopenharmony_ci case TextureFormat::UNORM_BYTE_44: 1350e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_SHORT_565: 1351e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_565: 1352e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_555: 1353e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_SHORT_4444: 1354e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_4444: 1355e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_SHORT_5551: 1356e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_5551: 1357e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT_101010: 1358e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT_1010102_REV: 1359e5c31af7Sopenharmony_ci case TextureFormat::USCALED_INT_1010102_REV: 1360e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT_1010102_REV: 1361e5c31af7Sopenharmony_ci case TextureFormat::SNORM_INT_1010102_REV: 1362e5c31af7Sopenharmony_ci case TextureFormat::SSCALED_INT_1010102_REV: 1363e5c31af7Sopenharmony_ci case TextureFormat::SIGNED_INT_1010102_REV: 1364e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_1555: 1365e5c31af7Sopenharmony_ci return getPixelInt(x, y, z).cast<deInt64>(); 1366e5c31af7Sopenharmony_ci 1367e5c31af7Sopenharmony_ci default: 1368e5c31af7Sopenharmony_ci break; // To generic path. 1369e5c31af7Sopenharmony_ci } 1370e5c31af7Sopenharmony_ci 1371e5c31af7Sopenharmony_ci // Generic path. 1372e5c31af7Sopenharmony_ci auto pixelPtr = reinterpret_cast<const deUint8*>(getPixelPtr(x, y, z)); 1373e5c31af7Sopenharmony_ci return getPixelIntGeneric<deInt64>(pixelPtr, m_format); 1374e5c31af7Sopenharmony_ci} 1375e5c31af7Sopenharmony_ci 1376e5c31af7Sopenharmony_ciU64Vec4 ConstPixelBufferAccess::getPixelBitsAsUint64 (int x, int y, int z) const 1377e5c31af7Sopenharmony_ci{ 1378e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(x, 0, m_size.x())); 1379e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(y, 0, m_size.y())); 1380e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(z, 0, m_size.z())); 1381e5c31af7Sopenharmony_ci DE_ASSERT(!isCombinedDepthStencilType(m_format.type)); // combined types cannot be accessed directly 1382e5c31af7Sopenharmony_ci DE_ASSERT(m_format.order != TextureFormat::DS); // combined formats cannot be accessed directly 1383e5c31af7Sopenharmony_ci 1384e5c31af7Sopenharmony_ci const deUint8* const pixelPtr = (const deUint8*)getPixelPtr(x, y, z); 1385e5c31af7Sopenharmony_ci 1386e5c31af7Sopenharmony_ci if (m_format.type == TextureFormat::UNORM_INT8) 1387e5c31af7Sopenharmony_ci { 1388e5c31af7Sopenharmony_ci if (m_format.order == TextureFormat::RGBA || m_format.order == TextureFormat::sRGBA) 1389e5c31af7Sopenharmony_ci return U64Vec4(pixelPtr[0], pixelPtr[1], pixelPtr[2], pixelPtr[3]); 1390e5c31af7Sopenharmony_ci else if (m_format.order == TextureFormat::RGB || m_format.order == TextureFormat::sRGB) 1391e5c31af7Sopenharmony_ci return U64Vec4(pixelPtr[0], pixelPtr[1], pixelPtr[2], 1); 1392e5c31af7Sopenharmony_ci } 1393e5c31af7Sopenharmony_ci 1394e5c31af7Sopenharmony_ci#define U8(OFFS, COUNT) ((*((const deUint8* )pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1)) 1395e5c31af7Sopenharmony_ci#define U16(OFFS, COUNT) ((*((const deUint16*)pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1)) 1396e5c31af7Sopenharmony_ci#define U32(OFFS, COUNT) ((*((const deUint32*)pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1)) 1397e5c31af7Sopenharmony_ci 1398e5c31af7Sopenharmony_ci switch (m_format.type) 1399e5c31af7Sopenharmony_ci { 1400e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_BYTE_44: // Fall-through 1401e5c31af7Sopenharmony_ci case TextureFormat::UNORM_BYTE_44: return U64Vec4(U8 ( 4, 4), U8 ( 0, 4), 0u, 1u); 1402e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_SHORT_565: // Fall-through 1403e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_565: return swizzleGe(U64Vec4(U16(11, 5), U16( 5, 6), U16( 0, 5), 1), m_format.order, TextureFormat::RGB); 1404e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_555: return swizzleGe(U64Vec4(U16(10, 5), U16( 5, 5), U16( 0, 5), 1), m_format.order, TextureFormat::RGB); 1405e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_SHORT_4444: // Fall-through 1406e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_4444: return swizzleGe(U64Vec4(U16(12, 4), U16( 8, 4), U16( 4, 4), U16( 0, 4)), m_format.order, TextureFormat::RGBA); 1407e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_SHORT_5551: // Fall-through 1408e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_5551: return swizzleGe(U64Vec4(U16(11, 5), U16( 6, 5), U16( 1, 5), U16( 0, 1)), m_format.order, TextureFormat::RGBA); 1409e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT_101010: return U64Vec4(U32(22, 10), U32(12, 10), U32( 2, 10), 1); 1410e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT_1010102_REV: // Fall-through 1411e5c31af7Sopenharmony_ci case TextureFormat::USCALED_INT_1010102_REV: // Fall-through 1412e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT_1010102_REV: return swizzleGe(U64Vec4(U32( 0, 10), U32(10, 10), U32(20, 10), U32(30, 2)), m_format.order, TextureFormat::RGBA); 1413e5c31af7Sopenharmony_ci case TextureFormat::SNORM_INT_1010102_REV: // Fall-through 1414e5c31af7Sopenharmony_ci case TextureFormat::SSCALED_INT_1010102_REV: // Fall-through 1415e5c31af7Sopenharmony_ci case TextureFormat::SIGNED_INT_1010102_REV: return swizzleGe(U64Vec4(U32( 0, 10), U32(10, 10), U32(20, 10), U32(30, 2)), m_format.order, TextureFormat::RGBA); 1416e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_1555: return swizzleGe(U64Vec4(U16(15, 1), U16(10, 5), U16( 5, 5), U16( 0, 5)), m_format.order, TextureFormat::RGBA); 1417e5c31af7Sopenharmony_ci 1418e5c31af7Sopenharmony_ci 1419e5c31af7Sopenharmony_ci default: 1420e5c31af7Sopenharmony_ci break; // To generic path. 1421e5c31af7Sopenharmony_ci } 1422e5c31af7Sopenharmony_ci 1423e5c31af7Sopenharmony_ci#undef U8 1424e5c31af7Sopenharmony_ci#undef U16 1425e5c31af7Sopenharmony_ci#undef U32 1426e5c31af7Sopenharmony_ci 1427e5c31af7Sopenharmony_ci // Generic path. 1428e5c31af7Sopenharmony_ci return getPixelAsBitsUint64(pixelPtr, m_format); 1429e5c31af7Sopenharmony_ci} 1430e5c31af7Sopenharmony_ci 1431e5c31af7Sopenharmony_citemplate<> 1432e5c31af7Sopenharmony_ciVec4 ConstPixelBufferAccess::getPixelT (int x, int y, int z) const 1433e5c31af7Sopenharmony_ci{ 1434e5c31af7Sopenharmony_ci return getPixel(x, y, z); 1435e5c31af7Sopenharmony_ci} 1436e5c31af7Sopenharmony_ci 1437e5c31af7Sopenharmony_citemplate<> 1438e5c31af7Sopenharmony_ciIVec4 ConstPixelBufferAccess::getPixelT (int x, int y, int z) const 1439e5c31af7Sopenharmony_ci{ 1440e5c31af7Sopenharmony_ci return getPixelInt(x, y, z); 1441e5c31af7Sopenharmony_ci} 1442e5c31af7Sopenharmony_ci 1443e5c31af7Sopenharmony_citemplate<> 1444e5c31af7Sopenharmony_ciUVec4 ConstPixelBufferAccess::getPixelT (int x, int y, int z) const 1445e5c31af7Sopenharmony_ci{ 1446e5c31af7Sopenharmony_ci return getPixelUint(x, y, z); 1447e5c31af7Sopenharmony_ci} 1448e5c31af7Sopenharmony_ci 1449e5c31af7Sopenharmony_citemplate<> 1450e5c31af7Sopenharmony_ciI64Vec4 ConstPixelBufferAccess::getPixelT (int x, int y, int z) const 1451e5c31af7Sopenharmony_ci{ 1452e5c31af7Sopenharmony_ci return getPixelInt64(x, y, z); 1453e5c31af7Sopenharmony_ci} 1454e5c31af7Sopenharmony_ci 1455e5c31af7Sopenharmony_citemplate<> 1456e5c31af7Sopenharmony_ciU64Vec4 ConstPixelBufferAccess::getPixelT (int x, int y, int z) const 1457e5c31af7Sopenharmony_ci{ 1458e5c31af7Sopenharmony_ci return getPixelUint64(x, y, z); 1459e5c31af7Sopenharmony_ci} 1460e5c31af7Sopenharmony_ci 1461e5c31af7Sopenharmony_cifloat ConstPixelBufferAccess::getPixDepth (int x, int y, int z) const 1462e5c31af7Sopenharmony_ci{ 1463e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(x, 0, getWidth())); 1464e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(y, 0, getHeight())); 1465e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(z, 0, getDepth())); 1466e5c31af7Sopenharmony_ci 1467e5c31af7Sopenharmony_ci const deUint8* const pixelPtr = (const deUint8*)getPixelPtr(x, y, z); 1468e5c31af7Sopenharmony_ci 1469e5c31af7Sopenharmony_ci switch (m_format.type) 1470e5c31af7Sopenharmony_ci { 1471e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT_16_8_8: 1472e5c31af7Sopenharmony_ci DE_ASSERT(m_format.order == TextureFormat::DS); 1473e5c31af7Sopenharmony_ci return (float)readUint32High16(pixelPtr) / 65535.0f; 1474e5c31af7Sopenharmony_ci 1475e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT_24_8: 1476e5c31af7Sopenharmony_ci DE_ASSERT(m_format.order == TextureFormat::D || m_format.order == TextureFormat::DS); 1477e5c31af7Sopenharmony_ci return (float)readUint32High24(pixelPtr) / 16777215.0f; 1478e5c31af7Sopenharmony_ci 1479e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT_24_8_REV: 1480e5c31af7Sopenharmony_ci DE_ASSERT(m_format.order == TextureFormat::D || m_format.order == TextureFormat::DS); 1481e5c31af7Sopenharmony_ci return (float)readUint32Low24(pixelPtr) / 16777215.0f; 1482e5c31af7Sopenharmony_ci 1483e5c31af7Sopenharmony_ci case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV: 1484e5c31af7Sopenharmony_ci DE_ASSERT(m_format.order == TextureFormat::DS); 1485e5c31af7Sopenharmony_ci return *((const float*)pixelPtr); 1486e5c31af7Sopenharmony_ci 1487e5c31af7Sopenharmony_ci default: 1488e5c31af7Sopenharmony_ci DE_ASSERT(m_format.order == TextureFormat::D); // no other combined depth stencil types 1489e5c31af7Sopenharmony_ci return channelToFloat(pixelPtr, m_format.type); 1490e5c31af7Sopenharmony_ci } 1491e5c31af7Sopenharmony_ci} 1492e5c31af7Sopenharmony_ci 1493e5c31af7Sopenharmony_ciint ConstPixelBufferAccess::getPixStencil (int x, int y, int z) const 1494e5c31af7Sopenharmony_ci{ 1495e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(x, 0, getWidth())); 1496e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(y, 0, getHeight())); 1497e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(z, 0, getDepth())); 1498e5c31af7Sopenharmony_ci 1499e5c31af7Sopenharmony_ci const deUint8* const pixelPtr = (const deUint8*)getPixelPtr(x, y, z); 1500e5c31af7Sopenharmony_ci 1501e5c31af7Sopenharmony_ci switch (m_format.type) 1502e5c31af7Sopenharmony_ci { 1503e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT_24_8_REV: 1504e5c31af7Sopenharmony_ci DE_ASSERT(m_format.order == TextureFormat::DS); 1505e5c31af7Sopenharmony_ci return (int)readUint32High8(pixelPtr); 1506e5c31af7Sopenharmony_ci 1507e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT_16_8_8: 1508e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT_24_8: 1509e5c31af7Sopenharmony_ci DE_ASSERT(m_format.order == TextureFormat::DS); 1510e5c31af7Sopenharmony_ci return (int)readUint32Low8(pixelPtr); 1511e5c31af7Sopenharmony_ci 1512e5c31af7Sopenharmony_ci case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV: 1513e5c31af7Sopenharmony_ci DE_ASSERT(m_format.order == TextureFormat::DS); 1514e5c31af7Sopenharmony_ci return (int)readUint32Low8(pixelPtr + 4); 1515e5c31af7Sopenharmony_ci 1516e5c31af7Sopenharmony_ci default: 1517e5c31af7Sopenharmony_ci { 1518e5c31af7Sopenharmony_ci DE_ASSERT(m_format.order == TextureFormat::S); // no other combined depth stencil types 1519e5c31af7Sopenharmony_ci return channelToInt(pixelPtr, m_format.type); 1520e5c31af7Sopenharmony_ci } 1521e5c31af7Sopenharmony_ci } 1522e5c31af7Sopenharmony_ci} 1523e5c31af7Sopenharmony_ci 1524e5c31af7Sopenharmony_civoid PixelBufferAccess::setPixel (const Vec4& color, int x, int y, int z) const 1525e5c31af7Sopenharmony_ci{ 1526e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(x, 0, getWidth())); 1527e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(y, 0, getHeight())); 1528e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(z, 0, getDepth())); 1529e5c31af7Sopenharmony_ci DE_ASSERT(!isCombinedDepthStencilType(m_format.type)); // combined types cannot be accessed directly 1530e5c31af7Sopenharmony_ci DE_ASSERT(m_format.order != TextureFormat::DS); // combined formats cannot be accessed directly 1531e5c31af7Sopenharmony_ci 1532e5c31af7Sopenharmony_ci deUint8* const pixelPtr = (deUint8*)getPixelPtr(x, y, z); 1533e5c31af7Sopenharmony_ci 1534e5c31af7Sopenharmony_ci // Optimized fomats. 1535e5c31af7Sopenharmony_ci if (m_format.type == TextureFormat::UNORM_INT8) 1536e5c31af7Sopenharmony_ci { 1537e5c31af7Sopenharmony_ci if (m_format.order == TextureFormat::RGBA || m_format.order == TextureFormat::sRGBA) 1538e5c31af7Sopenharmony_ci { 1539e5c31af7Sopenharmony_ci writeRGBA8888Float(pixelPtr, color); 1540e5c31af7Sopenharmony_ci return; 1541e5c31af7Sopenharmony_ci } 1542e5c31af7Sopenharmony_ci else if (m_format.order == TextureFormat::RGB || m_format.order == TextureFormat::sRGB) 1543e5c31af7Sopenharmony_ci { 1544e5c31af7Sopenharmony_ci writeRGB888Float(pixelPtr, color); 1545e5c31af7Sopenharmony_ci return; 1546e5c31af7Sopenharmony_ci } 1547e5c31af7Sopenharmony_ci } 1548e5c31af7Sopenharmony_ci 1549e5c31af7Sopenharmony_ci#define PN(VAL, OFFS, BITS) (unormFloatToChannel((VAL), (BITS)) << (OFFS)) 1550e5c31af7Sopenharmony_ci#define PS(VAL, OFFS, BITS) (snormFloatToChannel((VAL), (BITS)) << (OFFS)) 1551e5c31af7Sopenharmony_ci#define PU(VAL, OFFS, BITS) (uintToChannel((VAL), (BITS)) << (OFFS)) 1552e5c31af7Sopenharmony_ci#define PI(VAL, OFFS, BITS) (intToChannel((VAL), (BITS)) << (OFFS)) 1553e5c31af7Sopenharmony_ci 1554e5c31af7Sopenharmony_ci switch (m_format.type) 1555e5c31af7Sopenharmony_ci { 1556e5c31af7Sopenharmony_ci case TextureFormat::UNORM_BYTE_44: *((deUint8 *)pixelPtr) = (deUint8)(PN(color[0], 4, 4) | PN(color[1], 0, 4)); break; 1557e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_BYTE_44: *((deUint8 *)pixelPtr) = (deUint8)(PU((deUint32)color[0], 4, 4) | PU((deUint32)color[1], 0, 4)); break; 1558e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT_101010: *((deUint32*)pixelPtr) = PN(color[0], 22, 10) | PN(color[1], 12, 10) | PN(color[2], 2, 10); break; 1559e5c31af7Sopenharmony_ci 1560e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_565: 1561e5c31af7Sopenharmony_ci { 1562e5c31af7Sopenharmony_ci const Vec4 swizzled = swizzleGe(color, TextureFormat::RGB, m_format.order); 1563e5c31af7Sopenharmony_ci *((deUint16*)pixelPtr) = (deUint16)(PN(swizzled[0], 11, 5) | PN(swizzled[1], 5, 6) | PN(swizzled[2], 0, 5)); 1564e5c31af7Sopenharmony_ci break; 1565e5c31af7Sopenharmony_ci } 1566e5c31af7Sopenharmony_ci 1567e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_SHORT_565: 1568e5c31af7Sopenharmony_ci { 1569e5c31af7Sopenharmony_ci const UVec4 swizzled = swizzleGe(color.cast<deUint32>(), TextureFormat::RGB, m_format.order); 1570e5c31af7Sopenharmony_ci *((deUint16*)pixelPtr) = (deUint16)(PU(swizzled[0], 11, 5) | PU(swizzled[1], 5, 6) | PU(swizzled[2], 0, 5)); 1571e5c31af7Sopenharmony_ci break; 1572e5c31af7Sopenharmony_ci } 1573e5c31af7Sopenharmony_ci 1574e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_555: 1575e5c31af7Sopenharmony_ci { 1576e5c31af7Sopenharmony_ci const Vec4 swizzled = swizzleGe(color, TextureFormat::RGB, m_format.order); 1577e5c31af7Sopenharmony_ci *((deUint16*)pixelPtr) = (deUint16)(PN(swizzled[0], 10, 5) | PN(swizzled[1], 5, 5) | PN(swizzled[2], 0, 5)); 1578e5c31af7Sopenharmony_ci break; 1579e5c31af7Sopenharmony_ci } 1580e5c31af7Sopenharmony_ci 1581e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_4444: 1582e5c31af7Sopenharmony_ci { 1583e5c31af7Sopenharmony_ci const Vec4 swizzled = swizzleGe(color, TextureFormat::RGBA, m_format.order); 1584e5c31af7Sopenharmony_ci *((deUint16*)pixelPtr) = (deUint16)(PN(swizzled[0], 12, 4) | PN(swizzled[1], 8, 4) | PN(swizzled[2], 4, 4) | PN(swizzled[3], 0, 4)); 1585e5c31af7Sopenharmony_ci break; 1586e5c31af7Sopenharmony_ci } 1587e5c31af7Sopenharmony_ci 1588e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_SHORT_4444: 1589e5c31af7Sopenharmony_ci { 1590e5c31af7Sopenharmony_ci const UVec4 swizzled = swizzleGe(color.cast<deUint32>(), TextureFormat::RGBA, m_format.order); 1591e5c31af7Sopenharmony_ci *((deUint16*)pixelPtr) = (deUint16)(PU(swizzled[0], 12, 4) | PU(swizzled[1], 8, 4) | PU(swizzled[2], 4, 4) | PU(swizzled[3], 0, 4)); 1592e5c31af7Sopenharmony_ci break; 1593e5c31af7Sopenharmony_ci } 1594e5c31af7Sopenharmony_ci 1595e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_5551: 1596e5c31af7Sopenharmony_ci { 1597e5c31af7Sopenharmony_ci const Vec4 swizzled = swizzleGe(color, TextureFormat::RGBA, m_format.order); 1598e5c31af7Sopenharmony_ci *((deUint16*)pixelPtr) = (deUint16)(PN(swizzled[0], 11, 5) | PN(swizzled[1], 6, 5) | PN(swizzled[2], 1, 5) | PN(swizzled[3], 0, 1)); 1599e5c31af7Sopenharmony_ci break; 1600e5c31af7Sopenharmony_ci } 1601e5c31af7Sopenharmony_ci 1602e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_1555: 1603e5c31af7Sopenharmony_ci { 1604e5c31af7Sopenharmony_ci const Vec4 swizzled = swizzleGe(color, TextureFormat::RGBA, m_format.order); 1605e5c31af7Sopenharmony_ci *((deUint16*)pixelPtr) = (deUint16)(PN(swizzled[0], 15, 1) | PN(swizzled[1], 10, 5) | PN(swizzled[2], 5, 5) | PN(swizzled[3], 0, 5)); 1606e5c31af7Sopenharmony_ci break; 1607e5c31af7Sopenharmony_ci } 1608e5c31af7Sopenharmony_ci 1609e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_SHORT_5551: 1610e5c31af7Sopenharmony_ci { 1611e5c31af7Sopenharmony_ci const UVec4 swizzled = swizzleGe(color.cast<deUint32>(), TextureFormat::RGBA, m_format.order); 1612e5c31af7Sopenharmony_ci *((deUint16*)pixelPtr) = (deUint16)(PU(swizzled[0], 11, 5) | PU(swizzled[1], 6, 5) | PU(swizzled[2], 1, 5) | PU(swizzled[3], 0, 1)); 1613e5c31af7Sopenharmony_ci break; 1614e5c31af7Sopenharmony_ci } 1615e5c31af7Sopenharmony_ci 1616e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT_1010102_REV: 1617e5c31af7Sopenharmony_ci { 1618e5c31af7Sopenharmony_ci const Vec4 u = swizzleGe(color, TextureFormat::RGBA, m_format.order); 1619e5c31af7Sopenharmony_ci *((deUint32*)pixelPtr) = PN(u[0], 0, 10) | PN(u[1], 10, 10) | PN(u[2], 20, 10) | PN(u[3], 30, 2); 1620e5c31af7Sopenharmony_ci break; 1621e5c31af7Sopenharmony_ci } 1622e5c31af7Sopenharmony_ci 1623e5c31af7Sopenharmony_ci case TextureFormat::SNORM_INT_1010102_REV: 1624e5c31af7Sopenharmony_ci { 1625e5c31af7Sopenharmony_ci const Vec4 u = swizzleGe(color, TextureFormat::RGBA, m_format.order); 1626e5c31af7Sopenharmony_ci *((deUint32*)pixelPtr) = PS(u[0], 0, 10) | PS(u[1], 10, 10) | PS(u[2], 20, 10) | PS(u[3], 30, 2); 1627e5c31af7Sopenharmony_ci break; 1628e5c31af7Sopenharmony_ci } 1629e5c31af7Sopenharmony_ci 1630e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT_1010102_REV: 1631e5c31af7Sopenharmony_ci case TextureFormat::USCALED_INT_1010102_REV: 1632e5c31af7Sopenharmony_ci { 1633e5c31af7Sopenharmony_ci const UVec4 u = swizzleGe(color.cast<deUint32>(), TextureFormat::RGBA, m_format.order); 1634e5c31af7Sopenharmony_ci *((deUint32*)pixelPtr) = PU(u[0], 0, 10) | PU(u[1], 10, 10) | PU(u[2], 20, 10) | PU(u[3], 30, 2); 1635e5c31af7Sopenharmony_ci break; 1636e5c31af7Sopenharmony_ci } 1637e5c31af7Sopenharmony_ci 1638e5c31af7Sopenharmony_ci case TextureFormat::SIGNED_INT_1010102_REV: 1639e5c31af7Sopenharmony_ci case TextureFormat::SSCALED_INT_1010102_REV: 1640e5c31af7Sopenharmony_ci { 1641e5c31af7Sopenharmony_ci const IVec4 u = swizzleGe(color.cast<deInt32>(), TextureFormat::RGBA, m_format.order); 1642e5c31af7Sopenharmony_ci *((deUint32*)pixelPtr) = PI(u[0], 0, 10) | PI(u[1], 10, 10) | PI(u[2], 20, 10) | PI(u[3], 30, 2); 1643e5c31af7Sopenharmony_ci break; 1644e5c31af7Sopenharmony_ci } 1645e5c31af7Sopenharmony_ci 1646e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT_11F_11F_10F_REV: 1647e5c31af7Sopenharmony_ci *((deUint32*)pixelPtr) = Float11(color[0]).bits() | (Float11(color[1]).bits() << 11) | (Float10(color[2]).bits() << 22); 1648e5c31af7Sopenharmony_ci break; 1649e5c31af7Sopenharmony_ci 1650e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT_999_E5_REV: 1651e5c31af7Sopenharmony_ci *((deUint32*)pixelPtr) = packRGB999E5(color); 1652e5c31af7Sopenharmony_ci break; 1653e5c31af7Sopenharmony_ci 1654e5c31af7Sopenharmony_ci default: 1655e5c31af7Sopenharmony_ci { 1656e5c31af7Sopenharmony_ci // Generic path. 1657e5c31af7Sopenharmony_ci int numChannels = getNumUsedChannels(m_format.order); 1658e5c31af7Sopenharmony_ci const TextureSwizzle::Channel* map = getChannelWriteSwizzle(m_format.order).components; 1659e5c31af7Sopenharmony_ci int channelSize = getChannelSize(m_format.type); 1660e5c31af7Sopenharmony_ci 1661e5c31af7Sopenharmony_ci for (int c = 0; c < numChannels; c++) 1662e5c31af7Sopenharmony_ci { 1663e5c31af7Sopenharmony_ci DE_ASSERT(deInRange32(map[c], TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3)); 1664e5c31af7Sopenharmony_ci floatToChannel(pixelPtr + channelSize*c, color[map[c]], m_format.type); 1665e5c31af7Sopenharmony_ci } 1666e5c31af7Sopenharmony_ci break; 1667e5c31af7Sopenharmony_ci } 1668e5c31af7Sopenharmony_ci } 1669e5c31af7Sopenharmony_ci 1670e5c31af7Sopenharmony_ci#undef PN 1671e5c31af7Sopenharmony_ci#undef PS 1672e5c31af7Sopenharmony_ci#undef PU 1673e5c31af7Sopenharmony_ci#undef PI 1674e5c31af7Sopenharmony_ci} 1675e5c31af7Sopenharmony_ci 1676e5c31af7Sopenharmony_civoid PixelBufferAccess::setPixel (const IVec4& color, int x, int y, int z) const 1677e5c31af7Sopenharmony_ci{ 1678e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(x, 0, getWidth())); 1679e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(y, 0, getHeight())); 1680e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(z, 0, getDepth())); 1681e5c31af7Sopenharmony_ci DE_ASSERT(!isCombinedDepthStencilType(m_format.type)); // combined types cannot be accessed directly 1682e5c31af7Sopenharmony_ci DE_ASSERT(m_format.order != TextureFormat::DS); // combined formats cannot be accessed directly 1683e5c31af7Sopenharmony_ci 1684e5c31af7Sopenharmony_ci deUint8* const pixelPtr = (deUint8*)getPixelPtr(x, y, z); 1685e5c31af7Sopenharmony_ci 1686e5c31af7Sopenharmony_ci // Optimized fomats. 1687e5c31af7Sopenharmony_ci if (m_format.type == TextureFormat::UNORM_INT8) 1688e5c31af7Sopenharmony_ci { 1689e5c31af7Sopenharmony_ci if (m_format.order == TextureFormat::RGBA || m_format.order == TextureFormat::sRGBA) 1690e5c31af7Sopenharmony_ci { 1691e5c31af7Sopenharmony_ci writeRGBA8888Int(pixelPtr, color); 1692e5c31af7Sopenharmony_ci return; 1693e5c31af7Sopenharmony_ci } 1694e5c31af7Sopenharmony_ci else if (m_format.order == TextureFormat::RGB || m_format.order == TextureFormat::sRGB) 1695e5c31af7Sopenharmony_ci { 1696e5c31af7Sopenharmony_ci writeRGB888Int(pixelPtr, color); 1697e5c31af7Sopenharmony_ci return; 1698e5c31af7Sopenharmony_ci } 1699e5c31af7Sopenharmony_ci } 1700e5c31af7Sopenharmony_ci 1701e5c31af7Sopenharmony_ci#define PU(VAL, OFFS, BITS) (uintToChannel((deUint32)(VAL), (BITS)) << (OFFS)) 1702e5c31af7Sopenharmony_ci#define PI(VAL, OFFS, BITS) (intToChannel((deUint32)(VAL), (BITS)) << (OFFS)) 1703e5c31af7Sopenharmony_ci 1704e5c31af7Sopenharmony_ci switch (m_format.type) 1705e5c31af7Sopenharmony_ci { 1706e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_BYTE_44: // Fall-through 1707e5c31af7Sopenharmony_ci case TextureFormat::UNORM_BYTE_44: *((deUint8 *)pixelPtr) = (deUint8 )(PU(color[0], 4, 4) | PU(color[1], 0, 4)); break; 1708e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT_101010: *((deUint32*)pixelPtr) = PU(color[0], 22, 10) | PU(color[1], 12, 10) | PU(color[2], 2, 10); break; 1709e5c31af7Sopenharmony_ci 1710e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_565: 1711e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_SHORT_565: 1712e5c31af7Sopenharmony_ci { 1713e5c31af7Sopenharmony_ci const IVec4 swizzled = swizzleGe(color, TextureFormat::RGB, m_format.order); 1714e5c31af7Sopenharmony_ci *((deUint16*)pixelPtr) = (deUint16)(PU(swizzled[0], 11, 5) | PU(swizzled[1], 5, 6) | PU(swizzled[2], 0, 5)); 1715e5c31af7Sopenharmony_ci break; 1716e5c31af7Sopenharmony_ci } 1717e5c31af7Sopenharmony_ci 1718e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_555: 1719e5c31af7Sopenharmony_ci { 1720e5c31af7Sopenharmony_ci const IVec4 swizzled = swizzleGe(color, TextureFormat::RGB, m_format.order); 1721e5c31af7Sopenharmony_ci *((deUint16*)pixelPtr) = (deUint16)(PU(swizzled[0], 10, 5) | PU(swizzled[1], 5, 5) | PU(swizzled[2], 0, 5)); 1722e5c31af7Sopenharmony_ci break; 1723e5c31af7Sopenharmony_ci } 1724e5c31af7Sopenharmony_ci 1725e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_4444: 1726e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_SHORT_4444: 1727e5c31af7Sopenharmony_ci { 1728e5c31af7Sopenharmony_ci const IVec4 swizzled = swizzleGe(color, TextureFormat::RGBA, m_format.order); 1729e5c31af7Sopenharmony_ci *((deUint16*)pixelPtr) = (deUint16)(PU(swizzled[0], 12, 4) | PU(swizzled[1], 8, 4) | PU(swizzled[2], 4, 4) | PU(swizzled[3], 0, 4)); 1730e5c31af7Sopenharmony_ci break; 1731e5c31af7Sopenharmony_ci } 1732e5c31af7Sopenharmony_ci 1733e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_5551: 1734e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_SHORT_5551: 1735e5c31af7Sopenharmony_ci { 1736e5c31af7Sopenharmony_ci const IVec4 swizzled = swizzleGe(color, TextureFormat::RGBA, m_format.order); 1737e5c31af7Sopenharmony_ci *((deUint16*)pixelPtr) = (deUint16)(PU(swizzled[0], 11, 5) | PU(swizzled[1], 6, 5) | PU(swizzled[2], 1, 5) | PU(swizzled[3], 0, 1)); 1738e5c31af7Sopenharmony_ci break; 1739e5c31af7Sopenharmony_ci } 1740e5c31af7Sopenharmony_ci 1741e5c31af7Sopenharmony_ci case TextureFormat::UNORM_SHORT_1555: 1742e5c31af7Sopenharmony_ci { 1743e5c31af7Sopenharmony_ci const IVec4 swizzled = swizzleGe(color, TextureFormat::RGBA, m_format.order); 1744e5c31af7Sopenharmony_ci *((deUint16*)pixelPtr) = (deUint16)(PU(swizzled[0], 15, 1) | PU(swizzled[1], 10, 5) | PU(swizzled[2], 5, 5) | PU(swizzled[3], 0, 5)); 1745e5c31af7Sopenharmony_ci break; 1746e5c31af7Sopenharmony_ci } 1747e5c31af7Sopenharmony_ci 1748e5c31af7Sopenharmony_ci case TextureFormat::UNORM_INT_1010102_REV: 1749e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT_1010102_REV: 1750e5c31af7Sopenharmony_ci case TextureFormat::USCALED_INT_1010102_REV: 1751e5c31af7Sopenharmony_ci { 1752e5c31af7Sopenharmony_ci const IVec4 swizzled = swizzleGe(color, TextureFormat::RGBA, m_format.order); 1753e5c31af7Sopenharmony_ci *((deUint32*)pixelPtr) = PU(swizzled[0], 0, 10) | PU(swizzled[1], 10, 10) | PU(swizzled[2], 20, 10) | PU(swizzled[3], 30, 2); 1754e5c31af7Sopenharmony_ci break; 1755e5c31af7Sopenharmony_ci } 1756e5c31af7Sopenharmony_ci 1757e5c31af7Sopenharmony_ci case TextureFormat::SNORM_INT_1010102_REV: 1758e5c31af7Sopenharmony_ci case TextureFormat::SIGNED_INT_1010102_REV: 1759e5c31af7Sopenharmony_ci case TextureFormat::SSCALED_INT_1010102_REV: 1760e5c31af7Sopenharmony_ci { 1761e5c31af7Sopenharmony_ci const IVec4 swizzled = swizzleGe(color, TextureFormat::RGBA, m_format.order); 1762e5c31af7Sopenharmony_ci *((deUint32*)pixelPtr) = PI(swizzled[0], 0, 10) | PI(swizzled[1], 10, 10) | PI(swizzled[2], 20, 10) | PI(swizzled[3], 30, 2); 1763e5c31af7Sopenharmony_ci break; 1764e5c31af7Sopenharmony_ci } 1765e5c31af7Sopenharmony_ci 1766e5c31af7Sopenharmony_ci default: 1767e5c31af7Sopenharmony_ci { 1768e5c31af7Sopenharmony_ci // Generic path. 1769e5c31af7Sopenharmony_ci int numChannels = getNumUsedChannels(m_format.order); 1770e5c31af7Sopenharmony_ci const TextureSwizzle::Channel* map = getChannelWriteSwizzle(m_format.order).components; 1771e5c31af7Sopenharmony_ci int channelSize = getChannelSize(m_format.type); 1772e5c31af7Sopenharmony_ci 1773e5c31af7Sopenharmony_ci for (int c = 0; c < numChannels; c++) 1774e5c31af7Sopenharmony_ci { 1775e5c31af7Sopenharmony_ci DE_ASSERT(deInRange32(map[c], TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3)); 1776e5c31af7Sopenharmony_ci intToChannel(pixelPtr + channelSize*c, color[map[c]], m_format.type); 1777e5c31af7Sopenharmony_ci } 1778e5c31af7Sopenharmony_ci break; 1779e5c31af7Sopenharmony_ci } 1780e5c31af7Sopenharmony_ci } 1781e5c31af7Sopenharmony_ci 1782e5c31af7Sopenharmony_ci#undef PU 1783e5c31af7Sopenharmony_ci#undef PI 1784e5c31af7Sopenharmony_ci} 1785e5c31af7Sopenharmony_ci 1786e5c31af7Sopenharmony_civoid PixelBufferAccess::setPixDepth (float depth, int x, int y, int z) const 1787e5c31af7Sopenharmony_ci{ 1788e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(x, 0, getWidth())); 1789e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(y, 0, getHeight())); 1790e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(z, 0, getDepth())); 1791e5c31af7Sopenharmony_ci 1792e5c31af7Sopenharmony_ci deUint8* const pixelPtr = (deUint8*)getPixelPtr(x, y, z); 1793e5c31af7Sopenharmony_ci 1794e5c31af7Sopenharmony_ci switch (m_format.type) 1795e5c31af7Sopenharmony_ci { 1796e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT_16_8_8: 1797e5c31af7Sopenharmony_ci DE_ASSERT(m_format.order == TextureFormat::DS); 1798e5c31af7Sopenharmony_ci writeUint32High16(pixelPtr, convertSatRte<deUint16>(depth * 65535.0f)); 1799e5c31af7Sopenharmony_ci break; 1800e5c31af7Sopenharmony_ci 1801e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT_24_8: 1802e5c31af7Sopenharmony_ci DE_ASSERT(m_format.order == TextureFormat::D || m_format.order == TextureFormat::DS); 1803e5c31af7Sopenharmony_ci writeUint32High24(pixelPtr, convertSatRteUint24(depth * 16777215.0f)); 1804e5c31af7Sopenharmony_ci break; 1805e5c31af7Sopenharmony_ci 1806e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT_24_8_REV: 1807e5c31af7Sopenharmony_ci DE_ASSERT(m_format.order == TextureFormat::D || m_format.order == TextureFormat::DS); 1808e5c31af7Sopenharmony_ci writeUint32Low24(pixelPtr, convertSatRteUint24(depth * 16777215.0f)); 1809e5c31af7Sopenharmony_ci break; 1810e5c31af7Sopenharmony_ci 1811e5c31af7Sopenharmony_ci case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV: 1812e5c31af7Sopenharmony_ci DE_ASSERT(m_format.order == TextureFormat::DS); 1813e5c31af7Sopenharmony_ci *((float*)pixelPtr) = depth; 1814e5c31af7Sopenharmony_ci break; 1815e5c31af7Sopenharmony_ci 1816e5c31af7Sopenharmony_ci default: 1817e5c31af7Sopenharmony_ci DE_ASSERT(m_format.order == TextureFormat::D); // no other combined depth stencil types 1818e5c31af7Sopenharmony_ci floatToChannel(pixelPtr, depth, m_format.type); 1819e5c31af7Sopenharmony_ci break; 1820e5c31af7Sopenharmony_ci } 1821e5c31af7Sopenharmony_ci} 1822e5c31af7Sopenharmony_ci 1823e5c31af7Sopenharmony_civoid PixelBufferAccess::setPixStencil (int stencil, int x, int y, int z) const 1824e5c31af7Sopenharmony_ci{ 1825e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(x, 0, getWidth())); 1826e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(y, 0, getHeight())); 1827e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(z, 0, getDepth())); 1828e5c31af7Sopenharmony_ci 1829e5c31af7Sopenharmony_ci deUint8* const pixelPtr = (deUint8*)getPixelPtr(x, y, z); 1830e5c31af7Sopenharmony_ci 1831e5c31af7Sopenharmony_ci switch (m_format.type) 1832e5c31af7Sopenharmony_ci { 1833e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT_16_8_8: 1834e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT_24_8: 1835e5c31af7Sopenharmony_ci DE_ASSERT(m_format.order == TextureFormat::DS); 1836e5c31af7Sopenharmony_ci writeUint32Low8(pixelPtr, convertSat<deUint8>((deUint32)stencil)); 1837e5c31af7Sopenharmony_ci break; 1838e5c31af7Sopenharmony_ci 1839e5c31af7Sopenharmony_ci case TextureFormat::UNSIGNED_INT_24_8_REV: 1840e5c31af7Sopenharmony_ci DE_ASSERT(m_format.order == TextureFormat::DS); 1841e5c31af7Sopenharmony_ci writeUint32High8(pixelPtr, convertSat<deUint8>((deUint32)stencil)); 1842e5c31af7Sopenharmony_ci break; 1843e5c31af7Sopenharmony_ci 1844e5c31af7Sopenharmony_ci case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV: 1845e5c31af7Sopenharmony_ci DE_ASSERT(m_format.order == TextureFormat::DS); 1846e5c31af7Sopenharmony_ci writeUint32Low8(pixelPtr + 4, convertSat<deUint8>((deUint32)stencil)); 1847e5c31af7Sopenharmony_ci break; 1848e5c31af7Sopenharmony_ci 1849e5c31af7Sopenharmony_ci default: 1850e5c31af7Sopenharmony_ci DE_ASSERT(m_format.order == TextureFormat::S); // no other combined depth stencil types 1851e5c31af7Sopenharmony_ci intToChannel(pixelPtr, stencil, m_format.type); 1852e5c31af7Sopenharmony_ci break; 1853e5c31af7Sopenharmony_ci } 1854e5c31af7Sopenharmony_ci} 1855e5c31af7Sopenharmony_ci 1856e5c31af7Sopenharmony_cistatic inline int imod (int a, int b) 1857e5c31af7Sopenharmony_ci{ 1858e5c31af7Sopenharmony_ci int m = a % b; 1859e5c31af7Sopenharmony_ci return m < 0 ? m + b : m; 1860e5c31af7Sopenharmony_ci} 1861e5c31af7Sopenharmony_ci 1862e5c31af7Sopenharmony_cistatic inline int mirror (int a) 1863e5c31af7Sopenharmony_ci{ 1864e5c31af7Sopenharmony_ci return a >= 0 ? a : -(1 + a); 1865e5c31af7Sopenharmony_ci} 1866e5c31af7Sopenharmony_ci 1867e5c31af7Sopenharmony_ci// Nearest-even rounding in case of tie (fractional part 0.5), otherwise ordinary rounding. 1868e5c31af7Sopenharmony_cistatic inline float rint (float a) 1869e5c31af7Sopenharmony_ci{ 1870e5c31af7Sopenharmony_ci DE_STATIC_ASSERT((-3 % 2 != 0) && (-4 % 2 == 0)); 1871e5c31af7Sopenharmony_ci 1872e5c31af7Sopenharmony_ci float fracVal = deFloatFrac(a); 1873e5c31af7Sopenharmony_ci 1874e5c31af7Sopenharmony_ci if (fracVal != 0.5f) 1875e5c31af7Sopenharmony_ci return deFloatRound(a); // Ordinary case. 1876e5c31af7Sopenharmony_ci 1877e5c31af7Sopenharmony_ci float floorVal = a - fracVal; 1878e5c31af7Sopenharmony_ci bool roundUp = (deInt64)floorVal % 2 != 0; 1879e5c31af7Sopenharmony_ci 1880e5c31af7Sopenharmony_ci return floorVal + (roundUp ? 1.0f : 0.0f); 1881e5c31af7Sopenharmony_ci} 1882e5c31af7Sopenharmony_ci 1883e5c31af7Sopenharmony_cistatic inline int wrap (Sampler::WrapMode mode, int c, int size) 1884e5c31af7Sopenharmony_ci{ 1885e5c31af7Sopenharmony_ci switch (mode) 1886e5c31af7Sopenharmony_ci { 1887e5c31af7Sopenharmony_ci case tcu::Sampler::CLAMP_TO_BORDER: 1888e5c31af7Sopenharmony_ci return deClamp32(c, -1, size); 1889e5c31af7Sopenharmony_ci 1890e5c31af7Sopenharmony_ci case tcu::Sampler::CLAMP_TO_EDGE: 1891e5c31af7Sopenharmony_ci return deClamp32(c, 0, size-1); 1892e5c31af7Sopenharmony_ci 1893e5c31af7Sopenharmony_ci case tcu::Sampler::REPEAT_GL: 1894e5c31af7Sopenharmony_ci return imod(c, size); 1895e5c31af7Sopenharmony_ci 1896e5c31af7Sopenharmony_ci case tcu::Sampler::REPEAT_CL: 1897e5c31af7Sopenharmony_ci return imod(c, size); 1898e5c31af7Sopenharmony_ci 1899e5c31af7Sopenharmony_ci case tcu::Sampler::MIRRORED_ONCE: 1900e5c31af7Sopenharmony_ci c = deClamp32(c, -size, size); 1901e5c31af7Sopenharmony_ci // Fall-through 1902e5c31af7Sopenharmony_ci 1903e5c31af7Sopenharmony_ci case tcu::Sampler::MIRRORED_REPEAT_GL: 1904e5c31af7Sopenharmony_ci return (size - 1) - mirror(imod(c, 2*size) - size); 1905e5c31af7Sopenharmony_ci 1906e5c31af7Sopenharmony_ci case tcu::Sampler::MIRRORED_REPEAT_CL: 1907e5c31af7Sopenharmony_ci return deClamp32(c, 0, size-1); // \note Actual mirroring done already in unnormalization function. 1908e5c31af7Sopenharmony_ci 1909e5c31af7Sopenharmony_ci default: 1910e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 1911e5c31af7Sopenharmony_ci return 0; 1912e5c31af7Sopenharmony_ci } 1913e5c31af7Sopenharmony_ci} 1914e5c31af7Sopenharmony_ci 1915e5c31af7Sopenharmony_ci// Special unnormalization for REPEAT_CL and MIRRORED_REPEAT_CL wrap modes; otherwise ordinary unnormalization. 1916e5c31af7Sopenharmony_cistatic inline float unnormalize (Sampler::WrapMode mode, float c, int size) 1917e5c31af7Sopenharmony_ci{ 1918e5c31af7Sopenharmony_ci switch (mode) 1919e5c31af7Sopenharmony_ci { 1920e5c31af7Sopenharmony_ci case tcu::Sampler::CLAMP_TO_EDGE: 1921e5c31af7Sopenharmony_ci case tcu::Sampler::CLAMP_TO_BORDER: 1922e5c31af7Sopenharmony_ci case tcu::Sampler::REPEAT_GL: 1923e5c31af7Sopenharmony_ci case tcu::Sampler::MIRRORED_REPEAT_GL: 1924e5c31af7Sopenharmony_ci case tcu::Sampler::MIRRORED_ONCE: // Fall-through (ordinary case). 1925e5c31af7Sopenharmony_ci return (float)size*c; 1926e5c31af7Sopenharmony_ci 1927e5c31af7Sopenharmony_ci case tcu::Sampler::REPEAT_CL: 1928e5c31af7Sopenharmony_ci return (float)size * (c - deFloatFloor(c)); 1929e5c31af7Sopenharmony_ci 1930e5c31af7Sopenharmony_ci case tcu::Sampler::MIRRORED_REPEAT_CL: 1931e5c31af7Sopenharmony_ci return (float)size * deFloatAbs(c - 2.0f * rint(0.5f * c)); 1932e5c31af7Sopenharmony_ci 1933e5c31af7Sopenharmony_ci default: 1934e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 1935e5c31af7Sopenharmony_ci return 0.0f; 1936e5c31af7Sopenharmony_ci } 1937e5c31af7Sopenharmony_ci} 1938e5c31af7Sopenharmony_ci 1939e5c31af7Sopenharmony_cistatic bool isFixedPointDepthTextureFormat (const tcu::TextureFormat& format) 1940e5c31af7Sopenharmony_ci{ 1941e5c31af7Sopenharmony_ci DE_ASSERT(format.order == TextureFormat::D || format.order == TextureFormat::R); 1942e5c31af7Sopenharmony_ci 1943e5c31af7Sopenharmony_ci const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type); 1944e5c31af7Sopenharmony_ci if (channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT) 1945e5c31af7Sopenharmony_ci return false; 1946e5c31af7Sopenharmony_ci else if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT) 1947e5c31af7Sopenharmony_ci return true; 1948e5c31af7Sopenharmony_ci else 1949e5c31af7Sopenharmony_ci { 1950e5c31af7Sopenharmony_ci DE_ASSERT(false); 1951e5c31af7Sopenharmony_ci return false; 1952e5c31af7Sopenharmony_ci } 1953e5c31af7Sopenharmony_ci} 1954e5c31af7Sopenharmony_ci 1955e5c31af7Sopenharmony_ci// Texel lookup with color conversion. 1956e5c31af7Sopenharmony_cistatic inline Vec4 lookup (const ConstPixelBufferAccess& access, int i, int j, int k) 1957e5c31af7Sopenharmony_ci{ 1958e5c31af7Sopenharmony_ci const TextureFormat& format = access.getFormat(); 1959e5c31af7Sopenharmony_ci 1960e5c31af7Sopenharmony_ci if (isSRGB(format)) 1961e5c31af7Sopenharmony_ci { 1962e5c31af7Sopenharmony_ci if (format.type == TextureFormat::UNORM_INT8 && format.order == TextureFormat::sRGB) 1963e5c31af7Sopenharmony_ci return sRGB8ToLinear(access.getPixelUint(i, j, k)); 1964e5c31af7Sopenharmony_ci else if (format.type == TextureFormat::UNORM_INT8 && format.order == TextureFormat::sRGBA) 1965e5c31af7Sopenharmony_ci return sRGBA8ToLinear(access.getPixelUint(i, j, k)); 1966e5c31af7Sopenharmony_ci else 1967e5c31af7Sopenharmony_ci return sRGBToLinear(access.getPixel(i, j, k)); 1968e5c31af7Sopenharmony_ci } 1969e5c31af7Sopenharmony_ci else 1970e5c31af7Sopenharmony_ci { 1971e5c31af7Sopenharmony_ci return access.getPixel(i, j, k); 1972e5c31af7Sopenharmony_ci } 1973e5c31af7Sopenharmony_ci} 1974e5c31af7Sopenharmony_ci 1975e5c31af7Sopenharmony_ci// Border texel lookup with color conversion. 1976e5c31af7Sopenharmony_cistatic inline Vec4 lookupBorder (const tcu::TextureFormat& format, const tcu::Sampler& sampler) 1977e5c31af7Sopenharmony_ci{ 1978e5c31af7Sopenharmony_ci // "lookup" for a combined format does not make sense, disallow 1979e5c31af7Sopenharmony_ci DE_ASSERT(!isCombinedDepthStencilType(format.type)); 1980e5c31af7Sopenharmony_ci 1981e5c31af7Sopenharmony_ci const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type); 1982e5c31af7Sopenharmony_ci const bool isFloat = channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT; 1983e5c31af7Sopenharmony_ci const bool isFixed = channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT || 1984e5c31af7Sopenharmony_ci channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT; 1985e5c31af7Sopenharmony_ci const bool isPureInteger = channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER; 1986e5c31af7Sopenharmony_ci const bool isPureUnsignedInteger = channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER; 1987e5c31af7Sopenharmony_ci 1988e5c31af7Sopenharmony_ci if (isFloat || isFixed) 1989e5c31af7Sopenharmony_ci return sampleTextureBorder<float>(format, sampler); 1990e5c31af7Sopenharmony_ci else if (isPureInteger) 1991e5c31af7Sopenharmony_ci return sampleTextureBorder<deInt32>(format, sampler).cast<float>(); 1992e5c31af7Sopenharmony_ci else if (isPureUnsignedInteger) 1993e5c31af7Sopenharmony_ci return sampleTextureBorder<deUint32>(format, sampler).cast<float>(); 1994e5c31af7Sopenharmony_ci else 1995e5c31af7Sopenharmony_ci { 1996e5c31af7Sopenharmony_ci DE_ASSERT(false); 1997e5c31af7Sopenharmony_ci return Vec4(-1.0); 1998e5c31af7Sopenharmony_ci } 1999e5c31af7Sopenharmony_ci} 2000e5c31af7Sopenharmony_ci 2001e5c31af7Sopenharmony_cistatic inline float execCompare (const tcu::Vec4& color, Sampler::CompareMode compare, int chanNdx, float ref_, bool isFixedPoint) 2002e5c31af7Sopenharmony_ci{ 2003e5c31af7Sopenharmony_ci const bool clampValues = isFixedPoint; // if comparing against a floating point texture, ref (and value) is not clamped 2004e5c31af7Sopenharmony_ci const float cmp = (clampValues) ? (de::clamp(color[chanNdx], 0.0f, 1.0f)) : (color[chanNdx]); 2005e5c31af7Sopenharmony_ci const float ref = (clampValues) ? (de::clamp(ref_, 0.0f, 1.0f)) : (ref_); 2006e5c31af7Sopenharmony_ci bool res = false; 2007e5c31af7Sopenharmony_ci 2008e5c31af7Sopenharmony_ci switch (compare) 2009e5c31af7Sopenharmony_ci { 2010e5c31af7Sopenharmony_ci case Sampler::COMPAREMODE_LESS: res = ref < cmp; break; 2011e5c31af7Sopenharmony_ci case Sampler::COMPAREMODE_LESS_OR_EQUAL: res = ref <= cmp; break; 2012e5c31af7Sopenharmony_ci case Sampler::COMPAREMODE_GREATER: res = ref > cmp; break; 2013e5c31af7Sopenharmony_ci case Sampler::COMPAREMODE_GREATER_OR_EQUAL: res = ref >= cmp; break; 2014e5c31af7Sopenharmony_ci case Sampler::COMPAREMODE_EQUAL: res = ref == cmp; break; 2015e5c31af7Sopenharmony_ci case Sampler::COMPAREMODE_NOT_EQUAL: res = ref != cmp; break; 2016e5c31af7Sopenharmony_ci case Sampler::COMPAREMODE_ALWAYS: res = true; break; 2017e5c31af7Sopenharmony_ci case Sampler::COMPAREMODE_NEVER: res = false; break; 2018e5c31af7Sopenharmony_ci default: 2019e5c31af7Sopenharmony_ci DE_ASSERT(false); 2020e5c31af7Sopenharmony_ci } 2021e5c31af7Sopenharmony_ci 2022e5c31af7Sopenharmony_ci return res ? 1.0f : 0.0f; 2023e5c31af7Sopenharmony_ci} 2024e5c31af7Sopenharmony_ci 2025e5c31af7Sopenharmony_cistatic Vec4 sampleNearest1D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, const IVec2& offset) 2026e5c31af7Sopenharmony_ci{ 2027e5c31af7Sopenharmony_ci int width = access.getWidth(); 2028e5c31af7Sopenharmony_ci 2029e5c31af7Sopenharmony_ci int x = deFloorFloatToInt32(u)+offset.x(); 2030e5c31af7Sopenharmony_ci 2031e5c31af7Sopenharmony_ci // Check for CLAMP_TO_BORDER. 2032e5c31af7Sopenharmony_ci if (sampler.wrapS == Sampler::CLAMP_TO_BORDER && !deInBounds32(x, 0, width)) 2033e5c31af7Sopenharmony_ci return lookupBorder(access.getFormat(), sampler); 2034e5c31af7Sopenharmony_ci 2035e5c31af7Sopenharmony_ci int i = wrap(sampler.wrapS, x, width); 2036e5c31af7Sopenharmony_ci 2037e5c31af7Sopenharmony_ci return lookup(access, i, offset.y(), 0); 2038e5c31af7Sopenharmony_ci} 2039e5c31af7Sopenharmony_ci 2040e5c31af7Sopenharmony_cistatic Vec4 sampleNearest2D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, float v, const IVec3& offset) 2041e5c31af7Sopenharmony_ci{ 2042e5c31af7Sopenharmony_ci int width = access.getWidth(); 2043e5c31af7Sopenharmony_ci int height = access.getHeight(); 2044e5c31af7Sopenharmony_ci 2045e5c31af7Sopenharmony_ci int x = deFloorFloatToInt32(u)+offset.x(); 2046e5c31af7Sopenharmony_ci int y = deFloorFloatToInt32(v)+offset.y(); 2047e5c31af7Sopenharmony_ci 2048e5c31af7Sopenharmony_ci // Check for CLAMP_TO_BORDER. 2049e5c31af7Sopenharmony_ci if ((sampler.wrapS == Sampler::CLAMP_TO_BORDER && !deInBounds32(x, 0, width)) || 2050e5c31af7Sopenharmony_ci (sampler.wrapT == Sampler::CLAMP_TO_BORDER && !deInBounds32(y, 0, height))) 2051e5c31af7Sopenharmony_ci return lookupBorder(access.getFormat(), sampler); 2052e5c31af7Sopenharmony_ci 2053e5c31af7Sopenharmony_ci int i = wrap(sampler.wrapS, x, width); 2054e5c31af7Sopenharmony_ci int j = wrap(sampler.wrapT, y, height); 2055e5c31af7Sopenharmony_ci 2056e5c31af7Sopenharmony_ci return lookup(access, i, j, offset.z()); 2057e5c31af7Sopenharmony_ci} 2058e5c31af7Sopenharmony_ci 2059e5c31af7Sopenharmony_cistatic Vec4 sampleNearest3D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, float v, float w, const IVec3& offset) 2060e5c31af7Sopenharmony_ci{ 2061e5c31af7Sopenharmony_ci int width = access.getWidth(); 2062e5c31af7Sopenharmony_ci int height = access.getHeight(); 2063e5c31af7Sopenharmony_ci int depth = access.getDepth(); 2064e5c31af7Sopenharmony_ci 2065e5c31af7Sopenharmony_ci int x = deFloorFloatToInt32(u)+offset.x(); 2066e5c31af7Sopenharmony_ci int y = deFloorFloatToInt32(v)+offset.y(); 2067e5c31af7Sopenharmony_ci int z = deFloorFloatToInt32(w)+offset.z(); 2068e5c31af7Sopenharmony_ci 2069e5c31af7Sopenharmony_ci // Check for CLAMP_TO_BORDER. 2070e5c31af7Sopenharmony_ci if ((sampler.wrapS == Sampler::CLAMP_TO_BORDER && !deInBounds32(x, 0, width)) || 2071e5c31af7Sopenharmony_ci (sampler.wrapT == Sampler::CLAMP_TO_BORDER && !deInBounds32(y, 0, height)) || 2072e5c31af7Sopenharmony_ci (sampler.wrapR == Sampler::CLAMP_TO_BORDER && !deInBounds32(z, 0, depth))) 2073e5c31af7Sopenharmony_ci return lookupBorder(access.getFormat(), sampler); 2074e5c31af7Sopenharmony_ci 2075e5c31af7Sopenharmony_ci int i = wrap(sampler.wrapS, x, width); 2076e5c31af7Sopenharmony_ci int j = wrap(sampler.wrapT, y, height); 2077e5c31af7Sopenharmony_ci int k = wrap(sampler.wrapR, z, depth); 2078e5c31af7Sopenharmony_ci 2079e5c31af7Sopenharmony_ci return lookup(access, i, j, k); 2080e5c31af7Sopenharmony_ci} 2081e5c31af7Sopenharmony_ci 2082e5c31af7Sopenharmony_cistatic Vec4 sampleLinear1D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, const IVec2& offset) 2083e5c31af7Sopenharmony_ci{ 2084e5c31af7Sopenharmony_ci int w = access.getWidth(); 2085e5c31af7Sopenharmony_ci 2086e5c31af7Sopenharmony_ci int x0 = deFloorFloatToInt32(u-0.5f)+offset.x(); 2087e5c31af7Sopenharmony_ci int x1 = x0+1; 2088e5c31af7Sopenharmony_ci 2089e5c31af7Sopenharmony_ci int i0 = wrap(sampler.wrapS, x0, w); 2090e5c31af7Sopenharmony_ci int i1 = wrap(sampler.wrapS, x1, w); 2091e5c31af7Sopenharmony_ci 2092e5c31af7Sopenharmony_ci float a = deFloatFrac(u-0.5f); 2093e5c31af7Sopenharmony_ci 2094e5c31af7Sopenharmony_ci bool i0UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i0, 0, w); 2095e5c31af7Sopenharmony_ci bool i1UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i1, 0, w); 2096e5c31af7Sopenharmony_ci 2097e5c31af7Sopenharmony_ci // Border color for out-of-range coordinates if using CLAMP_TO_BORDER, otherwise execute lookups. 2098e5c31af7Sopenharmony_ci Vec4 p0 = i0UseBorder ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, offset.y(), 0); 2099e5c31af7Sopenharmony_ci Vec4 p1 = i1UseBorder ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, offset.y(), 0); 2100e5c31af7Sopenharmony_ci 2101e5c31af7Sopenharmony_ci // Interpolate. 2102e5c31af7Sopenharmony_ci return p0 * (1.0f - a) + p1 * a; 2103e5c31af7Sopenharmony_ci} 2104e5c31af7Sopenharmony_ci 2105e5c31af7Sopenharmony_cistatic Vec4 sampleCubic1D(const ConstPixelBufferAccess& access, const Sampler& sampler, float u, const IVec2& offset) 2106e5c31af7Sopenharmony_ci{ 2107e5c31af7Sopenharmony_ci int width = access.getWidth(); 2108e5c31af7Sopenharmony_ci 2109e5c31af7Sopenharmony_ci tcu::IVec4 x, i; 2110e5c31af7Sopenharmony_ci 2111e5c31af7Sopenharmony_ci x[0] = deFloorFloatToInt32(u - 1.5f) + offset.x(); 2112e5c31af7Sopenharmony_ci x[1] = x[0] + 1; 2113e5c31af7Sopenharmony_ci x[2] = x[1] + 1; 2114e5c31af7Sopenharmony_ci x[3] = x[2] + 1; 2115e5c31af7Sopenharmony_ci 2116e5c31af7Sopenharmony_ci for (deUint32 m = 0; m < 4; ++m) 2117e5c31af7Sopenharmony_ci i[m] = wrap(sampler.wrapS, x[m], width); 2118e5c31af7Sopenharmony_ci 2119e5c31af7Sopenharmony_ci bool iUseBorder[4]; 2120e5c31af7Sopenharmony_ci for (deUint32 m = 0; m < 4; ++m) 2121e5c31af7Sopenharmony_ci iUseBorder[m] = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i[m], 0, width); 2122e5c31af7Sopenharmony_ci 2123e5c31af7Sopenharmony_ci // Catmull-Rom basis matrix 2124e5c31af7Sopenharmony_ci static const float crValues[16] = { 0.0f, 1.0f, 0.0f, 0.0f, 2125e5c31af7Sopenharmony_ci -0.5f, 0.0f, 0.5f, 0.0f, 2126e5c31af7Sopenharmony_ci 1.0f, -2.5f, 2.0f, -0.5f, 2127e5c31af7Sopenharmony_ci -0.5f, 1.5f, -1.5f, 0.5f }; 2128e5c31af7Sopenharmony_ci static const tcu::Mat4 crBasis(crValues); 2129e5c31af7Sopenharmony_ci 2130e5c31af7Sopenharmony_ci float a = deFloatFrac(u - 0.5f); 2131e5c31af7Sopenharmony_ci tcu::Vec4 alpha(1, a, a*a, a*a*a); 2132e5c31af7Sopenharmony_ci tcu::Vec4 wi = alpha * crBasis; 2133e5c31af7Sopenharmony_ci 2134e5c31af7Sopenharmony_ci tcu::Vec4 result(0.0f, 0.0f, 0.0f, 0.0f); 2135e5c31af7Sopenharmony_ci for (deUint32 m = 0; m < 4; ++m) 2136e5c31af7Sopenharmony_ci { 2137e5c31af7Sopenharmony_ci tcu::Vec4 p = (iUseBorder[m]) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i[m], offset.y(), 0); 2138e5c31af7Sopenharmony_ci result += wi[m] * p; 2139e5c31af7Sopenharmony_ci } 2140e5c31af7Sopenharmony_ci return result; 2141e5c31af7Sopenharmony_ci} 2142e5c31af7Sopenharmony_ci 2143e5c31af7Sopenharmony_cistatic Vec4 sampleLinear2D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, float v, const IVec3& offset) 2144e5c31af7Sopenharmony_ci{ 2145e5c31af7Sopenharmony_ci int w = access.getWidth(); 2146e5c31af7Sopenharmony_ci int h = access.getHeight(); 2147e5c31af7Sopenharmony_ci 2148e5c31af7Sopenharmony_ci int x0 = deFloorFloatToInt32(u-0.5f)+offset.x(); 2149e5c31af7Sopenharmony_ci int x1 = x0+1; 2150e5c31af7Sopenharmony_ci int y0 = deFloorFloatToInt32(v-0.5f)+offset.y(); 2151e5c31af7Sopenharmony_ci int y1 = y0+1; 2152e5c31af7Sopenharmony_ci 2153e5c31af7Sopenharmony_ci int i0 = wrap(sampler.wrapS, x0, w); 2154e5c31af7Sopenharmony_ci int i1 = wrap(sampler.wrapS, x1, w); 2155e5c31af7Sopenharmony_ci int j0 = wrap(sampler.wrapT, y0, h); 2156e5c31af7Sopenharmony_ci int j1 = wrap(sampler.wrapT, y1, h); 2157e5c31af7Sopenharmony_ci 2158e5c31af7Sopenharmony_ci float a = deFloatFrac(u-0.5f); 2159e5c31af7Sopenharmony_ci float b = deFloatFrac(v-0.5f); 2160e5c31af7Sopenharmony_ci 2161e5c31af7Sopenharmony_ci bool i0UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i0, 0, w); 2162e5c31af7Sopenharmony_ci bool i1UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i1, 0, w); 2163e5c31af7Sopenharmony_ci bool j0UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j0, 0, h); 2164e5c31af7Sopenharmony_ci bool j1UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j1, 0, h); 2165e5c31af7Sopenharmony_ci 2166e5c31af7Sopenharmony_ci // Border color for out-of-range coordinates if using CLAMP_TO_BORDER, otherwise execute lookups. 2167e5c31af7Sopenharmony_ci Vec4 p00 = (i0UseBorder || j0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j0, offset.z()); 2168e5c31af7Sopenharmony_ci Vec4 p10 = (i1UseBorder || j0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j0, offset.z()); 2169e5c31af7Sopenharmony_ci Vec4 p01 = (i0UseBorder || j1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j1, offset.z()); 2170e5c31af7Sopenharmony_ci Vec4 p11 = (i1UseBorder || j1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j1, offset.z()); 2171e5c31af7Sopenharmony_ci 2172e5c31af7Sopenharmony_ci // Interpolate. 2173e5c31af7Sopenharmony_ci return (p00*(1.0f-a)*(1.0f-b)) + 2174e5c31af7Sopenharmony_ci (p10*( a)*(1.0f-b)) + 2175e5c31af7Sopenharmony_ci (p01*(1.0f-a)*( b)) + 2176e5c31af7Sopenharmony_ci (p11*( a)*( b)); 2177e5c31af7Sopenharmony_ci} 2178e5c31af7Sopenharmony_ci 2179e5c31af7Sopenharmony_cistatic Vec4 sampleCubic2D(const ConstPixelBufferAccess& access, const Sampler& sampler, float u, float v, const IVec3& offset) 2180e5c31af7Sopenharmony_ci{ 2181e5c31af7Sopenharmony_ci int width = access.getWidth(); 2182e5c31af7Sopenharmony_ci int height = access.getHeight(); 2183e5c31af7Sopenharmony_ci 2184e5c31af7Sopenharmony_ci tcu::IVec4 x, y, i, j; 2185e5c31af7Sopenharmony_ci 2186e5c31af7Sopenharmony_ci x[0] = deFloorFloatToInt32(u - 1.5f) + offset.x(); 2187e5c31af7Sopenharmony_ci x[1] = x[0] + 1; 2188e5c31af7Sopenharmony_ci x[2] = x[1] + 1; 2189e5c31af7Sopenharmony_ci x[3] = x[2] + 1; 2190e5c31af7Sopenharmony_ci y[0] = deFloorFloatToInt32(v - 1.5f) + offset.y(); 2191e5c31af7Sopenharmony_ci y[1] = y[0] + 1; 2192e5c31af7Sopenharmony_ci y[2] = y[1] + 1; 2193e5c31af7Sopenharmony_ci y[3] = y[2] + 1; 2194e5c31af7Sopenharmony_ci 2195e5c31af7Sopenharmony_ci for (deUint32 m = 0; m < 4; ++m) 2196e5c31af7Sopenharmony_ci i[m] = wrap(sampler.wrapS, x[m], width); 2197e5c31af7Sopenharmony_ci for (deUint32 n = 0; n < 4; ++n) 2198e5c31af7Sopenharmony_ci j[n] = wrap(sampler.wrapT, y[n], height); 2199e5c31af7Sopenharmony_ci 2200e5c31af7Sopenharmony_ci bool iUseBorder[4], jUseBorder[4]; 2201e5c31af7Sopenharmony_ci for (deUint32 m = 0; m < 4; ++m) 2202e5c31af7Sopenharmony_ci iUseBorder[m] = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i[m], 0, width); 2203e5c31af7Sopenharmony_ci for (deUint32 n = 0; n < 4; ++n) 2204e5c31af7Sopenharmony_ci jUseBorder[n] = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j[n], 0, height); 2205e5c31af7Sopenharmony_ci 2206e5c31af7Sopenharmony_ci // Catmull-Rom basis matrix 2207e5c31af7Sopenharmony_ci static const float crValues[16] = { 0.0f, 1.0f, 0.0f, 0.0f, 2208e5c31af7Sopenharmony_ci -0.5f, 0.0f, 0.5f, 0.0f, 2209e5c31af7Sopenharmony_ci 1.0f, -2.5f, 2.0f, -0.5f, 2210e5c31af7Sopenharmony_ci -0.5f, 1.5f, -1.5f, 0.5f }; 2211e5c31af7Sopenharmony_ci static const tcu::Mat4 crBasis(crValues); 2212e5c31af7Sopenharmony_ci 2213e5c31af7Sopenharmony_ci float a = deFloatFrac(u - 0.5f); 2214e5c31af7Sopenharmony_ci float b = deFloatFrac(v - 0.5f); 2215e5c31af7Sopenharmony_ci tcu::Vec4 alpha (1, a, a*a, a*a*a); 2216e5c31af7Sopenharmony_ci tcu::Vec4 beta (1, b, b*b, b*b*b); 2217e5c31af7Sopenharmony_ci tcu::Vec4 wi = alpha * crBasis; 2218e5c31af7Sopenharmony_ci tcu::Vec4 wj = beta * crBasis; 2219e5c31af7Sopenharmony_ci 2220e5c31af7Sopenharmony_ci tcu::Vec4 result(0.0f, 0.0f, 0.0f, 0.0f); 2221e5c31af7Sopenharmony_ci for (deUint32 n = 0; n < 4; ++n) 2222e5c31af7Sopenharmony_ci for (deUint32 m = 0; m < 4; ++m) 2223e5c31af7Sopenharmony_ci { 2224e5c31af7Sopenharmony_ci tcu::Vec4 p = (iUseBorder[m] || jUseBorder[n]) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i[m], j[n], offset.z()); 2225e5c31af7Sopenharmony_ci result += wi[m] * wj[n] * p; 2226e5c31af7Sopenharmony_ci } 2227e5c31af7Sopenharmony_ci return result; 2228e5c31af7Sopenharmony_ci} 2229e5c31af7Sopenharmony_ci 2230e5c31af7Sopenharmony_cistatic float sampleLinear1DCompare (const ConstPixelBufferAccess& access, const Sampler& sampler, float ref, float u, const IVec2& offset, bool isFixedPointDepthFormat) 2231e5c31af7Sopenharmony_ci{ 2232e5c31af7Sopenharmony_ci int w = access.getWidth(); 2233e5c31af7Sopenharmony_ci 2234e5c31af7Sopenharmony_ci int x0 = deFloorFloatToInt32(u-0.5f)+offset.x(); 2235e5c31af7Sopenharmony_ci int x1 = x0+1; 2236e5c31af7Sopenharmony_ci 2237e5c31af7Sopenharmony_ci int i0 = wrap(sampler.wrapS, x0, w); 2238e5c31af7Sopenharmony_ci int i1 = wrap(sampler.wrapS, x1, w); 2239e5c31af7Sopenharmony_ci 2240e5c31af7Sopenharmony_ci float a = deFloatFrac(u-0.5f); 2241e5c31af7Sopenharmony_ci 2242e5c31af7Sopenharmony_ci bool i0UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i0, 0, w); 2243e5c31af7Sopenharmony_ci bool i1UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i1, 0, w); 2244e5c31af7Sopenharmony_ci 2245e5c31af7Sopenharmony_ci // Border color for out-of-range coordinates if using CLAMP_TO_BORDER, otherwise execute lookups. 2246e5c31af7Sopenharmony_ci Vec4 p0Clr = i0UseBorder ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, offset.y(), 0); 2247e5c31af7Sopenharmony_ci Vec4 p1Clr = i1UseBorder ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, offset.y(), 0); 2248e5c31af7Sopenharmony_ci 2249e5c31af7Sopenharmony_ci // Execute comparisons. 2250e5c31af7Sopenharmony_ci float p0 = execCompare(p0Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat); 2251e5c31af7Sopenharmony_ci float p1 = execCompare(p1Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat); 2252e5c31af7Sopenharmony_ci 2253e5c31af7Sopenharmony_ci // Interpolate. 2254e5c31af7Sopenharmony_ci return (p0 * (1.0f - a)) + (p1 * a); 2255e5c31af7Sopenharmony_ci} 2256e5c31af7Sopenharmony_ci 2257e5c31af7Sopenharmony_cistatic float sampleLinear2DCompare (const ConstPixelBufferAccess& access, const Sampler& sampler, float ref, float u, float v, const IVec3& offset, bool isFixedPointDepthFormat) 2258e5c31af7Sopenharmony_ci{ 2259e5c31af7Sopenharmony_ci int w = access.getWidth(); 2260e5c31af7Sopenharmony_ci int h = access.getHeight(); 2261e5c31af7Sopenharmony_ci 2262e5c31af7Sopenharmony_ci int x0 = deFloorFloatToInt32(u-0.5f)+offset.x(); 2263e5c31af7Sopenharmony_ci int x1 = x0+1; 2264e5c31af7Sopenharmony_ci int y0 = deFloorFloatToInt32(v-0.5f)+offset.y(); 2265e5c31af7Sopenharmony_ci int y1 = y0+1; 2266e5c31af7Sopenharmony_ci 2267e5c31af7Sopenharmony_ci int i0 = wrap(sampler.wrapS, x0, w); 2268e5c31af7Sopenharmony_ci int i1 = wrap(sampler.wrapS, x1, w); 2269e5c31af7Sopenharmony_ci int j0 = wrap(sampler.wrapT, y0, h); 2270e5c31af7Sopenharmony_ci int j1 = wrap(sampler.wrapT, y1, h); 2271e5c31af7Sopenharmony_ci 2272e5c31af7Sopenharmony_ci float a = deFloatFrac(u-0.5f); 2273e5c31af7Sopenharmony_ci float b = deFloatFrac(v-0.5f); 2274e5c31af7Sopenharmony_ci 2275e5c31af7Sopenharmony_ci bool i0UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i0, 0, w); 2276e5c31af7Sopenharmony_ci bool i1UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i1, 0, w); 2277e5c31af7Sopenharmony_ci bool j0UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j0, 0, h); 2278e5c31af7Sopenharmony_ci bool j1UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j1, 0, h); 2279e5c31af7Sopenharmony_ci 2280e5c31af7Sopenharmony_ci // Border color for out-of-range coordinates if using CLAMP_TO_BORDER, otherwise execute lookups. 2281e5c31af7Sopenharmony_ci Vec4 p00Clr = (i0UseBorder || j0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j0, offset.z()); 2282e5c31af7Sopenharmony_ci Vec4 p10Clr = (i1UseBorder || j0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j0, offset.z()); 2283e5c31af7Sopenharmony_ci Vec4 p01Clr = (i0UseBorder || j1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j1, offset.z()); 2284e5c31af7Sopenharmony_ci Vec4 p11Clr = (i1UseBorder || j1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j1, offset.z()); 2285e5c31af7Sopenharmony_ci 2286e5c31af7Sopenharmony_ci // Execute comparisons. 2287e5c31af7Sopenharmony_ci float p00 = execCompare(p00Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat); 2288e5c31af7Sopenharmony_ci float p10 = execCompare(p10Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat); 2289e5c31af7Sopenharmony_ci float p01 = execCompare(p01Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat); 2290e5c31af7Sopenharmony_ci float p11 = execCompare(p11Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat); 2291e5c31af7Sopenharmony_ci 2292e5c31af7Sopenharmony_ci // Interpolate. 2293e5c31af7Sopenharmony_ci return (p00*(1.0f-a)*(1.0f-b)) + 2294e5c31af7Sopenharmony_ci (p10*( a)*(1.0f-b)) + 2295e5c31af7Sopenharmony_ci (p01*(1.0f-a)*( b)) + 2296e5c31af7Sopenharmony_ci (p11*( a)*( b)); 2297e5c31af7Sopenharmony_ci} 2298e5c31af7Sopenharmony_ci 2299e5c31af7Sopenharmony_cistatic Vec4 sampleLinear3D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, float v, float w, const IVec3& offset) 2300e5c31af7Sopenharmony_ci{ 2301e5c31af7Sopenharmony_ci int width = access.getWidth(); 2302e5c31af7Sopenharmony_ci int height = access.getHeight(); 2303e5c31af7Sopenharmony_ci int depth = access.getDepth(); 2304e5c31af7Sopenharmony_ci 2305e5c31af7Sopenharmony_ci int x0 = deFloorFloatToInt32(u-0.5f)+offset.x(); 2306e5c31af7Sopenharmony_ci int x1 = x0+1; 2307e5c31af7Sopenharmony_ci int y0 = deFloorFloatToInt32(v-0.5f)+offset.y(); 2308e5c31af7Sopenharmony_ci int y1 = y0+1; 2309e5c31af7Sopenharmony_ci int z0 = deFloorFloatToInt32(w-0.5f)+offset.z(); 2310e5c31af7Sopenharmony_ci int z1 = z0+1; 2311e5c31af7Sopenharmony_ci 2312e5c31af7Sopenharmony_ci int i0 = wrap(sampler.wrapS, x0, width); 2313e5c31af7Sopenharmony_ci int i1 = wrap(sampler.wrapS, x1, width); 2314e5c31af7Sopenharmony_ci int j0 = wrap(sampler.wrapT, y0, height); 2315e5c31af7Sopenharmony_ci int j1 = wrap(sampler.wrapT, y1, height); 2316e5c31af7Sopenharmony_ci int k0 = wrap(sampler.wrapR, z0, depth); 2317e5c31af7Sopenharmony_ci int k1 = wrap(sampler.wrapR, z1, depth); 2318e5c31af7Sopenharmony_ci 2319e5c31af7Sopenharmony_ci float a = deFloatFrac(u-0.5f); 2320e5c31af7Sopenharmony_ci float b = deFloatFrac(v-0.5f); 2321e5c31af7Sopenharmony_ci float c = deFloatFrac(w-0.5f); 2322e5c31af7Sopenharmony_ci 2323e5c31af7Sopenharmony_ci bool i0UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i0, 0, width); 2324e5c31af7Sopenharmony_ci bool i1UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i1, 0, width); 2325e5c31af7Sopenharmony_ci bool j0UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j0, 0, height); 2326e5c31af7Sopenharmony_ci bool j1UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j1, 0, height); 2327e5c31af7Sopenharmony_ci bool k0UseBorder = sampler.wrapR == Sampler::CLAMP_TO_BORDER && !de::inBounds(k0, 0, depth); 2328e5c31af7Sopenharmony_ci bool k1UseBorder = sampler.wrapR == Sampler::CLAMP_TO_BORDER && !de::inBounds(k1, 0, depth); 2329e5c31af7Sopenharmony_ci 2330e5c31af7Sopenharmony_ci // Border color for out-of-range coordinates if using CLAMP_TO_BORDER, otherwise execute lookups. 2331e5c31af7Sopenharmony_ci Vec4 p000 = (i0UseBorder || j0UseBorder || k0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j0, k0); 2332e5c31af7Sopenharmony_ci Vec4 p100 = (i1UseBorder || j0UseBorder || k0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j0, k0); 2333e5c31af7Sopenharmony_ci Vec4 p010 = (i0UseBorder || j1UseBorder || k0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j1, k0); 2334e5c31af7Sopenharmony_ci Vec4 p110 = (i1UseBorder || j1UseBorder || k0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j1, k0); 2335e5c31af7Sopenharmony_ci Vec4 p001 = (i0UseBorder || j0UseBorder || k1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j0, k1); 2336e5c31af7Sopenharmony_ci Vec4 p101 = (i1UseBorder || j0UseBorder || k1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j0, k1); 2337e5c31af7Sopenharmony_ci Vec4 p011 = (i0UseBorder || j1UseBorder || k1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j1, k1); 2338e5c31af7Sopenharmony_ci Vec4 p111 = (i1UseBorder || j1UseBorder || k1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j1, k1); 2339e5c31af7Sopenharmony_ci 2340e5c31af7Sopenharmony_ci // Interpolate. 2341e5c31af7Sopenharmony_ci return (p000*(1.0f-a)*(1.0f-b)*(1.0f-c)) + 2342e5c31af7Sopenharmony_ci (p100*( a)*(1.0f-b)*(1.0f-c)) + 2343e5c31af7Sopenharmony_ci (p010*(1.0f-a)*( b)*(1.0f-c)) + 2344e5c31af7Sopenharmony_ci (p110*( a)*( b)*(1.0f-c)) + 2345e5c31af7Sopenharmony_ci (p001*(1.0f-a)*(1.0f-b)*( c)) + 2346e5c31af7Sopenharmony_ci (p101*( a)*(1.0f-b)*( c)) + 2347e5c31af7Sopenharmony_ci (p011*(1.0f-a)*( b)*( c)) + 2348e5c31af7Sopenharmony_ci (p111*( a)*( b)*( c)); 2349e5c31af7Sopenharmony_ci} 2350e5c31af7Sopenharmony_ci 2351e5c31af7Sopenharmony_cistatic Vec4 sampleCubic3D(const ConstPixelBufferAccess& access, const Sampler& sampler, float u, float v, float w, const IVec3& offset) 2352e5c31af7Sopenharmony_ci{ 2353e5c31af7Sopenharmony_ci int width = access.getWidth(); 2354e5c31af7Sopenharmony_ci int height = access.getHeight(); 2355e5c31af7Sopenharmony_ci int depth = access.getDepth(); 2356e5c31af7Sopenharmony_ci 2357e5c31af7Sopenharmony_ci tcu::IVec4 x, y, z, i, j, k; 2358e5c31af7Sopenharmony_ci 2359e5c31af7Sopenharmony_ci x[0] = deFloorFloatToInt32(u - 1.5f) + offset.x(); 2360e5c31af7Sopenharmony_ci x[1] = x[0] + 1; 2361e5c31af7Sopenharmony_ci x[2] = x[1] + 1; 2362e5c31af7Sopenharmony_ci x[3] = x[2] + 1; 2363e5c31af7Sopenharmony_ci y[0] = deFloorFloatToInt32(v - 1.5f) + offset.y(); 2364e5c31af7Sopenharmony_ci y[1] = y[0] + 1; 2365e5c31af7Sopenharmony_ci y[2] = y[1] + 1; 2366e5c31af7Sopenharmony_ci y[3] = y[2] + 1; 2367e5c31af7Sopenharmony_ci z[0] = deFloorFloatToInt32(w - 1.5f) + offset.z(); 2368e5c31af7Sopenharmony_ci z[1] = z[0] + 1; 2369e5c31af7Sopenharmony_ci z[2] = z[1] + 1; 2370e5c31af7Sopenharmony_ci z[3] = z[2] + 1; 2371e5c31af7Sopenharmony_ci 2372e5c31af7Sopenharmony_ci for (deUint32 m = 0; m < 4; ++m) 2373e5c31af7Sopenharmony_ci i[m] = wrap(sampler.wrapS, x[m], width); 2374e5c31af7Sopenharmony_ci for (deUint32 n = 0; n < 4; ++n) 2375e5c31af7Sopenharmony_ci j[n] = wrap(sampler.wrapT, y[n], height); 2376e5c31af7Sopenharmony_ci for (deUint32 o = 0; o < 4; ++o) 2377e5c31af7Sopenharmony_ci k[o] = wrap(sampler.wrapR, k[o], depth); 2378e5c31af7Sopenharmony_ci 2379e5c31af7Sopenharmony_ci bool iUseBorder[4], jUseBorder[4], kUseBorder[4]; 2380e5c31af7Sopenharmony_ci for (deUint32 m = 0; m < 4; ++m) 2381e5c31af7Sopenharmony_ci iUseBorder[m] = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i[m], 0, width); 2382e5c31af7Sopenharmony_ci for (deUint32 n = 0; n < 4; ++n) 2383e5c31af7Sopenharmony_ci jUseBorder[n] = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j[n], 0, height); 2384e5c31af7Sopenharmony_ci for (deUint32 o = 0; o < 4; ++o) 2385e5c31af7Sopenharmony_ci kUseBorder[o] = sampler.wrapR == Sampler::CLAMP_TO_BORDER && !de::inBounds(k[o], 0, depth); 2386e5c31af7Sopenharmony_ci 2387e5c31af7Sopenharmony_ci // Catmull-Rom basis matrix 2388e5c31af7Sopenharmony_ci static const float crValues[16] = { 0.0f, 1.0f, 0.0f, 0.0f, 2389e5c31af7Sopenharmony_ci -0.5f, 0.0f, 0.5f, 0.0f, 2390e5c31af7Sopenharmony_ci 1.0f, -2.5f, 2.0f, -0.5f, 2391e5c31af7Sopenharmony_ci -0.5f, 1.5f, -1.5f, 0.5f }; 2392e5c31af7Sopenharmony_ci static const tcu::Mat4 crBasis(crValues); 2393e5c31af7Sopenharmony_ci 2394e5c31af7Sopenharmony_ci float a = deFloatFrac(u - 0.5f); 2395e5c31af7Sopenharmony_ci float b = deFloatFrac(v - 0.5f); 2396e5c31af7Sopenharmony_ci float c = deFloatFrac(w - 0.5f); 2397e5c31af7Sopenharmony_ci tcu::Vec4 alpha (1, a, a*a, a*a*a); 2398e5c31af7Sopenharmony_ci tcu::Vec4 beta (1, b, b*b, b*b*b); 2399e5c31af7Sopenharmony_ci tcu::Vec4 gamma (1, c, c*c, c*c*c); 2400e5c31af7Sopenharmony_ci tcu::Vec4 wi = alpha * crBasis; 2401e5c31af7Sopenharmony_ci tcu::Vec4 wj = beta * crBasis; 2402e5c31af7Sopenharmony_ci tcu::Vec4 wk = gamma * crBasis; 2403e5c31af7Sopenharmony_ci 2404e5c31af7Sopenharmony_ci tcu::Vec4 result(0.0f, 0.0f, 0.0f, 0.0f); 2405e5c31af7Sopenharmony_ci for (deUint32 o = 0; o < 4; ++o) 2406e5c31af7Sopenharmony_ci for (deUint32 n = 0; n < 4; ++n) 2407e5c31af7Sopenharmony_ci for (deUint32 m = 0; m < 4; ++m) 2408e5c31af7Sopenharmony_ci { 2409e5c31af7Sopenharmony_ci tcu::Vec4 p = (iUseBorder[m] || jUseBorder[n] || kUseBorder[o]) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i[m], j[n], k[o]); 2410e5c31af7Sopenharmony_ci result += wi[m] * wj[n] * wk[o] * p; 2411e5c31af7Sopenharmony_ci } 2412e5c31af7Sopenharmony_ci return result; 2413e5c31af7Sopenharmony_ci} 2414e5c31af7Sopenharmony_ci 2415e5c31af7Sopenharmony_ciVec4 ConstPixelBufferAccess::sample1D (const Sampler& sampler, Sampler::FilterMode filter, float s, int level) const 2416e5c31af7Sopenharmony_ci{ 2417e5c31af7Sopenharmony_ci // check selected layer exists 2418e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(level, 0, m_size.y())); 2419e5c31af7Sopenharmony_ci 2420e5c31af7Sopenharmony_ci return sample1DOffset(sampler, filter, s, tcu::IVec2(0, level)); 2421e5c31af7Sopenharmony_ci} 2422e5c31af7Sopenharmony_ci 2423e5c31af7Sopenharmony_ciVec4 ConstPixelBufferAccess::sample2D (const Sampler& sampler, Sampler::FilterMode filter, float s, float t, int depth) const 2424e5c31af7Sopenharmony_ci{ 2425e5c31af7Sopenharmony_ci // check selected layer exists 2426e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(depth, 0, m_size.z())); 2427e5c31af7Sopenharmony_ci 2428e5c31af7Sopenharmony_ci return sample2DOffset(sampler, filter, s, t, tcu::IVec3(0, 0, depth)); 2429e5c31af7Sopenharmony_ci} 2430e5c31af7Sopenharmony_ci 2431e5c31af7Sopenharmony_ciVec4 ConstPixelBufferAccess::sample3D (const Sampler& sampler, Sampler::FilterMode filter, float s, float t, float r) const 2432e5c31af7Sopenharmony_ci{ 2433e5c31af7Sopenharmony_ci return sample3DOffset(sampler, filter, s, t, r, tcu::IVec3(0, 0, 0)); 2434e5c31af7Sopenharmony_ci} 2435e5c31af7Sopenharmony_ci 2436e5c31af7Sopenharmony_ciVec4 ConstPixelBufferAccess::sample1DOffset (const Sampler& sampler, Sampler::FilterMode filter, float s, const IVec2& offset) const 2437e5c31af7Sopenharmony_ci{ 2438e5c31af7Sopenharmony_ci // check selected layer exists 2439e5c31af7Sopenharmony_ci // \note offset.x is X offset, offset.y is the selected layer 2440e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(offset.y(), 0, m_size.y())); 2441e5c31af7Sopenharmony_ci 2442e5c31af7Sopenharmony_ci // Non-normalized coordinates. 2443e5c31af7Sopenharmony_ci float u = s; 2444e5c31af7Sopenharmony_ci 2445e5c31af7Sopenharmony_ci if (sampler.normalizedCoords) 2446e5c31af7Sopenharmony_ci u = unnormalize(sampler.wrapS, s, m_size.x()); 2447e5c31af7Sopenharmony_ci 2448e5c31af7Sopenharmony_ci switch (filter) 2449e5c31af7Sopenharmony_ci { 2450e5c31af7Sopenharmony_ci case Sampler::NEAREST: return sampleNearest1D (*this, sampler, u, offset); 2451e5c31af7Sopenharmony_ci case Sampler::LINEAR: return sampleLinear1D (*this, sampler, u, offset); 2452e5c31af7Sopenharmony_ci case Sampler::CUBIC: return sampleCubic1D (*this, sampler, u, offset); 2453e5c31af7Sopenharmony_ci default: 2454e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 2455e5c31af7Sopenharmony_ci return Vec4(0.0f); 2456e5c31af7Sopenharmony_ci } 2457e5c31af7Sopenharmony_ci} 2458e5c31af7Sopenharmony_ci 2459e5c31af7Sopenharmony_ciVec4 ConstPixelBufferAccess::sample2DOffset (const Sampler& sampler, Sampler::FilterMode filter, float s, float t, const IVec3& offset) const 2460e5c31af7Sopenharmony_ci{ 2461e5c31af7Sopenharmony_ci // check selected layer exists 2462e5c31af7Sopenharmony_ci // \note offset.xy is the XY offset, offset.z is the selected layer 2463e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(offset.z(), 0, m_size.z())); 2464e5c31af7Sopenharmony_ci 2465e5c31af7Sopenharmony_ci // Non-normalized coordinates. 2466e5c31af7Sopenharmony_ci float u = s; 2467e5c31af7Sopenharmony_ci float v = t; 2468e5c31af7Sopenharmony_ci 2469e5c31af7Sopenharmony_ci if (sampler.normalizedCoords) 2470e5c31af7Sopenharmony_ci { 2471e5c31af7Sopenharmony_ci u = unnormalize(sampler.wrapS, s, m_size.x()); 2472e5c31af7Sopenharmony_ci v = unnormalize(sampler.wrapT, t, m_size.y()); 2473e5c31af7Sopenharmony_ci } 2474e5c31af7Sopenharmony_ci 2475e5c31af7Sopenharmony_ci switch (filter) 2476e5c31af7Sopenharmony_ci { 2477e5c31af7Sopenharmony_ci case Sampler::NEAREST: return sampleNearest2D (*this, sampler, u, v, offset); 2478e5c31af7Sopenharmony_ci case Sampler::LINEAR: return sampleLinear2D (*this, sampler, u, v, offset); 2479e5c31af7Sopenharmony_ci case Sampler::CUBIC: return sampleCubic2D (*this, sampler, u, v, offset); 2480e5c31af7Sopenharmony_ci default: 2481e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 2482e5c31af7Sopenharmony_ci return Vec4(0.0f); 2483e5c31af7Sopenharmony_ci } 2484e5c31af7Sopenharmony_ci} 2485e5c31af7Sopenharmony_ci 2486e5c31af7Sopenharmony_ciVec4 ConstPixelBufferAccess::sample3DOffset (const Sampler& sampler, Sampler::FilterMode filter, float s, float t, float r, const IVec3& offset) const 2487e5c31af7Sopenharmony_ci{ 2488e5c31af7Sopenharmony_ci // Non-normalized coordinates. 2489e5c31af7Sopenharmony_ci float u = s; 2490e5c31af7Sopenharmony_ci float v = t; 2491e5c31af7Sopenharmony_ci float w = r; 2492e5c31af7Sopenharmony_ci 2493e5c31af7Sopenharmony_ci if (sampler.normalizedCoords) 2494e5c31af7Sopenharmony_ci { 2495e5c31af7Sopenharmony_ci u = unnormalize(sampler.wrapS, s, m_size.x()); 2496e5c31af7Sopenharmony_ci v = unnormalize(sampler.wrapT, t, m_size.y()); 2497e5c31af7Sopenharmony_ci w = unnormalize(sampler.wrapR, r, m_size.z()); 2498e5c31af7Sopenharmony_ci } 2499e5c31af7Sopenharmony_ci 2500e5c31af7Sopenharmony_ci switch (filter) 2501e5c31af7Sopenharmony_ci { 2502e5c31af7Sopenharmony_ci case Sampler::NEAREST: return sampleNearest3D (*this, sampler, u, v, w, offset); 2503e5c31af7Sopenharmony_ci case Sampler::LINEAR: return sampleLinear3D (*this, sampler, u, v, w, offset); 2504e5c31af7Sopenharmony_ci case Sampler::CUBIC: return sampleCubic3D (*this, sampler, u, v, w, offset); 2505e5c31af7Sopenharmony_ci default: 2506e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 2507e5c31af7Sopenharmony_ci return Vec4(0.0f); 2508e5c31af7Sopenharmony_ci } 2509e5c31af7Sopenharmony_ci} 2510e5c31af7Sopenharmony_ci 2511e5c31af7Sopenharmony_cifloat ConstPixelBufferAccess::sample1DCompare (const Sampler& sampler, Sampler::FilterMode filter, float ref, float s, const IVec2& offset) const 2512e5c31af7Sopenharmony_ci{ 2513e5c31af7Sopenharmony_ci // check selected layer exists 2514e5c31af7Sopenharmony_ci // \note offset.x is X offset, offset.y is the selected layer 2515e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(offset.y(), 0, m_size.y())); 2516e5c31af7Sopenharmony_ci 2517e5c31af7Sopenharmony_ci // Format information for comparison function 2518e5c31af7Sopenharmony_ci const bool isFixedPointDepth = isFixedPointDepthTextureFormat(m_format); 2519e5c31af7Sopenharmony_ci 2520e5c31af7Sopenharmony_ci // Non-normalized coordinates. 2521e5c31af7Sopenharmony_ci float u = s; 2522e5c31af7Sopenharmony_ci 2523e5c31af7Sopenharmony_ci if (sampler.normalizedCoords) 2524e5c31af7Sopenharmony_ci u = unnormalize(sampler.wrapS, s, m_size.x()); 2525e5c31af7Sopenharmony_ci 2526e5c31af7Sopenharmony_ci switch (filter) 2527e5c31af7Sopenharmony_ci { 2528e5c31af7Sopenharmony_ci case Sampler::NEAREST: return execCompare(sampleNearest1D(*this, sampler, u, offset), sampler.compare, sampler.compareChannel, ref, isFixedPointDepth); 2529e5c31af7Sopenharmony_ci case Sampler::LINEAR: return sampleLinear1DCompare(*this, sampler, ref, u, offset, isFixedPointDepth); 2530e5c31af7Sopenharmony_ci default: 2531e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 2532e5c31af7Sopenharmony_ci return 0.0f; 2533e5c31af7Sopenharmony_ci } 2534e5c31af7Sopenharmony_ci} 2535e5c31af7Sopenharmony_ci 2536e5c31af7Sopenharmony_cifloat ConstPixelBufferAccess::sample2DCompare (const Sampler& sampler, Sampler::FilterMode filter, float ref, float s, float t, const IVec3& offset) const 2537e5c31af7Sopenharmony_ci{ 2538e5c31af7Sopenharmony_ci // check selected layer exists 2539e5c31af7Sopenharmony_ci // \note offset.xy is XY offset, offset.z is the selected layer 2540e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(offset.z(), 0, m_size.z())); 2541e5c31af7Sopenharmony_ci 2542e5c31af7Sopenharmony_ci // Format information for comparison function 2543e5c31af7Sopenharmony_ci const bool isFixedPointDepth = isFixedPointDepthTextureFormat(m_format); 2544e5c31af7Sopenharmony_ci 2545e5c31af7Sopenharmony_ci // Non-normalized coordinates. 2546e5c31af7Sopenharmony_ci float u = s; 2547e5c31af7Sopenharmony_ci float v = t; 2548e5c31af7Sopenharmony_ci 2549e5c31af7Sopenharmony_ci if (sampler.normalizedCoords) 2550e5c31af7Sopenharmony_ci { 2551e5c31af7Sopenharmony_ci u = unnormalize(sampler.wrapS, s, m_size.x()); 2552e5c31af7Sopenharmony_ci v = unnormalize(sampler.wrapT, t, m_size.y()); 2553e5c31af7Sopenharmony_ci } 2554e5c31af7Sopenharmony_ci 2555e5c31af7Sopenharmony_ci switch (filter) 2556e5c31af7Sopenharmony_ci { 2557e5c31af7Sopenharmony_ci case Sampler::NEAREST: return execCompare(sampleNearest2D(*this, sampler, u, v, offset), sampler.compare, sampler.compareChannel, ref, isFixedPointDepth); 2558e5c31af7Sopenharmony_ci case Sampler::LINEAR: return sampleLinear2DCompare(*this, sampler, ref, u, v, offset, isFixedPointDepth); 2559e5c31af7Sopenharmony_ci default: 2560e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 2561e5c31af7Sopenharmony_ci return 0.0f; 2562e5c31af7Sopenharmony_ci } 2563e5c31af7Sopenharmony_ci} 2564e5c31af7Sopenharmony_ci 2565e5c31af7Sopenharmony_ciTextureLevel::TextureLevel (void) 2566e5c31af7Sopenharmony_ci : m_format () 2567e5c31af7Sopenharmony_ci , m_size (0) 2568e5c31af7Sopenharmony_ci{ 2569e5c31af7Sopenharmony_ci} 2570e5c31af7Sopenharmony_ci 2571e5c31af7Sopenharmony_ciTextureLevel::TextureLevel (const TextureFormat& format) 2572e5c31af7Sopenharmony_ci : m_format (format) 2573e5c31af7Sopenharmony_ci , m_size (0) 2574e5c31af7Sopenharmony_ci{ 2575e5c31af7Sopenharmony_ci} 2576e5c31af7Sopenharmony_ci 2577e5c31af7Sopenharmony_ciTextureLevel::TextureLevel (const TextureFormat& format, int width, int height, int depth) 2578e5c31af7Sopenharmony_ci : m_format (format) 2579e5c31af7Sopenharmony_ci , m_size (0) 2580e5c31af7Sopenharmony_ci{ 2581e5c31af7Sopenharmony_ci setSize(width, height, depth); 2582e5c31af7Sopenharmony_ci} 2583e5c31af7Sopenharmony_ci 2584e5c31af7Sopenharmony_ciTextureLevel::~TextureLevel (void) 2585e5c31af7Sopenharmony_ci{ 2586e5c31af7Sopenharmony_ci} 2587e5c31af7Sopenharmony_ci 2588e5c31af7Sopenharmony_civoid TextureLevel::setStorage (const TextureFormat& format, int width, int height, int depth) 2589e5c31af7Sopenharmony_ci{ 2590e5c31af7Sopenharmony_ci m_format = format; 2591e5c31af7Sopenharmony_ci setSize(width, height, depth); 2592e5c31af7Sopenharmony_ci} 2593e5c31af7Sopenharmony_ci 2594e5c31af7Sopenharmony_civoid TextureLevel::setSize (int width, int height, int depth) 2595e5c31af7Sopenharmony_ci{ 2596e5c31af7Sopenharmony_ci int pixelSize = m_format.getPixelSize(); 2597e5c31af7Sopenharmony_ci 2598e5c31af7Sopenharmony_ci m_size = IVec3(width, height, depth); 2599e5c31af7Sopenharmony_ci 2600e5c31af7Sopenharmony_ci m_data.setStorage(m_size.x() * m_size.y() * m_size.z() * pixelSize); 2601e5c31af7Sopenharmony_ci} 2602e5c31af7Sopenharmony_ci 2603e5c31af7Sopenharmony_ciVec4 sampleLevelArray1D (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, int depth, float lod) 2604e5c31af7Sopenharmony_ci{ 2605e5c31af7Sopenharmony_ci return sampleLevelArray1DOffset(levels, numLevels, sampler, s, lod, IVec2(0, depth)); // y-offset in 1D textures is layer selector 2606e5c31af7Sopenharmony_ci} 2607e5c31af7Sopenharmony_ci 2608e5c31af7Sopenharmony_ciVec4 sampleLevelArray2D (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, int depth, float lod, bool es2, ImageViewMinLodParams* minLodParams) 2609e5c31af7Sopenharmony_ci{ 2610e5c31af7Sopenharmony_ci return sampleLevelArray2DOffset(levels, numLevels, sampler, s, t, lod, IVec3(0, 0, depth), es2, minLodParams); // z-offset in 2D textures is layer selector 2611e5c31af7Sopenharmony_ci} 2612e5c31af7Sopenharmony_ci 2613e5c31af7Sopenharmony_ciVec4 sampleLevelArray3D (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, float r, float lod, ImageViewMinLodParams* minLodParams) 2614e5c31af7Sopenharmony_ci{ 2615e5c31af7Sopenharmony_ci return sampleLevelArray3DOffset(levels, numLevels, sampler, s, t, r, lod, IVec3(0, 0, 0), minLodParams); 2616e5c31af7Sopenharmony_ci} 2617e5c31af7Sopenharmony_ci 2618e5c31af7Sopenharmony_ciVec4 sampleLevelArray1DOffset (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float lod, const IVec2& offset) 2619e5c31af7Sopenharmony_ci{ 2620e5c31af7Sopenharmony_ci bool magnified = lod <= sampler.lodThreshold; 2621e5c31af7Sopenharmony_ci Sampler::FilterMode filterMode = magnified ? sampler.magFilter : sampler.minFilter; 2622e5c31af7Sopenharmony_ci 2623e5c31af7Sopenharmony_ci switch (filterMode) 2624e5c31af7Sopenharmony_ci { 2625e5c31af7Sopenharmony_ci case Sampler::NEAREST: return levels[0].sample1DOffset(sampler, filterMode, s, offset); 2626e5c31af7Sopenharmony_ci case Sampler::LINEAR: return levels[0].sample1DOffset(sampler, filterMode, s, offset); 2627e5c31af7Sopenharmony_ci 2628e5c31af7Sopenharmony_ci case Sampler::NEAREST_MIPMAP_NEAREST: 2629e5c31af7Sopenharmony_ci case Sampler::LINEAR_MIPMAP_NEAREST: 2630e5c31af7Sopenharmony_ci { 2631e5c31af7Sopenharmony_ci int maxLevel = (int)numLevels-1; 2632e5c31af7Sopenharmony_ci int level = deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel); 2633e5c31af7Sopenharmony_ci Sampler::FilterMode levelFilter = (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST; 2634e5c31af7Sopenharmony_ci 2635e5c31af7Sopenharmony_ci return levels[level].sample1DOffset(sampler, levelFilter, s, offset); 2636e5c31af7Sopenharmony_ci } 2637e5c31af7Sopenharmony_ci 2638e5c31af7Sopenharmony_ci case Sampler::NEAREST_MIPMAP_LINEAR: 2639e5c31af7Sopenharmony_ci case Sampler::LINEAR_MIPMAP_LINEAR: 2640e5c31af7Sopenharmony_ci { 2641e5c31af7Sopenharmony_ci int maxLevel = (int)numLevels-1; 2642e5c31af7Sopenharmony_ci int level0 = deClamp32((int)deFloatFloor(lod), 0, maxLevel); 2643e5c31af7Sopenharmony_ci int level1 = de::min(maxLevel, level0 + 1); 2644e5c31af7Sopenharmony_ci Sampler::FilterMode levelFilter = (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST; 2645e5c31af7Sopenharmony_ci float f = deFloatFrac(lod); 2646e5c31af7Sopenharmony_ci tcu::Vec4 t0 = levels[level0].sample1DOffset(sampler, levelFilter, s, offset); 2647e5c31af7Sopenharmony_ci tcu::Vec4 t1 = levels[level1].sample1DOffset(sampler, levelFilter, s, offset); 2648e5c31af7Sopenharmony_ci 2649e5c31af7Sopenharmony_ci return t0*(1.0f - f) + t1*f; 2650e5c31af7Sopenharmony_ci } 2651e5c31af7Sopenharmony_ci 2652e5c31af7Sopenharmony_ci default: 2653e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 2654e5c31af7Sopenharmony_ci return Vec4(0.0f); 2655e5c31af7Sopenharmony_ci } 2656e5c31af7Sopenharmony_ci} 2657e5c31af7Sopenharmony_ci 2658e5c31af7Sopenharmony_ciVec4 sampleLevelArray2DOffset (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, float lod, const IVec3& offset, bool es2, ImageViewMinLodParams* minLodParams) 2659e5c31af7Sopenharmony_ci{ 2660e5c31af7Sopenharmony_ci bool magnified; 2661e5c31af7Sopenharmony_ci // minLodRelative is used to calculate the image level to sample from, when VK_EXT_image_view_min_lod extension is enabled. 2662e5c31af7Sopenharmony_ci // The value is relative to baseLevel as the Texture*View was created as the baseLevel being level[0]. 2663e5c31af7Sopenharmony_ci const float minLodRelative = (minLodParams != DE_NULL) ? getImageViewMinLod(minLodParams->minLod) - (float)minLodParams->baseLevel : 0.0f; 2664e5c31af7Sopenharmony_ci 2665e5c31af7Sopenharmony_ci if (es2 && sampler.magFilter == Sampler::LINEAR && 2666e5c31af7Sopenharmony_ci (sampler.minFilter == Sampler::NEAREST_MIPMAP_NEAREST || sampler.minFilter == Sampler::NEAREST_MIPMAP_LINEAR)) 2667e5c31af7Sopenharmony_ci magnified = lod <= 0.5; 2668e5c31af7Sopenharmony_ci else 2669e5c31af7Sopenharmony_ci magnified = lod <= sampler.lodThreshold; 2670e5c31af7Sopenharmony_ci 2671e5c31af7Sopenharmony_ci // VK_EXT_image_view_min_lod: Integer Texel Coordinates case (with robustness2 supported) 2672e5c31af7Sopenharmony_ci if (minLodParams != DE_NULL && minLodParams->intTexCoord) 2673e5c31af7Sopenharmony_ci { 2674e5c31af7Sopenharmony_ci if (lod < deFloatFloor(minLodRelative) || lod >= (float)numLevels) 2675e5c31af7Sopenharmony_ci return Vec4(0.0f); 2676e5c31af7Sopenharmony_ci 2677e5c31af7Sopenharmony_ci if (s < 0.0f || s > 1.0f || t < 0.0f || t > 1.0f) 2678e5c31af7Sopenharmony_ci return Vec4(0.0f); 2679e5c31af7Sopenharmony_ci } 2680e5c31af7Sopenharmony_ci 2681e5c31af7Sopenharmony_ci Sampler::FilterMode filterMode = magnified ? sampler.magFilter : sampler.minFilter; 2682e5c31af7Sopenharmony_ci switch (filterMode) 2683e5c31af7Sopenharmony_ci { 2684e5c31af7Sopenharmony_ci case Sampler::NEAREST: 2685e5c31af7Sopenharmony_ci case Sampler::LINEAR: 2686e5c31af7Sopenharmony_ci case Sampler::CUBIC: 2687e5c31af7Sopenharmony_ci { 2688e5c31af7Sopenharmony_ci bool isLinearMipmapMode = magnified && tcu::isSamplerMipmapModeLinear(sampler.minFilter); 2689e5c31af7Sopenharmony_ci const int maxLevel = (int)numLevels - 1; 2690e5c31af7Sopenharmony_ci const int level0 = isLinearMipmapMode ? (int)deFloatFloor(minLodRelative) : deClamp32((int)deFloatCeil(minLodRelative + 0.5f) - 1, 0, maxLevel); 2691e5c31af7Sopenharmony_ci tcu::Vec4 t0 = levels[level0].sample2DOffset(sampler, filterMode, s, t, offset); 2692e5c31af7Sopenharmony_ci 2693e5c31af7Sopenharmony_ci if (!isLinearMipmapMode) 2694e5c31af7Sopenharmony_ci return t0; 2695e5c31af7Sopenharmony_ci 2696e5c31af7Sopenharmony_ci const float frac = deFloatFrac(minLodRelative); 2697e5c31af7Sopenharmony_ci const int level1 = de::min(level0 + 1, maxLevel); 2698e5c31af7Sopenharmony_ci tcu::Vec4 t1 = levels[level1].sample2DOffset(sampler, filterMode, s, t, offset); 2699e5c31af7Sopenharmony_ci return t0*(1.0f - frac) + t1*frac; 2700e5c31af7Sopenharmony_ci } 2701e5c31af7Sopenharmony_ci 2702e5c31af7Sopenharmony_ci case Sampler::NEAREST_MIPMAP_NEAREST: 2703e5c31af7Sopenharmony_ci case Sampler::LINEAR_MIPMAP_NEAREST: 2704e5c31af7Sopenharmony_ci case Sampler::CUBIC_MIPMAP_NEAREST: 2705e5c31af7Sopenharmony_ci { 2706e5c31af7Sopenharmony_ci if (minLodParams != DE_NULL && !minLodParams->intTexCoord) 2707e5c31af7Sopenharmony_ci lod = de::max(lod, minLodRelative); 2708e5c31af7Sopenharmony_ci 2709e5c31af7Sopenharmony_ci int maxLevel = (int)numLevels-1; 2710e5c31af7Sopenharmony_ci int level = deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel); 2711e5c31af7Sopenharmony_ci Sampler::FilterMode levelFilter; 2712e5c31af7Sopenharmony_ci switch (filterMode) 2713e5c31af7Sopenharmony_ci { 2714e5c31af7Sopenharmony_ci case Sampler::NEAREST_MIPMAP_NEAREST: levelFilter = Sampler::NEAREST; break; 2715e5c31af7Sopenharmony_ci case Sampler::LINEAR_MIPMAP_NEAREST: levelFilter = Sampler::LINEAR; break; 2716e5c31af7Sopenharmony_ci case Sampler::CUBIC_MIPMAP_NEAREST: levelFilter = Sampler::CUBIC; break; 2717e5c31af7Sopenharmony_ci default: 2718e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 2719e5c31af7Sopenharmony_ci return Vec4(0.0f); 2720e5c31af7Sopenharmony_ci } 2721e5c31af7Sopenharmony_ci 2722e5c31af7Sopenharmony_ci return levels[level].sample2DOffset(sampler, levelFilter, s, t, offset); 2723e5c31af7Sopenharmony_ci } 2724e5c31af7Sopenharmony_ci 2725e5c31af7Sopenharmony_ci case Sampler::NEAREST_MIPMAP_LINEAR: 2726e5c31af7Sopenharmony_ci case Sampler::LINEAR_MIPMAP_LINEAR: 2727e5c31af7Sopenharmony_ci case Sampler::CUBIC_MIPMAP_LINEAR: 2728e5c31af7Sopenharmony_ci { 2729e5c31af7Sopenharmony_ci if (minLodParams != DE_NULL && !minLodParams->intTexCoord) 2730e5c31af7Sopenharmony_ci lod = de::max(lod, minLodRelative); 2731e5c31af7Sopenharmony_ci 2732e5c31af7Sopenharmony_ci int maxLevel = (int)numLevels-1; 2733e5c31af7Sopenharmony_ci int level0 = deClamp32((int)deFloatFloor(lod), 0, maxLevel); 2734e5c31af7Sopenharmony_ci int level1 = de::min(maxLevel, level0 + 1); 2735e5c31af7Sopenharmony_ci Sampler::FilterMode levelFilter; 2736e5c31af7Sopenharmony_ci switch (filterMode) 2737e5c31af7Sopenharmony_ci { 2738e5c31af7Sopenharmony_ci case Sampler::NEAREST_MIPMAP_LINEAR: levelFilter = Sampler::NEAREST; break; 2739e5c31af7Sopenharmony_ci case Sampler::LINEAR_MIPMAP_LINEAR: levelFilter = Sampler::LINEAR; break; 2740e5c31af7Sopenharmony_ci case Sampler::CUBIC_MIPMAP_LINEAR: levelFilter = Sampler::CUBIC; break; 2741e5c31af7Sopenharmony_ci default: 2742e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 2743e5c31af7Sopenharmony_ci return Vec4(0.0f); 2744e5c31af7Sopenharmony_ci } 2745e5c31af7Sopenharmony_ci float f = deFloatFrac(lod); 2746e5c31af7Sopenharmony_ci tcu::Vec4 t0 = levels[level0].sample2DOffset(sampler, levelFilter, s, t, offset); 2747e5c31af7Sopenharmony_ci tcu::Vec4 t1 = levels[level1].sample2DOffset(sampler, levelFilter, s, t, offset); 2748e5c31af7Sopenharmony_ci 2749e5c31af7Sopenharmony_ci return t0*(1.0f - f) + t1*f; 2750e5c31af7Sopenharmony_ci } 2751e5c31af7Sopenharmony_ci 2752e5c31af7Sopenharmony_ci default: 2753e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 2754e5c31af7Sopenharmony_ci return Vec4(0.0f); 2755e5c31af7Sopenharmony_ci } 2756e5c31af7Sopenharmony_ci} 2757e5c31af7Sopenharmony_ci 2758e5c31af7Sopenharmony_ciVec4 sampleLevelArray3DOffset (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, float r, float lod, const IVec3& offset, ImageViewMinLodParams* minLodParams) 2759e5c31af7Sopenharmony_ci{ 2760e5c31af7Sopenharmony_ci // minLodRelative is used to calculate the image level to sample from, when VK_EXT_image_view_min_lod extension is enabled. 2761e5c31af7Sopenharmony_ci // The value is relative to baseLevel as the Texture*View was created as the baseLevel being level[0]. 2762e5c31af7Sopenharmony_ci const float minLodRelative = (minLodParams != DE_NULL) ? getImageViewMinLod(minLodParams->minLod) - (float)minLodParams->baseLevel : 0.0f; 2763e5c31af7Sopenharmony_ci bool magnified = lod <= sampler.lodThreshold; 2764e5c31af7Sopenharmony_ci Sampler::FilterMode filterMode = magnified ? sampler.magFilter : sampler.minFilter; 2765e5c31af7Sopenharmony_ci 2766e5c31af7Sopenharmony_ci // VK_EXT_image_view_min_lod: Integer Texel Coordinates case (with robustness2 supported) 2767e5c31af7Sopenharmony_ci if (minLodParams != DE_NULL && minLodParams->intTexCoord) 2768e5c31af7Sopenharmony_ci { 2769e5c31af7Sopenharmony_ci if (lod < deFloatFloor(minLodRelative) || lod >= (float)numLevels) 2770e5c31af7Sopenharmony_ci return Vec4(0.0f); 2771e5c31af7Sopenharmony_ci 2772e5c31af7Sopenharmony_ci if (s < 0.0f || s > 1.0f || t < 0.0f || t > 1.0f) 2773e5c31af7Sopenharmony_ci return Vec4(0.0f); 2774e5c31af7Sopenharmony_ci } 2775e5c31af7Sopenharmony_ci 2776e5c31af7Sopenharmony_ci switch (filterMode) 2777e5c31af7Sopenharmony_ci { 2778e5c31af7Sopenharmony_ci case Sampler::NEAREST: 2779e5c31af7Sopenharmony_ci case Sampler::LINEAR: 2780e5c31af7Sopenharmony_ci { 2781e5c31af7Sopenharmony_ci bool isLinearMipmapMode = magnified && tcu::isSamplerMipmapModeLinear(sampler.minFilter); 2782e5c31af7Sopenharmony_ci const int maxLevel = (int)numLevels - 1; 2783e5c31af7Sopenharmony_ci const int level0 = isLinearMipmapMode ? (int)deFloatFloor(minLodRelative) : deClamp32((int)deFloatCeil(minLodRelative + 0.5f) - 1, 0, maxLevel); 2784e5c31af7Sopenharmony_ci tcu::Vec4 t0 = levels[level0].sample3DOffset(sampler, filterMode, s, t, r, offset); 2785e5c31af7Sopenharmony_ci 2786e5c31af7Sopenharmony_ci if (!isLinearMipmapMode) 2787e5c31af7Sopenharmony_ci return t0; 2788e5c31af7Sopenharmony_ci 2789e5c31af7Sopenharmony_ci const float frac = deFloatFrac(minLodRelative); 2790e5c31af7Sopenharmony_ci const int level1 = de::min(level0 + 1, maxLevel); 2791e5c31af7Sopenharmony_ci tcu::Vec4 t1 = levels[level1].sample3DOffset(sampler, filterMode, s, t, r, offset); 2792e5c31af7Sopenharmony_ci return t0*(1.0f - frac) + t1*frac; 2793e5c31af7Sopenharmony_ci } 2794e5c31af7Sopenharmony_ci 2795e5c31af7Sopenharmony_ci case Sampler::NEAREST_MIPMAP_NEAREST: 2796e5c31af7Sopenharmony_ci case Sampler::LINEAR_MIPMAP_NEAREST: 2797e5c31af7Sopenharmony_ci { 2798e5c31af7Sopenharmony_ci if (minLodParams != DE_NULL && !minLodParams->intTexCoord) 2799e5c31af7Sopenharmony_ci lod = de::max(lod, minLodRelative); 2800e5c31af7Sopenharmony_ci 2801e5c31af7Sopenharmony_ci int maxLevel = (int)numLevels-1; 2802e5c31af7Sopenharmony_ci int level = deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel); 2803e5c31af7Sopenharmony_ci Sampler::FilterMode levelFilter = (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST; 2804e5c31af7Sopenharmony_ci 2805e5c31af7Sopenharmony_ci return levels[level].sample3DOffset(sampler, levelFilter, s, t, r, offset); 2806e5c31af7Sopenharmony_ci } 2807e5c31af7Sopenharmony_ci 2808e5c31af7Sopenharmony_ci case Sampler::NEAREST_MIPMAP_LINEAR: 2809e5c31af7Sopenharmony_ci case Sampler::LINEAR_MIPMAP_LINEAR: 2810e5c31af7Sopenharmony_ci { 2811e5c31af7Sopenharmony_ci if (minLodParams != DE_NULL && !minLodParams->intTexCoord) 2812e5c31af7Sopenharmony_ci lod = de::max(lod, minLodRelative); 2813e5c31af7Sopenharmony_ci 2814e5c31af7Sopenharmony_ci int maxLevel = (int)numLevels-1; 2815e5c31af7Sopenharmony_ci int level0 = deClamp32((int)deFloatFloor(lod), 0, maxLevel); 2816e5c31af7Sopenharmony_ci int level1 = de::min(maxLevel, level0 + 1); 2817e5c31af7Sopenharmony_ci Sampler::FilterMode levelFilter = (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST; 2818e5c31af7Sopenharmony_ci float f = deFloatFrac(lod); 2819e5c31af7Sopenharmony_ci tcu::Vec4 t0 = levels[level0].sample3DOffset(sampler, levelFilter, s, t, r, offset); 2820e5c31af7Sopenharmony_ci tcu::Vec4 t1 = levels[level1].sample3DOffset(sampler, levelFilter, s, t, r, offset); 2821e5c31af7Sopenharmony_ci 2822e5c31af7Sopenharmony_ci return t0*(1.0f - f) + t1*f; 2823e5c31af7Sopenharmony_ci } 2824e5c31af7Sopenharmony_ci 2825e5c31af7Sopenharmony_ci default: 2826e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 2827e5c31af7Sopenharmony_ci return Vec4(0.0f); 2828e5c31af7Sopenharmony_ci } 2829e5c31af7Sopenharmony_ci} 2830e5c31af7Sopenharmony_ci 2831e5c31af7Sopenharmony_cifloat sampleLevelArray1DCompare (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float ref, float s, float lod, const IVec2& offset) 2832e5c31af7Sopenharmony_ci{ 2833e5c31af7Sopenharmony_ci bool magnified = lod <= sampler.lodThreshold; 2834e5c31af7Sopenharmony_ci Sampler::FilterMode filterMode = magnified ? sampler.magFilter : sampler.minFilter; 2835e5c31af7Sopenharmony_ci 2836e5c31af7Sopenharmony_ci switch (filterMode) 2837e5c31af7Sopenharmony_ci { 2838e5c31af7Sopenharmony_ci case Sampler::NEAREST: return levels[0].sample1DCompare(sampler, filterMode, ref, s, offset); 2839e5c31af7Sopenharmony_ci case Sampler::LINEAR: return levels[0].sample1DCompare(sampler, filterMode, ref, s, offset); 2840e5c31af7Sopenharmony_ci 2841e5c31af7Sopenharmony_ci case Sampler::NEAREST_MIPMAP_NEAREST: 2842e5c31af7Sopenharmony_ci case Sampler::LINEAR_MIPMAP_NEAREST: 2843e5c31af7Sopenharmony_ci { 2844e5c31af7Sopenharmony_ci int maxLevel = (int)numLevels-1; 2845e5c31af7Sopenharmony_ci int level = deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel); 2846e5c31af7Sopenharmony_ci Sampler::FilterMode levelFilter = (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST; 2847e5c31af7Sopenharmony_ci 2848e5c31af7Sopenharmony_ci return levels[level].sample1DCompare(sampler, levelFilter, ref, s, offset); 2849e5c31af7Sopenharmony_ci } 2850e5c31af7Sopenharmony_ci 2851e5c31af7Sopenharmony_ci case Sampler::NEAREST_MIPMAP_LINEAR: 2852e5c31af7Sopenharmony_ci case Sampler::LINEAR_MIPMAP_LINEAR: 2853e5c31af7Sopenharmony_ci { 2854e5c31af7Sopenharmony_ci int maxLevel = (int)numLevels-1; 2855e5c31af7Sopenharmony_ci int level0 = deClamp32((int)deFloatFloor(lod), 0, maxLevel); 2856e5c31af7Sopenharmony_ci int level1 = de::min(maxLevel, level0 + 1); 2857e5c31af7Sopenharmony_ci Sampler::FilterMode levelFilter = (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST; 2858e5c31af7Sopenharmony_ci float f = deFloatFrac(lod); 2859e5c31af7Sopenharmony_ci float t0 = levels[level0].sample1DCompare(sampler, levelFilter, ref, s, offset); 2860e5c31af7Sopenharmony_ci float t1 = levels[level1].sample1DCompare(sampler, levelFilter, ref, s, offset); 2861e5c31af7Sopenharmony_ci 2862e5c31af7Sopenharmony_ci return t0*(1.0f - f) + t1*f; 2863e5c31af7Sopenharmony_ci } 2864e5c31af7Sopenharmony_ci 2865e5c31af7Sopenharmony_ci default: 2866e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 2867e5c31af7Sopenharmony_ci return 0.0f; 2868e5c31af7Sopenharmony_ci } 2869e5c31af7Sopenharmony_ci} 2870e5c31af7Sopenharmony_ci 2871e5c31af7Sopenharmony_cifloat sampleLevelArray2DCompare (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float ref, float s, float t, float lod, const IVec3& offset) 2872e5c31af7Sopenharmony_ci{ 2873e5c31af7Sopenharmony_ci bool magnified = lod <= sampler.lodThreshold; 2874e5c31af7Sopenharmony_ci Sampler::FilterMode filterMode = magnified ? sampler.magFilter : sampler.minFilter; 2875e5c31af7Sopenharmony_ci 2876e5c31af7Sopenharmony_ci switch (filterMode) 2877e5c31af7Sopenharmony_ci { 2878e5c31af7Sopenharmony_ci case Sampler::NEAREST: return levels[0].sample2DCompare(sampler, filterMode, ref, s, t, offset); 2879e5c31af7Sopenharmony_ci case Sampler::LINEAR: return levels[0].sample2DCompare(sampler, filterMode, ref, s, t, offset); 2880e5c31af7Sopenharmony_ci 2881e5c31af7Sopenharmony_ci case Sampler::NEAREST_MIPMAP_NEAREST: 2882e5c31af7Sopenharmony_ci case Sampler::LINEAR_MIPMAP_NEAREST: 2883e5c31af7Sopenharmony_ci { 2884e5c31af7Sopenharmony_ci int maxLevel = (int)numLevels-1; 2885e5c31af7Sopenharmony_ci int level = deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel); 2886e5c31af7Sopenharmony_ci Sampler::FilterMode levelFilter = (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST; 2887e5c31af7Sopenharmony_ci 2888e5c31af7Sopenharmony_ci return levels[level].sample2DCompare(sampler, levelFilter, ref, s, t, offset); 2889e5c31af7Sopenharmony_ci } 2890e5c31af7Sopenharmony_ci 2891e5c31af7Sopenharmony_ci case Sampler::NEAREST_MIPMAP_LINEAR: 2892e5c31af7Sopenharmony_ci case Sampler::LINEAR_MIPMAP_LINEAR: 2893e5c31af7Sopenharmony_ci { 2894e5c31af7Sopenharmony_ci int maxLevel = (int)numLevels-1; 2895e5c31af7Sopenharmony_ci int level0 = deClamp32((int)deFloatFloor(lod), 0, maxLevel); 2896e5c31af7Sopenharmony_ci int level1 = de::min(maxLevel, level0 + 1); 2897e5c31af7Sopenharmony_ci Sampler::FilterMode levelFilter = (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST; 2898e5c31af7Sopenharmony_ci float f = deFloatFrac(lod); 2899e5c31af7Sopenharmony_ci float t0 = levels[level0].sample2DCompare(sampler, levelFilter, ref, s, t, offset); 2900e5c31af7Sopenharmony_ci float t1 = levels[level1].sample2DCompare(sampler, levelFilter, ref, s, t, offset); 2901e5c31af7Sopenharmony_ci 2902e5c31af7Sopenharmony_ci return t0*(1.0f - f) + t1*f; 2903e5c31af7Sopenharmony_ci } 2904e5c31af7Sopenharmony_ci 2905e5c31af7Sopenharmony_ci default: 2906e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 2907e5c31af7Sopenharmony_ci return 0.0f; 2908e5c31af7Sopenharmony_ci } 2909e5c31af7Sopenharmony_ci} 2910e5c31af7Sopenharmony_ci 2911e5c31af7Sopenharmony_cistatic Vec4 fetchGatherArray2DOffsets (const ConstPixelBufferAccess& src, const Sampler& sampler, float s, float t, int depth, int componentNdx, const IVec2 (&offsets)[4]) 2912e5c31af7Sopenharmony_ci{ 2913e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(componentNdx, 0, 4)); 2914e5c31af7Sopenharmony_ci 2915e5c31af7Sopenharmony_ci const int w = src.getWidth(); 2916e5c31af7Sopenharmony_ci const int h = src.getHeight(); 2917e5c31af7Sopenharmony_ci const float u = unnormalize(sampler.wrapS, s, w); 2918e5c31af7Sopenharmony_ci const float v = unnormalize(sampler.wrapT, t, h); 2919e5c31af7Sopenharmony_ci const int x0 = deFloorFloatToInt32(u-0.5f); 2920e5c31af7Sopenharmony_ci const int y0 = deFloorFloatToInt32(v-0.5f); 2921e5c31af7Sopenharmony_ci 2922e5c31af7Sopenharmony_ci Vec4 result; 2923e5c31af7Sopenharmony_ci 2924e5c31af7Sopenharmony_ci for (int i = 0; i < 4; i++) 2925e5c31af7Sopenharmony_ci { 2926e5c31af7Sopenharmony_ci const int sampleX = wrap(sampler.wrapS, x0 + offsets[i].x(), w); 2927e5c31af7Sopenharmony_ci const int sampleY = wrap(sampler.wrapT, y0 + offsets[i].y(), h); 2928e5c31af7Sopenharmony_ci Vec4 pixel; 2929e5c31af7Sopenharmony_ci 2930e5c31af7Sopenharmony_ci if (deInBounds32(sampleX, 0, w) && deInBounds32(sampleY, 0, h)) 2931e5c31af7Sopenharmony_ci pixel = lookup(src, sampleX, sampleY, depth); 2932e5c31af7Sopenharmony_ci else 2933e5c31af7Sopenharmony_ci pixel = lookupBorder(src.getFormat(), sampler); 2934e5c31af7Sopenharmony_ci 2935e5c31af7Sopenharmony_ci result[i] = pixel[componentNdx]; 2936e5c31af7Sopenharmony_ci } 2937e5c31af7Sopenharmony_ci 2938e5c31af7Sopenharmony_ci return result; 2939e5c31af7Sopenharmony_ci} 2940e5c31af7Sopenharmony_ci 2941e5c31af7Sopenharmony_ciVec4 gatherArray2DOffsets (const ConstPixelBufferAccess& src, const Sampler& sampler, float s, float t, int depth, int componentNdx, const IVec2 (&offsets)[4]) 2942e5c31af7Sopenharmony_ci{ 2943e5c31af7Sopenharmony_ci DE_ASSERT(sampler.compare == Sampler::COMPAREMODE_NONE); 2944e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(componentNdx, 0, 4)); 2945e5c31af7Sopenharmony_ci 2946e5c31af7Sopenharmony_ci return fetchGatherArray2DOffsets(src, sampler, s, t, depth, componentNdx, offsets); 2947e5c31af7Sopenharmony_ci} 2948e5c31af7Sopenharmony_ci 2949e5c31af7Sopenharmony_ciVec4 gatherArray2DOffsetsCompare (const ConstPixelBufferAccess& src, const Sampler& sampler, float ref, float s, float t, int depth, const IVec2 (&offsets)[4]) 2950e5c31af7Sopenharmony_ci{ 2951e5c31af7Sopenharmony_ci DE_ASSERT(sampler.compare != Sampler::COMPAREMODE_NONE); 2952e5c31af7Sopenharmony_ci DE_ASSERT(src.getFormat().order == TextureFormat::D || src.getFormat().order == TextureFormat::DS); 2953e5c31af7Sopenharmony_ci DE_ASSERT(sampler.compareChannel == 0); 2954e5c31af7Sopenharmony_ci 2955e5c31af7Sopenharmony_ci const bool isFixedPoint = isFixedPointDepthTextureFormat(src.getFormat()); 2956e5c31af7Sopenharmony_ci const Vec4 gathered = fetchGatherArray2DOffsets(src, sampler, s, t, depth, 0 /* component 0: depth */, offsets); 2957e5c31af7Sopenharmony_ci Vec4 result; 2958e5c31af7Sopenharmony_ci 2959e5c31af7Sopenharmony_ci for (int i = 0; i < 4; i++) 2960e5c31af7Sopenharmony_ci result[i] = execCompare(gathered, sampler.compare, i, ref, isFixedPoint); 2961e5c31af7Sopenharmony_ci 2962e5c31af7Sopenharmony_ci return result; 2963e5c31af7Sopenharmony_ci} 2964e5c31af7Sopenharmony_ci 2965e5c31af7Sopenharmony_cistatic Vec4 sampleCubeSeamlessNearest (const ConstPixelBufferAccess& faceAccess, const Sampler& sampler, float s, float t, int depth) 2966e5c31af7Sopenharmony_ci{ 2967e5c31af7Sopenharmony_ci Sampler clampingSampler = sampler; 2968e5c31af7Sopenharmony_ci clampingSampler.wrapS = Sampler::CLAMP_TO_EDGE; 2969e5c31af7Sopenharmony_ci clampingSampler.wrapT = Sampler::CLAMP_TO_EDGE; 2970e5c31af7Sopenharmony_ci return faceAccess.sample2D(clampingSampler, Sampler::NEAREST, s, t, depth); 2971e5c31af7Sopenharmony_ci} 2972e5c31af7Sopenharmony_ci 2973e5c31af7Sopenharmony_ciCubeFace selectCubeFace (const Vec3& coords) 2974e5c31af7Sopenharmony_ci{ 2975e5c31af7Sopenharmony_ci const float x = coords.x(); 2976e5c31af7Sopenharmony_ci const float y = coords.y(); 2977e5c31af7Sopenharmony_ci const float z = coords.z(); 2978e5c31af7Sopenharmony_ci const float ax = deFloatAbs(x); 2979e5c31af7Sopenharmony_ci const float ay = deFloatAbs(y); 2980e5c31af7Sopenharmony_ci const float az = deFloatAbs(z); 2981e5c31af7Sopenharmony_ci 2982e5c31af7Sopenharmony_ci if (ay < ax && az < ax) 2983e5c31af7Sopenharmony_ci return x >= 0.0f ? CUBEFACE_POSITIVE_X : CUBEFACE_NEGATIVE_X; 2984e5c31af7Sopenharmony_ci else if (ax < ay && az < ay) 2985e5c31af7Sopenharmony_ci return y >= 0.0f ? CUBEFACE_POSITIVE_Y : CUBEFACE_NEGATIVE_Y; 2986e5c31af7Sopenharmony_ci else if (ax < az && ay < az) 2987e5c31af7Sopenharmony_ci return z >= 0.0f ? CUBEFACE_POSITIVE_Z : CUBEFACE_NEGATIVE_Z; 2988e5c31af7Sopenharmony_ci else 2989e5c31af7Sopenharmony_ci { 2990e5c31af7Sopenharmony_ci // Some of the components are equal. Use tie-breaking rule. 2991e5c31af7Sopenharmony_ci if (ax == ay) 2992e5c31af7Sopenharmony_ci { 2993e5c31af7Sopenharmony_ci if (ax < az) 2994e5c31af7Sopenharmony_ci return z >= 0.0f ? CUBEFACE_POSITIVE_Z : CUBEFACE_NEGATIVE_Z; 2995e5c31af7Sopenharmony_ci else 2996e5c31af7Sopenharmony_ci return x >= 0.0f ? CUBEFACE_POSITIVE_X : CUBEFACE_NEGATIVE_X; 2997e5c31af7Sopenharmony_ci } 2998e5c31af7Sopenharmony_ci else if (ax == az) 2999e5c31af7Sopenharmony_ci { 3000e5c31af7Sopenharmony_ci if (az < ay) 3001e5c31af7Sopenharmony_ci return y >= 0.0f ? CUBEFACE_POSITIVE_Y : CUBEFACE_NEGATIVE_Y; 3002e5c31af7Sopenharmony_ci else 3003e5c31af7Sopenharmony_ci return z >= 0.0f ? CUBEFACE_POSITIVE_Z : CUBEFACE_NEGATIVE_Z; 3004e5c31af7Sopenharmony_ci } 3005e5c31af7Sopenharmony_ci else if (ay == az) 3006e5c31af7Sopenharmony_ci { 3007e5c31af7Sopenharmony_ci if (ay < ax) 3008e5c31af7Sopenharmony_ci return x >= 0.0f ? CUBEFACE_POSITIVE_X : CUBEFACE_NEGATIVE_X; 3009e5c31af7Sopenharmony_ci else 3010e5c31af7Sopenharmony_ci return y >= 0.0f ? CUBEFACE_POSITIVE_Y : CUBEFACE_NEGATIVE_Y; 3011e5c31af7Sopenharmony_ci } 3012e5c31af7Sopenharmony_ci else 3013e5c31af7Sopenharmony_ci return x >= 0.0f ? CUBEFACE_POSITIVE_X : CUBEFACE_NEGATIVE_X; 3014e5c31af7Sopenharmony_ci } 3015e5c31af7Sopenharmony_ci} 3016e5c31af7Sopenharmony_ci 3017e5c31af7Sopenharmony_ciVec2 projectToFace (CubeFace face, const Vec3& coord) 3018e5c31af7Sopenharmony_ci{ 3019e5c31af7Sopenharmony_ci const float rx = coord.x(); 3020e5c31af7Sopenharmony_ci const float ry = coord.y(); 3021e5c31af7Sopenharmony_ci const float rz = coord.z(); 3022e5c31af7Sopenharmony_ci float sc = 0.0f; 3023e5c31af7Sopenharmony_ci float tc = 0.0f; 3024e5c31af7Sopenharmony_ci float ma = 0.0f; 3025e5c31af7Sopenharmony_ci float s; 3026e5c31af7Sopenharmony_ci float t; 3027e5c31af7Sopenharmony_ci 3028e5c31af7Sopenharmony_ci switch (face) 3029e5c31af7Sopenharmony_ci { 3030e5c31af7Sopenharmony_ci case CUBEFACE_NEGATIVE_X: sc = +rz; tc = -ry; ma = -rx; break; 3031e5c31af7Sopenharmony_ci case CUBEFACE_POSITIVE_X: sc = -rz; tc = -ry; ma = +rx; break; 3032e5c31af7Sopenharmony_ci case CUBEFACE_NEGATIVE_Y: sc = +rx; tc = -rz; ma = -ry; break; 3033e5c31af7Sopenharmony_ci case CUBEFACE_POSITIVE_Y: sc = +rx; tc = +rz; ma = +ry; break; 3034e5c31af7Sopenharmony_ci case CUBEFACE_NEGATIVE_Z: sc = -rx; tc = -ry; ma = -rz; break; 3035e5c31af7Sopenharmony_ci case CUBEFACE_POSITIVE_Z: sc = +rx; tc = -ry; ma = +rz; break; 3036e5c31af7Sopenharmony_ci default: 3037e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 3038e5c31af7Sopenharmony_ci } 3039e5c31af7Sopenharmony_ci 3040e5c31af7Sopenharmony_ci if (fabs(ma) < FLT_EPSILON) 3041e5c31af7Sopenharmony_ci { 3042e5c31af7Sopenharmony_ci return Vec2(0.0f); 3043e5c31af7Sopenharmony_ci } 3044e5c31af7Sopenharmony_ci 3045e5c31af7Sopenharmony_ci // Compute s, t 3046e5c31af7Sopenharmony_ci s = ((sc / ma) + 1.0f) / 2.0f; 3047e5c31af7Sopenharmony_ci t = ((tc / ma) + 1.0f) / 2.0f; 3048e5c31af7Sopenharmony_ci 3049e5c31af7Sopenharmony_ci return Vec2(s, t); 3050e5c31af7Sopenharmony_ci} 3051e5c31af7Sopenharmony_ci 3052e5c31af7Sopenharmony_ciCubeFaceFloatCoords getCubeFaceCoords (const Vec3& coords) 3053e5c31af7Sopenharmony_ci{ 3054e5c31af7Sopenharmony_ci const CubeFace face = selectCubeFace(coords); 3055e5c31af7Sopenharmony_ci return CubeFaceFloatCoords(face, projectToFace(face, coords)); 3056e5c31af7Sopenharmony_ci} 3057e5c31af7Sopenharmony_ci 3058e5c31af7Sopenharmony_ci// Checks if origCoords.coords is in bounds defined by size; if not, return a CubeFaceIntCoords with face set to the appropriate neighboring face and coords transformed accordingly. 3059e5c31af7Sopenharmony_ci// \note If both x and y in origCoords.coords are out of bounds, this returns with face CUBEFACE_LAST, signifying that there is no unique neighboring face. 3060e5c31af7Sopenharmony_ciCubeFaceIntCoords remapCubeEdgeCoords (const CubeFaceIntCoords& origCoords, int size) 3061e5c31af7Sopenharmony_ci{ 3062e5c31af7Sopenharmony_ci bool uInBounds = de::inBounds(origCoords.s, 0, size); 3063e5c31af7Sopenharmony_ci bool vInBounds = de::inBounds(origCoords.t, 0, size); 3064e5c31af7Sopenharmony_ci 3065e5c31af7Sopenharmony_ci if (uInBounds && vInBounds) 3066e5c31af7Sopenharmony_ci return origCoords; 3067e5c31af7Sopenharmony_ci 3068e5c31af7Sopenharmony_ci if (!uInBounds && !vInBounds) 3069e5c31af7Sopenharmony_ci return CubeFaceIntCoords(CUBEFACE_LAST, -1, -1); 3070e5c31af7Sopenharmony_ci 3071e5c31af7Sopenharmony_ci IVec2 coords(wrap(Sampler::CLAMP_TO_BORDER, origCoords.s, size), 3072e5c31af7Sopenharmony_ci wrap(Sampler::CLAMP_TO_BORDER, origCoords.t, size)); 3073e5c31af7Sopenharmony_ci IVec3 canonizedCoords; 3074e5c31af7Sopenharmony_ci 3075e5c31af7Sopenharmony_ci // Map the uv coordinates to canonized 3d coordinates. 3076e5c31af7Sopenharmony_ci 3077e5c31af7Sopenharmony_ci switch (origCoords.face) 3078e5c31af7Sopenharmony_ci { 3079e5c31af7Sopenharmony_ci case CUBEFACE_NEGATIVE_X: canonizedCoords = IVec3(0, size-1-coords.y(), coords.x()); break; 3080e5c31af7Sopenharmony_ci case CUBEFACE_POSITIVE_X: canonizedCoords = IVec3(size-1, size-1-coords.y(), size-1-coords.x()); break; 3081e5c31af7Sopenharmony_ci case CUBEFACE_NEGATIVE_Y: canonizedCoords = IVec3(coords.x(), 0, size-1-coords.y()); break; 3082e5c31af7Sopenharmony_ci case CUBEFACE_POSITIVE_Y: canonizedCoords = IVec3(coords.x(), size-1, coords.y()); break; 3083e5c31af7Sopenharmony_ci case CUBEFACE_NEGATIVE_Z: canonizedCoords = IVec3(size-1-coords.x(), size-1-coords.y(), 0); break; 3084e5c31af7Sopenharmony_ci case CUBEFACE_POSITIVE_Z: canonizedCoords = IVec3(coords.x(), size-1-coords.y(), size-1); break; 3085e5c31af7Sopenharmony_ci default: DE_ASSERT(false); 3086e5c31af7Sopenharmony_ci } 3087e5c31af7Sopenharmony_ci 3088e5c31af7Sopenharmony_ci // Find an appropriate face to re-map the coordinates to. 3089e5c31af7Sopenharmony_ci 3090e5c31af7Sopenharmony_ci if (canonizedCoords.x() == -1) 3091e5c31af7Sopenharmony_ci return CubeFaceIntCoords(CUBEFACE_NEGATIVE_X, IVec2(canonizedCoords.z(), size-1-canonizedCoords.y())); 3092e5c31af7Sopenharmony_ci 3093e5c31af7Sopenharmony_ci if (canonizedCoords.x() == size) 3094e5c31af7Sopenharmony_ci return CubeFaceIntCoords(CUBEFACE_POSITIVE_X, IVec2(size-1-canonizedCoords.z(), size-1-canonizedCoords.y())); 3095e5c31af7Sopenharmony_ci 3096e5c31af7Sopenharmony_ci if (canonizedCoords.y() == -1) 3097e5c31af7Sopenharmony_ci return CubeFaceIntCoords(CUBEFACE_NEGATIVE_Y, IVec2(canonizedCoords.x(), size-1-canonizedCoords.z())); 3098e5c31af7Sopenharmony_ci 3099e5c31af7Sopenharmony_ci if (canonizedCoords.y() == size) 3100e5c31af7Sopenharmony_ci return CubeFaceIntCoords(CUBEFACE_POSITIVE_Y, IVec2(canonizedCoords.x(), canonizedCoords.z())); 3101e5c31af7Sopenharmony_ci 3102e5c31af7Sopenharmony_ci if (canonizedCoords.z() == -1) 3103e5c31af7Sopenharmony_ci return CubeFaceIntCoords(CUBEFACE_NEGATIVE_Z, IVec2(size-1-canonizedCoords.x(), size-1-canonizedCoords.y())); 3104e5c31af7Sopenharmony_ci 3105e5c31af7Sopenharmony_ci if (canonizedCoords.z() == size) 3106e5c31af7Sopenharmony_ci return CubeFaceIntCoords(CUBEFACE_POSITIVE_Z, IVec2(canonizedCoords.x(), size-1-canonizedCoords.y())); 3107e5c31af7Sopenharmony_ci 3108e5c31af7Sopenharmony_ci DE_ASSERT(false); 3109e5c31af7Sopenharmony_ci return CubeFaceIntCoords(CUBEFACE_LAST, IVec2(-1)); 3110e5c31af7Sopenharmony_ci} 3111e5c31af7Sopenharmony_ci 3112e5c31af7Sopenharmony_cistatic void getCubeLinearSamples (const ConstPixelBufferAccess (&faceAccesses)[CUBEFACE_LAST], CubeFace baseFace, float u, float v, int depth, Vec4 (&dst)[4]) 3113e5c31af7Sopenharmony_ci{ 3114e5c31af7Sopenharmony_ci DE_ASSERT(faceAccesses[0].getWidth() == faceAccesses[0].getHeight()); 3115e5c31af7Sopenharmony_ci int size = faceAccesses[0].getWidth(); 3116e5c31af7Sopenharmony_ci int x0 = deFloorFloatToInt32(u-0.5f); 3117e5c31af7Sopenharmony_ci int x1 = x0+1; 3118e5c31af7Sopenharmony_ci int y0 = deFloorFloatToInt32(v-0.5f); 3119e5c31af7Sopenharmony_ci int y1 = y0+1; 3120e5c31af7Sopenharmony_ci IVec2 baseSampleCoords[4] = 3121e5c31af7Sopenharmony_ci { 3122e5c31af7Sopenharmony_ci IVec2(x0, y0), 3123e5c31af7Sopenharmony_ci IVec2(x1, y0), 3124e5c31af7Sopenharmony_ci IVec2(x0, y1), 3125e5c31af7Sopenharmony_ci IVec2(x1, y1) 3126e5c31af7Sopenharmony_ci }; 3127e5c31af7Sopenharmony_ci Vec4 sampleColors[4]; 3128e5c31af7Sopenharmony_ci bool hasBothCoordsOutOfBounds[4]; //!< Whether correctCubeFace() returns CUBEFACE_LAST, i.e. both u and v are out of bounds. 3129e5c31af7Sopenharmony_ci 3130e5c31af7Sopenharmony_ci // Find correct faces and coordinates for out-of-bounds sample coordinates. 3131e5c31af7Sopenharmony_ci 3132e5c31af7Sopenharmony_ci for (int i = 0; i < 4; i++) 3133e5c31af7Sopenharmony_ci { 3134e5c31af7Sopenharmony_ci CubeFaceIntCoords coords = remapCubeEdgeCoords(CubeFaceIntCoords(baseFace, baseSampleCoords[i]), size); 3135e5c31af7Sopenharmony_ci hasBothCoordsOutOfBounds[i] = coords.face == CUBEFACE_LAST; 3136e5c31af7Sopenharmony_ci if (!hasBothCoordsOutOfBounds[i]) 3137e5c31af7Sopenharmony_ci sampleColors[i] = lookup(faceAccesses[coords.face], coords.s, coords.t, depth); 3138e5c31af7Sopenharmony_ci } 3139e5c31af7Sopenharmony_ci 3140e5c31af7Sopenharmony_ci // If a sample was out of bounds in both u and v, we get its color from the average of the three other samples. 3141e5c31af7Sopenharmony_ci // \note This averaging behavior is not required by the GLES3 spec (though it is recommended). GLES3 spec only 3142e5c31af7Sopenharmony_ci // requires that if the three other samples all have the same color, then the doubly-out-of-bounds sample 3143e5c31af7Sopenharmony_ci // must have this color as well. 3144e5c31af7Sopenharmony_ci 3145e5c31af7Sopenharmony_ci { 3146e5c31af7Sopenharmony_ci int bothOutOfBoundsNdx = -1; 3147e5c31af7Sopenharmony_ci for (int i = 0; i < 4; i++) 3148e5c31af7Sopenharmony_ci { 3149e5c31af7Sopenharmony_ci if (hasBothCoordsOutOfBounds[i]) 3150e5c31af7Sopenharmony_ci { 3151e5c31af7Sopenharmony_ci DE_ASSERT(bothOutOfBoundsNdx < 0); // Only one sample can be out of bounds in both u and v. 3152e5c31af7Sopenharmony_ci bothOutOfBoundsNdx = i; 3153e5c31af7Sopenharmony_ci } 3154e5c31af7Sopenharmony_ci } 3155e5c31af7Sopenharmony_ci if (bothOutOfBoundsNdx != -1) 3156e5c31af7Sopenharmony_ci { 3157e5c31af7Sopenharmony_ci sampleColors[bothOutOfBoundsNdx] = Vec4(0.0f); 3158e5c31af7Sopenharmony_ci for (int i = 0; i < 4; i++) 3159e5c31af7Sopenharmony_ci if (i != bothOutOfBoundsNdx) 3160e5c31af7Sopenharmony_ci sampleColors[bothOutOfBoundsNdx] += sampleColors[i]; 3161e5c31af7Sopenharmony_ci 3162e5c31af7Sopenharmony_ci sampleColors[bothOutOfBoundsNdx] = sampleColors[bothOutOfBoundsNdx] * (1.0f/3.0f); 3163e5c31af7Sopenharmony_ci } 3164e5c31af7Sopenharmony_ci } 3165e5c31af7Sopenharmony_ci 3166e5c31af7Sopenharmony_ci for (int i = 0; i < DE_LENGTH_OF_ARRAY(sampleColors); i++) 3167e5c31af7Sopenharmony_ci dst[i] = sampleColors[i]; 3168e5c31af7Sopenharmony_ci} 3169e5c31af7Sopenharmony_ci 3170e5c31af7Sopenharmony_ci// \todo [2014-02-19 pyry] Optimize faceAccesses 3171e5c31af7Sopenharmony_cistatic Vec4 sampleCubeSeamlessLinear (const ConstPixelBufferAccess (&faceAccesses)[CUBEFACE_LAST], CubeFace baseFace, const Sampler& sampler, float s, float t, int depth) 3172e5c31af7Sopenharmony_ci{ 3173e5c31af7Sopenharmony_ci DE_ASSERT(faceAccesses[0].getWidth() == faceAccesses[0].getHeight()); 3174e5c31af7Sopenharmony_ci 3175e5c31af7Sopenharmony_ci int size = faceAccesses[0].getWidth(); 3176e5c31af7Sopenharmony_ci // Non-normalized coordinates. 3177e5c31af7Sopenharmony_ci float u = s; 3178e5c31af7Sopenharmony_ci float v = t; 3179e5c31af7Sopenharmony_ci 3180e5c31af7Sopenharmony_ci if (sampler.normalizedCoords) 3181e5c31af7Sopenharmony_ci { 3182e5c31af7Sopenharmony_ci u = unnormalize(sampler.wrapS, s, size); 3183e5c31af7Sopenharmony_ci v = unnormalize(sampler.wrapT, t, size); 3184e5c31af7Sopenharmony_ci } 3185e5c31af7Sopenharmony_ci 3186e5c31af7Sopenharmony_ci // Get sample colors. 3187e5c31af7Sopenharmony_ci 3188e5c31af7Sopenharmony_ci Vec4 sampleColors[4]; 3189e5c31af7Sopenharmony_ci getCubeLinearSamples(faceAccesses, baseFace, u, v, depth, sampleColors); 3190e5c31af7Sopenharmony_ci 3191e5c31af7Sopenharmony_ci // Interpolate. 3192e5c31af7Sopenharmony_ci 3193e5c31af7Sopenharmony_ci float a = deFloatFrac(u-0.5f); 3194e5c31af7Sopenharmony_ci float b = deFloatFrac(v-0.5f); 3195e5c31af7Sopenharmony_ci 3196e5c31af7Sopenharmony_ci return (sampleColors[0]*(1.0f-a)*(1.0f-b)) + 3197e5c31af7Sopenharmony_ci (sampleColors[1]*( a)*(1.0f-b)) + 3198e5c31af7Sopenharmony_ci (sampleColors[2]*(1.0f-a)*( b)) + 3199e5c31af7Sopenharmony_ci (sampleColors[3]*( a)*( b)); 3200e5c31af7Sopenharmony_ci} 3201e5c31af7Sopenharmony_ci 3202e5c31af7Sopenharmony_cistatic Vec4 sampleLevelArrayCubeSeamless (const ConstPixelBufferAccess* const (&faces)[CUBEFACE_LAST], int numLevels, CubeFace face, const Sampler& sampler, float s, float t, int depth, float lod, ImageViewMinLodParams* minLodParams) 3203e5c31af7Sopenharmony_ci{ 3204e5c31af7Sopenharmony_ci // minLodRelative is used to calculate the image level to sample from, when VK_EXT_image_view_min_lod extension is enabled. 3205e5c31af7Sopenharmony_ci // The value is relative to baseLevel as the Texture*View was created as the baseLevel being level[0]. 3206e5c31af7Sopenharmony_ci const float minLodRelative = (minLodParams != DE_NULL) ? getImageViewMinLod(minLodParams->minLod) - (float)minLodParams->baseLevel : 0.0f; 3207e5c31af7Sopenharmony_ci bool magnified = lod <= sampler.lodThreshold; 3208e5c31af7Sopenharmony_ci Sampler::FilterMode filterMode = magnified ? sampler.magFilter : sampler.minFilter; 3209e5c31af7Sopenharmony_ci 3210e5c31af7Sopenharmony_ci // VK_EXT_image_view_min_lod: Integer Texel Coordinates case (with robustness2 supported) 3211e5c31af7Sopenharmony_ci if (minLodParams != DE_NULL && minLodParams->intTexCoord) 3212e5c31af7Sopenharmony_ci { 3213e5c31af7Sopenharmony_ci if (lod < deFloatFloor(minLodRelative) || lod >= (float)(numLevels - 1)) 3214e5c31af7Sopenharmony_ci return Vec4(0.0f); 3215e5c31af7Sopenharmony_ci 3216e5c31af7Sopenharmony_ci if (s < 0.0f || s > 1.0f || t < 0.0f || t > 1.0f) 3217e5c31af7Sopenharmony_ci return Vec4(0.0f); 3218e5c31af7Sopenharmony_ci } 3219e5c31af7Sopenharmony_ci 3220e5c31af7Sopenharmony_ci switch (filterMode) 3221e5c31af7Sopenharmony_ci { 3222e5c31af7Sopenharmony_ci case Sampler::NEAREST: 3223e5c31af7Sopenharmony_ci { 3224e5c31af7Sopenharmony_ci bool isLinearMipmapMode = magnified && tcu::isSamplerMipmapModeLinear(sampler.minFilter); 3225e5c31af7Sopenharmony_ci const int maxLevel = (int)numLevels - 1; 3226e5c31af7Sopenharmony_ci const int level0 = isLinearMipmapMode ? (int)deFloatFloor(minLodRelative) : deClamp32((int)deFloatCeil(minLodRelative + 0.5f) - 1, 0, maxLevel); 3227e5c31af7Sopenharmony_ci tcu::Vec4 t0 = sampleCubeSeamlessNearest(faces[face][level0], sampler, s, t, depth); 3228e5c31af7Sopenharmony_ci 3229e5c31af7Sopenharmony_ci if (!isLinearMipmapMode) 3230e5c31af7Sopenharmony_ci return t0; 3231e5c31af7Sopenharmony_ci 3232e5c31af7Sopenharmony_ci const float frac = deFloatFrac(minLodRelative); 3233e5c31af7Sopenharmony_ci const int level1 = de::min(level0 + 1, maxLevel); 3234e5c31af7Sopenharmony_ci tcu::Vec4 t1 = sampleCubeSeamlessNearest(faces[face][level1], sampler, s, t, depth); 3235e5c31af7Sopenharmony_ci return t0*(1.0f - frac) + t1*frac; 3236e5c31af7Sopenharmony_ci } 3237e5c31af7Sopenharmony_ci 3238e5c31af7Sopenharmony_ci case Sampler::LINEAR: 3239e5c31af7Sopenharmony_ci { 3240e5c31af7Sopenharmony_ci bool cond = sampler.minFilter == Sampler::NEAREST_MIPMAP_LINEAR || sampler.minFilter == Sampler::LINEAR_MIPMAP_LINEAR; 3241e5c31af7Sopenharmony_ci const int index = cond ? (int)deFloatFloor(minLodRelative) : ((int)deFloatCeil(minLodRelative + 0.5f) - 1u); 3242e5c31af7Sopenharmony_ci ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST]; 3243e5c31af7Sopenharmony_ci for (int i = 0; i < (int)CUBEFACE_LAST; i++) 3244e5c31af7Sopenharmony_ci faceAccesses[i] = faces[i][index]; 3245e5c31af7Sopenharmony_ci 3246e5c31af7Sopenharmony_ci Vec4 result = sampleCubeSeamlessLinear(faceAccesses, face, sampler, s, t, depth); 3247e5c31af7Sopenharmony_ci 3248e5c31af7Sopenharmony_ci 3249e5c31af7Sopenharmony_ci if (cond && ((index + 1) < numLevels) && deFloatFrac(minLodRelative) != 0.0f) 3250e5c31af7Sopenharmony_ci { 3251e5c31af7Sopenharmony_ci // In case of a minLodRelative value with fractional part, we need to ponderate the different sample of N level 3252e5c31af7Sopenharmony_ci // and sample for level N+1 accordingly. 3253e5c31af7Sopenharmony_ci result = result * (1.0f - deFloatFrac(minLodRelative)); 3254e5c31af7Sopenharmony_ci 3255e5c31af7Sopenharmony_ci ConstPixelBufferAccess faceAccessesNext[CUBEFACE_LAST]; 3256e5c31af7Sopenharmony_ci for (int i = 0; i < (int)CUBEFACE_LAST; i++) 3257e5c31af7Sopenharmony_ci faceAccessesNext[i] = faces[i][index + 1]; 3258e5c31af7Sopenharmony_ci result += sampleCubeSeamlessLinear(faceAccesses, face, sampler, s, t, depth) * deFloatFrac(minLodRelative); 3259e5c31af7Sopenharmony_ci } 3260e5c31af7Sopenharmony_ci return result; 3261e5c31af7Sopenharmony_ci } 3262e5c31af7Sopenharmony_ci 3263e5c31af7Sopenharmony_ci case Sampler::NEAREST_MIPMAP_NEAREST: 3264e5c31af7Sopenharmony_ci case Sampler::LINEAR_MIPMAP_NEAREST: 3265e5c31af7Sopenharmony_ci { 3266e5c31af7Sopenharmony_ci if (minLodParams != DE_NULL && !minLodParams->intTexCoord) 3267e5c31af7Sopenharmony_ci lod = de::max(lod, minLodRelative); 3268e5c31af7Sopenharmony_ci 3269e5c31af7Sopenharmony_ci int maxLevel = (int)numLevels-1; 3270e5c31af7Sopenharmony_ci int level = deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel); 3271e5c31af7Sopenharmony_ci Sampler::FilterMode levelFilter = (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST; 3272e5c31af7Sopenharmony_ci 3273e5c31af7Sopenharmony_ci if (levelFilter == Sampler::NEAREST) 3274e5c31af7Sopenharmony_ci return sampleCubeSeamlessNearest(faces[face][level], sampler, s, t, depth); 3275e5c31af7Sopenharmony_ci else 3276e5c31af7Sopenharmony_ci { 3277e5c31af7Sopenharmony_ci DE_ASSERT(levelFilter == Sampler::LINEAR); 3278e5c31af7Sopenharmony_ci 3279e5c31af7Sopenharmony_ci ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST]; 3280e5c31af7Sopenharmony_ci for (int i = 0; i < (int)CUBEFACE_LAST; i++) 3281e5c31af7Sopenharmony_ci faceAccesses[i] = faces[i][level]; 3282e5c31af7Sopenharmony_ci 3283e5c31af7Sopenharmony_ci return sampleCubeSeamlessLinear(faceAccesses, face, sampler, s, t, depth); 3284e5c31af7Sopenharmony_ci } 3285e5c31af7Sopenharmony_ci } 3286e5c31af7Sopenharmony_ci 3287e5c31af7Sopenharmony_ci case Sampler::NEAREST_MIPMAP_LINEAR: 3288e5c31af7Sopenharmony_ci case Sampler::LINEAR_MIPMAP_LINEAR: 3289e5c31af7Sopenharmony_ci { 3290e5c31af7Sopenharmony_ci if (minLodParams != DE_NULL && !minLodParams->intTexCoord) 3291e5c31af7Sopenharmony_ci lod = de::max(lod, minLodRelative); 3292e5c31af7Sopenharmony_ci 3293e5c31af7Sopenharmony_ci int maxLevel = (int)numLevels-1; 3294e5c31af7Sopenharmony_ci int level0 = deClamp32((int)deFloatFloor(lod), 0, maxLevel); 3295e5c31af7Sopenharmony_ci int level1 = de::min(maxLevel, level0 + 1); 3296e5c31af7Sopenharmony_ci Sampler::FilterMode levelFilter = (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST; 3297e5c31af7Sopenharmony_ci float f = deFloatFrac(lod); 3298e5c31af7Sopenharmony_ci Vec4 t0; 3299e5c31af7Sopenharmony_ci Vec4 t1; 3300e5c31af7Sopenharmony_ci 3301e5c31af7Sopenharmony_ci if (levelFilter == Sampler::NEAREST) 3302e5c31af7Sopenharmony_ci { 3303e5c31af7Sopenharmony_ci t0 = sampleCubeSeamlessNearest(faces[face][level0], sampler, s, t, depth); 3304e5c31af7Sopenharmony_ci t1 = sampleCubeSeamlessNearest(faces[face][level1], sampler, s, t, depth); 3305e5c31af7Sopenharmony_ci } 3306e5c31af7Sopenharmony_ci else 3307e5c31af7Sopenharmony_ci { 3308e5c31af7Sopenharmony_ci DE_ASSERT(levelFilter == Sampler::LINEAR); 3309e5c31af7Sopenharmony_ci 3310e5c31af7Sopenharmony_ci ConstPixelBufferAccess faceAccesses0[CUBEFACE_LAST]; 3311e5c31af7Sopenharmony_ci ConstPixelBufferAccess faceAccesses1[CUBEFACE_LAST]; 3312e5c31af7Sopenharmony_ci for (int i = 0; i < (int)CUBEFACE_LAST; i++) 3313e5c31af7Sopenharmony_ci { 3314e5c31af7Sopenharmony_ci faceAccesses0[i] = faces[i][level0]; 3315e5c31af7Sopenharmony_ci faceAccesses1[i] = faces[i][level1]; 3316e5c31af7Sopenharmony_ci } 3317e5c31af7Sopenharmony_ci 3318e5c31af7Sopenharmony_ci t0 = sampleCubeSeamlessLinear(faceAccesses0, face, sampler, s, t, depth); 3319e5c31af7Sopenharmony_ci t1 = sampleCubeSeamlessLinear(faceAccesses1, face, sampler, s, t, depth); 3320e5c31af7Sopenharmony_ci } 3321e5c31af7Sopenharmony_ci 3322e5c31af7Sopenharmony_ci return t0*(1.0f - f) + t1*f; 3323e5c31af7Sopenharmony_ci } 3324e5c31af7Sopenharmony_ci 3325e5c31af7Sopenharmony_ci default: 3326e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 3327e5c31af7Sopenharmony_ci return Vec4(0.0f); 3328e5c31af7Sopenharmony_ci } 3329e5c31af7Sopenharmony_ci} 3330e5c31af7Sopenharmony_ci 3331e5c31af7Sopenharmony_cistatic float sampleCubeSeamlessNearestCompare (const ConstPixelBufferAccess& faceAccess, const Sampler& sampler, float ref, float s, float t, int depth = 0) 3332e5c31af7Sopenharmony_ci{ 3333e5c31af7Sopenharmony_ci Sampler clampingSampler = sampler; 3334e5c31af7Sopenharmony_ci clampingSampler.wrapS = Sampler::CLAMP_TO_EDGE; 3335e5c31af7Sopenharmony_ci clampingSampler.wrapT = Sampler::CLAMP_TO_EDGE; 3336e5c31af7Sopenharmony_ci return faceAccess.sample2DCompare(clampingSampler, Sampler::NEAREST, ref, s, t, IVec3(0, 0, depth)); 3337e5c31af7Sopenharmony_ci} 3338e5c31af7Sopenharmony_ci 3339e5c31af7Sopenharmony_cistatic float sampleCubeSeamlessLinearCompare (const ConstPixelBufferAccess (&faceAccesses)[CUBEFACE_LAST], CubeFace baseFace, const Sampler& sampler, float ref, float s, float t) 3340e5c31af7Sopenharmony_ci{ 3341e5c31af7Sopenharmony_ci DE_ASSERT(faceAccesses[0].getWidth() == faceAccesses[0].getHeight()); 3342e5c31af7Sopenharmony_ci 3343e5c31af7Sopenharmony_ci int size = faceAccesses[0].getWidth(); 3344e5c31af7Sopenharmony_ci // Non-normalized coordinates. 3345e5c31af7Sopenharmony_ci float u = s; 3346e5c31af7Sopenharmony_ci float v = t; 3347e5c31af7Sopenharmony_ci 3348e5c31af7Sopenharmony_ci if (sampler.normalizedCoords) 3349e5c31af7Sopenharmony_ci { 3350e5c31af7Sopenharmony_ci u = unnormalize(sampler.wrapS, s, size); 3351e5c31af7Sopenharmony_ci v = unnormalize(sampler.wrapT, t, size); 3352e5c31af7Sopenharmony_ci } 3353e5c31af7Sopenharmony_ci 3354e5c31af7Sopenharmony_ci int x0 = deFloorFloatToInt32(u-0.5f); 3355e5c31af7Sopenharmony_ci int x1 = x0+1; 3356e5c31af7Sopenharmony_ci int y0 = deFloorFloatToInt32(v-0.5f); 3357e5c31af7Sopenharmony_ci int y1 = y0+1; 3358e5c31af7Sopenharmony_ci IVec2 baseSampleCoords[4] = 3359e5c31af7Sopenharmony_ci { 3360e5c31af7Sopenharmony_ci IVec2(x0, y0), 3361e5c31af7Sopenharmony_ci IVec2(x1, y0), 3362e5c31af7Sopenharmony_ci IVec2(x0, y1), 3363e5c31af7Sopenharmony_ci IVec2(x1, y1) 3364e5c31af7Sopenharmony_ci }; 3365e5c31af7Sopenharmony_ci float sampleRes[4]; 3366e5c31af7Sopenharmony_ci bool hasBothCoordsOutOfBounds[4]; //!< Whether correctCubeFace() returns CUBEFACE_LAST, i.e. both u and v are out of bounds. 3367e5c31af7Sopenharmony_ci 3368e5c31af7Sopenharmony_ci // Find correct faces and coordinates for out-of-bounds sample coordinates. 3369e5c31af7Sopenharmony_ci 3370e5c31af7Sopenharmony_ci for (int i = 0; i < 4; i++) 3371e5c31af7Sopenharmony_ci { 3372e5c31af7Sopenharmony_ci CubeFaceIntCoords coords = remapCubeEdgeCoords(CubeFaceIntCoords(baseFace, baseSampleCoords[i]), size); 3373e5c31af7Sopenharmony_ci hasBothCoordsOutOfBounds[i] = coords.face == CUBEFACE_LAST; 3374e5c31af7Sopenharmony_ci 3375e5c31af7Sopenharmony_ci if (!hasBothCoordsOutOfBounds[i]) 3376e5c31af7Sopenharmony_ci { 3377e5c31af7Sopenharmony_ci const bool isFixedPointDepth = isFixedPointDepthTextureFormat(faceAccesses[coords.face].getFormat()); 3378e5c31af7Sopenharmony_ci 3379e5c31af7Sopenharmony_ci sampleRes[i] = execCompare(faceAccesses[coords.face].getPixel(coords.s, coords.t), sampler.compare, sampler.compareChannel, ref, isFixedPointDepth); 3380e5c31af7Sopenharmony_ci } 3381e5c31af7Sopenharmony_ci } 3382e5c31af7Sopenharmony_ci 3383e5c31af7Sopenharmony_ci // If a sample was out of bounds in both u and v, we get its color from the average of the three other samples. 3384e5c31af7Sopenharmony_ci // \note This averaging behavior is not required by the GLES3 spec (though it is recommended). GLES3 spec only 3385e5c31af7Sopenharmony_ci // requires that if the three other samples all have the same color, then the doubly-out-of-bounds sample 3386e5c31af7Sopenharmony_ci // must have this color as well. 3387e5c31af7Sopenharmony_ci 3388e5c31af7Sopenharmony_ci { 3389e5c31af7Sopenharmony_ci int bothOutOfBoundsNdx = -1; 3390e5c31af7Sopenharmony_ci for (int i = 0; i < 4; i++) 3391e5c31af7Sopenharmony_ci { 3392e5c31af7Sopenharmony_ci if (hasBothCoordsOutOfBounds[i]) 3393e5c31af7Sopenharmony_ci { 3394e5c31af7Sopenharmony_ci DE_ASSERT(bothOutOfBoundsNdx < 0); // Only one sample can be out of bounds in both u and v. 3395e5c31af7Sopenharmony_ci bothOutOfBoundsNdx = i; 3396e5c31af7Sopenharmony_ci } 3397e5c31af7Sopenharmony_ci } 3398e5c31af7Sopenharmony_ci if (bothOutOfBoundsNdx != -1) 3399e5c31af7Sopenharmony_ci { 3400e5c31af7Sopenharmony_ci sampleRes[bothOutOfBoundsNdx] = 0.0f; 3401e5c31af7Sopenharmony_ci for (int i = 0; i < 4; i++) 3402e5c31af7Sopenharmony_ci if (i != bothOutOfBoundsNdx) 3403e5c31af7Sopenharmony_ci sampleRes[bothOutOfBoundsNdx] += sampleRes[i]; 3404e5c31af7Sopenharmony_ci 3405e5c31af7Sopenharmony_ci sampleRes[bothOutOfBoundsNdx] = sampleRes[bothOutOfBoundsNdx] * (1.0f/3.0f); 3406e5c31af7Sopenharmony_ci } 3407e5c31af7Sopenharmony_ci } 3408e5c31af7Sopenharmony_ci 3409e5c31af7Sopenharmony_ci // Interpolate. 3410e5c31af7Sopenharmony_ci 3411e5c31af7Sopenharmony_ci float a = deFloatFrac(u-0.5f); 3412e5c31af7Sopenharmony_ci float b = deFloatFrac(v-0.5f); 3413e5c31af7Sopenharmony_ci 3414e5c31af7Sopenharmony_ci return (sampleRes[0]*(1.0f-a)*(1.0f-b)) + 3415e5c31af7Sopenharmony_ci (sampleRes[1]*( a)*(1.0f-b)) + 3416e5c31af7Sopenharmony_ci (sampleRes[2]*(1.0f-a)*( b)) + 3417e5c31af7Sopenharmony_ci (sampleRes[3]*( a)*( b)); 3418e5c31af7Sopenharmony_ci} 3419e5c31af7Sopenharmony_ci 3420e5c31af7Sopenharmony_cistatic float sampleLevelArrayCubeSeamlessCompare (const ConstPixelBufferAccess* const (&faces)[CUBEFACE_LAST], int numLevels, CubeFace face, const Sampler& sampler, float ref, float s, float t, float lod) 3421e5c31af7Sopenharmony_ci{ 3422e5c31af7Sopenharmony_ci bool magnified = lod <= sampler.lodThreshold; 3423e5c31af7Sopenharmony_ci Sampler::FilterMode filterMode = magnified ? sampler.magFilter : sampler.minFilter; 3424e5c31af7Sopenharmony_ci 3425e5c31af7Sopenharmony_ci switch (filterMode) 3426e5c31af7Sopenharmony_ci { 3427e5c31af7Sopenharmony_ci case Sampler::NEAREST: 3428e5c31af7Sopenharmony_ci return sampleCubeSeamlessNearestCompare(faces[face][0], sampler, ref, s, t); 3429e5c31af7Sopenharmony_ci 3430e5c31af7Sopenharmony_ci case Sampler::LINEAR: 3431e5c31af7Sopenharmony_ci { 3432e5c31af7Sopenharmony_ci ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST]; 3433e5c31af7Sopenharmony_ci for (int i = 0; i < (int)CUBEFACE_LAST; i++) 3434e5c31af7Sopenharmony_ci faceAccesses[i] = faces[i][0]; 3435e5c31af7Sopenharmony_ci 3436e5c31af7Sopenharmony_ci return sampleCubeSeamlessLinearCompare(faceAccesses, face, sampler, ref, s, t); 3437e5c31af7Sopenharmony_ci } 3438e5c31af7Sopenharmony_ci 3439e5c31af7Sopenharmony_ci case Sampler::NEAREST_MIPMAP_NEAREST: 3440e5c31af7Sopenharmony_ci case Sampler::LINEAR_MIPMAP_NEAREST: 3441e5c31af7Sopenharmony_ci { 3442e5c31af7Sopenharmony_ci int maxLevel = (int)numLevels-1; 3443e5c31af7Sopenharmony_ci int level = deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel); 3444e5c31af7Sopenharmony_ci Sampler::FilterMode levelFilter = (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST; 3445e5c31af7Sopenharmony_ci 3446e5c31af7Sopenharmony_ci if (levelFilter == Sampler::NEAREST) 3447e5c31af7Sopenharmony_ci return sampleCubeSeamlessNearestCompare(faces[face][level], sampler, ref, s, t); 3448e5c31af7Sopenharmony_ci else 3449e5c31af7Sopenharmony_ci { 3450e5c31af7Sopenharmony_ci DE_ASSERT(levelFilter == Sampler::LINEAR); 3451e5c31af7Sopenharmony_ci 3452e5c31af7Sopenharmony_ci ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST]; 3453e5c31af7Sopenharmony_ci for (int i = 0; i < (int)CUBEFACE_LAST; i++) 3454e5c31af7Sopenharmony_ci faceAccesses[i] = faces[i][level]; 3455e5c31af7Sopenharmony_ci 3456e5c31af7Sopenharmony_ci return sampleCubeSeamlessLinearCompare(faceAccesses, face, sampler, ref, s, t); 3457e5c31af7Sopenharmony_ci } 3458e5c31af7Sopenharmony_ci } 3459e5c31af7Sopenharmony_ci 3460e5c31af7Sopenharmony_ci case Sampler::NEAREST_MIPMAP_LINEAR: 3461e5c31af7Sopenharmony_ci case Sampler::LINEAR_MIPMAP_LINEAR: 3462e5c31af7Sopenharmony_ci { 3463e5c31af7Sopenharmony_ci int maxLevel = (int)numLevels-1; 3464e5c31af7Sopenharmony_ci int level0 = deClamp32((int)deFloatFloor(lod), 0, maxLevel); 3465e5c31af7Sopenharmony_ci int level1 = de::min(maxLevel, level0 + 1); 3466e5c31af7Sopenharmony_ci Sampler::FilterMode levelFilter = (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST; 3467e5c31af7Sopenharmony_ci float f = deFloatFrac(lod); 3468e5c31af7Sopenharmony_ci float t0; 3469e5c31af7Sopenharmony_ci float t1; 3470e5c31af7Sopenharmony_ci 3471e5c31af7Sopenharmony_ci if (levelFilter == Sampler::NEAREST) 3472e5c31af7Sopenharmony_ci { 3473e5c31af7Sopenharmony_ci t0 = sampleCubeSeamlessNearestCompare(faces[face][level0], sampler, ref, s, t); 3474e5c31af7Sopenharmony_ci t1 = sampleCubeSeamlessNearestCompare(faces[face][level1], sampler, ref, s, t); 3475e5c31af7Sopenharmony_ci } 3476e5c31af7Sopenharmony_ci else 3477e5c31af7Sopenharmony_ci { 3478e5c31af7Sopenharmony_ci DE_ASSERT(levelFilter == Sampler::LINEAR); 3479e5c31af7Sopenharmony_ci 3480e5c31af7Sopenharmony_ci ConstPixelBufferAccess faceAccesses0[CUBEFACE_LAST]; 3481e5c31af7Sopenharmony_ci ConstPixelBufferAccess faceAccesses1[CUBEFACE_LAST]; 3482e5c31af7Sopenharmony_ci for (int i = 0; i < (int)CUBEFACE_LAST; i++) 3483e5c31af7Sopenharmony_ci { 3484e5c31af7Sopenharmony_ci faceAccesses0[i] = faces[i][level0]; 3485e5c31af7Sopenharmony_ci faceAccesses1[i] = faces[i][level1]; 3486e5c31af7Sopenharmony_ci } 3487e5c31af7Sopenharmony_ci 3488e5c31af7Sopenharmony_ci t0 = sampleCubeSeamlessLinearCompare(faceAccesses0, face, sampler, ref, s, t); 3489e5c31af7Sopenharmony_ci t1 = sampleCubeSeamlessLinearCompare(faceAccesses1, face, sampler, ref, s, t); 3490e5c31af7Sopenharmony_ci } 3491e5c31af7Sopenharmony_ci 3492e5c31af7Sopenharmony_ci return t0*(1.0f - f) + t1*f; 3493e5c31af7Sopenharmony_ci } 3494e5c31af7Sopenharmony_ci 3495e5c31af7Sopenharmony_ci default: 3496e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 3497e5c31af7Sopenharmony_ci return 0.0f; 3498e5c31af7Sopenharmony_ci } 3499e5c31af7Sopenharmony_ci} 3500e5c31af7Sopenharmony_ci 3501e5c31af7Sopenharmony_ci// Cube map array sampling 3502e5c31af7Sopenharmony_ci 3503e5c31af7Sopenharmony_cistatic inline ConstPixelBufferAccess getCubeArrayFaceAccess (const ConstPixelBufferAccess* const levels, int levelNdx, int slice, CubeFace face) 3504e5c31af7Sopenharmony_ci{ 3505e5c31af7Sopenharmony_ci const ConstPixelBufferAccess& level = levels[levelNdx]; 3506e5c31af7Sopenharmony_ci const int depth = (slice * 6) + getCubeArrayFaceIndex(face); 3507e5c31af7Sopenharmony_ci 3508e5c31af7Sopenharmony_ci return getSubregion(level, 0, 0, depth, level.getWidth(), level.getHeight(), 1); 3509e5c31af7Sopenharmony_ci} 3510e5c31af7Sopenharmony_ci 3511e5c31af7Sopenharmony_cistatic Vec4 sampleCubeArraySeamless (const ConstPixelBufferAccess* const levels, int numLevels, int slice, CubeFace face, const Sampler& sampler, float s, float t, float lod) 3512e5c31af7Sopenharmony_ci{ 3513e5c31af7Sopenharmony_ci const int faceDepth = (slice * 6) + getCubeArrayFaceIndex(face); 3514e5c31af7Sopenharmony_ci const bool magnified = lod <= sampler.lodThreshold; 3515e5c31af7Sopenharmony_ci const Sampler::FilterMode filterMode = magnified ? sampler.magFilter : sampler.minFilter; 3516e5c31af7Sopenharmony_ci 3517e5c31af7Sopenharmony_ci switch (filterMode) 3518e5c31af7Sopenharmony_ci { 3519e5c31af7Sopenharmony_ci case Sampler::NEAREST: 3520e5c31af7Sopenharmony_ci return sampleCubeSeamlessNearest(levels[0], sampler, s, t, faceDepth); 3521e5c31af7Sopenharmony_ci 3522e5c31af7Sopenharmony_ci case Sampler::LINEAR: 3523e5c31af7Sopenharmony_ci { 3524e5c31af7Sopenharmony_ci ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST]; 3525e5c31af7Sopenharmony_ci for (int i = 0; i < (int)CUBEFACE_LAST; i++) 3526e5c31af7Sopenharmony_ci faceAccesses[i] = getCubeArrayFaceAccess(levels, 0, slice, (CubeFace)i); 3527e5c31af7Sopenharmony_ci 3528e5c31af7Sopenharmony_ci return sampleCubeSeamlessLinear(faceAccesses, face, sampler, s, t, 0); 3529e5c31af7Sopenharmony_ci } 3530e5c31af7Sopenharmony_ci 3531e5c31af7Sopenharmony_ci case Sampler::NEAREST_MIPMAP_NEAREST: 3532e5c31af7Sopenharmony_ci case Sampler::LINEAR_MIPMAP_NEAREST: 3533e5c31af7Sopenharmony_ci { 3534e5c31af7Sopenharmony_ci int maxLevel = (int)numLevels-1; 3535e5c31af7Sopenharmony_ci int level = deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel); 3536e5c31af7Sopenharmony_ci Sampler::FilterMode levelFilter = (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST; 3537e5c31af7Sopenharmony_ci 3538e5c31af7Sopenharmony_ci if (levelFilter == Sampler::NEAREST) 3539e5c31af7Sopenharmony_ci return sampleCubeSeamlessNearest(levels[level], sampler, s, t, faceDepth); 3540e5c31af7Sopenharmony_ci else 3541e5c31af7Sopenharmony_ci { 3542e5c31af7Sopenharmony_ci DE_ASSERT(levelFilter == Sampler::LINEAR); 3543e5c31af7Sopenharmony_ci 3544e5c31af7Sopenharmony_ci ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST]; 3545e5c31af7Sopenharmony_ci for (int i = 0; i < (int)CUBEFACE_LAST; i++) 3546e5c31af7Sopenharmony_ci faceAccesses[i] = getCubeArrayFaceAccess(levels, level, slice, (CubeFace)i); 3547e5c31af7Sopenharmony_ci 3548e5c31af7Sopenharmony_ci return sampleCubeSeamlessLinear(faceAccesses, face, sampler, s, t, 0); 3549e5c31af7Sopenharmony_ci } 3550e5c31af7Sopenharmony_ci } 3551e5c31af7Sopenharmony_ci 3552e5c31af7Sopenharmony_ci case Sampler::NEAREST_MIPMAP_LINEAR: 3553e5c31af7Sopenharmony_ci case Sampler::LINEAR_MIPMAP_LINEAR: 3554e5c31af7Sopenharmony_ci { 3555e5c31af7Sopenharmony_ci int maxLevel = (int)numLevels-1; 3556e5c31af7Sopenharmony_ci int level0 = deClamp32((int)deFloatFloor(lod), 0, maxLevel); 3557e5c31af7Sopenharmony_ci int level1 = de::min(maxLevel, level0 + 1); 3558e5c31af7Sopenharmony_ci Sampler::FilterMode levelFilter = (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST; 3559e5c31af7Sopenharmony_ci float f = deFloatFrac(lod); 3560e5c31af7Sopenharmony_ci Vec4 t0; 3561e5c31af7Sopenharmony_ci Vec4 t1; 3562e5c31af7Sopenharmony_ci 3563e5c31af7Sopenharmony_ci if (levelFilter == Sampler::NEAREST) 3564e5c31af7Sopenharmony_ci { 3565e5c31af7Sopenharmony_ci t0 = sampleCubeSeamlessNearest(levels[level0], sampler, s, t, faceDepth); 3566e5c31af7Sopenharmony_ci t1 = sampleCubeSeamlessNearest(levels[level1], sampler, s, t, faceDepth); 3567e5c31af7Sopenharmony_ci } 3568e5c31af7Sopenharmony_ci else 3569e5c31af7Sopenharmony_ci { 3570e5c31af7Sopenharmony_ci DE_ASSERT(levelFilter == Sampler::LINEAR); 3571e5c31af7Sopenharmony_ci 3572e5c31af7Sopenharmony_ci ConstPixelBufferAccess faceAccesses0[CUBEFACE_LAST]; 3573e5c31af7Sopenharmony_ci ConstPixelBufferAccess faceAccesses1[CUBEFACE_LAST]; 3574e5c31af7Sopenharmony_ci for (int i = 0; i < (int)CUBEFACE_LAST; i++) 3575e5c31af7Sopenharmony_ci { 3576e5c31af7Sopenharmony_ci faceAccesses0[i] = getCubeArrayFaceAccess(levels, level0, slice, (CubeFace)i); 3577e5c31af7Sopenharmony_ci faceAccesses1[i] = getCubeArrayFaceAccess(levels, level1, slice, (CubeFace)i); 3578e5c31af7Sopenharmony_ci } 3579e5c31af7Sopenharmony_ci 3580e5c31af7Sopenharmony_ci t0 = sampleCubeSeamlessLinear(faceAccesses0, face, sampler, s, t, 0); 3581e5c31af7Sopenharmony_ci t1 = sampleCubeSeamlessLinear(faceAccesses1, face, sampler, s, t, 0); 3582e5c31af7Sopenharmony_ci } 3583e5c31af7Sopenharmony_ci 3584e5c31af7Sopenharmony_ci return t0*(1.0f - f) + t1*f; 3585e5c31af7Sopenharmony_ci } 3586e5c31af7Sopenharmony_ci 3587e5c31af7Sopenharmony_ci default: 3588e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 3589e5c31af7Sopenharmony_ci return Vec4(0.0f); 3590e5c31af7Sopenharmony_ci } 3591e5c31af7Sopenharmony_ci} 3592e5c31af7Sopenharmony_ci 3593e5c31af7Sopenharmony_cistatic float sampleCubeArraySeamlessCompare (const ConstPixelBufferAccess* const levels, int numLevels, int slice, CubeFace face, const Sampler& sampler, float ref, float s, float t, float lod) 3594e5c31af7Sopenharmony_ci{ 3595e5c31af7Sopenharmony_ci const int faceDepth = (slice * 6) + getCubeArrayFaceIndex(face); 3596e5c31af7Sopenharmony_ci const bool magnified = lod <= sampler.lodThreshold; 3597e5c31af7Sopenharmony_ci Sampler::FilterMode filterMode = magnified ? sampler.magFilter : sampler.minFilter; 3598e5c31af7Sopenharmony_ci 3599e5c31af7Sopenharmony_ci switch (filterMode) 3600e5c31af7Sopenharmony_ci { 3601e5c31af7Sopenharmony_ci case Sampler::NEAREST: 3602e5c31af7Sopenharmony_ci return sampleCubeSeamlessNearestCompare(levels[0], sampler, ref, s, t, faceDepth); 3603e5c31af7Sopenharmony_ci 3604e5c31af7Sopenharmony_ci case Sampler::LINEAR: 3605e5c31af7Sopenharmony_ci { 3606e5c31af7Sopenharmony_ci ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST]; 3607e5c31af7Sopenharmony_ci for (int i = 0; i < (int)CUBEFACE_LAST; i++) 3608e5c31af7Sopenharmony_ci faceAccesses[i] = getCubeArrayFaceAccess(levels, 0, slice, (CubeFace)i); 3609e5c31af7Sopenharmony_ci 3610e5c31af7Sopenharmony_ci return sampleCubeSeamlessLinearCompare(faceAccesses, face, sampler, ref, s, t); 3611e5c31af7Sopenharmony_ci } 3612e5c31af7Sopenharmony_ci 3613e5c31af7Sopenharmony_ci case Sampler::NEAREST_MIPMAP_NEAREST: 3614e5c31af7Sopenharmony_ci case Sampler::LINEAR_MIPMAP_NEAREST: 3615e5c31af7Sopenharmony_ci { 3616e5c31af7Sopenharmony_ci int maxLevel = (int)numLevels-1; 3617e5c31af7Sopenharmony_ci int level = deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel); 3618e5c31af7Sopenharmony_ci Sampler::FilterMode levelFilter = (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST; 3619e5c31af7Sopenharmony_ci 3620e5c31af7Sopenharmony_ci if (levelFilter == Sampler::NEAREST) 3621e5c31af7Sopenharmony_ci return sampleCubeSeamlessNearestCompare(levels[level], sampler, ref, s, t, faceDepth); 3622e5c31af7Sopenharmony_ci else 3623e5c31af7Sopenharmony_ci { 3624e5c31af7Sopenharmony_ci DE_ASSERT(levelFilter == Sampler::LINEAR); 3625e5c31af7Sopenharmony_ci 3626e5c31af7Sopenharmony_ci ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST]; 3627e5c31af7Sopenharmony_ci for (int i = 0; i < (int)CUBEFACE_LAST; i++) 3628e5c31af7Sopenharmony_ci faceAccesses[i] = getCubeArrayFaceAccess(levels, level, slice, (CubeFace)i); 3629e5c31af7Sopenharmony_ci 3630e5c31af7Sopenharmony_ci return sampleCubeSeamlessLinearCompare(faceAccesses, face, sampler, ref, s, t); 3631e5c31af7Sopenharmony_ci } 3632e5c31af7Sopenharmony_ci } 3633e5c31af7Sopenharmony_ci 3634e5c31af7Sopenharmony_ci case Sampler::NEAREST_MIPMAP_LINEAR: 3635e5c31af7Sopenharmony_ci case Sampler::LINEAR_MIPMAP_LINEAR: 3636e5c31af7Sopenharmony_ci { 3637e5c31af7Sopenharmony_ci int maxLevel = (int)numLevels-1; 3638e5c31af7Sopenharmony_ci int level0 = deClamp32((int)deFloatFloor(lod), 0, maxLevel); 3639e5c31af7Sopenharmony_ci int level1 = de::min(maxLevel, level0 + 1); 3640e5c31af7Sopenharmony_ci Sampler::FilterMode levelFilter = (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST; 3641e5c31af7Sopenharmony_ci float f = deFloatFrac(lod); 3642e5c31af7Sopenharmony_ci float t0; 3643e5c31af7Sopenharmony_ci float t1; 3644e5c31af7Sopenharmony_ci 3645e5c31af7Sopenharmony_ci if (levelFilter == Sampler::NEAREST) 3646e5c31af7Sopenharmony_ci { 3647e5c31af7Sopenharmony_ci t0 = sampleCubeSeamlessNearestCompare(levels[level0], sampler, ref, s, t, faceDepth); 3648e5c31af7Sopenharmony_ci t1 = sampleCubeSeamlessNearestCompare(levels[level1], sampler, ref, s, t, faceDepth); 3649e5c31af7Sopenharmony_ci } 3650e5c31af7Sopenharmony_ci else 3651e5c31af7Sopenharmony_ci { 3652e5c31af7Sopenharmony_ci DE_ASSERT(levelFilter == Sampler::LINEAR); 3653e5c31af7Sopenharmony_ci 3654e5c31af7Sopenharmony_ci ConstPixelBufferAccess faceAccesses0[CUBEFACE_LAST]; 3655e5c31af7Sopenharmony_ci ConstPixelBufferAccess faceAccesses1[CUBEFACE_LAST]; 3656e5c31af7Sopenharmony_ci for (int i = 0; i < (int)CUBEFACE_LAST; i++) 3657e5c31af7Sopenharmony_ci { 3658e5c31af7Sopenharmony_ci faceAccesses0[i] = getCubeArrayFaceAccess(levels, level0, slice, (CubeFace)i); 3659e5c31af7Sopenharmony_ci faceAccesses1[i] = getCubeArrayFaceAccess(levels, level1, slice, (CubeFace)i); 3660e5c31af7Sopenharmony_ci } 3661e5c31af7Sopenharmony_ci 3662e5c31af7Sopenharmony_ci t0 = sampleCubeSeamlessLinearCompare(faceAccesses0, face, sampler, ref, s, t); 3663e5c31af7Sopenharmony_ci t1 = sampleCubeSeamlessLinearCompare(faceAccesses1, face, sampler, ref, s, t); 3664e5c31af7Sopenharmony_ci } 3665e5c31af7Sopenharmony_ci 3666e5c31af7Sopenharmony_ci return t0*(1.0f - f) + t1*f; 3667e5c31af7Sopenharmony_ci } 3668e5c31af7Sopenharmony_ci 3669e5c31af7Sopenharmony_ci default: 3670e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 3671e5c31af7Sopenharmony_ci return 0.0f; 3672e5c31af7Sopenharmony_ci } 3673e5c31af7Sopenharmony_ci} 3674e5c31af7Sopenharmony_ci 3675e5c31af7Sopenharmony_ciinline int computeMipPyramidLevels (int size) 3676e5c31af7Sopenharmony_ci{ 3677e5c31af7Sopenharmony_ci return deLog2Floor32(size)+1; 3678e5c31af7Sopenharmony_ci} 3679e5c31af7Sopenharmony_ci 3680e5c31af7Sopenharmony_ciinline int computeMipPyramidLevels (int width, int height) 3681e5c31af7Sopenharmony_ci{ 3682e5c31af7Sopenharmony_ci return deLog2Floor32(de::max(width, height))+1; 3683e5c31af7Sopenharmony_ci} 3684e5c31af7Sopenharmony_ci 3685e5c31af7Sopenharmony_ciinline int computeMipPyramidLevels (int width, int height, int depth) 3686e5c31af7Sopenharmony_ci{ 3687e5c31af7Sopenharmony_ci return deLog2Floor32(de::max(width, de::max(height, depth)))+1; 3688e5c31af7Sopenharmony_ci} 3689e5c31af7Sopenharmony_ci 3690e5c31af7Sopenharmony_ciinline int getMipPyramidLevelSize (int baseLevelSize, int levelNdx) 3691e5c31af7Sopenharmony_ci{ 3692e5c31af7Sopenharmony_ci return de::max(baseLevelSize >> levelNdx, 1); 3693e5c31af7Sopenharmony_ci} 3694e5c31af7Sopenharmony_ci 3695e5c31af7Sopenharmony_ci// TextureLevelPyramid 3696e5c31af7Sopenharmony_ci 3697e5c31af7Sopenharmony_ciTextureLevelPyramid::TextureLevelPyramid (const TextureFormat& format, int numLevels) 3698e5c31af7Sopenharmony_ci : m_format (format) 3699e5c31af7Sopenharmony_ci , m_data (numLevels) 3700e5c31af7Sopenharmony_ci , m_access (numLevels) 3701e5c31af7Sopenharmony_ci{ 3702e5c31af7Sopenharmony_ci} 3703e5c31af7Sopenharmony_ci 3704e5c31af7Sopenharmony_ciTextureLevelPyramid::TextureLevelPyramid (const TextureLevelPyramid& other) 3705e5c31af7Sopenharmony_ci : m_format (other.m_format) 3706e5c31af7Sopenharmony_ci , m_data (other.getNumLevels()) 3707e5c31af7Sopenharmony_ci , m_access (other.getNumLevels()) 3708e5c31af7Sopenharmony_ci{ 3709e5c31af7Sopenharmony_ci for (int levelNdx = 0; levelNdx < other.getNumLevels(); levelNdx++) 3710e5c31af7Sopenharmony_ci { 3711e5c31af7Sopenharmony_ci if (!other.isLevelEmpty(levelNdx)) 3712e5c31af7Sopenharmony_ci { 3713e5c31af7Sopenharmony_ci const tcu::ConstPixelBufferAccess& srcLevel = other.getLevel(levelNdx); 3714e5c31af7Sopenharmony_ci 3715e5c31af7Sopenharmony_ci m_data[levelNdx] = other.m_data[levelNdx]; 3716e5c31af7Sopenharmony_ci m_access[levelNdx] = PixelBufferAccess(srcLevel.getFormat(), srcLevel.getWidth(), srcLevel.getHeight(), srcLevel.getDepth(), m_data[levelNdx].getPtr()); 3717e5c31af7Sopenharmony_ci } 3718e5c31af7Sopenharmony_ci } 3719e5c31af7Sopenharmony_ci} 3720e5c31af7Sopenharmony_ci 3721e5c31af7Sopenharmony_ciTextureLevelPyramid& TextureLevelPyramid::operator= (const TextureLevelPyramid& other) 3722e5c31af7Sopenharmony_ci{ 3723e5c31af7Sopenharmony_ci if (this == &other) 3724e5c31af7Sopenharmony_ci return *this; 3725e5c31af7Sopenharmony_ci 3726e5c31af7Sopenharmony_ci m_format = other.m_format; 3727e5c31af7Sopenharmony_ci m_data.resize(other.getNumLevels()); 3728e5c31af7Sopenharmony_ci m_access.resize(other.getNumLevels()); 3729e5c31af7Sopenharmony_ci 3730e5c31af7Sopenharmony_ci for (int levelNdx = 0; levelNdx < other.getNumLevels(); levelNdx++) 3731e5c31af7Sopenharmony_ci { 3732e5c31af7Sopenharmony_ci if (!other.isLevelEmpty(levelNdx)) 3733e5c31af7Sopenharmony_ci { 3734e5c31af7Sopenharmony_ci const tcu::ConstPixelBufferAccess& srcLevel = other.getLevel(levelNdx); 3735e5c31af7Sopenharmony_ci 3736e5c31af7Sopenharmony_ci m_data[levelNdx] = other.m_data[levelNdx]; 3737e5c31af7Sopenharmony_ci m_access[levelNdx] = PixelBufferAccess(srcLevel.getFormat(), srcLevel.getWidth(), srcLevel.getHeight(), srcLevel.getDepth(), m_data[levelNdx].getPtr()); 3738e5c31af7Sopenharmony_ci } 3739e5c31af7Sopenharmony_ci else if (!isLevelEmpty(levelNdx)) 3740e5c31af7Sopenharmony_ci clearLevel(levelNdx); 3741e5c31af7Sopenharmony_ci } 3742e5c31af7Sopenharmony_ci 3743e5c31af7Sopenharmony_ci return *this; 3744e5c31af7Sopenharmony_ci} 3745e5c31af7Sopenharmony_ci 3746e5c31af7Sopenharmony_ciTextureLevelPyramid::~TextureLevelPyramid (void) 3747e5c31af7Sopenharmony_ci{ 3748e5c31af7Sopenharmony_ci} 3749e5c31af7Sopenharmony_ci 3750e5c31af7Sopenharmony_civoid TextureLevelPyramid::allocLevel (int levelNdx, int width, int height, int depth) 3751e5c31af7Sopenharmony_ci{ 3752e5c31af7Sopenharmony_ci const int size = m_format.getPixelSize()*width*height*depth; 3753e5c31af7Sopenharmony_ci 3754e5c31af7Sopenharmony_ci DE_ASSERT(isLevelEmpty(levelNdx)); 3755e5c31af7Sopenharmony_ci 3756e5c31af7Sopenharmony_ci m_data[levelNdx].setStorage(size); 3757e5c31af7Sopenharmony_ci m_access[levelNdx] = PixelBufferAccess(m_format, width, height, depth, m_data[levelNdx].getPtr()); 3758e5c31af7Sopenharmony_ci} 3759e5c31af7Sopenharmony_ci 3760e5c31af7Sopenharmony_civoid TextureLevelPyramid::clearLevel (int levelNdx) 3761e5c31af7Sopenharmony_ci{ 3762e5c31af7Sopenharmony_ci DE_ASSERT(!isLevelEmpty(levelNdx)); 3763e5c31af7Sopenharmony_ci 3764e5c31af7Sopenharmony_ci m_data[levelNdx].clear(); 3765e5c31af7Sopenharmony_ci m_access[levelNdx] = PixelBufferAccess(); 3766e5c31af7Sopenharmony_ci} 3767e5c31af7Sopenharmony_ci 3768e5c31af7Sopenharmony_ci// Texture1D 3769e5c31af7Sopenharmony_ci 3770e5c31af7Sopenharmony_ciTexture1D::Texture1D (const TextureFormat& format, int width) 3771e5c31af7Sopenharmony_ci : TextureLevelPyramid (format, computeMipPyramidLevels(width)) 3772e5c31af7Sopenharmony_ci , m_width (width) 3773e5c31af7Sopenharmony_ci , m_view (getNumLevels(), getLevels()) 3774e5c31af7Sopenharmony_ci{ 3775e5c31af7Sopenharmony_ci} 3776e5c31af7Sopenharmony_ci 3777e5c31af7Sopenharmony_ciTexture1D::Texture1D (const Texture1D& other) 3778e5c31af7Sopenharmony_ci : TextureLevelPyramid (other) 3779e5c31af7Sopenharmony_ci , m_width (other.m_width) 3780e5c31af7Sopenharmony_ci , m_view (getNumLevels(), getLevels()) 3781e5c31af7Sopenharmony_ci{ 3782e5c31af7Sopenharmony_ci} 3783e5c31af7Sopenharmony_ci 3784e5c31af7Sopenharmony_ciTexture1D& Texture1D::operator= (const Texture1D& other) 3785e5c31af7Sopenharmony_ci{ 3786e5c31af7Sopenharmony_ci if (this == &other) 3787e5c31af7Sopenharmony_ci return *this; 3788e5c31af7Sopenharmony_ci 3789e5c31af7Sopenharmony_ci TextureLevelPyramid::operator=(other); 3790e5c31af7Sopenharmony_ci 3791e5c31af7Sopenharmony_ci m_width = other.m_width; 3792e5c31af7Sopenharmony_ci m_view = Texture1DView(getNumLevels(), getLevels()); 3793e5c31af7Sopenharmony_ci 3794e5c31af7Sopenharmony_ci return *this; 3795e5c31af7Sopenharmony_ci} 3796e5c31af7Sopenharmony_ci 3797e5c31af7Sopenharmony_ciTexture1D::~Texture1D (void) 3798e5c31af7Sopenharmony_ci{ 3799e5c31af7Sopenharmony_ci} 3800e5c31af7Sopenharmony_ci 3801e5c31af7Sopenharmony_civoid Texture1D::allocLevel (int levelNdx) 3802e5c31af7Sopenharmony_ci{ 3803e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels())); 3804e5c31af7Sopenharmony_ci 3805e5c31af7Sopenharmony_ci const int width = getMipPyramidLevelSize(m_width, levelNdx); 3806e5c31af7Sopenharmony_ci 3807e5c31af7Sopenharmony_ci TextureLevelPyramid::allocLevel(levelNdx, width, 1, 1); 3808e5c31af7Sopenharmony_ci} 3809e5c31af7Sopenharmony_ci 3810e5c31af7Sopenharmony_ci// Texture2D 3811e5c31af7Sopenharmony_ci 3812e5c31af7Sopenharmony_ciTexture2D::Texture2D (const TextureFormat& format, int width, int height, bool es2) 3813e5c31af7Sopenharmony_ci : TextureLevelPyramid (format, computeMipPyramidLevels(width, height)) 3814e5c31af7Sopenharmony_ci , m_yuvTextureUsed (false) 3815e5c31af7Sopenharmony_ci , m_width (width) 3816e5c31af7Sopenharmony_ci , m_height (height) 3817e5c31af7Sopenharmony_ci , m_view (getNumLevels(), getLevels(), es2) 3818e5c31af7Sopenharmony_ci{ 3819e5c31af7Sopenharmony_ci} 3820e5c31af7Sopenharmony_ci 3821e5c31af7Sopenharmony_ciTexture2D::Texture2D (const TextureFormat& format, int width, int height, int mipmaps) 3822e5c31af7Sopenharmony_ci : TextureLevelPyramid (format, mipmaps) 3823e5c31af7Sopenharmony_ci , m_yuvTextureUsed (false) 3824e5c31af7Sopenharmony_ci , m_width (width) 3825e5c31af7Sopenharmony_ci , m_height (height) 3826e5c31af7Sopenharmony_ci , m_view (getNumLevels(), getLevels()) 3827e5c31af7Sopenharmony_ci{ 3828e5c31af7Sopenharmony_ci} 3829e5c31af7Sopenharmony_ci 3830e5c31af7Sopenharmony_ciTexture2D::Texture2D (const Texture2D& other) 3831e5c31af7Sopenharmony_ci : TextureLevelPyramid (other) 3832e5c31af7Sopenharmony_ci , m_yuvTextureUsed (other.m_yuvTextureUsed) 3833e5c31af7Sopenharmony_ci , m_width (other.m_width) 3834e5c31af7Sopenharmony_ci , m_height (other.m_height) 3835e5c31af7Sopenharmony_ci , m_view (getNumLevels(), getLevels(), other.getView().isES2()) 3836e5c31af7Sopenharmony_ci{ 3837e5c31af7Sopenharmony_ci} 3838e5c31af7Sopenharmony_ci 3839e5c31af7Sopenharmony_ciTexture2D& Texture2D::operator= (const Texture2D& other) 3840e5c31af7Sopenharmony_ci{ 3841e5c31af7Sopenharmony_ci if (this == &other) 3842e5c31af7Sopenharmony_ci return *this; 3843e5c31af7Sopenharmony_ci 3844e5c31af7Sopenharmony_ci TextureLevelPyramid::operator=(other); 3845e5c31af7Sopenharmony_ci 3846e5c31af7Sopenharmony_ci m_width = other.m_width; 3847e5c31af7Sopenharmony_ci m_height = other.m_height; 3848e5c31af7Sopenharmony_ci m_view = Texture2DView(getNumLevels(), getLevels(), other.getView().isES2()); 3849e5c31af7Sopenharmony_ci m_yuvTextureUsed = other.m_yuvTextureUsed; 3850e5c31af7Sopenharmony_ci return *this; 3851e5c31af7Sopenharmony_ci} 3852e5c31af7Sopenharmony_ci 3853e5c31af7Sopenharmony_ciTexture2D::~Texture2D (void) 3854e5c31af7Sopenharmony_ci{ 3855e5c31af7Sopenharmony_ci} 3856e5c31af7Sopenharmony_ci 3857e5c31af7Sopenharmony_civoid Texture2D::allocLevel (int levelNdx) 3858e5c31af7Sopenharmony_ci{ 3859e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels())); 3860e5c31af7Sopenharmony_ci 3861e5c31af7Sopenharmony_ci const int width = getMipPyramidLevelSize(m_width, levelNdx); 3862e5c31af7Sopenharmony_ci const int height = getMipPyramidLevelSize(m_height, levelNdx); 3863e5c31af7Sopenharmony_ci 3864e5c31af7Sopenharmony_ci TextureLevelPyramid::allocLevel(levelNdx, width, height, 1); 3865e5c31af7Sopenharmony_ci} 3866e5c31af7Sopenharmony_ci 3867e5c31af7Sopenharmony_ci// TextureCubeView 3868e5c31af7Sopenharmony_ci 3869e5c31af7Sopenharmony_ciTextureCubeView::TextureCubeView (void) 3870e5c31af7Sopenharmony_ci : m_numLevels(0) 3871e5c31af7Sopenharmony_ci , m_es2(false) 3872e5c31af7Sopenharmony_ci , m_minLodParams (DE_NULL) 3873e5c31af7Sopenharmony_ci{ 3874e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < CUBEFACE_LAST; ndx++) 3875e5c31af7Sopenharmony_ci m_levels[ndx] = DE_NULL; 3876e5c31af7Sopenharmony_ci} 3877e5c31af7Sopenharmony_ci 3878e5c31af7Sopenharmony_ciTextureCubeView::TextureCubeView (int numLevels, const ConstPixelBufferAccess* const (&levels) [CUBEFACE_LAST], bool es2, ImageViewMinLodParams *minLodParams) 3879e5c31af7Sopenharmony_ci : m_numLevels(numLevels) 3880e5c31af7Sopenharmony_ci , m_es2(es2) 3881e5c31af7Sopenharmony_ci , m_minLodParams(minLodParams) 3882e5c31af7Sopenharmony_ci{ 3883e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < CUBEFACE_LAST; ndx++) 3884e5c31af7Sopenharmony_ci m_levels[ndx] = levels[ndx]; 3885e5c31af7Sopenharmony_ci} 3886e5c31af7Sopenharmony_ci 3887e5c31af7Sopenharmony_citcu::Vec4 TextureCubeView::sample (const Sampler& sampler, float s, float t, float r, float lod) const 3888e5c31af7Sopenharmony_ci{ 3889e5c31af7Sopenharmony_ci DE_ASSERT(sampler.compare == Sampler::COMPAREMODE_NONE); 3890e5c31af7Sopenharmony_ci 3891e5c31af7Sopenharmony_ci // Computes (face, s, t). 3892e5c31af7Sopenharmony_ci const CubeFaceFloatCoords coords = getCubeFaceCoords(Vec3(s, t, r)); 3893e5c31af7Sopenharmony_ci if (sampler.seamlessCubeMap) 3894e5c31af7Sopenharmony_ci return sampleLevelArrayCubeSeamless(m_levels, m_numLevels, coords.face, sampler, coords.s, coords.t, 0 /* depth */, lod, m_minLodParams); 3895e5c31af7Sopenharmony_ci else 3896e5c31af7Sopenharmony_ci return sampleLevelArray2D(m_levels[coords.face], m_numLevels, sampler, coords.s, coords.t, 0 /* depth */, lod, m_es2, m_minLodParams); 3897e5c31af7Sopenharmony_ci} 3898e5c31af7Sopenharmony_ci 3899e5c31af7Sopenharmony_cifloat TextureCubeView::sampleCompare (const Sampler& sampler, float ref, float s, float t, float r, float lod) const 3900e5c31af7Sopenharmony_ci{ 3901e5c31af7Sopenharmony_ci DE_ASSERT(sampler.compare != Sampler::COMPAREMODE_NONE); 3902e5c31af7Sopenharmony_ci 3903e5c31af7Sopenharmony_ci // Computes (face, s, t). 3904e5c31af7Sopenharmony_ci const CubeFaceFloatCoords coords = getCubeFaceCoords(Vec3(s, t, r)); 3905e5c31af7Sopenharmony_ci if (sampler.seamlessCubeMap) 3906e5c31af7Sopenharmony_ci return sampleLevelArrayCubeSeamlessCompare(m_levels, m_numLevels, coords.face, sampler, ref, coords.s, coords.t, lod); 3907e5c31af7Sopenharmony_ci else 3908e5c31af7Sopenharmony_ci return sampleLevelArray2DCompare(m_levels[coords.face], m_numLevels, sampler, ref, coords.s, coords.t, lod, IVec3(0, 0, 0)); 3909e5c31af7Sopenharmony_ci} 3910e5c31af7Sopenharmony_ci 3911e5c31af7Sopenharmony_ciVec4 TextureCubeView::gather (const Sampler& sampler, float s, float t, float r, int componentNdx) const 3912e5c31af7Sopenharmony_ci{ 3913e5c31af7Sopenharmony_ci DE_ASSERT(sampler.compare == Sampler::COMPAREMODE_NONE); 3914e5c31af7Sopenharmony_ci 3915e5c31af7Sopenharmony_ci ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST]; 3916e5c31af7Sopenharmony_ci for (int i = 0; i < (int)CUBEFACE_LAST; i++) 3917e5c31af7Sopenharmony_ci faceAccesses[i] = m_levels[i][0]; 3918e5c31af7Sopenharmony_ci 3919e5c31af7Sopenharmony_ci const CubeFaceFloatCoords coords = getCubeFaceCoords(Vec3(s, t, r)); 3920e5c31af7Sopenharmony_ci const int size = faceAccesses[0].getWidth(); 3921e5c31af7Sopenharmony_ci // Non-normalized coordinates. 3922e5c31af7Sopenharmony_ci float u = coords.s; 3923e5c31af7Sopenharmony_ci float v = coords.t; 3924e5c31af7Sopenharmony_ci 3925e5c31af7Sopenharmony_ci if (sampler.normalizedCoords) 3926e5c31af7Sopenharmony_ci { 3927e5c31af7Sopenharmony_ci u = unnormalize(sampler.wrapS, coords.s, size); 3928e5c31af7Sopenharmony_ci v = unnormalize(sampler.wrapT, coords.t, size); 3929e5c31af7Sopenharmony_ci } 3930e5c31af7Sopenharmony_ci 3931e5c31af7Sopenharmony_ci Vec4 sampleColors[4]; 3932e5c31af7Sopenharmony_ci getCubeLinearSamples(faceAccesses, coords.face, u, v, 0, sampleColors); 3933e5c31af7Sopenharmony_ci 3934e5c31af7Sopenharmony_ci const int sampleIndices[4] = { 2, 3, 1, 0 }; // \note Gather returns the samples in a non-obvious order. 3935e5c31af7Sopenharmony_ci Vec4 result; 3936e5c31af7Sopenharmony_ci for (int i = 0; i < 4; i++) 3937e5c31af7Sopenharmony_ci result[i] = sampleColors[sampleIndices[i]][componentNdx]; 3938e5c31af7Sopenharmony_ci 3939e5c31af7Sopenharmony_ci return result; 3940e5c31af7Sopenharmony_ci} 3941e5c31af7Sopenharmony_ci 3942e5c31af7Sopenharmony_ciVec4 TextureCubeView::gatherCompare (const Sampler& sampler, float ref, float s, float t, float r) const 3943e5c31af7Sopenharmony_ci{ 3944e5c31af7Sopenharmony_ci DE_ASSERT(sampler.compare != Sampler::COMPAREMODE_NONE); 3945e5c31af7Sopenharmony_ci DE_ASSERT(m_levels[0][0].getFormat().order == TextureFormat::D || m_levels[0][0].getFormat().order == TextureFormat::DS); 3946e5c31af7Sopenharmony_ci DE_ASSERT(sampler.compareChannel == 0); 3947e5c31af7Sopenharmony_ci 3948e5c31af7Sopenharmony_ci Sampler noCompareSampler = sampler; 3949e5c31af7Sopenharmony_ci noCompareSampler.compare = Sampler::COMPAREMODE_NONE; 3950e5c31af7Sopenharmony_ci 3951e5c31af7Sopenharmony_ci const Vec4 gathered = gather(noCompareSampler, s, t, r, 0 /* component 0: depth */); 3952e5c31af7Sopenharmony_ci const bool isFixedPoint = isFixedPointDepthTextureFormat(m_levels[0][0].getFormat()); 3953e5c31af7Sopenharmony_ci Vec4 result; 3954e5c31af7Sopenharmony_ci for (int i = 0; i < 4; i++) 3955e5c31af7Sopenharmony_ci result[i] = execCompare(gathered, sampler.compare, i, ref, isFixedPoint); 3956e5c31af7Sopenharmony_ci 3957e5c31af7Sopenharmony_ci return result; 3958e5c31af7Sopenharmony_ci} 3959e5c31af7Sopenharmony_ci 3960e5c31af7Sopenharmony_ci// TextureCube 3961e5c31af7Sopenharmony_ci 3962e5c31af7Sopenharmony_ciTextureCube::TextureCube (const TextureFormat& format, int size, bool es2) 3963e5c31af7Sopenharmony_ci : m_format (format) 3964e5c31af7Sopenharmony_ci , m_size (size) 3965e5c31af7Sopenharmony_ci{ 3966e5c31af7Sopenharmony_ci const int numLevels = computeMipPyramidLevels(m_size); 3967e5c31af7Sopenharmony_ci const ConstPixelBufferAccess* levels[CUBEFACE_LAST]; 3968e5c31af7Sopenharmony_ci 3969e5c31af7Sopenharmony_ci for (int face = 0; face < CUBEFACE_LAST; face++) 3970e5c31af7Sopenharmony_ci { 3971e5c31af7Sopenharmony_ci m_data[face].resize(numLevels); 3972e5c31af7Sopenharmony_ci m_access[face].resize(numLevels); 3973e5c31af7Sopenharmony_ci levels[face] = &m_access[face][0]; 3974e5c31af7Sopenharmony_ci } 3975e5c31af7Sopenharmony_ci 3976e5c31af7Sopenharmony_ci m_view = TextureCubeView(numLevels, levels, es2); 3977e5c31af7Sopenharmony_ci} 3978e5c31af7Sopenharmony_ci 3979e5c31af7Sopenharmony_ciTextureCube::TextureCube (const TextureCube& other) 3980e5c31af7Sopenharmony_ci : m_format (other.m_format) 3981e5c31af7Sopenharmony_ci , m_size (other.m_size) 3982e5c31af7Sopenharmony_ci{ 3983e5c31af7Sopenharmony_ci const int numLevels = computeMipPyramidLevels(m_size); 3984e5c31af7Sopenharmony_ci const ConstPixelBufferAccess* levels[CUBEFACE_LAST]; 3985e5c31af7Sopenharmony_ci 3986e5c31af7Sopenharmony_ci for (int face = 0; face < CUBEFACE_LAST; face++) 3987e5c31af7Sopenharmony_ci { 3988e5c31af7Sopenharmony_ci m_data[face].resize(numLevels); 3989e5c31af7Sopenharmony_ci m_access[face].resize(numLevels); 3990e5c31af7Sopenharmony_ci levels[face] = &m_access[face][0]; 3991e5c31af7Sopenharmony_ci } 3992e5c31af7Sopenharmony_ci 3993e5c31af7Sopenharmony_ci m_view = TextureCubeView(numLevels, levels, other.getView().isES2()); 3994e5c31af7Sopenharmony_ci 3995e5c31af7Sopenharmony_ci for (int levelNdx = 0; levelNdx < numLevels; levelNdx++) 3996e5c31af7Sopenharmony_ci { 3997e5c31af7Sopenharmony_ci for (int face = 0; face < CUBEFACE_LAST; face++) 3998e5c31af7Sopenharmony_ci { 3999e5c31af7Sopenharmony_ci if (!other.isLevelEmpty((CubeFace)face, levelNdx)) 4000e5c31af7Sopenharmony_ci { 4001e5c31af7Sopenharmony_ci allocLevel((CubeFace)face, levelNdx); 4002e5c31af7Sopenharmony_ci copy(getLevelFace(levelNdx, (CubeFace)face), 4003e5c31af7Sopenharmony_ci other.getLevelFace(levelNdx, (CubeFace)face)); 4004e5c31af7Sopenharmony_ci } 4005e5c31af7Sopenharmony_ci } 4006e5c31af7Sopenharmony_ci } 4007e5c31af7Sopenharmony_ci} 4008e5c31af7Sopenharmony_ci 4009e5c31af7Sopenharmony_ciTextureCube& TextureCube::operator= (const TextureCube& other) 4010e5c31af7Sopenharmony_ci{ 4011e5c31af7Sopenharmony_ci if (this == &other) 4012e5c31af7Sopenharmony_ci return *this; 4013e5c31af7Sopenharmony_ci 4014e5c31af7Sopenharmony_ci const int numLevels = computeMipPyramidLevels(other.m_size); 4015e5c31af7Sopenharmony_ci const ConstPixelBufferAccess* levels[CUBEFACE_LAST]; 4016e5c31af7Sopenharmony_ci 4017e5c31af7Sopenharmony_ci for (int face = 0; face < CUBEFACE_LAST; face++) 4018e5c31af7Sopenharmony_ci { 4019e5c31af7Sopenharmony_ci m_data[face].resize(numLevels); 4020e5c31af7Sopenharmony_ci m_access[face].resize(numLevels); 4021e5c31af7Sopenharmony_ci levels[face] = &m_access[face][0]; 4022e5c31af7Sopenharmony_ci } 4023e5c31af7Sopenharmony_ci 4024e5c31af7Sopenharmony_ci m_format = other.m_format; 4025e5c31af7Sopenharmony_ci m_size = other.m_size; 4026e5c31af7Sopenharmony_ci m_view = TextureCubeView(numLevels, levels, other.getView().isES2()); 4027e5c31af7Sopenharmony_ci 4028e5c31af7Sopenharmony_ci for (int levelNdx = 0; levelNdx < numLevels; levelNdx++) 4029e5c31af7Sopenharmony_ci { 4030e5c31af7Sopenharmony_ci for (int face = 0; face < CUBEFACE_LAST; face++) 4031e5c31af7Sopenharmony_ci { 4032e5c31af7Sopenharmony_ci if (!isLevelEmpty((CubeFace)face, levelNdx)) 4033e5c31af7Sopenharmony_ci clearLevel((CubeFace)face, levelNdx); 4034e5c31af7Sopenharmony_ci 4035e5c31af7Sopenharmony_ci if (!other.isLevelEmpty((CubeFace)face, levelNdx)) 4036e5c31af7Sopenharmony_ci { 4037e5c31af7Sopenharmony_ci allocLevel((CubeFace)face, levelNdx); 4038e5c31af7Sopenharmony_ci copy(getLevelFace(levelNdx, (CubeFace)face), 4039e5c31af7Sopenharmony_ci other.getLevelFace(levelNdx, (CubeFace)face)); 4040e5c31af7Sopenharmony_ci } 4041e5c31af7Sopenharmony_ci } 4042e5c31af7Sopenharmony_ci } 4043e5c31af7Sopenharmony_ci 4044e5c31af7Sopenharmony_ci return *this; 4045e5c31af7Sopenharmony_ci} 4046e5c31af7Sopenharmony_ci 4047e5c31af7Sopenharmony_ciTextureCube::~TextureCube (void) 4048e5c31af7Sopenharmony_ci{ 4049e5c31af7Sopenharmony_ci} 4050e5c31af7Sopenharmony_ci 4051e5c31af7Sopenharmony_civoid TextureCube::allocLevel (tcu::CubeFace face, int levelNdx) 4052e5c31af7Sopenharmony_ci{ 4053e5c31af7Sopenharmony_ci const int size = getMipPyramidLevelSize(m_size, levelNdx); 4054e5c31af7Sopenharmony_ci const int dataSize = m_format.getPixelSize()*size*size; 4055e5c31af7Sopenharmony_ci DE_ASSERT(isLevelEmpty(face, levelNdx)); 4056e5c31af7Sopenharmony_ci 4057e5c31af7Sopenharmony_ci m_data[face][levelNdx].setStorage(dataSize); 4058e5c31af7Sopenharmony_ci m_access[face][levelNdx] = PixelBufferAccess(m_format, size, size, 1, m_data[face][levelNdx].getPtr()); 4059e5c31af7Sopenharmony_ci} 4060e5c31af7Sopenharmony_ci 4061e5c31af7Sopenharmony_civoid TextureCube::clearLevel (tcu::CubeFace face, int levelNdx) 4062e5c31af7Sopenharmony_ci{ 4063e5c31af7Sopenharmony_ci DE_ASSERT(!isLevelEmpty(face, levelNdx)); 4064e5c31af7Sopenharmony_ci m_data[face][levelNdx].clear(); 4065e5c31af7Sopenharmony_ci m_access[face][levelNdx] = PixelBufferAccess(); 4066e5c31af7Sopenharmony_ci} 4067e5c31af7Sopenharmony_ci 4068e5c31af7Sopenharmony_ci// Texture1DArrayView 4069e5c31af7Sopenharmony_ci 4070e5c31af7Sopenharmony_ciTexture1DArrayView::Texture1DArrayView (int numLevels, const ConstPixelBufferAccess* levels, bool es2 DE_UNUSED_ATTR, ImageViewMinLodParams* minLodParams DE_UNUSED_ATTR) 4071e5c31af7Sopenharmony_ci : m_numLevels (numLevels) 4072e5c31af7Sopenharmony_ci , m_levels (levels) 4073e5c31af7Sopenharmony_ci{ 4074e5c31af7Sopenharmony_ci} 4075e5c31af7Sopenharmony_ci 4076e5c31af7Sopenharmony_ciinline int Texture1DArrayView::selectLayer (float t) const 4077e5c31af7Sopenharmony_ci{ 4078e5c31af7Sopenharmony_ci DE_ASSERT(m_numLevels > 0 && m_levels); 4079e5c31af7Sopenharmony_ci return de::clamp(deFloorFloatToInt32(t + 0.5f), 0, m_levels[0].getHeight()-1); 4080e5c31af7Sopenharmony_ci} 4081e5c31af7Sopenharmony_ci 4082e5c31af7Sopenharmony_ciVec4 Texture1DArrayView::sample (const Sampler& sampler, float s, float t, float lod) const 4083e5c31af7Sopenharmony_ci{ 4084e5c31af7Sopenharmony_ci return sampleLevelArray1D(m_levels, m_numLevels, sampler, s, selectLayer(t), lod); 4085e5c31af7Sopenharmony_ci} 4086e5c31af7Sopenharmony_ci 4087e5c31af7Sopenharmony_ciVec4 Texture1DArrayView::sampleOffset (const Sampler& sampler, float s, float t, float lod, deInt32 offset) const 4088e5c31af7Sopenharmony_ci{ 4089e5c31af7Sopenharmony_ci return sampleLevelArray1DOffset(m_levels, m_numLevels, sampler, s, lod, IVec2(offset, selectLayer(t))); 4090e5c31af7Sopenharmony_ci} 4091e5c31af7Sopenharmony_ci 4092e5c31af7Sopenharmony_cifloat Texture1DArrayView::sampleCompare (const Sampler& sampler, float ref, float s, float t, float lod) const 4093e5c31af7Sopenharmony_ci{ 4094e5c31af7Sopenharmony_ci return sampleLevelArray1DCompare(m_levels, m_numLevels, sampler, ref, s, lod, IVec2(0, selectLayer(t))); 4095e5c31af7Sopenharmony_ci} 4096e5c31af7Sopenharmony_ci 4097e5c31af7Sopenharmony_cifloat Texture1DArrayView::sampleCompareOffset (const Sampler& sampler, float ref, float s, float t, float lod, deInt32 offset) const 4098e5c31af7Sopenharmony_ci{ 4099e5c31af7Sopenharmony_ci return sampleLevelArray1DCompare(m_levels, m_numLevels, sampler, ref, s, lod, IVec2(offset, selectLayer(t))); 4100e5c31af7Sopenharmony_ci} 4101e5c31af7Sopenharmony_ci 4102e5c31af7Sopenharmony_ci// Texture2DArrayView 4103e5c31af7Sopenharmony_ci 4104e5c31af7Sopenharmony_ciTexture2DArrayView::Texture2DArrayView (int numLevels, const ConstPixelBufferAccess* levels, bool es2 DE_UNUSED_ATTR, ImageViewMinLodParams* minLodParams DE_UNUSED_ATTR) 4105e5c31af7Sopenharmony_ci : m_numLevels (numLevels) 4106e5c31af7Sopenharmony_ci , m_levels (levels) 4107e5c31af7Sopenharmony_ci{ 4108e5c31af7Sopenharmony_ci} 4109e5c31af7Sopenharmony_ci 4110e5c31af7Sopenharmony_ciinline int Texture2DArrayView::selectLayer (float r) const 4111e5c31af7Sopenharmony_ci{ 4112e5c31af7Sopenharmony_ci DE_ASSERT(m_numLevels > 0 && m_levels); 4113e5c31af7Sopenharmony_ci return de::clamp(deFloorFloatToInt32(r + 0.5f), 0, m_levels[0].getDepth()-1); 4114e5c31af7Sopenharmony_ci} 4115e5c31af7Sopenharmony_ci 4116e5c31af7Sopenharmony_ciVec4 Texture2DArrayView::sample (const Sampler& sampler, float s, float t, float r, float lod) const 4117e5c31af7Sopenharmony_ci{ 4118e5c31af7Sopenharmony_ci return sampleLevelArray2D(m_levels, m_numLevels, sampler, s, t, selectLayer(r), lod); 4119e5c31af7Sopenharmony_ci} 4120e5c31af7Sopenharmony_ci 4121e5c31af7Sopenharmony_cifloat Texture2DArrayView::sampleCompare (const Sampler& sampler, float ref, float s, float t, float r, float lod) const 4122e5c31af7Sopenharmony_ci{ 4123e5c31af7Sopenharmony_ci return sampleLevelArray2DCompare(m_levels, m_numLevels, sampler, ref, s, t, lod, IVec3(0, 0, selectLayer(r))); 4124e5c31af7Sopenharmony_ci} 4125e5c31af7Sopenharmony_ci 4126e5c31af7Sopenharmony_ciVec4 Texture2DArrayView::sampleOffset (const Sampler& sampler, float s, float t, float r, float lod, const IVec2& offset) const 4127e5c31af7Sopenharmony_ci{ 4128e5c31af7Sopenharmony_ci return sampleLevelArray2DOffset(m_levels, m_numLevels, sampler, s, t, lod, IVec3(offset.x(), offset.y(), selectLayer(r))); 4129e5c31af7Sopenharmony_ci} 4130e5c31af7Sopenharmony_ci 4131e5c31af7Sopenharmony_cifloat Texture2DArrayView::sampleCompareOffset (const Sampler& sampler, float ref, float s, float t, float r, float lod, const IVec2& offset) const 4132e5c31af7Sopenharmony_ci{ 4133e5c31af7Sopenharmony_ci return sampleLevelArray2DCompare(m_levels, m_numLevels, sampler, ref, s, t, lod, IVec3(offset.x(), offset.y(), selectLayer(r))); 4134e5c31af7Sopenharmony_ci} 4135e5c31af7Sopenharmony_ci 4136e5c31af7Sopenharmony_ciVec4 Texture2DArrayView::gatherOffsets (const Sampler& sampler, float s, float t, float r, int componentNdx, const IVec2 (&offsets)[4]) const 4137e5c31af7Sopenharmony_ci{ 4138e5c31af7Sopenharmony_ci return gatherArray2DOffsets(m_levels[0], sampler, s, t, selectLayer(r), componentNdx, offsets); 4139e5c31af7Sopenharmony_ci} 4140e5c31af7Sopenharmony_ci 4141e5c31af7Sopenharmony_ciVec4 Texture2DArrayView::gatherOffsetsCompare (const Sampler& sampler, float ref, float s, float t, float r, const IVec2 (&offsets)[4]) const 4142e5c31af7Sopenharmony_ci{ 4143e5c31af7Sopenharmony_ci return gatherArray2DOffsetsCompare(m_levels[0], sampler, ref, s, t, selectLayer(r), offsets); 4144e5c31af7Sopenharmony_ci} 4145e5c31af7Sopenharmony_ci 4146e5c31af7Sopenharmony_ci// Texture1DArray 4147e5c31af7Sopenharmony_ci 4148e5c31af7Sopenharmony_ciTexture1DArray::Texture1DArray (const TextureFormat& format, int width, int numLayers) 4149e5c31af7Sopenharmony_ci : TextureLevelPyramid (format, computeMipPyramidLevels(width)) 4150e5c31af7Sopenharmony_ci , m_width (width) 4151e5c31af7Sopenharmony_ci , m_numLayers (numLayers) 4152e5c31af7Sopenharmony_ci , m_view (getNumLevels(), getLevels()) 4153e5c31af7Sopenharmony_ci{ 4154e5c31af7Sopenharmony_ci} 4155e5c31af7Sopenharmony_ci 4156e5c31af7Sopenharmony_ciTexture1DArray::Texture1DArray (const Texture1DArray& other) 4157e5c31af7Sopenharmony_ci : TextureLevelPyramid (other) 4158e5c31af7Sopenharmony_ci , m_width (other.m_width) 4159e5c31af7Sopenharmony_ci , m_numLayers (other.m_numLayers) 4160e5c31af7Sopenharmony_ci , m_view (getNumLevels(), getLevels()) 4161e5c31af7Sopenharmony_ci{ 4162e5c31af7Sopenharmony_ci} 4163e5c31af7Sopenharmony_ci 4164e5c31af7Sopenharmony_ciTexture1DArray& Texture1DArray::operator= (const Texture1DArray& other) 4165e5c31af7Sopenharmony_ci{ 4166e5c31af7Sopenharmony_ci if (this == &other) 4167e5c31af7Sopenharmony_ci return *this; 4168e5c31af7Sopenharmony_ci 4169e5c31af7Sopenharmony_ci TextureLevelPyramid::operator=(other); 4170e5c31af7Sopenharmony_ci 4171e5c31af7Sopenharmony_ci m_width = other.m_width; 4172e5c31af7Sopenharmony_ci m_numLayers = other.m_numLayers; 4173e5c31af7Sopenharmony_ci m_view = Texture1DArrayView(getNumLevels(), getLevels()); 4174e5c31af7Sopenharmony_ci 4175e5c31af7Sopenharmony_ci return *this; 4176e5c31af7Sopenharmony_ci} 4177e5c31af7Sopenharmony_ci 4178e5c31af7Sopenharmony_ciTexture1DArray::~Texture1DArray (void) 4179e5c31af7Sopenharmony_ci{ 4180e5c31af7Sopenharmony_ci} 4181e5c31af7Sopenharmony_ci 4182e5c31af7Sopenharmony_civoid Texture1DArray::allocLevel (int levelNdx) 4183e5c31af7Sopenharmony_ci{ 4184e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels())); 4185e5c31af7Sopenharmony_ci 4186e5c31af7Sopenharmony_ci const int width = getMipPyramidLevelSize(m_width, levelNdx); 4187e5c31af7Sopenharmony_ci 4188e5c31af7Sopenharmony_ci TextureLevelPyramid::allocLevel(levelNdx, width, m_numLayers, 1); 4189e5c31af7Sopenharmony_ci} 4190e5c31af7Sopenharmony_ci 4191e5c31af7Sopenharmony_ci// Texture2DArray 4192e5c31af7Sopenharmony_ci 4193e5c31af7Sopenharmony_ciTexture2DArray::Texture2DArray (const TextureFormat& format, int width, int height, int numLayers) 4194e5c31af7Sopenharmony_ci : TextureLevelPyramid (format, computeMipPyramidLevels(width, height)) 4195e5c31af7Sopenharmony_ci , m_width (width) 4196e5c31af7Sopenharmony_ci , m_height (height) 4197e5c31af7Sopenharmony_ci , m_numLayers (numLayers) 4198e5c31af7Sopenharmony_ci , m_view (getNumLevels(), getLevels()) 4199e5c31af7Sopenharmony_ci{ 4200e5c31af7Sopenharmony_ci} 4201e5c31af7Sopenharmony_ci 4202e5c31af7Sopenharmony_ciTexture2DArray::Texture2DArray (const Texture2DArray& other) 4203e5c31af7Sopenharmony_ci : TextureLevelPyramid (other) 4204e5c31af7Sopenharmony_ci , m_width (other.m_width) 4205e5c31af7Sopenharmony_ci , m_height (other.m_height) 4206e5c31af7Sopenharmony_ci , m_numLayers (other.m_numLayers) 4207e5c31af7Sopenharmony_ci , m_view (getNumLevels(), getLevels()) 4208e5c31af7Sopenharmony_ci{ 4209e5c31af7Sopenharmony_ci} 4210e5c31af7Sopenharmony_ci 4211e5c31af7Sopenharmony_ciTexture2DArray& Texture2DArray::operator= (const Texture2DArray& other) 4212e5c31af7Sopenharmony_ci{ 4213e5c31af7Sopenharmony_ci if (this == &other) 4214e5c31af7Sopenharmony_ci return *this; 4215e5c31af7Sopenharmony_ci 4216e5c31af7Sopenharmony_ci TextureLevelPyramid::operator=(other); 4217e5c31af7Sopenharmony_ci 4218e5c31af7Sopenharmony_ci m_width = other.m_width; 4219e5c31af7Sopenharmony_ci m_height = other.m_height; 4220e5c31af7Sopenharmony_ci m_numLayers = other.m_numLayers; 4221e5c31af7Sopenharmony_ci m_view = Texture2DArrayView(getNumLevels(), getLevels()); 4222e5c31af7Sopenharmony_ci 4223e5c31af7Sopenharmony_ci return *this; 4224e5c31af7Sopenharmony_ci} 4225e5c31af7Sopenharmony_ci 4226e5c31af7Sopenharmony_ciTexture2DArray::~Texture2DArray (void) 4227e5c31af7Sopenharmony_ci{ 4228e5c31af7Sopenharmony_ci} 4229e5c31af7Sopenharmony_ci 4230e5c31af7Sopenharmony_civoid Texture2DArray::allocLevel (int levelNdx) 4231e5c31af7Sopenharmony_ci{ 4232e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels())); 4233e5c31af7Sopenharmony_ci 4234e5c31af7Sopenharmony_ci const int width = getMipPyramidLevelSize(m_width, levelNdx); 4235e5c31af7Sopenharmony_ci const int height = getMipPyramidLevelSize(m_height, levelNdx); 4236e5c31af7Sopenharmony_ci 4237e5c31af7Sopenharmony_ci TextureLevelPyramid::allocLevel(levelNdx, width, height, m_numLayers); 4238e5c31af7Sopenharmony_ci} 4239e5c31af7Sopenharmony_ci 4240e5c31af7Sopenharmony_ci// Texture3DView 4241e5c31af7Sopenharmony_ci 4242e5c31af7Sopenharmony_ciTexture3DView::Texture3DView (int numLevels, const ConstPixelBufferAccess* levels, bool es2, ImageViewMinLodParams *minLodParams) 4243e5c31af7Sopenharmony_ci : m_numLevels (numLevels) 4244e5c31af7Sopenharmony_ci , m_levels (levels) 4245e5c31af7Sopenharmony_ci , m_es2 (es2) 4246e5c31af7Sopenharmony_ci , m_minLodParams (minLodParams) 4247e5c31af7Sopenharmony_ci{ 4248e5c31af7Sopenharmony_ci} 4249e5c31af7Sopenharmony_ci 4250e5c31af7Sopenharmony_ci// Texture3D 4251e5c31af7Sopenharmony_ci 4252e5c31af7Sopenharmony_ciTexture3D::Texture3D (const TextureFormat& format, int width, int height, int depth) 4253e5c31af7Sopenharmony_ci : TextureLevelPyramid (format, computeMipPyramidLevels(width, height, depth)) 4254e5c31af7Sopenharmony_ci , m_width (width) 4255e5c31af7Sopenharmony_ci , m_height (height) 4256e5c31af7Sopenharmony_ci , m_depth (depth) 4257e5c31af7Sopenharmony_ci , m_view (getNumLevels(), getLevels()) 4258e5c31af7Sopenharmony_ci{ 4259e5c31af7Sopenharmony_ci} 4260e5c31af7Sopenharmony_ci 4261e5c31af7Sopenharmony_ciTexture3D::Texture3D (const Texture3D& other) 4262e5c31af7Sopenharmony_ci : TextureLevelPyramid (other) 4263e5c31af7Sopenharmony_ci , m_width (other.m_width) 4264e5c31af7Sopenharmony_ci , m_height (other.m_height) 4265e5c31af7Sopenharmony_ci , m_depth (other.m_depth) 4266e5c31af7Sopenharmony_ci , m_view (getNumLevels(), getLevels()) 4267e5c31af7Sopenharmony_ci{ 4268e5c31af7Sopenharmony_ci} 4269e5c31af7Sopenharmony_ci 4270e5c31af7Sopenharmony_ciTexture3D& Texture3D::operator= (const Texture3D& other) 4271e5c31af7Sopenharmony_ci{ 4272e5c31af7Sopenharmony_ci if (this == &other) 4273e5c31af7Sopenharmony_ci return *this; 4274e5c31af7Sopenharmony_ci 4275e5c31af7Sopenharmony_ci TextureLevelPyramid::operator=(other); 4276e5c31af7Sopenharmony_ci 4277e5c31af7Sopenharmony_ci m_width = other.m_width; 4278e5c31af7Sopenharmony_ci m_height = other.m_height; 4279e5c31af7Sopenharmony_ci m_depth = other.m_depth; 4280e5c31af7Sopenharmony_ci m_view = Texture3DView(getNumLevels(), getLevels()); 4281e5c31af7Sopenharmony_ci 4282e5c31af7Sopenharmony_ci return *this; 4283e5c31af7Sopenharmony_ci} 4284e5c31af7Sopenharmony_ci 4285e5c31af7Sopenharmony_ciTexture3D::~Texture3D (void) 4286e5c31af7Sopenharmony_ci{ 4287e5c31af7Sopenharmony_ci} 4288e5c31af7Sopenharmony_ci 4289e5c31af7Sopenharmony_civoid Texture3D::allocLevel (int levelNdx) 4290e5c31af7Sopenharmony_ci{ 4291e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels())); 4292e5c31af7Sopenharmony_ci 4293e5c31af7Sopenharmony_ci const int width = getMipPyramidLevelSize(m_width, levelNdx); 4294e5c31af7Sopenharmony_ci const int height = getMipPyramidLevelSize(m_height, levelNdx); 4295e5c31af7Sopenharmony_ci const int depth = getMipPyramidLevelSize(m_depth, levelNdx); 4296e5c31af7Sopenharmony_ci 4297e5c31af7Sopenharmony_ci TextureLevelPyramid::allocLevel(levelNdx, width, height, depth); 4298e5c31af7Sopenharmony_ci} 4299e5c31af7Sopenharmony_ci 4300e5c31af7Sopenharmony_ci// TextureCubeArrayView 4301e5c31af7Sopenharmony_ci 4302e5c31af7Sopenharmony_ciTextureCubeArrayView::TextureCubeArrayView (int numLevels, const ConstPixelBufferAccess* levels, bool es2 DE_UNUSED_ATTR, ImageViewMinLodParams* minLodParams DE_UNUSED_ATTR) 4303e5c31af7Sopenharmony_ci : m_numLevels (numLevels) 4304e5c31af7Sopenharmony_ci , m_levels (levels) 4305e5c31af7Sopenharmony_ci{ 4306e5c31af7Sopenharmony_ci} 4307e5c31af7Sopenharmony_ci 4308e5c31af7Sopenharmony_ciinline int TextureCubeArrayView::selectLayer (float q) const 4309e5c31af7Sopenharmony_ci{ 4310e5c31af7Sopenharmony_ci DE_ASSERT(m_numLevels > 0 && m_levels); 4311e5c31af7Sopenharmony_ci DE_ASSERT((m_levels[0].getDepth() % 6) == 0); 4312e5c31af7Sopenharmony_ci 4313e5c31af7Sopenharmony_ci return de::clamp(deFloorFloatToInt32(q + 0.5f), 0, (m_levels[0].getDepth() / 6)-1); 4314e5c31af7Sopenharmony_ci} 4315e5c31af7Sopenharmony_ci 4316e5c31af7Sopenharmony_citcu::Vec4 TextureCubeArrayView::sample (const Sampler& sampler, float s, float t, float r, float q, float lod) const 4317e5c31af7Sopenharmony_ci{ 4318e5c31af7Sopenharmony_ci const CubeFaceFloatCoords coords = getCubeFaceCoords(Vec3(s, t, r)); 4319e5c31af7Sopenharmony_ci const int layer = selectLayer(q); 4320e5c31af7Sopenharmony_ci const int faceDepth = (layer * 6) + getCubeArrayFaceIndex(coords.face); 4321e5c31af7Sopenharmony_ci 4322e5c31af7Sopenharmony_ci DE_ASSERT(sampler.compare == Sampler::COMPAREMODE_NONE); 4323e5c31af7Sopenharmony_ci 4324e5c31af7Sopenharmony_ci if (sampler.seamlessCubeMap) 4325e5c31af7Sopenharmony_ci return sampleCubeArraySeamless(m_levels, m_numLevels, layer, coords.face, sampler, coords.s, coords.t, lod); 4326e5c31af7Sopenharmony_ci else 4327e5c31af7Sopenharmony_ci return sampleLevelArray2D(m_levels, m_numLevels, sampler, coords.s, coords.t, faceDepth, lod); 4328e5c31af7Sopenharmony_ci} 4329e5c31af7Sopenharmony_ci 4330e5c31af7Sopenharmony_cifloat TextureCubeArrayView::sampleCompare (const Sampler& sampler, float ref, float s, float t, float r, float q, float lod) const 4331e5c31af7Sopenharmony_ci{ 4332e5c31af7Sopenharmony_ci const CubeFaceFloatCoords coords = getCubeFaceCoords(Vec3(s, t, r)); 4333e5c31af7Sopenharmony_ci const int layer = selectLayer(q); 4334e5c31af7Sopenharmony_ci const int faceDepth = (layer * 6) + getCubeArrayFaceIndex(coords.face); 4335e5c31af7Sopenharmony_ci 4336e5c31af7Sopenharmony_ci DE_ASSERT(sampler.compare != Sampler::COMPAREMODE_NONE); 4337e5c31af7Sopenharmony_ci 4338e5c31af7Sopenharmony_ci if (sampler.seamlessCubeMap) 4339e5c31af7Sopenharmony_ci return sampleCubeArraySeamlessCompare(m_levels, m_numLevels, layer, coords.face, sampler, ref, coords.s, coords.t, lod); 4340e5c31af7Sopenharmony_ci else 4341e5c31af7Sopenharmony_ci return sampleLevelArray2DCompare(m_levels, m_numLevels, sampler, ref, coords.s, coords.t, lod, IVec3(0, 0, faceDepth)); 4342e5c31af7Sopenharmony_ci} 4343e5c31af7Sopenharmony_ci 4344e5c31af7Sopenharmony_ci// TextureCubeArray 4345e5c31af7Sopenharmony_ci 4346e5c31af7Sopenharmony_ciTextureCubeArray::TextureCubeArray (const TextureFormat& format, int size, int depth) 4347e5c31af7Sopenharmony_ci : TextureLevelPyramid (format, computeMipPyramidLevels(size)) 4348e5c31af7Sopenharmony_ci , m_size (size) 4349e5c31af7Sopenharmony_ci , m_depth (depth) 4350e5c31af7Sopenharmony_ci , m_view (getNumLevels(), getLevels()) 4351e5c31af7Sopenharmony_ci{ 4352e5c31af7Sopenharmony_ci DE_ASSERT(m_depth % 6 == 0); 4353e5c31af7Sopenharmony_ci} 4354e5c31af7Sopenharmony_ci 4355e5c31af7Sopenharmony_ciTextureCubeArray::TextureCubeArray (const TextureCubeArray& other) 4356e5c31af7Sopenharmony_ci : TextureLevelPyramid (other) 4357e5c31af7Sopenharmony_ci , m_size (other.m_size) 4358e5c31af7Sopenharmony_ci , m_depth (other.m_depth) 4359e5c31af7Sopenharmony_ci , m_view (getNumLevels(), getLevels()) 4360e5c31af7Sopenharmony_ci{ 4361e5c31af7Sopenharmony_ci DE_ASSERT(m_depth % 6 == 0); 4362e5c31af7Sopenharmony_ci} 4363e5c31af7Sopenharmony_ci 4364e5c31af7Sopenharmony_ciTextureCubeArray& TextureCubeArray::operator= (const TextureCubeArray& other) 4365e5c31af7Sopenharmony_ci{ 4366e5c31af7Sopenharmony_ci if (this == &other) 4367e5c31af7Sopenharmony_ci return *this; 4368e5c31af7Sopenharmony_ci 4369e5c31af7Sopenharmony_ci TextureLevelPyramid::operator=(other); 4370e5c31af7Sopenharmony_ci 4371e5c31af7Sopenharmony_ci m_size = other.m_size; 4372e5c31af7Sopenharmony_ci m_depth = other.m_depth; 4373e5c31af7Sopenharmony_ci m_view = TextureCubeArrayView(getNumLevels(), getLevels()); 4374e5c31af7Sopenharmony_ci 4375e5c31af7Sopenharmony_ci DE_ASSERT(m_depth % 6 == 0); 4376e5c31af7Sopenharmony_ci 4377e5c31af7Sopenharmony_ci return *this; 4378e5c31af7Sopenharmony_ci} 4379e5c31af7Sopenharmony_ci 4380e5c31af7Sopenharmony_ciTextureCubeArray::~TextureCubeArray (void) 4381e5c31af7Sopenharmony_ci{ 4382e5c31af7Sopenharmony_ci} 4383e5c31af7Sopenharmony_ci 4384e5c31af7Sopenharmony_civoid TextureCubeArray::allocLevel (int levelNdx) 4385e5c31af7Sopenharmony_ci{ 4386e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels())); 4387e5c31af7Sopenharmony_ci 4388e5c31af7Sopenharmony_ci const int size = getMipPyramidLevelSize(m_size, levelNdx); 4389e5c31af7Sopenharmony_ci 4390e5c31af7Sopenharmony_ci TextureLevelPyramid::allocLevel(levelNdx, size, size, m_depth); 4391e5c31af7Sopenharmony_ci} 4392e5c31af7Sopenharmony_ci 4393e5c31af7Sopenharmony_cistd::ostream& operator<< (std::ostream& str, TextureFormat::ChannelOrder order) 4394e5c31af7Sopenharmony_ci{ 4395e5c31af7Sopenharmony_ci const char* const orderStrings[] = 4396e5c31af7Sopenharmony_ci { 4397e5c31af7Sopenharmony_ci "R", 4398e5c31af7Sopenharmony_ci "A", 4399e5c31af7Sopenharmony_ci "I", 4400e5c31af7Sopenharmony_ci "L", 4401e5c31af7Sopenharmony_ci "LA", 4402e5c31af7Sopenharmony_ci "RG", 4403e5c31af7Sopenharmony_ci "RA", 4404e5c31af7Sopenharmony_ci "RGB", 4405e5c31af7Sopenharmony_ci "RGBA", 4406e5c31af7Sopenharmony_ci "ARGB", 4407e5c31af7Sopenharmony_ci "ABGR", 4408e5c31af7Sopenharmony_ci "BGR", 4409e5c31af7Sopenharmony_ci "BGRA", 4410e5c31af7Sopenharmony_ci 4411e5c31af7Sopenharmony_ci "sR", 4412e5c31af7Sopenharmony_ci "sRG", 4413e5c31af7Sopenharmony_ci "sRGB", 4414e5c31af7Sopenharmony_ci "sRGBA", 4415e5c31af7Sopenharmony_ci "sBGR", 4416e5c31af7Sopenharmony_ci "sBGRA", 4417e5c31af7Sopenharmony_ci 4418e5c31af7Sopenharmony_ci "D", 4419e5c31af7Sopenharmony_ci "S", 4420e5c31af7Sopenharmony_ci "DS" 4421e5c31af7Sopenharmony_ci }; 4422e5c31af7Sopenharmony_ci 4423e5c31af7Sopenharmony_ci return str << de::getSizedArrayElement<TextureFormat::CHANNELORDER_LAST>(orderStrings, order); 4424e5c31af7Sopenharmony_ci} 4425e5c31af7Sopenharmony_ci 4426e5c31af7Sopenharmony_cistd::ostream& operator<< (std::ostream& str, TextureFormat::ChannelType type) 4427e5c31af7Sopenharmony_ci{ 4428e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 48); 4429e5c31af7Sopenharmony_ci 4430e5c31af7Sopenharmony_ci const char* const typeStrings[] = 4431e5c31af7Sopenharmony_ci { 4432e5c31af7Sopenharmony_ci "SNORM_INT8", 4433e5c31af7Sopenharmony_ci "SNORM_INT16", 4434e5c31af7Sopenharmony_ci "SNORM_INT32", 4435e5c31af7Sopenharmony_ci "UNORM_INT8", 4436e5c31af7Sopenharmony_ci "UNORM_INT16", 4437e5c31af7Sopenharmony_ci "UNORM_INT24", 4438e5c31af7Sopenharmony_ci "UNORM_INT32", 4439e5c31af7Sopenharmony_ci "UNORM_BYTE_44", 4440e5c31af7Sopenharmony_ci "UNORM_SHORT_565", 4441e5c31af7Sopenharmony_ci "UNORM_SHORT_555", 4442e5c31af7Sopenharmony_ci "UNORM_SHORT_4444", 4443e5c31af7Sopenharmony_ci "UNORM_SHORT_5551", 4444e5c31af7Sopenharmony_ci "UNORM_SHORT_1555", 4445e5c31af7Sopenharmony_ci "UNORM_INT_101010", 4446e5c31af7Sopenharmony_ci "SNORM_INT_1010102_REV", 4447e5c31af7Sopenharmony_ci "UNORM_INT_1010102_REV", 4448e5c31af7Sopenharmony_ci "UNSIGNED_BYTE_44", 4449e5c31af7Sopenharmony_ci "UNSIGNED_SHORT_565", 4450e5c31af7Sopenharmony_ci "UNSIGNED_SHORT_4444", 4451e5c31af7Sopenharmony_ci "UNSIGNED_SHORT_5551", 4452e5c31af7Sopenharmony_ci "SIGNED_INT_1010102_REV", 4453e5c31af7Sopenharmony_ci "UNSIGNED_INT_1010102_REV", 4454e5c31af7Sopenharmony_ci "UNSIGNED_INT_11F_11F_10F_REV", 4455e5c31af7Sopenharmony_ci "UNSIGNED_INT_999_E5_REV", 4456e5c31af7Sopenharmony_ci "UNSIGNED_INT_16_8_8", 4457e5c31af7Sopenharmony_ci "UNSIGNED_INT_24_8", 4458e5c31af7Sopenharmony_ci "UNSIGNED_INT_24_8_REV", 4459e5c31af7Sopenharmony_ci "SIGNED_INT8", 4460e5c31af7Sopenharmony_ci "SIGNED_INT16", 4461e5c31af7Sopenharmony_ci "SIGNED_INT32", 4462e5c31af7Sopenharmony_ci "SIGNED_INT64", 4463e5c31af7Sopenharmony_ci "UNSIGNED_INT8", 4464e5c31af7Sopenharmony_ci "UNSIGNED_INT16", 4465e5c31af7Sopenharmony_ci "UNSIGNED_INT24", 4466e5c31af7Sopenharmony_ci "UNSIGNED_INT32", 4467e5c31af7Sopenharmony_ci "UNSIGNED_INT64", 4468e5c31af7Sopenharmony_ci "HALF_FLOAT", 4469e5c31af7Sopenharmony_ci "FLOAT", 4470e5c31af7Sopenharmony_ci "FLOAT64", 4471e5c31af7Sopenharmony_ci "FLOAT_UNSIGNED_INT_24_8_REV", 4472e5c31af7Sopenharmony_ci "UNORM_SHORT_10", 4473e5c31af7Sopenharmony_ci "UNORM_SHORT_12", 4474e5c31af7Sopenharmony_ci "USCALED_INT8", 4475e5c31af7Sopenharmony_ci "USCALED_INT16", 4476e5c31af7Sopenharmony_ci "SSCALED_INT8", 4477e5c31af7Sopenharmony_ci "SSCALED_INT16", 4478e5c31af7Sopenharmony_ci "USCALED_INT_1010102_REV", 4479e5c31af7Sopenharmony_ci "SSCALED_INT_1010102_REV" 4480e5c31af7Sopenharmony_ci }; 4481e5c31af7Sopenharmony_ci 4482e5c31af7Sopenharmony_ci return str << de::getSizedArrayElement<TextureFormat::CHANNELTYPE_LAST>(typeStrings, type); 4483e5c31af7Sopenharmony_ci} 4484e5c31af7Sopenharmony_ci 4485e5c31af7Sopenharmony_cistd::ostream& operator<< (std::ostream& str, CubeFace face) 4486e5c31af7Sopenharmony_ci{ 4487e5c31af7Sopenharmony_ci switch (face) 4488e5c31af7Sopenharmony_ci { 4489e5c31af7Sopenharmony_ci case CUBEFACE_NEGATIVE_X: return str << "CUBEFACE_NEGATIVE_X"; 4490e5c31af7Sopenharmony_ci case CUBEFACE_POSITIVE_X: return str << "CUBEFACE_POSITIVE_X"; 4491e5c31af7Sopenharmony_ci case CUBEFACE_NEGATIVE_Y: return str << "CUBEFACE_NEGATIVE_Y"; 4492e5c31af7Sopenharmony_ci case CUBEFACE_POSITIVE_Y: return str << "CUBEFACE_POSITIVE_Y"; 4493e5c31af7Sopenharmony_ci case CUBEFACE_NEGATIVE_Z: return str << "CUBEFACE_NEGATIVE_Z"; 4494e5c31af7Sopenharmony_ci case CUBEFACE_POSITIVE_Z: return str << "CUBEFACE_POSITIVE_Z"; 4495e5c31af7Sopenharmony_ci case CUBEFACE_LAST: return str << "CUBEFACE_LAST"; 4496e5c31af7Sopenharmony_ci default: return str << "UNKNOWN(" << (int)face << ")"; 4497e5c31af7Sopenharmony_ci } 4498e5c31af7Sopenharmony_ci} 4499e5c31af7Sopenharmony_ci 4500e5c31af7Sopenharmony_cistd::ostream& operator<< (std::ostream& str, TextureFormat format) 4501e5c31af7Sopenharmony_ci{ 4502e5c31af7Sopenharmony_ci return str << format.order << ", " << format.type << ""; 4503e5c31af7Sopenharmony_ci} 4504e5c31af7Sopenharmony_ci 4505e5c31af7Sopenharmony_cistd::ostream& operator<< (std::ostream& str, const ConstPixelBufferAccess& access) 4506e5c31af7Sopenharmony_ci{ 4507e5c31af7Sopenharmony_ci return str << "format = (" << access.getFormat() << "), size = " 4508e5c31af7Sopenharmony_ci << access.getWidth() << " x " << access.getHeight() << " x " << access.getDepth() 4509e5c31af7Sopenharmony_ci << ", pitch = " << access.getRowPitch() << " / " << access.getSlicePitch(); 4510e5c31af7Sopenharmony_ci} 4511e5c31af7Sopenharmony_ci 4512e5c31af7Sopenharmony_cideBool isSamplerMipmapModeLinear (tcu::Sampler::FilterMode filterMode) 4513e5c31af7Sopenharmony_ci{ 4514e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(tcu::Sampler::FILTERMODE_LAST == 9); 4515e5c31af7Sopenharmony_ci switch (filterMode) 4516e5c31af7Sopenharmony_ci { 4517e5c31af7Sopenharmony_ci case tcu::Sampler::NEAREST: 4518e5c31af7Sopenharmony_ci case tcu::Sampler::LINEAR: 4519e5c31af7Sopenharmony_ci case tcu::Sampler::CUBIC: 4520e5c31af7Sopenharmony_ci case tcu::Sampler::NEAREST_MIPMAP_NEAREST: 4521e5c31af7Sopenharmony_ci case tcu::Sampler::LINEAR_MIPMAP_NEAREST: 4522e5c31af7Sopenharmony_ci case tcu::Sampler::CUBIC_MIPMAP_NEAREST: 4523e5c31af7Sopenharmony_ci return DE_FALSE; 4524e5c31af7Sopenharmony_ci case tcu::Sampler::NEAREST_MIPMAP_LINEAR: 4525e5c31af7Sopenharmony_ci case tcu::Sampler::LINEAR_MIPMAP_LINEAR: 4526e5c31af7Sopenharmony_ci case tcu::Sampler::CUBIC_MIPMAP_LINEAR: 4527e5c31af7Sopenharmony_ci return DE_TRUE; 4528e5c31af7Sopenharmony_ci default: 4529e5c31af7Sopenharmony_ci DE_FATAL("Illegal filter mode"); 4530e5c31af7Sopenharmony_ci return DE_FALSE; 4531e5c31af7Sopenharmony_ci } 4532e5c31af7Sopenharmony_ci} 4533e5c31af7Sopenharmony_ci} // tcu 4534