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
260fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärviinline deUint16 convertSatRteUint10 (float f)
261fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi{
262fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi	const deUint16 rounded		= convertSatRte<deUint16>(f);
263fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi	const deUint16 maxUint10	= 0x3FFu;
264fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi	return de::min(rounded, maxUint10);
265fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi}
266fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi
267fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärviinline deUint16 convertSatRteUint12 (float f)
268fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi{
269fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi	const deUint16 rounded		= convertSatRte<deUint16>(f);
270fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi	const deUint16 maxUint12	= 0xFFFu;
271fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi	return de::min(rounded, maxUint12);
272fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi}
273fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline float channelToFloat (const deUint8* value, TextureFormat::ChannelType type)
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27607104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	// make sure this table is updated if format table is updated
277fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 40);
27807104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (type)
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT8:			return de::max(-1.0f, (float)*((const deInt8*)value) / 127.0f);
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT16:		return de::max(-1.0f, (float)*((const deInt16*)value) / 32767.0f);
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT32:		return de::max(-1.0f, (float)*((const deInt32*)value) / 2147483647.0f);
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT8:			return (float)*((const deUint8*)value) / 255.0f;
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT16:		return (float)*((const deUint16*)value) / 65535.0f;
28607104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry		case TextureFormat::UNORM_INT24:		return (float)readUint24(value) / 16777215.0f;
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT32:		return (float)*((const deUint32*)value) / 4294967295.0f;
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT8:		return (float)*((const deInt8*)value);
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT16:		return (float)*((const deInt16*)value);
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT32:		return (float)*((const deInt32*)value);
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT8:		return (float)*((const deUint8*)value);
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT16:		return (float)*((const deUint16*)value);
293db6ba452c1213fd1c2b03369fdf4c1d23f07cfadJarkko Pöyry		case TextureFormat::UNSIGNED_INT24:		return (float)readUint24(value);
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT32:		return (float)*((const deUint32*)value);
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::HALF_FLOAT:			return deFloat16To32(*(const deFloat16*)value);
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT:				return *((const float*)value);
297725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::FLOAT64:			return (float)*((const double*)value);
298fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi		case TextureFormat::UNORM_SHORT_10:		return (float)((*((const deUint16*)value)) >> 6u) / 1023.0f;
299fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi		case TextureFormat::UNORM_SHORT_12:		return (float)((*((const deUint16*)value)) >> 4u) / 4095.0f;
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int channelToInt (const deUint8* value, TextureFormat::ChannelType type)
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30807104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	// make sure this table is updated if format table is updated
309fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 40);
31007104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (type)
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT8:			return (int)*((const deInt8*)value);
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT16:		return (int)*((const deInt16*)value);
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT32:		return (int)*((const deInt32*)value);
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT8:			return (int)*((const deUint8*)value);
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT16:		return (int)*((const deUint16*)value);
31807104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry		case TextureFormat::UNORM_INT24:		return (int)readUint24(value);
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT32:		return (int)*((const deUint32*)value);
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT8:		return (int)*((const deInt8*)value);
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT16:		return (int)*((const deInt16*)value);
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT32:		return (int)*((const deInt32*)value);
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT8:		return (int)*((const deUint8*)value);
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT16:		return (int)*((const deUint16*)value);
325db6ba452c1213fd1c2b03369fdf4c1d23f07cfadJarkko Pöyry		case TextureFormat::UNSIGNED_INT24:		return (int)readUint24(value);
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT32:		return (int)*((const deUint32*)value);
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::HALF_FLOAT:			return (int)deFloat16To32(*(const deFloat16*)value);
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT:				return (int)*((const float*)value);
329725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::FLOAT64:			return (int)*((const double*)value);
330fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi		case TextureFormat::UNORM_SHORT_10:		return (int)((*(((const deUint16*)value))) >> 6u);
331fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi		case TextureFormat::UNORM_SHORT_12:		return (int)((*(((const deUint16*)value))) >> 4u);
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0;
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid floatToChannel (deUint8* dst, float src, TextureFormat::ChannelType type)
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34007104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	// make sure this table is updated if format table is updated
341fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 40);
34207104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (type)
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
345fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi		case TextureFormat::SNORM_INT8:			*((deInt8*)dst)			= convertSatRte<deInt8>		(src * 127.0f);				break;
346fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi		case TextureFormat::SNORM_INT16:		*((deInt16*)dst)		= convertSatRte<deInt16>	(src * 32767.0f);			break;
347fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi		case TextureFormat::SNORM_INT32:		*((deInt32*)dst)		= convertSatRte<deInt32>	(src * 2147483647.0f);		break;
348fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi		case TextureFormat::UNORM_INT8:			*((deUint8*)dst)		= convertSatRte<deUint8>	(src * 255.0f);				break;
349fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi		case TextureFormat::UNORM_INT16:		*((deUint16*)dst)		= convertSatRte<deUint16>	(src * 65535.0f);			break;
350fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi		case TextureFormat::UNORM_INT24:		writeUint24(dst,		  convertSatRteUint24		(src * 16777215.0f));		break;
351fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi		case TextureFormat::UNORM_INT32:		*((deUint32*)dst)		= convertSatRte<deUint32>	(src * 4294967295.0f);		break;
352fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi		case TextureFormat::SIGNED_INT8:		*((deInt8*)dst)			= convertSatRte<deInt8>		(src);						break;
353fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi		case TextureFormat::SIGNED_INT16:		*((deInt16*)dst)		= convertSatRte<deInt16>	(src);						break;
354fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi		case TextureFormat::SIGNED_INT32:		*((deInt32*)dst)		= convertSatRte<deInt32>	(src);						break;
355fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi		case TextureFormat::UNSIGNED_INT8:		*((deUint8*)dst)		= convertSatRte<deUint8>	(src);						break;
356fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi		case TextureFormat::UNSIGNED_INT16:		*((deUint16*)dst)		= convertSatRte<deUint16>	(src);						break;
357fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi		case TextureFormat::UNSIGNED_INT24:		writeUint24(dst,		  convertSatRteUint24		(src));						break;
358fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi		case TextureFormat::UNSIGNED_INT32:		*((deUint32*)dst)		= convertSatRte<deUint32>	(src);						break;
359fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi		case TextureFormat::HALF_FLOAT:			*((deFloat16*)dst)		= deFloat32To16				(src);						break;
360fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi		case TextureFormat::FLOAT:				*((float*)dst)			= src;													break;
361fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi		case TextureFormat::FLOAT64:			*((double*)dst)			= (double)src;											break;
362fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi		case TextureFormat::UNORM_SHORT_10:		*((deUint16*)dst)		= (deUint16)(convertSatRteUint10(src * 1023.0f) << 6u);	break;
363fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi		case TextureFormat::UNORM_SHORT_12:		*((deUint16*)dst)		= (deUint16)(convertSatRteUint12(src * 4095.0f) << 4u);	break;
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, typename S>
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline T convertSat (S src)
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	S min = (S)std::numeric_limits<T>::min();
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	S max = (S)std::numeric_limits<T>::max();
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (src < min)
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return (T)min;
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (src > max)
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return (T)max;
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return (T)src;
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38307104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyrytemplate <typename S>
38407104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyrystatic inline deUint32 convertSatUint24 (S src)
38507104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry{
38607104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	S min = (S)0u;
38707104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	S max = (S)0xFFFFFFu;
38807104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
38907104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	if (src < min)
39007104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry		return (deUint32)min;
39107104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	else if (src > max)
39207104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry		return (deUint32)max;
39307104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	else
39407104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry		return (deUint32)src;
39507104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry}
39607104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
397fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvitemplate <typename S>
398fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvistatic inline deUint16 convertSatUint10 (S src)
399fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi{
400fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi	S min = (S)0u;
401fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi	S max = (S)0x3FFu;
402fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi
403fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi	if (src < min)
404fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi		return (deUint16)min;
405fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi	else if (src > max)
406fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi		return (deUint16)max;
407fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi	else
408fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi		return (deUint16)src;
409fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi}
410fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi
411fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvitemplate <typename S>
412fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvistatic inline deUint16 convertSatUint12 (S src)
413fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi{
414fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi	S min = (S)0u;
415fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi	S max = (S)0xFFFu;
416fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi
417fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi	if (src < min)
418fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi		return (deUint16)min;
419fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi	else if (src > max)
420fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi		return (deUint16)max;
421fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi	else
422fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi		return (deUint16)src;
423fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi}
424fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid intToChannel (deUint8* dst, int src, TextureFormat::ChannelType type)
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
42707104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	// make sure this table is updated if format table is updated
428fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 40);
42907104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (type)
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT8:			*((deInt8*)dst)			= convertSat<deInt8>	(src);				break;
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT16:		*((deInt16*)dst)		= convertSat<deInt16>	(src);				break;
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT8:			*((deUint8*)dst)		= convertSat<deUint8>	(src);				break;
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT16:		*((deUint16*)dst)		= convertSat<deUint16>	(src);				break;
436db6ba452c1213fd1c2b03369fdf4c1d23f07cfadJarkko Pöyry		case TextureFormat::UNORM_INT24:		writeUint24(dst,		  convertSatUint24		(src));				break;
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT8:		*((deInt8*)dst)			= convertSat<deInt8>	(src);				break;
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT16:		*((deInt16*)dst)		= convertSat<deInt16>	(src);				break;
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT32:		*((deInt32*)dst)		= convertSat<deInt32>	(src);				break;
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT8:		*((deUint8*)dst)		= convertSat<deUint8>	((deUint32)src);	break;
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT16:		*((deUint16*)dst)		= convertSat<deUint16>	((deUint32)src);	break;
442db6ba452c1213fd1c2b03369fdf4c1d23f07cfadJarkko Pöyry		case TextureFormat::UNSIGNED_INT24:		writeUint24(dst,		  convertSatUint24		((deUint32)src));	break;
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT32:		*((deUint32*)dst)		= convertSat<deUint32>	((deUint32)src);	break;
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::HALF_FLOAT:			*((deFloat16*)dst)		= deFloat32To16((float)src);				break;
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT:				*((float*)dst)			= (float)src;								break;
446725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::FLOAT64:			*((double*)dst)			= (double)src;								break;
447fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi		case TextureFormat::UNORM_SHORT_10:		*((deUint16*)dst)		= (deUint16)(convertSatUint10(src) << 6u);	break;
448fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi		case TextureFormat::UNORM_SHORT_12:		*((deUint16*)dst)		= (deUint16)(convertSatUint12(src) << 4u);	break;
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
454725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulosinline float channelToUnormFloat (deUint32 src, int bits)
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
456725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 maxVal = (1u << bits) - 1;
457725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
458725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	// \note Will lose precision if bits > 23
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (float)src / (float)maxVal;
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
462725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos//! Extend < 32b signed integer to 32b
463725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulosinline deInt32 signExtend (deUint32 src, int bits)
464725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos{
465725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 signBit = 1u << (bits-1);
466725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
467725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	src |= ~((src & signBit) - 1);
468725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
469725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	return (deInt32)src;
470725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos}
471725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
472725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulosinline float channelToSnormFloat (deUint32 src, int bits)
473725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos{
474725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32	range	= (1u << (bits-1)) - 1;
475725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
476725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	// \note Will lose precision if bits > 24
477725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	return de::max(-1.0f, (float)signExtend(src, bits) / (float)range);
478725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos}
479725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
480725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulosinline deUint32 unormFloatToChannel (float src, int bits)
481725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos{
482725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32	maxVal	= (1u << bits) - 1;
483725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32	intVal	= convertSatRte<deUint32>(src * (float)maxVal);
484725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
485725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	return de::min(intVal, maxVal);
486725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos}
487725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
488725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulosinline deUint32 snormFloatToChannel (float src, int bits)
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
490725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deInt32	range	= (deInt32)((1u << (bits-1)) - 1u);
491725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32	mask	= (1u << bits) - 1;
492725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deInt32	intVal	= convertSatRte<deInt32>(src * (float)range);
493725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
494725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	return (deUint32)de::clamp(intVal, -range, range) & mask;
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline deUint32 uintToChannel (deUint32 src, int bits)
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
499725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 maxVal = (1u << bits) - 1;
500725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	return de::min(src, maxVal);
501725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos}
502725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
503725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulosinline deUint32 intToChannel (deInt32 src, int bits)
504725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos{
505725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deInt32	minVal	= -(deInt32)(1u << (bits-1));
506725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deInt32	maxVal	= (deInt32)((1u << (bits-1)) - 1u);
507725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32	mask	= (1u << bits) - 1;
508725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
509725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	return (deUint32)de::clamp(src, minVal, maxVal) & mask;
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Vec4 unpackRGB999E5 (deUint32 color)
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	mBits	= 9;
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	eBias	= 15;
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32	exp		= color >> 27;
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32	bs		= (color >> 18) & ((1<<9)-1);
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32	gs		= (color >> 9) & ((1<<9)-1);
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32	rs		= color & ((1<<9)-1);
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		e		= deFloatPow(2.0f, (float)((int)exp - eBias - mBits));
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		r		= (float)rs * e;
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		g		= (float)gs * e;
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		b		= (float)bs * e;
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return tcu::Vec4(r, g, b, 1.0f);
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
53025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulosbool isColorOrder (TextureFormat::ChannelOrder order)
53125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos{
53225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	DE_STATIC_ASSERT(TextureFormat::CHANNELORDER_LAST == 21);
53325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
53425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	switch (order)
53525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	{
53625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::R:
53725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::A:
53825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::I:
53925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::L:
54025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::LA:
54125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::RG:
54225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::RA:
54325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::RGB:
54425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::RGBA:
54525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::ARGB:
54625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::BGR:
54725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::BGRA:
54825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::sR:
54925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::sRG:
55025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::sRGB:
55125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::sRGBA:
55225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::sBGR:
55325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::sBGRA:
55425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return true;
55525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
55625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		default:
55725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return false;
55825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	}
55925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos}
56025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
56325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulosbool isValid (TextureFormat format)
56425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos{
56525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	const bool	isColor	= isColorOrder(format.order);
56625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
56725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	switch (format.type)
56825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	{
56925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::SNORM_INT8:
57025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::SNORM_INT16:
57125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::SNORM_INT32:
57225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return isColor;
57325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
57425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_INT8:
57525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_INT16:
57625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_INT24:
57725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_INT32:
57825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return isColor || format.order == TextureFormat::D;
57925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
58025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_BYTE_44:
58125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_BYTE_44:
58225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return format.order == TextureFormat::RG;
58325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
58425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_SHORT_565:
58525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_SHORT_555:
58625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_565:
58725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return format.order == TextureFormat::RGB || format.order == TextureFormat::BGR;
58825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
58925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_SHORT_4444:
59025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_SHORT_5551:
59125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_4444:
59225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_5551:
59325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return format.order == TextureFormat::RGBA || format.order == TextureFormat::BGRA;
59425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
5955b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos		case TextureFormat::UNORM_SHORT_1555:
5965b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			return format.order == TextureFormat::ARGB;
5975b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos
59825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_INT_101010:
59925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return format.order == TextureFormat::RGB;
60025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
60125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::SNORM_INT_1010102_REV:
60225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_INT_1010102_REV:
60325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::SIGNED_INT_1010102_REV:
60425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT_1010102_REV:
60525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return format.order == TextureFormat::RGBA || format.order == TextureFormat::BGRA;
60625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
60725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
60825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT_999_E5_REV:
60925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return format.order == TextureFormat::RGB;
61025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
61125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT_16_8_8:
61225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return format.order == TextureFormat::DS;
61325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
61425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT_24_8:
61525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT_24_8_REV:
61625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return format.order == TextureFormat::D || format.order == TextureFormat::DS;
61725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
61825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::SIGNED_INT8:
61925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::SIGNED_INT16:
62025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::SIGNED_INT32:
62125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return isColor;
62225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
62325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT8:
62425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT16:
62525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT24:
62625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT32:
62725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return isColor || format.order == TextureFormat::S;
62825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
62925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::HALF_FLOAT:
63025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::FLOAT:
63125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::FLOAT64:
63225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return isColor || format.order == TextureFormat::D;
63325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
63425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
63525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return format.order == TextureFormat::DS;
63625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
637fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi		case TextureFormat::UNORM_SHORT_10:
638fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi		case TextureFormat::UNORM_SHORT_12:
639fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi			return isColor;
640fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi
64125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		default:
64225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			DE_FATAL("Unknown format");
64325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return 0u;
64425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	}
64525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
646fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 40);
64725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos}
64825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
649199c73a9eb28e6ef553e30bdf6b766198a65e796Kantochint getNumUsedChannels (TextureFormat::ChannelOrder order)
650199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch{
651199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch	// make sure this table is updated if type table is updated
652199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch	DE_STATIC_ASSERT(TextureFormat::CHANNELORDER_LAST == 21);
653199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch
654199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch	switch (order)
655199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch	{
656199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch		case TextureFormat::R:			return 1;
657199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch		case TextureFormat::A:			return 1;
658199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch		case TextureFormat::I:			return 1;
659199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch		case TextureFormat::L:			return 1;
660199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch		case TextureFormat::LA:			return 2;
661199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch		case TextureFormat::RG:			return 2;
662199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch		case TextureFormat::RA:			return 2;
663199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch		case TextureFormat::RGB:		return 3;
664199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch		case TextureFormat::RGBA:		return 4;
665199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch		case TextureFormat::ARGB:		return 4;
666199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch		case TextureFormat::BGR:		return 3;
667199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch		case TextureFormat::BGRA:		return 4;
668199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch		case TextureFormat::sR:			return 1;
669199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch		case TextureFormat::sRG:		return 2;
670199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch		case TextureFormat::sRGB:		return 3;
671199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch		case TextureFormat::sRGBA:		return 4;
672199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch		case TextureFormat::sBGR:		return 3;
673199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch		case TextureFormat::sBGRA:		return 4;
674199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch		case TextureFormat::D:			return 1;
675199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch		case TextureFormat::S:			return 1;
676199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch		case TextureFormat::DS:			return 2;
677199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch		default:
678199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch			DE_ASSERT(DE_FALSE);
679199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch			return 0;
680199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch	}
681199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch}
682199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch
683afa7d2831523587d80e5540ffb7f75adf418ce5fCollin Bakerint getChannelSize (TextureFormat::ChannelType type)
684afa7d2831523587d80e5540ffb7f75adf418ce5fCollin Baker{
685afa7d2831523587d80e5540ffb7f75adf418ce5fCollin Baker	// make sure this table is updated if format table is updated
686fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 40);
687afa7d2831523587d80e5540ffb7f75adf418ce5fCollin Baker
688afa7d2831523587d80e5540ffb7f75adf418ce5fCollin Baker	switch (type)
689afa7d2831523587d80e5540ffb7f75adf418ce5fCollin Baker	{
690afa7d2831523587d80e5540ffb7f75adf418ce5fCollin Baker		case TextureFormat::SNORM_INT8:			return 1;
691afa7d2831523587d80e5540ffb7f75adf418ce5fCollin Baker		case TextureFormat::SNORM_INT16:		return 2;
692afa7d2831523587d80e5540ffb7f75adf418ce5fCollin Baker		case TextureFormat::SNORM_INT32:		return 4;
693afa7d2831523587d80e5540ffb7f75adf418ce5fCollin Baker		case TextureFormat::UNORM_INT8:			return 1;
694afa7d2831523587d80e5540ffb7f75adf418ce5fCollin Baker		case TextureFormat::UNORM_INT16:		return 2;
695afa7d2831523587d80e5540ffb7f75adf418ce5fCollin Baker		case TextureFormat::UNORM_INT24:		return 3;
696afa7d2831523587d80e5540ffb7f75adf418ce5fCollin Baker		case TextureFormat::UNORM_INT32:		return 4;
697afa7d2831523587d80e5540ffb7f75adf418ce5fCollin Baker		case TextureFormat::SIGNED_INT8:		return 1;
698afa7d2831523587d80e5540ffb7f75adf418ce5fCollin Baker		case TextureFormat::SIGNED_INT16:		return 2;
699afa7d2831523587d80e5540ffb7f75adf418ce5fCollin Baker		case TextureFormat::SIGNED_INT32:		return 4;
700afa7d2831523587d80e5540ffb7f75adf418ce5fCollin Baker		case TextureFormat::UNSIGNED_INT8:		return 1;
701afa7d2831523587d80e5540ffb7f75adf418ce5fCollin Baker		case TextureFormat::UNSIGNED_INT16:		return 2;
702afa7d2831523587d80e5540ffb7f75adf418ce5fCollin Baker		case TextureFormat::UNSIGNED_INT24:		return 3;
703afa7d2831523587d80e5540ffb7f75adf418ce5fCollin Baker		case TextureFormat::UNSIGNED_INT32:		return 4;
704afa7d2831523587d80e5540ffb7f75adf418ce5fCollin Baker		case TextureFormat::HALF_FLOAT:			return 2;
705afa7d2831523587d80e5540ffb7f75adf418ce5fCollin Baker		case TextureFormat::FLOAT:				return 4;
706afa7d2831523587d80e5540ffb7f75adf418ce5fCollin Baker		case TextureFormat::FLOAT64:			return 8;
707fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi		case TextureFormat::UNORM_SHORT_10:		return 2;
708fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi		case TextureFormat::UNORM_SHORT_12:		return 2;
709afa7d2831523587d80e5540ffb7f75adf418ce5fCollin Baker		default:
710afa7d2831523587d80e5540ffb7f75adf418ce5fCollin Baker			DE_ASSERT(DE_FALSE);
711afa7d2831523587d80e5540ffb7f75adf418ce5fCollin Baker			return 0;
712afa7d2831523587d80e5540ffb7f75adf418ce5fCollin Baker	}
713afa7d2831523587d80e5540ffb7f75adf418ce5fCollin Baker}
714afa7d2831523587d80e5540ffb7f75adf418ce5fCollin Baker
71525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos/** Get pixel size in bytes. */
71625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulosint getPixelSize (TextureFormat format)
71725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos{
71825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	const TextureFormat::ChannelOrder	order	= format.order;
71925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	const TextureFormat::ChannelType	type	= format.type;
72025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
72125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	DE_ASSERT(isValid(format));
72225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
72325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	// make sure this table is updated if format table is updated
724fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 40);
72525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
72625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	switch (type)
72725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	{
72825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_BYTE_44:
72925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_BYTE_44:
73025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return 1;
73125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
73225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_SHORT_565:
73325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_SHORT_555:
73425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_SHORT_4444:
73525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_SHORT_5551:
7365b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos		case TextureFormat::UNORM_SHORT_1555:
73725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_565:
73825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_4444:
73925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_5551:
74025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return 2;
74125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
74225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_INT_101010:
74325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT_999_E5_REV:
74425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
74525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::SNORM_INT_1010102_REV:
74625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_INT_1010102_REV:
74725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::SIGNED_INT_1010102_REV:
74825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT_1010102_REV:
74925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT_24_8:
75025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT_24_8_REV:
75125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT_16_8_8:
75225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return 4;
75325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
75425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
75525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return 8;
75625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
75725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		default:
75825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return getNumUsedChannels(order) * getChannelSize(type);
75925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	}
76025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos}
76125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
76225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulosint TextureFormat::getPixelSize (void) const
76325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos{
76425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	return ::tcu::getPixelSize(*this);
76525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos}
76625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
7676d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyryconst TextureSwizzle& getChannelReadSwizzle (TextureFormat::ChannelOrder order)
7686d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry{
7696d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	// make sure to update these tables when channel orders are updated
770725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	DE_STATIC_ASSERT(TextureFormat::CHANNELORDER_LAST == 21);
7716d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
7726d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle INV		= {{ TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ONE	}};
7736d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle R		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ONE	}};
7746d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle A		= {{ TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_0	}};
7756d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle I		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0	}};
7766d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle L		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ONE	}};
7776d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle LA		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1	}};
7786d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RG		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ONE	}};
7796d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RA		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_1	}};
7806d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RGB		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_ONE	}};
7816d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RGBA	= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_3	}};
782725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	static const TextureSwizzle BGR		= {{ TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ONE	}};
7836d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle BGRA	= {{ TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_3	}};
7846d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle ARGB	= {{ TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_3,		TextureSwizzle::CHANNEL_0	}};
7856d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle D		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ONE	}};
78609037a4653649d707449463dfe9817a78ccf7d2fJarkko Pöyry	static const TextureSwizzle S		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ONE	}};
7876d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
7886d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	switch (order)
7896d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	{
7906d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::R:			return R;
7916d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::A:			return A;
7926d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::I:			return I;
7936d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::L:			return L;
7946d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::LA:			return LA;
7956d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RG:			return RG;
7966d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RA:			return RA;
7976d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RGB:		return RGB;
7986d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RGBA:		return RGBA;
7996d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::ARGB:		return ARGB;
800725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::BGR:		return BGR;
8016d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::BGRA:		return BGRA;
80216d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		case TextureFormat::sR:			return R;
80316d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		case TextureFormat::sRG:		return RG;
8046d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::sRGB:		return RGB;
8056d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::sRGBA:		return RGBA;
806725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::sBGR:		return BGR;
807725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::sBGRA:		return BGRA;
8086d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::D:			return D;
8096d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::S:			return S;
8108baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry
8118baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry		case TextureFormat::DS:
8128baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			DE_ASSERT(false); // combined formats cannot be read from
8138baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			return INV;
8148baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry
8156d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		default:
8166d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			DE_ASSERT(DE_FALSE);
8176d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			return INV;
8186d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	}
8196d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry}
8206d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
8216d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyryconst TextureSwizzle& getChannelWriteSwizzle (TextureFormat::ChannelOrder order)
8226d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry{
8236d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	// make sure to update these tables when channel orders are updated
824725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	DE_STATIC_ASSERT(TextureFormat::CHANNELORDER_LAST == 21);
8256d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
8266d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle INV		= {{ TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
8276d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle R		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
8286d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle A		= {{ TextureSwizzle::CHANNEL_3,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
8296d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle I		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
8306d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle L		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
8316d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle LA		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_3,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
8326d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RG		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
8336d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RA		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_3,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
8346d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RGB		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_LAST	}};
8356d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RGBA	= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_3		}};
836725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	static const TextureSwizzle BGR		= {{ TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_LAST	}};
8376d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle BGRA	= {{ TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_3		}};
8386d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle ARGB	= {{ TextureSwizzle::CHANNEL_3,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_2		}};
8396d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle D		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
84009037a4653649d707449463dfe9817a78ccf7d2fJarkko Pöyry	static const TextureSwizzle S		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
8416d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
8426d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	switch (order)
8436d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	{
8446d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::R:			return R;
8456d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::A:			return A;
8466d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::I:			return I;
8476d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::L:			return L;
8486d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::LA:			return LA;
8496d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RG:			return RG;
8506d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RA:			return RA;
8516d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RGB:		return RGB;
8526d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RGBA:		return RGBA;
8536d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::ARGB:		return ARGB;
854725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::BGR:		return BGR;
8556d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::BGRA:		return BGRA;
85616d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		case TextureFormat::sR:			return R;
85716d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		case TextureFormat::sRG:		return RG;
8586d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::sRGB:		return RGB;
8596d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::sRGBA:		return RGBA;
860725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::sBGR:		return BGR;
861725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::sBGRA:		return BGRA;
8626d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::D:			return D;
8636d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::S:			return S;
8648baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry
8658baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry		case TextureFormat::DS:
8668baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			DE_ASSERT(false); // combined formats cannot be written to
8678baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			return INV;
8688baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry
8696d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		default:
8706d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			DE_ASSERT(DE_FALSE);
8716d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			return INV;
8726d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	}
8736d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry}
8746d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
87529340067e919854db7d50bb8c0b666117b229f5eMika IsojärviIVec3 calculatePackedPitch (const TextureFormat& format, const IVec3& size)
87629340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi{
87729340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	const int pixelSize		= format.getPixelSize();
87829340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	const int rowPitch		= pixelSize * size.x();
87929340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	const int slicePitch	= rowPitch * size.y();
88029340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
88129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	return IVec3(pixelSize, rowPitch, slicePitch);
88229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi}
88329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
8843c827367444ee418f129b2c238299f49d3264554Jarkko PoyryConstPixelBufferAccess::ConstPixelBufferAccess (void)
88529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	: m_size		(0)
88629340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_pitch		(0)
8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_data		(DE_NULL)
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8913c827367444ee418f129b2c238299f49d3264554Jarkko PoyryConstPixelBufferAccess::ConstPixelBufferAccess (const TextureFormat& format, int width, int height, int depth, const void* data)
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format		(format)
89329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size		(width, height, depth)
89429340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_pitch		(calculatePackedPitch(m_format, m_size))
89529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_data		((void*)data)
89629340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi{
89725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	DE_ASSERT(isValid(format));
89829340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi}
89929340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
90029340067e919854db7d50bb8c0b666117b229f5eMika IsojärviConstPixelBufferAccess::ConstPixelBufferAccess (const TextureFormat& format, const IVec3& size, const void* data)
90129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	: m_format		(format)
90229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size		(size)
90329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_pitch		(calculatePackedPitch(m_format, m_size))
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_data		((void*)data)
9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
90625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	DE_ASSERT(isValid(format));
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9093c827367444ee418f129b2c238299f49d3264554Jarkko PoyryConstPixelBufferAccess::ConstPixelBufferAccess (const TextureFormat& format, int width, int height, int depth, int rowPitch, int slicePitch, const void* data)
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format		(format)
91129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size		(width, height, depth)
91229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_pitch		(format.getPixelSize(), rowPitch, slicePitch)
91329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_data		((void*)data)
91429340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi{
91525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	DE_ASSERT(isValid(format));
91629340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi}
91729340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
91829340067e919854db7d50bb8c0b666117b229f5eMika IsojärviConstPixelBufferAccess::ConstPixelBufferAccess (const TextureFormat& format, const IVec3& size, const IVec3& pitch, const void* data)
91929340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	: m_format		(format)
92029340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size		(size)
92129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_pitch		(pitch)
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_data		((void*)data)
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
92425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	DE_ASSERT(isValid(format));
92529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(m_format.getPixelSize() <= m_pitch.x());
9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9283c827367444ee418f129b2c238299f49d3264554Jarkko PoyryConstPixelBufferAccess::ConstPixelBufferAccess (const TextureLevel& level)
9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format		(level.getFormat())
93029340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size		(level.getSize())
93129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_pitch		(calculatePackedPitch(m_format, m_size))
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_data		((void*)level.getPtr())
9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9363c827367444ee418f129b2c238299f49d3264554Jarkko PoyryPixelBufferAccess::PixelBufferAccess (const TextureFormat& format, int width, int height, int depth, void* data)
9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: ConstPixelBufferAccess(format, width, height, depth, data)
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
94129340067e919854db7d50bb8c0b666117b229f5eMika IsojärviPixelBufferAccess::PixelBufferAccess (const TextureFormat& format, const IVec3& size, void* data)
94229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	: ConstPixelBufferAccess(format, size, data)
94329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi{
94429340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi}
94529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
9463c827367444ee418f129b2c238299f49d3264554Jarkko PoyryPixelBufferAccess::PixelBufferAccess (const TextureFormat& format, int width, int height, int depth, int rowPitch, int slicePitch, void* data)
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: ConstPixelBufferAccess(format, width, height, depth, rowPitch, slicePitch, data)
9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
95129340067e919854db7d50bb8c0b666117b229f5eMika IsojärviPixelBufferAccess::PixelBufferAccess (const TextureFormat& format, const IVec3& size, const IVec3& pitch, void* data)
95229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	: ConstPixelBufferAccess(format, size, pitch, data)
95329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi{
95429340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi}
95529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
9563c827367444ee418f129b2c238299f49d3264554Jarkko PoyryPixelBufferAccess::PixelBufferAccess (TextureLevel& level)
9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: ConstPixelBufferAccess(level)
9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
961725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos//! Swizzle RGB(A) <-> BGR(A)
962725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulostemplate<typename T>
963725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry HaulosVector<T, 4> swizzleRB (const Vector<T, 4>& v, TextureFormat::ChannelOrder src, TextureFormat::ChannelOrder dst)
964725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos{
965725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	if (src == dst)
966725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		return v;
967725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	else
968725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	{
969725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		DE_ASSERT((src == TextureFormat::RGB && dst == TextureFormat::BGR) ||
970725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos				  (src == TextureFormat::BGR && dst == TextureFormat::RGB) ||
971725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos				  (src == TextureFormat::RGBA && dst == TextureFormat::BGRA) ||
972725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos				  (src == TextureFormat::BGRA && dst == TextureFormat::RGBA));
973725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		return v.swizzle(2,1,0,3);
974725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	}
975725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos}
976725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
9773c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 ConstPixelBufferAccess::getPixel (int x, int y, int z) const
9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
97929340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(x, 0, m_size.x()));
98029340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(y, 0, m_size.y()));
98129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(z, 0, m_size.z()));
9828baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	DE_ASSERT(!isCombinedDepthStencilType(m_format.type)); // combined types cannot be accessed directly
9838baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	DE_ASSERT(m_format.order != TextureFormat::DS); // combined formats cannot be accessed directly
98429340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
9858baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	const deUint8* pixelPtr = (const deUint8*)getPixelPtr(x, y, z);
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Optimized fomats.
9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_format.type == TextureFormat::UNORM_INT8)
9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9900158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		if (m_format.order == TextureFormat::RGBA || m_format.order == TextureFormat::sRGBA)
99129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi			return readRGBA8888Float(pixelPtr);
9920158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		else if (m_format.order == TextureFormat::RGB || m_format.order == TextureFormat::sRGB)
99329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi			return readRGB888Float(pixelPtr);
9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
996725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define UI8(OFFS, COUNT)		((*((const deUint8*)pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1))
997725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define UI16(OFFS, COUNT)		((*((const deUint16*)pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1))
998725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define UI32(OFFS, COUNT)		((*((const deUint32*)pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1))
999725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define SI32(OFFS, COUNT)		signExtend(UI32(OFFS, COUNT), (COUNT))
1000725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define UN8(OFFS, COUNT)		channelToUnormFloat(UI8 (OFFS, COUNT), (COUNT))
1001725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define UN16(OFFS, COUNT)		channelToUnormFloat(UI16(OFFS, COUNT), (COUNT))
1002725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define UN32(OFFS, COUNT)		channelToUnormFloat(UI32(OFFS, COUNT), (COUNT))
1003725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define SN32(OFFS, COUNT)		channelToSnormFloat(UI32(OFFS, COUNT), (COUNT))
10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Packed formats.
10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1008725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_BYTE_44:				return			  Vec4(UN8 (4,   4), UN8 ( 0,  4), 0.0f, 1.0f);
1009725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_BYTE_44:			return			 UVec4(UI8 (4,   4), UI8 ( 0,  4), 0u, 1u).cast<float>();
10105b2b45177edf5062ce3a76a885e60e3fb5044002Pyry 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);
10115b2b45177edf5062ce3a76a885e60e3fb5044002Pyry 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>();
10125b2b45177edf5062ce3a76a885e60e3fb5044002Pyry 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);
10135b2b45177edf5062ce3a76a885e60e3fb5044002Pyry 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);
10145b2b45177edf5062ce3a76a885e60e3fb5044002Pyry 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>();
10155b2b45177edf5062ce3a76a885e60e3fb5044002Pyry 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);
10165b2b45177edf5062ce3a76a885e60e3fb5044002Pyry 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>();
1017725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_INT_101010:			return			  Vec4(UN32(22, 10), UN32(12, 10), UN32( 2, 10), 1.0f);
10185b2b45177edf5062ce3a76a885e60e3fb5044002Pyry 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);
10195b2b45177edf5062ce3a76a885e60e3fb5044002Pyry 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);
10205b2b45177edf5062ce3a76a885e60e3fb5044002Pyry 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>();
10215b2b45177edf5062ce3a76a885e60e3fb5044002Pyry 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>();
10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_999_E5_REV:	return unpackRGB999E5(*((const deUint32*)pixelPtr));
10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10245b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos		case TextureFormat::UNORM_SHORT_1555:
10255b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::ARGB);
10265b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			return Vec4(UN16(15, 1), UN16(10, 5), UN16(5, 5), UN16(0, 5)).swizzle(1,2,3,0); // ARGB -> RGBA
10275b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos
10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
1029725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			return Vec4(Float11(UI32(0, 11)).asFloat(), Float11(UI32(11, 11)).asFloat(), Float10(UI32(22, 10)).asFloat(), 1.0f);
10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1035725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef UN8
1036725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef UN16
1037725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef UN32
1038725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef SN32
1039725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef SI32
1040725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef UI8
1041725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef UI16
1042725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef UI32
10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generic path.
10456d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	Vec4							result;
10466d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	const TextureSwizzle::Channel*	channelMap	= getChannelReadSwizzle(m_format.order).components;
10476d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	int								channelSize	= getChannelSize(m_format.type);
10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int c = 0; c < 4; c++)
10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10516d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		switch (channelMap[c])
10526d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		{
10536d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_0:
10546d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_1:
10556d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_2:
10566d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_3:
10576d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				result[c] = channelToFloat(pixelPtr + channelSize*((int)channelMap[c]), m_format.type);
10586d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				break;
10596d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
10606d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_ZERO:
10616d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				result[c] = 0.0f;
10626d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				break;
10636d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
10646d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_ONE:
10656d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				result[c] = 1.0f;
10666d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				break;
10676d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
10686d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			default:
10696d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				DE_ASSERT(false);
10706d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		}
10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10763c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIVec4 ConstPixelBufferAccess::getPixelInt (int x, int y, int z) const
10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
107829340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(x, 0, m_size.x()));
107929340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(y, 0, m_size.y()));
108029340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(z, 0, m_size.z()));
10818baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	DE_ASSERT(!isCombinedDepthStencilType(m_format.type)); // combined types cannot be accessed directly
10828baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	DE_ASSERT(m_format.order != TextureFormat::DS); // combined formats cannot be accessed directly
10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10848baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	const deUint8* const	pixelPtr = (const deUint8*)getPixelPtr(x, y, z);
108507104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	IVec4					result;
10863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Optimized fomats.
10883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_format.type == TextureFormat::UNORM_INT8)
10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10900158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		if (m_format.order == TextureFormat::RGBA || m_format.order == TextureFormat::sRGBA)
10910158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi			return readRGBA8888Int(pixelPtr);
10920158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		else if (m_format.order == TextureFormat::RGB || m_format.order == TextureFormat::sRGB)
10930158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi			return readRGB888Int(pixelPtr);
10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1096725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define U8(OFFS, COUNT)			((*((const deUint8* )pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1))
10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define U16(OFFS, COUNT)		((*((const deUint16*)pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1))
10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define U32(OFFS, COUNT)		((*((const deUint32*)pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1))
1099725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define S32(OFFS, COUNT)		signExtend(U32(OFFS, COUNT), (COUNT))
11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1103725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_BYTE_44:			// Fall-through
1104725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_BYTE_44:				return			 UVec4(U8 ( 4,  4), U8 ( 0,  4), 0u, 1u).cast<int>();
1105725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_565:			// Fall-through
11065b2b45177edf5062ce3a76a885e60e3fb5044002Pyry 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);
11075b2b45177edf5062ce3a76a885e60e3fb5044002Pyry 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);
1108725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_4444:		// Fall-through
11095b2b45177edf5062ce3a76a885e60e3fb5044002Pyry 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);
1110725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_5551:		// Fall-through
11115b2b45177edf5062ce3a76a885e60e3fb5044002Pyry 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);
1112725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_INT_101010:			return			 UVec4(U32(22, 10), U32(12, 10), U32( 2, 10), 1).cast<int>();
1113725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_INT_1010102_REV:		// Fall-through
11145b2b45177edf5062ce3a76a885e60e3fb5044002Pyry 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>();
1115725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::SNORM_INT_1010102_REV:		// Fall-through
11165b2b45177edf5062ce3a76a885e60e3fb5044002Pyry 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);
11175b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos
11185b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos		case TextureFormat::UNORM_SHORT_1555:
11195b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::ARGB);
11205b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			return UVec4(U16(15, 1), U16(10, 5), U16(5, 5), U16(0, 5)).cast<int>().swizzle(1,2,3,0); // ARGB -> RGBA
11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break; // To generic path.
11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1126725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef U8
11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef U16
11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef U32
1129725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef S32
11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generic path.
11326d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	const TextureSwizzle::Channel*	channelMap	= getChannelReadSwizzle(m_format.order).components;
11336d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	int								channelSize	= getChannelSize(m_format.type);
11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int c = 0; c < 4; c++)
11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11376d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		switch (channelMap[c])
11386d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		{
11396d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_0:
11406d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_1:
11416d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_2:
11426d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_3:
11436d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				result[c] = channelToInt(pixelPtr + channelSize*((int)channelMap[c]), m_format.type);
11446d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				break;
11456d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
11466d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_ZERO:
11476d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				result[c] = 0;
11486d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				break;
11496d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
11506d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_ONE:
11516d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				result[c] = 1;
11526d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				break;
11536d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
11546d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			default:
11556d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				DE_ASSERT(false);
11566d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		}
11573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
11603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<>
11633c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 ConstPixelBufferAccess::getPixelT (int x, int y, int z) const
11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return getPixel(x, y, z);
11663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11683c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<>
11693c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIVec4 ConstPixelBufferAccess::getPixelT (int x, int y, int z) const
11703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return getPixelInt(x, y, z);
11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<>
11753c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUVec4 ConstPixelBufferAccess::getPixelT (int x, int y, int z) const
11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return getPixelUint(x, y, z);
11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat ConstPixelBufferAccess::getPixDepth (int x, int y, int z) const
11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(x, 0, getWidth()));
11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(y, 0, getHeight()));
11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(z, 0, getDepth()));
11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11868baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	const deUint8* const pixelPtr = (const deUint8*)getPixelPtr(x, y, z);
11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1190725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_16_8_8:
119100d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::DS);
1192725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			return (float)readUint32High16(pixelPtr) / 65535.0f;
119374a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi
119400d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos		case TextureFormat::UNSIGNED_INT_24_8:
1195725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::D || m_format.order == TextureFormat::DS);
119600d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			return (float)readUint32High24(pixelPtr) / 16777215.0f;
11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1198725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_24_8_REV:
1199725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::D || m_format.order == TextureFormat::DS);
1200725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			return (float)readUint32Low24(pixelPtr) / 16777215.0f;
1201725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
12023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_format.order == TextureFormat::DS);
12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return *((const float*)pixelPtr);
12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
12078baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			DE_ASSERT(m_format.order == TextureFormat::D); // no other combined depth stencil types
12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return channelToFloat(pixelPtr, m_format.type);
12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12123c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint ConstPixelBufferAccess::getPixStencil (int x, int y, int z) const
12133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(x, 0, getWidth()));
12153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(y, 0, getHeight()));
12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(z, 0, getDepth()));
12173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12188baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	const deUint8* const pixelPtr = (const deUint8*)getPixelPtr(x, y, z);
12193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
12213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1222725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_24_8_REV:
122300d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::DS);
1224725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			return (int)readUint32High8(pixelPtr);
122500d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos
1226725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_16_8_8:
12273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_24_8:
122800d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::DS);
122900d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			return (int)readUint32Low8(pixelPtr);
12303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
12323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_format.order == TextureFormat::DS);
123374a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi			return (int)readUint32Low8(pixelPtr + 4);
12343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
12363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12378baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			DE_ASSERT(m_format.order == TextureFormat::S); // no other combined depth stencil types
12388baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			return channelToInt(pixelPtr, m_format.type);
12393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12433c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PixelBufferAccess::setPixel (const Vec4& color, int x, int y, int z) const
12443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(x, 0, getWidth()));
12463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(y, 0, getHeight()));
12473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(z, 0, getDepth()));
12488baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	DE_ASSERT(!isCombinedDepthStencilType(m_format.type)); // combined types cannot be accessed directly
12498baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	DE_ASSERT(m_format.order != TextureFormat::DS); // combined formats cannot be accessed directly
12503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12518baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	deUint8* const pixelPtr = (deUint8*)getPixelPtr(x, y, z);
125229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
12533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Optimized fomats.
12543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_format.type == TextureFormat::UNORM_INT8)
12553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12560158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		if (m_format.order == TextureFormat::RGBA || m_format.order == TextureFormat::sRGBA)
12573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
125829340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi			writeRGBA8888Float(pixelPtr, color);
12593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return;
12603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12610158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		else if (m_format.order == TextureFormat::RGB || m_format.order == TextureFormat::sRGB)
12623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
126329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi			writeRGB888Float(pixelPtr, color);
12643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return;
12653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1268725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define PN(VAL, OFFS, BITS)		(unormFloatToChannel((VAL), (BITS)) << (OFFS))
1269725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define PS(VAL, OFFS, BITS)		(snormFloatToChannel((VAL), (BITS)) << (OFFS))
12703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define PU(VAL, OFFS, BITS)		(uintToChannel((VAL), (BITS)) << (OFFS))
1271725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define PI(VAL, OFFS, BITS)		(intToChannel((VAL), (BITS)) << (OFFS))
12723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
12743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1275725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_BYTE_44:		*((deUint8 *)pixelPtr) = (deUint8)(PN(color[0], 4, 4) | PN(color[1], 0, 4));						break;
1276725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_BYTE_44:	*((deUint8 *)pixelPtr) = (deUint8)(PU((deUint32)color[0], 4, 4) | PU((deUint32)color[1], 0, 4));	break;
1277725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_INT_101010:	*((deUint32*)pixelPtr) = PN(color[0], 22, 10) | PN(color[1], 12, 10) | PN(color[2], 2, 10);			break;
1278725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1279725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_565:
1280725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
12815b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			const Vec4 swizzled = swizzleRB(color, TextureFormat::RGB, m_format.order);
1282725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PN(swizzled[0], 11, 5) | PN(swizzled[1], 5, 6) | PN(swizzled[2], 0, 5));
1283725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1284725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1285725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1286725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_565:
1287725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
12885b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			const UVec4 swizzled = swizzleRB(color.cast<deUint32>(), TextureFormat::RGB, m_format.order);
1289725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PU(swizzled[0], 11, 5) | PU(swizzled[1], 5, 6) | PU(swizzled[2], 0, 5));
1290725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1291725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1292725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1293725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_555:
1294725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
12955b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			const Vec4 swizzled = swizzleRB(color, TextureFormat::RGB, m_format.order);
1296725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PN(swizzled[0], 10, 5) | PN(swizzled[1], 5, 5) | PN(swizzled[2], 0, 5));
1297725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1298725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1299725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1300725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_4444:
1301725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
13025b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			const Vec4 swizzled = swizzleRB(color, TextureFormat::RGBA, m_format.order);
1303725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PN(swizzled[0], 12, 4) | PN(swizzled[1], 8, 4) | PN(swizzled[2], 4, 4) | PN(swizzled[3], 0, 4));
1304725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1305725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1306725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1307725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_4444:
1308725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
13095b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			const UVec4 swizzled = swizzleRB(color.cast<deUint32>(), TextureFormat::RGBA, m_format.order);
1310725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PU(swizzled[0], 12, 4) | PU(swizzled[1], 8, 4) | PU(swizzled[2], 4, 4) | PU(swizzled[3], 0, 4));
1311725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1312725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1313725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1314725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_5551:
1315725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
13165b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			const Vec4 swizzled = swizzleRB(color, TextureFormat::RGBA, m_format.order);
1317725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PN(swizzled[0], 11, 5) | PN(swizzled[1], 6, 5) | PN(swizzled[2], 1, 5) | PN(swizzled[3], 0, 1));
1318725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1319725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1320725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
13215b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos		case TextureFormat::UNORM_SHORT_1555:
13225b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos		{
13235b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			const Vec4 swizzled = color.swizzle(3,0,1,2); // RGBA -> ARGB
13245b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PN(swizzled[0], 15, 1) | PN(swizzled[1], 10, 5) | PN(swizzled[2], 5, 5) | PN(swizzled[3], 0, 5));
13255b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			break;
13265b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos		}
13275b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos
1328725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_5551:
1329725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
13305b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			const UVec4 swizzled = swizzleRB(color.cast<deUint32>(), TextureFormat::RGBA, m_format.order);
1331725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PU(swizzled[0], 11, 5) | PU(swizzled[1], 6, 5) | PU(swizzled[2], 1, 5) | PU(swizzled[3], 0, 1));
1332725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1333725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1334725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1335725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_INT_1010102_REV:
1336725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
13375b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			const Vec4 u = swizzleRB(color, TextureFormat::RGBA, m_format.order);
1338725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint32*)pixelPtr) = PN(u[0], 0, 10) | PN(u[1], 10, 10) | PN(u[2], 20, 10) | PN(u[3], 30, 2);
1339725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1340725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1341725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1342725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::SNORM_INT_1010102_REV:
1343725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
13445b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			const Vec4 u = swizzleRB(color, TextureFormat::RGBA, m_format.order);
1345725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint32*)pixelPtr) = PS(u[0], 0, 10) | PS(u[1], 10, 10) | PS(u[2], 20, 10) | PS(u[3], 30, 2);
1346725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1347725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
13483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_1010102_REV:
13503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13515b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			const UVec4 u = swizzleRB(color.cast<deUint32>(), TextureFormat::RGBA, m_format.order);
1352725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint32*)pixelPtr) = PU(u[0], 0, 10) | PU(u[1], 10, 10) | PU(u[2], 20, 10) | PU(u[3], 30, 2);
1353725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1354725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1355725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1356725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::SIGNED_INT_1010102_REV:
1357725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
13585b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			const IVec4 u = swizzleRB(color.cast<deInt32>(), TextureFormat::RGBA, m_format.order);
1359725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint32*)pixelPtr) = PI(u[0], 0, 10) | PI(u[1], 10, 10) | PI(u[2], 20, 10) | PI(u[3], 30, 2);
13603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
13613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
13643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			*((deUint32*)pixelPtr) = Float11(color[0]).bits() | (Float11(color[1]).bits() << 11) | (Float10(color[2]).bits() << 22);
13653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
13663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_999_E5_REV:
13683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			*((deUint32*)pixelPtr) = packRGB999E5(color);
13693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
13703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
13723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Generic path.
13746d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			int								numChannels	= getNumUsedChannels(m_format.order);
13756d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			const TextureSwizzle::Channel*	map			= getChannelWriteSwizzle(m_format.order).components;
13766d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			int								channelSize	= getChannelSize(m_format.type);
13773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int c = 0; c < numChannels; c++)
13796d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			{
13806d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				DE_ASSERT(deInRange32(map[c], TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3));
13813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				floatToChannel(pixelPtr + channelSize*c, color[map[c]], m_format.type);
13826d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			}
13833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
13843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef PN
1388725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef PS
13893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef PU
1390725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef PI
13913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13933c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PixelBufferAccess::setPixel (const IVec4& color, int x, int y, int z) const
13943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(x, 0, getWidth()));
13963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(y, 0, getHeight()));
13973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(z, 0, getDepth()));
13988baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	DE_ASSERT(!isCombinedDepthStencilType(m_format.type)); // combined types cannot be accessed directly
13998baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	DE_ASSERT(m_format.order != TextureFormat::DS); // combined formats cannot be accessed directly
14003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14018baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	deUint8* const pixelPtr = (deUint8*)getPixelPtr(x, y, z);
14023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Optimized fomats.
14043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_format.type == TextureFormat::UNORM_INT8)
14053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14060158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		if (m_format.order == TextureFormat::RGBA || m_format.order == TextureFormat::sRGBA)
14070158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		{
14080158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi			writeRGBA8888Int(pixelPtr, color);
14090158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi			return;
14100158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		}
14110158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		else if (m_format.order == TextureFormat::RGB || m_format.order == TextureFormat::sRGB)
14120158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		{
14130158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi			writeRGB888Int(pixelPtr, color);
14140158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi			return;
14150158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		}
14163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define PU(VAL, OFFS, BITS)		(uintToChannel((deUint32)(VAL), (BITS)) << (OFFS))
1419725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define PI(VAL, OFFS, BITS)		(intToChannel((deUint32)(VAL), (BITS)) << (OFFS))
14203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
14223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1423725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_BYTE_44:	// Fall-through
1424725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_BYTE_44:		*((deUint8 *)pixelPtr) = (deUint8 )(PU(color[0],  4, 4) | PU(color[1], 0, 4));				break;
1425725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_INT_101010:	*((deUint32*)pixelPtr) = PU(color[0], 22, 10) | PU(color[1], 12, 10) | PU(color[2], 2, 10);	break;
1426725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1427725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_565:
1428725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_565:
1429725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
14305b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			const IVec4 swizzled = swizzleRB(color, TextureFormat::RGB, m_format.order);
1431725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PU(swizzled[0], 11, 5) | PU(swizzled[1], 5, 6) | PU(swizzled[2], 0, 5));
1432725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1433725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1434725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1435725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_555:
1436725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
14375b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			const IVec4 swizzled = swizzleRB(color, TextureFormat::RGB, m_format.order);
1438725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PU(swizzled[0], 10, 5) | PU(swizzled[1], 5, 5) | PU(swizzled[2], 0, 5));
1439725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1440725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1441725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1442725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_4444:
1443725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_4444:
1444725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
14455b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			const IVec4 swizzled = swizzleRB(color, TextureFormat::RGBA, m_format.order);
1446725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PU(swizzled[0], 12, 4) | PU(swizzled[1], 8, 4) | PU(swizzled[2], 4, 4) | PU(swizzled[3], 0, 4));
1447725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1448725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1449725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1450725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_5551:
1451725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_5551:
1452725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
14535b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			const IVec4 swizzled = swizzleRB(color, TextureFormat::RGBA, m_format.order);
1454725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PU(swizzled[0], 11, 5) | PU(swizzled[1], 6, 5) | PU(swizzled[2], 1, 5) | PU(swizzled[3], 0, 1));
1455725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1456725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1457725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
14585b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos		case TextureFormat::UNORM_SHORT_1555:
14595b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos		{
14605b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			const IVec4 swizzled = color.swizzle(3,0,1,2); // RGBA -> ARGB
14615b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PU(swizzled[0], 15, 1) | PU(swizzled[1], 10, 5) | PU(swizzled[2], 5, 5) | PU(swizzled[3], 0, 5));
14625b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			break;
14635b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos		}
14645b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos
1465725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_INT_1010102_REV:
1466725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_1010102_REV:
1467725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
14685b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			const IVec4 swizzled = swizzleRB(color, TextureFormat::RGBA, m_format.order);
1469725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint32*)pixelPtr) = PU(swizzled[0],  0, 10) | PU(swizzled[1], 10, 10) | PU(swizzled[2], 20, 10) | PU(swizzled[3], 30, 2);
1470725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1471725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1472725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1473725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::SNORM_INT_1010102_REV:
1474725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::SIGNED_INT_1010102_REV:
1475725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
14765b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos			const IVec4 swizzled = swizzleRB(color, TextureFormat::RGBA, m_format.order);
1477725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint32*)pixelPtr) = PI(swizzled[0],  0, 10) | PI(swizzled[1], 10, 10) | PI(swizzled[2], 20, 10) | PI(swizzled[3], 30, 2);
1478725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1479725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
14803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
14823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Generic path.
14846d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			int								numChannels	= getNumUsedChannels(m_format.order);
14856d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			const TextureSwizzle::Channel*	map			= getChannelWriteSwizzle(m_format.order).components;
14866d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			int								channelSize	= getChannelSize(m_format.type);
14873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int c = 0; c < numChannels; c++)
14896d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			{
14906d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				DE_ASSERT(deInRange32(map[c], TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3));
14913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				intToChannel(pixelPtr + channelSize*c, color[map[c]], m_format.type);
14926d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			}
14933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
14943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef PU
1498725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef PI
14993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15013c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PixelBufferAccess::setPixDepth (float depth, int x, int y, int z) const
15023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(x, 0, getWidth()));
15043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(y, 0, getHeight()));
15053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(z, 0, getDepth()));
15063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15078baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	deUint8* const pixelPtr = (deUint8*)getPixelPtr(x, y, z);
15083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
15103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1511725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_16_8_8:
151200d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::DS);
1513725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			writeUint32High16(pixelPtr, convertSatRte<deUint16>(depth * 65535.0f));
151400d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			break;
151574a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi
151600d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos		case TextureFormat::UNSIGNED_INT_24_8:
1517725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::D || m_format.order == TextureFormat::DS);
151800d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			writeUint32High24(pixelPtr,  convertSatRteUint24(depth * 16777215.0f));
15193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
15203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1521725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_24_8_REV:
1522725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::D || m_format.order == TextureFormat::DS);
1523725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			writeUint32Low24(pixelPtr,  convertSatRteUint24(depth * 16777215.0f));
1524725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1525725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
15263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
15273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_format.order == TextureFormat::DS);
15283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			*((float*)pixelPtr) = depth;
15293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
15303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
15328baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			DE_ASSERT(m_format.order == TextureFormat::D); // no other combined depth stencil types
15333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			floatToChannel(pixelPtr, depth, m_format.type);
15343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
15353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PixelBufferAccess::setPixStencil (int stencil, int x, int y, int z) const
15393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(x, 0, getWidth()));
15413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(y, 0, getHeight()));
15423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(z, 0, getDepth()));
15433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15448baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	deUint8* const pixelPtr = (deUint8*)getPixelPtr(x, y, z);
15453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
15473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1548725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_16_8_8:
15493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_24_8:
155000d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::DS);
155100d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			writeUint32Low8(pixelPtr, convertSat<deUint8>((deUint32)stencil));
155200d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			break;
155374a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi
1554725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_24_8_REV:
155500d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::DS);
1556725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			writeUint32High8(pixelPtr, convertSat<deUint8>((deUint32)stencil));
15573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
15583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
15603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_format.order == TextureFormat::DS);
156174a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi			writeUint32Low8(pixelPtr + 4, convertSat<deUint8>((deUint32)stencil));
15623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
15633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
15658baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			DE_ASSERT(m_format.order == TextureFormat::S);  // no other combined depth stencil types
15668baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			intToChannel(pixelPtr, stencil, m_format.type);
15673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
15683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15713c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline int imod (int a, int b)
15723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int m = a % b;
15743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m < 0 ? m + b : m;
15753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15773c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline int mirror (int a)
15783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1579674ddbb09a7bb6b16f839e129d5f0f2ac6dc9e74Pyry Haulos	return a >= 0 ? a : -(1 + a);
15803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Nearest-even rounding in case of tie (fractional part 0.5), otherwise ordinary rounding.
15833c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline float rint (float a)
15843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_STATIC_ASSERT((-3 % 2 != 0) && (-4 % 2 == 0));
15863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		fracVal		= deFloatFrac(a);
15883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (fracVal != 0.5f)
15903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return deFloatRound(a); // Ordinary case.
15913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float	floorVal	= a - fracVal;
15933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool	roundUp		= (deInt64)floorVal % 2 != 0;
15943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return floorVal + (roundUp ? 1.0f : 0.0f);
15963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15983c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline int wrap (Sampler::WrapMode mode, int c, int size)
15993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (mode)
16013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::CLAMP_TO_BORDER:
16033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return deClamp32(c, -1, size);
16043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::CLAMP_TO_EDGE:
16063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return deClamp32(c, 0, size-1);
16073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::REPEAT_GL:
16093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return imod(c, size);
16103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::REPEAT_CL:
16123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return imod(c, size);
16133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
161473fd35f3b995f065863c495364f03a52699c2d4aPyry Haulos		case tcu::Sampler::MIRRORED_ONCE:
161573fd35f3b995f065863c495364f03a52699c2d4aPyry Haulos			c = deClamp32(c, -size, size);
161673fd35f3b995f065863c495364f03a52699c2d4aPyry Haulos			// Fall-through
161773fd35f3b995f065863c495364f03a52699c2d4aPyry Haulos
16183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::MIRRORED_REPEAT_GL:
16193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return (size - 1) - mirror(imod(c, 2*size) - size);
16203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::MIRRORED_REPEAT_CL:
16223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return deClamp32(c, 0, size-1); // \note Actual mirroring done already in unnormalization function.
16233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
16253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
16263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0;
16273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Special unnormalization for REPEAT_CL and MIRRORED_REPEAT_CL wrap modes; otherwise ordinary unnormalization.
16313c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline float unnormalize (Sampler::WrapMode mode, float c, int size)
16323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (mode)
16343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::CLAMP_TO_EDGE:
16363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::CLAMP_TO_BORDER:
16373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::REPEAT_GL:
163873fd35f3b995f065863c495364f03a52699c2d4aPyry Haulos		case tcu::Sampler::MIRRORED_REPEAT_GL:
163973fd35f3b995f065863c495364f03a52699c2d4aPyry Haulos		case tcu::Sampler::MIRRORED_ONCE:		// Fall-through (ordinary case).
16403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return (float)size*c;
16413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::REPEAT_CL:
16433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return (float)size * (c - deFloatFloor(c));
16443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::MIRRORED_REPEAT_CL:
16463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return (float)size * deFloatAbs(c - 2.0f * rint(0.5f * c));
16473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
16493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
16503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
16513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isFixedPointDepthTextureFormat (const tcu::TextureFormat& format)
16553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16568baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	DE_ASSERT(format.order == TextureFormat::D);
16573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16588baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
16598baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	if (channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
16608baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry		return false;
16618baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	else if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
16628baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry		return true;
16638baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	else
16643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16658baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry		DE_ASSERT(false);
16668baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry		return false;
16673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texel lookup with color conversion.
16713c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline Vec4 lookup (const ConstPixelBufferAccess& access, int i, int j, int k)
16723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1673a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi	const TextureFormat&	format	= access.getFormat();
1674a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi
1675a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi	if (isSRGB(format))
1676a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi	{
1677a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi		if (format.type == TextureFormat::UNORM_INT8 && format.order == TextureFormat::sRGB)
1678a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi				return sRGB8ToLinear(access.getPixelUint(i, j, k));
1679a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi		else if (format.type == TextureFormat::UNORM_INT8 && format.order == TextureFormat::sRGBA)
1680a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi				return sRGBA8ToLinear(access.getPixelUint(i, j, k));
1681a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi		else
1682a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi			return sRGBToLinear(access.getPixel(i, j, k));
1683a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi	}
1684a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi	else
1685a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi	{
1686a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi		return access.getPixel(i, j, k);
1687a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi	}
16883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1690222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry// Border texel lookup with color conversion.
169122941823a995126908aae341c87f2def77514ee7Jarkko Pöyrystatic inline Vec4 lookupBorder (const tcu::TextureFormat& format, const tcu::Sampler& sampler)
169222941823a995126908aae341c87f2def77514ee7Jarkko Pöyry{
1693222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	// "lookup" for a combined format does not make sense, disallow
1694222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	DE_ASSERT(!isCombinedDepthStencilType(format.type));
1695222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry
1696653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos	const tcu::TextureChannelClass	channelClass			= tcu::getTextureChannelClass(format.type);
1697222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	const bool						isFloat					= channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT;
1698222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	const bool						isFixed					= channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT ||
1699222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry															  channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT;
1700222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	const bool						isPureInteger			= channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER;
1701222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	const bool						isPureUnsignedInteger	= channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
1702222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry
1703222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	if (isFloat || isFixed)
1704d5be8ad612a000b4ad2caf14c8d93501f3558eb8Jarkko Pöyry		return sampleTextureBorder<float>(format, sampler);
1705222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	else if (isPureInteger)
1706222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry		return sampleTextureBorder<deInt32>(format, sampler).cast<float>();
1707222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	else if (isPureUnsignedInteger)
1708222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry		return sampleTextureBorder<deUint32>(format, sampler).cast<float>();
1709222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	else
1710222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	{
1711222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry		DE_ASSERT(false);
1712222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry		return Vec4(-1.0);
1713222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	}
171422941823a995126908aae341c87f2def77514ee7Jarkko Pöyry}
171522941823a995126908aae341c87f2def77514ee7Jarkko Pöyry
17163c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline float execCompare (const tcu::Vec4& color, Sampler::CompareMode compare, int chanNdx, float ref_, bool isFixedPoint)
17173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool	clampValues	= isFixedPoint;	// if comparing against a floating point texture, ref (and value) is not clamped
17193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	cmp			= (clampValues) ? (de::clamp(color[chanNdx], 0.0f, 1.0f)) : (color[chanNdx]);
17203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	ref			= (clampValues) ? (de::clamp(ref_, 0.0f, 1.0f)) : (ref_);
17213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		res			= false;
17223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (compare)
17243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_LESS:				res = ref < cmp;	break;
17263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_LESS_OR_EQUAL:	res = ref <= cmp;	break;
17273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_GREATER:			res = ref > cmp;	break;
17283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_GREATER_OR_EQUAL:	res = ref >= cmp;	break;
17293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_EQUAL:			res = ref == cmp;	break;
17303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_NOT_EQUAL:		res = ref != cmp;	break;
17313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_ALWAYS:			res = true;			break;
17323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_NEVER:			res = false;		break;
17333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
17343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
17353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return res ? 1.0f : 0.0f;
17383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17403c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleNearest1D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, const IVec2& offset)
17413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int width	= access.getWidth();
17433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x = deFloorFloatToInt32(u)+offset.x();
17453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check for CLAMP_TO_BORDER.
17473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.wrapS == Sampler::CLAMP_TO_BORDER && !deInBounds32(x, 0, width))
174822941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		return lookupBorder(access.getFormat(), sampler);
17493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i = wrap(sampler.wrapS, x, width);
17513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return lookup(access, i, offset.y(), 0);
17533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleNearest2D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, float v, const IVec3& offset)
17563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int width	= access.getWidth();
17583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int height	= access.getHeight();
17593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x = deFloorFloatToInt32(u)+offset.x();
17613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y = deFloorFloatToInt32(v)+offset.y();
17623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check for CLAMP_TO_BORDER.
17643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if ((sampler.wrapS == Sampler::CLAMP_TO_BORDER && !deInBounds32(x, 0, width)) ||
17653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		(sampler.wrapT == Sampler::CLAMP_TO_BORDER && !deInBounds32(y, 0, height)))
176622941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		return lookupBorder(access.getFormat(), sampler);
17673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i = wrap(sampler.wrapS, x, width);
17693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j = wrap(sampler.wrapT, y, height);
17703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return lookup(access, i, j, offset.z());
17723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17743c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleNearest3D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, float v, float w, const IVec3& offset)
17753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int width	= access.getWidth();
17773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int height	= access.getHeight();
17783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int depth	= access.getDepth();
17793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x = deFloorFloatToInt32(u)+offset.x();
17813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y = deFloorFloatToInt32(v)+offset.y();
17823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int z = deFloorFloatToInt32(w)+offset.z();
17833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check for CLAMP_TO_BORDER.
17853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if ((sampler.wrapS == Sampler::CLAMP_TO_BORDER && !deInBounds32(x, 0, width))	||
17863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		(sampler.wrapT == Sampler::CLAMP_TO_BORDER && !deInBounds32(y, 0, height))	||
17873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		(sampler.wrapR == Sampler::CLAMP_TO_BORDER && !deInBounds32(z, 0, depth)))
178822941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		return lookupBorder(access.getFormat(), sampler);
17893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i = wrap(sampler.wrapS, x, width);
17913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j = wrap(sampler.wrapT, y, height);
17923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int k = wrap(sampler.wrapR, z, depth);
17933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return lookup(access, i, j, k);
17953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17973c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleLinear1D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, const IVec2& offset)
17983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int w = access.getWidth();
18003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x0 = deFloorFloatToInt32(u-0.5f)+offset.x();
18023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x1 = x0+1;
18033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i0 = wrap(sampler.wrapS, x0, w);
18053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i1 = wrap(sampler.wrapS, x1, w);
18063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
18083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i0UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i0, 0, w);
18103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i1UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i1, 0, w);
18113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Border color for out-of-range coordinates if using CLAMP_TO_BORDER, otherwise execute lookups.
181322941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p0 = i0UseBorder ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, offset.y(), 0);
181422941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p1 = i1UseBorder ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, offset.y(), 0);
18153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
18173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return p0 * (1.0f - a) + p1 * a;
18183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18203c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleLinear2D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, float v, const IVec3& offset)
18213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int w = access.getWidth();
18233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int h = access.getHeight();
18243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x0 = deFloorFloatToInt32(u-0.5f)+offset.x();
18263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x1 = x0+1;
18273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y0 = deFloorFloatToInt32(v-0.5f)+offset.y();
18283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y1 = y0+1;
18293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i0 = wrap(sampler.wrapS, x0, w);
18313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i1 = wrap(sampler.wrapS, x1, w);
18323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j0 = wrap(sampler.wrapT, y0, h);
18333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j1 = wrap(sampler.wrapT, y1, h);
18343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
18363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float b = deFloatFrac(v-0.5f);
18373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i0UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i0, 0, w);
18393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i1UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i1, 0, w);
18403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool j0UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j0, 0, h);
18413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool j1UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j1, 0, h);
18423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Border color for out-of-range coordinates if using CLAMP_TO_BORDER, otherwise execute lookups.
184422941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p00 = (i0UseBorder || j0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j0, offset.z());
184522941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p10 = (i1UseBorder || j0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j0, offset.z());
184622941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p01 = (i0UseBorder || j1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j1, offset.z());
184722941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p11 = (i1UseBorder || j1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j1, offset.z());
18483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
18503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (p00*(1.0f-a)*(1.0f-b)) +
18513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p10*(     a)*(1.0f-b)) +
18523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p01*(1.0f-a)*(     b)) +
18533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p11*(     a)*(     b));
18543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18563c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float sampleLinear1DCompare (const ConstPixelBufferAccess& access, const Sampler& sampler, float ref, float u, const IVec2& offset, bool isFixedPointDepthFormat)
18573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int w = access.getWidth();
18593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x0 = deFloorFloatToInt32(u-0.5f)+offset.x();
18613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x1 = x0+1;
18623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i0 = wrap(sampler.wrapS, x0, w);
18643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i1 = wrap(sampler.wrapS, x1, w);
18653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
18673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i0UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i0, 0, w);
18693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i1UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i1, 0, w);
18703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Border color for out-of-range coordinates if using CLAMP_TO_BORDER, otherwise execute lookups.
187222941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p0Clr = i0UseBorder  ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, offset.y(), 0);
187322941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p1Clr = i1UseBorder  ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, offset.y(), 0);
18743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Execute comparisons.
18763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float p0 = execCompare(p0Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat);
18773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float p1 = execCompare(p1Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat);
18783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
18803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (p0 * (1.0f - a)) + (p1 * a);
18813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18833c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float sampleLinear2DCompare (const ConstPixelBufferAccess& access, const Sampler& sampler, float ref, float u, float v, const IVec3& offset, bool isFixedPointDepthFormat)
18843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int w = access.getWidth();
18863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int h = access.getHeight();
18873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x0 = deFloorFloatToInt32(u-0.5f)+offset.x();
18893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x1 = x0+1;
18903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y0 = deFloorFloatToInt32(v-0.5f)+offset.y();
18913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y1 = y0+1;
18923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i0 = wrap(sampler.wrapS, x0, w);
18943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i1 = wrap(sampler.wrapS, x1, w);
18953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j0 = wrap(sampler.wrapT, y0, h);
18963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j1 = wrap(sampler.wrapT, y1, h);
18973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
18993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float b = deFloatFrac(v-0.5f);
19003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i0UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i0, 0, w);
19023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i1UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i1, 0, w);
19033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool j0UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j0, 0, h);
19043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool j1UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j1, 0, h);
19053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Border color for out-of-range coordinates if using CLAMP_TO_BORDER, otherwise execute lookups.
190722941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p00Clr = (i0UseBorder || j0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j0, offset.z());
190822941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p10Clr = (i1UseBorder || j0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j0, offset.z());
190922941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p01Clr = (i0UseBorder || j1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j1, offset.z());
191022941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p11Clr = (i1UseBorder || j1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j1, offset.z());
19113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Execute comparisons.
19133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float p00 = execCompare(p00Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat);
19143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float p10 = execCompare(p10Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat);
19153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float p01 = execCompare(p01Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat);
19163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float p11 = execCompare(p11Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat);
19173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
19193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (p00*(1.0f-a)*(1.0f-b)) +
19203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p10*(     a)*(1.0f-b)) +
19213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p01*(1.0f-a)*(     b)) +
19223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p11*(     a)*(     b));
19233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19253c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleLinear3D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, float v, float w, const IVec3& offset)
19263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int width	= access.getWidth();
19283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int height	= access.getHeight();
19293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int depth	= access.getDepth();
19303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x0 = deFloorFloatToInt32(u-0.5f)+offset.x();
19323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x1 = x0+1;
19333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y0 = deFloorFloatToInt32(v-0.5f)+offset.y();
19343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y1 = y0+1;
19353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int z0 = deFloorFloatToInt32(w-0.5f)+offset.z();
19363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int z1 = z0+1;
19373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i0 = wrap(sampler.wrapS, x0, width);
19393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i1 = wrap(sampler.wrapS, x1, width);
19403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j0 = wrap(sampler.wrapT, y0, height);
19413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j1 = wrap(sampler.wrapT, y1, height);
19423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int k0 = wrap(sampler.wrapR, z0, depth);
19433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int k1 = wrap(sampler.wrapR, z1, depth);
19443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
19463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float b = deFloatFrac(v-0.5f);
19473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float c = deFloatFrac(w-0.5f);
19483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i0UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i0, 0, width);
19503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i1UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i1, 0, width);
19513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool j0UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j0, 0, height);
19523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool j1UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j1, 0, height);
19533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool k0UseBorder = sampler.wrapR == Sampler::CLAMP_TO_BORDER && !de::inBounds(k0, 0, depth);
19543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool k1UseBorder = sampler.wrapR == Sampler::CLAMP_TO_BORDER && !de::inBounds(k1, 0, depth);
19553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Border color for out-of-range coordinates if using CLAMP_TO_BORDER, otherwise execute lookups.
195722941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p000 = (i0UseBorder || j0UseBorder || k0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j0, k0);
195822941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p100 = (i1UseBorder || j0UseBorder || k0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j0, k0);
195922941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p010 = (i0UseBorder || j1UseBorder || k0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j1, k0);
196022941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p110 = (i1UseBorder || j1UseBorder || k0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j1, k0);
196122941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p001 = (i0UseBorder || j0UseBorder || k1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j0, k1);
196222941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p101 = (i1UseBorder || j0UseBorder || k1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j0, k1);
196322941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p011 = (i0UseBorder || j1UseBorder || k1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j1, k1);
196422941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p111 = (i1UseBorder || j1UseBorder || k1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j1, k1);
19653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
19673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (p000*(1.0f-a)*(1.0f-b)*(1.0f-c)) +
19683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p100*(     a)*(1.0f-b)*(1.0f-c)) +
19693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p010*(1.0f-a)*(     b)*(1.0f-c)) +
19703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p110*(     a)*(     b)*(1.0f-c)) +
19713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p001*(1.0f-a)*(1.0f-b)*(     c)) +
19723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p101*(     a)*(1.0f-b)*(     c)) +
19733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p011*(1.0f-a)*(     b)*(     c)) +
19743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p111*(     a)*(     b)*(     c));
19753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19773c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 ConstPixelBufferAccess::sample1D (const Sampler& sampler, Sampler::FilterMode filter, float s, int level) const
19783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1979612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// check selected layer exists
198029340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(level, 0, m_size.y()));
19813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1982612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	return sample1DOffset(sampler, filter, s, tcu::IVec2(0, level));
19833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19853c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 ConstPixelBufferAccess::sample2D (const Sampler& sampler, Sampler::FilterMode filter, float s, float t, int depth) const
19863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1987612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// check selected layer exists
198829340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(depth, 0, m_size.z()));
19893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1990612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	return sample2DOffset(sampler, filter, s, t, tcu::IVec3(0, 0, depth));
1991612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry}
19923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1993612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko PöyryVec4 ConstPixelBufferAccess::sample3D (const Sampler& sampler, Sampler::FilterMode filter, float s, float t, float r) const
1994612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry{
1995612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	return sample3DOffset(sampler, filter, s, t, r, tcu::IVec3(0, 0, 0));
19963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19983c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 ConstPixelBufferAccess::sample1DOffset (const Sampler& sampler, Sampler::FilterMode filter, float s, const IVec2& offset) const
19993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2000612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// check selected layer exists
2001612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// \note offset.x is X offset, offset.y is the selected layer
2002612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	DE_ASSERT(de::inBounds(offset.y(), 0, m_size.y()));
20033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
20053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float u = s;
20063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
200829340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		u = unnormalize(sampler.wrapS, s, m_size.x());
20093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filter)
20113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return sampleNearest1D	(*this, sampler, u, offset);
20133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return sampleLinear1D	(*this, sampler, u, offset);
20143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
20153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
20163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
20173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20203c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 ConstPixelBufferAccess::sample2DOffset (const Sampler& sampler, Sampler::FilterMode filter, float s, float t, const IVec3& offset) const
20213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2022612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// check selected layer exists
2023612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// \note offset.xy is the XY offset, offset.z is the selected layer
202429340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(offset.z(), 0, m_size.z()));
20253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
20273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float u = s;
20283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float v = t;
20293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
20313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
203229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		u = unnormalize(sampler.wrapS, s, m_size.x());
203329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		v = unnormalize(sampler.wrapT, t, m_size.y());
20343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filter)
20373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return sampleNearest2D	(*this, sampler, u, v, offset);
20393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return sampleLinear2D	(*this, sampler, u, v, offset);
20403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
20413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
20423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
20433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2046612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko PöyryVec4 ConstPixelBufferAccess::sample3DOffset (const Sampler& sampler, Sampler::FilterMode filter, float s, float t, float r, const IVec3& offset) const
20473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
20493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float u = s;
2050612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	float v = t;
2051612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	float w = r;
20523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
2054612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	{
205529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		u = unnormalize(sampler.wrapS, s, m_size.x());
2056612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		v = unnormalize(sampler.wrapT, t, m_size.y());
2057612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		w = unnormalize(sampler.wrapR, r, m_size.z());
2058612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	}
20593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filter)
20613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2062612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		case Sampler::NEAREST:	return sampleNearest3D	(*this, sampler, u, v, w, offset);
2063612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		case Sampler::LINEAR:	return sampleLinear3D	(*this, sampler, u, v, w, offset);
20643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
20653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
2066612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry			return Vec4(0.0f);
20673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2070612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyryfloat ConstPixelBufferAccess::sample1DCompare (const Sampler& sampler, Sampler::FilterMode filter, float ref, float s, const IVec2& offset) const
20713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2072612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// check selected layer exists
2073612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// \note offset.x is X offset, offset.y is the selected layer
2074612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	DE_ASSERT(de::inBounds(offset.y(), 0, m_size.y()));
20753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Format information for comparison function
20773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool isFixedPointDepth = isFixedPointDepthTextureFormat(m_format);
20783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
20803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float u = s;
20813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
208329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		u = unnormalize(sampler.wrapS, s, m_size.x());
20843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filter)
20863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2087612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		case Sampler::NEAREST:	return execCompare(sampleNearest1D(*this, sampler, u, offset), sampler.compare, sampler.compareChannel, ref, isFixedPointDepth);
2088612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		case Sampler::LINEAR:	return sampleLinear1DCompare(*this, sampler, ref, u, offset, isFixedPointDepth);
20893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
20903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
20913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
20923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2095612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyryfloat ConstPixelBufferAccess::sample2DCompare (const Sampler& sampler, Sampler::FilterMode filter, float ref, float s, float t, const IVec3& offset) const
20963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2097612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// check selected layer exists
2098612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// \note offset.xy is XY offset, offset.z is the selected layer
2099612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	DE_ASSERT(de::inBounds(offset.z(), 0, m_size.z()));
21003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2101612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// Format information for comparison function
2102612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	const bool isFixedPointDepth = isFixedPointDepthTextureFormat(m_format);
21033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
21053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float u = s;
21063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float v = t;
21073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
21093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
211029340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		u = unnormalize(sampler.wrapS, s, m_size.x());
211129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		v = unnormalize(sampler.wrapT, t, m_size.y());
21123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
21133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filter)
21153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2116612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		case Sampler::NEAREST:	return execCompare(sampleNearest2D(*this, sampler, u, v, offset), sampler.compare, sampler.compareChannel, ref, isFixedPointDepth);
2117612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		case Sampler::LINEAR:	return sampleLinear2DCompare(*this, sampler, ref, u, v, offset, isFixedPointDepth);
21183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
21193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
2120612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry			return 0.0f;
21213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
21223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
21233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21243c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevel::TextureLevel (void)
21253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	()
212629340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size	(0)
21273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
21283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
21293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21303c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevel::TextureLevel (const TextureFormat& format)
21313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	(format)
213229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size	(0)
21333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
21343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
21353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21363c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevel::TextureLevel (const TextureFormat& format, int width, int height, int depth)
21373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	(format)
213829340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size	(0)
21393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
21403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	setSize(width, height, depth);
21413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
21423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21433c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevel::~TextureLevel (void)
21443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
21453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
21463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureLevel::setStorage (const TextureFormat& format, int width, int height, int depth)
21483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
21493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_format = format;
21503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	setSize(width, height, depth);
21513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
21523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureLevel::setSize (int width, int height, int depth)
21543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
21553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int pixelSize = m_format.getPixelSize();
21563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
215729340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	m_size = IVec3(width, height, depth);
21583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
215929340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	m_data.setStorage(m_size.x() * m_size.y() * m_size.z() * pixelSize);
21603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
21613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21623c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 sampleLevelArray1D (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, int depth, float lod)
21633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
21641d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry	return sampleLevelArray1DOffset(levels, numLevels, sampler, s, lod, IVec2(0, depth)); // y-offset in 1D textures is layer selector
21651d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry}
21663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21671d75d23528999118c1911ed100d1d063b06040daJarkko PöyryVec4 sampleLevelArray2D (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, int depth, float lod)
21681d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry{
21691d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry	return sampleLevelArray2DOffset(levels, numLevels, sampler, s, t, lod, IVec3(0, 0, depth)); // z-offset in 2D textures is layer selector
21701d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry}
21713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21721d75d23528999118c1911ed100d1d063b06040daJarkko PöyryVec4 sampleLevelArray3D (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, float r, float lod)
21731d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry{
21741d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry	return sampleLevelArray3DOffset(levels, numLevels, sampler, s, t, r, lod, IVec3(0, 0, 0));
21753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
21763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21773c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 sampleLevelArray1DOffset (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float lod, const IVec2& offset)
21783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
21793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
21803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
21813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
21833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return levels[0].sample1DOffset(sampler, filterMode, s, offset);
21853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return levels[0].sample1DOffset(sampler, filterMode, s, offset);
21863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
21883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
21893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
21913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
21923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
21933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return levels[level].sample1DOffset(sampler, levelFilter, s, offset);
21953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
21963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
21983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
21993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
22013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
22023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level1		= de::min(maxLevel, level0 + 1);
22033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
22043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				f			= deFloatFrac(lod);
22053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4			t0			= levels[level0].sample1DOffset(sampler, levelFilter, s, offset);
22063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4			t1			= levels[level1].sample1DOffset(sampler, levelFilter, s, offset);
22073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
22093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
22123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
22133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
22143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
22153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
22163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22173c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 sampleLevelArray2DOffset (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, float lod, const IVec3& offset)
22183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
22193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
22203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
22213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
22233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
22243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return levels[0].sample2DOffset(sampler, filterMode, s, t, offset);
22253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return levels[0].sample2DOffset(sampler, filterMode, s, t, offset);
22263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
22283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
22293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
22313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
22323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
22333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return levels[level].sample2DOffset(sampler, levelFilter, s, t, offset);
22353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
22383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
22393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
22413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
22423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level1		= de::min(maxLevel, level0 + 1);
22433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
22443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				f			= deFloatFrac(lod);
22453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4			t0			= levels[level0].sample2DOffset(sampler, levelFilter, s, t, offset);
22463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4			t1			= levels[level1].sample2DOffset(sampler, levelFilter, s, t, offset);
22473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
22493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
22523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
22533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
22543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
22553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
22563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22573c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 sampleLevelArray3DOffset (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, float r, float lod, const IVec3& offset)
22583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
22593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
22603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
22613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
22633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
22643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return levels[0].sample3DOffset(sampler, filterMode, s, t, r, offset);
22653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return levels[0].sample3DOffset(sampler, filterMode, s, t, r, offset);
22663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
22683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
22693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
22713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
22723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
22733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return levels[level].sample3DOffset(sampler, levelFilter, s, t, r, offset);
22753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
22783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
22793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
22813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
22823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level1		= de::min(maxLevel, level0 + 1);
22833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
22843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				f			= deFloatFrac(lod);
22853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4			t0			= levels[level0].sample3DOffset(sampler, levelFilter, s, t, r, offset);
22863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4			t1			= levels[level1].sample3DOffset(sampler, levelFilter, s, t, r, offset);
22873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
22893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
22923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
22933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
22943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
22953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
22963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22973c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat sampleLevelArray1DCompare (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float ref, float s, float lod, const IVec2& offset)
22983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
22993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
23003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
23013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
23033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return levels[0].sample1DCompare(sampler, filterMode, ref, s, offset);
23053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return levels[0].sample1DCompare(sampler, filterMode, ref, s, offset);
23063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
23083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
23093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
23103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
23113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
23123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
23133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return levels[level].sample1DCompare(sampler, levelFilter, ref, s, offset);
23153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
23163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
23183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
23193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
23203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
23213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
23223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level1		= de::min(maxLevel, level0 + 1);
23233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
23243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				f			= deFloatFrac(lod);
23253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				t0			= levels[level0].sample1DCompare(sampler, levelFilter, ref, s, offset);
23263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				t1			= levels[level1].sample1DCompare(sampler, levelFilter, ref, s, offset);
23273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
23293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
23303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
23323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
23333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
23343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
23353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat sampleLevelArray2DCompare (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float ref, float s, float t, float lod, const IVec3& offset)
23383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
23403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
23413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
23433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return levels[0].sample2DCompare(sampler, filterMode, ref, s, t, offset);
23453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return levels[0].sample2DCompare(sampler, filterMode, ref, s, t, offset);
23463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
23483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
23493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
23503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
23513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
23523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
23533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return levels[level].sample2DCompare(sampler, levelFilter, ref, s, t, offset);
23553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
23563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
23583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
23593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
23603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
23613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
23623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level1		= de::min(maxLevel, level0 + 1);
23633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
23643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				f			= deFloatFrac(lod);
23653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				t0			= levels[level0].sample2DCompare(sampler, levelFilter, ref, s, t, offset);
23663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				t1			= levels[level1].sample2DCompare(sampler, levelFilter, ref, s, t, offset);
23673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
23693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
23703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
23723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
23733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
23743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
23753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
237722941823a995126908aae341c87f2def77514ee7Jarkko Pöyrystatic Vec4 fetchGatherArray2DOffsets (const ConstPixelBufferAccess& src, const Sampler& sampler, float s, float t, int depth, int componentNdx, const IVec2 (&offsets)[4])
23783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(componentNdx, 0, 4));
23803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		w	= src.getWidth();
23823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		h	= src.getHeight();
23833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float		u	= unnormalize(sampler.wrapS, s, w);
23843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float		v	= unnormalize(sampler.wrapT, t, h);
23853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		x0	= deFloorFloatToInt32(u-0.5f);
23863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		y0	= deFloorFloatToInt32(v-0.5f);
23873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
238822941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4			result;
23893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
23913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
239222941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		const int	sampleX	= wrap(sampler.wrapS, x0 + offsets[i].x(), w);
239322941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		const int	sampleY	= wrap(sampler.wrapT, y0 + offsets[i].y(), h);
239422941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		Vec4		pixel;
239522941823a995126908aae341c87f2def77514ee7Jarkko Pöyry
239622941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		if (deInBounds32(sampleX, 0, w) && deInBounds32(sampleY, 0, h))
239722941823a995126908aae341c87f2def77514ee7Jarkko Pöyry			pixel = lookup(src, sampleX, sampleY, depth);
239822941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		else
239922941823a995126908aae341c87f2def77514ee7Jarkko Pöyry			pixel = lookupBorder(src.getFormat(), sampler);
240022941823a995126908aae341c87f2def77514ee7Jarkko Pöyry
24013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result[i] = pixel[componentNdx];
24023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
24033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
24053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
240722941823a995126908aae341c87f2def77514ee7Jarkko PöyryVec4 gatherArray2DOffsets (const ConstPixelBufferAccess& src, const Sampler& sampler, float s, float t, int depth, int componentNdx, const IVec2 (&offsets)[4])
240822941823a995126908aae341c87f2def77514ee7Jarkko Pöyry{
240922941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	DE_ASSERT(sampler.compare == Sampler::COMPAREMODE_NONE);
241022941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	DE_ASSERT(de::inBounds(componentNdx, 0, 4));
241122941823a995126908aae341c87f2def77514ee7Jarkko Pöyry
241222941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	return fetchGatherArray2DOffsets(src, sampler, s, t, depth, componentNdx, offsets);
241322941823a995126908aae341c87f2def77514ee7Jarkko Pöyry}
241422941823a995126908aae341c87f2def77514ee7Jarkko Pöyry
24153c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 gatherArray2DOffsetsCompare (const ConstPixelBufferAccess& src, const Sampler& sampler, float ref, float s, float t, int depth, const IVec2 (&offsets)[4])
24163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare != Sampler::COMPAREMODE_NONE);
24183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(src.getFormat().order == TextureFormat::D || src.getFormat().order == TextureFormat::DS);
24193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compareChannel == 0);
24203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2421222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	const bool	isFixedPoint	= isFixedPointDepthTextureFormat(src.getFormat());
2422222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	const Vec4	gathered		= fetchGatherArray2DOffsets(src, sampler, s, t, depth, 0 /* component 0: depth */, offsets);
2423222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	Vec4		result;
24243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
24263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result[i] = execCompare(gathered, sampler.compare, i, ref, isFixedPoint);
24273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
24293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24313c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleCubeSeamlessNearest (const ConstPixelBufferAccess& faceAccess, const Sampler& sampler, float s, float t, int depth)
24323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler clampingSampler = sampler;
24343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	clampingSampler.wrapS = Sampler::CLAMP_TO_EDGE;
24353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	clampingSampler.wrapT = Sampler::CLAMP_TO_EDGE;
24363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return faceAccess.sample2D(clampingSampler, Sampler::NEAREST, s, t, depth);
24373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24393c827367444ee418f129b2c238299f49d3264554Jarkko PoyryCubeFace selectCubeFace (const Vec3& coords)
24403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	x	= coords.x();
24423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	y	= coords.y();
24433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	z	= coords.z();
24443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	ax	= deFloatAbs(x);
24453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	ay	= deFloatAbs(y);
24463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	az	= deFloatAbs(z);
24473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (ay < ax && az < ax)
24493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return x >= 0.0f ? CUBEFACE_POSITIVE_X : CUBEFACE_NEGATIVE_X;
24503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (ax < ay && az < ay)
24513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return y >= 0.0f ? CUBEFACE_POSITIVE_Y : CUBEFACE_NEGATIVE_Y;
24523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (ax < az && ay < az)
24533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return z >= 0.0f ? CUBEFACE_POSITIVE_Z : CUBEFACE_NEGATIVE_Z;
24543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
24553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Some of the components are equal. Use tie-breaking rule.
24573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (ax == ay)
24583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
24593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (ax < az)
24603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return z >= 0.0f ? CUBEFACE_POSITIVE_Z : CUBEFACE_NEGATIVE_Z;
24613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
24623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return x >= 0.0f ? CUBEFACE_POSITIVE_X : CUBEFACE_NEGATIVE_X;
24633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
24643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (ax == az)
24653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
24663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (az < ay)
24673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return y >= 0.0f ? CUBEFACE_POSITIVE_Y : CUBEFACE_NEGATIVE_Y;
24683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
24693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return z >= 0.0f ? CUBEFACE_POSITIVE_Z : CUBEFACE_NEGATIVE_Z;
24703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
24713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (ay == az)
24723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
24733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (ay < ax)
24743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return x >= 0.0f ? CUBEFACE_POSITIVE_X : CUBEFACE_NEGATIVE_X;
24753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
24763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return y >= 0.0f ? CUBEFACE_POSITIVE_Y : CUBEFACE_NEGATIVE_Y;
24773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
24783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
24793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return x >= 0.0f ? CUBEFACE_POSITIVE_X : CUBEFACE_NEGATIVE_X;
24803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
24813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24833c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec2 projectToFace (CubeFace face, const Vec3& coord)
24843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	rx		= coord.x();
24863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	ry		= coord.y();
24873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	rz		= coord.z();
24883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		sc		= 0.0f;
24893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		tc		= 0.0f;
24903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		ma		= 0.0f;
24913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		s;
24923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		t;
24933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (face)
24953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_X: sc = +rz; tc = -ry; ma = -rx; break;
24973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_X: sc = -rz; tc = -ry; ma = +rx; break;
24983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_Y: sc = +rx; tc = -rz; ma = -ry; break;
24993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_Y: sc = +rx; tc = +rz; ma = +ry; break;
25003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_Z: sc = -rx; tc = -ry; ma = -rz; break;
25013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_Z: sc = +rx; tc = -ry; ma = +rz; break;
25023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
25033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
25043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
25053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute s, t
25073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	s = ((sc / ma) + 1.0f) / 2.0f;
25083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	t = ((tc / ma) + 1.0f) / 2.0f;
25093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return Vec2(s, t);
25113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
25123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25133c827367444ee418f129b2c238299f49d3264554Jarkko PoyryCubeFaceFloatCoords getCubeFaceCoords (const Vec3& coords)
25143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
25153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CubeFace face = selectCubeFace(coords);
25163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return CubeFaceFloatCoords(face, projectToFace(face, coords));
25173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
25183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25193c827367444ee418f129b2c238299f49d3264554Jarkko 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.
25203c827367444ee418f129b2c238299f49d3264554Jarkko 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.
25213c827367444ee418f129b2c238299f49d3264554Jarkko PoyryCubeFaceIntCoords remapCubeEdgeCoords (const CubeFaceIntCoords& origCoords, int size)
25223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
25233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool uInBounds = de::inBounds(origCoords.s, 0, size);
25243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool vInBounds = de::inBounds(origCoords.t, 0, size);
25253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (uInBounds && vInBounds)
25273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return origCoords;
25283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!uInBounds && !vInBounds)
25303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_LAST, -1, -1);
25313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec2 coords(wrap(Sampler::CLAMP_TO_BORDER, origCoords.s, size),
25333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				 wrap(Sampler::CLAMP_TO_BORDER, origCoords.t, size));
25343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec3 canonizedCoords;
25353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Map the uv coordinates to canonized 3d coordinates.
25373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (origCoords.face)
25393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
25403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_X: canonizedCoords = IVec3(0,					size-1-coords.y(),	coords.x());			break;
25413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_X: canonizedCoords = IVec3(size-1,				size-1-coords.y(),	size-1-coords.x());		break;
25423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_Y: canonizedCoords = IVec3(coords.x(),			0,					size-1-coords.y());		break;
25433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_Y: canonizedCoords = IVec3(coords.x(),			size-1,				coords.y());			break;
25443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_Z: canonizedCoords = IVec3(size-1-coords.x(),	size-1-coords.y(),	0);						break;
25453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_Z: canonizedCoords = IVec3(coords.x(),			size-1-coords.y(),	size-1);				break;
25463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default: DE_ASSERT(false);
25473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
25483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Find an appropriate face to re-map the coordinates to.
25503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (canonizedCoords.x() == -1)
25523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_NEGATIVE_X, IVec2(canonizedCoords.z(), size-1-canonizedCoords.y()));
25533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (canonizedCoords.x() == size)
25553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_POSITIVE_X, IVec2(size-1-canonizedCoords.z(), size-1-canonizedCoords.y()));
25563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (canonizedCoords.y() == -1)
25583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_NEGATIVE_Y, IVec2(canonizedCoords.x(), size-1-canonizedCoords.z()));
25593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (canonizedCoords.y() == size)
25613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_POSITIVE_Y, IVec2(canonizedCoords.x(), canonizedCoords.z()));
25623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (canonizedCoords.z() == -1)
25643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_NEGATIVE_Z, IVec2(size-1-canonizedCoords.x(), size-1-canonizedCoords.y()));
25653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (canonizedCoords.z() == size)
25673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_POSITIVE_Z, IVec2(canonizedCoords.x(), size-1-canonizedCoords.y()));
25683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(false);
25703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return CubeFaceIntCoords(CUBEFACE_LAST, IVec2(-1));
25713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
25723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25733c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void getCubeLinearSamples (const ConstPixelBufferAccess (&faceAccesses)[CUBEFACE_LAST], CubeFace baseFace, float u, float v, int depth, Vec4 (&dst)[4])
25743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
25753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(faceAccesses[0].getWidth() == faceAccesses[0].getHeight());
25763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		size					= faceAccesses[0].getWidth();
25773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		x0						= deFloorFloatToInt32(u-0.5f);
25783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		x1						= x0+1;
25793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		y0						= deFloorFloatToInt32(v-0.5f);
25803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		y1						= y0+1;
25813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec2	baseSampleCoords[4]		=
25823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
25833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x0, y0),
25843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x1, y0),
25853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x0, y1),
25863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x1, y1)
25873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
25883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4	sampleColors[4];
25893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool	hasBothCoordsOutOfBounds[4]; //!< Whether correctCubeFace() returns CUBEFACE_LAST, i.e. both u and v are out of bounds.
25903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Find correct faces and coordinates for out-of-bounds sample coordinates.
25923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
25943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
25953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CubeFaceIntCoords coords = remapCubeEdgeCoords(CubeFaceIntCoords(baseFace, baseSampleCoords[i]), size);
25963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		hasBothCoordsOutOfBounds[i] = coords.face == CUBEFACE_LAST;
25973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!hasBothCoordsOutOfBounds[i])
25983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sampleColors[i] = lookup(faceAccesses[coords.face], coords.s, coords.t, depth);
25993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
26003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26013c827367444ee418f129b2c238299f49d3264554Jarkko 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.
26023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note This averaging behavior is not required by the GLES3 spec (though it is recommended). GLES3 spec only
26033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//		 requires that if the three other samples all have the same color, then the doubly-out-of-bounds sample
26043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//		 must have this color as well.
26053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
26073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int bothOutOfBoundsNdx = -1;
26083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < 4; i++)
26093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
26103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (hasBothCoordsOutOfBounds[i])
26113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
26123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(bothOutOfBoundsNdx < 0); // Only one sample can be out of bounds in both u and v.
26133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				bothOutOfBoundsNdx = i;
26143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
26153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
26163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (bothOutOfBoundsNdx != -1)
26173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
26183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sampleColors[bothOutOfBoundsNdx] = Vec4(0.0f);
26193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < 4; i++)
26203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (i != bothOutOfBoundsNdx)
26213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					sampleColors[bothOutOfBoundsNdx] += sampleColors[i];
26223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sampleColors[bothOutOfBoundsNdx] = sampleColors[bothOutOfBoundsNdx] * (1.0f/3.0f);
26243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
26253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
26263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < DE_LENGTH_OF_ARRAY(sampleColors); i++)
26283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dst[i] = sampleColors[i];
26293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
26303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \todo [2014-02-19 pyry] Optimize faceAccesses
26323c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleCubeSeamlessLinear (const ConstPixelBufferAccess (&faceAccesses)[CUBEFACE_LAST], CubeFace baseFace, const Sampler& sampler, float s, float t, int depth)
26333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(faceAccesses[0].getWidth() == faceAccesses[0].getHeight());
26353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		size	= faceAccesses[0].getWidth();
26373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
26383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float	u		= s;
26393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float	v		= t;
26403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
26423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
26433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		u = unnormalize(sampler.wrapS, s, size);
26443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		v = unnormalize(sampler.wrapT, t, size);
26453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
26463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Get sample colors.
26483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 sampleColors[4];
26503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	getCubeLinearSamples(faceAccesses, baseFace, u, v, depth, sampleColors);
26513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
26533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
26553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float b = deFloatFrac(v-0.5f);
26563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (sampleColors[0]*(1.0f-a)*(1.0f-b)) +
26583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (sampleColors[1]*(     a)*(1.0f-b)) +
26593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (sampleColors[2]*(1.0f-a)*(     b)) +
26603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (sampleColors[3]*(     a)*(     b));
26613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
26623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26633c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleLevelArrayCubeSeamless (const ConstPixelBufferAccess* const (&faces)[CUBEFACE_LAST], int numLevels, CubeFace face, const Sampler& sampler, float s, float t, int depth, float lod)
26643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
26663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
26673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
26693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
26703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:
26713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessNearest(faces[face][0], sampler, s, t, depth);
26723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:
26743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
26753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
26763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < (int)CUBEFACE_LAST; i++)
26773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				faceAccesses[i] = faces[i][0];
26783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessLinear(faceAccesses, face, sampler, s, t, depth);
26803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
26813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
26833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
26843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
26853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
26863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
26873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
26883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
26903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessNearest(faces[face][level], sampler, s, t, depth);
26913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
26923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
26933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
26943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
26963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
26973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses[i] = faces[i][level];
26983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessLinear(faceAccesses, face, sampler, s, t, depth);
27003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
27013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
27023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
27043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
27053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
27063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
27073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
27083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level1		= de::min(maxLevel, level0 + 1);
27093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
27103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					f			= deFloatFrac(lod);
27113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec4					t0;
27123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec4					t1;
27133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
27153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
27163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessNearest(faces[face][level0], sampler, s, t, depth);
27173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessNearest(faces[face][level1], sampler, s, t, depth);
27183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
27193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
27203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
27213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
27223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses0[CUBEFACE_LAST];
27243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses1[CUBEFACE_LAST];
27253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
27263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
27273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses0[i] = faces[i][level0];
27283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses1[i] = faces[i][level1];
27293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
27303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessLinear(faceAccesses0, face, sampler, s, t, depth);
27323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessLinear(faceAccesses1, face, sampler, s, t, depth);
27333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
27343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
27363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
27373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
27393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
27403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
27413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
27423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27443c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float sampleCubeSeamlessNearestCompare (const ConstPixelBufferAccess& faceAccess, const Sampler& sampler, float ref, float s, float t, int depth = 0)
27453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler clampingSampler = sampler;
27473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	clampingSampler.wrapS = Sampler::CLAMP_TO_EDGE;
27483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	clampingSampler.wrapT = Sampler::CLAMP_TO_EDGE;
27493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return faceAccess.sample2DCompare(clampingSampler, Sampler::NEAREST, ref, s, t, IVec3(0, 0, depth));
27503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27523c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float sampleCubeSeamlessLinearCompare (const ConstPixelBufferAccess (&faceAccesses)[CUBEFACE_LAST], CubeFace baseFace, const Sampler& sampler, float ref, float s, float t)
27533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(faceAccesses[0].getWidth() == faceAccesses[0].getHeight());
27553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		size	= faceAccesses[0].getWidth();
27573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
27583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float	u		= s;
27593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float	v		= t;
27603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
27623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
27633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		u = unnormalize(sampler.wrapS, s, size);
27643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		v = unnormalize(sampler.wrapT, t, size);
27653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
27663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			x0						= deFloorFloatToInt32(u-0.5f);
27683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			x1						= x0+1;
27693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			y0						= deFloorFloatToInt32(v-0.5f);
27703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			y1						= y0+1;
27713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec2		baseSampleCoords[4]		=
27723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
27733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x0, y0),
27743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x1, y0),
27753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x0, y1),
27763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x1, y1)
27773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
27783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		sampleRes[4];
27793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		hasBothCoordsOutOfBounds[4]; //!< Whether correctCubeFace() returns CUBEFACE_LAST, i.e. both u and v are out of bounds.
27803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Find correct faces and coordinates for out-of-bounds sample coordinates.
27823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
27843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
27853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CubeFaceIntCoords coords = remapCubeEdgeCoords(CubeFaceIntCoords(baseFace, baseSampleCoords[i]), size);
27863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		hasBothCoordsOutOfBounds[i] = coords.face == CUBEFACE_LAST;
27873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!hasBothCoordsOutOfBounds[i])
27893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
27903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool isFixedPointDepth = isFixedPointDepthTextureFormat(faceAccesses[coords.face].getFormat());
27913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sampleRes[i] = execCompare(faceAccesses[coords.face].getPixel(coords.s, coords.t), sampler.compare, sampler.compareChannel, ref, isFixedPointDepth);
27933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
27943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
27953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27963c827367444ee418f129b2c238299f49d3264554Jarkko 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.
27973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note This averaging behavior is not required by the GLES3 spec (though it is recommended). GLES3 spec only
27983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//		 requires that if the three other samples all have the same color, then the doubly-out-of-bounds sample
27993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//		 must have this color as well.
28003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
28023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int bothOutOfBoundsNdx = -1;
28033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < 4; i++)
28043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
28053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (hasBothCoordsOutOfBounds[i])
28063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
28073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(bothOutOfBoundsNdx < 0); // Only one sample can be out of bounds in both u and v.
28083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				bothOutOfBoundsNdx = i;
28093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
28103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
28113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (bothOutOfBoundsNdx != -1)
28123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
28133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sampleRes[bothOutOfBoundsNdx] = 0.0f;
28143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < 4; i++)
28153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (i != bothOutOfBoundsNdx)
28163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					sampleRes[bothOutOfBoundsNdx] += sampleRes[i];
28173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sampleRes[bothOutOfBoundsNdx] = sampleRes[bothOutOfBoundsNdx] * (1.0f/3.0f);
28193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
28203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
28213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
28233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
28253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float b = deFloatFrac(v-0.5f);
28263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (sampleRes[0]*(1.0f-a)*(1.0f-b)) +
28283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (sampleRes[1]*(     a)*(1.0f-b)) +
28293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (sampleRes[2]*(1.0f-a)*(     b)) +
28303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (sampleRes[3]*(     a)*(     b));
28313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28333c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float sampleLevelArrayCubeSeamlessCompare (const ConstPixelBufferAccess* const (&faces)[CUBEFACE_LAST], int numLevels, CubeFace face, const Sampler& sampler, float ref, float s, float t, float lod)
28343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
28363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
28373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
28393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
28403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:
28413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessNearestCompare(faces[face][0], sampler, ref, s, t);
28423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:
28443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
28453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
28463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < (int)CUBEFACE_LAST; i++)
28473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				faceAccesses[i] = faces[i][0];
28483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessLinearCompare(faceAccesses, face, sampler, ref, s, t);
28503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
28513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
28533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
28543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
28553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
28563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
28573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
28583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
28603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessNearestCompare(faces[face][level], sampler, ref, s, t);
28613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
28623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
28633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
28643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
28663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
28673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses[i] = faces[i][level];
28683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessLinearCompare(faceAccesses, face, sampler, ref, s, t);
28703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
28713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
28723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
28743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
28753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
28763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
28773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
28783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level1		= de::min(maxLevel, level0 + 1);
28793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
28803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					f			= deFloatFrac(lod);
28813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					t0;
28823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					t1;
28833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
28853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
28863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessNearestCompare(faces[face][level0], sampler, ref, s, t);
28873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessNearestCompare(faces[face][level1], sampler, ref, s, t);
28883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
28893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
28903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
28913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
28923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses0[CUBEFACE_LAST];
28943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses1[CUBEFACE_LAST];
28953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
28963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
28973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses0[i] = faces[i][level0];
28983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses1[i] = faces[i][level1];
28993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
29003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessLinearCompare(faceAccesses0, face, sampler, ref, s, t);
29023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessLinearCompare(faceAccesses1, face, sampler, ref, s, t);
29033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
29043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
29063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
29073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
29093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
29103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
29113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
29123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Cube map array sampling
29153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29163c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline ConstPixelBufferAccess getCubeArrayFaceAccess (const ConstPixelBufferAccess* const levels, int levelNdx, int slice, CubeFace face)
29173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ConstPixelBufferAccess&	level	= levels[levelNdx];
29193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						depth	= (slice * 6) + getCubeArrayFaceIndex(face);
29203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return getSubregion(level, 0, 0, depth, level.getWidth(), level.getHeight(), 1);
29223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29243c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleCubeArraySeamless (const ConstPixelBufferAccess* const levels, int numLevels, int slice, CubeFace face, const Sampler& sampler, float s, float t, float lod)
29253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					faceDepth	= (slice * 6) + getCubeArrayFaceIndex(face);
29273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool					magnified	= lod <= sampler.lodThreshold;
29283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Sampler::FilterMode	filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
29293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
29313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
29323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:
29333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessNearest(levels[0], sampler, s, t, faceDepth);
29343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:
29363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
29373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
29383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < (int)CUBEFACE_LAST; i++)
29393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				faceAccesses[i] = getCubeArrayFaceAccess(levels, 0, slice, (CubeFace)i);
29403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessLinear(faceAccesses, face, sampler, s, t, 0);
29423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
29433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
29453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
29463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
29473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
29483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
29493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
29503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
29523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessNearest(levels[level], sampler, s, t, faceDepth);
29533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
29543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
29553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
29563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
29583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
29593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses[i] = getCubeArrayFaceAccess(levels, level, slice, (CubeFace)i);
29603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessLinear(faceAccesses, face, sampler, s, t, 0);
29623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
29633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
29643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
29663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
29673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
29683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
29693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
29703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level1		= de::min(maxLevel, level0 + 1);
29713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
29723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					f			= deFloatFrac(lod);
29733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec4					t0;
29743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec4					t1;
29753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
29773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
29783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessNearest(levels[level0], sampler, s, t, faceDepth);
29793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessNearest(levels[level1], sampler, s, t, faceDepth);
29803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
29813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
29823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
29833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
29843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses0[CUBEFACE_LAST];
29863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses1[CUBEFACE_LAST];
29873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
29883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
29893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses0[i] = getCubeArrayFaceAccess(levels, level0, slice, (CubeFace)i);
29903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses1[i] = getCubeArrayFaceAccess(levels, level1, slice, (CubeFace)i);
29913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
29923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessLinear(faceAccesses0, face, sampler, s, t, 0);
29943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessLinear(faceAccesses1, face, sampler, s, t, 0);
29953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
29963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
29983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
29993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
30013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
30023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
30033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
30043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30063c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float sampleCubeArraySeamlessCompare (const ConstPixelBufferAccess* const levels, int numLevels, int slice, CubeFace face, const Sampler& sampler, float ref, float s, float t, float lod)
30073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int			faceDepth	= (slice * 6) + getCubeArrayFaceIndex(face);
30093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool			magnified	= lod <= sampler.lodThreshold;
30103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode	filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
30113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
30133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
30143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:
30153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessNearestCompare(levels[0], sampler, ref, s, t, faceDepth);
30163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:
30183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
30193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
30203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < (int)CUBEFACE_LAST; i++)
30213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				faceAccesses[i] = getCubeArrayFaceAccess(levels, 0, slice, (CubeFace)i);
30223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessLinearCompare(faceAccesses, face, sampler, ref, s, t);
30243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
30253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
30273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
30283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
30293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
30303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
30313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
30323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
30343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessNearestCompare(levels[level], sampler, ref, s, t, faceDepth);
30353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
30363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
30373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
30383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
30403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
30413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses[i] = getCubeArrayFaceAccess(levels, level, slice, (CubeFace)i);
30423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessLinearCompare(faceAccesses, face, sampler, ref, s, t);
30443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
30453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
30463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
30483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
30493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
30503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
30513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
30523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level1		= de::min(maxLevel, level0 + 1);
30533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
30543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					f			= deFloatFrac(lod);
30553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					t0;
30563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					t1;
30573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
30593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
30603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessNearestCompare(levels[level0], sampler, ref, s, t, faceDepth);
30613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessNearestCompare(levels[level1], sampler, ref, s, t, faceDepth);
30623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
30633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
30643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
30653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
30663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses0[CUBEFACE_LAST];
30683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses1[CUBEFACE_LAST];
30693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
30703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
30713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses0[i] = getCubeArrayFaceAccess(levels, level0, slice, (CubeFace)i);
30723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses1[i] = getCubeArrayFaceAccess(levels, level1, slice, (CubeFace)i);
30733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
30743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessLinearCompare(faceAccesses0, face, sampler, ref, s, t);
30763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessLinearCompare(faceAccesses1, face, sampler, ref, s, t);
30773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
30783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
30803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
30813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
30833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
30843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
30853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
30863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30883c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int computeMipPyramidLevels (int size)
30893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return deLog2Floor32(size)+1;
30913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30933c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int computeMipPyramidLevels (int width, int height)
30943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return deLog2Floor32(de::max(width, height))+1;
30963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30983c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int computeMipPyramidLevels (int width, int height, int depth)
30993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return deLog2Floor32(de::max(width, de::max(height, depth)))+1;
31013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31033c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int getMipPyramidLevelSize (int baseLevelSize, int levelNdx)
31043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return de::max(baseLevelSize >> levelNdx, 1);
31063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// TextureLevelPyramid
31093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31103c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevelPyramid::TextureLevelPyramid (const TextureFormat& format, int numLevels)
31113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	(format)
31123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_data	(numLevels)
31133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_access	(numLevels)
31143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31173c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevelPyramid::TextureLevelPyramid (const TextureLevelPyramid& other)
31183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	(other.m_format)
31193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_data	(other.getNumLevels())
31203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_access	(other.getNumLevels())
31213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int levelNdx = 0; levelNdx < other.getNumLevels(); levelNdx++)
31233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
31243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!other.isLevelEmpty(levelNdx))
31253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
31263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::ConstPixelBufferAccess& srcLevel = other.getLevel(levelNdx);
31273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_data[levelNdx] = other.m_data[levelNdx];
31293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_access[levelNdx] = PixelBufferAccess(srcLevel.getFormat(), srcLevel.getWidth(), srcLevel.getHeight(), srcLevel.getDepth(), m_data[levelNdx].getPtr());
31303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
31313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
31323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31343c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevelPyramid& TextureLevelPyramid::operator= (const TextureLevelPyramid& other)
31353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
31373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
31383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_format = other.m_format;
31403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_data.resize(other.getNumLevels());
31413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_access.resize(other.getNumLevels());
31423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int levelNdx = 0; levelNdx < other.getNumLevels(); levelNdx++)
31443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
31453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!other.isLevelEmpty(levelNdx))
31463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
31473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::ConstPixelBufferAccess& srcLevel = other.getLevel(levelNdx);
31483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_data[levelNdx] = other.m_data[levelNdx];
31503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_access[levelNdx] = PixelBufferAccess(srcLevel.getFormat(), srcLevel.getWidth(), srcLevel.getHeight(), srcLevel.getDepth(), m_data[levelNdx].getPtr());
31513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
31523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (!isLevelEmpty(levelNdx))
31533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			clearLevel(levelNdx);
31543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
31553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
31573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31593c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevelPyramid::~TextureLevelPyramid (void)
31603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureLevelPyramid::allocLevel (int levelNdx, int width, int height, int depth)
31643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	size	= m_format.getPixelSize()*width*height*depth;
31663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(isLevelEmpty(levelNdx));
31683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_data[levelNdx].setStorage(size);
31703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_access[levelNdx] = PixelBufferAccess(m_format, width, height, depth, m_data[levelNdx].getPtr());
31713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureLevelPyramid::clearLevel (int levelNdx)
31743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!isLevelEmpty(levelNdx));
31763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_data[levelNdx].clear();
31783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_access[levelNdx] = PixelBufferAccess();
31793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture1D
31823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31833c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1D::Texture1D (const TextureFormat& format, int width)
31843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(format, computeMipPyramidLevels(width))
31853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(width)
31863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
31873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31903c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1D::Texture1D (const Texture1D& other)
31913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(other)
31923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(other.m_width)
31933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
31943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31973c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1D& Texture1D::operator= (const Texture1D& other)
31983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
32003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
32013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::operator=(other);
32033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_width		= other.m_width;
32053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view		= Texture1DView(getNumLevels(), getLevels());
32063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
32083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32103c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1D::~Texture1D (void)
32113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32143c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture1D::allocLevel (int levelNdx)
32153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels()));
32173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int width = getMipPyramidLevelSize(m_width, levelNdx);
32193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::allocLevel(levelNdx, width, 1, 1);
32213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture2D
32243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32253c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2D::Texture2D (const TextureFormat& format, int width, int height)
32263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(format, computeMipPyramidLevels(width, height))
32273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(width)
32283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height				(height)
32293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
32303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32333c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2D::Texture2D (const Texture2D& other)
32343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(other)
32353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(other.m_width)
32363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height				(other.m_height)
32373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
32383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32413c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2D& Texture2D::operator= (const Texture2D& other)
32423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
32443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
32453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::operator=(other);
32473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_width		= other.m_width;
32493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_height	= other.m_height;
32503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view		= Texture2DView(getNumLevels(), getLevels());
32513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
32533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32553c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2D::~Texture2D (void)
32563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2D::allocLevel (int levelNdx)
32603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels()));
32623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	width	= getMipPyramidLevelSize(m_width, levelNdx);
32643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	height	= getMipPyramidLevelSize(m_height, levelNdx);
32653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::allocLevel(levelNdx, width, height, 1);
32673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// TextureCubeView
32703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32713c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeView::TextureCubeView (void)
32723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_numLevels(0)
32733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < CUBEFACE_LAST; ndx++)
32753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_levels[ndx] = DE_NULL;
32763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32783c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeView::TextureCubeView (int numLevels, const ConstPixelBufferAccess* const (&levels) [CUBEFACE_LAST])
32793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_numLevels(numLevels)
32803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < CUBEFACE_LAST; ndx++)
32823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_levels[ndx] = levels[ndx];
32833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Vec4 TextureCubeView::sample (const Sampler& sampler, float s, float t, float r, float lod) const
32863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare == Sampler::COMPAREMODE_NONE);
32883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Computes (face, s, t).
32903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CubeFaceFloatCoords coords = getCubeFaceCoords(Vec3(s, t, r));
32913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.seamlessCubeMap)
32923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sampleLevelArrayCubeSeamless(m_levels, m_numLevels, coords.face, sampler, coords.s, coords.t, 0 /* depth */, lod);
32933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
32943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sampleLevelArray2D(m_levels[coords.face], m_numLevels, sampler, coords.s, coords.t, 0 /* depth */, lod);
32953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32973c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat TextureCubeView::sampleCompare (const Sampler& sampler, float ref, float s, float t, float r, float lod) const
32983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare != Sampler::COMPAREMODE_NONE);
33003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Computes (face, s, t).
33023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CubeFaceFloatCoords coords = getCubeFaceCoords(Vec3(s, t, r));
33033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.seamlessCubeMap)
33043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sampleLevelArrayCubeSeamlessCompare(m_levels, m_numLevels, coords.face, sampler, ref, coords.s, coords.t, lod);
33053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
33063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sampleLevelArray2DCompare(m_levels[coords.face], m_numLevels, sampler, ref, coords.s, coords.t, lod, IVec3(0, 0, 0));
33073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33093c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 TextureCubeView::gather (const Sampler& sampler, float s, float t, float r, int componentNdx) const
33103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare == Sampler::COMPAREMODE_NONE);
33123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
33143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)CUBEFACE_LAST; i++)
33153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		faceAccesses[i] = m_levels[i][0];
33163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CubeFaceFloatCoords	coords	= getCubeFaceCoords(Vec3(s, t, r));
33183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					size	= faceAccesses[0].getWidth();
33193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
33203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float						u		= coords.s;
33213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float						v		= coords.t;
33223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
33243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
33253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		u = unnormalize(sampler.wrapS, coords.s, size);
33263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		v = unnormalize(sampler.wrapT, coords.t, size);
33273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
33283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 sampleColors[4];
33303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	getCubeLinearSamples(faceAccesses, coords.face, u, v, 0, sampleColors);
33313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	sampleIndices[4] = { 2, 3, 1, 0 }; // \note Gather returns the samples in a non-obvious order.
33333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4		result;
33343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
33353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result[i] = sampleColors[sampleIndices[i]][componentNdx];
33363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
33383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33403c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 TextureCubeView::gatherCompare (const Sampler& sampler, float ref, float s, float t, float r) const
33413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare != Sampler::COMPAREMODE_NONE);
33433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_levels[0][0].getFormat().order == TextureFormat::D || m_levels[0][0].getFormat().order == TextureFormat::DS);
33443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compareChannel == 0);
33453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler noCompareSampler = sampler;
33473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	noCompareSampler.compare = Sampler::COMPAREMODE_NONE;
33483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec4 gathered			= gather(noCompareSampler, s, t, r, 0 /* component 0: depth */);
33503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool isFixedPoint		= isFixedPointDepthTextureFormat(m_levels[0][0].getFormat());
33513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 result;
33523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
33533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result[i] = execCompare(gathered, sampler.compare, i, ref, isFixedPoint);
33543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
33563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// TextureCube
33593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33603c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCube::TextureCube (const TextureFormat& format, int size)
33613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	(format)
33623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_size	(size)
33633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						numLevels		= computeMipPyramidLevels(m_size);
33653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ConstPixelBufferAccess*	levels[CUBEFACE_LAST];
33663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int face = 0; face < CUBEFACE_LAST; face++)
33683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
33693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_data[face].resize(numLevels);
33703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_access[face].resize(numLevels);
33713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		levels[face] = &m_access[face][0];
33723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
33733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view = TextureCubeView(numLevels, levels);
33753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33773c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCube::TextureCube (const TextureCube& other)
33783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	(other.m_format)
33793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_size	(other.m_size)
33803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						numLevels		= computeMipPyramidLevels(m_size);
33823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ConstPixelBufferAccess*	levels[CUBEFACE_LAST];
33833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int face = 0; face < CUBEFACE_LAST; face++)
33853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
33863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_data[face].resize(numLevels);
33873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_access[face].resize(numLevels);
33883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		levels[face] = &m_access[face][0];
33893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
33903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view = TextureCubeView(numLevels, levels);
33923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
33943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
33953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int face = 0; face < CUBEFACE_LAST; face++)
33963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
33973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!other.isLevelEmpty((CubeFace)face, levelNdx))
33983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
33993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				allocLevel((CubeFace)face, levelNdx);
34003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				copy(getLevelFace(levelNdx, (CubeFace)face),
34013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 other.getLevelFace(levelNdx, (CubeFace)face));
34023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
34033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
34043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
34053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34073c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCube& TextureCube::operator= (const TextureCube& other)
34083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
34103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
34113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						numLevels		= computeMipPyramidLevels(other.m_size);
34133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ConstPixelBufferAccess*	levels[CUBEFACE_LAST];
34143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int face = 0; face < CUBEFACE_LAST; face++)
34163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
34173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_data[face].resize(numLevels);
34183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_access[face].resize(numLevels);
34193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		levels[face] = &m_access[face][0];
34203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
34213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_format	= other.m_format;
34233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_size		= other.m_size;
34243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view		= TextureCubeView(numLevels, levels);
34253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
34273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
34283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int face = 0; face < CUBEFACE_LAST; face++)
34293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
34303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!isLevelEmpty((CubeFace)face, levelNdx))
34313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				clearLevel((CubeFace)face, levelNdx);
34323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!other.isLevelEmpty((CubeFace)face, levelNdx))
34343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
34353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				allocLevel((CubeFace)face, levelNdx);
34363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				copy(getLevelFace(levelNdx, (CubeFace)face),
34373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 other.getLevelFace(levelNdx, (CubeFace)face));
34383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
34393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
34403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
34413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
34433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34453c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCube::~TextureCube (void)
34463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCube::allocLevel (tcu::CubeFace face, int levelNdx)
34503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	size		= getMipPyramidLevelSize(m_size, levelNdx);
34523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	dataSize	= m_format.getPixelSize()*size*size;
34533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(isLevelEmpty(face, levelNdx));
34543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_data[face][levelNdx].setStorage(dataSize);
34563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_access[face][levelNdx] = PixelBufferAccess(m_format, size, size, 1, m_data[face][levelNdx].getPtr());
34573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCube::clearLevel (tcu::CubeFace face, int levelNdx)
34603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!isLevelEmpty(face, levelNdx));
34623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_data[face][levelNdx].clear();
34633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_access[face][levelNdx] = PixelBufferAccess();
34643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture1DArrayView
34673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34683c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1DArrayView::Texture1DArrayView (int numLevels, const ConstPixelBufferAccess* levels)
34693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_numLevels	(numLevels)
34703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_levels		(levels)
34713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34743c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int Texture1DArrayView::selectLayer (float r) const
34753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_numLevels > 0 && m_levels);
34773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return de::clamp(deFloorFloatToInt32(r + 0.5f), 0, m_levels[0].getHeight()-1);
34783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34803c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 Texture1DArrayView::sample (const Sampler& sampler, float s, float t, float lod) const
34813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray1D(m_levels, m_numLevels, sampler, s, selectLayer(t), lod);
34833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34853c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 Texture1DArrayView::sampleOffset (const Sampler& sampler, float s, float t, float lod, deInt32 offset) const
34863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray1DOffset(m_levels, m_numLevels, sampler, s, lod, IVec2(offset, selectLayer(t)));
34883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat Texture1DArrayView::sampleCompare (const Sampler& sampler, float ref, float s, float t, float lod) const
34913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray1DCompare(m_levels, m_numLevels, sampler, ref, s, lod, IVec2(0, selectLayer(t)));
34933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34953c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat Texture1DArrayView::sampleCompareOffset (const Sampler& sampler, float ref, float s, float t, float lod, deInt32 offset) const
34963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray1DCompare(m_levels, m_numLevels, sampler, ref, s, lod, IVec2(offset, selectLayer(t)));
34983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture2DArrayView
35013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35023c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArrayView::Texture2DArrayView (int numLevels, const ConstPixelBufferAccess* levels)
35033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_numLevels	(numLevels)
35043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_levels		(levels)
35053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35083c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int Texture2DArrayView::selectLayer (float r) const
35093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_numLevels > 0 && m_levels);
35113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return de::clamp(deFloorFloatToInt32(r + 0.5f), 0, m_levels[0].getDepth()-1);
35123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35143c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 Texture2DArrayView::sample (const Sampler& sampler, float s, float t, float r, float lod) const
35153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray2D(m_levels, m_numLevels, sampler, s, t, selectLayer(r), lod);
35173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35193c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat Texture2DArrayView::sampleCompare (const Sampler& sampler, float ref, float s, float t, float r, float lod) const
35203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray2DCompare(m_levels, m_numLevels, sampler, ref, s, t, lod, IVec3(0, 0, selectLayer(r)));
35223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35243c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 Texture2DArrayView::sampleOffset (const Sampler& sampler, float s, float t, float r, float lod, const IVec2& offset) const
35253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray2DOffset(m_levels, m_numLevels, sampler, s, t, lod, IVec3(offset.x(), offset.y(), selectLayer(r)));
35273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35293c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat Texture2DArrayView::sampleCompareOffset (const Sampler& sampler, float ref, float s, float t, float r, float lod, const IVec2& offset) const
35303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray2DCompare(m_levels, m_numLevels, sampler, ref, s, t, lod, IVec3(offset.x(), offset.y(), selectLayer(r)));
35323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35343c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 Texture2DArrayView::gatherOffsets (const Sampler& sampler, float s, float t, float r, int componentNdx, const IVec2 (&offsets)[4]) const
35353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return gatherArray2DOffsets(m_levels[0], sampler, s, t, selectLayer(r), componentNdx, offsets);
35373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35393c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 Texture2DArrayView::gatherOffsetsCompare (const Sampler& sampler, float ref, float s, float t, float r, const IVec2 (&offsets)[4]) const
35403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return gatherArray2DOffsetsCompare(m_levels[0], sampler, ref, s, t, selectLayer(r), offsets);
35423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture1DArray
35453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35463c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1DArray::Texture1DArray (const TextureFormat& format, int width, int numLayers)
35473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(format, computeMipPyramidLevels(width))
35483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(width)
35493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numLayers			(numLayers)
35503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
35513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35543c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1DArray::Texture1DArray (const Texture1DArray& other)
35553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(other)
35563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(other.m_width)
35573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numLayers			(other.m_numLayers)
35583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
35593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35623c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1DArray& Texture1DArray::operator= (const Texture1DArray& other)
35633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
35653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
35663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::operator=(other);
35683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_width		= other.m_width;
35703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_numLayers	= other.m_numLayers;
35713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view		= Texture1DArrayView(getNumLevels(), getLevels());
35723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
35743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35763c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1DArray::~Texture1DArray (void)
35773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture1DArray::allocLevel (int levelNdx)
35813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels()));
35833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int width = getMipPyramidLevelSize(m_width, levelNdx);
35853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::allocLevel(levelNdx, width, m_numLayers, 1);
35873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture2DArray
35903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35913c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArray::Texture2DArray (const TextureFormat& format, int width, int height, int numLayers)
35923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(format, computeMipPyramidLevels(width, height))
35933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(width)
35943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height				(height)
35953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numLayers			(numLayers)
35963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
35973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36003c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArray::Texture2DArray (const Texture2DArray& other)
36013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(other)
36023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(other.m_width)
36033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height				(other.m_height)
36043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numLayers			(other.m_numLayers)
36053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
36063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36093c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArray& Texture2DArray::operator= (const Texture2DArray& other)
36103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
36123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
36133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::operator=(other);
36153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_width		= other.m_width;
36173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_height	= other.m_height;
36183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_numLayers	= other.m_numLayers;
36193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view		= Texture2DArrayView(getNumLevels(), getLevels());
36203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
36223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36243c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArray::~Texture2DArray (void)
36253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36283c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2DArray::allocLevel (int levelNdx)
36293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels()));
36313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	width	= getMipPyramidLevelSize(m_width,	levelNdx);
36333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	height	= getMipPyramidLevelSize(m_height,	levelNdx);
36343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::allocLevel(levelNdx, width, height, m_numLayers);
36363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture3DView
36393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36403c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3DView::Texture3DView (int numLevels, const ConstPixelBufferAccess* levels)
36413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_numLevels	(numLevels)
36423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_levels		(levels)
36433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture3D
36473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36483c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3D::Texture3D (const TextureFormat& format, int width, int height, int depth)
36493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(format, computeMipPyramidLevels(width, height, depth))
36503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(width)
36513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height				(height)
36523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_depth				(depth)
36533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
36543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36573c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3D::Texture3D (const Texture3D& other)
36583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(other)
36593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(other.m_width)
36603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height				(other.m_height)
36613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_depth				(other.m_depth)
36623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
36633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36663c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3D& Texture3D::operator= (const Texture3D& other)
36673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
36693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
36703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::operator=(other);
36723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_width		= other.m_width;
36743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_height	= other.m_height;
36753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_depth		= other.m_depth;
36763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view		= Texture3DView(getNumLevels(), getLevels());
36773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
36793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36813c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3D::~Texture3D (void)
36823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36853c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture3D::allocLevel (int levelNdx)
36863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels()));
36883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int width		= getMipPyramidLevelSize(m_width,	levelNdx);
36903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int height	= getMipPyramidLevelSize(m_height,	levelNdx);
36913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int depth		= getMipPyramidLevelSize(m_depth,	levelNdx);
36923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::allocLevel(levelNdx, width, height, depth);
36943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// TextureCubeArrayView
36973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36983c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeArrayView::TextureCubeArrayView (int numLevels, const ConstPixelBufferAccess* levels)
36993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_numLevels	(numLevels)
37003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_levels		(levels)
37013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
37023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
37033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37048852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryinline int TextureCubeArrayView::selectLayer (float q) const
37053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
37063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_numLevels > 0 && m_levels);
37073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT((m_levels[0].getDepth() % 6) == 0);
37083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return de::clamp(deFloorFloatToInt32(q + 0.5f), 0, (m_levels[0].getDepth() / 6)-1);
37103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
37113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37123c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Vec4 TextureCubeArrayView::sample (const Sampler& sampler, float s, float t, float r, float q, float lod) const
37133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
37143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CubeFaceFloatCoords	coords		= getCubeFaceCoords(Vec3(s, t, r));
37158852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const int					layer		= selectLayer(q);
37168852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const int					faceDepth	= (layer * 6) + getCubeArrayFaceIndex(coords.face);
37173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare == Sampler::COMPAREMODE_NONE);
37193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.seamlessCubeMap)
37218852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		return sampleCubeArraySeamless(m_levels, m_numLevels, layer, coords.face, sampler, coords.s, coords.t, lod);
37223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
37233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sampleLevelArray2D(m_levels, m_numLevels, sampler, coords.s, coords.t, faceDepth, lod);
37243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
37253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37263c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat TextureCubeArrayView::sampleCompare (const Sampler& sampler, float ref, float s, float t, float r, float q, float lod) const
37273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
37283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CubeFaceFloatCoords	coords		= getCubeFaceCoords(Vec3(s, t, r));
37298852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const int					layer		= selectLayer(q);
37308852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const int					faceDepth	= (layer * 6) + getCubeArrayFaceIndex(coords.face);
37313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare != Sampler::COMPAREMODE_NONE);
37333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.seamlessCubeMap)
37358852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		return sampleCubeArraySeamlessCompare(m_levels, m_numLevels, layer, coords.face, sampler, ref, coords.s, coords.t, lod);
37363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
37373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sampleLevelArray2DCompare(m_levels, m_numLevels, sampler, ref, coords.s, coords.t, lod, IVec3(0, 0, faceDepth));
37383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
37393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// TextureCubeArray
37413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37428852c82a1ffa4760985c17cc6875d5d521daf343Jarkko PoyryTextureCubeArray::TextureCubeArray (const TextureFormat& format, int size, int depth)
37433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(format, computeMipPyramidLevels(size))
37443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_size				(size)
37458852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	, m_depth				(depth)
37463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
37473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
37488852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	DE_ASSERT(m_depth % 6 == 0);
37493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
37503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37513c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeArray::TextureCubeArray (const TextureCubeArray& other)
37523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(other)
37533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_size				(other.m_size)
37548852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	, m_depth				(other.m_depth)
37553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
37563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
37578852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	DE_ASSERT(m_depth % 6 == 0);
37583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
37593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37603c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeArray& TextureCubeArray::operator= (const TextureCubeArray& other)
37613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
37623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
37633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
37643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::operator=(other);
37663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37678852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	m_size	= other.m_size;
37688852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	m_depth	= other.m_depth;
37698852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	m_view	= TextureCubeArrayView(getNumLevels(), getLevels());
37703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37718852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	DE_ASSERT(m_depth % 6 == 0);
37723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
37743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
37753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37763c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeArray::~TextureCubeArray (void)
37773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
37783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
37793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCubeArray::allocLevel (int levelNdx)
37813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
37823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels()));
37833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int size = getMipPyramidLevelSize(m_size, levelNdx);
37853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37868852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	TextureLevelPyramid::allocLevel(levelNdx, size, size, m_depth);
37873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
37883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37893c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& str, TextureFormat::ChannelOrder order)
37903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3791ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	const char* const orderStrings[] =
3792ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	{
3793ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"R",
3794ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"A",
3795ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"I",
3796ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"L",
3797ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"LA",
3798ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"RG",
3799ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"RA",
3800ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"RGB",
3801ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"RGBA",
3802ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"ARGB",
3803725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"BGR",
3804ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"BGRA",
3805ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi
380616d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		"sR",
380716d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		"sRG",
3808ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"sRGB",
3809ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"sRGBA",
3810725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"sBGR",
3811725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"sBGRA",
3812ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi
3813ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"D",
3814ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"S",
3815ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"DS"
3816ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	};
3817ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi
3818ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	return str << de::getSizedArrayElement<TextureFormat::CHANNELORDER_LAST>(orderStrings, order);
38193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
38203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38213c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& str, TextureFormat::ChannelType type)
38223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3823ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	const char* const typeStrings[] =
3824ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	{
3825ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"SNORM_INT8",
3826ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"SNORM_INT16",
3827ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"SNORM_INT32",
3828ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_INT8",
3829ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_INT16",
383007104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry		"UNORM_INT24",
3831ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_INT32",
3832725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"UNORM_BYTE_44",
3833ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_SHORT_565",
3834ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_SHORT_555",
3835ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_SHORT_4444",
3836ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_SHORT_5551",
38375b2b45177edf5062ce3a76a885e60e3fb5044002Pyry Haulos		"UNORM_SHORT_1555",
3838ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_INT_101010",
3839725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"SNORM_INT_1010102_REV",
3840ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_INT_1010102_REV",
3841725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"UNSIGNED_BYTE_44",
3842725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"UNSIGNED_SHORT_565",
3843725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"UNSIGNED_SHORT_4444",
3844725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"UNSIGNED_SHORT_5551",
3845725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"SIGNED_INT_1010102_REV",
3846ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT_1010102_REV",
3847ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT_11F_11F_10F_REV",
3848ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT_999_E5_REV",
3849725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"UNSIGNED_INT_16_8_8",
3850ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT_24_8",
3851725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"UNSIGNED_INT_24_8_REV",
3852ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"SIGNED_INT8",
3853ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"SIGNED_INT16",
3854ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"SIGNED_INT32",
3855ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT8",
3856ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT16",
3857db6ba452c1213fd1c2b03369fdf4c1d23f07cfadJarkko Pöyry		"UNSIGNED_INT24",
3858ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT32",
3859ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"HALF_FLOAT",
3860ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"FLOAT",
3861725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"FLOAT64",
3862fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi		"FLOAT_UNSIGNED_INT_24_8_REV",
3863fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi		"UNORM_SHORT_10",
3864fc8d2c5cad616ca8994be9d2dd94885f3953100dMika Isojärvi		"UNORM_SHORT_12"
3865ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	};
3866ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi
3867ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	return str << de::getSizedArrayElement<TextureFormat::CHANNELTYPE_LAST>(typeStrings, type);
38683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
38693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38703c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& str, CubeFace face)
38713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
38723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (face)
38733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
38743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_X:	return str << "CUBEFACE_NEGATIVE_X";
38753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_X:	return str << "CUBEFACE_POSITIVE_X";
38763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_Y:	return str << "CUBEFACE_NEGATIVE_Y";
38773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_Y:	return str << "CUBEFACE_POSITIVE_Y";
38783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_Z:	return str << "CUBEFACE_NEGATIVE_Z";
38793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_Z:	return str << "CUBEFACE_POSITIVE_Z";
38803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_LAST:			return str << "CUBEFACE_LAST";
38813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:					return str << "UNKNOWN(" << (int)face << ")";
38823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
38833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
38843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& str, TextureFormat format)
38863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
38873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return str << format.order << ", " << format.type << "";
38883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
38893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38903c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& str, const ConstPixelBufferAccess& access)
38913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
38923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return str << "format = (" << access.getFormat() << "), size = "
38933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			   << access.getWidth() << " x " << access.getHeight() << " x " << access.getDepth()
38943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			   << ", pitch = " << access.getRowPitch() << " / " << access.getSlicePitch();
38953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
38963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // tcu
3898