tcuTexture.cpp revision e2145884f87cdca749a754abfd246cdfe01ea2c1
13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program Tester Core
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * ----------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Reference Texture Implementation.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTexture.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deInt32.h"
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deFloat16.h"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMath.h"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMemory.h"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuSurface.hpp"
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuFloat.hpp"
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTextureUtil.hpp"
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp"
34d6148171f88da1301f053e2e0236afc69416137cJarkko Pöyry#include "deArrayUtil.hpp"
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <limits>
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace tcu
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41e2145884f87cdca749a754abfd246cdfe01ea2c1Pyry Haulos// \note No sign. Denorms are supported.
42e2145884f87cdca749a754abfd246cdfe01ea2c1Pyry Haulostypedef Float<deUint32, 5, 6, 15, FLOAT_SUPPORT_DENORM>	Float11;
43e2145884f87cdca749a754abfd246cdfe01ea2c1Pyry Haulostypedef Float<deUint32, 5, 5, 15, FLOAT_SUPPORT_DENORM>	Float10;
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Optimized getters for common formats.
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \todo [2012-11-14 pyry] Use intrinsics if available.
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline Vec4		readRGBA8888Float	(const deUint8* ptr) { return Vec4(ptr[0]/255.0f, ptr[1]/255.0f, ptr[2]/255.0f, ptr[3]/255.0f); }
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline Vec4		readRGB888Float		(const deUint8* ptr) { return Vec4(ptr[0]/255.0f, ptr[1]/255.0f, ptr[2]/255.0f, 1.0f); }
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline IVec4	readRGBA8888Int		(const deUint8* ptr) { return IVec4(ptr[0], ptr[1], ptr[2], ptr[3]); }
54e2145884f87cdca749a754abfd246cdfe01ea2c1Pyry Haulosinline IVec4	readRGB888Int		(const deUint8* ptr) { return IVec4(ptr[0], ptr[1], ptr[2], 1); }
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Optimized setters.
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline void writeRGBA8888Int (deUint8* ptr, const IVec4& val)
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6009307280328f7fe333960a53cddf8c2962af5536Jarkko Pöyry	ptr[0] = (deUint8)de::clamp(val[0], 0, 255);
6109307280328f7fe333960a53cddf8c2962af5536Jarkko Pöyry	ptr[1] = (deUint8)de::clamp(val[1], 0, 255);
6209307280328f7fe333960a53cddf8c2962af5536Jarkko Pöyry	ptr[2] = (deUint8)de::clamp(val[2], 0, 255);
6309307280328f7fe333960a53cddf8c2962af5536Jarkko Pöyry	ptr[3] = (deUint8)de::clamp(val[3], 0, 255);
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline void writeRGB888Int (deUint8* ptr, const IVec4& val)
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6809307280328f7fe333960a53cddf8c2962af5536Jarkko Pöyry	ptr[0] = (deUint8)de::clamp(val[0], 0, 255);
6909307280328f7fe333960a53cddf8c2962af5536Jarkko Pöyry	ptr[1] = (deUint8)de::clamp(val[1], 0, 255);
7009307280328f7fe333960a53cddf8c2962af5536Jarkko Pöyry	ptr[2] = (deUint8)de::clamp(val[2], 0, 255);
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline void writeRGBA8888Float (deUint8* ptr, const Vec4& val)
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ptr[0] = floatToU8(val[0]);
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ptr[1] = floatToU8(val[1]);
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ptr[2] = floatToU8(val[2]);
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ptr[3] = floatToU8(val[3]);
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline void writeRGB888Float (deUint8* ptr, const Vec4& val)
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ptr[0] = floatToU8(val[0]);
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ptr[1] = floatToU8(val[1]);
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ptr[2] = floatToU8(val[2]);
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8807104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyryinline void writeUint24 (deUint8* dst, deUint32 val)
8907104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry{
9007104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN)
9107104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	dst[0] = (deUint8)((val & 0x0000FFu) >>  0u);
9207104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	dst[1] = (deUint8)((val & 0x00FF00u) >>  8u);
9307104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	dst[2] = (deUint8)((val & 0xFF0000u) >> 16u);
9407104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry#else
9507104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	dst[0] = (deUint8)((val & 0xFF0000u) >> 16u);
9607104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	dst[1] = (deUint8)((val & 0x00FF00u) >>  8u);
9707104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	dst[2] = (deUint8)((val & 0x0000FFu) >>  0u);
9807104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry#endif
9907104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry}
10007104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
10107104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyryinline deUint32 readUint24 (const deUint8* src)
10207104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry{
10307104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN)
10407104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	return	(((deUint32)src[0]) <<  0u) |
10507104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry			(((deUint32)src[1]) <<  8u) |
10607104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry			(((deUint32)src[2]) << 16u);
10707104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry#else
10807104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	return	(((deUint32)src[0]) << 16u) |
10907104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry			(((deUint32)src[1]) <<  8u) |
11007104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry			(((deUint32)src[2]) <<  0u);
11107104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry#endif
11207104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry}
11307104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
114725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulosinline deUint8 readUint32Low8 (const deUint8* src)
11500d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos{
11600d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN)
117725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 uint32ByteOffsetBits0To8	= 0; //!< least significant byte in the lowest address
11800d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos#else
119725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 uint32ByteOffsetBits0To8	= 3; //!< least significant byte in the highest address
12000d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos#endif
12100d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos
122725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	return src[uint32ByteOffsetBits0To8];
12300d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos}
12400d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos
125725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulosinline deUint8 readUint32High8 (const deUint8* src)
12600d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos{
12700d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN)
128725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 uint32ByteOffsetBits24To32	= 3;
12900d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos#else
130725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 uint32ByteOffsetBits24To32	= 0;
13100d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos#endif
13200d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos
133725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	return src[uint32ByteOffsetBits24To32];
13400d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos}
13500d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos
136725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulosinline void writeUint32Low8 (deUint8* dst, deUint8 val)
13700d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos{
13800d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN)
139725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 uint32ByteOffsetBits0To8	= 0; //!< least significant byte in the lowest address
14000d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos#else
141725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 uint32ByteOffsetBits0To8	= 3; //!< least significant byte in the highest address
14200d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos#endif
143725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
144725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	dst[uint32ByteOffsetBits0To8] = val;
14500d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos}
14600d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos
147725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulosinline void writeUint32High8 (deUint8* dst, deUint8 val)
14800d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos{
14900d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN)
150725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 uint32ByteOffsetBits24To32	= 3;
15100d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos#else
152725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 uint32ByteOffsetBits24To32	= 0;
15300d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos#endif
154725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
155725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	dst[uint32ByteOffsetBits24To32] = val;
15600d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos}
15700d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos
158725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulosinline deUint32 readUint32High16 (const deUint8* src)
15974a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi{
16074a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN)
161725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 uint32ByteOffset16To32	= 2;
16274a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi#else
163725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 uint32ByteOffset16To32	= 0;
16474a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi#endif
16574a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi
166725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	return *(const deUint16*)(src + uint32ByteOffset16To32);
16774a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi}
16874a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi
169725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulosinline void writeUint32High16 (deUint8* dst, deUint16 val)
17074a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi{
17174a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN)
172725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 uint32ByteOffset16To32	= 2;
17374a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi#else
174725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 uint32ByteOffset16To32	= 0;
17574a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi#endif
17674a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi
177725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	*(deUint16*)(dst + uint32ByteOffset16To32) = val;
178725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos}
179725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
180725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulosinline deUint32 readUint32Low24 (const deUint8* src)
181725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos{
182725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN)
183725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 uint32ByteOffset0To24	= 0;
184725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#else
185725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 uint32ByteOffset0To24	= 1;
186725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#endif
187725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
188725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	return readUint24(src + uint32ByteOffset0To24);
18974a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi}
19074a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi
19174a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärviinline deUint32 readUint32High24 (const deUint8* src)
19274a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi{
19374a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN)
19474a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi	const deUint32 uint32ByteOffset8To32	= 1;
19574a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi#else
19674a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi	const deUint32 uint32ByteOffset8To32	= 0;
19774a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi#endif
19874a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi
19974a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi	return readUint24(src + uint32ByteOffset8To32);
20074a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi}
20174a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi
202725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulosinline void writeUint32Low24 (deUint8* dst, deUint32 val)
203725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos{
204725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN)
205725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 uint32ByteOffset0To24	= 0;
206725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#else
207725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 uint32ByteOffset0To24	= 1;
208725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#endif
209725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
210725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	writeUint24(dst + uint32ByteOffset0To24, val);
211725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos}
212725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
21374a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärviinline void writeUint32High24 (deUint8* dst, deUint32 val)
21474a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi{
21574a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN)
21674a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi	const deUint32 uint32ByteOffset8To32	= 1;
21774a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi#else
21874a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi	const deUint32 uint32ByteOffset8To32	= 0;
21974a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi#endif
22074a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi
22174a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi	writeUint24(dst + uint32ByteOffset8To32, val);
22274a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi}
22374a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \todo [2011-09-21 pyry] Move to tcutil?
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline T convertSatRte (float f)
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note Doesn't work for 64-bit types
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_STATIC_ASSERT(sizeof(T) < sizeof(deUint64));
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_STATIC_ASSERT((-3 % 2 != 0) && (-4 % 2 == 0));
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deInt64	minVal	= std::numeric_limits<T>::min();
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deInt64 maxVal	= std::numeric_limits<T>::max();
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float	q		= deFloatFrac(f);
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deInt64 intVal	= (deInt64)(f-q);
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Rounding.
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (q == 0.5f)
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (intVal % 2 != 0)
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			intVal++;
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (q > 0.5f)
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		intVal++;
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// else Don't add anything
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Saturate.
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	intVal = de::max(minVal, de::min(maxVal, intVal));
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (T)intVal;
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25307104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyryinline deUint32 convertSatRteUint24 (float f)
25407104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry{
25507104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	const deUint32 rounded		= convertSatRte<deUint32>(f);
25607104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	const deUint32 maxUint24	= 0xFFFFFFu;
25707104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	return de::min(rounded, maxUint24);
25807104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry}
25907104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint getChannelSize (TextureFormat::ChannelType type)
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26207104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	// make sure this table is updated if format table is updated
263725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 37);
26407104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (type)
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT8:			return 1;
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT16:		return 2;
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT32:		return 4;
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT8:			return 1;
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT16:		return 2;
27207104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry		case TextureFormat::UNORM_INT24:		return 3;
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT32:		return 4;
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT8:		return 1;
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT16:		return 2;
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT32:		return 4;
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT8:		return 1;
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT16:		return 2;
279db6ba452c1213fd1c2b03369fdf4c1d23f07cfadJarkko Pöyry		case TextureFormat::UNSIGNED_INT24:		return 3;
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT32:		return 4;
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::HALF_FLOAT:			return 2;
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT:				return 4;
283725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::FLOAT64:			return 8;
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0;
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint getNumUsedChannels (TextureFormat::ChannelOrder order)
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29207104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	// make sure this table is updated if type table is updated
293725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	DE_STATIC_ASSERT(TextureFormat::CHANNELORDER_LAST == 21);
29407104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (order)
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::R:			return 1;
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::A:			return 1;
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::I:			return 1;
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::L:			return 1;
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::LA:			return 2;
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::RG:			return 2;
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::RA:			return 2;
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::RGB:		return 3;
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::RGBA:		return 4;
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::ARGB:		return 4;
307725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::BGR:		return 3;
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::BGRA:		return 4;
30916d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		case TextureFormat::sR:			return 1;
31016d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		case TextureFormat::sRG:		return 2;
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::sRGB:		return 3;
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::sRGBA:		return 4;
313725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::sBGR:		return 3;
314725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::sBGRA:		return 4;
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::D:			return 1;
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::S:			return 1;
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::DS:			return 2;
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0;
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline float channelToFloat (const deUint8* value, TextureFormat::ChannelType type)
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32607104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	// make sure this table is updated if format table is updated
327725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 37);
32807104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (type)
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT8:			return de::max(-1.0f, (float)*((const deInt8*)value) / 127.0f);
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT16:		return de::max(-1.0f, (float)*((const deInt16*)value) / 32767.0f);
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT32:		return de::max(-1.0f, (float)*((const deInt32*)value) / 2147483647.0f);
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT8:			return (float)*((const deUint8*)value) / 255.0f;
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT16:		return (float)*((const deUint16*)value) / 65535.0f;
33607104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry		case TextureFormat::UNORM_INT24:		return (float)readUint24(value) / 16777215.0f;
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT32:		return (float)*((const deUint32*)value) / 4294967295.0f;
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT8:		return (float)*((const deInt8*)value);
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT16:		return (float)*((const deInt16*)value);
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT32:		return (float)*((const deInt32*)value);
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT8:		return (float)*((const deUint8*)value);
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT16:		return (float)*((const deUint16*)value);
343db6ba452c1213fd1c2b03369fdf4c1d23f07cfadJarkko Pöyry		case TextureFormat::UNSIGNED_INT24:		return (float)readUint24(value);
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT32:		return (float)*((const deUint32*)value);
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::HALF_FLOAT:			return deFloat16To32(*(const deFloat16*)value);
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT:				return *((const float*)value);
347725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::FLOAT64:			return (float)*((const double*)value);
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int channelToInt (const deUint8* value, TextureFormat::ChannelType type)
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35607104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	// make sure this table is updated if format table is updated
357725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 37);
35807104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (type)
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT8:			return (int)*((const deInt8*)value);
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT16:		return (int)*((const deInt16*)value);
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT32:		return (int)*((const deInt32*)value);
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT8:			return (int)*((const deUint8*)value);
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT16:		return (int)*((const deUint16*)value);
36607104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry		case TextureFormat::UNORM_INT24:		return (int)readUint24(value);
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT32:		return (int)*((const deUint32*)value);
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT8:		return (int)*((const deInt8*)value);
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT16:		return (int)*((const deInt16*)value);
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT32:		return (int)*((const deInt32*)value);
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT8:		return (int)*((const deUint8*)value);
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT16:		return (int)*((const deUint16*)value);
373db6ba452c1213fd1c2b03369fdf4c1d23f07cfadJarkko Pöyry		case TextureFormat::UNSIGNED_INT24:		return (int)readUint24(value);
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT32:		return (int)*((const deUint32*)value);
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::HALF_FLOAT:			return (int)deFloat16To32(*(const deFloat16*)value);
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT:				return (int)*((const float*)value);
377725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::FLOAT64:			return (int)*((const double*)value);
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0;
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid floatToChannel (deUint8* dst, float src, TextureFormat::ChannelType type)
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
38607104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	// make sure this table is updated if format table is updated
387725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 37);
38807104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (type)
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT8:			*((deInt8*)dst)			= convertSatRte<deInt8>		(src * 127.0f);			break;
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT16:		*((deInt16*)dst)		= convertSatRte<deInt16>	(src * 32767.0f);		break;
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT32:		*((deInt32*)dst)		= convertSatRte<deInt32>	(src * 2147483647.0f);	break;
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT8:			*((deUint8*)dst)		= convertSatRte<deUint8>	(src * 255.0f);			break;
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT16:		*((deUint16*)dst)		= convertSatRte<deUint16>	(src * 65535.0f);		break;
396db6ba452c1213fd1c2b03369fdf4c1d23f07cfadJarkko Pöyry		case TextureFormat::UNORM_INT24:		writeUint24(dst,		  convertSatRteUint24		(src * 16777215.0f));	break;
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT32:		*((deUint32*)dst)		= convertSatRte<deUint32>	(src * 4294967295.0f);	break;
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT8:		*((deInt8*)dst)			= convertSatRte<deInt8>		(src);					break;
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT16:		*((deInt16*)dst)		= convertSatRte<deInt16>	(src);					break;
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT32:		*((deInt32*)dst)		= convertSatRte<deInt32>	(src);					break;
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT8:		*((deUint8*)dst)		= convertSatRte<deUint8>	(src);					break;
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT16:		*((deUint16*)dst)		= convertSatRte<deUint16>	(src);					break;
403db6ba452c1213fd1c2b03369fdf4c1d23f07cfadJarkko Pöyry		case TextureFormat::UNSIGNED_INT24:		writeUint24(dst,		  convertSatRteUint24		(src));					break;
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT32:		*((deUint32*)dst)		= convertSatRte<deUint32>	(src);					break;
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::HALF_FLOAT:			*((deFloat16*)dst)		= deFloat32To16				(src);					break;
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT:				*((float*)dst)			= src;												break;
407725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::FLOAT64:			*((double*)dst)			= (double)src;										break;
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, typename S>
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline T convertSat (S src)
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	S min = (S)std::numeric_limits<T>::min();
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	S max = (S)std::numeric_limits<T>::max();
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (src < min)
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return (T)min;
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (src > max)
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return (T)max;
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return (T)src;
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
42707104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyrytemplate <typename S>
42807104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyrystatic inline deUint32 convertSatUint24 (S src)
42907104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry{
43007104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	S min = (S)0u;
43107104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	S max = (S)0xFFFFFFu;
43207104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
43307104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	if (src < min)
43407104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry		return (deUint32)min;
43507104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	else if (src > max)
43607104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry		return (deUint32)max;
43707104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	else
43807104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry		return (deUint32)src;
43907104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry}
44007104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid intToChannel (deUint8* dst, int src, TextureFormat::ChannelType type)
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
44307104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	// make sure this table is updated if format table is updated
444725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 37);
44507104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (type)
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT8:			*((deInt8*)dst)			= convertSat<deInt8>	(src);				break;
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT16:		*((deInt16*)dst)		= convertSat<deInt16>	(src);				break;
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT8:			*((deUint8*)dst)		= convertSat<deUint8>	(src);				break;
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT16:		*((deUint16*)dst)		= convertSat<deUint16>	(src);				break;
452db6ba452c1213fd1c2b03369fdf4c1d23f07cfadJarkko Pöyry		case TextureFormat::UNORM_INT24:		writeUint24(dst,		  convertSatUint24		(src));				break;
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT8:		*((deInt8*)dst)			= convertSat<deInt8>	(src);				break;
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT16:		*((deInt16*)dst)		= convertSat<deInt16>	(src);				break;
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT32:		*((deInt32*)dst)		= convertSat<deInt32>	(src);				break;
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT8:		*((deUint8*)dst)		= convertSat<deUint8>	((deUint32)src);	break;
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT16:		*((deUint16*)dst)		= convertSat<deUint16>	((deUint32)src);	break;
458db6ba452c1213fd1c2b03369fdf4c1d23f07cfadJarkko Pöyry		case TextureFormat::UNSIGNED_INT24:		writeUint24(dst,		  convertSatUint24		((deUint32)src));	break;
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT32:		*((deUint32*)dst)		= convertSat<deUint32>	((deUint32)src);	break;
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::HALF_FLOAT:			*((deFloat16*)dst)		= deFloat32To16((float)src);				break;
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT:				*((float*)dst)			= (float)src;								break;
462725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::FLOAT64:			*((double*)dst)			= (double)src;								break;
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
468725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulosinline float channelToUnormFloat (deUint32 src, int bits)
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
470725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 maxVal = (1u << bits) - 1;
471725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
472725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	// \note Will lose precision if bits > 23
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (float)src / (float)maxVal;
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
476725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos//! Extend < 32b signed integer to 32b
477725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulosinline deInt32 signExtend (deUint32 src, int bits)
478725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos{
479725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 signBit = 1u << (bits-1);
480725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
481725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	src |= ~((src & signBit) - 1);
482725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
483725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	return (deInt32)src;
484725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos}
485725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
486725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulosinline float channelToSnormFloat (deUint32 src, int bits)
487725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos{
488725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32	range	= (1u << (bits-1)) - 1;
489725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
490725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	// \note Will lose precision if bits > 24
491725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	return de::max(-1.0f, (float)signExtend(src, bits) / (float)range);
492725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos}
493725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
494725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulosinline deUint32 unormFloatToChannel (float src, int bits)
495725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos{
496725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32	maxVal	= (1u << bits) - 1;
497725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32	intVal	= convertSatRte<deUint32>(src * (float)maxVal);
498725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
499725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	return de::min(intVal, maxVal);
500725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos}
501725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
502725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulosinline deUint32 snormFloatToChannel (float src, int bits)
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
504725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deInt32	range	= (deInt32)((1u << (bits-1)) - 1u);
505725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32	mask	= (1u << bits) - 1;
506725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deInt32	intVal	= convertSatRte<deInt32>(src * (float)range);
507725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
508725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	return (deUint32)de::clamp(intVal, -range, range) & mask;
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline deUint32 uintToChannel (deUint32 src, int bits)
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
513725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32 maxVal = (1u << bits) - 1;
514725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	return de::min(src, maxVal);
515725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos}
516725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
517725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulosinline deUint32 intToChannel (deInt32 src, int bits)
518725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos{
519725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deInt32	minVal	= -(deInt32)(1u << (bits-1));
520725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deInt32	maxVal	= (deInt32)((1u << (bits-1)) - 1u);
521725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	const deUint32	mask	= (1u << bits) - 1;
522725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
523725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	return (deUint32)de::clamp(src, minVal, maxVal) & mask;
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Vec4 unpackRGB999E5 (deUint32 color)
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	mBits	= 9;
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	eBias	= 15;
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32	exp		= color >> 27;
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32	bs		= (color >> 18) & ((1<<9)-1);
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32	gs		= (color >> 9) & ((1<<9)-1);
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32	rs		= color & ((1<<9)-1);
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		e		= deFloatPow(2.0f, (float)((int)exp - eBias - mBits));
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		r		= (float)rs * e;
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		g		= (float)gs * e;
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		b		= (float)bs * e;
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return tcu::Vec4(r, g, b, 1.0f);
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
54425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulosbool isColorOrder (TextureFormat::ChannelOrder order)
54525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos{
54625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	DE_STATIC_ASSERT(TextureFormat::CHANNELORDER_LAST == 21);
54725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
54825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	switch (order)
54925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	{
55025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::R:
55125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::A:
55225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::I:
55325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::L:
55425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::LA:
55525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::RG:
55625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::RA:
55725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::RGB:
55825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::RGBA:
55925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::ARGB:
56025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::BGR:
56125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::BGRA:
56225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::sR:
56325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::sRG:
56425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::sRGB:
56525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::sRGBA:
56625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::sBGR:
56725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::sBGRA:
56825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return true;
56925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
57025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		default:
57125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return false;
57225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	}
57325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos}
57425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
57725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulosbool isValid (TextureFormat format)
57825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos{
57925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	const bool	isColor	= isColorOrder(format.order);
58025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
58125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	switch (format.type)
58225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	{
58325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::SNORM_INT8:
58425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::SNORM_INT16:
58525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::SNORM_INT32:
58625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return isColor;
58725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
58825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_INT8:
58925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_INT16:
59025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_INT24:
59125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_INT32:
59225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return isColor || format.order == TextureFormat::D;
59325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
59425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_BYTE_44:
59525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_BYTE_44:
59625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return format.order == TextureFormat::RG;
59725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
59825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_SHORT_565:
59925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_SHORT_555:
60025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_565:
60125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return format.order == TextureFormat::RGB || format.order == TextureFormat::BGR;
60225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
60325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_SHORT_4444:
60425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_SHORT_5551:
60525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_4444:
60625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_5551:
60725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return format.order == TextureFormat::RGBA || format.order == TextureFormat::BGRA;
60825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
60925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_INT_101010:
61025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return format.order == TextureFormat::RGB;
61125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
61225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::SNORM_INT_1010102_REV:
61325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_INT_1010102_REV:
61425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::SIGNED_INT_1010102_REV:
61525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT_1010102_REV:
61625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return format.order == TextureFormat::RGBA || format.order == TextureFormat::BGRA;
61725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
61825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
61925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT_999_E5_REV:
62025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return format.order == TextureFormat::RGB;
62125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
62225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT_16_8_8:
62325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return format.order == TextureFormat::DS;
62425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
62525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT_24_8:
62625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT_24_8_REV:
62725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return format.order == TextureFormat::D || format.order == TextureFormat::DS;
62825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
62925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::SIGNED_INT8:
63025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::SIGNED_INT16:
63125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::SIGNED_INT32:
63225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return isColor;
63325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
63425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT8:
63525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT16:
63625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT24:
63725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT32:
63825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return isColor || format.order == TextureFormat::S;
63925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
64025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::HALF_FLOAT:
64125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::FLOAT:
64225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::FLOAT64:
64325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return isColor || format.order == TextureFormat::D;
64425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
64525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
64625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return format.order == TextureFormat::DS;
64725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
64825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		default:
64925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			DE_FATAL("Unknown format");
65025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return 0u;
65125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	}
65225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
65325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 37);
65425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos}
65525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
65625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos/** Get pixel size in bytes. */
65725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulosint getPixelSize (TextureFormat format)
65825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos{
65925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	const TextureFormat::ChannelOrder	order	= format.order;
66025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	const TextureFormat::ChannelType	type	= format.type;
66125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
66225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	DE_ASSERT(isValid(format));
66325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
66425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	// make sure this table is updated if format table is updated
66525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 37);
66625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
66725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	switch (type)
66825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	{
66925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_BYTE_44:
67025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_BYTE_44:
67125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return 1;
67225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
67325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_SHORT_565:
67425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_SHORT_555:
67525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_SHORT_4444:
67625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_SHORT_5551:
67725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_565:
67825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_4444:
67925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_5551:
68025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return 2;
68125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
68225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_INT_101010:
68325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT_999_E5_REV:
68425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
68525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::SNORM_INT_1010102_REV:
68625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNORM_INT_1010102_REV:
68725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::SIGNED_INT_1010102_REV:
68825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT_1010102_REV:
68925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT_24_8:
69025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT_24_8_REV:
69125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::UNSIGNED_INT_16_8_8:
69225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return 4;
69325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
69425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
69525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return 8;
69625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
69725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos		default:
69825977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos			return getNumUsedChannels(order) * getChannelSize(type);
69925977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	}
70025977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos}
70125977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
70225977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulosint TextureFormat::getPixelSize (void) const
70325977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos{
70425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	return ::tcu::getPixelSize(*this);
70525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos}
70625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos
7076d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyryconst TextureSwizzle& getChannelReadSwizzle (TextureFormat::ChannelOrder order)
7086d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry{
7096d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	// make sure to update these tables when channel orders are updated
710725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	DE_STATIC_ASSERT(TextureFormat::CHANNELORDER_LAST == 21);
7116d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
7126d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle INV		= {{ TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ONE	}};
7136d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle R		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ONE	}};
7146d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle A		= {{ TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_0	}};
7156d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle I		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0	}};
7166d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle L		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ONE	}};
7176d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle LA		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1	}};
7186d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RG		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ONE	}};
7196d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RA		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_1	}};
7206d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RGB		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_ONE	}};
7216d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RGBA	= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_3	}};
722725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	static const TextureSwizzle BGR		= {{ TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ONE	}};
7236d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle BGRA	= {{ TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_3	}};
7246d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle ARGB	= {{ TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_3,		TextureSwizzle::CHANNEL_0	}};
7256d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle D		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ONE	}};
72609037a4653649d707449463dfe9817a78ccf7d2fJarkko Pöyry	static const TextureSwizzle S		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ONE	}};
7276d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
7286d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	switch (order)
7296d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	{
7306d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::R:			return R;
7316d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::A:			return A;
7326d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::I:			return I;
7336d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::L:			return L;
7346d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::LA:			return LA;
7356d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RG:			return RG;
7366d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RA:			return RA;
7376d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RGB:		return RGB;
7386d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RGBA:		return RGBA;
7396d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::ARGB:		return ARGB;
740725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::BGR:		return BGR;
7416d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::BGRA:		return BGRA;
74216d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		case TextureFormat::sR:			return R;
74316d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		case TextureFormat::sRG:		return RG;
7446d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::sRGB:		return RGB;
7456d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::sRGBA:		return RGBA;
746725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::sBGR:		return BGR;
747725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::sBGRA:		return BGRA;
7486d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::D:			return D;
7496d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::S:			return S;
7508baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry
7518baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry		case TextureFormat::DS:
7528baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			DE_ASSERT(false); // combined formats cannot be read from
7538baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			return INV;
7548baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry
7556d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		default:
7566d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			DE_ASSERT(DE_FALSE);
7576d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			return INV;
7586d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	}
7596d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry}
7606d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
7616d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyryconst TextureSwizzle& getChannelWriteSwizzle (TextureFormat::ChannelOrder order)
7626d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry{
7636d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	// make sure to update these tables when channel orders are updated
764725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	DE_STATIC_ASSERT(TextureFormat::CHANNELORDER_LAST == 21);
7656d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
7666d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle INV		= {{ TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
7676d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle R		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
7686d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle A		= {{ TextureSwizzle::CHANNEL_3,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
7696d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle I		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
7706d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle L		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
7716d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle LA		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_3,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
7726d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RG		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
7736d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RA		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_3,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
7746d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RGB		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_LAST	}};
7756d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RGBA	= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_3		}};
776725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	static const TextureSwizzle BGR		= {{ TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_LAST	}};
7776d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle BGRA	= {{ TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_3		}};
7786d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle ARGB	= {{ TextureSwizzle::CHANNEL_3,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_2		}};
7796d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle D		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
78009037a4653649d707449463dfe9817a78ccf7d2fJarkko Pöyry	static const TextureSwizzle S		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
7816d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
7826d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	switch (order)
7836d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	{
7846d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::R:			return R;
7856d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::A:			return A;
7866d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::I:			return I;
7876d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::L:			return L;
7886d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::LA:			return LA;
7896d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RG:			return RG;
7906d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RA:			return RA;
7916d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RGB:		return RGB;
7926d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RGBA:		return RGBA;
7936d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::ARGB:		return ARGB;
794725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::BGR:		return BGR;
7956d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::BGRA:		return BGRA;
79616d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		case TextureFormat::sR:			return R;
79716d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		case TextureFormat::sRG:		return RG;
7986d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::sRGB:		return RGB;
7996d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::sRGBA:		return RGBA;
800725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::sBGR:		return BGR;
801725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::sBGRA:		return BGRA;
8026d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::D:			return D;
8036d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::S:			return S;
8048baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry
8058baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry		case TextureFormat::DS:
8068baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			DE_ASSERT(false); // combined formats cannot be written to
8078baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			return INV;
8088baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry
8096d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		default:
8106d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			DE_ASSERT(DE_FALSE);
8116d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			return INV;
8126d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	}
8136d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry}
8146d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
81529340067e919854db7d50bb8c0b666117b229f5eMika IsojärviIVec3 calculatePackedPitch (const TextureFormat& format, const IVec3& size)
81629340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi{
81729340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	const int pixelSize		= format.getPixelSize();
81829340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	const int rowPitch		= pixelSize * size.x();
81929340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	const int slicePitch	= rowPitch * size.y();
82029340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
82129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	return IVec3(pixelSize, rowPitch, slicePitch);
82229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi}
82329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
8243c827367444ee418f129b2c238299f49d3264554Jarkko PoyryConstPixelBufferAccess::ConstPixelBufferAccess (void)
82529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	: m_size		(0)
82629340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_pitch		(0)
8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_data		(DE_NULL)
8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8313c827367444ee418f129b2c238299f49d3264554Jarkko PoyryConstPixelBufferAccess::ConstPixelBufferAccess (const TextureFormat& format, int width, int height, int depth, const void* data)
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format		(format)
83329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size		(width, height, depth)
83429340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_pitch		(calculatePackedPitch(m_format, m_size))
83529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_data		((void*)data)
83629340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi{
83725977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	DE_ASSERT(isValid(format));
83829340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi}
83929340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
84029340067e919854db7d50bb8c0b666117b229f5eMika IsojärviConstPixelBufferAccess::ConstPixelBufferAccess (const TextureFormat& format, const IVec3& size, const void* data)
84129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	: m_format		(format)
84229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size		(size)
84329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_pitch		(calculatePackedPitch(m_format, m_size))
8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_data		((void*)data)
8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
84625977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	DE_ASSERT(isValid(format));
8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8493c827367444ee418f129b2c238299f49d3264554Jarkko PoyryConstPixelBufferAccess::ConstPixelBufferAccess (const TextureFormat& format, int width, int height, int depth, int rowPitch, int slicePitch, const void* data)
8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format		(format)
85129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size		(width, height, depth)
85229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_pitch		(format.getPixelSize(), rowPitch, slicePitch)
85329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_data		((void*)data)
85429340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi{
85525977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	DE_ASSERT(isValid(format));
85629340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi}
85729340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
85829340067e919854db7d50bb8c0b666117b229f5eMika IsojärviConstPixelBufferAccess::ConstPixelBufferAccess (const TextureFormat& format, const IVec3& size, const IVec3& pitch, const void* data)
85929340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	: m_format		(format)
86029340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size		(size)
86129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_pitch		(pitch)
8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_data		((void*)data)
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
86425977694b814e285649d6a60c148cb3b5a04ef30Pyry Haulos	DE_ASSERT(isValid(format));
86529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(m_format.getPixelSize() <= m_pitch.x());
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8683c827367444ee418f129b2c238299f49d3264554Jarkko PoyryConstPixelBufferAccess::ConstPixelBufferAccess (const TextureLevel& level)
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format		(level.getFormat())
87029340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size		(level.getSize())
87129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_pitch		(calculatePackedPitch(m_format, m_size))
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_data		((void*)level.getPtr())
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8763c827367444ee418f129b2c238299f49d3264554Jarkko PoyryPixelBufferAccess::PixelBufferAccess (const TextureFormat& format, int width, int height, int depth, void* data)
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: ConstPixelBufferAccess(format, width, height, depth, data)
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
88129340067e919854db7d50bb8c0b666117b229f5eMika IsojärviPixelBufferAccess::PixelBufferAccess (const TextureFormat& format, const IVec3& size, void* data)
88229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	: ConstPixelBufferAccess(format, size, data)
88329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi{
88429340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi}
88529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
8863c827367444ee418f129b2c238299f49d3264554Jarkko PoyryPixelBufferAccess::PixelBufferAccess (const TextureFormat& format, int width, int height, int depth, int rowPitch, int slicePitch, void* data)
8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: ConstPixelBufferAccess(format, width, height, depth, rowPitch, slicePitch, data)
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
89129340067e919854db7d50bb8c0b666117b229f5eMika IsojärviPixelBufferAccess::PixelBufferAccess (const TextureFormat& format, const IVec3& size, const IVec3& pitch, void* data)
89229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	: ConstPixelBufferAccess(format, size, pitch, data)
89329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi{
89429340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi}
89529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
8963c827367444ee418f129b2c238299f49d3264554Jarkko PoyryPixelBufferAccess::PixelBufferAccess (TextureLevel& level)
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: ConstPixelBufferAccess(level)
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
901725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos//! Swizzle RGB(A) <-> BGR(A)
902725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulostemplate<typename T>
903725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry HaulosVector<T, 4> swizzleRB (const Vector<T, 4>& v, TextureFormat::ChannelOrder src, TextureFormat::ChannelOrder dst)
904725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos{
905725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	if (src == dst)
906725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		return v;
907725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	else
908725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	{
909725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		DE_ASSERT((src == TextureFormat::RGB && dst == TextureFormat::BGR) ||
910725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos				  (src == TextureFormat::BGR && dst == TextureFormat::RGB) ||
911725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos				  (src == TextureFormat::RGBA && dst == TextureFormat::BGRA) ||
912725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos				  (src == TextureFormat::BGRA && dst == TextureFormat::RGBA));
913725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		return v.swizzle(2,1,0,3);
914725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos	}
915725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos}
916725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
9173c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 ConstPixelBufferAccess::getPixel (int x, int y, int z) const
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
91929340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(x, 0, m_size.x()));
92029340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(y, 0, m_size.y()));
92129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(z, 0, m_size.z()));
9228baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	DE_ASSERT(!isCombinedDepthStencilType(m_format.type)); // combined types cannot be accessed directly
9238baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	DE_ASSERT(m_format.order != TextureFormat::DS); // combined formats cannot be accessed directly
92429340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
9258baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	const deUint8* pixelPtr = (const deUint8*)getPixelPtr(x, y, z);
9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Optimized fomats.
9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_format.type == TextureFormat::UNORM_INT8)
9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9300158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		if (m_format.order == TextureFormat::RGBA || m_format.order == TextureFormat::sRGBA)
93129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi			return readRGBA8888Float(pixelPtr);
9320158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		else if (m_format.order == TextureFormat::RGB || m_format.order == TextureFormat::sRGB)
93329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi			return readRGB888Float(pixelPtr);
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
936725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define UI8(OFFS, COUNT)		((*((const deUint8*)pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1))
937725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define UI16(OFFS, COUNT)		((*((const deUint16*)pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1))
938725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define UI32(OFFS, COUNT)		((*((const deUint32*)pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1))
939725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define SI32(OFFS, COUNT)		signExtend(UI32(OFFS, COUNT), (COUNT))
940725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define UN8(OFFS, COUNT)		channelToUnormFloat(UI8 (OFFS, COUNT), (COUNT))
941725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define UN16(OFFS, COUNT)		channelToUnormFloat(UI16(OFFS, COUNT), (COUNT))
942725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define UN32(OFFS, COUNT)		channelToUnormFloat(UI32(OFFS, COUNT), (COUNT))
943725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define SN32(OFFS, COUNT)		channelToSnormFloat(UI32(OFFS, COUNT), (COUNT))
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Packed formats.
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
948725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_BYTE_44:				return			  Vec4(UN8 (4,   4), UN8 ( 0,  4), 0.0f, 1.0f);
949725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_BYTE_44:			return			 UVec4(UI8 (4,   4), UI8 ( 0,  4), 0u, 1u).cast<float>();
950725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_565:			return swizzleRB( Vec4(UN16(11,  5), UN16( 5,  6), UN16( 0,  5), 1.0f), TextureFormat::RGB, m_format.order);
951725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_565:			return swizzleRB(UVec4(UI16(11,  5), UI16( 5,  6), UI16( 0,  5), 1u), TextureFormat::RGB, m_format.order).cast<float>();
952725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_555:			return swizzleRB( Vec4(UN16(10,  5), UN16( 5,  5), UN16( 0,  5), 1.0f), TextureFormat::RGB, m_format.order);
953725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_4444:			return swizzleRB( Vec4(UN16(12,  4), UN16( 8,  4), UN16( 4,  4), UN16( 0, 4)), TextureFormat::RGBA, m_format.order);
954725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_4444:		return swizzleRB(UVec4(UI16(12,  4), UI16( 8,  4), UI16( 4,  4), UI16( 0, 4)), TextureFormat::RGBA, m_format.order).cast<float>();
955725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_5551:			return swizzleRB( Vec4(UN16(11,  5), UN16( 6,  5), UN16( 1,  5), UN16( 0, 1)), TextureFormat::RGBA, m_format.order);
956725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_5551:		return swizzleRB(UVec4(UI16(11,  5), UI16( 6,  5), UI16( 1,  5), UI16( 0, 1)), TextureFormat::RGBA, m_format.order).cast<float>();
957725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_INT_101010:			return			  Vec4(UN32(22, 10), UN32(12, 10), UN32( 2, 10), 1.0f);
958725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_INT_1010102_REV:		return swizzleRB( Vec4(UN32( 0, 10), UN32(10, 10), UN32(20, 10), UN32(30, 2)), TextureFormat::RGBA, m_format.order);
959725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::SNORM_INT_1010102_REV:		return swizzleRB( Vec4(SN32( 0, 10), SN32(10, 10), SN32(20, 10), SN32(30, 2)), TextureFormat::RGBA, m_format.order);
960725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_1010102_REV:	return swizzleRB( UVec4(UI32(0, 10), UI32(10, 10), UI32(20, 10), UI32(30, 2)), TextureFormat::RGBA, m_format.order).cast<float>();
961725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::SIGNED_INT_1010102_REV:		return swizzleRB( UVec4(SI32(0, 10), SI32(10, 10), SI32(20, 10), SI32(30, 2)), TextureFormat::RGBA, m_format.order).cast<float>();
9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_999_E5_REV:	return unpackRGB999E5(*((const deUint32*)pixelPtr));
9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
965725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			return Vec4(Float11(UI32(0, 11)).asFloat(), Float11(UI32(11, 11)).asFloat(), Float10(UI32(22, 10)).asFloat(), 1.0f);
9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
971725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef UN8
972725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef UN16
973725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef UN32
974725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef SN32
975725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef SI32
976725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef UI8
977725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef UI16
978725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef UI32
9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generic path.
9816d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	Vec4							result;
9826d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	const TextureSwizzle::Channel*	channelMap	= getChannelReadSwizzle(m_format.order).components;
9836d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	int								channelSize	= getChannelSize(m_format.type);
9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int c = 0; c < 4; c++)
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9876d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		switch (channelMap[c])
9886d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		{
9896d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_0:
9906d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_1:
9916d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_2:
9926d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_3:
9936d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				result[c] = channelToFloat(pixelPtr + channelSize*((int)channelMap[c]), m_format.type);
9946d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				break;
9956d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
9966d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_ZERO:
9976d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				result[c] = 0.0f;
9986d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				break;
9996d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
10006d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_ONE:
10016d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				result[c] = 1.0f;
10026d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				break;
10036d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
10046d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			default:
10056d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				DE_ASSERT(false);
10066d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		}
10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10123c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIVec4 ConstPixelBufferAccess::getPixelInt (int x, int y, int z) const
10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
101429340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(x, 0, m_size.x()));
101529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(y, 0, m_size.y()));
101629340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(z, 0, m_size.z()));
10178baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	DE_ASSERT(!isCombinedDepthStencilType(m_format.type)); // combined types cannot be accessed directly
10188baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	DE_ASSERT(m_format.order != TextureFormat::DS); // combined formats cannot be accessed directly
10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10208baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	const deUint8* const	pixelPtr = (const deUint8*)getPixelPtr(x, y, z);
102107104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	IVec4					result;
10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Optimized fomats.
10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_format.type == TextureFormat::UNORM_INT8)
10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10260158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		if (m_format.order == TextureFormat::RGBA || m_format.order == TextureFormat::sRGBA)
10270158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi			return readRGBA8888Int(pixelPtr);
10280158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		else if (m_format.order == TextureFormat::RGB || m_format.order == TextureFormat::sRGB)
10290158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi			return readRGB888Int(pixelPtr);
10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1032725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define U8(OFFS, COUNT)			((*((const deUint8* )pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1))
10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define U16(OFFS, COUNT)		((*((const deUint16*)pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1))
10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define U32(OFFS, COUNT)		((*((const deUint32*)pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1))
1035725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define S32(OFFS, COUNT)		signExtend(U32(OFFS, COUNT), (COUNT))
10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1039725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_BYTE_44:			// Fall-through
1040725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_BYTE_44:				return			 UVec4(U8 ( 4,  4), U8 ( 0,  4), 0u, 1u).cast<int>();
1041725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_565:			// Fall-through
1042725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_565:			return swizzleRB(UVec4(U16(11,  5), U16( 5,  6), U16( 0,  5), 1).cast<int>(), TextureFormat::RGB, m_format.order);
1043725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_555:			return swizzleRB(UVec4(U16(10,  5), U16( 5,  5), U16( 0,  5), 1).cast<int>(), TextureFormat::RGB, m_format.order);
1044725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_4444:		// Fall-through
1045725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_4444:			return swizzleRB(UVec4(U16(12,  4), U16( 8,  4), U16( 4,  4), U16( 0, 4)).cast<int>(), TextureFormat::RGBA, m_format.order);
1046725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_5551:		// Fall-through
1047725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_5551:			return swizzleRB(UVec4(U16(11,  5), U16( 6,  5), U16( 1,  5), U16( 0, 1)).cast<int>(), TextureFormat::RGBA, m_format.order);
1048725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_INT_101010:			return			 UVec4(U32(22, 10), U32(12, 10), U32( 2, 10), 1).cast<int>();
1049725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_INT_1010102_REV:		// Fall-through
1050725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_1010102_REV:	return swizzleRB(UVec4(U32( 0, 10), U32(10, 10), U32(20, 10), U32(30, 2)), TextureFormat::RGBA, m_format.order).cast<int>();
1051725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::SNORM_INT_1010102_REV:		// Fall-through
1052725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::SIGNED_INT_1010102_REV:		return swizzleRB(IVec4(S32( 0, 10), S32(10, 10), S32(20, 10), S32(30, 2)), TextureFormat::RGBA, m_format.order);
10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break; // To generic path.
10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1058725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef U8
10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef U16
10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef U32
1061725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef S32
10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generic path.
10646d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	const TextureSwizzle::Channel*	channelMap	= getChannelReadSwizzle(m_format.order).components;
10656d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	int								channelSize	= getChannelSize(m_format.type);
10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int c = 0; c < 4; c++)
10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10696d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		switch (channelMap[c])
10706d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		{
10716d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_0:
10726d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_1:
10736d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_2:
10746d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_3:
10756d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				result[c] = channelToInt(pixelPtr + channelSize*((int)channelMap[c]), m_format.type);
10766d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				break;
10776d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
10786d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_ZERO:
10796d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				result[c] = 0;
10806d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				break;
10816d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
10826d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_ONE:
10836d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				result[c] = 1;
10846d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				break;
10856d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
10866d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			default:
10876d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				DE_ASSERT(false);
10886d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		}
10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<>
10953c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 ConstPixelBufferAccess::getPixelT (int x, int y, int z) const
10963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return getPixel(x, y, z);
10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<>
11013c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIVec4 ConstPixelBufferAccess::getPixelT (int x, int y, int z) const
11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return getPixelInt(x, y, z);
11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<>
11073c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUVec4 ConstPixelBufferAccess::getPixelT (int x, int y, int z) const
11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return getPixelUint(x, y, z);
11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat ConstPixelBufferAccess::getPixDepth (int x, int y, int z) const
11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(x, 0, getWidth()));
11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(y, 0, getHeight()));
11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(z, 0, getDepth()));
11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11188baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	const deUint8* const pixelPtr = (const deUint8*)getPixelPtr(x, y, z);
11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1122725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_16_8_8:
112300d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::DS);
1124725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			return (float)readUint32High16(pixelPtr) / 65535.0f;
112574a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi
112600d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos		case TextureFormat::UNSIGNED_INT_24_8:
1127725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::D || m_format.order == TextureFormat::DS);
112800d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			return (float)readUint32High24(pixelPtr) / 16777215.0f;
11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1130725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_24_8_REV:
1131725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::D || m_format.order == TextureFormat::DS);
1132725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			return (float)readUint32Low24(pixelPtr) / 16777215.0f;
1133725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_format.order == TextureFormat::DS);
11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return *((const float*)pixelPtr);
11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
11398baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			DE_ASSERT(m_format.order == TextureFormat::D); // no other combined depth stencil types
11403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return channelToFloat(pixelPtr, m_format.type);
11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11443c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint ConstPixelBufferAccess::getPixStencil (int x, int y, int z) const
11453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(x, 0, getWidth()));
11473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(y, 0, getHeight()));
11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(z, 0, getDepth()));
11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11508baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	const deUint8* const pixelPtr = (const deUint8*)getPixelPtr(x, y, z);
11513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1154725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_24_8_REV:
115500d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::DS);
1156725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			return (int)readUint32High8(pixelPtr);
115700d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos
1158725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_16_8_8:
11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_24_8:
116000d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::DS);
116100d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			return (int)readUint32Low8(pixelPtr);
11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_format.order == TextureFormat::DS);
116574a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi			return (int)readUint32Low8(pixelPtr + 4);
11663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
11683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11698baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			DE_ASSERT(m_format.order == TextureFormat::S); // no other combined depth stencil types
11708baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			return channelToInt(pixelPtr, m_format.type);
11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PixelBufferAccess::setPixel (const Vec4& color, int x, int y, int z) const
11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(x, 0, getWidth()));
11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(y, 0, getHeight()));
11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(z, 0, getDepth()));
11808baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	DE_ASSERT(!isCombinedDepthStencilType(m_format.type)); // combined types cannot be accessed directly
11818baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	DE_ASSERT(m_format.order != TextureFormat::DS); // combined formats cannot be accessed directly
11823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11838baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	deUint8* const pixelPtr = (deUint8*)getPixelPtr(x, y, z);
118429340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Optimized fomats.
11863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_format.type == TextureFormat::UNORM_INT8)
11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11880158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		if (m_format.order == TextureFormat::RGBA || m_format.order == TextureFormat::sRGBA)
11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
119029340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi			writeRGBA8888Float(pixelPtr, color);
11913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return;
11923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11930158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		else if (m_format.order == TextureFormat::RGB || m_format.order == TextureFormat::sRGB)
11943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
119529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi			writeRGB888Float(pixelPtr, color);
11963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return;
11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1200725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define PN(VAL, OFFS, BITS)		(unormFloatToChannel((VAL), (BITS)) << (OFFS))
1201725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define PS(VAL, OFFS, BITS)		(snormFloatToChannel((VAL), (BITS)) << (OFFS))
12023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define PU(VAL, OFFS, BITS)		(uintToChannel((VAL), (BITS)) << (OFFS))
1203725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define PI(VAL, OFFS, BITS)		(intToChannel((VAL), (BITS)) << (OFFS))
12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1207725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_BYTE_44:		*((deUint8 *)pixelPtr) = (deUint8)(PN(color[0], 4, 4) | PN(color[1], 0, 4));						break;
1208725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_BYTE_44:	*((deUint8 *)pixelPtr) = (deUint8)(PU((deUint32)color[0], 4, 4) | PU((deUint32)color[1], 0, 4));	break;
1209725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_INT_101010:	*((deUint32*)pixelPtr) = PN(color[0], 22, 10) | PN(color[1], 12, 10) | PN(color[2], 2, 10);			break;
1210725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1211725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_565:
1212725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
1213725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			const Vec4 swizzled = swizzleRB(color, m_format.order, TextureFormat::RGB);
1214725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PN(swizzled[0], 11, 5) | PN(swizzled[1], 5, 6) | PN(swizzled[2], 0, 5));
1215725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1216725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1217725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1218725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_565:
1219725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
1220725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			const UVec4 swizzled = swizzleRB(color.cast<deUint32>(), m_format.order, TextureFormat::RGB);
1221725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PU(swizzled[0], 11, 5) | PU(swizzled[1], 5, 6) | PU(swizzled[2], 0, 5));
1222725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1223725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1224725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1225725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_555:
1226725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
1227725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			const Vec4 swizzled = swizzleRB(color, m_format.order, TextureFormat::RGB);
1228725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PN(swizzled[0], 10, 5) | PN(swizzled[1], 5, 5) | PN(swizzled[2], 0, 5));
1229725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1230725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1231725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1232725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_4444:
1233725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
1234725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			const Vec4 swizzled = swizzleRB(color, m_format.order, TextureFormat::RGBA);
1235725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PN(swizzled[0], 12, 4) | PN(swizzled[1], 8, 4) | PN(swizzled[2], 4, 4) | PN(swizzled[3], 0, 4));
1236725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1237725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1238725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1239725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_4444:
1240725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
1241725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			const UVec4 swizzled = swizzleRB(color.cast<deUint32>(), m_format.order, TextureFormat::RGBA);
1242725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PU(swizzled[0], 12, 4) | PU(swizzled[1], 8, 4) | PU(swizzled[2], 4, 4) | PU(swizzled[3], 0, 4));
1243725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1244725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1245725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1246725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_5551:
1247725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
1248725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			const Vec4 swizzled = swizzleRB(color, m_format.order, TextureFormat::RGBA);
1249725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PN(swizzled[0], 11, 5) | PN(swizzled[1], 6, 5) | PN(swizzled[2], 1, 5) | PN(swizzled[3], 0, 1));
1250725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1251725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1252725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1253725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_5551:
1254725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
1255725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			const UVec4 swizzled = swizzleRB(color.cast<deUint32>(), m_format.order, TextureFormat::RGBA);
1256725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PU(swizzled[0], 11, 5) | PU(swizzled[1], 6, 5) | PU(swizzled[2], 1, 5) | PU(swizzled[3], 0, 1));
1257725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1258725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1259725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1260725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_INT_1010102_REV:
1261725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
1262725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			const Vec4 u = swizzleRB(color, m_format.order, TextureFormat::RGBA);
1263725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint32*)pixelPtr) = PN(u[0], 0, 10) | PN(u[1], 10, 10) | PN(u[2], 20, 10) | PN(u[3], 30, 2);
1264725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1265725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1266725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1267725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::SNORM_INT_1010102_REV:
1268725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
1269725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			const Vec4 u = swizzleRB(color, m_format.order, TextureFormat::RGBA);
1270725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint32*)pixelPtr) = PS(u[0], 0, 10) | PS(u[1], 10, 10) | PS(u[2], 20, 10) | PS(u[3], 30, 2);
1271725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1272725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
12733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_1010102_REV:
12753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1276725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			const UVec4 u = swizzleRB(color.cast<deUint32>(), m_format.order, TextureFormat::RGBA);
1277725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint32*)pixelPtr) = PU(u[0], 0, 10) | PU(u[1], 10, 10) | PU(u[2], 20, 10) | PU(u[3], 30, 2);
1278725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1279725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1280725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1281725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::SIGNED_INT_1010102_REV:
1282725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
1283725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			const IVec4 u = swizzleRB(color.cast<deInt32>(), m_format.order, TextureFormat::RGBA);
1284725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint32*)pixelPtr) = PI(u[0], 0, 10) | PI(u[1], 10, 10) | PI(u[2], 20, 10) | PI(u[3], 30, 2);
12853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
12863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
12893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			*((deUint32*)pixelPtr) = Float11(color[0]).bits() | (Float11(color[1]).bits() << 11) | (Float10(color[2]).bits() << 22);
12903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
12913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_999_E5_REV:
12933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			*((deUint32*)pixelPtr) = packRGB999E5(color);
12943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
12953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
12973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Generic path.
12996d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			int								numChannels	= getNumUsedChannels(m_format.order);
13006d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			const TextureSwizzle::Channel*	map			= getChannelWriteSwizzle(m_format.order).components;
13016d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			int								channelSize	= getChannelSize(m_format.type);
13023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int c = 0; c < numChannels; c++)
13046d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			{
13056d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				DE_ASSERT(deInRange32(map[c], TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3));
13063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				floatToChannel(pixelPtr + channelSize*c, color[map[c]], m_format.type);
13076d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			}
13083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
13093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef PN
1313725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef PS
13143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef PU
1315725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef PI
13163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13183c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PixelBufferAccess::setPixel (const IVec4& color, int x, int y, int z) const
13193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(x, 0, getWidth()));
13213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(y, 0, getHeight()));
13223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(z, 0, getDepth()));
13238baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	DE_ASSERT(!isCombinedDepthStencilType(m_format.type)); // combined types cannot be accessed directly
13248baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	DE_ASSERT(m_format.order != TextureFormat::DS); // combined formats cannot be accessed directly
13253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13268baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	deUint8* const pixelPtr = (deUint8*)getPixelPtr(x, y, z);
13273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Optimized fomats.
13293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_format.type == TextureFormat::UNORM_INT8)
13303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13310158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		if (m_format.order == TextureFormat::RGBA || m_format.order == TextureFormat::sRGBA)
13320158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		{
13330158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi			writeRGBA8888Int(pixelPtr, color);
13340158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi			return;
13350158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		}
13360158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		else if (m_format.order == TextureFormat::RGB || m_format.order == TextureFormat::sRGB)
13370158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		{
13380158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi			writeRGB888Int(pixelPtr, color);
13390158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi			return;
13400158a3f0836be6001b70396c93223f5355d6e657Mika Isojärvi		}
13413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define PU(VAL, OFFS, BITS)		(uintToChannel((deUint32)(VAL), (BITS)) << (OFFS))
1344725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#define PI(VAL, OFFS, BITS)		(intToChannel((deUint32)(VAL), (BITS)) << (OFFS))
13453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
13473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1348725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_BYTE_44:	// Fall-through
1349725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_BYTE_44:		*((deUint8 *)pixelPtr) = (deUint8 )(PU(color[0],  4, 4) | PU(color[1], 0, 4));				break;
1350725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_INT_101010:	*((deUint32*)pixelPtr) = PU(color[0], 22, 10) | PU(color[1], 12, 10) | PU(color[2], 2, 10);	break;
1351725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1352725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_565:
1353725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_565:
1354725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
1355725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			const IVec4 swizzled = swizzleRB(color, m_format.order, TextureFormat::RGB);
1356725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PU(swizzled[0], 11, 5) | PU(swizzled[1], 5, 6) | PU(swizzled[2], 0, 5));
1357725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1358725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1359725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1360725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_555:
1361725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
1362725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			const IVec4 swizzled = swizzleRB(color, m_format.order, TextureFormat::RGB);
1363725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PU(swizzled[0], 10, 5) | PU(swizzled[1], 5, 5) | PU(swizzled[2], 0, 5));
1364725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1365725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1366725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1367725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_4444:
1368725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_4444:
1369725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
1370725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			const IVec4 swizzled = swizzleRB(color, m_format.order, TextureFormat::RGBA);
1371725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PU(swizzled[0], 12, 4) | PU(swizzled[1], 8, 4) | PU(swizzled[2], 4, 4) | PU(swizzled[3], 0, 4));
1372725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1373725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1374725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1375725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_SHORT_5551:
1376725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_SHORT_5551:
1377725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
1378725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			const IVec4 swizzled = swizzleRB(color, m_format.order, TextureFormat::RGBA);
1379725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint16*)pixelPtr) = (deUint16)(PU(swizzled[0], 11, 5) | PU(swizzled[1], 6, 5) | PU(swizzled[2], 1, 5) | PU(swizzled[3], 0, 1));
1380725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1381725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1382725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1383725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNORM_INT_1010102_REV:
1384725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_1010102_REV:
1385725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
1386725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			const IVec4 swizzled = swizzleRB(color, m_format.order, TextureFormat::RGBA);
1387725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint32*)pixelPtr) = PU(swizzled[0],  0, 10) | PU(swizzled[1], 10, 10) | PU(swizzled[2], 20, 10) | PU(swizzled[3], 30, 2);
1388725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1389725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
1390725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
1391725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::SNORM_INT_1010102_REV:
1392725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::SIGNED_INT_1010102_REV:
1393725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		{
1394725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			const IVec4 swizzled = swizzleRB(color, m_format.order, TextureFormat::RGBA);
1395725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			*((deUint32*)pixelPtr) = PI(swizzled[0],  0, 10) | PI(swizzled[1], 10, 10) | PI(swizzled[2], 20, 10) | PI(swizzled[3], 30, 2);
1396725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1397725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		}
13983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
14003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Generic path.
14026d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			int								numChannels	= getNumUsedChannels(m_format.order);
14036d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			const TextureSwizzle::Channel*	map			= getChannelWriteSwizzle(m_format.order).components;
14046d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			int								channelSize	= getChannelSize(m_format.type);
14053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int c = 0; c < numChannels; c++)
14076d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			{
14086d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				DE_ASSERT(deInRange32(map[c], TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3));
14093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				intToChannel(pixelPtr + channelSize*c, color[map[c]], m_format.type);
14106d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			}
14113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
14123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef PU
1416725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos#undef PI
14173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14193c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PixelBufferAccess::setPixDepth (float depth, int x, int y, int z) const
14203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(x, 0, getWidth()));
14223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(y, 0, getHeight()));
14233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(z, 0, getDepth()));
14243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14258baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	deUint8* const pixelPtr = (deUint8*)getPixelPtr(x, y, z);
14263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
14283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1429725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_16_8_8:
143000d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::DS);
1431725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			writeUint32High16(pixelPtr, convertSatRte<deUint16>(depth * 65535.0f));
143200d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			break;
143374a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi
143400d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos		case TextureFormat::UNSIGNED_INT_24_8:
1435725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::D || m_format.order == TextureFormat::DS);
143600d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			writeUint32High24(pixelPtr,  convertSatRteUint24(depth * 16777215.0f));
14373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
14383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1439725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_24_8_REV:
1440725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::D || m_format.order == TextureFormat::DS);
1441725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			writeUint32Low24(pixelPtr,  convertSatRteUint24(depth * 16777215.0f));
1442725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			break;
1443725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos
14443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
14453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_format.order == TextureFormat::DS);
14463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			*((float*)pixelPtr) = depth;
14473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
14483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
14508baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			DE_ASSERT(m_format.order == TextureFormat::D); // no other combined depth stencil types
14513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			floatToChannel(pixelPtr, depth, m_format.type);
14523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
14533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PixelBufferAccess::setPixStencil (int stencil, int x, int y, int z) const
14573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(x, 0, getWidth()));
14593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(y, 0, getHeight()));
14603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(z, 0, getDepth()));
14613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14628baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	deUint8* const pixelPtr = (deUint8*)getPixelPtr(x, y, z);
14633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
14653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1466725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_16_8_8:
14673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_24_8:
146800d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::DS);
146900d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			writeUint32Low8(pixelPtr, convertSat<deUint8>((deUint32)stencil));
147000d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			break;
147174a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi
1472725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		case TextureFormat::UNSIGNED_INT_24_8_REV:
147300d2d01b88792c1cbdabac206ec38d9b63c6f401Pyry Haulos			DE_ASSERT(m_format.order == TextureFormat::DS);
1474725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos			writeUint32High8(pixelPtr, convertSat<deUint8>((deUint32)stencil));
14753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
14763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
14783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_format.order == TextureFormat::DS);
147974a1a14a329e7b40806248400aeb1393d91636a7Mika Isojärvi			writeUint32Low8(pixelPtr + 4, convertSat<deUint8>((deUint32)stencil));
14803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
14813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
14838baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			DE_ASSERT(m_format.order == TextureFormat::S);  // no other combined depth stencil types
14848baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry			intToChannel(pixelPtr, stencil, m_format.type);
14853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
14863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14893c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline int imod (int a, int b)
14903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int m = a % b;
14923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m < 0 ? m + b : m;
14933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14953c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline int mirror (int a)
14963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return a >= 0.0f ? a : -(1 + a);
14983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Nearest-even rounding in case of tie (fractional part 0.5), otherwise ordinary rounding.
15013c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline float rint (float a)
15023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_STATIC_ASSERT((-3 % 2 != 0) && (-4 % 2 == 0));
15043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		fracVal		= deFloatFrac(a);
15063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (fracVal != 0.5f)
15083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return deFloatRound(a); // Ordinary case.
15093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float	floorVal	= a - fracVal;
15113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool	roundUp		= (deInt64)floorVal % 2 != 0;
15123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return floorVal + (roundUp ? 1.0f : 0.0f);
15143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15163c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline int wrap (Sampler::WrapMode mode, int c, int size)
15173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (mode)
15193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::CLAMP_TO_BORDER:
15213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return deClamp32(c, -1, size);
15223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::CLAMP_TO_EDGE:
15243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return deClamp32(c, 0, size-1);
15253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::REPEAT_GL:
15273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return imod(c, size);
15283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::REPEAT_CL:
15303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return imod(c, size);
15313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::MIRRORED_REPEAT_GL:
15333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return (size - 1) - mirror(imod(c, 2*size) - size);
15343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::MIRRORED_REPEAT_CL:
15363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return deClamp32(c, 0, size-1); // \note Actual mirroring done already in unnormalization function.
15373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
15393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
15403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0;
15413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Special unnormalization for REPEAT_CL and MIRRORED_REPEAT_CL wrap modes; otherwise ordinary unnormalization.
15453c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline float unnormalize (Sampler::WrapMode mode, float c, int size)
15463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (mode)
15483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::CLAMP_TO_EDGE:
15503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::CLAMP_TO_BORDER:
15513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::REPEAT_GL:
15523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::MIRRORED_REPEAT_GL: // Fall-through (ordinary case).
15533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return (float)size*c;
15543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::REPEAT_CL:
15563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return (float)size * (c - deFloatFloor(c));
15573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::MIRRORED_REPEAT_CL:
15593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return (float)size * deFloatAbs(c - 2.0f * rint(0.5f * c));
15603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
15623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
15633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
15643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15673c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isFixedPointDepthTextureFormat (const tcu::TextureFormat& format)
15683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15698baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	DE_ASSERT(format.order == TextureFormat::D);
15703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15718baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
15728baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	if (channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
15738baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry		return false;
15748baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	else if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
15758baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry		return true;
15768baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry	else
15773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15788baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry		DE_ASSERT(false);
15798baf73a7505944cb677c87b1349664912a4a6db1Jarkko Pöyry		return false;
15803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texel lookup with color conversion.
15843c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline Vec4 lookup (const ConstPixelBufferAccess& access, int i, int j, int k)
15853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1586a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi	const TextureFormat&	format	= access.getFormat();
1587a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi
1588a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi	if (isSRGB(format))
1589a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi	{
1590a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi		if (format.type == TextureFormat::UNORM_INT8 && format.order == TextureFormat::sRGB)
1591a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi				return sRGB8ToLinear(access.getPixelUint(i, j, k));
1592a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi		else if (format.type == TextureFormat::UNORM_INT8 && format.order == TextureFormat::sRGBA)
1593a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi				return sRGBA8ToLinear(access.getPixelUint(i, j, k));
1594a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi		else
1595a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi			return sRGBToLinear(access.getPixel(i, j, k));
1596a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi	}
1597a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi	else
1598a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi	{
1599a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi		return access.getPixel(i, j, k);
1600a99421e9ede7fac9c1ea832038e2b6dfe4231845Mika Isojärvi	}
16013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1603222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry// Border texel lookup with color conversion.
160422941823a995126908aae341c87f2def77514ee7Jarkko Pöyrystatic inline Vec4 lookupBorder (const tcu::TextureFormat& format, const tcu::Sampler& sampler)
160522941823a995126908aae341c87f2def77514ee7Jarkko Pöyry{
1606222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	// "lookup" for a combined format does not make sense, disallow
1607222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	DE_ASSERT(!isCombinedDepthStencilType(format.type));
1608222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry
1609222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	const tcu::TextureChannelClass	channelClass 			= tcu::getTextureChannelClass(format.type);
1610222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	const bool						isFloat					= channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT;
1611222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	const bool						isFixed					= channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT ||
1612222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry															  channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT;
1613222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	const bool						isPureInteger			= channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER;
1614222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	const bool						isPureUnsignedInteger	= channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
1615222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry
1616222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	if (isFloat || isFixed)
1617d5be8ad612a000b4ad2caf14c8d93501f3558eb8Jarkko Pöyry		return sampleTextureBorder<float>(format, sampler);
1618222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	else if (isPureInteger)
1619222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry		return sampleTextureBorder<deInt32>(format, sampler).cast<float>();
1620222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	else if (isPureUnsignedInteger)
1621222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry		return sampleTextureBorder<deUint32>(format, sampler).cast<float>();
1622222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	else
1623222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	{
1624222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry		DE_ASSERT(false);
1625222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry		return Vec4(-1.0);
1626222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	}
162722941823a995126908aae341c87f2def77514ee7Jarkko Pöyry}
162822941823a995126908aae341c87f2def77514ee7Jarkko Pöyry
16293c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline float execCompare (const tcu::Vec4& color, Sampler::CompareMode compare, int chanNdx, float ref_, bool isFixedPoint)
16303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool	clampValues	= isFixedPoint;	// if comparing against a floating point texture, ref (and value) is not clamped
16323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	cmp			= (clampValues) ? (de::clamp(color[chanNdx], 0.0f, 1.0f)) : (color[chanNdx]);
16333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	ref			= (clampValues) ? (de::clamp(ref_, 0.0f, 1.0f)) : (ref_);
16343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		res			= false;
16353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (compare)
16373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_LESS:				res = ref < cmp;	break;
16393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_LESS_OR_EQUAL:	res = ref <= cmp;	break;
16403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_GREATER:			res = ref > cmp;	break;
16413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_GREATER_OR_EQUAL:	res = ref >= cmp;	break;
16423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_EQUAL:			res = ref == cmp;	break;
16433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_NOT_EQUAL:		res = ref != cmp;	break;
16443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_ALWAYS:			res = true;			break;
16453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_NEVER:			res = false;		break;
16463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
16473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
16483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return res ? 1.0f : 0.0f;
16513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16533c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleNearest1D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, const IVec2& offset)
16543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int width	= access.getWidth();
16563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x = deFloorFloatToInt32(u)+offset.x();
16583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check for CLAMP_TO_BORDER.
16603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.wrapS == Sampler::CLAMP_TO_BORDER && !deInBounds32(x, 0, width))
166122941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		return lookupBorder(access.getFormat(), sampler);
16623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i = wrap(sampler.wrapS, x, width);
16643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return lookup(access, i, offset.y(), 0);
16663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16683c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleNearest2D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, float v, const IVec3& offset)
16693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int width	= access.getWidth();
16713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int height	= access.getHeight();
16723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x = deFloorFloatToInt32(u)+offset.x();
16743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y = deFloorFloatToInt32(v)+offset.y();
16753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check for CLAMP_TO_BORDER.
16773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if ((sampler.wrapS == Sampler::CLAMP_TO_BORDER && !deInBounds32(x, 0, width)) ||
16783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		(sampler.wrapT == Sampler::CLAMP_TO_BORDER && !deInBounds32(y, 0, height)))
167922941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		return lookupBorder(access.getFormat(), sampler);
16803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i = wrap(sampler.wrapS, x, width);
16823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j = wrap(sampler.wrapT, y, height);
16833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return lookup(access, i, j, offset.z());
16853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16873c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleNearest3D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, float v, float w, const IVec3& offset)
16883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int width	= access.getWidth();
16903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int height	= access.getHeight();
16913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int depth	= access.getDepth();
16923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x = deFloorFloatToInt32(u)+offset.x();
16943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y = deFloorFloatToInt32(v)+offset.y();
16953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int z = deFloorFloatToInt32(w)+offset.z();
16963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check for CLAMP_TO_BORDER.
16983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if ((sampler.wrapS == Sampler::CLAMP_TO_BORDER && !deInBounds32(x, 0, width))	||
16993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		(sampler.wrapT == Sampler::CLAMP_TO_BORDER && !deInBounds32(y, 0, height))	||
17003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		(sampler.wrapR == Sampler::CLAMP_TO_BORDER && !deInBounds32(z, 0, depth)))
170122941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		return lookupBorder(access.getFormat(), sampler);
17023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i = wrap(sampler.wrapS, x, width);
17043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j = wrap(sampler.wrapT, y, height);
17053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int k = wrap(sampler.wrapR, z, depth);
17063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return lookup(access, i, j, k);
17083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17103c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleLinear1D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, const IVec2& offset)
17113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int w = access.getWidth();
17133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x0 = deFloorFloatToInt32(u-0.5f)+offset.x();
17153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x1 = x0+1;
17163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i0 = wrap(sampler.wrapS, x0, w);
17183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i1 = wrap(sampler.wrapS, x1, w);
17193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
17213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i0UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i0, 0, w);
17233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i1UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i1, 0, w);
17243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Border color for out-of-range coordinates if using CLAMP_TO_BORDER, otherwise execute lookups.
172622941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p0 = i0UseBorder ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, offset.y(), 0);
172722941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p1 = i1UseBorder ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, offset.y(), 0);
17283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
17303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return p0 * (1.0f - a) + p1 * a;
17313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17333c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleLinear2D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, float v, const IVec3& offset)
17343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int w = access.getWidth();
17363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int h = access.getHeight();
17373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x0 = deFloorFloatToInt32(u-0.5f)+offset.x();
17393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x1 = x0+1;
17403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y0 = deFloorFloatToInt32(v-0.5f)+offset.y();
17413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y1 = y0+1;
17423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i0 = wrap(sampler.wrapS, x0, w);
17443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i1 = wrap(sampler.wrapS, x1, w);
17453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j0 = wrap(sampler.wrapT, y0, h);
17463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j1 = wrap(sampler.wrapT, y1, h);
17473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
17493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float b = deFloatFrac(v-0.5f);
17503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i0UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i0, 0, w);
17523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i1UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i1, 0, w);
17533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool j0UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j0, 0, h);
17543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool j1UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j1, 0, h);
17553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Border color for out-of-range coordinates if using CLAMP_TO_BORDER, otherwise execute lookups.
175722941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p00 = (i0UseBorder || j0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j0, offset.z());
175822941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p10 = (i1UseBorder || j0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j0, offset.z());
175922941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p01 = (i0UseBorder || j1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j1, offset.z());
176022941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p11 = (i1UseBorder || j1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j1, offset.z());
17613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
17633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (p00*(1.0f-a)*(1.0f-b)) +
17643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p10*(     a)*(1.0f-b)) +
17653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p01*(1.0f-a)*(     b)) +
17663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p11*(     a)*(     b));
17673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17693c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float sampleLinear1DCompare (const ConstPixelBufferAccess& access, const Sampler& sampler, float ref, float u, const IVec2& offset, bool isFixedPointDepthFormat)
17703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int w = access.getWidth();
17723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x0 = deFloorFloatToInt32(u-0.5f)+offset.x();
17743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x1 = x0+1;
17753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i0 = wrap(sampler.wrapS, x0, w);
17773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i1 = wrap(sampler.wrapS, x1, w);
17783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
17803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i0UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i0, 0, w);
17823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i1UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i1, 0, w);
17833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Border color for out-of-range coordinates if using CLAMP_TO_BORDER, otherwise execute lookups.
178522941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p0Clr = i0UseBorder  ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, offset.y(), 0);
178622941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p1Clr = i1UseBorder  ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, offset.y(), 0);
17873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Execute comparisons.
17893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float p0 = execCompare(p0Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat);
17903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float p1 = execCompare(p1Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat);
17913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
17933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (p0 * (1.0f - a)) + (p1 * a);
17943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17963c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float sampleLinear2DCompare (const ConstPixelBufferAccess& access, const Sampler& sampler, float ref, float u, float v, const IVec3& offset, bool isFixedPointDepthFormat)
17973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int w = access.getWidth();
17993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int h = access.getHeight();
18003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x0 = deFloorFloatToInt32(u-0.5f)+offset.x();
18023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x1 = x0+1;
18033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y0 = deFloorFloatToInt32(v-0.5f)+offset.y();
18043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y1 = y0+1;
18053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i0 = wrap(sampler.wrapS, x0, w);
18073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i1 = wrap(sampler.wrapS, x1, w);
18083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j0 = wrap(sampler.wrapT, y0, h);
18093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j1 = wrap(sampler.wrapT, y1, h);
18103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
18123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float b = deFloatFrac(v-0.5f);
18133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i0UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i0, 0, w);
18153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i1UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i1, 0, w);
18163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool j0UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j0, 0, h);
18173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool j1UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j1, 0, h);
18183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Border color for out-of-range coordinates if using CLAMP_TO_BORDER, otherwise execute lookups.
182022941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p00Clr = (i0UseBorder || j0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j0, offset.z());
182122941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p10Clr = (i1UseBorder || j0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j0, offset.z());
182222941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p01Clr = (i0UseBorder || j1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j1, offset.z());
182322941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p11Clr = (i1UseBorder || j1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j1, offset.z());
18243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Execute comparisons.
18263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float p00 = execCompare(p00Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat);
18273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float p10 = execCompare(p10Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat);
18283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float p01 = execCompare(p01Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat);
18293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float p11 = execCompare(p11Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat);
18303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
18323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (p00*(1.0f-a)*(1.0f-b)) +
18333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p10*(     a)*(1.0f-b)) +
18343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p01*(1.0f-a)*(     b)) +
18353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p11*(     a)*(     b));
18363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18383c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleLinear3D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, float v, float w, const IVec3& offset)
18393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int width	= access.getWidth();
18413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int height	= access.getHeight();
18423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int depth	= access.getDepth();
18433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x0 = deFloorFloatToInt32(u-0.5f)+offset.x();
18453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x1 = x0+1;
18463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y0 = deFloorFloatToInt32(v-0.5f)+offset.y();
18473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y1 = y0+1;
18483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int z0 = deFloorFloatToInt32(w-0.5f)+offset.z();
18493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int z1 = z0+1;
18503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i0 = wrap(sampler.wrapS, x0, width);
18523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i1 = wrap(sampler.wrapS, x1, width);
18533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j0 = wrap(sampler.wrapT, y0, height);
18543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j1 = wrap(sampler.wrapT, y1, height);
18553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int k0 = wrap(sampler.wrapR, z0, depth);
18563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int k1 = wrap(sampler.wrapR, z1, depth);
18573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
18593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float b = deFloatFrac(v-0.5f);
18603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float c = deFloatFrac(w-0.5f);
18613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i0UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i0, 0, width);
18633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i1UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i1, 0, width);
18643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool j0UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j0, 0, height);
18653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool j1UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j1, 0, height);
18663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool k0UseBorder = sampler.wrapR == Sampler::CLAMP_TO_BORDER && !de::inBounds(k0, 0, depth);
18673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool k1UseBorder = sampler.wrapR == Sampler::CLAMP_TO_BORDER && !de::inBounds(k1, 0, depth);
18683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Border color for out-of-range coordinates if using CLAMP_TO_BORDER, otherwise execute lookups.
187022941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p000 = (i0UseBorder || j0UseBorder || k0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j0, k0);
187122941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p100 = (i1UseBorder || j0UseBorder || k0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j0, k0);
187222941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p010 = (i0UseBorder || j1UseBorder || k0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j1, k0);
187322941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p110 = (i1UseBorder || j1UseBorder || k0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j1, k0);
187422941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p001 = (i0UseBorder || j0UseBorder || k1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j0, k1);
187522941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p101 = (i1UseBorder || j0UseBorder || k1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j0, k1);
187622941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p011 = (i0UseBorder || j1UseBorder || k1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j1, k1);
187722941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p111 = (i1UseBorder || j1UseBorder || k1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j1, k1);
18783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
18803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (p000*(1.0f-a)*(1.0f-b)*(1.0f-c)) +
18813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p100*(     a)*(1.0f-b)*(1.0f-c)) +
18823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p010*(1.0f-a)*(     b)*(1.0f-c)) +
18833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p110*(     a)*(     b)*(1.0f-c)) +
18843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p001*(1.0f-a)*(1.0f-b)*(     c)) +
18853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p101*(     a)*(1.0f-b)*(     c)) +
18863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p011*(1.0f-a)*(     b)*(     c)) +
18873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p111*(     a)*(     b)*(     c));
18883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18903c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 ConstPixelBufferAccess::sample1D (const Sampler& sampler, Sampler::FilterMode filter, float s, int level) const
18913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1892612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// check selected layer exists
189329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(level, 0, m_size.y()));
18943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1895612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	return sample1DOffset(sampler, filter, s, tcu::IVec2(0, level));
18963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18983c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 ConstPixelBufferAccess::sample2D (const Sampler& sampler, Sampler::FilterMode filter, float s, float t, int depth) const
18993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1900612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// check selected layer exists
190129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(depth, 0, m_size.z()));
19023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1903612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	return sample2DOffset(sampler, filter, s, t, tcu::IVec3(0, 0, depth));
1904612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry}
19053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1906612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko PöyryVec4 ConstPixelBufferAccess::sample3D (const Sampler& sampler, Sampler::FilterMode filter, float s, float t, float r) const
1907612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry{
1908612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	return sample3DOffset(sampler, filter, s, t, r, tcu::IVec3(0, 0, 0));
19093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19113c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 ConstPixelBufferAccess::sample1DOffset (const Sampler& sampler, Sampler::FilterMode filter, float s, const IVec2& offset) const
19123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1913612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// check selected layer exists
1914612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// \note offset.x is X offset, offset.y is the selected layer
1915612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	DE_ASSERT(de::inBounds(offset.y(), 0, m_size.y()));
19163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
19183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float u = s;
19193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
192129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		u = unnormalize(sampler.wrapS, s, m_size.x());
19223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filter)
19243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return sampleNearest1D	(*this, sampler, u, offset);
19263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return sampleLinear1D	(*this, sampler, u, offset);
19273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
19283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
19293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
19303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19333c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 ConstPixelBufferAccess::sample2DOffset (const Sampler& sampler, Sampler::FilterMode filter, float s, float t, const IVec3& offset) const
19343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1935612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// check selected layer exists
1936612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// \note offset.xy is the XY offset, offset.z is the selected layer
193729340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(offset.z(), 0, m_size.z()));
19383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
19403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float u = s;
19413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float v = t;
19423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
19443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
194529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		u = unnormalize(sampler.wrapS, s, m_size.x());
194629340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		v = unnormalize(sampler.wrapT, t, m_size.y());
19473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filter)
19503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return sampleNearest2D	(*this, sampler, u, v, offset);
19523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return sampleLinear2D	(*this, sampler, u, v, offset);
19533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
19543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
19553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
19563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1959612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko PöyryVec4 ConstPixelBufferAccess::sample3DOffset (const Sampler& sampler, Sampler::FilterMode filter, float s, float t, float r, const IVec3& offset) const
19603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
19623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float u = s;
1963612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	float v = t;
1964612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	float w = r;
19653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
1967612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	{
196829340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		u = unnormalize(sampler.wrapS, s, m_size.x());
1969612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		v = unnormalize(sampler.wrapT, t, m_size.y());
1970612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		w = unnormalize(sampler.wrapR, r, m_size.z());
1971612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	}
19723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filter)
19743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1975612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		case Sampler::NEAREST:	return sampleNearest3D	(*this, sampler, u, v, w, offset);
1976612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		case Sampler::LINEAR:	return sampleLinear3D	(*this, sampler, u, v, w, offset);
19773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
19783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
1979612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry			return Vec4(0.0f);
19803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1983612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyryfloat ConstPixelBufferAccess::sample1DCompare (const Sampler& sampler, Sampler::FilterMode filter, float ref, float s, const IVec2& offset) const
19843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1985612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// check selected layer exists
1986612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// \note offset.x is X offset, offset.y is the selected layer
1987612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	DE_ASSERT(de::inBounds(offset.y(), 0, m_size.y()));
19883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Format information for comparison function
19903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool isFixedPointDepth = isFixedPointDepthTextureFormat(m_format);
19913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
19933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float u = s;
19943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
199629340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		u = unnormalize(sampler.wrapS, s, m_size.x());
19973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filter)
19993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2000612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		case Sampler::NEAREST:	return execCompare(sampleNearest1D(*this, sampler, u, offset), sampler.compare, sampler.compareChannel, ref, isFixedPointDepth);
2001612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		case Sampler::LINEAR:	return sampleLinear1DCompare(*this, sampler, ref, u, offset, isFixedPointDepth);
20023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
20033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
20043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
20053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2008612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyryfloat ConstPixelBufferAccess::sample2DCompare (const Sampler& sampler, Sampler::FilterMode filter, float ref, float s, float t, const IVec3& offset) const
20093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2010612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// check selected layer exists
2011612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// \note offset.xy is XY offset, offset.z is the selected layer
2012612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	DE_ASSERT(de::inBounds(offset.z(), 0, m_size.z()));
20133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2014612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// Format information for comparison function
2015612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	const bool isFixedPointDepth = isFixedPointDepthTextureFormat(m_format);
20163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
20183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float u = s;
20193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float v = t;
20203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
20223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
202329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		u = unnormalize(sampler.wrapS, s, m_size.x());
202429340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		v = unnormalize(sampler.wrapT, t, m_size.y());
20253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filter)
20283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2029612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		case Sampler::NEAREST:	return execCompare(sampleNearest2D(*this, sampler, u, v, offset), sampler.compare, sampler.compareChannel, ref, isFixedPointDepth);
2030612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		case Sampler::LINEAR:	return sampleLinear2DCompare(*this, sampler, ref, u, v, offset, isFixedPointDepth);
20313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
20323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
2033612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry			return 0.0f;
20343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20373c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevel::TextureLevel (void)
20383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	()
203929340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size	(0)
20403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20433c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevel::TextureLevel (const TextureFormat& format)
20443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	(format)
204529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size	(0)
20463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20493c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevel::TextureLevel (const TextureFormat& format, int width, int height, int depth)
20503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	(format)
205129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size	(0)
20523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	setSize(width, height, depth);
20543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20563c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevel::~TextureLevel (void)
20573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureLevel::setStorage (const TextureFormat& format, int width, int height, int depth)
20613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_format = format;
20633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	setSize(width, height, depth);
20643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureLevel::setSize (int width, int height, int depth)
20673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int pixelSize = m_format.getPixelSize();
20693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
207029340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	m_size = IVec3(width, height, depth);
20713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
207229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	m_data.setStorage(m_size.x() * m_size.y() * m_size.z() * pixelSize);
20733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20753c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 sampleLevelArray1D (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, int depth, float lod)
20763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20771d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry	return sampleLevelArray1DOffset(levels, numLevels, sampler, s, lod, IVec2(0, depth)); // y-offset in 1D textures is layer selector
20781d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry}
20793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20801d75d23528999118c1911ed100d1d063b06040daJarkko PöyryVec4 sampleLevelArray2D (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, int depth, float lod)
20811d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry{
20821d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry	return sampleLevelArray2DOffset(levels, numLevels, sampler, s, t, lod, IVec3(0, 0, depth)); // z-offset in 2D textures is layer selector
20831d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry}
20843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20851d75d23528999118c1911ed100d1d063b06040daJarkko PöyryVec4 sampleLevelArray3D (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, float r, float lod)
20861d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry{
20871d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry	return sampleLevelArray3DOffset(levels, numLevels, sampler, s, t, r, lod, IVec3(0, 0, 0));
20883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20903c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 sampleLevelArray1DOffset (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float lod, const IVec2& offset)
20913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
20933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
20943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
20963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return levels[0].sample1DOffset(sampler, filterMode, s, offset);
20983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return levels[0].sample1DOffset(sampler, filterMode, s, offset);
20993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
21013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
21023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
21043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
21053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
21063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return levels[level].sample1DOffset(sampler, levelFilter, s, offset);
21083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
21093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
21113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
21123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
21143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
21153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level1		= de::min(maxLevel, level0 + 1);
21163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
21173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				f			= deFloatFrac(lod);
21183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4			t0			= levels[level0].sample1DOffset(sampler, levelFilter, s, offset);
21193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4			t1			= levels[level1].sample1DOffset(sampler, levelFilter, s, offset);
21203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
21223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
21233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
21253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
21263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
21273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
21283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
21293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21303c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 sampleLevelArray2DOffset (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, float lod, const IVec3& offset)
21313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
21323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
21333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
21343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
21363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return levels[0].sample2DOffset(sampler, filterMode, s, t, offset);
21383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return levels[0].sample2DOffset(sampler, filterMode, s, t, offset);
21393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
21413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
21423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
21443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
21453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
21463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return levels[level].sample2DOffset(sampler, levelFilter, s, t, offset);
21483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
21493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
21513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
21523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
21543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
21553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level1		= de::min(maxLevel, level0 + 1);
21563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
21573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				f			= deFloatFrac(lod);
21583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4			t0			= levels[level0].sample2DOffset(sampler, levelFilter, s, t, offset);
21593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4			t1			= levels[level1].sample2DOffset(sampler, levelFilter, s, t, offset);
21603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
21623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
21633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
21653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
21663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
21673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
21683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
21693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21703c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 sampleLevelArray3DOffset (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, float r, float lod, const IVec3& offset)
21713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
21723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
21733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
21743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
21763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return levels[0].sample3DOffset(sampler, filterMode, s, t, r, offset);
21783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return levels[0].sample3DOffset(sampler, filterMode, s, t, r, offset);
21793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
21813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
21823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
21843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
21853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
21863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return levels[level].sample3DOffset(sampler, levelFilter, s, t, r, offset);
21883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
21893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
21913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
21923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
21943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
21953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level1		= de::min(maxLevel, level0 + 1);
21963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
21973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				f			= deFloatFrac(lod);
21983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4			t0			= levels[level0].sample3DOffset(sampler, levelFilter, s, t, r, offset);
21993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4			t1			= levels[level1].sample3DOffset(sampler, levelFilter, s, t, r, offset);
22003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
22023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
22053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
22063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
22073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
22083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
22093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22103c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat sampleLevelArray1DCompare (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float ref, float s, float lod, const IVec2& offset)
22113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
22123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
22133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
22143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
22163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
22173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return levels[0].sample1DCompare(sampler, filterMode, ref, s, offset);
22183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return levels[0].sample1DCompare(sampler, filterMode, ref, s, offset);
22193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
22213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
22223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
22243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
22253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
22263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return levels[level].sample1DCompare(sampler, levelFilter, ref, s, offset);
22283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
22313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
22323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
22343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
22353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level1		= de::min(maxLevel, level0 + 1);
22363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
22373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				f			= deFloatFrac(lod);
22383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				t0			= levels[level0].sample1DCompare(sampler, levelFilter, ref, s, offset);
22393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				t1			= levels[level1].sample1DCompare(sampler, levelFilter, ref, s, offset);
22403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
22423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
22453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
22463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
22473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
22483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
22493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat sampleLevelArray2DCompare (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float ref, float s, float t, float lod, const IVec3& offset)
22513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
22523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
22533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
22543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
22563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
22573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return levels[0].sample2DCompare(sampler, filterMode, ref, s, t, offset);
22583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return levels[0].sample2DCompare(sampler, filterMode, ref, s, t, offset);
22593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
22613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
22623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
22643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
22653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
22663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return levels[level].sample2DCompare(sampler, levelFilter, ref, s, t, offset);
22683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
22713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
22723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
22743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
22753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level1		= de::min(maxLevel, level0 + 1);
22763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
22773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				f			= deFloatFrac(lod);
22783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				t0			= levels[level0].sample2DCompare(sampler, levelFilter, ref, s, t, offset);
22793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				t1			= levels[level1].sample2DCompare(sampler, levelFilter, ref, s, t, offset);
22803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
22823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
22853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
22863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
22873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
22883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
22893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
229022941823a995126908aae341c87f2def77514ee7Jarkko Pöyrystatic Vec4 fetchGatherArray2DOffsets (const ConstPixelBufferAccess& src, const Sampler& sampler, float s, float t, int depth, int componentNdx, const IVec2 (&offsets)[4])
22913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
22923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(componentNdx, 0, 4));
22933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		w	= src.getWidth();
22953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		h	= src.getHeight();
22963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float		u	= unnormalize(sampler.wrapS, s, w);
22973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float		v	= unnormalize(sampler.wrapT, t, h);
22983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		x0	= deFloorFloatToInt32(u-0.5f);
22993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		y0	= deFloorFloatToInt32(v-0.5f);
23003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
230122941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4			result;
23023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
23043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
230522941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		const int	sampleX	= wrap(sampler.wrapS, x0 + offsets[i].x(), w);
230622941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		const int	sampleY	= wrap(sampler.wrapT, y0 + offsets[i].y(), h);
230722941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		Vec4		pixel;
230822941823a995126908aae341c87f2def77514ee7Jarkko Pöyry
230922941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		if (deInBounds32(sampleX, 0, w) && deInBounds32(sampleY, 0, h))
231022941823a995126908aae341c87f2def77514ee7Jarkko Pöyry			pixel = lookup(src, sampleX, sampleY, depth);
231122941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		else
231222941823a995126908aae341c87f2def77514ee7Jarkko Pöyry			pixel = lookupBorder(src.getFormat(), sampler);
231322941823a995126908aae341c87f2def77514ee7Jarkko Pöyry
23143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result[i] = pixel[componentNdx];
23153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
23163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
23183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
232022941823a995126908aae341c87f2def77514ee7Jarkko PöyryVec4 gatherArray2DOffsets (const ConstPixelBufferAccess& src, const Sampler& sampler, float s, float t, int depth, int componentNdx, const IVec2 (&offsets)[4])
232122941823a995126908aae341c87f2def77514ee7Jarkko Pöyry{
232222941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	DE_ASSERT(sampler.compare == Sampler::COMPAREMODE_NONE);
232322941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	DE_ASSERT(de::inBounds(componentNdx, 0, 4));
232422941823a995126908aae341c87f2def77514ee7Jarkko Pöyry
232522941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	return fetchGatherArray2DOffsets(src, sampler, s, t, depth, componentNdx, offsets);
232622941823a995126908aae341c87f2def77514ee7Jarkko Pöyry}
232722941823a995126908aae341c87f2def77514ee7Jarkko Pöyry
23283c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 gatherArray2DOffsetsCompare (const ConstPixelBufferAccess& src, const Sampler& sampler, float ref, float s, float t, int depth, const IVec2 (&offsets)[4])
23293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare != Sampler::COMPAREMODE_NONE);
23313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(src.getFormat().order == TextureFormat::D || src.getFormat().order == TextureFormat::DS);
23323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compareChannel == 0);
23333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2334222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	const bool	isFixedPoint	= isFixedPointDepthTextureFormat(src.getFormat());
2335222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	const Vec4	gathered		= fetchGatherArray2DOffsets(src, sampler, s, t, depth, 0 /* component 0: depth */, offsets);
2336222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	Vec4		result;
23373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
23393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result[i] = execCompare(gathered, sampler.compare, i, ref, isFixedPoint);
23403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
23423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23443c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleCubeSeamlessNearest (const ConstPixelBufferAccess& faceAccess, const Sampler& sampler, float s, float t, int depth)
23453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler clampingSampler = sampler;
23473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	clampingSampler.wrapS = Sampler::CLAMP_TO_EDGE;
23483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	clampingSampler.wrapT = Sampler::CLAMP_TO_EDGE;
23493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return faceAccess.sample2D(clampingSampler, Sampler::NEAREST, s, t, depth);
23503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23523c827367444ee418f129b2c238299f49d3264554Jarkko PoyryCubeFace selectCubeFace (const Vec3& coords)
23533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	x	= coords.x();
23553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	y	= coords.y();
23563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	z	= coords.z();
23573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	ax	= deFloatAbs(x);
23583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	ay	= deFloatAbs(y);
23593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	az	= deFloatAbs(z);
23603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (ay < ax && az < ax)
23623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return x >= 0.0f ? CUBEFACE_POSITIVE_X : CUBEFACE_NEGATIVE_X;
23633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (ax < ay && az < ay)
23643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return y >= 0.0f ? CUBEFACE_POSITIVE_Y : CUBEFACE_NEGATIVE_Y;
23653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (ax < az && ay < az)
23663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return z >= 0.0f ? CUBEFACE_POSITIVE_Z : CUBEFACE_NEGATIVE_Z;
23673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
23683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Some of the components are equal. Use tie-breaking rule.
23703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (ax == ay)
23713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
23723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (ax < az)
23733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return z >= 0.0f ? CUBEFACE_POSITIVE_Z : CUBEFACE_NEGATIVE_Z;
23743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
23753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return x >= 0.0f ? CUBEFACE_POSITIVE_X : CUBEFACE_NEGATIVE_X;
23763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
23773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (ax == az)
23783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
23793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (az < ay)
23803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return y >= 0.0f ? CUBEFACE_POSITIVE_Y : CUBEFACE_NEGATIVE_Y;
23813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
23823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return z >= 0.0f ? CUBEFACE_POSITIVE_Z : CUBEFACE_NEGATIVE_Z;
23833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
23843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (ay == az)
23853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
23863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (ay < ax)
23873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return x >= 0.0f ? CUBEFACE_POSITIVE_X : CUBEFACE_NEGATIVE_X;
23883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
23893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return y >= 0.0f ? CUBEFACE_POSITIVE_Y : CUBEFACE_NEGATIVE_Y;
23903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
23913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
23923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return x >= 0.0f ? CUBEFACE_POSITIVE_X : CUBEFACE_NEGATIVE_X;
23933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
23943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23963c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec2 projectToFace (CubeFace face, const Vec3& coord)
23973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	rx		= coord.x();
23993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	ry		= coord.y();
24003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	rz		= coord.z();
24013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		sc		= 0.0f;
24023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		tc		= 0.0f;
24033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		ma		= 0.0f;
24043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		s;
24053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		t;
24063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (face)
24083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_X: sc = +rz; tc = -ry; ma = -rx; break;
24103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_X: sc = -rz; tc = -ry; ma = +rx; break;
24113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_Y: sc = +rx; tc = -rz; ma = -ry; break;
24123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_Y: sc = +rx; tc = +rz; ma = +ry; break;
24133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_Z: sc = -rx; tc = -ry; ma = -rz; break;
24143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_Z: sc = +rx; tc = -ry; ma = +rz; break;
24153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
24163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
24173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
24183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute s, t
24203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	s = ((sc / ma) + 1.0f) / 2.0f;
24213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	t = ((tc / ma) + 1.0f) / 2.0f;
24223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return Vec2(s, t);
24243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24263c827367444ee418f129b2c238299f49d3264554Jarkko PoyryCubeFaceFloatCoords getCubeFaceCoords (const Vec3& coords)
24273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CubeFace face = selectCubeFace(coords);
24293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return CubeFaceFloatCoords(face, projectToFace(face, coords));
24303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24323c827367444ee418f129b2c238299f49d3264554Jarkko 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.
24333c827367444ee418f129b2c238299f49d3264554Jarkko 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.
24343c827367444ee418f129b2c238299f49d3264554Jarkko PoyryCubeFaceIntCoords remapCubeEdgeCoords (const CubeFaceIntCoords& origCoords, int size)
24353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool uInBounds = de::inBounds(origCoords.s, 0, size);
24373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool vInBounds = de::inBounds(origCoords.t, 0, size);
24383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (uInBounds && vInBounds)
24403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return origCoords;
24413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!uInBounds && !vInBounds)
24433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_LAST, -1, -1);
24443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec2 coords(wrap(Sampler::CLAMP_TO_BORDER, origCoords.s, size),
24463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				 wrap(Sampler::CLAMP_TO_BORDER, origCoords.t, size));
24473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec3 canonizedCoords;
24483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Map the uv coordinates to canonized 3d coordinates.
24503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (origCoords.face)
24523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_X: canonizedCoords = IVec3(0,					size-1-coords.y(),	coords.x());			break;
24543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_X: canonizedCoords = IVec3(size-1,				size-1-coords.y(),	size-1-coords.x());		break;
24553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_Y: canonizedCoords = IVec3(coords.x(),			0,					size-1-coords.y());		break;
24563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_Y: canonizedCoords = IVec3(coords.x(),			size-1,				coords.y());			break;
24573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_Z: canonizedCoords = IVec3(size-1-coords.x(),	size-1-coords.y(),	0);						break;
24583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_Z: canonizedCoords = IVec3(coords.x(),			size-1-coords.y(),	size-1);				break;
24593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default: DE_ASSERT(false);
24603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
24613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Find an appropriate face to re-map the coordinates to.
24633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (canonizedCoords.x() == -1)
24653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_NEGATIVE_X, IVec2(canonizedCoords.z(), size-1-canonizedCoords.y()));
24663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (canonizedCoords.x() == size)
24683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_POSITIVE_X, IVec2(size-1-canonizedCoords.z(), size-1-canonizedCoords.y()));
24693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (canonizedCoords.y() == -1)
24713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_NEGATIVE_Y, IVec2(canonizedCoords.x(), size-1-canonizedCoords.z()));
24723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (canonizedCoords.y() == size)
24743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_POSITIVE_Y, IVec2(canonizedCoords.x(), canonizedCoords.z()));
24753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (canonizedCoords.z() == -1)
24773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_NEGATIVE_Z, IVec2(size-1-canonizedCoords.x(), size-1-canonizedCoords.y()));
24783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (canonizedCoords.z() == size)
24803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_POSITIVE_Z, IVec2(canonizedCoords.x(), size-1-canonizedCoords.y()));
24813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(false);
24833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return CubeFaceIntCoords(CUBEFACE_LAST, IVec2(-1));
24843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24863c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void getCubeLinearSamples (const ConstPixelBufferAccess (&faceAccesses)[CUBEFACE_LAST], CubeFace baseFace, float u, float v, int depth, Vec4 (&dst)[4])
24873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(faceAccesses[0].getWidth() == faceAccesses[0].getHeight());
24893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		size					= faceAccesses[0].getWidth();
24903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		x0						= deFloorFloatToInt32(u-0.5f);
24913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		x1						= x0+1;
24923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		y0						= deFloorFloatToInt32(v-0.5f);
24933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		y1						= y0+1;
24943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec2	baseSampleCoords[4]		=
24953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x0, y0),
24973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x1, y0),
24983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x0, y1),
24993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x1, y1)
25003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
25013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4	sampleColors[4];
25023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool	hasBothCoordsOutOfBounds[4]; //!< Whether correctCubeFace() returns CUBEFACE_LAST, i.e. both u and v are out of bounds.
25033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Find correct faces and coordinates for out-of-bounds sample coordinates.
25053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
25073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
25083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CubeFaceIntCoords coords = remapCubeEdgeCoords(CubeFaceIntCoords(baseFace, baseSampleCoords[i]), size);
25093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		hasBothCoordsOutOfBounds[i] = coords.face == CUBEFACE_LAST;
25103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!hasBothCoordsOutOfBounds[i])
25113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sampleColors[i] = lookup(faceAccesses[coords.face], coords.s, coords.t, depth);
25123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
25133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25143c827367444ee418f129b2c238299f49d3264554Jarkko 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.
25153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note This averaging behavior is not required by the GLES3 spec (though it is recommended). GLES3 spec only
25163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//		 requires that if the three other samples all have the same color, then the doubly-out-of-bounds sample
25173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//		 must have this color as well.
25183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
25203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int bothOutOfBoundsNdx = -1;
25213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < 4; i++)
25223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
25233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (hasBothCoordsOutOfBounds[i])
25243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
25253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(bothOutOfBoundsNdx < 0); // Only one sample can be out of bounds in both u and v.
25263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				bothOutOfBoundsNdx = i;
25273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
25283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
25293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (bothOutOfBoundsNdx != -1)
25303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
25313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sampleColors[bothOutOfBoundsNdx] = Vec4(0.0f);
25323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < 4; i++)
25333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (i != bothOutOfBoundsNdx)
25343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					sampleColors[bothOutOfBoundsNdx] += sampleColors[i];
25353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sampleColors[bothOutOfBoundsNdx] = sampleColors[bothOutOfBoundsNdx] * (1.0f/3.0f);
25373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
25383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
25393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < DE_LENGTH_OF_ARRAY(sampleColors); i++)
25413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dst[i] = sampleColors[i];
25423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
25433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \todo [2014-02-19 pyry] Optimize faceAccesses
25453c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleCubeSeamlessLinear (const ConstPixelBufferAccess (&faceAccesses)[CUBEFACE_LAST], CubeFace baseFace, const Sampler& sampler, float s, float t, int depth)
25463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
25473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(faceAccesses[0].getWidth() == faceAccesses[0].getHeight());
25483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		size	= faceAccesses[0].getWidth();
25503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
25513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float	u		= s;
25523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float	v		= t;
25533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
25553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
25563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		u = unnormalize(sampler.wrapS, s, size);
25573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		v = unnormalize(sampler.wrapT, t, size);
25583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
25593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Get sample colors.
25613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 sampleColors[4];
25633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	getCubeLinearSamples(faceAccesses, baseFace, u, v, depth, sampleColors);
25643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
25663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
25683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float b = deFloatFrac(v-0.5f);
25693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (sampleColors[0]*(1.0f-a)*(1.0f-b)) +
25713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (sampleColors[1]*(     a)*(1.0f-b)) +
25723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (sampleColors[2]*(1.0f-a)*(     b)) +
25733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (sampleColors[3]*(     a)*(     b));
25743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
25753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25763c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleLevelArrayCubeSeamless (const ConstPixelBufferAccess* const (&faces)[CUBEFACE_LAST], int numLevels, CubeFace face, const Sampler& sampler, float s, float t, int depth, float lod)
25773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
25783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
25793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
25803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
25823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
25833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:
25843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessNearest(faces[face][0], sampler, s, t, depth);
25853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:
25873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
25883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
25893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < (int)CUBEFACE_LAST; i++)
25903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				faceAccesses[i] = faces[i][0];
25913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessLinear(faceAccesses, face, sampler, s, t, depth);
25933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
25943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
25963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
25973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
25983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
25993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
26003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
26013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
26033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessNearest(faces[face][level], sampler, s, t, depth);
26043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
26053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
26063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
26073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
26093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
26103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses[i] = faces[i][level];
26113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessLinear(faceAccesses, face, sampler, s, t, depth);
26133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
26143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
26153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
26173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
26183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
26193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
26203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
26213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level1		= de::min(maxLevel, level0 + 1);
26223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
26233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					f			= deFloatFrac(lod);
26243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec4					t0;
26253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec4					t1;
26263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
26283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
26293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessNearest(faces[face][level0], sampler, s, t, depth);
26303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessNearest(faces[face][level1], sampler, s, t, depth);
26313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
26323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
26333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
26343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
26353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses0[CUBEFACE_LAST];
26373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses1[CUBEFACE_LAST];
26383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
26393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
26403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses0[i] = faces[i][level0];
26413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses1[i] = faces[i][level1];
26423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
26433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessLinear(faceAccesses0, face, sampler, s, t, depth);
26453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessLinear(faceAccesses1, face, sampler, s, t, depth);
26463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
26473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
26493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
26503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
26523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
26533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
26543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
26553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
26563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26573c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float sampleCubeSeamlessNearestCompare (const ConstPixelBufferAccess& faceAccess, const Sampler& sampler, float ref, float s, float t, int depth = 0)
26583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler clampingSampler = sampler;
26603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	clampingSampler.wrapS = Sampler::CLAMP_TO_EDGE;
26613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	clampingSampler.wrapT = Sampler::CLAMP_TO_EDGE;
26623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return faceAccess.sample2DCompare(clampingSampler, Sampler::NEAREST, ref, s, t, IVec3(0, 0, depth));
26633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
26643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26653c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float sampleCubeSeamlessLinearCompare (const ConstPixelBufferAccess (&faceAccesses)[CUBEFACE_LAST], CubeFace baseFace, const Sampler& sampler, float ref, float s, float t)
26663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(faceAccesses[0].getWidth() == faceAccesses[0].getHeight());
26683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		size	= faceAccesses[0].getWidth();
26703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
26713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float	u		= s;
26723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float	v		= t;
26733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
26753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
26763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		u = unnormalize(sampler.wrapS, s, size);
26773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		v = unnormalize(sampler.wrapT, t, size);
26783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
26793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			x0						= deFloorFloatToInt32(u-0.5f);
26813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			x1						= x0+1;
26823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			y0						= deFloorFloatToInt32(v-0.5f);
26833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			y1						= y0+1;
26843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec2		baseSampleCoords[4]		=
26853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
26863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x0, y0),
26873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x1, y0),
26883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x0, y1),
26893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x1, y1)
26903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
26913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		sampleRes[4];
26923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		hasBothCoordsOutOfBounds[4]; //!< Whether correctCubeFace() returns CUBEFACE_LAST, i.e. both u and v are out of bounds.
26933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Find correct faces and coordinates for out-of-bounds sample coordinates.
26953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
26973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
26983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CubeFaceIntCoords coords = remapCubeEdgeCoords(CubeFaceIntCoords(baseFace, baseSampleCoords[i]), size);
26993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		hasBothCoordsOutOfBounds[i] = coords.face == CUBEFACE_LAST;
27003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!hasBothCoordsOutOfBounds[i])
27023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
27033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool isFixedPointDepth = isFixedPointDepthTextureFormat(faceAccesses[coords.face].getFormat());
27043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sampleRes[i] = execCompare(faceAccesses[coords.face].getPixel(coords.s, coords.t), sampler.compare, sampler.compareChannel, ref, isFixedPointDepth);
27063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
27073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
27083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27093c827367444ee418f129b2c238299f49d3264554Jarkko 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.
27103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note This averaging behavior is not required by the GLES3 spec (though it is recommended). GLES3 spec only
27113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//		 requires that if the three other samples all have the same color, then the doubly-out-of-bounds sample
27123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//		 must have this color as well.
27133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
27153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int bothOutOfBoundsNdx = -1;
27163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < 4; i++)
27173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
27183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (hasBothCoordsOutOfBounds[i])
27193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
27203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(bothOutOfBoundsNdx < 0); // Only one sample can be out of bounds in both u and v.
27213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				bothOutOfBoundsNdx = i;
27223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
27233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
27243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (bothOutOfBoundsNdx != -1)
27253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
27263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sampleRes[bothOutOfBoundsNdx] = 0.0f;
27273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < 4; i++)
27283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (i != bothOutOfBoundsNdx)
27293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					sampleRes[bothOutOfBoundsNdx] += sampleRes[i];
27303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sampleRes[bothOutOfBoundsNdx] = sampleRes[bothOutOfBoundsNdx] * (1.0f/3.0f);
27323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
27333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
27343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
27363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
27383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float b = deFloatFrac(v-0.5f);
27393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (sampleRes[0]*(1.0f-a)*(1.0f-b)) +
27413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (sampleRes[1]*(     a)*(1.0f-b)) +
27423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (sampleRes[2]*(1.0f-a)*(     b)) +
27433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (sampleRes[3]*(     a)*(     b));
27443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27463c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float sampleLevelArrayCubeSeamlessCompare (const ConstPixelBufferAccess* const (&faces)[CUBEFACE_LAST], int numLevels, CubeFace face, const Sampler& sampler, float ref, float s, float t, float lod)
27473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
27493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
27503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
27523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
27533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:
27543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessNearestCompare(faces[face][0], sampler, ref, s, t);
27553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:
27573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
27583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
27593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < (int)CUBEFACE_LAST; i++)
27603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				faceAccesses[i] = faces[i][0];
27613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessLinearCompare(faceAccesses, face, sampler, ref, s, t);
27633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
27643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
27663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
27673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
27683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
27693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
27703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
27713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
27733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessNearestCompare(faces[face][level], sampler, ref, s, t);
27743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
27753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
27763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
27773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
27793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
27803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses[i] = faces[i][level];
27813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessLinearCompare(faceAccesses, face, sampler, ref, s, t);
27833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
27843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
27853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
27873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
27883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
27893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
27903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
27913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level1		= de::min(maxLevel, level0 + 1);
27923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
27933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					f			= deFloatFrac(lod);
27943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					t0;
27953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					t1;
27963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
27983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
27993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessNearestCompare(faces[face][level0], sampler, ref, s, t);
28003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessNearestCompare(faces[face][level1], sampler, ref, s, t);
28013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
28023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
28033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
28043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
28053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses0[CUBEFACE_LAST];
28073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses1[CUBEFACE_LAST];
28083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
28093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
28103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses0[i] = faces[i][level0];
28113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses1[i] = faces[i][level1];
28123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
28133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessLinearCompare(faceAccesses0, face, sampler, ref, s, t);
28153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessLinearCompare(faceAccesses1, face, sampler, ref, s, t);
28163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
28173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
28193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
28203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
28223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
28233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
28243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
28253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Cube map array sampling
28283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28293c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline ConstPixelBufferAccess getCubeArrayFaceAccess (const ConstPixelBufferAccess* const levels, int levelNdx, int slice, CubeFace face)
28303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ConstPixelBufferAccess&	level	= levels[levelNdx];
28323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						depth	= (slice * 6) + getCubeArrayFaceIndex(face);
28333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return getSubregion(level, 0, 0, depth, level.getWidth(), level.getHeight(), 1);
28353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28373c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleCubeArraySeamless (const ConstPixelBufferAccess* const levels, int numLevels, int slice, CubeFace face, const Sampler& sampler, float s, float t, float lod)
28383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					faceDepth	= (slice * 6) + getCubeArrayFaceIndex(face);
28403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool					magnified	= lod <= sampler.lodThreshold;
28413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Sampler::FilterMode	filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
28423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
28443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
28453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:
28463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessNearest(levels[0], sampler, s, t, faceDepth);
28473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:
28493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
28503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
28513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < (int)CUBEFACE_LAST; i++)
28523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				faceAccesses[i] = getCubeArrayFaceAccess(levels, 0, slice, (CubeFace)i);
28533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessLinear(faceAccesses, face, sampler, s, t, 0);
28553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
28563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
28583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
28593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
28603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
28613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
28623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
28633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
28653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessNearest(levels[level], sampler, s, t, faceDepth);
28663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
28673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
28683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
28693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
28713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
28723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses[i] = getCubeArrayFaceAccess(levels, level, slice, (CubeFace)i);
28733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessLinear(faceAccesses, face, sampler, s, t, 0);
28753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
28763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
28773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
28793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
28803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
28813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
28823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
28833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level1		= de::min(maxLevel, level0 + 1);
28843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
28853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					f			= deFloatFrac(lod);
28863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec4					t0;
28873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec4					t1;
28883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
28903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
28913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessNearest(levels[level0], sampler, s, t, faceDepth);
28923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessNearest(levels[level1], sampler, s, t, faceDepth);
28933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
28943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
28953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
28963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
28973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses0[CUBEFACE_LAST];
28993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses1[CUBEFACE_LAST];
29003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
29013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
29023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses0[i] = getCubeArrayFaceAccess(levels, level0, slice, (CubeFace)i);
29033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses1[i] = getCubeArrayFaceAccess(levels, level1, slice, (CubeFace)i);
29043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
29053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessLinear(faceAccesses0, face, sampler, s, t, 0);
29073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessLinear(faceAccesses1, face, sampler, s, t, 0);
29083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
29093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
29113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
29123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
29143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
29153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
29163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
29173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29193c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float sampleCubeArraySeamlessCompare (const ConstPixelBufferAccess* const levels, int numLevels, int slice, CubeFace face, const Sampler& sampler, float ref, float s, float t, float lod)
29203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int			faceDepth	= (slice * 6) + getCubeArrayFaceIndex(face);
29223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool			magnified	= lod <= sampler.lodThreshold;
29233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode	filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
29243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
29263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
29273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:
29283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessNearestCompare(levels[0], sampler, ref, s, t, faceDepth);
29293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:
29313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
29323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
29333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < (int)CUBEFACE_LAST; i++)
29343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				faceAccesses[i] = getCubeArrayFaceAccess(levels, 0, slice, (CubeFace)i);
29353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessLinearCompare(faceAccesses, face, sampler, ref, s, t);
29373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
29383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
29403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
29413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
29423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
29433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
29443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
29453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
29473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessNearestCompare(levels[level], sampler, ref, s, t, faceDepth);
29483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
29493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
29503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
29513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
29533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
29543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses[i] = getCubeArrayFaceAccess(levels, level, slice, (CubeFace)i);
29553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessLinearCompare(faceAccesses, face, sampler, ref, s, t);
29573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
29583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
29593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
29613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
29623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
29633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
29643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
29653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level1		= de::min(maxLevel, level0 + 1);
29663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
29673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					f			= deFloatFrac(lod);
29683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					t0;
29693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					t1;
29703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
29723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
29733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessNearestCompare(levels[level0], sampler, ref, s, t, faceDepth);
29743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessNearestCompare(levels[level1], sampler, ref, s, t, faceDepth);
29753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
29763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
29773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
29783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
29793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses0[CUBEFACE_LAST];
29813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses1[CUBEFACE_LAST];
29823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
29833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
29843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses0[i] = getCubeArrayFaceAccess(levels, level0, slice, (CubeFace)i);
29853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses1[i] = getCubeArrayFaceAccess(levels, level1, slice, (CubeFace)i);
29863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
29873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessLinearCompare(faceAccesses0, face, sampler, ref, s, t);
29893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessLinearCompare(faceAccesses1, face, sampler, ref, s, t);
29903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
29913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
29933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
29943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
29963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
29973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
29983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
29993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30013c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int computeMipPyramidLevels (int size)
30023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return deLog2Floor32(size)+1;
30043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30063c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int computeMipPyramidLevels (int width, int height)
30073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return deLog2Floor32(de::max(width, height))+1;
30093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30113c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int computeMipPyramidLevels (int width, int height, int depth)
30123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return deLog2Floor32(de::max(width, de::max(height, depth)))+1;
30143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30163c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int getMipPyramidLevelSize (int baseLevelSize, int levelNdx)
30173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return de::max(baseLevelSize >> levelNdx, 1);
30193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// TextureLevelPyramid
30223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30233c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevelPyramid::TextureLevelPyramid (const TextureFormat& format, int numLevels)
30243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	(format)
30253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_data	(numLevels)
30263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_access	(numLevels)
30273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30303c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevelPyramid::TextureLevelPyramid (const TextureLevelPyramid& other)
30313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	(other.m_format)
30323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_data	(other.getNumLevels())
30333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_access	(other.getNumLevels())
30343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int levelNdx = 0; levelNdx < other.getNumLevels(); levelNdx++)
30363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
30373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!other.isLevelEmpty(levelNdx))
30383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
30393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::ConstPixelBufferAccess& srcLevel = other.getLevel(levelNdx);
30403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_data[levelNdx] = other.m_data[levelNdx];
30423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_access[levelNdx] = PixelBufferAccess(srcLevel.getFormat(), srcLevel.getWidth(), srcLevel.getHeight(), srcLevel.getDepth(), m_data[levelNdx].getPtr());
30433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
30443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
30453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30473c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevelPyramid& TextureLevelPyramid::operator= (const TextureLevelPyramid& other)
30483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
30503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
30513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_format = other.m_format;
30533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_data.resize(other.getNumLevels());
30543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_access.resize(other.getNumLevels());
30553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int levelNdx = 0; levelNdx < other.getNumLevels(); levelNdx++)
30573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
30583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!other.isLevelEmpty(levelNdx))
30593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
30603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::ConstPixelBufferAccess& srcLevel = other.getLevel(levelNdx);
30613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_data[levelNdx] = other.m_data[levelNdx];
30633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_access[levelNdx] = PixelBufferAccess(srcLevel.getFormat(), srcLevel.getWidth(), srcLevel.getHeight(), srcLevel.getDepth(), m_data[levelNdx].getPtr());
30643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
30653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (!isLevelEmpty(levelNdx))
30663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			clearLevel(levelNdx);
30673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
30683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
30703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30723c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevelPyramid::~TextureLevelPyramid (void)
30733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30763c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureLevelPyramid::allocLevel (int levelNdx, int width, int height, int depth)
30773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	size	= m_format.getPixelSize()*width*height*depth;
30793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(isLevelEmpty(levelNdx));
30813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_data[levelNdx].setStorage(size);
30833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_access[levelNdx] = PixelBufferAccess(m_format, width, height, depth, m_data[levelNdx].getPtr());
30843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30863c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureLevelPyramid::clearLevel (int levelNdx)
30873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!isLevelEmpty(levelNdx));
30893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_data[levelNdx].clear();
30913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_access[levelNdx] = PixelBufferAccess();
30923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture1D
30953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30963c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1D::Texture1D (const TextureFormat& format, int width)
30973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(format, computeMipPyramidLevels(width))
30983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(width)
30993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
31003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31033c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1D::Texture1D (const Texture1D& other)
31043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(other)
31053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(other.m_width)
31063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
31073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31103c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1D& Texture1D::operator= (const Texture1D& other)
31113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
31133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
31143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::operator=(other);
31163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_width		= other.m_width;
31183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view		= Texture1DView(getNumLevels(), getLevels());
31193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
31213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31233c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1D::~Texture1D (void)
31243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31273c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture1D::allocLevel (int levelNdx)
31283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels()));
31303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int width = getMipPyramidLevelSize(m_width, levelNdx);
31323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::allocLevel(levelNdx, width, 1, 1);
31343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture2D
31373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31383c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2D::Texture2D (const TextureFormat& format, int width, int height)
31393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(format, computeMipPyramidLevels(width, height))
31403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(width)
31413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height				(height)
31423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
31433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31463c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2D::Texture2D (const Texture2D& other)
31473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(other)
31483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(other.m_width)
31493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height				(other.m_height)
31503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
31513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31543c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2D& Texture2D::operator= (const Texture2D& other)
31553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
31573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
31583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::operator=(other);
31603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_width		= other.m_width;
31623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_height	= other.m_height;
31633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view		= Texture2DView(getNumLevels(), getLevels());
31643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
31663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31683c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2D::~Texture2D (void)
31693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31723c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2D::allocLevel (int levelNdx)
31733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels()));
31753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	width	= getMipPyramidLevelSize(m_width, levelNdx);
31773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	height	= getMipPyramidLevelSize(m_height, levelNdx);
31783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::allocLevel(levelNdx, width, height, 1);
31803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// TextureCubeView
31833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31843c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeView::TextureCubeView (void)
31853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_numLevels(0)
31863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < CUBEFACE_LAST; ndx++)
31883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_levels[ndx] = DE_NULL;
31893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31913c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeView::TextureCubeView (int numLevels, const ConstPixelBufferAccess* const (&levels) [CUBEFACE_LAST])
31923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_numLevels(numLevels)
31933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < CUBEFACE_LAST; ndx++)
31953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_levels[ndx] = levels[ndx];
31963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31983c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Vec4 TextureCubeView::sample (const Sampler& sampler, float s, float t, float r, float lod) const
31993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare == Sampler::COMPAREMODE_NONE);
32013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Computes (face, s, t).
32033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CubeFaceFloatCoords coords = getCubeFaceCoords(Vec3(s, t, r));
32043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.seamlessCubeMap)
32053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sampleLevelArrayCubeSeamless(m_levels, m_numLevels, coords.face, sampler, coords.s, coords.t, 0 /* depth */, lod);
32063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
32073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sampleLevelArray2D(m_levels[coords.face], m_numLevels, sampler, coords.s, coords.t, 0 /* depth */, lod);
32083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32103c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat TextureCubeView::sampleCompare (const Sampler& sampler, float ref, float s, float t, float r, float lod) const
32113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare != Sampler::COMPAREMODE_NONE);
32133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Computes (face, s, t).
32153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CubeFaceFloatCoords coords = getCubeFaceCoords(Vec3(s, t, r));
32163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.seamlessCubeMap)
32173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sampleLevelArrayCubeSeamlessCompare(m_levels, m_numLevels, coords.face, sampler, ref, coords.s, coords.t, lod);
32183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
32193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sampleLevelArray2DCompare(m_levels[coords.face], m_numLevels, sampler, ref, coords.s, coords.t, lod, IVec3(0, 0, 0));
32203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32223c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 TextureCubeView::gather (const Sampler& sampler, float s, float t, float r, int componentNdx) const
32233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare == Sampler::COMPAREMODE_NONE);
32253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
32273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)CUBEFACE_LAST; i++)
32283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		faceAccesses[i] = m_levels[i][0];
32293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CubeFaceFloatCoords	coords	= getCubeFaceCoords(Vec3(s, t, r));
32313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					size	= faceAccesses[0].getWidth();
32323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
32333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float						u		= coords.s;
32343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float						v		= coords.t;
32353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
32373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
32383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		u = unnormalize(sampler.wrapS, coords.s, size);
32393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		v = unnormalize(sampler.wrapT, coords.t, size);
32403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
32413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 sampleColors[4];
32433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	getCubeLinearSamples(faceAccesses, coords.face, u, v, 0, sampleColors);
32443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	sampleIndices[4] = { 2, 3, 1, 0 }; // \note Gather returns the samples in a non-obvious order.
32463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4		result;
32473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
32483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result[i] = sampleColors[sampleIndices[i]][componentNdx];
32493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
32513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32533c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 TextureCubeView::gatherCompare (const Sampler& sampler, float ref, float s, float t, float r) const
32543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare != Sampler::COMPAREMODE_NONE);
32563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_levels[0][0].getFormat().order == TextureFormat::D || m_levels[0][0].getFormat().order == TextureFormat::DS);
32573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compareChannel == 0);
32583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler noCompareSampler = sampler;
32603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	noCompareSampler.compare = Sampler::COMPAREMODE_NONE;
32613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec4 gathered			= gather(noCompareSampler, s, t, r, 0 /* component 0: depth */);
32633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool isFixedPoint		= isFixedPointDepthTextureFormat(m_levels[0][0].getFormat());
32643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 result;
32653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
32663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result[i] = execCompare(gathered, sampler.compare, i, ref, isFixedPoint);
32673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
32693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// TextureCube
32723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32733c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCube::TextureCube (const TextureFormat& format, int size)
32743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	(format)
32753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_size	(size)
32763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						numLevels		= computeMipPyramidLevels(m_size);
32783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ConstPixelBufferAccess*	levels[CUBEFACE_LAST];
32793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int face = 0; face < CUBEFACE_LAST; face++)
32813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
32823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_data[face].resize(numLevels);
32833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_access[face].resize(numLevels);
32843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		levels[face] = &m_access[face][0];
32853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
32863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view = TextureCubeView(numLevels, levels);
32883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32903c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCube::TextureCube (const TextureCube& other)
32913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	(other.m_format)
32923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_size	(other.m_size)
32933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						numLevels		= computeMipPyramidLevels(m_size);
32953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ConstPixelBufferAccess*	levels[CUBEFACE_LAST];
32963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int face = 0; face < CUBEFACE_LAST; face++)
32983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
32993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_data[face].resize(numLevels);
33003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_access[face].resize(numLevels);
33013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		levels[face] = &m_access[face][0];
33023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
33033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view = TextureCubeView(numLevels, levels);
33053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
33073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
33083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int face = 0; face < CUBEFACE_LAST; face++)
33093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
33103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!other.isLevelEmpty((CubeFace)face, levelNdx))
33113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
33123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				allocLevel((CubeFace)face, levelNdx);
33133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				copy(getLevelFace(levelNdx, (CubeFace)face),
33143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 other.getLevelFace(levelNdx, (CubeFace)face));
33153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
33163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
33173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
33183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33203c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCube& TextureCube::operator= (const TextureCube& other)
33213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
33233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
33243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						numLevels		= computeMipPyramidLevels(other.m_size);
33263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ConstPixelBufferAccess*	levels[CUBEFACE_LAST];
33273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int face = 0; face < CUBEFACE_LAST; face++)
33293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
33303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_data[face].resize(numLevels);
33313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_access[face].resize(numLevels);
33323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		levels[face] = &m_access[face][0];
33333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
33343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_format	= other.m_format;
33363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_size		= other.m_size;
33373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view		= TextureCubeView(numLevels, levels);
33383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
33403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
33413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int face = 0; face < CUBEFACE_LAST; face++)
33423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
33433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!isLevelEmpty((CubeFace)face, levelNdx))
33443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				clearLevel((CubeFace)face, levelNdx);
33453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!other.isLevelEmpty((CubeFace)face, levelNdx))
33473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
33483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				allocLevel((CubeFace)face, levelNdx);
33493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				copy(getLevelFace(levelNdx, (CubeFace)face),
33503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 other.getLevelFace(levelNdx, (CubeFace)face));
33513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
33523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
33533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
33543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
33563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33583c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCube::~TextureCube (void)
33593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33623c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCube::allocLevel (tcu::CubeFace face, int levelNdx)
33633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	size		= getMipPyramidLevelSize(m_size, levelNdx);
33653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	dataSize	= m_format.getPixelSize()*size*size;
33663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(isLevelEmpty(face, levelNdx));
33673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_data[face][levelNdx].setStorage(dataSize);
33693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_access[face][levelNdx] = PixelBufferAccess(m_format, size, size, 1, m_data[face][levelNdx].getPtr());
33703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33723c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCube::clearLevel (tcu::CubeFace face, int levelNdx)
33733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!isLevelEmpty(face, levelNdx));
33753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_data[face][levelNdx].clear();
33763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_access[face][levelNdx] = PixelBufferAccess();
33773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture1DArrayView
33803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33813c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1DArrayView::Texture1DArrayView (int numLevels, const ConstPixelBufferAccess* levels)
33823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_numLevels	(numLevels)
33833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_levels		(levels)
33843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33873c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int Texture1DArrayView::selectLayer (float r) const
33883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_numLevels > 0 && m_levels);
33903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return de::clamp(deFloorFloatToInt32(r + 0.5f), 0, m_levels[0].getHeight()-1);
33913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33933c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 Texture1DArrayView::sample (const Sampler& sampler, float s, float t, float lod) const
33943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray1D(m_levels, m_numLevels, sampler, s, selectLayer(t), lod);
33963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33983c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 Texture1DArrayView::sampleOffset (const Sampler& sampler, float s, float t, float lod, deInt32 offset) const
33993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray1DOffset(m_levels, m_numLevels, sampler, s, lod, IVec2(offset, selectLayer(t)));
34013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34033c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat Texture1DArrayView::sampleCompare (const Sampler& sampler, float ref, float s, float t, float lod) const
34043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray1DCompare(m_levels, m_numLevels, sampler, ref, s, lod, IVec2(0, selectLayer(t)));
34063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34083c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat Texture1DArrayView::sampleCompareOffset (const Sampler& sampler, float ref, float s, float t, float lod, deInt32 offset) const
34093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray1DCompare(m_levels, m_numLevels, sampler, ref, s, lod, IVec2(offset, selectLayer(t)));
34113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture2DArrayView
34143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34153c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArrayView::Texture2DArrayView (int numLevels, const ConstPixelBufferAccess* levels)
34163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_numLevels	(numLevels)
34173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_levels		(levels)
34183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34213c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int Texture2DArrayView::selectLayer (float r) const
34223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_numLevels > 0 && m_levels);
34243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return de::clamp(deFloorFloatToInt32(r + 0.5f), 0, m_levels[0].getDepth()-1);
34253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34273c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 Texture2DArrayView::sample (const Sampler& sampler, float s, float t, float r, float lod) const
34283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray2D(m_levels, m_numLevels, sampler, s, t, selectLayer(r), lod);
34303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34323c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat Texture2DArrayView::sampleCompare (const Sampler& sampler, float ref, float s, float t, float r, float lod) const
34333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray2DCompare(m_levels, m_numLevels, sampler, ref, s, t, lod, IVec3(0, 0, selectLayer(r)));
34353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34373c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 Texture2DArrayView::sampleOffset (const Sampler& sampler, float s, float t, float r, float lod, const IVec2& offset) const
34383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray2DOffset(m_levels, m_numLevels, sampler, s, t, lod, IVec3(offset.x(), offset.y(), selectLayer(r)));
34403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34423c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat Texture2DArrayView::sampleCompareOffset (const Sampler& sampler, float ref, float s, float t, float r, float lod, const IVec2& offset) const
34433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray2DCompare(m_levels, m_numLevels, sampler, ref, s, t, lod, IVec3(offset.x(), offset.y(), selectLayer(r)));
34453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34473c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 Texture2DArrayView::gatherOffsets (const Sampler& sampler, float s, float t, float r, int componentNdx, const IVec2 (&offsets)[4]) const
34483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return gatherArray2DOffsets(m_levels[0], sampler, s, t, selectLayer(r), componentNdx, offsets);
34503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34523c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 Texture2DArrayView::gatherOffsetsCompare (const Sampler& sampler, float ref, float s, float t, float r, const IVec2 (&offsets)[4]) const
34533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return gatherArray2DOffsetsCompare(m_levels[0], sampler, ref, s, t, selectLayer(r), offsets);
34553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture1DArray
34583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34593c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1DArray::Texture1DArray (const TextureFormat& format, int width, int numLayers)
34603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(format, computeMipPyramidLevels(width))
34613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(width)
34623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numLayers			(numLayers)
34633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
34643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34673c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1DArray::Texture1DArray (const Texture1DArray& other)
34683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(other)
34693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(other.m_width)
34703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numLayers			(other.m_numLayers)
34713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
34723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34753c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1DArray& Texture1DArray::operator= (const Texture1DArray& other)
34763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
34783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
34793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::operator=(other);
34813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_width		= other.m_width;
34833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_numLayers	= other.m_numLayers;
34843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view		= Texture1DArrayView(getNumLevels(), getLevels());
34853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
34873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34893c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1DArray::~Texture1DArray (void)
34903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34933c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture1DArray::allocLevel (int levelNdx)
34943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels()));
34963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int width = getMipPyramidLevelSize(m_width, levelNdx);
34983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::allocLevel(levelNdx, width, m_numLayers, 1);
35003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture2DArray
35033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35043c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArray::Texture2DArray (const TextureFormat& format, int width, int height, int numLayers)
35053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(format, computeMipPyramidLevels(width, height))
35063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(width)
35073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height				(height)
35083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numLayers			(numLayers)
35093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
35103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35133c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArray::Texture2DArray (const Texture2DArray& other)
35143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(other)
35153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(other.m_width)
35163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height				(other.m_height)
35173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numLayers			(other.m_numLayers)
35183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
35193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35223c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArray& Texture2DArray::operator= (const Texture2DArray& other)
35233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
35253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
35263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::operator=(other);
35283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_width		= other.m_width;
35303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_height	= other.m_height;
35313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_numLayers	= other.m_numLayers;
35323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view		= Texture2DArrayView(getNumLevels(), getLevels());
35333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
35353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35373c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArray::~Texture2DArray (void)
35383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2DArray::allocLevel (int levelNdx)
35423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels()));
35443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	width	= getMipPyramidLevelSize(m_width,	levelNdx);
35463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	height	= getMipPyramidLevelSize(m_height,	levelNdx);
35473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::allocLevel(levelNdx, width, height, m_numLayers);
35493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture3DView
35523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35533c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3DView::Texture3DView (int numLevels, const ConstPixelBufferAccess* levels)
35543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_numLevels	(numLevels)
35553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_levels		(levels)
35563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture3D
35603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35613c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3D::Texture3D (const TextureFormat& format, int width, int height, int depth)
35623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(format, computeMipPyramidLevels(width, height, depth))
35633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(width)
35643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height				(height)
35653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_depth				(depth)
35663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
35673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35703c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3D::Texture3D (const Texture3D& other)
35713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(other)
35723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(other.m_width)
35733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height				(other.m_height)
35743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_depth				(other.m_depth)
35753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
35763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35793c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3D& Texture3D::operator= (const Texture3D& other)
35803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
35823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
35833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::operator=(other);
35853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_width		= other.m_width;
35873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_height	= other.m_height;
35883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_depth		= other.m_depth;
35893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view		= Texture3DView(getNumLevels(), getLevels());
35903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
35923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35943c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3D::~Texture3D (void)
35953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35983c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture3D::allocLevel (int levelNdx)
35993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels()));
36013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int width		= getMipPyramidLevelSize(m_width,	levelNdx);
36033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int height	= getMipPyramidLevelSize(m_height,	levelNdx);
36043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int depth		= getMipPyramidLevelSize(m_depth,	levelNdx);
36053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::allocLevel(levelNdx, width, height, depth);
36073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// TextureCubeArrayView
36103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36113c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeArrayView::TextureCubeArrayView (int numLevels, const ConstPixelBufferAccess* levels)
36123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_numLevels	(numLevels)
36133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_levels		(levels)
36143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36178852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryinline int TextureCubeArrayView::selectLayer (float q) const
36183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_numLevels > 0 && m_levels);
36203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT((m_levels[0].getDepth() % 6) == 0);
36213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return de::clamp(deFloorFloatToInt32(q + 0.5f), 0, (m_levels[0].getDepth() / 6)-1);
36233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36253c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Vec4 TextureCubeArrayView::sample (const Sampler& sampler, float s, float t, float r, float q, float lod) const
36263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CubeFaceFloatCoords	coords		= getCubeFaceCoords(Vec3(s, t, r));
36288852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const int					layer		= selectLayer(q);
36298852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const int					faceDepth	= (layer * 6) + getCubeArrayFaceIndex(coords.face);
36303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare == Sampler::COMPAREMODE_NONE);
36323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.seamlessCubeMap)
36348852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		return sampleCubeArraySeamless(m_levels, m_numLevels, layer, coords.face, sampler, coords.s, coords.t, lod);
36353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
36363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sampleLevelArray2D(m_levels, m_numLevels, sampler, coords.s, coords.t, faceDepth, lod);
36373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36393c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat TextureCubeArrayView::sampleCompare (const Sampler& sampler, float ref, float s, float t, float r, float q, float lod) const
36403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CubeFaceFloatCoords	coords		= getCubeFaceCoords(Vec3(s, t, r));
36428852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const int					layer		= selectLayer(q);
36438852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const int					faceDepth	= (layer * 6) + getCubeArrayFaceIndex(coords.face);
36443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare != Sampler::COMPAREMODE_NONE);
36463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.seamlessCubeMap)
36488852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		return sampleCubeArraySeamlessCompare(m_levels, m_numLevels, layer, coords.face, sampler, ref, coords.s, coords.t, lod);
36493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
36503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sampleLevelArray2DCompare(m_levels, m_numLevels, sampler, ref, coords.s, coords.t, lod, IVec3(0, 0, faceDepth));
36513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// TextureCubeArray
36543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36558852c82a1ffa4760985c17cc6875d5d521daf343Jarkko PoyryTextureCubeArray::TextureCubeArray (const TextureFormat& format, int size, int depth)
36563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(format, computeMipPyramidLevels(size))
36573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_size				(size)
36588852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	, m_depth				(depth)
36593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
36603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36618852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	DE_ASSERT(m_depth % 6 == 0);
36623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36643c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeArray::TextureCubeArray (const TextureCubeArray& other)
36653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(other)
36663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_size				(other.m_size)
36678852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	, m_depth				(other.m_depth)
36683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
36693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36708852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	DE_ASSERT(m_depth % 6 == 0);
36713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36733c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeArray& TextureCubeArray::operator= (const TextureCubeArray& other)
36743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
36763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
36773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::operator=(other);
36793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36808852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	m_size	= other.m_size;
36818852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	m_depth	= other.m_depth;
36828852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	m_view	= TextureCubeArrayView(getNumLevels(), getLevels());
36833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36848852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	DE_ASSERT(m_depth % 6 == 0);
36853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
36873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36893c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeArray::~TextureCubeArray (void)
36903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36933c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCubeArray::allocLevel (int levelNdx)
36943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels()));
36963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int size = getMipPyramidLevelSize(m_size, levelNdx);
36983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36998852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	TextureLevelPyramid::allocLevel(levelNdx, size, size, m_depth);
37003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
37013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37023c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& str, TextureFormat::ChannelOrder order)
37033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3704ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	const char* const orderStrings[] =
3705ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	{
3706ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"R",
3707ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"A",
3708ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"I",
3709ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"L",
3710ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"LA",
3711ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"RG",
3712ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"RA",
3713ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"RGB",
3714ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"RGBA",
3715ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"ARGB",
3716725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"BGR",
3717ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"BGRA",
3718ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi
371916d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		"sR",
372016d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		"sRG",
3721ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"sRGB",
3722ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"sRGBA",
3723725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"sBGR",
3724725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"sBGRA",
3725ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi
3726ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"D",
3727ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"S",
3728ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"DS"
3729ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	};
3730ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi
3731ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	return str << de::getSizedArrayElement<TextureFormat::CHANNELORDER_LAST>(orderStrings, order);
37323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
37333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37343c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& str, TextureFormat::ChannelType type)
37353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3736ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	const char* const typeStrings[] =
3737ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	{
3738ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"SNORM_INT8",
3739ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"SNORM_INT16",
3740ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"SNORM_INT32",
3741ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_INT8",
3742ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_INT16",
374307104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry		"UNORM_INT24",
3744ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_INT32",
3745725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"UNORM_BYTE_44",
3746ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_SHORT_565",
3747ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_SHORT_555",
3748ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_SHORT_4444",
3749ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_SHORT_5551",
3750ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_INT_101010",
3751725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"SNORM_INT_1010102_REV",
3752ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_INT_1010102_REV",
3753725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"UNSIGNED_BYTE_44",
3754725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"UNSIGNED_SHORT_565",
3755725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"UNSIGNED_SHORT_4444",
3756725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"UNSIGNED_SHORT_5551",
3757725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"SIGNED_INT_1010102_REV",
3758ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT_1010102_REV",
3759ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT_11F_11F_10F_REV",
3760ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT_999_E5_REV",
3761725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"UNSIGNED_INT_16_8_8",
3762ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT_24_8",
3763725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"UNSIGNED_INT_24_8_REV",
3764ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"SIGNED_INT8",
3765ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"SIGNED_INT16",
3766ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"SIGNED_INT32",
3767ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT8",
3768ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT16",
3769db6ba452c1213fd1c2b03369fdf4c1d23f07cfadJarkko Pöyry		"UNSIGNED_INT24",
3770ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT32",
3771ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"HALF_FLOAT",
3772ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"FLOAT",
3773725691d12fb107f6ba64aa8ab5aafa0a1cea2847Pyry Haulos		"FLOAT64",
3774ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"FLOAT_UNSIGNED_INT_24_8_REV"
3775ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	};
3776ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi
3777ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	return str << de::getSizedArrayElement<TextureFormat::CHANNELTYPE_LAST>(typeStrings, type);
37783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
37793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37803c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& str, CubeFace face)
37813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
37823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (face)
37833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
37843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_X:	return str << "CUBEFACE_NEGATIVE_X";
37853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_X:	return str << "CUBEFACE_POSITIVE_X";
37863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_Y:	return str << "CUBEFACE_NEGATIVE_Y";
37873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_Y:	return str << "CUBEFACE_POSITIVE_Y";
37883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_Z:	return str << "CUBEFACE_NEGATIVE_Z";
37893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_Z:	return str << "CUBEFACE_POSITIVE_Z";
37903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_LAST:			return str << "CUBEFACE_LAST";
37913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:					return str << "UNKNOWN(" << (int)face << ")";
37923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
37933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
37943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37953c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& str, TextureFormat format)
37963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
37973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return str << format.order << ", " << format.type << "";
37983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
37993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38003c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& str, const ConstPixelBufferAccess& access)
38013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
38023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return str << "format = (" << access.getFormat() << "), size = "
38033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			   << access.getWidth() << " x " << access.getHeight() << " x " << access.getDepth()
38043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			   << ", pitch = " << access.getRowPitch() << " / " << access.getSlicePitch();
38053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
38063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // tcu
3808