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