tcuTexture.cpp revision 222c1cfbf44db3a0bd251ef230e55c3602e518cc
13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program Tester Core
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * ----------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Reference Texture Implementation.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTexture.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deInt32.h"
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deFloat16.h"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMath.h"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMemory.h"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuSurface.hpp"
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuFloat.hpp"
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTextureUtil.hpp"
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp"
34d6148171f88da1301f053e2e0236afc69416137cJarkko Pöyry#include "deArrayUtil.hpp"
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <limits>
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace tcu
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \note No denorm support, no sign.
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef Float<deUint32, 5, 6, 15, 0>	Float11;
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef Float<deUint32, 5, 5, 15, 0>	Float10;
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Optimized getters for common formats.
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \todo [2012-11-14 pyry] Use intrinsics if available.
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline Vec4		readRGBA8888Float	(const deUint8* ptr) { return Vec4(ptr[0]/255.0f, ptr[1]/255.0f, ptr[2]/255.0f, ptr[3]/255.0f); }
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline Vec4		readRGB888Float		(const deUint8* ptr) { return Vec4(ptr[0]/255.0f, ptr[1]/255.0f, ptr[2]/255.0f, 1.0f); }
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline IVec4	readRGBA8888Int		(const deUint8* ptr) { return IVec4(ptr[0], ptr[1], ptr[2], ptr[3]); }
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline IVec4	readRGB888Int		(const deUint8* ptr) { return IVec4(ptr[0], ptr[1], ptr[2], 0xff); }
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Optimized setters.
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline void writeRGBA8888Int (deUint8* ptr, const IVec4& val)
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ptr[0] = de::clamp(val[0], 0, 255);
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ptr[1] = de::clamp(val[1], 0, 255);
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ptr[2] = de::clamp(val[2], 0, 255);
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ptr[3] = de::clamp(val[3], 0, 255);
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline void writeRGB888Int (deUint8* ptr, const IVec4& val)
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ptr[0] = de::clamp(val[0], 0, 255);
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ptr[1] = de::clamp(val[1], 0, 255);
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ptr[2] = 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
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \todo [2011-09-21 pyry] Move to tcutil?
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline T convertSatRte (float f)
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note Doesn't work for 64-bit types
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_STATIC_ASSERT(sizeof(T) < sizeof(deUint64));
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_STATIC_ASSERT((-3 % 2 != 0) && (-4 % 2 == 0));
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deInt64	minVal	= std::numeric_limits<T>::min();
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deInt64 maxVal	= std::numeric_limits<T>::max();
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float	q		= deFloatFrac(f);
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deInt64 intVal	= (deInt64)(f-q);
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Rounding.
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (q == 0.5f)
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (intVal % 2 != 0)
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			intVal++;
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (q > 0.5f)
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		intVal++;
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// else Don't add anything
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Saturate.
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	intVal = de::max(minVal, de::min(maxVal, intVal));
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (T)intVal;
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14307104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyryinline deUint32 convertSatRteUint24 (float f)
14407104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry{
14507104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	const deUint32 rounded		= convertSatRte<deUint32>(f);
14607104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	const deUint32 maxUint24	= 0xFFFFFFu;
14707104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	return de::min(rounded, maxUint24);
14807104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry}
14907104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint getChannelSize (TextureFormat::ChannelType type)
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15207104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	// make sure this table is updated if format table is updated
153db6ba452c1213fd1c2b03369fdf4c1d23f07cfadJarkko Pöyry	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 27);
15407104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (type)
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT8:			return 1;
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT16:		return 2;
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT32:		return 4;
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT8:			return 1;
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT16:		return 2;
16207104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry		case TextureFormat::UNORM_INT24:		return 3;
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT32:		return 4;
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT8:		return 1;
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT16:		return 2;
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT32:		return 4;
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT8:		return 1;
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT16:		return 2;
169db6ba452c1213fd1c2b03369fdf4c1d23f07cfadJarkko Pöyry		case TextureFormat::UNSIGNED_INT24:		return 3;
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT32:		return 4;
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::HALF_FLOAT:			return 2;
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT:				return 4;
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0;
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint getNumUsedChannels (TextureFormat::ChannelOrder order)
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18107104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	// make sure this table is updated if type table is updated
18216d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry	DE_STATIC_ASSERT(TextureFormat::CHANNELORDER_LAST == 18);
18307104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (order)
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::R:			return 1;
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::A:			return 1;
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::I:			return 1;
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::L:			return 1;
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::LA:			return 2;
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::RG:			return 2;
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::RA:			return 2;
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::RGB:		return 3;
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::RGBA:		return 4;
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::ARGB:		return 4;
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::BGRA:		return 4;
19716d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		case TextureFormat::sR:			return 1;
19816d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		case TextureFormat::sRG:		return 2;
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::sRGB:		return 3;
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::sRGBA:		return 4;
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::D:			return 1;
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::S:			return 1;
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::DS:			return 2;
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0;
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline float channelToFloat (const deUint8* value, TextureFormat::ChannelType type)
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
21207104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	// make sure this table is updated if format table is updated
213db6ba452c1213fd1c2b03369fdf4c1d23f07cfadJarkko Pöyry	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 27);
21407104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (type)
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT8:			return de::max(-1.0f, (float)*((const deInt8*)value) / 127.0f);
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT16:		return de::max(-1.0f, (float)*((const deInt16*)value) / 32767.0f);
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT32:		return de::max(-1.0f, (float)*((const deInt32*)value) / 2147483647.0f);
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT8:			return (float)*((const deUint8*)value) / 255.0f;
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT16:		return (float)*((const deUint16*)value) / 65535.0f;
22207104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry		case TextureFormat::UNORM_INT24:		return (float)readUint24(value) / 16777215.0f;
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT32:		return (float)*((const deUint32*)value) / 4294967295.0f;
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT8:		return (float)*((const deInt8*)value);
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT16:		return (float)*((const deInt16*)value);
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT32:		return (float)*((const deInt32*)value);
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT8:		return (float)*((const deUint8*)value);
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT16:		return (float)*((const deUint16*)value);
229db6ba452c1213fd1c2b03369fdf4c1d23f07cfadJarkko Pöyry		case TextureFormat::UNSIGNED_INT24:		return (float)readUint24(value);
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT32:		return (float)*((const deUint32*)value);
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::HALF_FLOAT:			return deFloat16To32(*(const deFloat16*)value);
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT:				return *((const float*)value);
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int channelToInt (const deUint8* value, TextureFormat::ChannelType type)
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24107104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	// make sure this table is updated if format table is updated
242db6ba452c1213fd1c2b03369fdf4c1d23f07cfadJarkko Pöyry	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 27);
24307104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (type)
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT8:			return (int)*((const deInt8*)value);
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT16:		return (int)*((const deInt16*)value);
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT32:		return (int)*((const deInt32*)value);
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT8:			return (int)*((const deUint8*)value);
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT16:		return (int)*((const deUint16*)value);
25107104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry		case TextureFormat::UNORM_INT24:		return (int)readUint24(value);
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT32:		return (int)*((const deUint32*)value);
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT8:		return (int)*((const deInt8*)value);
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT16:		return (int)*((const deInt16*)value);
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT32:		return (int)*((const deInt32*)value);
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT8:		return (int)*((const deUint8*)value);
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT16:		return (int)*((const deUint16*)value);
258db6ba452c1213fd1c2b03369fdf4c1d23f07cfadJarkko Pöyry		case TextureFormat::UNSIGNED_INT24:		return (int)readUint24(value);
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT32:		return (int)*((const deUint32*)value);
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::HALF_FLOAT:			return (int)deFloat16To32(*(const deFloat16*)value);
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT:				return (int)*((const float*)value);
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0;
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid floatToChannel (deUint8* dst, float src, TextureFormat::ChannelType type)
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27007104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	// make sure this table is updated if format table is updated
271db6ba452c1213fd1c2b03369fdf4c1d23f07cfadJarkko Pöyry	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 27);
27207104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (type)
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT8:			*((deInt8*)dst)			= convertSatRte<deInt8>		(src * 127.0f);			break;
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT16:		*((deInt16*)dst)		= convertSatRte<deInt16>	(src * 32767.0f);		break;
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT32:		*((deInt32*)dst)		= convertSatRte<deInt32>	(src * 2147483647.0f);	break;
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT8:			*((deUint8*)dst)		= convertSatRte<deUint8>	(src * 255.0f);			break;
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT16:		*((deUint16*)dst)		= convertSatRte<deUint16>	(src * 65535.0f);		break;
280db6ba452c1213fd1c2b03369fdf4c1d23f07cfadJarkko Pöyry		case TextureFormat::UNORM_INT24:		writeUint24(dst,		  convertSatRteUint24		(src * 16777215.0f));	break;
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT32:		*((deUint32*)dst)		= convertSatRte<deUint32>	(src * 4294967295.0f);	break;
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT8:		*((deInt8*)dst)			= convertSatRte<deInt8>		(src);					break;
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT16:		*((deInt16*)dst)		= convertSatRte<deInt16>	(src);					break;
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT32:		*((deInt32*)dst)		= convertSatRte<deInt32>	(src);					break;
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT8:		*((deUint8*)dst)		= convertSatRte<deUint8>	(src);					break;
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT16:		*((deUint16*)dst)		= convertSatRte<deUint16>	(src);					break;
287db6ba452c1213fd1c2b03369fdf4c1d23f07cfadJarkko Pöyry		case TextureFormat::UNSIGNED_INT24:		writeUint24(dst,		  convertSatRteUint24		(src));					break;
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT32:		*((deUint32*)dst)		= convertSatRte<deUint32>	(src);					break;
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::HALF_FLOAT:			*((deFloat16*)dst)		= deFloat32To16				(src);					break;
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT:				*((float*)dst)			= src;												break;
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, typename S>
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline T convertSat (S src)
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	S min = (S)std::numeric_limits<T>::min();
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	S max = (S)std::numeric_limits<T>::max();
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (src < min)
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return (T)min;
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (src > max)
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return (T)max;
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return (T)src;
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31007104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyrytemplate <typename S>
31107104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyrystatic inline deUint32 convertSatUint24 (S src)
31207104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry{
31307104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	S min = (S)0u;
31407104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	S max = (S)0xFFFFFFu;
31507104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
31607104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	if (src < min)
31707104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry		return (deUint32)min;
31807104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	else if (src > max)
31907104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry		return (deUint32)max;
32007104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	else
32107104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry		return (deUint32)src;
32207104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry}
32307104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid intToChannel (deUint8* dst, int src, TextureFormat::ChannelType type)
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32607104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	// make sure this table is updated if format table is updated
327db6ba452c1213fd1c2b03369fdf4c1d23f07cfadJarkko Pöyry	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 27);
32807104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (type)
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT8:			*((deInt8*)dst)			= convertSat<deInt8>	(src);				break;
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT16:		*((deInt16*)dst)		= convertSat<deInt16>	(src);				break;
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT8:			*((deUint8*)dst)		= convertSat<deUint8>	(src);				break;
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT16:		*((deUint16*)dst)		= convertSat<deUint16>	(src);				break;
335db6ba452c1213fd1c2b03369fdf4c1d23f07cfadJarkko Pöyry		case TextureFormat::UNORM_INT24:		writeUint24(dst,		  convertSatUint24		(src));				break;
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT8:		*((deInt8*)dst)			= convertSat<deInt8>	(src);				break;
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT16:		*((deInt16*)dst)		= convertSat<deInt16>	(src);				break;
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT32:		*((deInt32*)dst)		= convertSat<deInt32>	(src);				break;
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT8:		*((deUint8*)dst)		= convertSat<deUint8>	((deUint32)src);	break;
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT16:		*((deUint16*)dst)		= convertSat<deUint16>	((deUint32)src);	break;
341db6ba452c1213fd1c2b03369fdf4c1d23f07cfadJarkko Pöyry		case TextureFormat::UNSIGNED_INT24:		writeUint24(dst,		  convertSatUint24		((deUint32)src));	break;
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT32:		*((deUint32*)dst)		= convertSat<deUint32>	((deUint32)src);	break;
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::HALF_FLOAT:			*((deFloat16*)dst)		= deFloat32To16((float)src);				break;
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT:				*((float*)dst)			= (float)src;								break;
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline float channelToNormFloat (deUint32 src, int bits)
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 maxVal = (1u << bits) - 1;
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (float)src / (float)maxVal;
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline deUint32 normFloatToChannel (float src, int bits)
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 maxVal = (1u << bits) - 1;
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 intVal = convertSatRte<deUint32>(src * (float)maxVal);
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return de::min(maxVal, intVal);
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline deUint32 uintToChannel (deUint32 src, int bits)
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 maxVal = (1u << bits) - 1;
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return de::min(maxVal, src);
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Vec4 unpackRGB999E5 (deUint32 color)
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	mBits	= 9;
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	eBias	= 15;
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32	exp		= color >> 27;
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32	bs		= (color >> 18) & ((1<<9)-1);
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32	gs		= (color >> 9) & ((1<<9)-1);
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32	rs		= color & ((1<<9)-1);
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		e		= deFloatPow(2.0f, (float)((int)exp - eBias - mBits));
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		r		= (float)rs * e;
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		g		= (float)gs * e;
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		b		= (float)bs * e;
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return tcu::Vec4(r, g, b, 1.0f);
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3896d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyryconst TextureSwizzle& getChannelReadSwizzle (TextureFormat::ChannelOrder order)
3906d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry{
3916d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	// make sure to update these tables when channel orders are updated
39216d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry	DE_STATIC_ASSERT(TextureFormat::CHANNELORDER_LAST == 18);
3936d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
3946d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle INV		= {{ TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ONE	}};
3956d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle R		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ONE	}};
3966d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle A		= {{ TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_0	}};
3976d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle I		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0	}};
3986d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle L		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ONE	}};
3996d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle LA		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1	}};
4006d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RG		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ONE	}};
4016d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RA		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_1	}};
4026d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RGB		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_ONE	}};
4036d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RGBA	= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_3	}};
4046d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle BGRA	= {{ TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_3	}};
4056d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle ARGB	= {{ TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_3,		TextureSwizzle::CHANNEL_0	}};
4066d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle D		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ONE	}};
40709037a4653649d707449463dfe9817a78ccf7d2fJarkko Pöyry	static const TextureSwizzle S		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ONE	}};
4086d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle DS		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_1	}};
4096d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
4106d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	switch (order)
4116d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	{
4126d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::R:			return R;
4136d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::A:			return A;
4146d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::I:			return I;
4156d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::L:			return L;
4166d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::LA:			return LA;
4176d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RG:			return RG;
4186d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RA:			return RA;
4196d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RGB:		return RGB;
4206d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RGBA:		return RGBA;
4216d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::ARGB:		return ARGB;
4226d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::BGRA:		return BGRA;
42316d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		case TextureFormat::sR:			return R;
42416d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		case TextureFormat::sRG:		return RG;
4256d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::sRGB:		return RGB;
4266d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::sRGBA:		return RGBA;
4276d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::D:			return D;
4286d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::S:			return S;
4296d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::DS:			return DS;
4306d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		default:
4316d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			DE_ASSERT(DE_FALSE);
4326d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			return INV;
4336d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	}
4346d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry}
4356d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
4366d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyryconst TextureSwizzle& getChannelWriteSwizzle (TextureFormat::ChannelOrder order)
4376d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry{
4386d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	// make sure to update these tables when channel orders are updated
43916d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry	DE_STATIC_ASSERT(TextureFormat::CHANNELORDER_LAST == 18);
4406d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
4416d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle INV		= {{ TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
4426d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle R		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
4436d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle A		= {{ TextureSwizzle::CHANNEL_3,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
4446d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle I		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
4456d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle L		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
4466d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle LA		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_3,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
4476d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RG		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
4486d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RA		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_3,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
4496d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RGB		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_LAST	}};
4506d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RGBA	= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_3		}};
4516d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle BGRA	= {{ TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_3		}};
4526d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle ARGB	= {{ TextureSwizzle::CHANNEL_3,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_2		}};
4536d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle D		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
45409037a4653649d707449463dfe9817a78ccf7d2fJarkko Pöyry	static const TextureSwizzle S		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
4556d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle DS		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_3,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
4566d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
4576d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	switch (order)
4586d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	{
4596d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::R:			return R;
4606d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::A:			return A;
4616d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::I:			return I;
4626d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::L:			return L;
4636d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::LA:			return LA;
4646d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RG:			return RG;
4656d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RA:			return RA;
4666d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RGB:		return RGB;
4676d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RGBA:		return RGBA;
4686d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::ARGB:		return ARGB;
4696d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::BGRA:		return BGRA;
47016d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		case TextureFormat::sR:			return R;
47116d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		case TextureFormat::sRG:		return RG;
4726d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::sRGB:		return RGB;
4736d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::sRGBA:		return RGBA;
4746d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::D:			return D;
4756d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::S:			return S;
4766d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::DS:			return DS;
4776d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		default:
4786d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			DE_ASSERT(DE_FALSE);
4796d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			return INV;
4806d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	}
4816d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry}
4826d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
48329340067e919854db7d50bb8c0b666117b229f5eMika IsojärviIVec3 calculatePackedPitch (const TextureFormat& format, const IVec3& size)
48429340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi{
48529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	const int pixelSize		= format.getPixelSize();
48629340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	const int rowPitch		= pixelSize * size.x();
48729340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	const int slicePitch	= rowPitch * size.y();
48829340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
48929340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	return IVec3(pixelSize, rowPitch, slicePitch);
49029340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi}
49129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/** Get pixel size in bytes. */
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint TextureFormat::getPixelSize (void) const
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (type == CHANNELTYPE_LAST && order == CHANNELORDER_LAST)
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Invalid/empty format.
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 0;
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (type == UNORM_SHORT_565	||
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 type == UNORM_SHORT_555	||
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 type == UNORM_SHORT_4444	||
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 type == UNORM_SHORT_5551)
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(order == RGB || order == RGBA);
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 2;
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (type == UNORM_INT_101010			||
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 type == UNSIGNED_INT_999_E5_REV	||
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 type == UNSIGNED_INT_11F_11F_10F_REV)
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(order == RGB);
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 4;
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (type == UNORM_INT_1010102_REV		||
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 type == UNSIGNED_INT_1010102_REV)
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(order == RGBA);
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 4;
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (type == UNSIGNED_INT_24_8)
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(order == D || order == DS);
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 4;
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (type == FLOAT_UNSIGNED_INT_24_8_REV)
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(order == DS);
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 8;
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
53207104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry		return getNumUsedChannels(order) * getChannelSize(type);
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5353c827367444ee418f129b2c238299f49d3264554Jarkko PoyryConstPixelBufferAccess::ConstPixelBufferAccess (void)
53629340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	: m_size		(0)
53729340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_pitch		(0)
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_data		(DE_NULL)
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5423c827367444ee418f129b2c238299f49d3264554Jarkko PoyryConstPixelBufferAccess::ConstPixelBufferAccess (const TextureFormat& format, int width, int height, int depth, const void* data)
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format		(format)
54429340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size		(width, height, depth)
54529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_pitch		(calculatePackedPitch(m_format, m_size))
54629340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_data		((void*)data)
54729340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi{
54829340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi}
54929340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
55029340067e919854db7d50bb8c0b666117b229f5eMika IsojärviConstPixelBufferAccess::ConstPixelBufferAccess (const TextureFormat& format, const IVec3& size, const void* data)
55129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	: m_format		(format)
55229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size		(size)
55329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_pitch		(calculatePackedPitch(m_format, m_size))
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_data		((void*)data)
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5583c827367444ee418f129b2c238299f49d3264554Jarkko PoyryConstPixelBufferAccess::ConstPixelBufferAccess (const TextureFormat& format, int width, int height, int depth, int rowPitch, int slicePitch, const void* data)
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format		(format)
56029340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size		(width, height, depth)
56129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_pitch		(format.getPixelSize(), rowPitch, slicePitch)
56229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_data		((void*)data)
56329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi{
56429340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi}
56529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
56629340067e919854db7d50bb8c0b666117b229f5eMika IsojärviConstPixelBufferAccess::ConstPixelBufferAccess (const TextureFormat& format, const IVec3& size, const IVec3& pitch, const void* data)
56729340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	: m_format		(format)
56829340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size		(size)
56929340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_pitch		(pitch)
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_data		((void*)data)
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
57229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(m_format.getPixelSize() <= m_pitch.x());
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5753c827367444ee418f129b2c238299f49d3264554Jarkko PoyryConstPixelBufferAccess::ConstPixelBufferAccess (const TextureLevel& level)
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format		(level.getFormat())
57729340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size		(level.getSize())
57829340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_pitch		(calculatePackedPitch(m_format, m_size))
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_data		((void*)level.getPtr())
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5833c827367444ee418f129b2c238299f49d3264554Jarkko PoyryPixelBufferAccess::PixelBufferAccess (const TextureFormat& format, int width, int height, int depth, void* data)
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: ConstPixelBufferAccess(format, width, height, depth, data)
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
58829340067e919854db7d50bb8c0b666117b229f5eMika IsojärviPixelBufferAccess::PixelBufferAccess (const TextureFormat& format, const IVec3& size, void* data)
58929340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	: ConstPixelBufferAccess(format, size, data)
59029340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi{
59129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi}
59229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
5933c827367444ee418f129b2c238299f49d3264554Jarkko PoyryPixelBufferAccess::PixelBufferAccess (const TextureFormat& format, int width, int height, int depth, int rowPitch, int slicePitch, void* data)
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: ConstPixelBufferAccess(format, width, height, depth, rowPitch, slicePitch, data)
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
59829340067e919854db7d50bb8c0b666117b229f5eMika IsojärviPixelBufferAccess::PixelBufferAccess (const TextureFormat& format, const IVec3& size, const IVec3& pitch, void* data)
59929340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	: ConstPixelBufferAccess(format, size, pitch, data)
60029340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi{
60129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi}
60229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
6033c827367444ee418f129b2c238299f49d3264554Jarkko PoyryPixelBufferAccess::PixelBufferAccess (TextureLevel& level)
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: ConstPixelBufferAccess(level)
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6083c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 ConstPixelBufferAccess::getPixel (int x, int y, int z) const
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
61029340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(x, 0, m_size.x()));
61129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(y, 0, m_size.y()));
61229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(z, 0, m_size.z()));
61329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
61429340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	const deUint8* pixelPtr = (const deUint8*)getDataPtr() + z*m_pitch.z() + y*m_pitch.y() + x*m_pitch.x();
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Optimized fomats.
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_format.type == TextureFormat::UNORM_INT8)
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_format.order == TextureFormat::RGBA)
62029340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi			return readRGBA8888Float(pixelPtr);
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (m_format.order == TextureFormat::RGB)
62229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi			return readRGB888Float(pixelPtr);
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define UB16(OFFS, COUNT)		((*((const deUint16*)pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1))
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define UB32(OFFS, COUNT)		((*((const deUint32*)pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1))
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define NB16(OFFS, COUNT)		channelToNormFloat(UB16(OFFS, COUNT), (COUNT))
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define NB32(OFFS, COUNT)		channelToNormFloat(UB32(OFFS, COUNT), (COUNT))
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Packed formats.
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_SHORT_565:			return Vec4(NB16(11,  5), NB16( 5,  6), NB16( 0,  5), 1.0f);
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_SHORT_555:			return Vec4(NB16(10,  5), NB16( 5,  5), NB16( 0,  5), 1.0f);
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_SHORT_4444:			return Vec4(NB16(12,  4), NB16( 8,  4), NB16( 4,  4), NB16( 0, 4));
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_SHORT_5551:			return Vec4(NB16(11,  5), NB16( 6,  5), NB16( 1,  5), NB16( 0, 1));
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT_101010:			return Vec4(NB32(22, 10), NB32(12, 10), NB32( 2, 10), 1.0f);
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT_1010102_REV:		return Vec4(NB32( 0, 10), NB32(10, 10), NB32(20, 10), NB32(30, 2));
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_1010102_REV:	return UVec4(UB32(0, 10), UB32(10, 10), UB32(20, 10), UB32(30, 2)).cast<float>();
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_999_E5_REV:	return unpackRGB999E5(*((const deUint32*)pixelPtr));
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_24_8:
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (m_format.order)
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// \note Stencil is always ignored.
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TextureFormat::D:	return Vec4(NB32(8, 24), 0.0f, 0.0f, 1.0f);
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TextureFormat::DS:	return Vec4(NB32(8, 24), 0.0f, 0.0f, 1.0f /* (float)UB32(0, 8) */);
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(false);
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_format.order == TextureFormat::DS);
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float	d	= *((const float*)pixelPtr);
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// \note Stencil is ignored.
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//			deUint8	s	= *((const deUint32*)(pixelPtr+4)) & 0xff;
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(d, 0.0f, 0.0f, 1.0f);
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(Float11(UB32(0, 11)).asFloat(), Float11(UB32(11, 11)).asFloat(), Float10(UB32(22, 10)).asFloat(), 1.0f);
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef NB16
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef NB32
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef UB16
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef UB32
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generic path.
6746d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	Vec4							result;
6756d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	const TextureSwizzle::Channel*	channelMap	= getChannelReadSwizzle(m_format.order).components;
6766d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	int								channelSize	= getChannelSize(m_format.type);
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int c = 0; c < 4; c++)
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6806d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		switch (channelMap[c])
6816d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		{
6826d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_0:
6836d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_1:
6846d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_2:
6856d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_3:
6866d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				result[c] = channelToFloat(pixelPtr + channelSize*((int)channelMap[c]), m_format.type);
6876d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				break;
6886d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
6896d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_ZERO:
6906d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				result[c] = 0.0f;
6916d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				break;
6926d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
6936d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_ONE:
6946d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				result[c] = 1.0f;
6956d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				break;
6966d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
6976d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			default:
6986d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				DE_ASSERT(false);
6996d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		}
7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7053c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIVec4 ConstPixelBufferAccess::getPixelInt (int x, int y, int z) const
7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
70729340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(x, 0, m_size.x()));
70829340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(y, 0, m_size.y()));
70929340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(z, 0, m_size.z()));
7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
71107104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	const deUint8* const	pixelPtr = (const deUint8*)getDataPtr() + z*m_pitch.z() + y*m_pitch.y() + x*m_pitch.x();
71207104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	IVec4					result;
7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Optimized fomats.
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_format.type == TextureFormat::UNORM_INT8)
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_format.order == TextureFormat::RGBA)		return readRGBA8888Int(pixelPtr);
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (m_format.order == TextureFormat::RGB)	return readRGB888Int(pixelPtr);
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define U16(OFFS, COUNT)		((*((const deUint16*)pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1))
7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define U32(OFFS, COUNT)		((*((const deUint32*)pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1))
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_SHORT_565:			return UVec4(U16(11,  5), U16( 5,  6), U16( 0,  5), 1).cast<int>();
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_SHORT_555:			return UVec4(U16(10,  5), U16( 5,  5), U16( 0,  5), 1).cast<int>();
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_SHORT_4444:			return UVec4(U16(12,  4), U16( 8,  4), U16( 4,  4), U16( 0, 4)).cast<int>();
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_SHORT_5551:			return UVec4(U16(11,  5), U16( 6,  5), U16( 1,  5), U16( 0, 1)).cast<int>();
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT_101010:			return UVec4(U32(22, 10), U32(12, 10), U32( 2, 10), 1).cast<int>();
7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT_1010102_REV:		return UVec4(U32( 0, 10), U32(10, 10), U32(20, 10), U32(30, 2)).cast<int>();
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_1010102_REV:	return UVec4(U32( 0, 10), U32(10, 10), U32(20, 10), U32(30, 2)).cast<int>();
7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_24_8:
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (m_format.order)
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TextureFormat::D:	return UVec4(U32(8, 24), 0, 0, 1).cast<int>();
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TextureFormat::S:	return UVec4(0, 0, 0, U32(8, 24)).cast<int>();
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TextureFormat::DS:	return UVec4(U32(8, 24), 0, 0, U32(0, 8)).cast<int>();
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(false);
7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_format.order == TextureFormat::DS);
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float	d	= *((const float*)pixelPtr);
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint8	s	= *((const deUint32*)(pixelPtr+4)) & 0xffu;
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// \note Returns bit-representation of depth floating-point value.
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return UVec4(tcu::Float32(d).bits(), 0, 0, s).cast<int>();
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break; // To generic path.
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef U16
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef U32
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generic path.
7616d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	const TextureSwizzle::Channel*	channelMap	= getChannelReadSwizzle(m_format.order).components;
7626d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	int								channelSize	= getChannelSize(m_format.type);
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int c = 0; c < 4; c++)
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7666d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		switch (channelMap[c])
7676d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		{
7686d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_0:
7696d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_1:
7706d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_2:
7716d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_3:
7726d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				result[c] = channelToInt(pixelPtr + channelSize*((int)channelMap[c]), m_format.type);
7736d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				break;
7746d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
7756d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_ZERO:
7766d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				result[c] = 0;
7776d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				break;
7786d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
7796d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_ONE:
7806d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				result[c] = 1;
7816d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				break;
7826d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
7836d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			default:
7846d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				DE_ASSERT(false);
7856d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		}
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<>
7923c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 ConstPixelBufferAccess::getPixelT (int x, int y, int z) const
7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return getPixel(x, y, z);
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<>
7983c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIVec4 ConstPixelBufferAccess::getPixelT (int x, int y, int z) const
7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return getPixelInt(x, y, z);
8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<>
8043c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUVec4 ConstPixelBufferAccess::getPixelT (int x, int y, int z) const
8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return getPixelUint(x, y, z);
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat ConstPixelBufferAccess::getPixDepth (int x, int y, int z) const
8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(x, 0, getWidth()));
8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(y, 0, getHeight()));
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(z, 0, getDepth()));
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
81507104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	const deUint8* const pixelPtr = (const deUint8*)getDataPtr() + z*m_pitch.z() + y*m_pitch.y() + x*m_pitch.x();
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define UB32(OFFS, COUNT) ((*((const deUint32*)pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1))
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define NB32(OFFS, COUNT) channelToNormFloat(UB32(OFFS, COUNT), (COUNT))
8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_format.order == TextureFormat::DS || m_format.order == TextureFormat::D);
8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_24_8:
8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (m_format.order)
8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TextureFormat::D:
8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TextureFormat::DS: // \note Fall-through.
8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return NB32(8, 24);
8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:
8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(false);
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return 0.0f;
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_format.order == TextureFormat::DS);
8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return *((const float*)pixelPtr);
8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_format.order == TextureFormat::D || m_format.order == TextureFormat::DS);
8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return channelToFloat(pixelPtr, m_format.type);
8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef UB32
8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef NB32
8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint ConstPixelBufferAccess::getPixStencil (int x, int y, int z) const
8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(x, 0, getWidth()));
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(y, 0, getHeight()));
8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(z, 0, getDepth()));
8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
85407104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	const deUint8* const pixelPtr = (const deUint8*)getDataPtr() + z*m_pitch.z() + y*m_pitch.y() + x*m_pitch.x();
8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_24_8:
8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (m_format.order)
8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TextureFormat::S:		return (int)(*((const deUint32*)pixelPtr) >> 8);
8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TextureFormat::DS:		return (int)(*((const deUint32*)pixelPtr) & 0xff);
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:
8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(false);
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return 0;
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_format.order == TextureFormat::DS);
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return *((const deUint32*)(pixelPtr+4)) & 0xff;
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_format.order == TextureFormat::S)
8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return channelToInt(pixelPtr, m_format.type);
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(m_format.order == TextureFormat::DS);
8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int stencilChannelIndex = 3;
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return channelToInt(pixelPtr + getChannelSize(m_format.type)*stencilChannelIndex, m_format.type);
8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PixelBufferAccess::setPixel (const Vec4& color, int x, int y, int z) const
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(x, 0, getWidth()));
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(y, 0, getHeight()));
8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(z, 0, getDepth()));
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
89329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	deUint8* const pixelPtr = (deUint8*)getDataPtr() + z*m_pitch.z() + y*m_pitch.y() + x*m_pitch.x();
89429340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Optimized fomats.
8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_format.type == TextureFormat::UNORM_INT8)
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_format.order == TextureFormat::RGBA)
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
90029340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi			writeRGBA8888Float(pixelPtr, color);
9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return;
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (m_format.order == TextureFormat::RGB)
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
90529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi			writeRGB888Float(pixelPtr, color);
9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return;
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define PN(VAL, OFFS, BITS)		(normFloatToChannel((VAL), (BITS)) << (OFFS))
9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define PU(VAL, OFFS, BITS)		(uintToChannel((VAL), (BITS)) << (OFFS))
9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_SHORT_565:		*((deUint16*)pixelPtr) = (deUint16)(PN(color[0], 11, 5) | PN(color[1], 5, 6) | PN(color[2], 0, 5));							break;
9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_SHORT_555:		*((deUint16*)pixelPtr) = (deUint16)(PN(color[0], 10, 5) | PN(color[1], 5, 5) | PN(color[2], 0, 5));							break;
9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_SHORT_4444:		*((deUint16*)pixelPtr) = (deUint16)(PN(color[0], 12, 4) | PN(color[1], 8, 4) | PN(color[2], 4, 4) | PN(color[3], 0, 4));	break;
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_SHORT_5551:		*((deUint16*)pixelPtr) = (deUint16)(PN(color[0], 11, 5) | PN(color[1], 6, 5) | PN(color[2], 1, 5) | PN(color[3], 0, 1));	break;
9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT_101010:		*((deUint32*)pixelPtr) = PN(color[0], 22, 10) | PN(color[1], 12, 10) | PN(color[2], 2, 10);									break;
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT_1010102_REV:	*((deUint32*)pixelPtr) = PN(color[0],  0, 10) | PN(color[1], 10, 10) | PN(color[2], 20, 10) | PN(color[3], 30, 2);			break;
9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_1010102_REV:
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			UVec4 u = color.cast<deUint32>();
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			*((deUint32*)pixelPtr) = PU(u[0], 0, 10) | PU(u[1], 10, 10) |PU(u[2], 20, 10) | PU(u[3], 30, 2);
9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			*((deUint32*)pixelPtr) = Float11(color[0]).bits() | (Float11(color[1]).bits() << 11) | (Float10(color[2]).bits() << 22);
9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_999_E5_REV:
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			*((deUint32*)pixelPtr) = packRGB999E5(color);
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_24_8:
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (m_format.order)
9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TextureFormat::D:		*((deUint32*)pixelPtr) = PN(color[0], 8, 24);									break;
9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TextureFormat::S:		*((deUint32*)pixelPtr) = PN(color[3], 8, 24);									break;
9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TextureFormat::DS:		*((deUint32*)pixelPtr) = PN(color[0], 8, 24) | PU((deUint32)color[3], 0, 8);	break;
9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(false);
9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_format.order == TextureFormat::DS);
9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			*((float*)pixelPtr)			= color[0];
9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			*((deUint32*)(pixelPtr+4))	= PU((deUint32)color[3], 0, 8);
9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT:
9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_format.order == TextureFormat::D)
9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				*((float*)pixelPtr) = color[0];
9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// else fall-through to default case!
9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Generic path.
9656d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			int								numChannels	= getNumUsedChannels(m_format.order);
9666d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			const TextureSwizzle::Channel*	map			= getChannelWriteSwizzle(m_format.order).components;
9676d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			int								channelSize	= getChannelSize(m_format.type);
9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int c = 0; c < numChannels; c++)
9706d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			{
9716d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				DE_ASSERT(deInRange32(map[c], TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3));
9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				floatToChannel(pixelPtr + channelSize*c, color[map[c]], m_format.type);
9736d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			}
9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef PN
9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef PU
9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PixelBufferAccess::setPixel (const IVec4& color, int x, int y, int z) const
9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(x, 0, getWidth()));
9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(y, 0, getHeight()));
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(z, 0, getDepth()));
9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
98807104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	deUint8* const pixelPtr = (deUint8*)getDataPtr() + z*m_pitch.z() + y*m_pitch.y() + x*m_pitch.x();
9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Optimized fomats.
9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_format.type == TextureFormat::UNORM_INT8)
9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_format.order == TextureFormat::RGBA)		{ writeRGBA8888Int(pixelPtr, color);	return; }
9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (m_format.order == TextureFormat::RGB)	{ writeRGB888Int(pixelPtr, color);		return; }
9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define PU(VAL, OFFS, BITS)		(uintToChannel((deUint32)(VAL), (BITS)) << (OFFS))
9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_SHORT_565:			*((deUint16*)pixelPtr) = (deUint16)(PU(color[0], 11, 5) | PU(color[1], 5, 6) | PU(color[2], 0, 5));							break;
10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_SHORT_555:			*((deUint16*)pixelPtr) = (deUint16)(PU(color[0], 10, 5) | PU(color[1], 5, 5) | PU(color[2], 0, 5));							break;
10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_SHORT_4444:			*((deUint16*)pixelPtr) = (deUint16)(PU(color[0], 12, 4) | PU(color[1], 8, 4) | PU(color[2], 4, 4) | PU(color[3], 0, 4));	break;
10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_SHORT_5551:			*((deUint16*)pixelPtr) = (deUint16)(PU(color[0], 11, 5) | PU(color[1], 6, 5) | PU(color[2], 1, 5) | PU(color[3], 0, 1));	break;
10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT_101010:			*((deUint32*)pixelPtr) = PU(color[0], 22, 10) | PU(color[1], 12, 10) | PU(color[2], 2, 10);									break;
10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT_1010102_REV:		*((deUint32*)pixelPtr) = PU(color[0],  0, 10) | PU(color[1], 10, 10) | PU(color[2], 20, 10) | PU(color[3], 30, 2);			break;
10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_1010102_REV:	*((deUint32*)pixelPtr) = PU(color[0],  0, 10) | PU(color[1], 10, 10) | PU(color[2], 20, 10) | PU(color[3], 30, 2);			break;
10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_24_8:
10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (m_format.order)
10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TextureFormat::D:		*((deUint32*)pixelPtr) = PU(color[0], 8, 24);										break;
10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TextureFormat::S:		*((deUint32*)pixelPtr) = PU(color[3], 8, 24);										break;
10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TextureFormat::DS:		*((deUint32*)pixelPtr) = PU(color[0], 8, 24) | PU((deUint32)color[3], 0, 8);		break;
10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:
10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(false);
10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_format.order == TextureFormat::DS);
10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			*((deUint32*)pixelPtr)		= color[0];
10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			*((deUint32*)(pixelPtr+4))	= PU((deUint32)color[3], 0, 8);
10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Generic path.
10296d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			int								numChannels	= getNumUsedChannels(m_format.order);
10306d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			const TextureSwizzle::Channel*	map			= getChannelWriteSwizzle(m_format.order).components;
10316d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			int								channelSize	= getChannelSize(m_format.type);
10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int c = 0; c < numChannels; c++)
10346d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			{
10356d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				DE_ASSERT(deInRange32(map[c], TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3));
10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				intToChannel(pixelPtr + channelSize*c, color[map[c]], m_format.type);
10376d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			}
10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef PU
10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PixelBufferAccess::setPixDepth (float depth, int x, int y, int z) const
10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(x, 0, getWidth()));
10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(y, 0, getHeight()));
10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(z, 0, getDepth()));
10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
105107104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	deUint8* const pixelPtr = (deUint8*)getDataPtr() + z*m_pitch.z() + y*m_pitch.y() + x*m_pitch.x();
10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define PN(VAL, OFFS, BITS) (normFloatToChannel((VAL), (BITS)) << (OFFS))
10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_24_8:
10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (m_format.order)
10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TextureFormat::D:		*((deUint32*)pixelPtr) = PN(depth, 8, 24);											break;
10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TextureFormat::DS:		*((deUint32*)pixelPtr) = (*((deUint32*)pixelPtr) & 0x000000ff) | PN(depth, 8, 24);	break;
10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:
10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(false);
10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_format.order == TextureFormat::DS);
10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			*((float*)pixelPtr) = depth;
10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_format.order == TextureFormat::D || m_format.order == TextureFormat::DS);
10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			floatToChannel(pixelPtr, depth, m_format.type);
10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef PN
10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10813c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PixelBufferAccess::setPixStencil (int stencil, int x, int y, int z) const
10823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(x, 0, getWidth()));
10843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(y, 0, getHeight()));
10853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(z, 0, getDepth()));
10863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
108707104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	deUint8* const pixelPtr = (deUint8*)getDataPtr() + z*m_pitch.z() + y*m_pitch.y() + x*m_pitch.x();
10883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define PU(VAL, OFFS, BITS) (uintToChannel((deUint32)(VAL), (BITS)) << (OFFS))
10903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_24_8:
10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (m_format.order)
10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
10963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TextureFormat::S:		*((deUint32*)pixelPtr) = PU(stencil, 8, 24);										break;
10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TextureFormat::DS:		*((deUint32*)pixelPtr) = (*((deUint32*)pixelPtr) & 0xffffff00) | PU(stencil, 0, 8);	break;
10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:
10993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(false);
11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_format.order == TextureFormat::DS);
11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			*((deUint32*)(pixelPtr+4))	= PU((deUint32)stencil, 0, 8);
11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_format.order == TextureFormat::S)
11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				intToChannel(pixelPtr, stencil, m_format.type);
11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(m_format.order == TextureFormat::DS);
11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int stencilChannelIndex = 3;
11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				intToChannel(pixelPtr + getChannelSize(m_format.type)*stencilChannelIndex, stencil, m_format.type);
11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef PU
11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline int imod (int a, int b)
11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int m = a % b;
11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m < 0 ? m + b : m;
11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline int mirror (int a)
11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return a >= 0.0f ? a : -(1 + a);
11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Nearest-even rounding in case of tie (fractional part 0.5), otherwise ordinary rounding.
11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline float rint (float a)
11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_STATIC_ASSERT((-3 % 2 != 0) && (-4 % 2 == 0));
11393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		fracVal		= deFloatFrac(a);
11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (fracVal != 0.5f)
11433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return deFloatRound(a); // Ordinary case.
11443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float	floorVal	= a - fracVal;
11463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool	roundUp		= (deInt64)floorVal % 2 != 0;
11473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return floorVal + (roundUp ? 1.0f : 0.0f);
11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11513c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline int wrap (Sampler::WrapMode mode, int c, int size)
11523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (mode)
11543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::CLAMP_TO_BORDER:
11563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return deClamp32(c, -1, size);
11573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::CLAMP_TO_EDGE:
11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return deClamp32(c, 0, size-1);
11603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::REPEAT_GL:
11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return imod(c, size);
11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::REPEAT_CL:
11653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return imod(c, size);
11663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::MIRRORED_REPEAT_GL:
11683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return (size - 1) - mirror(imod(c, 2*size) - size);
11693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::MIRRORED_REPEAT_CL:
11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return deClamp32(c, 0, size-1); // \note Actual mirroring done already in unnormalization function.
11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0;
11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Special unnormalization for REPEAT_CL and MIRRORED_REPEAT_CL wrap modes; otherwise ordinary unnormalization.
11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline float unnormalize (Sampler::WrapMode mode, float c, int size)
11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (mode)
11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::CLAMP_TO_EDGE:
11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::CLAMP_TO_BORDER:
11863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::REPEAT_GL:
11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::MIRRORED_REPEAT_GL: // Fall-through (ordinary case).
11883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return (float)size*c;
11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::REPEAT_CL:
11913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return (float)size * (c - deFloatFloor(c));
11923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::MIRRORED_REPEAT_CL:
11943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return (float)size * deFloatAbs(c - 2.0f * rint(0.5f * c));
11953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12023c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isFixedPointDepthTextureFormat (const tcu::TextureFormat& format)
12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (format.order == TextureFormat::D)
12073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// depth internal formats cannot be non-normalized integers
12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return channelClass != tcu::TEXTURECHANNELCLASS_FLOATING_POINT;
12103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (format.order == TextureFormat::DS)
12123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// combined formats have no single channel class, detect format manually
12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		switch (format.type)
12153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:	return false;
12173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case tcu::TextureFormat::UNSIGNED_INT_24_8:				return true;
12183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			default:
12203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
12213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// unknown format
12223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(false);
12233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return true;
12243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
12253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return false;
12293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texel lookup with color conversion.
12323c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline Vec4 lookup (const ConstPixelBufferAccess& access, int i, int j, int k)
12333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 p = access.getPixel(i, j, k);
12353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return isSRGB(access.getFormat()) ? sRGBToLinear(p) : p;
12363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1238222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry// Border texel lookup with color conversion.
123922941823a995126908aae341c87f2def77514ee7Jarkko Pöyrystatic inline Vec4 lookupBorder (const tcu::TextureFormat& format, const tcu::Sampler& sampler)
124022941823a995126908aae341c87f2def77514ee7Jarkko Pöyry{
1241222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	// "lookup" for a combined format does not make sense, disallow
1242222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	DE_ASSERT(!isCombinedDepthStencilType(format.type));
1243222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry
1244222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	const tcu::TextureChannelClass	channelClass 			= tcu::getTextureChannelClass(format.type);
1245222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	const bool						isFloat					= channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT;
1246222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	const bool						isFixed					= channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT ||
1247222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry															  channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT;
1248222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	const bool						isPureInteger			= channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER;
1249222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	const bool						isPureUnsignedInteger	= channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
1250222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry
1251222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	if (isFloat || isFixed)
1252222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	{
1253222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry		const Vec4 p = sampleTextureBorder<float>(format, sampler);
1254222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry		return isSRGB(format) ? sRGBToLinear(p) : p;
1255222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	}
1256222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	else if (isPureInteger)
1257222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry		return sampleTextureBorder<deInt32>(format, sampler).cast<float>();
1258222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	else if (isPureUnsignedInteger)
1259222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry		return sampleTextureBorder<deUint32>(format, sampler).cast<float>();
1260222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	else
1261222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	{
1262222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry		DE_ASSERT(false);
1263222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry		return Vec4(-1.0);
1264222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	}
126522941823a995126908aae341c87f2def77514ee7Jarkko Pöyry}
126622941823a995126908aae341c87f2def77514ee7Jarkko Pöyry
12673c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline float execCompare (const tcu::Vec4& color, Sampler::CompareMode compare, int chanNdx, float ref_, bool isFixedPoint)
12683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool	clampValues	= isFixedPoint;	// if comparing against a floating point texture, ref (and value) is not clamped
12703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	cmp			= (clampValues) ? (de::clamp(color[chanNdx], 0.0f, 1.0f)) : (color[chanNdx]);
12713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	ref			= (clampValues) ? (de::clamp(ref_, 0.0f, 1.0f)) : (ref_);
12723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		res			= false;
12733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (compare)
12753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_LESS:				res = ref < cmp;	break;
12773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_LESS_OR_EQUAL:	res = ref <= cmp;	break;
12783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_GREATER:			res = ref > cmp;	break;
12793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_GREATER_OR_EQUAL:	res = ref >= cmp;	break;
12803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_EQUAL:			res = ref == cmp;	break;
12813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_NOT_EQUAL:		res = ref != cmp;	break;
12823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_ALWAYS:			res = true;			break;
12833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_NEVER:			res = false;		break;
12843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
12853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
12863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return res ? 1.0f : 0.0f;
12893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12913c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleNearest1D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, const IVec2& offset)
12923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int width	= access.getWidth();
12943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x = deFloorFloatToInt32(u)+offset.x();
12963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check for CLAMP_TO_BORDER.
12983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.wrapS == Sampler::CLAMP_TO_BORDER && !deInBounds32(x, 0, width))
129922941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		return lookupBorder(access.getFormat(), sampler);
13003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i = wrap(sampler.wrapS, x, width);
13023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return lookup(access, i, offset.y(), 0);
13043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13063c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleNearest2D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, float v, const IVec3& offset)
13073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int width	= access.getWidth();
13093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int height	= access.getHeight();
13103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x = deFloorFloatToInt32(u)+offset.x();
13123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y = deFloorFloatToInt32(v)+offset.y();
13133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check for CLAMP_TO_BORDER.
13153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if ((sampler.wrapS == Sampler::CLAMP_TO_BORDER && !deInBounds32(x, 0, width)) ||
13163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		(sampler.wrapT == Sampler::CLAMP_TO_BORDER && !deInBounds32(y, 0, height)))
131722941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		return lookupBorder(access.getFormat(), sampler);
13183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i = wrap(sampler.wrapS, x, width);
13203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j = wrap(sampler.wrapT, y, height);
13213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return lookup(access, i, j, offset.z());
13233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13253c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleNearest3D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, float v, float w, const IVec3& offset)
13263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int width	= access.getWidth();
13283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int height	= access.getHeight();
13293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int depth	= access.getDepth();
13303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x = deFloorFloatToInt32(u)+offset.x();
13323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y = deFloorFloatToInt32(v)+offset.y();
13333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int z = deFloorFloatToInt32(w)+offset.z();
13343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check for CLAMP_TO_BORDER.
13363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if ((sampler.wrapS == Sampler::CLAMP_TO_BORDER && !deInBounds32(x, 0, width))	||
13373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		(sampler.wrapT == Sampler::CLAMP_TO_BORDER && !deInBounds32(y, 0, height))	||
13383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		(sampler.wrapR == Sampler::CLAMP_TO_BORDER && !deInBounds32(z, 0, depth)))
133922941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		return lookupBorder(access.getFormat(), sampler);
13403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i = wrap(sampler.wrapS, x, width);
13423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j = wrap(sampler.wrapT, y, height);
13433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int k = wrap(sampler.wrapR, z, depth);
13443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return lookup(access, i, j, k);
13463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13483c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleLinear1D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, const IVec2& offset)
13493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int w = access.getWidth();
13513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x0 = deFloorFloatToInt32(u-0.5f)+offset.x();
13533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x1 = x0+1;
13543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i0 = wrap(sampler.wrapS, x0, w);
13563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i1 = wrap(sampler.wrapS, x1, w);
13573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
13593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i0UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i0, 0, w);
13613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i1UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i1, 0, w);
13623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Border color for out-of-range coordinates if using CLAMP_TO_BORDER, otherwise execute lookups.
136422941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p0 = i0UseBorder ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, offset.y(), 0);
136522941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p1 = i1UseBorder ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, offset.y(), 0);
13663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
13683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return p0 * (1.0f - a) + p1 * a;
13693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13713c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleLinear2D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, float v, const IVec3& offset)
13723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int w = access.getWidth();
13743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int h = access.getHeight();
13753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x0 = deFloorFloatToInt32(u-0.5f)+offset.x();
13773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x1 = x0+1;
13783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y0 = deFloorFloatToInt32(v-0.5f)+offset.y();
13793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y1 = y0+1;
13803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i0 = wrap(sampler.wrapS, x0, w);
13823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i1 = wrap(sampler.wrapS, x1, w);
13833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j0 = wrap(sampler.wrapT, y0, h);
13843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j1 = wrap(sampler.wrapT, y1, h);
13853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
13873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float b = deFloatFrac(v-0.5f);
13883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i0UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i0, 0, w);
13903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i1UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i1, 0, w);
13913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool j0UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j0, 0, h);
13923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool j1UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j1, 0, h);
13933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Border color for out-of-range coordinates if using CLAMP_TO_BORDER, otherwise execute lookups.
139522941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p00 = (i0UseBorder || j0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j0, offset.z());
139622941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p10 = (i1UseBorder || j0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j0, offset.z());
139722941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p01 = (i0UseBorder || j1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j1, offset.z());
139822941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p11 = (i1UseBorder || j1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j1, offset.z());
13993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
14013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (p00*(1.0f-a)*(1.0f-b)) +
14023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p10*(     a)*(1.0f-b)) +
14033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p01*(1.0f-a)*(     b)) +
14043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p11*(     a)*(     b));
14053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14073c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float sampleLinear1DCompare (const ConstPixelBufferAccess& access, const Sampler& sampler, float ref, float u, const IVec2& offset, bool isFixedPointDepthFormat)
14083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int w = access.getWidth();
14103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x0 = deFloorFloatToInt32(u-0.5f)+offset.x();
14123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x1 = x0+1;
14133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i0 = wrap(sampler.wrapS, x0, w);
14153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i1 = wrap(sampler.wrapS, x1, w);
14163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
14183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i0UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i0, 0, w);
14203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i1UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i1, 0, w);
14213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Border color for out-of-range coordinates if using CLAMP_TO_BORDER, otherwise execute lookups.
142322941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p0Clr = i0UseBorder  ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, offset.y(), 0);
142422941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p1Clr = i1UseBorder  ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, offset.y(), 0);
14253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Execute comparisons.
14273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float p0 = execCompare(p0Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat);
14283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float p1 = execCompare(p1Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat);
14293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
14313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (p0 * (1.0f - a)) + (p1 * a);
14323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14343c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float sampleLinear2DCompare (const ConstPixelBufferAccess& access, const Sampler& sampler, float ref, float u, float v, const IVec3& offset, bool isFixedPointDepthFormat)
14353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int w = access.getWidth();
14373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int h = access.getHeight();
14383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x0 = deFloorFloatToInt32(u-0.5f)+offset.x();
14403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x1 = x0+1;
14413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y0 = deFloorFloatToInt32(v-0.5f)+offset.y();
14423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y1 = y0+1;
14433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i0 = wrap(sampler.wrapS, x0, w);
14453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i1 = wrap(sampler.wrapS, x1, w);
14463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j0 = wrap(sampler.wrapT, y0, h);
14473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j1 = wrap(sampler.wrapT, y1, h);
14483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
14503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float b = deFloatFrac(v-0.5f);
14513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i0UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i0, 0, w);
14533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i1UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i1, 0, w);
14543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool j0UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j0, 0, h);
14553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool j1UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j1, 0, h);
14563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Border color for out-of-range coordinates if using CLAMP_TO_BORDER, otherwise execute lookups.
145822941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p00Clr = (i0UseBorder || j0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j0, offset.z());
145922941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p10Clr = (i1UseBorder || j0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j0, offset.z());
146022941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p01Clr = (i0UseBorder || j1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j1, offset.z());
146122941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p11Clr = (i1UseBorder || j1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j1, offset.z());
14623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Execute comparisons.
14643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float p00 = execCompare(p00Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat);
14653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float p10 = execCompare(p10Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat);
14663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float p01 = execCompare(p01Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat);
14673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float p11 = execCompare(p11Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat);
14683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
14703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (p00*(1.0f-a)*(1.0f-b)) +
14713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p10*(     a)*(1.0f-b)) +
14723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p01*(1.0f-a)*(     b)) +
14733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p11*(     a)*(     b));
14743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14763c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleLinear3D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, float v, float w, const IVec3& offset)
14773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int width	= access.getWidth();
14793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int height	= access.getHeight();
14803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int depth	= access.getDepth();
14813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x0 = deFloorFloatToInt32(u-0.5f)+offset.x();
14833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x1 = x0+1;
14843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y0 = deFloorFloatToInt32(v-0.5f)+offset.y();
14853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y1 = y0+1;
14863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int z0 = deFloorFloatToInt32(w-0.5f)+offset.z();
14873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int z1 = z0+1;
14883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i0 = wrap(sampler.wrapS, x0, width);
14903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i1 = wrap(sampler.wrapS, x1, width);
14913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j0 = wrap(sampler.wrapT, y0, height);
14923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j1 = wrap(sampler.wrapT, y1, height);
14933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int k0 = wrap(sampler.wrapR, z0, depth);
14943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int k1 = wrap(sampler.wrapR, z1, depth);
14953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
14973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float b = deFloatFrac(v-0.5f);
14983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float c = deFloatFrac(w-0.5f);
14993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i0UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i0, 0, width);
15013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i1UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i1, 0, width);
15023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool j0UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j0, 0, height);
15033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool j1UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j1, 0, height);
15043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool k0UseBorder = sampler.wrapR == Sampler::CLAMP_TO_BORDER && !de::inBounds(k0, 0, depth);
15053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool k1UseBorder = sampler.wrapR == Sampler::CLAMP_TO_BORDER && !de::inBounds(k1, 0, depth);
15063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Border color for out-of-range coordinates if using CLAMP_TO_BORDER, otherwise execute lookups.
150822941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p000 = (i0UseBorder || j0UseBorder || k0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j0, k0);
150922941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p100 = (i1UseBorder || j0UseBorder || k0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j0, k0);
151022941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p010 = (i0UseBorder || j1UseBorder || k0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j1, k0);
151122941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p110 = (i1UseBorder || j1UseBorder || k0UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j1, k0);
151222941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p001 = (i0UseBorder || j0UseBorder || k1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j0, k1);
151322941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p101 = (i1UseBorder || j0UseBorder || k1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j0, k1);
151422941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p011 = (i0UseBorder || j1UseBorder || k1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i0, j1, k1);
151522941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4 p111 = (i1UseBorder || j1UseBorder || k1UseBorder) ? lookupBorder(access.getFormat(), sampler) : lookup(access, i1, j1, k1);
15163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
15183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (p000*(1.0f-a)*(1.0f-b)*(1.0f-c)) +
15193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p100*(     a)*(1.0f-b)*(1.0f-c)) +
15203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p010*(1.0f-a)*(     b)*(1.0f-c)) +
15213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p110*(     a)*(     b)*(1.0f-c)) +
15223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p001*(1.0f-a)*(1.0f-b)*(     c)) +
15233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p101*(     a)*(1.0f-b)*(     c)) +
15243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p011*(1.0f-a)*(     b)*(     c)) +
15253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p111*(     a)*(     b)*(     c));
15263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15283c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 ConstPixelBufferAccess::sample1D (const Sampler& sampler, Sampler::FilterMode filter, float s, int level) const
15293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1530612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// check selected layer exists
153129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(level, 0, m_size.y()));
15323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1533612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	return sample1DOffset(sampler, filter, s, tcu::IVec2(0, level));
15343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15363c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 ConstPixelBufferAccess::sample2D (const Sampler& sampler, Sampler::FilterMode filter, float s, float t, int depth) const
15373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1538612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// check selected layer exists
153929340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(depth, 0, m_size.z()));
15403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1541612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	return sample2DOffset(sampler, filter, s, t, tcu::IVec3(0, 0, depth));
1542612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry}
15433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1544612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko PöyryVec4 ConstPixelBufferAccess::sample3D (const Sampler& sampler, Sampler::FilterMode filter, float s, float t, float r) const
1545612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry{
1546612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	return sample3DOffset(sampler, filter, s, t, r, tcu::IVec3(0, 0, 0));
15473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15493c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 ConstPixelBufferAccess::sample1DOffset (const Sampler& sampler, Sampler::FilterMode filter, float s, const IVec2& offset) const
15503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1551612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// check selected layer exists
1552612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// \note offset.x is X offset, offset.y is the selected layer
1553612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	DE_ASSERT(de::inBounds(offset.y(), 0, m_size.y()));
15543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
15563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float u = s;
15573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
155929340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		u = unnormalize(sampler.wrapS, s, m_size.x());
15603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filter)
15623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return sampleNearest1D	(*this, sampler, u, offset);
15643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return sampleLinear1D	(*this, sampler, u, offset);
15653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
15663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
15673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
15683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15713c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 ConstPixelBufferAccess::sample2DOffset (const Sampler& sampler, Sampler::FilterMode filter, float s, float t, const IVec3& offset) const
15723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1573612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// check selected layer exists
1574612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// \note offset.xy is the XY offset, offset.z is the selected layer
157529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(offset.z(), 0, m_size.z()));
15763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
15783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float u = s;
15793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float v = t;
15803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
15823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
158329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		u = unnormalize(sampler.wrapS, s, m_size.x());
158429340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		v = unnormalize(sampler.wrapT, t, m_size.y());
15853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filter)
15883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return sampleNearest2D	(*this, sampler, u, v, offset);
15903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return sampleLinear2D	(*this, sampler, u, v, offset);
15913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
15923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
15933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
15943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1597612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko PöyryVec4 ConstPixelBufferAccess::sample3DOffset (const Sampler& sampler, Sampler::FilterMode filter, float s, float t, float r, const IVec3& offset) const
15983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
16003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float u = s;
1601612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	float v = t;
1602612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	float w = r;
16033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
1605612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	{
160629340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		u = unnormalize(sampler.wrapS, s, m_size.x());
1607612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		v = unnormalize(sampler.wrapT, t, m_size.y());
1608612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		w = unnormalize(sampler.wrapR, r, m_size.z());
1609612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	}
16103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filter)
16123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1613612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		case Sampler::NEAREST:	return sampleNearest3D	(*this, sampler, u, v, w, offset);
1614612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		case Sampler::LINEAR:	return sampleLinear3D	(*this, sampler, u, v, w, offset);
16153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
16163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
1617612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry			return Vec4(0.0f);
16183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1621612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyryfloat ConstPixelBufferAccess::sample1DCompare (const Sampler& sampler, Sampler::FilterMode filter, float ref, float s, const IVec2& offset) const
16223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1623612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// check selected layer exists
1624612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// \note offset.x is X offset, offset.y is the selected layer
1625612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	DE_ASSERT(de::inBounds(offset.y(), 0, m_size.y()));
16263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Format information for comparison function
16283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool isFixedPointDepth = isFixedPointDepthTextureFormat(m_format);
16293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
16313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float u = s;
16323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
163429340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		u = unnormalize(sampler.wrapS, s, m_size.x());
16353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filter)
16373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1638612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		case Sampler::NEAREST:	return execCompare(sampleNearest1D(*this, sampler, u, offset), sampler.compare, sampler.compareChannel, ref, isFixedPointDepth);
1639612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		case Sampler::LINEAR:	return sampleLinear1DCompare(*this, sampler, ref, u, offset, isFixedPointDepth);
16403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
16413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
16423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
16433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1646612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyryfloat ConstPixelBufferAccess::sample2DCompare (const Sampler& sampler, Sampler::FilterMode filter, float ref, float s, float t, const IVec3& offset) const
16473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1648612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// check selected layer exists
1649612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// \note offset.xy is XY offset, offset.z is the selected layer
1650612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	DE_ASSERT(de::inBounds(offset.z(), 0, m_size.z()));
16513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1652612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// Format information for comparison function
1653612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	const bool isFixedPointDepth = isFixedPointDepthTextureFormat(m_format);
16543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
16563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float u = s;
16573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float v = t;
16583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
16603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
166129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		u = unnormalize(sampler.wrapS, s, m_size.x());
166229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		v = unnormalize(sampler.wrapT, t, m_size.y());
16633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filter)
16663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1667612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		case Sampler::NEAREST:	return execCompare(sampleNearest2D(*this, sampler, u, v, offset), sampler.compare, sampler.compareChannel, ref, isFixedPointDepth);
1668612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		case Sampler::LINEAR:	return sampleLinear2DCompare(*this, sampler, ref, u, v, offset, isFixedPointDepth);
16693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
16703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
1671612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry			return 0.0f;
16723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16753c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevel::TextureLevel (void)
16763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	()
167729340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size	(0)
16783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16813c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevel::TextureLevel (const TextureFormat& format)
16823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	(format)
168329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size	(0)
16843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16873c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevel::TextureLevel (const TextureFormat& format, int width, int height, int depth)
16883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	(format)
168929340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size	(0)
16903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	setSize(width, height, depth);
16923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16943c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevel::~TextureLevel (void)
16953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16983c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureLevel::setStorage (const TextureFormat& format, int width, int height, int depth)
16993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_format = format;
17013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	setSize(width, height, depth);
17023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17043c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureLevel::setSize (int width, int height, int depth)
17053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int pixelSize = m_format.getPixelSize();
17073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
170829340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	m_size = IVec3(width, height, depth);
17093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
171029340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	m_data.setStorage(m_size.x() * m_size.y() * m_size.z() * pixelSize);
17113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17133c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 sampleLevelArray1D (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, int depth, float lod)
17143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17151d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry	return sampleLevelArray1DOffset(levels, numLevels, sampler, s, lod, IVec2(0, depth)); // y-offset in 1D textures is layer selector
17161d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry}
17173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17181d75d23528999118c1911ed100d1d063b06040daJarkko PöyryVec4 sampleLevelArray2D (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, int depth, float lod)
17191d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry{
17201d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry	return sampleLevelArray2DOffset(levels, numLevels, sampler, s, t, lod, IVec3(0, 0, depth)); // z-offset in 2D textures is layer selector
17211d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry}
17223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17231d75d23528999118c1911ed100d1d063b06040daJarkko PöyryVec4 sampleLevelArray3D (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, float r, float lod)
17241d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry{
17251d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry	return sampleLevelArray3DOffset(levels, numLevels, sampler, s, t, r, lod, IVec3(0, 0, 0));
17263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17283c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 sampleLevelArray1DOffset (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float lod, const IVec2& offset)
17293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
17313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
17323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
17343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return levels[0].sample1DOffset(sampler, filterMode, s, offset);
17363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return levels[0].sample1DOffset(sampler, filterMode, s, offset);
17373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
17393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
17403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
17423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
17433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
17443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return levels[level].sample1DOffset(sampler, levelFilter, s, offset);
17463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
17493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
17503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
17523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
17533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level1		= de::min(maxLevel, level0 + 1);
17543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
17553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				f			= deFloatFrac(lod);
17563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4			t0			= levels[level0].sample1DOffset(sampler, levelFilter, s, offset);
17573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4			t1			= levels[level1].sample1DOffset(sampler, levelFilter, s, offset);
17583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
17603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
17633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
17643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
17653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17683c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 sampleLevelArray2DOffset (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, float lod, const IVec3& offset)
17693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
17713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
17723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
17743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return levels[0].sample2DOffset(sampler, filterMode, s, t, offset);
17763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return levels[0].sample2DOffset(sampler, filterMode, s, t, offset);
17773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
17793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
17803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
17823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
17833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
17843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return levels[level].sample2DOffset(sampler, levelFilter, s, t, offset);
17863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
17893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
17903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
17923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
17933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level1		= de::min(maxLevel, level0 + 1);
17943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
17953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				f			= deFloatFrac(lod);
17963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4			t0			= levels[level0].sample2DOffset(sampler, levelFilter, s, t, offset);
17973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4			t1			= levels[level1].sample2DOffset(sampler, levelFilter, s, t, offset);
17983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
18003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
18013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
18033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
18043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
18053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18083c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 sampleLevelArray3DOffset (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, float r, float lod, const IVec3& offset)
18093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
18113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
18123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
18143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return levels[0].sample3DOffset(sampler, filterMode, s, t, r, offset);
18163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return levels[0].sample3DOffset(sampler, filterMode, s, t, r, offset);
18173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
18193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
18203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
18213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
18223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
18233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
18243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return levels[level].sample3DOffset(sampler, levelFilter, s, t, r, offset);
18263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
18273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
18293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
18303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
18313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
18323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
18333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level1		= de::min(maxLevel, level0 + 1);
18343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
18353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				f			= deFloatFrac(lod);
18363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4			t0			= levels[level0].sample3DOffset(sampler, levelFilter, s, t, r, offset);
18373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4			t1			= levels[level1].sample3DOffset(sampler, levelFilter, s, t, r, offset);
18383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
18403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
18413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
18433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
18443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
18453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat sampleLevelArray1DCompare (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float ref, float s, float lod, const IVec2& offset)
18493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
18513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
18523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
18543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return levels[0].sample1DCompare(sampler, filterMode, ref, s, offset);
18563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return levels[0].sample1DCompare(sampler, filterMode, ref, s, offset);
18573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
18593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
18603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
18613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
18623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
18633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
18643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return levels[level].sample1DCompare(sampler, levelFilter, ref, s, offset);
18663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
18673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
18693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
18703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
18713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
18723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
18733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level1		= de::min(maxLevel, level0 + 1);
18743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
18753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				f			= deFloatFrac(lod);
18763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				t0			= levels[level0].sample1DCompare(sampler, levelFilter, ref, s, offset);
18773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				t1			= levels[level1].sample1DCompare(sampler, levelFilter, ref, s, offset);
18783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
18803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
18813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
18833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
18843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
18853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18883c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat sampleLevelArray2DCompare (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float ref, float s, float t, float lod, const IVec3& offset)
18893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
18913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
18923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
18943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return levels[0].sample2DCompare(sampler, filterMode, ref, s, t, offset);
18963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return levels[0].sample2DCompare(sampler, filterMode, ref, s, t, offset);
18973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
18993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
19003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
19023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
19033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
19043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return levels[level].sample2DCompare(sampler, levelFilter, ref, s, t, offset);
19063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
19073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
19093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
19103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
19123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
19133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level1		= de::min(maxLevel, level0 + 1);
19143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
19153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				f			= deFloatFrac(lod);
19163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				t0			= levels[level0].sample2DCompare(sampler, levelFilter, ref, s, t, offset);
19173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				t1			= levels[level1].sample2DCompare(sampler, levelFilter, ref, s, t, offset);
19183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
19203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
19213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
19233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
19243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
19253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
192822941823a995126908aae341c87f2def77514ee7Jarkko Pöyrystatic Vec4 fetchGatherArray2DOffsets (const ConstPixelBufferAccess& src, const Sampler& sampler, float s, float t, int depth, int componentNdx, const IVec2 (&offsets)[4])
19293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(componentNdx, 0, 4));
19313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		w	= src.getWidth();
19333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		h	= src.getHeight();
19343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float		u	= unnormalize(sampler.wrapS, s, w);
19353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float		v	= unnormalize(sampler.wrapT, t, h);
19363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		x0	= deFloorFloatToInt32(u-0.5f);
19373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		y0	= deFloorFloatToInt32(v-0.5f);
19383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
193922941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	Vec4			result;
19403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
19423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
194322941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		const int	sampleX	= wrap(sampler.wrapS, x0 + offsets[i].x(), w);
194422941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		const int	sampleY	= wrap(sampler.wrapT, y0 + offsets[i].y(), h);
194522941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		Vec4		pixel;
194622941823a995126908aae341c87f2def77514ee7Jarkko Pöyry
194722941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		if (deInBounds32(sampleX, 0, w) && deInBounds32(sampleY, 0, h))
194822941823a995126908aae341c87f2def77514ee7Jarkko Pöyry			pixel = lookup(src, sampleX, sampleY, depth);
194922941823a995126908aae341c87f2def77514ee7Jarkko Pöyry		else
195022941823a995126908aae341c87f2def77514ee7Jarkko Pöyry			pixel = lookupBorder(src.getFormat(), sampler);
195122941823a995126908aae341c87f2def77514ee7Jarkko Pöyry
19523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result[i] = pixel[componentNdx];
19533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
19563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
195822941823a995126908aae341c87f2def77514ee7Jarkko PöyryVec4 gatherArray2DOffsets (const ConstPixelBufferAccess& src, const Sampler& sampler, float s, float t, int depth, int componentNdx, const IVec2 (&offsets)[4])
195922941823a995126908aae341c87f2def77514ee7Jarkko Pöyry{
196022941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	DE_ASSERT(sampler.compare == Sampler::COMPAREMODE_NONE);
196122941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	DE_ASSERT(de::inBounds(componentNdx, 0, 4));
196222941823a995126908aae341c87f2def77514ee7Jarkko Pöyry
196322941823a995126908aae341c87f2def77514ee7Jarkko Pöyry	return fetchGatherArray2DOffsets(src, sampler, s, t, depth, componentNdx, offsets);
196422941823a995126908aae341c87f2def77514ee7Jarkko Pöyry}
196522941823a995126908aae341c87f2def77514ee7Jarkko Pöyry
19663c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 gatherArray2DOffsetsCompare (const ConstPixelBufferAccess& src, const Sampler& sampler, float ref, float s, float t, int depth, const IVec2 (&offsets)[4])
19673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare != Sampler::COMPAREMODE_NONE);
19693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(src.getFormat().order == TextureFormat::D || src.getFormat().order == TextureFormat::DS);
19703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compareChannel == 0);
19713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1972222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	const bool	isFixedPoint	= isFixedPointDepthTextureFormat(src.getFormat());
1973222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	const Vec4	gathered		= fetchGatherArray2DOffsets(src, sampler, s, t, depth, 0 /* component 0: depth */, offsets);
1974222c1cfbf44db3a0bd251ef230e55c3602e518ccJarkko Pöyry	Vec4		result;
19753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
19773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result[i] = execCompare(gathered, sampler.compare, i, ref, isFixedPoint);
19783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
19803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19823c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleCubeSeamlessNearest (const ConstPixelBufferAccess& faceAccess, const Sampler& sampler, float s, float t, int depth)
19833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler clampingSampler = sampler;
19853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	clampingSampler.wrapS = Sampler::CLAMP_TO_EDGE;
19863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	clampingSampler.wrapT = Sampler::CLAMP_TO_EDGE;
19873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return faceAccess.sample2D(clampingSampler, Sampler::NEAREST, s, t, depth);
19883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19903c827367444ee418f129b2c238299f49d3264554Jarkko PoyryCubeFace selectCubeFace (const Vec3& coords)
19913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	x	= coords.x();
19933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	y	= coords.y();
19943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	z	= coords.z();
19953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	ax	= deFloatAbs(x);
19963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	ay	= deFloatAbs(y);
19973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	az	= deFloatAbs(z);
19983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (ay < ax && az < ax)
20003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return x >= 0.0f ? CUBEFACE_POSITIVE_X : CUBEFACE_NEGATIVE_X;
20013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (ax < ay && az < ay)
20023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return y >= 0.0f ? CUBEFACE_POSITIVE_Y : CUBEFACE_NEGATIVE_Y;
20033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (ax < az && ay < az)
20043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return z >= 0.0f ? CUBEFACE_POSITIVE_Z : CUBEFACE_NEGATIVE_Z;
20053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
20063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Some of the components are equal. Use tie-breaking rule.
20083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (ax == ay)
20093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
20103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (ax < az)
20113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return z >= 0.0f ? CUBEFACE_POSITIVE_Z : CUBEFACE_NEGATIVE_Z;
20123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
20133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return x >= 0.0f ? CUBEFACE_POSITIVE_X : CUBEFACE_NEGATIVE_X;
20143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
20153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (ax == az)
20163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
20173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (az < ay)
20183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return y >= 0.0f ? CUBEFACE_POSITIVE_Y : CUBEFACE_NEGATIVE_Y;
20193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
20203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return z >= 0.0f ? CUBEFACE_POSITIVE_Z : CUBEFACE_NEGATIVE_Z;
20213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
20223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (ay == az)
20233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
20243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (ay < ax)
20253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return x >= 0.0f ? CUBEFACE_POSITIVE_X : CUBEFACE_NEGATIVE_X;
20263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
20273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return y >= 0.0f ? CUBEFACE_POSITIVE_Y : CUBEFACE_NEGATIVE_Y;
20283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
20293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
20303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return x >= 0.0f ? CUBEFACE_POSITIVE_X : CUBEFACE_NEGATIVE_X;
20313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20343c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec2 projectToFace (CubeFace face, const Vec3& coord)
20353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	rx		= coord.x();
20373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	ry		= coord.y();
20383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	rz		= coord.z();
20393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		sc		= 0.0f;
20403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		tc		= 0.0f;
20413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		ma		= 0.0f;
20423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		s;
20433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		t;
20443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (face)
20463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_X: sc = +rz; tc = -ry; ma = -rx; break;
20483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_X: sc = -rz; tc = -ry; ma = +rx; break;
20493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_Y: sc = +rx; tc = -rz; ma = -ry; break;
20503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_Y: sc = +rx; tc = +rz; ma = +ry; break;
20513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_Z: sc = -rx; tc = -ry; ma = -rz; break;
20523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_Z: sc = +rx; tc = -ry; ma = +rz; break;
20533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
20543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
20553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute s, t
20583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	s = ((sc / ma) + 1.0f) / 2.0f;
20593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	t = ((tc / ma) + 1.0f) / 2.0f;
20603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return Vec2(s, t);
20623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20643c827367444ee418f129b2c238299f49d3264554Jarkko PoyryCubeFaceFloatCoords getCubeFaceCoords (const Vec3& coords)
20653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CubeFace face = selectCubeFace(coords);
20673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return CubeFaceFloatCoords(face, projectToFace(face, coords));
20683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20703c827367444ee418f129b2c238299f49d3264554Jarkko 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.
20713c827367444ee418f129b2c238299f49d3264554Jarkko 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.
20723c827367444ee418f129b2c238299f49d3264554Jarkko PoyryCubeFaceIntCoords remapCubeEdgeCoords (const CubeFaceIntCoords& origCoords, int size)
20733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool uInBounds = de::inBounds(origCoords.s, 0, size);
20753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool vInBounds = de::inBounds(origCoords.t, 0, size);
20763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (uInBounds && vInBounds)
20783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return origCoords;
20793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!uInBounds && !vInBounds)
20813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_LAST, -1, -1);
20823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec2 coords(wrap(Sampler::CLAMP_TO_BORDER, origCoords.s, size),
20843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				 wrap(Sampler::CLAMP_TO_BORDER, origCoords.t, size));
20853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec3 canonizedCoords;
20863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Map the uv coordinates to canonized 3d coordinates.
20883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (origCoords.face)
20903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_X: canonizedCoords = IVec3(0,					size-1-coords.y(),	coords.x());			break;
20923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_X: canonizedCoords = IVec3(size-1,				size-1-coords.y(),	size-1-coords.x());		break;
20933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_Y: canonizedCoords = IVec3(coords.x(),			0,					size-1-coords.y());		break;
20943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_Y: canonizedCoords = IVec3(coords.x(),			size-1,				coords.y());			break;
20953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_Z: canonizedCoords = IVec3(size-1-coords.x(),	size-1-coords.y(),	0);						break;
20963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_Z: canonizedCoords = IVec3(coords.x(),			size-1-coords.y(),	size-1);				break;
20973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default: DE_ASSERT(false);
20983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Find an appropriate face to re-map the coordinates to.
21013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (canonizedCoords.x() == -1)
21033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_NEGATIVE_X, IVec2(canonizedCoords.z(), size-1-canonizedCoords.y()));
21043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (canonizedCoords.x() == size)
21063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_POSITIVE_X, IVec2(size-1-canonizedCoords.z(), size-1-canonizedCoords.y()));
21073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (canonizedCoords.y() == -1)
21093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_NEGATIVE_Y, IVec2(canonizedCoords.x(), size-1-canonizedCoords.z()));
21103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (canonizedCoords.y() == size)
21123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_POSITIVE_Y, IVec2(canonizedCoords.x(), canonizedCoords.z()));
21133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (canonizedCoords.z() == -1)
21153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_NEGATIVE_Z, IVec2(size-1-canonizedCoords.x(), size-1-canonizedCoords.y()));
21163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (canonizedCoords.z() == size)
21183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_POSITIVE_Z, IVec2(canonizedCoords.x(), size-1-canonizedCoords.y()));
21193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(false);
21213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return CubeFaceIntCoords(CUBEFACE_LAST, IVec2(-1));
21223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
21233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21243c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void getCubeLinearSamples (const ConstPixelBufferAccess (&faceAccesses)[CUBEFACE_LAST], CubeFace baseFace, float u, float v, int depth, Vec4 (&dst)[4])
21253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
21263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(faceAccesses[0].getWidth() == faceAccesses[0].getHeight());
21273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		size					= faceAccesses[0].getWidth();
21283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		x0						= deFloorFloatToInt32(u-0.5f);
21293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		x1						= x0+1;
21303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		y0						= deFloorFloatToInt32(v-0.5f);
21313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		y1						= y0+1;
21323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec2	baseSampleCoords[4]		=
21333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x0, y0),
21353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x1, y0),
21363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x0, y1),
21373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x1, y1)
21383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
21393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4	sampleColors[4];
21403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool	hasBothCoordsOutOfBounds[4]; //!< Whether correctCubeFace() returns CUBEFACE_LAST, i.e. both u and v are out of bounds.
21413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Find correct faces and coordinates for out-of-bounds sample coordinates.
21433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
21453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CubeFaceIntCoords coords = remapCubeEdgeCoords(CubeFaceIntCoords(baseFace, baseSampleCoords[i]), size);
21473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		hasBothCoordsOutOfBounds[i] = coords.face == CUBEFACE_LAST;
21483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!hasBothCoordsOutOfBounds[i])
21493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sampleColors[i] = lookup(faceAccesses[coords.face], coords.s, coords.t, depth);
21503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
21513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21523c827367444ee418f129b2c238299f49d3264554Jarkko 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.
21533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note This averaging behavior is not required by the GLES3 spec (though it is recommended). GLES3 spec only
21543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//		 requires that if the three other samples all have the same color, then the doubly-out-of-bounds sample
21553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//		 must have this color as well.
21563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int bothOutOfBoundsNdx = -1;
21593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < 4; i++)
21603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (hasBothCoordsOutOfBounds[i])
21623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
21633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(bothOutOfBoundsNdx < 0); // Only one sample can be out of bounds in both u and v.
21643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				bothOutOfBoundsNdx = i;
21653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
21663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
21673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (bothOutOfBoundsNdx != -1)
21683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sampleColors[bothOutOfBoundsNdx] = Vec4(0.0f);
21703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < 4; i++)
21713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (i != bothOutOfBoundsNdx)
21723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					sampleColors[bothOutOfBoundsNdx] += sampleColors[i];
21733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sampleColors[bothOutOfBoundsNdx] = sampleColors[bothOutOfBoundsNdx] * (1.0f/3.0f);
21753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
21763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
21773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < DE_LENGTH_OF_ARRAY(sampleColors); i++)
21793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dst[i] = sampleColors[i];
21803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
21813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \todo [2014-02-19 pyry] Optimize faceAccesses
21833c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleCubeSeamlessLinear (const ConstPixelBufferAccess (&faceAccesses)[CUBEFACE_LAST], CubeFace baseFace, const Sampler& sampler, float s, float t, int depth)
21843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
21853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(faceAccesses[0].getWidth() == faceAccesses[0].getHeight());
21863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		size	= faceAccesses[0].getWidth();
21883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
21893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float	u		= s;
21903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float	v		= t;
21913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
21933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		u = unnormalize(sampler.wrapS, s, size);
21953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		v = unnormalize(sampler.wrapT, t, size);
21963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
21973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Get sample colors.
21993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 sampleColors[4];
22013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	getCubeLinearSamples(faceAccesses, baseFace, u, v, depth, sampleColors);
22023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
22043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
22063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float b = deFloatFrac(v-0.5f);
22073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (sampleColors[0]*(1.0f-a)*(1.0f-b)) +
22093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (sampleColors[1]*(     a)*(1.0f-b)) +
22103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (sampleColors[2]*(1.0f-a)*(     b)) +
22113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (sampleColors[3]*(     a)*(     b));
22123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
22133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22143c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleLevelArrayCubeSeamless (const ConstPixelBufferAccess* const (&faces)[CUBEFACE_LAST], int numLevels, CubeFace face, const Sampler& sampler, float s, float t, int depth, float lod)
22153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
22163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
22173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
22183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
22203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
22213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:
22223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessNearest(faces[face][0], sampler, s, t, depth);
22233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:
22253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
22273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < (int)CUBEFACE_LAST; i++)
22283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				faceAccesses[i] = faces[i][0];
22293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessLinear(faceAccesses, face, sampler, s, t, depth);
22313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
22343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
22353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
22373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
22383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
22393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
22413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessNearest(faces[face][level], sampler, s, t, depth);
22423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
22433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
22443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
22453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
22473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
22483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses[i] = faces[i][level];
22493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessLinear(faceAccesses, face, sampler, s, t, depth);
22513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
22523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
22553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
22563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
22583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
22593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level1		= de::min(maxLevel, level0 + 1);
22603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
22613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					f			= deFloatFrac(lod);
22623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec4					t0;
22633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec4					t1;
22643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
22663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
22673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessNearest(faces[face][level0], sampler, s, t, depth);
22683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessNearest(faces[face][level1], sampler, s, t, depth);
22693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
22703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
22713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
22723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
22733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses0[CUBEFACE_LAST];
22753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses1[CUBEFACE_LAST];
22763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
22773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
22783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses0[i] = faces[i][level0];
22793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses1[i] = faces[i][level1];
22803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
22813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessLinear(faceAccesses0, face, sampler, s, t, depth);
22833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessLinear(faceAccesses1, face, sampler, s, t, depth);
22843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
22853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
22873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
22903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
22913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
22923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
22933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
22943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22953c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float sampleCubeSeamlessNearestCompare (const ConstPixelBufferAccess& faceAccess, const Sampler& sampler, float ref, float s, float t, int depth = 0)
22963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
22973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler clampingSampler = sampler;
22983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	clampingSampler.wrapS = Sampler::CLAMP_TO_EDGE;
22993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	clampingSampler.wrapT = Sampler::CLAMP_TO_EDGE;
23003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return faceAccess.sample2DCompare(clampingSampler, Sampler::NEAREST, ref, s, t, IVec3(0, 0, depth));
23013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23033c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float sampleCubeSeamlessLinearCompare (const ConstPixelBufferAccess (&faceAccesses)[CUBEFACE_LAST], CubeFace baseFace, const Sampler& sampler, float ref, float s, float t)
23043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(faceAccesses[0].getWidth() == faceAccesses[0].getHeight());
23063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		size	= faceAccesses[0].getWidth();
23083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
23093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float	u		= s;
23103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float	v		= t;
23113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
23133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		u = unnormalize(sampler.wrapS, s, size);
23153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		v = unnormalize(sampler.wrapT, t, size);
23163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
23173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			x0						= deFloorFloatToInt32(u-0.5f);
23193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			x1						= x0+1;
23203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			y0						= deFloorFloatToInt32(v-0.5f);
23213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			y1						= y0+1;
23223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec2		baseSampleCoords[4]		=
23233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x0, y0),
23253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x1, y0),
23263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x0, y1),
23273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x1, y1)
23283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
23293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		sampleRes[4];
23303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		hasBothCoordsOutOfBounds[4]; //!< Whether correctCubeFace() returns CUBEFACE_LAST, i.e. both u and v are out of bounds.
23313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Find correct faces and coordinates for out-of-bounds sample coordinates.
23333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
23353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CubeFaceIntCoords coords = remapCubeEdgeCoords(CubeFaceIntCoords(baseFace, baseSampleCoords[i]), size);
23373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		hasBothCoordsOutOfBounds[i] = coords.face == CUBEFACE_LAST;
23383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!hasBothCoordsOutOfBounds[i])
23403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
23413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool isFixedPointDepth = isFixedPointDepthTextureFormat(faceAccesses[coords.face].getFormat());
23423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sampleRes[i] = execCompare(faceAccesses[coords.face].getPixel(coords.s, coords.t), sampler.compare, sampler.compareChannel, ref, isFixedPointDepth);
23443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
23453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
23463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23473c827367444ee418f129b2c238299f49d3264554Jarkko 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.
23483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note This averaging behavior is not required by the GLES3 spec (though it is recommended). GLES3 spec only
23493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//		 requires that if the three other samples all have the same color, then the doubly-out-of-bounds sample
23503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//		 must have this color as well.
23513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int bothOutOfBoundsNdx = -1;
23543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < 4; i++)
23553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
23563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (hasBothCoordsOutOfBounds[i])
23573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
23583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(bothOutOfBoundsNdx < 0); // Only one sample can be out of bounds in both u and v.
23593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				bothOutOfBoundsNdx = i;
23603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
23613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
23623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (bothOutOfBoundsNdx != -1)
23633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
23643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sampleRes[bothOutOfBoundsNdx] = 0.0f;
23653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < 4; i++)
23663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (i != bothOutOfBoundsNdx)
23673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					sampleRes[bothOutOfBoundsNdx] += sampleRes[i];
23683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sampleRes[bothOutOfBoundsNdx] = sampleRes[bothOutOfBoundsNdx] * (1.0f/3.0f);
23703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
23713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
23723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
23743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
23763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float b = deFloatFrac(v-0.5f);
23773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (sampleRes[0]*(1.0f-a)*(1.0f-b)) +
23793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (sampleRes[1]*(     a)*(1.0f-b)) +
23803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (sampleRes[2]*(1.0f-a)*(     b)) +
23813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (sampleRes[3]*(     a)*(     b));
23823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23843c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float sampleLevelArrayCubeSeamlessCompare (const ConstPixelBufferAccess* const (&faces)[CUBEFACE_LAST], int numLevels, CubeFace face, const Sampler& sampler, float ref, float s, float t, float lod)
23853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
23873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
23883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
23903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:
23923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessNearestCompare(faces[face][0], sampler, ref, s, t);
23933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:
23953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
23963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
23973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < (int)CUBEFACE_LAST; i++)
23983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				faceAccesses[i] = faces[i][0];
23993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessLinearCompare(faceAccesses, face, sampler, ref, s, t);
24013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
24023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
24043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
24053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
24063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
24073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
24083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
24093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
24113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessNearestCompare(faces[face][level], sampler, ref, s, t);
24123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
24133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
24143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
24153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
24173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
24183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses[i] = faces[i][level];
24193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessLinearCompare(faceAccesses, face, sampler, ref, s, t);
24213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
24223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
24233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
24253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
24263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
24273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
24283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
24293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level1		= de::min(maxLevel, level0 + 1);
24303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
24313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					f			= deFloatFrac(lod);
24323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					t0;
24333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					t1;
24343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
24363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
24373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessNearestCompare(faces[face][level0], sampler, ref, s, t);
24383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessNearestCompare(faces[face][level1], sampler, ref, s, t);
24393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
24403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
24413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
24423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
24433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses0[CUBEFACE_LAST];
24453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses1[CUBEFACE_LAST];
24463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
24473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
24483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses0[i] = faces[i][level0];
24493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses1[i] = faces[i][level1];
24503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
24513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessLinearCompare(faceAccesses0, face, sampler, ref, s, t);
24533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessLinearCompare(faceAccesses1, face, sampler, ref, s, t);
24543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
24553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
24573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
24583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
24603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
24613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
24623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
24633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Cube map array sampling
24663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24673c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline ConstPixelBufferAccess getCubeArrayFaceAccess (const ConstPixelBufferAccess* const levels, int levelNdx, int slice, CubeFace face)
24683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ConstPixelBufferAccess&	level	= levels[levelNdx];
24703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						depth	= (slice * 6) + getCubeArrayFaceIndex(face);
24713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return getSubregion(level, 0, 0, depth, level.getWidth(), level.getHeight(), 1);
24733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleCubeArraySeamless (const ConstPixelBufferAccess* const levels, int numLevels, int slice, CubeFace face, const Sampler& sampler, float s, float t, float lod)
24763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					faceDepth	= (slice * 6) + getCubeArrayFaceIndex(face);
24783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool					magnified	= lod <= sampler.lodThreshold;
24793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Sampler::FilterMode	filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
24803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
24823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:
24843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessNearest(levels[0], sampler, s, t, faceDepth);
24853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:
24873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
24883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
24893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < (int)CUBEFACE_LAST; i++)
24903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				faceAccesses[i] = getCubeArrayFaceAccess(levels, 0, slice, (CubeFace)i);
24913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessLinear(faceAccesses, face, sampler, s, t, 0);
24933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
24943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
24963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
24973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
24983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
24993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
25003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
25013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
25033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessNearest(levels[level], sampler, s, t, faceDepth);
25043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
25053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
25063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
25073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
25093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
25103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses[i] = getCubeArrayFaceAccess(levels, level, slice, (CubeFace)i);
25113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessLinear(faceAccesses, face, sampler, s, t, 0);
25133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
25143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
25153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
25173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
25183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
25193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
25203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
25213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level1		= de::min(maxLevel, level0 + 1);
25223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
25233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					f			= deFloatFrac(lod);
25243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec4					t0;
25253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec4					t1;
25263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
25283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
25293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessNearest(levels[level0], sampler, s, t, faceDepth);
25303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessNearest(levels[level1], sampler, s, t, faceDepth);
25313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
25323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
25333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
25343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
25353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses0[CUBEFACE_LAST];
25373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses1[CUBEFACE_LAST];
25383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
25393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
25403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses0[i] = getCubeArrayFaceAccess(levels, level0, slice, (CubeFace)i);
25413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses1[i] = getCubeArrayFaceAccess(levels, level1, slice, (CubeFace)i);
25423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
25433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessLinear(faceAccesses0, face, sampler, s, t, 0);
25453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessLinear(faceAccesses1, face, sampler, s, t, 0);
25463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
25473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
25493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
25503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
25523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
25533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
25543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
25553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
25563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25573c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float sampleCubeArraySeamlessCompare (const ConstPixelBufferAccess* const levels, int numLevels, int slice, CubeFace face, const Sampler& sampler, float ref, float s, float t, float lod)
25583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
25593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int			faceDepth	= (slice * 6) + getCubeArrayFaceIndex(face);
25603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool			magnified	= lod <= sampler.lodThreshold;
25613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode	filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
25623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
25643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
25653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:
25663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessNearestCompare(levels[0], sampler, ref, s, t, faceDepth);
25673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:
25693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
25703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
25713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < (int)CUBEFACE_LAST; i++)
25723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				faceAccesses[i] = getCubeArrayFaceAccess(levels, 0, slice, (CubeFace)i);
25733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessLinearCompare(faceAccesses, face, sampler, ref, s, t);
25753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
25763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
25783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
25793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
25803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
25813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
25823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
25833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
25853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessNearestCompare(levels[level], sampler, ref, s, t, faceDepth);
25863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
25873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
25883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
25893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
25913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
25923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses[i] = getCubeArrayFaceAccess(levels, level, slice, (CubeFace)i);
25933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessLinearCompare(faceAccesses, face, sampler, ref, s, t);
25953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
25963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
25973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
25993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
26003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
26013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
26023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
26033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level1		= de::min(maxLevel, level0 + 1);
26043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
26053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					f			= deFloatFrac(lod);
26063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					t0;
26073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					t1;
26083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
26103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
26113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessNearestCompare(levels[level0], sampler, ref, s, t, faceDepth);
26123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessNearestCompare(levels[level1], sampler, ref, s, t, faceDepth);
26133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
26143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
26153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
26163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
26173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses0[CUBEFACE_LAST];
26193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses1[CUBEFACE_LAST];
26203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
26213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
26223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses0[i] = getCubeArrayFaceAccess(levels, level0, slice, (CubeFace)i);
26233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses1[i] = getCubeArrayFaceAccess(levels, level1, slice, (CubeFace)i);
26243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
26253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessLinearCompare(faceAccesses0, face, sampler, ref, s, t);
26273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessLinearCompare(faceAccesses1, face, sampler, ref, s, t);
26283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
26293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
26313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
26323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
26343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
26353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
26363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
26373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
26383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26393c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int computeMipPyramidLevels (int size)
26403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return deLog2Floor32(size)+1;
26423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
26433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26443c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int computeMipPyramidLevels (int width, int height)
26453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return deLog2Floor32(de::max(width, height))+1;
26473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
26483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int computeMipPyramidLevels (int width, int height, int depth)
26503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return deLog2Floor32(de::max(width, de::max(height, depth)))+1;
26523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
26533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int getMipPyramidLevelSize (int baseLevelSize, int levelNdx)
26553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return de::max(baseLevelSize >> levelNdx, 1);
26573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
26583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// TextureLevelPyramid
26603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26613c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevelPyramid::TextureLevelPyramid (const TextureFormat& format, int numLevels)
26623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	(format)
26633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_data	(numLevels)
26643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_access	(numLevels)
26653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
26673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26683c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevelPyramid::TextureLevelPyramid (const TextureLevelPyramid& other)
26693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	(other.m_format)
26703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_data	(other.getNumLevels())
26713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_access	(other.getNumLevels())
26723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int levelNdx = 0; levelNdx < other.getNumLevels(); levelNdx++)
26743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
26753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!other.isLevelEmpty(levelNdx))
26763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
26773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::ConstPixelBufferAccess& srcLevel = other.getLevel(levelNdx);
26783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_data[levelNdx] = other.m_data[levelNdx];
26803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_access[levelNdx] = PixelBufferAccess(srcLevel.getFormat(), srcLevel.getWidth(), srcLevel.getHeight(), srcLevel.getDepth(), m_data[levelNdx].getPtr());
26813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
26823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
26833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
26843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26853c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevelPyramid& TextureLevelPyramid::operator= (const TextureLevelPyramid& other)
26863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
26883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
26893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_format = other.m_format;
26913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_data.resize(other.getNumLevels());
26923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_access.resize(other.getNumLevels());
26933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int levelNdx = 0; levelNdx < other.getNumLevels(); levelNdx++)
26953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
26963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!other.isLevelEmpty(levelNdx))
26973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
26983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::ConstPixelBufferAccess& srcLevel = other.getLevel(levelNdx);
26993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_data[levelNdx] = other.m_data[levelNdx];
27013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_access[levelNdx] = PixelBufferAccess(srcLevel.getFormat(), srcLevel.getWidth(), srcLevel.getHeight(), srcLevel.getDepth(), m_data[levelNdx].getPtr());
27023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
27033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (!isLevelEmpty(levelNdx))
27043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			clearLevel(levelNdx);
27053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
27063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
27083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27103c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevelPyramid::~TextureLevelPyramid (void)
27113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27143c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureLevelPyramid::allocLevel (int levelNdx, int width, int height, int depth)
27153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	size	= m_format.getPixelSize()*width*height*depth;
27173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(isLevelEmpty(levelNdx));
27193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_data[levelNdx].setStorage(size);
27213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_access[levelNdx] = PixelBufferAccess(m_format, width, height, depth, m_data[levelNdx].getPtr());
27223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27243c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureLevelPyramid::clearLevel (int levelNdx)
27253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!isLevelEmpty(levelNdx));
27273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_data[levelNdx].clear();
27293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_access[levelNdx] = PixelBufferAccess();
27303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture1D
27333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27343c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1D::Texture1D (const TextureFormat& format, int width)
27353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(format, computeMipPyramidLevels(width))
27363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(width)
27373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
27383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27413c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1D::Texture1D (const Texture1D& other)
27423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(other)
27433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(other.m_width)
27443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
27453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27483c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1D& Texture1D::operator= (const Texture1D& other)
27493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
27513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
27523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::operator=(other);
27543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_width		= other.m_width;
27563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view		= Texture1DView(getNumLevels(), getLevels());
27573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
27593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27613c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1D::~Texture1D (void)
27623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture1D::allocLevel (int levelNdx)
27663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels()));
27683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int width = getMipPyramidLevelSize(m_width, levelNdx);
27703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::allocLevel(levelNdx, width, 1, 1);
27723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture2D
27753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27763c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2D::Texture2D (const TextureFormat& format, int width, int height)
27773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(format, computeMipPyramidLevels(width, height))
27783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(width)
27793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height				(height)
27803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
27813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27843c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2D::Texture2D (const Texture2D& other)
27853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(other)
27863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(other.m_width)
27873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height				(other.m_height)
27883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
27893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27923c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2D& Texture2D::operator= (const Texture2D& other)
27933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
27953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
27963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::operator=(other);
27983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_width		= other.m_width;
28003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_height	= other.m_height;
28013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view		= Texture2DView(getNumLevels(), getLevels());
28023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
28043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28063c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2D::~Texture2D (void)
28073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28103c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2D::allocLevel (int levelNdx)
28113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels()));
28133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	width	= getMipPyramidLevelSize(m_width, levelNdx);
28153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	height	= getMipPyramidLevelSize(m_height, levelNdx);
28163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::allocLevel(levelNdx, width, height, 1);
28183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// TextureCubeView
28213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28223c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeView::TextureCubeView (void)
28233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_numLevels(0)
28243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < CUBEFACE_LAST; ndx++)
28263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_levels[ndx] = DE_NULL;
28273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28293c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeView::TextureCubeView (int numLevels, const ConstPixelBufferAccess* const (&levels) [CUBEFACE_LAST])
28303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_numLevels(numLevels)
28313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < CUBEFACE_LAST; ndx++)
28333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_levels[ndx] = levels[ndx];
28343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28363c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Vec4 TextureCubeView::sample (const Sampler& sampler, float s, float t, float r, float lod) const
28373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare == Sampler::COMPAREMODE_NONE);
28393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Computes (face, s, t).
28413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CubeFaceFloatCoords coords = getCubeFaceCoords(Vec3(s, t, r));
28423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.seamlessCubeMap)
28433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sampleLevelArrayCubeSeamless(m_levels, m_numLevels, coords.face, sampler, coords.s, coords.t, 0 /* depth */, lod);
28443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
28453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sampleLevelArray2D(m_levels[coords.face], m_numLevels, sampler, coords.s, coords.t, 0 /* depth */, lod);
28463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat TextureCubeView::sampleCompare (const Sampler& sampler, float ref, float s, float t, float r, float lod) const
28493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare != Sampler::COMPAREMODE_NONE);
28513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Computes (face, s, t).
28533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CubeFaceFloatCoords coords = getCubeFaceCoords(Vec3(s, t, r));
28543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.seamlessCubeMap)
28553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sampleLevelArrayCubeSeamlessCompare(m_levels, m_numLevels, coords.face, sampler, ref, coords.s, coords.t, lod);
28563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
28573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sampleLevelArray2DCompare(m_levels[coords.face], m_numLevels, sampler, ref, coords.s, coords.t, lod, IVec3(0, 0, 0));
28583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28603c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 TextureCubeView::gather (const Sampler& sampler, float s, float t, float r, int componentNdx) const
28613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare == Sampler::COMPAREMODE_NONE);
28633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
28653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)CUBEFACE_LAST; i++)
28663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		faceAccesses[i] = m_levels[i][0];
28673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CubeFaceFloatCoords	coords	= getCubeFaceCoords(Vec3(s, t, r));
28693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					size	= faceAccesses[0].getWidth();
28703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
28713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float						u		= coords.s;
28723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float						v		= coords.t;
28733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
28753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
28763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		u = unnormalize(sampler.wrapS, coords.s, size);
28773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		v = unnormalize(sampler.wrapT, coords.t, size);
28783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
28793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 sampleColors[4];
28813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	getCubeLinearSamples(faceAccesses, coords.face, u, v, 0, sampleColors);
28823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	sampleIndices[4] = { 2, 3, 1, 0 }; // \note Gather returns the samples in a non-obvious order.
28843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4		result;
28853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
28863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result[i] = sampleColors[sampleIndices[i]][componentNdx];
28873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
28893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28913c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 TextureCubeView::gatherCompare (const Sampler& sampler, float ref, float s, float t, float r) const
28923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare != Sampler::COMPAREMODE_NONE);
28943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_levels[0][0].getFormat().order == TextureFormat::D || m_levels[0][0].getFormat().order == TextureFormat::DS);
28953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compareChannel == 0);
28963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler noCompareSampler = sampler;
28983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	noCompareSampler.compare = Sampler::COMPAREMODE_NONE;
28993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec4 gathered			= gather(noCompareSampler, s, t, r, 0 /* component 0: depth */);
29013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool isFixedPoint		= isFixedPointDepthTextureFormat(m_levels[0][0].getFormat());
29023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 result;
29033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
29043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result[i] = execCompare(gathered, sampler.compare, i, ref, isFixedPoint);
29053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
29073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// TextureCube
29103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29113c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCube::TextureCube (const TextureFormat& format, int size)
29123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	(format)
29133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_size	(size)
29143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						numLevels		= computeMipPyramidLevels(m_size);
29163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ConstPixelBufferAccess*	levels[CUBEFACE_LAST];
29173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int face = 0; face < CUBEFACE_LAST; face++)
29193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
29203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_data[face].resize(numLevels);
29213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_access[face].resize(numLevels);
29223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		levels[face] = &m_access[face][0];
29233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
29243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view = TextureCubeView(numLevels, levels);
29263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29283c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCube::TextureCube (const TextureCube& other)
29293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	(other.m_format)
29303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_size	(other.m_size)
29313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						numLevels		= computeMipPyramidLevels(m_size);
29333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ConstPixelBufferAccess*	levels[CUBEFACE_LAST];
29343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int face = 0; face < CUBEFACE_LAST; face++)
29363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
29373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_data[face].resize(numLevels);
29383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_access[face].resize(numLevels);
29393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		levels[face] = &m_access[face][0];
29403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
29413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view = TextureCubeView(numLevels, levels);
29433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
29453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
29463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int face = 0; face < CUBEFACE_LAST; face++)
29473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
29483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!other.isLevelEmpty((CubeFace)face, levelNdx))
29493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
29503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				allocLevel((CubeFace)face, levelNdx);
29513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				copy(getLevelFace(levelNdx, (CubeFace)face),
29523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 other.getLevelFace(levelNdx, (CubeFace)face));
29533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
29543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
29553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
29563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29583c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCube& TextureCube::operator= (const TextureCube& other)
29593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
29613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
29623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						numLevels		= computeMipPyramidLevels(other.m_size);
29643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ConstPixelBufferAccess*	levels[CUBEFACE_LAST];
29653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int face = 0; face < CUBEFACE_LAST; face++)
29673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
29683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_data[face].resize(numLevels);
29693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_access[face].resize(numLevels);
29703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		levels[face] = &m_access[face][0];
29713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
29723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_format	= other.m_format;
29743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_size		= other.m_size;
29753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view		= TextureCubeView(numLevels, levels);
29763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
29783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
29793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int face = 0; face < CUBEFACE_LAST; face++)
29803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
29813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!isLevelEmpty((CubeFace)face, levelNdx))
29823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				clearLevel((CubeFace)face, levelNdx);
29833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!other.isLevelEmpty((CubeFace)face, levelNdx))
29853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
29863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				allocLevel((CubeFace)face, levelNdx);
29873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				copy(getLevelFace(levelNdx, (CubeFace)face),
29883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 other.getLevelFace(levelNdx, (CubeFace)face));
29893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
29903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
29913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
29923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
29943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29963c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCube::~TextureCube (void)
29973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30003c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCube::allocLevel (tcu::CubeFace face, int levelNdx)
30013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	size		= getMipPyramidLevelSize(m_size, levelNdx);
30033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	dataSize	= m_format.getPixelSize()*size*size;
30043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(isLevelEmpty(face, levelNdx));
30053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_data[face][levelNdx].setStorage(dataSize);
30073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_access[face][levelNdx] = PixelBufferAccess(m_format, size, size, 1, m_data[face][levelNdx].getPtr());
30083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30103c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCube::clearLevel (tcu::CubeFace face, int levelNdx)
30113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!isLevelEmpty(face, levelNdx));
30133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_data[face][levelNdx].clear();
30143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_access[face][levelNdx] = PixelBufferAccess();
30153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture1DArrayView
30183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30193c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1DArrayView::Texture1DArrayView (int numLevels, const ConstPixelBufferAccess* levels)
30203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_numLevels	(numLevels)
30213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_levels		(levels)
30223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30253c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int Texture1DArrayView::selectLayer (float r) const
30263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_numLevels > 0 && m_levels);
30283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return de::clamp(deFloorFloatToInt32(r + 0.5f), 0, m_levels[0].getHeight()-1);
30293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30313c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 Texture1DArrayView::sample (const Sampler& sampler, float s, float t, float lod) const
30323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray1D(m_levels, m_numLevels, sampler, s, selectLayer(t), lod);
30343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30363c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 Texture1DArrayView::sampleOffset (const Sampler& sampler, float s, float t, float lod, deInt32 offset) const
30373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray1DOffset(m_levels, m_numLevels, sampler, s, lod, IVec2(offset, selectLayer(t)));
30393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat Texture1DArrayView::sampleCompare (const Sampler& sampler, float ref, float s, float t, float lod) const
30423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray1DCompare(m_levels, m_numLevels, sampler, ref, s, lod, IVec2(0, selectLayer(t)));
30443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat Texture1DArrayView::sampleCompareOffset (const Sampler& sampler, float ref, float s, float t, float lod, deInt32 offset) const
30473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray1DCompare(m_levels, m_numLevels, sampler, ref, s, lod, IVec2(offset, selectLayer(t)));
30493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture2DArrayView
30523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30533c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArrayView::Texture2DArrayView (int numLevels, const ConstPixelBufferAccess* levels)
30543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_numLevels	(numLevels)
30553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_levels		(levels)
30563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int Texture2DArrayView::selectLayer (float r) const
30603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_numLevels > 0 && m_levels);
30623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return de::clamp(deFloorFloatToInt32(r + 0.5f), 0, m_levels[0].getDepth()-1);
30633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30653c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 Texture2DArrayView::sample (const Sampler& sampler, float s, float t, float r, float lod) const
30663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray2D(m_levels, m_numLevels, sampler, s, t, selectLayer(r), lod);
30683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30703c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat Texture2DArrayView::sampleCompare (const Sampler& sampler, float ref, float s, float t, float r, float lod) const
30713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray2DCompare(m_levels, m_numLevels, sampler, ref, s, t, lod, IVec3(0, 0, selectLayer(r)));
30733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30753c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 Texture2DArrayView::sampleOffset (const Sampler& sampler, float s, float t, float r, float lod, const IVec2& offset) const
30763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray2DOffset(m_levels, m_numLevels, sampler, s, t, lod, IVec3(offset.x(), offset.y(), selectLayer(r)));
30783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat Texture2DArrayView::sampleCompareOffset (const Sampler& sampler, float ref, float s, float t, float r, float lod, const IVec2& offset) const
30813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray2DCompare(m_levels, m_numLevels, sampler, ref, s, t, lod, IVec3(offset.x(), offset.y(), selectLayer(r)));
30833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30853c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 Texture2DArrayView::gatherOffsets (const Sampler& sampler, float s, float t, float r, int componentNdx, const IVec2 (&offsets)[4]) const
30863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return gatherArray2DOffsets(m_levels[0], sampler, s, t, selectLayer(r), componentNdx, offsets);
30883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30903c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 Texture2DArrayView::gatherOffsetsCompare (const Sampler& sampler, float ref, float s, float t, float r, const IVec2 (&offsets)[4]) const
30913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return gatherArray2DOffsetsCompare(m_levels[0], sampler, ref, s, t, selectLayer(r), offsets);
30933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture1DArray
30963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30973c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1DArray::Texture1DArray (const TextureFormat& format, int width, int numLayers)
30983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(format, computeMipPyramidLevels(width))
30993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(width)
31003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numLayers			(numLayers)
31013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
31023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31053c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1DArray::Texture1DArray (const Texture1DArray& other)
31063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(other)
31073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(other.m_width)
31083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numLayers			(other.m_numLayers)
31093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
31103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31133c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1DArray& Texture1DArray::operator= (const Texture1DArray& other)
31143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
31163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
31173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::operator=(other);
31193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_width		= other.m_width;
31213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_numLayers	= other.m_numLayers;
31223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view		= Texture1DArrayView(getNumLevels(), getLevels());
31233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
31253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31273c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1DArray::~Texture1DArray (void)
31283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31313c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture1DArray::allocLevel (int levelNdx)
31323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels()));
31343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int width = getMipPyramidLevelSize(m_width, levelNdx);
31363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::allocLevel(levelNdx, width, m_numLayers, 1);
31383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture2DArray
31413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31423c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArray::Texture2DArray (const TextureFormat& format, int width, int height, int numLayers)
31433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(format, computeMipPyramidLevels(width, height))
31443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(width)
31453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height				(height)
31463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numLayers			(numLayers)
31473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
31483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31513c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArray::Texture2DArray (const Texture2DArray& other)
31523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(other)
31533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(other.m_width)
31543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height				(other.m_height)
31553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numLayers			(other.m_numLayers)
31563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
31573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31603c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArray& Texture2DArray::operator= (const Texture2DArray& other)
31613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
31633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
31643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::operator=(other);
31663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_width		= other.m_width;
31683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_height	= other.m_height;
31693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_numLayers	= other.m_numLayers;
31703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view		= Texture2DArrayView(getNumLevels(), getLevels());
31713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
31733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31753c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArray::~Texture2DArray (void)
31763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31793c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2DArray::allocLevel (int levelNdx)
31803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels()));
31823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	width	= getMipPyramidLevelSize(m_width,	levelNdx);
31843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	height	= getMipPyramidLevelSize(m_height,	levelNdx);
31853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::allocLevel(levelNdx, width, height, m_numLayers);
31873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture3DView
31903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31913c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3DView::Texture3DView (int numLevels, const ConstPixelBufferAccess* levels)
31923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_numLevels	(numLevels)
31933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_levels		(levels)
31943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture3D
31983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31993c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3D::Texture3D (const TextureFormat& format, int width, int height, int depth)
32003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(format, computeMipPyramidLevels(width, height, depth))
32013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(width)
32023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height				(height)
32033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_depth				(depth)
32043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
32053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32083c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3D::Texture3D (const Texture3D& other)
32093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(other)
32103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(other.m_width)
32113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height				(other.m_height)
32123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_depth				(other.m_depth)
32133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
32143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32173c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3D& Texture3D::operator= (const Texture3D& other)
32183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
32203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
32213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::operator=(other);
32233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_width		= other.m_width;
32253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_height	= other.m_height;
32263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_depth		= other.m_depth;
32273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view		= Texture3DView(getNumLevels(), getLevels());
32283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
32303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32323c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3D::~Texture3D (void)
32333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32363c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture3D::allocLevel (int levelNdx)
32373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels()));
32393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int width		= getMipPyramidLevelSize(m_width,	levelNdx);
32413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int height	= getMipPyramidLevelSize(m_height,	levelNdx);
32423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int depth		= getMipPyramidLevelSize(m_depth,	levelNdx);
32433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::allocLevel(levelNdx, width, height, depth);
32453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// TextureCubeArrayView
32483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32493c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeArrayView::TextureCubeArrayView (int numLevels, const ConstPixelBufferAccess* levels)
32503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_numLevels	(numLevels)
32513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_levels		(levels)
32523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32558852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryinline int TextureCubeArrayView::selectLayer (float q) const
32563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_numLevels > 0 && m_levels);
32583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT((m_levels[0].getDepth() % 6) == 0);
32593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return de::clamp(deFloorFloatToInt32(q + 0.5f), 0, (m_levels[0].getDepth() / 6)-1);
32613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32633c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Vec4 TextureCubeArrayView::sample (const Sampler& sampler, float s, float t, float r, float q, float lod) const
32643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CubeFaceFloatCoords	coords		= getCubeFaceCoords(Vec3(s, t, r));
32668852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const int					layer		= selectLayer(q);
32678852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const int					faceDepth	= (layer * 6) + getCubeArrayFaceIndex(coords.face);
32683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare == Sampler::COMPAREMODE_NONE);
32703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.seamlessCubeMap)
32728852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		return sampleCubeArraySeamless(m_levels, m_numLevels, layer, coords.face, sampler, coords.s, coords.t, lod);
32733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
32743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sampleLevelArray2D(m_levels, m_numLevels, sampler, coords.s, coords.t, faceDepth, lod);
32753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32773c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat TextureCubeArrayView::sampleCompare (const Sampler& sampler, float ref, float s, float t, float r, float q, float lod) const
32783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CubeFaceFloatCoords	coords		= getCubeFaceCoords(Vec3(s, t, r));
32808852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const int					layer		= selectLayer(q);
32818852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const int					faceDepth	= (layer * 6) + getCubeArrayFaceIndex(coords.face);
32823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare != Sampler::COMPAREMODE_NONE);
32843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.seamlessCubeMap)
32868852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		return sampleCubeArraySeamlessCompare(m_levels, m_numLevels, layer, coords.face, sampler, ref, coords.s, coords.t, lod);
32873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
32883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sampleLevelArray2DCompare(m_levels, m_numLevels, sampler, ref, coords.s, coords.t, lod, IVec3(0, 0, faceDepth));
32893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// TextureCubeArray
32923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32938852c82a1ffa4760985c17cc6875d5d521daf343Jarkko PoyryTextureCubeArray::TextureCubeArray (const TextureFormat& format, int size, int depth)
32943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(format, computeMipPyramidLevels(size))
32953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_size				(size)
32968852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	, m_depth				(depth)
32973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
32983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32998852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	DE_ASSERT(m_depth % 6 == 0);
33003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33023c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeArray::TextureCubeArray (const TextureCubeArray& other)
33033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(other)
33043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_size				(other.m_size)
33058852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	, m_depth				(other.m_depth)
33063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
33073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33088852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	DE_ASSERT(m_depth % 6 == 0);
33093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33113c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeArray& TextureCubeArray::operator= (const TextureCubeArray& other)
33123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
33143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
33153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::operator=(other);
33173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33188852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	m_size	= other.m_size;
33198852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	m_depth	= other.m_depth;
33208852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	m_view	= TextureCubeArrayView(getNumLevels(), getLevels());
33213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33228852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	DE_ASSERT(m_depth % 6 == 0);
33233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
33253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33273c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeArray::~TextureCubeArray (void)
33283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33313c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCubeArray::allocLevel (int levelNdx)
33323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels()));
33343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int size = getMipPyramidLevelSize(m_size, levelNdx);
33363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33378852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	TextureLevelPyramid::allocLevel(levelNdx, size, size, m_depth);
33383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33403c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& str, TextureFormat::ChannelOrder order)
33413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3342ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	const char* const orderStrings[] =
3343ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	{
3344ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"R",
3345ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"A",
3346ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"I",
3347ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"L",
3348ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"LA",
3349ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"RG",
3350ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"RA",
3351ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"RGB",
3352ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"RGBA",
3353ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"ARGB",
3354ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"BGRA",
3355ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi
335616d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		"sR",
335716d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		"sRG",
3358ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"sRGB",
3359ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"sRGBA",
3360ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi
3361ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"D",
3362ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"S",
3363ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"DS"
3364ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	};
3365ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi
3366ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	return str << de::getSizedArrayElement<TextureFormat::CHANNELORDER_LAST>(orderStrings, order);
33673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33693c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& str, TextureFormat::ChannelType type)
33703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3371ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	const char* const typeStrings[] =
3372ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	{
3373ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"SNORM_INT8",
3374ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"SNORM_INT16",
3375ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"SNORM_INT32",
3376ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_INT8",
3377ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_INT16",
337807104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry		"UNORM_INT24",
3379ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_INT32",
3380ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_SHORT_565",
3381ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_SHORT_555",
3382ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_SHORT_4444",
3383ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_SHORT_5551",
3384ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_INT_101010",
3385ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_INT_1010102_REV",
3386ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT_1010102_REV",
3387ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT_11F_11F_10F_REV",
3388ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT_999_E5_REV",
3389ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT_24_8",
3390ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"SIGNED_INT8",
3391ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"SIGNED_INT16",
3392ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"SIGNED_INT32",
3393ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT8",
3394ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT16",
3395db6ba452c1213fd1c2b03369fdf4c1d23f07cfadJarkko Pöyry		"UNSIGNED_INT24",
3396ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT32",
3397ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"HALF_FLOAT",
3398ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"FLOAT",
3399ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"FLOAT_UNSIGNED_INT_24_8_REV"
3400ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	};
3401ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi
3402ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	return str << de::getSizedArrayElement<TextureFormat::CHANNELTYPE_LAST>(typeStrings, type);
34033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34053c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& str, CubeFace face)
34063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (face)
34083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
34093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_X:	return str << "CUBEFACE_NEGATIVE_X";
34103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_X:	return str << "CUBEFACE_POSITIVE_X";
34113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_Y:	return str << "CUBEFACE_NEGATIVE_Y";
34123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_Y:	return str << "CUBEFACE_POSITIVE_Y";
34133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_Z:	return str << "CUBEFACE_NEGATIVE_Z";
34143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_Z:	return str << "CUBEFACE_POSITIVE_Z";
34153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_LAST:			return str << "CUBEFACE_LAST";
34163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:					return str << "UNKNOWN(" << (int)face << ")";
34173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
34183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34203c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& str, TextureFormat format)
34213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return str << format.order << ", " << format.type << "";
34233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34253c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& str, const ConstPixelBufferAccess& access)
34263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return str << "format = (" << access.getFormat() << "), size = "
34283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			   << access.getWidth() << " x " << access.getHeight() << " x " << access.getDepth()
34293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			   << ", pitch = " << access.getRowPitch() << " / " << access.getSlicePitch();
34303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // tcu
3433