• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2016 The Khronos Group Inc.
6  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
7  * Copyright (c) 2016 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 Texture access and query function tests.
24  *//*--------------------------------------------------------------------*/
25 
26 #include "vktShaderRenderTextureFunctionTests.hpp"
27 #include "vktShaderRender.hpp"
28 #include "gluTextureUtil.hpp"
29 #include "tcuTexture.hpp"
30 #include "tcuTextureUtil.hpp"
31 #include "tcuTestLog.hpp"
32 #include "tcuCommandLine.hpp"
33 #include "glwEnums.hpp"
34 #include "deMath.h"
35 #include "vkBarrierUtil.hpp"
36 #include "vkImageUtil.hpp"
37 #include "vkQueryUtil.hpp"
38 #include "vkObjUtil.hpp"
39 #include "vkCmdUtil.hpp"
40 #include <limits>
41 
42 namespace vkt
43 {
44 namespace sr
45 {
46 namespace
47 {
48 
49 using tcu::Vec2;
50 using tcu::Vec3;
51 using tcu::Vec4;
52 using tcu::IVec2;
53 using tcu::IVec3;
54 using tcu::IVec4;
55 
56 using std::vector;
57 
58 enum Function
59 {
60 	FUNCTION_TEXTURE = 0,		//!< texture(), textureOffset(), textureClampARB, textureOffsetClampARB
61 	FUNCTION_TEXTUREPROJ,		//!< textureProj(), textureProjOffset()
62 	FUNCTION_TEXTUREPROJ2,		//!< textureProj(sampler1D, vec2)
63 	FUNCTION_TEXTUREPROJ3,		//!< textureProj(sampler2D, vec3)
64 	FUNCTION_TEXTURELOD,		// ...
65 	FUNCTION_TEXTUREPROJLOD,
66 	FUNCTION_TEXTUREPROJLOD2,	//!< textureProjLod(sampler1D, vec2)
67 	FUNCTION_TEXTUREPROJLOD3,	//!< textureProjLod(sampler2D, vec3)
68 	FUNCTION_TEXTUREGRAD,		//!< textureGrad, textureGradOffset, textureGradClampARB, textureGradOffsetClampARB
69 	FUNCTION_TEXTUREPROJGRAD,
70 	FUNCTION_TEXTUREPROJGRAD2,	//!< textureProjGrad(sampler1D, vec2)
71 	FUNCTION_TEXTUREPROJGRAD3,	//!< textureProjGrad(sampler2D, vec3)
72 	FUNCTION_TEXELFETCH,
73 
74 	FUNCTION_LAST
75 };
76 
functionHasAutoLod(glu::ShaderType shaderType,Function function)77 inline bool functionHasAutoLod (glu::ShaderType shaderType, Function function)
78 {
79 	return shaderType == glu::SHADERTYPE_FRAGMENT &&
80 		   (function == FUNCTION_TEXTURE		||
81 			function == FUNCTION_TEXTUREPROJ	||
82 			function == FUNCTION_TEXTUREPROJ2	||
83 			function == FUNCTION_TEXTUREPROJ3);
84 }
85 
functionHasProj(Function function)86 inline bool functionHasProj (Function function)
87 {
88 	return function == FUNCTION_TEXTUREPROJ		||
89 		   function == FUNCTION_TEXTUREPROJ2	||
90 		   function == FUNCTION_TEXTUREPROJ3	||
91 		   function == FUNCTION_TEXTUREPROJLOD	||
92 		   function == FUNCTION_TEXTUREPROJLOD2	||
93 		   function == FUNCTION_TEXTUREPROJLOD3	||
94 		   function == FUNCTION_TEXTUREPROJGRAD	||
95 		   function == FUNCTION_TEXTUREPROJGRAD2||
96 		   function == FUNCTION_TEXTUREPROJGRAD3;
97 }
98 
functionHasGrad(Function function)99 inline bool functionHasGrad (Function function)
100 {
101 	return function == FUNCTION_TEXTUREGRAD		||
102 		   function == FUNCTION_TEXTUREPROJGRAD	||
103 		   function == FUNCTION_TEXTUREPROJGRAD2||
104 		   function == FUNCTION_TEXTUREPROJGRAD3;
105 }
106 
functionHasLod(Function function)107 inline bool functionHasLod (Function function)
108 {
109 	return function == FUNCTION_TEXTURELOD		||
110 		   function == FUNCTION_TEXTUREPROJLOD	||
111 		   function == FUNCTION_TEXTUREPROJLOD2	||
112 		   function == FUNCTION_TEXTUREPROJLOD3	||
113 		   function == FUNCTION_TEXELFETCH;
114 }
115 
116 struct TextureLookupSpec
117 {
118 	Function		function;
119 
120 	tcu::Vec4		minCoord;
121 	tcu::Vec4		maxCoord;
122 
123 	// Bias
124 	bool			useBias;
125 
126 	// Bias or Lod for *Lod* functions
127 	float			minLodBias;
128 	float			maxLodBias;
129 
130 	// For *Grad* functions
131 	tcu::Vec3		minDX;
132 	tcu::Vec3		maxDX;
133 	tcu::Vec3		minDY;
134 	tcu::Vec3		maxDY;
135 
136 	bool			useOffset;
137 	tcu::IVec3		offset;
138 
139 	// Lod clamp
140 	bool			useClamp;
141 	float			lodClamp;
142 
TextureLookupSpecvkt::sr::__anonb7fde05a0111::TextureLookupSpec143 	TextureLookupSpec (void)
144 		: function		(FUNCTION_LAST)
145 		, minCoord		(0.0f)
146 		, maxCoord		(1.0f)
147 		, useBias		(false)
148 		, minLodBias	(0.0f)
149 		, maxLodBias	(0.0f)
150 		, minDX			(0.0f)
151 		, maxDX			(0.0f)
152 		, minDY			(0.0f)
153 		, maxDY			(0.0f)
154 		, useOffset		(false)
155 		, offset		(0)
156 		, useClamp		(false)
157 		, lodClamp		(0.0f)
158 	{
159 	}
160 
TextureLookupSpecvkt::sr::__anonb7fde05a0111::TextureLookupSpec161 	TextureLookupSpec (Function				function_,
162 					   const tcu::Vec4&		minCoord_,
163 					   const tcu::Vec4&		maxCoord_,
164 					   bool					useBias_,
165 					   float				minLodBias_,
166 					   float				maxLodBias_,
167 					   const tcu::Vec3&		minDX_,
168 					   const tcu::Vec3&		maxDX_,
169 					   const tcu::Vec3&		minDY_,
170 					   const tcu::Vec3&		maxDY_,
171 					   bool					useOffset_,
172 					   const tcu::IVec3&	offset_,
173 					   bool					useClamp_,
174 					   float				lodClamp_)
175 		: function		(function_)
176 		, minCoord		(minCoord_)
177 		, maxCoord		(maxCoord_)
178 		, useBias		(useBias_)
179 		, minLodBias	(minLodBias_)
180 		, maxLodBias	(maxLodBias_)
181 		, minDX			(minDX_)
182 		, maxDX			(maxDX_)
183 		, minDY			(minDY_)
184 		, maxDY			(maxDY_)
185 		, useOffset		(useOffset_)
186 		, offset		(offset_)
187 		, useClamp		(useClamp_)
188 		, lodClamp		(lodClamp_)
189 	{
190 	}
191 };
192 
193 enum TextureType
194 {
195 	TEXTURETYPE_1D = 0,
196 	TEXTURETYPE_2D,
197 	TEXTURETYPE_3D,
198 	TEXTURETYPE_CUBE_MAP,
199 	TEXTURETYPE_1D_ARRAY,
200 	TEXTURETYPE_2D_ARRAY,
201 	TEXTURETYPE_CUBE_ARRAY,
202 
203 	TEXTURETYPE_LAST
204 };
205 
206 struct TextureSpec
207 {
208 	TextureType			type;		//!< Texture type (2D, cubemap, ...)
209 	deUint32			format;		//!< Internal format.
210 	int					width;
211 	int					height;
212 	int					depth;
213 	int					numLevels;
214 	tcu::Sampler		sampler;
215 
TextureSpecvkt::sr::__anonb7fde05a0111::TextureSpec216 	TextureSpec (void)
217 		: type			(TEXTURETYPE_LAST)
218 		, format		(GL_NONE)
219 		, width			(0)
220 		, height		(0)
221 		, depth			(0)
222 		, numLevels		(0)
223 	{
224 	}
225 
TextureSpecvkt::sr::__anonb7fde05a0111::TextureSpec226 	TextureSpec (TextureType			type_,
227 				 deUint32				format_,
228 				 int					width_,
229 				 int					height_,
230 				 int					depth_,
231 				 int					numLevels_,
232 				 const tcu::Sampler&	sampler_)
233 		: type			(type_)
234 		, format		(format_)
235 		, width			(width_)
236 		, height		(height_)
237 		, depth			(depth_)
238 		, numLevels		(numLevels_)
239 		, sampler		(sampler_)
240 	{
241 	}
242 };
243 
244 struct TexLookupParams
245 {
246 	float				lod;
247 	float				lodClamp;
248 	tcu::IVec3			offset;
249 	tcu::Vec4			scale;
250 	tcu::Vec4			bias;
251 
TexLookupParamsvkt::sr::__anonb7fde05a0111::TexLookupParams252 	TexLookupParams (void)
253 		: lod		(0.0f)
254 		, lodClamp	(0.0f)
255 		, offset	(0)
256 		, scale		(1.0f)
257 		, bias		(0.0f)
258 	{
259 	}
260 };
261 
262 // \note LodMode and computeLodFromDerivates functions are copied from glsTextureTestUtil
263 namespace TextureTestUtil
264 {
265 
266 enum LodMode
267 {
268 	LODMODE_EXACT = 0,		//!< Ideal lod computation.
269 	LODMODE_MIN_BOUND,		//!< Use estimation range minimum bound.
270 	LODMODE_MAX_BOUND,		//!< Use estimation range maximum bound.
271 
272 	LODMODE_LAST
273 };
274 
275 // 1D lookup LOD computation.
276 
computeLodFromDerivates(LodMode mode,float dudx,float dudy)277 float computeLodFromDerivates (LodMode mode, float dudx, float dudy)
278 {
279 	float p = 0.0f;
280 	switch (mode)
281 	{
282 		// \note [mika] Min and max bounds equal to exact with 1D textures
283 		case LODMODE_EXACT:
284 		case LODMODE_MIN_BOUND:
285 		case LODMODE_MAX_BOUND:
286 			p = de::max(deFloatAbs(dudx), deFloatAbs(dudy));
287 			break;
288 
289 		default:
290 			DE_ASSERT(DE_FALSE);
291 	}
292 
293 	return deFloatLog2(p);
294 }
295 
296 // 2D lookup LOD computation.
297 
computeLodFromDerivates(LodMode mode,float dudx,float dvdx,float dudy,float dvdy)298 float computeLodFromDerivates (LodMode mode, float dudx, float dvdx, float dudy, float dvdy)
299 {
300 	float p = 0.0f;
301 	switch (mode)
302 	{
303 		case LODMODE_EXACT:
304 			p = de::max(deFloatSqrt(dudx*dudx + dvdx*dvdx), deFloatSqrt(dudy*dudy + dvdy*dvdy));
305 			break;
306 
307 		case LODMODE_MIN_BOUND:
308 		case LODMODE_MAX_BOUND:
309 		{
310 			float mu = de::max(deFloatAbs(dudx), deFloatAbs(dudy));
311 			float mv = de::max(deFloatAbs(dvdx), deFloatAbs(dvdy));
312 
313 			p = mode == LODMODE_MIN_BOUND ? de::max(mu, mv) : mu + mv;
314 			break;
315 		}
316 
317 		default:
318 			DE_ASSERT(DE_FALSE);
319 	}
320 
321 	return deFloatLog2(p);
322 }
323 
324 // 3D lookup LOD computation.
325 
computeLodFromDerivates(LodMode mode,float dudx,float dvdx,float dwdx,float dudy,float dvdy,float dwdy)326 float computeLodFromDerivates (LodMode mode, float dudx, float dvdx, float dwdx, float dudy, float dvdy, float dwdy)
327 {
328 	float p = 0.0f;
329 	switch (mode)
330 	{
331 		case LODMODE_EXACT:
332 			p = de::max(deFloatSqrt(dudx*dudx + dvdx*dvdx + dwdx*dwdx), deFloatSqrt(dudy*dudy + dvdy*dvdy + dwdy*dwdy));
333 			break;
334 
335 		case LODMODE_MIN_BOUND:
336 		case LODMODE_MAX_BOUND:
337 		{
338 			float mu = de::max(deFloatAbs(dudx), deFloatAbs(dudy));
339 			float mv = de::max(deFloatAbs(dvdx), deFloatAbs(dvdy));
340 			float mw = de::max(deFloatAbs(dwdx), deFloatAbs(dwdy));
341 
342 			p = mode == LODMODE_MIN_BOUND ? de::max(de::max(mu, mv), mw) : (mu + mv + mw);
343 			break;
344 		}
345 
346 		default:
347 			DE_ASSERT(DE_FALSE);
348 	}
349 
350 	return deFloatLog2(p);
351 }
352 
353 } // TextureTestUtil
354 
355 using namespace TextureTestUtil;
356 
357 static const LodMode DEFAULT_LOD_MODE = LODMODE_EXACT;
358 
computeLodFromGrad2D(const ShaderEvalContext & c)359 inline float computeLodFromGrad2D (const ShaderEvalContext& c)
360 {
361 	float w = (float)c.textures[0].tex2D->getWidth();
362 	float h = (float)c.textures[0].tex2D->getHeight();
363 	return computeLodFromDerivates(DEFAULT_LOD_MODE, c.in[1].x()*w, c.in[1].y()*h, c.in[2].x()*w, c.in[2].y()*h);
364 }
365 
computeLodFromGrad2DArray(const ShaderEvalContext & c)366 inline float computeLodFromGrad2DArray (const ShaderEvalContext& c)
367 {
368 	float w = (float)c.textures[0].tex2DArray->getWidth();
369 	float h = (float)c.textures[0].tex2DArray->getHeight();
370 	return computeLodFromDerivates(DEFAULT_LOD_MODE, c.in[1].x()*w, c.in[1].y()*h, c.in[2].x()*w, c.in[2].y()*h);
371 }
372 
computeLodFromGrad3D(const ShaderEvalContext & c)373 inline float computeLodFromGrad3D (const ShaderEvalContext& c)
374 {
375 	float w = (float)c.textures[0].tex3D->getWidth();
376 	float h = (float)c.textures[0].tex3D->getHeight();
377 	float d = (float)c.textures[0].tex3D->getDepth();
378 	return computeLodFromDerivates(DEFAULT_LOD_MODE, c.in[1].x()*w, c.in[1].y()*h, c.in[1].z()*d, c.in[2].x()*w, c.in[2].y()*h, c.in[2].z()*d);
379 }
380 
computeLodFromGradCube(const ShaderEvalContext & c)381 inline float computeLodFromGradCube (const ShaderEvalContext& c)
382 {
383 	// \note Major axis is always -Z or +Z
384 	float m = de::abs(c.in[0].z());
385 	float d = (float)c.textures[0].texCube->getSize();
386 	float s = d/(2.0f*m);
387 	float t = d/(2.0f*m);
388 	return computeLodFromDerivates(DEFAULT_LOD_MODE, c.in[1].x()*s, c.in[1].y()*t, c.in[2].x()*s, c.in[2].y()*t);
389 }
390 
computeLodFromGrad1D(const ShaderEvalContext & c)391 inline float computeLodFromGrad1D (const ShaderEvalContext& c)
392 {
393 	float w = (float)c.textures[0].tex1D->getWidth();
394 	return computeLodFromDerivates(DEFAULT_LOD_MODE, c.in[1].x()*w, c.in[2].x()*w);
395 }
396 
computeLodFromGrad1DArray(const ShaderEvalContext & c)397 inline float computeLodFromGrad1DArray (const ShaderEvalContext& c)
398 {
399 	float w = (float)c.textures[0].tex1DArray->getWidth();
400 	return computeLodFromDerivates(DEFAULT_LOD_MODE, c.in[1].x()*w, c.in[2].x()*w);
401 }
402 
computeLodFromGradCubeArray(const ShaderEvalContext & c)403 inline float computeLodFromGradCubeArray (const ShaderEvalContext& c)
404 {
405 	// \note Major axis is always -Z or +Z
406 	float m = de::abs(c.in[0].z());
407 	float d = (float)c.textures[0].texCubeArray->getSize();
408 	float s = d/(2.0f*m);
409 	float t = d/(2.0f*m);
410 	return computeLodFromDerivates(DEFAULT_LOD_MODE, c.in[1].x()*s, c.in[1].y()*t, c.in[2].x()*s, c.in[2].y()*t);
411 }
412 
413 typedef void (*TexEvalFunc) (ShaderEvalContext& c, const TexLookupParams& lookupParams);
414 
texture2D(const ShaderEvalContext & c,float s,float t,float lod)415 inline Vec4 texture2D			(const ShaderEvalContext& c, float s, float t, float lod)					{ return c.textures[0].tex2D->sample(c.textures[0].sampler, s, t, lod);					}
textureCube(const ShaderEvalContext & c,float s,float t,float r,float lod)416 inline Vec4 textureCube			(const ShaderEvalContext& c, float s, float t, float r, float lod)			{ return c.textures[0].texCube->sample(c.textures[0].sampler, s, t, r, lod);			}
texture2DArray(const ShaderEvalContext & c,float s,float t,float r,float lod)417 inline Vec4 texture2DArray		(const ShaderEvalContext& c, float s, float t, float r, float lod)			{ return c.textures[0].tex2DArray->sample(c.textures[0].sampler, s, t, r, lod);			}
texture3D(const ShaderEvalContext & c,float s,float t,float r,float lod)418 inline Vec4 texture3D			(const ShaderEvalContext& c, float s, float t, float r, float lod)			{ return c.textures[0].tex3D->sample(c.textures[0].sampler, s, t, r, lod);				}
texture1D(const ShaderEvalContext & c,float s,float lod)419 inline Vec4 texture1D			(const ShaderEvalContext& c, float s, float lod)							{ return c.textures[0].tex1D->sample(c.textures[0].sampler, s, lod);					}
texture1DArray(const ShaderEvalContext & c,float s,float t,float lod)420 inline Vec4 texture1DArray		(const ShaderEvalContext& c, float s, float t, float lod)					{ return c.textures[0].tex1DArray->sample(c.textures[0].sampler, s, t, lod);			}
textureCubeArray(const ShaderEvalContext & c,float s,float t,float r,float q,float lod)421 inline Vec4 textureCubeArray	(const ShaderEvalContext& c, float s, float t, float r, float q, float lod)	{ return c.textures[0].texCubeArray->sample(c.textures[0].sampler, s, t, r, q, lod);	}
422 
texture2DShadow(const ShaderEvalContext & c,float ref,float s,float t,float lod)423 inline float texture2DShadow		(const ShaderEvalContext& c, float ref, float s, float t, float lod)					{ return c.textures[0].tex2D->sampleCompare(c.textures[0].sampler, ref, s, t, lod);					}
textureCubeShadow(const ShaderEvalContext & c,float ref,float s,float t,float r,float lod)424 inline float textureCubeShadow		(const ShaderEvalContext& c, float ref, float s, float t, float r, float lod)			{ return c.textures[0].texCube->sampleCompare(c.textures[0].sampler, ref, s, t, r, lod);			}
texture2DArrayShadow(const ShaderEvalContext & c,float ref,float s,float t,float r,float lod)425 inline float texture2DArrayShadow	(const ShaderEvalContext& c, float ref, float s, float t, float r, float lod)			{ return c.textures[0].tex2DArray->sampleCompare(c.textures[0].sampler, ref, s, t, r, lod);			}
texture1DShadow(const ShaderEvalContext & c,float ref,float s,float lod)426 inline float texture1DShadow		(const ShaderEvalContext& c, float ref, float s, float lod)								{ return c.textures[0].tex1D->sampleCompare(c.textures[0].sampler, ref, s, lod);					}
texture1DArrayShadow(const ShaderEvalContext & c,float ref,float s,float t,float lod)427 inline float texture1DArrayShadow	(const ShaderEvalContext& c, float ref, float s, float t, float lod)					{ return c.textures[0].tex1DArray->sampleCompare(c.textures[0].sampler, ref, s, t, lod);			}
textureCubeArrayShadow(const ShaderEvalContext & c,float ref,float s,float t,float r,float q,float lod)428 inline float textureCubeArrayShadow	(const ShaderEvalContext& c, float ref, float s, float t, float r, float q, float lod)	{ return c.textures[0].texCubeArray->sampleCompare(c.textures[0].sampler, ref, s, t, r, q, lod);	}
429 
texture2DOffset(const ShaderEvalContext & c,float s,float t,float lod,IVec2 offset)430 inline Vec4 texture2DOffset			(const ShaderEvalContext& c, float s, float t, float lod, IVec2 offset)				{ return c.textures[0].tex2D->sampleOffset(c.textures[0].sampler, s, t, lod, offset);			}
texture2DArrayOffset(const ShaderEvalContext & c,float s,float t,float r,float lod,IVec2 offset)431 inline Vec4 texture2DArrayOffset	(const ShaderEvalContext& c, float s, float t, float r, float lod, IVec2 offset)	{ return c.textures[0].tex2DArray->sampleOffset(c.textures[0].sampler, s, t, r, lod, offset);	}
texture3DOffset(const ShaderEvalContext & c,float s,float t,float r,float lod,IVec3 offset)432 inline Vec4 texture3DOffset			(const ShaderEvalContext& c, float s, float t, float r, float lod, IVec3 offset)	{ return c.textures[0].tex3D->sampleOffset(c.textures[0].sampler, s, t, r, lod, offset);		}
texture1DOffset(const ShaderEvalContext & c,float s,float lod,deInt32 offset)433 inline Vec4 texture1DOffset			(const ShaderEvalContext& c, float s, float lod, deInt32 offset)					{ return c.textures[0].tex1D->sampleOffset(c.textures[0].sampler, s, lod, offset);				}
texture1DArrayOffset(const ShaderEvalContext & c,float s,float t,float lod,deInt32 offset)434 inline Vec4 texture1DArrayOffset	(const ShaderEvalContext& c, float s, float t, float lod, deInt32 offset)			{ return c.textures[0].tex1DArray->sampleOffset(c.textures[0].sampler, s, t, lod, offset);		}
435 
texture2DShadowOffset(const ShaderEvalContext & c,float ref,float s,float t,float lod,IVec2 offset)436 inline float texture2DShadowOffset		(const ShaderEvalContext& c, float ref, float s, float t, float lod, IVec2 offset)			{ return c.textures[0].tex2D->sampleCompareOffset(c.textures[0].sampler, ref, s, t, lod, offset);			}
texture2DArrayShadowOffset(const ShaderEvalContext & c,float ref,float s,float t,float r,float lod,IVec2 offset)437 inline float texture2DArrayShadowOffset	(const ShaderEvalContext& c, float ref, float s, float t, float r, float lod, IVec2 offset)	{ return c.textures[0].tex2DArray->sampleCompareOffset(c.textures[0].sampler, ref, s, t, r, lod, offset);	}
texture1DShadowOffset(const ShaderEvalContext & c,float ref,float s,float lod,deInt32 offset)438 inline float texture1DShadowOffset		(const ShaderEvalContext& c, float ref, float s, float lod, deInt32 offset)					{ return c.textures[0].tex1D->sampleCompareOffset(c.textures[0].sampler, ref, s, lod, offset);				}
texture1DArrayShadowOffset(const ShaderEvalContext & c,float ref,float s,float t,float lod,deInt32 offset)439 inline float texture1DArrayShadowOffset	(const ShaderEvalContext& c, float ref, float s, float t, float lod, deInt32 offset)		{ return c.textures[0].tex1DArray->sampleCompareOffset(c.textures[0].sampler, ref, s, t, lod, offset);		}
440 
441 // Eval functions.
evalTexture2D(ShaderEvalContext & c,const TexLookupParams & p)442 static void		evalTexture2D					(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2D(c, c.in[0].x(), c.in[0].y(), p.lod)*p.scale + p.bias; }
evalTextureCube(ShaderEvalContext & c,const TexLookupParams & p)443 static void		evalTextureCube					(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = textureCube(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod)*p.scale + p.bias; }
evalTexture2DArray(ShaderEvalContext & c,const TexLookupParams & p)444 static void		evalTexture2DArray				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DArray(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod)*p.scale + p.bias; }
evalTexture3D(ShaderEvalContext & c,const TexLookupParams & p)445 static void		evalTexture3D					(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3D(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod)*p.scale + p.bias; }
evalTexture1D(ShaderEvalContext & c,const TexLookupParams & p)446 static void		evalTexture1D					(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1D(c, c.in[0].x(), p.lod)*p.scale + p.bias; }
evalTexture1DArray(ShaderEvalContext & c,const TexLookupParams & p)447 static void		evalTexture1DArray				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DArray(c, c.in[0].x(), c.in[0].y(), p.lod)*p.scale + p.bias; }
evalTextureCubeArray(ShaderEvalContext & c,const TexLookupParams & p)448 static void		evalTextureCubeArray			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = textureCubeArray(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), c.in[0].w(), p.lod)*p.scale + p.bias; }
449 
evalTexture2DBias(ShaderEvalContext & c,const TexLookupParams & p)450 static void		evalTexture2DBias				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2D(c, c.in[0].x(), c.in[0].y(), p.lod+c.in[1].x())*p.scale + p.bias; }
evalTextureCubeBias(ShaderEvalContext & c,const TexLookupParams & p)451 static void		evalTextureCubeBias				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = textureCube(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod+c.in[1].x())*p.scale + p.bias; }
evalTexture2DArrayBias(ShaderEvalContext & c,const TexLookupParams & p)452 static void		evalTexture2DArrayBias			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DArray(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod+c.in[1].x())*p.scale + p.bias; }
evalTexture3DBias(ShaderEvalContext & c,const TexLookupParams & p)453 static void		evalTexture3DBias				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3D(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod+c.in[1].x())*p.scale + p.bias; }
evalTexture1DBias(ShaderEvalContext & c,const TexLookupParams & p)454 static void		evalTexture1DBias				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1D(c, c.in[0].x(), p.lod+c.in[1].x())*p.scale + p.bias; }
evalTexture1DArrayBias(ShaderEvalContext & c,const TexLookupParams & p)455 static void		evalTexture1DArrayBias			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DArray(c, c.in[0].x(), c.in[0].y(), p.lod+c.in[1].x())*p.scale + p.bias; }
evalTextureCubeArrayBias(ShaderEvalContext & c,const TexLookupParams & p)456 static void		evalTextureCubeArrayBias		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = textureCubeArray(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), c.in[0].w(), p.lod+c.in[1].x())*p.scale + p.bias; }
457 
evalTexture2DProj3(ShaderEvalContext & c,const TexLookupParams & p)458 static void		evalTexture2DProj3				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2D(c, c.in[0].x()/c.in[0].z(), c.in[0].y()/c.in[0].z(), p.lod)*p.scale + p.bias; }
evalTexture2DProj3Bias(ShaderEvalContext & c,const TexLookupParams & p)459 static void		evalTexture2DProj3Bias			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2D(c, c.in[0].x()/c.in[0].z(), c.in[0].y()/c.in[0].z(), p.lod+c.in[1].x())*p.scale + p.bias; }
evalTexture2DProj(ShaderEvalContext & c,const TexLookupParams & p)460 static void		evalTexture2DProj				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2D(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), p.lod)*p.scale + p.bias; }
evalTexture2DProjBias(ShaderEvalContext & c,const TexLookupParams & p)461 static void		evalTexture2DProjBias			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2D(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), p.lod+c.in[1].x())*p.scale + p.bias; }
evalTexture3DProj(ShaderEvalContext & c,const TexLookupParams & p)462 static void		evalTexture3DProj				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3D(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), c.in[0].z()/c.in[0].w(), p.lod)*p.scale + p.bias; }
evalTexture3DProjBias(ShaderEvalContext & c,const TexLookupParams & p)463 static void		evalTexture3DProjBias			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3D(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), c.in[0].z()/c.in[0].w(), p.lod+c.in[1].x())*p.scale + p.bias; }
evalTexture1DProj2(ShaderEvalContext & c,const TexLookupParams & p)464 static void		evalTexture1DProj2				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1D(c, c.in[0].x()/c.in[0].y(), p.lod)*p.scale + p.bias; }
evalTexture1DProj2Bias(ShaderEvalContext & c,const TexLookupParams & p)465 static void		evalTexture1DProj2Bias			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1D(c, c.in[0].x()/c.in[0].y(), p.lod+c.in[1].x())*p.scale + p.bias; }
evalTexture1DProj(ShaderEvalContext & c,const TexLookupParams & p)466 static void		evalTexture1DProj				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1D(c, c.in[0].x()/c.in[0].w(), p.lod)*p.scale + p.bias; }
evalTexture1DProjBias(ShaderEvalContext & c,const TexLookupParams & p)467 static void		evalTexture1DProjBias			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1D(c, c.in[0].x()/c.in[0].w(), p.lod+c.in[1].x())*p.scale + p.bias; }
468 
evalTexture2DLod(ShaderEvalContext & c,const TexLookupParams & p)469 static void		evalTexture2DLod				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2D(c, c.in[0].x(), c.in[0].y(), c.in[1].x())*p.scale + p.bias; }
evalTextureCubeLod(ShaderEvalContext & c,const TexLookupParams & p)470 static void		evalTextureCubeLod				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = textureCube(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), c.in[1].x())*p.scale + p.bias; }
evalTexture2DArrayLod(ShaderEvalContext & c,const TexLookupParams & p)471 static void		evalTexture2DArrayLod			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DArray(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), c.in[1].x())*p.scale + p.bias; }
evalTexture3DLod(ShaderEvalContext & c,const TexLookupParams & p)472 static void		evalTexture3DLod				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3D(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), c.in[1].x())*p.scale + p.bias; }
evalTexture1DLod(ShaderEvalContext & c,const TexLookupParams & p)473 static void		evalTexture1DLod				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1D(c, c.in[0].x(), c.in[1].x())*p.scale + p.bias; }
evalTexture1DArrayLod(ShaderEvalContext & c,const TexLookupParams & p)474 static void		evalTexture1DArrayLod			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DArray(c, c.in[0].x(), c.in[0].y(), c.in[1].x())*p.scale + p.bias; }
evalTextureCubeArrayLod(ShaderEvalContext & c,const TexLookupParams & p)475 static void		evalTextureCubeArrayLod			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = textureCubeArray(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), c.in[0].w(), c.in[1].x())*p.scale + p.bias; }
476 
evalTexture2DProjLod3(ShaderEvalContext & c,const TexLookupParams & p)477 static void		evalTexture2DProjLod3			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2D(c, c.in[0].x()/c.in[0].z(), c.in[0].y()/c.in[0].z(), c.in[1].x())*p.scale + p.bias; }
evalTexture2DProjLod(ShaderEvalContext & c,const TexLookupParams & p)478 static void		evalTexture2DProjLod			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2D(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), c.in[1].x())*p.scale + p.bias; }
evalTexture3DProjLod(ShaderEvalContext & c,const TexLookupParams & p)479 static void		evalTexture3DProjLod			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3D(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), c.in[0].z()/c.in[0].w(), c.in[1].x())*p.scale + p.bias; }
evalTexture1DProjLod2(ShaderEvalContext & c,const TexLookupParams & p)480 static void		evalTexture1DProjLod2			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1D(c, c.in[0].x()/c.in[0].y(), c.in[1].x())*p.scale + p.bias; }
evalTexture1DProjLod(ShaderEvalContext & c,const TexLookupParams & p)481 static void		evalTexture1DProjLod			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1D(c, c.in[0].x()/c.in[0].w(), c.in[1].x())*p.scale + p.bias; }
482 
evalTexture2DBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)483 static void		evalTexture2DBiasClamp			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2D(c, c.in[0].x(), c.in[0].y(), de::max(p.lod+c.in[1].x(), p.lodClamp))*p.scale + p.bias; }
evalTextureCubeBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)484 static void		evalTextureCubeBiasClamp		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = textureCube(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), de::max(p.lod+c.in[1].x(), p.lodClamp))*p.scale + p.bias; }
evalTexture2DArrayBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)485 static void		evalTexture2DArrayBiasClamp		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DArray(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), de::max(p.lod+c.in[1].x(), p.lodClamp))*p.scale + p.bias; }
evalTexture3DBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)486 static void		evalTexture3DBiasClamp			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3D(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), de::max(p.lod+c.in[1].x(), p.lodClamp))*p.scale + p.bias; }
evalTexture1DBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)487 static void		evalTexture1DBiasClamp			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1D(c, c.in[0].x(), de::max(p.lod+c.in[1].x(), p.lodClamp))*p.scale + p.bias; }
evalTexture1DArrayBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)488 static void		evalTexture1DArrayBiasClamp		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DArray(c, c.in[0].x(), c.in[0].y(), de::max(p.lod+c.in[1].x(), p.lodClamp))*p.scale + p.bias; }
evalTextureCubeArrayBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)489 static void		evalTextureCubeArrayBiasClamp	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = textureCubeArray(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), c.in[0].w(), de::max(p.lod+c.in[1].x(), p.lodClamp))*p.scale + p.bias; }
490 
491 // Offset variants
492 
evalTexture2DOffset(ShaderEvalContext & c,const TexLookupParams & p)493 static void		evalTexture2DOffset				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DOffset(c, c.in[0].x(), c.in[0].y(), p.lod, p.offset.swizzle(0,1))*p.scale + p.bias; }
evalTexture2DArrayOffset(ShaderEvalContext & c,const TexLookupParams & p)494 static void		evalTexture2DArrayOffset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DArrayOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod, p.offset.swizzle(0,1))*p.scale + p.bias; }
evalTexture3DOffset(ShaderEvalContext & c,const TexLookupParams & p)495 static void		evalTexture3DOffset				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3DOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod, p.offset)*p.scale + p.bias; }
evalTexture1DOffset(ShaderEvalContext & c,const TexLookupParams & p)496 static void		evalTexture1DOffset				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DOffset(c, c.in[0].x(), p.lod, p.offset.x())*p.scale + p.bias; }
evalTexture1DArrayOffset(ShaderEvalContext & c,const TexLookupParams & p)497 static void		evalTexture1DArrayOffset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DArrayOffset(c, c.in[0].x(), c.in[0].y(), p.lod, p.offset.x())*p.scale + p.bias; }
498 
evalTexture2DOffsetBias(ShaderEvalContext & c,const TexLookupParams & p)499 static void		evalTexture2DOffsetBias			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DOffset(c, c.in[0].x(), c.in[0].y(), p.lod+c.in[1].x(), p.offset.swizzle(0,1))*p.scale + p.bias; }
evalTexture2DArrayOffsetBias(ShaderEvalContext & c,const TexLookupParams & p)500 static void		evalTexture2DArrayOffsetBias	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DArrayOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod+c.in[1].x(), p.offset.swizzle(0,1))*p.scale + p.bias; }
evalTexture3DOffsetBias(ShaderEvalContext & c,const TexLookupParams & p)501 static void		evalTexture3DOffsetBias			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3DOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod+c.in[1].x(), p.offset)*p.scale + p.bias; }
evalTexture1DOffsetBias(ShaderEvalContext & c,const TexLookupParams & p)502 static void		evalTexture1DOffsetBias			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DOffset(c, c.in[0].x(), p.lod+c.in[1].x(), p.offset.x())*p.scale + p.bias; }
evalTexture1DArrayOffsetBias(ShaderEvalContext & c,const TexLookupParams & p)503 static void		evalTexture1DArrayOffsetBias	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DArrayOffset(c, c.in[0].x(), c.in[0].y(), p.lod+c.in[1].x(), p.offset.x())*p.scale + p.bias; }
504 
evalTexture2DLodOffset(ShaderEvalContext & c,const TexLookupParams & p)505 static void		evalTexture2DLodOffset			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DOffset(c, c.in[0].x(), c.in[0].y(), c.in[1].x(), p.offset.swizzle(0,1))*p.scale + p.bias; }
evalTexture2DArrayLodOffset(ShaderEvalContext & c,const TexLookupParams & p)506 static void		evalTexture2DArrayLodOffset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DArrayOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), c.in[1].x(), p.offset.swizzle(0,1))*p.scale + p.bias; }
evalTexture3DLodOffset(ShaderEvalContext & c,const TexLookupParams & p)507 static void		evalTexture3DLodOffset			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3DOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), c.in[1].x(), p.offset)*p.scale + p.bias; }
evalTexture1DLodOffset(ShaderEvalContext & c,const TexLookupParams & p)508 static void		evalTexture1DLodOffset			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DOffset(c, c.in[0].x(), c.in[1].x(), p.offset.x())*p.scale + p.bias; }
evalTexture1DArrayLodOffset(ShaderEvalContext & c,const TexLookupParams & p)509 static void		evalTexture1DArrayLodOffset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DArrayOffset(c, c.in[0].x(), c.in[0].y(), c.in[1].x(), p.offset.x())*p.scale + p.bias; }
510 
evalTexture2DProj3Offset(ShaderEvalContext & c,const TexLookupParams & p)511 static void		evalTexture2DProj3Offset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DOffset(c, c.in[0].x()/c.in[0].z(), c.in[0].y()/c.in[0].z(), p.lod, p.offset.swizzle(0,1))*p.scale + p.bias; }
evalTexture2DProj3OffsetBias(ShaderEvalContext & c,const TexLookupParams & p)512 static void		evalTexture2DProj3OffsetBias	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DOffset(c, c.in[0].x()/c.in[0].z(), c.in[0].y()/c.in[0].z(), p.lod+c.in[1].x(), p.offset.swizzle(0,1))*p.scale + p.bias; }
evalTexture2DProjOffset(ShaderEvalContext & c,const TexLookupParams & p)513 static void		evalTexture2DProjOffset			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DOffset(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), p.lod, p.offset.swizzle(0,1))*p.scale + p.bias; }
evalTexture2DProjOffsetBias(ShaderEvalContext & c,const TexLookupParams & p)514 static void		evalTexture2DProjOffsetBias		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DOffset(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), p.lod+c.in[1].x(), p.offset.swizzle(0,1))*p.scale + p.bias; }
evalTexture3DProjOffset(ShaderEvalContext & c,const TexLookupParams & p)515 static void		evalTexture3DProjOffset			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3DOffset(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), c.in[0].z()/c.in[0].w(), p.lod, p.offset)*p.scale + p.bias; }
evalTexture3DProjOffsetBias(ShaderEvalContext & c,const TexLookupParams & p)516 static void		evalTexture3DProjOffsetBias		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3DOffset(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), c.in[0].z()/c.in[0].w(), p.lod+c.in[1].x(), p.offset)*p.scale + p.bias; }
evalTexture1DProj2Offset(ShaderEvalContext & c,const TexLookupParams & p)517 static void		evalTexture1DProj2Offset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DOffset(c, c.in[0].x()/c.in[0].y(), p.lod, p.offset.x())*p.scale + p.bias; }
evalTexture1DProj2OffsetBias(ShaderEvalContext & c,const TexLookupParams & p)518 static void		evalTexture1DProj2OffsetBias	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DOffset(c, c.in[0].x()/c.in[0].y(), p.lod+c.in[1].x(), p.offset.x())*p.scale + p.bias; }
evalTexture1DProjOffset(ShaderEvalContext & c,const TexLookupParams & p)519 static void		evalTexture1DProjOffset			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DOffset(c, c.in[0].x()/c.in[0].w(), p.lod, p.offset.x())*p.scale + p.bias; }
evalTexture1DProjOffsetBias(ShaderEvalContext & c,const TexLookupParams & p)520 static void		evalTexture1DProjOffsetBias		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DOffset(c, c.in[0].x()/c.in[0].w(), p.lod+c.in[1].x(), p.offset.x())*p.scale + p.bias; }
521 
evalTexture2DProjLod3Offset(ShaderEvalContext & c,const TexLookupParams & p)522 static void		evalTexture2DProjLod3Offset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DOffset(c, c.in[0].x()/c.in[0].z(), c.in[0].y()/c.in[0].z(), c.in[1].x(), p.offset.swizzle(0,1))*p.scale + p.bias; }
evalTexture2DProjLodOffset(ShaderEvalContext & c,const TexLookupParams & p)523 static void		evalTexture2DProjLodOffset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DOffset(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), c.in[1].x(), p.offset.swizzle(0,1))*p.scale + p.bias; }
evalTexture3DProjLodOffset(ShaderEvalContext & c,const TexLookupParams & p)524 static void		evalTexture3DProjLodOffset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3DOffset(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), c.in[0].z()/c.in[0].w(), c.in[1].x(), p.offset)*p.scale + p.bias; }
evalTexture1DProjLod2Offset(ShaderEvalContext & c,const TexLookupParams & p)525 static void		evalTexture1DProjLod2Offset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DOffset(c, c.in[0].x()/c.in[0].y(), c.in[1].x(), p.offset.x())*p.scale + p.bias; }
evalTexture1DProjLodOffset(ShaderEvalContext & c,const TexLookupParams & p)526 static void		evalTexture1DProjLodOffset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DOffset(c, c.in[0].x()/c.in[0].w(), c.in[1].x(), p.offset.x())*p.scale + p.bias; }
527 
evalTexture2DOffsetBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)528 static void		evalTexture2DOffsetBiasClamp		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DOffset(c, c.in[0].x(), c.in[0].y(), de::max(p.lod+c.in[1].x(), p.lodClamp), p.offset.swizzle(0,1))*p.scale + p.bias; }
evalTexture2DArrayOffsetBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)529 static void		evalTexture2DArrayOffsetBiasClamp	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DArrayOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), de::max(p.lod+c.in[1].x(), p.lodClamp), p.offset.swizzle(0,1))*p.scale + p.bias; }
evalTexture3DOffsetBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)530 static void		evalTexture3DOffsetBiasClamp		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3DOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), de::max(p.lod+c.in[1].x(), p.lodClamp), p.offset)*p.scale + p.bias; }
evalTexture1DOffsetBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)531 static void		evalTexture1DOffsetBiasClamp		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DOffset(c, c.in[0].x(), de::max(p.lod+c.in[1].x(), p.lodClamp), p.offset.x())*p.scale + p.bias; }
evalTexture1DArrayOffsetBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)532 static void		evalTexture1DArrayOffsetBiasClamp	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DArrayOffset(c, c.in[0].x(), c.in[0].y(), de::max(p.lod+c.in[1].x(), p.lodClamp), p.offset.x())*p.scale + p.bias; }
533 
534 // Shadow variants
535 
evalTexture2DShadow(ShaderEvalContext & c,const TexLookupParams & p)536 static void		evalTexture2DShadow				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture2DShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), p.lod); }
evalTexture2DShadowBias(ShaderEvalContext & c,const TexLookupParams & p)537 static void		evalTexture2DShadowBias			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture2DShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), p.lod+c.in[1].x()); }
538 
evalTextureCubeShadow(ShaderEvalContext & c,const TexLookupParams & p)539 static void		evalTextureCubeShadow			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = textureCubeShadow(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod); }
evalTextureCubeShadowBias(ShaderEvalContext & c,const TexLookupParams & p)540 static void		evalTextureCubeShadowBias		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = textureCubeShadow(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod+c.in[1].x()); }
541 
evalTexture2DArrayShadow(ShaderEvalContext & c,const TexLookupParams & p)542 static void		evalTexture2DArrayShadow		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture2DArrayShadow(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod); }
evalTexture1DShadow(ShaderEvalContext & c,const TexLookupParams & p)543 static void		evalTexture1DShadow				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DShadow(c, c.in[0].z(), c.in[0].x(), p.lod); }
evalTexture1DShadowBias(ShaderEvalContext & c,const TexLookupParams & p)544 static void		evalTexture1DShadowBias			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DShadow(c, c.in[0].z(), c.in[0].x(), p.lod+c.in[1].x()); }
evalTexture1DArrayShadow(ShaderEvalContext & c,const TexLookupParams & p)545 static void		evalTexture1DArrayShadow		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DArrayShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), p.lod); }
evalTexture1DArrayShadowBias(ShaderEvalContext & c,const TexLookupParams & p)546 static void		evalTexture1DArrayShadowBias	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DArrayShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), p.lod+c.in[1].x()); }
evalTextureCubeArrayShadow(ShaderEvalContext & c,const TexLookupParams & p)547 static void		evalTextureCubeArrayShadow		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = textureCubeArrayShadow(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(), c.in[0].w(), p.lod); }
548 
evalTexture2DShadowLod(ShaderEvalContext & c,const TexLookupParams &)549 static void		evalTexture2DShadowLod				(ShaderEvalContext& c, const TexLookupParams&)		{ c.color.x() = texture2DShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), c.in[1].x()); }
evalTexture2DShadowLodOffset(ShaderEvalContext & c,const TexLookupParams & p)550 static void		evalTexture2DShadowLodOffset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture2DShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), c.in[1].x(), p.offset.swizzle(0,1)); }
evalTexture1DShadowLod(ShaderEvalContext & c,const TexLookupParams &)551 static void		evalTexture1DShadowLod				(ShaderEvalContext& c, const TexLookupParams&)		{ c.color.x() = texture1DShadow(c, c.in[0].z(), c.in[0].x(), c.in[1].x()); }
evalTexture1DShadowLodOffset(ShaderEvalContext & c,const TexLookupParams & p)552 static void		evalTexture1DShadowLodOffset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[1].x(), p.offset.x()); }
evalTexture1DArrayShadowLod(ShaderEvalContext & c,const TexLookupParams &)553 static void		evalTexture1DArrayShadowLod			(ShaderEvalContext& c, const TexLookupParams&)		{ c.color.x() = texture1DArrayShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), c.in[1].x()); }
evalTexture1DArrayShadowLodOffset(ShaderEvalContext & c,const TexLookupParams & p)554 static void		evalTexture1DArrayShadowLodOffset	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DArrayShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), c.in[1].x(), p.offset.x()); }
555 
evalTexture2DShadowProj(ShaderEvalContext & c,const TexLookupParams & p)556 static void		evalTexture2DShadowProj				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture2DShadow(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), p.lod); }
evalTexture2DShadowProjBias(ShaderEvalContext & c,const TexLookupParams & p)557 static void		evalTexture2DShadowProjBias			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture2DShadow(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), p.lod+c.in[1].x()); }
evalTexture1DShadowProj(ShaderEvalContext & c,const TexLookupParams & p)558 static void		evalTexture1DShadowProj				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DShadow(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), p.lod); }
evalTexture1DShadowProjBias(ShaderEvalContext & c,const TexLookupParams & p)559 static void		evalTexture1DShadowProjBias			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DShadow(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), p.lod+c.in[1].x()); }
560 
evalTexture2DShadowProjLod(ShaderEvalContext & c,const TexLookupParams &)561 static void		evalTexture2DShadowProjLod			(ShaderEvalContext& c, const TexLookupParams&)		{ c.color.x() = texture2DShadow(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), c.in[1].x()); }
evalTexture2DShadowProjLodOffset(ShaderEvalContext & c,const TexLookupParams & p)562 static void		evalTexture2DShadowProjLodOffset	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture2DShadowOffset(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), c.in[1].x(), p.offset.swizzle(0,1)); }
evalTexture1DShadowProjLod(ShaderEvalContext & c,const TexLookupParams &)563 static void		evalTexture1DShadowProjLod			(ShaderEvalContext& c, const TexLookupParams&)		{ c.color.x() = texture1DShadow(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), c.in[1].x()); }
evalTexture1DShadowProjLodOffset(ShaderEvalContext & c,const TexLookupParams & p)564 static void		evalTexture1DShadowProjLodOffset	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DShadowOffset(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), c.in[1].x(), p.offset.x()); }
565 
evalTexture2DShadowOffset(ShaderEvalContext & c,const TexLookupParams & p)566 static void		evalTexture2DShadowOffset			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture2DShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), p.lod, p.offset.swizzle(0,1)); }
evalTexture2DShadowOffsetBias(ShaderEvalContext & c,const TexLookupParams & p)567 static void		evalTexture2DShadowOffsetBias		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture2DShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), p.lod+c.in[1].x(), p.offset.swizzle(0,1)); }
evalTexture2DArrayShadowOffset(ShaderEvalContext & c,const TexLookupParams & p)568 static void		evalTexture2DArrayShadowOffset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture2DArrayShadowOffset(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod, p.offset.swizzle(0,1)); }
evalTexture1DShadowOffset(ShaderEvalContext & c,const TexLookupParams & p)569 static void		evalTexture1DShadowOffset			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DShadowOffset(c, c.in[0].z(), c.in[0].x(), p.lod, p.offset.x()); }
evalTexture1DShadowOffsetBias(ShaderEvalContext & c,const TexLookupParams & p)570 static void		evalTexture1DShadowOffsetBias		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DShadowOffset(c, c.in[0].z(), c.in[0].x(), p.lod+c.in[1].x(), p.offset.x()); }
evalTexture1DArrayShadowOffset(ShaderEvalContext & c,const TexLookupParams & p)571 static void		evalTexture1DArrayShadowOffset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DArrayShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), p.lod, p.offset.x()); }
evalTexture1DArrayShadowOffsetBias(ShaderEvalContext & c,const TexLookupParams & p)572 static void		evalTexture1DArrayShadowOffsetBias	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DArrayShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), p.lod+c.in[1].x(), p.offset.x()); }
573 
evalTexture2DShadowProjOffset(ShaderEvalContext & c,const TexLookupParams & p)574 static void		evalTexture2DShadowProjOffset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture2DShadowOffset(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), p.lod, p.offset.swizzle(0,1)); }
evalTexture2DShadowProjOffsetBias(ShaderEvalContext & c,const TexLookupParams & p)575 static void		evalTexture2DShadowProjOffsetBias	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture2DShadowOffset(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), p.lod+c.in[1].x(), p.offset.swizzle(0,1)); }
evalTexture1DShadowProjOffset(ShaderEvalContext & c,const TexLookupParams & p)576 static void		evalTexture1DShadowProjOffset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DShadowOffset(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), p.lod, p.offset.x()); }
evalTexture1DShadowProjOffsetBias(ShaderEvalContext & c,const TexLookupParams & p)577 static void		evalTexture1DShadowProjOffsetBias	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DShadowOffset(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), p.lod+c.in[1].x(), p.offset.x()); }
578 
evalTexture2DShadowBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)579 static void		evalTexture2DShadowBiasClamp		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture2DShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), de::max(p.lod+c.in[1].x(), p.lodClamp)); }
evalTextureCubeShadowBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)580 static void		evalTextureCubeShadowBiasClamp		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = textureCubeShadow(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(), de::max(p.lod+c.in[1].x(), p.lodClamp)); }
evalTexture1DShadowBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)581 static void		evalTexture1DShadowBiasClamp		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DShadow(c, c.in[0].z(), c.in[0].x(), de::max(p.lod+c.in[1].x(), p.lodClamp)); }
evalTexture1DArrayShadowBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)582 static void		evalTexture1DArrayShadowBiasClamp	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DArrayShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), de::max(p.lod+c.in[1].x(), p.lodClamp)); }
evalTexture2DShadowOffsetBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)583 static void		evalTexture2DShadowOffsetBiasClamp		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture2DShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), de::max(p.lod+c.in[1].x(), p.lodClamp), p.offset.swizzle(0,1)); }
evalTexture1DShadowOffsetBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)584 static void		evalTexture1DShadowOffsetBiasClamp		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DShadowOffset(c, c.in[0].z(), c.in[0].x(), de::max(p.lod+c.in[1].x(), p.lodClamp), p.offset.x()); }
evalTexture1DArrayShadowOffsetBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)585 static void		evalTexture1DArrayShadowOffsetBiasClamp	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DArrayShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), de::max(p.lod+c.in[1].x(), p.lodClamp), p.offset.x()); }
586 
587 // Gradient variarts
588 
evalTexture2DGrad(ShaderEvalContext & c,const TexLookupParams & p)589 static void		evalTexture2DGrad			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2D(c, c.in[0].x(), c.in[0].y(), computeLodFromGrad2D(c))*p.scale + p.bias; }
evalTextureCubeGrad(ShaderEvalContext & c,const TexLookupParams & p)590 static void		evalTextureCubeGrad			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = textureCube(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), computeLodFromGradCube(c))*p.scale + p.bias; }
evalTexture2DArrayGrad(ShaderEvalContext & c,const TexLookupParams & p)591 static void		evalTexture2DArrayGrad		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DArray(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), computeLodFromGrad2DArray(c))*p.scale + p.bias; }
evalTexture3DGrad(ShaderEvalContext & c,const TexLookupParams & p)592 static void		evalTexture3DGrad			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3D(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), computeLodFromGrad3D(c))*p.scale + p.bias; }
evalTexture1DGrad(ShaderEvalContext & c,const TexLookupParams & p)593 static void		evalTexture1DGrad			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1D(c, c.in[0].x(), computeLodFromGrad1D(c))*p.scale + p.bias; }
evalTexture1DArrayGrad(ShaderEvalContext & c,const TexLookupParams & p)594 static void		evalTexture1DArrayGrad		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DArray(c, c.in[0].x(), c.in[0].y(), computeLodFromGrad1DArray(c))*p.scale + p.bias; }
evalTextureCubeArrayGrad(ShaderEvalContext & c,const TexLookupParams & p)595 static void		evalTextureCubeArrayGrad	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = textureCubeArray(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), c.in[0].w(), computeLodFromGradCubeArray(c))*p.scale + p.bias; }
596 
evalTexture2DShadowGrad(ShaderEvalContext & c,const TexLookupParams &)597 static void		evalTexture2DShadowGrad			(ShaderEvalContext& c, const TexLookupParams&)		{ c.color.x() = texture2DShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), computeLodFromGrad2D(c)); }
evalTextureCubeShadowGrad(ShaderEvalContext & c,const TexLookupParams &)598 static void		evalTextureCubeShadowGrad		(ShaderEvalContext& c, const TexLookupParams&)		{ c.color.x() = textureCubeShadow(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(), computeLodFromGradCube(c)); }
evalTexture2DArrayShadowGrad(ShaderEvalContext & c,const TexLookupParams &)599 static void		evalTexture2DArrayShadowGrad	(ShaderEvalContext& c, const TexLookupParams&)		{ c.color.x() = texture2DArrayShadow(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(), computeLodFromGrad2DArray(c)); }
evalTexture1DShadowGrad(ShaderEvalContext & c,const TexLookupParams &)600 static void		evalTexture1DShadowGrad			(ShaderEvalContext& c, const TexLookupParams&)		{ c.color.x() = texture1DShadow(c, c.in[0].z(), c.in[0].x(), computeLodFromGrad1D(c)); }
evalTexture1DArrayShadowGrad(ShaderEvalContext & c,const TexLookupParams &)601 static void		evalTexture1DArrayShadowGrad	(ShaderEvalContext& c, const TexLookupParams&)		{ c.color.x() = texture1DArrayShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), computeLodFromGrad1DArray(c)); }
602 
evalTexture2DGradOffset(ShaderEvalContext & c,const TexLookupParams & p)603 static void		evalTexture2DGradOffset			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DOffset(c, c.in[0].x(), c.in[0].y(), computeLodFromGrad2D(c), p.offset.swizzle(0,1))*p.scale + p.bias; }
evalTexture2DArrayGradOffset(ShaderEvalContext & c,const TexLookupParams & p)604 static void		evalTexture2DArrayGradOffset	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DArrayOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), computeLodFromGrad2DArray(c), p.offset.swizzle(0,1))*p.scale + p.bias; }
evalTexture3DGradOffset(ShaderEvalContext & c,const TexLookupParams & p)605 static void		evalTexture3DGradOffset			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3DOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), computeLodFromGrad3D(c), p.offset)*p.scale + p.bias; }
evalTexture1DGradOffset(ShaderEvalContext & c,const TexLookupParams & p)606 static void		evalTexture1DGradOffset			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DOffset(c, c.in[0].x(), computeLodFromGrad1D(c), p.offset.x())*p.scale + p.bias; }
evalTexture1DArrayGradOffset(ShaderEvalContext & c,const TexLookupParams & p)607 static void		evalTexture1DArrayGradOffset	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DArrayOffset(c, c.in[0].x(), c.in[0].y(), computeLodFromGrad1DArray(c), p.offset.x())*p.scale + p.bias; }
608 
evalTexture2DShadowGradOffset(ShaderEvalContext & c,const TexLookupParams & p)609 static void		evalTexture2DShadowGradOffset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture2DShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), computeLodFromGrad2D(c), p.offset.swizzle(0,1)); }
evalTexture2DArrayShadowGradOffset(ShaderEvalContext & c,const TexLookupParams & p)610 static void		evalTexture2DArrayShadowGradOffset	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture2DArrayShadowOffset(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(), computeLodFromGrad2DArray(c), p.offset.swizzle(0,1)); }
evalTexture1DShadowGradOffset(ShaderEvalContext & c,const TexLookupParams & p)611 static void		evalTexture1DShadowGradOffset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DShadowOffset(c, c.in[0].z(), c.in[0].x(), computeLodFromGrad1D(c), p.offset.x()); }
evalTexture1DArrayShadowGradOffset(ShaderEvalContext & c,const TexLookupParams & p)612 static void		evalTexture1DArrayShadowGradOffset	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DArrayShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), computeLodFromGrad1DArray(c), p.offset.x()); }
613 
evalTexture2DShadowProjGrad(ShaderEvalContext & c,const TexLookupParams &)614 static void		evalTexture2DShadowProjGrad			(ShaderEvalContext& c, const TexLookupParams&)		{ c.color.x() = texture2DShadow(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), computeLodFromGrad2D(c)); }
evalTexture2DShadowProjGradOffset(ShaderEvalContext & c,const TexLookupParams & p)615 static void		evalTexture2DShadowProjGradOffset	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture2DShadowOffset(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), computeLodFromGrad2D(c), p.offset.swizzle(0,1)); }
evalTexture1DShadowProjGrad(ShaderEvalContext & c,const TexLookupParams &)616 static void		evalTexture1DShadowProjGrad			(ShaderEvalContext& c, const TexLookupParams&)		{ c.color.x() = texture1DShadow(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), computeLodFromGrad1D(c)); }
evalTexture1DShadowProjGradOffset(ShaderEvalContext & c,const TexLookupParams & p)617 static void		evalTexture1DShadowProjGradOffset	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DShadowOffset(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), computeLodFromGrad1D(c), p.offset.x()); }
618 
evalTexture2DProjGrad3(ShaderEvalContext & c,const TexLookupParams & p)619 static void		evalTexture2DProjGrad3			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2D(c, c.in[0].x()/c.in[0].z(), c.in[0].y()/c.in[0].z(), computeLodFromGrad2D(c))*p.scale + p.bias; }
evalTexture2DProjGrad(ShaderEvalContext & c,const TexLookupParams & p)620 static void		evalTexture2DProjGrad			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2D(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), computeLodFromGrad2D(c))*p.scale + p.bias; }
evalTexture3DProjGrad(ShaderEvalContext & c,const TexLookupParams & p)621 static void		evalTexture3DProjGrad			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3D(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), c.in[0].z()/c.in[0].w(), computeLodFromGrad3D(c))*p.scale + p.bias; }
evalTexture1DProjGrad2(ShaderEvalContext & c,const TexLookupParams & p)622 static void		evalTexture1DProjGrad2			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1D(c, c.in[0].x()/c.in[0].y(), computeLodFromGrad1D(c))*p.scale + p.bias; }
evalTexture1DProjGrad(ShaderEvalContext & c,const TexLookupParams & p)623 static void		evalTexture1DProjGrad			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1D(c, c.in[0].x()/c.in[0].w(), computeLodFromGrad1D(c))*p.scale + p.bias; }
624 
evalTexture2DProjGrad3Offset(ShaderEvalContext & c,const TexLookupParams & p)625 static void		evalTexture2DProjGrad3Offset	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DOffset(c, c.in[0].x()/c.in[0].z(), c.in[0].y()/c.in[0].z(), computeLodFromGrad2D(c), p.offset.swizzle(0,1))*p.scale + p.bias; }
evalTexture2DProjGradOffset(ShaderEvalContext & c,const TexLookupParams & p)626 static void		evalTexture2DProjGradOffset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DOffset(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), computeLodFromGrad2D(c), p.offset.swizzle(0,1))*p.scale + p.bias; }
evalTexture3DProjGradOffset(ShaderEvalContext & c,const TexLookupParams & p)627 static void		evalTexture3DProjGradOffset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3DOffset(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), c.in[0].z()/c.in[0].w(), computeLodFromGrad3D(c), p.offset)*p.scale + p.bias; }
evalTexture1DProjGrad2Offset(ShaderEvalContext & c,const TexLookupParams & p)628 static void		evalTexture1DProjGrad2Offset	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DOffset(c, c.in[0].x()/c.in[0].y(), computeLodFromGrad1D(c), p.offset.x())*p.scale + p.bias; }
evalTexture1DProjGradOffset(ShaderEvalContext & c,const TexLookupParams & p)629 static void		evalTexture1DProjGradOffset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DOffset(c, c.in[0].x()/c.in[0].w(), computeLodFromGrad1D(c), p.offset.x())*p.scale + p.bias; }
630 
evalTexture2DGradClamp(ShaderEvalContext & c,const TexLookupParams & p)631 static void		evalTexture2DGradClamp			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2D(c, c.in[0].x(), c.in[0].y(), de::max(computeLodFromGrad2D(c), p.lodClamp))*p.scale + p.bias; }
evalTextureCubeGradClamp(ShaderEvalContext & c,const TexLookupParams & p)632 static void		evalTextureCubeGradClamp		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = textureCube(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), de::max(computeLodFromGradCube(c), p.lodClamp))*p.scale + p.bias; }
evalTexture2DArrayGradClamp(ShaderEvalContext & c,const TexLookupParams & p)633 static void		evalTexture2DArrayGradClamp		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DArray(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), de::max(computeLodFromGrad2DArray(c), p.lodClamp))*p.scale + p.bias; }
evalTexture3DGradClamp(ShaderEvalContext & c,const TexLookupParams & p)634 static void		evalTexture3DGradClamp			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3D(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), de::max(computeLodFromGrad3D(c), p.lodClamp))*p.scale + p.bias; }
evalTexture1DGradClamp(ShaderEvalContext & c,const TexLookupParams & p)635 static void		evalTexture1DGradClamp			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1D(c, c.in[0].x(), de::max(computeLodFromGrad1D(c), p.lodClamp))*p.scale + p.bias; }
evalTexture1DArrayGradClamp(ShaderEvalContext & c,const TexLookupParams & p)636 static void		evalTexture1DArrayGradClamp		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DArray(c, c.in[0].x(), c.in[0].y(), de::max(computeLodFromGrad1DArray(c), p.lodClamp))*p.scale + p.bias; }
evalTextureCubeArrayGradClamp(ShaderEvalContext & c,const TexLookupParams & p)637 static void		evalTextureCubeArrayGradClamp	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = textureCubeArray(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), c.in[0].w(), de::max(computeLodFromGradCubeArray(c), p.lodClamp))*p.scale + p.bias; }
638 
evalTexture2DShadowGradClamp(ShaderEvalContext & c,const TexLookupParams & p)639 static void		evalTexture2DShadowGradClamp		(ShaderEvalContext& c, const TexLookupParams& p)		{ c.color.x() = texture2DShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), de::max(computeLodFromGrad2D(c), p.lodClamp)); }
evalTextureCubeShadowGradClamp(ShaderEvalContext & c,const TexLookupParams & p)640 static void		evalTextureCubeShadowGradClamp		(ShaderEvalContext& c, const TexLookupParams& p)		{ c.color.x() = textureCubeShadow(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(), de::max(computeLodFromGradCube(c), p.lodClamp)); }
evalTexture2DArrayShadowGradClamp(ShaderEvalContext & c,const TexLookupParams & p)641 static void		evalTexture2DArrayShadowGradClamp	(ShaderEvalContext& c, const TexLookupParams& p)		{ c.color.x() = texture2DArrayShadow(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(), de::max(computeLodFromGrad2DArray(c), p.lodClamp)); }
evalTexture1DShadowGradClamp(ShaderEvalContext & c,const TexLookupParams & p)642 static void		evalTexture1DShadowGradClamp		(ShaderEvalContext& c, const TexLookupParams& p)		{ c.color.x() = texture1DShadow(c, c.in[0].z(), c.in[0].x(), de::max(computeLodFromGrad1D(c), p.lodClamp)); }
evalTexture1DArrayShadowGradClamp(ShaderEvalContext & c,const TexLookupParams & p)643 static void		evalTexture1DArrayShadowGradClamp	(ShaderEvalContext& c, const TexLookupParams& p)		{ c.color.x() = texture1DArrayShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), de::max(computeLodFromGrad1DArray(c), p.lodClamp)); }
644 
evalTexture2DGradOffsetClamp(ShaderEvalContext & c,const TexLookupParams & p)645 static void		evalTexture2DGradOffsetClamp		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DOffset(c, c.in[0].x(), c.in[0].y(), de::max(computeLodFromGrad2D(c), p.lodClamp), p.offset.swizzle(0,1))*p.scale + p.bias; }
evalTexture2DArrayGradOffsetClamp(ShaderEvalContext & c,const TexLookupParams & p)646 static void		evalTexture2DArrayGradOffsetClamp	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DArrayOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), de::max(computeLodFromGrad2DArray(c), p.lodClamp), p.offset.swizzle(0,1))*p.scale + p.bias; }
evalTexture3DGradOffsetClamp(ShaderEvalContext & c,const TexLookupParams & p)647 static void		evalTexture3DGradOffsetClamp		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3DOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), de::max(computeLodFromGrad3D(c), p.lodClamp), p.offset)*p.scale + p.bias; }
evalTexture1DGradOffsetClamp(ShaderEvalContext & c,const TexLookupParams & p)648 static void		evalTexture1DGradOffsetClamp		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DOffset(c, c.in[0].x(), de::max(computeLodFromGrad1D(c), p.lodClamp), p.offset.x())*p.scale + p.bias; }
evalTexture1DArrayGradOffsetClamp(ShaderEvalContext & c,const TexLookupParams & p)649 static void		evalTexture1DArrayGradOffsetClamp	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DArrayOffset(c, c.in[0].x(), c.in[0].y(), de::max(computeLodFromGrad1DArray(c), p.lodClamp), p.offset.x())*p.scale + p.bias; }
650 
evalTexture2DShadowGradOffsetClamp(ShaderEvalContext & c,const TexLookupParams & p)651 static void		evalTexture2DShadowGradOffsetClamp		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture2DShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), de::max(computeLodFromGrad2D(c), p.lodClamp), p.offset.swizzle(0,1)); }
evalTexture2DArrayShadowGradOffsetClamp(ShaderEvalContext & c,const TexLookupParams & p)652 static void		evalTexture2DArrayShadowGradOffsetClamp	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture2DArrayShadowOffset(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(), de::max(computeLodFromGrad2DArray(c), p.lodClamp), p.offset.swizzle(0,1)); }
evalTexture1DShadowGradOffsetClamp(ShaderEvalContext & c,const TexLookupParams & p)653 static void		evalTexture1DShadowGradOffsetClamp		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DShadowOffset(c, c.in[0].z(), c.in[0].x(), de::max(computeLodFromGrad1D(c), p.lodClamp), p.offset.x()); }
evalTexture1DArrayShadowGradOffsetClamp(ShaderEvalContext & c,const TexLookupParams & p)654 static void		evalTexture1DArrayShadowGradOffsetClamp	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DArrayShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), de::max(computeLodFromGrad1DArray(c), p.lodClamp), p.offset.x()); }
655 
656 // Texel fetch variants
657 
evalTexelFetch2D(ShaderEvalContext & c,const TexLookupParams & p)658 static void evalTexelFetch2D (ShaderEvalContext& c, const TexLookupParams& p)
659 {
660 	int	x	= deChopFloatToInt32(c.in[0].x())+p.offset.x();
661 	int	y	= deChopFloatToInt32(c.in[0].y())+p.offset.y();
662 	int	lod = deChopFloatToInt32(c.in[1].x());
663 	c.color = c.textures[0].tex2D->getLevel(lod).getPixel(x, y)*p.scale + p.bias;
664 }
665 
evalTexelFetch2DArray(ShaderEvalContext & c,const TexLookupParams & p)666 static void evalTexelFetch2DArray (ShaderEvalContext& c, const TexLookupParams& p)
667 {
668 	int	x	= deChopFloatToInt32(c.in[0].x())+p.offset.x();
669 	int	y	= deChopFloatToInt32(c.in[0].y())+p.offset.y();
670 	int	l	= deChopFloatToInt32(c.in[0].z());
671 	int	lod = deChopFloatToInt32(c.in[1].x());
672 	c.color = c.textures[0].tex2DArray->getLevel(lod).getPixel(x, y, l)*p.scale + p.bias;
673 }
674 
evalTexelFetch3D(ShaderEvalContext & c,const TexLookupParams & p)675 static void evalTexelFetch3D (ShaderEvalContext& c, const TexLookupParams& p)
676 {
677 	int	x	= deChopFloatToInt32(c.in[0].x())+p.offset.x();
678 	int	y	= deChopFloatToInt32(c.in[0].y())+p.offset.y();
679 	int	z	= deChopFloatToInt32(c.in[0].z())+p.offset.z();
680 	int	lod = deChopFloatToInt32(c.in[1].x());
681 	c.color = c.textures[0].tex3D->getLevel(lod).getPixel(x, y, z)*p.scale + p.bias;
682 }
683 
evalTexelFetch1D(ShaderEvalContext & c,const TexLookupParams & p)684 static void evalTexelFetch1D (ShaderEvalContext& c, const TexLookupParams& p)
685 {
686 	int	x	= deChopFloatToInt32(c.in[0].x())+p.offset.x();
687 	int	lod = deChopFloatToInt32(c.in[1].x());
688 	c.color = c.textures[0].tex1D->getLevel(lod).getPixel(x, 0)*p.scale + p.bias;
689 }
690 
evalTexelFetch1DArray(ShaderEvalContext & c,const TexLookupParams & p)691 static void evalTexelFetch1DArray (ShaderEvalContext& c, const TexLookupParams& p)
692 {
693 	int	x	= deChopFloatToInt32(c.in[0].x())+p.offset.x();
694 	int	l	= deChopFloatToInt32(c.in[0].y());
695 	int	lod = deChopFloatToInt32(c.in[1].x());
696 	c.color = c.textures[0].tex1DArray->getLevel(lod).getPixel(x, l)*p.scale + p.bias;
697 }
698 
699 class TexLookupEvaluator : public ShaderEvaluator
700 {
701 public:
TexLookupEvaluator(TexEvalFunc evalFunc,const TexLookupParams & lookupParams)702 							TexLookupEvaluator		(TexEvalFunc evalFunc, const TexLookupParams& lookupParams) : m_evalFunc(evalFunc), m_lookupParams(lookupParams) {}
~TexLookupEvaluator(void)703 	virtual					~TexLookupEvaluator		(void) {}
704 
evaluate(ShaderEvalContext & ctx) const705 	virtual void			evaluate				(ShaderEvalContext& ctx) const { m_evalFunc(ctx, m_lookupParams); }
706 
707 private:
708 	TexEvalFunc				m_evalFunc;
709 	const TexLookupParams&	m_lookupParams;
710 };
711 
checkDeviceFeatures(Context & context,TextureType textureType)712 static void checkDeviceFeatures (Context& context, TextureType textureType)
713 {
714 	if (textureType == TEXTURETYPE_CUBE_ARRAY)
715 	{
716 		const vk::VkPhysicalDeviceFeatures&	deviceFeatures	= context.getDeviceFeatures();
717 
718 		if (!deviceFeatures.imageCubeArray)
719 			TCU_THROW(NotSupportedError, "Cube array is not supported");
720 	}
721 }
722 
checkMutableComparisonSamplersSupport(Context & context,const TextureSpec & textureSpec)723 static void checkMutableComparisonSamplersSupport(Context& context, const TextureSpec& textureSpec)
724 {
725 	// when compare mode is not none then ShaderRenderCaseInstance::createSamplerUniform
726 	// uses mapSampler utill from vkImageUtil that sets compareEnable to true
727 	// for portability this needs to be under feature flag
728 #ifndef CTS_USES_VULKANSC
729 	if (context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
730 	   !context.getPortabilitySubsetFeatures().mutableComparisonSamplers &&
731 	   (textureSpec.sampler.compare != tcu::Sampler::COMPAREMODE_NONE))
732 	{
733 		TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: mutableComparisonSamplers are not supported by this implementation");
734 	}
735 #else
736 	DE_UNREF(context);
737 	DE_UNREF(textureSpec);
738 #endif // CTS_USES_VULKANSC
739 }
740 
741 class ShaderTextureFunctionInstance : public ShaderRenderCaseInstance
742 {
743 public:
744 								ShaderTextureFunctionInstance		(Context&					context,
745 																	 const bool					isVertexCase,
746 																	 const ShaderEvaluator&		evaluator,
747 																	 const UniformSetup&		uniformSetup,
748 																	 const TextureLookupSpec&	lookupSpec,
749 																	 const TextureSpec&			textureSpec,
750 																	 const TexLookupParams&		lookupParams,
751 																	 const ImageBackingMode		imageBackingMode = IMAGE_BACKING_MODE_REGULAR);
752 	virtual						~ShaderTextureFunctionInstance		(void);
753 
754 protected:
755 	virtual void				setupUniforms						(const tcu::Vec4&);
756 	void						initTexture							(void);
757 private:
758 	const TextureLookupSpec&	m_lookupSpec;
759 	const TextureSpec&			m_textureSpec;
760 	const TexLookupParams&		m_lookupParams;
761 };
762 
ShaderTextureFunctionInstance(Context & context,const bool isVertexCase,const ShaderEvaluator & evaluator,const UniformSetup & uniformSetup,const TextureLookupSpec & lookupSpec,const TextureSpec & textureSpec,const TexLookupParams & lookupParams,const ImageBackingMode imageBackingMode)763 ShaderTextureFunctionInstance::ShaderTextureFunctionInstance (Context&						context,
764 															  const bool					isVertexCase,
765 															  const ShaderEvaluator&		evaluator,
766 															  const UniformSetup&			uniformSetup,
767 															  const TextureLookupSpec&		lookupSpec,
768 															  const TextureSpec&			textureSpec,
769 															  const TexLookupParams&		lookupParams,
770 															  const ImageBackingMode		imageBackingMode)
771 	: ShaderRenderCaseInstance	(context, isVertexCase, evaluator, uniformSetup, DE_NULL, imageBackingMode,
772 								(isVertexCase ? 92 : GRID_SIZE_DEFAULT_FRAGMENT))
773 	, m_lookupSpec				(lookupSpec)
774 	, m_textureSpec				(textureSpec)
775 	, m_lookupParams			(lookupParams)
776 {
777 	checkDeviceFeatures(m_context, m_textureSpec.type);
778 
779 	if (lookupSpec.useClamp)
780 	{
781 		const vk::VkPhysicalDeviceFeatures&	deviceFeatures	= context.getDeviceFeatures();
782 
783 		if (!deviceFeatures.shaderResourceMinLod)
784 			TCU_THROW(NotSupportedError, "ShaderResourceMinLod feature not supported.");
785 	}
786 
787 	{
788 		// Base coord scale & bias
789 		Vec4 s = m_lookupSpec.maxCoord-m_lookupSpec.minCoord;
790 		Vec4 b = m_lookupSpec.minCoord;
791 
792 		float baseCoordTrans[] =
793 		{
794 			s.x(),		0.0f,		0.f,	b.x(),
795 			0.f,		s.y(),		0.f,	b.y(),
796 			s.z()/2.f,	-s.z()/2.f,	0.f,	s.z()/2.f + b.z(),
797 			-s.w()/2.f,	s.w()/2.f,	0.f,	s.w()/2.f + b.w()
798 		};
799 
800 		m_userAttribTransforms.push_back(tcu::Mat4(baseCoordTrans));
801 
802 		useAttribute(4u, A_IN0);
803 	}
804 
805 	bool hasLodBias	= functionHasLod(m_lookupSpec.function) || m_lookupSpec.useBias;
806 	bool isGrad		= functionHasGrad(m_lookupSpec.function);
807 	DE_ASSERT(!isGrad || !hasLodBias);
808 
809 	if (hasLodBias)
810 	{
811 		float s = m_lookupSpec.maxLodBias-m_lookupSpec.minLodBias;
812 		float b = m_lookupSpec.minLodBias;
813 		float lodCoordTrans[] =
814 		{
815 			s/2.0f,		s/2.0f,		0.f,	b,
816 			0.0f,		0.0f,		0.0f,	0.0f,
817 			0.0f,		0.0f,		0.0f,	0.0f,
818 			0.0f,		0.0f,		0.0f,	0.0f
819 		};
820 
821 		m_userAttribTransforms.push_back(tcu::Mat4(lodCoordTrans));
822 
823 		useAttribute(5u, A_IN1);
824 	}
825 	else if (isGrad)
826 	{
827 		Vec3 sx = m_lookupSpec.maxDX-m_lookupSpec.minDX;
828 		Vec3 sy = m_lookupSpec.maxDY-m_lookupSpec.minDY;
829 		float gradDxTrans[] =
830 		{
831 			sx.x()/2.0f,	sx.x()/2.0f,	0.f,	m_lookupSpec.minDX.x(),
832 			sx.y()/2.0f,	sx.y()/2.0f,	0.0f,	m_lookupSpec.minDX.y(),
833 			sx.z()/2.0f,	sx.z()/2.0f,	0.0f,	m_lookupSpec.minDX.z(),
834 			0.0f,			0.0f,			0.0f,	0.0f
835 		};
836 		float gradDyTrans[] =
837 		{
838 			-sy.x()/2.0f,	-sy.x()/2.0f,	0.f,	m_lookupSpec.maxDY.x(),
839 			-sy.y()/2.0f,	-sy.y()/2.0f,	0.0f,	m_lookupSpec.maxDY.y(),
840 			-sy.z()/2.0f,	-sy.z()/2.0f,	0.0f,	m_lookupSpec.maxDY.z(),
841 			0.0f,			0.0f,			0.0f,	0.0f
842 		};
843 
844 		m_userAttribTransforms.push_back(tcu::Mat4(gradDxTrans));
845 		m_userAttribTransforms.push_back(tcu::Mat4(gradDyTrans));
846 
847 		useAttribute(5u, A_IN1);
848 		useAttribute(6u, A_IN2);
849 	}
850 
851 	initTexture();
852 }
853 
~ShaderTextureFunctionInstance(void)854 ShaderTextureFunctionInstance::~ShaderTextureFunctionInstance (void)
855 {
856 }
857 
setupUniforms(const tcu::Vec4 &)858 void ShaderTextureFunctionInstance::setupUniforms (const tcu::Vec4&)
859 {
860 	useSampler(0u, 0u);
861 	addUniform(1u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, sizeof(tcu::Vec4), m_lookupParams.scale.getPtr());
862 	addUniform(2u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, sizeof(tcu::Vec4), m_lookupParams.bias.getPtr());
863 }
864 
initTexture(void)865 void ShaderTextureFunctionInstance::initTexture (void)
866 {
867 	static const IVec4		texCubeSwz[] =
868 	{
869 		IVec4(0,0,1,1),
870 		IVec4(1,1,0,0),
871 		IVec4(0,1,0,1),
872 		IVec4(1,0,1,0),
873 		IVec4(0,1,1,0),
874 		IVec4(1,0,0,1)
875 	};
876 	DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(texCubeSwz) == tcu::CUBEFACE_LAST);
877 
878 	tcu::TextureFormat		texFmt			= glu::mapGLInternalFormat(m_textureSpec.format);
879 	tcu::TextureFormatInfo	fmtInfo			= tcu::getTextureFormatInfo(texFmt);
880 	tcu::UVec2				viewportSize	= getViewportSize();
881 	bool					isProj			= functionHasProj(m_lookupSpec.function);
882 	bool					isAutoLod		= functionHasAutoLod(m_isVertexCase ? glu::SHADERTYPE_VERTEX : glu::SHADERTYPE_FRAGMENT,
883 																 m_lookupSpec.function); // LOD can vary significantly
884 	float					proj			= isProj ? 1.0f/m_lookupSpec.minCoord[m_lookupSpec.function == FUNCTION_TEXTUREPROJ2 ? 1 : m_lookupSpec.function == FUNCTION_TEXTUREPROJ3 ? 2 : 3] : 1.0f;
885 	TexLookupParams			lookupParams;
886 
887 	switch (m_textureSpec.type)
888 	{
889 		case TEXTURETYPE_2D:
890 		{
891 			float								levelStep		= isAutoLod ? 0.0f : 1.0f / (float)de::max(1, m_textureSpec.numLevels-1);
892 			Vec4								cScale			= fmtInfo.valueMax-fmtInfo.valueMin;
893 			Vec4								cBias			= fmtInfo.valueMin;
894 			int									baseCellSize	= de::min(m_textureSpec.width/4, m_textureSpec.height/4);
895 			de::MovePtr<tcu::Texture2D>			texture2D;
896 
897 			texture2D = de::MovePtr<tcu::Texture2D>(new tcu::Texture2D(texFmt, m_textureSpec.width, m_textureSpec.height));
898 
899 			for (int level = 0; level < m_textureSpec.numLevels; level++)
900 			{
901 				float	fA		= float(level)*levelStep;
902 				float	fB		= 1.0f-fA;
903 				Vec4	colorA	= cBias + cScale*Vec4(fA, fB, fA, fB);
904 				Vec4	colorB	= cBias + cScale*Vec4(fB, fA, fB, fA);
905 
906 				texture2D->allocLevel(level);
907 				tcu::fillWithGrid(texture2D->getLevel(level), de::max(1, baseCellSize>>level), colorA, colorB);
908 			}
909 
910 			// Compute LOD.
911 			float	dudx	= (m_lookupSpec.maxCoord[0]-m_lookupSpec.minCoord[0])*proj*(float)m_textureSpec.width	/ (float)viewportSize[0];
912 			float	dvdy	= (m_lookupSpec.maxCoord[1]-m_lookupSpec.minCoord[1])*proj*(float)m_textureSpec.height	/ (float)viewportSize[1];
913 			lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f, 0.0f, dvdy);
914 
915 			// Append to texture list.
916 			m_textures.push_back(TextureBindingSp(new TextureBinding(texture2D.release(), m_textureSpec.sampler)));
917 			break;
918 		}
919 
920 		case TEXTURETYPE_CUBE_MAP:
921 		{
922 			float								levelStep		= isAutoLod ? 0.0f : 1.0f / (float)de::max(1, m_textureSpec.numLevels-1);
923 			Vec4								cScale			= fmtInfo.valueMax-fmtInfo.valueMin;
924 			Vec4								cBias			= fmtInfo.valueMin;
925 			Vec4								cCorner			= cBias + cScale*0.5f;
926 			int									baseCellSize	= de::min(m_textureSpec.width/4, m_textureSpec.height/4);
927 			de::MovePtr<tcu::TextureCube>		textureCube;
928 
929 			DE_ASSERT(m_textureSpec.width == m_textureSpec.height);
930 			textureCube = de::MovePtr<tcu::TextureCube>(new tcu::TextureCube(texFmt, m_textureSpec.width));
931 
932 			for (int level = 0; level < m_textureSpec.numLevels; level++)
933 			{
934 				float	fA		= float(level)*levelStep;
935 				float	fB		= 1.0f-fA;
936 				Vec2	f		(fA, fB);
937 
938 				for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
939 				{
940 					const IVec4&	swzA	= texCubeSwz[face];
941 					IVec4			swzB	= 1-swzA;
942 					Vec4			colorA	= cBias + cScale*f.swizzle(swzA[0], swzA[1], swzA[2], swzA[3]);
943 					Vec4			colorB	= cBias + cScale*f.swizzle(swzB[0], swzB[1], swzB[2], swzB[3]);
944 
945 					textureCube->allocLevel((tcu::CubeFace)face, level);
946 
947 					{
948 						const tcu::PixelBufferAccess	access		= textureCube->getLevelFace(level, (tcu::CubeFace)face);
949 						const int						lastPix		= access.getWidth()-1;
950 
951 						tcu::fillWithGrid(access, de::max(1, baseCellSize>>level), colorA, colorB);
952 
953 						// Ensure all corners have identical colors in order to avoid dealing with ambiguous corner texel filtering
954 						access.setPixel(cCorner, 0, 0);
955 						access.setPixel(cCorner, 0, lastPix);
956 						access.setPixel(cCorner, lastPix, 0);
957 						access.setPixel(cCorner, lastPix, lastPix);
958 					}
959 				}
960 			}
961 
962 			// Compute LOD \note Assumes that only single side is accessed and R is constant major axis.
963 			DE_ASSERT(de::abs(m_lookupSpec.minCoord[2] - m_lookupSpec.maxCoord[2]) < 0.005);
964 			DE_ASSERT(de::abs(m_lookupSpec.minCoord[0]) < de::abs(m_lookupSpec.minCoord[2]) && de::abs(m_lookupSpec.maxCoord[0]) < de::abs(m_lookupSpec.minCoord[2]));
965 			DE_ASSERT(de::abs(m_lookupSpec.minCoord[1]) < de::abs(m_lookupSpec.minCoord[2]) && de::abs(m_lookupSpec.maxCoord[1]) < de::abs(m_lookupSpec.minCoord[2]));
966 
967 			tcu::CubeFaceFloatCoords	c00		= tcu::getCubeFaceCoords(Vec3(m_lookupSpec.minCoord[0]*proj, m_lookupSpec.minCoord[1]*proj, m_lookupSpec.minCoord[2]*proj));
968 			tcu::CubeFaceFloatCoords	c10		= tcu::getCubeFaceCoords(Vec3(m_lookupSpec.maxCoord[0]*proj, m_lookupSpec.minCoord[1]*proj, m_lookupSpec.minCoord[2]*proj));
969 			tcu::CubeFaceFloatCoords	c01		= tcu::getCubeFaceCoords(Vec3(m_lookupSpec.minCoord[0]*proj, m_lookupSpec.maxCoord[1]*proj, m_lookupSpec.minCoord[2]*proj));
970 			float						dudx	= (c10.s - c00.s)*(float)m_textureSpec.width	/ (float)viewportSize[0];
971 			float						dvdy	= (c01.t - c00.t)*(float)m_textureSpec.height	/ (float)viewportSize[1];
972 			lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f, 0.0f, dvdy);
973 
974 			// Append to texture list.
975 			m_textures.push_back(TextureBindingSp(new TextureBinding(textureCube.release(), m_textureSpec.sampler)));
976 			break;
977 		}
978 
979 		case TEXTURETYPE_2D_ARRAY:
980 		{
981 			float								layerStep		= 1.0f / (float)m_textureSpec.depth;
982 			float								levelStep		= isAutoLod ? 0.0f : 1.0f / (float)(de::max(1, m_textureSpec.numLevels-1)*m_textureSpec.depth);
983 			Vec4								cScale			= fmtInfo.valueMax-fmtInfo.valueMin;
984 			Vec4								cBias			= fmtInfo.valueMin;
985 			int									baseCellSize	= de::min(m_textureSpec.width/4, m_textureSpec.height/4);
986 			de::MovePtr<tcu::Texture2DArray>	texture2DArray;
987 
988 			texture2DArray = de::MovePtr<tcu::Texture2DArray>(new tcu::Texture2DArray(texFmt, m_textureSpec.width, m_textureSpec.height, m_textureSpec.depth));
989 
990 			for (int level = 0; level < m_textureSpec.numLevels; level++)
991 			{
992 				texture2DArray->allocLevel(level);
993 				tcu::PixelBufferAccess levelAccess = texture2DArray->getLevel(level);
994 
995 				for (int layer = 0; layer < levelAccess.getDepth(); layer++)
996 				{
997 					float	fA		= (float)layer*layerStep + (float)level*levelStep;
998 					float	fB		= 1.0f-fA;
999 					Vec4	colorA	= cBias + cScale*Vec4(fA, fB, fA, fB);
1000 					Vec4	colorB	= cBias + cScale*Vec4(fB, fA, fB, fA);
1001 
1002 					tcu::fillWithGrid(tcu::getSubregion(levelAccess, 0, 0, layer, levelAccess.getWidth(), levelAccess.getHeight(), 1), de::max(1, baseCellSize>>level), colorA, colorB);
1003 				}
1004 			}
1005 
1006 			// Compute LOD.
1007 			float	dudx	= (m_lookupSpec.maxCoord[0]-m_lookupSpec.minCoord[0])*proj*(float)m_textureSpec.width	/ (float)viewportSize[0];
1008 			float	dvdy	= (m_lookupSpec.maxCoord[1]-m_lookupSpec.minCoord[1])*proj*(float)m_textureSpec.height	/ (float)viewportSize[1];
1009 			lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f, 0.0f, dvdy);
1010 
1011 			// Append to texture list.
1012 			m_textures.push_back(TextureBindingSp(new TextureBinding(texture2DArray.release(), m_textureSpec.sampler)));
1013 			break;
1014 		}
1015 
1016 		case TEXTURETYPE_3D:
1017 		{
1018 			float								levelStep		= isAutoLod ? 0.0f : 1.0f / (float)de::max(1, m_textureSpec.numLevels-1);
1019 			Vec4								cScale			= fmtInfo.valueMax-fmtInfo.valueMin;
1020 			Vec4								cBias			= fmtInfo.valueMin;
1021 			int									baseCellSize	= de::min(de::min(m_textureSpec.width/2, m_textureSpec.height/2), m_textureSpec.depth/2);
1022 			de::MovePtr<tcu::Texture3D>			texture3D;
1023 
1024 			texture3D = de::MovePtr<tcu::Texture3D>(new tcu::Texture3D(texFmt, m_textureSpec.width, m_textureSpec.height, m_textureSpec.depth));
1025 
1026 			for (int level = 0; level < m_textureSpec.numLevels; level++)
1027 			{
1028 				float	fA		= (float)level*levelStep;
1029 				float	fB		= 1.0f-fA;
1030 				Vec4	colorA	= cBias + cScale*Vec4(fA, fB, fA, fB);
1031 				Vec4	colorB	= cBias + cScale*Vec4(fB, fA, fB, fA);
1032 
1033 				texture3D->allocLevel(level);
1034 				tcu::fillWithGrid(texture3D->getLevel(level), de::max(1, baseCellSize>>level), colorA, colorB);
1035 			}
1036 
1037 			// Compute LOD.
1038 			float	dudx	= (m_lookupSpec.maxCoord[0]-m_lookupSpec.minCoord[0])*proj*(float)m_textureSpec.width		/ (float)viewportSize[0];
1039 			float	dvdy	= (m_lookupSpec.maxCoord[1]-m_lookupSpec.minCoord[1])*proj*(float)m_textureSpec.height		/ (float)viewportSize[1];
1040 			float	dwdx	= (m_lookupSpec.maxCoord[2]-m_lookupSpec.minCoord[2])*0.5f*proj*(float)m_textureSpec.depth	/ (float)viewportSize[0];
1041 			float	dwdy	= (m_lookupSpec.maxCoord[2]-m_lookupSpec.minCoord[2])*0.5f*proj*(float)m_textureSpec.depth	/ (float)viewportSize[1];
1042 			lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f, dwdx, 0.0f, dvdy, dwdy);
1043 
1044 			// Append to texture list.
1045 			m_textures.push_back(TextureBindingSp(new TextureBinding(texture3D.release(), m_textureSpec.sampler)));
1046 			break;
1047 		}
1048 
1049 		case TEXTURETYPE_1D:
1050 		{
1051 			float								levelStep		= isAutoLod ? 0.0f : 1.0f / (float)de::max(1, m_textureSpec.numLevels-1);
1052 			Vec4								cScale			= fmtInfo.valueMax-fmtInfo.valueMin;
1053 			Vec4								cBias			= fmtInfo.valueMin;
1054 			int									baseCellSize	= m_textureSpec.width/4;
1055 			de::MovePtr<tcu::Texture1D>			texture1D;
1056 
1057 			texture1D = de::MovePtr<tcu::Texture1D>(new tcu::Texture1D(texFmt, m_textureSpec.width));
1058 
1059 			for (int level = 0; level < m_textureSpec.numLevels; level++)
1060 			{
1061 				float	fA		= float(level)*levelStep;
1062 				float	fB		= 1.0f-fA;
1063 				Vec4	colorA	= cBias + cScale*Vec4(fA, fB, fA, fB);
1064 				Vec4	colorB	= cBias + cScale*Vec4(fB, fA, fB, fA);
1065 
1066 				texture1D->allocLevel(level);
1067 				tcu::fillWithGrid(texture1D->getLevel(level), de::max(1, baseCellSize>>level), colorA, colorB);
1068 			}
1069 
1070 			// Compute LOD.
1071 			float	dudx	= (m_lookupSpec.maxCoord[0]-m_lookupSpec.minCoord[0])*proj*(float)m_textureSpec.width	/ (float)viewportSize[0];
1072 			lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f);
1073 
1074 			// Append to texture list.
1075 			m_textures.push_back(TextureBindingSp(new TextureBinding(texture1D.release(), m_textureSpec.sampler)));
1076 			break;
1077 		}
1078 
1079 		case TEXTURETYPE_1D_ARRAY:
1080 		{
1081 			float								layerStep		= 1.0f / (float)m_textureSpec.depth;
1082 			float								levelStep		= isAutoLod ? 0.0f : 1.0f / (float)(de::max(1, m_textureSpec.numLevels-1)*m_textureSpec.depth);
1083 			Vec4								cScale			= fmtInfo.valueMax-fmtInfo.valueMin;
1084 			Vec4								cBias			= fmtInfo.valueMin;
1085 			int									baseCellSize	= m_textureSpec.width/4;
1086 			de::MovePtr<tcu::Texture1DArray>	texture1DArray;
1087 
1088 			texture1DArray = de::MovePtr<tcu::Texture1DArray>(new tcu::Texture1DArray(texFmt, m_textureSpec.width, m_textureSpec.depth));
1089 
1090 			for (int level = 0; level < m_textureSpec.numLevels; level++)
1091 			{
1092 				texture1DArray->allocLevel(level);
1093 				tcu::PixelBufferAccess levelAccess = texture1DArray->getLevel(level);
1094 
1095 				for (int layer = 0; layer < levelAccess.getHeight(); layer++)
1096 				{
1097 					float	fA		= (float)layer*layerStep + (float)level*levelStep;
1098 					float	fB		= 1.0f-fA;
1099 					Vec4	colorA	= cBias + cScale*Vec4(fA, fB, fA, fB);
1100 					Vec4	colorB	= cBias + cScale*Vec4(fB, fA, fB, fA);
1101 
1102 					tcu::fillWithGrid(tcu::getSubregion(levelAccess, 0, layer, 0, levelAccess.getWidth(), 1, 1), de::max(1, baseCellSize>>level), colorA, colorB);
1103 				}
1104 			}
1105 
1106 			// Compute LOD.
1107 			float	dudx	= (m_lookupSpec.maxCoord[0]-m_lookupSpec.minCoord[0])*proj*(float)m_textureSpec.width	/ (float)viewportSize[0];
1108 			lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f);
1109 
1110 			// Append to texture list.
1111 			m_textures.push_back(TextureBindingSp(new TextureBinding(texture1DArray.release(), m_textureSpec.sampler)));
1112 			break;
1113 		}
1114 
1115 		case TEXTURETYPE_CUBE_ARRAY:
1116 		{
1117 			float								layerStep			= 1.0f / (float)(m_textureSpec.depth/6);
1118 			float								levelStep			= isAutoLod ? 0.0f : 1.0f / (float)(de::max(1, m_textureSpec.numLevels-1)*(m_textureSpec.depth/6));
1119 			Vec4								cScale				= fmtInfo.valueMax-fmtInfo.valueMin;
1120 			Vec4								cBias				= fmtInfo.valueMin;
1121 			Vec4								cCorner				= cBias + cScale*0.5f;
1122 			int									baseCellSize		= de::min(m_textureSpec.width/4, m_textureSpec.height/4);
1123 			de::MovePtr<tcu::TextureCubeArray>	textureCubeArray;
1124 
1125 			DE_ASSERT(m_textureSpec.width == m_textureSpec.height);
1126 			DE_ASSERT(m_textureSpec.depth % 6 == 0);
1127 
1128 			textureCubeArray = de::MovePtr<tcu::TextureCubeArray>(new tcu::TextureCubeArray(texFmt, m_textureSpec.width, m_textureSpec.depth));
1129 
1130 			for (int level = 0; level < m_textureSpec.numLevels; level++)
1131 			{
1132 				float	fA		= float(level)*levelStep;
1133 				float	fB		= 1.0f-fA;
1134 				Vec2	f		(fA, fB);
1135 
1136 				textureCubeArray->allocLevel(level);
1137 				tcu::PixelBufferAccess levelAccess = textureCubeArray->getLevel(level);
1138 
1139 				for (int layer = 0; layer < m_textureSpec.depth/6; layer++)
1140 				{
1141 					float layerCorr = 1.0f-(float)layer*layerStep;
1142 
1143 					for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
1144 					{
1145 						const IVec4&	swzA	= texCubeSwz[face];
1146 						IVec4			swzB	= 1-swzA;
1147 						Vec4			colorA	= cBias + cScale*f.swizzle(swzA[0], swzA[1], swzA[2], swzA[3])*layerCorr;
1148 						Vec4			colorB	= cBias + cScale*f.swizzle(swzB[0], swzB[1], swzB[2], swzB[3])*layerCorr;
1149 
1150 						{
1151 							const tcu::PixelBufferAccess	access		= tcu::getSubregion(levelAccess, 0, 0, (layer*6)+face, levelAccess.getWidth(), levelAccess.getHeight(), 1);
1152 							const int						lastPix		= access.getWidth()-1;
1153 
1154 							tcu::fillWithGrid(access, de::max(1, baseCellSize>>level), colorA, colorB);
1155 
1156 							// Ensure all corners have identical colors in order to avoid dealing with ambiguous corner texel filtering
1157 							access.setPixel(cCorner, 0, 0);
1158 							access.setPixel(cCorner, 0, lastPix);
1159 							access.setPixel(cCorner, lastPix, 0);
1160 							access.setPixel(cCorner, lastPix, lastPix);
1161 						}
1162 					}
1163 				}
1164 			}
1165 
1166 			// Compute LOD \note Assumes that only single side is accessed and R is constant major axis.
1167 			DE_ASSERT(de::abs(m_lookupSpec.minCoord[2] - m_lookupSpec.maxCoord[2]) < 0.005);
1168 			DE_ASSERT(de::abs(m_lookupSpec.minCoord[0]) < de::abs(m_lookupSpec.minCoord[2]) && de::abs(m_lookupSpec.maxCoord[0]) < de::abs(m_lookupSpec.minCoord[2]));
1169 			DE_ASSERT(de::abs(m_lookupSpec.minCoord[1]) < de::abs(m_lookupSpec.minCoord[2]) && de::abs(m_lookupSpec.maxCoord[1]) < de::abs(m_lookupSpec.minCoord[2]));
1170 
1171 			tcu::CubeFaceFloatCoords	c00		= tcu::getCubeFaceCoords(Vec3(m_lookupSpec.minCoord[0]*proj, m_lookupSpec.minCoord[1]*proj, m_lookupSpec.minCoord[2]*proj));
1172 			tcu::CubeFaceFloatCoords	c10		= tcu::getCubeFaceCoords(Vec3(m_lookupSpec.maxCoord[0]*proj, m_lookupSpec.minCoord[1]*proj, m_lookupSpec.minCoord[2]*proj));
1173 			tcu::CubeFaceFloatCoords	c01		= tcu::getCubeFaceCoords(Vec3(m_lookupSpec.minCoord[0]*proj, m_lookupSpec.maxCoord[1]*proj, m_lookupSpec.minCoord[2]*proj));
1174 			float						dudx	= (c10.s - c00.s)*(float)m_textureSpec.width	/ (float)viewportSize[0];
1175 			float						dvdy	= (c01.t - c00.t)*(float)m_textureSpec.height	/ (float)viewportSize[1];
1176 			lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f, 0.0f, dvdy);
1177 
1178 			// Append to texture list.
1179 			m_textures.push_back(TextureBindingSp(new TextureBinding(textureCubeArray.release(), m_textureSpec.sampler)));
1180 			break;
1181 		}
1182 
1183 		default:
1184 			DE_ASSERT(DE_FALSE);
1185 	}
1186 
1187 	// Set lookup scale & bias
1188 	lookupParams.scale		= fmtInfo.lookupScale;
1189 	lookupParams.bias		= fmtInfo.lookupBias;
1190 	lookupParams.offset		= m_lookupSpec.offset;
1191 	lookupParams.lodClamp	= m_lookupSpec.lodClamp;
1192 
1193 	// \todo [dirnerakos] Avoid const cast somehow
1194 	const_cast<TexLookupParams&>(m_lookupParams) = lookupParams;
1195 }
1196 
1197 class ShaderTextureFunctionCase : public ShaderRenderCase
1198 {
1199 public:
1200 								ShaderTextureFunctionCase		(tcu::TestContext&				testCtx,
1201 																 const std::string&				name,
1202 																 const TextureLookupSpec&		lookup,
1203 																 const TextureSpec&				texture,
1204 																 TexEvalFunc					evalFunc,
1205 																 bool							isVertexCase);
1206 	virtual						~ShaderTextureFunctionCase		(void);
1207 
1208 	virtual TestInstance*		createInstance					(Context& context) const;
1209 	virtual void				checkSupport					(Context& context) const;
1210 
1211 protected:
1212 	const TextureLookupSpec		m_lookupSpec;
1213 	const TextureSpec			m_textureSpec;
1214 	const TexLookupParams		m_lookupParams;
1215 
1216 	void						initShaderSources				(void);
1217 };
1218 
ShaderTextureFunctionCase(tcu::TestContext & testCtx,const std::string & name,const TextureLookupSpec & lookup,const TextureSpec & texture,TexEvalFunc evalFunc,bool isVertexCase)1219 ShaderTextureFunctionCase::ShaderTextureFunctionCase (tcu::TestContext&				testCtx,
1220 													  const std::string&			name,
1221 													  const TextureLookupSpec&		lookup,
1222 													  const TextureSpec&			texture,
1223 													  TexEvalFunc					evalFunc,
1224 													  bool							isVertexCase)
1225 	: ShaderRenderCase		(testCtx, name, isVertexCase, new TexLookupEvaluator(evalFunc, m_lookupParams), NULL, NULL)
1226 	, m_lookupSpec			(lookup)
1227 	, m_textureSpec			(texture)
1228 {
1229 	initShaderSources();
1230 }
1231 
~ShaderTextureFunctionCase(void)1232 ShaderTextureFunctionCase::~ShaderTextureFunctionCase (void)
1233 {
1234 }
1235 
createInstance(Context & context) const1236 TestInstance* ShaderTextureFunctionCase::createInstance (Context& context) const
1237 {
1238 	DE_ASSERT(m_evaluator != DE_NULL);
1239 	DE_ASSERT(m_uniformSetup != DE_NULL);
1240 	return new ShaderTextureFunctionInstance(context, m_isVertexCase, *m_evaluator, *m_uniformSetup, m_lookupSpec, m_textureSpec, m_lookupParams);
1241 }
1242 
checkSupport(Context & context) const1243 void ShaderTextureFunctionCase::checkSupport(Context& context) const
1244 {
1245 	checkMutableComparisonSamplersSupport(context, m_textureSpec);
1246 }
1247 
initShaderSources(void)1248 void ShaderTextureFunctionCase::initShaderSources (void)
1249 {
1250 	Function			function			= m_lookupSpec.function;
1251 	bool				isVtxCase			= m_isVertexCase;
1252 	bool				isProj				= functionHasProj(function);
1253 	bool				isGrad				= functionHasGrad(function);
1254 	bool				isShadow			= m_textureSpec.sampler.compare != tcu::Sampler::COMPAREMODE_NONE;
1255 	bool				is2DProj4			= !isShadow && m_textureSpec.type == TEXTURETYPE_2D && (function == FUNCTION_TEXTUREPROJ || function == FUNCTION_TEXTUREPROJLOD || function == FUNCTION_TEXTUREPROJGRAD);
1256 	bool				is1DProj4			= !isShadow && m_textureSpec.type == TEXTURETYPE_1D && (function == FUNCTION_TEXTUREPROJ || function == FUNCTION_TEXTUREPROJLOD || function == FUNCTION_TEXTUREPROJGRAD);
1257 	bool				isIntCoord			= function == FUNCTION_TEXELFETCH;
1258 	bool				hasLodBias			= functionHasLod(m_lookupSpec.function) || m_lookupSpec.useBias;
1259 	int					texCoordComps		= m_textureSpec.type == TEXTURETYPE_1D ? 1 :
1260 											  m_textureSpec.type == TEXTURETYPE_1D_ARRAY || m_textureSpec.type == TEXTURETYPE_2D ? 2 :
1261 											  m_textureSpec.type == TEXTURETYPE_CUBE_ARRAY ? 4 :
1262 											  3;
1263 	int					extraCoordComps		= (isProj ? (is2DProj4 ? 2 : (is1DProj4 ? 3 : 1)) : 0) + (isShadow ? (m_textureSpec.type == TEXTURETYPE_1D ? 2 : 1) : 0);
1264 	const bool			isCubeArrayShadow	= isShadow && m_textureSpec.type == TEXTURETYPE_CUBE_ARRAY;
1265 	glu::DataType		coordType			= glu::getDataTypeFloatVec(isCubeArrayShadow ? 4 : texCoordComps+extraCoordComps);
1266 	glu::Precision		coordPrec			= glu::PRECISION_HIGHP;
1267 	const char*			coordTypeName		= glu::getDataTypeName(coordType);
1268 	const char*			coordPrecName		= glu::getPrecisionName(coordPrec);
1269 	tcu::TextureFormat	texFmt				= glu::mapGLInternalFormat(m_textureSpec.format);
1270 	glu::DataType		samplerType			= glu::TYPE_LAST;
1271 	glu::DataType		gradType			= m_textureSpec.type == TEXTURETYPE_1D || m_textureSpec.type == TEXTURETYPE_1D_ARRAY ? glu::TYPE_FLOAT :
1272 											  m_textureSpec.type == TEXTURETYPE_3D || m_textureSpec.type == TEXTURETYPE_CUBE_MAP || m_textureSpec.type == TEXTURETYPE_CUBE_ARRAY ? glu::TYPE_FLOAT_VEC3 :
1273 											  glu::TYPE_FLOAT_VEC2;
1274 	const char*			gradTypeName		= glu::getDataTypeName(gradType);
1275 	const char*			baseFuncName		= DE_NULL;
1276 
1277 	DE_ASSERT(!isGrad || !hasLodBias);
1278 
1279 	switch (m_textureSpec.type)
1280 	{
1281 		case TEXTURETYPE_2D:			samplerType = isShadow ? glu::TYPE_SAMPLER_2D_SHADOW			: glu::getSampler2DType(texFmt);		break;
1282 		case TEXTURETYPE_CUBE_MAP:		samplerType = isShadow ? glu::TYPE_SAMPLER_CUBE_SHADOW			: glu::getSamplerCubeType(texFmt);		break;
1283 		case TEXTURETYPE_2D_ARRAY:		samplerType = isShadow ? glu::TYPE_SAMPLER_2D_ARRAY_SHADOW		: glu::getSampler2DArrayType(texFmt);	break;
1284 		case TEXTURETYPE_3D:			DE_ASSERT(!isShadow); samplerType = glu::getSampler3DType(texFmt);										break;
1285 		case TEXTURETYPE_1D:			samplerType = isShadow ? glu::TYPE_SAMPLER_1D_SHADOW			: glu::getSampler1DType(texFmt);		break;
1286 		case TEXTURETYPE_1D_ARRAY:		samplerType = isShadow ? glu::TYPE_SAMPLER_1D_ARRAY_SHADOW		: glu::getSampler1DArrayType(texFmt);	break;
1287 		case TEXTURETYPE_CUBE_ARRAY:	samplerType = isShadow ? glu::TYPE_SAMPLER_CUBE_ARRAY_SHADOW	: glu::getSamplerCubeArrayType(texFmt);	break;
1288 		default:
1289 			DE_ASSERT(DE_FALSE);
1290 	}
1291 
1292 	switch (m_lookupSpec.function)
1293 	{
1294 		case FUNCTION_TEXTURE:			baseFuncName = "texture";			break;
1295 		case FUNCTION_TEXTUREPROJ:		baseFuncName = "textureProj";		break;
1296 		case FUNCTION_TEXTUREPROJ2:		baseFuncName = "textureProj";		break;
1297 		case FUNCTION_TEXTUREPROJ3:		baseFuncName = "textureProj";		break;
1298 		case FUNCTION_TEXTURELOD:		baseFuncName = "textureLod";		break;
1299 		case FUNCTION_TEXTUREPROJLOD:	baseFuncName = "textureProjLod";	break;
1300 		case FUNCTION_TEXTUREPROJLOD2:	baseFuncName = "textureProjLod";	break;
1301 		case FUNCTION_TEXTUREPROJLOD3:	baseFuncName = "textureProjLod";	break;
1302 		case FUNCTION_TEXTUREGRAD:		baseFuncName = "textureGrad";		break;
1303 		case FUNCTION_TEXTUREPROJGRAD:	baseFuncName = "textureProjGrad";	break;
1304 		case FUNCTION_TEXTUREPROJGRAD2:	baseFuncName = "textureProjGrad";	break;
1305 		case FUNCTION_TEXTUREPROJGRAD3:	baseFuncName = "textureProjGrad";	break;
1306 		case FUNCTION_TEXELFETCH:		baseFuncName = "texelFetch";		break;
1307 		default:
1308 			DE_ASSERT(DE_FALSE);
1309 	}
1310 
1311 	std::ostringstream	vert;
1312 	std::ostringstream	frag;
1313 	std::ostringstream&	op		= isVtxCase ? vert : frag;
1314 
1315 	vert << "#version 450 core\n"
1316 		 << "layout(location = 0) in highp vec4 a_position;\n"
1317 		 << "layout(location = 4) in " << coordPrecName << " " << coordTypeName << " a_in0;\n";
1318 
1319 	if (isGrad)
1320 	{
1321 		vert << "layout(location = 5) in " << coordPrecName << " " << gradTypeName << " a_in1;\n";
1322 		vert << "layout(location = 6) in " << coordPrecName << " " << gradTypeName << " a_in2;\n";
1323 	}
1324 	else if (hasLodBias)
1325 		vert << "layout(location = 5) in " << coordPrecName << " float a_in1;\n";
1326 
1327 	frag << "#version 450 core\n";
1328 
1329 	if (m_lookupSpec.useClamp)
1330 		frag << "#extension GL_ARB_sparse_texture_clamp : require\n";
1331 
1332 	frag  << "layout(location = 0) out mediump vec4 o_color;\n";
1333 
1334 	if (isVtxCase)
1335 	{
1336 		vert << "layout(location = 0) out mediump vec4 v_color;\n";
1337 		frag << "layout(location = 0) in mediump vec4 v_color;\n";
1338 	}
1339 	else
1340 	{
1341 		vert << "layout(location = 0) out " << coordPrecName << " " << coordTypeName << " v_texCoord;\n";
1342 		frag << "layout(location = 0) in " << coordPrecName << " " << coordTypeName << " v_texCoord;\n";
1343 
1344 		if (isGrad)
1345 		{
1346 			vert << "layout(location = 1) out " << coordPrecName << " " << gradTypeName << " v_gradX;\n";
1347 			vert << "layout(location = 2) out " << coordPrecName << " " << gradTypeName << " v_gradY;\n";
1348 			frag << "layout(location = 1) in " << coordPrecName << " " << gradTypeName << " v_gradX;\n";
1349 			frag << "layout(location = 2) in " << coordPrecName << " " << gradTypeName << " v_gradY;\n";
1350 		}
1351 		else if (hasLodBias)
1352 		{
1353 			vert << "layout(location = 1) out " << coordPrecName << " float v_lodBias;\n";
1354 			frag << "layout(location = 1) in " << coordPrecName << " float v_lodBias;\n";
1355 		}
1356 	}
1357 
1358 	// Uniforms
1359 	op << "layout(set = 0, binding = 0) uniform highp " << glu::getDataTypeName(samplerType) << " u_sampler;\n"
1360 	   << "layout(set = 0, binding = 1) uniform buf0 { highp vec4 u_scale; };\n"
1361 	   << "layout(set = 0, binding = 2) uniform buf1 { highp vec4 u_bias; };\n";
1362 
1363 	vert << "out gl_PerVertex {\n"
1364 		 << "\tvec4 gl_Position;\n"
1365 		 << "};\n";
1366 
1367 	vert << "\nvoid main()\n{\n"
1368 		 << "\tgl_Position = a_position;\n";
1369 	frag << "\nvoid main()\n{\n";
1370 
1371 	if (isVtxCase)
1372 		vert << "\tv_color = ";
1373 	else
1374 		frag << "\to_color = ";
1375 
1376 	// Op.
1377 	{
1378 		const char*	texCoord	= isVtxCase ? "a_in0" : "v_texCoord";
1379 		const char* gradX		= isVtxCase ? "a_in1" : "v_gradX";
1380 		const char* gradY		= isVtxCase ? "a_in2" : "v_gradY";
1381 		const char*	lodBias		= isVtxCase ? "a_in1" : "v_lodBias";
1382 
1383 		op << "vec4(" << baseFuncName;
1384 		if (m_lookupSpec.useOffset)
1385 			op << "Offset";
1386 		if (m_lookupSpec.useClamp)
1387 			op << "ClampARB";
1388 		op << "(u_sampler, ";
1389 
1390 		if (isIntCoord)
1391 			op << glu::getDataTypeName(glu::getDataTypeIntVec(texCoordComps+extraCoordComps)) << "(";
1392 
1393 		op << texCoord;
1394 
1395 		if (isIntCoord)
1396 			op << ")";
1397 
1398 		if (isGrad)
1399 			op << ", " << gradX << ", " << gradY;
1400 
1401 		if (functionHasLod(function))
1402 		{
1403 			if (isIntCoord)
1404 				op << ", int(" << lodBias << ")";
1405 			else
1406 				op << ", " << lodBias;
1407 		}
1408 
1409 		if (m_lookupSpec.useOffset)
1410 		{
1411 			int offsetComps = m_textureSpec.type == TEXTURETYPE_1D || m_textureSpec.type == TEXTURETYPE_1D_ARRAY ? 1 :
1412 							  m_textureSpec.type == TEXTURETYPE_3D ? 3 : 2;
1413 
1414 			op << ", " << glu::getDataTypeName(glu::getDataTypeIntVec(offsetComps)) << "(";
1415 			for (int ndx = 0; ndx < offsetComps; ndx++)
1416 			{
1417 				if (ndx != 0)
1418 					op << ", ";
1419 				op << m_lookupSpec.offset[ndx];
1420 			}
1421 			op << ")";
1422 		}
1423 
1424 		if (m_lookupSpec.useClamp)
1425 			op << ", float(" << m_lookupSpec.lodClamp << ")";
1426 
1427 		if (isCubeArrayShadow && m_lookupSpec.function == FUNCTION_TEXTURE)
1428 			op << ", " << texCoord << ".w";
1429 
1430 		if (m_lookupSpec.useBias)
1431 			op << ", " << lodBias;
1432 
1433 		op << ")";
1434 
1435 		if (isShadow)
1436 			op << ", 0.0, 0.0, 1.0)";
1437 		else
1438 			op << ")*u_scale + u_bias";
1439 
1440 		op << ";\n";
1441 	}
1442 
1443 	if (isVtxCase)
1444 		frag << "\to_color = v_color;\n";
1445 	else
1446 	{
1447 		vert << "\tv_texCoord = a_in0;\n";
1448 
1449 		if (isGrad)
1450 		{
1451 			vert << "\tv_gradX = a_in1;\n";
1452 			vert << "\tv_gradY = a_in2;\n";
1453 		}
1454 		else if (hasLodBias)
1455 			vert << "\tv_lodBias = a_in1;\n";
1456 	}
1457 
1458 	vert << "}\n";
1459 	frag << "}\n";
1460 
1461 	m_vertShaderSource = vert.str();
1462 	m_fragShaderSource = frag.str();
1463 }
1464 
1465 enum QueryFunction
1466 {
1467 	QUERYFUNCTION_TEXTURESIZE = 0,
1468 	QUERYFUNCTION_TEXTURESIZEMS,
1469 	QUERYFUNCTION_TEXTUREQUERYLOD,
1470 	QUERYFUNCTION_TEXTUREQUERYLEVELS,
1471 	QUERYFUNCTION_TEXTURESAMPLES,
1472 
1473 	QUERYFUNCTION_LAST
1474 };
1475 
1476 // test mode used to alter test behaviour
1477 using TestMode = deUint32;
1478 
1479 enum QueryLodTestModes
1480 {
1481 	QLODTM_DEFAULT			= 0,		// uv coords have different values
1482 	QLODTM_ZERO_UV_WIDTH				// all uv coords are 0; there were implementations that incorrectly returned 0 in that case instead of -maxSamplerLodBias or less
1483 };
1484 
1485 class TextureQueryInstance : public ShaderRenderCaseInstance
1486 {
1487 public:
1488 								TextureQueryInstance			(Context&					context,
1489 																 const bool					isVertexCase,
1490 																 const TextureSpec&			textureSpec);
1491 	virtual						~TextureQueryInstance			(void);
1492 
1493 protected:
1494 	virtual void				setupDefaultInputs				(void);
1495 	virtual void				setupUniforms					(const tcu::Vec4&);
1496 
1497 	void						render							(void);
1498 
1499 protected:
1500 	const TextureSpec&			m_textureSpec;
1501 };
1502 
TextureQueryInstance(Context & context,const bool isVertexCase,const TextureSpec & textureSpec)1503 TextureQueryInstance::TextureQueryInstance (Context&				context,
1504 											const bool				isVertexCase,
1505 											const TextureSpec&		textureSpec)
1506 	: ShaderRenderCaseInstance	(context, isVertexCase, DE_NULL, DE_NULL, DE_NULL)
1507 	, m_textureSpec				(textureSpec)
1508 {
1509 	m_colorFormat = vk::VK_FORMAT_R32G32B32A32_SFLOAT;
1510 
1511 	checkDeviceFeatures(m_context, m_textureSpec.type);
1512 }
1513 
~TextureQueryInstance(void)1514 TextureQueryInstance::~TextureQueryInstance (void)
1515 {
1516 }
1517 
setupDefaultInputs(void)1518 void TextureQueryInstance::setupDefaultInputs (void)
1519 {
1520 	const deUint32		numVertices		= 4;
1521 	const float			positions[]		=
1522 	{
1523 		-1.0f, -1.0f, 0.0f, 1.0f,
1524 		-1.0f,  1.0f, 0.0f, 1.0f,
1525 		 1.0f, -1.0f, 0.0f, 1.0f,
1526 		 1.0f,  1.0f, 0.0f, 1.0f
1527 	};
1528 
1529 	addAttribute(0u, vk::VK_FORMAT_R32G32B32A32_SFLOAT, 4 * (deUint32)sizeof(float), numVertices, positions);
1530 }
1531 
setupUniforms(const tcu::Vec4 &)1532 void TextureQueryInstance::setupUniforms (const tcu::Vec4&)
1533 {
1534 	useSampler(0u, 0u);
1535 }
1536 
render(void)1537 void TextureQueryInstance::render (void)
1538 {
1539 	const deUint32		numVertices		= 4;
1540 	const deUint32		numTriangles	= 2;
1541 	const deUint16		indices[6]		= { 0, 1, 2, 2, 1, 3 };
1542 
1543 	ShaderRenderCaseInstance::setup();
1544 
1545 	ShaderRenderCaseInstance::render(numVertices, numTriangles, indices);
1546 }
1547 
getMaxTextureSize(TextureType type,const tcu::IVec3 & textureSize)1548 static int getMaxTextureSize (TextureType type, const tcu::IVec3& textureSize)
1549 {
1550 	int		maxSize		= 0;
1551 
1552 	switch (type)
1553 	{
1554 		case TEXTURETYPE_1D:
1555 		case TEXTURETYPE_1D_ARRAY:
1556 			maxSize = textureSize.x();
1557 			break;
1558 
1559 		case TEXTURETYPE_2D:
1560 		case TEXTURETYPE_2D_ARRAY:
1561 		case TEXTURETYPE_CUBE_MAP:
1562 		case TEXTURETYPE_CUBE_ARRAY:
1563 			maxSize = de::max(textureSize.x(), textureSize.y());
1564 			break;
1565 
1566 		case TEXTURETYPE_3D:
1567 			maxSize = de::max(textureSize.x(), de::max(textureSize.y(), textureSize.z()));
1568 			break;
1569 
1570 		default:
1571 			DE_ASSERT(false);
1572 	}
1573 
1574 	return maxSize;
1575 }
1576 
getTextureSizeString(TextureType type,const tcu::IVec3 & textureSize)1577 static std::string getTextureSizeString (TextureType type, const tcu::IVec3& textureSize)
1578 {
1579 	std::ostringstream	str;
1580 
1581 	switch (type)
1582 	{
1583 		case TEXTURETYPE_1D:
1584 			str << textureSize.x() << "x1";
1585 			break;
1586 
1587 		case TEXTURETYPE_2D:
1588 		case TEXTURETYPE_CUBE_MAP:
1589 			str << textureSize.x() << "x" << textureSize.y();
1590 			break;
1591 
1592 		case TEXTURETYPE_3D:
1593 			str << textureSize.x() << "x" << textureSize.y() << "x" << textureSize.z();
1594 			break;
1595 
1596 		case TEXTURETYPE_1D_ARRAY:
1597 			str << textureSize.x() << "x1 with " << textureSize.z() << " layer(s)";
1598 			break;
1599 
1600 		case TEXTURETYPE_2D_ARRAY:
1601 		case TEXTURETYPE_CUBE_ARRAY:
1602 			str << textureSize.x() << "x" << textureSize.y() << " with " << textureSize.z() << " layers(s)";
1603 			break;
1604 
1605 		default:
1606 			DE_ASSERT(false);
1607 			break;
1608 	}
1609 
1610 	return str.str();
1611 }
1612 
isValidCase(TextureType type,const tcu::IVec3 & textureSize,int lodBase)1613 static bool isValidCase (TextureType type, const tcu::IVec3& textureSize, int lodBase)
1614 {
1615 	const bool	isSquare	= textureSize.x() == textureSize.y();
1616 	const bool	isCubeArray	= isSquare && (textureSize.z() % 6) == 0;
1617 	const int	maxSize		= getMaxTextureSize(type, textureSize);
1618 	const bool	isBaseValid	= (maxSize >> lodBase) != 0;
1619 
1620 	if (!isBaseValid)
1621 		return false;
1622 	if (type == TEXTURETYPE_CUBE_MAP && !isSquare)
1623 		return false;
1624 	if (type == TEXTURETYPE_CUBE_ARRAY && !isCubeArray)
1625 		return false;
1626 
1627 	return true;
1628 }
1629 
createEmptyTexture(deUint32 format,TextureType type,const tcu::IVec3 & textureSize,int numLevels,int lodBase,const tcu::Sampler & sampler)1630 static TextureBindingSp createEmptyTexture (deUint32				format,
1631 											TextureType				type,
1632 											const tcu::IVec3&		textureSize,
1633 											int						numLevels,
1634 											int						lodBase,
1635 											const tcu::Sampler&		sampler)
1636 {
1637 	const tcu::TextureFormat			texFmt				= glu::mapGLInternalFormat(format);
1638 	const TextureBinding::Parameters	params				(lodBase);
1639 	TextureBindingSp					textureBinding;
1640 
1641 	switch (type)
1642 	{
1643 
1644 		case TEXTURETYPE_1D:
1645 		{
1646 			de::MovePtr<tcu::Texture1D>			texture		(new tcu::Texture1D(texFmt, textureSize.x()));
1647 
1648 			for (int level = 0; level < numLevels; level++)
1649 				texture->allocLevel(level);
1650 
1651 			textureBinding = TextureBindingSp(new TextureBinding(texture.release(), sampler));
1652 			break;
1653 		}
1654 
1655 		case TEXTURETYPE_2D:
1656 		{
1657 			de::MovePtr<tcu::Texture2D>			texture		(new tcu::Texture2D(texFmt, textureSize.x(), textureSize.y()));
1658 
1659 			for (int level = 0; level < numLevels; level++)
1660 				texture->allocLevel(level);
1661 
1662 			textureBinding = TextureBindingSp(new TextureBinding(texture.release(), sampler));
1663 			break;
1664 		}
1665 
1666 		case TEXTURETYPE_3D:
1667 		{
1668 			de::MovePtr<tcu::Texture3D>			texture		(new tcu::Texture3D(texFmt, textureSize.x(), textureSize.y(), textureSize.z()));
1669 
1670 			for (int level = 0; level < numLevels; level++)
1671 				texture->allocLevel(level);
1672 
1673 			textureBinding = TextureBindingSp(new TextureBinding(texture.release(), sampler));
1674 			break;
1675 		}
1676 
1677 		case TEXTURETYPE_CUBE_MAP:
1678 		{
1679 			de::MovePtr<tcu::TextureCube>		texture		(new tcu::TextureCube(texFmt, textureSize.x()));
1680 
1681 			for (int level = 0; level < numLevels; level++)
1682 				for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
1683 					texture->allocLevel((tcu::CubeFace)face, level);
1684 
1685 			textureBinding = TextureBindingSp(new TextureBinding(texture.release(), sampler));
1686 			break;
1687 		}
1688 
1689 		case TEXTURETYPE_1D_ARRAY:
1690 		{
1691 			de::MovePtr<tcu::Texture1DArray>	texture		(new tcu::Texture1DArray(texFmt, textureSize.x(), textureSize.z()));
1692 
1693 			for (int level = 0; level < numLevels; level++)
1694 				texture->allocLevel(level);
1695 
1696 			textureBinding = TextureBindingSp(new TextureBinding(texture.release(), sampler));
1697 			break;
1698 		}
1699 
1700 		case TEXTURETYPE_2D_ARRAY:
1701 		{
1702 			de::MovePtr<tcu::Texture2DArray>	texture		(new tcu::Texture2DArray(texFmt, textureSize.x(), textureSize.y(), textureSize.z()));
1703 
1704 			for (int level = 0; level < numLevels; level++)
1705 				texture->allocLevel(level);
1706 
1707 			textureBinding = TextureBindingSp(new TextureBinding(texture.release(), sampler));
1708 			break;
1709 		}
1710 
1711 		case TEXTURETYPE_CUBE_ARRAY:
1712 		{
1713 			de::MovePtr<tcu::TextureCubeArray>	texture		(new tcu::TextureCubeArray(texFmt, textureSize.x(), textureSize.z()));
1714 
1715 			for (int level = 0; level < numLevels; level++)
1716 				texture->allocLevel(level);
1717 
1718 			textureBinding = TextureBindingSp(new TextureBinding(texture.release(), sampler));
1719 			break;
1720 		}
1721 
1722 		default:
1723 			DE_ASSERT(false);
1724 			break;
1725 	}
1726 
1727 	textureBinding->setParameters(params);
1728 	return textureBinding;
1729 }
1730 
getTextureSizeFuncResultType(TextureType textureType)1731 static inline glu::DataType getTextureSizeFuncResultType (TextureType textureType)
1732 {
1733 	switch (textureType)
1734 	{
1735 		case TEXTURETYPE_1D:
1736 			return glu::TYPE_INT;
1737 
1738 		case TEXTURETYPE_2D:
1739 		case TEXTURETYPE_CUBE_MAP:
1740 		case TEXTURETYPE_1D_ARRAY:
1741 			return glu::TYPE_INT_VEC2;
1742 
1743 		case TEXTURETYPE_3D:
1744 		case TEXTURETYPE_2D_ARRAY:
1745 		case TEXTURETYPE_CUBE_ARRAY:
1746 			return glu::TYPE_INT_VEC3;
1747 
1748 		default:
1749 			DE_ASSERT(false);
1750 			return glu::TYPE_LAST;
1751 	}
1752 }
1753 
1754 class TextureSizeInstance : public TextureQueryInstance
1755 {
1756 public:
1757 								TextureSizeInstance				(Context&					context,
1758 																 const bool					isVertexCase,
1759 																 const TextureSpec&			textureSpec);
1760 	virtual						~TextureSizeInstance			(void);
1761 
1762 	virtual tcu::TestStatus		iterate							(void);
1763 
1764 protected:
1765 	virtual void				setupUniforms					(const tcu::Vec4& constCoords);
1766 
1767 private:
1768 	struct TestSize
1769 	{
1770 		tcu::IVec3	textureSize;
1771 		int			lod;
1772 		int			lodBase;
1773 		tcu::IVec3	expectedSize;
1774 	};
1775 
1776 	void						initTexture						(void);
1777 	bool						testTextureSize					(void);
1778 
1779 	TestSize					m_testSize;
1780 	tcu::IVec3					m_expectedSize;
1781 	int							m_iterationCounter;
1782 };
1783 
TextureSizeInstance(Context & context,const bool isVertexCase,const TextureSpec & textureSpec)1784 TextureSizeInstance::TextureSizeInstance (Context&					context,
1785 										  const bool				isVertexCase,
1786 										  const TextureSpec&		textureSpec)
1787 	: TextureQueryInstance		(context, isVertexCase, textureSpec)
1788 	, m_testSize				()
1789 	, m_expectedSize			()
1790 	, m_iterationCounter		(0)
1791 {
1792 	deMemset(&m_testSize, 0, sizeof(TestSize));
1793 
1794 #ifdef CTS_USES_VULKANSC
1795 	const VkDevice			vkDevice			= getDevice();
1796 	const DeviceInterface&	vk					= getDeviceInterface();
1797 	const deUint32			queueFamilyIndex	= getUniversalQueueFamilyIndex();
1798 	m_externalCommandPool						= de::SharedPtr<Unique<VkCommandPool>>(new vk::Unique<VkCommandPool>(createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex)));
1799 #endif // CTS_USES_VULKANSC
1800 
1801 	m_renderSize = tcu::UVec2(1, 1);
1802 }
1803 
~TextureSizeInstance(void)1804 TextureSizeInstance::~TextureSizeInstance (void)
1805 {
1806 }
1807 
setupUniforms(const tcu::Vec4 & constCoords)1808 void TextureSizeInstance::setupUniforms (const tcu::Vec4& constCoords)
1809 {
1810 	TextureQueryInstance::setupUniforms(constCoords);
1811 	addUniform(1u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, sizeof(int), &m_testSize.lod);
1812 }
1813 
initTexture(void)1814 void TextureSizeInstance::initTexture (void)
1815 {
1816 	tcu::TestLog&			log					= m_context.getTestContext().getLog();
1817 	const int				numLevels			= deLog2Floor32(getMaxTextureSize(m_textureSpec.type, m_testSize.textureSize)) + 1;
1818 	TextureBindingSp		textureBinding;
1819 
1820 	log << tcu::TestLog::Message << "Testing image size " << getTextureSizeString(m_textureSpec.type, m_testSize.textureSize) << tcu::TestLog::EndMessage;
1821 	log << tcu::TestLog::Message << "Lod: " << m_testSize.lod << ", base level: " << m_testSize.lodBase << tcu::TestLog::EndMessage;
1822 
1823 	switch (m_textureSpec.type)
1824 	{
1825 		case TEXTURETYPE_3D:
1826 			log << tcu::TestLog::Message << "Expecting: " << m_testSize.expectedSize.x() << "x" << m_testSize.expectedSize.y() << "x" << m_testSize.expectedSize.z() << tcu::TestLog::EndMessage;
1827 			break;
1828 
1829 		case TEXTURETYPE_2D:
1830 			log << tcu::TestLog::Message << "Expecting: " << m_testSize.expectedSize.x() << "x" << m_testSize.expectedSize.y() << tcu::TestLog::EndMessage;
1831 			break;
1832 
1833 		case TEXTURETYPE_CUBE_MAP:
1834 			log << tcu::TestLog::Message << "Expecting: " << m_testSize.expectedSize.x() << "x" << m_testSize.expectedSize.y() << tcu::TestLog::EndMessage;
1835 			break;
1836 
1837 		case TEXTURETYPE_2D_ARRAY:
1838 			log << tcu::TestLog::Message << "Expecting: " << m_testSize.expectedSize.x() << "x" << m_testSize.expectedSize.y() << " and " << m_testSize.textureSize.z() << " layer(s)" << tcu::TestLog::EndMessage;
1839 			break;
1840 
1841 		case TEXTURETYPE_CUBE_ARRAY:
1842 			log << tcu::TestLog::Message << "Expecting: " << m_testSize.expectedSize.x() << "x" << m_testSize.expectedSize.y() << " and " << (m_testSize.textureSize.z() / 6) << " cube(s)" << tcu::TestLog::EndMessage;
1843 			break;
1844 
1845 		case TEXTURETYPE_1D:
1846 			log << tcu::TestLog::Message << "Expecting: " << m_testSize.expectedSize.x() << tcu::TestLog::EndMessage;
1847 			break;
1848 
1849 		case TEXTURETYPE_1D_ARRAY:
1850 			log << tcu::TestLog::Message << "Expecting: " << m_testSize.expectedSize.x() << " and " << m_testSize.textureSize.z() << " layer(s)" << tcu::TestLog::EndMessage;
1851 			break;
1852 
1853 		default:
1854 			DE_ASSERT(false);
1855 			break;
1856 	}
1857 
1858 	textureBinding = createEmptyTexture(m_textureSpec.format, m_textureSpec.type, m_testSize.textureSize, numLevels, m_testSize.lodBase, m_textureSpec.sampler);
1859 
1860 	m_textures.clear();
1861 	m_textures.push_back(textureBinding);
1862 }
1863 
iterate(void)1864 tcu::TestStatus TextureSizeInstance::iterate (void)
1865 {
1866 	const TestSize testSizes[] =
1867 	{
1868 		{ tcu::IVec3(1, 2, 1),			0,		0,	tcu::IVec3(1, 2, 1)			},
1869 		{ tcu::IVec3(1, 2, 1),			1,		0,	tcu::IVec3(1, 1, 1)			},
1870 
1871 		{ tcu::IVec3(1, 3, 2),			0,		0,	tcu::IVec3(1, 3, 2)			},
1872 		{ tcu::IVec3(1, 3, 2),			1,		0,	tcu::IVec3(1, 1, 1)			},
1873 
1874 		{ tcu::IVec3(100, 31, 18),		0,		0,	tcu::IVec3(100, 31, 18)		},
1875 		{ tcu::IVec3(100, 31, 18),		1,		0,	tcu::IVec3(50, 15, 9)		},
1876 		{ tcu::IVec3(100, 31, 18),		2,		0,	tcu::IVec3(25, 7, 4)		},
1877 		{ tcu::IVec3(100, 31, 18),		3,		0,	tcu::IVec3(12, 3, 2)		},
1878 		{ tcu::IVec3(100, 31, 18),		4,		0,	tcu::IVec3(6, 1, 1)			},
1879 		{ tcu::IVec3(100, 31, 18),		5,		0,	tcu::IVec3(3, 1, 1)			},
1880 		{ tcu::IVec3(100, 31, 18),		6,		0,	tcu::IVec3(1, 1, 1)			},
1881 
1882 		{ tcu::IVec3(100, 128, 32),		0,		0,	tcu::IVec3(100, 128, 32)	},
1883 		{ tcu::IVec3(100, 128, 32),		1,		0,	tcu::IVec3(50, 64, 16)		},
1884 		{ tcu::IVec3(100, 128, 32),		2,		0,	tcu::IVec3(25, 32, 8)		},
1885 		{ tcu::IVec3(100, 128, 32),		3,		0,	tcu::IVec3(12, 16, 4)		},
1886 		{ tcu::IVec3(100, 128, 32),		4,		0,	tcu::IVec3(6, 8, 2)			},
1887 		{ tcu::IVec3(100, 128, 32),		5,		0,	tcu::IVec3(3, 4, 1)			},
1888 		{ tcu::IVec3(100, 128, 32),		6,		0,	tcu::IVec3(1, 2, 1)			},
1889 		{ tcu::IVec3(100, 128, 32),		7,		0,	tcu::IVec3(1, 1, 1)			},
1890 
1891 		// pow 2
1892 		{ tcu::IVec3(128, 64, 32),		0,		0,	tcu::IVec3(128, 64, 32)		},
1893 		{ tcu::IVec3(128, 64, 32),		1,		0,	tcu::IVec3(64, 32, 16)		},
1894 		{ tcu::IVec3(128, 64, 32),		2,		0,	tcu::IVec3(32, 16, 8)		},
1895 		{ tcu::IVec3(128, 64, 32),		3,		0,	tcu::IVec3(16, 8, 4)		},
1896 		{ tcu::IVec3(128, 64, 32),		4,		0,	tcu::IVec3(8, 4, 2)			},
1897 		{ tcu::IVec3(128, 64, 32),		5,		0,	tcu::IVec3(4, 2, 1)			},
1898 		{ tcu::IVec3(128, 64, 32),		6,		0,	tcu::IVec3(2, 1, 1)			},
1899 		{ tcu::IVec3(128, 64, 32),		7,		0,	tcu::IVec3(1, 1, 1)			},
1900 
1901 		// w == h
1902 		{ tcu::IVec3(1, 1, 1),			0,		0,	tcu::IVec3(1, 1, 1)			},
1903 		{ tcu::IVec3(64, 64, 64),		0,		0,	tcu::IVec3(64, 64, 64)		},
1904 		{ tcu::IVec3(64, 64, 64),		1,		0,	tcu::IVec3(32, 32, 32)		},
1905 		{ tcu::IVec3(64, 64, 64),		2,		0,	tcu::IVec3(16, 16, 16)		},
1906 		{ tcu::IVec3(64, 64, 64),		3,		0,	tcu::IVec3(8, 8, 8)			},
1907 		{ tcu::IVec3(64, 64, 64),		4,		0,	tcu::IVec3(4, 4, 4)			},
1908 
1909 		// with lod base
1910 		{ tcu::IVec3(100, 31, 18),		3,		1,	tcu::IVec3(6, 1, 1)			},
1911 		{ tcu::IVec3(128, 64, 32),		3,		1,	tcu::IVec3(8, 4, 2)			},
1912 		{ tcu::IVec3(64, 64, 64),		1,		1,	tcu::IVec3(16, 16, 16)		},
1913 
1914 		{ tcu::IVec3(100, 31, 18),		1,		2,	tcu::IVec3(12, 3, 2)		},
1915 		{ tcu::IVec3(100, 31, 18),		2,		2,	tcu::IVec3(6, 1, 1)			},
1916 		{ tcu::IVec3(100, 31, 18),		1,		4,	tcu::IVec3(3, 1, 1)			},
1917 
1918 		// out-of-range mip levels
1919 		{ tcu::IVec3(1, 3, 2),			-7,		0,	tcu::IVec3(0, 0, 0)			},
1920 		{ tcu::IVec3(1, 3, 2),			106,	0,	tcu::IVec3(0, 0, 0)			},
1921 		{ tcu::IVec3(100, 31, 18),		7,		0,	tcu::IVec3(0, 0, 0)			},
1922 		{ tcu::IVec3(32, 32, 12),		6,		0,	tcu::IVec3(0, 0, 0)			},
1923 		{ tcu::IVec3(32, 32, 12),		-9,		0,	tcu::IVec3(0, 0, 0)			},
1924 		{ tcu::IVec3(32, 32, 12),		4396,	0,	tcu::IVec3(0, 0, 0)			},
1925 
1926 		// w == h and d % 6 == 0 (for cube array)
1927 		{ tcu::IVec3(1, 1, 6),			0,		0,	tcu::IVec3(1, 1, 6)			},
1928 		{ tcu::IVec3(32, 32, 12),		0,		0,	tcu::IVec3(32, 32, 12)		},
1929 		{ tcu::IVec3(32, 32, 12),		0,		1,	tcu::IVec3(16, 16, 6)		},
1930 		{ tcu::IVec3(32, 32, 12),		1,		0,	tcu::IVec3(16, 16, 6)		},
1931 		{ tcu::IVec3(32, 32, 12),		2,		0,	tcu::IVec3(8, 8, 3)			},
1932 		{ tcu::IVec3(32, 32, 12),		3,		0,	tcu::IVec3(4, 4, 1)			},
1933 		{ tcu::IVec3(32, 32, 12),		4,		0,	tcu::IVec3(2, 2, 1)			},
1934 		{ tcu::IVec3(32, 32, 12),		5,		0,	tcu::IVec3(1, 1, 1)			},
1935 	};
1936 	const int lastIterationIndex = DE_LENGTH_OF_ARRAY(testSizes) + 1;
1937 
1938 	m_iterationCounter++;
1939 
1940 	if (m_iterationCounter == lastIterationIndex)
1941 		return tcu::TestStatus::pass("Pass");
1942 	else
1943 	{
1944 		// set current test size
1945 		m_testSize = testSizes[m_iterationCounter - 1];
1946 
1947 		bool result = testTextureSize();
1948 #ifdef CTS_USES_VULKANSC
1949 		if (m_context.getTestContext().getCommandLine().isSubProcess())
1950 #endif // CTS_USES_VULKANSC
1951 		{
1952 			if (!result)
1953 				return tcu::TestStatus::fail("Got unexpected result");
1954 		}
1955 		return tcu::TestStatus::incomplete();
1956 	}
1957 }
1958 
testTextureSize(void)1959 bool TextureSizeInstance::testTextureSize (void)
1960 {
1961 	tcu::TestLog&			log				= m_context.getTestContext().getLog();
1962 	bool					success			= true;
1963 
1964 	// skip incompatible cases
1965 	if (!isValidCase(m_textureSpec.type, m_testSize.textureSize, m_testSize.lodBase))
1966 		return true;
1967 
1968 	// setup texture
1969 	initTexture();
1970 
1971 	// determine expected texture size
1972 	switch (m_textureSpec.type)
1973 	{
1974 		case TEXTURETYPE_1D:
1975 		case TEXTURETYPE_2D:
1976 		case TEXTURETYPE_3D:
1977 		case TEXTURETYPE_CUBE_MAP:
1978 			m_expectedSize = m_testSize.expectedSize;
1979 			break;
1980 
1981 		case TEXTURETYPE_1D_ARRAY:
1982 			m_expectedSize = tcu::IVec3(m_testSize.expectedSize.x(), m_testSize.textureSize.z(), 0);
1983 			break;
1984 
1985 		case TEXTURETYPE_2D_ARRAY:
1986 			m_expectedSize = tcu::IVec3(m_testSize.expectedSize.x(), m_testSize.expectedSize.y(), m_testSize.textureSize.z());
1987 			break;
1988 
1989 		case TEXTURETYPE_CUBE_ARRAY:
1990 			m_expectedSize = tcu::IVec3(m_testSize.expectedSize.x(), m_testSize.expectedSize.y(), m_testSize.textureSize.z() / 6);
1991 			break;
1992 
1993 		default:
1994 			DE_ASSERT(false);
1995 			break;
1996 	}
1997 
1998 	// render
1999 	TextureQueryInstance::render();
2000 
2001 	// test
2002 	{
2003 		const tcu::TextureLevel&	result				= getResultImage();
2004 		tcu::IVec4					output				= result.getAccess().getPixelInt(0, 0);
2005 		const int					resultComponents	= glu::getDataTypeScalarSize(getTextureSizeFuncResultType(m_textureSpec.type));
2006 
2007 		for (int ndx = 0; ndx < resultComponents; ndx++)
2008 		{
2009 			// We test all levels, but only compare results for valid LoDs. The others give
2010 			// undefined values.
2011 			const int	maxSize		= getMaxTextureSize(m_textureSpec.type, m_testSize.textureSize);
2012 			const bool	isLodValid	= (maxSize >> (m_testSize.lod + m_testSize.lodBase)) != 0;
2013 			if (isLodValid && output[ndx] != m_expectedSize[ndx])
2014 			{
2015 				success = false;
2016 				break;
2017 			}
2018 		}
2019 
2020 		if (success)
2021 		{
2022 			// success
2023 			log << tcu::TestLog::Message << "Passed" << tcu::TestLog::EndMessage;
2024 		}
2025 		else
2026 		{
2027 			// failure
2028 			std::stringstream	resultSizeStr;
2029 			switch (resultComponents)
2030 			{
2031 				case 1:
2032 					resultSizeStr << output[0];
2033 					break;
2034 				case 2:
2035 					resultSizeStr << output.toWidth<2>();
2036 					break;
2037 				case 3:
2038 					resultSizeStr << output.toWidth<3>();
2039 					break;
2040 				default:
2041 					DE_ASSERT(false);
2042 					break;
2043 			}
2044 			log << tcu::TestLog::Message << "Result: " << resultSizeStr.str() << tcu::TestLog::EndMessage;
2045 			log << tcu::TestLog::Message << "Failed" << tcu::TestLog::EndMessage;
2046 		}
2047 	}
2048 
2049 	log << tcu::TestLog::Message << tcu::TestLog::EndMessage;
2050 
2051 	return success;
2052 }
2053 
getVkImageType(TextureType type)2054 static vk::VkImageType getVkImageType (TextureType type)
2055 {
2056 	switch (type)
2057 	{
2058 		case TEXTURETYPE_1D:
2059 		case TEXTURETYPE_1D_ARRAY:
2060 			return vk::VK_IMAGE_TYPE_1D;
2061 
2062 		case TEXTURETYPE_2D:
2063 		case TEXTURETYPE_2D_ARRAY:
2064 		case TEXTURETYPE_CUBE_MAP:
2065 		case TEXTURETYPE_CUBE_ARRAY:
2066 			return vk::VK_IMAGE_TYPE_2D;
2067 
2068 		case TEXTURETYPE_3D:
2069 			return vk::VK_IMAGE_TYPE_3D;
2070 
2071 		default:
2072 			DE_ASSERT(false);
2073 			return (vk::VkImageType)0;
2074 	}
2075 }
2076 
2077 class TextureSizeMSInstance : public TextureQueryInstance
2078 {
2079 public:
2080 								TextureSizeMSInstance			(Context&					context,
2081 																 const bool					isVertexCase,
2082 																 const TextureSpec&			textureSpec);
2083 	virtual						~TextureSizeMSInstance			(void);
2084 
2085 	virtual tcu::TestStatus		iterate							(void);
2086 
2087 private:
2088 	void						initTexture						(vk::VkSampleCountFlagBits samples, const tcu::IVec3 &dim);
2089 	bool						testSize						(vk::VkSampleCountFlagBits samples, const tcu::IVec3 &dim);
2090 
2091 	unsigned								m_iterationCounter;
2092 	vector<vk::VkSampleCountFlagBits>		m_iterations;
2093 };
2094 
TextureSizeMSInstance(Context & context,const bool isVertexCase,const TextureSpec & textureSpec)2095 TextureSizeMSInstance::TextureSizeMSInstance	(Context&				context,
2096 												const bool				isVertexCase,
2097 												const TextureSpec&		textureSpec)
2098 	: TextureQueryInstance		(context, isVertexCase, textureSpec)
2099 	, m_iterationCounter		(0)
2100 {
2101 	m_renderSize = tcu::UVec2(1, 1);
2102 
2103 	// determine available sample counts
2104 	{
2105 		const vk::VkFormat						format			= vk::mapTextureFormat(glu::mapGLInternalFormat(m_textureSpec.format));
2106 		const vk::VkImageType					imageType		= getVkImageType(m_textureSpec.type);
2107 		vk::VkImageFormatProperties				properties;
2108 
2109 		if (m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(m_context.getPhysicalDevice(),
2110 																					format,
2111 																					imageType,
2112 																					vk::VK_IMAGE_TILING_OPTIMAL,
2113 																					vk::VK_IMAGE_USAGE_SAMPLED_BIT | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT,
2114 																					(vk::VkImageCreateFlags)0,
2115 																					&properties) == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
2116 			TCU_THROW(NotSupportedError, "Format not supported");
2117 
2118 		// NOTE: The test case initializes MS images (for all supported N of samples), runs a program
2119 		//       which invokes OpImageQuerySize against the image and checks the result.
2120 		//
2121 		//       Multisample images do not support a sample count of 1, so start from 2 samples.
2122 		static const vk::VkSampleCountFlagBits	sampleFlags[]	=
2123 		{
2124 			vk::VK_SAMPLE_COUNT_2_BIT,
2125 			vk::VK_SAMPLE_COUNT_4_BIT,
2126 			vk::VK_SAMPLE_COUNT_8_BIT,
2127 			vk::VK_SAMPLE_COUNT_16_BIT,
2128 			vk::VK_SAMPLE_COUNT_32_BIT,
2129 			vk::VK_SAMPLE_COUNT_64_BIT
2130 		};
2131 
2132 		for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(sampleFlags); samplesNdx++)
2133 		{
2134 			const vk::VkSampleCountFlagBits&	flag			= sampleFlags[samplesNdx];
2135 
2136 			if ((properties.sampleCounts & flag) != 0)
2137 				m_iterations.push_back(flag);
2138 		}
2139 
2140 		if (m_iterations.empty())
2141 		{
2142 			// Sampled images of integer formats may support only 1 sample. Exit the test with "Not supported" in these cases.
2143 			if (tcu::getTextureChannelClass(mapVkFormat(format).type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ||
2144 				tcu::getTextureChannelClass(mapVkFormat(format).type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
2145 			{
2146 				TCU_THROW(NotSupportedError, "Skipping validation of integer formats as only VK_SAMPLE_COUNT_1_BIT is supported.");
2147 			}
2148 
2149 			DE_ASSERT(false);
2150 		}
2151 	}
2152 }
2153 
~TextureSizeMSInstance(void)2154 TextureSizeMSInstance::~TextureSizeMSInstance (void)
2155 {
2156 }
2157 
iterate(void)2158 tcu::TestStatus TextureSizeMSInstance::iterate (void)
2159 {
2160 	const tcu::IVec3 testSizes[] =
2161 	{
2162 		tcu::IVec3(1, 1, 1),
2163 		tcu::IVec3(1, 2, 1),
2164 		tcu::IVec3(1, 3, 2),
2165 		tcu::IVec3(1, 1, 6),
2166 		tcu::IVec3(32, 32, 12),
2167 		tcu::IVec3(64, 64, 64),
2168 		tcu::IVec3(100, 31, 18),
2169 		tcu::IVec3(100, 128, 32),
2170 		tcu::IVec3(128, 64, 32),
2171 	};
2172 
2173 	unsigned sampleIdx	= m_iterationCounter / DE_LENGTH_OF_ARRAY(testSizes);
2174 	unsigned dimIdx		= m_iterationCounter % DE_LENGTH_OF_ARRAY(testSizes);
2175 
2176 	if (m_iterationCounter++ <  m_iterations.size() * DE_LENGTH_OF_ARRAY(testSizes))
2177 	{
2178 		bool result = testSize(m_iterations[sampleIdx], testSizes[dimIdx]);
2179 #ifdef CTS_USES_VULKANSC
2180 		if (m_context.getTestContext().getCommandLine().isSubProcess())
2181 #endif // CTS_USES_VULKANSC
2182 		{
2183 			if (!result)
2184 				return tcu::TestStatus::fail("Got unexpected result");
2185 		}
2186 		return tcu::TestStatus::incomplete();
2187 	}
2188 	else
2189 		return tcu::TestStatus::pass("Pass");
2190 }
2191 
testSize(vk::VkSampleCountFlagBits samples,const tcu::IVec3 & dim)2192 bool TextureSizeMSInstance::testSize (vk::VkSampleCountFlagBits samples, const tcu::IVec3 &dim)
2193 {
2194 	tcu::TestLog&		log		= m_context.getTestContext().getLog();
2195 
2196 	// setup texture
2197 	initTexture(samples, dim);
2198 
2199 	// render
2200 	TextureQueryInstance::render();
2201 
2202 	// test
2203 	{
2204 		const tcu::TextureLevel&	result				= getResultImage();
2205 		tcu::IVec4					output				= result.getAccess().getPixelInt(0, 0);
2206 		const int					resultComponents	= glu::getDataTypeScalarSize(getTextureSizeFuncResultType(m_textureSpec.type));
2207 
2208 		bool success = true;
2209 
2210 		for (int ndx = 0; ndx < resultComponents; ndx++)
2211 		{
2212 			if (output[ndx] != dim[ndx])
2213 			{
2214 				success = false;
2215 				break;
2216 			}
2217 		}
2218 
2219 		if (success)
2220 		{
2221 			// success
2222 			log << tcu::TestLog::Message << "Passed" << tcu::TestLog::EndMessage;
2223 			return true;
2224 		}
2225 		else
2226 		{
2227 			// failure
2228 			std::stringstream	resultSizeStr;
2229 			switch (resultComponents)
2230 			{
2231 				case 1:
2232 					resultSizeStr << output[0];
2233 					break;
2234 				case 2:
2235 					resultSizeStr << output.toWidth<2>();
2236 					break;
2237 				case 3:
2238 					resultSizeStr << output.toWidth<3>();
2239 					break;
2240 				default:
2241 					DE_ASSERT(false);
2242 					break;
2243 			}
2244 			log << tcu::TestLog::Message << "Result: " << resultSizeStr.str() << tcu::TestLog::EndMessage;
2245 			log << tcu::TestLog::Message << "Failed" << tcu::TestLog::EndMessage;
2246 			return false;
2247 		}
2248 	}
2249 }
2250 
initTexture(vk::VkSampleCountFlagBits samples,const tcu::IVec3 & dim)2251 void TextureSizeMSInstance::initTexture (vk::VkSampleCountFlagBits samples, const tcu::IVec3 &dim)
2252 {
2253 	tcu::TestLog&			log					= m_context.getTestContext().getLog();
2254 	TextureBindingSp		textureBinding;
2255 
2256 	DE_ASSERT(m_textureSpec.type == TEXTURETYPE_2D || m_textureSpec.type == TEXTURETYPE_2D_ARRAY);
2257 
2258 	log << tcu::TestLog::Message << "Image size: " << getTextureSizeString(m_textureSpec.type, dim) << ", samples: " << samples << tcu::TestLog::EndMessage;
2259 
2260 	textureBinding = createEmptyTexture(m_textureSpec.format, m_textureSpec.type, dim, m_textureSpec.numLevels, 0 /* lodBase */, m_textureSpec.sampler);
2261 
2262 	m_textures.clear();
2263 	m_textures.push_back(textureBinding);
2264 
2265 	// update samples count
2266 	{
2267 		DE_ASSERT(m_textures.size() == 1);
2268 
2269 		TextureBinding::Parameters	params	= m_textures[0]->getParameters();
2270 
2271 		params.initialization	= TextureBinding::INIT_CLEAR;
2272 		params.samples			= samples;
2273 
2274 		m_textures[0]->setParameters(params);
2275 	}
2276 }
2277 
2278 class TextureSamplesInstance : public TextureQueryInstance
2279 {
2280 public:
2281 								TextureSamplesInstance			(Context&					context,
2282 																 const bool					isVertexCase,
2283 																 const TextureSpec&			textureSpec);
2284 	virtual						~TextureSamplesInstance			(void);
2285 
2286 	virtual tcu::TestStatus		iterate							(void);
2287 
2288 private:
2289 	void						initTexture						(void);
2290 
2291 	int										m_iterationCounter;
2292 	vector<vk::VkSampleCountFlagBits>		m_iterations;
2293 };
2294 
TextureSamplesInstance(Context & context,const bool isVertexCase,const TextureSpec & textureSpec)2295 TextureSamplesInstance::TextureSamplesInstance (Context&				context,
2296 												const bool				isVertexCase,
2297 												const TextureSpec&		textureSpec)
2298 	: TextureQueryInstance		(context, isVertexCase, textureSpec)
2299 	, m_iterationCounter		(0)
2300 {
2301 	m_renderSize = tcu::UVec2(1, 1);
2302 
2303 	// determine available sample counts
2304 	{
2305 		const vk::VkFormat						format			= vk::mapTextureFormat(glu::mapGLInternalFormat(m_textureSpec.format));
2306 		const vk::VkImageType					imageType		= getVkImageType(m_textureSpec.type);
2307 		vk::VkImageFormatProperties				properties;
2308 
2309 		if (m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(m_context.getPhysicalDevice(),
2310 																					format,
2311 																					imageType,
2312 																					vk::VK_IMAGE_TILING_OPTIMAL,
2313 																					vk::VK_IMAGE_USAGE_SAMPLED_BIT | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT,
2314 																					(vk::VkImageCreateFlags)0,
2315 																					&properties) == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
2316 			TCU_THROW(NotSupportedError, "Format not supported");
2317 
2318 		// NOTE: The test case initializes MS images (for all supported N of samples), runs a program
2319 		//       which invokes OpImageQuerySamples against the image and checks the result.
2320 		//
2321 		//       Now, in the SPIR-V spec for the very operation we have the following language:
2322 		//
2323 		//       OpImageQuerySamples
2324 		//       Query the number of samples available per texel fetch in a multisample image.
2325 		//       Result Type must be a scalar integer type.
2326 		//       The result is the number of samples.
2327 		//       Image must be an object whose type is OpTypeImage.
2328 		//       Its Dim operand must be one of 2D and **MS of 1(multisampled).
2329 		//
2330 		//       "MS of 1" implies the image must not be single-sample, meaning we must exclude
2331 		//       VK_SAMPLE_COUNT_1_BIT in the sampleFlags array below, and may have to skip further testing.
2332 		static const vk::VkSampleCountFlagBits	sampleFlags[]	=
2333 		{
2334 			vk::VK_SAMPLE_COUNT_2_BIT,
2335 			vk::VK_SAMPLE_COUNT_4_BIT,
2336 			vk::VK_SAMPLE_COUNT_8_BIT,
2337 			vk::VK_SAMPLE_COUNT_16_BIT,
2338 			vk::VK_SAMPLE_COUNT_32_BIT,
2339 			vk::VK_SAMPLE_COUNT_64_BIT
2340 		};
2341 
2342 		for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(sampleFlags); samplesNdx++)
2343 		{
2344 			const vk::VkSampleCountFlagBits&	flag			= sampleFlags[samplesNdx];
2345 
2346 			if ((properties.sampleCounts & flag) != 0)
2347 				m_iterations.push_back(flag);
2348 		}
2349 
2350 		if (m_iterations.empty())
2351 		{
2352 			// Sampled images of integer formats may support only 1 sample. Exit the test with "Not supported" in these cases.
2353 			if (tcu::getTextureChannelClass(mapVkFormat(format).type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ||
2354 				tcu::getTextureChannelClass(mapVkFormat(format).type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
2355 			{
2356 				TCU_THROW(NotSupportedError, "Skipping validation of integer formats as only VK_SAMPLE_COUNT_1_BIT is supported.");
2357 			}
2358 
2359 			DE_ASSERT(false);
2360 		}
2361 	}
2362 
2363 	// setup texture
2364 	initTexture();
2365 }
2366 
~TextureSamplesInstance(void)2367 TextureSamplesInstance::~TextureSamplesInstance (void)
2368 {
2369 }
2370 
iterate(void)2371 tcu::TestStatus TextureSamplesInstance::iterate (void)
2372 {
2373 	tcu::TestLog&		log		= m_context.getTestContext().getLog();
2374 
2375 	// update samples count
2376 	{
2377 		DE_ASSERT(m_textures.size() == 1);
2378 
2379 		TextureBinding::Parameters	params	= m_textures[0]->getParameters();
2380 
2381 		params.initialization	= TextureBinding::INIT_CLEAR;
2382 		params.samples			= m_iterations[m_iterationCounter];
2383 		log << tcu::TestLog::Message << "Expected samples: " << m_iterations[m_iterationCounter] << tcu::TestLog::EndMessage;
2384 
2385 		m_textures[0]->setParameters(params);
2386 	}
2387 
2388 	// render
2389 	TextureQueryInstance::render();
2390 
2391 	// test
2392 	{
2393 		const tcu::TextureLevel&	result				= getResultImage();
2394 		tcu::IVec4					output				= result.getAccess().getPixelInt(0, 0);
2395 
2396 #ifdef CTS_USES_VULKANSC
2397 		if (m_context.getTestContext().getCommandLine().isSubProcess())
2398 #endif // CTS_USES_VULKANSC
2399 		{
2400 			if (output.x() == (int)m_iterations[m_iterationCounter])
2401 			{
2402 				// success
2403 				log << tcu::TestLog::Message << "Passed" << tcu::TestLog::EndMessage;
2404 			}
2405 			else
2406 			{
2407 				// failure
2408 				log << tcu::TestLog::Message << "Result: " << output.x() << tcu::TestLog::EndMessage;
2409 				log << tcu::TestLog::Message << "Failed" << tcu::TestLog::EndMessage;
2410 				return tcu::TestStatus::fail("Got unexpected result");
2411 			}
2412 		}
2413 
2414 		m_iterationCounter++;
2415 		if (m_iterationCounter == (int)m_iterations.size())
2416 			return tcu::TestStatus::pass("Pass");
2417 		else
2418 			return tcu::TestStatus::incomplete();
2419 	}
2420 }
2421 
initTexture(void)2422 void TextureSamplesInstance::initTexture (void)
2423 {
2424 	tcu::TestLog&			log					= m_context.getTestContext().getLog();
2425 	tcu::IVec3				textureSize			(m_textureSpec.width, m_textureSpec.height, m_textureSpec.depth);
2426 	TextureBindingSp		textureBinding;
2427 
2428 	DE_ASSERT(m_textures.empty());
2429 	DE_ASSERT(m_textureSpec.type == TEXTURETYPE_2D || m_textureSpec.type == TEXTURETYPE_2D_ARRAY);
2430 
2431 	log << tcu::TestLog::Message << "Image size: " << getTextureSizeString(m_textureSpec.type, textureSize) << tcu::TestLog::EndMessage;
2432 
2433 	textureBinding = createEmptyTexture(m_textureSpec.format, m_textureSpec.type, textureSize, m_textureSpec.numLevels, 0 /* lodBase */, m_textureSpec.sampler);
2434 
2435 	m_textures.push_back(textureBinding);
2436 }
2437 
2438 class TextureQueryLevelsInstance : public TextureQueryInstance
2439 {
2440 public:
2441 								TextureQueryLevelsInstance		(Context&					context,
2442 																 const bool					isVertexCase,
2443 																 const TextureSpec&			textureSpec);
2444 	virtual						~TextureQueryLevelsInstance		(void);
2445 
2446 	virtual tcu::TestStatus		iterate							(void);
2447 
2448 private:
2449 	struct TestSize
2450 	{
2451 		tcu::IVec3	textureSize;
2452 		int			lodBase;
2453 	};
2454 
2455 	void						initTexture						(void);
2456 	bool						testTextureLevels				(void);
2457 
2458 	TestSize					m_testSize;
2459 	int							m_levels;
2460 	int							m_iterationCounter;
2461 };
2462 
TextureQueryLevelsInstance(Context & context,const bool isVertexCase,const TextureSpec & textureSpec)2463 TextureQueryLevelsInstance::TextureQueryLevelsInstance (Context&				context,
2464 														const bool				isVertexCase,
2465 														const TextureSpec&		textureSpec)
2466 	: TextureQueryInstance		(context, isVertexCase, textureSpec)
2467 	, m_testSize				()
2468 	, m_levels					(0)
2469 	, m_iterationCounter		(0)
2470 {
2471 	deMemset(&m_testSize, 0, sizeof(TestSize));
2472 
2473 	m_renderSize								= tcu::UVec2(1, 1);
2474 
2475 #ifdef CTS_USES_VULKANSC
2476 	const VkDevice			vkDevice			= getDevice();
2477 	const DeviceInterface&	vk					= getDeviceInterface();
2478 	const deUint32			queueFamilyIndex	= getUniversalQueueFamilyIndex();
2479 	m_externalCommandPool						= de::SharedPtr<Unique<VkCommandPool>>(new vk::Unique<VkCommandPool>(createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex)));
2480 #endif // CTS_USES_VULKANSC
2481 }
2482 
~TextureQueryLevelsInstance(void)2483 TextureQueryLevelsInstance::~TextureQueryLevelsInstance (void)
2484 {
2485 }
2486 
iterate(void)2487 tcu::TestStatus TextureQueryLevelsInstance::iterate (void)
2488 {
2489 	const TestSize testSizes[] =
2490 	{
2491 		{ tcu::IVec3(1, 2, 1),			0	},
2492 		{ tcu::IVec3(1, 2, 1),			1	},
2493 
2494 		{ tcu::IVec3(1, 3, 2),			0	},
2495 		{ tcu::IVec3(1, 3, 2),			1	},
2496 
2497 		{ tcu::IVec3(100, 31, 18),		0	},
2498 		{ tcu::IVec3(100, 31, 18),		1	},
2499 		{ tcu::IVec3(100, 31, 18),		2	},
2500 		{ tcu::IVec3(100, 31, 18),		3	},
2501 		{ tcu::IVec3(100, 31, 18),		4	},
2502 		{ tcu::IVec3(100, 31, 18),		5	},
2503 		{ tcu::IVec3(100, 31, 18),		6	},
2504 
2505 		{ tcu::IVec3(100, 128, 32),		0	},
2506 		{ tcu::IVec3(100, 128, 32),		1	},
2507 		{ tcu::IVec3(100, 128, 32),		2	},
2508 		{ tcu::IVec3(100, 128, 32),		3	},
2509 		{ tcu::IVec3(100, 128, 32),		4	},
2510 		{ tcu::IVec3(100, 128, 32),		5	},
2511 		{ tcu::IVec3(100, 128, 32),		6	},
2512 		{ tcu::IVec3(100, 128, 32),		7	},
2513 
2514 		// pow 2
2515 		{ tcu::IVec3(128, 64, 32),		0	},
2516 		{ tcu::IVec3(128, 64, 32),		1	},
2517 		{ tcu::IVec3(128, 64, 32),		2	},
2518 		{ tcu::IVec3(128, 64, 32),		3	},
2519 		{ tcu::IVec3(128, 64, 32),		4	},
2520 		{ tcu::IVec3(128, 64, 32),		5	},
2521 		{ tcu::IVec3(128, 64, 32),		6	},
2522 		{ tcu::IVec3(128, 64, 32),		7	},
2523 
2524 		// w == h
2525 		{ tcu::IVec3(1, 1, 1),			0	},
2526 		{ tcu::IVec3(64, 64, 64),		0	},
2527 		{ tcu::IVec3(64, 64, 64),		1	},
2528 		{ tcu::IVec3(64, 64, 64),		2	},
2529 		{ tcu::IVec3(64, 64, 64),		3	},
2530 		{ tcu::IVec3(64, 64, 64),		4	},
2531 		{ tcu::IVec3(64, 64, 64),		5	},
2532 		{ tcu::IVec3(64, 64, 64),		6	},
2533 
2534 		// w == h and d % 6 == 0 (for cube array)
2535 		{ tcu::IVec3(1, 1, 6),			0	},
2536 		{ tcu::IVec3(32, 32, 12),		0	},
2537 		{ tcu::IVec3(32, 32, 12),		1	},
2538 		{ tcu::IVec3(32, 32, 12),		2	},
2539 		{ tcu::IVec3(32, 32, 12),		3	},
2540 		{ tcu::IVec3(32, 32, 12),		4	},
2541 		{ tcu::IVec3(32, 32, 12),		5	},
2542 	};
2543 	const int lastIterationIndex = DE_LENGTH_OF_ARRAY(testSizes) + 1;
2544 
2545 	m_iterationCounter++;
2546 
2547 	if (m_iterationCounter == lastIterationIndex)
2548 		return tcu::TestStatus::pass("Pass");
2549 	else
2550 	{
2551 		// set current test size
2552 		m_testSize = testSizes[m_iterationCounter - 1];
2553 
2554 		bool result = testTextureLevels();
2555 #ifdef CTS_USES_VULKANSC
2556 		if (m_context.getTestContext().getCommandLine().isSubProcess())
2557 #endif // CTS_USES_VULKANSC
2558 		{
2559 			if (!result)
2560 				return tcu::TestStatus::fail("Got unexpected result");
2561 		}
2562 		return tcu::TestStatus::incomplete();
2563 	}
2564 }
2565 
testTextureLevels(void)2566 bool TextureQueryLevelsInstance::testTextureLevels (void)
2567 {
2568 	tcu::TestLog&			log				= m_context.getTestContext().getLog();
2569 	bool					success			= true;
2570 
2571 	// skip incompatible cases
2572 	if (!isValidCase(m_textureSpec.type, m_testSize.textureSize, m_testSize.lodBase))
2573 		return true;
2574 
2575 	// setup texture
2576 	initTexture();
2577 
2578 	// calculate accessible levels
2579 	{
2580 		const int	mipLevels	= deLog2Floor32(getMaxTextureSize(m_textureSpec.type, m_testSize.textureSize)) + 1;
2581 
2582 		m_levels = mipLevels - m_testSize.lodBase;
2583 		DE_ASSERT(m_levels > 0);
2584 
2585 		log << tcu::TestLog::Message << "Expected levels: " << m_levels << tcu::TestLog::EndMessage;
2586 	}
2587 
2588 	// render
2589 	TextureQueryInstance::render();
2590 
2591 	// test
2592 	{
2593 		const tcu::TextureLevel&	result				= getResultImage();
2594 		tcu::IVec4					output				= result.getAccess().getPixelInt(0, 0);
2595 
2596 		if (output.x() == m_levels)
2597 		{
2598 			// success
2599 			log << tcu::TestLog::Message << "Passed" << tcu::TestLog::EndMessage;
2600 		}
2601 		else
2602 		{
2603 			// failure
2604 			log << tcu::TestLog::Message << "Result: " << output.x() << tcu::TestLog::EndMessage;
2605 			log << tcu::TestLog::Message << "Failed" << tcu::TestLog::EndMessage;
2606 			success = false;
2607 		}
2608 	}
2609 
2610 	log << tcu::TestLog::Message << tcu::TestLog::EndMessage;
2611 
2612 	return success;
2613 }
2614 
initTexture(void)2615 void TextureQueryLevelsInstance::initTexture (void)
2616 {
2617 	tcu::TestLog&			log					= m_context.getTestContext().getLog();
2618 	int						numLevels			= m_testSize.lodBase + 1;
2619 	TextureBindingSp		textureBinding;
2620 
2621 	log << tcu::TestLog::Message << "Image size: " << getTextureSizeString(m_textureSpec.type, m_testSize.textureSize) << tcu::TestLog::EndMessage;
2622 	log << tcu::TestLog::Message << "Base level: " << m_testSize.lodBase << tcu::TestLog::EndMessage;
2623 
2624 	textureBinding = createEmptyTexture(m_textureSpec.format, m_textureSpec.type, m_testSize.textureSize, numLevels, m_testSize.lodBase, m_textureSpec.sampler);
2625 
2626 	m_textures.clear();
2627 	m_textures.push_back(textureBinding);
2628 }
2629 
getQueryLodFuncTextCoordComps(TextureType type)2630 static int getQueryLodFuncTextCoordComps (TextureType type)
2631 {
2632 	switch (type)
2633 	{
2634 		case TEXTURETYPE_1D:
2635 		case TEXTURETYPE_1D_ARRAY:
2636 			return 1;
2637 
2638 		case TEXTURETYPE_2D:
2639 		case TEXTURETYPE_2D_ARRAY:
2640 			return 2;
2641 
2642 		case TEXTURETYPE_3D:
2643 		case TEXTURETYPE_CUBE_MAP:
2644 		case TEXTURETYPE_CUBE_ARRAY:
2645 			return 3;
2646 
2647 		default:
2648 			DE_ASSERT(false);
2649 			return 0;
2650 	}
2651 }
2652 
2653 class TextureQueryLodInstance : public TextureQueryInstance
2654 {
2655 public:
2656 								TextureQueryLodInstance			(Context&					context,
2657 																 const bool					isVertexCase,
2658 																 const TextureSpec&			textureSpec,
2659 																 const TestMode				mode);
2660 	virtual						~TextureQueryLodInstance		(void);
2661 
2662 	virtual tcu::TestStatus		iterate							(void);
2663 
2664 protected:
2665 	virtual void				setupDefaultInputs				(void);
2666 
2667 private:
2668 	void						initTexture						(void);
2669 	float						computeLevelFromLod				(float computedLod) const;
2670 	vector<float>				computeQuadTexCoord				(void) const;
2671 
2672 	const TestMode				m_mode;
2673 	tcu::Vec4					m_minCoord;
2674 	tcu::Vec4					m_maxCoord;
2675 	tcu::Vec2					m_lodBounds;
2676 	tcu::Vec2					m_levelBounds;
2677 };
2678 
TextureQueryLodInstance(Context & context,const bool isVertexCase,const TextureSpec & textureSpec,const TestMode mode)2679 TextureQueryLodInstance::TextureQueryLodInstance (Context&					context,
2680 												  const bool				isVertexCase,
2681 												  const TextureSpec&		textureSpec,
2682 												  const TestMode			mode)
2683 	: TextureQueryInstance		(context, isVertexCase, textureSpec)
2684 	, m_mode					(mode)
2685 	, m_minCoord				()
2686 	, m_maxCoord				()
2687 	, m_lodBounds				()
2688 	, m_levelBounds				()
2689 {
2690 	// setup texture
2691 	initTexture();
2692 
2693 	if (m_mode == QLODTM_DEFAULT)
2694 	{
2695 		const tcu::UVec2&	viewportSize	= getViewportSize();
2696 		const float			lodEps			= (1.0f / float(1u << m_context.getDeviceProperties().limits.mipmapPrecisionBits)) + 0.008f;
2697 
2698 		// init min/max coords and calculate lod and accessed level
2699 		switch (m_textureSpec.type)
2700 		{
2701 			case TEXTURETYPE_1D:
2702 			case TEXTURETYPE_1D_ARRAY:
2703 			{
2704 				m_minCoord = Vec4(-0.2f, 0.0f, 0.0f, 0.0f);
2705 				m_maxCoord = Vec4( 1.5f, 0.0f, 0.0f, 0.0f);
2706 
2707 				const float	dudx	= (m_maxCoord[0]-m_minCoord[0])*(float)m_textureSpec.width	/ (float)viewportSize[0];
2708 
2709 				m_lodBounds[0]		= computeLodFromDerivates(LODMODE_MIN_BOUND, dudx, 0.0f)-lodEps;
2710 				m_lodBounds[1]		= computeLodFromDerivates(LODMODE_MAX_BOUND, dudx, 0.0f)+lodEps;
2711 				break;
2712 			}
2713 
2714 			case TEXTURETYPE_2D:
2715 			case TEXTURETYPE_2D_ARRAY:
2716 			{
2717 				m_minCoord = Vec4(-0.2f, -0.4f, 0.0f, 0.0f);
2718 				m_maxCoord = Vec4( 1.5f,  2.3f, 0.0f, 0.0f);
2719 
2720 				const float	dudx	= (m_maxCoord[0]-m_minCoord[0])*(float)m_textureSpec.width	/ (float)viewportSize[0];
2721 				const float	dvdy	= (m_maxCoord[1]-m_minCoord[1])*(float)m_textureSpec.height	/ (float)viewportSize[1];
2722 
2723 				m_lodBounds[0]		= computeLodFromDerivates(LODMODE_MIN_BOUND, dudx, 0.0f, 0.0f, dvdy)-lodEps;
2724 				m_lodBounds[1]		= computeLodFromDerivates(LODMODE_MAX_BOUND, dudx, 0.0f, 0.0f, dvdy)+lodEps;
2725 				break;
2726 			}
2727 
2728 			case TEXTURETYPE_CUBE_MAP:
2729 			case TEXTURETYPE_CUBE_ARRAY:
2730 			{
2731 				m_minCoord = Vec4(-1.0f, -1.0f, 1.01f, 0.0f);
2732 				m_maxCoord = Vec4( 1.0f,  1.0f, 1.01f, 0.0f);
2733 
2734 				// Compute LOD \note Assumes that only single side is accessed and R is constant major axis.
2735 				DE_ASSERT(de::abs(m_minCoord[2] - m_maxCoord[2]) < 0.005);
2736 				DE_ASSERT(de::abs(m_minCoord[0]) < de::abs(m_minCoord[2]) && de::abs(m_maxCoord[0]) < de::abs(m_minCoord[2]));
2737 				DE_ASSERT(de::abs(m_minCoord[1]) < de::abs(m_minCoord[2]) && de::abs(m_maxCoord[1]) < de::abs(m_minCoord[2]));
2738 
2739 				tcu::CubeFaceFloatCoords	c00		= tcu::getCubeFaceCoords(Vec3(m_minCoord[0], m_minCoord[1], m_minCoord[2]));
2740 				tcu::CubeFaceFloatCoords	c10		= tcu::getCubeFaceCoords(Vec3(m_maxCoord[0], m_minCoord[1], m_minCoord[2]));
2741 				tcu::CubeFaceFloatCoords	c01		= tcu::getCubeFaceCoords(Vec3(m_minCoord[0], m_maxCoord[1], m_minCoord[2]));
2742 				float						dudx	= (c10.s - c00.s)*(float)m_textureSpec.width	/ (float)viewportSize[0];
2743 				float						dvdy	= (c01.t - c00.t)*(float)m_textureSpec.height	/ (float)viewportSize[1];
2744 
2745 				m_lodBounds[0]		= computeLodFromDerivates(LODMODE_MIN_BOUND, dudx, 0.0f, 0.0f, dvdy)-lodEps;
2746 				m_lodBounds[1]		= computeLodFromDerivates(LODMODE_MAX_BOUND, dudx, 0.0f, 0.0f, dvdy)+lodEps;
2747 				break;
2748 			}
2749 
2750 			case TEXTURETYPE_3D:
2751 			{
2752 				m_minCoord = Vec4(-1.2f, -1.4f, 0.1f, 0.0f);
2753 				m_maxCoord = Vec4( 1.5f,  2.3f, 2.3f, 0.0f);
2754 
2755 				const float	dudx	= (m_maxCoord[0]-m_minCoord[0])*(float)m_textureSpec.width		/ (float)viewportSize[0];
2756 				const float	dvdy	= (m_maxCoord[1]-m_minCoord[1])*(float)m_textureSpec.height		/ (float)viewportSize[1];
2757 				const float	dwdx	= (m_maxCoord[2]-m_minCoord[2])*0.5f*(float)m_textureSpec.depth	/ (float)viewportSize[0];
2758 				const float	dwdy	= (m_maxCoord[2]-m_minCoord[2])*0.5f*(float)m_textureSpec.depth	/ (float)viewportSize[1];
2759 
2760 				m_lodBounds[0]		= computeLodFromDerivates(LODMODE_MIN_BOUND, dudx, 0.0f, dwdx, 0.0f, dvdy, dwdy)-lodEps;
2761 				m_lodBounds[1]		= computeLodFromDerivates(LODMODE_MAX_BOUND, dudx, 0.0f, dwdx, 0.0f, dvdy, dwdy)+lodEps;
2762 				break;
2763 			}
2764 
2765 			default:
2766 				DE_ASSERT(false);
2767 				break;
2768 		}
2769 
2770 		m_levelBounds[0] = computeLevelFromLod(m_lodBounds[0]);
2771 		m_levelBounds[1] = computeLevelFromLod(m_lodBounds[1]);
2772 
2773 		return;
2774 	}
2775 
2776 	if (m_mode == QLODTM_ZERO_UV_WIDTH)
2777 	{
2778 		// setup same texture coordinates that will result in pmax
2779 		// beeing 0 and as a result lambda being -inf; on most
2780 		// implementations lambda is computed as fixed-point, so
2781 		// infinities can't be returned, instead -maxSamplerLodBias or less
2782 		// should be returned
2783 
2784 		m_minCoord = Vec4(0.0f, 0.0f, 1.0f, 0.0f);
2785 		m_maxCoord = Vec4(0.0f, 0.0f, 1.0f, 0.0f);
2786 
2787 		m_lodBounds[0]		= -std::numeric_limits<float>::infinity();
2788 		m_lodBounds[1]		= -context.getDeviceProperties().limits.maxSamplerLodBias;
2789 		m_levelBounds[0]	= 0.0f;
2790 		m_levelBounds[1]	= 0.0f;
2791 
2792 		return;
2793 	}
2794 
2795 	DE_ASSERT(false);
2796 }
2797 
~TextureQueryLodInstance(void)2798 TextureQueryLodInstance::~TextureQueryLodInstance (void)
2799 {
2800 }
2801 
iterate(void)2802 tcu::TestStatus TextureQueryLodInstance::iterate (void)
2803 {
2804 	tcu::TestLog&		log		= m_context.getTestContext().getLog();
2805 
2806 	log << tcu::TestLog::Message << "Expected: level in range " << m_levelBounds << ", lod in range " << m_lodBounds << tcu::TestLog::EndMessage;
2807 
2808 	// render
2809 	TextureQueryInstance::render();
2810 
2811 	// test
2812 	{
2813 		const tcu::TextureLevel&	result		= getResultImage();
2814 		const tcu::Vec4				output		= result.getAccess().getPixel(0, 0);
2815 		const float					resLevel	= output.x();
2816 		const float					resLod		= output.y();
2817 
2818 		if (de::inRange(resLevel, m_levelBounds[0], m_levelBounds[1]) && de::inRange(resLod, m_lodBounds[0], m_lodBounds[1]))
2819 		{
2820 			// success
2821 			log << tcu::TestLog::Message << "Passed" << tcu::TestLog::EndMessage;
2822 			return tcu::TestStatus::pass("Pass");
2823 		}
2824 		else
2825 		{
2826 			// failure
2827 			log << tcu::TestLog::Message << "Result: level: " << resLevel << ", lod: " << resLod << tcu::TestLog::EndMessage;
2828 			log << tcu::TestLog::Message << "Failed" << tcu::TestLog::EndMessage;
2829 			return tcu::TestStatus::fail("Got unexpected result");
2830 		}
2831 	}
2832 }
2833 
setupDefaultInputs(void)2834 void TextureQueryLodInstance::setupDefaultInputs (void)
2835 {
2836 	TextureQueryInstance::setupDefaultInputs();
2837 
2838 	const deUint32			numVertices			= 4;
2839 	const vector<float>		texCoord			= computeQuadTexCoord();
2840 	const int				texCoordComps		= getQueryLodFuncTextCoordComps(m_textureSpec.type);
2841 	const vk::VkFormat		coordFormats[]		=
2842 	{
2843 		vk::VK_FORMAT_R32_SFLOAT,
2844 		vk::VK_FORMAT_R32G32_SFLOAT,
2845 		vk::VK_FORMAT_R32G32B32_SFLOAT
2846 	};
2847 
2848 	DE_ASSERT(de::inRange(texCoordComps, 1, 3));
2849 	DE_ASSERT((int)texCoord.size() == texCoordComps * 4);
2850 
2851 	addAttribute(1u, coordFormats[texCoordComps - 1], (deUint32)(texCoordComps * sizeof(float)), numVertices, texCoord.data());
2852 }
2853 
initTexture(void)2854 void TextureQueryLodInstance::initTexture (void)
2855 {
2856 	tcu::TestLog&			log					= m_context.getTestContext().getLog();
2857 	tcu::IVec3				textureSize			(m_textureSpec.width, m_textureSpec.height, m_textureSpec.depth);
2858 	TextureBindingSp		textureBinding;
2859 
2860 	DE_ASSERT(m_textures.empty());
2861 
2862 	log << tcu::TestLog::Message << "Image size: " << getTextureSizeString(m_textureSpec.type, textureSize) << tcu::TestLog::EndMessage;
2863 
2864 	textureBinding = createEmptyTexture(m_textureSpec.format, m_textureSpec.type, textureSize, m_textureSpec.numLevels, 0 /* lodBase */, m_textureSpec.sampler);
2865 
2866 	m_textures.push_back(textureBinding);
2867 }
2868 
computeLevelFromLod(float computedLod) const2869 float TextureQueryLodInstance::computeLevelFromLod (float computedLod) const
2870 {
2871 	const int	maxAccessibleLevel	= m_textureSpec.numLevels - 1;
2872 
2873 	// Clamp the computed LOD to the range of accessible levels.
2874 	computedLod = deFloatClamp(computedLod, 0.0f, (float)maxAccessibleLevel);
2875 
2876 	// Return a value according to the min filter.
2877 	switch (m_textureSpec.sampler.minFilter)
2878 	{
2879 		case tcu::Sampler::LINEAR:
2880 		case tcu::Sampler::NEAREST:
2881 			return 0.0f;
2882 
2883 		case tcu::Sampler::NEAREST_MIPMAP_NEAREST:
2884 		case tcu::Sampler::LINEAR_MIPMAP_NEAREST:
2885 			return deFloatClamp(deFloatCeil(computedLod + 0.5f) - 1.0f, 0.0f, (float)maxAccessibleLevel);
2886 
2887 		case tcu::Sampler::NEAREST_MIPMAP_LINEAR:
2888 		case tcu::Sampler::LINEAR_MIPMAP_LINEAR:
2889 			return computedLod;
2890 
2891 		default:
2892 			DE_ASSERT(false);
2893 			return 0.0f;
2894 	}
2895 }
2896 
computeQuadTexCoord(void) const2897 vector<float> TextureQueryLodInstance::computeQuadTexCoord (void) const
2898 {
2899 	vector<float>	res;
2900 	tcu::Mat4		coordTransMat;
2901 
2902 	{
2903 		Vec4 s = m_maxCoord - m_minCoord;
2904 		Vec4 b = m_minCoord;
2905 
2906 		float baseCoordTrans[] =
2907 		{
2908 			s.x(),		0.0f,		0.f,	b.x(),
2909 			0.f,		s.y(),		0.f,	b.y(),
2910 			s.z()/2.f,	-s.z()/2.f,	0.f,	s.z()/2.f + b.z(),
2911 			-s.w()/2.f,	s.w()/2.f,	0.f,	s.w()/2.f + b.w()
2912 		};
2913 
2914 		coordTransMat = tcu::Mat4(baseCoordTrans);
2915 	}
2916 
2917 	const int		texCoordComps	= getQueryLodFuncTextCoordComps(m_textureSpec.type);
2918 	Vec4			coords[4]		=
2919 	{
2920 		coordTransMat * tcu::Vec4(0, 0, 0, 1),
2921 		coordTransMat * tcu::Vec4(0, 1, 0, 1),
2922 		coordTransMat * tcu::Vec4(1, 0, 0, 1),
2923 		coordTransMat * tcu::Vec4(1, 1, 0, 1)
2924 	};
2925 
2926 	res.resize(4 * texCoordComps);
2927 
2928 	for (int ndx = 0; ndx < 4; ndx++)
2929 		deMemcpy(&res[ndx * texCoordComps], coords[ndx].getPtr(), texCoordComps * sizeof(float));
2930 
2931 	return res;
2932 }
2933 
2934 class TextureQueryCase : public ShaderRenderCase
2935 {
2936 public:
2937 								TextureQueryCase				(tcu::TestContext&			testCtx,
2938 																 const std::string&			name,
2939 																 const std::string&			samplerType,
2940 																 const TextureSpec&			texture,
2941 																 bool						isVertexCase,
2942 																 QueryFunction				function,
2943 																 TestMode					mode = 0);
2944 	virtual						~TextureQueryCase				(void);
2945 
2946 	virtual TestInstance*		createInstance					(Context& context) const;
2947 	virtual void				checkSupport					(Context& context) const;
2948 
2949 protected:
2950 	void						initShaderSources				(void);
2951 
2952 	const std::string			m_samplerTypeStr;
2953 	const TextureSpec			m_textureSpec;
2954 	const QueryFunction			m_function;
2955 	const TestMode				m_mode;
2956 };
2957 
TextureQueryCase(tcu::TestContext & testCtx,const std::string & name,const std::string & samplerType,const TextureSpec & texture,bool isVertexCase,QueryFunction function,TestMode mode)2958 TextureQueryCase::TextureQueryCase (tcu::TestContext&		testCtx,
2959 									const std::string&		name,
2960 									const std::string&		samplerType,
2961 									const TextureSpec&		texture,
2962 									bool					isVertexCase,
2963 									QueryFunction			function,
2964 									TestMode				mode)
2965 	: ShaderRenderCase	(testCtx, name, isVertexCase, (ShaderEvaluator*)DE_NULL, DE_NULL, DE_NULL)
2966 	, m_samplerTypeStr	(samplerType)
2967 	, m_textureSpec		(texture)
2968 	, m_function		(function)
2969 	, m_mode			(mode)
2970 {
2971 	initShaderSources();
2972 }
2973 
~TextureQueryCase(void)2974 TextureQueryCase::~TextureQueryCase (void)
2975 {
2976 }
2977 
createInstance(Context & context) const2978 TestInstance* TextureQueryCase::createInstance (Context& context) const
2979 {
2980 	switch (m_function)
2981 	{
2982 		case QUERYFUNCTION_TEXTURESIZE:				return new TextureSizeInstance(context, m_isVertexCase, m_textureSpec);
2983 		case QUERYFUNCTION_TEXTURESIZEMS:			return new TextureSizeMSInstance(context, m_isVertexCase, m_textureSpec);
2984 		case QUERYFUNCTION_TEXTUREQUERYLOD:			return new TextureQueryLodInstance(context, m_isVertexCase, m_textureSpec, m_mode);
2985 		case QUERYFUNCTION_TEXTUREQUERYLEVELS:		return new TextureQueryLevelsInstance(context, m_isVertexCase, m_textureSpec);
2986 		case QUERYFUNCTION_TEXTURESAMPLES:			return new TextureSamplesInstance(context, m_isVertexCase, m_textureSpec);
2987 		default:
2988 			DE_ASSERT(false);
2989 			return DE_NULL;
2990 	}
2991 }
2992 
checkSupport(Context & context) const2993 void TextureQueryCase::checkSupport(Context& context) const
2994 {
2995 	checkMutableComparisonSamplersSupport(context, m_textureSpec);
2996 }
2997 
initShaderSources(void)2998 void TextureQueryCase::initShaderSources (void)
2999 {
3000 	std::ostringstream		vert;
3001 	std::ostringstream		frag;
3002 	std::ostringstream&		op			= m_isVertexCase ? vert : frag;
3003 
3004 	DE_ASSERT(m_function != QUERYFUNCTION_TEXTUREQUERYLOD || !m_isVertexCase);
3005 
3006 	vert << "#version 450 core\n"
3007 		 << "layout(location = 0) in highp vec4 a_position;\n";
3008 
3009 	frag << "#version 450 core\n"
3010 		 << "layout(location = 0) out mediump vec4 o_color;\n";
3011 
3012 	if (m_isVertexCase)
3013 	{
3014 		vert << "layout(location = 0) out mediump vec4 v_color;\n";
3015 		frag << "layout(location = 0) in mediump vec4 v_color;\n";
3016 	}
3017 
3018 	if (m_function == QUERYFUNCTION_TEXTUREQUERYLOD)
3019 	{
3020 		const int		texCoordComps	= getQueryLodFuncTextCoordComps(m_textureSpec.type);
3021 		const char*		coordTypeName	= glu::getDataTypeName(glu::getDataTypeFloatVec(texCoordComps));
3022 
3023 		vert << "layout (location = 1) in highp " << coordTypeName << " a_texCoord;\n";
3024 		vert << "layout (location = 0) out highp " << coordTypeName << " v_texCoord;\n";
3025 		frag << "layout (location = 0) in highp " << coordTypeName << " v_texCoord;\n";
3026 	}
3027 
3028 	// uniforms
3029 	op << "layout(set = 0, binding = 0) uniform highp " << m_samplerTypeStr << " u_sampler;\n";
3030 	if (m_function == QUERYFUNCTION_TEXTURESIZE)
3031 		op << "layout(set = 0, binding = 1) uniform buf0 { highp int u_lod; };\n";
3032 
3033 	vert << "out gl_PerVertex {\n"
3034 		 << "\tvec4 gl_Position;\n"
3035 		 << "};\n";
3036 
3037 	vert << "\nvoid main()\n{\n"
3038 		 << "\tgl_Position = a_position;\n";
3039 	frag << "\nvoid main()\n{\n";
3040 
3041 	if (m_isVertexCase)
3042 		vert << "\tv_color = ";
3043 	else
3044 		frag << "\to_color = ";
3045 
3046 	// op
3047 	{
3048 		op << "vec4(";
3049 
3050 		switch (m_function)
3051 		{
3052 			case QUERYFUNCTION_TEXTURESIZE:
3053 			{
3054 				const int		resultComponents	= glu::getDataTypeScalarSize(getTextureSizeFuncResultType(m_textureSpec.type));
3055 
3056 				op << "textureSize(u_sampler, u_lod)";
3057 				for (int ndx = 0; ndx < 3 - resultComponents; ndx++)
3058 					op << ", 0.0";
3059 				op << ", 1.0";
3060 
3061 				break;
3062 			}
3063 
3064 			case QUERYFUNCTION_TEXTURESIZEMS:
3065 			{
3066 				const int		resultComponents	= glu::getDataTypeScalarSize(getTextureSizeFuncResultType(m_textureSpec.type));
3067 
3068 				op << "textureSize(u_sampler)";
3069 				for (int ndx = 0; ndx < 3 - resultComponents; ndx++)
3070 					op << ", 0.0";
3071 				op << ", 1.0";
3072 
3073 				break;
3074 			}
3075 
3076 			case QUERYFUNCTION_TEXTUREQUERYLOD:
3077 				op << "textureQueryLod(u_sampler, v_texCoord), 0.0, 1.0";
3078 				break;
3079 
3080 			case QUERYFUNCTION_TEXTUREQUERYLEVELS:
3081 				op << "textureQueryLevels(u_sampler), 0.0, 0.0, 1.0";
3082 				break;
3083 
3084 			case QUERYFUNCTION_TEXTURESAMPLES:
3085 				op << "textureSamples(u_sampler), 0.0, 0.0, 1.0";
3086 				break;
3087 
3088 			default:
3089 				DE_ASSERT(false);
3090 				break;
3091 		}
3092 
3093 		op << ");\n";
3094 	}
3095 
3096 	if (m_isVertexCase)
3097 		frag << "\to_color = v_color;\n";
3098 
3099 	if (m_function == QUERYFUNCTION_TEXTUREQUERYLOD)
3100 		vert << "\tv_texCoord = a_texCoord;\n";
3101 
3102 	vert << "}\n";
3103 	frag << "}\n";
3104 
3105 	m_vertShaderSource = vert.str();
3106 	m_fragShaderSource = frag.str();
3107 }
3108 
3109 namespace SpecialCases
3110 {
3111 using namespace vk;
3112 
textureSizeOOBPrograms(vk::SourceCollections & programCollection)3113 void textureSizeOOBPrograms(vk::SourceCollections& programCollection)
3114 {
3115 	programCollection.glslSources.add("comp") << glu::ComputeSource("#version 450\n"
3116 		"layout(local_size_x = 1) in;\n"
3117 		"layout(binding = 0) buffer InBuffer\n"
3118 		"{\n"
3119 		"  highp int lods[];\n"
3120 		"};\n"
3121 		"layout(binding = 1) buffer OutBuffer\n"
3122 		"{\n"
3123 		"  highp ivec2 results[];\n"
3124 		"};\n"
3125 		"layout(binding = 2) uniform sampler2D u_image;\n"
3126 		"void main(void)\n"
3127 		"{\n"
3128 		"  uint invocationNdx = gl_WorkGroupID.x;\n"
3129 		"  int lod = lods[invocationNdx];\n"
3130 		"  results[invocationNdx] = textureSize(u_image, lod);\n"
3131 		"}\n");
3132 }
3133 
textureSizeOOBTest(Context & context)3134 tcu::TestStatus textureSizeOOBTest(Context& context)
3135 {
3136 	// run few shader invocations, some invocations have in-bounds lod values, some out of bounds
3137 
3138 	const int		testedLods[]	= { 0, 10, 0, 1, 50, 0, 1, 2, -1, 0 };
3139 	const IVec2		imageSize		= { 16, 8 };
3140 
3141 	const DeviceInterface&	vk					= context.getDeviceInterface();
3142 	const VkDevice			device				= context.getDevice();
3143 	const VkQueue			queue				= context.getUniversalQueue();
3144 	const deUint32			queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
3145 	Allocator&				allocator			= context.getDefaultAllocator();
3146 
3147 	// create input and output buffers
3148 	const VkDeviceSize		bufferSizeBytes		= sizeof(int) * DE_LENGTH_OF_ARRAY(testedLods) * 2;
3149 	VkBufferCreateInfo		bufferCreateInfo	= makeBufferCreateInfo(bufferSizeBytes, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
3150 	BufferWithMemory		inBuffer			(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible);
3151 	BufferWithMemory		outBuffer			(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible);
3152 
3153 	// write data to input buffer
3154 	auto& inAlloc = inBuffer.getAllocation();
3155 	deMemcpy(inAlloc.getHostPtr(), testedLods, sizeof(int) * DE_LENGTH_OF_ARRAY(testedLods));
3156 	flushAlloc(vk, device, inAlloc);
3157 
3158 	// create image, we do not need to fill it with data for this test
3159 	const VkImageCreateInfo imageCreateInfo
3160 	{
3161 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,							// VkStructureType			sType;
3162 		DE_NULL,														// const void*				pNext;
3163 		0u,																// VkImageCreateFlags		flags;
3164 		VK_IMAGE_TYPE_2D,												// VkImageType				imageType;
3165 		VK_FORMAT_R8G8B8A8_UNORM,										// VkFormat					format;
3166 		vk::makeExtent3D(imageSize.x(), imageSize.y(), 1),				// VkExtent3D				extent;
3167 		3u,																// deUint32					mipLevels;
3168 		1u,																// deUint32					arrayLayers;
3169 		VK_SAMPLE_COUNT_1_BIT,											// VkSampleCountFlagBits	samples;
3170 		VK_IMAGE_TILING_OPTIMAL,										// VkImageTiling			tiling;
3171 		VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,	// VkImageUsageFlags		usage;
3172 		VK_SHARING_MODE_EXCLUSIVE,										// VkSharingMode			sharingMode;
3173 		0u,																// deUint32					queueFamilyIndexCount;
3174 		DE_NULL,														// const deUint32*			pQueueFamilyIndices;
3175 		VK_IMAGE_LAYOUT_UNDEFINED,										// VkImageLayout			initialLayout;
3176 	};
3177 	const ImageWithMemory			image				(vk, device, allocator, imageCreateInfo, MemoryRequirement::Any);
3178 	const VkImageSubresourceRange	subresourceRange	(makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 3u, 0u, 1u));
3179 	const Unique<VkImageView>		imageView			(makeImageView(vk, device, *image, VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_R8G8B8A8_UNORM, subresourceRange));
3180 
3181 	// create sampler with everything set to 0 as we wont use it in test
3182 	const VkSamplerCreateInfo		samplerCreateInfo	= initVulkanStructure();
3183 	const Unique<VkSampler>			sampler				(createSampler(vk, device, &samplerCreateInfo));
3184 
3185 	// create descriptors
3186 	const Unique<VkDescriptorPool> descriptorPool(DescriptorPoolBuilder()
3187 		.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2u)
3188 		.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
3189 		.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
3190 
3191 	const Unique<VkDescriptorSetLayout> descriptorSetLayout(DescriptorSetLayoutBuilder()
3192 		.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
3193 		.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
3194 		.addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_COMPUTE_BIT)
3195 		.build(vk, device));
3196 
3197 	const Unique<VkDescriptorSet>	descriptorSet		(makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
3198 	const VkDescriptorBufferInfo	inDescriptorInfo	= makeDescriptorBufferInfo(*inBuffer, 0ull, bufferSizeBytes);
3199 	const VkDescriptorBufferInfo	outDescriptorInfo	= makeDescriptorBufferInfo(*outBuffer, 0ull, bufferSizeBytes);
3200 	const VkDescriptorImageInfo		imageDescriptorInfo	= makeDescriptorImageInfo(*sampler, *imageView, VK_IMAGE_LAYOUT_GENERAL);
3201 	DescriptorSetUpdateBuilder()
3202 		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &inDescriptorInfo)
3203 		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outDescriptorInfo)
3204 		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageDescriptorInfo)
3205 		.update(vk, device);
3206 
3207 	// perform the computation
3208 	const Unique<VkShaderModule>	shaderModule	(createShaderModule(vk, device, context.getBinaryCollection().get("comp"), 0u));
3209 	const Unique<VkPipelineLayout>	pipelineLayout	(makePipelineLayout(vk, device, *descriptorSetLayout));
3210 	const Unique<VkPipeline>		pipeline		(makeComputePipeline(vk, device, *pipelineLayout, *shaderModule));
3211 	const VkImageMemoryBarrier		layoutBarrier	(makeImageMemoryBarrier(0u, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, *image, subresourceRange));
3212 	const VkBufferMemoryBarrier		outBarrier		(makeBufferMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *outBuffer, 0ull, bufferSizeBytes));
3213 	const Unique<VkCommandPool>		cmdPool			(makeCommandPool(vk, device, queueFamilyIndex));
3214 	const Unique<VkCommandBuffer>	cmdBuffer		(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
3215 
3216 	// start recording commands
3217 	beginCommandBuffer(vk, *cmdBuffer);
3218 
3219 	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, (VkDependencyFlags)0, 0, DE_NULL, 0, DE_NULL, 1, &layoutBarrier);
3220 	vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
3221 	vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
3222 	vk.cmdDispatch(*cmdBuffer, DE_LENGTH_OF_ARRAY(testedLods), 1, 1);
3223 	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, DE_NULL, 1, &outBarrier, 0, DE_NULL);
3224 
3225 	endCommandBuffer(vk, *cmdBuffer);
3226 	submitCommandsAndWait(vk, device, queue, *cmdBuffer);
3227 
3228 	// validate the results
3229 	const Allocation& bufferAllocation = outBuffer.getAllocation();
3230 	invalidateAlloc(vk, device, bufferAllocation);
3231 
3232 	std::map<int, IVec2> expectedLodSize
3233 	{
3234 		{ 0, { 16, 8 } },
3235 		{ 1, {  8, 4 } },
3236 		{ 2, {  4, 2 } },
3237 	};
3238 	bool			testFailed	= false;
3239 	tcu::TestLog&	log			= context.getTestContext().getLog();
3240 	const int*		bufferPtr	= static_cast<int*>(bufferAllocation.getHostPtr());
3241 
3242 	for (deUint32 lodNdx = 0; lodNdx < DE_LENGTH_OF_ARRAY(testedLods); ++lodNdx)
3243 	{
3244 		const int returnedWidth		= bufferPtr[2 * lodNdx + 0];
3245 		const int returnedHeight	= bufferPtr[2 * lodNdx + 1];
3246 		const int usedLod			= testedLods[lodNdx];
3247 
3248 		if ((usedLod >= 0) && (usedLod < 3))
3249 		{
3250 			const auto& expectedSize = expectedLodSize[usedLod];
3251 			if ((returnedWidth != expectedSize.x()) || (returnedHeight != expectedSize.y()))
3252 			{
3253 				log << tcu::TestLog::Message << "Wrong size for invocation " << lodNdx << ", expected " << expectedSize
3254 					<< " got (" << returnedWidth << ", " << returnedHeight << ")" << tcu::TestLog::EndMessage;
3255 				testFailed = true;
3256 			}
3257 		}
3258 	}
3259 
3260 	if (testFailed)
3261 		return tcu::TestStatus::fail("Fail");
3262 	return tcu::TestStatus::pass("Pass");
3263 }
3264 
3265 } // SpecialCases
3266 
3267 class ShaderTextureFunctionTests : public tcu::TestCaseGroup
3268 {
3269 public:
3270 									ShaderTextureFunctionTests		(tcu::TestContext& context);
3271 	virtual							~ShaderTextureFunctionTests		(void);
3272 	virtual void					init							(void);
3273 
3274 private:
3275 									ShaderTextureFunctionTests		(const ShaderTextureFunctionTests&);		// not allowed!
3276 	ShaderTextureFunctionTests&		operator=						(const ShaderTextureFunctionTests&);		// not allowed!
3277 };
3278 
ShaderTextureFunctionTests(tcu::TestContext & context)3279 ShaderTextureFunctionTests::ShaderTextureFunctionTests (tcu::TestContext& context)
3280 	: TestCaseGroup(context, "texture_functions")
3281 {
3282 }
3283 
~ShaderTextureFunctionTests(void)3284 ShaderTextureFunctionTests::~ShaderTextureFunctionTests (void)
3285 {
3286 }
3287 
3288 enum CaseFlags
3289 {
3290 	VERTEX		= (1<<0),
3291 	FRAGMENT	= (1<<1),
3292 	BOTH		= VERTEX|FRAGMENT
3293 };
3294 
3295 struct TexFuncCaseSpec
3296 {
3297 	const char*			name;
3298 	TextureLookupSpec	lookupSpec;
3299 	TextureSpec			texSpec;
3300 	TexEvalFunc			evalFunc;
3301 	deUint32			flags;
3302 };
3303 
3304 #define CASE_SPEC(NAME, FUNC, MINCOORD, MAXCOORD, USEBIAS, MINLOD, MAXLOD, USEOFFSET, OFFSET, TEXSPEC, EVALFUNC, FLAGS) \
3305 	{ #NAME, TextureLookupSpec(FUNC, MINCOORD, MAXCOORD, USEBIAS, MINLOD, MAXLOD, tcu::Vec3(0.0f), tcu::Vec3(0.0f), tcu::Vec3(0.0f), tcu::Vec3(0.0f), USEOFFSET, OFFSET, false, 0.0f), TEXSPEC, EVALFUNC, FLAGS }
3306 #define GRAD_CASE_SPEC(NAME, FUNC, MINCOORD, MAXCOORD, MINDX, MAXDX, MINDY, MAXDY, USEOFFSET, OFFSET, TEXSPEC, EVALFUNC, FLAGS) \
3307 	{ #NAME, TextureLookupSpec(FUNC, MINCOORD, MAXCOORD, false, 0.0f, 0.0f, MINDX, MAXDX, MINDY, MAXDY, USEOFFSET, OFFSET, false, 0.0f), TEXSPEC, EVALFUNC, FLAGS }
3308 #define CLAMP_CASE_SPEC(NAME, FUNC, MINCOORD, MAXCOORD, USEBIAS, MINLOD, MAXLOD, USEOFFSET, OFFSET, LODCLAMP, TEXSPEC, EVALFUNC, FLAGS) \
3309 	{ #NAME, TextureLookupSpec(FUNC, MINCOORD, MAXCOORD, USEBIAS, MINLOD, MAXLOD, tcu::Vec3(0.0f), tcu::Vec3(0.0f), tcu::Vec3(0.0f), tcu::Vec3(0.0f), USEOFFSET, OFFSET, true, LODCLAMP), TEXSPEC, EVALFUNC, FLAGS }
3310 #define GRADCLAMP_CASE_SPEC(NAME, FUNC, MINCOORD, MAXCOORD, MINDX, MAXDX, MINDY, MAXDY, USEOFFSET, OFFSET, LODCLAMP, TEXSPEC, EVALFUNC, FLAGS) \
3311 	{ #NAME, TextureLookupSpec(FUNC, MINCOORD, MAXCOORD, false, 0.0f, 0.0f, MINDX, MAXDX, MINDY, MAXDY, USEOFFSET, OFFSET, true, LODCLAMP), TEXSPEC, EVALFUNC, FLAGS }
3312 
3313 #ifndef CTS_USES_VULKANSC
3314 
3315 class SparseShaderTextureFunctionInstance : public ShaderTextureFunctionInstance
3316 {
3317 public:
3318 				SparseShaderTextureFunctionInstance		(Context&					context,
3319 														const bool					isVertexCase,
3320 														const ShaderEvaluator&		evaluator,
3321 														const UniformSetup&			uniformSetup,
3322 														const TextureLookupSpec&	lookupSpec,
3323 														const TextureSpec&			textureSpec,
3324 														const TexLookupParams&		lookupParams,
3325 														const ImageBackingMode		imageBackingMode = IMAGE_BACKING_MODE_SPARSE);
3326 	virtual		~SparseShaderTextureFunctionInstance	(void);
3327 };
3328 
SparseShaderTextureFunctionInstance(Context & context,const bool isVertexCase,const ShaderEvaluator & evaluator,const UniformSetup & uniformSetup,const TextureLookupSpec & lookupSpec,const TextureSpec & textureSpec,const TexLookupParams & lookupParams,const ImageBackingMode imageBackingMode)3329 SparseShaderTextureFunctionInstance::SparseShaderTextureFunctionInstance (Context&					context,
3330 																		 const bool					isVertexCase,
3331 																		 const ShaderEvaluator&		evaluator,
3332 																		 const UniformSetup&		uniformSetup,
3333 																		 const TextureLookupSpec&	lookupSpec,
3334 																		 const TextureSpec&			textureSpec,
3335 																		 const TexLookupParams&		lookupParams,
3336 																		 const ImageBackingMode		imageBackingMode)
3337 	: ShaderTextureFunctionInstance (context, isVertexCase, evaluator, uniformSetup, lookupSpec, textureSpec, lookupParams, imageBackingMode)
3338 {
3339 	if (lookupSpec.useClamp)
3340 	{
3341 		const vk::VkPhysicalDeviceFeatures&	deviceFeatures	= context.getDeviceFeatures();
3342 
3343 		if (!deviceFeatures.shaderResourceMinLod)
3344 			TCU_THROW(NotSupportedError, "ShaderResourceMinLod feature not supported.");
3345 	}
3346 }
3347 
~SparseShaderTextureFunctionInstance(void)3348 SparseShaderTextureFunctionInstance::~SparseShaderTextureFunctionInstance (void)
3349 {
3350 }
3351 
3352 class SparseShaderTextureFunctionCase : public ShaderTextureFunctionCase
3353 {
3354 public:
3355 							SparseShaderTextureFunctionCase		(tcu::TestContext&			testCtx,
3356 																const std::string&			name,
3357 																const TextureLookupSpec&	lookup,
3358 																const TextureSpec&			texture,
3359 																TexEvalFunc					evalFunc,
3360 																bool						isVertexCase);
3361 
3362 	virtual					~SparseShaderTextureFunctionCase	(void);
3363 
3364 	virtual	TestInstance*	createInstance						(Context& context) const;
3365 	virtual	void			checkSupport						(Context& context) const;
3366 protected:
3367 	void					initShaderSources					(void);
3368 };
3369 
SparseShaderTextureFunctionCase(tcu::TestContext & testCtx,const std::string & name,const TextureLookupSpec & lookup,const TextureSpec & texture,TexEvalFunc evalFunc,bool isVertexCase)3370 SparseShaderTextureFunctionCase::SparseShaderTextureFunctionCase (tcu::TestContext&				testCtx,
3371 																  const std::string&			name,
3372 																  const TextureLookupSpec&		lookup,
3373 																  const TextureSpec&			texture,
3374 																  TexEvalFunc					evalFunc,
3375 																  bool							isVertexCase)
3376 	: ShaderTextureFunctionCase		(testCtx, name, lookup, texture, evalFunc, isVertexCase)
3377 {
3378 	initShaderSources();
3379 }
3380 
initShaderSources(void)3381 void SparseShaderTextureFunctionCase::initShaderSources (void)
3382 {
3383 	const Function				function			= m_lookupSpec.function;
3384 	const bool					isVtxCase			= m_isVertexCase;
3385 	const bool					isProj				= functionHasProj(function);
3386 	const bool					isGrad				= functionHasGrad(function);
3387 	const bool					isShadow			= m_textureSpec.sampler.compare != tcu::Sampler::COMPAREMODE_NONE;
3388 	const bool					is2DProj4			= !isShadow && m_textureSpec.type == TEXTURETYPE_2D && (function == FUNCTION_TEXTUREPROJ || function == FUNCTION_TEXTUREPROJLOD || function == FUNCTION_TEXTUREPROJGRAD);
3389 	const bool					isIntCoord			= function == FUNCTION_TEXELFETCH;
3390 	const bool					hasLodBias			= functionHasLod(m_lookupSpec.function) || m_lookupSpec.useBias;
3391 	const int					texCoordComps		= m_textureSpec.type == TEXTURETYPE_2D ? 2 : 3;
3392 	const int					extraCoordComps		= (isProj ? (is2DProj4 ? 2 : 1) : 0) + (isShadow ? 1 : 0);
3393 	const glu::DataType			coordType			= glu::getDataTypeFloatVec(texCoordComps+extraCoordComps);
3394 	const glu::Precision		coordPrec			= glu::PRECISION_HIGHP;
3395 	const char*					coordTypeName		= glu::getDataTypeName(coordType);
3396 	const char*					coordPrecName		= glu::getPrecisionName(coordPrec);
3397 	const tcu::TextureFormat	texFmt				= glu::mapGLInternalFormat(m_textureSpec.format);
3398 	glu::DataType				samplerType			= glu::TYPE_LAST;
3399 	const glu::DataType			gradType			= (m_textureSpec.type == TEXTURETYPE_CUBE_MAP || m_textureSpec.type == TEXTURETYPE_3D) ? glu::TYPE_FLOAT_VEC3 : glu::TYPE_FLOAT_VEC2;
3400 	const char*					gradTypeName		= glu::getDataTypeName(gradType);
3401 	const char*					baseFuncName		= DE_NULL;
3402 
3403 	DE_ASSERT(!isGrad || !hasLodBias);
3404 
3405 	switch (m_textureSpec.type)
3406 	{
3407 		case TEXTURETYPE_2D:		samplerType = isShadow ? glu::TYPE_SAMPLER_2D_SHADOW		: glu::getSampler2DType(texFmt);		break;
3408 		case TEXTURETYPE_CUBE_MAP:	samplerType = isShadow ? glu::TYPE_SAMPLER_CUBE_SHADOW		: glu::getSamplerCubeType(texFmt);		break;
3409 		case TEXTURETYPE_2D_ARRAY:	samplerType = isShadow ? glu::TYPE_SAMPLER_2D_ARRAY_SHADOW	: glu::getSampler2DArrayType(texFmt);	break;
3410 		case TEXTURETYPE_3D:		DE_ASSERT(!isShadow); samplerType = glu::getSampler3DType(texFmt);									break;
3411 		default:
3412 			DE_ASSERT(DE_FALSE);
3413 	}
3414 
3415 	// Not supported cases
3416 	switch (m_lookupSpec.function)
3417 	{
3418 		case FUNCTION_TEXTURE:			baseFuncName = "sparseTexture";			break;
3419 		case FUNCTION_TEXTURELOD:		baseFuncName = "sparseTextureLod";		break;
3420 		case FUNCTION_TEXTUREGRAD:		baseFuncName = "sparseTextureGrad";		break;
3421 		case FUNCTION_TEXELFETCH:		baseFuncName = "sparseTexelFetch";		break;
3422 		default:
3423 			DE_ASSERT(DE_FALSE);
3424 	}
3425 
3426 	std::ostringstream	vert;
3427 	std::ostringstream	frag;
3428 	std::ostringstream&	op		= isVtxCase ? vert : frag;
3429 
3430 	vert << "#version 450\n"
3431 		 << "#extension GL_ARB_sparse_texture2 : require\n"
3432 		 << "layout(location = 0) in highp vec4 a_position;\n"
3433 		 << "layout(location = 4) in " << coordPrecName << " " << coordTypeName << " a_in0;\n";
3434 
3435 	if (isGrad)
3436 	{
3437 		vert << "layout(location = 5) in " << coordPrecName << " " << gradTypeName << " a_in1;\n";
3438 		vert << "layout(location = 6) in " << coordPrecName << " " << gradTypeName << " a_in2;\n";
3439 	}
3440 	else if (hasLodBias)
3441 		vert << "layout(location = 5) in " << coordPrecName << " float a_in1;\n";
3442 
3443 	frag << "#version 450\n"
3444 		 << "#extension GL_ARB_sparse_texture2 : require\n";
3445 
3446 	if (m_lookupSpec.useClamp)
3447 		frag << "#extension GL_ARB_sparse_texture_clamp : require\n";
3448 
3449 	frag << "layout(location = 0) out mediump vec4 o_color;\n";
3450 
3451 	if (isVtxCase)
3452 	{
3453 		vert << "layout(location = 0) out mediump vec4 v_color;\n";
3454 		frag << "layout(location = 0) in mediump vec4 v_color;\n";
3455 	}
3456 	else
3457 	{
3458 		vert << "layout(location = 0) out " << coordPrecName << " " << coordTypeName << " v_texCoord;\n";
3459 		frag << "layout(location = 0) in " << coordPrecName << " " << coordTypeName << " v_texCoord;\n";
3460 
3461 		if (isGrad)
3462 		{
3463 			vert << "layout(location = 1) out " << coordPrecName << " " << gradTypeName << " v_gradX;\n";
3464 			vert << "layout(location = 2) out " << coordPrecName << " " << gradTypeName << " v_gradY;\n";
3465 			frag << "layout(location = 1) in " << coordPrecName << " " << gradTypeName << " v_gradX;\n";
3466 			frag << "layout(location = 2) in " << coordPrecName << " " << gradTypeName << " v_gradY;\n";
3467 		}
3468 		else if (hasLodBias)
3469 		{
3470 			vert << "layout(location = 1) out " << coordPrecName << " float v_lodBias;\n";
3471 			frag << "layout(location = 1) in " << coordPrecName << " float v_lodBias;\n";
3472 		}
3473 	}
3474 
3475 	// Uniforms
3476 	op << "layout(set = 0, binding = 0) uniform highp " << glu::getDataTypeName(samplerType) << " u_sampler;\n"
3477 	   << "layout(set = 0, binding = 1) uniform buf0 { highp vec4 u_scale; };\n"
3478 	   << "layout(set = 0, binding = 2) uniform buf1 { highp vec4 u_bias; };\n";
3479 
3480 	vert << "out gl_PerVertex {\n"
3481 		 << "	vec4 gl_Position;\n"
3482 		 << "};\n";
3483 	vert << "\nvoid main()\n{\n"
3484 		 << "\tgl_Position = a_position;\n";
3485 	frag << "\nvoid main()\n{\n";
3486 
3487 	// Op.
3488 	{
3489 		// Texel declaration
3490 		if (isShadow)
3491 			op << "\tfloat texel;\n";
3492 		else
3493 			op << "\tvec4 texel;\n";
3494 
3495 		const char*	const texCoord	= isVtxCase ? "a_in0" : "v_texCoord";
3496 		const char* const gradX		= isVtxCase ? "a_in1" : "v_gradX";
3497 		const char* const gradY		= isVtxCase ? "a_in2" : "v_gradY";
3498 		const char*	const lodBias	= isVtxCase ? "a_in1" : "v_lodBias";
3499 
3500 		op << "\tint success = " << baseFuncName;
3501 
3502 		if (m_lookupSpec.useOffset)
3503 			op << "Offset";
3504 
3505 		if (m_lookupSpec.useClamp)
3506 			op << "Clamp";
3507 
3508 		op << "ARB(u_sampler, ";
3509 
3510 		if (isIntCoord)
3511 			op << "ivec" << (texCoordComps+extraCoordComps) << "(";
3512 
3513 		op << texCoord;
3514 
3515 		if (isIntCoord)
3516 			op << ")";
3517 
3518 		if (isGrad)
3519 			op << ", " << gradX << ", " << gradY;
3520 
3521 		if (functionHasLod(function))
3522 		{
3523 			if (isIntCoord)
3524 				op << ", int(" << lodBias << ")";
3525 			else
3526 				op << ", " << lodBias;
3527 		}
3528 
3529 		if (m_lookupSpec.useOffset)
3530 		{
3531 			int offsetComps = m_textureSpec.type == TEXTURETYPE_3D ? 3 : 2;
3532 
3533 			op << ", ivec" << offsetComps << "(";
3534 			for (int ndx = 0; ndx < offsetComps; ndx++)
3535 			{
3536 				if (ndx != 0)
3537 					op << ", ";
3538 				op << m_lookupSpec.offset[ndx];
3539 			}
3540 			op << ")";
3541 		}
3542 
3543 		if (m_lookupSpec.useClamp)
3544 			op << ", float(" << m_lookupSpec.lodClamp << ")";
3545 
3546 		op << ", texel";
3547 
3548 		if (m_lookupSpec.useBias)
3549 			op << ", " << lodBias;
3550 
3551 		op << ");\n";
3552 
3553 		// Check sparse validity, and handle each case
3554 		op << "\tif (sparseTexelsResidentARB(success))\n";
3555 
3556 		if (isVtxCase)
3557 			vert << "\t\tv_color = ";
3558 		else
3559 			frag << "\t\to_color = ";
3560 
3561 		if (isShadow)
3562 			op << "vec4(texel, 0.0, 0.0, 1.0);\n";
3563 		else
3564 			op << "vec4(texel * u_scale + u_bias);\n";
3565 
3566 		op << "\telse\n";
3567 
3568 		// This color differs from the used colors
3569 		if (isVtxCase)
3570 			vert << "\t\tv_color = vec4(0.54117647058, 0.16862745098, 0.8862745098, 1.0);\n";
3571 		else
3572 			frag << "\t\to_color = vec4(0.54117647058, 0.16862745098, 0.8862745098, 1.0);\n";
3573 	}
3574 
3575 	if (isVtxCase)
3576 		frag << "\to_color = v_color;\n";
3577 	else
3578 	{
3579 		vert << "\tv_texCoord = a_in0;\n";
3580 
3581 		if (isGrad)
3582 		{
3583 			vert << "\tv_gradX = a_in1;\n";
3584 			vert << "\tv_gradY = a_in2;\n";
3585 		}
3586 		else if (hasLodBias)
3587 			vert << "\tv_lodBias = a_in1;\n";
3588 	}
3589 
3590 	vert << "}\n";
3591 	frag << "}\n";
3592 
3593 	m_vertShaderSource = vert.str();
3594 	m_fragShaderSource = frag.str();
3595 }
3596 
~SparseShaderTextureFunctionCase()3597 SparseShaderTextureFunctionCase::~SparseShaderTextureFunctionCase ()
3598 {
3599 }
3600 
createInstance(Context & context) const3601 TestInstance* SparseShaderTextureFunctionCase::createInstance (Context& context) const
3602 {
3603 	DE_ASSERT(m_evaluator != DE_NULL);
3604 	DE_ASSERT(m_uniformSetup != DE_NULL);
3605 	return new SparseShaderTextureFunctionInstance(context, m_isVertexCase, *m_evaluator, *m_uniformSetup, m_lookupSpec, m_textureSpec, m_lookupParams);
3606 }
3607 
checkSupport(Context & context) const3608 void SparseShaderTextureFunctionCase::checkSupport(Context& context) const
3609 {
3610 	checkMutableComparisonSamplersSupport(context, m_textureSpec);
3611 }
3612 
3613 #endif // CTS_USES_VULKANSC
3614 
createCaseGroup(tcu::TestCaseGroup * parent,const char * groupName,const TexFuncCaseSpec * cases,int numCases)3615 static void createCaseGroup (tcu::TestCaseGroup* parent, const char* groupName, const TexFuncCaseSpec* cases, int numCases)
3616 {
3617 	de::MovePtr<tcu::TestCaseGroup>	group	(new tcu::TestCaseGroup(parent->getTestContext(), groupName));
3618 
3619 	for (int ndx = 0; ndx < numCases; ndx++)
3620 	{
3621 		std::string	name			= cases[ndx].name;
3622 #ifndef CTS_USES_VULKANSC
3623 		bool		sparseSupported	= !functionHasProj(cases[ndx].lookupSpec.function)		&&
3624 									  TEXTURETYPE_1D			!= cases[ndx].texSpec.type	&&
3625 									  TEXTURETYPE_1D_ARRAY		!= cases[ndx].texSpec.type	&&
3626 									  TEXTURETYPE_CUBE_ARRAY	!= cases[ndx].texSpec.type;
3627 #endif // CTS_USES_VULKANSC
3628 
3629 		if (cases[ndx].flags & VERTEX)
3630 		{
3631 #ifndef CTS_USES_VULKANSC
3632 			if (sparseSupported)
3633 				group->addChild(new SparseShaderTextureFunctionCase(parent->getTestContext(), ("sparse_" + name + "_vertex"), cases[ndx].lookupSpec, cases[ndx].texSpec, cases[ndx].evalFunc, true ));
3634 #endif // CTS_USES_VULKANSC
3635 
3636 			group->addChild(new ShaderTextureFunctionCase(parent->getTestContext(), (name + "_vertex"), cases[ndx].lookupSpec, cases[ndx].texSpec, cases[ndx].evalFunc, true ));
3637 		}
3638 
3639 		if (cases[ndx].flags & FRAGMENT)
3640 		{
3641 #ifndef CTS_USES_VULKANSC
3642 			if (sparseSupported)
3643 				group->addChild(new SparseShaderTextureFunctionCase(parent->getTestContext(), ("sparse_" + name + "_fragment"), cases[ndx].lookupSpec, cases[ndx].texSpec, cases[ndx].evalFunc, false));
3644 #endif // CTS_USES_VULKANSC
3645 
3646 			group->addChild(new ShaderTextureFunctionCase(parent->getTestContext(), (name + "_fragment"), cases[ndx].lookupSpec, cases[ndx].texSpec, cases[ndx].evalFunc, false));
3647 		}
3648 	}
3649 
3650 	parent->addChild(group.release());
3651 }
3652 
init(void)3653 void ShaderTextureFunctionTests::init (void)
3654 {
3655 	// Samplers
3656 	static const tcu::Sampler	samplerNearestNoMipmap	(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
3657 														 tcu::Sampler::NEAREST, tcu::Sampler::NEAREST,
3658 														 0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_NONE,
3659 														 0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
3660 	static const tcu::Sampler	samplerLinearNoMipmap	(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
3661 														 tcu::Sampler::LINEAR, tcu::Sampler::LINEAR,
3662 														 0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_NONE,
3663 														 0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
3664 	static const tcu::Sampler	samplerNearestMipmap	(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
3665 														 tcu::Sampler::NEAREST_MIPMAP_NEAREST, tcu::Sampler::NEAREST,
3666 														 0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_NONE,
3667 														 0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
3668 	static const tcu::Sampler	samplerLinearMipmap		(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
3669 														 tcu::Sampler::LINEAR_MIPMAP_NEAREST, tcu::Sampler::LINEAR,
3670 														 0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_NONE,
3671 														 0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
3672 
3673 	static const tcu::Sampler	samplerShadowNoMipmap	(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
3674 														 tcu::Sampler::NEAREST, tcu::Sampler::NEAREST,
3675 														 0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_LESS,
3676 														 0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
3677 	static const tcu::Sampler	samplerShadowMipmap		(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
3678 														 tcu::Sampler::NEAREST_MIPMAP_NEAREST, tcu::Sampler::NEAREST,
3679 														 0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_LESS,
3680 														 0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
3681 
3682 	static const tcu::Sampler	samplerTexelFetch		(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
3683 														 tcu::Sampler::NEAREST_MIPMAP_NEAREST, tcu::Sampler::NEAREST,
3684 														 00.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_NONE,
3685 														 0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
3686 
3687 	// Default textures.
3688 	//												Type					Format					W		H		D	L	Sampler
3689 	static const TextureSpec tex2DFixed				(TEXTURETYPE_2D,		GL_RGBA8,				256,	256,	1,	1,	samplerLinearNoMipmap);
3690 	static const TextureSpec tex2DFloat				(TEXTURETYPE_2D,		GL_RGBA16F,				256,	256,	1,	1,	samplerLinearNoMipmap);
3691 	static const TextureSpec tex2DInt				(TEXTURETYPE_2D,		GL_RGBA8I,				256,	256,	1,	1,	samplerNearestNoMipmap);
3692 	static const TextureSpec tex2DUint				(TEXTURETYPE_2D,		GL_RGBA8UI,				256,	256,	1,	1,	samplerNearestNoMipmap);
3693 	static const TextureSpec tex2DMipmapFixed		(TEXTURETYPE_2D,		GL_RGBA8,				256,	256,	1,	9,	samplerLinearMipmap);
3694 	static const TextureSpec tex2DMipmapFloat		(TEXTURETYPE_2D,		GL_RGBA16F,				256,	256,	1,	9,	samplerLinearMipmap);
3695 	static const TextureSpec tex2DMipmapInt			(TEXTURETYPE_2D,		GL_RGBA8I,				256,	256,	1,	9,	samplerNearestMipmap);
3696 	static const TextureSpec tex2DMipmapUint		(TEXTURETYPE_2D,		GL_RGBA8UI,				256,	256,	1,	9,	samplerNearestMipmap);
3697 
3698 	static const TextureSpec tex2DShadow			(TEXTURETYPE_2D,		GL_DEPTH_COMPONENT16,	256,	256,	1,	1,	samplerShadowNoMipmap);
3699 	static const TextureSpec tex2DMipmapShadow		(TEXTURETYPE_2D,		GL_DEPTH_COMPONENT16,	256,	256,	1,	9,	samplerShadowMipmap);
3700 
3701 	static const TextureSpec tex2DTexelFetchFixed	(TEXTURETYPE_2D,		GL_RGBA8,				256,	256,	1,	9,	samplerTexelFetch);
3702 	static const TextureSpec tex2DTexelFetchFloat	(TEXTURETYPE_2D,		GL_RGBA16F,				256,	256,	1,	9,	samplerTexelFetch);
3703 	static const TextureSpec tex2DTexelFetchInt		(TEXTURETYPE_2D,		GL_RGBA8I,				256,	256,	1,	9,	samplerTexelFetch);
3704 	static const TextureSpec tex2DTexelFetchUint	(TEXTURETYPE_2D,		GL_RGBA8UI,				256,	256,	1,	9,	samplerTexelFetch);
3705 
3706 	static const TextureSpec texCubeFixed			(TEXTURETYPE_CUBE_MAP,	GL_RGBA8,	256,	256,	1,	1,	samplerLinearNoMipmap);
3707 	static const TextureSpec texCubeFloat			(TEXTURETYPE_CUBE_MAP,	GL_RGBA16F,	256,	256,	1,	1,	samplerLinearNoMipmap);
3708 	static const TextureSpec texCubeInt				(TEXTURETYPE_CUBE_MAP,	GL_RGBA8I,	256,	256,	1,	1,	samplerNearestNoMipmap);
3709 	static const TextureSpec texCubeUint			(TEXTURETYPE_CUBE_MAP,	GL_RGBA8UI,	256,	256,	1,	1,	samplerNearestNoMipmap);
3710 	static const TextureSpec texCubeMipmapFixed		(TEXTURETYPE_CUBE_MAP,	GL_RGBA8,	256,	256,	1,	9,	samplerLinearMipmap);
3711 	static const TextureSpec texCubeMipmapFloat		(TEXTURETYPE_CUBE_MAP,	GL_RGBA16F,	128,	128,	1,	8,	samplerLinearMipmap);
3712 	static const TextureSpec texCubeMipmapInt		(TEXTURETYPE_CUBE_MAP,	GL_RGBA8I,	256,	256,	1,	9,	samplerNearestMipmap);
3713 	static const TextureSpec texCubeMipmapUint		(TEXTURETYPE_CUBE_MAP,	GL_RGBA8UI,	256,	256,	1,	9,	samplerNearestMipmap);
3714 
3715 	static const TextureSpec texCubeShadow			(TEXTURETYPE_CUBE_MAP,	GL_DEPTH_COMPONENT16,	256,	256,	1,	1,	samplerShadowNoMipmap);
3716 	static const TextureSpec texCubeMipmapShadow	(TEXTURETYPE_CUBE_MAP,	GL_DEPTH_COMPONENT16,	256,	256,	1,	9,	samplerShadowMipmap);
3717 
3718 	static const TextureSpec tex2DArrayFixed		(TEXTURETYPE_2D_ARRAY,	GL_RGBA8,	128,	128,	4,	1,	samplerLinearNoMipmap);
3719 	static const TextureSpec tex2DArrayFloat		(TEXTURETYPE_2D_ARRAY,	GL_RGBA16F,	128,	128,	4,	1,	samplerLinearNoMipmap);
3720 	static const TextureSpec tex2DArrayInt			(TEXTURETYPE_2D_ARRAY,	GL_RGBA8I,	128,	128,	4,	1,	samplerNearestNoMipmap);
3721 	static const TextureSpec tex2DArrayUint			(TEXTURETYPE_2D_ARRAY,	GL_RGBA8UI,	128,	128,	4,	1,	samplerNearestNoMipmap);
3722 	static const TextureSpec tex2DArrayMipmapFixed	(TEXTURETYPE_2D_ARRAY,	GL_RGBA8,	128,	128,	4,	8,	samplerLinearMipmap);
3723 	static const TextureSpec tex2DArrayMipmapFloat	(TEXTURETYPE_2D_ARRAY,	GL_RGBA16F,	128,	128,	4,	8,	samplerLinearMipmap);
3724 	static const TextureSpec tex2DArrayMipmapInt	(TEXTURETYPE_2D_ARRAY,	GL_RGBA8I,	128,	128,	4,	8,	samplerNearestMipmap);
3725 	static const TextureSpec tex2DArrayMipmapUint	(TEXTURETYPE_2D_ARRAY,	GL_RGBA8UI,	128,	128,	4,	8,	samplerNearestMipmap);
3726 
3727 	static const TextureSpec tex2DArrayShadow		(TEXTURETYPE_2D_ARRAY,	GL_DEPTH_COMPONENT16,	128,	128,	4,	1,	samplerShadowNoMipmap);
3728 	static const TextureSpec tex2DArrayMipmapShadow	(TEXTURETYPE_2D_ARRAY,	GL_DEPTH_COMPONENT16,	128,	128,	4,	8,	samplerShadowMipmap);
3729 
3730 	static const TextureSpec tex2DArrayTexelFetchFixed	(TEXTURETYPE_2D_ARRAY,	GL_RGBA8,	128,	128,	4,	8,	samplerTexelFetch);
3731 	static const TextureSpec tex2DArrayTexelFetchFloat	(TEXTURETYPE_2D_ARRAY,	GL_RGBA16F,	128,	128,	4,	8,	samplerTexelFetch);
3732 	static const TextureSpec tex2DArrayTexelFetchInt	(TEXTURETYPE_2D_ARRAY,	GL_RGBA8I,	128,	128,	4,	8,	samplerTexelFetch);
3733 	static const TextureSpec tex2DArrayTexelFetchUint	(TEXTURETYPE_2D_ARRAY,	GL_RGBA8UI,	128,	128,	4,	8,	samplerTexelFetch);
3734 
3735 	static const TextureSpec tex3DFixed				(TEXTURETYPE_3D,		GL_RGBA8,	64,		32,		32,	1,	samplerLinearNoMipmap);
3736 	static const TextureSpec tex3DFloat				(TEXTURETYPE_3D,		GL_RGBA16F,	64,		32,		32,	1,	samplerLinearNoMipmap);
3737 	static const TextureSpec tex3DInt				(TEXTURETYPE_3D,		GL_RGBA8I,	64,		32,		32,	1,	samplerNearestNoMipmap);
3738 	static const TextureSpec tex3DUint				(TEXTURETYPE_3D,		GL_RGBA8UI,	64,		32,		32,	1,	samplerNearestNoMipmap);
3739 	static const TextureSpec tex3DMipmapFixed		(TEXTURETYPE_3D,		GL_RGBA8,	64,		32,		32,	7,	samplerLinearMipmap);
3740 	static const TextureSpec tex3DMipmapFloat		(TEXTURETYPE_3D,		GL_RGBA16F,	64,		32,		32,	7,	samplerLinearMipmap);
3741 	static const TextureSpec tex3DMipmapInt			(TEXTURETYPE_3D,		GL_RGBA8I,	64,		32,		32,	7,	samplerNearestMipmap);
3742 	static const TextureSpec tex3DMipmapUint		(TEXTURETYPE_3D,		GL_RGBA8UI,	64,		32,		32,	7,	samplerNearestMipmap);
3743 
3744 	static const TextureSpec tex3DTexelFetchFixed	(TEXTURETYPE_3D,		GL_RGBA8,	64,		32,		32,	7,	samplerTexelFetch);
3745 	static const TextureSpec tex3DTexelFetchFloat	(TEXTURETYPE_3D,		GL_RGBA16F,	64,		32,		32,	7,	samplerTexelFetch);
3746 	static const TextureSpec tex3DTexelFetchInt		(TEXTURETYPE_3D,		GL_RGBA8I,	64,		32,		32,	7,	samplerTexelFetch);
3747 	static const TextureSpec tex3DTexelFetchUint	(TEXTURETYPE_3D,		GL_RGBA8UI,	64,		32,		32,	7,	samplerTexelFetch);
3748 
3749 	static const TextureSpec tex1DFixed				(TEXTURETYPE_1D,		GL_RGBA8,				256,	1,	1,	1,	samplerLinearNoMipmap);
3750 	static const TextureSpec tex1DFloat				(TEXTURETYPE_1D,		GL_RGBA16F,				256,	1,	1,	1,	samplerLinearNoMipmap);
3751 	static const TextureSpec tex1DInt				(TEXTURETYPE_1D,		GL_RGBA8I,				256,	1,	1,	1,	samplerNearestNoMipmap);
3752 	static const TextureSpec tex1DUint				(TEXTURETYPE_1D,		GL_RGBA8UI,				256,	1,	1,	1,	samplerNearestNoMipmap);
3753 	static const TextureSpec tex1DMipmapFixed		(TEXTURETYPE_1D,		GL_RGBA8,				256,	1,	1,	9,	samplerLinearMipmap);
3754 	static const TextureSpec tex1DMipmapFloat		(TEXTURETYPE_1D,		GL_RGBA16F,				256,	1,	1,	9,	samplerLinearMipmap);
3755 	static const TextureSpec tex1DMipmapInt			(TEXTURETYPE_1D,		GL_RGBA8I,				256,	1,	1,	9,	samplerNearestMipmap);
3756 	static const TextureSpec tex1DMipmapUint		(TEXTURETYPE_1D,		GL_RGBA8UI,				256,	1,	1,	9,	samplerNearestMipmap);
3757 
3758 	static const TextureSpec tex1DShadow			(TEXTURETYPE_1D,		GL_DEPTH_COMPONENT16,	256,	1,	1,	1,	samplerShadowNoMipmap);
3759 	static const TextureSpec tex1DMipmapShadow		(TEXTURETYPE_1D,		GL_DEPTH_COMPONENT16,	256,	1,	1,	9,	samplerShadowMipmap);
3760 
3761 	static const TextureSpec tex1DTexelFetchFixed	(TEXTURETYPE_1D,		GL_RGBA8,				256,	1,	1,	9,	samplerTexelFetch);
3762 	static const TextureSpec tex1DTexelFetchFloat	(TEXTURETYPE_1D,		GL_RGBA16F,				256,	1,	1,	9,	samplerTexelFetch);
3763 	static const TextureSpec tex1DTexelFetchInt		(TEXTURETYPE_1D,		GL_RGBA8I,				256,	1,	1,	9,	samplerTexelFetch);
3764 	static const TextureSpec tex1DTexelFetchUint	(TEXTURETYPE_1D,		GL_RGBA8UI,				256,	1,	1,	9,	samplerTexelFetch);
3765 
3766 	static const TextureSpec tex1DArrayFixed		(TEXTURETYPE_1D_ARRAY,	GL_RGBA8,	256,	1,	4,	1,	samplerLinearNoMipmap);
3767 	static const TextureSpec tex1DArrayFloat		(TEXTURETYPE_1D_ARRAY,	GL_RGBA16F,	256,	1,	4,	1,	samplerLinearNoMipmap);
3768 	static const TextureSpec tex1DArrayInt			(TEXTURETYPE_1D_ARRAY,	GL_RGBA8I,	256,	1,	4,	1,	samplerNearestNoMipmap);
3769 	static const TextureSpec tex1DArrayUint			(TEXTURETYPE_1D_ARRAY,	GL_RGBA8UI,	256,	1,	4,	1,	samplerNearestNoMipmap);
3770 	static const TextureSpec tex1DArrayMipmapFixed	(TEXTURETYPE_1D_ARRAY,	GL_RGBA8,	256,	1,	4,	9,	samplerLinearMipmap);
3771 	static const TextureSpec tex1DArrayMipmapFloat	(TEXTURETYPE_1D_ARRAY,	GL_RGBA16F,	256,	1,	4,	9,	samplerLinearMipmap);
3772 	static const TextureSpec tex1DArrayMipmapInt	(TEXTURETYPE_1D_ARRAY,	GL_RGBA8I,	256,	1,	4,	9,	samplerNearestMipmap);
3773 	static const TextureSpec tex1DArrayMipmapUint	(TEXTURETYPE_1D_ARRAY,	GL_RGBA8UI,	256,	1,	4,	9,	samplerNearestMipmap);
3774 
3775 	static const TextureSpec tex1DArrayShadow		(TEXTURETYPE_1D_ARRAY,	GL_DEPTH_COMPONENT16,	256,	1,	4,	1,	samplerShadowNoMipmap);
3776 	static const TextureSpec tex1DArrayMipmapShadow	(TEXTURETYPE_1D_ARRAY,	GL_DEPTH_COMPONENT16,	256,	1,	4,	9,	samplerShadowMipmap);
3777 
3778 	static const TextureSpec tex1DArrayTexelFetchFixed	(TEXTURETYPE_1D_ARRAY,	GL_RGBA8,	256,	1,	4,	9,	samplerTexelFetch);
3779 	static const TextureSpec tex1DArrayTexelFetchFloat	(TEXTURETYPE_1D_ARRAY,	GL_RGBA16F,	256,	1,	4,	9,	samplerTexelFetch);
3780 	static const TextureSpec tex1DArrayTexelFetchInt	(TEXTURETYPE_1D_ARRAY,	GL_RGBA8I,	256,	1,	4,	9,	samplerTexelFetch);
3781 	static const TextureSpec tex1DArrayTexelFetchUint	(TEXTURETYPE_1D_ARRAY,	GL_RGBA8UI,	256,	1,	4,	9,	samplerTexelFetch);
3782 
3783 	static const TextureSpec texCubeArrayFixed			(TEXTURETYPE_CUBE_ARRAY,	GL_RGBA8,	64,		64,		12,	1,	samplerLinearNoMipmap);
3784 	static const TextureSpec texCubeArrayFloat			(TEXTURETYPE_CUBE_ARRAY,	GL_RGBA16F,	64,		64,		12,	1,	samplerLinearNoMipmap);
3785 	static const TextureSpec texCubeArrayInt			(TEXTURETYPE_CUBE_ARRAY,	GL_RGBA8I,	64,		64,		12,	1,	samplerNearestNoMipmap);
3786 	static const TextureSpec texCubeArrayUint			(TEXTURETYPE_CUBE_ARRAY,	GL_RGBA8UI,	64,		64,		12,	1,	samplerNearestNoMipmap);
3787 	static const TextureSpec texCubeArrayMipmapFixed	(TEXTURETYPE_CUBE_ARRAY,	GL_RGBA8,	64,		64,		12,	7,	samplerLinearMipmap);
3788 	static const TextureSpec texCubeArrayMipmapFloat	(TEXTURETYPE_CUBE_ARRAY,	GL_RGBA16F,	64,		64,		12,	7,	samplerLinearMipmap);
3789 	static const TextureSpec texCubeArrayMipmapInt		(TEXTURETYPE_CUBE_ARRAY,	GL_RGBA8I,	64,		64,		12,	7,	samplerNearestMipmap);
3790 	static const TextureSpec texCubeArrayMipmapUint		(TEXTURETYPE_CUBE_ARRAY,	GL_RGBA8UI,	64,		64,		12,	7,	samplerNearestMipmap);
3791 
3792 	static const TextureSpec texCubeArrayShadow			(TEXTURETYPE_CUBE_ARRAY,	GL_DEPTH_COMPONENT16,	64,		64,		12,	1,	samplerShadowNoMipmap);
3793 	static const TextureSpec texCubeArrayMipmapShadow	(TEXTURETYPE_CUBE_ARRAY,	GL_DEPTH_COMPONENT16,	64,		64,		12,	7,	samplerShadowMipmap);
3794 
3795 	// texture() cases
3796 	static const TexFuncCaseSpec textureCases[] =
3797 	{
3798 		//		  Name							Function			MinCoord							MaxCoord							Bias?	MinLod	MaxLod	Offset?	Offset		Format					EvalFunc				Flags
3799 		CASE_SPEC(sampler2d_fixed,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DFixed,				evalTexture2D,			VERTEX),
3800 		CASE_SPEC(sampler2d_fixed,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DMipmapFixed,		evalTexture2D,			FRAGMENT),
3801 		CASE_SPEC(sampler2d_float,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DFloat,				evalTexture2D,			VERTEX),
3802 		CASE_SPEC(sampler2d_float,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DMipmapFloat,		evalTexture2D,			FRAGMENT),
3803 		CASE_SPEC(isampler2d,					FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DInt,				evalTexture2D,			VERTEX),
3804 		CASE_SPEC(isampler2d,					FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DMipmapInt,			evalTexture2D,			FRAGMENT),
3805 		CASE_SPEC(usampler2d,					FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DUint,				evalTexture2D,			VERTEX),
3806 		CASE_SPEC(usampler2d,					FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DMipmapUint,		evalTexture2D,			FRAGMENT),
3807 
3808 		CASE_SPEC(sampler2d_bias_fixed,			FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex2DMipmapFixed,		evalTexture2DBias,		FRAGMENT),
3809 		CASE_SPEC(sampler2d_bias_float,			FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex2DMipmapFloat,		evalTexture2DBias,		FRAGMENT),
3810 		CASE_SPEC(isampler2d_bias,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex2DMipmapInt,			evalTexture2DBias,		FRAGMENT),
3811 		CASE_SPEC(usampler2d_bias,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex2DMipmapUint,		evalTexture2DBias,		FRAGMENT),
3812 
3813 		CASE_SPEC(samplercube_fixed,			FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f,  1.01f,  0.0f),	Vec4( 1.0f,  1.0f,  1.01f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	texCubeFixed,			evalTextureCube,		VERTEX),
3814 		CASE_SPEC(samplercube_fixed,			FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f,  1.01f,  0.0f),	Vec4( 1.0f,  1.0f,  1.01f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	texCubeMipmapFixed,		evalTextureCube,		FRAGMENT),
3815 		CASE_SPEC(samplercube_float,			FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f, -1.01f,  0.0f),	Vec4( 1.0f,  1.0f, -1.01f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	texCubeFloat,			evalTextureCube,		VERTEX),
3816 		CASE_SPEC(samplercube_float,			FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f, -1.01f,  0.0f),	Vec4( 1.0f,  1.0f, -1.01f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	texCubeMipmapFloat,		evalTextureCube,		FRAGMENT),
3817 		CASE_SPEC(isamplercube,					FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f,  1.01f,  0.0f),	Vec4( 1.0f,  1.0f,  1.01f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	texCubeInt,				evalTextureCube,		VERTEX),
3818 		CASE_SPEC(isamplercube,					FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f,  1.01f,  0.0f),	Vec4( 1.0f,  1.0f,  1.01f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	texCubeMipmapInt,		evalTextureCube,		FRAGMENT),
3819 		CASE_SPEC(usamplercube,					FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f, -1.01f,  0.0f),	Vec4( 1.0f,  1.0f, -1.01f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	texCubeUint,			evalTextureCube,		VERTEX),
3820 		CASE_SPEC(usamplercube,					FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f, -1.01f,  0.0f),	Vec4( 1.0f,  1.0f, -1.01f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	texCubeMipmapUint,		evalTextureCube,		FRAGMENT),
3821 
3822 		CASE_SPEC(samplercube_bias_fixed,		FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f,  1.01f,  0.0f),	Vec4( 1.0f,  1.0f,  1.01f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	texCubeMipmapFixed,		evalTextureCubeBias,	FRAGMENT),
3823 		CASE_SPEC(samplercube_bias_float,		FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f, -1.01f,  0.0f),	Vec4( 1.0f,  1.0f, -1.01f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	texCubeMipmapFloat,		evalTextureCubeBias,	FRAGMENT),
3824 		CASE_SPEC(isamplercube_bias,			FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f,  1.01f,  0.0f),	Vec4( 1.0f,  1.0f,  1.01f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	texCubeMipmapInt,		evalTextureCubeBias,	FRAGMENT),
3825 		CASE_SPEC(usamplercube_bias,			FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f, -1.01f,  0.0f),	Vec4( 1.0f,  1.0f, -1.01f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	texCubeMipmapUint,		evalTextureCubeBias,	FRAGMENT),
3826 
3827 		CASE_SPEC(sampler2darray_fixed,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DArrayFixed,		evalTexture2DArray,		VERTEX),
3828 		CASE_SPEC(sampler2darray_fixed,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DArrayMipmapFixed,	evalTexture2DArray,		FRAGMENT),
3829 		CASE_SPEC(sampler2darray_float,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DArrayFloat,		evalTexture2DArray,		VERTEX),
3830 		CASE_SPEC(sampler2darray_float,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DArrayMipmapFloat,	evalTexture2DArray,		FRAGMENT),
3831 		CASE_SPEC(isampler2darray,				FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DArrayInt,			evalTexture2DArray,		VERTEX),
3832 		CASE_SPEC(isampler2darray,				FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DArrayMipmapInt,	evalTexture2DArray,		FRAGMENT),
3833 		CASE_SPEC(usampler2darray,				FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DArrayUint,			evalTexture2DArray,		VERTEX),
3834 		CASE_SPEC(usampler2darray,				FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DArrayMipmapUint,	evalTexture2DArray,		FRAGMENT),
3835 
3836 		CASE_SPEC(sampler2darray_bias_fixed,	FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex2DArrayMipmapFixed,	evalTexture2DArrayBias,	FRAGMENT),
3837 		CASE_SPEC(sampler2darray_bias_float,	FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex2DArrayMipmapFloat,	evalTexture2DArrayBias,	FRAGMENT),
3838 		CASE_SPEC(isampler2darray_bias,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex2DArrayMipmapInt,	evalTexture2DArrayBias,	FRAGMENT),
3839 		CASE_SPEC(usampler2darray_bias,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex2DArrayMipmapUint,	evalTexture2DArrayBias,	FRAGMENT),
3840 
3841 		CASE_SPEC(sampler3d_fixed,				FUNCTION_TEXTURE,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex3DFixed,				evalTexture3D,			VERTEX),
3842 		CASE_SPEC(sampler3d_fixed,				FUNCTION_TEXTURE,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex3DMipmapFixed,		evalTexture3D,			FRAGMENT),
3843 		CASE_SPEC(sampler3d_float,				FUNCTION_TEXTURE,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex3DFloat,				evalTexture3D,			VERTEX),
3844 		CASE_SPEC(sampler3d_float,				FUNCTION_TEXTURE,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex3DMipmapFloat,		evalTexture3D,			FRAGMENT),
3845 		CASE_SPEC(isampler3d,					FUNCTION_TEXTURE,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex3DInt,				evalTexture3D,			VERTEX),
3846 		CASE_SPEC(isampler3d,					FUNCTION_TEXTURE,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex3DMipmapInt,			evalTexture3D,			FRAGMENT),
3847 		CASE_SPEC(usampler3d,					FUNCTION_TEXTURE,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex3DUint,				evalTexture3D,			VERTEX),
3848 		CASE_SPEC(usampler3d,					FUNCTION_TEXTURE,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex3DMipmapUint,		evalTexture3D,			FRAGMENT),
3849 
3850 		CASE_SPEC(sampler3d_bias_fixed,			FUNCTION_TEXTURE,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	true,	-2.0f,	1.0f,	false,	IVec3(0),	tex3DMipmapFixed,		evalTexture3DBias,		FRAGMENT),
3851 		CASE_SPEC(sampler3d_bias_float,			FUNCTION_TEXTURE,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	true,	-2.0f,	1.0f,	false,	IVec3(0),	tex3DMipmapFloat,		evalTexture3DBias,		FRAGMENT),
3852 		CASE_SPEC(isampler3d_bias,				FUNCTION_TEXTURE,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex3DMipmapInt,			evalTexture3DBias,		FRAGMENT),
3853 		CASE_SPEC(usampler3d_bias,				FUNCTION_TEXTURE,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex3DMipmapUint,		evalTexture3DBias,		FRAGMENT),
3854 
3855 		CASE_SPEC(sampler1d_fixed,				FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DFixed,				evalTexture1D,			VERTEX),
3856 		CASE_SPEC(sampler1d_fixed,				FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DMipmapFixed,		evalTexture1D,			FRAGMENT),
3857 		CASE_SPEC(sampler1d_float,				FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DFloat,				evalTexture1D,			VERTEX),
3858 		CASE_SPEC(sampler1d_float,				FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DMipmapFloat,		evalTexture1D,			FRAGMENT),
3859 		CASE_SPEC(isampler1d,					FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DInt,				evalTexture1D,			VERTEX),
3860 		CASE_SPEC(isampler1d,					FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DMipmapInt,			evalTexture1D,			FRAGMENT),
3861 		CASE_SPEC(usampler1d,					FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DUint,				evalTexture1D,			VERTEX),
3862 		CASE_SPEC(usampler1d,					FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DMipmapUint,		evalTexture1D,			FRAGMENT),
3863 
3864 		CASE_SPEC(sampler1d_bias_fixed,			FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex1DMipmapFixed,		evalTexture1DBias,		FRAGMENT),
3865 		CASE_SPEC(sampler1d_bias_float,			FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex1DMipmapFloat,		evalTexture1DBias,		FRAGMENT),
3866 		CASE_SPEC(isampler1d_bias,				FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex1DMipmapInt,			evalTexture1DBias,		FRAGMENT),
3867 		CASE_SPEC(usampler1d_bias,				FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex1DMipmapUint,		evalTexture1DBias,		FRAGMENT),
3868 
3869 		CASE_SPEC(sampler1darray_fixed,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DArrayFixed,		evalTexture1DArray,		VERTEX),
3870 		CASE_SPEC(sampler1darray_fixed,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DArrayMipmapFixed,	evalTexture1DArray,		FRAGMENT),
3871 		CASE_SPEC(sampler1darray_float,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DArrayFloat,		evalTexture1DArray,		VERTEX),
3872 		CASE_SPEC(sampler1darray_float,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DArrayMipmapFloat,	evalTexture1DArray,		FRAGMENT),
3873 		CASE_SPEC(isampler1darray,				FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DArrayInt,			evalTexture1DArray,		VERTEX),
3874 		CASE_SPEC(isampler1darray,				FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DArrayMipmapInt,	evalTexture1DArray,		FRAGMENT),
3875 		CASE_SPEC(usampler1darray,				FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DArrayUint,			evalTexture1DArray,		VERTEX),
3876 		CASE_SPEC(usampler1darray,				FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DArrayMipmapUint,	evalTexture1DArray,		FRAGMENT),
3877 
3878 		CASE_SPEC(sampler1darray_bias_fixed,	FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex1DArrayMipmapFixed,	evalTexture1DArrayBias,	FRAGMENT),
3879 		CASE_SPEC(sampler1darray_bias_float,	FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex1DArrayMipmapFloat,	evalTexture1DArrayBias,	FRAGMENT),
3880 		CASE_SPEC(isampler1darray_bias,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex1DArrayMipmapInt,	evalTexture1DArrayBias,	FRAGMENT),
3881 		CASE_SPEC(usampler1darray_bias,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex1DArrayMipmapUint,	evalTexture1DArrayBias,	FRAGMENT),
3882 
3883 		CASE_SPEC(samplercubearray_fixed,		FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f,  1.01f, -0.5f),	Vec4( 1.0f,  1.0f,  1.01f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	texCubeArrayFixed,			evalTextureCubeArray,		VERTEX),
3884 		CASE_SPEC(samplercubearray_fixed,		FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f,  1.01f, -0.5f),	Vec4( 1.0f,  1.0f,  1.01f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	texCubeArrayMipmapFixed,	evalTextureCubeArray,		FRAGMENT),
3885 		CASE_SPEC(samplercubearray_float,		FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f, -1.01f, -0.5f),	Vec4( 1.0f,  1.0f, -1.01f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	texCubeArrayFloat,			evalTextureCubeArray,		VERTEX),
3886 		CASE_SPEC(samplercubearray_float,		FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f, -1.01f, -0.5f),	Vec4( 1.0f,  1.0f, -1.01f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	texCubeArrayMipmapFloat,	evalTextureCubeArray,		FRAGMENT),
3887 		CASE_SPEC(isamplercubearray,			FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f,  1.01f, -0.5f),	Vec4( 1.0f,  1.0f,  1.01f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	texCubeArrayInt,			evalTextureCubeArray,		VERTEX),
3888 		CASE_SPEC(isamplercubearray,			FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f,  1.01f, -0.5f),	Vec4( 1.0f,  1.0f,  1.01f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	texCubeArrayMipmapInt,		evalTextureCubeArray,		FRAGMENT),
3889 		CASE_SPEC(usamplercubearray,			FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f, -1.01f, -0.5f),	Vec4( 1.0f,  1.0f, -1.01f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	texCubeArrayUint,			evalTextureCubeArray,		VERTEX),
3890 		CASE_SPEC(usamplercubearray,			FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f, -1.01f, -0.5f),	Vec4( 1.0f,  1.0f, -1.01f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	texCubeArrayMipmapUint,		evalTextureCubeArray,		FRAGMENT),
3891 
3892 		CASE_SPEC(samplercubearray_bias_fixed,	FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f,  1.01f, -0.5f),	Vec4( 1.0f,  1.0f,  1.01f,  1.5f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	texCubeArrayMipmapFixed,	evalTextureCubeArrayBias,	FRAGMENT),
3893 		CASE_SPEC(samplercubearray_bias_float,	FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f, -1.01f, -0.5f),	Vec4( 1.0f,  1.0f, -1.01f,  1.5f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	texCubeArrayMipmapFloat,	evalTextureCubeArrayBias,	FRAGMENT),
3894 		CASE_SPEC(isamplercubearray_bias,		FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f,  1.01f, -0.5f),	Vec4( 1.0f,  1.0f,  1.01f,  1.5f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	texCubeArrayMipmapInt,		evalTextureCubeArrayBias,	FRAGMENT),
3895 		CASE_SPEC(usamplercubearray_bias,		FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f, -1.01f, -0.5f),	Vec4( 1.0f,  1.0f, -1.01f,  1.5f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	texCubeArrayMipmapUint,		evalTextureCubeArrayBias,	FRAGMENT),
3896 
3897 		CASE_SPEC(sampler2dshadow,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  1.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DShadow,			evalTexture2DShadow,			VERTEX),
3898 		CASE_SPEC(sampler2dshadow,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  1.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DMipmapShadow,		evalTexture2DShadow,			FRAGMENT),
3899 		CASE_SPEC(sampler2dshadow_bias,			FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  1.0f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex2DMipmapShadow,		evalTexture2DShadowBias,		FRAGMENT),
3900 
3901 		CASE_SPEC(samplercubeshadow,			FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f,  1.01f,  0.0f),	Vec4( 1.0f,  1.0f,  1.01f,  1.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	texCubeShadow,			evalTextureCubeShadow,			VERTEX),
3902 		CASE_SPEC(samplercubeshadow,			FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f,  1.01f,  0.0f),	Vec4( 1.0f,  1.0f,  1.01f,  1.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	texCubeMipmapShadow,	evalTextureCubeShadow,			FRAGMENT),
3903 		CASE_SPEC(samplercubeshadow_bias,		FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f,  1.01f,  0.0f),	Vec4( 1.0f,  1.0f,  1.01f,  1.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	texCubeMipmapShadow,	evalTextureCubeShadowBias,		FRAGMENT),
3904 
3905 		CASE_SPEC(sampler2darrayshadow,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  1.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DArrayShadow,		evalTexture2DArrayShadow,		VERTEX),
3906 		CASE_SPEC(sampler2darrayshadow,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  1.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DArrayMipmapShadow,	evalTexture2DArrayShadow,		FRAGMENT),
3907 
3908 		CASE_SPEC(sampler1dshadow,				FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  1.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DShadow,			evalTexture1DShadow,			VERTEX),
3909 		CASE_SPEC(sampler1dshadow,				FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  1.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DMipmapShadow,		evalTexture1DShadow,			FRAGMENT),
3910 		CASE_SPEC(sampler1dshadow_bias,			FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  1.0f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex1DMipmapShadow,		evalTexture1DShadowBias,		FRAGMENT),
3911 
3912 		CASE_SPEC(sampler1darrayshadow,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  1.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DArrayShadow,		evalTexture1DArrayShadow,		VERTEX),
3913 		CASE_SPEC(sampler1darrayshadow,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  1.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DArrayMipmapShadow,	evalTexture1DArrayShadow,		FRAGMENT),
3914 		CASE_SPEC(sampler1darrayshadow_bias,	FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  1.0f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex1DArrayMipmapShadow,	evalTexture1DArrayShadowBias,	FRAGMENT),
3915 
3916 		CASE_SPEC(samplercubearrayshadow,		FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f,  1.01f, -0.5f),	Vec4( 1.0f,  1.0f,  1.01f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	texCubeArrayMipmapShadow,	evalTextureCubeArrayShadow,		FRAGMENT),
3917 	};
3918 	createCaseGroup(this, "texture", textureCases, DE_LENGTH_OF_ARRAY(textureCases));
3919 
3920 	// textureClampARB() cases
3921 	static const TexFuncCaseSpec textureClampARBCases[] =
3922 	{
3923 		//			    Name							Function			MinCoord						MaxCoord							Bias?	MinLod	MaxLod	Offset?	Offset		LodClamp	Format					EvalFunc							Flags
3924 		CLAMP_CASE_SPEC(sampler2d_bias_fixed,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4(1.0f, 1.0f, 0.0f, 0.0f),		true,	0.0f,	5.0f,	false,	IVec3(0),	5.0f,	tex2DMipmapFixed,			evalTexture2DBiasClamp,				FRAGMENT),
3925 		CLAMP_CASE_SPEC(sampler2d_bias_float,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4(1.0f, 1.0f, 0.0f, 0.0f),		true,	0.0f,	5.0f,	false,	IVec3(0),	5.0f,	tex2DMipmapFloat,			evalTexture2DBiasClamp,				FRAGMENT),
3926 		CLAMP_CASE_SPEC(isampler2d_bias,				FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4(6.0f, 6.0f, 0.0f, 0.0f),		true,	2.0f,	5.0f,	false,	IVec3(0),	7.0f,	tex2DMipmapInt,				evalTexture2DBiasClamp,				FRAGMENT),
3927 		CLAMP_CASE_SPEC(usampler2d_bias,				FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4(6.0f, 6.0f, 0.0f, 0.0f),		true,	2.0f,	5.0f,	false,	IVec3(0),	7.0f,	tex2DMipmapUint,			evalTexture2DBiasClamp,				FRAGMENT),
3928 
3929 		CLAMP_CASE_SPEC(samplercube_bias_fixed,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 1.01f, 0.0f),	Vec4(1.0f, 1.0f, 1.01f, 0.0f),		true,	0.0f,	5.0f,	false,	IVec3(0),	4.0f,	texCubeMipmapFixed,			evalTextureCubeBiasClamp,			FRAGMENT),
3930 		CLAMP_CASE_SPEC(samplercube_bias_float,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 1.01f, 0.0f),	Vec4(1.0f, 1.0f, 1.01f, 0.0f),		true,	0.0f,	5.0f,	false,	IVec3(0),	4.0f,	texCubeMipmapFloat,			evalTextureCubeBiasClamp,			FRAGMENT),
3931 		CLAMP_CASE_SPEC(isamplercube_bias,				FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 6.01f, 0.0f),	Vec4(6.0f, 6.0f, 6.01f, 0.0f),		true,	2.0f,	5.0f,	false,	IVec3(0),	6.0f,	texCubeMipmapInt,			evalTextureCubeBiasClamp,			FRAGMENT),
3932 		CLAMP_CASE_SPEC(usamplercube_bias,				FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 6.01f, 0.0f),	Vec4(6.0f, 6.0f, 6.01f, 0.0f),		true,	2.0f,	5.0f,	false,	IVec3(0),	6.0f,	texCubeMipmapUint,			evalTextureCubeBiasClamp,			FRAGMENT),
3933 
3934 		CLAMP_CASE_SPEC(sampler2darray_bias_fixed,		FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(1.0f, 1.0f, 4.0f,  0.0f),		true,	0.0f,	5.0f,	false,	IVec3(0),	5.0f,	tex2DArrayMipmapFixed,		evalTexture2DArrayBiasClamp,		FRAGMENT),
3935 		CLAMP_CASE_SPEC(sampler2darray_bias_float,		FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(1.0f, 1.0f, 4.0f,  0.0f),		true,	0.0f,	5.0f,	false,	IVec3(0),	5.0f,	tex2DArrayMipmapFloat,		evalTexture2DArrayBiasClamp,		FRAGMENT),
3936 		CLAMP_CASE_SPEC(isampler2darray_bias,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(6.0f, 6.0f, 4.0f,  0.0f),		true,	2.0f,	5.0f,	false,	IVec3(0),	7.0f,	tex2DArrayMipmapInt,		evalTexture2DArrayBiasClamp,		FRAGMENT),
3937 		CLAMP_CASE_SPEC(usampler2darray_bias,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(6.0f, 6.0f, 4.0f,  0.0f),		true,	2.0f,	5.0f,	false,	IVec3(0),	7.0f,	tex2DArrayMipmapUint,		evalTexture2DArrayBiasClamp,		FRAGMENT),
3938 
3939 		CLAMP_CASE_SPEC(sampler3d_bias_fixed,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(1.0f, 1.0f, 4.0f,  0.0f),		true,	-10.0f,	10.0f,	false,	IVec3(0),	0.0f,	tex3DMipmapFixed,			evalTexture3DBiasClamp,				FRAGMENT),
3940 		CLAMP_CASE_SPEC(sampler3d_bias_float,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(1.0f, 1.0f, 4.0f,  0.0f),		true,	-10.0f,	10.0f,	false,	IVec3(0),	0.0f,	tex3DMipmapFloat,			evalTexture3DBiasClamp,				FRAGMENT),
3941 		CLAMP_CASE_SPEC(isampler3d_bias,				FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(6.0f, 6.0f, 4.0f,  0.0f),		true,	0.0f,	8.0f,	false,	IVec3(0),	5.0f,	tex3DMipmapInt,				evalTexture3DBiasClamp,				FRAGMENT),
3942 		CLAMP_CASE_SPEC(usampler3d_bias,				FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(6.0f, 6.0f, 4.0f,  0.0f),		true,	0.0f,	8.0f,	false,	IVec3(0),	5.0f,	tex3DMipmapUint,			evalTexture3DBiasClamp,				FRAGMENT),
3943 
3944 		CLAMP_CASE_SPEC(sampler1d_bias_fixed,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(1.0f, 0.0f, 0.0f,  0.0f),		true,	0.0f,	5.0f,	false,	IVec3(0),	4.0f,	tex1DMipmapFixed,			evalTexture1DBiasClamp,				FRAGMENT),
3945 		CLAMP_CASE_SPEC(sampler1d_bias_float,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(1.0f, 0.0f, 0.0f,  0.0f),		true,	0.0f,	5.0f,	false,	IVec3(0),	4.0f,	tex1DMipmapFloat,			evalTexture1DBiasClamp,				FRAGMENT),
3946 		CLAMP_CASE_SPEC(isampler1d_bias,				FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(6.0f, 0.0f, 0.0f,  0.0f),		true,	2.0f,	5.0f,	false,	IVec3(0),	7.0f,	tex1DMipmapInt,				evalTexture1DBiasClamp,				FRAGMENT),
3947 		CLAMP_CASE_SPEC(usampler1d_bias,				FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(6.0f, 0.0f, 0.0f,  0.0f),		true,	2.0f,	5.0f,	false,	IVec3(0),	7.0f,	tex1DMipmapUint,			evalTexture1DBiasClamp,				FRAGMENT),
3948 
3949 		CLAMP_CASE_SPEC(sampler1darray_bias_fixed,		FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(1.0f,  4.0f,  0.0f,  0.0f),	true,	0.0f,	5.0f,	false,	IVec3(0),	5.0f,	tex1DArrayMipmapFixed,		evalTexture1DArrayBiasClamp,		FRAGMENT),
3950 		CLAMP_CASE_SPEC(sampler1darray_bias_float,		FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(1.0f,  4.0f,  0.0f,  0.0f),	true,	0.0f,	5.0f,	false,	IVec3(0),	5.0f,	tex1DArrayMipmapFloat,		evalTexture1DArrayBiasClamp,		FRAGMENT),
3951 		CLAMP_CASE_SPEC(isampler1darray_bias,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(6.0f,  4.0f,  0.0f,  0.0f),	true,	2.0f,	5.0f,	false,	IVec3(0),	7.0f,	tex1DArrayMipmapInt,		evalTexture1DArrayBiasClamp,		FRAGMENT),
3952 		CLAMP_CASE_SPEC(usampler1darray_bias,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(6.0f,  4.0f,  0.0f,  0.0f),	true,	2.0f,	5.0f,	false,	IVec3(0),	7.0f,	tex1DArrayMipmapUint,		evalTexture1DArrayBiasClamp,		FRAGMENT),
3953 
3954 		CLAMP_CASE_SPEC(samplercubearray_bias_fixed,	FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 1.01f, 0.0f),	Vec4(1.0f,  1.0f, 1.01f,  2.0f),	true,	0.0f,	5.0f,	false,	IVec3(0),	3.0f,	texCubeArrayMipmapFixed,	evalTextureCubeArrayBiasClamp,		FRAGMENT),
3955 		CLAMP_CASE_SPEC(samplercubearray_bias_float,	FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 1.01f, 0.0f),	Vec4(1.0f,  1.0f, 1.01f,  2.0f),	true,	0.0f,	5.0f,	false,	IVec3(0),	3.0f,	texCubeArrayMipmapFloat,	evalTextureCubeArrayBiasClamp,		FRAGMENT),
3956 		CLAMP_CASE_SPEC(isamplercubearray_bias,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 6.01f, 0.0f),	Vec4(6.0f,  6.0f, 6.01f,  2.0f),	true,	2.0f,	5.0f,	false,	IVec3(0),	4.0f,	texCubeArrayMipmapInt,		evalTextureCubeArrayBiasClamp,		FRAGMENT),
3957 		CLAMP_CASE_SPEC(usamplercubearray_bias,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 6.01f, 0.0f),	Vec4(6.0f,  6.0f, 6.01f,  2.0f),	true,	2.0f,	5.0f,	false,	IVec3(0),	4.0f,	texCubeArrayMipmapUint,		evalTextureCubeArrayBiasClamp,		FRAGMENT),
3958 
3959 		CLAMP_CASE_SPEC(sampler2dshadow_bias,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4( 1.0f,  1.0f,  1.0f,  0.0f),	true,	0.0f,	5.0f,	false,	IVec3(0),	7.0f,	tex2DMipmapShadow,			evalTexture2DShadowBiasClamp,		FRAGMENT),
3960 		CLAMP_CASE_SPEC(samplercubeshadow_bias,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 1.01f,  0.0f),	Vec4( 1.0f,  1.0f,  1.01f, 0.0f),	true,	0.0f,	5.0f,	false,	IVec3(0),	7.0f,	texCubeMipmapShadow,		evalTextureCubeShadowBiasClamp,		FRAGMENT),
3961 		CLAMP_CASE_SPEC(sampler1dshadow_bias,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4( 1.0f,  0.0f,  1.0f,  0.0f),	true,	0.0f,	5.0f,	false,	IVec3(0),	7.0f,	tex1DMipmapShadow,			evalTexture1DShadowBiasClamp,		FRAGMENT),
3962 		CLAMP_CASE_SPEC(sampler1darrayshadow_bias,		FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4( 1.0f,  4.0f,  1.0f,  0.0f),	true,	0.0f,	5.0f,	false,	IVec3(0),	7.0f,	tex1DArrayMipmapShadow,		evalTexture1DArrayShadowBiasClamp,	FRAGMENT),
3963 	};
3964 	createCaseGroup(this, "textureclamp", textureClampARBCases, DE_LENGTH_OF_ARRAY(textureClampARBCases));
3965 
3966 	// textureOffset() cases
3967 	// \note _bias variants are not using mipmap thanks to wide allowed range for LOD computation
3968 	static const TexFuncCaseSpec textureOffsetCases[] =
3969 	{
3970 		//		  Name							Function			MinCoord							MaxCoord							Bias?	MinLod	MaxLod	Offset?	Offset				Format					EvalFunc						Flags
3971 		CASE_SPEC(sampler2d_fixed,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DFixed,				evalTexture2DOffset,			VERTEX),
3972 		CASE_SPEC(sampler2d_fixed,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapFixed,		evalTexture2DOffset,			FRAGMENT),
3973 		CASE_SPEC(sampler2d_float,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DFloat,				evalTexture2DOffset,			VERTEX),
3974 		CASE_SPEC(sampler2d_float,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapFloat,		evalTexture2DOffset,			FRAGMENT),
3975 		CASE_SPEC(isampler2d,					FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DInt,				evalTexture2DOffset,			VERTEX),
3976 		CASE_SPEC(isampler2d,					FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapInt,			evalTexture2DOffset,			FRAGMENT),
3977 		CASE_SPEC(usampler2d,					FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DUint,				evalTexture2DOffset,			VERTEX),
3978 		CASE_SPEC(usampler2d,					FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapUint,		evalTexture2DOffset,			FRAGMENT),
3979 
3980 		CASE_SPEC(sampler2d_bias_fixed,			FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 7, 0),	tex2DFixed,				evalTexture2DOffsetBias,		FRAGMENT),
3981 		CASE_SPEC(sampler2d_bias_float,			FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(7, -8, 0),	tex2DFloat,				evalTexture2DOffsetBias,		FRAGMENT),
3982 		CASE_SPEC(isampler2d_bias,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 7, 0),	tex2DInt,				evalTexture2DOffsetBias,		FRAGMENT),
3983 		CASE_SPEC(usampler2d_bias,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(7, -8, 0),	tex2DUint,				evalTexture2DOffsetBias,		FRAGMENT),
3984 
3985 		CASE_SPEC(sampler2darray_fixed,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DArrayFixed,		evalTexture2DArrayOffset,		VERTEX),
3986 		CASE_SPEC(sampler2darray_fixed,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7, -8, 0),	tex2DArrayMipmapFixed,	evalTexture2DArrayOffset,		FRAGMENT),
3987 		CASE_SPEC(sampler2darray_float,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DArrayFloat,		evalTexture2DArrayOffset,		VERTEX),
3988 		CASE_SPEC(sampler2darray_float,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7, -8, 0),	tex2DArrayMipmapFloat,	evalTexture2DArrayOffset,		FRAGMENT),
3989 		CASE_SPEC(isampler2darray,				FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DArrayInt,			evalTexture2DArrayOffset,		VERTEX),
3990 		CASE_SPEC(isampler2darray,				FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7, -8, 0),	tex2DArrayMipmapInt,	evalTexture2DArrayOffset,		FRAGMENT),
3991 		CASE_SPEC(usampler2darray,				FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DArrayUint,			evalTexture2DArrayOffset,		VERTEX),
3992 		CASE_SPEC(usampler2darray,				FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7, -8, 0),	tex2DArrayMipmapUint,	evalTexture2DArrayOffset,		FRAGMENT),
3993 
3994 		CASE_SPEC(sampler2darray_bias_fixed,	FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 7, 0),	tex2DArrayFixed,		evalTexture2DArrayOffsetBias,	FRAGMENT),
3995 		CASE_SPEC(sampler2darray_bias_float,	FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(7, -8, 0),	tex2DArrayFloat,		evalTexture2DArrayOffsetBias,	FRAGMENT),
3996 		CASE_SPEC(isampler2darray_bias,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 7, 0),	tex2DArrayInt,			evalTexture2DArrayOffsetBias,	FRAGMENT),
3997 		CASE_SPEC(usampler2darray_bias,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(7, -8, 0),	tex2DArrayUint,			evalTexture2DArrayOffsetBias,	FRAGMENT),
3998 
3999 		CASE_SPEC(sampler3d_fixed,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 3),	tex3DFixed,				evalTexture3DOffset,			VERTEX),
4000 		CASE_SPEC(sampler3d_fixed,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7, 3, -8),	tex3DMipmapFixed,		evalTexture3DOffset,			FRAGMENT),
4001 		CASE_SPEC(sampler3d_float,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(3, -8, 7),	tex3DFloat,				evalTexture3DOffset,			VERTEX),
4002 		CASE_SPEC(sampler3d_float,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 3),	tex3DMipmapFloat,		evalTexture3DOffset,			FRAGMENT),
4003 		CASE_SPEC(isampler3d,					FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7, 3, -8),	tex3DInt,				evalTexture3DOffset,			VERTEX),
4004 		CASE_SPEC(isampler3d,					FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(3, -8, 7),	tex3DMipmapInt,			evalTexture3DOffset,			FRAGMENT),
4005 		CASE_SPEC(usampler3d,					FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 3),	tex3DUint,				evalTexture3DOffset,			VERTEX),
4006 		CASE_SPEC(usampler3d,					FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7, 3, -8),	tex3DMipmapUint,		evalTexture3DOffset,			FRAGMENT),
4007 
4008 		CASE_SPEC(sampler3d_bias_fixed,			FUNCTION_TEXTURE,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	true,	-2.0f,	1.0f,	true,	IVec3(-8, 7, 3),	tex3DFixed,				evalTexture3DOffsetBias,		FRAGMENT),
4009 		CASE_SPEC(sampler3d_bias_float,			FUNCTION_TEXTURE,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	true,	-2.0f,	1.0f,	true,	IVec3(7, 3, -8),	tex3DFloat,				evalTexture3DOffsetBias,		FRAGMENT),
4010 		CASE_SPEC(isampler3d_bias,				FUNCTION_TEXTURE,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(3, -8, 7),	tex3DInt,				evalTexture3DOffsetBias,		FRAGMENT),
4011 		CASE_SPEC(usampler3d_bias,				FUNCTION_TEXTURE,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 7, 3),	tex3DUint,				evalTexture3DOffsetBias,		FRAGMENT),
4012 
4013 		CASE_SPEC(sampler1d_fixed,				FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DFixed,				evalTexture1DOffset,			VERTEX),
4014 		CASE_SPEC(sampler1d_fixed,				FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3( 7, 0, 0),	tex1DMipmapFixed,		evalTexture1DOffset,			FRAGMENT),
4015 		CASE_SPEC(sampler1d_float,				FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DFloat,				evalTexture1DOffset,			VERTEX),
4016 		CASE_SPEC(sampler1d_float,				FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3( 7, 0, 0),	tex1DMipmapFloat,		evalTexture1DOffset,			FRAGMENT),
4017 		CASE_SPEC(isampler1d,					FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DInt,				evalTexture1DOffset,			VERTEX),
4018 		CASE_SPEC(isampler1d,					FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3( 7, 0, 0),	tex1DMipmapInt,			evalTexture1DOffset,			FRAGMENT),
4019 		CASE_SPEC(usampler1d,					FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DUint,				evalTexture1DOffset,			VERTEX),
4020 		CASE_SPEC(usampler1d,					FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3( 7, 0, 0),	tex1DMipmapUint,		evalTexture1DOffset,			FRAGMENT),
4021 
4022 		CASE_SPEC(sampler1d_bias_fixed,			FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 0, 0),	tex1DFixed,				evalTexture1DOffsetBias,		FRAGMENT),
4023 		CASE_SPEC(sampler1d_bias_float,			FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3( 7, 0, 0),	tex1DFloat,				evalTexture1DOffsetBias,		FRAGMENT),
4024 		CASE_SPEC(isampler1d_bias,				FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 0, 0),	tex1DInt,				evalTexture1DOffsetBias,		FRAGMENT),
4025 		CASE_SPEC(usampler1d_bias,				FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3( 7, 0, 0),	tex1DUint,				evalTexture1DOffsetBias,		FRAGMENT),
4026 
4027 		CASE_SPEC(sampler1darray_fixed,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DArrayFixed,		evalTexture1DArrayOffset,		VERTEX),
4028 		CASE_SPEC(sampler1darray_fixed,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3( 7, 0, 0),	tex1DArrayMipmapFixed,	evalTexture1DArrayOffset,		FRAGMENT),
4029 		CASE_SPEC(sampler1darray_float,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DArrayFloat,		evalTexture1DArrayOffset,		VERTEX),
4030 		CASE_SPEC(sampler1darray_float,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3( 7, 0, 0),	tex1DArrayMipmapFloat,	evalTexture1DArrayOffset,		FRAGMENT),
4031 		CASE_SPEC(isampler1darray,				FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DArrayInt,			evalTexture1DArrayOffset,		VERTEX),
4032 		CASE_SPEC(isampler1darray,				FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3( 7, 0, 0),	tex1DArrayMipmapInt,	evalTexture1DArrayOffset,		FRAGMENT),
4033 		CASE_SPEC(usampler1darray,				FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DArrayUint,			evalTexture1DArrayOffset,		VERTEX),
4034 		CASE_SPEC(usampler1darray,				FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3( 7, 0, 0),	tex1DArrayMipmapUint,	evalTexture1DArrayOffset,		FRAGMENT),
4035 
4036 		CASE_SPEC(sampler1darray_bias_fixed,	FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f, -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 0, 0),	tex1DArrayFixed,		evalTexture1DArrayOffsetBias,	FRAGMENT),
4037 		CASE_SPEC(sampler1darray_bias_float,	FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3( 7, 0, 0),	tex1DArrayFloat,		evalTexture1DArrayOffsetBias,	FRAGMENT),
4038 		CASE_SPEC(isampler1darray_bias,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 0, 0),	tex1DArrayInt,			evalTexture1DArrayOffsetBias,	FRAGMENT),
4039 		CASE_SPEC(usampler1darray_bias,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3( 7, 0, 0),	tex1DArrayUint,			evalTexture1DArrayOffsetBias,	FRAGMENT),
4040 
4041 		CASE_SPEC(sampler2dshadow,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  1.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DShadow,			evalTexture2DShadowOffset,			VERTEX),
4042 		CASE_SPEC(sampler2dshadow,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  1.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapShadow,		evalTexture2DShadowOffset,			FRAGMENT),
4043 		CASE_SPEC(sampler2dshadow_bias,			FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  1.0f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 7, 0),	tex2DShadow,			evalTexture2DShadowOffsetBias,		FRAGMENT),
4044 		CASE_SPEC(sampler2darrayshadow,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  1.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DArrayShadow,		evalTexture2DArrayShadowOffset,		VERTEX),
4045 		CASE_SPEC(sampler2darrayshadow,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  1.0f),	false,	0.0f,	0.0f,	true,	IVec3(7, -8, 0),	tex2DArrayMipmapShadow,	evalTexture2DArrayShadowOffset,		FRAGMENT),
4046 		CASE_SPEC(sampler1dshadow,				FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  1.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DShadow,			evalTexture1DShadowOffset,			VERTEX),
4047 		CASE_SPEC(sampler1dshadow,				FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  1.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3( 7, 0, 0),	tex1DMipmapShadow,		evalTexture1DShadowOffset,			FRAGMENT),
4048 		CASE_SPEC(sampler1dshadow_bias,			FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  1.0f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 0, 0),	tex1DShadow,			evalTexture1DShadowOffsetBias,		FRAGMENT),
4049 		CASE_SPEC(sampler1darrayshadow,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  1.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DArrayShadow,		evalTexture1DArrayShadowOffset,		VERTEX),
4050 		CASE_SPEC(sampler1darrayshadow,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  1.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3( 7, 0, 0),	tex1DArrayMipmapShadow,	evalTexture1DArrayShadowOffset,		FRAGMENT),
4051 		CASE_SPEC(sampler1darrayshadow_bias,	FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  1.0f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 0, 0),	tex1DArrayShadow,		evalTexture1DArrayShadowOffsetBias,	FRAGMENT),
4052 	};
4053 	createCaseGroup(this, "textureoffset", textureOffsetCases, DE_LENGTH_OF_ARRAY(textureOffsetCases));
4054 
4055 	// textureOffsetClampARB() cases
4056 	static const TexFuncCaseSpec textureOffsetClampARBCases[] =
4057 	{
4058 		//			    Name							Function			MinCoord						MaxCoord							Bias?	MinLod	MaxLod	Offset?	Offset				LodClamp	Format					EvalFunc									Flags
4059 		CLAMP_CASE_SPEC(sampler2d_bias_fixed,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4(1.0f, 1.0f, 0.0f, 0.0f),		true,	0.0f,	5.0f,	true,	IVec3(7, -8, 0),	5.0f,	tex2DMipmapFixed,			evalTexture2DOffsetBiasClamp,				FRAGMENT),
4060 		CLAMP_CASE_SPEC(sampler2d_bias_float,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4(1.0f, 1.0f, 0.0f, 0.0f),		true,	0.0f,	5.0f,	true,	IVec3(7, -8, 0),	5.0f,	tex2DMipmapFloat,			evalTexture2DOffsetBiasClamp,				FRAGMENT),
4061 		CLAMP_CASE_SPEC(isampler2d_bias,				FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4(6.0f, 6.0f, 0.0f, 0.0f),		true,	2.0f,	5.0f,	true,	IVec3(7, -8, 0),	7.0f,	tex2DMipmapInt,				evalTexture2DOffsetBiasClamp,				FRAGMENT),
4062 		CLAMP_CASE_SPEC(usampler2d_bias,				FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4(6.0f, 6.0f, 0.0f, 0.0f),		true,	2.0f,	5.0f,	true,	IVec3(7, -8, 0),	7.0f,	tex2DMipmapUint,			evalTexture2DOffsetBiasClamp,				FRAGMENT),
4063 
4064 		CLAMP_CASE_SPEC(sampler2darray_bias_fixed,		FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(1.0f, 1.0f, 4.0f,  0.0f),		true,	0.0f,	5.0f,	true,	IVec3(7, -8, 0),	5.0f,	tex2DArrayMipmapFixed,		evalTexture2DArrayOffsetBiasClamp,			FRAGMENT),
4065 		CLAMP_CASE_SPEC(sampler2darray_bias_float,		FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(1.0f, 1.0f, 4.0f,  0.0f),		true,	0.0f,	5.0f,	true,	IVec3(7, -8, 0),	5.0f,	tex2DArrayMipmapFloat,		evalTexture2DArrayOffsetBiasClamp,			FRAGMENT),
4066 		CLAMP_CASE_SPEC(isampler2darray_bias,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(6.0f, 6.0f, 4.0f,  0.0f),		true,	2.0f,	5.0f,	true,	IVec3(7, -8, 0),	7.0f,	tex2DArrayMipmapInt,		evalTexture2DArrayOffsetBiasClamp,			FRAGMENT),
4067 		CLAMP_CASE_SPEC(usampler2darray_bias,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(6.0f, 6.0f, 4.0f,  0.0f),		true,	2.0f,	5.0f,	true,	IVec3(7, -8, 0),	7.0f,	tex2DArrayMipmapUint,		evalTexture2DArrayOffsetBiasClamp,			FRAGMENT),
4068 
4069 		CLAMP_CASE_SPEC(sampler3d_bias_fixed,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(1.0f, 1.0f, 4.0f,  0.0f),		true,	-12.0f,	12.0f,	true,	IVec3(-8, 7, 3),	2.0f,	tex3DMipmapFixed,			evalTexture3DOffsetBiasClamp,				FRAGMENT),
4070 		CLAMP_CASE_SPEC(sampler3d_bias_float,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(1.0f, 1.0f, 4.0f,  0.0f),		true,	-12.0f,	12.0f,	true,	IVec3(-8, 7, 3),	2.0f,	tex3DMipmapFloat,			evalTexture3DOffsetBiasClamp,				FRAGMENT),
4071 		CLAMP_CASE_SPEC(isampler3d_bias,				FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(6.0f, 6.0f, 4.0f,  0.0f),		true,	-5.0f,	5.0f,	true,	IVec3(-8, 7, 3),	1.0f,	tex3DMipmapInt,				evalTexture3DOffsetBiasClamp,				FRAGMENT),
4072 		CLAMP_CASE_SPEC(usampler3d_bias,				FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(6.0f, 6.0f, 4.0f,  0.0f),		true,	-5.0f,	5.0f,	true,	IVec3(-8, 7, 3),	1.0f,	tex3DMipmapUint,			evalTexture3DOffsetBiasClamp,				FRAGMENT),
4073 
4074 		CLAMP_CASE_SPEC(sampler1d_bias_fixed,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(1.0f, 0.0f, 0.0f,  0.0f),		true,	0.0f,	5.0f,	true,	IVec3(-8, 0, 0),	4.0f,	tex1DMipmapFixed,			evalTexture1DOffsetBiasClamp,				FRAGMENT),
4075 		CLAMP_CASE_SPEC(sampler1d_bias_float,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(1.0f, 0.0f, 0.0f,  0.0f),		true,	0.0f,	5.0f,	true,	IVec3( 7, 0, 0),	4.0f,	tex1DMipmapFloat,			evalTexture1DOffsetBiasClamp,				FRAGMENT),
4076 		CLAMP_CASE_SPEC(isampler1d_bias,				FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(6.0f, 0.0f, 0.0f,  0.0f),		true,	2.0f,	5.0f,	true,	IVec3(-8, 0, 0),	7.0f,	tex1DMipmapInt,				evalTexture1DOffsetBiasClamp,				FRAGMENT),
4077 		CLAMP_CASE_SPEC(usampler1d_bias,				FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(6.0f, 0.0f, 0.0f,  0.0f),		true,	2.0f,	5.0f,	true,	IVec3( 7, 0, 0),	7.0f,	tex1DMipmapUint,			evalTexture1DOffsetBiasClamp,				FRAGMENT),
4078 
4079 		CLAMP_CASE_SPEC(sampler1darray_bias_fixed,		FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(1.0f,  4.0f,  0.0f,  0.0f),	true,	0.0f,	5.0f,	true,	IVec3(-8, 0, 0),	5.0f,	tex1DArrayMipmapFixed,		evalTexture1DArrayOffsetBiasClamp,			FRAGMENT),
4080 		CLAMP_CASE_SPEC(sampler1darray_bias_float,		FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(1.0f,  4.0f,  0.0f,  0.0f),	true,	0.0f,	5.0f,	true,	IVec3( 7, 0, 0),	5.0f,	tex1DArrayMipmapFloat,		evalTexture1DArrayOffsetBiasClamp,			FRAGMENT),
4081 		CLAMP_CASE_SPEC(isampler1darray_bias,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(6.0f,  4.0f,  0.0f,  0.0f),	true,	2.0f,	5.0f,	true,	IVec3(-8, 0, 0),	7.0f,	tex1DArrayMipmapInt,		evalTexture1DArrayOffsetBiasClamp,			FRAGMENT),
4082 		CLAMP_CASE_SPEC(usampler1darray_bias,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(6.0f,  4.0f,  0.0f,  0.0f),	true,	2.0f,	5.0f,	true,	IVec3( 7, 0, 0),	7.0f,	tex1DArrayMipmapUint,		evalTexture1DArrayOffsetBiasClamp,			FRAGMENT),
4083 
4084 		CLAMP_CASE_SPEC(sampler2dshadow_bias,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4( 1.0f,  1.0f,  1.0f,  0.0f),	true,	0.0f,	5.0f,	true,	IVec3(-8, 7, 0),	7.0f,	tex2DMipmapShadow,			evalTexture2DShadowOffsetBiasClamp,			FRAGMENT),
4085 		CLAMP_CASE_SPEC(sampler1dshadow_bias,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4( 1.0f,  0.0f,  1.0f,  0.0f),	true,	0.0f,	5.0f,	true,	IVec3(-8, 0, 0),	7.0f,	tex1DMipmapShadow,			evalTexture1DShadowOffsetBiasClamp,			FRAGMENT),
4086 		CLAMP_CASE_SPEC(sampler1darrayshadow_bias,		FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4( 1.0f,  4.0f,  1.0f,  0.0f),	true,	0.0f,	5.0f,	true,	IVec3(-8, 0, 0),	7.0f,	tex1DArrayMipmapShadow,		evalTexture1DArrayShadowOffsetBiasClamp,	FRAGMENT),
4087 	};
4088 	createCaseGroup(this, "textureoffsetclamp", textureOffsetClampARBCases, DE_LENGTH_OF_ARRAY(textureOffsetClampARBCases));
4089 
4090 	// textureProj() cases
4091 	// \note Currently uses constant divider!
4092 	static const TexFuncCaseSpec textureProjCases[] =
4093 	{
4094 		//		  Name							Function				MinCoord							MaxCoord							Bias?	MinLod	MaxLod	Offset?	Offset		Format					EvalFunc				Flags
4095 		CASE_SPEC(sampler2d_vec3_fixed,			FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DFixed,				evalTexture2DProj3,		VERTEX),
4096 		CASE_SPEC(sampler2d_vec3_fixed,			FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DMipmapFixed,		evalTexture2DProj3,		FRAGMENT),
4097 		CASE_SPEC(sampler2d_vec3_float,			FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DFloat,				evalTexture2DProj3,		VERTEX),
4098 		CASE_SPEC(sampler2d_vec3_float,			FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DMipmapFloat,		evalTexture2DProj3,		FRAGMENT),
4099 		CASE_SPEC(isampler2d_vec3,				FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DInt,				evalTexture2DProj3,		VERTEX),
4100 		CASE_SPEC(isampler2d_vec3,				FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DMipmapInt,			evalTexture2DProj3,		FRAGMENT),
4101 		CASE_SPEC(usampler2d_vec3,				FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DUint,				evalTexture2DProj3,		VERTEX),
4102 		CASE_SPEC(usampler2d_vec3,				FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DMipmapUint,		evalTexture2DProj3,		FRAGMENT),
4103 
4104 		CASE_SPEC(sampler2d_vec3_bias_fixed,	FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex2DMipmapFixed,		evalTexture2DProj3Bias,	FRAGMENT),
4105 		CASE_SPEC(sampler2d_vec3_bias_float,	FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex2DMipmapFloat,		evalTexture2DProj3Bias,	FRAGMENT),
4106 		CASE_SPEC(isampler2d_vec3_bias,			FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex2DMipmapInt,			evalTexture2DProj3Bias,	FRAGMENT),
4107 		CASE_SPEC(usampler2d_vec3_bias,			FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex2DMipmapUint,		evalTexture2DProj3Bias,	FRAGMENT),
4108 
4109 		CASE_SPEC(sampler2d_vec4_fixed,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DFixed,				evalTexture2DProj,		VERTEX),
4110 		CASE_SPEC(sampler2d_vec4_fixed,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DMipmapFixed,		evalTexture2DProj,		FRAGMENT),
4111 		CASE_SPEC(sampler2d_vec4_float,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DFloat,				evalTexture2DProj,		VERTEX),
4112 		CASE_SPEC(sampler2d_vec4_float,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DMipmapFloat,		evalTexture2DProj,		FRAGMENT),
4113 		CASE_SPEC(isampler2d_vec4,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DInt,				evalTexture2DProj,		VERTEX),
4114 		CASE_SPEC(isampler2d_vec4,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DMipmapInt,			evalTexture2DProj,		FRAGMENT),
4115 		CASE_SPEC(usampler2d_vec4,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DUint,				evalTexture2DProj,		VERTEX),
4116 		CASE_SPEC(usampler2d_vec4,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DMipmapUint,		evalTexture2DProj,		FRAGMENT),
4117 
4118 		CASE_SPEC(sampler2d_vec4_bias_fixed,	FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex2DMipmapFixed,		evalTexture2DProjBias,	FRAGMENT),
4119 		CASE_SPEC(sampler2d_vec4_bias_float,	FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex2DMipmapFloat,		evalTexture2DProjBias,	FRAGMENT),
4120 		CASE_SPEC(isampler2d_vec4_bias,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex2DMipmapInt,			evalTexture2DProjBias,	FRAGMENT),
4121 		CASE_SPEC(usampler2d_vec4_bias,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex2DMipmapUint,		evalTexture2DProjBias,	FRAGMENT),
4122 
4123 		CASE_SPEC(sampler3d_fixed,				FUNCTION_TEXTUREPROJ,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex3DFixed,				evalTexture3DProj,		VERTEX),
4124 		CASE_SPEC(sampler3d_fixed,				FUNCTION_TEXTUREPROJ,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex3DMipmapFixed,		evalTexture3DProj,		FRAGMENT),
4125 		CASE_SPEC(sampler3d_float,				FUNCTION_TEXTUREPROJ,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex3DFloat,				evalTexture3DProj,		VERTEX),
4126 		CASE_SPEC(sampler3d_float,				FUNCTION_TEXTUREPROJ,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex3DMipmapFloat,		evalTexture3DProj,		FRAGMENT),
4127 		CASE_SPEC(isampler3d,					FUNCTION_TEXTUREPROJ,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex3DInt,				evalTexture3DProj,		VERTEX),
4128 		CASE_SPEC(isampler3d,					FUNCTION_TEXTUREPROJ,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex3DMipmapInt,			evalTexture3DProj,		FRAGMENT),
4129 		CASE_SPEC(usampler3d,					FUNCTION_TEXTUREPROJ,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex3DUint,				evalTexture3DProj,		VERTEX),
4130 		CASE_SPEC(usampler3d,					FUNCTION_TEXTUREPROJ,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex3DMipmapUint,		evalTexture3DProj,		FRAGMENT),
4131 
4132 		CASE_SPEC(sampler3d_bias_fixed,			FUNCTION_TEXTUREPROJ,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	true,	-2.0f,	1.0f,	false,	IVec3(0),	tex3DMipmapFixed,		evalTexture3DProjBias,	FRAGMENT),
4133 		CASE_SPEC(sampler3d_bias_float,			FUNCTION_TEXTUREPROJ,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	true,	-2.0f,	1.0f,	false,	IVec3(0),	tex3DMipmapFloat,		evalTexture3DProjBias,	FRAGMENT),
4134 		CASE_SPEC(isampler3d_bias,				FUNCTION_TEXTUREPROJ,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex3DMipmapInt,			evalTexture3DProjBias,	FRAGMENT),
4135 		CASE_SPEC(usampler3d_bias,				FUNCTION_TEXTUREPROJ,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex3DMipmapUint,		evalTexture3DProjBias,	FRAGMENT),
4136 
4137 		CASE_SPEC(sampler1d_vec2_fixed,			FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DFixed,				evalTexture1DProj2,		VERTEX),
4138 		CASE_SPEC(sampler1d_vec2_fixed,			FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DMipmapFixed,		evalTexture1DProj2,		FRAGMENT),
4139 		CASE_SPEC(sampler1d_vec2_float,			FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DFloat,				evalTexture1DProj2,		VERTEX),
4140 		CASE_SPEC(sampler1d_vec2_float,			FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DMipmapFloat,		evalTexture1DProj2,		FRAGMENT),
4141 		CASE_SPEC(isampler1d_vec2,				FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DInt,				evalTexture1DProj2,		VERTEX),
4142 		CASE_SPEC(isampler1d_vec2,				FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DMipmapInt,			evalTexture1DProj2,		FRAGMENT),
4143 		CASE_SPEC(usampler1d_vec2,				FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DUint,				evalTexture1DProj2,		VERTEX),
4144 		CASE_SPEC(usampler1d_vec2,				FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DMipmapUint,		evalTexture1DProj2,		FRAGMENT),
4145 
4146 		CASE_SPEC(sampler1d_vec2_bias_fixed,	FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex1DMipmapFixed,		evalTexture1DProj2Bias,	FRAGMENT),
4147 		CASE_SPEC(sampler1d_vec2_bias_float,	FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex1DMipmapFloat,		evalTexture1DProj2Bias,	FRAGMENT),
4148 		CASE_SPEC(isampler1d_vec2_bias,			FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex1DMipmapInt,			evalTexture1DProj2Bias,	FRAGMENT),
4149 		CASE_SPEC(usampler1d_vec2_bias,			FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex1DMipmapUint,		evalTexture1DProj2Bias,	FRAGMENT),
4150 
4151 		CASE_SPEC(sampler1d_vec4_fixed,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DFixed,				evalTexture1DProj,		VERTEX),
4152 		CASE_SPEC(sampler1d_vec4_fixed,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DMipmapFixed,		evalTexture1DProj,		FRAGMENT),
4153 		CASE_SPEC(sampler1d_vec4_float,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DFloat,				evalTexture1DProj,		VERTEX),
4154 		CASE_SPEC(sampler1d_vec4_float,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DMipmapFloat,		evalTexture1DProj,		FRAGMENT),
4155 		CASE_SPEC(isampler1d_vec4,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DInt,				evalTexture1DProj,		VERTEX),
4156 		CASE_SPEC(isampler1d_vec4,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DMipmapInt,			evalTexture1DProj,		FRAGMENT),
4157 		CASE_SPEC(usampler1d_vec4,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DUint,				evalTexture1DProj,		VERTEX),
4158 		CASE_SPEC(usampler1d_vec4,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DMipmapUint,		evalTexture1DProj,		FRAGMENT),
4159 
4160 		CASE_SPEC(sampler1d_vec4_bias_fixed,	FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex1DMipmapFixed,		evalTexture1DProjBias,	FRAGMENT),
4161 		CASE_SPEC(sampler1d_vec4_bias_float,	FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex1DMipmapFloat,		evalTexture1DProjBias,	FRAGMENT),
4162 		CASE_SPEC(isampler1d_vec4_bias,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex1DMipmapInt,			evalTexture1DProjBias,	FRAGMENT),
4163 		CASE_SPEC(usampler1d_vec4_bias,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex1DMipmapUint,		evalTexture1DProjBias,	FRAGMENT),
4164 
4165 		CASE_SPEC(sampler2dshadow,				FUNCTION_TEXTUREPROJ,	Vec4( 0.2f, 0.6f,  0.0f,  1.5f),	Vec4(-2.25f, -3.45f, 1.5f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DShadow,			evalTexture2DShadowProj,		VERTEX),
4166 		CASE_SPEC(sampler2dshadow,				FUNCTION_TEXTUREPROJ,	Vec4( 0.2f, 0.6f,  0.0f,  1.5f),	Vec4(-2.25f, -3.45f, 1.5f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DMipmapShadow,		evalTexture2DShadowProj,		FRAGMENT),
4167 		CASE_SPEC(sampler2dshadow_bias,			FUNCTION_TEXTUREPROJ,	Vec4( 0.2f, 0.6f,  0.0f,  1.5f),	Vec4(-2.25f, -3.45f, 1.5f,  1.5f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex2DMipmapShadow,		evalTexture2DShadowProjBias,	FRAGMENT),
4168 		CASE_SPEC(sampler1dshadow,				FUNCTION_TEXTUREPROJ,	Vec4( 0.2f, 0.0f,  0.0f,  1.5f),	Vec4(-2.25f,   0.0f, 1.5f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DShadow,			evalTexture1DShadowProj,		VERTEX),
4169 		CASE_SPEC(sampler1dshadow,				FUNCTION_TEXTUREPROJ,	Vec4( 0.2f, 0.0f,  0.0f,  1.5f),	Vec4(-2.25f,   0.0f, 1.5f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DMipmapShadow,		evalTexture1DShadowProj,		FRAGMENT),
4170 		CASE_SPEC(sampler1dshadow_bias,			FUNCTION_TEXTUREPROJ,	Vec4( 0.2f, 0.0f,  0.0f,  1.5f),	Vec4(-2.25f,   0.0f, 1.5f,  1.5f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex1DMipmapShadow,		evalTexture1DShadowProjBias,	FRAGMENT),
4171 	};
4172 	createCaseGroup(this, "textureproj", textureProjCases, DE_LENGTH_OF_ARRAY(textureProjCases));
4173 
4174 	// textureProjOffset() cases
4175 	// \note Currently uses constant divider!
4176 	static const TexFuncCaseSpec textureProjOffsetCases[] =
4177 	{
4178 		//		  Name							Function				MinCoord							MaxCoord							Bias?	MinLod	MaxLod	Offset?	Offset				Format					EvalFunc						Flags
4179 		CASE_SPEC(sampler2d_vec3_fixed,			FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DFixed,				evalTexture2DProj3Offset,		VERTEX),
4180 		CASE_SPEC(sampler2d_vec3_fixed,			FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapFixed,		evalTexture2DProj3Offset,		FRAGMENT),
4181 		CASE_SPEC(sampler2d_vec3_float,			FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DFloat,				evalTexture2DProj3Offset,		VERTEX),
4182 		CASE_SPEC(sampler2d_vec3_float,			FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapFloat,		evalTexture2DProj3Offset,		FRAGMENT),
4183 		CASE_SPEC(isampler2d_vec3,				FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DInt,				evalTexture2DProj3Offset,		VERTEX),
4184 		CASE_SPEC(isampler2d_vec3,				FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapInt,			evalTexture2DProj3Offset,		FRAGMENT),
4185 		CASE_SPEC(usampler2d_vec3,				FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DUint,				evalTexture2DProj3Offset,		VERTEX),
4186 		CASE_SPEC(usampler2d_vec3,				FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapUint,		evalTexture2DProj3Offset,		FRAGMENT),
4187 
4188 		CASE_SPEC(sampler2d_vec3_bias_fixed,	FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 7, 0),	tex2DFixed,				evalTexture2DProj3OffsetBias,	FRAGMENT),
4189 		CASE_SPEC(sampler2d_vec3_bias_float,	FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(7, -8, 0),	tex2DFloat,				evalTexture2DProj3OffsetBias,	FRAGMENT),
4190 		CASE_SPEC(isampler2d_vec3_bias,			FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 7, 0),	tex2DInt,				evalTexture2DProj3OffsetBias,	FRAGMENT),
4191 		CASE_SPEC(usampler2d_vec3_bias,			FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(7, -8, 0),	tex2DUint,				evalTexture2DProj3OffsetBias,	FRAGMENT),
4192 
4193 		CASE_SPEC(sampler2d_vec4_fixed,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DFixed,				evalTexture2DProjOffset,		VERTEX),
4194 		CASE_SPEC(sampler2d_vec4_fixed,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapFixed,		evalTexture2DProjOffset,		FRAGMENT),
4195 		CASE_SPEC(sampler2d_vec4_float,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DFloat,				evalTexture2DProjOffset,		VERTEX),
4196 		CASE_SPEC(sampler2d_vec4_float,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapFloat,		evalTexture2DProjOffset,		FRAGMENT),
4197 		CASE_SPEC(isampler2d_vec4,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DInt,				evalTexture2DProjOffset,		VERTEX),
4198 		CASE_SPEC(isampler2d_vec4,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapInt,			evalTexture2DProjOffset,		FRAGMENT),
4199 		CASE_SPEC(usampler2d_vec4,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DUint,				evalTexture2DProjOffset,		VERTEX),
4200 		CASE_SPEC(usampler2d_vec4,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapUint,		evalTexture2DProjOffset,		FRAGMENT),
4201 
4202 		CASE_SPEC(sampler2d_vec4_bias_fixed,	FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 7, 0),	tex2DFixed,				evalTexture2DProjOffsetBias,	FRAGMENT),
4203 		CASE_SPEC(sampler2d_vec4_bias_float,	FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	true,	-2.0f,	2.0f,	true,	IVec3(7, -8, 0),	tex2DFloat,				evalTexture2DProjOffsetBias,	FRAGMENT),
4204 		CASE_SPEC(isampler2d_vec4_bias,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 7, 0),	tex2DInt,				evalTexture2DProjOffsetBias,	FRAGMENT),
4205 		CASE_SPEC(usampler2d_vec4_bias,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	true,	-2.0f,	2.0f,	true,	IVec3(7, -8, 0),	tex2DUint,				evalTexture2DProjOffsetBias,	FRAGMENT),
4206 
4207 		CASE_SPEC(sampler3d_fixed,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  2.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 3),	tex3DFixed,				evalTexture3DProjOffset,		VERTEX),
4208 		CASE_SPEC(sampler3d_fixed,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  2.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(7, 3, -8),	tex3DMipmapFixed,		evalTexture3DProjOffset,		FRAGMENT),
4209 		CASE_SPEC(sampler3d_float,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  2.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(3, -8, 7),	tex3DFloat,				evalTexture3DProjOffset,		VERTEX),
4210 		CASE_SPEC(sampler3d_float,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  2.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 3),	tex3DMipmapFloat,		evalTexture3DProjOffset,		FRAGMENT),
4211 		CASE_SPEC(isampler3d,					FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  2.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(7, 3, -8),	tex3DInt,				evalTexture3DProjOffset,		VERTEX),
4212 		CASE_SPEC(isampler3d,					FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  2.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(3, -8, 7),	tex3DMipmapInt,			evalTexture3DProjOffset,		FRAGMENT),
4213 		CASE_SPEC(usampler3d,					FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  2.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 3),	tex3DUint,				evalTexture3DProjOffset,		VERTEX),
4214 		CASE_SPEC(usampler3d,					FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  2.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(7, 3, -8),	tex3DMipmapUint,		evalTexture3DProjOffset,		FRAGMENT),
4215 
4216 		CASE_SPEC(sampler3d_bias_fixed,			FUNCTION_TEXTUREPROJ,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 7, 3),	tex3DFixed,				evalTexture3DProjOffsetBias,	FRAGMENT),
4217 		CASE_SPEC(sampler3d_bias_float,			FUNCTION_TEXTUREPROJ,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	true,	-2.0f,	2.0f,	true,	IVec3(7, 3, -8),	tex3DFloat,				evalTexture3DProjOffsetBias,	FRAGMENT),
4218 		CASE_SPEC(isampler3d_bias,				FUNCTION_TEXTUREPROJ,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	true,	-2.0f,	2.0f,	true,	IVec3(3, -8, 7),	tex3DInt,				evalTexture3DProjOffsetBias,	FRAGMENT),
4219 		CASE_SPEC(usampler3d_bias,				FUNCTION_TEXTUREPROJ,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 7, 3),	tex3DUint,				evalTexture3DProjOffsetBias,	FRAGMENT),
4220 
4221 		CASE_SPEC(sampler1d_vec2_fixed,			FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DFixed,				evalTexture1DProj2Offset,		VERTEX),
4222 		CASE_SPEC(sampler1d_vec2_fixed,			FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7,  0, 0),	tex1DMipmapFixed,		evalTexture1DProj2Offset,		FRAGMENT),
4223 		CASE_SPEC(sampler1d_vec2_float,			FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DFloat,				evalTexture1DProj2Offset,		VERTEX),
4224 		CASE_SPEC(sampler1d_vec2_float,			FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7,  0, 0),	tex1DMipmapFloat,		evalTexture1DProj2Offset,		FRAGMENT),
4225 		CASE_SPEC(isampler1d_vec2,				FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DInt,				evalTexture1DProj2Offset,		VERTEX),
4226 		CASE_SPEC(isampler1d_vec2,				FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7,  0, 0),	tex1DMipmapInt,			evalTexture1DProj2Offset,		FRAGMENT),
4227 		CASE_SPEC(usampler1d_vec2,				FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DUint,				evalTexture1DProj2Offset,		VERTEX),
4228 		CASE_SPEC(usampler1d_vec2,				FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7,  0, 0),	tex1DMipmapUint,		evalTexture1DProj2Offset,		FRAGMENT),
4229 
4230 		CASE_SPEC(sampler1d_vec2_bias_fixed,	FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 0, 0),	tex1DFixed,				evalTexture1DProj2OffsetBias,	FRAGMENT),
4231 		CASE_SPEC(sampler1d_vec2_bias_float,	FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(7,  0, 0),	tex1DFloat,				evalTexture1DProj2OffsetBias,	FRAGMENT),
4232 		CASE_SPEC(isampler1d_vec2_bias,			FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 0, 0),	tex1DInt,				evalTexture1DProj2OffsetBias,	FRAGMENT),
4233 		CASE_SPEC(usampler1d_vec2_bias,			FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(7,  0, 0),	tex1DUint,				evalTexture1DProj2OffsetBias,	FRAGMENT),
4234 
4235 		CASE_SPEC(sampler1d_vec4_fixed,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DFixed,				evalTexture1DProjOffset,		VERTEX),
4236 		CASE_SPEC(sampler1d_vec4_fixed,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(7,  0, 0),	tex1DMipmapFixed,		evalTexture1DProjOffset,		FRAGMENT),
4237 		CASE_SPEC(sampler1d_vec4_float,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DFloat,				evalTexture1DProjOffset,		VERTEX),
4238 		CASE_SPEC(sampler1d_vec4_float,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(7,  0, 0),	tex1DMipmapFloat,		evalTexture1DProjOffset,		FRAGMENT),
4239 		CASE_SPEC(isampler1d_vec4,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DInt,				evalTexture1DProjOffset,		VERTEX),
4240 		CASE_SPEC(isampler1d_vec4,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(7,  0, 0),	tex1DMipmapInt,			evalTexture1DProjOffset,		FRAGMENT),
4241 		CASE_SPEC(usampler1d_vec4,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DUint,				evalTexture1DProjOffset,		VERTEX),
4242 		CASE_SPEC(usampler1d_vec4,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(7,  0, 0),	tex1DMipmapUint,		evalTexture1DProjOffset,		FRAGMENT),
4243 
4244 		CASE_SPEC(sampler1d_vec4_bias_fixed,	FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 0, 0),	tex1DFixed,				evalTexture1DProjOffsetBias,	FRAGMENT),
4245 		CASE_SPEC(sampler1d_vec4_bias_float,	FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	true,	-2.0f,	2.0f,	true,	IVec3(7,  0, 0),	tex1DFloat,				evalTexture1DProjOffsetBias,	FRAGMENT),
4246 		CASE_SPEC(isampler1d_vec4_bias,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 0, 0),	tex1DInt,				evalTexture1DProjOffsetBias,	FRAGMENT),
4247 		CASE_SPEC(usampler1d_vec4_bias,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	true,	-2.0f,	2.0f,	true,	IVec3(7,  0, 0),	tex1DUint,				evalTexture1DProjOffsetBias,	FRAGMENT),
4248 
4249 		CASE_SPEC(sampler2dshadow,				FUNCTION_TEXTUREPROJ,	Vec4( 0.2f, 0.6f,  0.0f,  1.5f),	Vec4(-2.25f, -3.45f, 1.5f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DShadow,			evalTexture2DShadowProjOffset,		VERTEX),
4250 		CASE_SPEC(sampler2dshadow,				FUNCTION_TEXTUREPROJ,	Vec4( 0.2f, 0.6f,  0.0f,  1.5f),	Vec4(-2.25f, -3.45f, 1.5f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapShadow,		evalTexture2DShadowProjOffset,		FRAGMENT),
4251 		CASE_SPEC(sampler2dshadow_bias,			FUNCTION_TEXTUREPROJ,	Vec4( 0.2f, 0.6f,  0.0f,  1.5f),	Vec4(-2.25f, -3.45f, 1.5f,  1.5f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 7, 0),	tex2DShadow,			evalTexture2DShadowProjOffsetBias,	FRAGMENT),
4252 		CASE_SPEC(sampler1dshadow,				FUNCTION_TEXTUREPROJ,	Vec4( 0.2f, 0.0f,  0.0f,  1.5f),	Vec4(-2.25f,   0.0f, 1.5f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DShadow,			evalTexture1DShadowProjOffset,		VERTEX),
4253 		CASE_SPEC(sampler1dshadow,				FUNCTION_TEXTUREPROJ,	Vec4( 0.2f, 0.0f,  0.0f,  1.5f),	Vec4(-2.25f,   0.0f, 1.5f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(7,  0, 0),	tex1DMipmapShadow,		evalTexture1DShadowProjOffset,		FRAGMENT),
4254 		CASE_SPEC(sampler1dshadow_bias,			FUNCTION_TEXTUREPROJ,	Vec4( 0.2f, 0.0f,  0.0f,  1.5f),	Vec4(-2.25f,   0.0f, 1.5f,  1.5f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 0, 0),	tex1DShadow,			evalTexture1DShadowProjOffsetBias,	FRAGMENT),
4255 	};
4256 	createCaseGroup(this, "textureprojoffset", textureProjOffsetCases, DE_LENGTH_OF_ARRAY(textureProjOffsetCases));
4257 
4258 	// textureLod() cases
4259 	static const TexFuncCaseSpec textureLodCases[] =
4260 	{
4261 		//		  Name							Function				MinCoord							MaxCoord							Bias?	MinLod	MaxLod	Offset?	Offset		Format					EvalFunc				Flags
4262 		CASE_SPEC(sampler2d_fixed,				FUNCTION_TEXTURELOD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex2DMipmapFixed,		evalTexture2DLod,		BOTH),
4263 		CASE_SPEC(sampler2d_float,				FUNCTION_TEXTURELOD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex2DMipmapFloat,		evalTexture2DLod,		BOTH),
4264 		CASE_SPEC(isampler2d,					FUNCTION_TEXTURELOD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex2DMipmapInt,			evalTexture2DLod,		BOTH),
4265 		CASE_SPEC(usampler2d,					FUNCTION_TEXTURELOD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex2DMipmapUint,		evalTexture2DLod,		BOTH),
4266 
4267 		CASE_SPEC(samplercube_fixed,			FUNCTION_TEXTURELOD,	Vec4(-1.0f, -1.0f,  1.01f,  0.0f),	Vec4( 1.0f,  1.0f,  1.01f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	texCubeMipmapFixed,		evalTextureCubeLod,		BOTH),
4268 		CASE_SPEC(samplercube_float,			FUNCTION_TEXTURELOD,	Vec4(-1.0f, -1.0f, -1.01f,  0.0f),	Vec4( 1.0f,  1.0f, -1.01f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	texCubeMipmapFloat,		evalTextureCubeLod,		BOTH),
4269 		CASE_SPEC(isamplercube,					FUNCTION_TEXTURELOD,	Vec4(-1.0f, -1.0f,  1.01f,  0.0f),	Vec4( 1.0f,  1.0f,  1.01f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	texCubeMipmapInt,		evalTextureCubeLod,		BOTH),
4270 		CASE_SPEC(usamplercube,					FUNCTION_TEXTURELOD,	Vec4(-1.0f, -1.0f, -1.01f,  0.0f),	Vec4( 1.0f,  1.0f, -1.01f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	texCubeMipmapUint,		evalTextureCubeLod,		BOTH),
4271 
4272 		CASE_SPEC(sampler2darray_fixed,			FUNCTION_TEXTURELOD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	-1.0f,	8.0f,	false,	IVec3(0),	tex2DArrayMipmapFixed,	evalTexture2DArrayLod,	BOTH),
4273 		CASE_SPEC(sampler2darray_float,			FUNCTION_TEXTURELOD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	-1.0f,	8.0f,	false,	IVec3(0),	tex2DArrayMipmapFloat,	evalTexture2DArrayLod,	BOTH),
4274 		CASE_SPEC(isampler2darray,				FUNCTION_TEXTURELOD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	-1.0f,	8.0f,	false,	IVec3(0),	tex2DArrayMipmapInt,	evalTexture2DArrayLod,	BOTH),
4275 		CASE_SPEC(usampler2darray,				FUNCTION_TEXTURELOD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	-1.0f,	8.0f,	false,	IVec3(0),	tex2DArrayMipmapUint,	evalTexture2DArrayLod,	BOTH),
4276 
4277 		CASE_SPEC(sampler3d_fixed,				FUNCTION_TEXTURELOD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	-1.0f,	7.0f,	false,	IVec3(0),	tex3DMipmapFixed,		evalTexture3DLod,		BOTH),
4278 		CASE_SPEC(sampler3d_float,				FUNCTION_TEXTURELOD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	-1.0f,	7.0f,	false,	IVec3(0),	tex3DMipmapFloat,		evalTexture3DLod,		BOTH),
4279 		CASE_SPEC(isampler3d,					FUNCTION_TEXTURELOD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	-1.0f,	7.0f,	false,	IVec3(0),	tex3DMipmapInt,			evalTexture3DLod,		BOTH),
4280 		CASE_SPEC(usampler3d,					FUNCTION_TEXTURELOD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	-1.0f,	7.0f,	false,	IVec3(0),	tex3DMipmapUint,		evalTexture3DLod,		BOTH),
4281 
4282 		CASE_SPEC(sampler1d_fixed,				FUNCTION_TEXTURELOD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex1DMipmapFixed,		evalTexture1DLod,		BOTH),
4283 		CASE_SPEC(sampler1d_float,				FUNCTION_TEXTURELOD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex1DMipmapFloat,		evalTexture1DLod,		BOTH),
4284 		CASE_SPEC(isampler1d,					FUNCTION_TEXTURELOD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex1DMipmapInt,			evalTexture1DLod,		BOTH),
4285 		CASE_SPEC(usampler1d,					FUNCTION_TEXTURELOD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex1DMipmapUint,		evalTexture1DLod,		BOTH),
4286 
4287 		CASE_SPEC(sampler1darray_fixed,			FUNCTION_TEXTURELOD,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex1DArrayMipmapFixed,	evalTexture1DArrayLod,	BOTH),
4288 		CASE_SPEC(sampler1darray_float,			FUNCTION_TEXTURELOD,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex1DArrayMipmapFloat,	evalTexture1DArrayLod,	BOTH),
4289 		CASE_SPEC(isampler1darray,				FUNCTION_TEXTURELOD,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex1DArrayMipmapInt,	evalTexture1DArrayLod,	BOTH),
4290 		CASE_SPEC(usampler1darray,				FUNCTION_TEXTURELOD,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex1DArrayMipmapUint,	evalTexture1DArrayLod,	BOTH),
4291 
4292 		CASE_SPEC(samplercubearray_fixed,		FUNCTION_TEXTURELOD,	Vec4(-1.0f, -1.0f,  1.01f, -0.5f),	Vec4( 1.0f,  1.0f,  1.01f,  1.5f),	false,	-1.0f,	7.0f,	false,	IVec3(0),	texCubeArrayMipmapFixed,	evalTextureCubeArrayLod,	BOTH),
4293 		CASE_SPEC(samplercubearray_float,		FUNCTION_TEXTURELOD,	Vec4(-1.0f, -1.0f, -1.01f, -0.5f),	Vec4( 1.0f,  1.0f, -1.01f,  1.5f),	false,	-1.0f,	7.0f,	false,	IVec3(0),	texCubeArrayMipmapFloat,	evalTextureCubeArrayLod,	BOTH),
4294 		CASE_SPEC(isamplercubearray,			FUNCTION_TEXTURELOD,	Vec4(-1.0f, -1.0f,  1.01f, -0.5f),	Vec4( 1.0f,  1.0f,  1.01f,  1.5f),	false,	-1.0f,	7.0f,	false,	IVec3(0),	texCubeArrayMipmapInt,		evalTextureCubeArrayLod,	BOTH),
4295 		CASE_SPEC(usamplercubearray,			FUNCTION_TEXTURELOD,	Vec4(-1.0f, -1.0f, -1.01f, -0.5f),	Vec4( 1.0f,  1.0f, -1.01f,  1.5f),	false,	-1.0f,	7.0f,	false,	IVec3(0),	texCubeArrayMipmapUint,		evalTextureCubeArrayLod,	BOTH),
4296 
4297 		CASE_SPEC(sampler2dshadow,				FUNCTION_TEXTURELOD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  1.0f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex2DMipmapShadow,		evalTexture2DShadowLod,			BOTH),
4298 		CASE_SPEC(sampler1dshadow,				FUNCTION_TEXTURELOD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  1.0f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex1DMipmapShadow,		evalTexture1DShadowLod,			BOTH),
4299 		CASE_SPEC(sampler1darrayshadow,			FUNCTION_TEXTURELOD,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  1.0f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex1DArrayMipmapShadow,	evalTexture1DArrayShadowLod,	BOTH),
4300 	};
4301 	createCaseGroup(this, "texturelod", textureLodCases, DE_LENGTH_OF_ARRAY(textureLodCases));
4302 
4303 	// textureLodOffset() cases
4304 	static const TexFuncCaseSpec textureLodOffsetCases[] =
4305 	{
4306 		//		  Name							Function				MinCoord							MaxCoord							Bias?	MinLod	MaxLod	Offset?	Offset				Format					EvalFunc						Flags
4307 		CASE_SPEC(sampler2d_fixed,				FUNCTION_TEXTURELOD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(-8, 7, 0),	tex2DMipmapFixed,		evalTexture2DLodOffset,			BOTH),
4308 		CASE_SPEC(sampler2d_float,				FUNCTION_TEXTURELOD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapFloat,		evalTexture2DLodOffset,			BOTH),
4309 		CASE_SPEC(isampler2d,					FUNCTION_TEXTURELOD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(-8, 7, 0),	tex2DMipmapInt,			evalTexture2DLodOffset,			BOTH),
4310 		CASE_SPEC(usampler2d,					FUNCTION_TEXTURELOD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapUint,		evalTexture2DLodOffset,			BOTH),
4311 
4312 		CASE_SPEC(sampler2darray_fixed,			FUNCTION_TEXTURELOD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	-1.0f,	8.0f,	true,	IVec3(-8, 7, 0),	tex2DArrayMipmapFixed,	evalTexture2DArrayLodOffset,	BOTH),
4313 		CASE_SPEC(sampler2darray_float,			FUNCTION_TEXTURELOD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	-1.0f,	8.0f,	true,	IVec3(7, -8, 0),	tex2DArrayMipmapFloat,	evalTexture2DArrayLodOffset,	BOTH),
4314 		CASE_SPEC(isampler2darray,				FUNCTION_TEXTURELOD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	-1.0f,	8.0f,	true,	IVec3(-8, 7, 0),	tex2DArrayMipmapInt,	evalTexture2DArrayLodOffset,	BOTH),
4315 		CASE_SPEC(usampler2darray,				FUNCTION_TEXTURELOD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	-1.0f,	8.0f,	true,	IVec3(7, -8, 0),	tex2DArrayMipmapUint,	evalTexture2DArrayLodOffset,	BOTH),
4316 
4317 		CASE_SPEC(sampler3d_fixed,				FUNCTION_TEXTURELOD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	-1.0f,	7.0f,	true,	IVec3(-8, 7, 3),	tex3DMipmapFixed,		evalTexture3DLodOffset,			BOTH),
4318 		CASE_SPEC(sampler3d_float,				FUNCTION_TEXTURELOD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	-1.0f,	7.0f,	true,	IVec3(7, 3, -8),	tex3DMipmapFloat,		evalTexture3DLodOffset,			BOTH),
4319 		CASE_SPEC(isampler3d,					FUNCTION_TEXTURELOD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	-1.0f,	7.0f,	true,	IVec3(3, -8, 7),	tex3DMipmapInt,			evalTexture3DLodOffset,			BOTH),
4320 		CASE_SPEC(usampler3d,					FUNCTION_TEXTURELOD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	-1.0f,	7.0f,	true,	IVec3(-8, 7, 3),	tex3DMipmapUint,		evalTexture3DLodOffset,			BOTH),
4321 
4322 		CASE_SPEC(sampler1d_fixed,				FUNCTION_TEXTURELOD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(-8, 0, 0),	tex1DMipmapFixed,		evalTexture1DLodOffset,			BOTH),
4323 		CASE_SPEC(sampler1d_float,				FUNCTION_TEXTURELOD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(7,  0, 0),	tex1DMipmapFloat,		evalTexture1DLodOffset,			BOTH),
4324 		CASE_SPEC(isampler1d,					FUNCTION_TEXTURELOD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(-8, 0, 0),	tex1DMipmapInt,			evalTexture1DLodOffset,			BOTH),
4325 		CASE_SPEC(usampler1d,					FUNCTION_TEXTURELOD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(7,  0, 0),	tex1DMipmapUint,		evalTexture1DLodOffset,			BOTH),
4326 
4327 		CASE_SPEC(sampler1darray_fixed,			FUNCTION_TEXTURELOD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(-8, 0, 0),	tex1DArrayMipmapFixed,	evalTexture1DArrayLodOffset,	BOTH),
4328 		CASE_SPEC(sampler1darray_float,			FUNCTION_TEXTURELOD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(7,  0, 0),	tex1DArrayMipmapFloat,	evalTexture1DArrayLodOffset,	BOTH),
4329 		CASE_SPEC(isampler1darray,				FUNCTION_TEXTURELOD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(-8, 0, 0),	tex1DArrayMipmapInt,	evalTexture1DArrayLodOffset,	BOTH),
4330 		CASE_SPEC(usampler1darray,				FUNCTION_TEXTURELOD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(7,  0, 0),	tex1DArrayMipmapUint,	evalTexture1DArrayLodOffset,	BOTH),
4331 
4332 		CASE_SPEC(sampler2dshadow,				FUNCTION_TEXTURELOD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  1.0f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(-8, 7, 0),	tex2DMipmapShadow,		evalTexture2DShadowLodOffset,		BOTH),
4333 		CASE_SPEC(sampler1dshadow,				FUNCTION_TEXTURELOD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  1.0f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(-8, 0, 0),	tex1DMipmapShadow,		evalTexture1DShadowLodOffset,		BOTH),
4334 		CASE_SPEC(sampler1darrayshadow,			FUNCTION_TEXTURELOD,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  1.0f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(7,  0, 0),	tex1DArrayMipmapShadow,	evalTexture1DArrayShadowLodOffset,	BOTH),
4335 	};
4336 	createCaseGroup(this, "texturelodoffset", textureLodOffsetCases, DE_LENGTH_OF_ARRAY(textureLodOffsetCases));
4337 
4338 	// textureProjLod() cases
4339 	static const TexFuncCaseSpec textureProjLodCases[] =
4340 	{
4341 		//		  Name							Function					MinCoord							MaxCoord							Bias?	MinLod	MaxLod	Offset?	Offset		Format					EvalFunc					Flags
4342 		CASE_SPEC(sampler2d_vec3_fixed,			FUNCTION_TEXTUREPROJLOD3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex2DMipmapFixed,		evalTexture2DProjLod3,		BOTH),
4343 		CASE_SPEC(sampler2d_vec3_float,			FUNCTION_TEXTUREPROJLOD3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex2DMipmapFloat,		evalTexture2DProjLod3,		BOTH),
4344 		CASE_SPEC(isampler2d_vec3,				FUNCTION_TEXTUREPROJLOD3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex2DMipmapInt,			evalTexture2DProjLod3,		BOTH),
4345 		CASE_SPEC(usampler2d_vec3,				FUNCTION_TEXTUREPROJLOD3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex2DMipmapUint,		evalTexture2DProjLod3,		BOTH),
4346 
4347 		CASE_SPEC(sampler2d_vec4_fixed,			FUNCTION_TEXTUREPROJLOD,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex2DMipmapFixed,		evalTexture2DProjLod,		BOTH),
4348 		CASE_SPEC(sampler2d_vec4_float,			FUNCTION_TEXTUREPROJLOD,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex2DMipmapFloat,		evalTexture2DProjLod,		BOTH),
4349 		CASE_SPEC(isampler2d_vec4,				FUNCTION_TEXTUREPROJLOD,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex2DMipmapInt,			evalTexture2DProjLod,		BOTH),
4350 		CASE_SPEC(usampler2d_vec4,				FUNCTION_TEXTUREPROJLOD,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex2DMipmapUint,		evalTexture2DProjLod,		BOTH),
4351 
4352 		CASE_SPEC(sampler3d_fixed,				FUNCTION_TEXTUREPROJLOD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	false,	-1.0f,	7.0f,	false,	IVec3(0),	tex3DMipmapFixed,		evalTexture3DProjLod,		BOTH),
4353 		CASE_SPEC(sampler3d_float,				FUNCTION_TEXTUREPROJLOD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	false,	-1.0f,	7.0f,	false,	IVec3(0),	tex3DMipmapFloat,		evalTexture3DProjLod,		BOTH),
4354 		CASE_SPEC(isampler3d,					FUNCTION_TEXTUREPROJLOD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	false,	-1.0f,	7.0f,	false,	IVec3(0),	tex3DMipmapInt,			evalTexture3DProjLod,		BOTH),
4355 		CASE_SPEC(usampler3d,					FUNCTION_TEXTUREPROJLOD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	false,	-1.0f,	7.0f,	false,	IVec3(0),	tex3DMipmapUint,		evalTexture3DProjLod,		BOTH),
4356 
4357 		CASE_SPEC(sampler1d_vec2_fixed,			FUNCTION_TEXTUREPROJLOD2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex1DMipmapFixed,		evalTexture1DProjLod2,		BOTH),
4358 		CASE_SPEC(sampler1d_vec2_float,			FUNCTION_TEXTUREPROJLOD2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex1DMipmapFloat,		evalTexture1DProjLod2,		BOTH),
4359 		CASE_SPEC(isampler1d_vec2,				FUNCTION_TEXTUREPROJLOD2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex1DMipmapInt,			evalTexture1DProjLod2,		BOTH),
4360 		CASE_SPEC(usampler1d_vec2,				FUNCTION_TEXTUREPROJLOD2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex1DMipmapUint,		evalTexture1DProjLod2,		BOTH),
4361 
4362 		CASE_SPEC(sampler1d_vec4_fixed,			FUNCTION_TEXTUREPROJLOD,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex1DMipmapFixed,		evalTexture1DProjLod,		BOTH),
4363 		CASE_SPEC(sampler1d_vec4_float,			FUNCTION_TEXTUREPROJLOD,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex1DMipmapFloat,		evalTexture1DProjLod,		BOTH),
4364 		CASE_SPEC(isampler1d_vec4,				FUNCTION_TEXTUREPROJLOD,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex1DMipmapInt,			evalTexture1DProjLod,		BOTH),
4365 		CASE_SPEC(usampler1d_vec4,				FUNCTION_TEXTUREPROJLOD,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex1DMipmapUint,		evalTexture1DProjLod,		BOTH),
4366 
4367 		CASE_SPEC(sampler2dshadow,				FUNCTION_TEXTUREPROJLOD,	Vec4( 0.2f, 0.6f,  0.0f,  1.5f),	Vec4(-2.25f, -3.45f, 1.5f,  1.5f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex2DMipmapShadow,		evalTexture2DShadowProjLod,	BOTH),
4368 		CASE_SPEC(sampler1dshadow,				FUNCTION_TEXTUREPROJLOD,	Vec4( 0.2f, 0.0f,  0.0f,  1.5f),	Vec4(-2.25f,  0.0f,  0.0f,  1.5f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex1DMipmapShadow,		evalTexture1DShadowProjLod,	BOTH),
4369 	};
4370 	createCaseGroup(this, "textureprojlod", textureProjLodCases, DE_LENGTH_OF_ARRAY(textureProjLodCases));
4371 
4372 	// textureProjLodOffset() cases
4373 	static const TexFuncCaseSpec textureProjLodOffsetCases[] =
4374 	{
4375 		//		  Name							Function					MinCoord							MaxCoord							Bias?	MinLod	MaxLod	Offset?	Offset				Format					EvalFunc								Flags
4376 		CASE_SPEC(sampler2d_vec3_fixed,			FUNCTION_TEXTUREPROJLOD3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(-8, 7, 0),	tex2DMipmapFixed,		evalTexture2DProjLod3Offset,	BOTH),
4377 		CASE_SPEC(sampler2d_vec3_float,			FUNCTION_TEXTUREPROJLOD3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapFloat,		evalTexture2DProjLod3Offset,	BOTH),
4378 		CASE_SPEC(isampler2d_vec3,				FUNCTION_TEXTUREPROJLOD3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(-8, 7, 0),	tex2DMipmapInt,			evalTexture2DProjLod3Offset,	BOTH),
4379 		CASE_SPEC(usampler2d_vec3,				FUNCTION_TEXTUREPROJLOD3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapUint,		evalTexture2DProjLod3Offset,	BOTH),
4380 
4381 		CASE_SPEC(sampler2d_vec4_fixed,			FUNCTION_TEXTUREPROJLOD,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	-1.0f,	9.0f,	true,	IVec3(-8, 7, 0),	tex2DMipmapFixed,		evalTexture2DProjLodOffset,		BOTH),
4382 		CASE_SPEC(sampler2d_vec4_float,			FUNCTION_TEXTUREPROJLOD,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	-1.0f,	9.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapFloat,		evalTexture2DProjLodOffset,		BOTH),
4383 		CASE_SPEC(isampler2d_vec4,				FUNCTION_TEXTUREPROJLOD,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	-1.0f,	9.0f,	true,	IVec3(-8, 7, 0),	tex2DMipmapInt,			evalTexture2DProjLodOffset,		BOTH),
4384 		CASE_SPEC(usampler2d_vec4,				FUNCTION_TEXTUREPROJLOD,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	-1.0f,	9.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapUint,		evalTexture2DProjLodOffset,		BOTH),
4385 
4386 		CASE_SPEC(sampler3d_fixed,				FUNCTION_TEXTUREPROJLOD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	false,	-1.0f,	7.0f,	true,	IVec3(-8, 7, 3),	tex3DMipmapFixed,		evalTexture3DProjLodOffset,		BOTH),
4387 		CASE_SPEC(sampler3d_float,				FUNCTION_TEXTUREPROJLOD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	false,	-1.0f,	7.0f,	true,	IVec3(7, 3, -8),	tex3DMipmapFloat,		evalTexture3DProjLodOffset,		BOTH),
4388 		CASE_SPEC(isampler3d,					FUNCTION_TEXTUREPROJLOD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	false,	-1.0f,	7.0f,	true,	IVec3(3, -8, 7),	tex3DMipmapInt,			evalTexture3DProjLodOffset,		BOTH),
4389 		CASE_SPEC(usampler3d,					FUNCTION_TEXTUREPROJLOD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	false,	-1.0f,	7.0f,	true,	IVec3(-8, 7, 3),	tex3DMipmapUint,		evalTexture3DProjLodOffset,		BOTH),
4390 
4391 		CASE_SPEC(sampler1d_vec2_fixed,			FUNCTION_TEXTUREPROJLOD2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(-8, 0, 0),	tex1DMipmapFixed,		evalTexture1DProjLod2Offset,	BOTH),
4392 		CASE_SPEC(sampler1d_vec2_float,			FUNCTION_TEXTUREPROJLOD2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(7,  0, 0),	tex1DMipmapFloat,		evalTexture1DProjLod2Offset,	BOTH),
4393 		CASE_SPEC(isampler1d_vec2,				FUNCTION_TEXTUREPROJLOD2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(-8, 0, 0),	tex1DMipmapInt,			evalTexture1DProjLod2Offset,	BOTH),
4394 		CASE_SPEC(usampler1d_vec2,				FUNCTION_TEXTUREPROJLOD2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(7,  0, 0),	tex1DMipmapUint,		evalTexture1DProjLod2Offset,	BOTH),
4395 
4396 		CASE_SPEC(sampler1d_vec4_fixed,			FUNCTION_TEXTUREPROJLOD,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	-1.0f,	9.0f,	true,	IVec3(-8, 0, 0),	tex1DMipmapFixed,		evalTexture1DProjLodOffset,		BOTH),
4397 		CASE_SPEC(sampler1d_vec4_float,			FUNCTION_TEXTUREPROJLOD,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	-1.0f,	9.0f,	true,	IVec3(7,  0, 0),	tex1DMipmapFloat,		evalTexture1DProjLodOffset,		BOTH),
4398 		CASE_SPEC(isampler1d_vec4,				FUNCTION_TEXTUREPROJLOD,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	-1.0f,	9.0f,	true,	IVec3(-8, 0, 0),	tex1DMipmapInt,			evalTexture1DProjLodOffset,		BOTH),
4399 		CASE_SPEC(usampler1d_vec4,				FUNCTION_TEXTUREPROJLOD,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	-1.0f,	9.0f,	true,	IVec3(7,  0, 0),	tex1DMipmapUint,		evalTexture1DProjLodOffset,		BOTH),
4400 
4401 		CASE_SPEC(sampler2dshadow,				FUNCTION_TEXTUREPROJLOD,	Vec4( 0.2f, 0.6f,  0.0f,  1.5f),	Vec4(-2.25f, -3.45f, 1.5f,  1.5f),	false,	-1.0f,	9.0f,	true,	IVec3(-8, 7, 0),	tex2DMipmapShadow,		evalTexture2DShadowProjLodOffset,	BOTH),
4402 		CASE_SPEC(sampler1dshadow,				FUNCTION_TEXTUREPROJLOD,	Vec4( 0.2f, 0.0f,  0.0f,  1.5f),	Vec4(-2.25f,  0.0f,  1.5f,  1.5f),	false,	-1.0f,	9.0f,	true,	IVec3(7,  0, 0),	tex1DMipmapShadow,		evalTexture1DShadowProjLodOffset,	BOTH),
4403 	};
4404 	createCaseGroup(this, "textureprojlodoffset", textureProjLodOffsetCases, DE_LENGTH_OF_ARRAY(textureProjLodOffsetCases));
4405 
4406 	// textureGrad() cases
4407 	// \note Only one of dudx, dudy, dvdx, dvdy is non-zero since spec allows approximating p from derivates by various methods.
4408 	static const TexFuncCaseSpec textureGradCases[] =
4409 	{
4410 		//		  Name							Function				MinCoord							MaxCoord							MinDx						MaxDx						MinDy						MaxDy						Offset?	Offset		Format					EvalFunc				Flags
4411 		GRAD_CASE_SPEC(sampler2d_fixed,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex2DMipmapFixed,		evalTexture2DGrad,		BOTH),
4412 		GRAD_CASE_SPEC(sampler2d_float,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex2DMipmapFloat,		evalTexture2DGrad,		BOTH),
4413 		GRAD_CASE_SPEC(isampler2d,				FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	tex2DMipmapInt,			evalTexture2DGrad,		BOTH),
4414 		GRAD_CASE_SPEC(usampler2d,				FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	false,	IVec3(0),	tex2DMipmapUint,		evalTexture2DGrad,		BOTH),
4415 
4416 		GRAD_CASE_SPEC(samplercube_fixed,		FUNCTION_TEXTUREGRAD,	Vec4(-1.0f, -1.0f,  1.01f,  0.0f),	Vec4( 1.0f,  1.0f,  1.01f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	texCubeMipmapFixed,		evalTextureCubeGrad,	BOTH),
4417 		GRAD_CASE_SPEC(samplercube_float,		FUNCTION_TEXTUREGRAD,	Vec4(-1.0f, -1.0f, -1.01f,  0.0f),	Vec4( 1.0f,  1.0f, -1.01f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	texCubeMipmapFloat,		evalTextureCubeGrad,	BOTH),
4418 		GRAD_CASE_SPEC(isamplercube,			FUNCTION_TEXTUREGRAD,	Vec4(-1.0f, -1.0f,  1.01f,  0.0f),	Vec4( 1.0f,  1.0f,  1.01f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	texCubeMipmapInt,		evalTextureCubeGrad,	BOTH),
4419 		GRAD_CASE_SPEC(usamplercube,			FUNCTION_TEXTUREGRAD,	Vec4(-1.0f, -1.0f, -1.01f,  0.0f),	Vec4( 1.0f,  1.0f, -1.01f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	false,	IVec3(0),	texCubeMipmapUint,		evalTextureCubeGrad,	BOTH),
4420 
4421 		GRAD_CASE_SPEC(sampler2darray_fixed,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex2DArrayMipmapFixed,	evalTexture2DArrayGrad,	BOTH),
4422 		GRAD_CASE_SPEC(sampler2darray_float,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex2DArrayMipmapFloat,	evalTexture2DArrayGrad,	BOTH),
4423 		GRAD_CASE_SPEC(isampler2darray,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	tex2DArrayMipmapInt,	evalTexture2DArrayGrad,	BOTH),
4424 		GRAD_CASE_SPEC(usampler2darray,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	false,	IVec3(0),	tex2DArrayMipmapUint,	evalTexture2DArrayGrad,	BOTH),
4425 
4426 		GRAD_CASE_SPEC(sampler3d_fixed,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex3DMipmapFixed,		evalTexture3DGrad,		BOTH),
4427 		GRAD_CASE_SPEC(sampler3d_float,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex3DMipmapFloat,		evalTexture3DGrad,		VERTEX),
4428 		GRAD_CASE_SPEC(sampler3d_float,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.2f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex3DMipmapFloat,		evalTexture3DGrad,		FRAGMENT),
4429 		GRAD_CASE_SPEC(isampler3d,				FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	tex3DMipmapInt,			evalTexture3DGrad,		BOTH),
4430 		GRAD_CASE_SPEC(usampler3d,				FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	false,	IVec3(0),	tex3DMipmapUint,		evalTexture3DGrad,		VERTEX),
4431 		GRAD_CASE_SPEC(usampler3d,				FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f, -0.2f),	false,	IVec3(0),	tex3DMipmapUint,		evalTexture3DGrad,		FRAGMENT),
4432 
4433 		GRAD_CASE_SPEC(sampler1d_fixed,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DMipmapFixed,		evalTexture1DGrad,		BOTH),
4434 		GRAD_CASE_SPEC(sampler1d_float,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DMipmapFloat,		evalTexture1DGrad,		BOTH),
4435 		GRAD_CASE_SPEC(isampler1d,				FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DMipmapInt,			evalTexture1DGrad,		BOTH),
4436 		GRAD_CASE_SPEC(usampler1d,				FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DMipmapUint,		evalTexture1DGrad,		BOTH),
4437 
4438 		GRAD_CASE_SPEC(sampler1darray_fixed,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DArrayMipmapFixed,	evalTexture1DArrayGrad,	BOTH),
4439 		GRAD_CASE_SPEC(sampler1darray_float,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DArrayMipmapFloat,	evalTexture1DArrayGrad,	BOTH),
4440 		GRAD_CASE_SPEC(isampler1darray,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DArrayMipmapInt,	evalTexture1DArrayGrad,	BOTH),
4441 		GRAD_CASE_SPEC(usampler1darray,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DArrayMipmapUint,	evalTexture1DArrayGrad,	BOTH),
4442 
4443 		GRAD_CASE_SPEC(samplercubearray_fixed,	FUNCTION_TEXTUREGRAD,	Vec4(-1.0f, -1.0f,  1.01f, -0.5f),	Vec4( 1.0f,  1.0f,  1.01f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	texCubeArrayMipmapFixed,	evalTextureCubeArrayGrad,	BOTH),
4444 		GRAD_CASE_SPEC(samplercubearray_float,	FUNCTION_TEXTUREGRAD,	Vec4(-1.0f, -1.0f, -1.01f, -0.5f),	Vec4( 1.0f,  1.0f, -1.01f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	texCubeArrayMipmapFloat,	evalTextureCubeArrayGrad,	BOTH),
4445 		GRAD_CASE_SPEC(isamplercubearray,		FUNCTION_TEXTUREGRAD,	Vec4(-1.0f, -1.0f,  1.01f, -0.5f),	Vec4( 1.0f,  1.0f,  1.01f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	texCubeArrayMipmapInt,		evalTextureCubeArrayGrad,	BOTH),
4446 		GRAD_CASE_SPEC(usamplercubearray,		FUNCTION_TEXTUREGRAD,	Vec4(-1.0f, -1.0f, -1.01f, -0.5f),	Vec4( 1.0f,  1.0f, -1.01f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	false,	IVec3(0),	texCubeArrayMipmapUint,		evalTextureCubeArrayGrad,	BOTH),
4447 
4448 		GRAD_CASE_SPEC(sampler2dshadow,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  1.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex2DMipmapShadow,		evalTexture2DShadowGrad,		BOTH),
4449 		GRAD_CASE_SPEC(samplercubeshadow,		FUNCTION_TEXTUREGRAD,	Vec4(-1.0f, -1.0f,  1.01f, 0.0f),	Vec4( 1.0f,  1.0f,  1.01f, 1.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	texCubeMipmapShadow,	evalTextureCubeShadowGrad,		BOTH),
4450 		GRAD_CASE_SPEC(sampler2darrayshadow,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f, -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  1.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	false,	IVec3(0),	tex2DArrayMipmapShadow,	evalTexture2DArrayShadowGrad,	VERTEX),
4451 		GRAD_CASE_SPEC(sampler2darrayshadow,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f, -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  1.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	false,	IVec3(0),	tex2DArrayMipmapShadow,	evalTexture2DArrayShadowGrad,	FRAGMENT),
4452 		GRAD_CASE_SPEC(sampler1dshadow,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  1.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DMipmapShadow,		evalTexture1DShadowGrad,		BOTH),
4453 		GRAD_CASE_SPEC(sampler1darrayshadow,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  1.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DArrayMipmapShadow,	evalTexture1DArrayShadowGrad,	VERTEX),
4454 		GRAD_CASE_SPEC(sampler1darrayshadow,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  1.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DArrayMipmapShadow,	evalTexture1DArrayShadowGrad,	FRAGMENT),
4455 	};
4456 	createCaseGroup(this, "texturegrad", textureGradCases, DE_LENGTH_OF_ARRAY(textureGradCases));
4457 
4458 	// textureGradClampARB() cases
4459 	static const TexFuncCaseSpec textureGradClampCases[] =
4460 	{
4461 		//		  Name									Function				MinCoord							MaxCoord							MinDx						MaxDx						MinDy						MaxDy						Offset?	Offset		LodClamp	Format					EvalFunc						Flags
4462 		GRADCLAMP_CASE_SPEC(sampler2d_fixed,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex2DMipmapFixed,			evalTexture2DGradClamp,				FRAGMENT),
4463 		GRADCLAMP_CASE_SPEC(sampler2d_float,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex2DMipmapFloat,			evalTexture2DGradClamp,				FRAGMENT),
4464 		GRADCLAMP_CASE_SPEC(isampler2d,					FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex2DMipmapInt,				evalTexture2DGradClamp,				FRAGMENT),
4465 		GRADCLAMP_CASE_SPEC(usampler2d,					FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	false,	IVec3(0),	5.0f,	tex2DMipmapUint,			evalTexture2DGradClamp,				FRAGMENT),
4466 
4467 		GRADCLAMP_CASE_SPEC(samplercube_fixed,			FUNCTION_TEXTUREGRAD,	Vec4(-1.0f, -1.0f,  1.01f,  0.0f),	Vec4( 1.0f,  1.0f,  1.01f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	texCubeMipmapFixed,			evalTextureCubeGradClamp,			FRAGMENT),
4468 		GRADCLAMP_CASE_SPEC(samplercube_float,			FUNCTION_TEXTUREGRAD,	Vec4(-1.0f, -1.0f, -1.01f,  0.0f),	Vec4( 1.0f,  1.0f, -1.01f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	texCubeMipmapFloat,			evalTextureCubeGradClamp,			FRAGMENT),
4469 		GRADCLAMP_CASE_SPEC(isamplercube,				FUNCTION_TEXTUREGRAD,	Vec4(-1.0f, -1.0f,  1.01f,  0.0f),	Vec4( 1.0f,  1.0f,  1.01f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	texCubeMipmapInt,			evalTextureCubeGradClamp,			FRAGMENT),
4470 		GRADCLAMP_CASE_SPEC(usamplercube,				FUNCTION_TEXTUREGRAD,	Vec4(-1.0f, -1.0f, -1.01f,  0.0f),	Vec4( 1.0f,  1.0f, -1.01f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	false,	IVec3(0),	5.0f,	texCubeMipmapUint,			evalTextureCubeGradClamp,			FRAGMENT),
4471 
4472 		GRADCLAMP_CASE_SPEC(sampler2darray_fixed,		FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex2DArrayMipmapFixed,		evalTexture2DArrayGradClamp,		FRAGMENT),
4473 		GRADCLAMP_CASE_SPEC(sampler2darray_float,		FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex2DArrayMipmapFloat,		evalTexture2DArrayGradClamp,		FRAGMENT),
4474 		GRADCLAMP_CASE_SPEC(isampler2darray,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex2DArrayMipmapInt,		evalTexture2DArrayGradClamp,		FRAGMENT),
4475 		GRADCLAMP_CASE_SPEC(usampler2darray,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	false,	IVec3(0),	5.0f,	tex2DArrayMipmapUint,		evalTexture2DArrayGradClamp,		FRAGMENT),
4476 
4477 		GRADCLAMP_CASE_SPEC(sampler3d_fixed,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex3DMipmapFixed,			evalTexture3DGradClamp,			FRAGMENT),
4478 		GRADCLAMP_CASE_SPEC(sampler3d_float,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.2f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex3DMipmapFloat,			evalTexture3DGradClamp,				FRAGMENT),
4479 		GRADCLAMP_CASE_SPEC(isampler3d,					FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex3DMipmapInt,				evalTexture3DGradClamp,				FRAGMENT),
4480 		GRADCLAMP_CASE_SPEC(usampler3d,					FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f, -0.2f),	false,	IVec3(0),	5.0f,	tex3DMipmapUint,			evalTexture3DGradClamp,				FRAGMENT),
4481 
4482 		GRADCLAMP_CASE_SPEC(sampler1d_fixed,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex1DMipmapFixed,			evalTexture1DGradClamp,				FRAGMENT),
4483 		GRADCLAMP_CASE_SPEC(sampler1d_float,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex1DMipmapFloat,			evalTexture1DGradClamp,				FRAGMENT),
4484 		GRADCLAMP_CASE_SPEC(isampler1d,					FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex1DMipmapInt,				evalTexture1DGradClamp,				FRAGMENT),
4485 		GRADCLAMP_CASE_SPEC(usampler1d,					FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex1DMipmapUint,			evalTexture1DGradClamp,				FRAGMENT),
4486 
4487 		GRADCLAMP_CASE_SPEC(sampler1darray_fixed,		FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex1DArrayMipmapFixed,		evalTexture1DArrayGradClamp,		FRAGMENT),
4488 		GRADCLAMP_CASE_SPEC(sampler1darray_float,		FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex1DArrayMipmapFloat,		evalTexture1DArrayGradClamp,		FRAGMENT),
4489 		GRADCLAMP_CASE_SPEC(isampler1darray,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex1DArrayMipmapInt,		evalTexture1DArrayGradClamp,		FRAGMENT),
4490 		GRADCLAMP_CASE_SPEC(usampler1darray,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex1DArrayMipmapUint,		evalTexture1DArrayGradClamp,		FRAGMENT),
4491 
4492 		GRADCLAMP_CASE_SPEC(samplercubearray_fixed,		FUNCTION_TEXTUREGRAD,	Vec4(-1.0f, -1.0f,  1.01f, -0.5f),	Vec4( 1.0f,  1.0f,  1.01f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	4.0f,	texCubeArrayMipmapFixed,	evalTextureCubeArrayGradClamp,		FRAGMENT),
4493 		GRADCLAMP_CASE_SPEC(samplercubearray_float,		FUNCTION_TEXTUREGRAD,	Vec4(-1.0f, -1.0f, -1.01f, -0.5f),	Vec4( 1.0f,  1.0f, -1.01f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	4.0f,	texCubeArrayMipmapFloat,	evalTextureCubeArrayGradClamp,		FRAGMENT),
4494 		GRADCLAMP_CASE_SPEC(isamplercubearray,			FUNCTION_TEXTUREGRAD,	Vec4(-1.0f, -1.0f,  1.01f, -0.5f),	Vec4( 1.0f,  1.0f,  1.01f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	4.0f,	texCubeArrayMipmapInt,		evalTextureCubeArrayGradClamp,		FRAGMENT),
4495 		GRADCLAMP_CASE_SPEC(usamplercubearray,			FUNCTION_TEXTUREGRAD,	Vec4(-1.0f, -1.0f, -1.01f, -0.5f),	Vec4( 1.0f,  1.0f, -1.01f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	false,	IVec3(0),	4.0f,	texCubeArrayMipmapUint,		evalTextureCubeArrayGradClamp,		FRAGMENT),
4496 
4497 		GRADCLAMP_CASE_SPEC(sampler2dshadow,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  1.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex2DMipmapShadow,			evalTexture2DShadowGradClamp,		FRAGMENT),
4498 		GRADCLAMP_CASE_SPEC(samplercubeshadow,			FUNCTION_TEXTUREGRAD,	Vec4(-1.0f, -1.0f,  1.01f,  0.0f),	Vec4( 1.0f,  1.0f,  1.01f,  1.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	texCubeMipmapShadow,		evalTextureCubeShadowGradClamp,		FRAGMENT),
4499 		GRADCLAMP_CASE_SPEC(sampler2darrayshadow,		FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  1.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	false,	IVec3(0),	5.0f,	tex2DArrayMipmapShadow,		evalTexture2DArrayShadowGradClamp,	FRAGMENT),
4500 		GRADCLAMP_CASE_SPEC(sampler1dshadow,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  1.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex1DMipmapShadow,			evalTexture1DShadowGradClamp,		FRAGMENT),
4501 		GRADCLAMP_CASE_SPEC(sampler1darrayshadow,		FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  1.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex1DArrayMipmapShadow,		evalTexture1DArrayShadowGradClamp,	FRAGMENT),
4502 	};
4503 	createCaseGroup(this, "texturegradclamp", textureGradClampCases, DE_LENGTH_OF_ARRAY(textureGradClampCases));
4504 
4505 	// textureGradOffset() cases
4506 	static const TexFuncCaseSpec textureGradOffsetCases[] =
4507 	{
4508 		//		  Name							Function				MinCoord							MaxCoord							MinDx						MaxDx						MinDy						MaxDy						Offset?	Offset				Format					EvalFunc							Flags
4509 		GRAD_CASE_SPEC(sampler2d_fixed,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	tex2DMipmapFixed,		evalTexture2DGradOffset,			BOTH),
4510 		GRAD_CASE_SPEC(sampler2d_float,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(7, -8, 0),	tex2DMipmapFloat,		evalTexture2DGradOffset,			BOTH),
4511 		GRAD_CASE_SPEC(isampler2d,				FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	tex2DMipmapInt,			evalTexture2DGradOffset,			BOTH),
4512 		GRAD_CASE_SPEC(usampler2d,				FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	true,	IVec3(7, -8, 0),	tex2DMipmapUint,		evalTexture2DGradOffset,			BOTH),
4513 
4514 		GRAD_CASE_SPEC(sampler2darray_fixed,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	tex2DArrayMipmapFixed,	evalTexture2DArrayGradOffset,		BOTH),
4515 		GRAD_CASE_SPEC(sampler2darray_float,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(7, -8, 0),	tex2DArrayMipmapFloat,	evalTexture2DArrayGradOffset,		BOTH),
4516 		GRAD_CASE_SPEC(isampler2darray,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	tex2DArrayMipmapInt,	evalTexture2DArrayGradOffset,		BOTH),
4517 		GRAD_CASE_SPEC(usampler2darray,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	true,	IVec3(7, -8, 0),	tex2DArrayMipmapUint,	evalTexture2DArrayGradOffset,		BOTH),
4518 
4519 		GRAD_CASE_SPEC(sampler3d_fixed,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 3),	tex3DMipmapFixed,		evalTexture3DGradOffset,			BOTH),
4520 		GRAD_CASE_SPEC(sampler3d_float,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(7, 3, -8),	tex3DMipmapFloat,		evalTexture3DGradOffset,			VERTEX),
4521 		GRAD_CASE_SPEC(sampler3d_float,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.2f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(3, -8, 7),	tex3DMipmapFloat,		evalTexture3DGradOffset,			FRAGMENT),
4522 		GRAD_CASE_SPEC(isampler3d,				FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 3),	tex3DMipmapInt,			evalTexture3DGradOffset,			BOTH),
4523 		GRAD_CASE_SPEC(usampler3d,				FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	true,	IVec3(7, 3, -8),	tex3DMipmapUint,		evalTexture3DGradOffset,			VERTEX),
4524 		GRAD_CASE_SPEC(usampler3d,				FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f, -0.2f),	true,	IVec3(3, -8, 7),	tex3DMipmapUint,		evalTexture3DGradOffset,			FRAGMENT),
4525 
4526 		GRAD_CASE_SPEC(sampler1d_fixed,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(-8, 0, 0),	tex1DMipmapFixed,		evalTexture1DGradOffset,			BOTH),
4527 		GRAD_CASE_SPEC(sampler1d_float,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(7,  0, 0),	tex1DMipmapFloat,		evalTexture1DGradOffset,			BOTH),
4528 		GRAD_CASE_SPEC(isampler1d,				FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	true,	IVec3(-8, 0, 0),	tex1DMipmapInt,			evalTexture1DGradOffset,			BOTH),
4529 		GRAD_CASE_SPEC(usampler1d,				FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	true,	IVec3(7,  0, 0),	tex1DMipmapUint,		evalTexture1DGradOffset,			BOTH),
4530 
4531 		GRAD_CASE_SPEC(sampler1darray_fixed,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(-8, 0, 0),	tex1DArrayMipmapFixed,	evalTexture1DArrayGradOffset,		BOTH),
4532 		GRAD_CASE_SPEC(sampler1darray_float,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(7,  0, 0),	tex1DArrayMipmapFloat,	evalTexture1DArrayGradOffset,		BOTH),
4533 		GRAD_CASE_SPEC(isampler1darray,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	true,	IVec3(-8, 0, 0),	tex1DArrayMipmapInt,	evalTexture1DArrayGradOffset,		BOTH),
4534 		GRAD_CASE_SPEC(usampler1darray,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	true,	IVec3(7,  0, 0),	tex1DArrayMipmapUint,	evalTexture1DArrayGradOffset,		BOTH),
4535 
4536 		GRAD_CASE_SPEC(sampler2dshadow,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  1.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	tex2DMipmapShadow,		evalTexture2DShadowGradOffset,		VERTEX),
4537 		GRAD_CASE_SPEC(sampler2dshadow,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  1.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(7, -8, 0),	tex2DMipmapShadow,		evalTexture2DShadowGradOffset,		FRAGMENT),
4538 		GRAD_CASE_SPEC(sampler2darrayshadow,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  1.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	tex2DArrayMipmapShadow,	evalTexture2DArrayShadowGradOffset,	VERTEX),
4539 		GRAD_CASE_SPEC(sampler2darrayshadow,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  1.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	true,	IVec3(7, -8, 0),	tex2DArrayMipmapShadow,	evalTexture2DArrayShadowGradOffset,	FRAGMENT),
4540 		GRAD_CASE_SPEC(sampler1dshadow,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  1.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(-8, 0, 0),	tex1DMipmapShadow,		evalTexture1DShadowGradOffset,		VERTEX),
4541 		GRAD_CASE_SPEC(sampler1dshadow,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  1.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(7,  0, 0),	tex1DMipmapShadow,		evalTexture1DShadowGradOffset,		FRAGMENT),
4542 		GRAD_CASE_SPEC(sampler1darrayshadow,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  1.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	true,	IVec3(-8, 0, 0),	tex1DArrayMipmapShadow,	evalTexture1DArrayShadowGradOffset,	VERTEX),
4543 		GRAD_CASE_SPEC(sampler1darrayshadow,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  1.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	true,	IVec3(7,  0, 0),	tex1DArrayMipmapShadow,	evalTexture1DArrayShadowGradOffset,	FRAGMENT),
4544 	};
4545 	createCaseGroup(this, "texturegradoffset", textureGradOffsetCases, DE_LENGTH_OF_ARRAY(textureGradOffsetCases));
4546 
4547 	// textureGradOffsetClampARB() cases
4548 	static const TexFuncCaseSpec textureGradOffsetClampCases[] =
4549 	{
4550 		//		  Name								Function				MinCoord							MaxCoord							MinDx						MaxDx						MinDy						MaxDy						Offset?	Offset				LodClamp	Format				EvalFunc									Flags
4551 		GRADCLAMP_CASE_SPEC(sampler2d_fixed,		FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	5.0f,	tex2DMipmapFixed,		evalTexture2DGradOffsetClamp,				FRAGMENT),
4552 		GRADCLAMP_CASE_SPEC(sampler2d_float,		FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(7, -8, 0),	5.0f,	tex2DMipmapFloat,		evalTexture2DGradOffsetClamp,				FRAGMENT),
4553 		GRADCLAMP_CASE_SPEC(isampler2d,				FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	5.0f,	tex2DMipmapInt,			evalTexture2DGradOffsetClamp,				FRAGMENT),
4554 		GRADCLAMP_CASE_SPEC(usampler2d,				FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	true,	IVec3(7, -8, 0),	5.0f,	tex2DMipmapUint,		evalTexture2DGradOffsetClamp,				FRAGMENT),
4555 
4556 		GRADCLAMP_CASE_SPEC(sampler2darray_fixed,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	5.0f,	tex2DArrayMipmapFixed,	evalTexture2DArrayGradOffsetClamp,			FRAGMENT),
4557 		GRADCLAMP_CASE_SPEC(sampler2darray_float,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(7, -8, 0),	5.0f,	tex2DArrayMipmapFloat,	evalTexture2DArrayGradOffsetClamp,			FRAGMENT),
4558 		GRADCLAMP_CASE_SPEC(isampler2darray,		FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	5.0f,	tex2DArrayMipmapInt,	evalTexture2DArrayGradOffsetClamp,			FRAGMENT),
4559 		GRADCLAMP_CASE_SPEC(usampler2darray,		FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	true,	IVec3(7, -8, 0),	5.0f,	tex2DArrayMipmapUint,	evalTexture2DArrayGradOffsetClamp,			FRAGMENT),
4560 
4561 		GRADCLAMP_CASE_SPEC(sampler3d_fixed,		FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 3),	5.0f,	tex3DMipmapFixed,		evalTexture3DGradOffsetClamp,				FRAGMENT),
4562 		GRADCLAMP_CASE_SPEC(sampler3d_float,		FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.2f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(3, -8, 7),	5.0f,	tex3DMipmapFloat,		evalTexture3DGradOffsetClamp,				FRAGMENT),
4563 		GRADCLAMP_CASE_SPEC(isampler3d,				FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 3),	5.0f,	tex3DMipmapInt,			evalTexture3DGradOffsetClamp,				FRAGMENT),
4564 		GRADCLAMP_CASE_SPEC(usampler3d,				FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f, -0.2f),	true,	IVec3(3, -8, 7),	5.0f,	tex3DMipmapUint,		evalTexture3DGradOffsetClamp,				FRAGMENT),
4565 
4566 		GRADCLAMP_CASE_SPEC(sampler1d_fixed,		FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(-8, 0, 0),	5.0f,	tex1DMipmapFixed,		evalTexture1DGradOffsetClamp,				FRAGMENT),
4567 		GRADCLAMP_CASE_SPEC(sampler1d_float,		FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(7,  0, 0),	5.0f,	tex1DMipmapFloat,		evalTexture1DGradOffsetClamp,				FRAGMENT),
4568 		GRADCLAMP_CASE_SPEC(isampler1d,				FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	true,	IVec3(-8, 0, 0),	5.0f,	tex1DMipmapInt,			evalTexture1DGradOffsetClamp,				FRAGMENT),
4569 		GRADCLAMP_CASE_SPEC(usampler1d,				FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	true,	IVec3(7,  0, 0),	5.0f,	tex1DMipmapUint,		evalTexture1DGradOffsetClamp,				FRAGMENT),
4570 
4571 		GRADCLAMP_CASE_SPEC(sampler1darray_fixed,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(-8, 0, 0),	5.0f,	tex1DArrayMipmapFixed,	evalTexture1DArrayGradOffsetClamp,			FRAGMENT),
4572 		GRADCLAMP_CASE_SPEC(sampler1darray_float,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(7,  0, 0),	5.0f,	tex1DArrayMipmapFloat,	evalTexture1DArrayGradOffsetClamp,			FRAGMENT),
4573 		GRADCLAMP_CASE_SPEC(isampler1darray,		FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	true,	IVec3(-8, 0, 0),	5.0f,	tex1DArrayMipmapInt,	evalTexture1DArrayGradOffsetClamp,			FRAGMENT),
4574 		GRADCLAMP_CASE_SPEC(usampler1darray,		FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	true,	IVec3(7,  0, 0),	5.0f,	tex1DArrayMipmapUint,	evalTexture1DArrayGradOffsetClamp,			FRAGMENT),
4575 
4576 		GRADCLAMP_CASE_SPEC(sampler2dshadow,		FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  1.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(7, -8, 0),	5.0f,	tex2DMipmapShadow,		evalTexture2DShadowGradOffsetClamp,			FRAGMENT),
4577 		GRADCLAMP_CASE_SPEC(sampler2darrayshadow,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  1.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	true,	IVec3(7, -8, 0),	5.0f,	tex2DArrayMipmapShadow,	evalTexture2DArrayShadowGradOffsetClamp,	FRAGMENT),
4578 		GRADCLAMP_CASE_SPEC(sampler1dshadow,		FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  1.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(7,  0, 0),	5.0f,	tex1DMipmapShadow,		evalTexture1DShadowGradOffsetClamp,			FRAGMENT),
4579 		GRADCLAMP_CASE_SPEC(sampler1darrayshadow,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  1.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	true,	IVec3(7,  0, 0),	5.0f,	tex1DArrayMipmapShadow,	evalTexture1DArrayShadowGradOffsetClamp,	FRAGMENT),
4580 	};
4581 	createCaseGroup(this, "texturegradoffsetclamp", textureGradOffsetClampCases, DE_LENGTH_OF_ARRAY(textureGradOffsetClampCases));
4582 
4583 
4584 	// textureProjGrad() cases
4585 	static const TexFuncCaseSpec textureProjGradCases[] =
4586 	{
4587 		//		  Name							Function					MinCoord							MaxCoord							MinDx						MaxDx						MinDy						MaxDy						Offset?	Offset		Format					EvalFunc					Flags
4588 		GRAD_CASE_SPEC(sampler2d_vec3_fixed,	FUNCTION_TEXTUREPROJGRAD3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex2DMipmapFixed,		evalTexture2DProjGrad3,		BOTH),
4589 		GRAD_CASE_SPEC(sampler2d_vec3_float,	FUNCTION_TEXTUREPROJGRAD3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex2DMipmapFloat,		evalTexture2DProjGrad3,		BOTH),
4590 		GRAD_CASE_SPEC(isampler2d_vec3,			FUNCTION_TEXTUREPROJGRAD3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	tex2DMipmapInt,			evalTexture2DProjGrad3,		BOTH),
4591 		GRAD_CASE_SPEC(usampler2d_vec3,			FUNCTION_TEXTUREPROJGRAD3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	false,	IVec3(0),	tex2DMipmapUint,		evalTexture2DProjGrad3,		BOTH),
4592 
4593 		GRAD_CASE_SPEC(sampler2d_vec4_fixed,	FUNCTION_TEXTUREPROJGRAD,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex2DMipmapFixed,		evalTexture2DProjGrad,		BOTH),
4594 		GRAD_CASE_SPEC(sampler2d_vec4_float,	FUNCTION_TEXTUREPROJGRAD,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex2DMipmapFloat,		evalTexture2DProjGrad,		BOTH),
4595 		GRAD_CASE_SPEC(isampler2d_vec4,			FUNCTION_TEXTUREPROJGRAD,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	tex2DMipmapInt,			evalTexture2DProjGrad,		BOTH),
4596 		GRAD_CASE_SPEC(usampler2d_vec4,			FUNCTION_TEXTUREPROJGRAD,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	false,	IVec3(0),	tex2DMipmapUint,		evalTexture2DProjGrad,		BOTH),
4597 
4598 		GRAD_CASE_SPEC(sampler3d_fixed,			FUNCTION_TEXTUREPROJGRAD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex3DMipmapFixed,		evalTexture3DProjGrad,		BOTH),
4599 		GRAD_CASE_SPEC(sampler3d_float,			FUNCTION_TEXTUREPROJGRAD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex3DMipmapFloat,		evalTexture3DProjGrad,		VERTEX),
4600 		GRAD_CASE_SPEC(sampler3d_float,			FUNCTION_TEXTUREPROJGRAD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.2f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex3DMipmapFloat,		evalTexture3DProjGrad,		FRAGMENT),
4601 		GRAD_CASE_SPEC(isampler3d,				FUNCTION_TEXTUREPROJGRAD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	tex3DMipmapInt,			evalTexture3DProjGrad,		BOTH),
4602 		GRAD_CASE_SPEC(usampler3d,				FUNCTION_TEXTUREPROJGRAD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	false,	IVec3(0),	tex3DMipmapUint,		evalTexture3DProjGrad,		VERTEX),
4603 		GRAD_CASE_SPEC(usampler3d,				FUNCTION_TEXTUREPROJGRAD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f, -0.2f),	false,	IVec3(0),	tex3DMipmapUint,		evalTexture3DProjGrad,		FRAGMENT),
4604 
4605 		GRAD_CASE_SPEC(sampler1d_vec2_fixed,	FUNCTION_TEXTUREPROJGRAD2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DMipmapFixed,		evalTexture1DProjGrad2,		BOTH),
4606 		GRAD_CASE_SPEC(sampler1d_vec2_float,	FUNCTION_TEXTUREPROJGRAD2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DMipmapFloat,		evalTexture1DProjGrad2,		BOTH),
4607 		GRAD_CASE_SPEC(isampler1d_vec2,			FUNCTION_TEXTUREPROJGRAD2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DMipmapInt,			evalTexture1DProjGrad2,		BOTH),
4608 		GRAD_CASE_SPEC(usampler1d_vec2,			FUNCTION_TEXTUREPROJGRAD2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DMipmapUint,		evalTexture1DProjGrad2,		BOTH),
4609 
4610 		GRAD_CASE_SPEC(sampler1d_vec4_fixed,	FUNCTION_TEXTUREPROJGRAD,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DMipmapFixed,		evalTexture1DProjGrad,		BOTH),
4611 		GRAD_CASE_SPEC(sampler1d_vec4_float,	FUNCTION_TEXTUREPROJGRAD,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DMipmapFloat,		evalTexture1DProjGrad,		BOTH),
4612 		GRAD_CASE_SPEC(isampler1d_vec4,			FUNCTION_TEXTUREPROJGRAD,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DMipmapInt,			evalTexture1DProjGrad,		BOTH),
4613 		GRAD_CASE_SPEC(usampler1d_vec4,			FUNCTION_TEXTUREPROJGRAD,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DMipmapUint,		evalTexture1DProjGrad,		BOTH),
4614 
4615 		GRAD_CASE_SPEC(sampler2dshadow,			FUNCTION_TEXTUREPROJGRAD,	Vec4( 0.2f, 0.6f,  0.0f,  -1.5f),	Vec4(-2.25f, -3.45f, -1.5f, -1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex2DMipmapShadow,		evalTexture2DShadowProjGrad,	VERTEX),
4616 		GRAD_CASE_SPEC(sampler2dshadow,			FUNCTION_TEXTUREPROJGRAD,	Vec4( 0.2f, 0.6f,  0.0f,  -1.5f),	Vec4(-2.25f, -3.45f, -1.5f, -1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	false,	IVec3(0),	tex2DMipmapShadow,		evalTexture2DShadowProjGrad,	FRAGMENT),
4617 		GRAD_CASE_SPEC(sampler1dshadow,			FUNCTION_TEXTUREPROJGRAD,	Vec4( 0.2f, 0.0f,  0.0f,  -1.5f),	Vec4(-2.25f,   0.0f, -1.5f, -1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DMipmapShadow,		evalTexture1DShadowProjGrad,	VERTEX),
4618 		GRAD_CASE_SPEC(sampler1dshadow,			FUNCTION_TEXTUREPROJGRAD,	Vec4( 0.2f, 0.0f,  0.0f,  -1.5f),	Vec4(-2.25f,   0.0f, -1.5f, -1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DMipmapShadow,		evalTexture1DShadowProjGrad,	FRAGMENT),
4619 	};
4620 	createCaseGroup(this, "textureprojgrad", textureProjGradCases, DE_LENGTH_OF_ARRAY(textureProjGradCases));
4621 
4622 	// textureProjGradOffset() cases
4623 	static const TexFuncCaseSpec textureProjGradOffsetCases[] =
4624 	{
4625 		//		  Name							Function					MinCoord							MaxCoord							MinDx						MaxDx						MinDy						MaxDy						Offset?	Offset				Format					EvalFunc							Flags
4626 		GRAD_CASE_SPEC(sampler2d_vec3_fixed,	FUNCTION_TEXTUREPROJGRAD3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	tex2DMipmapFixed,		evalTexture2DProjGrad3Offset,		BOTH),
4627 		GRAD_CASE_SPEC(sampler2d_vec3_float,	FUNCTION_TEXTUREPROJGRAD3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(7, -8, 0),	tex2DMipmapFloat,		evalTexture2DProjGrad3Offset,		BOTH),
4628 		GRAD_CASE_SPEC(isampler2d_vec3,			FUNCTION_TEXTUREPROJGRAD3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	tex2DMipmapInt,			evalTexture2DProjGrad3Offset,		BOTH),
4629 		GRAD_CASE_SPEC(usampler2d_vec3,			FUNCTION_TEXTUREPROJGRAD3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	true,	IVec3(7, -8, 0),	tex2DMipmapUint,		evalTexture2DProjGrad3Offset,		BOTH),
4630 
4631 		GRAD_CASE_SPEC(sampler2d_vec4_fixed,	FUNCTION_TEXTUREPROJGRAD,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	tex2DMipmapFixed,		evalTexture2DProjGradOffset,		BOTH),
4632 		GRAD_CASE_SPEC(sampler2d_vec4_float,	FUNCTION_TEXTUREPROJGRAD,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(7, -8, 0),	tex2DMipmapFloat,		evalTexture2DProjGradOffset,		BOTH),
4633 		GRAD_CASE_SPEC(isampler2d_vec4,			FUNCTION_TEXTUREPROJGRAD,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	tex2DMipmapInt,			evalTexture2DProjGradOffset,		BOTH),
4634 		GRAD_CASE_SPEC(usampler2d_vec4,			FUNCTION_TEXTUREPROJGRAD,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	true,	IVec3(7, -8, 0),	tex2DMipmapUint,		evalTexture2DProjGradOffset,		BOTH),
4635 
4636 		GRAD_CASE_SPEC(sampler3d_fixed,			FUNCTION_TEXTUREPROJGRAD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 3),	tex3DMipmapFixed,		evalTexture3DProjGradOffset,		BOTH),
4637 		GRAD_CASE_SPEC(sampler3d_float,			FUNCTION_TEXTUREPROJGRAD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(7, 3, -8),	tex3DMipmapFloat,		evalTexture3DProjGradOffset,		VERTEX),
4638 		GRAD_CASE_SPEC(sampler3d_float,			FUNCTION_TEXTUREPROJGRAD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.2f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(3, -8, 7),	tex3DMipmapFloat,		evalTexture3DProjGradOffset,		FRAGMENT),
4639 		GRAD_CASE_SPEC(isampler3d,				FUNCTION_TEXTUREPROJGRAD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 3),	tex3DMipmapInt,			evalTexture3DProjGradOffset,		BOTH),
4640 		GRAD_CASE_SPEC(usampler3d,				FUNCTION_TEXTUREPROJGRAD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	true,	IVec3(7, 3, -8),	tex3DMipmapUint,		evalTexture3DProjGradOffset,		VERTEX),
4641 		GRAD_CASE_SPEC(usampler3d,				FUNCTION_TEXTUREPROJGRAD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f, -0.2f),	true,	IVec3(3, -8, 7),	tex3DMipmapUint,		evalTexture3DProjGradOffset,		FRAGMENT),
4642 
4643 		GRAD_CASE_SPEC(sampler1d_vec2_fixed,	FUNCTION_TEXTUREPROJGRAD2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	tex1DMipmapFixed,		evalTexture1DProjGrad2Offset,		BOTH),
4644 		GRAD_CASE_SPEC(sampler1d_vec2_float,	FUNCTION_TEXTUREPROJGRAD2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(7, -8, 0),	tex1DMipmapFloat,		evalTexture1DProjGrad2Offset,		BOTH),
4645 		GRAD_CASE_SPEC(isampler1d_vec2,			FUNCTION_TEXTUREPROJGRAD2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	tex1DMipmapInt,			evalTexture1DProjGrad2Offset,		BOTH),
4646 		GRAD_CASE_SPEC(usampler1d_vec2,			FUNCTION_TEXTUREPROJGRAD2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	true,	IVec3(7, -8, 0),	tex1DMipmapUint,		evalTexture1DProjGrad2Offset,		BOTH),
4647 
4648 		GRAD_CASE_SPEC(sampler1d_vec4_fixed,	FUNCTION_TEXTUREPROJGRAD,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	tex1DMipmapFixed,		evalTexture1DProjGradOffset,		BOTH),
4649 		GRAD_CASE_SPEC(sampler1d_vec4_float,	FUNCTION_TEXTUREPROJGRAD,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(7, -8, 0),	tex1DMipmapFloat,		evalTexture1DProjGradOffset,		BOTH),
4650 		GRAD_CASE_SPEC(isampler1d_vec4,			FUNCTION_TEXTUREPROJGRAD,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	tex1DMipmapInt,			evalTexture1DProjGradOffset,		BOTH),
4651 		GRAD_CASE_SPEC(usampler1d_vec4,			FUNCTION_TEXTUREPROJGRAD,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	true,	IVec3(7, -8, 0),	tex1DMipmapUint,		evalTexture1DProjGradOffset,		BOTH),
4652 
4653 		GRAD_CASE_SPEC(sampler2dshadow,			FUNCTION_TEXTUREPROJGRAD,	Vec4( 0.2f, 0.6f,  0.0f,  -1.5f),	Vec4(-2.25f, -3.45f, -1.5f, -1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	tex2DMipmapShadow,		evalTexture2DShadowProjGradOffset,	VERTEX),
4654 		GRAD_CASE_SPEC(sampler2dshadow,			FUNCTION_TEXTUREPROJGRAD,	Vec4( 0.2f, 0.6f,  0.0f,  -1.5f),	Vec4(-2.25f, -3.45f, -1.5f, -1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	true,	IVec3(7, -8, 0),	tex2DMipmapShadow,		evalTexture2DShadowProjGradOffset,	FRAGMENT),
4655 		GRAD_CASE_SPEC(sampler1dshadow,			FUNCTION_TEXTUREPROJGRAD,	Vec4( 0.2f, 0.0f,  0.0f,  -1.5f),	Vec4(-2.25f,   0.0f, -1.5f, -1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	tex1DMipmapShadow,		evalTexture1DShadowProjGradOffset,	VERTEX),
4656 		GRAD_CASE_SPEC(sampler1dshadow,			FUNCTION_TEXTUREPROJGRAD,	Vec4( 0.2f, 0.0f,  0.0f,  -1.5f),	Vec4(-2.25f,   0.0f, -1.5f, -1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	true,	IVec3(7, -8, 0),	tex1DMipmapShadow,		evalTexture1DShadowProjGradOffset,	FRAGMENT),
4657 	};
4658 	createCaseGroup(this, "textureprojgradoffset", textureProjGradOffsetCases, DE_LENGTH_OF_ARRAY(textureProjGradOffsetCases));
4659 
4660 	// texelFetch() cases
4661 	// \note Level is constant across quad
4662 	static const TexFuncCaseSpec texelFetchCases[] =
4663 	{
4664 		//		  Name							Function				MinCoord							MaxCoord						Bias?	MinLod	MaxLod	Offset?	Offset		Format						EvalFunc				Flags
4665 		CASE_SPEC(sampler2d_fixed,				FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4(255.9f, 255.9f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DTexelFetchFixed,		evalTexelFetch2D,		BOTH),
4666 		CASE_SPEC(sampler2d_float,				FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4(127.9f, 127.9f,  0.0f,  0.0f),	false,	1.0f,	1.0f,	false,	IVec3(0),	tex2DTexelFetchFloat,		evalTexelFetch2D,		BOTH),
4667 		CASE_SPEC(isampler2d,					FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4( 63.9f,  63.9f,  0.0f,  0.0f),	false,	2.0f,	2.0f,	false,	IVec3(0),	tex2DTexelFetchInt,			evalTexelFetch2D,		BOTH),
4668 		CASE_SPEC(usampler2d,					FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4( 15.9f,  15.9f,  0.0f,  0.0f),	false,	4.0f,	4.0f,	false,	IVec3(0),	tex2DTexelFetchUint,		evalTexelFetch2D,		BOTH),
4669 
4670 		CASE_SPEC(sampler2darray_fixed,			FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4(127.9f, 127.9f,  3.9f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DArrayTexelFetchFixed,	evalTexelFetch2DArray,	BOTH),
4671 		CASE_SPEC(sampler2darray_float,			FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4( 63.9f,  63.9f,  3.9f,  0.0f),	false,	1.0f,	1.0f,	false,	IVec3(0),	tex2DArrayTexelFetchFloat,	evalTexelFetch2DArray,	BOTH),
4672 		CASE_SPEC(isampler2darray,				FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4( 31.9f,  31.9f,  3.9f,  0.0f),	false,	2.0f,	2.0f,	false,	IVec3(0),	tex2DArrayTexelFetchInt,	evalTexelFetch2DArray,	BOTH),
4673 		CASE_SPEC(usampler2darray,				FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4( 15.9f,  15.9f,  3.9f,  0.0f),	false,	3.0f,	3.0f,	false,	IVec3(0),	tex2DArrayTexelFetchUint,	evalTexelFetch2DArray,	BOTH),
4674 
4675 		CASE_SPEC(sampler3d_fixed,				FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4(63.9f,  31.9f,  31.9f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex3DTexelFetchFixed,		evalTexelFetch3D,		BOTH),
4676 		CASE_SPEC(sampler3d_float,				FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4(31.9f,  15.9f,  15.9f,  0.0f),	false,	1.0f,	1.0f,	false,	IVec3(0),	tex3DTexelFetchFloat,		evalTexelFetch3D,		BOTH),
4677 		CASE_SPEC(isampler3d,					FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4(15.9f,   7.9f,   7.9f,  0.0f),	false,	2.0f,	2.0f,	false,	IVec3(0),	tex3DTexelFetchInt,			evalTexelFetch3D,		BOTH),
4678 		CASE_SPEC(usampler3d,					FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4(63.9f,  31.9f,  31.9f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex3DTexelFetchUint,		evalTexelFetch3D,		BOTH),
4679 
4680 		CASE_SPEC(sampler1d_fixed,				FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4(255.9f,   0.0f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DTexelFetchFixed,		evalTexelFetch1D,		BOTH),
4681 		CASE_SPEC(sampler1d_float,				FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4(127.9f,   0.0f,  0.0f,  0.0f),	false,	1.0f,	1.0f,	false,	IVec3(0),	tex1DTexelFetchFloat,		evalTexelFetch1D,		BOTH),
4682 		CASE_SPEC(isampler1d,					FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4( 63.9f,   0.0f,  0.0f,  0.0f),	false,	2.0f,	2.0f,	false,	IVec3(0),	tex1DTexelFetchInt,			evalTexelFetch1D,		BOTH),
4683 		CASE_SPEC(usampler1d,					FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4( 15.9f,   0.0f,  0.0f,  0.0f),	false,	4.0f,	4.0f,	false,	IVec3(0),	tex1DTexelFetchUint,		evalTexelFetch1D,		BOTH),
4684 
4685 		CASE_SPEC(sampler1darray_fixed,			FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4(255.9f,   3.9f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DArrayTexelFetchFixed,	evalTexelFetch1DArray,	BOTH),
4686 		CASE_SPEC(sampler1darray_float,			FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4(127.9f,   3.9f,  0.0f,  0.0f),	false,	1.0f,	1.0f,	false,	IVec3(0),	tex1DArrayTexelFetchFloat,	evalTexelFetch1DArray,	BOTH),
4687 		CASE_SPEC(isampler1darray,				FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4( 63.9f,   3.9f,  0.0f,  0.0f),	false,	2.0f,	2.0f,	false,	IVec3(0),	tex1DArrayTexelFetchInt,	evalTexelFetch1DArray,	BOTH),
4688 		CASE_SPEC(usampler1darray,				FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4( 15.9f,   3.9f,  0.0f,  0.0f),	false,	4.0f,	4.0f,	false,	IVec3(0),	tex1DArrayTexelFetchUint,	evalTexelFetch1DArray,	BOTH),
4689 	};
4690 	createCaseGroup(this, "texelfetch", texelFetchCases, DE_LENGTH_OF_ARRAY(texelFetchCases));
4691 
4692 	// texelFetchOffset() cases
4693 	static const TexFuncCaseSpec texelFetchOffsetCases[] =
4694 	{
4695 		//		  Name							Function				MinCoord							MaxCoord						Bias?	MinLod	MaxLod	Offset?	Offset		Format						EvalFunc				Flags
4696 		CASE_SPEC(sampler2d_fixed,				FUNCTION_TEXELFETCH,	Vec4( 8.0f, -7.0f, 0.0f, 0.0f),	Vec4(263.9f, 248.9f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DTexelFetchFixed,		evalTexelFetch2D,		BOTH),
4697 		CASE_SPEC(sampler2d_float,				FUNCTION_TEXELFETCH,	Vec4(-7.0f,  8.0f, 0.0f, 0.0f),	Vec4(120.9f, 135.9f,  0.0f,  0.0f),	false,	1.0f,	1.0f,	true,	IVec3(7, -8, 0),	tex2DTexelFetchFloat,		evalTexelFetch2D,		BOTH),
4698 		CASE_SPEC(isampler2d,					FUNCTION_TEXELFETCH,	Vec4( 8.0f, -7.0f, 0.0f, 0.0f),	Vec4( 71.9f,  56.9f,  0.0f,  0.0f),	false,	2.0f,	2.0f,	true,	IVec3(-8, 7, 0),	tex2DTexelFetchInt,			evalTexelFetch2D,		BOTH),
4699 		CASE_SPEC(usampler2d,					FUNCTION_TEXELFETCH,	Vec4(-7.0f,  8.0f, 0.0f, 0.0f),	Vec4(  8.9f,  23.9f,  0.0f,  0.0f),	false,	4.0f,	4.0f,	true,	IVec3(7, -8, 0),	tex2DTexelFetchUint,		evalTexelFetch2D,		BOTH),
4700 
4701 		CASE_SPEC(sampler2darray_fixed,			FUNCTION_TEXELFETCH,	Vec4( 8.0f, -7.0f, 0.0f, 0.0f),	Vec4(135.9f, 120.9f,  3.9f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DArrayTexelFetchFixed,	evalTexelFetch2DArray,	BOTH),
4702 		CASE_SPEC(sampler2darray_float,			FUNCTION_TEXELFETCH,	Vec4(-7.0f,  8.0f, 0.0f, 0.0f),	Vec4( 56.9f,  71.9f,  3.9f,  0.0f),	false,	1.0f,	1.0f,	true,	IVec3(7, -8, 0),	tex2DArrayTexelFetchFloat,	evalTexelFetch2DArray,	BOTH),
4703 		CASE_SPEC(isampler2darray,				FUNCTION_TEXELFETCH,	Vec4( 8.0f, -7.0f, 0.0f, 0.0f),	Vec4( 39.9f,  24.9f,  3.9f,  0.0f),	false,	2.0f,	2.0f,	true,	IVec3(-8, 7, 0),	tex2DArrayTexelFetchInt,	evalTexelFetch2DArray,	BOTH),
4704 		CASE_SPEC(usampler2darray,				FUNCTION_TEXELFETCH,	Vec4(-7.0f,  8.0f, 0.0f, 0.0f),	Vec4(  8.9f,  23.9f,  3.9f,  0.0f),	false,	3.0f,	3.0f,	true,	IVec3(7, -8, 0),	tex2DArrayTexelFetchUint,	evalTexelFetch2DArray,	BOTH),
4705 
4706 		CASE_SPEC(sampler3d_fixed,				FUNCTION_TEXELFETCH,	Vec4( 8.0f, -7.0f, -3.0f, 0.0f),Vec4(71.9f,  24.9f,  28.9f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 3),	tex3DTexelFetchFixed,		evalTexelFetch3D,		BOTH),
4707 		CASE_SPEC(sampler3d_float,				FUNCTION_TEXELFETCH,	Vec4(-7.0f, -3.0f,  8.0f, 0.0f),Vec4(24.9f,  12.9f,  23.9f,  0.0f),	false,	1.0f,	1.0f,	true,	IVec3(7, 3, -8),	tex3DTexelFetchFloat,		evalTexelFetch3D,		BOTH),
4708 		CASE_SPEC(isampler3d,					FUNCTION_TEXELFETCH,	Vec4(-3.0f,  8.0f, -7.0f, 0.0f),Vec4(12.9f,  15.9f,   0.9f,  0.0f),	false,	2.0f,	2.0f,	true,	IVec3(3, -8, 7),	tex3DTexelFetchInt,			evalTexelFetch3D,		BOTH),
4709 		CASE_SPEC(usampler3d,					FUNCTION_TEXELFETCH,	Vec4( 8.0f, -7.0f, -3.0f, 0.0f),Vec4(71.9f,  24.9f,  28.9f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 3),	tex3DTexelFetchUint,		evalTexelFetch3D,		BOTH),
4710 
4711 		CASE_SPEC(sampler1d_fixed,				FUNCTION_TEXELFETCH,	Vec4( 8.0f,  0.0f, 0.0f, 0.0f),	Vec4(263.9f,   0.0f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DTexelFetchFixed,		evalTexelFetch1D,		BOTH),
4712 		CASE_SPEC(sampler1d_float,				FUNCTION_TEXELFETCH,	Vec4(-7.0f,  0.0f, 0.0f, 0.0f),	Vec4(120.9f,   0.0f,  0.0f,  0.0f),	false,	1.0f,	1.0f,	true,	IVec3(7,  0, 0),	tex1DTexelFetchFloat,		evalTexelFetch1D,		BOTH),
4713 		CASE_SPEC(isampler1d,					FUNCTION_TEXELFETCH,	Vec4( 8.0f,  0.0f, 0.0f, 0.0f),	Vec4( 71.9f,   0.0f,  0.0f,  0.0f),	false,	2.0f,	2.0f,	true,	IVec3(-8, 0, 0),	tex1DTexelFetchInt,			evalTexelFetch1D,		BOTH),
4714 		CASE_SPEC(usampler1d,					FUNCTION_TEXELFETCH,	Vec4(-7.0f,  0.0f, 0.0f, 0.0f),	Vec4(  8.9f,   0.0f,  0.0f,  0.0f),	false,	4.0f,	4.0f,	true,	IVec3(7,  0, 0),	tex1DTexelFetchUint,		evalTexelFetch1D,		BOTH),
4715 
4716 		CASE_SPEC(sampler1darray_fixed,			FUNCTION_TEXELFETCH,	Vec4( 8.0f,  0.0f, 0.0f, 0.0f),	Vec4(135.9f,   3.9f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DArrayTexelFetchFixed,	evalTexelFetch1DArray,	BOTH),
4717 		CASE_SPEC(sampler1darray_float,			FUNCTION_TEXELFETCH,	Vec4(-7.0f,  0.0f, 0.0f, 0.0f),	Vec4( 56.9f,   3.9f,  0.0f,  0.0f),	false,	1.0f,	1.0f,	true,	IVec3(7,  0, 0),	tex1DArrayTexelFetchFloat,	evalTexelFetch1DArray,	BOTH),
4718 		CASE_SPEC(isampler1darray,				FUNCTION_TEXELFETCH,	Vec4( 8.0f,  0.0f, 0.0f, 0.0f),	Vec4( 39.9f,   3.9f,  0.0f,  0.0f),	false,	2.0f,	2.0f,	true,	IVec3(-8, 0, 0),	tex1DArrayTexelFetchInt,	evalTexelFetch1DArray,	BOTH),
4719 		CASE_SPEC(usampler1darray,				FUNCTION_TEXELFETCH,	Vec4(-7.0f,  0.0f, 0.0f, 0.0f),	Vec4(  8.9f,   3.9f,  0.0f,  0.0f),	false,	3.0f,	3.0f,	true,	IVec3(7,  0, 0),	tex1DArrayTexelFetchUint,	evalTexelFetch1DArray,	BOTH),
4720 	};
4721 	createCaseGroup(this, "texelfetchoffset", texelFetchOffsetCases, DE_LENGTH_OF_ARRAY(texelFetchOffsetCases));
4722 
4723 	// texture query functions
4724 	{
4725 		struct TexQueryFuncCaseSpec
4726 		{
4727 			const char*		name;
4728 			const char*		samplerName;
4729 			TextureSpec		textureSpec;
4730 		};
4731 
4732 		de::MovePtr<tcu::TestCaseGroup>			queryGroup	(new tcu::TestCaseGroup(m_testCtx, "query"));
4733 
4734 		// textureSize() cases
4735 		{
4736 			const TexQueryFuncCaseSpec textureSizeCases[] =
4737 			{
4738 				{ "sampler2d_fixed",			"sampler2D",				tex2DFixed			},
4739 				{ "sampler2d_float",			"sampler2D",				tex2DFloat			},
4740 				{ "isampler2d",					"isampler2D",				tex2DInt			},
4741 				{ "usampler2d",					"usampler2D",				tex2DUint			},
4742 				{ "sampler2dshadow",			"sampler2DShadow",			tex2DShadow			},
4743 				{ "sampler3d_fixed",			"sampler3D",				tex3DFixed			},
4744 				{ "sampler3d_float",			"sampler3D",				tex3DFloat			},
4745 				{ "isampler3d",					"isampler3D",				tex3DInt			},
4746 				{ "usampler3d",					"usampler3D",				tex3DUint			},
4747 				{ "samplercube_fixed",			"samplerCube",				texCubeFixed		},
4748 				{ "samplercube_float",			"samplerCube",				texCubeFloat		},
4749 				{ "isamplercube",				"isamplerCube",				texCubeInt			},
4750 				{ "usamplercube",				"usamplerCube",				texCubeUint			},
4751 				{ "samplercubeshadow",			"samplerCubeShadow",		texCubeShadow		},
4752 				{ "sampler2darray_fixed",		"sampler2DArray",			tex2DArrayFixed		},
4753 				{ "sampler2darray_float",		"sampler2DArray",			tex2DArrayFloat		},
4754 				{ "isampler2darray",			"isampler2DArray",			tex2DArrayInt		},
4755 				{ "usampler2darray",			"usampler2DArray",			tex2DArrayUint		},
4756 				{ "sampler2darrayshadow",		"sampler2DArrayShadow",		tex2DArrayShadow	},
4757 				{ "samplercubearray_fixed",		"samplerCubeArray",			texCubeArrayFixed	},
4758 				{ "samplercubearray_float",		"samplerCubeArray",			texCubeArrayFloat	},
4759 				{ "isamplercubearray",			"isamplerCubeArray",		texCubeArrayInt		},
4760 				{ "usamplercubearray",			"usamplerCubeArray",		texCubeArrayUint	},
4761 				{ "samplercubearrayshadow",		"samplerCubeArrayShadow",	texCubeArrayShadow	},
4762 				{ "sampler1d_fixed",			"sampler1D",				tex1DFixed			},
4763 				{ "sampler1d_float",			"sampler1D",				tex1DFloat			},
4764 				{ "isampler1d",					"isampler1D",				tex1DInt			},
4765 				{ "usampler1d",					"usampler1D",				tex1DUint			},
4766 				{ "sampler1dshadow",			"sampler1DShadow",			tex1DShadow			},
4767 				{ "sampler1darray_fixed",		"sampler1DArray",			tex1DArrayFixed		},
4768 				{ "sampler1darray_float",		"sampler1DArray",			tex1DArrayFloat		},
4769 				{ "isampler1darray",			"isampler1DArray",			tex1DArrayInt		},
4770 				{ "usampler1darray",			"usampler1DArray",			tex1DArrayUint		},
4771 				{ "sampler1darrayshadow",		"sampler1DArrayShadow",		tex1DArrayShadow	},
4772 			};
4773 
4774 			de::MovePtr<tcu::TestCaseGroup>		group		(new tcu::TestCaseGroup(m_testCtx, "texturesize"));
4775 
4776 			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(textureSizeCases); ++ndx)
4777 			{
4778 				const TexQueryFuncCaseSpec&		caseSpec	= textureSizeCases[ndx];
4779 
4780 				group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_vertex"), caseSpec.samplerName, caseSpec.textureSpec, true,  QUERYFUNCTION_TEXTURESIZE));
4781 				group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_fragment"), caseSpec.samplerName, caseSpec.textureSpec, false, QUERYFUNCTION_TEXTURESIZE));
4782 			}
4783 
4784 			// additional coverage for textureSize special cases
4785 			addFunctionCaseWithPrograms(group.get(), "oob_lod", SpecialCases::textureSizeOOBPrograms, SpecialCases::textureSizeOOBTest);
4786 
4787 			queryGroup->addChild(group.release());
4788 		}
4789 
4790 		// textureSize() cases for multisample textures
4791 		{
4792 			const TexQueryFuncCaseSpec textureSizeMSCases[] =
4793 			{
4794 				{ "sampler2dms_fixed",			"sampler2DMS",				tex2DFixed			},
4795 				{ "sampler2dms_float",			"sampler2DMS",				tex2DFloat			},
4796 				{ "isampler2dms",				"isampler2DMS",				tex2DInt			},
4797 				{ "usampler2dms",				"usampler2DMS",				tex2DUint			},
4798 				{ "sampler2dmsarray_fixed",		"sampler2DMSArray",			tex2DArrayFixed		},
4799 				{ "sampler2dmsarray_float",		"sampler2DMSArray",			tex2DArrayFloat		},
4800 				{ "isampler2dmsarray",			"isampler2DMSArray",		tex2DArrayInt		},
4801 				{ "usampler2dmsarray",			"usampler2DMSArray",		tex2DArrayUint		},
4802 			};
4803 
4804 			de::MovePtr<tcu::TestCaseGroup>		group		(new tcu::TestCaseGroup(m_testCtx, "texturesizems"));
4805 
4806 			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(textureSizeMSCases); ++ndx)
4807 			{
4808 				const TexQueryFuncCaseSpec&		caseSpec	= textureSizeMSCases[ndx];
4809 
4810 				group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_vertex"), caseSpec.samplerName, caseSpec.textureSpec, true,  QUERYFUNCTION_TEXTURESIZEMS));
4811 				group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_fragment"), caseSpec.samplerName, caseSpec.textureSpec, false, QUERYFUNCTION_TEXTURESIZEMS));
4812 			}
4813 
4814 			queryGroup->addChild(group.release());
4815 		}
4816 
4817 		// textureSamples() cases
4818 		{
4819 			const TexQueryFuncCaseSpec textureSamplesCases[] =
4820 			{
4821 				{ "sampler2dms_fixed",			"sampler2DMS",				tex2DFixed			},
4822 				{ "sampler2dms_float",			"sampler2DMS",				tex2DFloat			},
4823 				{ "isampler2dms",				"isampler2DMS",				tex2DInt			},
4824 				{ "usampler2dms",				"usampler2DMS",				tex2DUint			},
4825 				{ "sampler2dmsarray_fixed",		"sampler2DMSArray",			tex2DArrayFixed		},
4826 				{ "sampler2dmsarray_float",		"sampler2DMSArray",			tex2DArrayFloat		},
4827 				{ "isampler2dmsarray",			"isampler2DMSArray",		tex2DArrayInt		},
4828 				{ "usampler2dmsarray",			"usampler2DMSArray",		tex2DArrayUint		},
4829 			};
4830 
4831 			de::MovePtr<tcu::TestCaseGroup>		group		(new tcu::TestCaseGroup(m_testCtx, "texturesamples"));
4832 
4833 			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(textureSamplesCases); ++ndx)
4834 			{
4835 				const TexQueryFuncCaseSpec&		caseSpec	= textureSamplesCases[ndx];
4836 
4837 				group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_vertex"), caseSpec.samplerName, caseSpec.textureSpec, true,  QUERYFUNCTION_TEXTURESAMPLES));
4838 				group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_fragment"), caseSpec.samplerName, caseSpec.textureSpec, false, QUERYFUNCTION_TEXTURESAMPLES));
4839 			}
4840 
4841 			queryGroup->addChild(group.release());
4842 		}
4843 
4844 		// textureQueryLevels() cases
4845 		{
4846 			const TexQueryFuncCaseSpec textureQueryLevelsCases[] =
4847 			{
4848 				{ "sampler2d_fixed",			"sampler2D",				tex2DFixed			},
4849 				{ "sampler2d_float",			"sampler2D",				tex2DFloat			},
4850 				{ "isampler2d",					"isampler2D",				tex2DInt			},
4851 				{ "usampler2d",					"usampler2D",				tex2DUint			},
4852 				{ "sampler2dshadow",			"sampler2DShadow",			tex2DShadow			},
4853 				{ "sampler3d_fixed",			"sampler3D",				tex3DFixed			},
4854 				{ "sampler3d_float",			"sampler3D",				tex3DFloat			},
4855 				{ "isampler3d",					"isampler3D",				tex3DInt			},
4856 				{ "usampler3d",					"usampler3D",				tex3DUint			},
4857 				{ "samplercube_fixed",			"samplerCube",				texCubeFixed		},
4858 				{ "samplercube_float",			"samplerCube",				texCubeFloat		},
4859 				{ "isamplercube",				"isamplerCube",				texCubeInt			},
4860 				{ "usamplercube",				"usamplerCube",				texCubeUint			},
4861 				{ "samplercubeshadow",			"samplerCubeShadow",		texCubeShadow		},
4862 				{ "sampler2darray_fixed",		"sampler2DArray",			tex2DArrayFixed		},
4863 				{ "sampler2darray_float",		"sampler2DArray",			tex2DArrayFloat		},
4864 				{ "isampler2darray",			"isampler2DArray",			tex2DArrayInt		},
4865 				{ "usampler2darray",			"usampler2DArray",			tex2DArrayUint		},
4866 				{ "sampler2darrayshadow",		"sampler2DArrayShadow",		tex2DArrayShadow	},
4867 				{ "samplercubearray_fixed",		"samplerCubeArray",			texCubeArrayFixed	},
4868 				{ "samplercubearray_float",		"samplerCubeArray",			texCubeArrayFloat	},
4869 				{ "isamplercubearray",			"isamplerCubeArray",		texCubeArrayInt		},
4870 				{ "usamplercubearray",			"usamplerCubeArray",		texCubeArrayUint	},
4871 				{ "samplercubearrayshadow",		"samplerCubeArrayShadow",	texCubeArrayShadow	},
4872 				{ "sampler1d_fixed",			"sampler1D",				tex1DFixed			},
4873 				{ "sampler1d_float",			"sampler1D",				tex1DFloat			},
4874 				{ "isampler1d",					"isampler1D",				tex1DInt			},
4875 				{ "usampler1d",					"usampler1D",				tex1DUint			},
4876 				{ "sampler1dshadow",			"sampler1DShadow",			tex1DShadow			},
4877 				{ "sampler1darray_fixed",		"sampler1DArray",			tex1DArrayFixed		},
4878 				{ "sampler1darray_float",		"sampler1DArray",			tex1DArrayFloat		},
4879 				{ "isampler1darray",			"isampler1DArray",			tex1DArrayInt		},
4880 				{ "usampler1darray",			"usampler1DArray",			tex1DArrayUint		},
4881 				{ "sampler1darrayshadow",		"sampler1DArrayShadow",		tex1DArrayShadow	},
4882 			};
4883 
4884 			de::MovePtr<tcu::TestCaseGroup>		group		(new tcu::TestCaseGroup(m_testCtx, "texturequerylevels"));
4885 
4886 			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(textureQueryLevelsCases); ++ndx)
4887 			{
4888 				const TexQueryFuncCaseSpec&		caseSpec	= textureQueryLevelsCases[ndx];
4889 
4890 				group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_vertex"), caseSpec.samplerName, caseSpec.textureSpec, true,  QUERYFUNCTION_TEXTUREQUERYLEVELS));
4891 				group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_fragment"), caseSpec.samplerName, caseSpec.textureSpec, false, QUERYFUNCTION_TEXTUREQUERYLEVELS));
4892 			}
4893 
4894 			queryGroup->addChild(group.release());
4895 		}
4896 
4897 		// textureQueryLod() cases
4898 		{
4899 			const TexQueryFuncCaseSpec textureQueryLodCases[] =
4900 			{
4901 				{ "sampler2d_fixed",			"sampler2D",				tex2DMipmapFixed			},
4902 				{ "sampler2d_float",			"sampler2D",				tex2DMipmapFloat			},
4903 				{ "isampler2d",					"isampler2D",				tex2DMipmapInt				},
4904 				{ "usampler2d",					"usampler2D",				tex2DMipmapUint				},
4905 				{ "sampler2dshadow",			"sampler2DShadow",			tex2DMipmapShadow			},
4906 				{ "sampler3d_fixed",			"sampler3D",				tex3DMipmapFixed			},
4907 				{ "sampler3d_float",			"sampler3D",				tex3DMipmapFloat			},
4908 				{ "isampler3d",					"isampler3D",				tex3DMipmapInt				},
4909 				{ "usampler3d",					"usampler3D",				tex3DMipmapUint				},
4910 				{ "samplercube_fixed",			"samplerCube",				texCubeMipmapFixed			},
4911 				{ "samplercube_float",			"samplerCube",				texCubeMipmapFloat			},
4912 				{ "isamplercube",				"isamplerCube",				texCubeMipmapInt			},
4913 				{ "usamplercube",				"usamplerCube",				texCubeMipmapUint			},
4914 				{ "samplercubeshadow",			"samplerCubeShadow",		texCubeMipmapShadow			},
4915 				{ "sampler2darray_fixed",		"sampler2DArray",			tex2DArrayMipmapFixed		},
4916 				{ "sampler2darray_float",		"sampler2DArray",			tex2DArrayMipmapFloat		},
4917 				{ "isampler2darray",			"isampler2DArray",			tex2DArrayMipmapInt			},
4918 				{ "usampler2darray",			"usampler2DArray",			tex2DArrayMipmapUint		},
4919 				{ "sampler2darrayshadow",		"sampler2DArrayShadow",		tex2DArrayMipmapShadow		},
4920 				{ "samplercubearray_fixed",		"samplerCubeArray",			texCubeArrayMipmapFixed		},
4921 				{ "samplercubearray_float",		"samplerCubeArray",			texCubeArrayMipmapFloat		},
4922 				{ "isamplercubearray",			"isamplerCubeArray",		texCubeArrayMipmapInt		},
4923 				{ "usamplercubearray",			"usamplerCubeArray",		texCubeArrayMipmapUint		},
4924 				{ "samplercubearrayshadow",		"samplerCubeArrayShadow",	texCubeArrayMipmapShadow	},
4925 				{ "sampler1d_fixed",			"sampler1D",				tex1DMipmapFixed			},
4926 				{ "sampler1d_float",			"sampler1D",				tex1DMipmapFloat			},
4927 				{ "isampler1d",					"isampler1D",				tex1DMipmapInt				},
4928 				{ "usampler1d",					"usampler1D",				tex1DMipmapUint				},
4929 				{ "sampler1dshadow",			"sampler1DShadow",			tex1DMipmapShadow			},
4930 				{ "sampler1darray_fixed",		"sampler1DArray",			tex1DArrayMipmapFixed		},
4931 				{ "sampler1darray_float",		"sampler1DArray",			tex1DArrayMipmapFloat		},
4932 				{ "isampler1darray",			"isampler1DArray",			tex1DArrayMipmapInt			},
4933 				{ "usampler1darray",			"usampler1DArray",			tex1DArrayMipmapUint		},
4934 				{ "sampler1darrayshadow",		"sampler1DArrayShadow",		tex1DArrayMipmapShadow		},
4935 			};
4936 
4937 			de::MovePtr<tcu::TestCaseGroup>		group		(new tcu::TestCaseGroup(m_testCtx, "texturequerylod"));
4938 
4939 			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(textureQueryLodCases); ++ndx)
4940 			{
4941 				const TexQueryFuncCaseSpec&		caseSpec	= textureQueryLodCases[ndx];
4942 
4943 				// available only in fragment shader
4944 				group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_fragment"), caseSpec.samplerName, caseSpec.textureSpec, false, QUERYFUNCTION_TEXTUREQUERYLOD));
4945 				group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_zero_uv_width_fragment"), caseSpec.samplerName, caseSpec.textureSpec, false, QUERYFUNCTION_TEXTUREQUERYLOD, QLODTM_ZERO_UV_WIDTH));
4946 			}
4947 
4948 			queryGroup->addChild(group.release());
4949 		}
4950 
4951 		addChild(queryGroup.release());
4952 	}
4953 }
4954 
4955 } // anonymous
4956 
createTextureFunctionTests(tcu::TestContext & testCtx)4957 tcu::TestCaseGroup* createTextureFunctionTests (tcu::TestContext& testCtx)
4958 {
4959 	return new ShaderTextureFunctionTests(testCtx);
4960 }
4961 
4962 } // sr
4963 } // vkt
4964