11e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#ifndef _TCUTEXTURE_HPP
21e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#define _TCUTEXTURE_HPP
31e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)/*-------------------------------------------------------------------------
41e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) * drawElements Quality Program Tester Core
51e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) * ----------------------------------------
61e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) *
71e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) * Copyright 2014 The Android Open Source Project
81e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) *
91e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) * Licensed under the Apache License, Version 2.0 (the "License");
101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) * you may not use this file except in compliance with the License.
111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) * You may obtain a copy of the License at
121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) *
131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) *      http://www.apache.org/licenses/LICENSE-2.0
141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) *
151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) * Unless required by applicable law or agreed to in writing, software
161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) * distributed under the License is distributed on an "AS IS" BASIS,
171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) * See the License for the specific language governing permissions and
191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) * limitations under the License.
201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) *
211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) *//*!
221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) * \file
231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) * \brief Reference Texture Implementation.
241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) *//*--------------------------------------------------------------------*/
251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "tcuDefs.hpp"
271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "tcuVector.hpp"
281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "deArrayBuffer.hpp"
291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include <vector>
311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include <ostream>
321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)namespace tcu
341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles){
351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)/*--------------------------------------------------------------------*//*!
371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) * \brief Texture format
381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) *//*--------------------------------------------------------------------*/
391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)class TextureFormat
401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles){
411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)public:
421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	enum ChannelOrder
431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	{
441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		R = 0,
451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		A,
461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		I,
471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		L,
481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		LA,
491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		RG,
501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		RA,
511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		RGB,
521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		RGBA,
531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		ARGB,
541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		BGRA,
551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		sRGB,
571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		sRGBA,
581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		D,
601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		S,
611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		DS,
621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		CHANNELORDER_LAST
641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	};
651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	enum ChannelType
671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	{
681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		SNORM_INT8 = 0,
691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		SNORM_INT16,
701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		SNORM_INT32,
711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		UNORM_INT8,
721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		UNORM_INT16,
731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		UNORM_INT32,
741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		UNORM_SHORT_565,
751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		UNORM_SHORT_555,
761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		UNORM_SHORT_4444,
771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		UNORM_SHORT_5551,
781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		UNORM_INT_101010,
791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		UNORM_INT_1010102_REV,
801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		UNSIGNED_INT_1010102_REV,
811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		UNSIGNED_INT_11F_11F_10F_REV,
821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		UNSIGNED_INT_999_E5_REV,
831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		UNSIGNED_INT_24_8,
841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		SIGNED_INT8,
851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		SIGNED_INT16,
861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		SIGNED_INT32,
871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		UNSIGNED_INT8,
881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		UNSIGNED_INT16,
891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		UNSIGNED_INT32,
901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		HALF_FLOAT,
911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		FLOAT,
921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		FLOAT_UNSIGNED_INT_24_8_REV,
931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		CHANNELTYPE_LAST
951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	};
961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	ChannelOrder	order;
981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	ChannelType		type;
991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	TextureFormat (ChannelOrder order_, ChannelType type_)
1011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		: order	(order_)
1021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		, type	(type_)
1031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	{
1041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	}
1051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	TextureFormat (void)
1071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		: order	(CHANNELORDER_LAST)
1081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		, type	(CHANNELTYPE_LAST)
1091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	{
1101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	}
1111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	int getPixelSize (void) const;
1131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	bool operator== (const TextureFormat& other) const { return !(*this != other); }
1151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	bool operator!= (const TextureFormat& other) const
1161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	{
1171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		return (order != other.order || type != other.type);
1181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	}
1191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)};
1201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)/*--------------------------------------------------------------------*//*!
1221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) * \brief Sampling parameters
1231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) *//*--------------------------------------------------------------------*/
1241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)class Sampler
1251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles){
1261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)public:
1271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	enum WrapMode
1281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	{
1291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		CLAMP_TO_EDGE = 0,	//! Clamp to edge
1301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		CLAMP_TO_BORDER,	//! Use border color at edge
1311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		REPEAT_GL,			//! Repeat with OpenGL semantics
1321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		REPEAT_CL,			//! Repeat with OpenCL semantics
1331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		MIRRORED_REPEAT_GL,	//! Mirrored repeat with OpenGL semantics
1341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		MIRRORED_REPEAT_CL, //! Mirrored repeat with OpenCL semantics
1351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		WRAPMODE_LAST
1371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	};
1381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	enum FilterMode
1401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	{
1411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		NEAREST = 0,
1421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		LINEAR,
1431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		NEAREST_MIPMAP_NEAREST,
1451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		NEAREST_MIPMAP_LINEAR,
1461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		LINEAR_MIPMAP_NEAREST,
1471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		LINEAR_MIPMAP_LINEAR,
1481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		FILTERMODE_LAST
1501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	};
1511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	enum CompareMode
1531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	{
1541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		COMPAREMODE_NONE = 0,
1551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		COMPAREMODE_LESS,
1561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		COMPAREMODE_LESS_OR_EQUAL,
1571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		COMPAREMODE_GREATER,
1581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		COMPAREMODE_GREATER_OR_EQUAL,
1591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		COMPAREMODE_EQUAL,
1601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		COMPAREMODE_NOT_EQUAL,
1611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		COMPAREMODE_ALWAYS,
1621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		COMPAREMODE_NEVER,
1631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		COMPAREMODE_LAST
1651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	};
1661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	// Wrap control
168a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)	WrapMode		wrapS;
169a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)	WrapMode		wrapT;
1701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	WrapMode		wrapR;
1711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	// Minifcation & magnification
173	FilterMode		minFilter;
174	FilterMode		magFilter;
175	float			lodThreshold;		// lod <= lodThreshold ? magnified : minified
176
177	// Coordinate normalization
178	bool			normalizedCoords;
179
180	// Shadow comparison
181	CompareMode		compare;
182	int				compareChannel;
183
184	// Border color
185	Vec4			borderColor;
186
187	// Seamless cube map filtering
188	bool			seamlessCubeMap;
189
190	Sampler (WrapMode		wrapS_,
191			 WrapMode		wrapT_,
192			 WrapMode		wrapR_,
193			 FilterMode		minFilter_,
194			 FilterMode		magFilter_,
195			 float			lodThreshold_		= 0.0f,
196			 bool			normalizedCoords_	= true,
197			 CompareMode	compare_			= COMPAREMODE_NONE,
198			 int			compareChannel_		= 0,
199			 const Vec4&	borderColor_		= Vec4(0.0f, 0.0f, 0.0f, 0.0f),
200			 bool			seamlessCubeMap_	= false)
201		: wrapS				(wrapS_)
202		, wrapT				(wrapT_)
203		, wrapR				(wrapR_)
204		, minFilter			(minFilter_)
205		, magFilter			(magFilter_)
206		, lodThreshold		(lodThreshold_)
207		, normalizedCoords	(normalizedCoords_)
208		, compare			(compare_)
209		, compareChannel	(compareChannel_)
210		, borderColor		(borderColor_)
211		, seamlessCubeMap	(seamlessCubeMap_)
212	{
213	}
214
215	Sampler (void)
216		: wrapS				(WRAPMODE_LAST)
217		, wrapT				(WRAPMODE_LAST)
218		, wrapR				(WRAPMODE_LAST)
219		, minFilter			(FILTERMODE_LAST)
220		, magFilter			(FILTERMODE_LAST)
221		, lodThreshold		(0.0f)
222		, normalizedCoords	(true)
223		, compare			(COMPAREMODE_NONE)
224		, compareChannel	(0)
225		, borderColor		(0.0f, 0.0f, 0.0f, 0.0f)
226		, seamlessCubeMap	(false)
227	{
228	}
229};
230
231class TextureLevel;
232
233/*--------------------------------------------------------------------*//*!
234 * \brief Read-only pixel data access
235 *
236 * ConstPixelBufferAccess encapsulates pixel data pointer along with
237 * format and layout information. It can be used for read-only access
238 * to arbitrary pixel buffers.
239 *
240 * Access objects are like iterators or pointers. They can be passed around
241 * as values and are valid as long as the storage doesn't change.
242 *//*--------------------------------------------------------------------*/
243class ConstPixelBufferAccess
244{
245public:
246							ConstPixelBufferAccess		(void);
247							ConstPixelBufferAccess		(const TextureLevel& level);
248							ConstPixelBufferAccess		(const TextureFormat& format, int width, int height, int depth, const void* data);
249							ConstPixelBufferAccess		(const TextureFormat& format, int width, int height, int depth, int rowPitch, int slicePitch, const void* data);
250
251	const TextureFormat&	getFormat					(void) const	{ return m_format;		}
252	int						getWidth					(void) const	{ return m_width;		}
253	int						getHeight					(void) const	{ return m_height;		}
254	int						getDepth					(void) const	{ return m_depth;		}
255	int						getRowPitch					(void) const	{ return m_rowPitch;	}
256	int						getSlicePitch				(void) const	{ return m_slicePitch;	}
257
258	const void*				getDataPtr					(void) const	{ return m_data;		}
259	int						getDataSize					(void) const	{ return m_depth*m_slicePitch;	}
260
261	Vec4					getPixel					(int x, int y, int z = 0) const;
262	IVec4					getPixelInt					(int x, int y, int z = 0) const;
263	UVec4					getPixelUint				(int x, int y, int z = 0) const { return getPixelInt(x, y, z).cast<deUint32>(); }
264
265	template<typename T>
266	Vector<T, 4>			getPixelT					(int x, int y, int z = 0) const;
267
268	float					getPixDepth					(int x, int y, int z = 0) const;
269	int						getPixStencil				(int x, int y, int z = 0) const;
270
271	Vec4					sample1D					(const Sampler& sampler, Sampler::FilterMode filter, float s, int level) const;
272	Vec4					sample2D					(const Sampler& sampler, Sampler::FilterMode filter, float s, float t, int depth) const;
273	Vec4					sample3D					(const Sampler& sampler, Sampler::FilterMode filter, float s, float t, float r) const;
274
275	Vec4					sample1DOffset				(const Sampler& sampler, Sampler::FilterMode filter, float s, const IVec2& offset) const;
276	Vec4					sample2DOffset				(const Sampler& sampler, Sampler::FilterMode filter, float s, float t, const IVec3& offset) const;
277	Vec4					sample3DOffset				(const Sampler& sampler, Sampler::FilterMode filter, float s, float t, float r, const IVec3& offset) const;
278
279	float					sample1DCompare				(const Sampler& sampler, Sampler::FilterMode filter, float ref, float s, const IVec2& offset) const;
280	float					sample2DCompare				(const Sampler& sampler, Sampler::FilterMode filter, float ref, float s, float t, const IVec3& offset) const;
281
282protected:
283	TextureFormat			m_format;
284	int						m_width;
285	int						m_height;
286	int						m_depth;
287	int						m_rowPitch;
288	int						m_slicePitch;
289	mutable void*			m_data;
290};
291
292/*--------------------------------------------------------------------*//*!
293 * \brief Read-write pixel data access
294 *
295 * This class extends read-only access object by providing write functionality.
296 *
297 * \note PixelBufferAccess may not have any data members nor add any
298 *		 virtual functions. It must be possible to reinterpret_cast<>
299 *		 PixelBufferAccess to ConstPixelBufferAccess.
300 *//*--------------------------------------------------------------------*/
301class PixelBufferAccess : public ConstPixelBufferAccess
302{
303public:
304							PixelBufferAccess			(void) {}
305							PixelBufferAccess			(TextureLevel& level);
306							PixelBufferAccess			(const TextureFormat& format, int width, int height, int depth, void* data);
307							PixelBufferAccess			(const TextureFormat& format, int width, int height, int depth, int rowPitch, int slicePitch, void* data);
308
309	void*					getDataPtr					(void) const { return m_data; }
310
311	void					setPixels					(const void* buf, int bufSize) const;
312	void					setPixel					(const tcu::Vec4& color, int x, int y, int z = 0) const;
313	void					setPixel					(const tcu::IVec4& color, int x, int y, int z = 0) const;
314	void					setPixel					(const tcu::UVec4& color, int x, int y, int z = 0) const { setPixel(color.cast<int>(), x, y, z); }
315
316	void					setPixDepth					(float depth, int x, int y, int z = 0) const;
317	void					setPixStencil				(int stencil, int x, int y, int z = 0) const;
318};
319
320/*--------------------------------------------------------------------*//*!
321 * \brief Generic pixel data container
322 *
323 * This container supports all valid TextureFormat combinations and
324 * both 2D and 3D textures. To read or manipulate data access object must
325 * be queried using getAccess().
326 *//*--------------------------------------------------------------------*/
327class TextureLevel
328{
329public:
330							TextureLevel		(void);
331							TextureLevel		(const TextureFormat& format);
332							TextureLevel		(const TextureFormat& format, int width, int height, int depth = 1);
333							~TextureLevel		(void);
334
335	int						getWidth			(void) const	{ return m_width;	}
336	int						getHeight			(void) const	{ return m_height;	}
337	int						getDepth			(void) const	{ return m_depth;	}
338	bool					isEmpty				(void) const	{ return m_width == 0 || m_height == 0 || m_depth == 0; }
339	const TextureFormat		getFormat			(void) const	{ return m_format;	}
340
341	void					setStorage			(const TextureFormat& format, int width, int heigth, int depth = 1);
342	void					setSize				(int width, int height, int depth = 1);
343
344	PixelBufferAccess		getAccess			(void)			{ return PixelBufferAccess(m_format, m_width, m_height, m_depth, getPtr());			}
345	ConstPixelBufferAccess	getAccess			(void) const	{ return ConstPixelBufferAccess(m_format, m_width, m_height, m_depth, getPtr());	}
346
347private:
348	void*					getPtr				(void)			{ return m_data.getPtr(); }
349	const void*				getPtr				(void) const	{ return m_data.getPtr(); }
350
351	TextureFormat			m_format;
352	int						m_width;
353	int						m_height;
354	int						m_depth;
355	de::ArrayBuffer<deUint8> m_data;
356
357	friend class ConstPixelBufferAccess;
358};
359
360Vec4	sampleLevelArray1D				(const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, int level, float lod);
361Vec4	sampleLevelArray2D				(const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, int depth, float lod);
362Vec4	sampleLevelArray3D				(const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, float r, float lod);
363
364Vec4	sampleLevelArray1DOffset		(const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float lod, const IVec2& offset);
365Vec4	sampleLevelArray2DOffset		(const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, float lod, const IVec3& offset);
366Vec4	sampleLevelArray3DOffset		(const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, float r, float lod, const IVec3& offset);
367
368float	sampleLevelArray1DCompare		(const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float ref, float s, float lod, const IVec2& offset);
369float	sampleLevelArray2DCompare		(const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float ref, float s, float t, float lod, const IVec3& offset);
370
371Vec4	gatherArray2DOffsets			(const ConstPixelBufferAccess& src, const Sampler& sampler, float s, float t, int depth, int componentNdx, const IVec2 (&offsets)[4]);
372Vec4	gatherArray2DOffsetsCompare		(const ConstPixelBufferAccess& src, const Sampler& sampler, float ref, float s, float t, int depth, const IVec2 (&offsets)[4]);
373
374enum CubeFace
375{
376	CUBEFACE_NEGATIVE_X = 0,
377	CUBEFACE_POSITIVE_X,
378	CUBEFACE_NEGATIVE_Y,
379	CUBEFACE_POSITIVE_Y,
380	CUBEFACE_NEGATIVE_Z,
381	CUBEFACE_POSITIVE_Z,
382
383	CUBEFACE_LAST
384};
385
386/*--------------------------------------------------------------------*//*!
387 * \brief Coordinates projected onto cube face.
388 *//*--------------------------------------------------------------------*/
389template<typename T>
390struct CubeFaceCoords
391{
392	CubeFace		face;
393	T				s;
394	T				t;
395
396					CubeFaceCoords		(CubeFace face_, T s_, T t_) : face(face_), s(s_), t(t_) {}
397					CubeFaceCoords		(CubeFace face_, const Vector<T, 2>& c) : face(face_), s(c.x()), t(c.y()) {}
398};
399
400typedef CubeFaceCoords<float>	CubeFaceFloatCoords;
401typedef CubeFaceCoords<int>		CubeFaceIntCoords;
402
403CubeFace				selectCubeFace			(const Vec3& coords);
404Vec2					projectToFace			(CubeFace face, const Vec3& coords);
405CubeFaceFloatCoords		getCubeFaceCoords		(const Vec3& coords);
406CubeFaceIntCoords		remapCubeEdgeCoords		(const CubeFaceIntCoords& coords, int size);
407
408/*--------------------------------------------------------------------*//*!
409 * \brief 1D Texture View
410 *//*--------------------------------------------------------------------*/
411class Texture1DView
412{
413public:
414									Texture1DView		(int numLevels, const ConstPixelBufferAccess* levels);
415
416	int								getNumLevels		(void) const	{ return m_numLevels;										}
417	int								getWidth			(void) const	{ return m_numLevels > 0 ? m_levels[0].getWidth()	: 0;	}
418	const ConstPixelBufferAccess&	getLevel			(int ndx) const	{ DE_ASSERT(de::inBounds(ndx, 0, m_numLevels)); return m_levels[ndx];	}
419	const ConstPixelBufferAccess*	getLevels			(void) const	{ return m_levels;											}
420
421	Vec4							sample				(const Sampler& sampler, float s, float lod) const;
422	Vec4							sampleOffset		(const Sampler& sampler, float s, float lod, deInt32 offset) const;
423	float							sampleCompare		(const Sampler& sampler, float ref, float s, float lod) const;
424	float							sampleCompareOffset	(const Sampler& sampler, float ref, float s, float lod, deInt32 offset) const;
425
426protected:
427	int								m_numLevels;
428	const ConstPixelBufferAccess*	m_levels;
429};
430
431inline Texture1DView::Texture1DView (int numLevels, const ConstPixelBufferAccess* levels)
432	: m_numLevels	(numLevels)
433	, m_levels		(levels)
434{
435	DE_ASSERT(m_numLevels >= 0 && ((m_numLevels == 0) == !m_levels));
436}
437
438inline Vec4 Texture1DView::sample (const Sampler& sampler, float s, float lod) const
439{
440	return sampleLevelArray1D(m_levels, m_numLevels, sampler, s, 0 /* depth */, lod);
441}
442
443inline Vec4 Texture1DView::sampleOffset (const Sampler& sampler, float s, float lod, deInt32 offset) const
444{
445	return sampleLevelArray1DOffset(m_levels, m_numLevels, sampler, s, lod, IVec2(offset, 0));
446}
447
448inline float Texture1DView::sampleCompare (const Sampler& sampler, float ref, float s, float lod) const
449{
450	return sampleLevelArray1DCompare(m_levels, m_numLevels, sampler, ref, s, lod, IVec2(0, 0));
451}
452
453inline float Texture1DView::sampleCompareOffset (const Sampler& sampler, float ref, float s, float lod, deInt32 offset) const
454{
455	return sampleLevelArray1DCompare(m_levels, m_numLevels, sampler, ref, s, lod, IVec2(offset, 0));
456}
457
458/*--------------------------------------------------------------------*//*!
459 * \brief 2D Texture View
460 *//*--------------------------------------------------------------------*/
461class Texture2DView
462{
463public:
464									Texture2DView		(int numLevels, const ConstPixelBufferAccess* levels);
465
466	int								getNumLevels		(void) const	{ return m_numLevels;										}
467	int								getWidth			(void) const	{ return m_numLevels > 0 ? m_levels[0].getWidth()	: 0;	}
468	int								getHeight			(void) const	{ return m_numLevels > 0 ? m_levels[0].getHeight()	: 0;	}
469	const ConstPixelBufferAccess&	getLevel			(int ndx) const	{ DE_ASSERT(de::inBounds(ndx, 0, m_numLevels)); return m_levels[ndx];	}
470	const ConstPixelBufferAccess*	getLevels			(void) const	{ return m_levels;											}
471
472	Vec4							sample				(const Sampler& sampler, float s, float t, float lod) const;
473	Vec4							sampleOffset		(const Sampler& sampler, float s, float t, float lod, const IVec2& offset) const;
474	float							sampleCompare		(const Sampler& sampler, float ref, float s, float t, float lod) const;
475	float							sampleCompareOffset	(const Sampler& sampler, float ref, float s, float t, float lod, const IVec2& offset) const;
476
477	Vec4							gatherOffsets		(const Sampler& sampler, float s, float t, int componentNdx, const IVec2 (&offsets)[4]) const;
478	Vec4							gatherOffsetsCompare(const Sampler& sampler, float ref, float s, float t, const IVec2 (&offsets)[4]) const;
479
480protected:
481	int								m_numLevels;
482	const ConstPixelBufferAccess*	m_levels;
483};
484
485inline Texture2DView::Texture2DView (int numLevels, const ConstPixelBufferAccess* levels)
486	: m_numLevels	(numLevels)
487	, m_levels		(levels)
488{
489	DE_ASSERT(m_numLevels >= 0 && ((m_numLevels == 0) == !m_levels));
490}
491
492inline Vec4 Texture2DView::sample (const Sampler& sampler, float s, float t, float lod) const
493{
494	return sampleLevelArray2D(m_levels, m_numLevels, sampler, s, t, 0 /* depth */, lod);
495}
496
497inline Vec4 Texture2DView::sampleOffset (const Sampler& sampler, float s, float t, float lod, const IVec2& offset) const
498{
499	return sampleLevelArray2DOffset(m_levels, m_numLevels, sampler, s, t, lod, IVec3(offset.x(), offset.y(), 0));
500}
501
502inline float Texture2DView::sampleCompare (const Sampler& sampler, float ref, float s, float t, float lod) const
503{
504	return sampleLevelArray2DCompare(m_levels, m_numLevels, sampler, ref, s, t, lod, IVec3(0, 0, 0));
505}
506
507inline float Texture2DView::sampleCompareOffset (const Sampler& sampler, float ref, float s, float t, float lod, const IVec2& offset) const
508{
509	return sampleLevelArray2DCompare(m_levels, m_numLevels, sampler, ref, s, t, lod, IVec3(offset.x(), offset.y(), 0));
510}
511
512inline Vec4 Texture2DView::gatherOffsets (const Sampler& sampler, float s, float t, int componentNdx, const IVec2 (&offsets)[4]) const
513{
514	return gatherArray2DOffsets(m_levels[0], sampler, s, t, 0, componentNdx, offsets);
515}
516
517inline Vec4 Texture2DView::gatherOffsetsCompare (const Sampler& sampler, float ref, float s, float t, const IVec2 (&offsets)[4]) const
518{
519	return gatherArray2DOffsetsCompare(m_levels[0], sampler, ref, s, t, 0, offsets);
520}
521
522/*--------------------------------------------------------------------*//*!
523 * \brief Base class for textures that have single mip-map pyramid
524 *//*--------------------------------------------------------------------*/
525class TextureLevelPyramid
526{
527public:
528									TextureLevelPyramid	(const TextureFormat& format, int numLevels);
529									TextureLevelPyramid	(const TextureLevelPyramid& other);
530									~TextureLevelPyramid(void);
531
532	const TextureFormat&			getFormat			(void) const			{ return m_format;					}
533	bool							isLevelEmpty		(int levelNdx) const	{ return m_data[levelNdx].empty();	}
534
535	int								getNumLevels		(void) const			{ return (int)m_access.size();		}
536	const ConstPixelBufferAccess&	getLevel			(int ndx) const			{ return m_access[ndx];				}
537	const PixelBufferAccess&		getLevel			(int ndx)				{ return m_access[ndx];				}
538
539	const ConstPixelBufferAccess*	getLevels			(void) const			{ return &m_access[0];				}
540	const PixelBufferAccess*		getLevels			(void)					{ return &m_access[0];				}
541
542	void							allocLevel			(int levelNdx, int width, int height, int depth);
543	void							clearLevel			(int levelNdx);
544
545	TextureLevelPyramid&			operator=			(const TextureLevelPyramid& other);
546
547private:
548	typedef de::ArrayBuffer<deUint8> LevelData;
549
550	TextureFormat					m_format;
551	std::vector<LevelData>			m_data;
552	std::vector<PixelBufferAccess>	m_access;
553};
554
555/*--------------------------------------------------------------------*//*!
556 * \brief 1D Texture reference implementation
557 *//*--------------------------------------------------------------------*/
558class Texture1D : private TextureLevelPyramid
559{
560public:
561									Texture1D			(const TextureFormat& format, int width);
562									Texture1D			(const Texture1D& other);
563									~Texture1D			(void);
564
565	int								getWidth			(void) const	{ return m_width;	}
566	const Texture1DView&			getView				(void) const	{ return m_view;	}
567
568	void							allocLevel			(int levelNdx);
569
570	// Sampling
571	Vec4							sample				(const Sampler& sampler, float s, float lod) const;
572	Vec4							sampleOffset		(const Sampler& sampler, float s, float lod, deInt32 offset) const;
573
574	using TextureLevelPyramid::getFormat;
575	using TextureLevelPyramid::getNumLevels;
576	using TextureLevelPyramid::getLevel;
577	using TextureLevelPyramid::clearLevel;
578	using TextureLevelPyramid::isLevelEmpty;
579
580	Texture1D&						operator=			(const Texture1D& other);
581
582	operator Texture1DView (void) const { return m_view; }
583
584private:
585	int								m_width;
586	Texture1DView					m_view;
587};
588
589inline Vec4 Texture1D::sample (const Sampler& sampler, float s, float lod) const
590{
591	return m_view.sample(sampler, s, lod);
592}
593
594inline Vec4 Texture1D::sampleOffset (const Sampler& sampler, float s, float lod, deInt32 offset) const
595{
596	return m_view.sampleOffset(sampler, s, lod, offset);
597}
598
599/*--------------------------------------------------------------------*//*!
600 * \brief 2D Texture reference implementation
601 *//*--------------------------------------------------------------------*/
602class Texture2D : private TextureLevelPyramid
603{
604public:
605									Texture2D			(const TextureFormat& format, int width, int height);
606									Texture2D			(const Texture2D& other);
607									~Texture2D			(void);
608
609	int								getWidth			(void) const	{ return m_width;	}
610	int								getHeight			(void) const	{ return m_height;	}
611	const Texture2DView&			getView				(void) const	{ return m_view;	}
612
613	void							allocLevel			(int levelNdx);
614
615	// Sampling
616	Vec4							sample				(const Sampler& sampler, float s, float t, float lod) const;
617	Vec4							sampleOffset		(const Sampler& sampler, float s, float t, float lod, const IVec2& offset) const;
618	float							sampleCompare		(const Sampler& sampler, float ref, float s, float t, float lod) const;
619	float							sampleCompareOffset	(const Sampler& sampler, float ref, float s, float t, float lod, const IVec2& offset) const;
620
621	Vec4							gatherOffsets		(const Sampler& sampler, float s, float t, int componentNdx, const IVec2 (&offsets)[4]) const;
622	Vec4							gatherOffsetsCompare(const Sampler& sampler, float ref, float s, float t, const IVec2 (&offsets)[4]) const;
623
624	using TextureLevelPyramid::getFormat;
625	using TextureLevelPyramid::getNumLevels;
626	using TextureLevelPyramid::getLevel;
627	using TextureLevelPyramid::clearLevel;
628	using TextureLevelPyramid::isLevelEmpty;
629
630	Texture2D&						operator=			(const Texture2D& other);
631
632	operator Texture2DView (void) const { return m_view; }
633
634private:
635	int								m_width;
636	int								m_height;
637	Texture2DView					m_view;
638};
639
640inline Vec4 Texture2D::sample (const Sampler& sampler, float s, float t, float lod) const
641{
642	return m_view.sample(sampler, s, t, lod);
643}
644
645inline Vec4 Texture2D::sampleOffset (const Sampler& sampler, float s, float t, float lod, const IVec2& offset) const
646{
647	return m_view.sampleOffset(sampler, s, t, lod, offset);
648}
649
650inline float Texture2D::sampleCompare (const Sampler& sampler, float ref, float s, float t, float lod) const
651{
652	return m_view.sampleCompare(sampler, ref, s, t, lod);
653}
654
655inline float Texture2D::sampleCompareOffset	(const Sampler& sampler, float ref, float s, float t, float lod, const IVec2& offset) const
656{
657	return m_view.sampleCompareOffset(sampler, ref, s, t, lod, offset);
658}
659
660inline Vec4 Texture2D::gatherOffsets (const Sampler& sampler, float s, float t, int componentNdx, const IVec2 (&offsets)[4]) const
661{
662	return m_view.gatherOffsets(sampler, s, t, componentNdx, offsets);
663}
664
665inline Vec4 Texture2D::gatherOffsetsCompare (const Sampler& sampler, float ref, float s, float t, const IVec2 (&offsets)[4]) const
666{
667	return m_view.gatherOffsetsCompare(sampler, ref, s, t, offsets);
668}
669
670/*--------------------------------------------------------------------*//*!
671 * \brief Cube Map Texture View
672 *//*--------------------------------------------------------------------*/
673class TextureCubeView
674{
675public:
676									TextureCubeView		(void);
677									TextureCubeView		(int numLevels, const ConstPixelBufferAccess* const (&levels)[CUBEFACE_LAST]);
678
679	int								getNumLevels		(void) const	{ return m_numLevels;										}
680	int								getSize				(void) const	{ return m_numLevels > 0 ? m_levels[0][0].getWidth() : 0;	}
681	const ConstPixelBufferAccess&	getLevelFace		(int ndx, CubeFace face) const	{ DE_ASSERT(de::inBounds(ndx, 0, m_numLevels)); return m_levels[face][ndx];	}
682	const ConstPixelBufferAccess*	getFaceLevels		(CubeFace face) const			{ return m_levels[face];					}
683
684	Vec4							sample				(const Sampler& sampler, float s, float t, float p, float lod) const;
685	float							sampleCompare		(const Sampler& sampler, float ref, float s, float t, float r, float lod) const;
686
687	Vec4							gather				(const Sampler& sampler, float s, float t, float r, int componentNdx) const;
688	Vec4							gatherCompare		(const Sampler& sampler, float ref, float s, float t, float r) const;
689
690protected:
691	int								m_numLevels;
692	const ConstPixelBufferAccess*	m_levels[CUBEFACE_LAST];
693};
694
695/*--------------------------------------------------------------------*//*!
696 * \brief Cube Map Texture reference implementation
697 *//*--------------------------------------------------------------------*/
698class TextureCube
699{
700public:
701									TextureCube			(const TextureFormat& format, int size);
702									TextureCube			(const TextureCube& other);
703									~TextureCube		(void);
704
705	const TextureFormat&			getFormat			(void) const	{ return m_format;	}
706	int								getSize				(void) const	{ return m_size;	}
707
708	int								getNumLevels		(void) const					{ return (int)m_access[0].size();	}
709	const ConstPixelBufferAccess&	getLevelFace		(int ndx, CubeFace face) const	{ return m_access[face][ndx];		}
710	const PixelBufferAccess&		getLevelFace		(int ndx, CubeFace face)		{ return m_access[face][ndx];		}
711
712	void							allocLevel			(CubeFace face, int levelNdx);
713	void							clearLevel			(CubeFace face, int levelNdx);
714	bool							isLevelEmpty		(CubeFace face, int levelNdx) const		{ return m_data[face][levelNdx].empty();	}
715
716	Vec4							sample				(const Sampler& sampler, float s, float t, float p, float lod) const;
717	float							sampleCompare		(const Sampler& sampler, float ref, float s, float t, float r, float lod) const;
718
719	Vec4							gather				(const Sampler& sampler, float s, float t, float r, int componentNdx) const;
720	Vec4							gatherCompare		(const Sampler& sampler, float ref, float s, float t, float r) const;
721
722	TextureCube&					operator=			(const TextureCube& other);
723
724	operator TextureCubeView (void) const { return m_view; }
725
726private:
727	typedef de::ArrayBuffer<deUint8> LevelData;
728
729	TextureFormat					m_format;
730	int								m_size;
731	std::vector<LevelData>			m_data[CUBEFACE_LAST];
732	std::vector<PixelBufferAccess>	m_access[CUBEFACE_LAST];
733	TextureCubeView					m_view;
734};
735
736inline Vec4 TextureCube::sample (const Sampler& sampler, float s, float t, float p, float lod) const
737{
738	return m_view.sample(sampler, s, t, p, lod);
739}
740
741inline float TextureCube::sampleCompare (const Sampler& sampler, float ref, float s, float t, float r, float lod) const
742{
743	return m_view.sampleCompare(sampler, ref, s, t, r, lod);
744}
745
746inline Vec4 TextureCube::gather (const Sampler& sampler, float s, float t, float r, int componentNdx) const
747{
748	return m_view.gather(sampler, s, t, r, componentNdx);
749}
750
751inline Vec4 TextureCube::gatherCompare (const Sampler& sampler, float ref, float s, float t, float r) const
752{
753	return m_view.gatherCompare(sampler, ref, s, t, r);
754}
755
756/*--------------------------------------------------------------------*//*!
757 * \brief 1D Array Texture View
758 *//*--------------------------------------------------------------------*/
759class Texture1DArrayView
760{
761public:
762									Texture1DArrayView	(int numLevels, const ConstPixelBufferAccess* levels);
763
764	int								getWidth			(void) const	{ return m_numLevels > 0 ? m_levels[0].getWidth()	: 0;	}
765	int								getNumLayers		(void) const	{ return m_numLevels > 0 ? m_levels[0].getHeight()	: 0;	}
766	int								getNumLevels		(void) const	{ return m_numLevels;										}
767	const ConstPixelBufferAccess&	getLevel			(int ndx) const	{ DE_ASSERT(de::inBounds(ndx, 0, m_numLevels)); return m_levels[ndx];	}
768	const ConstPixelBufferAccess*	getLevels			(void) const	{ return m_levels;											}
769
770	Vec4							sample				(const Sampler& sampler, float s, float t, float lod) const;
771	Vec4							sampleOffset		(const Sampler& sampler, float s, float t, float lod, deInt32 offset) const;
772	float							sampleCompare		(const Sampler& sampler, float ref, float s, float t, float lod) const;
773	float							sampleCompareOffset	(const Sampler& sampler, float ref, float s, float t, float lod, deInt32 offset) const;
774
775protected:
776	int								selectLayer			(float r) const;
777
778	int								m_numLevels;
779	const ConstPixelBufferAccess*	m_levels;
780};
781
782/*--------------------------------------------------------------------*//*!
783 * \brief 2D Array Texture View
784 *//*--------------------------------------------------------------------*/
785class Texture2DArrayView
786{
787public:
788									Texture2DArrayView	(int numLevels, const ConstPixelBufferAccess* levels);
789
790	int								getWidth			(void) const	{ return m_numLevels > 0 ? m_levels[0].getWidth()	: 0;	}
791	int								getHeight			(void) const	{ return m_numLevels > 0 ? m_levels[0].getHeight()	: 0;	}
792	int								getNumLayers		(void) const	{ return m_numLevels > 0 ? m_levels[0].getDepth()	: 0;	}
793	int								getNumLevels		(void) const	{ return m_numLevels;										}
794	const ConstPixelBufferAccess&	getLevel			(int ndx) const	{ DE_ASSERT(de::inBounds(ndx, 0, m_numLevels)); return m_levels[ndx];	}
795	const ConstPixelBufferAccess*	getLevels			(void) const	{ return m_levels;											}
796
797	Vec4							sample				(const Sampler& sampler, float s, float t, float r, float lod) const;
798	Vec4							sampleOffset		(const Sampler& sampler, float s, float t, float r, float lod, const IVec2& offset) const;
799	float							sampleCompare		(const Sampler& sampler, float ref, float s, float t, float r, float lod) const;
800	float							sampleCompareOffset	(const Sampler& sampler, float ref, float s, float t, float r, float lod, const IVec2& offset) const;
801
802	Vec4							gatherOffsets		(const Sampler& sampler, float s, float t, float r, int componentNdx, const IVec2 (&offsets)[4]) const;
803	Vec4							gatherOffsetsCompare(const Sampler& sampler, float ref, float s, float t, float r, const IVec2 (&offsets)[4]) const;
804
805protected:
806	int								selectLayer			(float r) const;
807
808	int								m_numLevels;
809	const ConstPixelBufferAccess*	m_levels;
810};
811
812/*--------------------------------------------------------------------*//*!
813 * \brief 1D Array Texture reference implementation
814 *//*--------------------------------------------------------------------*/
815class Texture1DArray : private TextureLevelPyramid
816{
817public:
818									Texture1DArray		(const TextureFormat& format, int width, int numLayers);
819									Texture1DArray		(const Texture1DArray& other);
820									~Texture1DArray		(void);
821
822	int								getWidth			(void) const	{ return m_width;		}
823	int								getNumLayers		(void) const	{ return m_numLayers;	}
824
825	void							allocLevel			(int levelNdx);
826
827	using TextureLevelPyramid::getFormat;
828	using TextureLevelPyramid::getNumLevels;
829	using TextureLevelPyramid::getLevel;
830	using TextureLevelPyramid::clearLevel;
831	using TextureLevelPyramid::isLevelEmpty;
832
833	Vec4							sample				(const Sampler& sampler, float s, float t, float lod) const;
834	Vec4							sampleOffset		(const Sampler& sampler, float s, float t, float lod, deInt32 offset) const;
835	float							sampleCompare		(const Sampler& sampler, float ref, float s, float t, float lod) const;
836	float							sampleCompareOffset	(const Sampler& sampler, float ref, float s, float t, float lod, deInt32 offset) const;
837
838	Texture1DArray&					operator=			(const Texture1DArray& other);
839
840	operator Texture1DArrayView (void) const { return m_view; }
841
842private:
843	int								m_width;
844	int								m_numLayers;
845	Texture1DArrayView				m_view;
846};
847
848inline Vec4 Texture1DArray::sample (const Sampler& sampler, float s, float t, float lod) const
849{
850	return m_view.sample(sampler, s, t, lod);
851}
852
853inline Vec4 Texture1DArray::sampleOffset (const Sampler& sampler, float s, float t, float lod, deInt32 offset) const
854{
855	return m_view.sampleOffset(sampler, s, t, lod, offset);
856}
857
858inline float Texture1DArray::sampleCompare (const Sampler& sampler, float ref, float s, float t, float lod) const
859{
860	return m_view.sampleCompare(sampler, ref, s, t, lod);
861}
862
863inline float Texture1DArray::sampleCompareOffset (const Sampler& sampler, float ref, float s, float t, float lod, deInt32 offset) const
864{
865	return m_view.sampleCompareOffset(sampler, ref, s, t, lod, offset);
866}
867
868/*--------------------------------------------------------------------*//*!
869 * \brief 2D Array Texture reference implementation
870 *//*--------------------------------------------------------------------*/
871class Texture2DArray : private TextureLevelPyramid
872{
873public:
874									Texture2DArray		(const TextureFormat& format, int width, int height, int numLayers);
875									Texture2DArray		(const Texture2DArray& other);
876									~Texture2DArray		(void);
877
878	int								getWidth			(void) const	{ return m_width;		}
879	int								getHeight			(void) const	{ return m_height;		}
880	int								getNumLayers		(void) const	{ return m_numLayers;	}
881
882	void							allocLevel			(int levelNdx);
883
884	using TextureLevelPyramid::getFormat;
885	using TextureLevelPyramid::getNumLevels;
886	using TextureLevelPyramid::getLevel;
887	using TextureLevelPyramid::clearLevel;
888	using TextureLevelPyramid::isLevelEmpty;
889
890	Vec4							sample				(const Sampler& sampler, float s, float t, float r, float lod) const;
891	Vec4							sampleOffset		(const Sampler& sampler, float s, float t, float r, float lod, const IVec2& offset) const;
892	float							sampleCompare		(const Sampler& sampler, float ref, float s, float t, float r, float lod) const;
893	float							sampleCompareOffset	(const Sampler& sampler, float ref, float s, float t, float r, float lod, const IVec2& offset) const;
894
895	Vec4							gatherOffsets		(const Sampler& sampler, float s, float t, float r, int componentNdx, const IVec2 (&offsets)[4]) const;
896	Vec4							gatherOffsetsCompare(const Sampler& sampler, float ref, float s, float t, float r, const IVec2 (&offsets)[4]) const;
897
898	Texture2DArray&					operator=			(const Texture2DArray& other);
899
900	operator Texture2DArrayView (void) const { return m_view; }
901
902private:
903	int								m_width;
904	int								m_height;
905	int								m_numLayers;
906	Texture2DArrayView				m_view;
907};
908
909inline Vec4 Texture2DArray::sample (const Sampler& sampler, float s, float t, float r, float lod) const
910{
911	return m_view.sample(sampler, s, t, r, lod);
912}
913
914inline Vec4 Texture2DArray::sampleOffset (const Sampler& sampler, float s, float t, float r, float lod, const IVec2& offset) const
915{
916	return m_view.sampleOffset(sampler, s, t, r, lod, offset);
917}
918
919inline float Texture2DArray::sampleCompare (const Sampler& sampler, float ref, float s, float t, float r, float lod) const
920{
921	return m_view.sampleCompare(sampler, ref, s, t, r, lod);
922}
923
924inline float Texture2DArray::sampleCompareOffset (const Sampler& sampler, float ref, float s, float t, float r, float lod, const IVec2& offset) const
925{
926	return m_view.sampleCompareOffset(sampler, ref, s, t, r, lod, offset);
927}
928
929inline Vec4 Texture2DArray::gatherOffsets (const Sampler& sampler, float s, float t, float r, int componentNdx, const IVec2 (&offsets)[4]) const
930{
931	return m_view.gatherOffsets(sampler, s, t, r, componentNdx, offsets);
932}
933
934inline Vec4 Texture2DArray::gatherOffsetsCompare (const Sampler& sampler, float ref, float s, float t, float r, const IVec2 (&offsets)[4]) const
935{
936	return m_view.gatherOffsetsCompare(sampler, ref, s, t, r, offsets);
937}
938
939/*--------------------------------------------------------------------*//*!
940 * \brief 3D Texture View
941 *//*--------------------------------------------------------------------*/
942class Texture3DView
943{
944public:
945									Texture3DView		(int numLevels, const ConstPixelBufferAccess* levels);
946
947	int								getWidth			(void) const	{ return m_numLevels > 0 ? m_levels[0].getWidth()	: 0;	}
948	int								getHeight			(void) const	{ return m_numLevels > 0 ? m_levels[0].getHeight()	: 0;	}
949	int								getDepth			(void) const	{ return m_numLevels > 0 ? m_levels[0].getDepth()	: 0;	}
950	int								getNumLevels		(void) const	{ return m_numLevels;										}
951	const ConstPixelBufferAccess&	getLevel			(int ndx) const	{ DE_ASSERT(de::inBounds(ndx, 0, m_numLevels)); return m_levels[ndx];	}
952	const ConstPixelBufferAccess*	getLevels			(void) const	{ return m_levels;											}
953
954	Vec4							sample				(const Sampler& sampler, float s, float t, float r, float lod) const;
955	Vec4							sampleOffset		(const Sampler& sampler, float s, float t, float r, float lod, const IVec3& offset) const;
956
957protected:
958	int								m_numLevels;
959	const ConstPixelBufferAccess*	m_levels;
960};
961
962inline Vec4 Texture3DView::sample (const Sampler& sampler, float s, float t, float r, float lod) const
963{
964	return sampleLevelArray3D(m_levels, m_numLevels, sampler, s, t, r, lod);
965}
966
967inline Vec4 Texture3DView::sampleOffset (const Sampler& sampler, float s, float t, float r, float lod, const IVec3& offset) const
968{
969	return sampleLevelArray3DOffset(m_levels, m_numLevels, sampler, s, t, r, lod, offset);
970}
971
972/*--------------------------------------------------------------------*//*!
973 * \brief 3D Texture reference implementation
974 *//*--------------------------------------------------------------------*/
975class Texture3D : private TextureLevelPyramid
976{
977public:
978									Texture3D			(const TextureFormat& format, int width, int height, int depth);
979									Texture3D			(const Texture3D& other);
980									~Texture3D			(void);
981
982	int								getWidth			(void) const	{ return m_width;	}
983	int								getHeight			(void) const	{ return m_height;	}
984	int								getDepth			(void) const	{ return m_depth;	}
985
986	void							allocLevel			(int levelNdx);
987
988	using TextureLevelPyramid::getFormat;
989	using TextureLevelPyramid::getNumLevels;
990	using TextureLevelPyramid::getLevel;
991	using TextureLevelPyramid::clearLevel;
992	using TextureLevelPyramid::isLevelEmpty;
993
994	Vec4							sample				(const Sampler& sampler, float s, float t, float r, float lod) const;
995	Vec4							sampleOffset		(const Sampler& sampler, float s, float t, float r, float lod, const IVec3& offset) const;
996
997	Texture3D&						operator=			(const Texture3D& other);
998
999	operator Texture3DView (void) const { return m_view; }
1000
1001private:
1002	int								m_width;
1003	int								m_height;
1004	int								m_depth;
1005	Texture3DView					m_view;
1006};
1007
1008inline Vec4 Texture3D::sample (const Sampler& sampler, float s, float t, float r, float lod) const
1009{
1010	return m_view.sample(sampler, s, t, r, lod);
1011}
1012
1013inline Vec4 Texture3D::sampleOffset (const Sampler& sampler, float s, float t, float r, float lod, const IVec3& offset) const
1014{
1015	return m_view.sampleOffset(sampler, s, t, r, lod, offset);
1016}
1017
1018/*--------------------------------------------------------------------*//*!
1019 * \brief Cube Map Array Texture View
1020 *//*--------------------------------------------------------------------*/
1021class TextureCubeArrayView
1022{
1023public:
1024									TextureCubeArrayView	(int numLevels, const ConstPixelBufferAccess* levels);
1025
1026	int								getSize					(void) const	{ return m_numLevels > 0 ? m_levels[0].getWidth()	: 0;	}
1027	int								getDepth				(void) const	{ return m_numLevels > 0 ? m_levels[0].getDepth()	: 0;	}
1028	int								getNumLayers			(void) const	{ return getDepth()	/ 6;	}
1029	int								getNumLevels			(void) const	{ return m_numLevels;										}
1030	const ConstPixelBufferAccess&	getLevel				(int ndx) const	{ DE_ASSERT(de::inBounds(ndx, 0, m_numLevels)); return m_levels[ndx];	}
1031	const ConstPixelBufferAccess*	getLevels				(void) const	{ return m_levels;											}
1032
1033	Vec4							sample					(const Sampler& sampler, float s, float t, float r, float q, float lod) const;
1034	Vec4							sampleOffset			(const Sampler& sampler, float s, float t, float r, float q, float lod, const IVec2& offset) const;
1035	float							sampleCompare			(const Sampler& sampler, float ref, float s, float t, float r, float q, float lod) const;
1036	float							sampleCompareOffset		(const Sampler& sampler, float ref, float s, float t, float r, float q, float lod, const IVec2& offset) const;
1037
1038protected:
1039	int								selectLayer				(float q) const;
1040
1041	int								m_numLevels;
1042	const ConstPixelBufferAccess*	m_levels;
1043};
1044
1045/*--------------------------------------------------------------------*//*!
1046 * \brief Cube Map Array Texture reference implementation
1047 *//*--------------------------------------------------------------------*/
1048class TextureCubeArray : private TextureLevelPyramid
1049{
1050public:
1051									TextureCubeArray	(const TextureFormat& format, int size, int depth);
1052									TextureCubeArray	(const TextureCubeArray& other);
1053									~TextureCubeArray	(void);
1054
1055	int								getSize				(void) const	{ return m_size;	}
1056	int								getDepth			(void) const	{ return m_depth;	}
1057
1058	void							allocLevel			(int levelNdx);
1059
1060	using TextureLevelPyramid::getFormat;
1061	using TextureLevelPyramid::getNumLevels;
1062	using TextureLevelPyramid::getLevel;
1063	using TextureLevelPyramid::clearLevel;
1064	using TextureLevelPyramid::isLevelEmpty;
1065
1066	Vec4							sample				(const Sampler& sampler, float s, float t, float r, float q, float lod) const;
1067	Vec4							sampleOffset		(const Sampler& sampler, float s, float t, float r, float q, float lod, const IVec2& offset) const;
1068	float							sampleCompare		(const Sampler& sampler, float ref, float s, float t, float r, float q, float lod) const;
1069	float							sampleCompareOffset	(const Sampler& sampler, float ref, float s, float t, float r, float q, float lod, const IVec2& offset) const;
1070
1071	TextureCubeArray&				operator=			(const TextureCubeArray& other);
1072
1073	operator TextureCubeArrayView (void) const { return m_view; }
1074
1075private:
1076	int								m_size;
1077	int								m_depth;
1078	TextureCubeArrayView			m_view;
1079};
1080
1081inline Vec4 TextureCubeArray::sample (const Sampler& sampler, float s, float t, float r, float q, float lod) const
1082{
1083	return m_view.sample(sampler, s, t, r, q, lod);
1084}
1085
1086inline Vec4 TextureCubeArray::sampleOffset (const Sampler& sampler, float s, float t, float r, float q, float lod, const IVec2& offset) const
1087{
1088	return m_view.sampleOffset(sampler, s, t, r, q, lod, offset);
1089}
1090
1091inline float TextureCubeArray::sampleCompare (const Sampler& sampler, float ref, float s, float t, float r, float q, float lod) const
1092{
1093	return m_view.sampleCompare(sampler, ref, s, t, r, q, lod);
1094}
1095
1096inline float TextureCubeArray::sampleCompareOffset (const Sampler& sampler, float ref, float s, float t, float r, float q, float lod, const IVec2& offset) const
1097{
1098	return m_view.sampleCompareOffset(sampler, ref, s, t, r, q, lod, offset);
1099}
1100
1101// Stream operators.
1102std::ostream&		operator<<		(std::ostream& str, TextureFormat::ChannelOrder order);
1103std::ostream&		operator<<		(std::ostream& str, TextureFormat::ChannelType type);
1104std::ostream&		operator<<		(std::ostream& str, TextureFormat format);
1105std::ostream&		operator<<		(std::ostream& str, CubeFace face);
1106std::ostream&		operator<<		(std::ostream& str, const ConstPixelBufferAccess& access);
1107
1108} // tcu
1109
1110#endif // _TCUTEXTURE_HPP
1111