tcuTexture.cpp revision 725691d12fb107f6ba64aa8ab5aafa0a1cea2847
13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program Tester Core
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * ----------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Reference Texture Implementation.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTexture.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deInt32.h"
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deFloat16.h"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMath.h"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMemory.h"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuSurface.hpp"
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuFloat.hpp"
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTextureUtil.hpp"
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp"
34d6148171f88da1301f053e2e0236afc69416137cJarkko Pöyry#include "deArrayUtil.hpp"
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <limits>
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace tcu
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \note No denorm support, no sign.
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef Float<deUint32, 5, 6, 15, 0>	Float11;
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef Float<deUint32, 5, 5, 15, 0>	Float10;
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Optimized getters for common formats.
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \todo [2012-11-14 pyry] Use intrinsics if available.
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline Vec4		readRGBA8888Float	(const deUint8* ptr) { return Vec4(ptr[0]/255.0f, ptr[1]/255.0f, ptr[2]/255.0f, ptr[3]/255.0f); }
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline Vec4		readRGB888Float		(const deUint8* ptr) { return Vec4(ptr[0]/255.0f, ptr[1]/255.0f, ptr[2]/255.0f, 1.0f); }
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline IVec4	readRGBA8888Int		(const deUint8* ptr) { return IVec4(ptr[0], ptr[1], ptr[2], ptr[3]); }
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline IVec4	readRGB888Int		(const deUint8* ptr) { return IVec4(ptr[0], ptr[1], ptr[2], 0xff); }
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Optimized setters.
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline void writeRGBA8888Int (deUint8* ptr, const IVec4& val)
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6009307280328f7fe333960a53cddf8c2962af5536Jarkko Pöyry	ptr[0] = (deUint8)de::clamp(val[0], 0, 255);
6109307280328f7fe333960a53cddf8c2962af5536Jarkko Pöyry	ptr[1] = (deUint8)de::clamp(val[1], 0, 255);
6209307280328f7fe333960a53cddf8c2962af5536Jarkko Pöyry	ptr[2] = (deUint8)de::clamp(val[2], 0, 255);
6309307280328f7fe333960a53cddf8c2962af5536Jarkko Pöyry	ptr[3] = (deUint8)de::clamp(val[3], 0, 255);
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline void writeRGB888Int (deUint8* ptr, const IVec4& val)
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6809307280328f7fe333960a53cddf8c2962af5536Jarkko Pöyry	ptr[0] = (deUint8)de::clamp(val[0], 0, 255);
6909307280328f7fe333960a53cddf8c2962af5536Jarkko Pöyry	ptr[1] = (deUint8)de::clamp(val[1], 0, 255);
7009307280328f7fe333960a53cddf8c2962af5536Jarkko Pöyry	ptr[2] = (deUint8)de::clamp(val[2], 0, 255);
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline void writeRGBA8888Float (deUint8* ptr, const Vec4& val)
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ptr[0] = floatToU8(val[0]);
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ptr[1] = floatToU8(val[1]);
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ptr[2] = floatToU8(val[2]);
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ptr[3] = floatToU8(val[3]);
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline void writeRGB888Float (deUint8* ptr, const Vec4& val)
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ptr[0] = floatToU8(val[0]);
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ptr[1] = floatToU8(val[1]);
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ptr[2] = floatToU8(val[2]);
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8807104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyryinline void writeUint24 (deUint8* dst, deUint32 val)
8907104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry{
9007104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN)
9107104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	dst[0] = (deUint8)((val & 0x0000FFu) >>  0u);
9207104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	dst[1] = (deUint8)((val & 0x00FF00u) >>  8u);
9307104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	dst[2] = (deUint8)((val & 0xFF0000u) >> 16u);
9407104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry#else
9507104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	dst[0] = (deUint8)((val & 0xFF0000u) >> 16u);
9607104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	dst[1] = (deUint8)((val & 0x00FF00u) >>  8u);
9707104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	dst[2] = (deUint8)((val & 0x0000FFu) >>  0u);
9807104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry#endif
9907104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry}
10007104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
10107104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyryinline deUint32 readUint24 (const deUint8* src)
10207104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry{
10307104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN)
10407104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	return	(((deUint32)src[0]) <<  0u) |
10507104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry			(((deUint32)src[1]) <<  8u) |
10607104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry			(((deUint32)src[2]) << 16u);
10707104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry#else
10807104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	return	(((deUint32)src[0]) << 16u) |
10907104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry			(((deUint32)src[1]) <<  8u) |
11007104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry			(((deUint32)src[2]) <<  0u);
11107104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry#endif
11207104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry}
11307104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
114725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulosinline deUint8 readUint32Low8 (const deUint8* src)
11500d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos{
11600d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN)
117725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 uint32ByteOffsetBits0To8	= 0; //!< least significant byte in the lowest address
11800d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos#else
119725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 uint32ByteOffsetBits0To8	= 3; //!< least significant byte in the highest address
12000d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos#endif
12100d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos
122725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	return src[uint32ByteOffsetBits0To8];
12300d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos}
12400d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos
125725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulosinline deUint8 readUint32High8 (const deUint8* src)
12600d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos{
12700d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN)
128725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 uint32ByteOffsetBits24To32	= 3;
12900d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos#else
130725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 uint32ByteOffsetBits24To32	= 0;
13100d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos#endif
13200d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos
133725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	return src[uint32ByteOffsetBits24To32];
13400d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos}
13500d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos
136725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulosinline void writeUint32Low8 (deUint8* dst, deUint8 val)
13700d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos{
13800d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN)
139725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 uint32ByteOffsetBits0To8	= 0; //!< least significant byte in the lowest address
14000d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos#else
141725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 uint32ByteOffsetBits0To8	= 3; //!< least significant byte in the highest address
14200d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos#endif
143725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
144725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	dst[uint32ByteOffsetBits0To8] = val;
14500d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos}
14600d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos
147725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulosinline void writeUint32High8 (deUint8* dst, deUint8 val)
14800d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos{
14900d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN)
150725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 uint32ByteOffsetBits24To32	= 3;
15100d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos#else
152725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 uint32ByteOffsetBits24To32	= 0;
15300d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos#endif
154725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
155725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	dst[uint32ByteOffsetBits24To32] = val;
15600d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos}
15700d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos
158725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulosinline deUint32 readUint32High16 (const deUint8* src)
15974a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi{
16074a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN)
161725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 uint32ByteOffset16To32	= 2;
16274a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi#else
163725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 uint32ByteOffset16To32	= 0;
16474a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi#endif
16574a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi
166725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	return *(const deUint16*)(src + uint32ByteOffset16To32);
16774a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi}
16874a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi
169725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulosinline void writeUint32High16 (deUint8* dst, deUint16 val)
17074a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi{
17174a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN)
172725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 uint32ByteOffset16To32	= 2;
17374a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi#else
174725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 uint32ByteOffset16To32	= 0;
17574a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi#endif
17674a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi
177725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	*(deUint16*)(dst + uint32ByteOffset16To32) = val;
178725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos}
179725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
180725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulosinline deUint32 readUint32Low24 (const deUint8* src)
181725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos{
182725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN)
183725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 uint32ByteOffset0To24	= 0;
184725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#else
185725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 uint32ByteOffset0To24	= 1;
186725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#endif
187725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
188725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	return readUint24(src + uint32ByteOffset0To24);
18974a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi}
19074a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi
19174a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärviinline deUint32 readUint32High24 (const deUint8* src)
19274a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi{
19374a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN)
19474a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi	const deUint32 uint32ByteOffset8To32	= 1;
19574a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi#else
19674a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi	const deUint32 uint32ByteOffset8To32	= 0;
19774a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi#endif
19874a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi
19974a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi	return readUint24(src + uint32ByteOffset8To32);
20074a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi}
20174a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi
202725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulosinline void writeUint32Low24 (deUint8* dst, deUint32 val)
203725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos{
204725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN)
205725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 uint32ByteOffset0To24	= 0;
206725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#else
207725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 uint32ByteOffset0To24	= 1;
208725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#endif
209725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
210725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	writeUint24(dst + uint32ByteOffset0To24, val);
211725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos}
212725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
21374a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärviinline void writeUint32High24 (deUint8* dst, deUint32 val)
21474a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi{
21574a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN)
21674a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi	const deUint32 uint32ByteOffset8To32	= 1;
21774a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi#else
21874a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi	const deUint32 uint32ByteOffset8To32	= 0;
21974a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi#endif
22074a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi
22174a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi	writeUint24(dst + uint32ByteOffset8To32, val);
22274a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi}
22374a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \todo [2011-09-21 pyry] Move to tcutil?
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline T convertSatRte (float f)
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note Doesn't work for 64-bit types
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_STATIC_ASSERT(sizeof(T) < sizeof(deUint64));
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_STATIC_ASSERT((-3 % 2 != 0) && (-4 % 2 == 0));
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deInt64	minVal	= std::numeric_limits<T>::min();
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deInt64 maxVal	= std::numeric_limits<T>::max();
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float	q		= deFloatFrac(f);
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deInt64 intVal	= (deInt64)(f-q);
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Rounding.
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (q == 0.5f)
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (intVal % 2 != 0)
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			intVal++;
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (q > 0.5f)
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		intVal++;
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// else Don't add anything
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Saturate.
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	intVal = de::max(minVal, de::min(maxVal, intVal));
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (T)intVal;
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25307104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyryinline deUint32 convertSatRteUint24 (float f)
25407104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry{
25507104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	const deUint32 rounded		= convertSatRte<deUint32>(f);
25607104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	const deUint32 maxUint24	= 0xFFFFFFu;
25707104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	return de::min(rounded, maxUint24);
25807104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry}
25907104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint getChannelSize (TextureFormat::ChannelType type)
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26207104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	// make sure this table is updated if format table is updated
263725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 37);
26407104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (type)
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT8:			return 1;
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT16:		return 2;
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT32:		return 4;
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT8:			return 1;
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT16:		return 2;
27207104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry		case TextureFormat::UNORM_INT24:		return 3;
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT32:		return 4;
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT8:		return 1;
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT16:		return 2;
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT32:		return 4;
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT8:		return 1;
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT16:		return 2;
279db6ba452c1213fd1c2b03369fdf4c1d23f07cfadJarkko Pöyry		case TextureFormat::UNSIGNED_INT24:		return 3;
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT32:		return 4;
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::HALF_FLOAT:			return 2;
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT:				return 4;
283725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::FLOAT64:			return 8;
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0;
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint getNumUsedChannels (TextureFormat::ChannelOrder order)
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29207104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	// make sure this table is updated if type table is updated
293725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	DE_STATIC_ASSERT(TextureFormat::CHANNELORDER_LAST == 21);
29407104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (order)
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::R:			return 1;
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::A:			return 1;
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::I:			return 1;
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::L:			return 1;
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::LA:			return 2;
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::RG:			return 2;
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::RA:			return 2;
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::RGB:		return 3;
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::RGBA:		return 4;
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::ARGB:		return 4;
307725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::BGR:		return 3;
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::BGRA:		return 4;
30916d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		case TextureFormat::sR:			return 1;
31016d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		case TextureFormat::sRG:		return 2;
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::sRGB:		return 3;
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::sRGBA:		return 4;
313725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::sBGR:		return 3;
314725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::sBGRA:		return 4;
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::D:			return 1;
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::S:			return 1;
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::DS:			return 2;
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0;
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline float channelToFloat (const deUint8* value, TextureFormat::ChannelType type)
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32607104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	// make sure this table is updated if format table is updated
327725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 37);
32807104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (type)
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT8:			return de::max(-1.0f, (float)*((const deInt8*)value) / 127.0f);
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT16:		return de::max(-1.0f, (float)*((const deInt16*)value) / 32767.0f);
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT32:		return de::max(-1.0f, (float)*((const deInt32*)value) / 2147483647.0f);
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT8:			return (float)*((const deUint8*)value) / 255.0f;
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT16:		return (float)*((const deUint16*)value) / 65535.0f;
33607104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry		case TextureFormat::UNORM_INT24:		return (float)readUint24(value) / 16777215.0f;
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT32:		return (float)*((const deUint32*)value) / 4294967295.0f;
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT8:		return (float)*((const deInt8*)value);
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT16:		return (float)*((const deInt16*)value);
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT32:		return (float)*((const deInt32*)value);
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT8:		return (float)*((const deUint8*)value);
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT16:		return (float)*((const deUint16*)value);
343db6ba452c1213fd1c2b03369fdf4c1d23f07cfadJarkko Pöyry		case TextureFormat::UNSIGNED_INT24:		return (float)readUint24(value);
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT32:		return (float)*((const deUint32*)value);
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::HALF_FLOAT:			return deFloat16To32(*(const deFloat16*)value);
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT:				return *((const float*)value);
347725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::FLOAT64:			return (float)*((const double*)value);
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int channelToInt (const deUint8* value, TextureFormat::ChannelType type)
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35607104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	// make sure this table is updated if format table is updated
357725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 37);
35807104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (type)
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT8:			return (int)*((const deInt8*)value);
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT16:		return (int)*((const deInt16*)value);
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT32:		return (int)*((const deInt32*)value);
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT8:			return (int)*((const deUint8*)value);
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT16:		return (int)*((const deUint16*)value);
36607104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry		case TextureFormat::UNORM_INT24:		return (int)readUint24(value);
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT32:		return (int)*((const deUint32*)value);
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT8:		return (int)*((const deInt8*)value);
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT16:		return (int)*((const deInt16*)value);
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT32:		return (int)*((const deInt32*)value);
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT8:		return (int)*((const deUint8*)value);
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT16:		return (int)*((const deUint16*)value);
373db6ba452c1213fd1c2b03369fdf4c1d23f07cfadJarkko Pöyry		case TextureFormat::UNSIGNED_INT24:		return (int)readUint24(value);
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT32:		return (int)*((const deUint32*)value);
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::HALF_FLOAT:			return (int)deFloat16To32(*(const deFloat16*)value);
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT:				return (int)*((const float*)value);
377725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::FLOAT64:			return (int)*((const double*)value);
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0;
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid floatToChannel (deUint8* dst, float src, TextureFormat::ChannelType type)
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
38607104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	// make sure this table is updated if format table is updated
387725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 37);
38807104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (type)
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT8:			*((deInt8*)dst)			= convertSatRte<deInt8>		(src * 127.0f);			break;
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT16:		*((deInt16*)dst)		= convertSatRte<deInt16>	(src * 32767.0f);		break;
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT32:		*((deInt32*)dst)		= convertSatRte<deInt32>	(src * 2147483647.0f);	break;
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT8:			*((deUint8*)dst)		= convertSatRte<deUint8>	(src * 255.0f);			break;
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT16:		*((deUint16*)dst)		= convertSatRte<deUint16>	(src * 65535.0f);		break;
396db6ba452c1213fd1c2b03369fdf4c1d23f07cfadJarkko Pöyry		case TextureFormat::UNORM_INT24:		writeUint24(dst,		  convertSatRteUint24		(src * 16777215.0f));	break;
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT32:		*((deUint32*)dst)		= convertSatRte<deUint32>	(src * 4294967295.0f);	break;
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT8:		*((deInt8*)dst)			= convertSatRte<deInt8>		(src);					break;
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT16:		*((deInt16*)dst)		= convertSatRte<deInt16>	(src);					break;
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT32:		*((deInt32*)dst)		= convertSatRte<deInt32>	(src);					break;
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT8:		*((deUint8*)dst)		= convertSatRte<deUint8>	(src);					break;
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT16:		*((deUint16*)dst)		= convertSatRte<deUint16>	(src);					break;
403db6ba452c1213fd1c2b03369fdf4c1d23f07cfadJarkko Pöyry		case TextureFormat::UNSIGNED_INT24:		writeUint24(dst,		  convertSatRteUint24		(src));					break;
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT32:		*((deUint32*)dst)		= convertSatRte<deUint32>	(src);					break;
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::HALF_FLOAT:			*((deFloat16*)dst)		= deFloat32To16				(src);					break;
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT:				*((float*)dst)			= src;												break;
407725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::FLOAT64:			*((double*)dst)			= (double)src;										break;
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, typename S>
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline T convertSat (S src)
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	S min = (S)std::numeric_limits<T>::min();
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	S max = (S)std::numeric_limits<T>::max();
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (src < min)
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return (T)min;
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (src > max)
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return (T)max;
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return (T)src;
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
42707104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyrytemplate <typename S>
42807104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyrystatic inline deUint32 convertSatUint24 (S src)
42907104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry{
43007104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	S min = (S)0u;
43107104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	S max = (S)0xFFFFFFu;
43207104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
43307104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	if (src < min)
43407104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry		return (deUint32)min;
43507104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	else if (src > max)
43607104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry		return (deUint32)max;
43707104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	else
43807104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry		return (deUint32)src;
43907104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry}
44007104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid intToChannel (deUint8* dst, int src, TextureFormat::ChannelType type)
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
44307104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	// make sure this table is updated if format table is updated
444725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 37);
44507104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (type)
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT8:			*((deInt8*)dst)			= convertSat<deInt8>	(src);				break;
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT16:		*((deInt16*)dst)		= convertSat<deInt16>	(src);				break;
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT8:			*((deUint8*)dst)		= convertSat<deUint8>	(src);				break;
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT16:		*((deUint16*)dst)		= convertSat<deUint16>	(src);				break;
452db6ba452c1213fd1c2b03369fdf4c1d23f07cfadJarkko Pöyry		case TextureFormat::UNORM_INT24:		writeUint24(dst,		  convertSatUint24		(src));				break;
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT8:		*((deInt8*)dst)			= convertSat<deInt8>	(src);				break;
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT16:		*((deInt16*)dst)		= convertSat<deInt16>	(src);				break;
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT32:		*((deInt32*)dst)		= convertSat<deInt32>	(src);				break;
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT8:		*((deUint8*)dst)		= convertSat<deUint8>	((deUint32)src);	break;
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT16:		*((deUint16*)dst)		= convertSat<deUint16>	((deUint32)src);	break;
458db6ba452c1213fd1c2b03369fdf4c1d23f07cfadJarkko Pöyry		case TextureFormat::UNSIGNED_INT24:		writeUint24(dst,		  convertSatUint24		((deUint32)src));	break;
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT32:		*((deUint32*)dst)		= convertSat<deUint32>	((deUint32)src);	break;
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::HALF_FLOAT:			*((deFloat16*)dst)		= deFloat32To16((float)src);				break;
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT:				*((float*)dst)			= (float)src;								break;
462725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::FLOAT64:			*((double*)dst)			= (double)src;								break;
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
468725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulosinline float channelToUnormFloat (deUint32 src, int bits)
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
470725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 maxVal = (1u << bits) - 1;
471725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
472725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	// \note Will lose precision if bits > 23
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (float)src / (float)maxVal;
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
476725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos//! Extend < 32b signed integer to 32b
477725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulosinline deInt32 signExtend (deUint32 src, int bits)
478725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos{
479725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 signBit = 1u << (bits-1);
480725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
481725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	src |= ~((src & signBit) - 1);
482725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
483725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	return (deInt32)src;
484725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos}
485725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
486725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulosinline float channelToSnormFloat (deUint32 src, int bits)
487725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos{
488725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32	range	= (1u << (bits-1)) - 1;
489725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
490725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	// \note Will lose precision if bits > 24
491725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	return de::max(-1.0f, (float)signExtend(src, bits) / (float)range);
492725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos}
493725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
494725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulosinline deUint32 unormFloatToChannel (float src, int bits)
495725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos{
496725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32	maxVal	= (1u << bits) - 1;
497725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32	intVal	= convertSatRte<deUint32>(src * (float)maxVal);
498725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
499725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	return de::min(intVal, maxVal);
500725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos}
501725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
502725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulosinline deUint32 snormFloatToChannel (float src, int bits)
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
504725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deInt32	range	= (deInt32)((1u << (bits-1)) - 1u);
505725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32	mask	= (1u << bits) - 1;
506725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deInt32	intVal	= convertSatRte<deInt32>(src * (float)range);
507725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
508725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	return (deUint32)de::clamp(intVal, -range, range) & mask;
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline deUint32 uintToChannel (deUint32 src, int bits)
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
513725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 maxVal = (1u << bits) - 1;
514725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	return de::min(src, maxVal);
515725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos}
516725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
517725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulosinline deUint32 intToChannel (deInt32 src, int bits)
518725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos{
519725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deInt32	minVal	= -(deInt32)(1u << (bits-1));
520725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deInt32	maxVal	= (deInt32)((1u << (bits-1)) - 1u);
521725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32	mask	= (1u << bits) - 1;
522725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
523725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	return (deUint32)de::clamp(src, minVal, maxVal) & mask;
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Vec4 unpackRGB999E5 (deUint32 color)
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	mBits	= 9;
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	eBias	= 15;
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32	exp		= color >> 27;
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32	bs		= (color >> 18) & ((1<<9)-1);
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32	gs		= (color >> 9) & ((1<<9)-1);
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32	rs		= color & ((1<<9)-1);
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		e		= deFloatPow(2.0f, (float)((int)exp - eBias - mBits));
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		r		= (float)rs * e;
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		g		= (float)gs * e;
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		b		= (float)bs * e;
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return tcu::Vec4(r, g, b, 1.0f);
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5466d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyryconst TextureSwizzle& getChannelReadSwizzle (TextureFormat::ChannelOrder order)
5476d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry{
5486d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	// make sure to update these tables when channel orders are updated
549725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	DE_STATIC_ASSERT(TextureFormat::CHANNELORDER_LAST == 21);
5506d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
5516d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle INV		= {{ TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ONE	}};
5526d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle R		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ONE	}};
5536d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle A		= {{ TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_0	}};
5546d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle I		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0	}};
5556d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle L		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ONE	}};
5566d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle LA		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1	}};
5576d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RG		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ONE	}};
5586d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RA		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_1	}};
5596d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RGB		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_ONE	}};
5606d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RGBA	= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_3	}};
561725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	static const TextureSwizzle BGR		= {{ TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ONE	}};
5626d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle BGRA	= {{ TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_3	}};
5636d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle ARGB	= {{ TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_3,		TextureSwizzle::CHANNEL_0	}};
5646d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle D		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ONE	}};
56509037a4653649d707449463dfe9817a78ccf7d2fJarkko Pöyry	static const TextureSwizzle S		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ONE	}};
5666d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
5676d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	switch (order)
5686d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	{
5696d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::R:			return R;
5706d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::A:			return A;
5716d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::I:			return I;
5726d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::L:			return L;
5736d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::LA:			return LA;
5746d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RG:			return RG;
5756d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RA:			return RA;
5766d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RGB:		return RGB;
5776d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RGBA:		return RGBA;
5786d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::ARGB:		return ARGB;
579725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::BGR:		return BGR;
5806d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::BGRA:		return BGRA;
58116d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		case TextureFormat::sR:			return R;
58216d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		case TextureFormat::sRG:		return RG;
5836d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::sRGB:		return RGB;
5846d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::sRGBA:		return RGBA;
585725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::sBGR:		return BGR;
586725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::sBGRA:		return BGRA;
5876d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::D:			return D;
5886d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::S:			return S;
5898baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry
5908baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry		case TextureFormat::DS:
5918baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			DE_ASSERT(false); // combined formats cannot be read from
5928baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			return INV;
5938baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry
5946d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		default:
5956d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			DE_ASSERT(DE_FALSE);
5966d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			return INV;
5976d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	}
5986d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry}
5996d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
6006d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyryconst TextureSwizzle& getChannelWriteSwizzle (TextureFormat::ChannelOrder order)
6016d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry{
6026d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	// make sure to update these tables when channel orders are updated
603725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	DE_STATIC_ASSERT(TextureFormat::CHANNELORDER_LAST == 21);
6046d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
6056d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle INV		= {{ TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
6066d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle R		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
6076d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle A		= {{ TextureSwizzle::CHANNEL_3,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
6086d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle I		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
6096d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle L		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
6106d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle LA		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_3,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
6116d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RG		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
6126d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RA		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_3,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
6136d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RGB		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_LAST	}};
6146d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RGBA	= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_3		}};
615725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	static const TextureSwizzle BGR		= {{ TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_LAST	}};
6166d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle BGRA	= {{ TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_3		}};
6176d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle ARGB	= {{ TextureSwizzle::CHANNEL_3,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_2		}};
6186d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle D		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
61909037a4653649d707449463dfe9817a78ccf7d2fJarkko Pöyry	static const TextureSwizzle S		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
6206d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
6216d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	switch (order)
6226d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	{
6236d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::R:			return R;
6246d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::A:			return A;
6256d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::I:			return I;
6266d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::L:			return L;
6276d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::LA:			return LA;
6286d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RG:			return RG;
6296d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RA:			return RA;
6306d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RGB:		return RGB;
6316d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RGBA:		return RGBA;
6326d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::ARGB:		return ARGB;
633725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::BGR:		return BGR;
6346d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::BGRA:		return BGRA;
63516d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		case TextureFormat::sR:			return R;
63616d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		case TextureFormat::sRG:		return RG;
6376d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::sRGB:		return RGB;
6386d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::sRGBA:		return RGBA;
639725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::sBGR:		return BGR;
640725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::sBGRA:		return BGRA;
6416d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::D:			return D;
6426d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::S:			return S;
6438baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry
6448baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry		case TextureFormat::DS:
6458baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			DE_ASSERT(false); // combined formats cannot be written to
6468baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			return INV;
6478baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry
6486d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		default:
6496d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			DE_ASSERT(DE_FALSE);
6506d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			return INV;
6516d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	}
6526d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry}
6536d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
65429340067e919854db7d50bb8c0b666117b229f5eMika IsojärviIVec3 calculatePackedPitch (const TextureFormat& format, const IVec3& size)
65529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi{
65629340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	const int pixelSize		= format.getPixelSize();
65729340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	const int rowPitch		= pixelSize * size.x();
65829340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	const int slicePitch	= rowPitch * size.y();
65929340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
66029340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	return IVec3(pixelSize, rowPitch, slicePitch);
66129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi}
66229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/** Get pixel size in bytes. */
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint TextureFormat::getPixelSize (void) const
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (type == CHANNELTYPE_LAST && order == CHANNELORDER_LAST)
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Invalid/empty format.
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 0;
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
671725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	else if (type == UNORM_BYTE_44)
672725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	{
673725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		DE_ASSERT(order == RG);
674725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		return 1;
675725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	}
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (type == UNORM_SHORT_565	||
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 type == UNORM_SHORT_555	||
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 type == UNORM_SHORT_4444	||
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 type == UNORM_SHORT_5551)
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
681725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		DE_ASSERT(order == RGB || order == RGBA || order == BGR || order == BGRA);
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 2;
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (type == UNORM_INT_101010			||
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 type == UNSIGNED_INT_999_E5_REV	||
6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 type == UNSIGNED_INT_11F_11F_10F_REV)
6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(order == RGB);
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 4;
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (type == UNORM_INT_1010102_REV		||
692725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			 type == UNSIGNED_INT_1010102_REV	||
693725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			 type == SNORM_INT_1010102_REV		||
694725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			 type == SIGNED_INT_1010102_REV)
6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
696725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		DE_ASSERT(order == RGBA || order == BGRA);
6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 4;
6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
699725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	else if (type == UNSIGNED_INT_24_8		||
700725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			 type == UNSIGNED_INT_24_8_REV	||
701725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			 type == UNSIGNED_INT_16_8_8)
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(order == D || order == DS);
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 4;
7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (type == FLOAT_UNSIGNED_INT_24_8_REV)
7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(order == DS);
7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 8;
7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
71207104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry		return getNumUsedChannels(order) * getChannelSize(type);
7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7153c827367444ee418f129b2c238299f49d3264554Jarkko PoyryConstPixelBufferAccess::ConstPixelBufferAccess (void)
71629340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	: m_size		(0)
71729340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_pitch		(0)
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_data		(DE_NULL)
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7223c827367444ee418f129b2c238299f49d3264554Jarkko PoyryConstPixelBufferAccess::ConstPixelBufferAccess (const TextureFormat& format, int width, int height, int depth, const void* data)
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format		(format)
72429340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size		(width, height, depth)
72529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_pitch		(calculatePackedPitch(m_format, m_size))
72629340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_data		((void*)data)
72729340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi{
72829340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi}
72929340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
73029340067e919854db7d50bb8c0b666117b229f5eMika IsojärviConstPixelBufferAccess::ConstPixelBufferAccess (const TextureFormat& format, const IVec3& size, const void* data)
73129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	: m_format		(format)
73229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size		(size)
73329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_pitch		(calculatePackedPitch(m_format, m_size))
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_data		((void*)data)
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7383c827367444ee418f129b2c238299f49d3264554Jarkko PoyryConstPixelBufferAccess::ConstPixelBufferAccess (const TextureFormat& format, int width, int height, int depth, int rowPitch, int slicePitch, const void* data)
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format		(format)
74029340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size		(width, height, depth)
74129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_pitch		(format.getPixelSize(), rowPitch, slicePitch)
74229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_data		((void*)data)
74329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi{
74429340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi}
74529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
74629340067e919854db7d50bb8c0b666117b229f5eMika IsojärviConstPixelBufferAccess::ConstPixelBufferAccess (const TextureFormat& format, const IVec3& size, const IVec3& pitch, const void* data)
74729340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	: m_format		(format)
74829340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size		(size)
74929340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_pitch		(pitch)
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_data		((void*)data)
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
75229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(m_format.getPixelSize() <= m_pitch.x());
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7553c827367444ee418f129b2c238299f49d3264554Jarkko PoyryConstPixelBufferAccess::ConstPixelBufferAccess (const TextureLevel& level)
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format		(level.getFormat())
75729340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size		(level.getSize())
75829340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_pitch		(calculatePackedPitch(m_format, m_size))
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_data		((void*)level.getPtr())
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7633c827367444ee418f129b2c238299f49d3264554Jarkko PoyryPixelBufferAccess::PixelBufferAccess (const TextureFormat& format, int width, int height, int depth, void* data)
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: ConstPixelBufferAccess(format, width, height, depth, data)
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
76829340067e919854db7d50bb8c0b666117b229f5eMika IsojärviPixelBufferAccess::PixelBufferAccess (const TextureFormat& format, const IVec3& size, void* data)
76929340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	: ConstPixelBufferAccess(format, size, data)
77029340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi{
77129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi}
77229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
7733c827367444ee418f129b2c238299f49d3264554Jarkko PoyryPixelBufferAccess::PixelBufferAccess (const TextureFormat& format, int width, int height, int depth, int rowPitch, int slicePitch, void* data)
7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: ConstPixelBufferAccess(format, width, height, depth, rowPitch, slicePitch, data)
7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
77829340067e919854db7d50bb8c0b666117b229f5eMika IsojärviPixelBufferAccess::PixelBufferAccess (const TextureFormat& format, const IVec3& size, const IVec3& pitch, void* data)
77929340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	: ConstPixelBufferAccess(format, size, pitch, data)
78029340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi{
78129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi}
78229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
7833c827367444ee418f129b2c238299f49d3264554Jarkko PoyryPixelBufferAccess::PixelBufferAccess (TextureLevel& level)
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: ConstPixelBufferAccess(level)
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
788725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos//! Swizzle RGB(A) <-> BGR(A)
789725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulostemplate<typename T>
790725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry HaulosVector<T, 4> swizzleRB (const Vector<T, 4>& v, TextureFormat::ChannelOrder src, TextureFormat::ChannelOrder dst)
791725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos{
792725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	if (src == dst)
793725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		return v;
794725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	else
795725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	{
796725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		DE_ASSERT((src == TextureFormat::RGB && dst == TextureFormat::BGR) ||
797725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos				  (src == TextureFormat::BGR && dst == TextureFormat::RGB) ||
798725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos				  (src == TextureFormat::RGBA && dst == TextureFormat::BGRA) ||
799725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos				  (src == TextureFormat::BGRA && dst == TextureFormat::RGBA));
800725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		return v.swizzle(2,1,0,3);
801725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	}
802725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos}
803725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
8043c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 ConstPixelBufferAccess::getPixel (int x, int y, int z) const
8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
80629340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(x, 0, m_size.x()));
80729340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(y, 0, m_size.y()));
80829340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(z, 0, m_size.z()));
8098baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	DE_ASSERT(!isCombinedDepthStencilType(m_format.type)); // combined types cannot be accessed directly
8108baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	DE_ASSERT(m_format.order != TextureFormat::DS); // combined formats cannot be accessed directly
81129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
8128baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	const deUint8* pixelPtr = (const deUint8*)getPixelPtr(x, y, z);
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Optimized fomats.
8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_format.type == TextureFormat::UNORM_INT8)
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8170158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		if (m_format.order == TextureFormat::RGBA || m_format.order == TextureFormat::sRGBA)
81829340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi			return readRGBA8888Float(pixelPtr);
8190158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		else if (m_format.order == TextureFormat::RGB || m_format.order == TextureFormat::sRGB)
82029340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi			return readRGB888Float(pixelPtr);
8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
823725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define UI8(OFFS, COUNT)		((*((const deUint8*)pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1))
824725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define UI16(OFFS, COUNT)		((*((const deUint16*)pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1))
825725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define UI32(OFFS, COUNT)		((*((const deUint32*)pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1))
826725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define SI32(OFFS, COUNT)		signExtend(UI32(OFFS, COUNT), (COUNT))
827725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define UN8(OFFS, COUNT)		channelToUnormFloat(UI8 (OFFS, COUNT), (COUNT))
828725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define UN16(OFFS, COUNT)		channelToUnormFloat(UI16(OFFS, COUNT), (COUNT))
829725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define UN32(OFFS, COUNT)		channelToUnormFloat(UI32(OFFS, COUNT), (COUNT))
830725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define SN32(OFFS, COUNT)		channelToSnormFloat(UI32(OFFS, COUNT), (COUNT))
8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Packed formats.
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
835725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_BYTE_44:				return			  Vec4(UN8 (4,   4), UN8 ( 0,  4), 0.0f, 1.0f);
836725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_BYTE_44:			return			 UVec4(UI8 (4,   4), UI8 ( 0,  4), 0u, 1u).cast<float>();
837725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_565:			return swizzleRB( Vec4(UN16(11,  5), UN16( 5,  6), UN16( 0,  5), 1.0f), TextureFormat::RGB, m_format.order);
838725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_565:			return swizzleRB(UVec4(UI16(11,  5), UI16( 5,  6), UI16( 0,  5), 1u), TextureFormat::RGB, m_format.order).cast<float>();
839725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_555:			return swizzleRB( Vec4(UN16(10,  5), UN16( 5,  5), UN16( 0,  5), 1.0f), TextureFormat::RGB, m_format.order);
840725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_4444:			return swizzleRB( Vec4(UN16(12,  4), UN16( 8,  4), UN16( 4,  4), UN16( 0, 4)), TextureFormat::RGBA, m_format.order);
841725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_4444:		return swizzleRB(UVec4(UI16(12,  4), UI16( 8,  4), UI16( 4,  4), UI16( 0, 4)), TextureFormat::RGBA, m_format.order).cast<float>();
842725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_5551:			return swizzleRB( Vec4(UN16(11,  5), UN16( 6,  5), UN16( 1,  5), UN16( 0, 1)), TextureFormat::RGBA, m_format.order);
843725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_5551:		return swizzleRB(UVec4(UI16(11,  5), UI16( 6,  5), UI16( 1,  5), UI16( 0, 1)), TextureFormat::RGBA, m_format.order).cast<float>();
844725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_INT_101010:			return			  Vec4(UN32(22, 10), UN32(12, 10), UN32( 2, 10), 1.0f);
845725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_INT_1010102_REV:		return swizzleRB( Vec4(UN32( 0, 10), UN32(10, 10), UN32(20, 10), UN32(30, 2)), TextureFormat::RGBA, m_format.order);
846725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::SNORM_INT_1010102_REV:		return swizzleRB( Vec4(SN32( 0, 10), SN32(10, 10), SN32(20, 10), SN32(30, 2)), TextureFormat::RGBA, m_format.order);
847725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_1010102_REV:	return swizzleRB( UVec4(UI32(0, 10), UI32(10, 10), UI32(20, 10), UI32(30, 2)), TextureFormat::RGBA, m_format.order).cast<float>();
848725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::SIGNED_INT_1010102_REV:		return swizzleRB( UVec4(SI32(0, 10), SI32(10, 10), SI32(20, 10), SI32(30, 2)), TextureFormat::RGBA, m_format.order).cast<float>();
8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_999_E5_REV:	return unpackRGB999E5(*((const deUint32*)pixelPtr));
8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
852725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			return Vec4(Float11(UI32(0, 11)).asFloat(), Float11(UI32(11, 11)).asFloat(), Float10(UI32(22, 10)).asFloat(), 1.0f);
8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
858725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef UN8
859725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef UN16
860725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef UN32
861725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef SN32
862725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef SI32
863725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef UI8
864725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef UI16
865725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef UI32
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generic path.
8686d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	Vec4							result;
8696d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	const TextureSwizzle::Channel*	channelMap	= getChannelReadSwizzle(m_format.order).components;
8706d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	int								channelSize	= getChannelSize(m_format.type);
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int c = 0; c < 4; c++)
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8746d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		switch (channelMap[c])
8756d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		{
8766d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_0:
8776d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_1:
8786d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_2:
8796d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_3:
8806d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				result[c] = channelToFloat(pixelPtr + channelSize*((int)channelMap[c]), m_format.type);
8816d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				break;
8826d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
8836d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_ZERO:
8846d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				result[c] = 0.0f;
8856d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				break;
8866d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
8876d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_ONE:
8886d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				result[c] = 1.0f;
8896d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				break;
8906d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
8916d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			default:
8926d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				DE_ASSERT(false);
8936d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		}
8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8993c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIVec4 ConstPixelBufferAccess::getPixelInt (int x, int y, int z) const
9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
90129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(x, 0, m_size.x()));
90229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(y, 0, m_size.y()));
90329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(z, 0, m_size.z()));
9048baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	DE_ASSERT(!isCombinedDepthStencilType(m_format.type)); // combined types cannot be accessed directly
9058baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	DE_ASSERT(m_format.order != TextureFormat::DS); // combined formats cannot be accessed directly
9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9078baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	const deUint8* const	pixelPtr = (const deUint8*)getPixelPtr(x, y, z);
90807104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	IVec4					result;
9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Optimized fomats.
9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_format.type == TextureFormat::UNORM_INT8)
9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9130158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		if (m_format.order == TextureFormat::RGBA || m_format.order == TextureFormat::sRGBA)
9140158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi			return readRGBA8888Int(pixelPtr);
9150158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		else if (m_format.order == TextureFormat::RGB || m_format.order == TextureFormat::sRGB)
9160158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi			return readRGB888Int(pixelPtr);
9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
919725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define U8(OFFS, COUNT)			((*((const deUint8* )pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1))
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define U16(OFFS, COUNT)		((*((const deUint16*)pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1))
9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define U32(OFFS, COUNT)		((*((const deUint32*)pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1))
922725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define S32(OFFS, COUNT)		signExtend(U32(OFFS, COUNT), (COUNT))
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
926725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_BYTE_44:			// Fall-through
927725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_BYTE_44:				return			 UVec4(U8 ( 4,  4), U8 ( 0,  4), 0u, 1u).cast<int>();
928725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_565:			// Fall-through
929725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_565:			return swizzleRB(UVec4(U16(11,  5), U16( 5,  6), U16( 0,  5), 1).cast<int>(), TextureFormat::RGB, m_format.order);
930725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_555:			return swizzleRB(UVec4(U16(10,  5), U16( 5,  5), U16( 0,  5), 1).cast<int>(), TextureFormat::RGB, m_format.order);
931725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_4444:		// Fall-through
932725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_4444:			return swizzleRB(UVec4(U16(12,  4), U16( 8,  4), U16( 4,  4), U16( 0, 4)).cast<int>(), TextureFormat::RGBA, m_format.order);
933725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_5551:		// Fall-through
934725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_5551:			return swizzleRB(UVec4(U16(11,  5), U16( 6,  5), U16( 1,  5), U16( 0, 1)).cast<int>(), TextureFormat::RGBA, m_format.order);
935725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_INT_101010:			return			 UVec4(U32(22, 10), U32(12, 10), U32( 2, 10), 1).cast<int>();
936725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_INT_1010102_REV:		// Fall-through
937725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_1010102_REV:	return swizzleRB(UVec4(U32( 0, 10), U32(10, 10), U32(20, 10), U32(30, 2)), TextureFormat::RGBA, m_format.order).cast<int>();
938725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::SNORM_INT_1010102_REV:		// Fall-through
939725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::SIGNED_INT_1010102_REV:		return swizzleRB(IVec4(S32( 0, 10), S32(10, 10), S32(20, 10), S32(30, 2)), TextureFormat::RGBA, m_format.order);
9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break; // To generic path.
9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
945725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef U8
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef U16
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef U32
948725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef S32
9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generic path.
9516d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	const TextureSwizzle::Channel*	channelMap	= getChannelReadSwizzle(m_format.order).components;
9526d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	int								channelSize	= getChannelSize(m_format.type);
9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int c = 0; c < 4; c++)
9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9566d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		switch (channelMap[c])
9576d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		{
9586d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_0:
9596d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_1:
9606d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_2:
9616d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_3:
9626d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				result[c] = channelToInt(pixelPtr + channelSize*((int)channelMap[c]), m_format.type);
9636d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				break;
9646d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
9656d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_ZERO:
9666d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				result[c] = 0;
9676d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				break;
9686d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
9696d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_ONE:
9706d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				result[c] = 1;
9716d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				break;
9726d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
9736d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			default:
9746d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				DE_ASSERT(false);
9756d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		}
9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<>
9823c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 ConstPixelBufferAccess::getPixelT (int x, int y, int z) const
9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return getPixel(x, y, z);
9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<>
9883c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIVec4 ConstPixelBufferAccess::getPixelT (int x, int y, int z) const
9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return getPixelInt(x, y, z);
9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<>
9943c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUVec4 ConstPixelBufferAccess::getPixelT (int x, int y, int z) const
9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return getPixelUint(x, y, z);
9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat ConstPixelBufferAccess::getPixDepth (int x, int y, int z) const
10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(x, 0, getWidth()));
10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(y, 0, getHeight()));
10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(z, 0, getDepth()));
10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10058baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	const deUint8* const pixelPtr = (const deUint8*)getPixelPtr(x, y, z);
10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1009725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_16_8_8:
101000d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::DS);
1011725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			return (float)readUint32High16(pixelPtr) / 65535.0f;
101274a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi
101300d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos		case TextureFormat::UNSIGNED_INT_24_8:
1014725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::D || m_format.order == TextureFormat::DS);
101500d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			return (float)readUint32High24(pixelPtr) / 16777215.0f;
10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1017725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_24_8_REV:
1018725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::D || m_format.order == TextureFormat::DS);
1019725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			return (float)readUint32Low24(pixelPtr) / 16777215.0f;
1020725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_format.order == TextureFormat::DS);
10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return *((const float*)pixelPtr);
10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
10268baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			DE_ASSERT(m_format.order == TextureFormat::D); // no other combined depth stencil types
10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return channelToFloat(pixelPtr, m_format.type);
10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint ConstPixelBufferAccess::getPixStencil (int x, int y, int z) const
10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(x, 0, getWidth()));
10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(y, 0, getHeight()));
10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(z, 0, getDepth()));
10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10378baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	const deUint8* const pixelPtr = (const deUint8*)getPixelPtr(x, y, z);
10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1041725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_24_8_REV:
104200d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::DS);
1043725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			return (int)readUint32High8(pixelPtr);
104400d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos
1045725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_16_8_8:
10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_24_8:
104700d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::DS);
104800d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			return (int)readUint32Low8(pixelPtr);
10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_format.order == TextureFormat::DS);
105274a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi			return (int)readUint32Low8(pixelPtr + 4);
10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10568baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			DE_ASSERT(m_format.order == TextureFormat::S); // no other combined depth stencil types
10578baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			return channelToInt(pixelPtr, m_format.type);
10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PixelBufferAccess::setPixel (const Vec4& color, int x, int y, int z) const
10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(x, 0, getWidth()));
10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(y, 0, getHeight()));
10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(z, 0, getDepth()));
10678baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	DE_ASSERT(!isCombinedDepthStencilType(m_format.type)); // combined types cannot be accessed directly
10688baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	DE_ASSERT(m_format.order != TextureFormat::DS); // combined formats cannot be accessed directly
10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10708baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	deUint8* const pixelPtr = (deUint8*)getPixelPtr(x, y, z);
107129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Optimized fomats.
10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_format.type == TextureFormat::UNORM_INT8)
10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10750158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		if (m_format.order == TextureFormat::RGBA || m_format.order == TextureFormat::sRGBA)
10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
107729340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi			writeRGBA8888Float(pixelPtr, color);
10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return;
10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10800158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		else if (m_format.order == TextureFormat::RGB || m_format.order == TextureFormat::sRGB)
10813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
108229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi			writeRGB888Float(pixelPtr, color);
10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return;
10843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1087725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define PN(VAL, OFFS, BITS)		(unormFloatToChannel((VAL), (BITS)) << (OFFS))
1088725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define PS(VAL, OFFS, BITS)		(snormFloatToChannel((VAL), (BITS)) << (OFFS))
10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define PU(VAL, OFFS, BITS)		(uintToChannel((VAL), (BITS)) << (OFFS))
1090725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define PI(VAL, OFFS, BITS)		(intToChannel((VAL), (BITS)) << (OFFS))
10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1094725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_BYTE_44:		*((deUint8 *)pixelPtr) = (deUint8)(PN(color[0], 4, 4) | PN(color[1], 0, 4));						break;
1095725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_BYTE_44:	*((deUint8 *)pixelPtr) = (deUint8)(PU((deUint32)color[0], 4, 4) | PU((deUint32)color[1], 0, 4));	break;
1096725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_INT_101010:	*((deUint32*)pixelPtr) = PN(color[0], 22, 10) | PN(color[1], 12, 10) | PN(color[2], 2, 10);			break;
1097725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1098725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_565:
1099725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
1100725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			const Vec4 swizzled = swizzleRB(color, m_format.order, TextureFormat::RGB);
1101725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PN(swizzled[0], 11, 5) | PN(swizzled[1], 5, 6) | PN(swizzled[2], 0, 5));
1102725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1103725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1104725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1105725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_565:
1106725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
1107725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			const UVec4 swizzled = swizzleRB(color.cast<deUint32>(), m_format.order, TextureFormat::RGB);
1108725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PU(swizzled[0], 11, 5) | PU(swizzled[1], 5, 6) | PU(swizzled[2], 0, 5));
1109725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1110725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1111725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1112725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_555:
1113725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
1114725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			const Vec4 swizzled = swizzleRB(color, m_format.order, TextureFormat::RGB);
1115725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PN(swizzled[0], 10, 5) | PN(swizzled[1], 5, 5) | PN(swizzled[2], 0, 5));
1116725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1117725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1118725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1119725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_4444:
1120725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
1121725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			const Vec4 swizzled = swizzleRB(color, m_format.order, TextureFormat::RGBA);
1122725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PN(swizzled[0], 12, 4) | PN(swizzled[1], 8, 4) | PN(swizzled[2], 4, 4) | PN(swizzled[3], 0, 4));
1123725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1124725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1125725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1126725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_4444:
1127725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
1128725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			const UVec4 swizzled = swizzleRB(color.cast<deUint32>(), m_format.order, TextureFormat::RGBA);
1129725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PU(swizzled[0], 12, 4) | PU(swizzled[1], 8, 4) | PU(swizzled[2], 4, 4) | PU(swizzled[3], 0, 4));
1130725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1131725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1132725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1133725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_5551:
1134725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
1135725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			const Vec4 swizzled = swizzleRB(color, m_format.order, TextureFormat::RGBA);
1136725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PN(swizzled[0], 11, 5) | PN(swizzled[1], 6, 5) | PN(swizzled[2], 1, 5) | PN(swizzled[3], 0, 1));
1137725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1138725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1139725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1140725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_5551:
1141725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
1142725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			const UVec4 swizzled = swizzleRB(color.cast<deUint32>(), m_format.order, TextureFormat::RGBA);
1143725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PU(swizzled[0], 11, 5) | PU(swizzled[1], 6, 5) | PU(swizzled[2], 1, 5) | PU(swizzled[3], 0, 1));
1144725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1145725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1146725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1147725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_INT_1010102_REV:
1148725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
1149725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			const Vec4 u = swizzleRB(color, m_format.order, TextureFormat::RGBA);
1150725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint32*)pixelPtr) = PN(u[0], 0, 10) | PN(u[1], 10, 10) | PN(u[2], 20, 10) | PN(u[3], 30, 2);
1151725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1152725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1153725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1154725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::SNORM_INT_1010102_REV:
1155725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
1156725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			const Vec4 u = swizzleRB(color, m_format.order, TextureFormat::RGBA);
1157725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint32*)pixelPtr) = PS(u[0], 0, 10) | PS(u[1], 10, 10) | PS(u[2], 20, 10) | PS(u[3], 30, 2);
1158725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1159725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
11603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_1010102_REV:
11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1163725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			const UVec4 u = swizzleRB(color.cast<deUint32>(), m_format.order, TextureFormat::RGBA);
1164725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint32*)pixelPtr) = PU(u[0], 0, 10) | PU(u[1], 10, 10) | PU(u[2], 20, 10) | PU(u[3], 30, 2);
1165725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1166725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1167725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1168725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::SIGNED_INT_1010102_REV:
1169725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
1170725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			const IVec4 u = swizzleRB(color.cast<deInt32>(), m_format.order, TextureFormat::RGBA);
1171725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint32*)pixelPtr) = PI(u[0], 0, 10) | PI(u[1], 10, 10) | PI(u[2], 20, 10) | PI(u[3], 30, 2);
11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			*((deUint32*)pixelPtr) = Float11(color[0]).bits() | (Float11(color[1]).bits() << 11) | (Float10(color[2]).bits() << 22);
11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_999_E5_REV:
11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			*((deUint32*)pixelPtr) = packRGB999E5(color);
11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
11823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Generic path.
11866d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			int								numChannels	= getNumUsedChannels(m_format.order);
11876d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			const TextureSwizzle::Channel*	map			= getChannelWriteSwizzle(m_format.order).components;
11886d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			int								channelSize	= getChannelSize(m_format.type);
11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int c = 0; c < numChannels; c++)
11916d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			{
11926d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				DE_ASSERT(deInRange32(map[c], TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3));
11933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				floatToChannel(pixelPtr + channelSize*c, color[map[c]], m_format.type);
11946d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			}
11953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
11963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef PN
1200725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef PS
12013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef PU
1202725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef PI
12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PixelBufferAccess::setPixel (const IVec4& color, int x, int y, int z) const
12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(x, 0, getWidth()));
12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(y, 0, getHeight()));
12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(z, 0, getDepth()));
12108baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	DE_ASSERT(!isCombinedDepthStencilType(m_format.type)); // combined types cannot be accessed directly
12118baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	DE_ASSERT(m_format.order != TextureFormat::DS); // combined formats cannot be accessed directly
12123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12138baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	deUint8* const pixelPtr = (deUint8*)getPixelPtr(x, y, z);
12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Optimized fomats.
12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_format.type == TextureFormat::UNORM_INT8)
12173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12180158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		if (m_format.order == TextureFormat::RGBA || m_format.order == TextureFormat::sRGBA)
12190158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		{
12200158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi			writeRGBA8888Int(pixelPtr, color);
12210158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi			return;
12220158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		}
12230158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		else if (m_format.order == TextureFormat::RGB || m_format.order == TextureFormat::sRGB)
12240158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		{
12250158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi			writeRGB888Int(pixelPtr, color);
12260158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi			return;
12270158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		}
12283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define PU(VAL, OFFS, BITS)		(uintToChannel((deUint32)(VAL), (BITS)) << (OFFS))
1231725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define PI(VAL, OFFS, BITS)		(intToChannel((deUint32)(VAL), (BITS)) << (OFFS))
12323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
12343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1235725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_BYTE_44:	// Fall-through
1236725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_BYTE_44:		*((deUint8 *)pixelPtr) = (deUint8 )(PU(color[0],  4, 4) | PU(color[1], 0, 4));				break;
1237725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_INT_101010:	*((deUint32*)pixelPtr) = PU(color[0], 22, 10) | PU(color[1], 12, 10) | PU(color[2], 2, 10);	break;
1238725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1239725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_565:
1240725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_565:
1241725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
1242725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			const IVec4 swizzled = swizzleRB(color, m_format.order, TextureFormat::RGB);
1243725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PU(swizzled[0], 11, 5) | PU(swizzled[1], 5, 6) | PU(swizzled[2], 0, 5));
1244725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1245725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1246725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1247725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_555:
1248725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
1249725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			const IVec4 swizzled = swizzleRB(color, m_format.order, TextureFormat::RGB);
1250725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PU(swizzled[0], 10, 5) | PU(swizzled[1], 5, 5) | PU(swizzled[2], 0, 5));
1251725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1252725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1253725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1254725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_4444:
1255725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_4444:
1256725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
1257725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			const IVec4 swizzled = swizzleRB(color, m_format.order, TextureFormat::RGBA);
1258725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PU(swizzled[0], 12, 4) | PU(swizzled[1], 8, 4) | PU(swizzled[2], 4, 4) | PU(swizzled[3], 0, 4));
1259725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1260725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1261725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1262725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_5551:
1263725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_5551:
1264725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
1265725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			const IVec4 swizzled = swizzleRB(color, m_format.order, TextureFormat::RGBA);
1266725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PU(swizzled[0], 11, 5) | PU(swizzled[1], 6, 5) | PU(swizzled[2], 1, 5) | PU(swizzled[3], 0, 1));
1267725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1268725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1269725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1270725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_INT_1010102_REV:
1271725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_1010102_REV:
1272725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
1273725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			const IVec4 swizzled = swizzleRB(color, m_format.order, TextureFormat::RGBA);
1274725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint32*)pixelPtr) = PU(swizzled[0],  0, 10) | PU(swizzled[1], 10, 10) | PU(swizzled[2], 20, 10) | PU(swizzled[3], 30, 2);
1275725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1276725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1277725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1278725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::SNORM_INT_1010102_REV:
1279725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::SIGNED_INT_1010102_REV:
1280725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
1281725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			const IVec4 swizzled = swizzleRB(color, m_format.order, TextureFormat::RGBA);
1282725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint32*)pixelPtr) = PI(swizzled[0],  0, 10) | PI(swizzled[1], 10, 10) | PI(swizzled[2], 20, 10) | PI(swizzled[3], 30, 2);
1283725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1284725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
12853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
12873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Generic path.
12896d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			int								numChannels	= getNumUsedChannels(m_format.order);
12906d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			const TextureSwizzle::Channel*	map			= getChannelWriteSwizzle(m_format.order).components;
12916d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			int								channelSize	= getChannelSize(m_format.type);
12923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int c = 0; c < numChannels; c++)
12946d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			{
12956d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				DE_ASSERT(deInRange32(map[c], TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3));
12963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				intToChannel(pixelPtr + channelSize*c, color[map[c]], m_format.type);
12976d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			}
12983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
12993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef PU
1303725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef PI
13043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13063c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PixelBufferAccess::setPixDepth (float depth, int x, int y, int z) const
13073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(x, 0, getWidth()));
13093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(y, 0, getHeight()));
13103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(z, 0, getDepth()));
13113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13128baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	deUint8* const pixelPtr = (deUint8*)getPixelPtr(x, y, z);
13133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
13153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1316725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_16_8_8:
131700d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::DS);
1318725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			writeUint32High16(pixelPtr, convertSatRte<deUint16>(depth * 65535.0f));
131900d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			break;
132074a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi
132100d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos		case TextureFormat::UNSIGNED_INT_24_8:
1322725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::D || m_format.order == TextureFormat::DS);
132300d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			writeUint32High24(pixelPtr,  convertSatRteUint24(depth * 16777215.0f));
13243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
13253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1326725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_24_8_REV:
1327725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::D || m_format.order == TextureFormat::DS);
1328725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			writeUint32Low24(pixelPtr,  convertSatRteUint24(depth * 16777215.0f));
1329725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1330725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
13313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
13323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_format.order == TextureFormat::DS);
13333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			*((float*)pixelPtr) = depth;
13343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
13353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
13378baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			DE_ASSERT(m_format.order == TextureFormat::D); // no other combined depth stencil types
13383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			floatToChannel(pixelPtr, depth, m_format.type);
13393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
13403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13433c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PixelBufferAccess::setPixStencil (int stencil, int x, int y, int z) const
13443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(x, 0, getWidth()));
13463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(y, 0, getHeight()));
13473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(z, 0, getDepth()));
13483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13498baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	deUint8* const pixelPtr = (deUint8*)getPixelPtr(x, y, z);
13503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
13523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1353725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_16_8_8:
13543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_24_8:
135500d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::DS);
135600d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			writeUint32Low8(pixelPtr, convertSat<deUint8>((deUint32)stencil));
135700d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			break;
135874a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi
1359725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_24_8_REV:
136000d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::DS);
1361725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			writeUint32High8(pixelPtr, convertSat<deUint8>((deUint32)stencil));
13623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
13633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
13653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_format.order == TextureFormat::DS);
136674a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi			writeUint32Low8(pixelPtr + 4, convertSat<deUint8>((deUint32)stencil));
13673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
13683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
13708baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			DE_ASSERT(m_format.order == TextureFormat::S);  // no other combined depth stencil types
13718baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			intToChannel(pixelPtr, stencil, m_format.type);
13723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
13733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13763c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline int imod (int a, int b)
13773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int m = a % b;
13793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m < 0 ? m + b : m;
13803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13823c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline int mirror (int a)
13833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return a >= 0.0f ? a : -(1 + a);
13853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Nearest-even rounding in case of tie (fractional part 0.5), otherwise ordinary rounding.
13883c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline float rint (float a)
13893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_STATIC_ASSERT((-3 % 2 != 0) && (-4 % 2 == 0));
13913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		fracVal		= deFloatFrac(a);
13933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (fracVal != 0.5f)
13953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return deFloatRound(a); // Ordinary case.
13963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float	floorVal	= a - fracVal;
13983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool	roundUp		= (deInt64)floorVal % 2 != 0;
13993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return floorVal + (roundUp ? 1.0f : 0.0f);
14013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14033c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline int wrap (Sampler::WrapMode mode, int c, int size)
14043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (mode)
14063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::CLAMP_TO_BORDER:
14083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return deClamp32(c, -1, size);
14093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::CLAMP_TO_EDGE:
14113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return deClamp32(c, 0, size-1);
14123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::REPEAT_GL:
14143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return imod(c, size);
14153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::REPEAT_CL:
14173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return imod(c, size);
14183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::MIRRORED_REPEAT_GL:
14203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return (size - 1) - mirror(imod(c, 2*size) - size);
14213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::MIRRORED_REPEAT_CL:
14233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return deClamp32(c, 0, size-1); // \note Actual mirroring done already in unnormalization function.
14243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
14263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
14273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0;
14283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Special unnormalization for REPEAT_CL and MIRRORED_REPEAT_CL wrap modes; otherwise ordinary unnormalization.
14323c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline float unnormalize (Sampler::WrapMode mode, float c, int size)
14333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (mode)
14353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::CLAMP_TO_EDGE:
14373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::CLAMP_TO_BORDER:
14383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::REPEAT_GL:
14393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::MIRRORED_REPEAT_GL: // Fall-through (ordinary case).
14403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return (float)size*c;
14413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::REPEAT_CL:
14433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return (float)size * (c - deFloatFloor(c));
14443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::MIRRORED_REPEAT_CL:
14463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return (float)size * deFloatAbs(c - 2.0f * rint(0.5f * c));
14473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
14493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
14503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
14513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isFixedPointDepthTextureFormat (const tcu::TextureFormat& format)
14553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14568baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	DE_ASSERT(format.order == TextureFormat::D);
14573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14588baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
14598baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	if (channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
14608baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry		return false;
14618baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	else if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
14628baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry		return true;
14638baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	else
14643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14658baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry		DE_ASSERT(false);
14668baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry		return false;
14673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texel lookup with color conversion.
14713c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline Vec4 lookup (const ConstPixelBufferAccess& access, int i, int j, int k)
14723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1473a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi	const TextureFormat&	format	= access.getFormat();
1474a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi
1475a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi	if (isSRGB(format))
1476a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi	{
1477a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi		if (format.type == TextureFormat::UNORM_INT8 && format.order == TextureFormat::sRGB)
1478a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi				return sRGB8ToLinear(access.getPixelUint(i, j, k));
1479a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi		else if (format.type == TextureFormat::UNORM_INT8 && format.order == TextureFormat::sRGBA)
1480a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi				return sRGBA8ToLinear(access.getPixelUint(i, j, k));
1481a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi		else
1482a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi			return sRGBToLinear(access.getPixel(i, j, k));
1483a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi	}
1484a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi	else
1485a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi	{
1486a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi		return access.getPixel(i, j, k);
1487a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi	}
14883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1490222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry// Border texel lookup with color conversion.
149122941823a995126908aae341c87f2def77514ee7Jarkko Pöyrystatic inline Vec4 lookupBorder (const tcu::TextureFormat& format, const tcu::Sampler& sampler)
149222941823a995126908aae341c87f2def77514ee7Jarkko Pöyry{
1493222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	// "lookup" for a combined format does not make sense, disallow
1494222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	DE_ASSERT(!isCombinedDepthStencilType(format.type));
1495222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry
1496222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	const tcu::TextureChannelClass	channelClass 			= tcu::getTextureChannelClass(format.type);
1497222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	const bool						isFloat					= channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT;
1498222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	const bool						isFixed					= channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT ||
1499222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry															  channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT;
1500222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	const bool						isPureInteger			= channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER;
1501222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	const bool						isPureUnsignedInteger	= channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
1502222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry
1503222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	if (isFloat || isFixed)
1504d5be8ad612a000b4ad2caf14c8d93501f3558eb8Jarkko Pöyry		return sampleTextureBorder<float>(format, sampler);
1505222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	else if (isPureInteger)
1506222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry		return sampleTextureBorder<deInt32>(format, sampler).cast<float>();
1507222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	else if (isPureUnsignedInteger)
1508222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry		return sampleTextureBorder<deUint32>(format, sampler).cast<float>();
1509222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	else
1510222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	{
1511222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry		DE_ASSERT(false);
1512222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry		return Vec4(-1.0);
1513222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	}
151422941823a995126908aae341c87f2def77514ee7Jarkko Pöyry}
151522941823a995126908aae341c87f2def77514ee7Jarkko Pöyry
15163c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline float execCompare (const tcu::Vec4& color, Sampler::CompareMode compare, int chanNdx, float ref_, bool isFixedPoint)
15173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool	clampValues	= isFixedPoint;	// if comparing against a floating point texture, ref (and value) is not clamped
15193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	cmp			= (clampValues) ? (de::clamp(color[chanNdx], 0.0f, 1.0f)) : (color[chanNdx]);
15203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	ref			= (clampValues) ? (de::clamp(ref_, 0.0f, 1.0f)) : (ref_);
15213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		res			= false;
15223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (compare)
15243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_LESS:				res = ref < cmp;	break;
15263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_LESS_OR_EQUAL:	res = ref <= cmp;	break;
15273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_GREATER:			res = ref > cmp;	break;
15283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_GREATER_OR_EQUAL:	res = ref >= cmp;	break;
15293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_EQUAL:			res = ref == cmp;	break;
15303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_NOT_EQUAL:		res = ref != cmp;	break;
15313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_ALWAYS:			res = true;			break;
15323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_NEVER:			res = false;		break;
15333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
15343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
15353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return res ? 1.0f : 0.0f;
15383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15403c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleNearest1D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, const IVec2& offset)
15413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int width	= access.getWidth();
15433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x = deFloorFloatToInt32(u)+offset.x();
15453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check for CLAMP_TO_BORDER.
15473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.wrapS == Sampler::CLAMP_TO_BORDER && !deInBounds32(x, 0, width))
154822941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		return lookupBorder(access.getFormat(), sampler);
15493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i = wrap(sampler.wrapS, x, width);
15513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return lookup(access, i, offset.y(), 0);
15533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleNearest2D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, float v, const IVec3& offset)
15563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int width	= access.getWidth();
15583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int height	= access.getHeight();
15593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x = deFloorFloatToInt32(u)+offset.x();
15613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y = deFloorFloatToInt32(v)+offset.y();
15623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check for CLAMP_TO_BORDER.
15643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if ((sampler.wrapS == Sampler::CLAMP_TO_BORDER && !deInBounds32(x, 0, width)) ||
15653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		(sampler.wrapT == Sampler::CLAMP_TO_BORDER && !deInBounds32(y, 0, height)))
156622941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		return lookupBorder(access.getFormat(), sampler);
15673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i = wrap(sampler.wrapS, x, width);
15693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j = wrap(sampler.wrapT, y, height);
15703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return lookup(access, i, j, offset.z());
15723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15743c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleNearest3D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, float v, float w, const IVec3& offset)
15753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int width	= access.getWidth();
15773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int height	= access.getHeight();
15783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int depth	= access.getDepth();
15793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x = deFloorFloatToInt32(u)+offset.x();
15813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y = deFloorFloatToInt32(v)+offset.y();
15823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int z = deFloorFloatToInt32(w)+offset.z();
15833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check for CLAMP_TO_BORDER.
15853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if ((sampler.wrapS == Sampler::CLAMP_TO_BORDER && !deInBounds32(x, 0, width))	||
15863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		(sampler.wrapT == Sampler::CLAMP_TO_BORDER && !deInBounds32(y, 0, height))	||
15873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		(sampler.wrapR == Sampler::CLAMP_TO_BORDER && !deInBounds32(z, 0, depth)))
158822941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		return lookupBorder(access.getFormat(), sampler);
15893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i = wrap(sampler.wrapS, x, width);
15913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j = wrap(sampler.wrapT, y, height);
15923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int k = wrap(sampler.wrapR, z, depth);
15933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return lookup(access, i, j, k);
15953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15973c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleLinear1D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, const IVec2& offset)
15983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int w = access.getWidth();
16003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x0 = deFloorFloatToInt32(u-0.5f)+offset.x();
16023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x1 = x0+1;
16033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i0 = wrap(sampler.wrapS, x0, w);
16053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i1 = wrap(sampler.wrapS, x1, w);
16063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
16083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i0UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i0, 0, w);
16103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i1UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i1, 0, w);
16113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Border color for out-of-range coordinates if using CLAMP_TO_BORDER, otherwise execute lookups.
161322941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p0 = i0UseBorder ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, offset.y(), 0);
161422941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p1 = i1UseBorder ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, offset.y(), 0);
16153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
16173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return p0 * (1.0f - a) + p1 * a;
16183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16203c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleLinear2D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, float v, const IVec3& offset)
16213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int w = access.getWidth();
16233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int h = access.getHeight();
16243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x0 = deFloorFloatToInt32(u-0.5f)+offset.x();
16263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x1 = x0+1;
16273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y0 = deFloorFloatToInt32(v-0.5f)+offset.y();
16283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y1 = y0+1;
16293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i0 = wrap(sampler.wrapS, x0, w);
16313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i1 = wrap(sampler.wrapS, x1, w);
16323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j0 = wrap(sampler.wrapT, y0, h);
16333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j1 = wrap(sampler.wrapT, y1, h);
16343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
16363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float b = deFloatFrac(v-0.5f);
16373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i0UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i0, 0, w);
16393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i1UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i1, 0, w);
16403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool j0UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j0, 0, h);
16413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool j1UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j1, 0, h);
16423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Border color for out-of-range coordinates if using CLAMP_TO_BORDER, otherwise execute lookups.
164422941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p00 = (i0UseBorder || j0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j0, offset.z());
164522941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p10 = (i1UseBorder || j0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j0, offset.z());
164622941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p01 = (i0UseBorder || j1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j1, offset.z());
164722941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p11 = (i1UseBorder || j1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j1, offset.z());
16483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
16503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (p00*(1.0f-a)*(1.0f-b)) +
16513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p10*(     a)*(1.0f-b)) +
16523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p01*(1.0f-a)*(     b)) +
16533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p11*(     a)*(     b));
16543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16563c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float sampleLinear1DCompare (const ConstPixelBufferAccess& access, const Sampler& sampler, float ref, float u, const IVec2& offset, bool isFixedPointDepthFormat)
16573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int w = access.getWidth();
16593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x0 = deFloorFloatToInt32(u-0.5f)+offset.x();
16613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x1 = x0+1;
16623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i0 = wrap(sampler.wrapS, x0, w);
16643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i1 = wrap(sampler.wrapS, x1, w);
16653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
16673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i0UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i0, 0, w);
16693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i1UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i1, 0, w);
16703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Border color for out-of-range coordinates if using CLAMP_TO_BORDER, otherwise execute lookups.
167222941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p0Clr = i0UseBorder  ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, offset.y(), 0);
167322941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p1Clr = i1UseBorder  ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, offset.y(), 0);
16743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Execute comparisons.
16763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float p0 = execCompare(p0Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat);
16773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float p1 = execCompare(p1Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat);
16783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
16803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (p0 * (1.0f - a)) + (p1 * a);
16813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16833c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float sampleLinear2DCompare (const ConstPixelBufferAccess& access, const Sampler& sampler, float ref, float u, float v, const IVec3& offset, bool isFixedPointDepthFormat)
16843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int w = access.getWidth();
16863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int h = access.getHeight();
16873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x0 = deFloorFloatToInt32(u-0.5f)+offset.x();
16893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x1 = x0+1;
16903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y0 = deFloorFloatToInt32(v-0.5f)+offset.y();
16913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y1 = y0+1;
16923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i0 = wrap(sampler.wrapS, x0, w);
16943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i1 = wrap(sampler.wrapS, x1, w);
16953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j0 = wrap(sampler.wrapT, y0, h);
16963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j1 = wrap(sampler.wrapT, y1, h);
16973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
16993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float b = deFloatFrac(v-0.5f);
17003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i0UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i0, 0, w);
17023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i1UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i1, 0, w);
17033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool j0UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j0, 0, h);
17043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool j1UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j1, 0, h);
17053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Border color for out-of-range coordinates if using CLAMP_TO_BORDER, otherwise execute lookups.
170722941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p00Clr = (i0UseBorder || j0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j0, offset.z());
170822941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p10Clr = (i1UseBorder || j0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j0, offset.z());
170922941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p01Clr = (i0UseBorder || j1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j1, offset.z());
171022941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p11Clr = (i1UseBorder || j1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j1, offset.z());
17113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Execute comparisons.
17133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float p00 = execCompare(p00Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat);
17143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float p10 = execCompare(p10Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat);
17153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float p01 = execCompare(p01Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat);
17163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float p11 = execCompare(p11Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat);
17173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
17193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (p00*(1.0f-a)*(1.0f-b)) +
17203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p10*(     a)*(1.0f-b)) +
17213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p01*(1.0f-a)*(     b)) +
17223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p11*(     a)*(     b));
17233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17253c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleLinear3D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, float v, float w, const IVec3& offset)
17263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int width	= access.getWidth();
17283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int height	= access.getHeight();
17293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int depth	= access.getDepth();
17303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x0 = deFloorFloatToInt32(u-0.5f)+offset.x();
17323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x1 = x0+1;
17333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y0 = deFloorFloatToInt32(v-0.5f)+offset.y();
17343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y1 = y0+1;
17353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int z0 = deFloorFloatToInt32(w-0.5f)+offset.z();
17363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int z1 = z0+1;
17373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i0 = wrap(sampler.wrapS, x0, width);
17393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i1 = wrap(sampler.wrapS, x1, width);
17403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j0 = wrap(sampler.wrapT, y0, height);
17413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j1 = wrap(sampler.wrapT, y1, height);
17423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int k0 = wrap(sampler.wrapR, z0, depth);
17433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int k1 = wrap(sampler.wrapR, z1, depth);
17443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
17463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float b = deFloatFrac(v-0.5f);
17473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float c = deFloatFrac(w-0.5f);
17483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i0UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i0, 0, width);
17503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i1UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i1, 0, width);
17513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool j0UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j0, 0, height);
17523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool j1UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j1, 0, height);
17533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool k0UseBorder = sampler.wrapR == Sampler::CLAMP_TO_BORDER && !de::inBounds(k0, 0, depth);
17543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool k1UseBorder = sampler.wrapR == Sampler::CLAMP_TO_BORDER && !de::inBounds(k1, 0, depth);
17553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Border color for out-of-range coordinates if using CLAMP_TO_BORDER, otherwise execute lookups.
175722941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p000 = (i0UseBorder || j0UseBorder || k0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j0, k0);
175822941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p100 = (i1UseBorder || j0UseBorder || k0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j0, k0);
175922941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p010 = (i0UseBorder || j1UseBorder || k0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j1, k0);
176022941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p110 = (i1UseBorder || j1UseBorder || k0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j1, k0);
176122941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p001 = (i0UseBorder || j0UseBorder || k1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j0, k1);
176222941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p101 = (i1UseBorder || j0UseBorder || k1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j0, k1);
176322941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p011 = (i0UseBorder || j1UseBorder || k1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j1, k1);
176422941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p111 = (i1UseBorder || j1UseBorder || k1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j1, k1);
17653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
17673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (p000*(1.0f-a)*(1.0f-b)*(1.0f-c)) +
17683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p100*(     a)*(1.0f-b)*(1.0f-c)) +
17693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p010*(1.0f-a)*(     b)*(1.0f-c)) +
17703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p110*(     a)*(     b)*(1.0f-c)) +
17713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p001*(1.0f-a)*(1.0f-b)*(     c)) +
17723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p101*(     a)*(1.0f-b)*(     c)) +
17733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p011*(1.0f-a)*(     b)*(     c)) +
17743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p111*(     a)*(     b)*(     c));
17753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17773c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 ConstPixelBufferAccess::sample1D (const Sampler& sampler, Sampler::FilterMode filter, float s, int level) const
17783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1779612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// check selected layer exists
178029340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(level, 0, m_size.y()));
17813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1782612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	return sample1DOffset(sampler, filter, s, tcu::IVec2(0, level));
17833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17853c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 ConstPixelBufferAccess::sample2D (const Sampler& sampler, Sampler::FilterMode filter, float s, float t, int depth) const
17863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1787612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// check selected layer exists
178829340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(depth, 0, m_size.z()));
17893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1790612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	return sample2DOffset(sampler, filter, s, t, tcu::IVec3(0, 0, depth));
1791612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry}
17923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1793612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko PöyryVec4 ConstPixelBufferAccess::sample3D (const Sampler& sampler, Sampler::FilterMode filter, float s, float t, float r) const
1794612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry{
1795612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	return sample3DOffset(sampler, filter, s, t, r, tcu::IVec3(0, 0, 0));
17963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17983c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 ConstPixelBufferAccess::sample1DOffset (const Sampler& sampler, Sampler::FilterMode filter, float s, const IVec2& offset) const
17993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1800612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// check selected layer exists
1801612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// \note offset.x is X offset, offset.y is the selected layer
1802612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	DE_ASSERT(de::inBounds(offset.y(), 0, m_size.y()));
18033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
18053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float u = s;
18063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
180829340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		u = unnormalize(sampler.wrapS, s, m_size.x());
18093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filter)
18113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return sampleNearest1D	(*this, sampler, u, offset);
18133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return sampleLinear1D	(*this, sampler, u, offset);
18143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
18153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
18163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
18173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18203c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 ConstPixelBufferAccess::sample2DOffset (const Sampler& sampler, Sampler::FilterMode filter, float s, float t, const IVec3& offset) const
18213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1822612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// check selected layer exists
1823612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// \note offset.xy is the XY offset, offset.z is the selected layer
182429340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(offset.z(), 0, m_size.z()));
18253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
18273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float u = s;
18283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float v = t;
18293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
18313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
183229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		u = unnormalize(sampler.wrapS, s, m_size.x());
183329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		v = unnormalize(sampler.wrapT, t, m_size.y());
18343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filter)
18373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return sampleNearest2D	(*this, sampler, u, v, offset);
18393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return sampleLinear2D	(*this, sampler, u, v, offset);
18403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
18413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
18423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
18433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1846612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko PöyryVec4 ConstPixelBufferAccess::sample3DOffset (const Sampler& sampler, Sampler::FilterMode filter, float s, float t, float r, const IVec3& offset) const
18473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
18493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float u = s;
1850612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	float v = t;
1851612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	float w = r;
18523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
1854612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	{
185529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		u = unnormalize(sampler.wrapS, s, m_size.x());
1856612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		v = unnormalize(sampler.wrapT, t, m_size.y());
1857612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		w = unnormalize(sampler.wrapR, r, m_size.z());
1858612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	}
18593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filter)
18613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1862612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		case Sampler::NEAREST:	return sampleNearest3D	(*this, sampler, u, v, w, offset);
1863612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		case Sampler::LINEAR:	return sampleLinear3D	(*this, sampler, u, v, w, offset);
18643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
18653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
1866612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry			return Vec4(0.0f);
18673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1870612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyryfloat ConstPixelBufferAccess::sample1DCompare (const Sampler& sampler, Sampler::FilterMode filter, float ref, float s, const IVec2& offset) const
18713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1872612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// check selected layer exists
1873612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// \note offset.x is X offset, offset.y is the selected layer
1874612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	DE_ASSERT(de::inBounds(offset.y(), 0, m_size.y()));
18753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Format information for comparison function
18773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool isFixedPointDepth = isFixedPointDepthTextureFormat(m_format);
18783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
18803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float u = s;
18813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
188329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		u = unnormalize(sampler.wrapS, s, m_size.x());
18843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filter)
18863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1887612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		case Sampler::NEAREST:	return execCompare(sampleNearest1D(*this, sampler, u, offset), sampler.compare, sampler.compareChannel, ref, isFixedPointDepth);
1888612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		case Sampler::LINEAR:	return sampleLinear1DCompare(*this, sampler, ref, u, offset, isFixedPointDepth);
18893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
18903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
18913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
18923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1895612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyryfloat ConstPixelBufferAccess::sample2DCompare (const Sampler& sampler, Sampler::FilterMode filter, float ref, float s, float t, const IVec3& offset) const
18963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1897612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// check selected layer exists
1898612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// \note offset.xy is XY offset, offset.z is the selected layer
1899612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	DE_ASSERT(de::inBounds(offset.z(), 0, m_size.z()));
19003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1901612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// Format information for comparison function
1902612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	const bool isFixedPointDepth = isFixedPointDepthTextureFormat(m_format);
19033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
19053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float u = s;
19063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float v = t;
19073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
19093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
191029340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		u = unnormalize(sampler.wrapS, s, m_size.x());
191129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		v = unnormalize(sampler.wrapT, t, m_size.y());
19123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filter)
19153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1916612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		case Sampler::NEAREST:	return execCompare(sampleNearest2D(*this, sampler, u, v, offset), sampler.compare, sampler.compareChannel, ref, isFixedPointDepth);
1917612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		case Sampler::LINEAR:	return sampleLinear2DCompare(*this, sampler, ref, u, v, offset, isFixedPointDepth);
19183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
19193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
1920612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry			return 0.0f;
19213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19243c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevel::TextureLevel (void)
19253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	()
192629340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size	(0)
19273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19303c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevel::TextureLevel (const TextureFormat& format)
19313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	(format)
193229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size	(0)
19333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19363c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevel::TextureLevel (const TextureFormat& format, int width, int height, int depth)
19373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	(format)
193829340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size	(0)
19393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	setSize(width, height, depth);
19413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19433c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevel::~TextureLevel (void)
19443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureLevel::setStorage (const TextureFormat& format, int width, int height, int depth)
19483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_format = format;
19503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	setSize(width, height, depth);
19513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureLevel::setSize (int width, int height, int depth)
19543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int pixelSize = m_format.getPixelSize();
19563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
195729340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	m_size = IVec3(width, height, depth);
19583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
195929340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	m_data.setStorage(m_size.x() * m_size.y() * m_size.z() * pixelSize);
19603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19623c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 sampleLevelArray1D (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, int depth, float lod)
19633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19641d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry	return sampleLevelArray1DOffset(levels, numLevels, sampler, s, lod, IVec2(0, depth)); // y-offset in 1D textures is layer selector
19651d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry}
19663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19671d75d23528999118c1911ed100d1d063b06040daJarkko PöyryVec4 sampleLevelArray2D (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, int depth, float lod)
19681d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry{
19691d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry	return sampleLevelArray2DOffset(levels, numLevels, sampler, s, t, lod, IVec3(0, 0, depth)); // z-offset in 2D textures is layer selector
19701d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry}
19713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19721d75d23528999118c1911ed100d1d063b06040daJarkko PöyryVec4 sampleLevelArray3D (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, float r, float lod)
19731d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry{
19741d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry	return sampleLevelArray3DOffset(levels, numLevels, sampler, s, t, r, lod, IVec3(0, 0, 0));
19753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19773c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 sampleLevelArray1DOffset (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float lod, const IVec2& offset)
19783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
19803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
19813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
19833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return levels[0].sample1DOffset(sampler, filterMode, s, offset);
19853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return levels[0].sample1DOffset(sampler, filterMode, s, offset);
19863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
19883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
19893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
19913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
19923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
19933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return levels[level].sample1DOffset(sampler, levelFilter, s, offset);
19953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
19963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
19983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
19993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
20003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
20013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
20023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level1		= de::min(maxLevel, level0 + 1);
20033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
20043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				f			= deFloatFrac(lod);
20053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4			t0			= levels[level0].sample1DOffset(sampler, levelFilter, s, offset);
20063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4			t1			= levels[level1].sample1DOffset(sampler, levelFilter, s, offset);
20073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
20093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
20103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
20123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
20133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
20143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20173c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 sampleLevelArray2DOffset (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, float lod, const IVec3& offset)
20183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
20203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
20213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
20233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return levels[0].sample2DOffset(sampler, filterMode, s, t, offset);
20253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return levels[0].sample2DOffset(sampler, filterMode, s, t, offset);
20263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
20283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
20293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
20303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
20313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
20323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
20333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return levels[level].sample2DOffset(sampler, levelFilter, s, t, offset);
20353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
20363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
20383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
20393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
20403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
20413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
20423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level1		= de::min(maxLevel, level0 + 1);
20433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
20443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				f			= deFloatFrac(lod);
20453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4			t0			= levels[level0].sample2DOffset(sampler, levelFilter, s, t, offset);
20463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4			t1			= levels[level1].sample2DOffset(sampler, levelFilter, s, t, offset);
20473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
20493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
20503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
20523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
20533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
20543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20573c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 sampleLevelArray3DOffset (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, float r, float lod, const IVec3& offset)
20583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
20603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
20613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
20633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return levels[0].sample3DOffset(sampler, filterMode, s, t, r, offset);
20653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return levels[0].sample3DOffset(sampler, filterMode, s, t, r, offset);
20663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
20683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
20693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
20703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
20713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
20723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
20733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return levels[level].sample3DOffset(sampler, levelFilter, s, t, r, offset);
20753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
20763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
20783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
20793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
20803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
20813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
20823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level1		= de::min(maxLevel, level0 + 1);
20833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
20843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				f			= deFloatFrac(lod);
20853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4			t0			= levels[level0].sample3DOffset(sampler, levelFilter, s, t, r, offset);
20863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4			t1			= levels[level1].sample3DOffset(sampler, levelFilter, s, t, r, offset);
20873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
20893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
20903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
20923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
20933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
20943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20973c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat sampleLevelArray1DCompare (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float ref, float s, float lod, const IVec2& offset)
20983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
21003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
21013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
21033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return levels[0].sample1DCompare(sampler, filterMode, ref, s, offset);
21053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return levels[0].sample1DCompare(sampler, filterMode, ref, s, offset);
21063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
21083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
21093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
21113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
21123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
21133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return levels[level].sample1DCompare(sampler, levelFilter, ref, s, offset);
21153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
21163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
21183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
21193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
21213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
21223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level1		= de::min(maxLevel, level0 + 1);
21233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
21243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				f			= deFloatFrac(lod);
21253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				t0			= levels[level0].sample1DCompare(sampler, levelFilter, ref, s, offset);
21263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				t1			= levels[level1].sample1DCompare(sampler, levelFilter, ref, s, offset);
21273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
21293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
21303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
21323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
21333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
21343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
21353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
21363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat sampleLevelArray2DCompare (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float ref, float s, float t, float lod, const IVec3& offset)
21383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
21393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
21403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
21413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
21433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return levels[0].sample2DCompare(sampler, filterMode, ref, s, t, offset);
21453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return levels[0].sample2DCompare(sampler, filterMode, ref, s, t, offset);
21463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
21483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
21493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
21513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
21523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
21533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return levels[level].sample2DCompare(sampler, levelFilter, ref, s, t, offset);
21553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
21563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
21583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
21593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
21613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
21623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level1		= de::min(maxLevel, level0 + 1);
21633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
21643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				f			= deFloatFrac(lod);
21653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				t0			= levels[level0].sample2DCompare(sampler, levelFilter, ref, s, t, offset);
21663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				t1			= levels[level1].sample2DCompare(sampler, levelFilter, ref, s, t, offset);
21673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
21693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
21703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
21723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
21733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
21743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
21753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
21763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
217722941823a995126908aae341c87f2def77514ee7Jarkko Pöyrystatic Vec4 fetchGatherArray2DOffsets (const ConstPixelBufferAccess& src, const Sampler& sampler, float s, float t, int depth, int componentNdx, const IVec2 (&offsets)[4])
21783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
21793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(componentNdx, 0, 4));
21803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		w	= src.getWidth();
21823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		h	= src.getHeight();
21833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float		u	= unnormalize(sampler.wrapS, s, w);
21843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float		v	= unnormalize(sampler.wrapT, t, h);
21853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		x0	= deFloorFloatToInt32(u-0.5f);
21863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		y0	= deFloorFloatToInt32(v-0.5f);
21873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
218822941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4			result;
21893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
21913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
219222941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		const int	sampleX	= wrap(sampler.wrapS, x0 + offsets[i].x(), w);
219322941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		const int	sampleY	= wrap(sampler.wrapT, y0 + offsets[i].y(), h);
219422941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		Vec4		pixel;
219522941823a995126908aae341c87f2def77514ee7Jarkko Pöyry
219622941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		if (deInBounds32(sampleX, 0, w) && deInBounds32(sampleY, 0, h))
219722941823a995126908aae341c87f2def77514ee7Jarkko Pöyry			pixel = lookup(src, sampleX, sampleY, depth);
219822941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		else
219922941823a995126908aae341c87f2def77514ee7Jarkko Pöyry			pixel = lookupBorder(src.getFormat(), sampler);
220022941823a995126908aae341c87f2def77514ee7Jarkko Pöyry
22013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result[i] = pixel[componentNdx];
22023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
22033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
22053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
22063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
220722941823a995126908aae341c87f2def77514ee7Jarkko PöyryVec4 gatherArray2DOffsets (const ConstPixelBufferAccess& src, const Sampler& sampler, float s, float t, int depth, int componentNdx, const IVec2 (&offsets)[4])
220822941823a995126908aae341c87f2def77514ee7Jarkko Pöyry{
220922941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	DE_ASSERT(sampler.compare == Sampler::COMPAREMODE_NONE);
221022941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	DE_ASSERT(de::inBounds(componentNdx, 0, 4));
221122941823a995126908aae341c87f2def77514ee7Jarkko Pöyry
221222941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	return fetchGatherArray2DOffsets(src, sampler, s, t, depth, componentNdx, offsets);
221322941823a995126908aae341c87f2def77514ee7Jarkko Pöyry}
221422941823a995126908aae341c87f2def77514ee7Jarkko Pöyry
22153c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 gatherArray2DOffsetsCompare (const ConstPixelBufferAccess& src, const Sampler& sampler, float ref, float s, float t, int depth, const IVec2 (&offsets)[4])
22163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
22173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare != Sampler::COMPAREMODE_NONE);
22183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(src.getFormat().order == TextureFormat::D || src.getFormat().order == TextureFormat::DS);
22193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compareChannel == 0);
22203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2221222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	const bool	isFixedPoint	= isFixedPointDepthTextureFormat(src.getFormat());
2222222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	const Vec4	gathered		= fetchGatherArray2DOffsets(src, sampler, s, t, depth, 0 /* component 0: depth */, offsets);
2223222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	Vec4		result;
22243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
22263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result[i] = execCompare(gathered, sampler.compare, i, ref, isFixedPoint);
22273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
22293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
22303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22313c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleCubeSeamlessNearest (const ConstPixelBufferAccess& faceAccess, const Sampler& sampler, float s, float t, int depth)
22323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
22333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler clampingSampler = sampler;
22343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	clampingSampler.wrapS = Sampler::CLAMP_TO_EDGE;
22353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	clampingSampler.wrapT = Sampler::CLAMP_TO_EDGE;
22363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return faceAccess.sample2D(clampingSampler, Sampler::NEAREST, s, t, depth);
22373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
22383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22393c827367444ee418f129b2c238299f49d3264554Jarkko PoyryCubeFace selectCubeFace (const Vec3& coords)
22403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
22413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	x	= coords.x();
22423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	y	= coords.y();
22433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	z	= coords.z();
22443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	ax	= deFloatAbs(x);
22453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	ay	= deFloatAbs(y);
22463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	az	= deFloatAbs(z);
22473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (ay < ax && az < ax)
22493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return x >= 0.0f ? CUBEFACE_POSITIVE_X : CUBEFACE_NEGATIVE_X;
22503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (ax < ay && az < ay)
22513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return y >= 0.0f ? CUBEFACE_POSITIVE_Y : CUBEFACE_NEGATIVE_Y;
22523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (ax < az && ay < az)
22533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return z >= 0.0f ? CUBEFACE_POSITIVE_Z : CUBEFACE_NEGATIVE_Z;
22543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
22553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
22563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Some of the components are equal. Use tie-breaking rule.
22573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (ax == ay)
22583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (ax < az)
22603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return z >= 0.0f ? CUBEFACE_POSITIVE_Z : CUBEFACE_NEGATIVE_Z;
22613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
22623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return x >= 0.0f ? CUBEFACE_POSITIVE_X : CUBEFACE_NEGATIVE_X;
22633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (ax == az)
22653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (az < ay)
22673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return y >= 0.0f ? CUBEFACE_POSITIVE_Y : CUBEFACE_NEGATIVE_Y;
22683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
22693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return z >= 0.0f ? CUBEFACE_POSITIVE_Z : CUBEFACE_NEGATIVE_Z;
22703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (ay == az)
22723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (ay < ax)
22743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return x >= 0.0f ? CUBEFACE_POSITIVE_X : CUBEFACE_NEGATIVE_X;
22753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
22763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return y >= 0.0f ? CUBEFACE_POSITIVE_Y : CUBEFACE_NEGATIVE_Y;
22773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
22793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return x >= 0.0f ? CUBEFACE_POSITIVE_X : CUBEFACE_NEGATIVE_X;
22803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
22813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
22823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22833c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec2 projectToFace (CubeFace face, const Vec3& coord)
22843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
22853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	rx		= coord.x();
22863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	ry		= coord.y();
22873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	rz		= coord.z();
22883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		sc		= 0.0f;
22893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		tc		= 0.0f;
22903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		ma		= 0.0f;
22913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		s;
22923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		t;
22933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (face)
22953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
22963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_X: sc = +rz; tc = -ry; ma = -rx; break;
22973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_X: sc = -rz; tc = -ry; ma = +rx; break;
22983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_Y: sc = +rx; tc = -rz; ma = -ry; break;
22993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_Y: sc = +rx; tc = +rz; ma = +ry; break;
23003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_Z: sc = -rx; tc = -ry; ma = -rz; break;
23013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_Z: sc = +rx; tc = -ry; ma = +rz; break;
23023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
23033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
23043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
23053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute s, t
23073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	s = ((sc / ma) + 1.0f) / 2.0f;
23083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	t = ((tc / ma) + 1.0f) / 2.0f;
23093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return Vec2(s, t);
23113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23133c827367444ee418f129b2c238299f49d3264554Jarkko PoyryCubeFaceFloatCoords getCubeFaceCoords (const Vec3& coords)
23143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CubeFace face = selectCubeFace(coords);
23163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return CubeFaceFloatCoords(face, projectToFace(face, coords));
23173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// 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.
23203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \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.
23213c827367444ee418f129b2c238299f49d3264554Jarkko PoyryCubeFaceIntCoords remapCubeEdgeCoords (const CubeFaceIntCoords& origCoords, int size)
23223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool uInBounds = de::inBounds(origCoords.s, 0, size);
23243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool vInBounds = de::inBounds(origCoords.t, 0, size);
23253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (uInBounds && vInBounds)
23273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return origCoords;
23283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!uInBounds && !vInBounds)
23303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_LAST, -1, -1);
23313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec2 coords(wrap(Sampler::CLAMP_TO_BORDER, origCoords.s, size),
23333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				 wrap(Sampler::CLAMP_TO_BORDER, origCoords.t, size));
23343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec3 canonizedCoords;
23353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Map the uv coordinates to canonized 3d coordinates.
23373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (origCoords.face)
23393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_X: canonizedCoords = IVec3(0,					size-1-coords.y(),	coords.x());			break;
23413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_X: canonizedCoords = IVec3(size-1,				size-1-coords.y(),	size-1-coords.x());		break;
23423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_Y: canonizedCoords = IVec3(coords.x(),			0,					size-1-coords.y());		break;
23433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_Y: canonizedCoords = IVec3(coords.x(),			size-1,				coords.y());			break;
23443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_Z: canonizedCoords = IVec3(size-1-coords.x(),	size-1-coords.y(),	0);						break;
23453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_Z: canonizedCoords = IVec3(coords.x(),			size-1-coords.y(),	size-1);				break;
23463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default: DE_ASSERT(false);
23473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
23483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Find an appropriate face to re-map the coordinates to.
23503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (canonizedCoords.x() == -1)
23523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_NEGATIVE_X, IVec2(canonizedCoords.z(), size-1-canonizedCoords.y()));
23533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (canonizedCoords.x() == size)
23553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_POSITIVE_X, IVec2(size-1-canonizedCoords.z(), size-1-canonizedCoords.y()));
23563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (canonizedCoords.y() == -1)
23583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_NEGATIVE_Y, IVec2(canonizedCoords.x(), size-1-canonizedCoords.z()));
23593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (canonizedCoords.y() == size)
23613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_POSITIVE_Y, IVec2(canonizedCoords.x(), canonizedCoords.z()));
23623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (canonizedCoords.z() == -1)
23643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_NEGATIVE_Z, IVec2(size-1-canonizedCoords.x(), size-1-canonizedCoords.y()));
23653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (canonizedCoords.z() == size)
23673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_POSITIVE_Z, IVec2(canonizedCoords.x(), size-1-canonizedCoords.y()));
23683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(false);
23703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return CubeFaceIntCoords(CUBEFACE_LAST, IVec2(-1));
23713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23733c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void getCubeLinearSamples (const ConstPixelBufferAccess (&faceAccesses)[CUBEFACE_LAST], CubeFace baseFace, float u, float v, int depth, Vec4 (&dst)[4])
23743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(faceAccesses[0].getWidth() == faceAccesses[0].getHeight());
23763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		size					= faceAccesses[0].getWidth();
23773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		x0						= deFloorFloatToInt32(u-0.5f);
23783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		x1						= x0+1;
23793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		y0						= deFloorFloatToInt32(v-0.5f);
23803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		y1						= y0+1;
23813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec2	baseSampleCoords[4]		=
23823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x0, y0),
23843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x1, y0),
23853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x0, y1),
23863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x1, y1)
23873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
23883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4	sampleColors[4];
23893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool	hasBothCoordsOutOfBounds[4]; //!< Whether correctCubeFace() returns CUBEFACE_LAST, i.e. both u and v are out of bounds.
23903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Find correct faces and coordinates for out-of-bounds sample coordinates.
23923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
23943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CubeFaceIntCoords coords = remapCubeEdgeCoords(CubeFaceIntCoords(baseFace, baseSampleCoords[i]), size);
23963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		hasBothCoordsOutOfBounds[i] = coords.face == CUBEFACE_LAST;
23973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!hasBothCoordsOutOfBounds[i])
23983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sampleColors[i] = lookup(faceAccesses[coords.face], coords.s, coords.t, depth);
23993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
24003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// If a sample was out of bounds in both u and v, we get its color from the average of the three other samples.
24023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note This averaging behavior is not required by the GLES3 spec (though it is recommended). GLES3 spec only
24033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//		 requires that if the three other samples all have the same color, then the doubly-out-of-bounds sample
24043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//		 must have this color as well.
24053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int bothOutOfBoundsNdx = -1;
24083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < 4; i++)
24093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
24103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (hasBothCoordsOutOfBounds[i])
24113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
24123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(bothOutOfBoundsNdx < 0); // Only one sample can be out of bounds in both u and v.
24133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				bothOutOfBoundsNdx = i;
24143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
24153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
24163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (bothOutOfBoundsNdx != -1)
24173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
24183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sampleColors[bothOutOfBoundsNdx] = Vec4(0.0f);
24193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < 4; i++)
24203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (i != bothOutOfBoundsNdx)
24213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					sampleColors[bothOutOfBoundsNdx] += sampleColors[i];
24223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sampleColors[bothOutOfBoundsNdx] = sampleColors[bothOutOfBoundsNdx] * (1.0f/3.0f);
24243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
24253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
24263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < DE_LENGTH_OF_ARRAY(sampleColors); i++)
24283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dst[i] = sampleColors[i];
24293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \todo [2014-02-19 pyry] Optimize faceAccesses
24323c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleCubeSeamlessLinear (const ConstPixelBufferAccess (&faceAccesses)[CUBEFACE_LAST], CubeFace baseFace, const Sampler& sampler, float s, float t, int depth)
24333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(faceAccesses[0].getWidth() == faceAccesses[0].getHeight());
24353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		size	= faceAccesses[0].getWidth();
24373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
24383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float	u		= s;
24393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float	v		= t;
24403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
24423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		u = unnormalize(sampler.wrapS, s, size);
24443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		v = unnormalize(sampler.wrapT, t, size);
24453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
24463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Get sample colors.
24483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 sampleColors[4];
24503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	getCubeLinearSamples(faceAccesses, baseFace, u, v, depth, sampleColors);
24513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
24533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
24553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float b = deFloatFrac(v-0.5f);
24563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (sampleColors[0]*(1.0f-a)*(1.0f-b)) +
24583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (sampleColors[1]*(     a)*(1.0f-b)) +
24593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (sampleColors[2]*(1.0f-a)*(     b)) +
24603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (sampleColors[3]*(     a)*(     b));
24613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24633c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleLevelArrayCubeSeamless (const ConstPixelBufferAccess* const (&faces)[CUBEFACE_LAST], int numLevels, CubeFace face, const Sampler& sampler, float s, float t, int depth, float lod)
24643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
24663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
24673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
24693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:
24713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessNearest(faces[face][0], sampler, s, t, depth);
24723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:
24743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
24753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
24763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < (int)CUBEFACE_LAST; i++)
24773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				faceAccesses[i] = faces[i][0];
24783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessLinear(faceAccesses, face, sampler, s, t, depth);
24803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
24813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
24833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
24843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
24853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
24863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
24873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
24883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
24903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessNearest(faces[face][level], sampler, s, t, depth);
24913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
24923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
24933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
24943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
24963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
24973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses[i] = faces[i][level];
24983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessLinear(faceAccesses, face, sampler, s, t, depth);
25003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
25013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
25023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
25043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
25053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
25063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
25073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
25083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level1		= de::min(maxLevel, level0 + 1);
25093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
25103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					f			= deFloatFrac(lod);
25113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec4					t0;
25123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec4					t1;
25133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
25153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
25163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessNearest(faces[face][level0], sampler, s, t, depth);
25173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessNearest(faces[face][level1], sampler, s, t, depth);
25183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
25193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
25203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
25213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
25223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses0[CUBEFACE_LAST];
25243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses1[CUBEFACE_LAST];
25253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
25263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
25273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses0[i] = faces[i][level0];
25283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses1[i] = faces[i][level1];
25293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
25303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessLinear(faceAccesses0, face, sampler, s, t, depth);
25323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessLinear(faceAccesses1, face, sampler, s, t, depth);
25333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
25343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
25363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
25373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
25393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
25403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
25413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
25423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
25433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25443c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float sampleCubeSeamlessNearestCompare (const ConstPixelBufferAccess& faceAccess, const Sampler& sampler, float ref, float s, float t, int depth = 0)
25453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
25463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler clampingSampler = sampler;
25473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	clampingSampler.wrapS = Sampler::CLAMP_TO_EDGE;
25483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	clampingSampler.wrapT = Sampler::CLAMP_TO_EDGE;
25493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return faceAccess.sample2DCompare(clampingSampler, Sampler::NEAREST, ref, s, t, IVec3(0, 0, depth));
25503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
25513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25523c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float sampleCubeSeamlessLinearCompare (const ConstPixelBufferAccess (&faceAccesses)[CUBEFACE_LAST], CubeFace baseFace, const Sampler& sampler, float ref, float s, float t)
25533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
25543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(faceAccesses[0].getWidth() == faceAccesses[0].getHeight());
25553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		size	= faceAccesses[0].getWidth();
25573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
25583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float	u		= s;
25593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float	v		= t;
25603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
25623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
25633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		u = unnormalize(sampler.wrapS, s, size);
25643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		v = unnormalize(sampler.wrapT, t, size);
25653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
25663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			x0						= deFloorFloatToInt32(u-0.5f);
25683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			x1						= x0+1;
25693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			y0						= deFloorFloatToInt32(v-0.5f);
25703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			y1						= y0+1;
25713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec2		baseSampleCoords[4]		=
25723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
25733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x0, y0),
25743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x1, y0),
25753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x0, y1),
25763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x1, y1)
25773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
25783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		sampleRes[4];
25793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		hasBothCoordsOutOfBounds[4]; //!< Whether correctCubeFace() returns CUBEFACE_LAST, i.e. both u and v are out of bounds.
25803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Find correct faces and coordinates for out-of-bounds sample coordinates.
25823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
25843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
25853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CubeFaceIntCoords coords = remapCubeEdgeCoords(CubeFaceIntCoords(baseFace, baseSampleCoords[i]), size);
25863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		hasBothCoordsOutOfBounds[i] = coords.face == CUBEFACE_LAST;
25873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!hasBothCoordsOutOfBounds[i])
25893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
25903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool isFixedPointDepth = isFixedPointDepthTextureFormat(faceAccesses[coords.face].getFormat());
25913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sampleRes[i] = execCompare(faceAccesses[coords.face].getPixel(coords.s, coords.t), sampler.compare, sampler.compareChannel, ref, isFixedPointDepth);
25933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
25943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
25953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// If a sample was out of bounds in both u and v, we get its color from the average of the three other samples.
25973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note This averaging behavior is not required by the GLES3 spec (though it is recommended). GLES3 spec only
25983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//		 requires that if the three other samples all have the same color, then the doubly-out-of-bounds sample
25993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//		 must have this color as well.
26003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
26023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int bothOutOfBoundsNdx = -1;
26033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < 4; i++)
26043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
26053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (hasBothCoordsOutOfBounds[i])
26063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
26073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(bothOutOfBoundsNdx < 0); // Only one sample can be out of bounds in both u and v.
26083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				bothOutOfBoundsNdx = i;
26093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
26103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
26113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (bothOutOfBoundsNdx != -1)
26123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
26133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sampleRes[bothOutOfBoundsNdx] = 0.0f;
26143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < 4; i++)
26153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (i != bothOutOfBoundsNdx)
26163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					sampleRes[bothOutOfBoundsNdx] += sampleRes[i];
26173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sampleRes[bothOutOfBoundsNdx] = sampleRes[bothOutOfBoundsNdx] * (1.0f/3.0f);
26193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
26203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
26213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
26233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
26253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float b = deFloatFrac(v-0.5f);
26263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (sampleRes[0]*(1.0f-a)*(1.0f-b)) +
26283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (sampleRes[1]*(     a)*(1.0f-b)) +
26293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (sampleRes[2]*(1.0f-a)*(     b)) +
26303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (sampleRes[3]*(     a)*(     b));
26313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
26323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26333c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float sampleLevelArrayCubeSeamlessCompare (const ConstPixelBufferAccess* const (&faces)[CUBEFACE_LAST], int numLevels, CubeFace face, const Sampler& sampler, float ref, float s, float t, float lod)
26343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
26363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
26373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
26393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
26403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:
26413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessNearestCompare(faces[face][0], sampler, ref, s, t);
26423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:
26443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
26453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
26463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < (int)CUBEFACE_LAST; i++)
26473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				faceAccesses[i] = faces[i][0];
26483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessLinearCompare(faceAccesses, face, sampler, ref, s, t);
26503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
26513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
26533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
26543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
26553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
26563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
26573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
26583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
26603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessNearestCompare(faces[face][level], sampler, ref, s, t);
26613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
26623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
26633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
26643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
26663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
26673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses[i] = faces[i][level];
26683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessLinearCompare(faceAccesses, face, sampler, ref, s, t);
26703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
26713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
26723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
26743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
26753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
26763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
26773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
26783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level1		= de::min(maxLevel, level0 + 1);
26793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
26803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					f			= deFloatFrac(lod);
26813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					t0;
26823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					t1;
26833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
26853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
26863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessNearestCompare(faces[face][level0], sampler, ref, s, t);
26873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessNearestCompare(faces[face][level1], sampler, ref, s, t);
26883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
26893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
26903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
26913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
26923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses0[CUBEFACE_LAST];
26943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses1[CUBEFACE_LAST];
26953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
26963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
26973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses0[i] = faces[i][level0];
26983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses1[i] = faces[i][level1];
26993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
27003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessLinearCompare(faceAccesses0, face, sampler, ref, s, t);
27023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessLinearCompare(faceAccesses1, face, sampler, ref, s, t);
27033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
27043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
27063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
27073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
27093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
27103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
27113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
27123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Cube map array sampling
27153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27163c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline ConstPixelBufferAccess getCubeArrayFaceAccess (const ConstPixelBufferAccess* const levels, int levelNdx, int slice, CubeFace face)
27173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ConstPixelBufferAccess&	level	= levels[levelNdx];
27193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						depth	= (slice * 6) + getCubeArrayFaceIndex(face);
27203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return getSubregion(level, 0, 0, depth, level.getWidth(), level.getHeight(), 1);
27223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27243c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleCubeArraySeamless (const ConstPixelBufferAccess* const levels, int numLevels, int slice, CubeFace face, const Sampler& sampler, float s, float t, float lod)
27253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					faceDepth	= (slice * 6) + getCubeArrayFaceIndex(face);
27273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool					magnified	= lod <= sampler.lodThreshold;
27283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Sampler::FilterMode	filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
27293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
27313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
27323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:
27333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessNearest(levels[0], sampler, s, t, faceDepth);
27343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:
27363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
27373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
27383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < (int)CUBEFACE_LAST; i++)
27393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				faceAccesses[i] = getCubeArrayFaceAccess(levels, 0, slice, (CubeFace)i);
27403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessLinear(faceAccesses, face, sampler, s, t, 0);
27423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
27433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
27453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
27463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
27473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
27483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
27493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
27503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
27523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessNearest(levels[level], sampler, s, t, faceDepth);
27533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
27543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
27553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
27563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
27583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
27593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses[i] = getCubeArrayFaceAccess(levels, level, slice, (CubeFace)i);
27603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessLinear(faceAccesses, face, sampler, s, t, 0);
27623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
27633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
27643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
27663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
27673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
27683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
27693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
27703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level1		= de::min(maxLevel, level0 + 1);
27713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
27723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					f			= deFloatFrac(lod);
27733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec4					t0;
27743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec4					t1;
27753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
27773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
27783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessNearest(levels[level0], sampler, s, t, faceDepth);
27793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessNearest(levels[level1], sampler, s, t, faceDepth);
27803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
27813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
27823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
27833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
27843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses0[CUBEFACE_LAST];
27863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses1[CUBEFACE_LAST];
27873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
27883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
27893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses0[i] = getCubeArrayFaceAccess(levels, level0, slice, (CubeFace)i);
27903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses1[i] = getCubeArrayFaceAccess(levels, level1, slice, (CubeFace)i);
27913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
27923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessLinear(faceAccesses0, face, sampler, s, t, 0);
27943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessLinear(faceAccesses1, face, sampler, s, t, 0);
27953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
27963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
27983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
27993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
28013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
28023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
28033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
28043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28063c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float sampleCubeArraySeamlessCompare (const ConstPixelBufferAccess* const levels, int numLevels, int slice, CubeFace face, const Sampler& sampler, float ref, float s, float t, float lod)
28073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int			faceDepth	= (slice * 6) + getCubeArrayFaceIndex(face);
28093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool			magnified	= lod <= sampler.lodThreshold;
28103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode	filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
28113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
28133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
28143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:
28153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessNearestCompare(levels[0], sampler, ref, s, t, faceDepth);
28163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:
28183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
28193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
28203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < (int)CUBEFACE_LAST; i++)
28213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				faceAccesses[i] = getCubeArrayFaceAccess(levels, 0, slice, (CubeFace)i);
28223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessLinearCompare(faceAccesses, face, sampler, ref, s, t);
28243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
28253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
28273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
28283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
28293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
28303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
28313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
28323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
28343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessNearestCompare(levels[level], sampler, ref, s, t, faceDepth);
28353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
28363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
28373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
28383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
28403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
28413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses[i] = getCubeArrayFaceAccess(levels, level, slice, (CubeFace)i);
28423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessLinearCompare(faceAccesses, face, sampler, ref, s, t);
28443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
28453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
28463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
28483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
28493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
28503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
28513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
28523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level1		= de::min(maxLevel, level0 + 1);
28533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
28543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					f			= deFloatFrac(lod);
28553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					t0;
28563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					t1;
28573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
28593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
28603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessNearestCompare(levels[level0], sampler, ref, s, t, faceDepth);
28613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessNearestCompare(levels[level1], sampler, ref, s, t, faceDepth);
28623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
28633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
28643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
28653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
28663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses0[CUBEFACE_LAST];
28683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses1[CUBEFACE_LAST];
28693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
28703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
28713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses0[i] = getCubeArrayFaceAccess(levels, level0, slice, (CubeFace)i);
28723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses1[i] = getCubeArrayFaceAccess(levels, level1, slice, (CubeFace)i);
28733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
28743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessLinearCompare(faceAccesses0, face, sampler, ref, s, t);
28763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessLinearCompare(faceAccesses1, face, sampler, ref, s, t);
28773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
28783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
28803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
28813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
28833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
28843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
28853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
28863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28883c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int computeMipPyramidLevels (int size)
28893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return deLog2Floor32(size)+1;
28913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28933c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int computeMipPyramidLevels (int width, int height)
28943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return deLog2Floor32(de::max(width, height))+1;
28963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28983c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int computeMipPyramidLevels (int width, int height, int depth)
28993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return deLog2Floor32(de::max(width, de::max(height, depth)))+1;
29013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29033c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int getMipPyramidLevelSize (int baseLevelSize, int levelNdx)
29043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return de::max(baseLevelSize >> levelNdx, 1);
29063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// TextureLevelPyramid
29093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29103c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevelPyramid::TextureLevelPyramid (const TextureFormat& format, int numLevels)
29113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	(format)
29123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_data	(numLevels)
29133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_access	(numLevels)
29143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29173c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevelPyramid::TextureLevelPyramid (const TextureLevelPyramid& other)
29183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	(other.m_format)
29193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_data	(other.getNumLevels())
29203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_access	(other.getNumLevels())
29213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int levelNdx = 0; levelNdx < other.getNumLevels(); levelNdx++)
29233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
29243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!other.isLevelEmpty(levelNdx))
29253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
29263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::ConstPixelBufferAccess& srcLevel = other.getLevel(levelNdx);
29273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_data[levelNdx] = other.m_data[levelNdx];
29293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_access[levelNdx] = PixelBufferAccess(srcLevel.getFormat(), srcLevel.getWidth(), srcLevel.getHeight(), srcLevel.getDepth(), m_data[levelNdx].getPtr());
29303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
29313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
29323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29343c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevelPyramid& TextureLevelPyramid::operator= (const TextureLevelPyramid& other)
29353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
29373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
29383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_format = other.m_format;
29403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_data.resize(other.getNumLevels());
29413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_access.resize(other.getNumLevels());
29423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int levelNdx = 0; levelNdx < other.getNumLevels(); levelNdx++)
29443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
29453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!other.isLevelEmpty(levelNdx))
29463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
29473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::ConstPixelBufferAccess& srcLevel = other.getLevel(levelNdx);
29483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_data[levelNdx] = other.m_data[levelNdx];
29503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_access[levelNdx] = PixelBufferAccess(srcLevel.getFormat(), srcLevel.getWidth(), srcLevel.getHeight(), srcLevel.getDepth(), m_data[levelNdx].getPtr());
29513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
29523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (!isLevelEmpty(levelNdx))
29533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			clearLevel(levelNdx);
29543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
29553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
29573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29593c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevelPyramid::~TextureLevelPyramid (void)
29603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureLevelPyramid::allocLevel (int levelNdx, int width, int height, int depth)
29643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	size	= m_format.getPixelSize()*width*height*depth;
29663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(isLevelEmpty(levelNdx));
29683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_data[levelNdx].setStorage(size);
29703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_access[levelNdx] = PixelBufferAccess(m_format, width, height, depth, m_data[levelNdx].getPtr());
29713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureLevelPyramid::clearLevel (int levelNdx)
29743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!isLevelEmpty(levelNdx));
29763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_data[levelNdx].clear();
29783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_access[levelNdx] = PixelBufferAccess();
29793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture1D
29823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29833c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1D::Texture1D (const TextureFormat& format, int width)
29843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(format, computeMipPyramidLevels(width))
29853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(width)
29863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
29873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29903c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1D::Texture1D (const Texture1D& other)
29913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(other)
29923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(other.m_width)
29933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
29943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29973c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1D& Texture1D::operator= (const Texture1D& other)
29983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
30003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
30013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::operator=(other);
30033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_width		= other.m_width;
30053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view		= Texture1DView(getNumLevels(), getLevels());
30063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
30083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30103c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1D::~Texture1D (void)
30113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30143c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture1D::allocLevel (int levelNdx)
30153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels()));
30173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int width = getMipPyramidLevelSize(m_width, levelNdx);
30193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::allocLevel(levelNdx, width, 1, 1);
30213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture2D
30243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30253c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2D::Texture2D (const TextureFormat& format, int width, int height)
30263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(format, computeMipPyramidLevels(width, height))
30273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(width)
30283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height				(height)
30293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
30303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30333c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2D::Texture2D (const Texture2D& other)
30343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(other)
30353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(other.m_width)
30363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height				(other.m_height)
30373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
30383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30413c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2D& Texture2D::operator= (const Texture2D& other)
30423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
30443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
30453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::operator=(other);
30473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_width		= other.m_width;
30493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_height	= other.m_height;
30503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view		= Texture2DView(getNumLevels(), getLevels());
30513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
30533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30553c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2D::~Texture2D (void)
30563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2D::allocLevel (int levelNdx)
30603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels()));
30623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	width	= getMipPyramidLevelSize(m_width, levelNdx);
30643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	height	= getMipPyramidLevelSize(m_height, levelNdx);
30653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::allocLevel(levelNdx, width, height, 1);
30673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// TextureCubeView
30703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30713c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeView::TextureCubeView (void)
30723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_numLevels(0)
30733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < CUBEFACE_LAST; ndx++)
30753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_levels[ndx] = DE_NULL;
30763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30783c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeView::TextureCubeView (int numLevels, const ConstPixelBufferAccess* const (&levels) [CUBEFACE_LAST])
30793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_numLevels(numLevels)
30803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < CUBEFACE_LAST; ndx++)
30823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_levels[ndx] = levels[ndx];
30833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Vec4 TextureCubeView::sample (const Sampler& sampler, float s, float t, float r, float lod) const
30863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare == Sampler::COMPAREMODE_NONE);
30883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Computes (face, s, t).
30903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CubeFaceFloatCoords coords = getCubeFaceCoords(Vec3(s, t, r));
30913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.seamlessCubeMap)
30923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sampleLevelArrayCubeSeamless(m_levels, m_numLevels, coords.face, sampler, coords.s, coords.t, 0 /* depth */, lod);
30933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
30943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sampleLevelArray2D(m_levels[coords.face], m_numLevels, sampler, coords.s, coords.t, 0 /* depth */, lod);
30953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30973c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat TextureCubeView::sampleCompare (const Sampler& sampler, float ref, float s, float t, float r, float lod) const
30983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare != Sampler::COMPAREMODE_NONE);
31003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Computes (face, s, t).
31023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CubeFaceFloatCoords coords = getCubeFaceCoords(Vec3(s, t, r));
31033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.seamlessCubeMap)
31043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sampleLevelArrayCubeSeamlessCompare(m_levels, m_numLevels, coords.face, sampler, ref, coords.s, coords.t, lod);
31053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
31063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sampleLevelArray2DCompare(m_levels[coords.face], m_numLevels, sampler, ref, coords.s, coords.t, lod, IVec3(0, 0, 0));
31073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31093c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 TextureCubeView::gather (const Sampler& sampler, float s, float t, float r, int componentNdx) const
31103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare == Sampler::COMPAREMODE_NONE);
31123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
31143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)CUBEFACE_LAST; i++)
31153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		faceAccesses[i] = m_levels[i][0];
31163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CubeFaceFloatCoords	coords	= getCubeFaceCoords(Vec3(s, t, r));
31183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					size	= faceAccesses[0].getWidth();
31193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
31203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float						u		= coords.s;
31213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float						v		= coords.t;
31223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
31243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
31253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		u = unnormalize(sampler.wrapS, coords.s, size);
31263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		v = unnormalize(sampler.wrapT, coords.t, size);
31273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
31283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 sampleColors[4];
31303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	getCubeLinearSamples(faceAccesses, coords.face, u, v, 0, sampleColors);
31313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	sampleIndices[4] = { 2, 3, 1, 0 }; // \note Gather returns the samples in a non-obvious order.
31333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4		result;
31343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
31353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result[i] = sampleColors[sampleIndices[i]][componentNdx];
31363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
31383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31403c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 TextureCubeView::gatherCompare (const Sampler& sampler, float ref, float s, float t, float r) const
31413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare != Sampler::COMPAREMODE_NONE);
31433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_levels[0][0].getFormat().order == TextureFormat::D || m_levels[0][0].getFormat().order == TextureFormat::DS);
31443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compareChannel == 0);
31453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler noCompareSampler = sampler;
31473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	noCompareSampler.compare = Sampler::COMPAREMODE_NONE;
31483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec4 gathered			= gather(noCompareSampler, s, t, r, 0 /* component 0: depth */);
31503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool isFixedPoint		= isFixedPointDepthTextureFormat(m_levels[0][0].getFormat());
31513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 result;
31523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
31533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result[i] = execCompare(gathered, sampler.compare, i, ref, isFixedPoint);
31543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
31563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// TextureCube
31593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31603c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCube::TextureCube (const TextureFormat& format, int size)
31613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	(format)
31623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_size	(size)
31633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						numLevels		= computeMipPyramidLevels(m_size);
31653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ConstPixelBufferAccess*	levels[CUBEFACE_LAST];
31663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int face = 0; face < CUBEFACE_LAST; face++)
31683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
31693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_data[face].resize(numLevels);
31703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_access[face].resize(numLevels);
31713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		levels[face] = &m_access[face][0];
31723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
31733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view = TextureCubeView(numLevels, levels);
31753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31773c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCube::TextureCube (const TextureCube& other)
31783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	(other.m_format)
31793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_size	(other.m_size)
31803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						numLevels		= computeMipPyramidLevels(m_size);
31823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ConstPixelBufferAccess*	levels[CUBEFACE_LAST];
31833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int face = 0; face < CUBEFACE_LAST; face++)
31853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
31863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_data[face].resize(numLevels);
31873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_access[face].resize(numLevels);
31883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		levels[face] = &m_access[face][0];
31893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
31903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view = TextureCubeView(numLevels, levels);
31923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
31943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
31953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int face = 0; face < CUBEFACE_LAST; face++)
31963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
31973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!other.isLevelEmpty((CubeFace)face, levelNdx))
31983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
31993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				allocLevel((CubeFace)face, levelNdx);
32003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				copy(getLevelFace(levelNdx, (CubeFace)face),
32013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 other.getLevelFace(levelNdx, (CubeFace)face));
32023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
32033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
32043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
32053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32073c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCube& TextureCube::operator= (const TextureCube& other)
32083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
32103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
32113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						numLevels		= computeMipPyramidLevels(other.m_size);
32133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ConstPixelBufferAccess*	levels[CUBEFACE_LAST];
32143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int face = 0; face < CUBEFACE_LAST; face++)
32163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
32173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_data[face].resize(numLevels);
32183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_access[face].resize(numLevels);
32193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		levels[face] = &m_access[face][0];
32203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
32213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_format	= other.m_format;
32233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_size		= other.m_size;
32243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view		= TextureCubeView(numLevels, levels);
32253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
32273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
32283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int face = 0; face < CUBEFACE_LAST; face++)
32293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
32303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!isLevelEmpty((CubeFace)face, levelNdx))
32313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				clearLevel((CubeFace)face, levelNdx);
32323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!other.isLevelEmpty((CubeFace)face, levelNdx))
32343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
32353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				allocLevel((CubeFace)face, levelNdx);
32363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				copy(getLevelFace(levelNdx, (CubeFace)face),
32373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 other.getLevelFace(levelNdx, (CubeFace)face));
32383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
32393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
32403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
32413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
32433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32453c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCube::~TextureCube (void)
32463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCube::allocLevel (tcu::CubeFace face, int levelNdx)
32503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	size		= getMipPyramidLevelSize(m_size, levelNdx);
32523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	dataSize	= m_format.getPixelSize()*size*size;
32533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(isLevelEmpty(face, levelNdx));
32543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_data[face][levelNdx].setStorage(dataSize);
32563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_access[face][levelNdx] = PixelBufferAccess(m_format, size, size, 1, m_data[face][levelNdx].getPtr());
32573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCube::clearLevel (tcu::CubeFace face, int levelNdx)
32603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!isLevelEmpty(face, levelNdx));
32623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_data[face][levelNdx].clear();
32633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_access[face][levelNdx] = PixelBufferAccess();
32643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture1DArrayView
32673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32683c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1DArrayView::Texture1DArrayView (int numLevels, const ConstPixelBufferAccess* levels)
32693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_numLevels	(numLevels)
32703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_levels		(levels)
32713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32743c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int Texture1DArrayView::selectLayer (float r) const
32753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_numLevels > 0 && m_levels);
32773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return de::clamp(deFloorFloatToInt32(r + 0.5f), 0, m_levels[0].getHeight()-1);
32783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32803c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 Texture1DArrayView::sample (const Sampler& sampler, float s, float t, float lod) const
32813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray1D(m_levels, m_numLevels, sampler, s, selectLayer(t), lod);
32833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32853c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 Texture1DArrayView::sampleOffset (const Sampler& sampler, float s, float t, float lod, deInt32 offset) const
32863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray1DOffset(m_levels, m_numLevels, sampler, s, lod, IVec2(offset, selectLayer(t)));
32883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat Texture1DArrayView::sampleCompare (const Sampler& sampler, float ref, float s, float t, float lod) const
32913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray1DCompare(m_levels, m_numLevels, sampler, ref, s, lod, IVec2(0, selectLayer(t)));
32933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32953c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat Texture1DArrayView::sampleCompareOffset (const Sampler& sampler, float ref, float s, float t, float lod, deInt32 offset) const
32963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray1DCompare(m_levels, m_numLevels, sampler, ref, s, lod, IVec2(offset, selectLayer(t)));
32983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture2DArrayView
33013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33023c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArrayView::Texture2DArrayView (int numLevels, const ConstPixelBufferAccess* levels)
33033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_numLevels	(numLevels)
33043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_levels		(levels)
33053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33083c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int Texture2DArrayView::selectLayer (float r) const
33093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_numLevels > 0 && m_levels);
33113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return de::clamp(deFloorFloatToInt32(r + 0.5f), 0, m_levels[0].getDepth()-1);
33123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33143c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 Texture2DArrayView::sample (const Sampler& sampler, float s, float t, float r, float lod) const
33153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray2D(m_levels, m_numLevels, sampler, s, t, selectLayer(r), lod);
33173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33193c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat Texture2DArrayView::sampleCompare (const Sampler& sampler, float ref, float s, float t, float r, float lod) const
33203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray2DCompare(m_levels, m_numLevels, sampler, ref, s, t, lod, IVec3(0, 0, selectLayer(r)));
33223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33243c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 Texture2DArrayView::sampleOffset (const Sampler& sampler, float s, float t, float r, float lod, const IVec2& offset) const
33253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray2DOffset(m_levels, m_numLevels, sampler, s, t, lod, IVec3(offset.x(), offset.y(), selectLayer(r)));
33273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33293c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat Texture2DArrayView::sampleCompareOffset (const Sampler& sampler, float ref, float s, float t, float r, float lod, const IVec2& offset) const
33303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray2DCompare(m_levels, m_numLevels, sampler, ref, s, t, lod, IVec3(offset.x(), offset.y(), selectLayer(r)));
33323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33343c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 Texture2DArrayView::gatherOffsets (const Sampler& sampler, float s, float t, float r, int componentNdx, const IVec2 (&offsets)[4]) const
33353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return gatherArray2DOffsets(m_levels[0], sampler, s, t, selectLayer(r), componentNdx, offsets);
33373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33393c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 Texture2DArrayView::gatherOffsetsCompare (const Sampler& sampler, float ref, float s, float t, float r, const IVec2 (&offsets)[4]) const
33403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return gatherArray2DOffsetsCompare(m_levels[0], sampler, ref, s, t, selectLayer(r), offsets);
33423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture1DArray
33453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33463c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1DArray::Texture1DArray (const TextureFormat& format, int width, int numLayers)
33473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(format, computeMipPyramidLevels(width))
33483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(width)
33493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numLayers			(numLayers)
33503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
33513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33543c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1DArray::Texture1DArray (const Texture1DArray& other)
33553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(other)
33563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(other.m_width)
33573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numLayers			(other.m_numLayers)
33583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
33593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33623c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1DArray& Texture1DArray::operator= (const Texture1DArray& other)
33633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
33653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
33663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::operator=(other);
33683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_width		= other.m_width;
33703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_numLayers	= other.m_numLayers;
33713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view		= Texture1DArrayView(getNumLevels(), getLevels());
33723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
33743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33763c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1DArray::~Texture1DArray (void)
33773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture1DArray::allocLevel (int levelNdx)
33813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels()));
33833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int width = getMipPyramidLevelSize(m_width, levelNdx);
33853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::allocLevel(levelNdx, width, m_numLayers, 1);
33873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture2DArray
33903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33913c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArray::Texture2DArray (const TextureFormat& format, int width, int height, int numLayers)
33923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(format, computeMipPyramidLevels(width, height))
33933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(width)
33943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height				(height)
33953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numLayers			(numLayers)
33963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
33973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34003c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArray::Texture2DArray (const Texture2DArray& other)
34013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(other)
34023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(other.m_width)
34033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height				(other.m_height)
34043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numLayers			(other.m_numLayers)
34053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
34063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34093c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArray& Texture2DArray::operator= (const Texture2DArray& other)
34103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
34123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
34133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::operator=(other);
34153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_width		= other.m_width;
34173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_height	= other.m_height;
34183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_numLayers	= other.m_numLayers;
34193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view		= Texture2DArrayView(getNumLevels(), getLevels());
34203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
34223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34243c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArray::~Texture2DArray (void)
34253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34283c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2DArray::allocLevel (int levelNdx)
34293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels()));
34313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	width	= getMipPyramidLevelSize(m_width,	levelNdx);
34333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	height	= getMipPyramidLevelSize(m_height,	levelNdx);
34343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::allocLevel(levelNdx, width, height, m_numLayers);
34363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture3DView
34393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34403c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3DView::Texture3DView (int numLevels, const ConstPixelBufferAccess* levels)
34413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_numLevels	(numLevels)
34423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_levels		(levels)
34433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture3D
34473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34483c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3D::Texture3D (const TextureFormat& format, int width, int height, int depth)
34493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(format, computeMipPyramidLevels(width, height, depth))
34503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(width)
34513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height				(height)
34523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_depth				(depth)
34533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
34543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34573c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3D::Texture3D (const Texture3D& other)
34583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(other)
34593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(other.m_width)
34603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height				(other.m_height)
34613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_depth				(other.m_depth)
34623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
34633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34663c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3D& Texture3D::operator= (const Texture3D& other)
34673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
34693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
34703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::operator=(other);
34723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_width		= other.m_width;
34743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_height	= other.m_height;
34753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_depth		= other.m_depth;
34763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view		= Texture3DView(getNumLevels(), getLevels());
34773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
34793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34813c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3D::~Texture3D (void)
34823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34853c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture3D::allocLevel (int levelNdx)
34863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels()));
34883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int width		= getMipPyramidLevelSize(m_width,	levelNdx);
34903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int height	= getMipPyramidLevelSize(m_height,	levelNdx);
34913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int depth		= getMipPyramidLevelSize(m_depth,	levelNdx);
34923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::allocLevel(levelNdx, width, height, depth);
34943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// TextureCubeArrayView
34973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34983c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeArrayView::TextureCubeArrayView (int numLevels, const ConstPixelBufferAccess* levels)
34993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_numLevels	(numLevels)
35003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_levels		(levels)
35013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35048852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryinline int TextureCubeArrayView::selectLayer (float q) const
35053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_numLevels > 0 && m_levels);
35073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT((m_levels[0].getDepth() % 6) == 0);
35083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return de::clamp(deFloorFloatToInt32(q + 0.5f), 0, (m_levels[0].getDepth() / 6)-1);
35103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35123c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Vec4 TextureCubeArrayView::sample (const Sampler& sampler, float s, float t, float r, float q, float lod) const
35133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CubeFaceFloatCoords	coords		= getCubeFaceCoords(Vec3(s, t, r));
35158852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const int					layer		= selectLayer(q);
35168852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const int					faceDepth	= (layer * 6) + getCubeArrayFaceIndex(coords.face);
35173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare == Sampler::COMPAREMODE_NONE);
35193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.seamlessCubeMap)
35218852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		return sampleCubeArraySeamless(m_levels, m_numLevels, layer, coords.face, sampler, coords.s, coords.t, lod);
35223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
35233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sampleLevelArray2D(m_levels, m_numLevels, sampler, coords.s, coords.t, faceDepth, lod);
35243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35263c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat TextureCubeArrayView::sampleCompare (const Sampler& sampler, float ref, float s, float t, float r, float q, float lod) const
35273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CubeFaceFloatCoords	coords		= getCubeFaceCoords(Vec3(s, t, r));
35298852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const int					layer		= selectLayer(q);
35308852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const int					faceDepth	= (layer * 6) + getCubeArrayFaceIndex(coords.face);
35313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare != Sampler::COMPAREMODE_NONE);
35333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.seamlessCubeMap)
35358852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		return sampleCubeArraySeamlessCompare(m_levels, m_numLevels, layer, coords.face, sampler, ref, coords.s, coords.t, lod);
35363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
35373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sampleLevelArray2DCompare(m_levels, m_numLevels, sampler, ref, coords.s, coords.t, lod, IVec3(0, 0, faceDepth));
35383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// TextureCubeArray
35413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35428852c82a1ffa4760985c17cc6875d5d521daf343Jarkko PoyryTextureCubeArray::TextureCubeArray (const TextureFormat& format, int size, int depth)
35433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(format, computeMipPyramidLevels(size))
35443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_size				(size)
35458852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	, m_depth				(depth)
35463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
35473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35488852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	DE_ASSERT(m_depth % 6 == 0);
35493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35513c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeArray::TextureCubeArray (const TextureCubeArray& other)
35523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(other)
35533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_size				(other.m_size)
35548852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	, m_depth				(other.m_depth)
35553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
35563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35578852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	DE_ASSERT(m_depth % 6 == 0);
35583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35603c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeArray& TextureCubeArray::operator= (const TextureCubeArray& other)
35613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
35633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
35643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::operator=(other);
35663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35678852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	m_size	= other.m_size;
35688852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	m_depth	= other.m_depth;
35698852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	m_view	= TextureCubeArrayView(getNumLevels(), getLevels());
35703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35718852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	DE_ASSERT(m_depth % 6 == 0);
35723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
35743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35763c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeArray::~TextureCubeArray (void)
35773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCubeArray::allocLevel (int levelNdx)
35813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels()));
35833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int size = getMipPyramidLevelSize(m_size, levelNdx);
35853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35868852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	TextureLevelPyramid::allocLevel(levelNdx, size, size, m_depth);
35873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35893c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& str, TextureFormat::ChannelOrder order)
35903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3591ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	const char* const orderStrings[] =
3592ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	{
3593ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"R",
3594ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"A",
3595ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"I",
3596ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"L",
3597ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"LA",
3598ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"RG",
3599ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"RA",
3600ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"RGB",
3601ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"RGBA",
3602ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"ARGB",
3603725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"BGR",
3604ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"BGRA",
3605ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi
360616d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		"sR",
360716d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		"sRG",
3608ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"sRGB",
3609ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"sRGBA",
3610725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"sBGR",
3611725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"sBGRA",
3612ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi
3613ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"D",
3614ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"S",
3615ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"DS"
3616ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	};
3617ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi
3618ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	return str << de::getSizedArrayElement<TextureFormat::CHANNELORDER_LAST>(orderStrings, order);
36193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36213c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& str, TextureFormat::ChannelType type)
36223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3623ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	const char* const typeStrings[] =
3624ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	{
3625ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"SNORM_INT8",
3626ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"SNORM_INT16",
3627ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"SNORM_INT32",
3628ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_INT8",
3629ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_INT16",
363007104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry		"UNORM_INT24",
3631ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_INT32",
3632725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"UNORM_BYTE_44",
3633ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_SHORT_565",
3634ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_SHORT_555",
3635ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_SHORT_4444",
3636ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_SHORT_5551",
3637ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_INT_101010",
3638725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"SNORM_INT_1010102_REV",
3639ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_INT_1010102_REV",
3640725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"UNSIGNED_BYTE_44",
3641725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"UNSIGNED_SHORT_565",
3642725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"UNSIGNED_SHORT_4444",
3643725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"UNSIGNED_SHORT_5551",
3644725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"SIGNED_INT_1010102_REV",
3645ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT_1010102_REV",
3646ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT_11F_11F_10F_REV",
3647ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT_999_E5_REV",
3648725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"UNSIGNED_INT_16_8_8",
3649ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT_24_8",
3650725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"UNSIGNED_INT_24_8_REV",
3651ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"SIGNED_INT8",
3652ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"SIGNED_INT16",
3653ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"SIGNED_INT32",
3654ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT8",
3655ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT16",
3656db6ba452c1213fd1c2b03369fdf4c1d23f07cfadJarkko Pöyry		"UNSIGNED_INT24",
3657ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT32",
3658ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"HALF_FLOAT",
3659ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"FLOAT",
3660725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"FLOAT64",
3661ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"FLOAT_UNSIGNED_INT_24_8_REV"
3662ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	};
3663ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi
3664ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	return str << de::getSizedArrayElement<TextureFormat::CHANNELTYPE_LAST>(typeStrings, type);
36653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36673c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& str, CubeFace face)
36683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (face)
36703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
36713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_X:	return str << "CUBEFACE_NEGATIVE_X";
36723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_X:	return str << "CUBEFACE_POSITIVE_X";
36733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_Y:	return str << "CUBEFACE_NEGATIVE_Y";
36743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_Y:	return str << "CUBEFACE_POSITIVE_Y";
36753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_Z:	return str << "CUBEFACE_NEGATIVE_Z";
36763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_Z:	return str << "CUBEFACE_POSITIVE_Z";
36773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_LAST:			return str << "CUBEFACE_LAST";
36783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:					return str << "UNKNOWN(" << (int)face << ")";
36793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
36803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36823c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& str, TextureFormat format)
36833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return str << format.order << ", " << format.type << "";
36853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36873c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& str, const ConstPixelBufferAccess& access)
36883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return str << "format = (" << access.getFormat() << "), size = "
36903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			   << access.getWidth() << " x " << access.getHeight() << " x " << access.getDepth()
36913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			   << ", pitch = " << access.getRowPitch() << " / " << access.getSlicePitch();
36923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // tcu
3695