tcuTexture.cpp revision 1d75d23528999118c1911ed100d1d063b06040da
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
15307104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 26);
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;
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT32:		return 4;
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::HALF_FLOAT:			return 2;
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT:				return 4;
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0;
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint getNumUsedChannels (TextureFormat::ChannelOrder order)
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18007104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	// make sure this table is updated if type table is updated
18116d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry	DE_STATIC_ASSERT(TextureFormat::CHANNELORDER_LAST == 18);
18207104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (order)
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::R:			return 1;
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::A:			return 1;
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::I:			return 1;
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::L:			return 1;
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::LA:			return 2;
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::RG:			return 2;
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::RA:			return 2;
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::RGB:		return 3;
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::RGBA:		return 4;
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::ARGB:		return 4;
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::BGRA:		return 4;
19616d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		case TextureFormat::sR:			return 1;
19716d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		case TextureFormat::sRG:		return 2;
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::sRGB:		return 3;
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::sRGBA:		return 4;
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::D:			return 1;
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::S:			return 1;
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::DS:			return 2;
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0;
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline float channelToFloat (const deUint8* value, TextureFormat::ChannelType type)
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
21107104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	// make sure this table is updated if format table is updated
21207104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 26);
21307104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (type)
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT8:			return de::max(-1.0f, (float)*((const deInt8*)value) / 127.0f);
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT16:		return de::max(-1.0f, (float)*((const deInt16*)value) / 32767.0f);
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT32:		return de::max(-1.0f, (float)*((const deInt32*)value) / 2147483647.0f);
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT8:			return (float)*((const deUint8*)value) / 255.0f;
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT16:		return (float)*((const deUint16*)value) / 65535.0f;
22107104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry		case TextureFormat::UNORM_INT24:		return (float)readUint24(value) / 16777215.0f;
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT32:		return (float)*((const deUint32*)value) / 4294967295.0f;
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT8:		return (float)*((const deInt8*)value);
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT16:		return (float)*((const deInt16*)value);
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT32:		return (float)*((const deInt32*)value);
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT8:		return (float)*((const deUint8*)value);
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT16:		return (float)*((const deUint16*)value);
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT32:		return (float)*((const deUint32*)value);
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::HALF_FLOAT:			return deFloat16To32(*(const deFloat16*)value);
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT:				return *((const float*)value);
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int channelToInt (const deUint8* value, TextureFormat::ChannelType type)
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23907104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	// make sure this table is updated if format table is updated
24007104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 26);
24107104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (type)
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT8:			return (int)*((const deInt8*)value);
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT16:		return (int)*((const deInt16*)value);
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT32:		return (int)*((const deInt32*)value);
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT8:			return (int)*((const deUint8*)value);
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT16:		return (int)*((const deUint16*)value);
24907104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry		case TextureFormat::UNORM_INT24:		return (int)readUint24(value);
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT32:		return (int)*((const deUint32*)value);
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT8:		return (int)*((const deInt8*)value);
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT16:		return (int)*((const deInt16*)value);
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT32:		return (int)*((const deInt32*)value);
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT8:		return (int)*((const deUint8*)value);
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT16:		return (int)*((const deUint16*)value);
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT32:		return (int)*((const deUint32*)value);
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::HALF_FLOAT:			return (int)deFloat16To32(*(const deFloat16*)value);
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT:				return (int)*((const float*)value);
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0;
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid floatToChannel (deUint8* dst, float src, TextureFormat::ChannelType type)
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26707104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	// make sure this table is updated if format table is updated
26807104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 26);
26907104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (type)
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT8:			*((deInt8*)dst)			= convertSatRte<deInt8>		(src * 127.0f);			break;
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT16:		*((deInt16*)dst)		= convertSatRte<deInt16>	(src * 32767.0f);		break;
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT32:		*((deInt32*)dst)		= convertSatRte<deInt32>	(src * 2147483647.0f);	break;
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT8:			*((deUint8*)dst)		= convertSatRte<deUint8>	(src * 255.0f);			break;
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT16:		*((deUint16*)dst)		= convertSatRte<deUint16>	(src * 65535.0f);		break;
27707104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry		case TextureFormat::UNORM_INT24:		writeUint24(dst, convertSatRteUint24(src * 16777215.0f));						break;
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT32:		*((deUint32*)dst)		= convertSatRte<deUint32>	(src * 4294967295.0f);	break;
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT8:		*((deInt8*)dst)			= convertSatRte<deInt8>		(src);					break;
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT16:		*((deInt16*)dst)		= convertSatRte<deInt16>	(src);					break;
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT32:		*((deInt32*)dst)		= convertSatRte<deInt32>	(src);					break;
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT8:		*((deUint8*)dst)		= convertSatRte<deUint8>	(src);					break;
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT16:		*((deUint16*)dst)		= convertSatRte<deUint16>	(src);					break;
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT32:		*((deUint32*)dst)		= convertSatRte<deUint32>	(src);					break;
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::HALF_FLOAT:			*((deFloat16*)dst)		= deFloat32To16				(src);					break;
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT:				*((float*)dst)			= src;												break;
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, typename S>
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline T convertSat (S src)
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	S min = (S)std::numeric_limits<T>::min();
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	S max = (S)std::numeric_limits<T>::max();
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (src < min)
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return (T)min;
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (src > max)
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return (T)max;
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return (T)src;
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30607104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyrytemplate <typename S>
30707104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyrystatic inline deUint32 convertSatUint24 (S src)
30807104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry{
30907104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	S min = (S)0u;
31007104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	S max = (S)0xFFFFFFu;
31107104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
31207104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	if (src < min)
31307104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry		return (deUint32)min;
31407104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	else if (src > max)
31507104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry		return (deUint32)max;
31607104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	else
31707104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry		return (deUint32)src;
31807104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry}
31907104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid intToChannel (deUint8* dst, int src, TextureFormat::ChannelType type)
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32207104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	// make sure this table is updated if format table is updated
32307104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 26);
32407104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (type)
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT8:			*((deInt8*)dst)			= convertSat<deInt8>	(src);				break;
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SNORM_INT16:		*((deInt16*)dst)		= convertSat<deInt16>	(src);				break;
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT8:			*((deUint8*)dst)		= convertSat<deUint8>	(src);				break;
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT16:		*((deUint16*)dst)		= convertSat<deUint16>	(src);				break;
33107104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry		case TextureFormat::UNORM_INT24:		writeUint24(dst, convertSatUint24(src));							break;
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT8:		*((deInt8*)dst)			= convertSat<deInt8>	(src);				break;
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT16:		*((deInt16*)dst)		= convertSat<deInt16>	(src);				break;
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::SIGNED_INT32:		*((deInt32*)dst)		= convertSat<deInt32>	(src);				break;
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT8:		*((deUint8*)dst)		= convertSat<deUint8>	((deUint32)src);	break;
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT16:		*((deUint16*)dst)		= convertSat<deUint16>	((deUint32)src);	break;
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT32:		*((deUint32*)dst)		= convertSat<deUint32>	((deUint32)src);	break;
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::HALF_FLOAT:			*((deFloat16*)dst)		= deFloat32To16((float)src);				break;
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT:				*((float*)dst)			= (float)src;								break;
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline float channelToNormFloat (deUint32 src, int bits)
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 maxVal = (1u << bits) - 1;
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (float)src / (float)maxVal;
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline deUint32 normFloatToChannel (float src, int bits)
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 maxVal = (1u << bits) - 1;
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 intVal = convertSatRte<deUint32>(src * (float)maxVal);
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return de::min(maxVal, intVal);
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline deUint32 uintToChannel (deUint32 src, int bits)
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 maxVal = (1u << bits) - 1;
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return de::min(maxVal, src);
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Vec4 unpackRGB999E5 (deUint32 color)
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	mBits	= 9;
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	eBias	= 15;
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32	exp		= color >> 27;
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32	bs		= (color >> 18) & ((1<<9)-1);
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32	gs		= (color >> 9) & ((1<<9)-1);
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32	rs		= color & ((1<<9)-1);
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		e		= deFloatPow(2.0f, (float)((int)exp - eBias - mBits));
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		r		= (float)rs * e;
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		g		= (float)gs * e;
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		b		= (float)bs * e;
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return tcu::Vec4(r, g, b, 1.0f);
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3846d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyryconst TextureSwizzle& getChannelReadSwizzle (TextureFormat::ChannelOrder order)
3856d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry{
3866d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	// make sure to update these tables when channel orders are updated
38716d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry	DE_STATIC_ASSERT(TextureFormat::CHANNELORDER_LAST == 18);
3886d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
3896d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle INV		= {{ TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ONE	}};
3906d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle R		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ONE	}};
3916d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle A		= {{ TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_0	}};
3926d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle I		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0	}};
3936d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle L		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ONE	}};
3946d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle LA		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1	}};
3956d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RG		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ONE	}};
3966d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RA		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_1	}};
3976d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RGB		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_ONE	}};
3986d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RGBA	= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_3	}};
3996d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle BGRA	= {{ TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_3	}};
4006d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle ARGB	= {{ TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_3,		TextureSwizzle::CHANNEL_0	}};
4016d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle D		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ONE	}};
4026d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle S		= {{ TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_0	}};
4036d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle DS		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_1	}};
4046d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
4056d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	switch (order)
4066d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	{
4076d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::R:			return R;
4086d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::A:			return A;
4096d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::I:			return I;
4106d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::L:			return L;
4116d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::LA:			return LA;
4126d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RG:			return RG;
4136d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RA:			return RA;
4146d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RGB:		return RGB;
4156d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RGBA:		return RGBA;
4166d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::ARGB:		return ARGB;
4176d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::BGRA:		return BGRA;
41816d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		case TextureFormat::sR:			return R;
41916d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		case TextureFormat::sRG:		return RG;
4206d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::sRGB:		return RGB;
4216d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::sRGBA:		return RGBA;
4226d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::D:			return D;
4236d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::S:			return S;
4246d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::DS:			return DS;
4256d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		default:
4266d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			DE_ASSERT(DE_FALSE);
4276d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			return INV;
4286d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	}
4296d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry}
4306d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
4316d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyryconst TextureSwizzle& getChannelWriteSwizzle (TextureFormat::ChannelOrder order)
4326d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry{
4336d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	// make sure to update these tables when channel orders are updated
43416d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry	DE_STATIC_ASSERT(TextureFormat::CHANNELORDER_LAST == 18);
4356d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
4366d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle INV		= {{ TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
4376d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle R		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
4386d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle A		= {{ TextureSwizzle::CHANNEL_3,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
4396d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle I		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
4406d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle L		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
4416d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle LA		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_3,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
4426d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RG		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
4436d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RA		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_3,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
4446d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RGB		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_LAST	}};
4456d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle RGBA	= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_3		}};
4466d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle BGRA	= {{ TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_3		}};
4476d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle ARGB	= {{ TextureSwizzle::CHANNEL_3,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_2		}};
4486d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle D		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
4496d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle S		= {{ TextureSwizzle::CHANNEL_3,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
4506d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	static const TextureSwizzle DS		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_3,		TextureSwizzle::CHANNEL_LAST,	TextureSwizzle::CHANNEL_LAST	}};
4516d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
4526d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	switch (order)
4536d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	{
4546d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::R:			return R;
4556d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::A:			return A;
4566d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::I:			return I;
4576d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::L:			return L;
4586d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::LA:			return LA;
4596d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RG:			return RG;
4606d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RA:			return RA;
4616d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RGB:		return RGB;
4626d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::RGBA:		return RGBA;
4636d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::ARGB:		return ARGB;
4646d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::BGRA:		return BGRA;
46516d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		case TextureFormat::sR:			return R;
46616d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		case TextureFormat::sRG:		return RG;
4676d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::sRGB:		return RGB;
4686d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::sRGBA:		return RGBA;
4696d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::D:			return D;
4706d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::S:			return S;
4716d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		case TextureFormat::DS:			return DS;
4726d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		default:
4736d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			DE_ASSERT(DE_FALSE);
4746d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			return INV;
4756d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	}
4766d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry}
4776d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
47829340067e919854db7d50bb8c0b666117b229f5eMika IsojärviIVec3 calculatePackedPitch (const TextureFormat& format, const IVec3& size)
47929340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi{
48029340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	const int pixelSize		= format.getPixelSize();
48129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	const int rowPitch		= pixelSize * size.x();
48229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	const int slicePitch	= rowPitch * size.y();
48329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
48429340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	return IVec3(pixelSize, rowPitch, slicePitch);
48529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi}
48629340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/** Get pixel size in bytes. */
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint TextureFormat::getPixelSize (void) const
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (type == CHANNELTYPE_LAST && order == CHANNELORDER_LAST)
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Invalid/empty format.
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 0;
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (type == UNORM_SHORT_565	||
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 type == UNORM_SHORT_555	||
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 type == UNORM_SHORT_4444	||
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 type == UNORM_SHORT_5551)
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(order == RGB || order == RGBA);
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 2;
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (type == UNORM_INT_101010			||
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 type == UNSIGNED_INT_999_E5_REV	||
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 type == UNSIGNED_INT_11F_11F_10F_REV)
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(order == RGB);
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 4;
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (type == UNORM_INT_1010102_REV		||
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 type == UNSIGNED_INT_1010102_REV)
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(order == RGBA);
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 4;
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (type == UNSIGNED_INT_24_8)
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(order == D || order == DS);
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 4;
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (type == FLOAT_UNSIGNED_INT_24_8_REV)
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(order == DS);
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 8;
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
52707104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry		return getNumUsedChannels(order) * getChannelSize(type);
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5303c827367444ee418f129b2c238299f49d3264554Jarkko PoyryConstPixelBufferAccess::ConstPixelBufferAccess (void)
53129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	: m_size		(0)
53229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_pitch		(0)
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_data		(DE_NULL)
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5373c827367444ee418f129b2c238299f49d3264554Jarkko PoyryConstPixelBufferAccess::ConstPixelBufferAccess (const TextureFormat& format, int width, int height, int depth, const void* data)
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format		(format)
53929340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size		(width, height, depth)
54029340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_pitch		(calculatePackedPitch(m_format, m_size))
54129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_data		((void*)data)
54229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi{
54329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi}
54429340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
54529340067e919854db7d50bb8c0b666117b229f5eMika IsojärviConstPixelBufferAccess::ConstPixelBufferAccess (const TextureFormat& format, const IVec3& size, const void* data)
54629340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	: m_format		(format)
54729340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size		(size)
54829340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_pitch		(calculatePackedPitch(m_format, m_size))
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_data		((void*)data)
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5533c827367444ee418f129b2c238299f49d3264554Jarkko PoyryConstPixelBufferAccess::ConstPixelBufferAccess (const TextureFormat& format, int width, int height, int depth, int rowPitch, int slicePitch, const void* data)
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format		(format)
55529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size		(width, height, depth)
55629340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_pitch		(format.getPixelSize(), rowPitch, slicePitch)
55729340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_data		((void*)data)
55829340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi{
55929340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi}
56029340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
56129340067e919854db7d50bb8c0b666117b229f5eMika IsojärviConstPixelBufferAccess::ConstPixelBufferAccess (const TextureFormat& format, const IVec3& size, const IVec3& pitch, const void* data)
56229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	: m_format		(format)
56329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size		(size)
56429340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_pitch		(pitch)
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_data		((void*)data)
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
56729340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(m_format.getPixelSize() <= m_pitch.x());
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5703c827367444ee418f129b2c238299f49d3264554Jarkko PoyryConstPixelBufferAccess::ConstPixelBufferAccess (const TextureLevel& level)
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format		(level.getFormat())
57229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size		(level.getSize())
57329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_pitch		(calculatePackedPitch(m_format, m_size))
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_data		((void*)level.getPtr())
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5783c827367444ee418f129b2c238299f49d3264554Jarkko PoyryPixelBufferAccess::PixelBufferAccess (const TextureFormat& format, int width, int height, int depth, void* data)
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: ConstPixelBufferAccess(format, width, height, depth, data)
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
58329340067e919854db7d50bb8c0b666117b229f5eMika IsojärviPixelBufferAccess::PixelBufferAccess (const TextureFormat& format, const IVec3& size, void* data)
58429340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	: ConstPixelBufferAccess(format, size, data)
58529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi{
58629340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi}
58729340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
5883c827367444ee418f129b2c238299f49d3264554Jarkko PoyryPixelBufferAccess::PixelBufferAccess (const TextureFormat& format, int width, int height, int depth, int rowPitch, int slicePitch, void* data)
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: ConstPixelBufferAccess(format, width, height, depth, rowPitch, slicePitch, data)
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
59329340067e919854db7d50bb8c0b666117b229f5eMika IsojärviPixelBufferAccess::PixelBufferAccess (const TextureFormat& format, const IVec3& size, const IVec3& pitch, void* data)
59429340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	: ConstPixelBufferAccess(format, size, pitch, data)
59529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi{
59629340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi}
59729340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
5983c827367444ee418f129b2c238299f49d3264554Jarkko PoyryPixelBufferAccess::PixelBufferAccess (TextureLevel& level)
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: ConstPixelBufferAccess(level)
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PixelBufferAccess::setPixels (const void* buf, int bufSize) const
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(bufSize == getDataSize());
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMemcpy(getDataPtr(), buf, bufSize);
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6093c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 ConstPixelBufferAccess::getPixel (int x, int y, int z) const
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
61129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(x, 0, m_size.x()));
61229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(y, 0, m_size.y()));
61329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(z, 0, m_size.z()));
61429340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
61529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	const deUint8* pixelPtr = (const deUint8*)getDataPtr() + z*m_pitch.z() + y*m_pitch.y() + x*m_pitch.x();
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Optimized fomats.
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_format.type == TextureFormat::UNORM_INT8)
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_format.order == TextureFormat::RGBA)
62129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi			return readRGBA8888Float(pixelPtr);
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (m_format.order == TextureFormat::RGB)
62329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi			return readRGB888Float(pixelPtr);
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define UB16(OFFS, COUNT)		((*((const deUint16*)pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1))
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define UB32(OFFS, COUNT)		((*((const deUint32*)pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1))
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define NB16(OFFS, COUNT)		channelToNormFloat(UB16(OFFS, COUNT), (COUNT))
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define NB32(OFFS, COUNT)		channelToNormFloat(UB32(OFFS, COUNT), (COUNT))
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Packed formats.
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_SHORT_565:			return Vec4(NB16(11,  5), NB16( 5,  6), NB16( 0,  5), 1.0f);
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_SHORT_555:			return Vec4(NB16(10,  5), NB16( 5,  5), NB16( 0,  5), 1.0f);
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_SHORT_4444:			return Vec4(NB16(12,  4), NB16( 8,  4), NB16( 4,  4), NB16( 0, 4));
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_SHORT_5551:			return Vec4(NB16(11,  5), NB16( 6,  5), NB16( 1,  5), NB16( 0, 1));
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT_101010:			return Vec4(NB32(22, 10), NB32(12, 10), NB32( 2, 10), 1.0f);
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT_1010102_REV:		return Vec4(NB32( 0, 10), NB32(10, 10), NB32(20, 10), NB32(30, 2));
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_1010102_REV:	return UVec4(UB32(0, 10), UB32(10, 10), UB32(20, 10), UB32(30, 2)).cast<float>();
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_999_E5_REV:	return unpackRGB999E5(*((const deUint32*)pixelPtr));
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_24_8:
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (m_format.order)
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// \note Stencil is always ignored.
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TextureFormat::D:	return Vec4(NB32(8, 24), 0.0f, 0.0f, 1.0f);
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TextureFormat::DS:	return Vec4(NB32(8, 24), 0.0f, 0.0f, 1.0f /* (float)UB32(0, 8) */);
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(false);
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_format.order == TextureFormat::DS);
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float	d	= *((const float*)pixelPtr);
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// \note Stencil is ignored.
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//			deUint8	s	= *((const deUint32*)(pixelPtr+4)) & 0xff;
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(d, 0.0f, 0.0f, 1.0f);
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(Float11(UB32(0, 11)).asFloat(), Float11(UB32(11, 11)).asFloat(), Float10(UB32(22, 10)).asFloat(), 1.0f);
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef NB16
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef NB32
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef UB16
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef UB32
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generic path.
6756d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	Vec4							result;
6766d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	const TextureSwizzle::Channel*	channelMap	= getChannelReadSwizzle(m_format.order).components;
6776d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	int								channelSize	= getChannelSize(m_format.type);
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int c = 0; c < 4; c++)
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6816d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		switch (channelMap[c])
6826d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		{
6836d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_0:
6846d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_1:
6856d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_2:
6866d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_3:
6876d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				result[c] = channelToFloat(pixelPtr + channelSize*((int)channelMap[c]), m_format.type);
6886d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				break;
6896d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
6906d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_ZERO:
6916d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				result[c] = 0.0f;
6926d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				break;
6936d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
6946d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_ONE:
6956d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				result[c] = 1.0f;
6966d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				break;
6976d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
6986d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			default:
6996d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				DE_ASSERT(false);
7006d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		}
7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7063c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIVec4 ConstPixelBufferAccess::getPixelInt (int x, int y, int z) const
7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
70829340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(x, 0, m_size.x()));
70929340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(y, 0, m_size.y()));
71029340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(z, 0, m_size.z()));
7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
71207104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	const deUint8* const	pixelPtr = (const deUint8*)getDataPtr() + z*m_pitch.z() + y*m_pitch.y() + x*m_pitch.x();
71307104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	IVec4					result;
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Optimized fomats.
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_format.type == TextureFormat::UNORM_INT8)
7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_format.order == TextureFormat::RGBA)		return readRGBA8888Int(pixelPtr);
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (m_format.order == TextureFormat::RGB)	return readRGB888Int(pixelPtr);
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define U16(OFFS, COUNT)		((*((const deUint16*)pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1))
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define U32(OFFS, COUNT)		((*((const deUint32*)pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1))
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_SHORT_565:			return UVec4(U16(11,  5), U16( 5,  6), U16( 0,  5), 1).cast<int>();
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_SHORT_555:			return UVec4(U16(10,  5), U16( 5,  5), U16( 0,  5), 1).cast<int>();
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_SHORT_4444:			return UVec4(U16(12,  4), U16( 8,  4), U16( 4,  4), U16( 0, 4)).cast<int>();
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_SHORT_5551:			return UVec4(U16(11,  5), U16( 6,  5), U16( 1,  5), U16( 0, 1)).cast<int>();
7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT_101010:			return UVec4(U32(22, 10), U32(12, 10), U32( 2, 10), 1).cast<int>();
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT_1010102_REV:		return UVec4(U32( 0, 10), U32(10, 10), U32(20, 10), U32(30, 2)).cast<int>();
7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_1010102_REV:	return UVec4(U32( 0, 10), U32(10, 10), U32(20, 10), U32(30, 2)).cast<int>();
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_24_8:
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (m_format.order)
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TextureFormat::D:	return UVec4(U32(8, 24), 0, 0, 1).cast<int>();
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TextureFormat::S:	return UVec4(0, 0, 0, U32(8, 24)).cast<int>();
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TextureFormat::DS:	return UVec4(U32(8, 24), 0, 0, U32(0, 8)).cast<int>();
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:
7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(false);
7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_format.order == TextureFormat::DS);
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float	d	= *((const float*)pixelPtr);
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint8	s	= *((const deUint32*)(pixelPtr+4)) & 0xffu;
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// \note Returns bit-representation of depth floating-point value.
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return UVec4(tcu::Float32(d).bits(), 0, 0, s).cast<int>();
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break; // To generic path.
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef U16
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef U32
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generic path.
7626d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	const TextureSwizzle::Channel*	channelMap	= getChannelReadSwizzle(m_format.order).components;
7636d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry	int								channelSize	= getChannelSize(m_format.type);
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int c = 0; c < 4; c++)
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7676d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		switch (channelMap[c])
7686d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		{
7696d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_0:
7706d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_1:
7716d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_2:
7726d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_3:
7736d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				result[c] = channelToInt(pixelPtr + channelSize*((int)channelMap[c]), m_format.type);
7746d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				break;
7756d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
7766d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_ZERO:
7776d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				result[c] = 0;
7786d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				break;
7796d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
7806d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			case TextureSwizzle::CHANNEL_ONE:
7816d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				result[c] = 1;
7826d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				break;
7836d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry
7846d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			default:
7856d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				DE_ASSERT(false);
7866d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry		}
7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<>
7933c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 ConstPixelBufferAccess::getPixelT (int x, int y, int z) const
7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return getPixel(x, y, z);
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<>
7993c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIVec4 ConstPixelBufferAccess::getPixelT (int x, int y, int z) const
8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return getPixelInt(x, y, z);
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<>
8053c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUVec4 ConstPixelBufferAccess::getPixelT (int x, int y, int z) const
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return getPixelUint(x, y, z);
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat ConstPixelBufferAccess::getPixDepth (int x, int y, int z) const
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(x, 0, getWidth()));
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(y, 0, getHeight()));
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(z, 0, getDepth()));
8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
81607104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	const deUint8* const pixelPtr = (const deUint8*)getDataPtr() + z*m_pitch.z() + y*m_pitch.y() + x*m_pitch.x();
8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define UB32(OFFS, COUNT) ((*((const deUint32*)pixelPtr) >> (OFFS)) & ((1<<(COUNT))-1))
8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define NB32(OFFS, COUNT) channelToNormFloat(UB32(OFFS, COUNT), (COUNT))
8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_format.order == TextureFormat::DS || m_format.order == TextureFormat::D);
8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_24_8:
8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (m_format.order)
8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TextureFormat::D:
8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TextureFormat::DS: // \note Fall-through.
8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return NB32(8, 24);
8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(false);
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return 0.0f;
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_format.order == TextureFormat::DS);
8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return *((const float*)pixelPtr);
8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_format.order == TextureFormat::D || m_format.order == TextureFormat::DS);
8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return channelToFloat(pixelPtr, m_format.type);
8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef UB32
8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef NB32
8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint ConstPixelBufferAccess::getPixStencil (int x, int y, int z) const
8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(x, 0, getWidth()));
8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(y, 0, getHeight()));
8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(z, 0, getDepth()));
8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
85507104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	const deUint8* const pixelPtr = (const deUint8*)getDataPtr() + z*m_pitch.z() + y*m_pitch.y() + x*m_pitch.x();
8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_24_8:
8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (m_format.order)
8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TextureFormat::S:		return (int)(*((const deUint32*)pixelPtr) >> 8);
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TextureFormat::DS:		return (int)(*((const deUint32*)pixelPtr) & 0xff);
8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(false);
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return 0;
8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_format.order == TextureFormat::DS);
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return *((const deUint32*)(pixelPtr+4)) & 0xff;
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_format.order == TextureFormat::S)
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return channelToInt(pixelPtr, m_format.type);
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(m_format.order == TextureFormat::DS);
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int stencilChannelIndex = 3;
8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return channelToInt(pixelPtr + getChannelSize(m_format.type)*stencilChannelIndex, m_format.type);
8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PixelBufferAccess::setPixel (const Vec4& color, int x, int y, int z) const
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(x, 0, getWidth()));
8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(y, 0, getHeight()));
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(z, 0, getDepth()));
8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
89429340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	deUint8* const pixelPtr = (deUint8*)getDataPtr() + z*m_pitch.z() + y*m_pitch.y() + x*m_pitch.x();
89529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi
8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Optimized fomats.
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_format.type == TextureFormat::UNORM_INT8)
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_format.order == TextureFormat::RGBA)
9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
90129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi			writeRGBA8888Float(pixelPtr, color);
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return;
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (m_format.order == TextureFormat::RGB)
9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
90629340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi			writeRGB888Float(pixelPtr, color);
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return;
9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define PN(VAL, OFFS, BITS)		(normFloatToChannel((VAL), (BITS)) << (OFFS))
9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define PU(VAL, OFFS, BITS)		(uintToChannel((VAL), (BITS)) << (OFFS))
9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9163c827367444ee418f129b2c238299f49d3264554Jarkko 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;
9173c827367444ee418f129b2c238299f49d3264554Jarkko 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;
9183c827367444ee418f129b2c238299f49d3264554Jarkko 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;
9193c827367444ee418f129b2c238299f49d3264554Jarkko 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;
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT_101010:		*((deUint32*)pixelPtr) = PN(color[0], 22, 10) | PN(color[1], 12, 10) | PN(color[2], 2, 10);									break;
9213c827367444ee418f129b2c238299f49d3264554Jarkko 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;
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_1010102_REV:
9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			UVec4 u = color.cast<deUint32>();
9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			*((deUint32*)pixelPtr) = PU(u[0], 0, 10) | PU(u[1], 10, 10) |PU(u[2], 20, 10) | PU(u[3], 30, 2);
9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			*((deUint32*)pixelPtr) = Float11(color[0]).bits() | (Float11(color[1]).bits() << 11) | (Float10(color[2]).bits() << 22);
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_999_E5_REV:
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			*((deUint32*)pixelPtr) = packRGB999E5(color);
9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_24_8:
9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (m_format.order)
9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TextureFormat::D:		*((deUint32*)pixelPtr) = PN(color[0], 8, 24);									break;
9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TextureFormat::S:		*((deUint32*)pixelPtr) = PN(color[3], 8, 24);									break;
9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TextureFormat::DS:		*((deUint32*)pixelPtr) = PN(color[0], 8, 24) | PU((deUint32)color[3], 0, 8);	break;
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:
9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(false);
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_format.order == TextureFormat::DS);
9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			*((float*)pixelPtr)			= color[0];
9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			*((deUint32*)(pixelPtr+4))	= PU((deUint32)color[3], 0, 8);
9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT:
9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_format.order == TextureFormat::D)
9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				*((float*)pixelPtr) = color[0];
9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// else fall-through to default case!
9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Generic path.
9666d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			int								numChannels	= getNumUsedChannels(m_format.order);
9676d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			const TextureSwizzle::Channel*	map			= getChannelWriteSwizzle(m_format.order).components;
9686d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			int								channelSize	= getChannelSize(m_format.type);
9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int c = 0; c < numChannels; c++)
9716d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			{
9726d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				DE_ASSERT(deInRange32(map[c], TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3));
9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				floatToChannel(pixelPtr + channelSize*c, color[map[c]], m_format.type);
9746d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			}
9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef PN
9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef PU
9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PixelBufferAccess::setPixel (const IVec4& color, int x, int y, int z) const
9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(x, 0, getWidth()));
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(y, 0, getHeight()));
9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(z, 0, getDepth()));
9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
98907104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	deUint8* const pixelPtr = (deUint8*)getDataPtr() + z*m_pitch.z() + y*m_pitch.y() + x*m_pitch.x();
9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Optimized fomats.
9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_format.type == TextureFormat::UNORM_INT8)
9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_format.order == TextureFormat::RGBA)		{ writeRGBA8888Int(pixelPtr, color);	return; }
9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (m_format.order == TextureFormat::RGB)	{ writeRGB888Int(pixelPtr, color);		return; }
9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define PU(VAL, OFFS, BITS)		(uintToChannel((deUint32)(VAL), (BITS)) << (OFFS))
9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10023c827367444ee418f129b2c238299f49d3264554Jarkko 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;
10033c827367444ee418f129b2c238299f49d3264554Jarkko 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;
10043c827367444ee418f129b2c238299f49d3264554Jarkko 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;
10053c827367444ee418f129b2c238299f49d3264554Jarkko 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;
10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNORM_INT_101010:			*((deUint32*)pixelPtr) = PU(color[0], 22, 10) | PU(color[1], 12, 10) | PU(color[2], 2, 10);									break;
10073c827367444ee418f129b2c238299f49d3264554Jarkko 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;
10083c827367444ee418f129b2c238299f49d3264554Jarkko 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;
10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_24_8:
10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (m_format.order)
10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TextureFormat::D:		*((deUint32*)pixelPtr) = PU(color[0], 8, 24);										break;
10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TextureFormat::S:		*((deUint32*)pixelPtr) = PU(color[3], 8, 24);										break;
10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TextureFormat::DS:		*((deUint32*)pixelPtr) = PU(color[0], 8, 24) | PU((deUint32)color[3], 0, 8);		break;
10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:
10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(false);
10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_format.order == TextureFormat::DS);
10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			*((deUint32*)pixelPtr)		= color[0];
10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			*((deUint32*)(pixelPtr+4))	= PU((deUint32)color[3], 0, 8);
10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Generic path.
10306d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			int								numChannels	= getNumUsedChannels(m_format.order);
10316d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			const TextureSwizzle::Channel*	map			= getChannelWriteSwizzle(m_format.order).components;
10326d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			int								channelSize	= getChannelSize(m_format.type);
10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int c = 0; c < numChannels; c++)
10356d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			{
10366d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry				DE_ASSERT(deInRange32(map[c], TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3));
10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				intToChannel(pixelPtr + channelSize*c, color[map[c]], m_format.type);
10386d31105cb879614b2cf87193ea90215efd13bcceJarkko Pöyry			}
10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef PU
10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PixelBufferAccess::setPixDepth (float depth, int x, int y, int z) const
10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(x, 0, getWidth()));
10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(y, 0, getHeight()));
10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(z, 0, getDepth()));
10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
105207104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	deUint8* const pixelPtr = (deUint8*)getDataPtr() + z*m_pitch.z() + y*m_pitch.y() + x*m_pitch.x();
10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define PN(VAL, OFFS, BITS) (normFloatToChannel((VAL), (BITS)) << (OFFS))
10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_24_8:
10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (m_format.order)
10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TextureFormat::D:		*((deUint32*)pixelPtr) = PN(depth, 8, 24);											break;
10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TextureFormat::DS:		*((deUint32*)pixelPtr) = (*((deUint32*)pixelPtr) & 0x000000ff) | PN(depth, 8, 24);	break;
10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:
10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(false);
10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_format.order == TextureFormat::DS);
10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			*((float*)pixelPtr) = depth;
10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_format.order == TextureFormat::D || m_format.order == TextureFormat::DS);
10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			floatToChannel(pixelPtr, depth, m_format.type);
10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef PN
10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10823c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PixelBufferAccess::setPixStencil (int stencil, int x, int y, int z) const
10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(x, 0, getWidth()));
10853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(y, 0, getHeight()));
10863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(z, 0, getDepth()));
10873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
108807104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry	deUint8* const pixelPtr = (deUint8*)getDataPtr() + z*m_pitch.z() + y*m_pitch.y() + x*m_pitch.x();
10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define PU(VAL, OFFS, BITS) (uintToChannel((deUint32)(VAL), (BITS)) << (OFFS))
10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_format.type)
10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::UNSIGNED_INT_24_8:
10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (m_format.order)
10963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TextureFormat::S:		*((deUint32*)pixelPtr) = PU(stencil, 8, 24);										break;
10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TextureFormat::DS:		*((deUint32*)pixelPtr) = (*((deUint32*)pixelPtr) & 0xffffff00) | PU(stencil, 0, 8);	break;
10993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:
11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(false);
11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_format.order == TextureFormat::DS);
11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			*((deUint32*)(pixelPtr+4))	= PU((deUint32)stencil, 0, 8);
11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_format.order == TextureFormat::S)
11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				intToChannel(pixelPtr, stencil, m_format.type);
11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(m_format.order == TextureFormat::DS);
11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int stencilChannelIndex = 3;
11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				intToChannel(pixelPtr + getChannelSize(m_format.type)*stencilChannelIndex, stencil, m_format.type);
11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef PU
11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline int imod (int a, int b)
11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int m = a % b;
11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m < 0 ? m + b : m;
11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline int mirror (int a)
11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return a >= 0.0f ? a : -(1 + a);
11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Nearest-even rounding in case of tie (fractional part 0.5), otherwise ordinary rounding.
11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline float rint (float a)
11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_STATIC_ASSERT((-3 % 2 != 0) && (-4 % 2 == 0));
11403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		fracVal		= deFloatFrac(a);
11423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (fracVal != 0.5f)
11443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return deFloatRound(a); // Ordinary case.
11453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float	floorVal	= a - fracVal;
11473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool	roundUp		= (deInt64)floorVal % 2 != 0;
11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return floorVal + (roundUp ? 1.0f : 0.0f);
11503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11523c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline int wrap (Sampler::WrapMode mode, int c, int size)
11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (mode)
11553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::CLAMP_TO_BORDER:
11573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return deClamp32(c, -1, size);
11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::CLAMP_TO_EDGE:
11603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return deClamp32(c, 0, size-1);
11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::REPEAT_GL:
11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return imod(c, size);
11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::REPEAT_CL:
11663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return imod(c, size);
11673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::MIRRORED_REPEAT_GL:
11693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return (size - 1) - mirror(imod(c, 2*size) - size);
11703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::MIRRORED_REPEAT_CL:
11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return deClamp32(c, 0, size-1); // \note Actual mirroring done already in unnormalization function.
11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0;
11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Special unnormalization for REPEAT_CL and MIRRORED_REPEAT_CL wrap modes; otherwise ordinary unnormalization.
11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline float unnormalize (Sampler::WrapMode mode, float c, int size)
11823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (mode)
11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::CLAMP_TO_EDGE:
11863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::CLAMP_TO_BORDER:
11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::REPEAT_GL:
11883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::MIRRORED_REPEAT_GL: // Fall-through (ordinary case).
11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return (float)size*c;
11903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::REPEAT_CL:
11923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return (float)size * (c - deFloatFloor(c));
11933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::MIRRORED_REPEAT_CL:
11953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return (float)size * deFloatAbs(c - 2.0f * rint(0.5f * c));
11963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
12003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isFixedPointDepthTextureFormat (const tcu::TextureFormat& format)
12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (format.order == TextureFormat::D)
12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// depth internal formats cannot be non-normalized integers
12103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return channelClass != tcu::TEXTURECHANNELCLASS_FLOATING_POINT;
12113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (format.order == TextureFormat::DS)
12133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// combined formats have no single channel class, detect format manually
12153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		switch (format.type)
12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:	return false;
12183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case tcu::TextureFormat::UNSIGNED_INT_24_8:				return true;
12193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			default:
12213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
12223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// unknown format
12233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(false);
12243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return true;
12253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
12263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return false;
12303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texel lookup with color conversion.
12333c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline Vec4 lookup (const ConstPixelBufferAccess& access, int i, int j, int k)
12343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 p = access.getPixel(i, j, k);
12363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return isSRGB(access.getFormat()) ? sRGBToLinear(p) : p;
12373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12393c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline float execCompare (const tcu::Vec4& color, Sampler::CompareMode compare, int chanNdx, float ref_, bool isFixedPoint)
12403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool	clampValues	= isFixedPoint;	// if comparing against a floating point texture, ref (and value) is not clamped
12423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	cmp			= (clampValues) ? (de::clamp(color[chanNdx], 0.0f, 1.0f)) : (color[chanNdx]);
12433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	ref			= (clampValues) ? (de::clamp(ref_, 0.0f, 1.0f)) : (ref_);
12443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		res			= false;
12453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (compare)
12473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_LESS:				res = ref < cmp;	break;
12493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_LESS_OR_EQUAL:	res = ref <= cmp;	break;
12503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_GREATER:			res = ref > cmp;	break;
12513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_GREATER_OR_EQUAL:	res = ref >= cmp;	break;
12523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_EQUAL:			res = ref == cmp;	break;
12533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_NOT_EQUAL:		res = ref != cmp;	break;
12543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_ALWAYS:			res = true;			break;
12553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::COMPAREMODE_NEVER:			res = false;		break;
12563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
12573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
12583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return res ? 1.0f : 0.0f;
12613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12633c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleNearest1D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, const IVec2& offset)
12643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int width	= access.getWidth();
12663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x = deFloorFloatToInt32(u)+offset.x();
12683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check for CLAMP_TO_BORDER.
12703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.wrapS == Sampler::CLAMP_TO_BORDER && !deInBounds32(x, 0, width))
12713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sampler.borderColor;
12723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i = wrap(sampler.wrapS, x, width);
12743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return lookup(access, i, offset.y(), 0);
12763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12783c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleNearest2D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, float v, const IVec3& offset)
12793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int width	= access.getWidth();
12813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int height	= access.getHeight();
12823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x = deFloorFloatToInt32(u)+offset.x();
12843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y = deFloorFloatToInt32(v)+offset.y();
12853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check for CLAMP_TO_BORDER.
12873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if ((sampler.wrapS == Sampler::CLAMP_TO_BORDER && !deInBounds32(x, 0, width)) ||
12883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		(sampler.wrapT == Sampler::CLAMP_TO_BORDER && !deInBounds32(y, 0, height)))
12893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sampler.borderColor;
12903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i = wrap(sampler.wrapS, x, width);
12923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j = wrap(sampler.wrapT, y, height);
12933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return lookup(access, i, j, offset.z());
12953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12973c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleNearest3D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, float v, float w, const IVec3& offset)
12983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int width	= access.getWidth();
13003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int height	= access.getHeight();
13013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int depth	= access.getDepth();
13023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x = deFloorFloatToInt32(u)+offset.x();
13043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y = deFloorFloatToInt32(v)+offset.y();
13053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int z = deFloorFloatToInt32(w)+offset.z();
13063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check for CLAMP_TO_BORDER.
13083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if ((sampler.wrapS == Sampler::CLAMP_TO_BORDER && !deInBounds32(x, 0, width))	||
13093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		(sampler.wrapT == Sampler::CLAMP_TO_BORDER && !deInBounds32(y, 0, height))	||
13103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		(sampler.wrapR == Sampler::CLAMP_TO_BORDER && !deInBounds32(z, 0, depth)))
13113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sampler.borderColor;
13123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i = wrap(sampler.wrapS, x, width);
13143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j = wrap(sampler.wrapT, y, height);
13153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int k = wrap(sampler.wrapR, z, depth);
13163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return lookup(access, i, j, k);
13183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13203c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleLinear1D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, const IVec2& offset)
13213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int w = access.getWidth();
13233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x0 = deFloorFloatToInt32(u-0.5f)+offset.x();
13253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x1 = x0+1;
13263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i0 = wrap(sampler.wrapS, x0, w);
13283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i1 = wrap(sampler.wrapS, x1, w);
13293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
13313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i0UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i0, 0, w);
13333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i1UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i1, 0, w);
13343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Border color for out-of-range coordinates if using CLAMP_TO_BORDER, otherwise execute lookups.
13363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 p0 = i0UseBorder ? sampler.borderColor : lookup(access, i0, offset.y(), 0);
13373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 p1 = i1UseBorder ? sampler.borderColor : lookup(access, i1, offset.y(), 0);
13383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
13403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return p0 * (1.0f - a) + p1 * a;
13413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13433c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleLinear2D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, float v, const IVec3& offset)
13443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int w = access.getWidth();
13463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int h = access.getHeight();
13473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x0 = deFloorFloatToInt32(u-0.5f)+offset.x();
13493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x1 = x0+1;
13503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y0 = deFloorFloatToInt32(v-0.5f)+offset.y();
13513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y1 = y0+1;
13523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i0 = wrap(sampler.wrapS, x0, w);
13543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i1 = wrap(sampler.wrapS, x1, w);
13553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j0 = wrap(sampler.wrapT, y0, h);
13563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j1 = wrap(sampler.wrapT, y1, h);
13573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
13593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float b = deFloatFrac(v-0.5f);
13603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i0UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i0, 0, w);
13623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i1UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i1, 0, w);
13633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool j0UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j0, 0, h);
13643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool j1UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j1, 0, h);
13653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Border color for out-of-range coordinates if using CLAMP_TO_BORDER, otherwise execute lookups.
13673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 p00 = (i0UseBorder || j0UseBorder) ? sampler.borderColor : lookup(access, i0, j0, offset.z());
13683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 p10 = (i1UseBorder || j0UseBorder) ? sampler.borderColor : lookup(access, i1, j0, offset.z());
13693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 p01 = (i0UseBorder || j1UseBorder) ? sampler.borderColor : lookup(access, i0, j1, offset.z());
13703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 p11 = (i1UseBorder || j1UseBorder) ? sampler.borderColor : lookup(access, i1, j1, offset.z());
13713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
13733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (p00*(1.0f-a)*(1.0f-b)) +
13743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p10*(     a)*(1.0f-b)) +
13753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p01*(1.0f-a)*(     b)) +
13763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p11*(     a)*(     b));
13773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13793c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float sampleLinear1DCompare (const ConstPixelBufferAccess& access, const Sampler& sampler, float ref, float u, const IVec2& offset, bool isFixedPointDepthFormat)
13803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int w = access.getWidth();
13823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x0 = deFloorFloatToInt32(u-0.5f)+offset.x();
13843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x1 = x0+1;
13853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i0 = wrap(sampler.wrapS, x0, w);
13873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i1 = wrap(sampler.wrapS, x1, w);
13883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
13903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i0UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i0, 0, w);
13923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i1UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i1, 0, w);
13933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Border color for out-of-range coordinates if using CLAMP_TO_BORDER, otherwise execute lookups.
13953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 p0Clr = i0UseBorder  ? sampler.borderColor : lookup(access, i0, offset.y(), 0);
13963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 p1Clr = i1UseBorder  ? sampler.borderColor : lookup(access, i1, offset.y(), 0);
13973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Execute comparisons.
13993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float p0 = execCompare(p0Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat);
14003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float p1 = execCompare(p1Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat);
14013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
14033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (p0 * (1.0f - a)) + (p1 * a);
14043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14063c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float sampleLinear2DCompare (const ConstPixelBufferAccess& access, const Sampler& sampler, float ref, float u, float v, const IVec3& offset, bool isFixedPointDepthFormat)
14073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int w = access.getWidth();
14093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int h = access.getHeight();
14103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x0 = deFloorFloatToInt32(u-0.5f)+offset.x();
14123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x1 = x0+1;
14133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y0 = deFloorFloatToInt32(v-0.5f)+offset.y();
14143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y1 = y0+1;
14153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i0 = wrap(sampler.wrapS, x0, w);
14173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i1 = wrap(sampler.wrapS, x1, w);
14183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j0 = wrap(sampler.wrapT, y0, h);
14193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j1 = wrap(sampler.wrapT, y1, h);
14203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
14223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float b = deFloatFrac(v-0.5f);
14233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i0UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i0, 0, w);
14253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i1UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i1, 0, w);
14263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool j0UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j0, 0, h);
14273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool j1UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j1, 0, h);
14283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Border color for out-of-range coordinates if using CLAMP_TO_BORDER, otherwise execute lookups.
14303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 p00Clr = (i0UseBorder || j0UseBorder) ? sampler.borderColor : lookup(access, i0, j0, offset.z());
14313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 p10Clr = (i1UseBorder || j0UseBorder) ? sampler.borderColor : lookup(access, i1, j0, offset.z());
14323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 p01Clr = (i0UseBorder || j1UseBorder) ? sampler.borderColor : lookup(access, i0, j1, offset.z());
14333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 p11Clr = (i1UseBorder || j1UseBorder) ? sampler.borderColor : lookup(access, i1, j1, offset.z());
14343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Execute comparisons.
14363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float p00 = execCompare(p00Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat);
14373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float p10 = execCompare(p10Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat);
14383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float p01 = execCompare(p01Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat);
14393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float p11 = execCompare(p11Clr, sampler.compare, sampler.compareChannel, ref, isFixedPointDepthFormat);
14403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
14423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (p00*(1.0f-a)*(1.0f-b)) +
14433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p10*(     a)*(1.0f-b)) +
14443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p01*(1.0f-a)*(     b)) +
14453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p11*(     a)*(     b));
14463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14483c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleLinear3D (const ConstPixelBufferAccess& access, const Sampler& sampler, float u, float v, float w, const IVec3& offset)
14493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int width	= access.getWidth();
14513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int height	= access.getHeight();
14523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int depth	= access.getDepth();
14533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x0 = deFloorFloatToInt32(u-0.5f)+offset.x();
14553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int x1 = x0+1;
14563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y0 = deFloorFloatToInt32(v-0.5f)+offset.y();
14573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int y1 = y0+1;
14583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int z0 = deFloorFloatToInt32(w-0.5f)+offset.z();
14593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int z1 = z0+1;
14603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i0 = wrap(sampler.wrapS, x0, width);
14623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int i1 = wrap(sampler.wrapS, x1, width);
14633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j0 = wrap(sampler.wrapT, y0, height);
14643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int j1 = wrap(sampler.wrapT, y1, height);
14653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int k0 = wrap(sampler.wrapR, z0, depth);
14663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int k1 = wrap(sampler.wrapR, z1, depth);
14673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
14693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float b = deFloatFrac(v-0.5f);
14703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float c = deFloatFrac(w-0.5f);
14713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i0UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i0, 0, width);
14733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool i1UseBorder = sampler.wrapS == Sampler::CLAMP_TO_BORDER && !de::inBounds(i1, 0, width);
14743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool j0UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j0, 0, height);
14753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool j1UseBorder = sampler.wrapT == Sampler::CLAMP_TO_BORDER && !de::inBounds(j1, 0, height);
14763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool k0UseBorder = sampler.wrapR == Sampler::CLAMP_TO_BORDER && !de::inBounds(k0, 0, depth);
14773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool k1UseBorder = sampler.wrapR == Sampler::CLAMP_TO_BORDER && !de::inBounds(k1, 0, depth);
14783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Border color for out-of-range coordinates if using CLAMP_TO_BORDER, otherwise execute lookups.
14803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 p000 = (i0UseBorder || j0UseBorder || k0UseBorder) ? sampler.borderColor : lookup(access, i0, j0, k0);
14813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 p100 = (i1UseBorder || j0UseBorder || k0UseBorder) ? sampler.borderColor : lookup(access, i1, j0, k0);
14823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 p010 = (i0UseBorder || j1UseBorder || k0UseBorder) ? sampler.borderColor : lookup(access, i0, j1, k0);
14833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 p110 = (i1UseBorder || j1UseBorder || k0UseBorder) ? sampler.borderColor : lookup(access, i1, j1, k0);
14843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 p001 = (i0UseBorder || j0UseBorder || k1UseBorder) ? sampler.borderColor : lookup(access, i0, j0, k1);
14853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 p101 = (i1UseBorder || j0UseBorder || k1UseBorder) ? sampler.borderColor : lookup(access, i1, j0, k1);
14863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 p011 = (i0UseBorder || j1UseBorder || k1UseBorder) ? sampler.borderColor : lookup(access, i0, j1, k1);
14873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 p111 = (i1UseBorder || j1UseBorder || k1UseBorder) ? sampler.borderColor : lookup(access, i1, j1, k1);
14883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
14903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (p000*(1.0f-a)*(1.0f-b)*(1.0f-c)) +
14913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p100*(     a)*(1.0f-b)*(1.0f-c)) +
14923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p010*(1.0f-a)*(     b)*(1.0f-c)) +
14933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p110*(     a)*(     b)*(1.0f-c)) +
14943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p001*(1.0f-a)*(1.0f-b)*(     c)) +
14953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p101*(     a)*(1.0f-b)*(     c)) +
14963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p011*(1.0f-a)*(     b)*(     c)) +
14973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (p111*(     a)*(     b)*(     c));
14983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15003c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 ConstPixelBufferAccess::sample1D (const Sampler& sampler, Sampler::FilterMode filter, float s, int level) const
15013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1502612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// check selected layer exists
150329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(level, 0, m_size.y()));
15043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1505612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	return sample1DOffset(sampler, filter, s, tcu::IVec2(0, level));
15063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15083c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 ConstPixelBufferAccess::sample2D (const Sampler& sampler, Sampler::FilterMode filter, float s, float t, int depth) const
15093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1510612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// check selected layer exists
151129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(depth, 0, m_size.z()));
15123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1513612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	return sample2DOffset(sampler, filter, s, t, tcu::IVec3(0, 0, depth));
1514612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry}
15153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1516612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko PöyryVec4 ConstPixelBufferAccess::sample3D (const Sampler& sampler, Sampler::FilterMode filter, float s, float t, float r) const
1517612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry{
1518612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	return sample3DOffset(sampler, filter, s, t, r, tcu::IVec3(0, 0, 0));
15193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15213c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 ConstPixelBufferAccess::sample1DOffset (const Sampler& sampler, Sampler::FilterMode filter, float s, const IVec2& offset) const
15223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1523612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// check selected layer exists
1524612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// \note offset.x is X offset, offset.y is the selected layer
1525612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	DE_ASSERT(de::inBounds(offset.y(), 0, m_size.y()));
15263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
15283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float u = s;
15293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
153129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		u = unnormalize(sampler.wrapS, s, m_size.x());
15323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filter)
15343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return sampleNearest1D	(*this, sampler, u, offset);
15363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return sampleLinear1D	(*this, sampler, u, offset);
15373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
15383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
15393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
15403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15433c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 ConstPixelBufferAccess::sample2DOffset (const Sampler& sampler, Sampler::FilterMode filter, float s, float t, const IVec3& offset) const
15443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1545612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// check selected layer exists
1546612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// \note offset.xy is the XY offset, offset.z is the selected layer
154729340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	DE_ASSERT(de::inBounds(offset.z(), 0, m_size.z()));
15483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
15503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float u = s;
15513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float v = t;
15523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
15543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
155529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		u = unnormalize(sampler.wrapS, s, m_size.x());
155629340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		v = unnormalize(sampler.wrapT, t, m_size.y());
15573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filter)
15603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return sampleNearest2D	(*this, sampler, u, v, offset);
15623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return sampleLinear2D	(*this, sampler, u, v, offset);
15633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
15643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
15653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
15663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1569612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko PöyryVec4 ConstPixelBufferAccess::sample3DOffset (const Sampler& sampler, Sampler::FilterMode filter, float s, float t, float r, const IVec3& offset) const
15703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
15723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float u = s;
1573612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	float v = t;
1574612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	float w = r;
15753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
1577612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	{
157829340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		u = unnormalize(sampler.wrapS, s, m_size.x());
1579612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		v = unnormalize(sampler.wrapT, t, m_size.y());
1580612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		w = unnormalize(sampler.wrapR, r, m_size.z());
1581612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	}
15823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filter)
15843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1585612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		case Sampler::NEAREST:	return sampleNearest3D	(*this, sampler, u, v, w, offset);
1586612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		case Sampler::LINEAR:	return sampleLinear3D	(*this, sampler, u, v, w, offset);
15873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
15883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
1589612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry			return Vec4(0.0f);
15903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1593612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyryfloat ConstPixelBufferAccess::sample1DCompare (const Sampler& sampler, Sampler::FilterMode filter, float ref, float s, const IVec2& offset) const
15943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1595612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// check selected layer exists
1596612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// \note offset.x is X offset, offset.y is the selected layer
1597612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	DE_ASSERT(de::inBounds(offset.y(), 0, m_size.y()));
15983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Format information for comparison function
16003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool isFixedPointDepth = isFixedPointDepthTextureFormat(m_format);
16013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
16033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float u = s;
16043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
160629340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		u = unnormalize(sampler.wrapS, s, m_size.x());
16073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filter)
16093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1610612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		case Sampler::NEAREST:	return execCompare(sampleNearest1D(*this, sampler, u, offset), sampler.compare, sampler.compareChannel, ref, isFixedPointDepth);
1611612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		case Sampler::LINEAR:	return sampleLinear1DCompare(*this, sampler, ref, u, offset, isFixedPointDepth);
16123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
16133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
16143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
16153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1618612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyryfloat ConstPixelBufferAccess::sample2DCompare (const Sampler& sampler, Sampler::FilterMode filter, float ref, float s, float t, const IVec3& offset) const
16193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1620612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// check selected layer exists
1621612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// \note offset.xy is XY offset, offset.z is the selected layer
1622612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	DE_ASSERT(de::inBounds(offset.z(), 0, m_size.z()));
16233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1624612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	// Format information for comparison function
1625612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry	const bool isFixedPointDepth = isFixedPointDepthTextureFormat(m_format);
16263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
16283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float u = s;
16293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float v = t;
16303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
16323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
163329340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		u = unnormalize(sampler.wrapS, s, m_size.x());
163429340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi		v = unnormalize(sampler.wrapT, t, m_size.y());
16353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filter)
16383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1639612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		case Sampler::NEAREST:	return execCompare(sampleNearest2D(*this, sampler, u, v, offset), sampler.compare, sampler.compareChannel, ref, isFixedPointDepth);
1640612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry		case Sampler::LINEAR:	return sampleLinear2DCompare(*this, sampler, ref, u, v, offset, isFixedPointDepth);
16413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
16423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
1643612e371273c0f7a5b618569ad5995ca4b61b4502Jarkko Pöyry			return 0.0f;
16443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16473c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevel::TextureLevel (void)
16483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	()
164929340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size	(0)
16503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16533c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevel::TextureLevel (const TextureFormat& format)
16543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	(format)
165529340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size	(0)
16563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16593c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevel::TextureLevel (const TextureFormat& format, int width, int height, int depth)
16603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	(format)
166129340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	, m_size	(0)
16623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	setSize(width, height, depth);
16643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16663c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevel::~TextureLevel (void)
16673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16703c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureLevel::setStorage (const TextureFormat& format, int width, int height, int depth)
16713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_format = format;
16733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	setSize(width, height, depth);
16743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16763c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureLevel::setSize (int width, int height, int depth)
16773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int pixelSize = m_format.getPixelSize();
16793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
168029340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	m_size = IVec3(width, height, depth);
16813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
168229340067e919854db7d50bb8c0b666117b229f5eMika Isojärvi	m_data.setStorage(m_size.x() * m_size.y() * m_size.z() * pixelSize);
16833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16853c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 sampleLevelArray1D (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, int depth, float lod)
16863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16871d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry	return sampleLevelArray1DOffset(levels, numLevels, sampler, s, lod, IVec2(0, depth)); // y-offset in 1D textures is layer selector
16881d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry}
16893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16901d75d23528999118c1911ed100d1d063b06040daJarkko PöyryVec4 sampleLevelArray2D (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, int depth, float lod)
16911d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry{
16921d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry	return sampleLevelArray2DOffset(levels, numLevels, sampler, s, t, lod, IVec3(0, 0, depth)); // z-offset in 2D textures is layer selector
16931d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry}
16943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16951d75d23528999118c1911ed100d1d063b06040daJarkko PöyryVec4 sampleLevelArray3D (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, float r, float lod)
16961d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry{
16971d75d23528999118c1911ed100d1d063b06040daJarkko Pöyry	return sampleLevelArray3DOffset(levels, numLevels, sampler, s, t, r, lod, IVec3(0, 0, 0));
16983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17003c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 sampleLevelArray1DOffset (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float lod, const IVec2& offset)
17013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
17033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
17043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
17063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return levels[0].sample1DOffset(sampler, filterMode, s, offset);
17083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return levels[0].sample1DOffset(sampler, filterMode, s, offset);
17093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
17113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
17123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
17143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
17153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
17163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return levels[level].sample1DOffset(sampler, levelFilter, s, offset);
17183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
17213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
17223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
17243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
17253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level1		= de::min(maxLevel, level0 + 1);
17263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
17273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				f			= deFloatFrac(lod);
17283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4			t0			= levels[level0].sample1DOffset(sampler, levelFilter, s, offset);
17293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4			t1			= levels[level1].sample1DOffset(sampler, levelFilter, s, offset);
17303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
17323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
17353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
17363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
17373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17403c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 sampleLevelArray2DOffset (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, float lod, const IVec3& offset)
17413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
17433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
17443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
17463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return levels[0].sample2DOffset(sampler, filterMode, s, t, offset);
17483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return levels[0].sample2DOffset(sampler, filterMode, s, t, offset);
17493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
17513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
17523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
17543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
17553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
17563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return levels[level].sample2DOffset(sampler, levelFilter, s, t, offset);
17583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
17613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
17623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
17643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
17653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level1		= de::min(maxLevel, level0 + 1);
17663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
17673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				f			= deFloatFrac(lod);
17683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4			t0			= levels[level0].sample2DOffset(sampler, levelFilter, s, t, offset);
17693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4			t1			= levels[level1].sample2DOffset(sampler, levelFilter, s, t, offset);
17703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
17723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
17753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
17763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
17773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17803c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 sampleLevelArray3DOffset (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, float r, float lod, const IVec3& offset)
17813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
17833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
17843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
17863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return levels[0].sample3DOffset(sampler, filterMode, s, t, r, offset);
17883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return levels[0].sample3DOffset(sampler, filterMode, s, t, r, offset);
17893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
17913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
17923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
17943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
17953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
17963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return levels[level].sample3DOffset(sampler, levelFilter, s, t, r, offset);
17983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
18013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
18023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
18033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
18043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
18053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level1		= de::min(maxLevel, level0 + 1);
18063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
18073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				f			= deFloatFrac(lod);
18083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4			t0			= levels[level0].sample3DOffset(sampler, levelFilter, s, t, r, offset);
18093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Vec4			t1			= levels[level1].sample3DOffset(sampler, levelFilter, s, t, r, offset);
18103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
18123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
18133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
18153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
18163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
18173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18203c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat sampleLevelArray1DCompare (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float ref, float s, float lod, const IVec2& offset)
18213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
18233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
18243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
18263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return levels[0].sample1DCompare(sampler, filterMode, ref, s, offset);
18283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return levels[0].sample1DCompare(sampler, filterMode, ref, s, offset);
18293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
18313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
18323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
18333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
18343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
18353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
18363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return levels[level].sample1DCompare(sampler, levelFilter, ref, s, offset);
18383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
18393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
18413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
18423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
18433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
18443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
18453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level1		= de::min(maxLevel, level0 + 1);
18463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
18473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				f			= deFloatFrac(lod);
18483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				t0			= levels[level0].sample1DCompare(sampler, levelFilter, ref, s, offset);
18493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				t1			= levels[level1].sample1DCompare(sampler, levelFilter, ref, s, offset);
18503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
18523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
18533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
18553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
18563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
18573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat sampleLevelArray2DCompare (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float ref, float s, float t, float lod, const IVec3& offset)
18613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
18633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
18643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
18663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:	return levels[0].sample2DCompare(sampler, filterMode, ref, s, t, offset);
18683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:	return levels[0].sample2DCompare(sampler, filterMode, ref, s, t, offset);
18693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
18713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
18723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
18733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
18743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
18753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
18763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return levels[level].sample2DCompare(sampler, levelFilter, ref, s, t, offset);
18783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
18793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
18813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
18823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
18833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					maxLevel	= (int)numLevels-1;
18843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
18853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					level1		= de::min(maxLevel, level0 + 1);
18863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode	levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
18873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				f			= deFloatFrac(lod);
18883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				t0			= levels[level0].sample2DCompare(sampler, levelFilter, ref, s, t, offset);
18893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float				t1			= levels[level1].sample2DCompare(sampler, levelFilter, ref, s, t, offset);
18903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
18923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
18933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
18953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
18963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
18973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19003c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 gatherArray2DOffsets (const ConstPixelBufferAccess& src, const Sampler& sampler, float s, float t, int depth, int componentNdx, const IVec2 (&offsets)[4])
19013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare == Sampler::COMPAREMODE_NONE);
19033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(componentNdx, 0, 4));
19043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		w	= src.getWidth();
19063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		h	= src.getHeight();
19073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float		u	= unnormalize(sampler.wrapS, s, w);
19083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float		v	= unnormalize(sampler.wrapT, t, h);
19093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		x0	= deFloorFloatToInt32(u-0.5f);
19103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		y0	= deFloorFloatToInt32(v-0.5f);
19113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec2 samplePositions[4];
19133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < DE_LENGTH_OF_ARRAY(samplePositions); i++)
19143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		samplePositions[i] = IVec2(wrap(sampler.wrapS, x0 + offsets[i].x(), w),
19153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								   wrap(sampler.wrapT, y0 + offsets[i].y(), h));
19163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 result;
19183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
19193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Vec4 pixel = lookup(src, samplePositions[i].x(), samplePositions[i].y(), depth);
19213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result[i] = pixel[componentNdx];
19223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
19253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19273c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 gatherArray2DOffsetsCompare (const ConstPixelBufferAccess& src, const Sampler& sampler, float ref, float s, float t, int depth, const IVec2 (&offsets)[4])
19283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare != Sampler::COMPAREMODE_NONE);
19303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(src.getFormat().order == TextureFormat::D || src.getFormat().order == TextureFormat::DS);
19313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compareChannel == 0);
19323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler noCompareSampler = sampler;
19343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	noCompareSampler.compare = Sampler::COMPAREMODE_NONE;
19353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec4	gathered			= gatherArray2DOffsets(src, noCompareSampler, s, t, depth, 0 /* component 0: depth */, offsets);
19373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool	isFixedPoint		= isFixedPointDepthTextureFormat(src.getFormat());
19383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 result;
19393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
19403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result[i] = execCompare(gathered, sampler.compare, i, ref, isFixedPoint);
19413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
19433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19453c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleCubeSeamlessNearest (const ConstPixelBufferAccess& faceAccess, const Sampler& sampler, float s, float t, int depth)
19463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler clampingSampler = sampler;
19483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	clampingSampler.wrapS = Sampler::CLAMP_TO_EDGE;
19493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	clampingSampler.wrapT = Sampler::CLAMP_TO_EDGE;
19503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return faceAccess.sample2D(clampingSampler, Sampler::NEAREST, s, t, depth);
19513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19533c827367444ee418f129b2c238299f49d3264554Jarkko PoyryCubeFace selectCubeFace (const Vec3& coords)
19543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	x	= coords.x();
19563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	y	= coords.y();
19573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	z	= coords.z();
19583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	ax	= deFloatAbs(x);
19593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	ay	= deFloatAbs(y);
19603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	az	= deFloatAbs(z);
19613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (ay < ax && az < ax)
19633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return x >= 0.0f ? CUBEFACE_POSITIVE_X : CUBEFACE_NEGATIVE_X;
19643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (ax < ay && az < ay)
19653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return y >= 0.0f ? CUBEFACE_POSITIVE_Y : CUBEFACE_NEGATIVE_Y;
19663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (ax < az && ay < az)
19673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return z >= 0.0f ? CUBEFACE_POSITIVE_Z : CUBEFACE_NEGATIVE_Z;
19683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
19693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Some of the components are equal. Use tie-breaking rule.
19713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (ax == ay)
19723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (ax < az)
19743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return z >= 0.0f ? CUBEFACE_POSITIVE_Z : CUBEFACE_NEGATIVE_Z;
19753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
19763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return x >= 0.0f ? CUBEFACE_POSITIVE_X : CUBEFACE_NEGATIVE_X;
19773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
19783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (ax == az)
19793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (az < ay)
19813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return y >= 0.0f ? CUBEFACE_POSITIVE_Y : CUBEFACE_NEGATIVE_Y;
19823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
19833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return z >= 0.0f ? CUBEFACE_POSITIVE_Z : CUBEFACE_NEGATIVE_Z;
19843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
19853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (ay == az)
19863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (ay < ax)
19883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return x >= 0.0f ? CUBEFACE_POSITIVE_X : CUBEFACE_NEGATIVE_X;
19893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
19903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return y >= 0.0f ? CUBEFACE_POSITIVE_Y : CUBEFACE_NEGATIVE_Y;
19913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
19923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
19933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return x >= 0.0f ? CUBEFACE_POSITIVE_X : CUBEFACE_NEGATIVE_X;
19943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19973c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec2 projectToFace (CubeFace face, const Vec3& coord)
19983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	rx		= coord.x();
20003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	ry		= coord.y();
20013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	rz		= coord.z();
20023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		sc		= 0.0f;
20033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		tc		= 0.0f;
20043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		ma		= 0.0f;
20053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		s;
20063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		t;
20073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (face)
20093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_X: sc = +rz; tc = -ry; ma = -rx; break;
20113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_X: sc = -rz; tc = -ry; ma = +rx; break;
20123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_Y: sc = +rx; tc = -rz; ma = -ry; break;
20133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_Y: sc = +rx; tc = +rz; ma = +ry; break;
20143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_Z: sc = -rx; tc = -ry; ma = -rz; break;
20153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_Z: sc = +rx; tc = -ry; ma = +rz; break;
20163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
20173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
20183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute s, t
20213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	s = ((sc / ma) + 1.0f) / 2.0f;
20223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	t = ((tc / ma) + 1.0f) / 2.0f;
20233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return Vec2(s, t);
20253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20273c827367444ee418f129b2c238299f49d3264554Jarkko PoyryCubeFaceFloatCoords getCubeFaceCoords (const Vec3& coords)
20283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CubeFace face = selectCubeFace(coords);
20303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return CubeFaceFloatCoords(face, projectToFace(face, coords));
20313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20333c827367444ee418f129b2c238299f49d3264554Jarkko 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.
20343c827367444ee418f129b2c238299f49d3264554Jarkko 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.
20353c827367444ee418f129b2c238299f49d3264554Jarkko PoyryCubeFaceIntCoords remapCubeEdgeCoords (const CubeFaceIntCoords& origCoords, int size)
20363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool uInBounds = de::inBounds(origCoords.s, 0, size);
20383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool vInBounds = de::inBounds(origCoords.t, 0, size);
20393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (uInBounds && vInBounds)
20413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return origCoords;
20423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!uInBounds && !vInBounds)
20443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_LAST, -1, -1);
20453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec2 coords(wrap(Sampler::CLAMP_TO_BORDER, origCoords.s, size),
20473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				 wrap(Sampler::CLAMP_TO_BORDER, origCoords.t, size));
20483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec3 canonizedCoords;
20493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Map the uv coordinates to canonized 3d coordinates.
20513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (origCoords.face)
20533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_X: canonizedCoords = IVec3(0,					size-1-coords.y(),	coords.x());			break;
20553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_X: canonizedCoords = IVec3(size-1,				size-1-coords.y(),	size-1-coords.x());		break;
20563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_Y: canonizedCoords = IVec3(coords.x(),			0,					size-1-coords.y());		break;
20573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_Y: canonizedCoords = IVec3(coords.x(),			size-1,				coords.y());			break;
20583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_Z: canonizedCoords = IVec3(size-1-coords.x(),	size-1-coords.y(),	0);						break;
20593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_Z: canonizedCoords = IVec3(coords.x(),			size-1-coords.y(),	size-1);				break;
20603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default: DE_ASSERT(false);
20613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Find an appropriate face to re-map the coordinates to.
20643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (canonizedCoords.x() == -1)
20663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_NEGATIVE_X, IVec2(canonizedCoords.z(), size-1-canonizedCoords.y()));
20673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (canonizedCoords.x() == size)
20693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_POSITIVE_X, IVec2(size-1-canonizedCoords.z(), size-1-canonizedCoords.y()));
20703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (canonizedCoords.y() == -1)
20723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_NEGATIVE_Y, IVec2(canonizedCoords.x(), size-1-canonizedCoords.z()));
20733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (canonizedCoords.y() == size)
20753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_POSITIVE_Y, IVec2(canonizedCoords.x(), canonizedCoords.z()));
20763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (canonizedCoords.z() == -1)
20783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_NEGATIVE_Z, IVec2(size-1-canonizedCoords.x(), size-1-canonizedCoords.y()));
20793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (canonizedCoords.z() == size)
20813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CubeFaceIntCoords(CUBEFACE_POSITIVE_Z, IVec2(canonizedCoords.x(), size-1-canonizedCoords.y()));
20823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(false);
20843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return CubeFaceIntCoords(CUBEFACE_LAST, IVec2(-1));
20853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20873c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void getCubeLinearSamples (const ConstPixelBufferAccess (&faceAccesses)[CUBEFACE_LAST], CubeFace baseFace, float u, float v, int depth, Vec4 (&dst)[4])
20883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(faceAccesses[0].getWidth() == faceAccesses[0].getHeight());
20903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		size					= faceAccesses[0].getWidth();
20913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		x0						= deFloorFloatToInt32(u-0.5f);
20923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		x1						= x0+1;
20933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		y0						= deFloorFloatToInt32(v-0.5f);
20943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		y1						= y0+1;
20953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec2	baseSampleCoords[4]		=
20963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x0, y0),
20983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x1, y0),
20993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x0, y1),
21003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x1, y1)
21013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
21023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4	sampleColors[4];
21033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool	hasBothCoordsOutOfBounds[4]; //!< Whether correctCubeFace() returns CUBEFACE_LAST, i.e. both u and v are out of bounds.
21043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Find correct faces and coordinates for out-of-bounds sample coordinates.
21063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
21083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CubeFaceIntCoords coords = remapCubeEdgeCoords(CubeFaceIntCoords(baseFace, baseSampleCoords[i]), size);
21103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		hasBothCoordsOutOfBounds[i] = coords.face == CUBEFACE_LAST;
21113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!hasBothCoordsOutOfBounds[i])
21123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sampleColors[i] = lookup(faceAccesses[coords.face], coords.s, coords.t, depth);
21133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
21143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21153c827367444ee418f129b2c238299f49d3264554Jarkko 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.
21163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note This averaging behavior is not required by the GLES3 spec (though it is recommended). GLES3 spec only
21173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//		 requires that if the three other samples all have the same color, then the doubly-out-of-bounds sample
21183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//		 must have this color as well.
21193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int bothOutOfBoundsNdx = -1;
21223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < 4; i++)
21233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (hasBothCoordsOutOfBounds[i])
21253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
21263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(bothOutOfBoundsNdx < 0); // Only one sample can be out of bounds in both u and v.
21273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				bothOutOfBoundsNdx = i;
21283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
21293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
21303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (bothOutOfBoundsNdx != -1)
21313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sampleColors[bothOutOfBoundsNdx] = Vec4(0.0f);
21333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < 4; i++)
21343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (i != bothOutOfBoundsNdx)
21353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					sampleColors[bothOutOfBoundsNdx] += sampleColors[i];
21363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sampleColors[bothOutOfBoundsNdx] = sampleColors[bothOutOfBoundsNdx] * (1.0f/3.0f);
21383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
21393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
21403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < DE_LENGTH_OF_ARRAY(sampleColors); i++)
21423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dst[i] = sampleColors[i];
21433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
21443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \todo [2014-02-19 pyry] Optimize faceAccesses
21463c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleCubeSeamlessLinear (const ConstPixelBufferAccess (&faceAccesses)[CUBEFACE_LAST], CubeFace baseFace, const Sampler& sampler, float s, float t, int depth)
21473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
21483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(faceAccesses[0].getWidth() == faceAccesses[0].getHeight());
21493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		size	= faceAccesses[0].getWidth();
21513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
21523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float	u		= s;
21533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float	v		= t;
21543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
21563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		u = unnormalize(sampler.wrapS, s, size);
21583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		v = unnormalize(sampler.wrapT, t, size);
21593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
21603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Get sample colors.
21623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 sampleColors[4];
21643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	getCubeLinearSamples(faceAccesses, baseFace, u, v, depth, sampleColors);
21653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
21673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
21693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float b = deFloatFrac(v-0.5f);
21703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (sampleColors[0]*(1.0f-a)*(1.0f-b)) +
21723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (sampleColors[1]*(     a)*(1.0f-b)) +
21733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (sampleColors[2]*(1.0f-a)*(     b)) +
21743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (sampleColors[3]*(     a)*(     b));
21753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
21763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21773c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleLevelArrayCubeSeamless (const ConstPixelBufferAccess* const (&faces)[CUBEFACE_LAST], int numLevels, CubeFace face, const Sampler& sampler, float s, float t, int depth, float lod)
21783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
21793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
21803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
21813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
21833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:
21853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessNearest(faces[face][0], sampler, s, t, depth);
21863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:
21883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
21903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < (int)CUBEFACE_LAST; i++)
21913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				faceAccesses[i] = faces[i][0];
21923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessLinear(faceAccesses, face, sampler, s, t, depth);
21943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
21953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
21973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
21983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
22003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
22013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
22023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
22043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessNearest(faces[face][level], sampler, s, t, depth);
22053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
22063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
22073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
22083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
22103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
22113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses[i] = faces[i][level];
22123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessLinear(faceAccesses, face, sampler, s, t, depth);
22143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
22153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
22183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
22193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
22213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
22223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level1		= de::min(maxLevel, level0 + 1);
22233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
22243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					f			= deFloatFrac(lod);
22253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec4					t0;
22263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec4					t1;
22273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
22293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
22303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessNearest(faces[face][level0], sampler, s, t, depth);
22313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessNearest(faces[face][level1], sampler, s, t, depth);
22323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
22333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
22343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
22353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
22363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses0[CUBEFACE_LAST];
22383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses1[CUBEFACE_LAST];
22393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
22403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
22413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses0[i] = faces[i][level0];
22423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses1[i] = faces[i][level1];
22433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
22443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessLinear(faceAccesses0, face, sampler, s, t, depth);
22463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessLinear(faceAccesses1, face, sampler, s, t, depth);
22473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
22483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
22503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
22533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
22543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
22553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
22563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
22573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22583c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float sampleCubeSeamlessNearestCompare (const ConstPixelBufferAccess& faceAccess, const Sampler& sampler, float ref, float s, float t, int depth = 0)
22593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
22603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler clampingSampler = sampler;
22613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	clampingSampler.wrapS = Sampler::CLAMP_TO_EDGE;
22623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	clampingSampler.wrapT = Sampler::CLAMP_TO_EDGE;
22633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return faceAccess.sample2DCompare(clampingSampler, Sampler::NEAREST, ref, s, t, IVec3(0, 0, depth));
22643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
22653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22663c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float sampleCubeSeamlessLinearCompare (const ConstPixelBufferAccess (&faceAccesses)[CUBEFACE_LAST], CubeFace baseFace, const Sampler& sampler, float ref, float s, float t)
22673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
22683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(faceAccesses[0].getWidth() == faceAccesses[0].getHeight());
22693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		size	= faceAccesses[0].getWidth();
22713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
22723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float	u		= s;
22733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float	v		= t;
22743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
22763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
22773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		u = unnormalize(sampler.wrapS, s, size);
22783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		v = unnormalize(sampler.wrapT, t, size);
22793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
22803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			x0						= deFloorFloatToInt32(u-0.5f);
22823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			x1						= x0+1;
22833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			y0						= deFloorFloatToInt32(v-0.5f);
22843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			y1						= y0+1;
22853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec2		baseSampleCoords[4]		=
22863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
22873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x0, y0),
22883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x1, y0),
22893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x0, y1),
22903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(x1, y1)
22913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
22923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float		sampleRes[4];
22933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		hasBothCoordsOutOfBounds[4]; //!< Whether correctCubeFace() returns CUBEFACE_LAST, i.e. both u and v are out of bounds.
22943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Find correct faces and coordinates for out-of-bounds sample coordinates.
22963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
22983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
22993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CubeFaceIntCoords coords = remapCubeEdgeCoords(CubeFaceIntCoords(baseFace, baseSampleCoords[i]), size);
23003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		hasBothCoordsOutOfBounds[i] = coords.face == CUBEFACE_LAST;
23013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!hasBothCoordsOutOfBounds[i])
23033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
23043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool isFixedPointDepth = isFixedPointDepthTextureFormat(faceAccesses[coords.face].getFormat());
23053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sampleRes[i] = execCompare(faceAccesses[coords.face].getPixel(coords.s, coords.t), sampler.compare, sampler.compareChannel, ref, isFixedPointDepth);
23073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
23083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
23093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23103c827367444ee418f129b2c238299f49d3264554Jarkko 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.
23113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note This averaging behavior is not required by the GLES3 spec (though it is recommended). GLES3 spec only
23123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//		 requires that if the three other samples all have the same color, then the doubly-out-of-bounds sample
23133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//		 must have this color as well.
23143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int bothOutOfBoundsNdx = -1;
23173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < 4; i++)
23183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
23193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (hasBothCoordsOutOfBounds[i])
23203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
23213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(bothOutOfBoundsNdx < 0); // Only one sample can be out of bounds in both u and v.
23223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				bothOutOfBoundsNdx = i;
23233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
23243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
23253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (bothOutOfBoundsNdx != -1)
23263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
23273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sampleRes[bothOutOfBoundsNdx] = 0.0f;
23283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < 4; i++)
23293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (i != bothOutOfBoundsNdx)
23303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					sampleRes[bothOutOfBoundsNdx] += sampleRes[i];
23313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sampleRes[bothOutOfBoundsNdx] = sampleRes[bothOutOfBoundsNdx] * (1.0f/3.0f);
23333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
23343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
23353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interpolate.
23373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float a = deFloatFrac(u-0.5f);
23393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float b = deFloatFrac(v-0.5f);
23403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (sampleRes[0]*(1.0f-a)*(1.0f-b)) +
23423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (sampleRes[1]*(     a)*(1.0f-b)) +
23433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (sampleRes[2]*(1.0f-a)*(     b)) +
23443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   (sampleRes[3]*(     a)*(     b));
23453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23473c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float sampleLevelArrayCubeSeamlessCompare (const ConstPixelBufferAccess* const (&faces)[CUBEFACE_LAST], int numLevels, CubeFace face, const Sampler& sampler, float ref, float s, float t, float lod)
23483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					magnified	= lod <= sampler.lodThreshold;
23503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode		filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
23513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
23533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:
23553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessNearestCompare(faces[face][0], sampler, ref, s, t);
23563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:
23583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
23593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
23603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < (int)CUBEFACE_LAST; i++)
23613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				faceAccesses[i] = faces[i][0];
23623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessLinearCompare(faceAccesses, face, sampler, ref, s, t);
23643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
23653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
23673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
23683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
23693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
23703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
23713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
23723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
23743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessNearestCompare(faces[face][level], sampler, ref, s, t);
23753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
23763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
23773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
23783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
23803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
23813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses[i] = faces[i][level];
23823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessLinearCompare(faceAccesses, face, sampler, ref, s, t);
23843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
23853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
23863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
23883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
23893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
23903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
23913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
23923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level1		= de::min(maxLevel, level0 + 1);
23933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
23943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					f			= deFloatFrac(lod);
23953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					t0;
23963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					t1;
23973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
23993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
24003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessNearestCompare(faces[face][level0], sampler, ref, s, t);
24013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessNearestCompare(faces[face][level1], sampler, ref, s, t);
24023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
24033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
24043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
24053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
24063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses0[CUBEFACE_LAST];
24083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses1[CUBEFACE_LAST];
24093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
24103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
24113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses0[i] = faces[i][level0];
24123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses1[i] = faces[i][level1];
24133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
24143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessLinearCompare(faceAccesses0, face, sampler, ref, s, t);
24163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessLinearCompare(faceAccesses1, face, sampler, ref, s, t);
24173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
24183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
24203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
24213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
24233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
24243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
24253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
24263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Cube map array sampling
24293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24303c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline ConstPixelBufferAccess getCubeArrayFaceAccess (const ConstPixelBufferAccess* const levels, int levelNdx, int slice, CubeFace face)
24313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ConstPixelBufferAccess&	level	= levels[levelNdx];
24333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						depth	= (slice * 6) + getCubeArrayFaceIndex(face);
24343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return getSubregion(level, 0, 0, depth, level.getWidth(), level.getHeight(), 1);
24363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24383c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec4 sampleCubeArraySeamless (const ConstPixelBufferAccess* const levels, int numLevels, int slice, CubeFace face, const Sampler& sampler, float s, float t, float lod)
24393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					faceDepth	= (slice * 6) + getCubeArrayFaceIndex(face);
24413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool					magnified	= lod <= sampler.lodThreshold;
24423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Sampler::FilterMode	filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
24433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
24453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:
24473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessNearest(levels[0], sampler, s, t, faceDepth);
24483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:
24503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
24513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
24523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < (int)CUBEFACE_LAST; i++)
24533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				faceAccesses[i] = getCubeArrayFaceAccess(levels, 0, slice, (CubeFace)i);
24543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessLinear(faceAccesses, face, sampler, s, t, 0);
24563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
24573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
24593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
24603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
24613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
24623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
24633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
24643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
24663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessNearest(levels[level], sampler, s, t, faceDepth);
24673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
24683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
24693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
24703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
24723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
24733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses[i] = getCubeArrayFaceAccess(levels, level, slice, (CubeFace)i);
24743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessLinear(faceAccesses, face, sampler, s, t, 0);
24763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
24773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
24783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
24803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
24813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
24823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
24833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
24843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level1		= de::min(maxLevel, level0 + 1);
24853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
24863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					f			= deFloatFrac(lod);
24873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec4					t0;
24883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec4					t1;
24893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
24913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
24923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessNearest(levels[level0], sampler, s, t, faceDepth);
24933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessNearest(levels[level1], sampler, s, t, faceDepth);
24943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
24953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
24963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
24973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
24983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses0[CUBEFACE_LAST];
25003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses1[CUBEFACE_LAST];
25013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
25023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
25033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses0[i] = getCubeArrayFaceAccess(levels, level0, slice, (CubeFace)i);
25043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses1[i] = getCubeArrayFaceAccess(levels, level1, slice, (CubeFace)i);
25053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
25063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessLinear(faceAccesses0, face, sampler, s, t, 0);
25083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessLinear(faceAccesses1, face, sampler, s, t, 0);
25093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
25103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
25123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
25133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
25153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
25163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return Vec4(0.0f);
25173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
25183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
25193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25203c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float sampleCubeArraySeamlessCompare (const ConstPixelBufferAccess* const levels, int numLevels, int slice, CubeFace face, const Sampler& sampler, float ref, float s, float t, float lod)
25213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
25223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int			faceDepth	= (slice * 6) + getCubeArrayFaceIndex(face);
25233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool			magnified	= lod <= sampler.lodThreshold;
25243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler::FilterMode	filterMode	= magnified ? sampler.magFilter : sampler.minFilter;
25253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (filterMode)
25273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
25283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST:
25293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessNearestCompare(levels[0], sampler, ref, s, t, faceDepth);
25303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR:
25323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
25333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
25343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < (int)CUBEFACE_LAST; i++)
25353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				faceAccesses[i] = getCubeArrayFaceAccess(levels, 0, slice, (CubeFace)i);
25363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return sampleCubeSeamlessLinearCompare(faceAccesses, face, sampler, ref, s, t);
25383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
25393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_NEAREST:
25413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_NEAREST:
25423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
25433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
25443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level		= deClamp32((int)deFloatCeil(lod + 0.5f) - 1, 0, maxLevel);
25453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_NEAREST) ? Sampler::LINEAR : Sampler::NEAREST;
25463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
25483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessNearestCompare(levels[level], sampler, ref, s, t, faceDepth);
25493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
25503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
25513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
25523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
25543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
25553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses[i] = getCubeArrayFaceAccess(levels, level, slice, (CubeFace)i);
25563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return sampleCubeSeamlessLinearCompare(faceAccesses, face, sampler, ref, s, t);
25583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
25593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
25603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::NEAREST_MIPMAP_LINEAR:
25623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Sampler::LINEAR_MIPMAP_LINEAR:
25633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
25643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						maxLevel	= (int)numLevels-1;
25653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level0		= deClamp32((int)deFloatFloor(lod), 0, maxLevel);
25663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						level1		= de::min(maxLevel, level0 + 1);
25673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Sampler::FilterMode		levelFilter	= (filterMode == Sampler::LINEAR_MIPMAP_LINEAR) ? Sampler::LINEAR : Sampler::NEAREST;
25683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					f			= deFloatFrac(lod);
25693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					t0;
25703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float					t1;
25713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (levelFilter == Sampler::NEAREST)
25733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
25743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessNearestCompare(levels[level0], sampler, ref, s, t, faceDepth);
25753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessNearestCompare(levels[level1], sampler, ref, s, t, faceDepth);
25763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
25773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
25783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
25793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(levelFilter == Sampler::LINEAR);
25803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses0[CUBEFACE_LAST];
25823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstPixelBufferAccess faceAccesses1[CUBEFACE_LAST];
25833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)CUBEFACE_LAST; i++)
25843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
25853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses0[i] = getCubeArrayFaceAccess(levels, level0, slice, (CubeFace)i);
25863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					faceAccesses1[i] = getCubeArrayFaceAccess(levels, level1, slice, (CubeFace)i);
25873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
25883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t0 = sampleCubeSeamlessLinearCompare(faceAccesses0, face, sampler, ref, s, t);
25903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				t1 = sampleCubeSeamlessLinearCompare(faceAccesses1, face, sampler, ref, s, t);
25913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
25923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return t0*(1.0f - f) + t1*f;
25943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
25953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
25973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
25983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
25993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
26003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
26013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26023c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int computeMipPyramidLevels (int size)
26033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return deLog2Floor32(size)+1;
26053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
26063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26073c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int computeMipPyramidLevels (int width, int height)
26083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return deLog2Floor32(de::max(width, height))+1;
26103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
26113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26123c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int computeMipPyramidLevels (int width, int height, int depth)
26133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return deLog2Floor32(de::max(width, de::max(height, depth)))+1;
26153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
26163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26173c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int getMipPyramidLevelSize (int baseLevelSize, int levelNdx)
26183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return de::max(baseLevelSize >> levelNdx, 1);
26203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
26213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// TextureLevelPyramid
26233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26243c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevelPyramid::TextureLevelPyramid (const TextureFormat& format, int numLevels)
26253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	(format)
26263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_data	(numLevels)
26273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_access	(numLevels)
26283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
26303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26313c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevelPyramid::TextureLevelPyramid (const TextureLevelPyramid& other)
26323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	(other.m_format)
26333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_data	(other.getNumLevels())
26343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_access	(other.getNumLevels())
26353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int levelNdx = 0; levelNdx < other.getNumLevels(); levelNdx++)
26373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
26383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!other.isLevelEmpty(levelNdx))
26393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
26403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::ConstPixelBufferAccess& srcLevel = other.getLevel(levelNdx);
26413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_data[levelNdx] = other.m_data[levelNdx];
26433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_access[levelNdx] = PixelBufferAccess(srcLevel.getFormat(), srcLevel.getWidth(), srcLevel.getHeight(), srcLevel.getDepth(), m_data[levelNdx].getPtr());
26443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
26453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
26463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
26473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26483c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevelPyramid& TextureLevelPyramid::operator= (const TextureLevelPyramid& other)
26493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
26513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
26523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_format = other.m_format;
26543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_data.resize(other.getNumLevels());
26553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_access.resize(other.getNumLevels());
26563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int levelNdx = 0; levelNdx < other.getNumLevels(); levelNdx++)
26583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
26593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!other.isLevelEmpty(levelNdx))
26603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
26613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::ConstPixelBufferAccess& srcLevel = other.getLevel(levelNdx);
26623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_data[levelNdx] = other.m_data[levelNdx];
26643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_access[levelNdx] = PixelBufferAccess(srcLevel.getFormat(), srcLevel.getWidth(), srcLevel.getHeight(), srcLevel.getDepth(), m_data[levelNdx].getPtr());
26653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
26663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (!isLevelEmpty(levelNdx))
26673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			clearLevel(levelNdx);
26683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
26693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
26713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
26723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26733c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevelPyramid::~TextureLevelPyramid (void)
26743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
26763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26773c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureLevelPyramid::allocLevel (int levelNdx, int width, int height, int depth)
26783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	size	= m_format.getPixelSize()*width*height*depth;
26803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(isLevelEmpty(levelNdx));
26823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_data[levelNdx].setStorage(size);
26843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_access[levelNdx] = PixelBufferAccess(m_format, width, height, depth, m_data[levelNdx].getPtr());
26853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
26863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26873c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureLevelPyramid::clearLevel (int levelNdx)
26883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!isLevelEmpty(levelNdx));
26903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_data[levelNdx].clear();
26923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_access[levelNdx] = PixelBufferAccess();
26933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
26943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture1D
26963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26973c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1D::Texture1D (const TextureFormat& format, int width)
26983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(format, computeMipPyramidLevels(width))
26993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(width)
27003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
27013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27043c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1D::Texture1D (const Texture1D& other)
27053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(other)
27063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(other.m_width)
27073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
27083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27113c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1D& Texture1D::operator= (const Texture1D& other)
27123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
27143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
27153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::operator=(other);
27173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_width		= other.m_width;
27193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view		= Texture1DView(getNumLevels(), getLevels());
27203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
27223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27243c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1D::~Texture1D (void)
27253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27283c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture1D::allocLevel (int levelNdx)
27293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels()));
27313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int width = getMipPyramidLevelSize(m_width, levelNdx);
27333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::allocLevel(levelNdx, width, 1, 1);
27353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture2D
27383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27393c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2D::Texture2D (const TextureFormat& format, int width, int height)
27403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(format, computeMipPyramidLevels(width, height))
27413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(width)
27423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height				(height)
27433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
27443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27473c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2D::Texture2D (const Texture2D& other)
27483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(other)
27493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(other.m_width)
27503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height				(other.m_height)
27513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
27523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27553c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2D& Texture2D::operator= (const Texture2D& other)
27563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
27583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
27593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::operator=(other);
27613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_width		= other.m_width;
27633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_height	= other.m_height;
27643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view		= Texture2DView(getNumLevels(), getLevels());
27653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
27673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27693c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2D::~Texture2D (void)
27703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2D::allocLevel (int levelNdx)
27743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels()));
27763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	width	= getMipPyramidLevelSize(m_width, levelNdx);
27783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	height	= getMipPyramidLevelSize(m_height, levelNdx);
27793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::allocLevel(levelNdx, width, height, 1);
27813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// TextureCubeView
27843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27853c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeView::TextureCubeView (void)
27863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_numLevels(0)
27873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < CUBEFACE_LAST; ndx++)
27893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_levels[ndx] = DE_NULL;
27903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27923c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeView::TextureCubeView (int numLevels, const ConstPixelBufferAccess* const (&levels) [CUBEFACE_LAST])
27933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_numLevels(numLevels)
27943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < CUBEFACE_LAST; ndx++)
27963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_levels[ndx] = levels[ndx];
27973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27993c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Vec4 TextureCubeView::sample (const Sampler& sampler, float s, float t, float r, float lod) const
28003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare == Sampler::COMPAREMODE_NONE);
28023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Computes (face, s, t).
28043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CubeFaceFloatCoords coords = getCubeFaceCoords(Vec3(s, t, r));
28053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.seamlessCubeMap)
28063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sampleLevelArrayCubeSeamless(m_levels, m_numLevels, coords.face, sampler, coords.s, coords.t, 0 /* depth */, lod);
28073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
28083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sampleLevelArray2D(m_levels[coords.face], m_numLevels, sampler, coords.s, coords.t, 0 /* depth */, lod);
28093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28113c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat TextureCubeView::sampleCompare (const Sampler& sampler, float ref, float s, float t, float r, float lod) const
28123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare != Sampler::COMPAREMODE_NONE);
28143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Computes (face, s, t).
28163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CubeFaceFloatCoords coords = getCubeFaceCoords(Vec3(s, t, r));
28173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.seamlessCubeMap)
28183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sampleLevelArrayCubeSeamlessCompare(m_levels, m_numLevels, coords.face, sampler, ref, coords.s, coords.t, lod);
28193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
28203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sampleLevelArray2DCompare(m_levels[coords.face], m_numLevels, sampler, ref, coords.s, coords.t, lod, IVec3(0, 0, 0));
28213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28233c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 TextureCubeView::gather (const Sampler& sampler, float s, float t, float r, int componentNdx) const
28243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare == Sampler::COMPAREMODE_NONE);
28263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ConstPixelBufferAccess faceAccesses[CUBEFACE_LAST];
28283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)CUBEFACE_LAST; i++)
28293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		faceAccesses[i] = m_levels[i][0];
28303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CubeFaceFloatCoords	coords	= getCubeFaceCoords(Vec3(s, t, r));
28323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					size	= faceAccesses[0].getWidth();
28333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Non-normalized coordinates.
28343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float						u		= coords.s;
28353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float						v		= coords.t;
28363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.normalizedCoords)
28383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
28393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		u = unnormalize(sampler.wrapS, coords.s, size);
28403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		v = unnormalize(sampler.wrapT, coords.t, size);
28413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
28423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 sampleColors[4];
28443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	getCubeLinearSamples(faceAccesses, coords.face, u, v, 0, sampleColors);
28453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	sampleIndices[4] = { 2, 3, 1, 0 }; // \note Gather returns the samples in a non-obvious order.
28473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4		result;
28483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
28493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result[i] = sampleColors[sampleIndices[i]][componentNdx];
28503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
28523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28543c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 TextureCubeView::gatherCompare (const Sampler& sampler, float ref, float s, float t, float r) const
28553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare != Sampler::COMPAREMODE_NONE);
28573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_levels[0][0].getFormat().order == TextureFormat::D || m_levels[0][0].getFormat().order == TextureFormat::DS);
28583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compareChannel == 0);
28593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler noCompareSampler = sampler;
28613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	noCompareSampler.compare = Sampler::COMPAREMODE_NONE;
28623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec4 gathered			= gather(noCompareSampler, s, t, r, 0 /* component 0: depth */);
28643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool isFixedPoint		= isFixedPointDepthTextureFormat(m_levels[0][0].getFormat());
28653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4 result;
28663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
28673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result[i] = execCompare(gathered, sampler.compare, i, ref, isFixedPoint);
28683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
28703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// TextureCube
28733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28743c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCube::TextureCube (const TextureFormat& format, int size)
28753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	(format)
28763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_size	(size)
28773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						numLevels		= computeMipPyramidLevels(m_size);
28793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ConstPixelBufferAccess*	levels[CUBEFACE_LAST];
28803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int face = 0; face < CUBEFACE_LAST; face++)
28823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
28833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_data[face].resize(numLevels);
28843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_access[face].resize(numLevels);
28853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		levels[face] = &m_access[face][0];
28863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
28873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view = TextureCubeView(numLevels, levels);
28893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28913c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCube::TextureCube (const TextureCube& other)
28923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_format	(other.m_format)
28933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_size	(other.m_size)
28943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						numLevels		= computeMipPyramidLevels(m_size);
28963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ConstPixelBufferAccess*	levels[CUBEFACE_LAST];
28973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int face = 0; face < CUBEFACE_LAST; face++)
28993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
29003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_data[face].resize(numLevels);
29013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_access[face].resize(numLevels);
29023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		levels[face] = &m_access[face][0];
29033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
29043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view = TextureCubeView(numLevels, levels);
29063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
29083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
29093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int face = 0; face < CUBEFACE_LAST; face++)
29103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
29113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!other.isLevelEmpty((CubeFace)face, levelNdx))
29123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
29133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				allocLevel((CubeFace)face, levelNdx);
29143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				copy(getLevelFace(levelNdx, (CubeFace)face),
29153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 other.getLevelFace(levelNdx, (CubeFace)face));
29163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
29173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
29183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
29193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29213c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCube& TextureCube::operator= (const TextureCube& other)
29223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
29243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
29253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						numLevels		= computeMipPyramidLevels(other.m_size);
29273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ConstPixelBufferAccess*	levels[CUBEFACE_LAST];
29283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int face = 0; face < CUBEFACE_LAST; face++)
29303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
29313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_data[face].resize(numLevels);
29323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_access[face].resize(numLevels);
29333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		levels[face] = &m_access[face][0];
29343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
29353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_format	= other.m_format;
29373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_size		= other.m_size;
29383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view		= TextureCubeView(numLevels, levels);
29393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
29413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
29423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int face = 0; face < CUBEFACE_LAST; face++)
29433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
29443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!isLevelEmpty((CubeFace)face, levelNdx))
29453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				clearLevel((CubeFace)face, levelNdx);
29463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!other.isLevelEmpty((CubeFace)face, levelNdx))
29483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
29493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				allocLevel((CubeFace)face, levelNdx);
29503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				copy(getLevelFace(levelNdx, (CubeFace)face),
29513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 other.getLevelFace(levelNdx, (CubeFace)face));
29523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
29533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
29543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
29553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
29573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29593c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCube::~TextureCube (void)
29603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCube::allocLevel (tcu::CubeFace face, int levelNdx)
29643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	size		= getMipPyramidLevelSize(m_size, levelNdx);
29663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	dataSize	= m_format.getPixelSize()*size*size;
29673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(isLevelEmpty(face, levelNdx));
29683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_data[face][levelNdx].setStorage(dataSize);
29703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_access[face][levelNdx] = PixelBufferAccess(m_format, size, size, 1, m_data[face][levelNdx].getPtr());
29713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCube::clearLevel (tcu::CubeFace face, int levelNdx)
29743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!isLevelEmpty(face, levelNdx));
29763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_data[face][levelNdx].clear();
29773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_access[face][levelNdx] = PixelBufferAccess();
29783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture1DArrayView
29813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29823c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1DArrayView::Texture1DArrayView (int numLevels, const ConstPixelBufferAccess* levels)
29833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_numLevels	(numLevels)
29843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_levels		(levels)
29853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29883c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int Texture1DArrayView::selectLayer (float r) const
29893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_numLevels > 0 && m_levels);
29913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return de::clamp(deFloorFloatToInt32(r + 0.5f), 0, m_levels[0].getHeight()-1);
29923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29943c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 Texture1DArrayView::sample (const Sampler& sampler, float s, float t, float lod) const
29953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray1D(m_levels, m_numLevels, sampler, s, selectLayer(t), lod);
29973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29993c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 Texture1DArrayView::sampleOffset (const Sampler& sampler, float s, float t, float lod, deInt32 offset) const
30003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray1DOffset(m_levels, m_numLevels, sampler, s, lod, IVec2(offset, selectLayer(t)));
30023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30043c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat Texture1DArrayView::sampleCompare (const Sampler& sampler, float ref, float s, float t, float lod) const
30053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray1DCompare(m_levels, m_numLevels, sampler, ref, s, lod, IVec2(0, selectLayer(t)));
30073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30093c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat Texture1DArrayView::sampleCompareOffset (const Sampler& sampler, float ref, float s, float t, float lod, deInt32 offset) const
30103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray1DCompare(m_levels, m_numLevels, sampler, ref, s, lod, IVec2(offset, selectLayer(t)));
30123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture2DArrayView
30153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30163c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArrayView::Texture2DArrayView (int numLevels, const ConstPixelBufferAccess* levels)
30173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_numLevels	(numLevels)
30183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_levels		(levels)
30193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30223c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int Texture2DArrayView::selectLayer (float r) const
30233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_numLevels > 0 && m_levels);
30253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return de::clamp(deFloorFloatToInt32(r + 0.5f), 0, m_levels[0].getDepth()-1);
30263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30283c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 Texture2DArrayView::sample (const Sampler& sampler, float s, float t, float r, float lod) const
30293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray2D(m_levels, m_numLevels, sampler, s, t, selectLayer(r), lod);
30313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30333c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat Texture2DArrayView::sampleCompare (const Sampler& sampler, float ref, float s, float t, float r, float lod) const
30343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray2DCompare(m_levels, m_numLevels, sampler, ref, s, t, lod, IVec3(0, 0, selectLayer(r)));
30363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30383c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 Texture2DArrayView::sampleOffset (const Sampler& sampler, float s, float t, float r, float lod, const IVec2& offset) const
30393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray2DOffset(m_levels, m_numLevels, sampler, s, t, lod, IVec3(offset.x(), offset.y(), selectLayer(r)));
30413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30433c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat Texture2DArrayView::sampleCompareOffset (const Sampler& sampler, float ref, float s, float t, float r, float lod, const IVec2& offset) const
30443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sampleLevelArray2DCompare(m_levels, m_numLevels, sampler, ref, s, t, lod, IVec3(offset.x(), offset.y(), selectLayer(r)));
30463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30483c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 Texture2DArrayView::gatherOffsets (const Sampler& sampler, float s, float t, float r, int componentNdx, const IVec2 (&offsets)[4]) const
30493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return gatherArray2DOffsets(m_levels[0], sampler, s, t, selectLayer(r), componentNdx, offsets);
30513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30533c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 Texture2DArrayView::gatherOffsetsCompare (const Sampler& sampler, float ref, float s, float t, float r, const IVec2 (&offsets)[4]) const
30543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return gatherArray2DOffsetsCompare(m_levels[0], sampler, ref, s, t, selectLayer(r), offsets);
30563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture1DArray
30593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30603c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1DArray::Texture1DArray (const TextureFormat& format, int width, int numLayers)
30613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(format, computeMipPyramidLevels(width))
30623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(width)
30633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numLayers			(numLayers)
30643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
30653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30683c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1DArray::Texture1DArray (const Texture1DArray& other)
30693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(other)
30703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(other.m_width)
30713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numLayers			(other.m_numLayers)
30723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
30733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30763c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1DArray& Texture1DArray::operator= (const Texture1DArray& other)
30773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
30793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
30803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::operator=(other);
30823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_width		= other.m_width;
30843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_numLayers	= other.m_numLayers;
30853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view		= Texture1DArrayView(getNumLevels(), getLevels());
30863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
30883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30903c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1DArray::~Texture1DArray (void)
30913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30943c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture1DArray::allocLevel (int levelNdx)
30953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels()));
30973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int width = getMipPyramidLevelSize(m_width, levelNdx);
30993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::allocLevel(levelNdx, width, m_numLayers, 1);
31013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture2DArray
31043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31053c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArray::Texture2DArray (const TextureFormat& format, int width, int height, int numLayers)
31063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(format, computeMipPyramidLevels(width, height))
31073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(width)
31083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height				(height)
31093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numLayers			(numLayers)
31103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
31113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31143c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArray::Texture2DArray (const Texture2DArray& other)
31153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(other)
31163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(other.m_width)
31173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height				(other.m_height)
31183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numLayers			(other.m_numLayers)
31193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
31203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31233c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArray& Texture2DArray::operator= (const Texture2DArray& other)
31243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
31263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
31273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::operator=(other);
31293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_width		= other.m_width;
31313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_height	= other.m_height;
31323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_numLayers	= other.m_numLayers;
31333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view		= Texture2DArrayView(getNumLevels(), getLevels());
31343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
31363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31383c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArray::~Texture2DArray (void)
31393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31423c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2DArray::allocLevel (int levelNdx)
31433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels()));
31453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	width	= getMipPyramidLevelSize(m_width,	levelNdx);
31473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	height	= getMipPyramidLevelSize(m_height,	levelNdx);
31483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::allocLevel(levelNdx, width, height, m_numLayers);
31503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture3DView
31533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31543c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3DView::Texture3DView (int numLevels, const ConstPixelBufferAccess* levels)
31553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_numLevels	(numLevels)
31563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_levels		(levels)
31573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture3D
31613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31623c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3D::Texture3D (const TextureFormat& format, int width, int height, int depth)
31633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(format, computeMipPyramidLevels(width, height, depth))
31643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(width)
31653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height				(height)
31663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_depth				(depth)
31673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
31683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31713c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3D::Texture3D (const Texture3D& other)
31723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(other)
31733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_width				(other.m_width)
31743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_height				(other.m_height)
31753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_depth				(other.m_depth)
31763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
31773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31803c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3D& Texture3D::operator= (const Texture3D& other)
31813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
31833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
31843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::operator=(other);
31863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_width		= other.m_width;
31883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_height	= other.m_height;
31893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_depth		= other.m_depth;
31903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_view		= Texture3DView(getNumLevels(), getLevels());
31913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
31933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31953c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3D::~Texture3D (void)
31963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31993c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture3D::allocLevel (int levelNdx)
32003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels()));
32023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int width		= getMipPyramidLevelSize(m_width,	levelNdx);
32043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int height	= getMipPyramidLevelSize(m_height,	levelNdx);
32053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int depth		= getMipPyramidLevelSize(m_depth,	levelNdx);
32063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::allocLevel(levelNdx, width, height, depth);
32083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// TextureCubeArrayView
32113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32123c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeArrayView::TextureCubeArrayView (int numLevels, const ConstPixelBufferAccess* levels)
32133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_numLevels	(numLevels)
32143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_levels		(levels)
32153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32188852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryinline int TextureCubeArrayView::selectLayer (float q) const
32193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_numLevels > 0 && m_levels);
32213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT((m_levels[0].getDepth() % 6) == 0);
32223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return de::clamp(deFloorFloatToInt32(q + 0.5f), 0, (m_levels[0].getDepth() / 6)-1);
32243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32263c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Vec4 TextureCubeArrayView::sample (const Sampler& sampler, float s, float t, float r, float q, float lod) const
32273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CubeFaceFloatCoords	coords		= getCubeFaceCoords(Vec3(s, t, r));
32298852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const int					layer		= selectLayer(q);
32308852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const int					faceDepth	= (layer * 6) + getCubeArrayFaceIndex(coords.face);
32313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare == Sampler::COMPAREMODE_NONE);
32333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.seamlessCubeMap)
32358852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		return sampleCubeArraySeamless(m_levels, m_numLevels, layer, coords.face, sampler, coords.s, coords.t, lod);
32363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
32373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sampleLevelArray2D(m_levels, m_numLevels, sampler, coords.s, coords.t, faceDepth, lod);
32383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32403c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat TextureCubeArrayView::sampleCompare (const Sampler& sampler, float ref, float s, float t, float r, float q, float lod) const
32413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CubeFaceFloatCoords	coords		= getCubeFaceCoords(Vec3(s, t, r));
32438852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const int					layer		= selectLayer(q);
32448852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const int					faceDepth	= (layer * 6) + getCubeArrayFaceIndex(coords.face);
32453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sampler.compare != Sampler::COMPAREMODE_NONE);
32473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sampler.seamlessCubeMap)
32498852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		return sampleCubeArraySeamlessCompare(m_levels, m_numLevels, layer, coords.face, sampler, ref, coords.s, coords.t, lod);
32503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
32513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sampleLevelArray2DCompare(m_levels, m_numLevels, sampler, ref, coords.s, coords.t, lod, IVec3(0, 0, faceDepth));
32523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// TextureCubeArray
32553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32568852c82a1ffa4760985c17cc6875d5d521daf343Jarkko PoyryTextureCubeArray::TextureCubeArray (const TextureFormat& format, int size, int depth)
32573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(format, computeMipPyramidLevels(size))
32583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_size				(size)
32598852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	, m_depth				(depth)
32603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
32613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32628852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	DE_ASSERT(m_depth % 6 == 0);
32633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32653c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeArray::TextureCubeArray (const TextureCubeArray& other)
32663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TextureLevelPyramid	(other)
32673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_size				(other.m_size)
32688852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	, m_depth				(other.m_depth)
32693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view				(getNumLevels(), getLevels())
32703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32718852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	DE_ASSERT(m_depth % 6 == 0);
32723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32743c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeArray& TextureCubeArray::operator= (const TextureCubeArray& other)
32753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (this == &other)
32773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return *this;
32783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevelPyramid::operator=(other);
32803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32818852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	m_size	= other.m_size;
32828852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	m_depth	= other.m_depth;
32838852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	m_view	= TextureCubeArrayView(getNumLevels(), getLevels());
32843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32858852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	DE_ASSERT(m_depth % 6 == 0);
32863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
32883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32903c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeArray::~TextureCubeArray (void)
32913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32943c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCubeArray::allocLevel (int levelNdx)
32953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels()));
32973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int size = getMipPyramidLevelSize(m_size, levelNdx);
32993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33008852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	TextureLevelPyramid::allocLevel(levelNdx, size, size, m_depth);
33013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33033c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& str, TextureFormat::ChannelOrder order)
33043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3305ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	const char* const orderStrings[] =
3306ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	{
3307ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"R",
3308ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"A",
3309ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"I",
3310ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"L",
3311ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"LA",
3312ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"RG",
3313ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"RA",
3314ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"RGB",
3315ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"RGBA",
3316ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"ARGB",
3317ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"BGRA",
3318ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi
331916d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		"sR",
332016d404b8653856a3a402c67c36425e24afe456adJarkko Pöyry		"sRG",
3321ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"sRGB",
3322ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"sRGBA",
3323ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi
3324ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"D",
3325ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"S",
3326ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"DS"
3327ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	};
3328ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi
3329ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	return str << de::getSizedArrayElement<TextureFormat::CHANNELORDER_LAST>(orderStrings, order);
33303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33323c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& str, TextureFormat::ChannelType type)
33333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3334ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	const char* const typeStrings[] =
3335ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	{
3336ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"SNORM_INT8",
3337ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"SNORM_INT16",
3338ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"SNORM_INT32",
3339ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_INT8",
3340ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_INT16",
334107104dfa13013a73a59a93cbd8d132254a5a171dJarkko Pöyry		"UNORM_INT24",
3342ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_INT32",
3343ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_SHORT_565",
3344ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_SHORT_555",
3345ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_SHORT_4444",
3346ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_SHORT_5551",
3347ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_INT_101010",
3348ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNORM_INT_1010102_REV",
3349ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT_1010102_REV",
3350ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT_11F_11F_10F_REV",
3351ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT_999_E5_REV",
3352ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT_24_8",
3353ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"SIGNED_INT8",
3354ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"SIGNED_INT16",
3355ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"SIGNED_INT32",
3356ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT8",
3357ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT16",
3358ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"UNSIGNED_INT32",
3359ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"HALF_FLOAT",
3360ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"FLOAT",
3361ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi		"FLOAT_UNSIGNED_INT_24_8_REV"
3362ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	};
3363ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi
3364ce0c0418f73fc40d4267216513c54df7636926b6Mika Isojärvi	return str << de::getSizedArrayElement<TextureFormat::CHANNELTYPE_LAST>(typeStrings, type);
33653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33673c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& str, CubeFace face)
33683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (face)
33703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
33713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_X:	return str << "CUBEFACE_NEGATIVE_X";
33723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_X:	return str << "CUBEFACE_POSITIVE_X";
33733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_Y:	return str << "CUBEFACE_NEGATIVE_Y";
33743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_Y:	return str << "CUBEFACE_POSITIVE_Y";
33753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_NEGATIVE_Z:	return str << "CUBEFACE_NEGATIVE_Z";
33763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_POSITIVE_Z:	return str << "CUBEFACE_POSITIVE_Z";
33773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CUBEFACE_LAST:			return str << "CUBEFACE_LAST";
33783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:					return str << "UNKNOWN(" << (int)face << ")";
33793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
33803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33823c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& str, TextureFormat format)
33833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return str << format.order << ", " << format.type << "";
33853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33873c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& str, const ConstPixelBufferAccess& access)
33883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return str << "format = (" << access.getFormat() << "), size = "
33903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			   << access.getWidth() << " x " << access.getHeight() << " x " << access.getDepth()
33913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			   << ", pitch = " << access.getRowPitch() << " / " << access.getSlicePitch();
33923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // tcu
3395