1#ifndef _TCUTEXTURE_HPP
2#define _TCUTEXTURE_HPP
3/*-------------------------------------------------------------------------
4 * drawElements Quality Program Tester Core
5 * ----------------------------------------
6 *
7 * Copyright 2014 The Android Open Source Project
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 *      http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 *
21 *//*!
22 * \file
23 * \brief Reference Texture Implementation.
24 *//*--------------------------------------------------------------------*/
25
26#include "tcuDefs.hpp"
27#include "tcuVector.hpp"
28#include "rrGenericVector.hpp"
29#include "deArrayBuffer.hpp"
30
31#include <vector>
32#include <ostream>
33
34namespace tcu
35{
36
37/*--------------------------------------------------------------------*//*!
38 * \brief Texture format
39 *//*--------------------------------------------------------------------*/
40class TextureFormat
41{
42public:
43	enum ChannelOrder
44	{
45		R = 0,
46		A,
47		I,
48		L,
49		LA,
50		RG,
51		RA,
52		RGB,
53		RGBA,
54		ARGB,
55		BGR,
56		BGRA,
57
58		sR,
59		sRG,
60		sRGB,
61		sRGBA,
62		sBGR,
63		sBGRA,
64
65		D,
66		S,
67		DS,
68
69		CHANNELORDER_LAST
70	};
71
72	enum ChannelType
73	{
74		SNORM_INT8 = 0,
75		SNORM_INT16,
76		SNORM_INT32,
77		UNORM_INT8,
78		UNORM_INT16,
79		UNORM_INT24,
80		UNORM_INT32,
81		UNORM_BYTE_44,
82		UNORM_SHORT_565,
83		UNORM_SHORT_555,
84		UNORM_SHORT_4444,
85		UNORM_SHORT_5551,
86		UNORM_SHORT_1555,
87		UNORM_INT_101010,
88		SNORM_INT_1010102_REV,
89		UNORM_INT_1010102_REV,
90		UNSIGNED_BYTE_44,
91		UNSIGNED_SHORT_565,
92		UNSIGNED_SHORT_4444,
93		UNSIGNED_SHORT_5551,
94		SIGNED_INT_1010102_REV,
95		UNSIGNED_INT_1010102_REV,
96		UNSIGNED_INT_11F_11F_10F_REV,
97		UNSIGNED_INT_999_E5_REV,
98		UNSIGNED_INT_16_8_8,
99		UNSIGNED_INT_24_8,
100		UNSIGNED_INT_24_8_REV,
101		SIGNED_INT8,
102		SIGNED_INT16,
103		SIGNED_INT32,
104		UNSIGNED_INT8,
105		UNSIGNED_INT16,
106		UNSIGNED_INT24,
107		UNSIGNED_INT32,
108		HALF_FLOAT,
109		FLOAT,
110		FLOAT64,
111		FLOAT_UNSIGNED_INT_24_8_REV,
112
113		CHANNELTYPE_LAST
114	};
115
116	ChannelOrder	order;
117	ChannelType		type;
118
119	TextureFormat (ChannelOrder order_, ChannelType type_)
120		: order	(order_)
121		, type	(type_)
122	{
123	}
124
125	TextureFormat (void)
126		: order	(CHANNELORDER_LAST)
127		, type	(CHANNELTYPE_LAST)
128	{
129	}
130
131	int getPixelSize (void) const; //!< Deprecated, use tcu::getPixelSize(fmt)
132
133	bool operator== (const TextureFormat& other) const { return !(*this != other); }
134	bool operator!= (const TextureFormat& other) const
135	{
136		return (order != other.order || type != other.type);
137	}
138} DE_WARN_UNUSED_TYPE;
139
140bool	isValid				(TextureFormat format);
141int		getPixelSize		(TextureFormat format);
142int		getNumUsedChannels	(TextureFormat::ChannelOrder order);
143int		getChannelSize		(TextureFormat::ChannelType type);
144
145/*--------------------------------------------------------------------*//*!
146 * \brief Texture swizzle
147 *//*--------------------------------------------------------------------*/
148struct TextureSwizzle
149{
150	enum Channel
151	{
152		// \note CHANNEL_N must equal int N
153		CHANNEL_0 = 0,
154		CHANNEL_1,
155		CHANNEL_2,
156		CHANNEL_3,
157
158		CHANNEL_ZERO,
159		CHANNEL_ONE,
160
161		CHANNEL_LAST
162	};
163
164	Channel components[4];
165};
166
167//! get the swizzle used to expand texture data with a given channel order to RGBA form
168const TextureSwizzle& getChannelReadSwizzle		(TextureFormat::ChannelOrder order);
169
170//! get the swizzle used to narrow RGBA form data to native texture data with a given channel order
171const TextureSwizzle& getChannelWriteSwizzle	(TextureFormat::ChannelOrder order);
172
173/*--------------------------------------------------------------------*//*!
174 * \brief Sampling parameters
175 *//*--------------------------------------------------------------------*/
176class Sampler
177{
178public:
179	enum WrapMode
180	{
181		CLAMP_TO_EDGE = 0,	//! Clamp to edge
182		CLAMP_TO_BORDER,	//! Use border color at edge
183		REPEAT_GL,			//! Repeat with OpenGL semantics
184		REPEAT_CL,			//! Repeat with OpenCL semantics
185		MIRRORED_REPEAT_GL,	//! Mirrored repeat with OpenGL semantics
186		MIRRORED_REPEAT_CL, //! Mirrored repeat with OpenCL semantics
187		MIRRORED_ONCE,		//! Mirrored once in negative directions
188
189		WRAPMODE_LAST
190	};
191
192	enum FilterMode
193	{
194		NEAREST = 0,
195		LINEAR,
196
197		NEAREST_MIPMAP_NEAREST,
198		NEAREST_MIPMAP_LINEAR,
199		LINEAR_MIPMAP_NEAREST,
200		LINEAR_MIPMAP_LINEAR,
201
202		FILTERMODE_LAST
203	};
204
205	enum CompareMode
206	{
207		COMPAREMODE_NONE = 0,
208		COMPAREMODE_LESS,
209		COMPAREMODE_LESS_OR_EQUAL,
210		COMPAREMODE_GREATER,
211		COMPAREMODE_GREATER_OR_EQUAL,
212		COMPAREMODE_EQUAL,
213		COMPAREMODE_NOT_EQUAL,
214		COMPAREMODE_ALWAYS,
215		COMPAREMODE_NEVER,
216
217		COMPAREMODE_LAST
218	};
219
220	enum DepthStencilMode
221	{
222		MODE_DEPTH = 0,
223		MODE_STENCIL,
224
225		MODE_LAST
226	};
227
228	// Wrap control
229	WrapMode			wrapS;
230	WrapMode			wrapT;
231	WrapMode			wrapR;
232
233	// Minifcation & magnification
234	FilterMode			minFilter;
235	FilterMode			magFilter;
236	float				lodThreshold;		// lod <= lodThreshold ? magnified : minified
237
238	// Coordinate normalization
239	bool				normalizedCoords;
240
241	// Shadow comparison
242	CompareMode			compare;
243	int					compareChannel;
244
245	// Border color.
246	// \note It is setter's responsibility to guarantee that the values are representable
247	//       in sampled texture's internal format.
248	// \note It is setter's responsibility to guarantee that the format is compatible with the
249	//       sampled texture's internal format. Otherwise results are undefined.
250	rr::GenericVec4		borderColor;
251
252	// Seamless cube map filtering
253	bool				seamlessCubeMap;
254
255	// Depth stencil mode
256	DepthStencilMode	depthStencilMode;
257
258	Sampler (WrapMode			wrapS_,
259			 WrapMode			wrapT_,
260			 WrapMode			wrapR_,
261			 FilterMode			minFilter_,
262			 FilterMode			magFilter_,
263			 float				lodThreshold_		= 0.0f,
264			 bool				normalizedCoords_	= true,
265			 CompareMode		compare_			= COMPAREMODE_NONE,
266			 int				compareChannel_		= 0,
267			 const Vec4&		borderColor_		= Vec4(0.0f, 0.0f, 0.0f, 0.0f),
268			 bool				seamlessCubeMap_	= false,
269			 DepthStencilMode	depthStencilMode_	= MODE_DEPTH)
270		: wrapS				(wrapS_)
271		, wrapT				(wrapT_)
272		, wrapR				(wrapR_)
273		, minFilter			(minFilter_)
274		, magFilter			(magFilter_)
275		, lodThreshold		(lodThreshold_)
276		, normalizedCoords	(normalizedCoords_)
277		, compare			(compare_)
278		, compareChannel	(compareChannel_)
279		, borderColor		(borderColor_)
280		, seamlessCubeMap	(seamlessCubeMap_)
281		, depthStencilMode	(depthStencilMode_)
282	{
283	}
284
285	Sampler (void)
286		: wrapS				(WRAPMODE_LAST)
287		, wrapT				(WRAPMODE_LAST)
288		, wrapR				(WRAPMODE_LAST)
289		, minFilter			(FILTERMODE_LAST)
290		, magFilter			(FILTERMODE_LAST)
291		, lodThreshold		(0.0f)
292		, normalizedCoords	(true)
293		, compare			(COMPAREMODE_NONE)
294		, compareChannel	(0)
295		, borderColor		(Vec4(0.0f, 0.0f, 0.0f, 0.0f))
296		, seamlessCubeMap	(false)
297		, depthStencilMode	(MODE_DEPTH)
298	{
299	}
300} DE_WARN_UNUSED_TYPE;
301
302// Calculate pitches for pixel data with no padding.
303IVec3 calculatePackedPitch (const TextureFormat& format, const IVec3& size);
304
305class TextureLevel;
306
307/*--------------------------------------------------------------------*//*!
308 * \brief Read-only pixel data access
309 *
310 * ConstPixelBufferAccess encapsulates pixel data pointer along with
311 * format and layout information. It can be used for read-only access
312 * to arbitrary pixel buffers.
313 *
314 * Access objects are like iterators or pointers. They can be passed around
315 * as values and are valid as long as the storage doesn't change.
316 *//*--------------------------------------------------------------------*/
317class ConstPixelBufferAccess
318{
319public:
320							ConstPixelBufferAccess		(void);
321							ConstPixelBufferAccess		(const TextureLevel& level);
322							ConstPixelBufferAccess		(const TextureFormat& format, int width, int height, int depth, const void* data);
323							ConstPixelBufferAccess		(const TextureFormat& format, const IVec3& size, const void* data);
324							ConstPixelBufferAccess		(const TextureFormat& format, int width, int height, int depth, int rowPitch, int slicePitch, const void* data);
325							ConstPixelBufferAccess		(const TextureFormat& format, const IVec3& size, const IVec3& pitch, const void* data);
326
327	const TextureFormat&	getFormat					(void) const	{ return m_format;					}
328	const IVec3&			getSize						(void) const	{ return m_size;					}
329	int						getWidth					(void) const	{ return m_size.x();				}
330	int						getHeight					(void) const	{ return m_size.y();				}
331	int						getDepth					(void) const	{ return m_size.z();				}
332	int						getPixelPitch				(void) const	{ return m_pitch.x();				}
333	int						getRowPitch					(void) const	{ return m_pitch.y();				}
334	int						getSlicePitch				(void) const	{ return m_pitch.z();				}
335	const IVec3&			getPitch					(void) const	{ return m_pitch;					}
336
337	const void*				getDataPtr					(void) const	{ return m_data;					}
338	const void*				getPixelPtr					(int x, int y, int z = 0) const { return (const deUint8*)m_data + x * m_pitch.x() + y * m_pitch.y() + z * m_pitch.z(); }
339
340	Vec4					getPixel					(int x, int y, int z = 0) const;
341	IVec4					getPixelInt					(int x, int y, int z = 0) const;
342	UVec4					getPixelUint				(int x, int y, int z = 0) const { return getPixelInt(x, y, z).cast<deUint32>(); }
343
344	template<typename T>
345	Vector<T, 4>			getPixelT					(int x, int y, int z = 0) const;
346
347	float					getPixDepth					(int x, int y, int z = 0) const;
348	int						getPixStencil				(int x, int y, int z = 0) const;
349
350	Vec4					sample1D					(const Sampler& sampler, Sampler::FilterMode filter, float s, int level) const;
351	Vec4					sample2D					(const Sampler& sampler, Sampler::FilterMode filter, float s, float t, int depth) const;
352	Vec4					sample3D					(const Sampler& sampler, Sampler::FilterMode filter, float s, float t, float r) const;
353
354	Vec4					sample1DOffset				(const Sampler& sampler, Sampler::FilterMode filter, float s, const IVec2& offset) const;
355	Vec4					sample2DOffset				(const Sampler& sampler, Sampler::FilterMode filter, float s, float t, const IVec3& offset) const;
356	Vec4					sample3DOffset				(const Sampler& sampler, Sampler::FilterMode filter, float s, float t, float r, const IVec3& offset) const;
357
358	float					sample1DCompare				(const Sampler& sampler, Sampler::FilterMode filter, float ref, float s, const IVec2& offset) const;
359	float					sample2DCompare				(const Sampler& sampler, Sampler::FilterMode filter, float ref, float s, float t, const IVec3& offset) const;
360
361protected:
362	TextureFormat			m_format;
363	IVec3					m_size;
364	IVec3					m_pitch;	//!< (pixelPitch, rowPitch, slicePitch)
365	mutable void*			m_data;
366} DE_WARN_UNUSED_TYPE;
367
368/*--------------------------------------------------------------------*//*!
369 * \brief Read-write pixel data access
370 *
371 * This class extends read-only access object by providing write functionality.
372 *
373 * \note PixelBufferAccess may not have any data members nor add any
374 *		 virtual functions. It must be possible to reinterpret_cast<>
375 *		 PixelBufferAccess to ConstPixelBufferAccess.
376 *//*--------------------------------------------------------------------*/
377class PixelBufferAccess : public ConstPixelBufferAccess
378{
379public:
380						PixelBufferAccess	(void) {}
381						PixelBufferAccess	(TextureLevel& level);
382						PixelBufferAccess	(const TextureFormat& format, int width, int height, int depth, void* data);
383						PixelBufferAccess	(const TextureFormat& format, const IVec3& size, void* data);
384						PixelBufferAccess	(const TextureFormat& format, int width, int height, int depth, int rowPitch, int slicePitch, void* data);
385						PixelBufferAccess	(const TextureFormat& format, const IVec3& size, const IVec3& pitch, void* data);
386
387	void*				getDataPtr			(void) const { return m_data; }
388	void*				getPixelPtr			(int x, int y, int z = 0) const { return (deUint8*)m_data + x * m_pitch.x() + y * m_pitch.y() + z * m_pitch.z(); }
389
390	void				setPixel			(const tcu::Vec4& color, int x, int y, int z = 0) const;
391	void				setPixel			(const tcu::IVec4& color, int x, int y, int z = 0) const;
392	void				setPixel			(const tcu::UVec4& color, int x, int y, int z = 0) const { setPixel(color.cast<int>(), x, y, z); }
393
394	void				setPixDepth			(float depth, int x, int y, int z = 0) const;
395	void				setPixStencil		(int stencil, int x, int y, int z = 0) const;
396} DE_WARN_UNUSED_TYPE;
397
398/*--------------------------------------------------------------------*//*!
399 * \brief Generic pixel data container
400 *
401 * This container supports all valid TextureFormat combinations and
402 * both 2D and 3D textures. To read or manipulate data access object must
403 * be queried using getAccess().
404 *//*--------------------------------------------------------------------*/
405class TextureLevel
406{
407public:
408								TextureLevel		(void);
409								TextureLevel		(const TextureFormat& format);
410								TextureLevel		(const TextureFormat& format, int width, int height, int depth = 1);
411								~TextureLevel		(void);
412
413	const IVec3&				getSize				(void) const	{ return m_size;		}
414	int							getWidth			(void) const	{ return m_size.x();	}
415	int							getHeight			(void) const	{ return m_size.y();	}
416	int							getDepth			(void) const	{ return m_size.z();	}
417	bool						isEmpty				(void) const	{ return m_size.x() * m_size.y() * m_size.z() == 0; }
418	const TextureFormat			getFormat			(void) const	{ return m_format;	}
419
420	void						setStorage			(const TextureFormat& format, int width, int heigth, int depth = 1);
421	void						setSize				(int width, int height, int depth = 1);
422
423	PixelBufferAccess			getAccess			(void)			{ return isEmpty() ? PixelBufferAccess() : PixelBufferAccess(m_format, m_size, calculatePackedPitch(m_format, m_size), getPtr());			}
424	ConstPixelBufferAccess		getAccess			(void) const	{ return isEmpty() ? ConstPixelBufferAccess() : ConstPixelBufferAccess(m_format, m_size, calculatePackedPitch(m_format, m_size), getPtr());	}
425
426private:
427	void*						getPtr				(void)			{ return m_data.getPtr(); }
428	const void*					getPtr				(void) const	{ return m_data.getPtr(); }
429
430	TextureFormat				m_format;
431	IVec3						m_size;
432	de::ArrayBuffer<deUint8>	m_data;
433
434	friend class ConstPixelBufferAccess;
435} DE_WARN_UNUSED_TYPE;
436
437Vec4	sampleLevelArray1D				(const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, int level, float lod);
438Vec4	sampleLevelArray2D				(const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, int depth, float lod);
439Vec4	sampleLevelArray3D				(const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, float r, float lod);
440
441Vec4	sampleLevelArray1DOffset		(const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float lod, const IVec2& offset);
442Vec4	sampleLevelArray2DOffset		(const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, float lod, const IVec3& offset);
443Vec4	sampleLevelArray3DOffset		(const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, float r, float lod, const IVec3& offset);
444
445float	sampleLevelArray1DCompare		(const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float ref, float s, float lod, const IVec2& offset);
446float	sampleLevelArray2DCompare		(const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float ref, float s, float t, float lod, const IVec3& offset);
447
448Vec4	gatherArray2DOffsets			(const ConstPixelBufferAccess& src, const Sampler& sampler, float s, float t, int depth, int componentNdx, const IVec2 (&offsets)[4]);
449Vec4	gatherArray2DOffsetsCompare		(const ConstPixelBufferAccess& src, const Sampler& sampler, float ref, float s, float t, int depth, const IVec2 (&offsets)[4]);
450
451enum CubeFace
452{
453	CUBEFACE_NEGATIVE_X = 0,
454	CUBEFACE_POSITIVE_X,
455	CUBEFACE_NEGATIVE_Y,
456	CUBEFACE_POSITIVE_Y,
457	CUBEFACE_NEGATIVE_Z,
458	CUBEFACE_POSITIVE_Z,
459
460	CUBEFACE_LAST
461};
462
463/*--------------------------------------------------------------------*//*!
464 * \brief Coordinates projected onto cube face.
465 *//*--------------------------------------------------------------------*/
466template<typename T>
467struct CubeFaceCoords
468{
469	CubeFace		face;
470	T				s;
471	T				t;
472
473					CubeFaceCoords		(CubeFace face_, T s_, T t_) : face(face_), s(s_), t(t_) {}
474					CubeFaceCoords		(CubeFace face_, const Vector<T, 2>& c) : face(face_), s(c.x()), t(c.y()) {}
475} DE_WARN_UNUSED_TYPE;
476
477typedef CubeFaceCoords<float>	CubeFaceFloatCoords;
478typedef CubeFaceCoords<int>		CubeFaceIntCoords;
479
480CubeFace				selectCubeFace			(const Vec3& coords);
481Vec2					projectToFace			(CubeFace face, const Vec3& coords);
482CubeFaceFloatCoords		getCubeFaceCoords		(const Vec3& coords);
483CubeFaceIntCoords		remapCubeEdgeCoords		(const CubeFaceIntCoords& coords, int size);
484
485/*--------------------------------------------------------------------*//*!
486 * \brief 1D Texture View
487 *//*--------------------------------------------------------------------*/
488class Texture1DView
489{
490public:
491									Texture1DView		(int numLevels, const ConstPixelBufferAccess* levels);
492
493	int								getNumLevels		(void) const	{ return m_numLevels;										}
494	int								getWidth			(void) const	{ return m_numLevels > 0 ? m_levels[0].getWidth()	: 0;	}
495	const ConstPixelBufferAccess&	getLevel			(int ndx) const	{ DE_ASSERT(de::inBounds(ndx, 0, m_numLevels)); return m_levels[ndx];	}
496	const ConstPixelBufferAccess*	getLevels			(void) const	{ return m_levels;											}
497
498	Vec4							sample				(const Sampler& sampler, float s, float lod) const;
499	Vec4							sampleOffset		(const Sampler& sampler, float s, float lod, deInt32 offset) const;
500	float							sampleCompare		(const Sampler& sampler, float ref, float s, float lod) const;
501	float							sampleCompareOffset	(const Sampler& sampler, float ref, float s, float lod, deInt32 offset) const;
502
503protected:
504	int								m_numLevels;
505	const ConstPixelBufferAccess*	m_levels;
506} DE_WARN_UNUSED_TYPE;
507
508inline Texture1DView::Texture1DView (int numLevels, const ConstPixelBufferAccess* levels)
509	: m_numLevels	(numLevels)
510	, m_levels		(levels)
511{
512	DE_ASSERT(m_numLevels >= 0 && ((m_numLevels == 0) == !m_levels));
513}
514
515inline Vec4 Texture1DView::sample (const Sampler& sampler, float s, float lod) const
516{
517	return sampleLevelArray1D(m_levels, m_numLevels, sampler, s, 0 /* depth */, lod);
518}
519
520inline Vec4 Texture1DView::sampleOffset (const Sampler& sampler, float s, float lod, deInt32 offset) const
521{
522	return sampleLevelArray1DOffset(m_levels, m_numLevels, sampler, s, lod, IVec2(offset, 0));
523}
524
525inline float Texture1DView::sampleCompare (const Sampler& sampler, float ref, float s, float lod) const
526{
527	return sampleLevelArray1DCompare(m_levels, m_numLevels, sampler, ref, s, lod, IVec2(0, 0));
528}
529
530inline float Texture1DView::sampleCompareOffset (const Sampler& sampler, float ref, float s, float lod, deInt32 offset) const
531{
532	return sampleLevelArray1DCompare(m_levels, m_numLevels, sampler, ref, s, lod, IVec2(offset, 0));
533}
534
535/*--------------------------------------------------------------------*//*!
536 * \brief 2D Texture View
537 *//*--------------------------------------------------------------------*/
538class Texture2DView
539{
540public:
541									Texture2DView		(int numLevels, const ConstPixelBufferAccess* levels);
542
543	int								getNumLevels		(void) const	{ return m_numLevels;										}
544	int								getWidth			(void) const	{ return m_numLevels > 0 ? m_levels[0].getWidth()	: 0;	}
545	int								getHeight			(void) const	{ return m_numLevels > 0 ? m_levels[0].getHeight()	: 0;	}
546	const ConstPixelBufferAccess&	getLevel			(int ndx) const	{ DE_ASSERT(de::inBounds(ndx, 0, m_numLevels)); return m_levels[ndx];	}
547	const ConstPixelBufferAccess*	getLevels			(void) const	{ return m_levels;											}
548
549	Vec4							sample				(const Sampler& sampler, float s, float t, float lod) const;
550	Vec4							sampleOffset		(const Sampler& sampler, float s, float t, float lod, const IVec2& offset) const;
551	float							sampleCompare		(const Sampler& sampler, float ref, float s, float t, float lod) const;
552	float							sampleCompareOffset	(const Sampler& sampler, float ref, float s, float t, float lod, const IVec2& offset) const;
553
554	Vec4							gatherOffsets		(const Sampler& sampler, float s, float t, int componentNdx, const IVec2 (&offsets)[4]) const;
555	Vec4							gatherOffsetsCompare(const Sampler& sampler, float ref, float s, float t, const IVec2 (&offsets)[4]) const;
556
557protected:
558	int								m_numLevels;
559	const ConstPixelBufferAccess*	m_levels;
560} DE_WARN_UNUSED_TYPE;
561
562inline Texture2DView::Texture2DView (int numLevels, const ConstPixelBufferAccess* levels)
563	: m_numLevels	(numLevels)
564	, m_levels		(levels)
565{
566	DE_ASSERT(m_numLevels >= 0 && ((m_numLevels == 0) == !m_levels));
567}
568
569inline Vec4 Texture2DView::sample (const Sampler& sampler, float s, float t, float lod) const
570{
571	return sampleLevelArray2D(m_levels, m_numLevels, sampler, s, t, 0 /* depth */, lod);
572}
573
574inline Vec4 Texture2DView::sampleOffset (const Sampler& sampler, float s, float t, float lod, const IVec2& offset) const
575{
576	return sampleLevelArray2DOffset(m_levels, m_numLevels, sampler, s, t, lod, IVec3(offset.x(), offset.y(), 0));
577}
578
579inline float Texture2DView::sampleCompare (const Sampler& sampler, float ref, float s, float t, float lod) const
580{
581	return sampleLevelArray2DCompare(m_levels, m_numLevels, sampler, ref, s, t, lod, IVec3(0, 0, 0));
582}
583
584inline float Texture2DView::sampleCompareOffset (const Sampler& sampler, float ref, float s, float t, float lod, const IVec2& offset) const
585{
586	return sampleLevelArray2DCompare(m_levels, m_numLevels, sampler, ref, s, t, lod, IVec3(offset.x(), offset.y(), 0));
587}
588
589inline Vec4 Texture2DView::gatherOffsets (const Sampler& sampler, float s, float t, int componentNdx, const IVec2 (&offsets)[4]) const
590{
591	return gatherArray2DOffsets(m_levels[0], sampler, s, t, 0, componentNdx, offsets);
592}
593
594inline Vec4 Texture2DView::gatherOffsetsCompare (const Sampler& sampler, float ref, float s, float t, const IVec2 (&offsets)[4]) const
595{
596	return gatherArray2DOffsetsCompare(m_levels[0], sampler, ref, s, t, 0, offsets);
597}
598
599/*--------------------------------------------------------------------*//*!
600 * \brief Base class for textures that have single mip-map pyramid
601 *//*--------------------------------------------------------------------*/
602class TextureLevelPyramid
603{
604public:
605									TextureLevelPyramid	(const TextureFormat& format, int numLevels);
606									TextureLevelPyramid	(const TextureLevelPyramid& other);
607									~TextureLevelPyramid(void);
608
609	const TextureFormat&			getFormat			(void) const			{ return m_format;					}
610	int								getNumLevels		(void) const			{ return (int)m_access.size();		}
611
612	bool							isLevelEmpty		(int levelNdx) const	{ DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels())); return m_data[(size_t)levelNdx].empty();	}
613	const ConstPixelBufferAccess&	getLevel			(int levelNdx) const	{ DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels())); return m_access[(size_t)levelNdx];			}
614	const PixelBufferAccess&		getLevel			(int levelNdx)			{ DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels())); return m_access[(size_t)levelNdx];			}
615
616	const ConstPixelBufferAccess*	getLevels			(void) const			{ return &m_access[0];				}
617	const PixelBufferAccess*		getLevels			(void)					{ return &m_access[0];				}
618
619	void							allocLevel			(int levelNdx, int width, int height, int depth);
620	void							clearLevel			(int levelNdx);
621
622	TextureLevelPyramid&			operator=			(const TextureLevelPyramid& other);
623
624private:
625	typedef de::ArrayBuffer<deUint8> LevelData;
626
627	TextureFormat					m_format;
628	std::vector<LevelData>			m_data;
629	std::vector<PixelBufferAccess>	m_access;
630} DE_WARN_UNUSED_TYPE;
631
632/*--------------------------------------------------------------------*//*!
633 * \brief 1D Texture reference implementation
634 *//*--------------------------------------------------------------------*/
635class Texture1D : private TextureLevelPyramid
636{
637public:
638									Texture1D			(const TextureFormat& format, int width);
639									Texture1D			(const Texture1D& other);
640									~Texture1D			(void);
641
642	int								getWidth			(void) const	{ return m_width;	}
643	const Texture1DView&			getView				(void) const	{ return m_view;	}
644
645	void							allocLevel			(int levelNdx);
646
647	// Sampling
648	Vec4							sample				(const Sampler& sampler, float s, float lod) const;
649	Vec4							sampleOffset		(const Sampler& sampler, float s, float lod, deInt32 offset) const;
650	float							sampleCompare		(const Sampler& sampler, float ref, float s, float lod) const;
651	float							sampleCompareOffset	(const Sampler& sampler, float ref, float s, float lod, deInt32 offset) const;
652
653	using TextureLevelPyramid::getFormat;
654	using TextureLevelPyramid::getNumLevels;
655	using TextureLevelPyramid::getLevel;
656	using TextureLevelPyramid::clearLevel;
657	using TextureLevelPyramid::isLevelEmpty;
658
659	Texture1D&						operator=			(const Texture1D& other);
660
661	operator Texture1DView (void) const { return m_view; }
662
663private:
664	int								m_width;
665	Texture1DView					m_view;
666} DE_WARN_UNUSED_TYPE;
667
668inline Vec4 Texture1D::sample (const Sampler& sampler, float s, float lod) const
669{
670	return m_view.sample(sampler, s, lod);
671}
672
673inline Vec4 Texture1D::sampleOffset (const Sampler& sampler, float s, float lod, deInt32 offset) const
674{
675	return m_view.sampleOffset(sampler, s, lod, offset);
676}
677
678inline float Texture1D::sampleCompare (const Sampler& sampler, float ref, float s, float lod) const
679{
680	return m_view.sampleCompare(sampler, ref, s, lod);
681}
682
683inline float Texture1D::sampleCompareOffset	(const Sampler& sampler, float ref, float s, float lod, deInt32 offset) const
684{
685	return m_view.sampleCompareOffset(sampler, ref, s, lod, offset);
686}
687
688/*--------------------------------------------------------------------*//*!
689 * \brief 2D Texture reference implementation
690 *//*--------------------------------------------------------------------*/
691class Texture2D : private TextureLevelPyramid
692{
693public:
694									Texture2D			(const TextureFormat& format, int width, int height);
695									Texture2D			(const Texture2D& other);
696									~Texture2D			(void);
697
698	int								getWidth			(void) const	{ return m_width;	}
699	int								getHeight			(void) const	{ return m_height;	}
700	const Texture2DView&			getView				(void) const	{ return m_view;	}
701
702	void							allocLevel			(int levelNdx);
703
704	// Sampling
705	Vec4							sample				(const Sampler& sampler, float s, float t, float lod) const;
706	Vec4							sampleOffset		(const Sampler& sampler, float s, float t, float lod, const IVec2& offset) const;
707	float							sampleCompare		(const Sampler& sampler, float ref, float s, float t, float lod) const;
708	float							sampleCompareOffset	(const Sampler& sampler, float ref, float s, float t, float lod, const IVec2& offset) const;
709
710	Vec4							gatherOffsets		(const Sampler& sampler, float s, float t, int componentNdx, const IVec2 (&offsets)[4]) const;
711	Vec4							gatherOffsetsCompare(const Sampler& sampler, float ref, float s, float t, const IVec2 (&offsets)[4]) const;
712
713	using TextureLevelPyramid::getFormat;
714	using TextureLevelPyramid::getNumLevels;
715	using TextureLevelPyramid::getLevel;
716	using TextureLevelPyramid::clearLevel;
717	using TextureLevelPyramid::isLevelEmpty;
718
719	Texture2D&						operator=			(const Texture2D& other);
720
721	operator Texture2DView (void) const { return m_view; }
722
723private:
724	int								m_width;
725	int								m_height;
726	Texture2DView					m_view;
727} DE_WARN_UNUSED_TYPE;
728
729inline Vec4 Texture2D::sample (const Sampler& sampler, float s, float t, float lod) const
730{
731	return m_view.sample(sampler, s, t, lod);
732}
733
734inline Vec4 Texture2D::sampleOffset (const Sampler& sampler, float s, float t, float lod, const IVec2& offset) const
735{
736	return m_view.sampleOffset(sampler, s, t, lod, offset);
737}
738
739inline float Texture2D::sampleCompare (const Sampler& sampler, float ref, float s, float t, float lod) const
740{
741	return m_view.sampleCompare(sampler, ref, s, t, lod);
742}
743
744inline float Texture2D::sampleCompareOffset	(const Sampler& sampler, float ref, float s, float t, float lod, const IVec2& offset) const
745{
746	return m_view.sampleCompareOffset(sampler, ref, s, t, lod, offset);
747}
748
749inline Vec4 Texture2D::gatherOffsets (const Sampler& sampler, float s, float t, int componentNdx, const IVec2 (&offsets)[4]) const
750{
751	return m_view.gatherOffsets(sampler, s, t, componentNdx, offsets);
752}
753
754inline Vec4 Texture2D::gatherOffsetsCompare (const Sampler& sampler, float ref, float s, float t, const IVec2 (&offsets)[4]) const
755{
756	return m_view.gatherOffsetsCompare(sampler, ref, s, t, offsets);
757}
758
759/*--------------------------------------------------------------------*//*!
760 * \brief Cube Map Texture View
761 *//*--------------------------------------------------------------------*/
762class TextureCubeView
763{
764public:
765									TextureCubeView		(void);
766									TextureCubeView		(int numLevels, const ConstPixelBufferAccess* const (&levels)[CUBEFACE_LAST]);
767
768	int								getNumLevels		(void) const	{ return m_numLevels;										}
769	int								getSize				(void) const	{ return m_numLevels > 0 ? m_levels[0][0].getWidth() : 0;	}
770	const ConstPixelBufferAccess&	getLevelFace		(int ndx, CubeFace face) const	{ DE_ASSERT(de::inBounds(ndx, 0, m_numLevels)); return m_levels[face][ndx];	}
771	const ConstPixelBufferAccess*	getFaceLevels		(CubeFace face) const			{ return m_levels[face];					}
772
773	Vec4							sample				(const Sampler& sampler, float s, float t, float p, float lod) const;
774	float							sampleCompare		(const Sampler& sampler, float ref, float s, float t, float r, float lod) const;
775
776	Vec4							gather				(const Sampler& sampler, float s, float t, float r, int componentNdx) const;
777	Vec4							gatherCompare		(const Sampler& sampler, float ref, float s, float t, float r) const;
778
779protected:
780	int								m_numLevels;
781	const ConstPixelBufferAccess*	m_levels[CUBEFACE_LAST];
782} DE_WARN_UNUSED_TYPE;
783
784/*--------------------------------------------------------------------*//*!
785 * \brief Cube Map Texture reference implementation
786 *//*--------------------------------------------------------------------*/
787class TextureCube
788{
789public:
790									TextureCube			(const TextureFormat& format, int size);
791									TextureCube			(const TextureCube& other);
792									~TextureCube		(void);
793
794	const TextureFormat&			getFormat			(void) const	{ return m_format;	}
795	int								getSize				(void) const	{ return m_size;	}
796
797	int								getNumLevels		(void) const					{ return (int)m_access[0].size();	}
798	const ConstPixelBufferAccess&	getLevelFace		(int ndx, CubeFace face) const	{ DE_ASSERT(de::inBounds(ndx, 0, getNumLevels())); return m_access[face][(size_t)ndx];	}
799	const PixelBufferAccess&		getLevelFace		(int ndx, CubeFace face)		{ DE_ASSERT(de::inBounds(ndx, 0, getNumLevels())); return m_access[face][(size_t)ndx];	}
800
801	void							allocLevel			(CubeFace face, int levelNdx);
802	void							clearLevel			(CubeFace face, int levelNdx);
803	bool							isLevelEmpty		(CubeFace face, int levelNdx) const	{ DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels())); return m_data[face][(size_t)levelNdx].empty();	}
804
805	Vec4							sample				(const Sampler& sampler, float s, float t, float p, float lod) const;
806	float							sampleCompare		(const Sampler& sampler, float ref, float s, float t, float r, float lod) const;
807
808	Vec4							gather				(const Sampler& sampler, float s, float t, float r, int componentNdx) const;
809	Vec4							gatherCompare		(const Sampler& sampler, float ref, float s, float t, float r) const;
810
811	TextureCube&					operator=			(const TextureCube& other);
812
813	operator TextureCubeView (void) const { return m_view; }
814
815private:
816	typedef de::ArrayBuffer<deUint8> LevelData;
817
818	TextureFormat					m_format;
819	int								m_size;
820	std::vector<LevelData>			m_data[CUBEFACE_LAST];
821	std::vector<PixelBufferAccess>	m_access[CUBEFACE_LAST];
822	TextureCubeView					m_view;
823} DE_WARN_UNUSED_TYPE;
824
825inline Vec4 TextureCube::sample (const Sampler& sampler, float s, float t, float p, float lod) const
826{
827	return m_view.sample(sampler, s, t, p, lod);
828}
829
830inline float TextureCube::sampleCompare (const Sampler& sampler, float ref, float s, float t, float r, float lod) const
831{
832	return m_view.sampleCompare(sampler, ref, s, t, r, lod);
833}
834
835inline Vec4 TextureCube::gather (const Sampler& sampler, float s, float t, float r, int componentNdx) const
836{
837	return m_view.gather(sampler, s, t, r, componentNdx);
838}
839
840inline Vec4 TextureCube::gatherCompare (const Sampler& sampler, float ref, float s, float t, float r) const
841{
842	return m_view.gatherCompare(sampler, ref, s, t, r);
843}
844
845/*--------------------------------------------------------------------*//*!
846 * \brief 1D Array Texture View
847 *//*--------------------------------------------------------------------*/
848class Texture1DArrayView
849{
850public:
851									Texture1DArrayView	(int numLevels, const ConstPixelBufferAccess* levels);
852
853	int								getWidth			(void) const	{ return m_numLevels > 0 ? m_levels[0].getWidth()	: 0;	}
854	int								getNumLayers		(void) const	{ return m_numLevels > 0 ? m_levels[0].getHeight()	: 0;	}
855	int								getNumLevels		(void) const	{ return m_numLevels;										}
856	const ConstPixelBufferAccess&	getLevel			(int ndx) const	{ DE_ASSERT(de::inBounds(ndx, 0, m_numLevels)); return m_levels[ndx];	}
857	const ConstPixelBufferAccess*	getLevels			(void) const	{ return m_levels;											}
858
859	Vec4							sample				(const Sampler& sampler, float s, float t, float lod) const;
860	Vec4							sampleOffset		(const Sampler& sampler, float s, float t, float lod, deInt32 offset) const;
861	float							sampleCompare		(const Sampler& sampler, float ref, float s, float t, float lod) const;
862	float							sampleCompareOffset	(const Sampler& sampler, float ref, float s, float t, float lod, deInt32 offset) const;
863
864protected:
865	int								selectLayer			(float r) const;
866
867	int								m_numLevels;
868	const ConstPixelBufferAccess*	m_levels;
869} DE_WARN_UNUSED_TYPE;
870
871/*--------------------------------------------------------------------*//*!
872 * \brief 2D Array Texture View
873 *//*--------------------------------------------------------------------*/
874class Texture2DArrayView
875{
876public:
877									Texture2DArrayView	(int numLevels, const ConstPixelBufferAccess* levels);
878
879	int								getWidth			(void) const	{ return m_numLevels > 0 ? m_levels[0].getWidth()	: 0;	}
880	int								getHeight			(void) const	{ return m_numLevels > 0 ? m_levels[0].getHeight()	: 0;	}
881	int								getNumLayers		(void) const	{ return m_numLevels > 0 ? m_levels[0].getDepth()	: 0;	}
882	int								getNumLevels		(void) const	{ return m_numLevels;										}
883	const ConstPixelBufferAccess&	getLevel			(int ndx) const	{ DE_ASSERT(de::inBounds(ndx, 0, m_numLevels)); return m_levels[ndx];	}
884	const ConstPixelBufferAccess*	getLevels			(void) const	{ return m_levels;											}
885
886	Vec4							sample				(const Sampler& sampler, float s, float t, float r, float lod) const;
887	Vec4							sampleOffset		(const Sampler& sampler, float s, float t, float r, float lod, const IVec2& offset) const;
888	float							sampleCompare		(const Sampler& sampler, float ref, float s, float t, float r, float lod) const;
889	float							sampleCompareOffset	(const Sampler& sampler, float ref, float s, float t, float r, float lod, const IVec2& offset) const;
890
891	Vec4							gatherOffsets		(const Sampler& sampler, float s, float t, float r, int componentNdx, const IVec2 (&offsets)[4]) const;
892	Vec4							gatherOffsetsCompare(const Sampler& sampler, float ref, float s, float t, float r, const IVec2 (&offsets)[4]) const;
893
894protected:
895	int								selectLayer			(float r) const;
896
897	int								m_numLevels;
898	const ConstPixelBufferAccess*	m_levels;
899} DE_WARN_UNUSED_TYPE;
900
901/*--------------------------------------------------------------------*//*!
902 * \brief 1D Array Texture reference implementation
903 *//*--------------------------------------------------------------------*/
904class Texture1DArray : private TextureLevelPyramid
905{
906public:
907									Texture1DArray		(const TextureFormat& format, int width, int numLayers);
908									Texture1DArray		(const Texture1DArray& other);
909									~Texture1DArray		(void);
910
911	int								getWidth			(void) const	{ return m_width;		}
912	int								getNumLayers		(void) const	{ return m_numLayers;	}
913
914	void							allocLevel			(int levelNdx);
915
916	using TextureLevelPyramid::getFormat;
917	using TextureLevelPyramid::getNumLevels;
918	using TextureLevelPyramid::getLevel;
919	using TextureLevelPyramid::clearLevel;
920	using TextureLevelPyramid::isLevelEmpty;
921
922	Vec4							sample				(const Sampler& sampler, float s, float t, float lod) const;
923	Vec4							sampleOffset		(const Sampler& sampler, float s, float t, float lod, deInt32 offset) const;
924	float							sampleCompare		(const Sampler& sampler, float ref, float s, float t, float lod) const;
925	float							sampleCompareOffset	(const Sampler& sampler, float ref, float s, float t, float lod, deInt32 offset) const;
926
927	Texture1DArray&					operator=			(const Texture1DArray& other);
928
929	operator Texture1DArrayView (void) const { return m_view; }
930
931private:
932	int								m_width;
933	int								m_numLayers;
934	Texture1DArrayView				m_view;
935} DE_WARN_UNUSED_TYPE;
936
937inline Vec4 Texture1DArray::sample (const Sampler& sampler, float s, float t, float lod) const
938{
939	return m_view.sample(sampler, s, t, lod);
940}
941
942inline Vec4 Texture1DArray::sampleOffset (const Sampler& sampler, float s, float t, float lod, deInt32 offset) const
943{
944	return m_view.sampleOffset(sampler, s, t, lod, offset);
945}
946
947inline float Texture1DArray::sampleCompare (const Sampler& sampler, float ref, float s, float t, float lod) const
948{
949	return m_view.sampleCompare(sampler, ref, s, t, lod);
950}
951
952inline float Texture1DArray::sampleCompareOffset (const Sampler& sampler, float ref, float s, float t, float lod, deInt32 offset) const
953{
954	return m_view.sampleCompareOffset(sampler, ref, s, t, lod, offset);
955}
956
957/*--------------------------------------------------------------------*//*!
958 * \brief 2D Array Texture reference implementation
959 *//*--------------------------------------------------------------------*/
960class Texture2DArray : private TextureLevelPyramid
961{
962public:
963									Texture2DArray		(const TextureFormat& format, int width, int height, int numLayers);
964									Texture2DArray		(const Texture2DArray& other);
965									~Texture2DArray		(void);
966
967	int								getWidth			(void) const	{ return m_width;		}
968	int								getHeight			(void) const	{ return m_height;		}
969	int								getNumLayers		(void) const	{ return m_numLayers;	}
970
971	void							allocLevel			(int levelNdx);
972
973	using TextureLevelPyramid::getFormat;
974	using TextureLevelPyramid::getNumLevels;
975	using TextureLevelPyramid::getLevel;
976	using TextureLevelPyramid::clearLevel;
977	using TextureLevelPyramid::isLevelEmpty;
978
979	Vec4							sample				(const Sampler& sampler, float s, float t, float r, float lod) const;
980	Vec4							sampleOffset		(const Sampler& sampler, float s, float t, float r, float lod, const IVec2& offset) const;
981	float							sampleCompare		(const Sampler& sampler, float ref, float s, float t, float r, float lod) const;
982	float							sampleCompareOffset	(const Sampler& sampler, float ref, float s, float t, float r, float lod, const IVec2& offset) const;
983
984	Vec4							gatherOffsets		(const Sampler& sampler, float s, float t, float r, int componentNdx, const IVec2 (&offsets)[4]) const;
985	Vec4							gatherOffsetsCompare(const Sampler& sampler, float ref, float s, float t, float r, const IVec2 (&offsets)[4]) const;
986
987	Texture2DArray&					operator=			(const Texture2DArray& other);
988
989	operator Texture2DArrayView (void) const { return m_view; }
990
991private:
992	int								m_width;
993	int								m_height;
994	int								m_numLayers;
995	Texture2DArrayView				m_view;
996} DE_WARN_UNUSED_TYPE;
997
998inline Vec4 Texture2DArray::sample (const Sampler& sampler, float s, float t, float r, float lod) const
999{
1000	return m_view.sample(sampler, s, t, r, lod);
1001}
1002
1003inline Vec4 Texture2DArray::sampleOffset (const Sampler& sampler, float s, float t, float r, float lod, const IVec2& offset) const
1004{
1005	return m_view.sampleOffset(sampler, s, t, r, lod, offset);
1006}
1007
1008inline float Texture2DArray::sampleCompare (const Sampler& sampler, float ref, float s, float t, float r, float lod) const
1009{
1010	return m_view.sampleCompare(sampler, ref, s, t, r, lod);
1011}
1012
1013inline float Texture2DArray::sampleCompareOffset (const Sampler& sampler, float ref, float s, float t, float r, float lod, const IVec2& offset) const
1014{
1015	return m_view.sampleCompareOffset(sampler, ref, s, t, r, lod, offset);
1016}
1017
1018inline Vec4 Texture2DArray::gatherOffsets (const Sampler& sampler, float s, float t, float r, int componentNdx, const IVec2 (&offsets)[4]) const
1019{
1020	return m_view.gatherOffsets(sampler, s, t, r, componentNdx, offsets);
1021}
1022
1023inline Vec4 Texture2DArray::gatherOffsetsCompare (const Sampler& sampler, float ref, float s, float t, float r, const IVec2 (&offsets)[4]) const
1024{
1025	return m_view.gatherOffsetsCompare(sampler, ref, s, t, r, offsets);
1026}
1027
1028/*--------------------------------------------------------------------*//*!
1029 * \brief 3D Texture View
1030 *//*--------------------------------------------------------------------*/
1031class Texture3DView
1032{
1033public:
1034									Texture3DView		(int numLevels, const ConstPixelBufferAccess* levels);
1035
1036	int								getWidth			(void) const	{ return m_numLevels > 0 ? m_levels[0].getWidth()	: 0;	}
1037	int								getHeight			(void) const	{ return m_numLevels > 0 ? m_levels[0].getHeight()	: 0;	}
1038	int								getDepth			(void) const	{ return m_numLevels > 0 ? m_levels[0].getDepth()	: 0;	}
1039	int								getNumLevels		(void) const	{ return m_numLevels;										}
1040	const ConstPixelBufferAccess&	getLevel			(int ndx) const	{ DE_ASSERT(de::inBounds(ndx, 0, m_numLevels)); return m_levels[ndx];	}
1041	const ConstPixelBufferAccess*	getLevels			(void) const	{ return m_levels;											}
1042
1043	Vec4							sample				(const Sampler& sampler, float s, float t, float r, float lod) const;
1044	Vec4							sampleOffset		(const Sampler& sampler, float s, float t, float r, float lod, const IVec3& offset) const;
1045
1046protected:
1047	int								m_numLevels;
1048	const ConstPixelBufferAccess*	m_levels;
1049} DE_WARN_UNUSED_TYPE;
1050
1051inline Vec4 Texture3DView::sample (const Sampler& sampler, float s, float t, float r, float lod) const
1052{
1053	return sampleLevelArray3D(m_levels, m_numLevels, sampler, s, t, r, lod);
1054}
1055
1056inline Vec4 Texture3DView::sampleOffset (const Sampler& sampler, float s, float t, float r, float lod, const IVec3& offset) const
1057{
1058	return sampleLevelArray3DOffset(m_levels, m_numLevels, sampler, s, t, r, lod, offset);
1059}
1060
1061/*--------------------------------------------------------------------*//*!
1062 * \brief 3D Texture reference implementation
1063 *//*--------------------------------------------------------------------*/
1064class Texture3D : private TextureLevelPyramid
1065{
1066public:
1067									Texture3D			(const TextureFormat& format, int width, int height, int depth);
1068									Texture3D			(const Texture3D& other);
1069									~Texture3D			(void);
1070
1071	int								getWidth			(void) const	{ return m_width;	}
1072	int								getHeight			(void) const	{ return m_height;	}
1073	int								getDepth			(void) const	{ return m_depth;	}
1074
1075	void							allocLevel			(int levelNdx);
1076
1077	using TextureLevelPyramid::getFormat;
1078	using TextureLevelPyramid::getNumLevels;
1079	using TextureLevelPyramid::getLevel;
1080	using TextureLevelPyramid::clearLevel;
1081	using TextureLevelPyramid::isLevelEmpty;
1082
1083	Vec4							sample				(const Sampler& sampler, float s, float t, float r, float lod) const;
1084	Vec4							sampleOffset		(const Sampler& sampler, float s, float t, float r, float lod, const IVec3& offset) const;
1085
1086	Texture3D&						operator=			(const Texture3D& other);
1087
1088	operator Texture3DView (void) const { return m_view; }
1089
1090private:
1091	int								m_width;
1092	int								m_height;
1093	int								m_depth;
1094	Texture3DView					m_view;
1095} DE_WARN_UNUSED_TYPE;
1096
1097inline Vec4 Texture3D::sample (const Sampler& sampler, float s, float t, float r, float lod) const
1098{
1099	return m_view.sample(sampler, s, t, r, lod);
1100}
1101
1102inline Vec4 Texture3D::sampleOffset (const Sampler& sampler, float s, float t, float r, float lod, const IVec3& offset) const
1103{
1104	return m_view.sampleOffset(sampler, s, t, r, lod, offset);
1105}
1106
1107/*--------------------------------------------------------------------*//*!
1108 * \brief Cube Map Array Texture View
1109 *//*--------------------------------------------------------------------*/
1110class TextureCubeArrayView
1111{
1112public:
1113									TextureCubeArrayView	(int numLevels, const ConstPixelBufferAccess* levels);
1114
1115	int								getSize					(void) const	{ return m_numLevels > 0 ? m_levels[0].getWidth()	: 0;	}
1116	int								getDepth				(void) const	{ return m_numLevels > 0 ? m_levels[0].getDepth()	: 0;	}
1117	int								getNumLayers			(void) const	{ return getDepth()	/ 6;	}
1118	int								getNumLevels			(void) const	{ return m_numLevels;										}
1119	const ConstPixelBufferAccess&	getLevel				(int ndx) const	{ DE_ASSERT(de::inBounds(ndx, 0, m_numLevels)); return m_levels[ndx];	}
1120	const ConstPixelBufferAccess*	getLevels				(void) const	{ return m_levels;											}
1121
1122	Vec4							sample					(const Sampler& sampler, float s, float t, float r, float q, float lod) const;
1123	Vec4							sampleOffset			(const Sampler& sampler, float s, float t, float r, float q, float lod, const IVec2& offset) const;
1124	float							sampleCompare			(const Sampler& sampler, float ref, float s, float t, float r, float q, float lod) const;
1125	float							sampleCompareOffset		(const Sampler& sampler, float ref, float s, float t, float r, float q, float lod, const IVec2& offset) const;
1126
1127protected:
1128	int								selectLayer				(float q) const;
1129
1130	int								m_numLevels;
1131	const ConstPixelBufferAccess*	m_levels;
1132} DE_WARN_UNUSED_TYPE;
1133
1134/*--------------------------------------------------------------------*//*!
1135 * \brief Cube Map Array Texture reference implementation
1136 *//*--------------------------------------------------------------------*/
1137class TextureCubeArray : private TextureLevelPyramid
1138{
1139public:
1140									TextureCubeArray	(const TextureFormat& format, int size, int depth);
1141									TextureCubeArray	(const TextureCubeArray& other);
1142									~TextureCubeArray	(void);
1143
1144	int								getSize				(void) const	{ return m_size;	}
1145	int								getDepth			(void) const	{ return m_depth;	}
1146
1147	void							allocLevel			(int levelNdx);
1148
1149	using TextureLevelPyramid::getFormat;
1150	using TextureLevelPyramid::getNumLevels;
1151	using TextureLevelPyramid::getLevel;
1152	using TextureLevelPyramid::clearLevel;
1153	using TextureLevelPyramid::isLevelEmpty;
1154
1155	Vec4							sample				(const Sampler& sampler, float s, float t, float r, float q, float lod) const;
1156	Vec4							sampleOffset		(const Sampler& sampler, float s, float t, float r, float q, float lod, const IVec2& offset) const;
1157	float							sampleCompare		(const Sampler& sampler, float ref, float s, float t, float r, float q, float lod) const;
1158	float							sampleCompareOffset	(const Sampler& sampler, float ref, float s, float t, float r, float q, float lod, const IVec2& offset) const;
1159
1160	TextureCubeArray&				operator=			(const TextureCubeArray& other);
1161
1162	operator TextureCubeArrayView (void) const { return m_view; }
1163
1164private:
1165	int								m_size;
1166	int								m_depth;
1167	TextureCubeArrayView			m_view;
1168} DE_WARN_UNUSED_TYPE;
1169
1170inline Vec4 TextureCubeArray::sample (const Sampler& sampler, float s, float t, float r, float q, float lod) const
1171{
1172	return m_view.sample(sampler, s, t, r, q, lod);
1173}
1174
1175inline Vec4 TextureCubeArray::sampleOffset (const Sampler& sampler, float s, float t, float r, float q, float lod, const IVec2& offset) const
1176{
1177	return m_view.sampleOffset(sampler, s, t, r, q, lod, offset);
1178}
1179
1180inline float TextureCubeArray::sampleCompare (const Sampler& sampler, float ref, float s, float t, float r, float q, float lod) const
1181{
1182	return m_view.sampleCompare(sampler, ref, s, t, r, q, lod);
1183}
1184
1185inline float TextureCubeArray::sampleCompareOffset (const Sampler& sampler, float ref, float s, float t, float r, float q, float lod, const IVec2& offset) const
1186{
1187	return m_view.sampleCompareOffset(sampler, ref, s, t, r, q, lod, offset);
1188}
1189
1190// Stream operators.
1191std::ostream&		operator<<		(std::ostream& str, TextureFormat::ChannelOrder order);
1192std::ostream&		operator<<		(std::ostream& str, TextureFormat::ChannelType type);
1193std::ostream&		operator<<		(std::ostream& str, TextureFormat format);
1194std::ostream&		operator<<		(std::ostream& str, CubeFace face);
1195std::ostream&		operator<<		(std::ostream& str, const ConstPixelBufferAccess& access);
1196
1197} // tcu
1198
1199#endif // _TCUTEXTURE_HPP
1200