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