tcuTexture.cpp revision 5b2b45177edf5062ce3a76a885e60e3fb5044002
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
41e2145884f87cdca749a754abfd246cdfe01ea2c1Pyry Haulos// \note No sign. Denorms are supported.
42e2145884f87cdca749a754abfd246cdfe01ea2c1Pyry Haulostypedef Float<deUint32, 5, 6, 15, FLOAT_SUPPORT_DENORM>	Float11;
43e2145884f87cdca749a754abfd246cdfe01ea2c1Pyry Haulostypedef Float<deUint32, 5, 5, 15, FLOAT_SUPPORT_DENORM>	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]); }
54e2145884f87cdca749a754abfd246cdfe01ea2c1Pyry Haulosinline IVec4	readRGB888Int		(const deUint8* ptr) { return IVec4(ptr[0], ptr[1], ptr[2], 1); }
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
2635b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 38);
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
3275b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 38);
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
3575b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 38);
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
3875b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 38);
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
4445b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 38);
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
54425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulosbool isColorOrder (TextureFormat::ChannelOrder order)
54525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos{
54625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	DE_STATIC_ASSERT(TextureFormat::CHANNELORDER_LAST == 21);
54725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
54825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	switch (order)
54925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	{
55025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::R:
55125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::A:
55225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::I:
55325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::L:
55425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::LA:
55525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::RG:
55625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::RA:
55725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::RGB:
55825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::RGBA:
55925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::ARGB:
56025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::BGR:
56125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::BGRA:
56225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::sR:
56325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::sRG:
56425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::sRGB:
56525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::sRGBA:
56625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::sBGR:
56725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::sBGRA:
56825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return true;
56925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
57025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		default:
57125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return false;
57225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	}
57325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos}
57425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
57725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulosbool isValid (TextureFormat format)
57825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos{
57925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	const bool	isColor	= isColorOrder(format.order);
58025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
58125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	switch (format.type)
58225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	{
58325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::SNORM_INT8:
58425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::SNORM_INT16:
58525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::SNORM_INT32:
58625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return isColor;
58725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
58825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_INT8:
58925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_INT16:
59025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_INT24:
59125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_INT32:
59225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return isColor || format.order == TextureFormat::D;
59325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
59425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_BYTE_44:
59525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_BYTE_44:
59625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return format.order == TextureFormat::RG;
59725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
59825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_SHORT_565:
59925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_SHORT_555:
60025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_565:
60125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return format.order == TextureFormat::RGB || format.order == TextureFormat::BGR;
60225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
60325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_SHORT_4444:
60425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_SHORT_5551:
60525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_4444:
60625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_5551:
60725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return format.order == TextureFormat::RGBA || format.order == TextureFormat::BGRA;
60825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
6095b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos		case TextureFormat::UNORM_SHORT_1555:
6105b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			return format.order == TextureFormat::ARGB;
6115b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos
61225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_INT_101010:
61325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return format.order == TextureFormat::RGB;
61425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
61525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::SNORM_INT_1010102_REV:
61625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_INT_1010102_REV:
61725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::SIGNED_INT_1010102_REV:
61825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT_1010102_REV:
61925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return format.order == TextureFormat::RGBA || format.order == TextureFormat::BGRA;
62025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
62125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
62225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT_999_E5_REV:
62325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return format.order == TextureFormat::RGB;
62425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
62525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT_16_8_8:
62625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return format.order == TextureFormat::DS;
62725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
62825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT_24_8:
62925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT_24_8_REV:
63025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return format.order == TextureFormat::D || format.order == TextureFormat::DS;
63125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
63225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::SIGNED_INT8:
63325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::SIGNED_INT16:
63425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::SIGNED_INT32:
63525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return isColor;
63625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
63725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT8:
63825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT16:
63925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT24:
64025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT32:
64125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return isColor || format.order == TextureFormat::S;
64225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
64325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::HALF_FLOAT:
64425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::FLOAT:
64525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::FLOAT64:
64625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return isColor || format.order == TextureFormat::D;
64725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
64825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
64925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return format.order == TextureFormat::DS;
65025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
65125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		default:
65225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			DE_FATAL("Unknown format");
65325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return 0u;
65425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	}
65525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
6565b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 38);
65725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos}
65825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
65925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos/** Get pixel size in bytes. */
66025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulosint getPixelSize (TextureFormat format)
66125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos{
66225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	const TextureFormat::ChannelOrder	order	= format.order;
66325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	const TextureFormat::ChannelType	type	= format.type;
66425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
66525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	DE_ASSERT(isValid(format));
66625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
66725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	// make sure this table is updated if format table is updated
6685b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 38);
66925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
67025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	switch (type)
67125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	{
67225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_BYTE_44:
67325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_BYTE_44:
67425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return 1;
67525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
67625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_SHORT_565:
67725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_SHORT_555:
67825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_SHORT_4444:
67925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_SHORT_5551:
6805b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos		case TextureFormat::UNORM_SHORT_1555:
68125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_565:
68225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_4444:
68325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_5551:
68425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return 2;
68525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
68625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_INT_101010:
68725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT_999_E5_REV:
68825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
68925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::SNORM_INT_1010102_REV:
69025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_INT_1010102_REV:
69125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::SIGNED_INT_1010102_REV:
69225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT_1010102_REV:
69325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT_24_8:
69425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT_24_8_REV:
69525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT_16_8_8:
69625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return 4;
69725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
69825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
69925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return 8;
70025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
70125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		default:
70225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return getNumUsedChannels(order) * getChannelSize(type);
70325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	}
70425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos}
70525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
70625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulosint TextureFormat::getPixelSize (void) const
70725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos{
70825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	return ::tcu::getPixelSize(*this);
70925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos}
71025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
7116d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyryconst TextureSwizzle& getChannelReadSwizzle (TextureFormat::ChannelOrder order)
7126d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry{
7136d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	// make sure to update these tables when channel orders are updated
714725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	DE_STATIC_ASSERT(TextureFormat::CHANNELORDER_LAST == 21);
7156d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
7166d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle INV		= {{ TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ONE	}};
7176d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle R		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ONE	}};
7186d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle A		= {{ TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_0	}};
7196d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle I		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0	}};
7206d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle L		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ONE	}};
7216d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle LA		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1	}};
7226d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RG		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ONE	}};
7236d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RA		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_1	}};
7246d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RGB		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_ONE	}};
7256d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RGBA	= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_3	}};
726725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	static const TextureSwizzle BGR		= {{ TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ONE	}};
7276d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle BGRA	= {{ TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_3	}};
7286d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle ARGB	= {{ TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_3,		TextureSwizzle::CHANNEL_0	}};
7296d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle D		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ONE	}};
73009037a4653649d707449463dfe9817a78ccf7d2fJarkko Pöyry	static const TextureSwizzle S		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ONE	}};
7316d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
7326d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	switch (order)
7336d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	{
7346d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::R:			return R;
7356d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::A:			return A;
7366d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::I:			return I;
7376d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::L:			return L;
7386d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::LA:			return LA;
7396d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RG:			return RG;
7406d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RA:			return RA;
7416d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RGB:		return RGB;
7426d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RGBA:		return RGBA;
7436d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::ARGB:		return ARGB;
744725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::BGR:		return BGR;
7456d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::BGRA:		return BGRA;
74616d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		case TextureFormat::sR:			return R;
74716d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		case TextureFormat::sRG:		return RG;
7486d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::sRGB:		return RGB;
7496d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::sRGBA:		return RGBA;
750725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::sBGR:		return BGR;
751725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::sBGRA:		return BGRA;
7526d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::D:			return D;
7536d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::S:			return S;
7548baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry
7558baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry		case TextureFormat::DS:
7568baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			DE_ASSERT(false); // combined formats cannot be read from
7578baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			return INV;
7588baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry
7596d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		default:
7606d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			DE_ASSERT(DE_FALSE);
7616d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			return INV;
7626d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	}
7636d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry}
7646d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
7656d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyryconst TextureSwizzle& getChannelWriteSwizzle (TextureFormat::ChannelOrder order)
7666d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry{
7676d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	// make sure to update these tables when channel orders are updated
768725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	DE_STATIC_ASSERT(TextureFormat::CHANNELORDER_LAST == 21);
7696d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
7706d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle INV		= {{ TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
7716d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle R		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
7726d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle A		= {{ TextureSwizzle::CHANNEL_3,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
7736d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle I		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
7746d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle L		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
7756d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle LA		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_3,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
7766d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RG		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
7776d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RA		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_3,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
7786d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RGB		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_LAST	}};
7796d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RGBA	= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_3		}};
780725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	static const TextureSwizzle BGR		= {{ TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_LAST	}};
7816d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle BGRA	= {{ TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_3		}};
7826d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle ARGB	= {{ TextureSwizzle::CHANNEL_3,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_2		}};
7836d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle D		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
78409037a4653649d707449463dfe9817a78ccf7d2fJarkko Pöyry	static const TextureSwizzle S		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
7856d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
7866d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	switch (order)
7876d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	{
7886d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::R:			return R;
7896d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::A:			return A;
7906d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::I:			return I;
7916d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::L:			return L;
7926d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::LA:			return LA;
7936d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RG:			return RG;
7946d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RA:			return RA;
7956d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RGB:		return RGB;
7966d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RGBA:		return RGBA;
7976d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::ARGB:		return ARGB;
798725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::BGR:		return BGR;
7996d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::BGRA:		return BGRA;
80016d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		case TextureFormat::sR:			return R;
80116d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		case TextureFormat::sRG:		return RG;
8026d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::sRGB:		return RGB;
8036d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::sRGBA:		return RGBA;
804725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::sBGR:		return BGR;
805725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::sBGRA:		return BGRA;
8066d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::D:			return D;
8076d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::S:			return S;
8088baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry
8098baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry		case TextureFormat::DS:
8108baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			DE_ASSERT(false); // combined formats cannot be written to
8118baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			return INV;
8128baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry
8136d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		default:
8146d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			DE_ASSERT(DE_FALSE);
8156d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			return INV;
8166d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	}
8176d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry}
8186d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
81929340067e919854db7d50bb8c0b666117b229f5eMika IsojärviIVec3 calculatePackedPitch (const TextureFormat& format, const IVec3& size)
82029340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi{
82129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	const int pixelSize		= format.getPixelSize();
82229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	const int rowPitch		= pixelSize * size.x();
82329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	const int slicePitch	= rowPitch * size.y();
82429340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
82529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	return IVec3(pixelSize, rowPitch, slicePitch);
82629340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi}
82729340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
8283c827367444ee418f129b2c238299f49d3264554Jarkko PoyryConstPixelBufferAccess::ConstPixelBufferAccess (void)
82929340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	: m_size		(0)
83029340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_pitch		(0)
8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_data		(DE_NULL)
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8353c827367444ee418f129b2c238299f49d3264554Jarkko PoyryConstPixelBufferAccess::ConstPixelBufferAccess (const TextureFormat& format, int width, int height, int depth, const void* data)
8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format		(format)
83729340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size		(width, height, depth)
83829340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_pitch		(calculatePackedPitch(m_format, m_size))
83929340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_data		((void*)data)
84029340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi{
84125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	DE_ASSERT(isValid(format));
84229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi}
84329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
84429340067e919854db7d50bb8c0b666117b229f5eMika IsojärviConstPixelBufferAccess::ConstPixelBufferAccess (const TextureFormat& format, const IVec3& size, const void* data)
84529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	: m_format		(format)
84629340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size		(size)
84729340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_pitch		(calculatePackedPitch(m_format, m_size))
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_data		((void*)data)
8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
85025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	DE_ASSERT(isValid(format));
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8533c827367444ee418f129b2c238299f49d3264554Jarkko PoyryConstPixelBufferAccess::ConstPixelBufferAccess (const TextureFormat& format, int width, int height, int depth, int rowPitch, int slicePitch, const void* data)
8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format		(format)
85529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size		(width, height, depth)
85629340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_pitch		(format.getPixelSize(), rowPitch, slicePitch)
85729340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_data		((void*)data)
85829340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi{
85925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	DE_ASSERT(isValid(format));
86029340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi}
86129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
86229340067e919854db7d50bb8c0b666117b229f5eMika IsojärviConstPixelBufferAccess::ConstPixelBufferAccess (const TextureFormat& format, const IVec3& size, const IVec3& pitch, const void* data)
86329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	: m_format		(format)
86429340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size		(size)
86529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_pitch		(pitch)
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_data		((void*)data)
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
86825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	DE_ASSERT(isValid(format));
86929340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(m_format.getPixelSize() <= m_pitch.x());
8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8723c827367444ee418f129b2c238299f49d3264554Jarkko PoyryConstPixelBufferAccess::ConstPixelBufferAccess (const TextureLevel& level)
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format		(level.getFormat())
87429340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size		(level.getSize())
87529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_pitch		(calculatePackedPitch(m_format, m_size))
8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_data		((void*)level.getPtr())
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8803c827367444ee418f129b2c238299f49d3264554Jarkko PoyryPixelBufferAccess::PixelBufferAccess (const TextureFormat& format, int width, int height, int depth, void* data)
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: ConstPixelBufferAccess(format, width, height, depth, data)
8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
88529340067e919854db7d50bb8c0b666117b229f5eMika IsojärviPixelBufferAccess::PixelBufferAccess (const TextureFormat& format, const IVec3& size, void* data)
88629340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	: ConstPixelBufferAccess(format, size, data)
88729340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi{
88829340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi}
88929340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
8903c827367444ee418f129b2c238299f49d3264554Jarkko PoyryPixelBufferAccess::PixelBufferAccess (const TextureFormat& format, int width, int height, int depth, int rowPitch, int slicePitch, void* data)
8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: ConstPixelBufferAccess(format, width, height, depth, rowPitch, slicePitch, data)
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
89529340067e919854db7d50bb8c0b666117b229f5eMika IsojärviPixelBufferAccess::PixelBufferAccess (const TextureFormat& format, const IVec3& size, const IVec3& pitch, void* data)
89629340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	: ConstPixelBufferAccess(format, size, pitch, data)
89729340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi{
89829340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi}
89929340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
9003c827367444ee418f129b2c238299f49d3264554Jarkko PoyryPixelBufferAccess::PixelBufferAccess (TextureLevel& level)
9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: ConstPixelBufferAccess(level)
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
905725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos//! Swizzle RGB(A) <-> BGR(A)
906725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulostemplate<typename T>
907725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry HaulosVector<T, 4> swizzleRB (const Vector<T, 4>& v, TextureFormat::ChannelOrder src, TextureFormat::ChannelOrder dst)
908725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos{
909725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	if (src == dst)
910725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		return v;
911725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	else
912725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	{
913725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		DE_ASSERT((src == TextureFormat::RGB && dst == TextureFormat::BGR) ||
914725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos				  (src == TextureFormat::BGR && dst == TextureFormat::RGB) ||
915725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos				  (src == TextureFormat::RGBA && dst == TextureFormat::BGRA) ||
916725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos				  (src == TextureFormat::BGRA && dst == TextureFormat::RGBA));
917725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		return v.swizzle(2,1,0,3);
918725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	}
919725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos}
920725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
9213c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 ConstPixelBufferAccess::getPixel (int x, int y, int z) const
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
92329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(x, 0, m_size.x()));
92429340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(y, 0, m_size.y()));
92529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(z, 0, m_size.z()));
9268baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	DE_ASSERT(!isCombinedDepthStencilType(m_format.type)); // combined types cannot be accessed directly
9278baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	DE_ASSERT(m_format.order != TextureFormat::DS); // combined formats cannot be accessed directly
92829340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
9298baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	const deUint8* pixelPtr = (const deUint8*)getPixelPtr(x, y, z);
9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Optimized fomats.
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_format.type == TextureFormat::UNORM_INT8)
9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9340158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		if (m_format.order == TextureFormat::RGBA || m_format.order == TextureFormat::sRGBA)
93529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi			return readRGBA8888Float(pixelPtr);
9360158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		else if (m_format.order == TextureFormat::RGB || m_format.order == TextureFormat::sRGB)
93729340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi			return readRGB888Float(pixelPtr);
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
940725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define UI8(OFFS, COUNT)		((*((const deUint8*)pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1))
941725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define UI16(OFFS, COUNT)		((*((const deUint16*)pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1))
942725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define UI32(OFFS, COUNT)		((*((const deUint32*)pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1))
943725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define SI32(OFFS, COUNT)		signExtend(UI32(OFFS, COUNT), (COUNT))
944725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define UN8(OFFS, COUNT)		channelToUnormFloat(UI8 (OFFS, COUNT), (COUNT))
945725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define UN16(OFFS, COUNT)		channelToUnormFloat(UI16(OFFS, COUNT), (COUNT))
946725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define UN32(OFFS, COUNT)		channelToUnormFloat(UI32(OFFS, COUNT), (COUNT))
947725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define SN32(OFFS, COUNT)		channelToSnormFloat(UI32(OFFS, COUNT), (COUNT))
9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Packed formats.
9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
952725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_BYTE_44:				return			  Vec4(UN8 (4,   4), UN8 ( 0,  4), 0.0f, 1.0f);
953725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_BYTE_44:			return			 UVec4(UI8 (4,   4), UI8 ( 0,  4), 0u, 1u).cast<float>();
9545b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos		case TextureFormat::UNORM_SHORT_565:			return swizzleRB( Vec4(UN16(11,  5), UN16( 5,  6), UN16( 0,  5), 1.0f), m_format.order, TextureFormat::RGB);
9555b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_565:			return swizzleRB(UVec4(UI16(11,  5), UI16( 5,  6), UI16( 0,  5), 1u), m_format.order, TextureFormat::RGB).cast<float>();
9565b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos		case TextureFormat::UNORM_SHORT_555:			return swizzleRB( Vec4(UN16(10,  5), UN16( 5,  5), UN16( 0,  5), 1.0f), m_format.order, TextureFormat::RGB);
9575b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos		case TextureFormat::UNORM_SHORT_4444:			return swizzleRB( Vec4(UN16(12,  4), UN16( 8,  4), UN16( 4,  4), UN16( 0, 4)), m_format.order, TextureFormat::RGBA);
9585b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_4444:		return swizzleRB(UVec4(UI16(12,  4), UI16( 8,  4), UI16( 4,  4), UI16( 0, 4)), m_format.order, TextureFormat::RGBA).cast<float>();
9595b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos		case TextureFormat::UNORM_SHORT_5551:			return swizzleRB( Vec4(UN16(11,  5), UN16( 6,  5), UN16( 1,  5), UN16( 0, 1)), m_format.order, TextureFormat::RGBA);
9605b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_5551:		return swizzleRB(UVec4(UI16(11,  5), UI16( 6,  5), UI16( 1,  5), UI16( 0, 1)), m_format.order, TextureFormat::RGBA).cast<float>();
961725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_INT_101010:			return			  Vec4(UN32(22, 10), UN32(12, 10), UN32( 2, 10), 1.0f);
9625b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos		case TextureFormat::UNORM_INT_1010102_REV:		return swizzleRB( Vec4(UN32( 0, 10), UN32(10, 10), UN32(20, 10), UN32(30, 2)), m_format.order, TextureFormat::RGBA);
9635b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos		case TextureFormat::SNORM_INT_1010102_REV:		return swizzleRB( Vec4(SN32( 0, 10), SN32(10, 10), SN32(20, 10), SN32(30, 2)), m_format.order, TextureFormat::RGBA);
9645b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos		case TextureFormat::UNSIGNED_INT_1010102_REV:	return swizzleRB( UVec4(UI32(0, 10), UI32(10, 10), UI32(20, 10), UI32(30, 2)), m_format.order, TextureFormat::RGBA).cast<float>();
9655b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos		case TextureFormat::SIGNED_INT_1010102_REV:		return swizzleRB( UVec4(SI32(0, 10), SI32(10, 10), SI32(20, 10), SI32(30, 2)), m_format.order, TextureFormat::RGBA).cast<float>();
9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_999_E5_REV:	return unpackRGB999E5(*((const deUint32*)pixelPtr));
9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9685b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos		case TextureFormat::UNORM_SHORT_1555:
9695b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::ARGB);
9705b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			return Vec4(UN16(15, 1), UN16(10, 5), UN16(5, 5), UN16(0, 5)).swizzle(1,2,3,0); // ARGB -> RGBA
9715b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos
9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
973725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			return Vec4(Float11(UI32(0, 11)).asFloat(), Float11(UI32(11, 11)).asFloat(), Float10(UI32(22, 10)).asFloat(), 1.0f);
9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
979725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef UN8
980725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef UN16
981725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef UN32
982725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef SN32
983725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef SI32
984725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef UI8
985725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef UI16
986725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef UI32
9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generic path.
9896d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	Vec4							result;
9906d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	const TextureSwizzle::Channel*	channelMap	= getChannelReadSwizzle(m_format.order).components;
9916d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	int								channelSize	= getChannelSize(m_format.type);
9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int c = 0; c < 4; c++)
9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9956d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		switch (channelMap[c])
9966d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		{
9976d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_0:
9986d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_1:
9996d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_2:
10006d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_3:
10016d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				result[c] = channelToFloat(pixelPtr + channelSize*((int)channelMap[c]), m_format.type);
10026d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				break;
10036d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
10046d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_ZERO:
10056d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				result[c] = 0.0f;
10066d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				break;
10076d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
10086d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_ONE:
10096d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				result[c] = 1.0f;
10106d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				break;
10116d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
10126d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			default:
10136d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				DE_ASSERT(false);
10146d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		}
10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10203c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIVec4 ConstPixelBufferAccess::getPixelInt (int x, int y, int z) const
10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
102229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(x, 0, m_size.x()));
102329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(y, 0, m_size.y()));
102429340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(z, 0, m_size.z()));
10258baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	DE_ASSERT(!isCombinedDepthStencilType(m_format.type)); // combined types cannot be accessed directly
10268baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	DE_ASSERT(m_format.order != TextureFormat::DS); // combined formats cannot be accessed directly
10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10288baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	const deUint8* const	pixelPtr = (const deUint8*)getPixelPtr(x, y, z);
102907104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	IVec4					result;
10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Optimized fomats.
10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_format.type == TextureFormat::UNORM_INT8)
10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10340158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		if (m_format.order == TextureFormat::RGBA || m_format.order == TextureFormat::sRGBA)
10350158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi			return readRGBA8888Int(pixelPtr);
10360158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		else if (m_format.order == TextureFormat::RGB || m_format.order == TextureFormat::sRGB)
10370158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi			return readRGB888Int(pixelPtr);
10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1040725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define U8(OFFS, COUNT)			((*((const deUint8* )pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1))
10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define U16(OFFS, COUNT)		((*((const deUint16*)pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1))
10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define U32(OFFS, COUNT)		((*((const deUint32*)pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1))
1043725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define S32(OFFS, COUNT)		signExtend(U32(OFFS, COUNT), (COUNT))
10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1047725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_BYTE_44:			// Fall-through
1048725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_BYTE_44:				return			 UVec4(U8 ( 4,  4), U8 ( 0,  4), 0u, 1u).cast<int>();
1049725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_565:			// Fall-through
10505b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos		case TextureFormat::UNORM_SHORT_565:			return swizzleRB(UVec4(U16(11,  5), U16( 5,  6), U16( 0,  5), 1).cast<int>(), m_format.order, TextureFormat::RGB);
10515b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos		case TextureFormat::UNORM_SHORT_555:			return swizzleRB(UVec4(U16(10,  5), U16( 5,  5), U16( 0,  5), 1).cast<int>(), m_format.order, TextureFormat::RGB);
1052725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_4444:		// Fall-through
10535b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos		case TextureFormat::UNORM_SHORT_4444:			return swizzleRB(UVec4(U16(12,  4), U16( 8,  4), U16( 4,  4), U16( 0, 4)).cast<int>(), m_format.order, TextureFormat::RGBA);
1054725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_5551:		// Fall-through
10555b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos		case TextureFormat::UNORM_SHORT_5551:			return swizzleRB(UVec4(U16(11,  5), U16( 6,  5), U16( 1,  5), U16( 0, 1)).cast<int>(), m_format.order, TextureFormat::RGBA);
1056725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_INT_101010:			return			 UVec4(U32(22, 10), U32(12, 10), U32( 2, 10), 1).cast<int>();
1057725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_INT_1010102_REV:		// Fall-through
10585b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos		case TextureFormat::UNSIGNED_INT_1010102_REV:	return swizzleRB(UVec4(U32( 0, 10), U32(10, 10), U32(20, 10), U32(30, 2)), m_format.order, TextureFormat::RGBA).cast<int>();
1059725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::SNORM_INT_1010102_REV:		// Fall-through
10605b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos		case TextureFormat::SIGNED_INT_1010102_REV:		return swizzleRB(IVec4(S32( 0, 10), S32(10, 10), S32(20, 10), S32(30, 2)), m_format.order, TextureFormat::RGBA);
10615b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos
10625b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos		case TextureFormat::UNORM_SHORT_1555:
10635b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::ARGB);
10645b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			return UVec4(U16(15, 1), U16(10, 5), U16(5, 5), U16(0, 5)).cast<int>().swizzle(1,2,3,0); // ARGB -> RGBA
10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break; // To generic path.
10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1070725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef U8
10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef U16
10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef U32
1073725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef S32
10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generic path.
10766d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	const TextureSwizzle::Channel*	channelMap	= getChannelReadSwizzle(m_format.order).components;
10776d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	int								channelSize	= getChannelSize(m_format.type);
10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int c = 0; c < 4; c++)
10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10816d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		switch (channelMap[c])
10826d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		{
10836d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_0:
10846d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_1:
10856d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_2:
10866d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_3:
10876d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				result[c] = channelToInt(pixelPtr + channelSize*((int)channelMap[c]), m_format.type);
10886d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				break;
10896d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
10906d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_ZERO:
10916d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				result[c] = 0;
10926d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				break;
10936d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
10946d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_ONE:
10956d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				result[c] = 1;
10966d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				break;
10976d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
10986d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			default:
10996d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				DE_ASSERT(false);
11006d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		}
11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<>
11073c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 ConstPixelBufferAccess::getPixelT (int x, int y, int z) const
11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return getPixel(x, y, z);
11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<>
11133c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIVec4 ConstPixelBufferAccess::getPixelT (int x, int y, int z) const
11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return getPixelInt(x, y, z);
11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<>
11193c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUVec4 ConstPixelBufferAccess::getPixelT (int x, int y, int z) const
11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return getPixelUint(x, y, z);
11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat ConstPixelBufferAccess::getPixDepth (int x, int y, int z) const
11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(x, 0, getWidth()));
11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(y, 0, getHeight()));
11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(z, 0, getDepth()));
11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11308baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	const deUint8* const pixelPtr = (const deUint8*)getPixelPtr(x, y, z);
11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1134725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_16_8_8:
113500d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::DS);
1136725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			return (float)readUint32High16(pixelPtr) / 65535.0f;
113774a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi
113800d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos		case TextureFormat::UNSIGNED_INT_24_8:
1139725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::D || m_format.order == TextureFormat::DS);
114000d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			return (float)readUint32High24(pixelPtr) / 16777215.0f;
11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1142725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_24_8_REV:
1143725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::D || m_format.order == TextureFormat::DS);
1144725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			return (float)readUint32Low24(pixelPtr) / 16777215.0f;
1145725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
11463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
11473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_format.order == TextureFormat::DS);
11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return *((const float*)pixelPtr);
11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
11518baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			DE_ASSERT(m_format.order == TextureFormat::D); // no other combined depth stencil types
11523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return channelToFloat(pixelPtr, m_format.type);
11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint ConstPixelBufferAccess::getPixStencil (int x, int y, int z) const
11573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(x, 0, getWidth()));
11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(y, 0, getHeight()));
11603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(z, 0, getDepth()));
11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11628baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	const deUint8* const pixelPtr = (const deUint8*)getPixelPtr(x, y, z);
11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
11653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1166725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_24_8_REV:
116700d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::DS);
1168725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			return (int)readUint32High8(pixelPtr);
116900d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos
1170725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_16_8_8:
11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_24_8:
117200d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::DS);
117300d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			return (int)readUint32Low8(pixelPtr);
11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_format.order == TextureFormat::DS);
117774a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi			return (int)readUint32Low8(pixelPtr + 4);
11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11818baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			DE_ASSERT(m_format.order == TextureFormat::S); // no other combined depth stencil types
11828baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			return channelToInt(pixelPtr, m_format.type);
11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PixelBufferAccess::setPixel (const Vec4& color, int x, int y, int z) const
11883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(x, 0, getWidth()));
11903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(y, 0, getHeight()));
11913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(z, 0, getDepth()));
11928baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	DE_ASSERT(!isCombinedDepthStencilType(m_format.type)); // combined types cannot be accessed directly
11938baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	DE_ASSERT(m_format.order != TextureFormat::DS); // combined formats cannot be accessed directly
11943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11958baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	deUint8* const pixelPtr = (deUint8*)getPixelPtr(x, y, z);
119629340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Optimized fomats.
11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_format.type == TextureFormat::UNORM_INT8)
11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12000158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		if (m_format.order == TextureFormat::RGBA || m_format.order == TextureFormat::sRGBA)
12013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
120229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi			writeRGBA8888Float(pixelPtr, color);
12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return;
12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12050158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		else if (m_format.order == TextureFormat::RGB || m_format.order == TextureFormat::sRGB)
12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
120729340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi			writeRGB888Float(pixelPtr, color);
12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return;
12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1212725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define PN(VAL, OFFS, BITS)		(unormFloatToChannel((VAL), (BITS)) << (OFFS))
1213725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define PS(VAL, OFFS, BITS)		(snormFloatToChannel((VAL), (BITS)) << (OFFS))
12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define PU(VAL, OFFS, BITS)		(uintToChannel((VAL), (BITS)) << (OFFS))
1215725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define PI(VAL, OFFS, BITS)		(intToChannel((VAL), (BITS)) << (OFFS))
12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
12183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1219725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_BYTE_44:		*((deUint8 *)pixelPtr) = (deUint8)(PN(color[0], 4, 4) | PN(color[1], 0, 4));						break;
1220725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_BYTE_44:	*((deUint8 *)pixelPtr) = (deUint8)(PU((deUint32)color[0], 4, 4) | PU((deUint32)color[1], 0, 4));	break;
1221725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_INT_101010:	*((deUint32*)pixelPtr) = PN(color[0], 22, 10) | PN(color[1], 12, 10) | PN(color[2], 2, 10);			break;
1222725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1223725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_565:
1224725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
12255b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			const Vec4 swizzled = swizzleRB(color, TextureFormat::RGB, m_format.order);
1226725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PN(swizzled[0], 11, 5) | PN(swizzled[1], 5, 6) | PN(swizzled[2], 0, 5));
1227725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1228725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1229725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1230725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_565:
1231725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
12325b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			const UVec4 swizzled = swizzleRB(color.cast<deUint32>(), TextureFormat::RGB, m_format.order);
1233725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PU(swizzled[0], 11, 5) | PU(swizzled[1], 5, 6) | PU(swizzled[2], 0, 5));
1234725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1235725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1236725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1237725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_555:
1238725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
12395b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			const Vec4 swizzled = swizzleRB(color, TextureFormat::RGB, m_format.order);
1240725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PN(swizzled[0], 10, 5) | PN(swizzled[1], 5, 5) | PN(swizzled[2], 0, 5));
1241725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1242725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1243725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1244725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_4444:
1245725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
12465b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			const Vec4 swizzled = swizzleRB(color, TextureFormat::RGBA, m_format.order);
1247725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PN(swizzled[0], 12, 4) | PN(swizzled[1], 8, 4) | PN(swizzled[2], 4, 4) | PN(swizzled[3], 0, 4));
1248725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1249725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1250725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1251725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_4444:
1252725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
12535b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			const UVec4 swizzled = swizzleRB(color.cast<deUint32>(), TextureFormat::RGBA, m_format.order);
1254725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PU(swizzled[0], 12, 4) | PU(swizzled[1], 8, 4) | PU(swizzled[2], 4, 4) | PU(swizzled[3], 0, 4));
1255725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1256725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1257725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1258725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_5551:
1259725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
12605b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			const Vec4 swizzled = swizzleRB(color, TextureFormat::RGBA, m_format.order);
1261725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PN(swizzled[0], 11, 5) | PN(swizzled[1], 6, 5) | PN(swizzled[2], 1, 5) | PN(swizzled[3], 0, 1));
1262725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1263725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1264725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
12655b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos		case TextureFormat::UNORM_SHORT_1555:
12665b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos		{
12675b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			const Vec4 swizzled = color.swizzle(3,0,1,2); // RGBA -> ARGB
12685b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PN(swizzled[0], 15, 1) | PN(swizzled[1], 10, 5) | PN(swizzled[2], 5, 5) | PN(swizzled[3], 0, 5));
12695b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			break;
12705b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos		}
12715b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos
1272725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_5551:
1273725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
12745b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			const UVec4 swizzled = swizzleRB(color.cast<deUint32>(), TextureFormat::RGBA, m_format.order);
1275725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PU(swizzled[0], 11, 5) | PU(swizzled[1], 6, 5) | PU(swizzled[2], 1, 5) | PU(swizzled[3], 0, 1));
1276725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1277725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1278725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1279725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_INT_1010102_REV:
1280725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
12815b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			const Vec4 u = swizzleRB(color, TextureFormat::RGBA, m_format.order);
1282725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint32*)pixelPtr) = PN(u[0], 0, 10) | PN(u[1], 10, 10) | PN(u[2], 20, 10) | PN(u[3], 30, 2);
1283725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1284725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1285725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1286725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::SNORM_INT_1010102_REV:
1287725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
12885b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			const Vec4 u = swizzleRB(color, TextureFormat::RGBA, m_format.order);
1289725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint32*)pixelPtr) = PS(u[0], 0, 10) | PS(u[1], 10, 10) | PS(u[2], 20, 10) | PS(u[3], 30, 2);
1290725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1291725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
12923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_1010102_REV:
12943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12955b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			const UVec4 u = swizzleRB(color.cast<deUint32>(), TextureFormat::RGBA, m_format.order);
1296725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint32*)pixelPtr) = PU(u[0], 0, 10) | PU(u[1], 10, 10) | PU(u[2], 20, 10) | PU(u[3], 30, 2);
1297725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1298725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1299725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1300725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::SIGNED_INT_1010102_REV:
1301725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
13025b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			const IVec4 u = swizzleRB(color.cast<deInt32>(), TextureFormat::RGBA, m_format.order);
1303725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint32*)pixelPtr) = PI(u[0], 0, 10) | PI(u[1], 10, 10) | PI(u[2], 20, 10) | PI(u[3], 30, 2);
13043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
13053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
13083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			*((deUint32*)pixelPtr) = Float11(color[0]).bits() | (Float11(color[1]).bits() << 11) | (Float10(color[2]).bits() << 22);
13093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
13103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_999_E5_REV:
13123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			*((deUint32*)pixelPtr) = packRGB999E5(color);
13133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
13143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
13163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Generic path.
13186d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			int								numChannels	= getNumUsedChannels(m_format.order);
13196d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			const TextureSwizzle::Channel*	map			= getChannelWriteSwizzle(m_format.order).components;
13206d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			int								channelSize	= getChannelSize(m_format.type);
13213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int c = 0; c < numChannels; c++)
13236d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			{
13246d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				DE_ASSERT(deInRange32(map[c], TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3));
13253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				floatToChannel(pixelPtr + channelSize*c, color[map[c]], m_format.type);
13266d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			}
13273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
13283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef PN
1332725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef PS
13333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef PU
1334725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef PI
13353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PixelBufferAccess::setPixel (const IVec4& color, int x, int y, int z) const
13383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(x, 0, getWidth()));
13403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(y, 0, getHeight()));
13413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(z, 0, getDepth()));
13428baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	DE_ASSERT(!isCombinedDepthStencilType(m_format.type)); // combined types cannot be accessed directly
13438baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	DE_ASSERT(m_format.order != TextureFormat::DS); // combined formats cannot be accessed directly
13443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13458baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	deUint8* const pixelPtr = (deUint8*)getPixelPtr(x, y, z);
13463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Optimized fomats.
13483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_format.type == TextureFormat::UNORM_INT8)
13493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13500158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		if (m_format.order == TextureFormat::RGBA || m_format.order == TextureFormat::sRGBA)
13510158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		{
13520158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi			writeRGBA8888Int(pixelPtr, color);
13530158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi			return;
13540158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		}
13550158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		else if (m_format.order == TextureFormat::RGB || m_format.order == TextureFormat::sRGB)
13560158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		{
13570158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi			writeRGB888Int(pixelPtr, color);
13580158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi			return;
13590158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		}
13603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define PU(VAL, OFFS, BITS)		(uintToChannel((deUint32)(VAL), (BITS)) << (OFFS))
1363725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define PI(VAL, OFFS, BITS)		(intToChannel((deUint32)(VAL), (BITS)) << (OFFS))
13643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
13663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1367725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_BYTE_44:	// Fall-through
1368725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_BYTE_44:		*((deUint8 *)pixelPtr) = (deUint8 )(PU(color[0],  4, 4) | PU(color[1], 0, 4));				break;
1369725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_INT_101010:	*((deUint32*)pixelPtr) = PU(color[0], 22, 10) | PU(color[1], 12, 10) | PU(color[2], 2, 10);	break;
1370725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1371725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_565:
1372725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_565:
1373725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
13745b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			const IVec4 swizzled = swizzleRB(color, TextureFormat::RGB, m_format.order);
1375725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PU(swizzled[0], 11, 5) | PU(swizzled[1], 5, 6) | PU(swizzled[2], 0, 5));
1376725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1377725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1378725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1379725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_555:
1380725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
13815b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			const IVec4 swizzled = swizzleRB(color, TextureFormat::RGB, m_format.order);
1382725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PU(swizzled[0], 10, 5) | PU(swizzled[1], 5, 5) | PU(swizzled[2], 0, 5));
1383725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1384725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1385725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1386725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_4444:
1387725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_4444:
1388725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
13895b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			const IVec4 swizzled = swizzleRB(color, TextureFormat::RGBA, m_format.order);
1390725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PU(swizzled[0], 12, 4) | PU(swizzled[1], 8, 4) | PU(swizzled[2], 4, 4) | PU(swizzled[3], 0, 4));
1391725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1392725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1393725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1394725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_5551:
1395725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_5551:
1396725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
13975b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			const IVec4 swizzled = swizzleRB(color, TextureFormat::RGBA, m_format.order);
1398725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PU(swizzled[0], 11, 5) | PU(swizzled[1], 6, 5) | PU(swizzled[2], 1, 5) | PU(swizzled[3], 0, 1));
1399725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1400725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1401725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
14025b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos		case TextureFormat::UNORM_SHORT_1555:
14035b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos		{
14045b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			const IVec4 swizzled = color.swizzle(3,0,1,2); // RGBA -> ARGB
14055b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PU(swizzled[0], 15, 1) | PU(swizzled[1], 10, 5) | PU(swizzled[2], 5, 5) | PU(swizzled[3], 0, 5));
14065b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			break;
14075b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos		}
14085b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos
1409725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_INT_1010102_REV:
1410725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_1010102_REV:
1411725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
14125b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			const IVec4 swizzled = swizzleRB(color, TextureFormat::RGBA, m_format.order);
1413725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint32*)pixelPtr) = PU(swizzled[0],  0, 10) | PU(swizzled[1], 10, 10) | PU(swizzled[2], 20, 10) | PU(swizzled[3], 30, 2);
1414725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1415725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1416725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1417725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::SNORM_INT_1010102_REV:
1418725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::SIGNED_INT_1010102_REV:
1419725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
14205b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			const IVec4 swizzled = swizzleRB(color, TextureFormat::RGBA, m_format.order);
1421725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint32*)pixelPtr) = PI(swizzled[0],  0, 10) | PI(swizzled[1], 10, 10) | PI(swizzled[2], 20, 10) | PI(swizzled[3], 30, 2);
1422725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1423725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
14243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
14263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Generic path.
14286d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			int								numChannels	= getNumUsedChannels(m_format.order);
14296d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			const TextureSwizzle::Channel*	map			= getChannelWriteSwizzle(m_format.order).components;
14306d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			int								channelSize	= getChannelSize(m_format.type);
14313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int c = 0; c < numChannels; c++)
14336d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			{
14346d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				DE_ASSERT(deInRange32(map[c], TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3));
14353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				intToChannel(pixelPtr + channelSize*c, color[map[c]], m_format.type);
14366d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			}
14373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
14383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef PU
1442725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef PI
14433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14453c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PixelBufferAccess::setPixDepth (float depth, int x, int y, int z) const
14463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(x, 0, getWidth()));
14483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(y, 0, getHeight()));
14493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(z, 0, getDepth()));
14503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14518baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	deUint8* const pixelPtr = (deUint8*)getPixelPtr(x, y, z);
14523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
14543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1455725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_16_8_8:
145600d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::DS);
1457725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			writeUint32High16(pixelPtr, convertSatRte<deUint16>(depth * 65535.0f));
145800d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			break;
145974a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi
146000d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos		case TextureFormat::UNSIGNED_INT_24_8:
1461725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::D || m_format.order == TextureFormat::DS);
146200d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			writeUint32High24(pixelPtr,  convertSatRteUint24(depth * 16777215.0f));
14633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
14643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1465725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_24_8_REV:
1466725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::D || m_format.order == TextureFormat::DS);
1467725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			writeUint32Low24(pixelPtr,  convertSatRteUint24(depth * 16777215.0f));
1468725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1469725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
14703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
14713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_format.order == TextureFormat::DS);
14723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			*((float*)pixelPtr) = depth;
14733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
14743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
14768baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			DE_ASSERT(m_format.order == TextureFormat::D); // no other combined depth stencil types
14773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			floatToChannel(pixelPtr, depth, m_format.type);
14783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
14793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14823c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PixelBufferAccess::setPixStencil (int stencil, int x, int y, int z) const
14833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(x, 0, getWidth()));
14853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(y, 0, getHeight()));
14863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(z, 0, getDepth()));
14873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14888baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	deUint8* const pixelPtr = (deUint8*)getPixelPtr(x, y, z);
14893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
14913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1492725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_16_8_8:
14933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_24_8:
149400d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::DS);
149500d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			writeUint32Low8(pixelPtr, convertSat<deUint8>((deUint32)stencil));
149600d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			break;
149774a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi
1498725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_24_8_REV:
149900d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::DS);
1500725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			writeUint32High8(pixelPtr, convertSat<deUint8>((deUint32)stencil));
15013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
15023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
15043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_format.order == TextureFormat::DS);
150574a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi			writeUint32Low8(pixelPtr + 4, convertSat<deUint8>((deUint32)stencil));
15063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
15073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
15098baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			DE_ASSERT(m_format.order == TextureFormat::S);  // no other combined depth stencil types
15108baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			intToChannel(pixelPtr, stencil, m_format.type);
15113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
15123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15153c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline int imod (int a, int b)
15163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int m = a % b;
15183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m < 0 ? m + b : m;
15193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15213c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline int mirror (int a)
15223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return a >= 0.0f ? a : -(1 + a);
15243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Nearest-even rounding in case of tie (fractional part 0.5), otherwise ordinary rounding.
15273c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline float rint (float a)
15283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_STATIC_ASSERT((-3 % 2 != 0) && (-4 % 2 == 0));
15303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		fracVal		= deFloatFrac(a);
15323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (fracVal != 0.5f)
15343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return deFloatRound(a); // Ordinary case.
15353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float	floorVal	= a - fracVal;
15373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool	roundUp		= (deInt64)floorVal % 2 != 0;
15383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return floorVal + (roundUp ? 1.0f : 0.0f);
15403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15423c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline int wrap (Sampler::WrapMode mode, int c, int size)
15433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (mode)
15453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::CLAMP_TO_BORDER:
15473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return deClamp32(c, -1, size);
15483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::CLAMP_TO_EDGE:
15503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return deClamp32(c, 0, size-1);
15513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::REPEAT_GL:
15533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return imod(c, size);
15543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::REPEAT_CL:
15563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return imod(c, size);
15573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
155873fd35f3b995f065863c495364f03a52699c2d4aPyry Haulos		case tcu::Sampler::MIRRORED_ONCE:
155973fd35f3b995f065863c495364f03a52699c2d4aPyry Haulos			c = deClamp32(c, -size, size);
156073fd35f3b995f065863c495364f03a52699c2d4aPyry Haulos			// Fall-through
156173fd35f3b995f065863c495364f03a52699c2d4aPyry Haulos
15623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::MIRRORED_REPEAT_GL:
15633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return (size - 1) - mirror(imod(c, 2*size) - size);
15643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::MIRRORED_REPEAT_CL:
15663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return deClamp32(c, 0, size-1); // \note Actual mirroring done already in unnormalization function.
15673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
15693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
15703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0;
15713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Special unnormalization for REPEAT_CL and MIRRORED_REPEAT_CL wrap modes; otherwise ordinary unnormalization.
15753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline float unnormalize (Sampler::WrapMode mode, float c, int size)
15763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (mode)
15783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::CLAMP_TO_EDGE:
15803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::CLAMP_TO_BORDER:
15813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::REPEAT_GL:
158273fd35f3b995f065863c495364f03a52699c2d4aPyry Haulos		case tcu::Sampler::MIRRORED_REPEAT_GL:
158373fd35f3b995f065863c495364f03a52699c2d4aPyry Haulos		case tcu::Sampler::MIRRORED_ONCE:		// Fall-through (ordinary case).
15843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return (float)size*c;
15853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::REPEAT_CL:
15873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return (float)size * (c - deFloatFloor(c));
15883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::MIRRORED_REPEAT_CL:
15903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return (float)size * deFloatAbs(c - 2.0f * rint(0.5f * c));
15913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
15933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
15943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
15953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15983c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isFixedPointDepthTextureFormat (const tcu::TextureFormat& format)
15993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16008baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	DE_ASSERT(format.order == TextureFormat::D);
16013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16028baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
16038baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	if (channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
16048baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry		return false;
16058baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	else if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
16068baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry		return true;
16078baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	else
16083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16098baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry		DE_ASSERT(false);
16108baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry		return false;
16113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texel lookup with color conversion.
16153c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline Vec4 lookup (const ConstPixelBufferAccess& access, int i, int j, int k)
16163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1617a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi	const TextureFormat&	format	= access.getFormat();
1618a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi
1619a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi	if (isSRGB(format))
1620a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi	{
1621a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi		if (format.type == TextureFormat::UNORM_INT8 && format.order == TextureFormat::sRGB)
1622a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi				return sRGB8ToLinear(access.getPixelUint(i, j, k));
1623a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi		else if (format.type == TextureFormat::UNORM_INT8 && format.order == TextureFormat::sRGBA)
1624a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi				return sRGBA8ToLinear(access.getPixelUint(i, j, k));
1625a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi		else
1626a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi			return sRGBToLinear(access.getPixel(i, j, k));
1627a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi	}
1628a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi	else
1629a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi	{
1630a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi		return access.getPixel(i, j, k);
1631a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi	}
16323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1634222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry// Border texel lookup with color conversion.
163522941823a995126908aae341c87f2def77514ee7Jarkko Pöyrystatic inline Vec4 lookupBorder (const tcu::TextureFormat& format, const tcu::Sampler& sampler)
163622941823a995126908aae341c87f2def77514ee7Jarkko Pöyry{
1637222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	// "lookup" for a combined format does not make sense, disallow
1638222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	DE_ASSERT(!isCombinedDepthStencilType(format.type));
1639222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry
1640222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	const tcu::TextureChannelClass	channelClass 			= tcu::getTextureChannelClass(format.type);
1641222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	const bool						isFloat					= channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT;
1642222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	const bool						isFixed					= channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT ||
1643222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry															  channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT;
1644222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	const bool						isPureInteger			= channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER;
1645222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	const bool						isPureUnsignedInteger	= channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
1646222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry
1647222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	if (isFloat || isFixed)
1648d5be8ad612a000b4ad2caf14c8d93501f3558eb8Jarkko Pöyry		return sampleTextureBorder<float>(format, sampler);
1649222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	else if (isPureInteger)
1650222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry		return sampleTextureBorder<deInt32>(format, sampler).cast<float>();
1651222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	else if (isPureUnsignedInteger)
1652222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry		return sampleTextureBorder<deUint32>(format, sampler).cast<float>();
1653222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	else
1654222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	{
1655222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry		DE_ASSERT(false);
1656222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry		return Vec4(-1.0);
1657222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	}
165822941823a995126908aae341c87f2def77514ee7Jarkko Pöyry}
165922941823a995126908aae341c87f2def77514ee7Jarkko Pöyry
16603c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline float execCompare (const tcu::Vec4& color, Sampler::CompareMode compare, int chanNdx, float ref_, bool isFixedPoint)
16613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool	clampValues	= isFixedPoint;	// if comparing against a floating point texture, ref (and value) is not clamped
16633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	cmp			= (clampValues) ? (de::clamp(color[chanNdx], 0.0f, 1.0f)) : (color[chanNdx]);
16643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	ref			= (clampValues) ? (de::clamp(ref_, 0.0f, 1.0f)) : (ref_);
16653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		res			= false;
16663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (compare)
16683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_LESS:				res = ref < cmp;	break;
16703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_LESS_OR_EQUAL:	res = ref <= cmp;	break;
16713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_GREATER:			res = ref > cmp;	break;
16723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_GREATER_OR_EQUAL:	res = ref >= cmp;	break;
16733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_EQUAL:			res = ref == cmp;	break;
16743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_NOT_EQUAL:		res = ref != cmp;	break;
16753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_ALWAYS:			res = true;			break;
16763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_NEVER:			res = false;		break;
16773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
16783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
16793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return res ? 1.0f : 0.0f;
16823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16843c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleNearest1D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, const IVec2& offset)
16853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int width	= access.getWidth();
16873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x = deFloorFloatToInt32(u)+offset.x();
16893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check for CLAMP_TO_BORDER.
16913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.wrapS == Sampler::CLAMP_TO_BORDER && !deInBounds32(x, 0, width))
169222941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		return lookupBorder(access.getFormat(), sampler);
16933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i = wrap(sampler.wrapS, x, width);
16953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return lookup(access, i, offset.y(), 0);
16973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16993c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleNearest2D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, float v, const IVec3& offset)
17003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int width	= access.getWidth();
17023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int height	= access.getHeight();
17033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x = deFloorFloatToInt32(u)+offset.x();
17053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y = deFloorFloatToInt32(v)+offset.y();
17063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check for CLAMP_TO_BORDER.
17083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if ((sampler.wrapS == Sampler::CLAMP_TO_BORDER && !deInBounds32(x, 0, width)) ||
17093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		(sampler.wrapT == Sampler::CLAMP_TO_BORDER && !deInBounds32(y, 0, height)))
171022941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		return lookupBorder(access.getFormat(), sampler);
17113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i = wrap(sampler.wrapS, x, width);
17133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j = wrap(sampler.wrapT, y, height);
17143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return lookup(access, i, j, offset.z());
17163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17183c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleNearest3D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, float v, float w, const IVec3& offset)
17193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int width	= access.getWidth();
17213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int height	= access.getHeight();
17223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int depth	= access.getDepth();
17233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x = deFloorFloatToInt32(u)+offset.x();
17253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y = deFloorFloatToInt32(v)+offset.y();
17263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int z = deFloorFloatToInt32(w)+offset.z();
17273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check for CLAMP_TO_BORDER.
17293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if ((sampler.wrapS == Sampler::CLAMP_TO_BORDER && !deInBounds32(x, 0, width))	||
17303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		(sampler.wrapT == Sampler::CLAMP_TO_BORDER && !deInBounds32(y, 0, height))	||
17313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		(sampler.wrapR == Sampler::CLAMP_TO_BORDER && !deInBounds32(z, 0, depth)))
173222941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		return lookupBorder(access.getFormat(), sampler);
17333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i = wrap(sampler.wrapS, x, width);
17353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j = wrap(sampler.wrapT, y, height);
17363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int k = wrap(sampler.wrapR, z, depth);
17373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return lookup(access, i, j, k);
17393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17413c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleLinear1D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, const IVec2& offset)
17423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int w = access.getWidth();
17443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x0 = deFloorFloatToInt32(u-0.5f)+offset.x();
17463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x1 = x0+1;
17473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i0 = wrap(sampler.wrapS, x0, w);
17493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i1 = wrap(sampler.wrapS, x1, w);
17503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
17523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i0UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i0, 0, w);
17543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i1UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i1, 0, w);
17553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Border color for out-of-range coordinates if using CLAMP_TO_BORDER, otherwise execute lookups.
175722941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p0 = i0UseBorder ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, offset.y(), 0);
175822941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p1 = i1UseBorder ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, offset.y(), 0);
17593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
17613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return p0 * (1.0f - a) + p1 * a;
17623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17643c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleLinear2D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, float v, const IVec3& offset)
17653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int w = access.getWidth();
17673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int h = access.getHeight();
17683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x0 = deFloorFloatToInt32(u-0.5f)+offset.x();
17703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x1 = x0+1;
17713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y0 = deFloorFloatToInt32(v-0.5f)+offset.y();
17723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y1 = y0+1;
17733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i0 = wrap(sampler.wrapS, x0, w);
17753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i1 = wrap(sampler.wrapS, x1, w);
17763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j0 = wrap(sampler.wrapT, y0, h);
17773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j1 = wrap(sampler.wrapT, y1, h);
17783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
17803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float b = deFloatFrac(v-0.5f);
17813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i0UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i0, 0, w);
17833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i1UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i1, 0, w);
17843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool j0UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j0, 0, h);
17853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool j1UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j1, 0, h);
17863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Border color for out-of-range coordinates if using CLAMP_TO_BORDER, otherwise execute lookups.
178822941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p00 = (i0UseBorder || j0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j0, offset.z());
178922941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p10 = (i1UseBorder || j0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j0, offset.z());
179022941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p01 = (i0UseBorder || j1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j1, offset.z());
179122941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p11 = (i1UseBorder || j1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j1, offset.z());
17923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
17943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (p00*(1.0f-a)*(1.0f-b)) +
17953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p10*(     a)*(1.0f-b)) +
17963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p01*(1.0f-a)*(     b)) +
17973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p11*(     a)*(     b));
17983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18003c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float sampleLinear1DCompare (const ConstPixelBufferAccess& access, const Sampler& sampler, float ref, float u, const IVec2& offset, bool isFixedPointDepthFormat)
18013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int w = access.getWidth();
18033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x0 = deFloorFloatToInt32(u-0.5f)+offset.x();
18053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x1 = x0+1;
18063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i0 = wrap(sampler.wrapS, x0, w);
18083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i1 = wrap(sampler.wrapS, x1, w);
18093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
18113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i0UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i0, 0, w);
18133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i1UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i1, 0, w);
18143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Border color for out-of-range coordinates if using CLAMP_TO_BORDER, otherwise execute lookups.
181622941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p0Clr = i0UseBorder  ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, offset.y(), 0);
181722941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p1Clr = i1UseBorder  ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, offset.y(), 0);
18183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Execute comparisons.
18203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float p0 = execCompare(p0Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat);
18213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float p1 = execCompare(p1Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat);
18223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
18243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (p0 * (1.0f - a)) + (p1 * a);
18253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18273c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float sampleLinear2DCompare (const ConstPixelBufferAccess& access, const Sampler& sampler, float ref, float u, float v, const IVec3& offset, bool isFixedPointDepthFormat)
18283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int w = access.getWidth();
18303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int h = access.getHeight();
18313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x0 = deFloorFloatToInt32(u-0.5f)+offset.x();
18333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x1 = x0+1;
18343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y0 = deFloorFloatToInt32(v-0.5f)+offset.y();
18353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y1 = y0+1;
18363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i0 = wrap(sampler.wrapS, x0, w);
18383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i1 = wrap(sampler.wrapS, x1, w);
18393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j0 = wrap(sampler.wrapT, y0, h);
18403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j1 = wrap(sampler.wrapT, y1, h);
18413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
18433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float b = deFloatFrac(v-0.5f);
18443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i0UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i0, 0, w);
18463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i1UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i1, 0, w);
18473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool j0UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j0, 0, h);
18483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool j1UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j1, 0, h);
18493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Border color for out-of-range coordinates if using CLAMP_TO_BORDER, otherwise execute lookups.
185122941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p00Clr = (i0UseBorder || j0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j0, offset.z());
185222941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p10Clr = (i1UseBorder || j0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j0, offset.z());
185322941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p01Clr = (i0UseBorder || j1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j1, offset.z());
185422941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p11Clr = (i1UseBorder || j1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j1, offset.z());
18553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Execute comparisons.
18573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float p00 = execCompare(p00Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat);
18583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float p10 = execCompare(p10Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat);
18593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float p01 = execCompare(p01Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat);
18603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float p11 = execCompare(p11Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat);
18613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
18633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (p00*(1.0f-a)*(1.0f-b)) +
18643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p10*(     a)*(1.0f-b)) +
18653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p01*(1.0f-a)*(     b)) +
18663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p11*(     a)*(     b));
18673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18693c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleLinear3D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, float v, float w, const IVec3& offset)
18703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int width	= access.getWidth();
18723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int height	= access.getHeight();
18733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int depth	= access.getDepth();
18743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x0 = deFloorFloatToInt32(u-0.5f)+offset.x();
18763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x1 = x0+1;
18773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y0 = deFloorFloatToInt32(v-0.5f)+offset.y();
18783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y1 = y0+1;
18793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int z0 = deFloorFloatToInt32(w-0.5f)+offset.z();
18803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int z1 = z0+1;
18813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i0 = wrap(sampler.wrapS, x0, width);
18833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i1 = wrap(sampler.wrapS, x1, width);
18843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j0 = wrap(sampler.wrapT, y0, height);
18853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j1 = wrap(sampler.wrapT, y1, height);
18863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int k0 = wrap(sampler.wrapR, z0, depth);
18873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int k1 = wrap(sampler.wrapR, z1, depth);
18883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
18903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float b = deFloatFrac(v-0.5f);
18913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float c = deFloatFrac(w-0.5f);
18923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i0UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i0, 0, width);
18943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i1UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i1, 0, width);
18953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool j0UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j0, 0, height);
18963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool j1UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j1, 0, height);
18973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool k0UseBorder = sampler.wrapR == Sampler::CLAMP_TO_BORDER && !de::inBounds(k0, 0, depth);
18983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool k1UseBorder = sampler.wrapR == Sampler::CLAMP_TO_BORDER && !de::inBounds(k1, 0, depth);
18993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Border color for out-of-range coordinates if using CLAMP_TO_BORDER, otherwise execute lookups.
190122941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p000 = (i0UseBorder || j0UseBorder || k0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j0, k0);
190222941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p100 = (i1UseBorder || j0UseBorder || k0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j0, k0);
190322941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p010 = (i0UseBorder || j1UseBorder || k0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j1, k0);
190422941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p110 = (i1UseBorder || j1UseBorder || k0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j1, k0);
190522941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p001 = (i0UseBorder || j0UseBorder || k1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j0, k1);
190622941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p101 = (i1UseBorder || j0UseBorder || k1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j0, k1);
190722941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p011 = (i0UseBorder || j1UseBorder || k1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j1, k1);
190822941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p111 = (i1UseBorder || j1UseBorder || k1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j1, k1);
19093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
19113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (p000*(1.0f-a)*(1.0f-b)*(1.0f-c)) +
19123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p100*(     a)*(1.0f-b)*(1.0f-c)) +
19133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p010*(1.0f-a)*(     b)*(1.0f-c)) +
19143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p110*(     a)*(     b)*(1.0f-c)) +
19153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p001*(1.0f-a)*(1.0f-b)*(     c)) +
19163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p101*(     a)*(1.0f-b)*(     c)) +
19173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p011*(1.0f-a)*(     b)*(     c)) +
19183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p111*(     a)*(     b)*(     c));
19193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19213c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 ConstPixelBufferAccess::sample1D (const Sampler& sampler, Sampler::FilterMode filter, float s, int level) const
19223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1923612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// check selected layer exists
192429340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(level, 0, m_size.y()));
19253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1926612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	return sample1DOffset(sampler, filter, s, tcu::IVec2(0, level));
19273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19293c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 ConstPixelBufferAccess::sample2D (const Sampler& sampler, Sampler::FilterMode filter, float s, float t, int depth) const
19303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1931612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// check selected layer exists
193229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(depth, 0, m_size.z()));
19333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1934612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	return sample2DOffset(sampler, filter, s, t, tcu::IVec3(0, 0, depth));
1935612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry}
19363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1937612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko PöyryVec4 ConstPixelBufferAccess::sample3D (const Sampler& sampler, Sampler::FilterMode filter, float s, float t, float r) const
1938612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry{
1939612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	return sample3DOffset(sampler, filter, s, t, r, tcu::IVec3(0, 0, 0));
19403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19423c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 ConstPixelBufferAccess::sample1DOffset (const Sampler& sampler, Sampler::FilterMode filter, float s, const IVec2& offset) const
19433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1944612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// check selected layer exists
1945612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// \note offset.x is X offset, offset.y is the selected layer
1946612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	DE_ASSERT(de::inBounds(offset.y(), 0, m_size.y()));
19473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
19493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float u = s;
19503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
195229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		u = unnormalize(sampler.wrapS, s, m_size.x());
19533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filter)
19553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return sampleNearest1D	(*this, sampler, u, offset);
19573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return sampleLinear1D	(*this, sampler, u, offset);
19583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
19593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
19603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
19613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19643c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 ConstPixelBufferAccess::sample2DOffset (const Sampler& sampler, Sampler::FilterMode filter, float s, float t, const IVec3& offset) const
19653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1966612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// check selected layer exists
1967612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// \note offset.xy is the XY offset, offset.z is the selected layer
196829340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(offset.z(), 0, m_size.z()));
19693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
19713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float u = s;
19723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float v = t;
19733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
19753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
197629340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		u = unnormalize(sampler.wrapS, s, m_size.x());
197729340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		v = unnormalize(sampler.wrapT, t, m_size.y());
19783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filter)
19813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return sampleNearest2D	(*this, sampler, u, v, offset);
19833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return sampleLinear2D	(*this, sampler, u, v, offset);
19843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
19853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
19863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
19873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1990612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko PöyryVec4 ConstPixelBufferAccess::sample3DOffset (const Sampler& sampler, Sampler::FilterMode filter, float s, float t, float r, const IVec3& offset) const
19913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
19933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float u = s;
1994612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	float v = t;
1995612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	float w = r;
19963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
1998612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	{
199929340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		u = unnormalize(sampler.wrapS, s, m_size.x());
2000612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		v = unnormalize(sampler.wrapT, t, m_size.y());
2001612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		w = unnormalize(sampler.wrapR, r, m_size.z());
2002612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	}
20033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filter)
20053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2006612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		case Sampler::NEAREST:	return sampleNearest3D	(*this, sampler, u, v, w, offset);
2007612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		case Sampler::LINEAR:	return sampleLinear3D	(*this, sampler, u, v, w, offset);
20083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
20093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
2010612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry			return Vec4(0.0f);
20113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2014612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyryfloat ConstPixelBufferAccess::sample1DCompare (const Sampler& sampler, Sampler::FilterMode filter, float ref, float s, const IVec2& offset) const
20153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2016612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// check selected layer exists
2017612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// \note offset.x is X offset, offset.y is the selected layer
2018612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	DE_ASSERT(de::inBounds(offset.y(), 0, m_size.y()));
20193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Format information for comparison function
20213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool isFixedPointDepth = isFixedPointDepthTextureFormat(m_format);
20223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
20243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float u = s;
20253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
202729340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		u = unnormalize(sampler.wrapS, s, m_size.x());
20283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filter)
20303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2031612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		case Sampler::NEAREST:	return execCompare(sampleNearest1D(*this, sampler, u, offset), sampler.compare, sampler.compareChannel, ref, isFixedPointDepth);
2032612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		case Sampler::LINEAR:	return sampleLinear1DCompare(*this, sampler, ref, u, offset, isFixedPointDepth);
20333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
20343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
20353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
20363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2039612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyryfloat ConstPixelBufferAccess::sample2DCompare (const Sampler& sampler, Sampler::FilterMode filter, float ref, float s, float t, const IVec3& offset) const
20403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2041612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// check selected layer exists
2042612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// \note offset.xy is XY offset, offset.z is the selected layer
2043612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	DE_ASSERT(de::inBounds(offset.z(), 0, m_size.z()));
20443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2045612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// Format information for comparison function
2046612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	const bool isFixedPointDepth = isFixedPointDepthTextureFormat(m_format);
20473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
20493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float u = s;
20503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float v = t;
20513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
20533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
205429340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		u = unnormalize(sampler.wrapS, s, m_size.x());
205529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		v = unnormalize(sampler.wrapT, t, m_size.y());
20563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filter)
20593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2060612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		case Sampler::NEAREST:	return execCompare(sampleNearest2D(*this, sampler, u, v, offset), sampler.compare, sampler.compareChannel, ref, isFixedPointDepth);
2061612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		case Sampler::LINEAR:	return sampleLinear2DCompare(*this, sampler, ref, u, v, offset, isFixedPointDepth);
20623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
20633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
2064612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry			return 0.0f;
20653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20683c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevel::TextureLevel (void)
20693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	()
207029340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size	(0)
20713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20743c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevel::TextureLevel (const TextureFormat& format)
20753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	(format)
207629340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size	(0)
20773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20803c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevel::TextureLevel (const TextureFormat& format, int width, int height, int depth)
20813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	(format)
208229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size	(0)
20833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	setSize(width, height, depth);
20853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20873c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevel::~TextureLevel (void)
20883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20913c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureLevel::setStorage (const TextureFormat& format, int width, int height, int depth)
20923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_format = format;
20943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	setSize(width, height, depth);
20953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20973c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureLevel::setSize (int width, int height, int depth)
20983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int pixelSize = m_format.getPixelSize();
21003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
210129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	m_size = IVec3(width, height, depth);
21023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
210329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	m_data.setStorage(m_size.x() * m_size.y() * m_size.z() * pixelSize);
21043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
21053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21063c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 sampleLevelArray1D (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, int depth, float lod)
21073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
21081d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry	return sampleLevelArray1DOffset(levels, numLevels, sampler, s, lod, IVec2(0, depth)); // y-offset in 1D textures is layer selector
21091d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry}
21103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21111d75d23528999118c1911ed100d1d063b06040daJarkko PöyryVec4 sampleLevelArray2D (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, int depth, float lod)
21121d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry{
21131d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry	return sampleLevelArray2DOffset(levels, numLevels, sampler, s, t, lod, IVec3(0, 0, depth)); // z-offset in 2D textures is layer selector
21141d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry}
21153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21161d75d23528999118c1911ed100d1d063b06040daJarkko PöyryVec4 sampleLevelArray3D (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, float r, float lod)
21171d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry{
21181d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry	return sampleLevelArray3DOffset(levels, numLevels, sampler, s, t, r, lod, IVec3(0, 0, 0));
21193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
21203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21213c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 sampleLevelArray1DOffset (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float lod, const IVec2& offset)
21223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
21233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
21243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
21253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
21273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return levels[0].sample1DOffset(sampler, filterMode, s, offset);
21293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return levels[0].sample1DOffset(sampler, filterMode, s, offset);
21303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
21323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
21333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
21353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
21363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
21373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return levels[level].sample1DOffset(sampler, levelFilter, s, offset);
21393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
21403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
21423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
21433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
21453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
21463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level1		= de::min(maxLevel, level0 + 1);
21473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
21483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				f			= deFloatFrac(lod);
21493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4			t0			= levels[level0].sample1DOffset(sampler, levelFilter, s, offset);
21503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4			t1			= levels[level1].sample1DOffset(sampler, levelFilter, s, offset);
21513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
21533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
21543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
21563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
21573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
21583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
21593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
21603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21613c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 sampleLevelArray2DOffset (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, float lod, const IVec3& offset)
21623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
21633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
21643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
21653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
21673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return levels[0].sample2DOffset(sampler, filterMode, s, t, offset);
21693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return levels[0].sample2DOffset(sampler, filterMode, s, t, offset);
21703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
21723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
21733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
21753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
21763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
21773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return levels[level].sample2DOffset(sampler, levelFilter, s, t, offset);
21793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
21803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
21823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
21833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
21853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
21863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level1		= de::min(maxLevel, level0 + 1);
21873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
21883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				f			= deFloatFrac(lod);
21893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4			t0			= levels[level0].sample2DOffset(sampler, levelFilter, s, t, offset);
21903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4			t1			= levels[level1].sample2DOffset(sampler, levelFilter, s, t, offset);
21913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
21933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
21943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
21963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
21973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
21983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
21993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
22003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22013c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 sampleLevelArray3DOffset (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, float r, float lod, const IVec3& offset)
22023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
22033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
22043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
22053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
22073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
22083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return levels[0].sample3DOffset(sampler, filterMode, s, t, r, offset);
22093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return levels[0].sample3DOffset(sampler, filterMode, s, t, r, offset);
22103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
22123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
22133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
22153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
22163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
22173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return levels[level].sample3DOffset(sampler, levelFilter, s, t, r, offset);
22193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
22223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
22233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
22253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
22263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level1		= de::min(maxLevel, level0 + 1);
22273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
22283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				f			= deFloatFrac(lod);
22293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4			t0			= levels[level0].sample3DOffset(sampler, levelFilter, s, t, r, offset);
22303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4			t1			= levels[level1].sample3DOffset(sampler, levelFilter, s, t, r, offset);
22313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
22333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
22363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
22373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
22383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
22393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
22403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat sampleLevelArray1DCompare (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float ref, float s, float lod, const IVec2& offset)
22423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
22433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
22443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
22453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
22473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
22483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return levels[0].sample1DCompare(sampler, filterMode, ref, s, offset);
22493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return levels[0].sample1DCompare(sampler, filterMode, ref, s, offset);
22503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
22523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
22533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
22553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
22563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
22573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return levels[level].sample1DCompare(sampler, levelFilter, ref, s, offset);
22593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
22623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
22633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
22653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
22663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level1		= de::min(maxLevel, level0 + 1);
22673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
22683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				f			= deFloatFrac(lod);
22693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				t0			= levels[level0].sample1DCompare(sampler, levelFilter, ref, s, offset);
22703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				t1			= levels[level1].sample1DCompare(sampler, levelFilter, ref, s, offset);
22713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
22733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
22763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
22773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
22783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
22793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
22803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22813c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat sampleLevelArray2DCompare (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float ref, float s, float t, float lod, const IVec3& offset)
22823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
22833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
22843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
22853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
22873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
22883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return levels[0].sample2DCompare(sampler, filterMode, ref, s, t, offset);
22893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return levels[0].sample2DCompare(sampler, filterMode, ref, s, t, offset);
22903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
22923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
22933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
22953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
22963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
22973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return levels[level].sample2DCompare(sampler, levelFilter, ref, s, t, offset);
22993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
23003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
23023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
23033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
23043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
23053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
23063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level1		= de::min(maxLevel, level0 + 1);
23073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
23083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				f			= deFloatFrac(lod);
23093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				t0			= levels[level0].sample2DCompare(sampler, levelFilter, ref, s, t, offset);
23103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				t1			= levels[level1].sample2DCompare(sampler, levelFilter, ref, s, t, offset);
23113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
23133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
23143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
23163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
23173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
23183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
23193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
232122941823a995126908aae341c87f2def77514ee7Jarkko Pöyrystatic Vec4 fetchGatherArray2DOffsets (const ConstPixelBufferAccess& src, const Sampler& sampler, float s, float t, int depth, int componentNdx, const IVec2 (&offsets)[4])
23223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(componentNdx, 0, 4));
23243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		w	= src.getWidth();
23263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		h	= src.getHeight();
23273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float		u	= unnormalize(sampler.wrapS, s, w);
23283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float		v	= unnormalize(sampler.wrapT, t, h);
23293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		x0	= deFloorFloatToInt32(u-0.5f);
23303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		y0	= deFloorFloatToInt32(v-0.5f);
23313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
233222941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4			result;
23333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
23353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
233622941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		const int	sampleX	= wrap(sampler.wrapS, x0 + offsets[i].x(), w);
233722941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		const int	sampleY	= wrap(sampler.wrapT, y0 + offsets[i].y(), h);
233822941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		Vec4		pixel;
233922941823a995126908aae341c87f2def77514ee7Jarkko Pöyry
234022941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		if (deInBounds32(sampleX, 0, w) && deInBounds32(sampleY, 0, h))
234122941823a995126908aae341c87f2def77514ee7Jarkko Pöyry			pixel = lookup(src, sampleX, sampleY, depth);
234222941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		else
234322941823a995126908aae341c87f2def77514ee7Jarkko Pöyry			pixel = lookupBorder(src.getFormat(), sampler);
234422941823a995126908aae341c87f2def77514ee7Jarkko Pöyry
23453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result[i] = pixel[componentNdx];
23463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
23473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
23493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
235122941823a995126908aae341c87f2def77514ee7Jarkko PöyryVec4 gatherArray2DOffsets (const ConstPixelBufferAccess& src, const Sampler& sampler, float s, float t, int depth, int componentNdx, const IVec2 (&offsets)[4])
235222941823a995126908aae341c87f2def77514ee7Jarkko Pöyry{
235322941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	DE_ASSERT(sampler.compare == Sampler::COMPAREMODE_NONE);
235422941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	DE_ASSERT(de::inBounds(componentNdx, 0, 4));
235522941823a995126908aae341c87f2def77514ee7Jarkko Pöyry
235622941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	return fetchGatherArray2DOffsets(src, sampler, s, t, depth, componentNdx, offsets);
235722941823a995126908aae341c87f2def77514ee7Jarkko Pöyry}
235822941823a995126908aae341c87f2def77514ee7Jarkko Pöyry
23593c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 gatherArray2DOffsetsCompare (const ConstPixelBufferAccess& src, const Sampler& sampler, float ref, float s, float t, int depth, const IVec2 (&offsets)[4])
23603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare != Sampler::COMPAREMODE_NONE);
23623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(src.getFormat().order == TextureFormat::D || src.getFormat().order == TextureFormat::DS);
23633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compareChannel == 0);
23643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2365222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	const bool	isFixedPoint	= isFixedPointDepthTextureFormat(src.getFormat());
2366222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	const Vec4	gathered		= fetchGatherArray2DOffsets(src, sampler, s, t, depth, 0 /* component 0: depth */, offsets);
2367222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	Vec4		result;
23683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
23703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result[i] = execCompare(gathered, sampler.compare, i, ref, isFixedPoint);
23713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
23733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleCubeSeamlessNearest (const ConstPixelBufferAccess& faceAccess, const Sampler& sampler, float s, float t, int depth)
23763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler clampingSampler = sampler;
23783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	clampingSampler.wrapS = Sampler::CLAMP_TO_EDGE;
23793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	clampingSampler.wrapT = Sampler::CLAMP_TO_EDGE;
23803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return faceAccess.sample2D(clampingSampler, Sampler::NEAREST, s, t, depth);
23813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23833c827367444ee418f129b2c238299f49d3264554Jarkko PoyryCubeFace selectCubeFace (const Vec3& coords)
23843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	x	= coords.x();
23863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	y	= coords.y();
23873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	z	= coords.z();
23883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	ax	= deFloatAbs(x);
23893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	ay	= deFloatAbs(y);
23903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	az	= deFloatAbs(z);
23913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (ay < ax && az < ax)
23933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return x >= 0.0f ? CUBEFACE_POSITIVE_X : CUBEFACE_NEGATIVE_X;
23943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (ax < ay && az < ay)
23953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return y >= 0.0f ? CUBEFACE_POSITIVE_Y : CUBEFACE_NEGATIVE_Y;
23963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (ax < az && ay < az)
23973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return z >= 0.0f ? CUBEFACE_POSITIVE_Z : CUBEFACE_NEGATIVE_Z;
23983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
23993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Some of the components are equal. Use tie-breaking rule.
24013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (ax == ay)
24023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
24033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (ax < az)
24043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return z >= 0.0f ? CUBEFACE_POSITIVE_Z : CUBEFACE_NEGATIVE_Z;
24053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
24063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return x >= 0.0f ? CUBEFACE_POSITIVE_X : CUBEFACE_NEGATIVE_X;
24073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
24083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (ax == az)
24093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
24103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (az < ay)
24113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return y >= 0.0f ? CUBEFACE_POSITIVE_Y : CUBEFACE_NEGATIVE_Y;
24123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
24133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return z >= 0.0f ? CUBEFACE_POSITIVE_Z : CUBEFACE_NEGATIVE_Z;
24143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
24153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (ay == az)
24163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
24173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (ay < ax)
24183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return x >= 0.0f ? CUBEFACE_POSITIVE_X : CUBEFACE_NEGATIVE_X;
24193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
24203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return y >= 0.0f ? CUBEFACE_POSITIVE_Y : CUBEFACE_NEGATIVE_Y;
24213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
24223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
24233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return x >= 0.0f ? CUBEFACE_POSITIVE_X : CUBEFACE_NEGATIVE_X;
24243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
24253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24273c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec2 projectToFace (CubeFace face, const Vec3& coord)
24283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	rx		= coord.x();
24303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	ry		= coord.y();
24313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	rz		= coord.z();
24323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		sc		= 0.0f;
24333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		tc		= 0.0f;
24343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		ma		= 0.0f;
24353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		s;
24363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		t;
24373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (face)
24393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_X: sc = +rz; tc = -ry; ma = -rx; break;
24413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_X: sc = -rz; tc = -ry; ma = +rx; break;
24423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_Y: sc = +rx; tc = -rz; ma = -ry; break;
24433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_Y: sc = +rx; tc = +rz; ma = +ry; break;
24443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_Z: sc = -rx; tc = -ry; ma = -rz; break;
24453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_Z: sc = +rx; tc = -ry; ma = +rz; break;
24463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
24473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
24483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
24493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute s, t
24513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	s = ((sc / ma) + 1.0f) / 2.0f;
24523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	t = ((tc / ma) + 1.0f) / 2.0f;
24533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return Vec2(s, t);
24553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24573c827367444ee418f129b2c238299f49d3264554Jarkko PoyryCubeFaceFloatCoords getCubeFaceCoords (const Vec3& coords)
24583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CubeFace face = selectCubeFace(coords);
24603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return CubeFaceFloatCoords(face, projectToFace(face, coords));
24613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24633c827367444ee418f129b2c238299f49d3264554Jarkko 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.
24643c827367444ee418f129b2c238299f49d3264554Jarkko 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.
24653c827367444ee418f129b2c238299f49d3264554Jarkko PoyryCubeFaceIntCoords remapCubeEdgeCoords (const CubeFaceIntCoords& origCoords, int size)
24663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool uInBounds = de::inBounds(origCoords.s, 0, size);
24683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool vInBounds = de::inBounds(origCoords.t, 0, size);
24693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (uInBounds && vInBounds)
24713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return origCoords;
24723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!uInBounds && !vInBounds)
24743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_LAST, -1, -1);
24753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec2 coords(wrap(Sampler::CLAMP_TO_BORDER, origCoords.s, size),
24773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				 wrap(Sampler::CLAMP_TO_BORDER, origCoords.t, size));
24783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec3 canonizedCoords;
24793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Map the uv coordinates to canonized 3d coordinates.
24813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (origCoords.face)
24833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_X: canonizedCoords = IVec3(0,					size-1-coords.y(),	coords.x());			break;
24853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_X: canonizedCoords = IVec3(size-1,				size-1-coords.y(),	size-1-coords.x());		break;
24863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_Y: canonizedCoords = IVec3(coords.x(),			0,					size-1-coords.y());		break;
24873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_Y: canonizedCoords = IVec3(coords.x(),			size-1,				coords.y());			break;
24883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_Z: canonizedCoords = IVec3(size-1-coords.x(),	size-1-coords.y(),	0);						break;
24893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_Z: canonizedCoords = IVec3(coords.x(),			size-1-coords.y(),	size-1);				break;
24903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default: DE_ASSERT(false);
24913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
24923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Find an appropriate face to re-map the coordinates to.
24943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (canonizedCoords.x() == -1)
24963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_NEGATIVE_X, IVec2(canonizedCoords.z(), size-1-canonizedCoords.y()));
24973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (canonizedCoords.x() == size)
24993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_POSITIVE_X, IVec2(size-1-canonizedCoords.z(), size-1-canonizedCoords.y()));
25003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (canonizedCoords.y() == -1)
25023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_NEGATIVE_Y, IVec2(canonizedCoords.x(), size-1-canonizedCoords.z()));
25033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (canonizedCoords.y() == size)
25053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_POSITIVE_Y, IVec2(canonizedCoords.x(), canonizedCoords.z()));
25063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (canonizedCoords.z() == -1)
25083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_NEGATIVE_Z, IVec2(size-1-canonizedCoords.x(), size-1-canonizedCoords.y()));
25093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (canonizedCoords.z() == size)
25113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_POSITIVE_Z, IVec2(canonizedCoords.x(), size-1-canonizedCoords.y()));
25123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(false);
25143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return CubeFaceIntCoords(CUBEFACE_LAST, IVec2(-1));
25153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
25163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25173c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void getCubeLinearSamples (const ConstPixelBufferAccess (&faceAccesses)[CUBEFACE_LAST], CubeFace baseFace, float u, float v, int depth, Vec4 (&dst)[4])
25183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
25193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(faceAccesses[0].getWidth() == faceAccesses[0].getHeight());
25203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		size					= faceAccesses[0].getWidth();
25213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		x0						= deFloorFloatToInt32(u-0.5f);
25223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		x1						= x0+1;
25233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		y0						= deFloorFloatToInt32(v-0.5f);
25243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		y1						= y0+1;
25253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec2	baseSampleCoords[4]		=
25263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
25273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x0, y0),
25283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x1, y0),
25293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x0, y1),
25303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x1, y1)
25313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
25323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4	sampleColors[4];
25333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool	hasBothCoordsOutOfBounds[4]; //!< Whether correctCubeFace() returns CUBEFACE_LAST, i.e. both u and v are out of bounds.
25343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Find correct faces and coordinates for out-of-bounds sample coordinates.
25363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
25383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
25393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CubeFaceIntCoords coords = remapCubeEdgeCoords(CubeFaceIntCoords(baseFace, baseSampleCoords[i]), size);
25403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		hasBothCoordsOutOfBounds[i] = coords.face == CUBEFACE_LAST;
25413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!hasBothCoordsOutOfBounds[i])
25423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sampleColors[i] = lookup(faceAccesses[coords.face], coords.s, coords.t, depth);
25433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
25443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25453c827367444ee418f129b2c238299f49d3264554Jarkko 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.
25463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note This averaging behavior is not required by the GLES3 spec (though it is recommended). GLES3 spec only
25473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//		 requires that if the three other samples all have the same color, then the doubly-out-of-bounds sample
25483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//		 must have this color as well.
25493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
25513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int bothOutOfBoundsNdx = -1;
25523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < 4; i++)
25533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
25543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (hasBothCoordsOutOfBounds[i])
25553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
25563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(bothOutOfBoundsNdx < 0); // Only one sample can be out of bounds in both u and v.
25573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				bothOutOfBoundsNdx = i;
25583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
25593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
25603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (bothOutOfBoundsNdx != -1)
25613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
25623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sampleColors[bothOutOfBoundsNdx] = Vec4(0.0f);
25633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < 4; i++)
25643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (i != bothOutOfBoundsNdx)
25653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					sampleColors[bothOutOfBoundsNdx] += sampleColors[i];
25663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sampleColors[bothOutOfBoundsNdx] = sampleColors[bothOutOfBoundsNdx] * (1.0f/3.0f);
25683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
25693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
25703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < DE_LENGTH_OF_ARRAY(sampleColors); i++)
25723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dst[i] = sampleColors[i];
25733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
25743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \todo [2014-02-19 pyry] Optimize faceAccesses
25763c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleCubeSeamlessLinear (const ConstPixelBufferAccess (&faceAccesses)[CUBEFACE_LAST], CubeFace baseFace, const Sampler& sampler, float s, float t, int depth)
25773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
25783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(faceAccesses[0].getWidth() == faceAccesses[0].getHeight());
25793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		size	= faceAccesses[0].getWidth();
25813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
25823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float	u		= s;
25833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float	v		= t;
25843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
25863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
25873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		u = unnormalize(sampler.wrapS, s, size);
25883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		v = unnormalize(sampler.wrapT, t, size);
25893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
25903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Get sample colors.
25923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 sampleColors[4];
25943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	getCubeLinearSamples(faceAccesses, baseFace, u, v, depth, sampleColors);
25953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
25973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
25993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float b = deFloatFrac(v-0.5f);
26003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (sampleColors[0]*(1.0f-a)*(1.0f-b)) +
26023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (sampleColors[1]*(     a)*(1.0f-b)) +
26033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (sampleColors[2]*(1.0f-a)*(     b)) +
26043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (sampleColors[3]*(     a)*(     b));
26053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
26063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26073c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleLevelArrayCubeSeamless (const ConstPixelBufferAccess* const (&faces)[CUBEFACE_LAST], int numLevels, CubeFace face, const Sampler& sampler, float s, float t, int depth, float lod)
26083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
26103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
26113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
26133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
26143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:
26153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessNearest(faces[face][0], sampler, s, t, depth);
26163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:
26183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
26193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
26203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < (int)CUBEFACE_LAST; i++)
26213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				faceAccesses[i] = faces[i][0];
26223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessLinear(faceAccesses, face, sampler, s, t, depth);
26243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
26253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
26273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
26283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
26293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
26303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
26313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
26323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
26343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessNearest(faces[face][level], sampler, s, t, depth);
26353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
26363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
26373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
26383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
26403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
26413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses[i] = faces[i][level];
26423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessLinear(faceAccesses, face, sampler, s, t, depth);
26443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
26453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
26463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
26483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
26493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
26503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
26513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
26523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level1		= de::min(maxLevel, level0 + 1);
26533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
26543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					f			= deFloatFrac(lod);
26553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec4					t0;
26563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec4					t1;
26573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
26593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
26603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessNearest(faces[face][level0], sampler, s, t, depth);
26613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessNearest(faces[face][level1], sampler, s, t, depth);
26623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
26633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
26643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
26653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
26663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses0[CUBEFACE_LAST];
26683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses1[CUBEFACE_LAST];
26693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
26703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
26713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses0[i] = faces[i][level0];
26723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses1[i] = faces[i][level1];
26733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
26743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessLinear(faceAccesses0, face, sampler, s, t, depth);
26763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessLinear(faceAccesses1, face, sampler, s, t, depth);
26773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
26783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
26803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
26813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
26833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
26843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
26853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
26863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
26873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26883c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float sampleCubeSeamlessNearestCompare (const ConstPixelBufferAccess& faceAccess, const Sampler& sampler, float ref, float s, float t, int depth = 0)
26893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler clampingSampler = sampler;
26913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	clampingSampler.wrapS = Sampler::CLAMP_TO_EDGE;
26923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	clampingSampler.wrapT = Sampler::CLAMP_TO_EDGE;
26933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return faceAccess.sample2DCompare(clampingSampler, Sampler::NEAREST, ref, s, t, IVec3(0, 0, depth));
26943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
26953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26963c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float sampleCubeSeamlessLinearCompare (const ConstPixelBufferAccess (&faceAccesses)[CUBEFACE_LAST], CubeFace baseFace, const Sampler& sampler, float ref, float s, float t)
26973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(faceAccesses[0].getWidth() == faceAccesses[0].getHeight());
26993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		size	= faceAccesses[0].getWidth();
27013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
27023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float	u		= s;
27033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float	v		= t;
27043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
27063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
27073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		u = unnormalize(sampler.wrapS, s, size);
27083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		v = unnormalize(sampler.wrapT, t, size);
27093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
27103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			x0						= deFloorFloatToInt32(u-0.5f);
27123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			x1						= x0+1;
27133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			y0						= deFloorFloatToInt32(v-0.5f);
27143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			y1						= y0+1;
27153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec2		baseSampleCoords[4]		=
27163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
27173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x0, y0),
27183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x1, y0),
27193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x0, y1),
27203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x1, y1)
27213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
27223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		sampleRes[4];
27233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		hasBothCoordsOutOfBounds[4]; //!< Whether correctCubeFace() returns CUBEFACE_LAST, i.e. both u and v are out of bounds.
27243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Find correct faces and coordinates for out-of-bounds sample coordinates.
27263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
27283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
27293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CubeFaceIntCoords coords = remapCubeEdgeCoords(CubeFaceIntCoords(baseFace, baseSampleCoords[i]), size);
27303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		hasBothCoordsOutOfBounds[i] = coords.face == CUBEFACE_LAST;
27313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!hasBothCoordsOutOfBounds[i])
27333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
27343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool isFixedPointDepth = isFixedPointDepthTextureFormat(faceAccesses[coords.face].getFormat());
27353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sampleRes[i] = execCompare(faceAccesses[coords.face].getPixel(coords.s, coords.t), sampler.compare, sampler.compareChannel, ref, isFixedPointDepth);
27373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
27383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
27393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27403c827367444ee418f129b2c238299f49d3264554Jarkko 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.
27413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note This averaging behavior is not required by the GLES3 spec (though it is recommended). GLES3 spec only
27423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//		 requires that if the three other samples all have the same color, then the doubly-out-of-bounds sample
27433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//		 must have this color as well.
27443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
27463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int bothOutOfBoundsNdx = -1;
27473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < 4; i++)
27483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
27493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (hasBothCoordsOutOfBounds[i])
27503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
27513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(bothOutOfBoundsNdx < 0); // Only one sample can be out of bounds in both u and v.
27523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				bothOutOfBoundsNdx = i;
27533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
27543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
27553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (bothOutOfBoundsNdx != -1)
27563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
27573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sampleRes[bothOutOfBoundsNdx] = 0.0f;
27583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < 4; i++)
27593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (i != bothOutOfBoundsNdx)
27603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					sampleRes[bothOutOfBoundsNdx] += sampleRes[i];
27613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sampleRes[bothOutOfBoundsNdx] = sampleRes[bothOutOfBoundsNdx] * (1.0f/3.0f);
27633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
27643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
27653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
27673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
27693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float b = deFloatFrac(v-0.5f);
27703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (sampleRes[0]*(1.0f-a)*(1.0f-b)) +
27723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (sampleRes[1]*(     a)*(1.0f-b)) +
27733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (sampleRes[2]*(1.0f-a)*(     b)) +
27743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (sampleRes[3]*(     a)*(     b));
27753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27773c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float sampleLevelArrayCubeSeamlessCompare (const ConstPixelBufferAccess* const (&faces)[CUBEFACE_LAST], int numLevels, CubeFace face, const Sampler& sampler, float ref, float s, float t, float lod)
27783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
27803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
27813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
27833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
27843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:
27853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessNearestCompare(faces[face][0], sampler, ref, s, t);
27863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:
27883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
27893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
27903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < (int)CUBEFACE_LAST; i++)
27913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				faceAccesses[i] = faces[i][0];
27923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessLinearCompare(faceAccesses, face, sampler, ref, s, t);
27943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
27953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
27973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
27983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
27993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
28003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
28013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
28023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
28043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessNearestCompare(faces[face][level], sampler, ref, s, t);
28053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
28063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
28073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
28083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
28103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
28113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses[i] = faces[i][level];
28123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessLinearCompare(faceAccesses, face, sampler, ref, s, t);
28143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
28153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
28163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
28183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
28193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
28203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
28213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
28223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level1		= de::min(maxLevel, level0 + 1);
28233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
28243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					f			= deFloatFrac(lod);
28253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					t0;
28263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					t1;
28273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
28293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
28303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessNearestCompare(faces[face][level0], sampler, ref, s, t);
28313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessNearestCompare(faces[face][level1], sampler, ref, s, t);
28323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
28333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
28343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
28353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
28363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses0[CUBEFACE_LAST];
28383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses1[CUBEFACE_LAST];
28393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
28403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
28413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses0[i] = faces[i][level0];
28423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses1[i] = faces[i][level1];
28433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
28443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessLinearCompare(faceAccesses0, face, sampler, ref, s, t);
28463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessLinearCompare(faceAccesses1, face, sampler, ref, s, t);
28473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
28483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
28503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
28513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
28533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
28543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
28553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
28563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Cube map array sampling
28593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28603c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline ConstPixelBufferAccess getCubeArrayFaceAccess (const ConstPixelBufferAccess* const levels, int levelNdx, int slice, CubeFace face)
28613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ConstPixelBufferAccess&	level	= levels[levelNdx];
28633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						depth	= (slice * 6) + getCubeArrayFaceIndex(face);
28643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return getSubregion(level, 0, 0, depth, level.getWidth(), level.getHeight(), 1);
28663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28683c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleCubeArraySeamless (const ConstPixelBufferAccess* const levels, int numLevels, int slice, CubeFace face, const Sampler& sampler, float s, float t, float lod)
28693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					faceDepth	= (slice * 6) + getCubeArrayFaceIndex(face);
28713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool					magnified	= lod <= sampler.lodThreshold;
28723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Sampler::FilterMode	filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
28733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
28753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
28763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:
28773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessNearest(levels[0], sampler, s, t, faceDepth);
28783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:
28803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
28813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
28823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < (int)CUBEFACE_LAST; i++)
28833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				faceAccesses[i] = getCubeArrayFaceAccess(levels, 0, slice, (CubeFace)i);
28843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessLinear(faceAccesses, face, sampler, s, t, 0);
28863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
28873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
28893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
28903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
28913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
28923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
28933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
28943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
28963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessNearest(levels[level], sampler, s, t, faceDepth);
28973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
28983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
28993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
29003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
29023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
29033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses[i] = getCubeArrayFaceAccess(levels, level, slice, (CubeFace)i);
29043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessLinear(faceAccesses, face, sampler, s, t, 0);
29063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
29073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
29083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
29103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
29113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
29123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
29133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
29143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level1		= de::min(maxLevel, level0 + 1);
29153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
29163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					f			= deFloatFrac(lod);
29173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec4					t0;
29183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec4					t1;
29193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
29213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
29223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessNearest(levels[level0], sampler, s, t, faceDepth);
29233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessNearest(levels[level1], sampler, s, t, faceDepth);
29243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
29253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
29263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
29273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
29283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses0[CUBEFACE_LAST];
29303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses1[CUBEFACE_LAST];
29313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
29323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
29333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses0[i] = getCubeArrayFaceAccess(levels, level0, slice, (CubeFace)i);
29343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses1[i] = getCubeArrayFaceAccess(levels, level1, slice, (CubeFace)i);
29353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
29363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessLinear(faceAccesses0, face, sampler, s, t, 0);
29383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessLinear(faceAccesses1, face, sampler, s, t, 0);
29393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
29403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
29423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
29433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
29453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
29463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
29473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
29483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29503c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float sampleCubeArraySeamlessCompare (const ConstPixelBufferAccess* const levels, int numLevels, int slice, CubeFace face, const Sampler& sampler, float ref, float s, float t, float lod)
29513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int			faceDepth	= (slice * 6) + getCubeArrayFaceIndex(face);
29533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool			magnified	= lod <= sampler.lodThreshold;
29543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode	filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
29553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
29573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
29583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:
29593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessNearestCompare(levels[0], sampler, ref, s, t, faceDepth);
29603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:
29623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
29633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
29643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < (int)CUBEFACE_LAST; i++)
29653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				faceAccesses[i] = getCubeArrayFaceAccess(levels, 0, slice, (CubeFace)i);
29663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessLinearCompare(faceAccesses, face, sampler, ref, s, t);
29683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
29693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
29713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
29723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
29733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
29743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
29753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
29763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
29783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessNearestCompare(levels[level], sampler, ref, s, t, faceDepth);
29793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
29803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
29813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
29823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
29843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
29853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses[i] = getCubeArrayFaceAccess(levels, level, slice, (CubeFace)i);
29863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessLinearCompare(faceAccesses, face, sampler, ref, s, t);
29883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
29893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
29903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
29923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
29933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
29943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
29953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
29963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level1		= de::min(maxLevel, level0 + 1);
29973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
29983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					f			= deFloatFrac(lod);
29993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					t0;
30003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					t1;
30013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
30033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
30043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessNearestCompare(levels[level0], sampler, ref, s, t, faceDepth);
30053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessNearestCompare(levels[level1], sampler, ref, s, t, faceDepth);
30063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
30073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
30083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
30093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
30103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses0[CUBEFACE_LAST];
30123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses1[CUBEFACE_LAST];
30133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
30143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
30153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses0[i] = getCubeArrayFaceAccess(levels, level0, slice, (CubeFace)i);
30163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses1[i] = getCubeArrayFaceAccess(levels, level1, slice, (CubeFace)i);
30173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
30183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessLinearCompare(faceAccesses0, face, sampler, ref, s, t);
30203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessLinearCompare(faceAccesses1, face, sampler, ref, s, t);
30213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
30223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
30243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
30253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
30273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
30283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
30293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
30303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30323c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int computeMipPyramidLevels (int size)
30333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return deLog2Floor32(size)+1;
30353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int computeMipPyramidLevels (int width, int height)
30383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return deLog2Floor32(de::max(width, height))+1;
30403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30423c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int computeMipPyramidLevels (int width, int height, int depth)
30433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return deLog2Floor32(de::max(width, de::max(height, depth)))+1;
30453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int getMipPyramidLevelSize (int baseLevelSize, int levelNdx)
30483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return de::max(baseLevelSize >> levelNdx, 1);
30503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// TextureLevelPyramid
30533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30543c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevelPyramid::TextureLevelPyramid (const TextureFormat& format, int numLevels)
30553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	(format)
30563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_data	(numLevels)
30573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_access	(numLevels)
30583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30613c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevelPyramid::TextureLevelPyramid (const TextureLevelPyramid& other)
30623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	(other.m_format)
30633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_data	(other.getNumLevels())
30643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_access	(other.getNumLevels())
30653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int levelNdx = 0; levelNdx < other.getNumLevels(); levelNdx++)
30673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
30683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!other.isLevelEmpty(levelNdx))
30693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
30703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::ConstPixelBufferAccess& srcLevel = other.getLevel(levelNdx);
30713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_data[levelNdx] = other.m_data[levelNdx];
30733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_access[levelNdx] = PixelBufferAccess(srcLevel.getFormat(), srcLevel.getWidth(), srcLevel.getHeight(), srcLevel.getDepth(), m_data[levelNdx].getPtr());
30743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
30753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
30763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30783c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevelPyramid& TextureLevelPyramid::operator= (const TextureLevelPyramid& other)
30793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
30813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
30823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_format = other.m_format;
30843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_data.resize(other.getNumLevels());
30853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_access.resize(other.getNumLevels());
30863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int levelNdx = 0; levelNdx < other.getNumLevels(); levelNdx++)
30883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
30893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!other.isLevelEmpty(levelNdx))
30903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
30913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::ConstPixelBufferAccess& srcLevel = other.getLevel(levelNdx);
30923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_data[levelNdx] = other.m_data[levelNdx];
30943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_access[levelNdx] = PixelBufferAccess(srcLevel.getFormat(), srcLevel.getWidth(), srcLevel.getHeight(), srcLevel.getDepth(), m_data[levelNdx].getPtr());
30953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
30963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (!isLevelEmpty(levelNdx))
30973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			clearLevel(levelNdx);
30983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
30993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
31013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31033c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevelPyramid::~TextureLevelPyramid (void)
31043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31073c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureLevelPyramid::allocLevel (int levelNdx, int width, int height, int depth)
31083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	size	= m_format.getPixelSize()*width*height*depth;
31103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(isLevelEmpty(levelNdx));
31123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_data[levelNdx].setStorage(size);
31143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_access[levelNdx] = PixelBufferAccess(m_format, width, height, depth, m_data[levelNdx].getPtr());
31153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31173c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureLevelPyramid::clearLevel (int levelNdx)
31183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!isLevelEmpty(levelNdx));
31203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_data[levelNdx].clear();
31223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_access[levelNdx] = PixelBufferAccess();
31233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture1D
31263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31273c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1D::Texture1D (const TextureFormat& format, int width)
31283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(format, computeMipPyramidLevels(width))
31293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(width)
31303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
31313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31343c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1D::Texture1D (const Texture1D& other)
31353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(other)
31363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(other.m_width)
31373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
31383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31413c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1D& Texture1D::operator= (const Texture1D& other)
31423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
31443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
31453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::operator=(other);
31473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_width		= other.m_width;
31493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view		= Texture1DView(getNumLevels(), getLevels());
31503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
31523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31543c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1D::~Texture1D (void)
31553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture1D::allocLevel (int levelNdx)
31593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels()));
31613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int width = getMipPyramidLevelSize(m_width, levelNdx);
31633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::allocLevel(levelNdx, width, 1, 1);
31653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture2D
31683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31693c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2D::Texture2D (const TextureFormat& format, int width, int height)
31703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(format, computeMipPyramidLevels(width, height))
31713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(width)
31723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height				(height)
31733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
31743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31773c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2D::Texture2D (const Texture2D& other)
31783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(other)
31793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(other.m_width)
31803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height				(other.m_height)
31813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
31823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31853c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2D& Texture2D::operator= (const Texture2D& other)
31863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
31883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
31893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::operator=(other);
31913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_width		= other.m_width;
31933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_height	= other.m_height;
31943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view		= Texture2DView(getNumLevels(), getLevels());
31953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
31973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31993c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2D::~Texture2D (void)
32003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32033c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2D::allocLevel (int levelNdx)
32043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels()));
32063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	width	= getMipPyramidLevelSize(m_width, levelNdx);
32083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	height	= getMipPyramidLevelSize(m_height, levelNdx);
32093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::allocLevel(levelNdx, width, height, 1);
32113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// TextureCubeView
32143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32153c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeView::TextureCubeView (void)
32163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_numLevels(0)
32173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < CUBEFACE_LAST; ndx++)
32193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_levels[ndx] = DE_NULL;
32203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32223c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeView::TextureCubeView (int numLevels, const ConstPixelBufferAccess* const (&levels) [CUBEFACE_LAST])
32233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_numLevels(numLevels)
32243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < CUBEFACE_LAST; ndx++)
32263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_levels[ndx] = levels[ndx];
32273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32293c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Vec4 TextureCubeView::sample (const Sampler& sampler, float s, float t, float r, float lod) const
32303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare == Sampler::COMPAREMODE_NONE);
32323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Computes (face, s, t).
32343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CubeFaceFloatCoords coords = getCubeFaceCoords(Vec3(s, t, r));
32353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.seamlessCubeMap)
32363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sampleLevelArrayCubeSeamless(m_levels, m_numLevels, coords.face, sampler, coords.s, coords.t, 0 /* depth */, lod);
32373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
32383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sampleLevelArray2D(m_levels[coords.face], m_numLevels, sampler, coords.s, coords.t, 0 /* depth */, lod);
32393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat TextureCubeView::sampleCompare (const Sampler& sampler, float ref, float s, float t, float r, float lod) const
32423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare != Sampler::COMPAREMODE_NONE);
32443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Computes (face, s, t).
32463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CubeFaceFloatCoords coords = getCubeFaceCoords(Vec3(s, t, r));
32473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.seamlessCubeMap)
32483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sampleLevelArrayCubeSeamlessCompare(m_levels, m_numLevels, coords.face, sampler, ref, coords.s, coords.t, lod);
32493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
32503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sampleLevelArray2DCompare(m_levels[coords.face], m_numLevels, sampler, ref, coords.s, coords.t, lod, IVec3(0, 0, 0));
32513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32533c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 TextureCubeView::gather (const Sampler& sampler, float s, float t, float r, int componentNdx) const
32543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare == Sampler::COMPAREMODE_NONE);
32563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
32583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)CUBEFACE_LAST; i++)
32593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		faceAccesses[i] = m_levels[i][0];
32603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CubeFaceFloatCoords	coords	= getCubeFaceCoords(Vec3(s, t, r));
32623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					size	= faceAccesses[0].getWidth();
32633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
32643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float						u		= coords.s;
32653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float						v		= coords.t;
32663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
32683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
32693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		u = unnormalize(sampler.wrapS, coords.s, size);
32703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		v = unnormalize(sampler.wrapT, coords.t, size);
32713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
32723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 sampleColors[4];
32743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	getCubeLinearSamples(faceAccesses, coords.face, u, v, 0, sampleColors);
32753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	sampleIndices[4] = { 2, 3, 1, 0 }; // \note Gather returns the samples in a non-obvious order.
32773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4		result;
32783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
32793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result[i] = sampleColors[sampleIndices[i]][componentNdx];
32803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
32823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32843c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 TextureCubeView::gatherCompare (const Sampler& sampler, float ref, float s, float t, float r) const
32853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare != Sampler::COMPAREMODE_NONE);
32873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_levels[0][0].getFormat().order == TextureFormat::D || m_levels[0][0].getFormat().order == TextureFormat::DS);
32883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compareChannel == 0);
32893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler noCompareSampler = sampler;
32913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	noCompareSampler.compare = Sampler::COMPAREMODE_NONE;
32923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec4 gathered			= gather(noCompareSampler, s, t, r, 0 /* component 0: depth */);
32943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool isFixedPoint		= isFixedPointDepthTextureFormat(m_levels[0][0].getFormat());
32953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 result;
32963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
32973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result[i] = execCompare(gathered, sampler.compare, i, ref, isFixedPoint);
32983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
33003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// TextureCube
33033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33043c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCube::TextureCube (const TextureFormat& format, int size)
33053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	(format)
33063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_size	(size)
33073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						numLevels		= computeMipPyramidLevels(m_size);
33093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ConstPixelBufferAccess*	levels[CUBEFACE_LAST];
33103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int face = 0; face < CUBEFACE_LAST; face++)
33123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
33133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_data[face].resize(numLevels);
33143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_access[face].resize(numLevels);
33153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		levels[face] = &m_access[face][0];
33163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
33173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view = TextureCubeView(numLevels, levels);
33193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33213c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCube::TextureCube (const TextureCube& other)
33223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	(other.m_format)
33233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_size	(other.m_size)
33243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						numLevels		= computeMipPyramidLevels(m_size);
33263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ConstPixelBufferAccess*	levels[CUBEFACE_LAST];
33273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int face = 0; face < CUBEFACE_LAST; face++)
33293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
33303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_data[face].resize(numLevels);
33313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_access[face].resize(numLevels);
33323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		levels[face] = &m_access[face][0];
33333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
33343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view = TextureCubeView(numLevels, levels);
33363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
33383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
33393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int face = 0; face < CUBEFACE_LAST; face++)
33403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
33413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!other.isLevelEmpty((CubeFace)face, levelNdx))
33423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
33433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				allocLevel((CubeFace)face, levelNdx);
33443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				copy(getLevelFace(levelNdx, (CubeFace)face),
33453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 other.getLevelFace(levelNdx, (CubeFace)face));
33463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
33473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
33483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
33493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33513c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCube& TextureCube::operator= (const TextureCube& other)
33523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
33543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
33553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						numLevels		= computeMipPyramidLevels(other.m_size);
33573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ConstPixelBufferAccess*	levels[CUBEFACE_LAST];
33583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int face = 0; face < CUBEFACE_LAST; face++)
33603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
33613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_data[face].resize(numLevels);
33623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_access[face].resize(numLevels);
33633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		levels[face] = &m_access[face][0];
33643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
33653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_format	= other.m_format;
33673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_size		= other.m_size;
33683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view		= TextureCubeView(numLevels, levels);
33693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
33713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
33723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int face = 0; face < CUBEFACE_LAST; face++)
33733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
33743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!isLevelEmpty((CubeFace)face, levelNdx))
33753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				clearLevel((CubeFace)face, levelNdx);
33763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!other.isLevelEmpty((CubeFace)face, levelNdx))
33783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
33793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				allocLevel((CubeFace)face, levelNdx);
33803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				copy(getLevelFace(levelNdx, (CubeFace)face),
33813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 other.getLevelFace(levelNdx, (CubeFace)face));
33823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
33833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
33843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
33853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
33873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33893c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCube::~TextureCube (void)
33903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33933c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCube::allocLevel (tcu::CubeFace face, int levelNdx)
33943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	size		= getMipPyramidLevelSize(m_size, levelNdx);
33963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	dataSize	= m_format.getPixelSize()*size*size;
33973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(isLevelEmpty(face, levelNdx));
33983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_data[face][levelNdx].setStorage(dataSize);
34003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_access[face][levelNdx] = PixelBufferAccess(m_format, size, size, 1, m_data[face][levelNdx].getPtr());
34013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34033c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCube::clearLevel (tcu::CubeFace face, int levelNdx)
34043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!isLevelEmpty(face, levelNdx));
34063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_data[face][levelNdx].clear();
34073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_access[face][levelNdx] = PixelBufferAccess();
34083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture1DArrayView
34113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34123c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1DArrayView::Texture1DArrayView (int numLevels, const ConstPixelBufferAccess* levels)
34133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_numLevels	(numLevels)
34143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_levels		(levels)
34153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34183c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int Texture1DArrayView::selectLayer (float r) const
34193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_numLevels > 0 && m_levels);
34213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return de::clamp(deFloorFloatToInt32(r + 0.5f), 0, m_levels[0].getHeight()-1);
34223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34243c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 Texture1DArrayView::sample (const Sampler& sampler, float s, float t, float lod) const
34253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray1D(m_levels, m_numLevels, sampler, s, selectLayer(t), lod);
34273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34293c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 Texture1DArrayView::sampleOffset (const Sampler& sampler, float s, float t, float lod, deInt32 offset) const
34303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray1DOffset(m_levels, m_numLevels, sampler, s, lod, IVec2(offset, selectLayer(t)));
34323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34343c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat Texture1DArrayView::sampleCompare (const Sampler& sampler, float ref, float s, float t, float lod) const
34353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray1DCompare(m_levels, m_numLevels, sampler, ref, s, lod, IVec2(0, selectLayer(t)));
34373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34393c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat Texture1DArrayView::sampleCompareOffset (const Sampler& sampler, float ref, float s, float t, float lod, deInt32 offset) const
34403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray1DCompare(m_levels, m_numLevels, sampler, ref, s, lod, IVec2(offset, selectLayer(t)));
34423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture2DArrayView
34453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34463c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArrayView::Texture2DArrayView (int numLevels, const ConstPixelBufferAccess* levels)
34473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_numLevels	(numLevels)
34483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_levels		(levels)
34493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int Texture2DArrayView::selectLayer (float r) const
34533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_numLevels > 0 && m_levels);
34553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return de::clamp(deFloorFloatToInt32(r + 0.5f), 0, m_levels[0].getDepth()-1);
34563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34583c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 Texture2DArrayView::sample (const Sampler& sampler, float s, float t, float r, float lod) const
34593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray2D(m_levels, m_numLevels, sampler, s, t, selectLayer(r), lod);
34613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat Texture2DArrayView::sampleCompare (const Sampler& sampler, float ref, float s, float t, float r, float lod) const
34643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray2DCompare(m_levels, m_numLevels, sampler, ref, s, t, lod, IVec3(0, 0, selectLayer(r)));
34663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34683c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 Texture2DArrayView::sampleOffset (const Sampler& sampler, float s, float t, float r, float lod, const IVec2& offset) const
34693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray2DOffset(m_levels, m_numLevels, sampler, s, t, lod, IVec3(offset.x(), offset.y(), selectLayer(r)));
34713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat Texture2DArrayView::sampleCompareOffset (const Sampler& sampler, float ref, float s, float t, float r, float lod, const IVec2& offset) const
34743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray2DCompare(m_levels, m_numLevels, sampler, ref, s, t, lod, IVec3(offset.x(), offset.y(), selectLayer(r)));
34763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34783c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 Texture2DArrayView::gatherOffsets (const Sampler& sampler, float s, float t, float r, int componentNdx, const IVec2 (&offsets)[4]) const
34793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return gatherArray2DOffsets(m_levels[0], sampler, s, t, selectLayer(r), componentNdx, offsets);
34813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34833c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 Texture2DArrayView::gatherOffsetsCompare (const Sampler& sampler, float ref, float s, float t, float r, const IVec2 (&offsets)[4]) const
34843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return gatherArray2DOffsetsCompare(m_levels[0], sampler, ref, s, t, selectLayer(r), offsets);
34863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture1DArray
34893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34903c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1DArray::Texture1DArray (const TextureFormat& format, int width, int numLayers)
34913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(format, computeMipPyramidLevels(width))
34923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(width)
34933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numLayers			(numLayers)
34943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
34953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34983c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1DArray::Texture1DArray (const Texture1DArray& other)
34993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(other)
35003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(other.m_width)
35013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numLayers			(other.m_numLayers)
35023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
35033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35063c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1DArray& Texture1DArray::operator= (const Texture1DArray& other)
35073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
35093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
35103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::operator=(other);
35123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_width		= other.m_width;
35143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_numLayers	= other.m_numLayers;
35153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view		= Texture1DArrayView(getNumLevels(), getLevels());
35163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
35183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35203c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1DArray::~Texture1DArray (void)
35213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35243c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture1DArray::allocLevel (int levelNdx)
35253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels()));
35273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int width = getMipPyramidLevelSize(m_width, levelNdx);
35293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::allocLevel(levelNdx, width, m_numLayers, 1);
35313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture2DArray
35343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35353c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArray::Texture2DArray (const TextureFormat& format, int width, int height, int numLayers)
35363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(format, computeMipPyramidLevels(width, height))
35373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(width)
35383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height				(height)
35393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numLayers			(numLayers)
35403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
35413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35443c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArray::Texture2DArray (const Texture2DArray& other)
35453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(other)
35463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(other.m_width)
35473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height				(other.m_height)
35483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numLayers			(other.m_numLayers)
35493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
35503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35533c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArray& Texture2DArray::operator= (const Texture2DArray& other)
35543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
35563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
35573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::operator=(other);
35593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_width		= other.m_width;
35613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_height	= other.m_height;
35623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_numLayers	= other.m_numLayers;
35633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view		= Texture2DArrayView(getNumLevels(), getLevels());
35643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
35663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35683c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArray::~Texture2DArray (void)
35693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35723c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2DArray::allocLevel (int levelNdx)
35733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels()));
35753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	width	= getMipPyramidLevelSize(m_width,	levelNdx);
35773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	height	= getMipPyramidLevelSize(m_height,	levelNdx);
35783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::allocLevel(levelNdx, width, height, m_numLayers);
35803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture3DView
35833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35843c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3DView::Texture3DView (int numLevels, const ConstPixelBufferAccess* levels)
35853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_numLevels	(numLevels)
35863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_levels		(levels)
35873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture3D
35913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35923c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3D::Texture3D (const TextureFormat& format, int width, int height, int depth)
35933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(format, computeMipPyramidLevels(width, height, depth))
35943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(width)
35953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height				(height)
35963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_depth				(depth)
35973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
35983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36013c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3D::Texture3D (const Texture3D& other)
36023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(other)
36033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(other.m_width)
36043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height				(other.m_height)
36053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_depth				(other.m_depth)
36063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
36073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36103c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3D& Texture3D::operator= (const Texture3D& other)
36113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
36133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
36143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::operator=(other);
36163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_width		= other.m_width;
36183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_height	= other.m_height;
36193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_depth		= other.m_depth;
36203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view		= Texture3DView(getNumLevels(), getLevels());
36213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
36233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36253c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3D::~Texture3D (void)
36263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36293c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture3D::allocLevel (int levelNdx)
36303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels()));
36323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int width		= getMipPyramidLevelSize(m_width,	levelNdx);
36343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int height	= getMipPyramidLevelSize(m_height,	levelNdx);
36353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int depth		= getMipPyramidLevelSize(m_depth,	levelNdx);
36363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::allocLevel(levelNdx, width, height, depth);
36383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// TextureCubeArrayView
36413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36423c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeArrayView::TextureCubeArrayView (int numLevels, const ConstPixelBufferAccess* levels)
36433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_numLevels	(numLevels)
36443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_levels		(levels)
36453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36488852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryinline int TextureCubeArrayView::selectLayer (float q) const
36493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_numLevels > 0 && m_levels);
36513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT((m_levels[0].getDepth() % 6) == 0);
36523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return de::clamp(deFloorFloatToInt32(q + 0.5f), 0, (m_levels[0].getDepth() / 6)-1);
36543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36563c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Vec4 TextureCubeArrayView::sample (const Sampler& sampler, float s, float t, float r, float q, float lod) const
36573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CubeFaceFloatCoords	coords		= getCubeFaceCoords(Vec3(s, t, r));
36598852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const int					layer		= selectLayer(q);
36608852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const int					faceDepth	= (layer * 6) + getCubeArrayFaceIndex(coords.face);
36613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare == Sampler::COMPAREMODE_NONE);
36633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.seamlessCubeMap)
36658852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		return sampleCubeArraySeamless(m_levels, m_numLevels, layer, coords.face, sampler, coords.s, coords.t, lod);
36663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
36673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sampleLevelArray2D(m_levels, m_numLevels, sampler, coords.s, coords.t, faceDepth, lod);
36683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36703c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat TextureCubeArrayView::sampleCompare (const Sampler& sampler, float ref, float s, float t, float r, float q, float lod) const
36713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CubeFaceFloatCoords	coords		= getCubeFaceCoords(Vec3(s, t, r));
36738852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const int					layer		= selectLayer(q);
36748852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const int					faceDepth	= (layer * 6) + getCubeArrayFaceIndex(coords.face);
36753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare != Sampler::COMPAREMODE_NONE);
36773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.seamlessCubeMap)
36798852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		return sampleCubeArraySeamlessCompare(m_levels, m_numLevels, layer, coords.face, sampler, ref, coords.s, coords.t, lod);
36803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
36813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sampleLevelArray2DCompare(m_levels, m_numLevels, sampler, ref, coords.s, coords.t, lod, IVec3(0, 0, faceDepth));
36823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// TextureCubeArray
36853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36868852c82a1ffa4760985c17cc6875d5d521daf343Jarkko PoyryTextureCubeArray::TextureCubeArray (const TextureFormat& format, int size, int depth)
36873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(format, computeMipPyramidLevels(size))
36883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_size				(size)
36898852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	, m_depth				(depth)
36903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
36913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36928852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	DE_ASSERT(m_depth % 6 == 0);
36933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36953c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeArray::TextureCubeArray (const TextureCubeArray& other)
36963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(other)
36973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_size				(other.m_size)
36988852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	, m_depth				(other.m_depth)
36993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
37003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
37018852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	DE_ASSERT(m_depth % 6 == 0);
37023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
37033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37043c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeArray& TextureCubeArray::operator= (const TextureCubeArray& other)
37053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
37063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
37073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
37083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::operator=(other);
37103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37118852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	m_size	= other.m_size;
37128852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	m_depth	= other.m_depth;
37138852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	m_view	= TextureCubeArrayView(getNumLevels(), getLevels());
37143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37158852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	DE_ASSERT(m_depth % 6 == 0);
37163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
37183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
37193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37203c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeArray::~TextureCubeArray (void)
37213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
37223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
37233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37243c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCubeArray::allocLevel (int levelNdx)
37253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
37263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels()));
37273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int size = getMipPyramidLevelSize(m_size, levelNdx);
37293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37308852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	TextureLevelPyramid::allocLevel(levelNdx, size, size, m_depth);
37313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
37323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37333c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& str, TextureFormat::ChannelOrder order)
37343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3735ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	const char* const orderStrings[] =
3736ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	{
3737ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"R",
3738ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"A",
3739ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"I",
3740ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"L",
3741ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"LA",
3742ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"RG",
3743ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"RA",
3744ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"RGB",
3745ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"RGBA",
3746ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"ARGB",
3747725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"BGR",
3748ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"BGRA",
3749ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi
375016d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		"sR",
375116d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		"sRG",
3752ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"sRGB",
3753ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"sRGBA",
3754725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"sBGR",
3755725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"sBGRA",
3756ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi
3757ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"D",
3758ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"S",
3759ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"DS"
3760ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	};
3761ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi
3762ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	return str << de::getSizedArrayElement<TextureFormat::CHANNELORDER_LAST>(orderStrings, order);
37633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
37643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37653c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& str, TextureFormat::ChannelType type)
37663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3767ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	const char* const typeStrings[] =
3768ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	{
3769ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"SNORM_INT8",
3770ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"SNORM_INT16",
3771ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"SNORM_INT32",
3772ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_INT8",
3773ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_INT16",
377407104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry		"UNORM_INT24",
3775ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_INT32",
3776725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"UNORM_BYTE_44",
3777ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_SHORT_565",
3778ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_SHORT_555",
3779ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_SHORT_4444",
3780ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_SHORT_5551",
37815b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos		"UNORM_SHORT_1555",
3782ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_INT_101010",
3783725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"SNORM_INT_1010102_REV",
3784ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_INT_1010102_REV",
3785725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"UNSIGNED_BYTE_44",
3786725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"UNSIGNED_SHORT_565",
3787725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"UNSIGNED_SHORT_4444",
3788725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"UNSIGNED_SHORT_5551",
3789725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"SIGNED_INT_1010102_REV",
3790ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT_1010102_REV",
3791ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT_11F_11F_10F_REV",
3792ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT_999_E5_REV",
3793725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"UNSIGNED_INT_16_8_8",
3794ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT_24_8",
3795725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"UNSIGNED_INT_24_8_REV",
3796ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"SIGNED_INT8",
3797ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"SIGNED_INT16",
3798ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"SIGNED_INT32",
3799ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT8",
3800ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT16",
3801db6ba452c1213fd1c2b03369fdf4c1d23f07cfadJarkko Pöyry		"UNSIGNED_INT24",
3802ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT32",
3803ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"HALF_FLOAT",
3804ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"FLOAT",
3805725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"FLOAT64",
3806ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"FLOAT_UNSIGNED_INT_24_8_REV"
3807ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	};
3808ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi
3809ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	return str << de::getSizedArrayElement<TextureFormat::CHANNELTYPE_LAST>(typeStrings, type);
38103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
38113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38123c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& str, CubeFace face)
38133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
38143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (face)
38153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
38163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_X:	return str << "CUBEFACE_NEGATIVE_X";
38173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_X:	return str << "CUBEFACE_POSITIVE_X";
38183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_Y:	return str << "CUBEFACE_NEGATIVE_Y";
38193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_Y:	return str << "CUBEFACE_POSITIVE_Y";
38203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_Z:	return str << "CUBEFACE_NEGATIVE_Z";
38213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_Z:	return str << "CUBEFACE_POSITIVE_Z";
38223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_LAST:			return str << "CUBEFACE_LAST";
38233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:					return str << "UNKNOWN(" << (int)face << ")";
38243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
38253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
38263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38273c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& str, TextureFormat format)
38283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
38293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return str << format.order << ", " << format.type << "";
38303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
38313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38323c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& str, const ConstPixelBufferAccess& access)
38333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
38343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return str << "format = (" << access.getFormat() << "), size = "
38353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			   << access.getWidth() << " x " << access.getHeight() << " x " << access.getDepth()
38363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			   << ", pitch = " << access.getRowPitch() << " / " << access.getSlicePitch();
38373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
38383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // tcu
3840