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