Home | History | Annotate | Download | only in functional
      1 /*-------------------------------------------------------------------------
      2  * drawElements Quality Program OpenGL ES 3.0 Module
      3  * -------------------------------------------------
      4  *
      5  * Copyright 2014 The Android Open Source Project
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Unless required by applicable law or agreed to in writing, software
     14  * distributed under the License is distributed on an "AS IS" BASIS,
     15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  * See the License for the specific language governing permissions and
     17  * limitations under the License.
     18  *
     19  *//*!
     20  * \file
     21  * \brief Texture access function tests.
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "es3fShaderTextureFunctionTests.hpp"
     25 #include "glsShaderRenderCase.hpp"
     26 #include "glsShaderLibrary.hpp"
     27 #include "glsTextureTestUtil.hpp"
     28 #include "gluTexture.hpp"
     29 #include "gluTextureUtil.hpp"
     30 #include "gluPixelTransfer.hpp"
     31 #include "gluStrUtil.hpp"
     32 #include "tcuTextureUtil.hpp"
     33 #include "tcuMatrix.hpp"
     34 #include "tcuMatrixUtil.hpp"
     35 #include "tcuTestLog.hpp"
     36 #include "glwFunctions.hpp"
     37 #include "deMath.h"
     38 
     39 #include <sstream>
     40 
     41 #include "glwEnums.hpp"
     42 #include "glwFunctions.hpp"
     43 
     44 namespace deqp
     45 {
     46 namespace gles3
     47 {
     48 namespace Functional
     49 {
     50 
     51 namespace
     52 {
     53 
     54 using glu::TextureTestUtil::computeLodFromDerivates;
     55 
     56 enum Function
     57 {
     58 	FUNCTION_TEXTURE = 0,		//!< texture(), textureOffset()
     59 	FUNCTION_TEXTUREPROJ,		//!< textureProj(), textureProjOffset()
     60 	FUNCTION_TEXTUREPROJ3,		//!< textureProj(sampler2D, vec3)
     61 	FUNCTION_TEXTURELOD,		// ...
     62 	FUNCTION_TEXTUREPROJLOD,
     63 	FUNCTION_TEXTUREPROJLOD3,	//!< textureProjLod(sampler2D, vec3)
     64 	FUNCTION_TEXTUREGRAD,
     65 	FUNCTION_TEXTUREPROJGRAD,
     66 	FUNCTION_TEXTUREPROJGRAD3,	//!< textureProjGrad(sampler2D, vec3)
     67 	FUNCTION_TEXELFETCH,
     68 
     69 	FUNCTION_LAST
     70 };
     71 
     72 inline bool functionHasAutoLod (glu::ShaderType shaderType, Function function)
     73 {
     74 	return shaderType == glu::SHADERTYPE_FRAGMENT &&
     75 		   (function == FUNCTION_TEXTURE		||
     76 			function == FUNCTION_TEXTUREPROJ	||
     77 			function == FUNCTION_TEXTUREPROJ3);
     78 }
     79 
     80 inline bool functionHasProj (Function function)
     81 {
     82 	return function == FUNCTION_TEXTUREPROJ		||
     83 		   function == FUNCTION_TEXTUREPROJ3	||
     84 		   function == FUNCTION_TEXTUREPROJLOD	||
     85 		   function == FUNCTION_TEXTUREPROJGRAD	||
     86 		   function == FUNCTION_TEXTUREPROJLOD3	||
     87 		   function == FUNCTION_TEXTUREPROJGRAD3;
     88 }
     89 
     90 inline bool functionHasGrad (Function function)
     91 {
     92 	return function == FUNCTION_TEXTUREGRAD || function == FUNCTION_TEXTUREPROJGRAD || function == FUNCTION_TEXTUREPROJGRAD3;
     93 }
     94 
     95 inline bool functionHasLod (Function function)
     96 {
     97 	return function == FUNCTION_TEXTURELOD		||
     98 		   function == FUNCTION_TEXTUREPROJLOD	||
     99 		   function == FUNCTION_TEXTUREPROJLOD3	||
    100 		   function == FUNCTION_TEXELFETCH;
    101 }
    102 
    103 struct TextureLookupSpec
    104 {
    105 	Function		function;
    106 
    107 	tcu::Vec4		minCoord;
    108 	tcu::Vec4		maxCoord;
    109 
    110 	// Bias
    111 	bool			useBias;
    112 
    113 	// Bias or Lod for *Lod* functions
    114 	float			minLodBias;
    115 	float			maxLodBias;
    116 
    117 	// For *Grad* functions
    118 	tcu::Vec3		minDX;
    119 	tcu::Vec3		maxDX;
    120 	tcu::Vec3		minDY;
    121 	tcu::Vec3		maxDY;
    122 
    123 	bool			useOffset;
    124 	tcu::IVec3		offset;
    125 
    126 	TextureLookupSpec (void)
    127 		: function		(FUNCTION_LAST)
    128 		, minCoord		(0.0f)
    129 		, maxCoord		(1.0f)
    130 		, useBias		(false)
    131 		, minLodBias	(0.0f)
    132 		, maxLodBias	(0.0f)
    133 		, minDX			(0.0f)
    134 		, maxDX			(0.0f)
    135 		, minDY			(0.0f)
    136 		, maxDY			(0.0f)
    137 		, useOffset		(false)
    138 		, offset		(0)
    139 	{
    140 	}
    141 
    142 	TextureLookupSpec (Function				function_,
    143 					   const tcu::Vec4&		minCoord_,
    144 					   const tcu::Vec4&		maxCoord_,
    145 					   bool					useBias_,
    146 					   float				minLodBias_,
    147 					   float				maxLodBias_,
    148 					   const tcu::Vec3&		minDX_,
    149 					   const tcu::Vec3&		maxDX_,
    150 					   const tcu::Vec3&		minDY_,
    151 					   const tcu::Vec3&		maxDY_,
    152 					   bool					useOffset_,
    153 					   const tcu::IVec3&	offset_)
    154 		: function		(function_)
    155 		, minCoord		(minCoord_)
    156 		, maxCoord		(maxCoord_)
    157 		, useBias		(useBias_)
    158 		, minLodBias	(minLodBias_)
    159 		, maxLodBias	(maxLodBias_)
    160 		, minDX			(minDX_)
    161 		, maxDX			(maxDX_)
    162 		, minDY			(minDY_)
    163 		, maxDY			(maxDY_)
    164 		, useOffset		(useOffset_)
    165 		, offset		(offset_)
    166 	{
    167 	}
    168 };
    169 
    170 enum TextureType
    171 {
    172 	TEXTURETYPE_2D,
    173 	TEXTURETYPE_CUBE_MAP,
    174 	TEXTURETYPE_2D_ARRAY,
    175 	TEXTURETYPE_3D,
    176 
    177 	TEXTURETYPE_LAST
    178 };
    179 
    180 struct TextureSpec
    181 {
    182 	TextureType			type;		//!< Texture type (2D, cubemap, ...)
    183 	deUint32			format;		//!< Internal format.
    184 	int					width;
    185 	int					height;
    186 	int					depth;
    187 	int					numLevels;
    188 	tcu::Sampler		sampler;
    189 
    190 	TextureSpec (void)
    191 		: type			(TEXTURETYPE_LAST)
    192 		, format		(GL_NONE)
    193 		, width			(0)
    194 		, height		(0)
    195 		, depth			(0)
    196 		, numLevels		(0)
    197 	{
    198 	}
    199 
    200 	TextureSpec (TextureType			type_,
    201 				 deUint32				format_,
    202 				 int					width_,
    203 				 int					height_,
    204 				 int					depth_,
    205 				 int					numLevels_,
    206 				 const tcu::Sampler&	sampler_)
    207 		: type			(type_)
    208 		, format		(format_)
    209 		, width			(width_)
    210 		, height		(height_)
    211 		, depth			(depth_)
    212 		, numLevels		(numLevels_)
    213 		, sampler		(sampler_)
    214 	{
    215 	}
    216 };
    217 
    218 struct TexLookupParams
    219 {
    220 	float				lod;
    221 	tcu::IVec3			offset;
    222 	tcu::Vec4			scale;
    223 	tcu::Vec4			bias;
    224 
    225 	TexLookupParams (void)
    226 		: lod		(0.0f)
    227 		, offset	(0)
    228 		, scale		(1.0f)
    229 		, bias		(0.0f)
    230 	{
    231 	}
    232 };
    233 
    234 } // anonymous
    235 
    236 using tcu::Vec2;
    237 using tcu::Vec3;
    238 using tcu::Vec4;
    239 using tcu::IVec2;
    240 using tcu::IVec3;
    241 using tcu::IVec4;
    242 
    243 static const glu::TextureTestUtil::LodMode DEFAULT_LOD_MODE = glu::TextureTestUtil::LODMODE_EXACT;
    244 
    245 inline float computeLodFromGrad2D (const gls::ShaderEvalContext& c)
    246 {
    247 	float w = (float)c.textures[0].tex2D->getWidth();
    248 	float h = (float)c.textures[0].tex2D->getHeight();
    249 	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);
    250 }
    251 
    252 inline float computeLodFromGrad2DArray (const gls::ShaderEvalContext& c)
    253 {
    254 	float w = (float)c.textures[0].tex2DArray->getWidth();
    255 	float h = (float)c.textures[0].tex2DArray->getHeight();
    256 	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);
    257 }
    258 
    259 inline float computeLodFromGrad3D (const gls::ShaderEvalContext& c)
    260 {
    261 	float w = (float)c.textures[0].tex3D->getWidth();
    262 	float h = (float)c.textures[0].tex3D->getHeight();
    263 	float d = (float)c.textures[0].tex3D->getDepth();
    264 	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);
    265 }
    266 
    267 inline float computeLodFromGradCube (const gls::ShaderEvalContext& c)
    268 {
    269 	// \note Major axis is always -Z or +Z
    270 	float m = de::abs(c.in[0].z());
    271 	float d = (float)c.textures[0].texCube->getSize();
    272 	float s = d/(2.0f*m);
    273 	float t = d/(2.0f*m);
    274 	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);
    275 }
    276 
    277 typedef void (*TexEvalFunc) (gls::ShaderEvalContext& c, const TexLookupParams& lookupParams);
    278 
    279 inline Vec4 texture2D		(const gls::ShaderEvalContext& c, float s, float t, float lod)			{ return c.textures[0].tex2D->sample(c.textures[0].sampler, s, t, lod);			}
    280 inline Vec4 textureCube		(const gls::ShaderEvalContext& c, float s, float t, float r, float lod)	{ return c.textures[0].texCube->sample(c.textures[0].sampler, s, t, r, lod);	}
    281 inline Vec4 texture2DArray	(const gls::ShaderEvalContext& c, float s, float t, float r, float lod)	{ return c.textures[0].tex2DArray->sample(c.textures[0].sampler, s, t, r, lod);	}
    282 inline Vec4 texture3D		(const gls::ShaderEvalContext& c, float s, float t, float r, float lod)	{ return c.textures[0].tex3D->sample(c.textures[0].sampler, s, t, r, lod);		}
    283 
    284 inline float texture2DShadow		(const gls::ShaderEvalContext& c, float ref, float s, float t, float lod) { return c.textures[0].tex2D->sampleCompare(c.textures[0].sampler, ref, s, t, lod); }
    285 inline float textureCubeShadow		(const gls::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); }
    286 inline float texture2DArrayShadow	(const gls::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); }
    287 
    288 inline Vec4 texture2DOffset			(const gls::ShaderEvalContext& c, float s, float t, float lod, IVec2 offset)			{ return c.textures[0].tex2D->sampleOffset(c.textures[0].sampler, s, t, lod, offset);			}
    289 inline Vec4 texture2DArrayOffset	(const gls::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);	}
    290 inline Vec4 texture3DOffset			(const gls::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);		}
    291 
    292 inline float texture2DShadowOffset		(const gls::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); }
    293 inline float texture2DArrayShadowOffset	(const gls::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); }
    294 
    295 // Eval functions.
    296 static void		evalTexture2D			(gls::ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2D(c, c.in[0].x(), c.in[0].y(), p.lod)*p.scale + p.bias; }
    297 static void		evalTextureCube			(gls::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; }
    298 static void		evalTexture2DArray		(gls::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; }
    299 static void		evalTexture3D			(gls::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; }
    300 
    301 static void		evalTexture2DBias		(gls::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; }
    302 static void		evalTextureCubeBias		(gls::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; }
    303 static void		evalTexture2DArrayBias	(gls::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; }
    304 static void		evalTexture3DBias		(gls::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; }
    305 
    306 static void		evalTexture2DProj3		(gls::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; }
    307 static void		evalTexture2DProj3Bias	(gls::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; }
    308 static void		evalTexture2DProj		(gls::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; }
    309 static void		evalTexture2DProjBias	(gls::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; }
    310 static void		evalTexture3DProj		(gls::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; }
    311 static void		evalTexture3DProjBias	(gls::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; }
    312 
    313 static void		evalTexture2DLod		(gls::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; }
    314 static void		evalTextureCubeLod		(gls::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; }
    315 static void		evalTexture2DArrayLod	(gls::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; }
    316 static void		evalTexture3DLod		(gls::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; }
    317 
    318 static void		evalTexture2DProjLod3	(gls::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; }
    319 static void		evalTexture2DProjLod	(gls::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; }
    320 static void		evalTexture3DProjLod	(gls::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; }
    321 
    322 // Offset variants
    323 
    324 static void		evalTexture2DOffset				(gls::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; }
    325 static void		evalTexture2DArrayOffset		(gls::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; }
    326 static void		evalTexture3DOffset				(gls::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; }
    327 
    328 static void		evalTexture2DOffsetBias			(gls::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; }
    329 static void		evalTexture2DArrayOffsetBias	(gls::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; }
    330 static void		evalTexture3DOffsetBias			(gls::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; }
    331 
    332 static void		evalTexture2DLodOffset			(gls::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; }
    333 static void		evalTexture2DArrayLodOffset		(gls::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; }
    334 static void		evalTexture3DLodOffset			(gls::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; }
    335 
    336 static void		evalTexture2DProj3Offset		(gls::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; }
    337 static void		evalTexture2DProj3OffsetBias	(gls::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; }
    338 static void		evalTexture2DProjOffset			(gls::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; }
    339 static void		evalTexture2DProjOffsetBias		(gls::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; }
    340 static void		evalTexture3DProjOffset			(gls::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; }
    341 static void		evalTexture3DProjOffsetBias		(gls::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; }
    342 
    343 static void		evalTexture2DProjLod3Offset		(gls::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; }
    344 static void		evalTexture2DProjLodOffset		(gls::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; }
    345 static void		evalTexture3DProjLodOffset		(gls::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; }
    346 
    347 // Shadow variants
    348 
    349 static void		evalTexture2DShadow				(gls::ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture2DShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), p.lod); }
    350 static void		evalTexture2DShadowBias			(gls::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()); }
    351 
    352 static void		evalTextureCubeShadow			(gls::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); }
    353 static void		evalTextureCubeShadowBias		(gls::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()); }
    354 
    355 static void		evalTexture2DArrayShadow		(gls::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); }
    356 
    357 static void		evalTexture2DShadowLod			(gls::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()); }
    358 static void		evalTexture2DShadowLodOffset	(gls::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)); }
    359 
    360 static void		evalTexture2DShadowProj			(gls::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); }
    361 static void		evalTexture2DShadowProjBias		(gls::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()); }
    362 
    363 static void		evalTexture2DShadowProjLod		(gls::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()); }
    364 static void		evalTexture2DShadowProjLodOffset(gls::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)); }
    365 
    366 static void		evalTexture2DShadowOffset		(gls::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)); }
    367 static void		evalTexture2DShadowOffsetBias	(gls::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)); }
    368 
    369 static void		evalTexture2DShadowProjOffset		(gls::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)); }
    370 static void		evalTexture2DShadowProjOffsetBias	(gls::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)); }
    371 
    372 // Gradient variarts
    373 
    374 static void		evalTexture2DGrad		(gls::ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2D(c, c.in[0].x(), c.in[0].y(), computeLodFromGrad2D(c))*p.scale + p.bias; }
    375 static void		evalTextureCubeGrad		(gls::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; }
    376 static void		evalTexture2DArrayGrad	(gls::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; }
    377 static void		evalTexture3DGrad		(gls::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; }
    378 
    379 static void		evalTexture2DShadowGrad			(gls::ShaderEvalContext& c, const TexLookupParams&)		{ c.color.x() = texture2DShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), computeLodFromGrad2D(c)); }
    380 static void		evalTextureCubeShadowGrad		(gls::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)); }
    381 static void		evalTexture2DArrayShadowGrad	(gls::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)); }
    382 
    383 static void		evalTexture2DGradOffset			(gls::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; }
    384 static void		evalTexture2DArrayGradOffset	(gls::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; }
    385 static void		evalTexture3DGradOffset			(gls::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; }
    386 
    387 static void		evalTexture2DShadowGradOffset		(gls::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)); }
    388 static void		evalTexture2DArrayShadowGradOffset	(gls::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)); }
    389 
    390 static void		evalTexture2DShadowProjGrad			(gls::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)); }
    391 static void		evalTexture2DShadowProjGradOffset	(gls::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)); }
    392 
    393 static void		evalTexture2DProjGrad3			(gls::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; }
    394 static void		evalTexture2DProjGrad			(gls::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; }
    395 static void		evalTexture3DProjGrad			(gls::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; }
    396 
    397 static void		evalTexture2DProjGrad3Offset	(gls::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; }
    398 static void		evalTexture2DProjGradOffset		(gls::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; }
    399 static void		evalTexture3DProjGradOffset		(gls::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; }
    400 
    401 // Texel fetch variants
    402 
    403 static void evalTexelFetch2D (gls::ShaderEvalContext& c, const TexLookupParams& p)
    404 {
    405 	int	x	= deChopFloatToInt32(c.in[0].x())+p.offset.x();
    406 	int	y	= deChopFloatToInt32(c.in[0].y())+p.offset.y();
    407 	int	lod = deChopFloatToInt32(c.in[1].x());
    408 	c.color = c.textures[0].tex2D->getLevel(lod).getPixel(x, y)*p.scale + p.bias;
    409 }
    410 
    411 static void evalTexelFetch2DArray (gls::ShaderEvalContext& c, const TexLookupParams& p)
    412 {
    413 	int	x	= deChopFloatToInt32(c.in[0].x())+p.offset.x();
    414 	int	y	= deChopFloatToInt32(c.in[0].y())+p.offset.y();
    415 	int	l	= deChopFloatToInt32(c.in[0].z());
    416 	int	lod = deChopFloatToInt32(c.in[1].x());
    417 	c.color = c.textures[0].tex2DArray->getLevel(lod).getPixel(x, y, l)*p.scale + p.bias;
    418 }
    419 
    420 static void evalTexelFetch3D (gls::ShaderEvalContext& c, const TexLookupParams& p)
    421 {
    422 	int	x	= deChopFloatToInt32(c.in[0].x())+p.offset.x();
    423 	int	y	= deChopFloatToInt32(c.in[0].y())+p.offset.y();
    424 	int	z	= deChopFloatToInt32(c.in[0].z())+p.offset.z();
    425 	int	lod = deChopFloatToInt32(c.in[1].x());
    426 	c.color = c.textures[0].tex3D->getLevel(lod).getPixel(x, y, z)*p.scale + p.bias;
    427 }
    428 
    429 class TexLookupEvaluator : public gls::ShaderEvaluator
    430 {
    431 public:
    432 							TexLookupEvaluator		(TexEvalFunc evalFunc, const TexLookupParams& lookupParams) : m_evalFunc(evalFunc), m_lookupParams(lookupParams) {}
    433 
    434 	virtual void			evaluate				(gls::ShaderEvalContext& ctx) { m_evalFunc(ctx, m_lookupParams); }
    435 
    436 private:
    437 	TexEvalFunc				m_evalFunc;
    438 	const TexLookupParams&	m_lookupParams;
    439 };
    440 
    441 class ShaderTextureFunctionCase : public gls::ShaderRenderCase
    442 {
    443 public:
    444 							ShaderTextureFunctionCase		(Context& context, const char* name, const char* desc, const TextureLookupSpec& lookup, const TextureSpec& texture, TexEvalFunc evalFunc, bool isVertexCase);
    445 							~ShaderTextureFunctionCase		(void);
    446 
    447 	void					init							(void);
    448 	void					deinit							(void);
    449 
    450 protected:
    451 	void					setupUniforms					(int programID, const tcu::Vec4& constCoords);
    452 
    453 private:
    454 	void					initTexture						(void);
    455 	void					initShaderSources				(void);
    456 
    457 	TextureLookupSpec		m_lookupSpec;
    458 	TextureSpec				m_textureSpec;
    459 
    460 	TexLookupParams			m_lookupParams;
    461 	TexLookupEvaluator		m_evaluator;
    462 
    463 	glu::Texture2D*			m_texture2D;
    464 	glu::TextureCube*		m_textureCube;
    465 	glu::Texture2DArray*	m_texture2DArray;
    466 	glu::Texture3D*			m_texture3D;
    467 };
    468 
    469 ShaderTextureFunctionCase::ShaderTextureFunctionCase (Context& context, const char* name, const char* desc, const TextureLookupSpec& lookup, const TextureSpec& texture, TexEvalFunc evalFunc, bool isVertexCase)
    470 	: gls::ShaderRenderCase(context.getTestContext(), context.getRenderContext(), context.getContextInfo(), name, desc, isVertexCase, m_evaluator)
    471 	, m_lookupSpec			(lookup)
    472 	, m_textureSpec			(texture)
    473 	, m_evaluator			(evalFunc, m_lookupParams)
    474 	, m_texture2D			(DE_NULL)
    475 	, m_textureCube			(DE_NULL)
    476 	, m_texture2DArray		(DE_NULL)
    477 	, m_texture3D			(DE_NULL)
    478 {
    479 }
    480 
    481 ShaderTextureFunctionCase::~ShaderTextureFunctionCase (void)
    482 {
    483 	delete m_texture2D;
    484 	delete m_textureCube;
    485 	delete m_texture2DArray;
    486 	delete m_texture3D;
    487 }
    488 
    489 void ShaderTextureFunctionCase::init (void)
    490 {
    491 	{
    492 		// Base coord scale & bias
    493 		Vec4 s = m_lookupSpec.maxCoord-m_lookupSpec.minCoord;
    494 		Vec4 b = m_lookupSpec.minCoord;
    495 
    496 		float baseCoordTrans[] =
    497 		{
    498 			s.x(),		0.0f,		0.f,	b.x(),
    499 			0.f,		s.y(),		0.f,	b.y(),
    500 			s.z()/2.f,	-s.z()/2.f,	0.f,	s.z()/2.f + b.z(),
    501 			-s.w()/2.f,	s.w()/2.f,	0.f,	s.w()/2.f + b.w()
    502 		};
    503 
    504 		m_userAttribTransforms.push_back(tcu::Mat4(baseCoordTrans));
    505 	}
    506 
    507 	bool hasLodBias	= functionHasLod(m_lookupSpec.function) || m_lookupSpec.useBias;
    508 	bool isGrad		= functionHasGrad(m_lookupSpec.function);
    509 	DE_ASSERT(!isGrad || !hasLodBias);
    510 
    511 	if (hasLodBias)
    512 	{
    513 		float s = m_lookupSpec.maxLodBias-m_lookupSpec.minLodBias;
    514 		float b = m_lookupSpec.minLodBias;
    515 		float lodCoordTrans[] =
    516 		{
    517 			s/2.0f,		s/2.0f,		0.f,	b,
    518 			0.0f,		0.0f,		0.0f,	0.0f,
    519 			0.0f,		0.0f,		0.0f,	0.0f,
    520 			0.0f,		0.0f,		0.0f,	0.0f
    521 		};
    522 
    523 		m_userAttribTransforms.push_back(tcu::Mat4(lodCoordTrans));
    524 	}
    525 	else if (isGrad)
    526 	{
    527 		Vec3 sx = m_lookupSpec.maxDX-m_lookupSpec.minDX;
    528 		Vec3 sy = m_lookupSpec.maxDY-m_lookupSpec.minDY;
    529 		float gradDxTrans[] =
    530 		{
    531 			sx.x()/2.0f,	sx.x()/2.0f,	0.f,	m_lookupSpec.minDX.x(),
    532 			sx.y()/2.0f,	sx.y()/2.0f,	0.0f,	m_lookupSpec.minDX.y(),
    533 			sx.z()/2.0f,	sx.z()/2.0f,	0.0f,	m_lookupSpec.minDX.z(),
    534 			0.0f,			0.0f,			0.0f,	0.0f
    535 		};
    536 		float gradDyTrans[] =
    537 		{
    538 			-sy.x()/2.0f,	-sy.x()/2.0f,	0.f,	m_lookupSpec.maxDY.x(),
    539 			-sy.y()/2.0f,	-sy.y()/2.0f,	0.0f,	m_lookupSpec.maxDY.y(),
    540 			-sy.z()/2.0f,	-sy.z()/2.0f,	0.0f,	m_lookupSpec.maxDY.z(),
    541 			0.0f,			0.0f,			0.0f,	0.0f
    542 		};
    543 
    544 		m_userAttribTransforms.push_back(tcu::Mat4(gradDxTrans));
    545 		m_userAttribTransforms.push_back(tcu::Mat4(gradDyTrans));
    546 	}
    547 
    548 	initShaderSources();
    549 	initTexture();
    550 
    551 	gls::ShaderRenderCase::init();
    552 }
    553 
    554 void ShaderTextureFunctionCase::initTexture (void)
    555 {
    556 	static const IVec4 texCubeSwz[] =
    557 	{
    558 		IVec4(0,0,1,1),
    559 		IVec4(1,1,0,0),
    560 		IVec4(0,1,0,1),
    561 		IVec4(1,0,1,0),
    562 		IVec4(0,1,1,0),
    563 		IVec4(1,0,0,1)
    564 	};
    565 	DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(texCubeSwz) == tcu::CUBEFACE_LAST);
    566 
    567 	tcu::TextureFormat		texFmt			= glu::mapGLInternalFormat(m_textureSpec.format);
    568 	tcu::TextureFormatInfo	fmtInfo			= tcu::getTextureFormatInfo(texFmt);
    569 	tcu::IVec2				viewportSize	= getViewportSize();
    570 	bool					isProj			= functionHasProj(m_lookupSpec.function);
    571 	bool					isAutoLod		= functionHasAutoLod(m_isVertexCase ? glu::SHADERTYPE_VERTEX : glu::SHADERTYPE_FRAGMENT,
    572 																 m_lookupSpec.function); // LOD can vary significantly
    573 	float					proj			= isProj ? 1.0f/m_lookupSpec.minCoord[m_lookupSpec.function == FUNCTION_TEXTUREPROJ3 ? 2 : 3] : 1.0f;
    574 
    575 	switch (m_textureSpec.type)
    576 	{
    577 		case TEXTURETYPE_2D:
    578 		{
    579 			float	levelStep		= isAutoLod ? 0.0f : 1.0f / (float)de::max(1, m_textureSpec.numLevels-1);
    580 			Vec4	cScale			= fmtInfo.valueMax-fmtInfo.valueMin;
    581 			Vec4	cBias			= fmtInfo.valueMin;
    582 			int		baseCellSize	= de::min(m_textureSpec.width/4, m_textureSpec.height/4);
    583 
    584 			m_texture2D = new glu::Texture2D(m_renderCtx, m_textureSpec.format, m_textureSpec.width, m_textureSpec.height);
    585 			for (int level = 0; level < m_textureSpec.numLevels; level++)
    586 			{
    587 				float	fA		= float(level)*levelStep;
    588 				float	fB		= 1.0f-fA;
    589 				Vec4	colorA	= cBias + cScale*Vec4(fA, fB, fA, fB);
    590 				Vec4	colorB	= cBias + cScale*Vec4(fB, fA, fB, fA);
    591 
    592 				m_texture2D->getRefTexture().allocLevel(level);
    593 				tcu::fillWithGrid(m_texture2D->getRefTexture().getLevel(level), de::max(1, baseCellSize>>level), colorA, colorB);
    594 			}
    595 			m_texture2D->upload();
    596 
    597 			// Compute LOD.
    598 			float dudx = (m_lookupSpec.maxCoord[0]-m_lookupSpec.minCoord[0])*proj*(float)m_textureSpec.width	/ (float)viewportSize[0];
    599 			float dvdy = (m_lookupSpec.maxCoord[1]-m_lookupSpec.minCoord[1])*proj*(float)m_textureSpec.height	/ (float)viewportSize[1];
    600 			m_lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f, 0.0f, dvdy);
    601 
    602 			// Append to texture list.
    603 			m_textures.push_back(gls::TextureBinding(m_texture2D, m_textureSpec.sampler));
    604 			break;
    605 		}
    606 
    607 		case TEXTURETYPE_CUBE_MAP:
    608 		{
    609 			float	levelStep		= isAutoLod ? 0.0f : 1.0f / (float)de::max(1, m_textureSpec.numLevels-1);
    610 			Vec4	cScale			= fmtInfo.valueMax-fmtInfo.valueMin;
    611 			Vec4	cBias			= fmtInfo.valueMin;
    612 			Vec4	cCorner			= cBias + cScale*0.5f;
    613 			int		baseCellSize	= de::min(m_textureSpec.width/4, m_textureSpec.height/4);
    614 
    615 			DE_ASSERT(m_textureSpec.width == m_textureSpec.height);
    616 			m_textureCube = new glu::TextureCube(m_renderCtx, m_textureSpec.format, m_textureSpec.width);
    617 			for (int level = 0; level < m_textureSpec.numLevels; level++)
    618 			{
    619 				float	fA		= float(level)*levelStep;
    620 				float	fB		= 1.0f-fA;
    621 				Vec2	f		(fA, fB);
    622 
    623 				for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
    624 				{
    625 					const IVec4&	swzA	= texCubeSwz[face];
    626 					IVec4			swzB	= 1-swzA;
    627 					Vec4			colorA	= cBias + cScale*f.swizzle(swzA[0], swzA[1], swzA[2], swzA[3]);
    628 					Vec4			colorB	= cBias + cScale*f.swizzle(swzB[0], swzB[1], swzB[2], swzB[3]);
    629 
    630 					m_textureCube->getRefTexture().allocLevel((tcu::CubeFace)face, level);
    631 
    632 					{
    633 						const tcu::PixelBufferAccess	access		= m_textureCube->getRefTexture().getLevelFace(level, (tcu::CubeFace)face);
    634 						const int						lastPix		= access.getWidth()-1;
    635 
    636 						tcu::fillWithGrid(access, de::max(1, baseCellSize>>level), colorA, colorB);
    637 
    638 						// Ensure all corners have identical colors in order to avoid dealing with ambiguous corner texel filtering
    639 						access.setPixel(cCorner, 0, 0);
    640 						access.setPixel(cCorner, 0, lastPix);
    641 						access.setPixel(cCorner, lastPix, 0);
    642 						access.setPixel(cCorner, lastPix, lastPix);
    643 					}
    644 				}
    645 			}
    646 			m_textureCube->upload();
    647 
    648 			// Compute LOD \note Assumes that only single side is accessed and R is constant major axis.
    649 			DE_ASSERT(de::abs(m_lookupSpec.minCoord[2] - m_lookupSpec.maxCoord[2]) < 0.005);
    650 			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]));
    651 			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]));
    652 
    653 			tcu::CubeFaceFloatCoords	c00		= tcu::getCubeFaceCoords(Vec3(m_lookupSpec.minCoord[0]*proj, m_lookupSpec.minCoord[1]*proj, m_lookupSpec.minCoord[2]*proj));
    654 			tcu::CubeFaceFloatCoords	c10		= tcu::getCubeFaceCoords(Vec3(m_lookupSpec.maxCoord[0]*proj, m_lookupSpec.minCoord[1]*proj, m_lookupSpec.minCoord[2]*proj));
    655 			tcu::CubeFaceFloatCoords	c01		= tcu::getCubeFaceCoords(Vec3(m_lookupSpec.minCoord[0]*proj, m_lookupSpec.maxCoord[1]*proj, m_lookupSpec.minCoord[2]*proj));
    656 			float						dudx	= (c10.s - c00.s)*(float)m_textureSpec.width	/ (float)viewportSize[0];
    657 			float						dvdy	= (c01.t - c00.t)*(float)m_textureSpec.height	/ (float)viewportSize[1];
    658 
    659 			m_lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f, 0.0f, dvdy);
    660 
    661 			m_textures.push_back(gls::TextureBinding(m_textureCube, m_textureSpec.sampler));
    662 			break;
    663 		}
    664 
    665 		case TEXTURETYPE_2D_ARRAY:
    666 		{
    667 			float	layerStep		= 1.0f / (float)m_textureSpec.depth;
    668 			float	levelStep		= isAutoLod ? 0.0f : 1.0f / (float)(de::max(1, m_textureSpec.numLevels-1)*m_textureSpec.depth);
    669 			Vec4	cScale			= fmtInfo.valueMax-fmtInfo.valueMin;
    670 			Vec4	cBias			= fmtInfo.valueMin;
    671 			int		baseCellSize	= de::min(m_textureSpec.width/4, m_textureSpec.height/4);
    672 
    673 			m_texture2DArray = new glu::Texture2DArray(m_renderCtx, m_textureSpec.format, m_textureSpec.width, m_textureSpec.height, m_textureSpec.depth);
    674 			for (int level = 0; level < m_textureSpec.numLevels; level++)
    675 			{
    676 				m_texture2DArray->getRefTexture().allocLevel(level);
    677 				tcu::PixelBufferAccess levelAccess = m_texture2DArray->getRefTexture().getLevel(level);
    678 
    679 				for (int layer = 0; layer < levelAccess.getDepth(); layer++)
    680 				{
    681 					float	fA		= (float)layer*layerStep + (float)level*levelStep;
    682 					float	fB		= 1.0f-fA;
    683 					Vec4	colorA	= cBias + cScale*Vec4(fA, fB, fA, fB);
    684 					Vec4	colorB	= cBias + cScale*Vec4(fB, fA, fB, fA);
    685 
    686 					tcu::fillWithGrid(tcu::getSubregion(levelAccess, 0, 0, layer, levelAccess.getWidth(), levelAccess.getHeight(), 1), de::max(1, baseCellSize>>level), colorA, colorB);
    687 				}
    688 			}
    689 			m_texture2DArray->upload();
    690 
    691 			// Compute LOD.
    692 			float dudx = (m_lookupSpec.maxCoord[0]-m_lookupSpec.minCoord[0])*proj*(float)m_textureSpec.width	/ (float)viewportSize[0];
    693 			float dvdy = (m_lookupSpec.maxCoord[1]-m_lookupSpec.minCoord[1])*proj*(float)m_textureSpec.height	/ (float)viewportSize[1];
    694 			m_lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f, 0.0f, dvdy);
    695 
    696 			// Append to texture list.
    697 			m_textures.push_back(gls::TextureBinding(m_texture2DArray, m_textureSpec.sampler));
    698 			break;
    699 		}
    700 
    701 		case TEXTURETYPE_3D:
    702 		{
    703 			float	levelStep		= isAutoLod ? 0.0f : 1.0f / (float)de::max(1, m_textureSpec.numLevels-1);
    704 			Vec4	cScale			= fmtInfo.valueMax-fmtInfo.valueMin;
    705 			Vec4	cBias			= fmtInfo.valueMin;
    706 			int		baseCellSize	= de::min(de::min(m_textureSpec.width/2, m_textureSpec.height/2), m_textureSpec.depth/2);
    707 
    708 			m_texture3D = new glu::Texture3D(m_renderCtx, m_textureSpec.format, m_textureSpec.width, m_textureSpec.height, m_textureSpec.depth);
    709 			for (int level = 0; level < m_textureSpec.numLevels; level++)
    710 			{
    711 				float	fA		= (float)level*levelStep;
    712 				float	fB		= 1.0f-fA;
    713 				Vec4	colorA	= cBias + cScale*Vec4(fA, fB, fA, fB);
    714 				Vec4	colorB	= cBias + cScale*Vec4(fB, fA, fB, fA);
    715 
    716 				m_texture3D->getRefTexture().allocLevel(level);
    717 				tcu::fillWithGrid(m_texture3D->getRefTexture().getLevel(level), de::max(1, baseCellSize>>level), colorA, colorB);
    718 			}
    719 			m_texture3D->upload();
    720 
    721 			// Compute LOD.
    722 			float dudx = (m_lookupSpec.maxCoord[0]-m_lookupSpec.minCoord[0])*proj*(float)m_textureSpec.width		/ (float)viewportSize[0];
    723 			float dvdy = (m_lookupSpec.maxCoord[1]-m_lookupSpec.minCoord[1])*proj*(float)m_textureSpec.height		/ (float)viewportSize[1];
    724 			float dwdx = (m_lookupSpec.maxCoord[2]-m_lookupSpec.minCoord[2])*0.5f*proj*(float)m_textureSpec.depth	/ (float)viewportSize[0];
    725 			float dwdy = (m_lookupSpec.maxCoord[2]-m_lookupSpec.minCoord[2])*0.5f*proj*(float)m_textureSpec.depth	/ (float)viewportSize[1];
    726 			m_lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f, dwdx, 0.0f, dvdy, dwdy);
    727 
    728 			// Append to texture list.
    729 			m_textures.push_back(gls::TextureBinding(m_texture3D, m_textureSpec.sampler));
    730 			break;
    731 		}
    732 
    733 		default:
    734 			DE_ASSERT(DE_FALSE);
    735 	}
    736 
    737 	// Set lookup scale & bias
    738 	m_lookupParams.scale	= fmtInfo.lookupScale;
    739 	m_lookupParams.bias		= fmtInfo.lookupBias;
    740 	m_lookupParams.offset	= m_lookupSpec.offset;
    741 }
    742 
    743 void ShaderTextureFunctionCase::initShaderSources (void)
    744 {
    745 	Function			function			= m_lookupSpec.function;
    746 	bool				isVtxCase			= m_isVertexCase;
    747 	bool				isProj				= functionHasProj(function);
    748 	bool				isGrad				= functionHasGrad(function);
    749 	bool				isShadow			= m_textureSpec.sampler.compare != tcu::Sampler::COMPAREMODE_NONE;
    750 	bool				is2DProj4			= !isShadow && m_textureSpec.type == TEXTURETYPE_2D && (function == FUNCTION_TEXTUREPROJ || function == FUNCTION_TEXTUREPROJLOD || function == FUNCTION_TEXTUREPROJGRAD);
    751 	bool				isIntCoord			= function == FUNCTION_TEXELFETCH;
    752 	bool				hasLodBias			= functionHasLod(m_lookupSpec.function) || m_lookupSpec.useBias;
    753 	int					texCoordComps		= m_textureSpec.type == TEXTURETYPE_2D ? 2 : 3;
    754 	int					extraCoordComps		= (isProj ? (is2DProj4 ? 2 : 1) : 0) + (isShadow ? 1 : 0);
    755 	glu::DataType		coordType			= glu::getDataTypeFloatVec(texCoordComps+extraCoordComps);
    756 	glu::Precision		coordPrec			= glu::PRECISION_HIGHP;
    757 	const char*			coordTypeName		= glu::getDataTypeName(coordType);
    758 	const char*			coordPrecName		= glu::getPrecisionName(coordPrec);
    759 	tcu::TextureFormat	texFmt				= glu::mapGLInternalFormat(m_textureSpec.format);
    760 	glu::DataType		samplerType			= glu::TYPE_LAST;
    761 	glu::DataType		gradType			= (m_textureSpec.type == TEXTURETYPE_CUBE_MAP || m_textureSpec.type == TEXTURETYPE_3D) ? glu::TYPE_FLOAT_VEC3 : glu::TYPE_FLOAT_VEC2;
    762 	const char*			gradTypeName		= glu::getDataTypeName(gradType);
    763 	const char*			baseFuncName		= DE_NULL;
    764 
    765 	DE_ASSERT(!isGrad || !hasLodBias);
    766 
    767 	switch (m_textureSpec.type)
    768 	{
    769 		case TEXTURETYPE_2D:		samplerType = isShadow ? glu::TYPE_SAMPLER_2D_SHADOW		: glu::getSampler2DType(texFmt);		break;
    770 		case TEXTURETYPE_CUBE_MAP:	samplerType = isShadow ? glu::TYPE_SAMPLER_CUBE_SHADOW		: glu::getSamplerCubeType(texFmt);		break;
    771 		case TEXTURETYPE_2D_ARRAY:	samplerType = isShadow ? glu::TYPE_SAMPLER_2D_ARRAY_SHADOW	: glu::getSampler2DArrayType(texFmt);	break;
    772 		case TEXTURETYPE_3D:		DE_ASSERT(!isShadow); samplerType = glu::getSampler3DType(texFmt);									break;
    773 		default:
    774 			DE_ASSERT(DE_FALSE);
    775 	}
    776 
    777 	switch (m_lookupSpec.function)
    778 	{
    779 		case FUNCTION_TEXTURE:			baseFuncName = "texture";			break;
    780 		case FUNCTION_TEXTUREPROJ:		baseFuncName = "textureProj";		break;
    781 		case FUNCTION_TEXTUREPROJ3:		baseFuncName = "textureProj";		break;
    782 		case FUNCTION_TEXTURELOD:		baseFuncName = "textureLod";		break;
    783 		case FUNCTION_TEXTUREPROJLOD:	baseFuncName = "textureProjLod";	break;
    784 		case FUNCTION_TEXTUREPROJLOD3:	baseFuncName = "textureProjLod";	break;
    785 		case FUNCTION_TEXTUREGRAD:		baseFuncName = "textureGrad";		break;
    786 		case FUNCTION_TEXTUREPROJGRAD:	baseFuncName = "textureProjGrad";	break;
    787 		case FUNCTION_TEXTUREPROJGRAD3:	baseFuncName = "textureProjGrad";	break;
    788 		case FUNCTION_TEXELFETCH:		baseFuncName = "texelFetch";		break;
    789 		default:
    790 			DE_ASSERT(DE_FALSE);
    791 	}
    792 
    793 	std::ostringstream	vert;
    794 	std::ostringstream	frag;
    795 	std::ostringstream&	op		= isVtxCase ? vert : frag;
    796 
    797 	vert << "#version 300 es\n"
    798 		 << "in highp vec4 a_position;\n"
    799 		 << "in " << coordPrecName << " " << coordTypeName << " a_in0;\n";
    800 
    801 	if (isGrad)
    802 	{
    803 		vert << "in " << coordPrecName << " " << gradTypeName << " a_in1;\n";
    804 		vert << "in " << coordPrecName << " " << gradTypeName << " a_in2;\n";
    805 	}
    806 	else if (hasLodBias)
    807 		vert << "in " << coordPrecName << " float a_in1;\n";
    808 
    809 	frag << "#version 300 es\n"
    810 		 << "layout(location = 0) out mediump vec4 o_color;\n";
    811 
    812 	if (isVtxCase)
    813 	{
    814 		vert << "out mediump vec4 v_color;\n";
    815 		frag << "in mediump vec4 v_color;\n";
    816 	}
    817 	else
    818 	{
    819 		vert << "out " << coordPrecName << " " << coordTypeName << " v_texCoord;\n";
    820 		frag << "in " << coordPrecName << " " << coordTypeName << " v_texCoord;\n";
    821 
    822 		if (isGrad)
    823 		{
    824 			vert << "out " << coordPrecName << " " << gradTypeName << " v_gradX;\n";
    825 			vert << "out " << coordPrecName << " " << gradTypeName << " v_gradY;\n";
    826 			frag << "in " << coordPrecName << " " << gradTypeName << " v_gradX;\n";
    827 			frag << "in " << coordPrecName << " " << gradTypeName << " v_gradY;\n";
    828 		}
    829 
    830 		if (hasLodBias)
    831 		{
    832 			vert << "out " << coordPrecName << " float v_lodBias;\n";
    833 			frag << "in " << coordPrecName << " float v_lodBias;\n";
    834 		}
    835 	}
    836 
    837 	// Uniforms
    838 	op << "uniform highp " << glu::getDataTypeName(samplerType) << " u_sampler;\n"
    839 	   << "uniform highp vec4 u_scale;\n"
    840 	   << "uniform highp vec4 u_bias;\n";
    841 
    842 	vert << "\nvoid main()\n{\n"
    843 		 << "\tgl_Position = a_position;\n";
    844 	frag << "\nvoid main()\n{\n";
    845 
    846 	if (isVtxCase)
    847 		vert << "\tv_color = ";
    848 	else
    849 		frag << "\to_color = ";
    850 
    851 	// Op.
    852 	{
    853 		const char*	texCoord	= isVtxCase ? "a_in0" : "v_texCoord";
    854 		const char* gradX		= isVtxCase ? "a_in1" : "v_gradX";
    855 		const char* gradY		= isVtxCase ? "a_in2" : "v_gradY";
    856 		const char*	lodBias		= isVtxCase ? "a_in1" : "v_lodBias";
    857 
    858 		op << "vec4(" << baseFuncName;
    859 		if (m_lookupSpec.useOffset)
    860 			op << "Offset";
    861 		op << "(u_sampler, ";
    862 
    863 		if (isIntCoord)
    864 			op << "ivec" << (texCoordComps+extraCoordComps) << "(";
    865 
    866 		op << texCoord;
    867 
    868 		if (isIntCoord)
    869 			op << ")";
    870 
    871 		if (isGrad)
    872 			op << ", " << gradX << ", " << gradY;
    873 
    874 		if (functionHasLod(function))
    875 		{
    876 			if (isIntCoord)
    877 				op << ", int(" << lodBias << ")";
    878 			else
    879 				op << ", " << lodBias;
    880 		}
    881 
    882 		if (m_lookupSpec.useOffset)
    883 		{
    884 			int offsetComps = m_textureSpec.type == TEXTURETYPE_3D ? 3 : 2;
    885 
    886 			op << ", ivec" << offsetComps << "(";
    887 			for (int ndx = 0; ndx < offsetComps; ndx++)
    888 			{
    889 				if (ndx != 0)
    890 					op << ", ";
    891 				op << m_lookupSpec.offset[ndx];
    892 			}
    893 			op << ")";
    894 		}
    895 
    896 		if (m_lookupSpec.useBias)
    897 			op << ", " << lodBias;
    898 
    899 		op << ")";
    900 
    901 		if (isShadow)
    902 			op << ", 0.0, 0.0, 1.0)";
    903 		else
    904 			op << ")*u_scale + u_bias";
    905 
    906 		op << ";\n";
    907 	}
    908 
    909 	if (isVtxCase)
    910 		frag << "\to_color = v_color;\n";
    911 	else
    912 	{
    913 		vert << "\tv_texCoord = a_in0;\n";
    914 
    915 		if (isGrad)
    916 		{
    917 			vert << "\tv_gradX = a_in1;\n";
    918 			vert << "\tv_gradY = a_in2;\n";
    919 		}
    920 		else if (hasLodBias)
    921 			vert << "\tv_lodBias = a_in1;\n";
    922 	}
    923 
    924 	vert << "}\n";
    925 	frag << "}\n";
    926 
    927 	m_vertShaderSource = vert.str();
    928 	m_fragShaderSource = frag.str();
    929 }
    930 
    931 void ShaderTextureFunctionCase::deinit (void)
    932 {
    933 	gls::ShaderRenderCase::deinit();
    934 
    935 	delete m_texture2D;
    936 	delete m_textureCube;
    937 	delete m_texture2DArray;
    938 	delete m_texture3D;
    939 
    940 	m_texture2D			= DE_NULL;
    941 	m_textureCube		= DE_NULL;
    942 	m_texture2DArray	= DE_NULL;
    943 	m_texture3D			= DE_NULL;
    944 }
    945 
    946 void ShaderTextureFunctionCase::setupUniforms (int programID, const tcu::Vec4&)
    947 {
    948 	const glw::Functions& gl = m_renderCtx.getFunctions();
    949 	gl.uniform1i(gl.getUniformLocation(programID, "u_sampler"),	0);
    950 	gl.uniform4fv(gl.getUniformLocation(programID, "u_scale"),	1, m_lookupParams.scale.getPtr());
    951 	gl.uniform4fv(gl.getUniformLocation(programID, "u_bias"),	1, m_lookupParams.bias.getPtr());
    952 }
    953 
    954 class TextureSizeCase : public TestCase
    955 {
    956 public:
    957 						TextureSizeCase		(Context& context, const char* name, const char* desc, const char* samplerType, const TextureSpec& texture, bool isVertexCase);
    958 						~TextureSizeCase	(void);
    959 
    960 	void				deinit				(void);
    961 	IterateResult		iterate				(void);
    962 
    963 private:
    964 	struct TestSize
    965 	{
    966 		tcu::IVec3	textureSize;
    967 		int			lod;
    968 		int			lodBase;
    969 		tcu::IVec3	expectedSize;
    970 	};
    971 
    972 	bool				initShader			(void);
    973 	void				freeShader			(void);
    974 	bool				testTextureSize		(const TestSize&);
    975 	std::string			genVertexShader		(void) const;
    976 	std::string			genFragmentShader	(void) const;
    977 	glw::GLenum			getGLTextureTarget	(void) const;
    978 
    979 	const char*			m_samplerTypeStr;
    980 	const TextureSpec	m_textureSpec;
    981 	const bool			m_isVertexCase;
    982 	const bool			m_has3DSize;
    983 	glu::ShaderProgram*	m_program;
    984 	int					m_iterationCounter;
    985 };
    986 
    987 TextureSizeCase::TextureSizeCase (Context& context, const char* name, const char* desc, const char* samplerType, const TextureSpec& texture, bool isVertexCase)
    988 	: TestCase			(context, name, desc)
    989 	, m_samplerTypeStr	(samplerType)
    990 	, m_textureSpec		(texture)
    991 	, m_isVertexCase	(isVertexCase)
    992 	, m_has3DSize		(texture.type == TEXTURETYPE_3D || texture.type == TEXTURETYPE_2D_ARRAY)
    993 	, m_program			(DE_NULL)
    994 	, m_iterationCounter(0)
    995 {
    996 }
    997 
    998 TextureSizeCase::~TextureSizeCase (void)
    999 {
   1000 	deinit();
   1001 }
   1002 
   1003 void TextureSizeCase::deinit (void)
   1004 {
   1005 	freeShader();
   1006 }
   1007 
   1008 TestCase::IterateResult TextureSizeCase::iterate (void)
   1009 {
   1010 	const int currentIteration = m_iterationCounter++;
   1011 	const TestSize testSizes[] =
   1012 	{
   1013 		{ tcu::IVec3(1, 2, 1),			1,		0,	tcu::IVec3(1, 1, 1)			},
   1014 		{ tcu::IVec3(1, 2, 1),			0,		0,	tcu::IVec3(1, 2, 1)			},
   1015 
   1016 		{ tcu::IVec3(1, 3, 2),			0,		0,	tcu::IVec3(1, 3, 2)			},
   1017 		{ tcu::IVec3(1, 3, 2),			1,		0,	tcu::IVec3(1, 1, 1)			},
   1018 
   1019 		{ tcu::IVec3(100, 31, 18),		0,		0,	tcu::IVec3(100, 31, 18)		},
   1020 		{ tcu::IVec3(100, 31, 18),		1,		0,	tcu::IVec3(50, 15, 9)		},
   1021 		{ tcu::IVec3(100, 31, 18),		2,		0,	tcu::IVec3(25, 7, 4)		},
   1022 		{ tcu::IVec3(100, 31, 18),		3,		0,	tcu::IVec3(12, 3, 2)		},
   1023 		{ tcu::IVec3(100, 31, 18),		4,		0,	tcu::IVec3(6, 1, 1)			},
   1024 		{ tcu::IVec3(100, 31, 18),		5,		0,	tcu::IVec3(3, 1, 1)			},
   1025 		{ tcu::IVec3(100, 31, 18),		6,		0,	tcu::IVec3(1, 1, 1)			},
   1026 
   1027 		{ tcu::IVec3(100, 128, 32),		0,		0,	tcu::IVec3(100, 128, 32)	},
   1028 		{ tcu::IVec3(100, 128, 32),		1,		0,	tcu::IVec3(50, 64, 16)		},
   1029 		{ tcu::IVec3(100, 128, 32),		2,		0,	tcu::IVec3(25, 32, 8)		},
   1030 		{ tcu::IVec3(100, 128, 32),		3,		0,	tcu::IVec3(12, 16, 4)		},
   1031 		{ tcu::IVec3(100, 128, 32),		4,		0,	tcu::IVec3(6, 8, 2)			},
   1032 		{ tcu::IVec3(100, 128, 32),		5,		0,	tcu::IVec3(3, 4, 1)			},
   1033 		{ tcu::IVec3(100, 128, 32),		6,		0,	tcu::IVec3(1, 2, 1)			},
   1034 		{ tcu::IVec3(100, 128, 32),		7,		0,	tcu::IVec3(1, 1, 1)			},
   1035 
   1036 		// pow 2
   1037 		{ tcu::IVec3(128, 64, 32),		0,		0,	tcu::IVec3(128, 64, 32)		},
   1038 		{ tcu::IVec3(128, 64, 32),		1,		0,	tcu::IVec3(64, 32, 16)		},
   1039 		{ tcu::IVec3(128, 64, 32),		2,		0,	tcu::IVec3(32, 16, 8)		},
   1040 		{ tcu::IVec3(128, 64, 32),		3,		0,	tcu::IVec3(16, 8, 4)		},
   1041 		{ tcu::IVec3(128, 64, 32),		4,		0,	tcu::IVec3(8, 4, 2)			},
   1042 		{ tcu::IVec3(128, 64, 32),		5,		0,	tcu::IVec3(4, 2, 1)			},
   1043 		{ tcu::IVec3(128, 64, 32),		6,		0,	tcu::IVec3(2, 1, 1)			},
   1044 		{ tcu::IVec3(128, 64, 32),		7,		0,	tcu::IVec3(1, 1, 1)			},
   1045 
   1046 		// w == h
   1047 		{ tcu::IVec3(1, 1, 1),			0,		0,	tcu::IVec3(1, 1, 1)			},
   1048 		{ tcu::IVec3(64, 64, 64),		0,		0,	tcu::IVec3(64, 64, 64)		},
   1049 		{ tcu::IVec3(64, 64, 64),		1,		0,	tcu::IVec3(32, 32, 32)		},
   1050 		{ tcu::IVec3(64, 64, 64),		2,		0,	tcu::IVec3(16, 16, 16)		},
   1051 		{ tcu::IVec3(64, 64, 64),		3,		0,	tcu::IVec3(8, 8, 8)			},
   1052 		{ tcu::IVec3(64, 64, 64),		4,		0,	tcu::IVec3(4, 4, 4)			},
   1053 
   1054 		// with lod base
   1055 		{ tcu::IVec3(100, 31, 18),		3,		1,	tcu::IVec3(6, 1, 1)			},
   1056 		{ tcu::IVec3(128, 64, 32),		3,		1,	tcu::IVec3(8, 4, 2)			},
   1057 		{ tcu::IVec3(64, 64, 64),		1,		1,	tcu::IVec3(16, 16, 16)		},
   1058 
   1059 	};
   1060 	const int lastIterationIndex = DE_LENGTH_OF_ARRAY(testSizes) + 1;
   1061 
   1062 	if (currentIteration == 0)
   1063 	{
   1064 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   1065 		return initShader() ? CONTINUE : STOP;
   1066 	}
   1067 	else if (currentIteration == lastIterationIndex)
   1068 	{
   1069 		freeShader();
   1070 		return STOP;
   1071 	}
   1072 	else
   1073 	{
   1074 		if (!testTextureSize(testSizes[currentIteration - 1]))
   1075 			if (m_testCtx.getTestResult() != QP_TEST_RESULT_FAIL)
   1076 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got unexpected texture size");
   1077 		return CONTINUE;
   1078 	}
   1079 }
   1080 
   1081 bool TextureSizeCase::initShader (void)
   1082 {
   1083 	const std::string		vertSrc = genVertexShader();
   1084 	const std::string		fragSrc = genFragmentShader();
   1085 
   1086 	DE_ASSERT(m_program == DE_NULL);
   1087 	m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(vertSrc, fragSrc));
   1088 	m_context.getTestContext().getLog() << *m_program;
   1089 
   1090 	if (!m_program->isOk())
   1091 	{
   1092 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Shader failed");
   1093 		return false;
   1094 	}
   1095 
   1096 	return true;
   1097 }
   1098 
   1099 void TextureSizeCase::freeShader (void)
   1100 {
   1101 	delete m_program;
   1102 	m_program = DE_NULL;
   1103 }
   1104 
   1105 bool TextureSizeCase::testTextureSize (const TestSize& testSize)
   1106 {
   1107 	using tcu::TestLog;
   1108 
   1109 	const tcu::Vec4 triangle[3] = // covers entire viewport
   1110 	{
   1111 		tcu::Vec4(-1, -1, 0, 1),
   1112 		tcu::Vec4( 4, -1, 0, 1),
   1113 		tcu::Vec4(-1,  4, 0, 1),
   1114 	};
   1115 
   1116 	const glw::Functions&	gl				= m_context.getRenderContext().getFunctions();
   1117 
   1118 	const glw::GLint		positionLoc		= gl.getAttribLocation	(m_program->getProgram(), "a_position");
   1119 	const glw::GLint		samplerLoc		= gl.getUniformLocation	(m_program->getProgram(), "u_sampler");
   1120 	const glw::GLint		sizeLoc			= gl.getUniformLocation	(m_program->getProgram(), "u_texSize");
   1121 	const glw::GLint		lodLoc			= gl.getUniformLocation	(m_program->getProgram(), "u_lod");
   1122 	const glw::GLenum		textureTarget	= getGLTextureTarget	();
   1123 	const bool				isSquare		= testSize.textureSize.x() == testSize.textureSize.y();
   1124 	const bool				is2DLodValid	= (testSize.textureSize.x() >> (testSize.lod + testSize.lodBase)) != 0 || (testSize.textureSize.y() >> (testSize.lod + testSize.lodBase)) != 0;
   1125 	bool					success			= true;
   1126 	glw::GLenum				errorValue;
   1127 
   1128 	// Skip incompatible cases
   1129 	if (m_textureSpec.type == TEXTURETYPE_CUBE_MAP && !isSquare)
   1130 		return true;
   1131 	if (m_textureSpec.type == TEXTURETYPE_2D && !is2DLodValid)
   1132 		return true;
   1133 	if (m_textureSpec.type == TEXTURETYPE_2D_ARRAY && !is2DLodValid)
   1134 		return true;
   1135 
   1136 	// setup rendering
   1137 
   1138 	gl.useProgram				(m_program->getProgram());
   1139 	gl.uniform1i				(samplerLoc, 0);
   1140 	gl.clearColor				(0.5f, 0.5f, 0.5f, 1.0f);
   1141 	gl.viewport					(0, 0, 1, 1);
   1142 	gl.vertexAttribPointer		(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, triangle);
   1143 	gl.enableVertexAttribArray	(positionLoc);
   1144 
   1145 	// setup texture
   1146 	{
   1147 		const int	maxLevel	= testSize.lod + testSize.lodBase;
   1148 		const int	levels		= maxLevel + 1;
   1149 		glw::GLuint texId		= 0;
   1150 
   1151 		// gen texture
   1152 		gl.genTextures(1, &texId);
   1153 		gl.bindTexture(textureTarget, texId);
   1154 		gl.texParameteri(textureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   1155 		gl.texParameteri(textureTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   1156 		gl.texParameteri(textureTarget, GL_TEXTURE_BASE_LEVEL, testSize.lodBase);
   1157 
   1158 		// set up texture
   1159 
   1160 		switch (m_textureSpec.type)
   1161 		{
   1162 			case TEXTURETYPE_3D:
   1163 			{
   1164 				m_context.getTestContext().getLog() << TestLog::Message << "Testing image size " << testSize.textureSize.x() << "x" << testSize.textureSize.y() << "x" << testSize.textureSize.z() << TestLog::EndMessage;
   1165 				m_context.getTestContext().getLog() << TestLog::Message << "Lod: " << testSize.lod << ", base level: " << testSize.lodBase << TestLog::EndMessage;
   1166 				m_context.getTestContext().getLog() << TestLog::Message << "Expecting: " << testSize.expectedSize.x() << "x" << testSize.expectedSize.y() << "x" << testSize.expectedSize.z() << TestLog::EndMessage;
   1167 
   1168 				gl.uniform3iv(sizeLoc, 1, testSize.expectedSize.m_data);
   1169 				gl.uniform1iv(lodLoc,  1, &testSize.lod);
   1170 
   1171 				gl.texStorage3D(textureTarget, levels, m_textureSpec.format, testSize.textureSize.x(), testSize.textureSize.y(), testSize.textureSize.z());
   1172 				break;
   1173 			}
   1174 
   1175 			case TEXTURETYPE_2D:
   1176 			case TEXTURETYPE_CUBE_MAP:
   1177 			{
   1178 				m_context.getTestContext().getLog() << TestLog::Message << "Testing image size " << testSize.textureSize.x() << "x" << testSize.textureSize.y() << TestLog::EndMessage;
   1179 				m_context.getTestContext().getLog() << TestLog::Message << "Lod: " << testSize.lod << ", base level: " << testSize.lodBase << TestLog::EndMessage;
   1180 				m_context.getTestContext().getLog() << TestLog::Message << "Expecting: " << testSize.expectedSize.x() << "x" << testSize.expectedSize.y() << TestLog::EndMessage;
   1181 
   1182 				gl.uniform2iv(sizeLoc, 1, testSize.expectedSize.m_data);
   1183 				gl.uniform1iv(lodLoc,  1, &testSize.lod);
   1184 
   1185 				gl.texStorage2D(textureTarget, levels, m_textureSpec.format, testSize.textureSize.x(), testSize.textureSize.y());
   1186 				break;
   1187 			}
   1188 
   1189 			case TEXTURETYPE_2D_ARRAY:
   1190 			{
   1191 				tcu::IVec3 expectedSize(testSize.expectedSize.x(), testSize.expectedSize.y(), testSize.textureSize.z());
   1192 
   1193 				m_context.getTestContext().getLog() << TestLog::Message << "Testing image size " << testSize.textureSize.x() << "x" << testSize.textureSize.y() << " with " << testSize.textureSize.z() << " layer(s)" << TestLog::EndMessage;
   1194 				m_context.getTestContext().getLog() << TestLog::Message << "Lod: " << testSize.lod << ", base level: " << testSize.lodBase << TestLog::EndMessage;
   1195 				m_context.getTestContext().getLog() << TestLog::Message << "Expecting: " << testSize.expectedSize.x() << "x" << testSize.expectedSize.y() << " and " << testSize.textureSize.z() << " layer(s)" << TestLog::EndMessage;
   1196 
   1197 				gl.uniform3iv(sizeLoc, 1, expectedSize.m_data);
   1198 				gl.uniform1iv(lodLoc,  1, &testSize.lod);
   1199 
   1200 				gl.texStorage3D(textureTarget, levels, m_textureSpec.format, testSize.textureSize.x(), testSize.textureSize.y(), testSize.textureSize.z());
   1201 				break;
   1202 			}
   1203 
   1204 			default:
   1205 			{
   1206 				DE_ASSERT(false);
   1207 				break;
   1208 			}
   1209 		}
   1210 
   1211 		errorValue = gl.getError();
   1212 		if (errorValue == GL_OUT_OF_MEMORY)
   1213 		{
   1214 			throw glu::OutOfMemoryError("Failed to allocate texture, got GL_OUT_OF_MEMORY.", "TexStorageXD", __FILE__, __LINE__);
   1215 		}
   1216 		else if (errorValue != GL_NO_ERROR)
   1217 		{
   1218 			// error is a failure too
   1219 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Failed, got " << glu::getErrorStr(errorValue) << "." << tcu::TestLog::EndMessage;
   1220 			success = false;
   1221 		}
   1222 		else
   1223 		{
   1224 			// test
   1225 			const float			colorTolerance = 0.1f;
   1226 			tcu::TextureLevel	sample			(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), 1, 1);
   1227 			tcu::Vec4			outputColor;
   1228 
   1229 			gl.clear			(GL_COLOR_BUFFER_BIT);
   1230 			gl.drawArrays		(GL_TRIANGLES, 0, 3);
   1231 			gl.finish			();
   1232 
   1233 			glu::readPixels		(m_context.getRenderContext(), 0, 0, sample.getAccess());
   1234 
   1235 			outputColor = sample.getAccess().getPixel(0, 0);
   1236 
   1237 			if (outputColor.x() >= 1.0f - colorTolerance &&
   1238 				outputColor.y() >= 1.0f - colorTolerance &&
   1239 				outputColor.z() >= 1.0f - colorTolerance)
   1240 			{
   1241 				// success
   1242 				m_context.getTestContext().getLog() << TestLog::Message << "Passed" << TestLog::EndMessage;
   1243 			}
   1244 			else
   1245 			{
   1246 				// failure
   1247 				m_context.getTestContext().getLog() << TestLog::Message << "Failed" << TestLog::EndMessage;
   1248 				success = false;
   1249 			}
   1250 		}
   1251 
   1252 		// empty line to format log nicely
   1253 		m_context.getTestContext().getLog() << TestLog::Message << TestLog::EndMessage;
   1254 
   1255 		// free
   1256 		gl.bindTexture		(textureTarget, 0);
   1257 		gl.deleteTextures	(1, &texId);
   1258 	}
   1259 
   1260 	gl.useProgram(0);
   1261 
   1262 	return success;
   1263 }
   1264 
   1265 std::string TextureSizeCase::genVertexShader() const
   1266 {
   1267 	std::ostringstream	vert;
   1268 
   1269 	vert << "#version 300 es\n"
   1270 			<< "in highp vec4 a_position;\n";
   1271 
   1272 	if (m_isVertexCase)
   1273 	{
   1274 		vert << "out mediump vec4 v_color;\n";
   1275 		vert << "uniform highp " << m_samplerTypeStr << " u_sampler;\n";
   1276 		vert << "uniform highp ivec" << (m_has3DSize ? 3 : 2) << " u_texSize;\n";
   1277 		vert << "uniform highp int u_lod;\n";
   1278 	}
   1279 
   1280 	vert << "void main()\n{\n";
   1281 
   1282 	if (m_isVertexCase)
   1283 		vert << "	v_color = (textureSize(u_sampler, u_lod) == u_texSize ? vec4(1.0, 1.0, 1.0, 1.0) : vec4(0.0, 0.0, 0.0, 1.0));\n";
   1284 
   1285 	vert << "	gl_Position = a_position;\n"
   1286 			<< "}\n";
   1287 
   1288 	return vert.str();
   1289 }
   1290 
   1291 std::string TextureSizeCase::genFragmentShader() const
   1292 {
   1293 	std::ostringstream	frag;
   1294 
   1295 	frag << "#version 300 es\n"
   1296 			<< "layout(location = 0) out mediump vec4 o_color;\n";
   1297 
   1298 	if (m_isVertexCase)
   1299 			frag << "in mediump vec4 v_color;\n";
   1300 
   1301 	if (!m_isVertexCase)
   1302 	{
   1303 		frag << "uniform highp " << m_samplerTypeStr << " u_sampler;\n";
   1304 		frag << "uniform highp ivec" << (m_has3DSize ? 3 : 2) << " u_texSize;\n";
   1305 		frag << "uniform highp int u_lod;\n";
   1306 	}
   1307 
   1308 	frag << "void main()\n{\n";
   1309 
   1310 	if (!m_isVertexCase)
   1311 		frag << "	o_color = (textureSize(u_sampler, u_lod) == u_texSize ? vec4(1.0, 1.0, 1.0, 1.0) : vec4(0.0, 0.0, 0.0, 1.0));\n";
   1312 	else
   1313 		frag << "	o_color = v_color;\n";
   1314 
   1315 	frag << "}\n";
   1316 
   1317 	return frag.str();
   1318 }
   1319 
   1320 glw::GLenum TextureSizeCase::getGLTextureTarget() const
   1321 {
   1322 	switch (m_textureSpec.type)
   1323 	{
   1324 		case TEXTURETYPE_2D:		return GL_TEXTURE_2D;		break;
   1325 		case TEXTURETYPE_CUBE_MAP:	return GL_TEXTURE_CUBE_MAP;	break;
   1326 		case TEXTURETYPE_2D_ARRAY:	return GL_TEXTURE_2D_ARRAY;	break;
   1327 		case TEXTURETYPE_3D:		return GL_TEXTURE_3D;		break;
   1328 		default:					DE_ASSERT(DE_FALSE);		break;
   1329 	}
   1330 	return 0;
   1331 }
   1332 
   1333 ShaderTextureFunctionTests::ShaderTextureFunctionTests (Context& context)
   1334 	: TestCaseGroup(context, "texture_functions", "Texture Access Function Tests")
   1335 {
   1336 }
   1337 
   1338 ShaderTextureFunctionTests::~ShaderTextureFunctionTests (void)
   1339 {
   1340 }
   1341 
   1342 enum CaseFlags
   1343 {
   1344 	VERTEX		= (1<<0),
   1345 	FRAGMENT	= (1<<1),
   1346 	BOTH		= VERTEX|FRAGMENT
   1347 };
   1348 
   1349 struct TexFuncCaseSpec
   1350 {
   1351 	const char*			name;
   1352 	TextureLookupSpec	lookupSpec;
   1353 	TextureSpec			texSpec;
   1354 	TexEvalFunc			evalFunc;
   1355 	deUint32			flags;
   1356 };
   1357 
   1358 #define CASE_SPEC(NAME, FUNC, MINCOORD, MAXCOORD, USEBIAS, MINLOD, MAXLOD, USEOFFSET, OFFSET, TEXSPEC, EVALFUNC, FLAGS) \
   1359 	{ #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), TEXSPEC, EVALFUNC, FLAGS }
   1360 #define GRAD_CASE_SPEC(NAME, FUNC, MINCOORD, MAXCOORD, MINDX, MAXDX, MINDY, MAXDY, USEOFFSET, OFFSET, TEXSPEC, EVALFUNC, FLAGS) \
   1361 	{ #NAME, TextureLookupSpec(FUNC, MINCOORD, MAXCOORD, false, 0.0f, 0.0f, MINDX, MAXDX, MINDY, MAXDY, USEOFFSET, OFFSET), TEXSPEC, EVALFUNC, FLAGS }
   1362 
   1363 static void createCaseGroup (TestCaseGroup* parent, const char* groupName, const char* groupDesc, const TexFuncCaseSpec* cases, int numCases)
   1364 {
   1365 	tcu::TestCaseGroup* group = new tcu::TestCaseGroup(parent->getTestContext(), groupName, groupDesc);
   1366 	parent->addChild(group);
   1367 
   1368 	for (int ndx = 0; ndx < numCases; ndx++)
   1369 	{
   1370 		std::string name = cases[ndx].name;
   1371 		if (cases[ndx].flags & VERTEX)
   1372 			group->addChild(new ShaderTextureFunctionCase(parent->getContext(), (name + "_vertex").c_str(), "", cases[ndx].lookupSpec, cases[ndx].texSpec, cases[ndx].evalFunc, true));
   1373 		if (cases[ndx].flags & FRAGMENT)
   1374 			group->addChild(new ShaderTextureFunctionCase(parent->getContext(), (name + "_fragment").c_str(), "", cases[ndx].lookupSpec, cases[ndx].texSpec, cases[ndx].evalFunc, false));
   1375 	}
   1376 }
   1377 
   1378 void ShaderTextureFunctionTests::init (void)
   1379 {
   1380 	// Samplers
   1381 	static const tcu::Sampler	samplerNearestNoMipmap	(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
   1382 														 tcu::Sampler::NEAREST, tcu::Sampler::NEAREST,
   1383 														 0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_NONE,
   1384 														 0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
   1385 	static const tcu::Sampler	samplerLinearNoMipmap	(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
   1386 														 tcu::Sampler::LINEAR, tcu::Sampler::LINEAR,
   1387 														 0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_NONE,
   1388 														 0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
   1389 	static const tcu::Sampler	samplerNearestMipmap	(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
   1390 														 tcu::Sampler::NEAREST_MIPMAP_NEAREST, tcu::Sampler::NEAREST,
   1391 														 0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_NONE,
   1392 														 0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
   1393 	static const tcu::Sampler	samplerLinearMipmap		(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
   1394 														 tcu::Sampler::LINEAR_MIPMAP_NEAREST, tcu::Sampler::LINEAR,
   1395 														 0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_NONE,
   1396 														 0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
   1397 
   1398 	static const tcu::Sampler	samplerShadowNoMipmap	(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
   1399 														 tcu::Sampler::NEAREST, tcu::Sampler::NEAREST,
   1400 														 0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_LESS,
   1401 														 0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
   1402 	static const tcu::Sampler	samplerShadowMipmap		(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
   1403 														 tcu::Sampler::NEAREST_MIPMAP_NEAREST, tcu::Sampler::NEAREST,
   1404 														 0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_LESS,
   1405 														 0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
   1406 
   1407 	static const tcu::Sampler	samplerTexelFetch		(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
   1408 														 tcu::Sampler::NEAREST_MIPMAP_NEAREST, tcu::Sampler::NEAREST,
   1409 														 0.0f /* LOD threshold */, false /* non-normalized coords */, tcu::Sampler::COMPAREMODE_NONE,
   1410 														 0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
   1411 
   1412 	// Default textures.
   1413 	//												Type					Format					W		H		D	L	Sampler
   1414 	static const TextureSpec tex2DFixed				(TEXTURETYPE_2D,		GL_RGBA8,				256,	256,	1,	1,	samplerLinearNoMipmap);
   1415 	static const TextureSpec tex2DFloat				(TEXTURETYPE_2D,		GL_RGBA16F,				256,	256,	1,	1,	samplerLinearNoMipmap);
   1416 	static const TextureSpec tex2DInt				(TEXTURETYPE_2D,		GL_RGBA8I,				256,	256,	1,	1,	samplerNearestNoMipmap);
   1417 	static const TextureSpec tex2DUint				(TEXTURETYPE_2D,		GL_RGBA8UI,				256,	256,	1,	1,	samplerNearestNoMipmap);
   1418 	static const TextureSpec tex2DMipmapFixed		(TEXTURETYPE_2D,		GL_RGBA8,				256,	256,	1,	9,	samplerLinearMipmap);
   1419 	static const TextureSpec tex2DMipmapFloat		(TEXTURETYPE_2D,		GL_RGBA16F,				256,	256,	1,	9,	samplerLinearMipmap);
   1420 	static const TextureSpec tex2DMipmapInt			(TEXTURETYPE_2D,		GL_RGBA8I,				256,	256,	1,	9,	samplerNearestMipmap);
   1421 	static const TextureSpec tex2DMipmapUint		(TEXTURETYPE_2D,		GL_RGBA8UI,				256,	256,	1,	9,	samplerNearestMipmap);
   1422 
   1423 	static const TextureSpec tex2DShadow			(TEXTURETYPE_2D,		GL_DEPTH_COMPONENT16,	256,	256,	1,	9,	samplerShadowNoMipmap);
   1424 	static const TextureSpec tex2DMipmapShadow		(TEXTURETYPE_2D,		GL_DEPTH_COMPONENT16,	256,	256,	1,	9,	samplerShadowMipmap);
   1425 
   1426 	static const TextureSpec tex2DTexelFetchFixed	(TEXTURETYPE_2D,		GL_RGBA8,				256,	256,	1,	9,	samplerTexelFetch);
   1427 	static const TextureSpec tex2DTexelFetchFloat	(TEXTURETYPE_2D,		GL_RGBA16F,				256,	256,	1,	9,	samplerTexelFetch);
   1428 	static const TextureSpec tex2DTexelFetchInt		(TEXTURETYPE_2D,		GL_RGBA8I,				256,	256,	1,	9,	samplerTexelFetch);
   1429 	static const TextureSpec tex2DTexelFetchUint	(TEXTURETYPE_2D,		GL_RGBA8UI,				256,	256,	1,	9,	samplerTexelFetch);
   1430 
   1431 	static const TextureSpec texCubeFixed			(TEXTURETYPE_CUBE_MAP,	GL_RGBA8,	256,	256,	1,	1,	samplerLinearNoMipmap);
   1432 	static const TextureSpec texCubeFloat			(TEXTURETYPE_CUBE_MAP,	GL_RGBA16F,	256,	256,	1,	1,	samplerLinearNoMipmap);
   1433 	static const TextureSpec texCubeInt				(TEXTURETYPE_CUBE_MAP,	GL_RGBA8I,	256,	256,	1,	1,	samplerNearestNoMipmap);
   1434 	static const TextureSpec texCubeUint			(TEXTURETYPE_CUBE_MAP,	GL_RGBA8UI,	256,	256,	1,	1,	samplerNearestNoMipmap);
   1435 	static const TextureSpec texCubeMipmapFixed		(TEXTURETYPE_CUBE_MAP,	GL_RGBA8,	256,	256,	1,	9,	samplerLinearMipmap);
   1436 	static const TextureSpec texCubeMipmapFloat		(TEXTURETYPE_CUBE_MAP,	GL_RGBA16F,	128,	128,	1,	8,	samplerLinearMipmap);
   1437 	static const TextureSpec texCubeMipmapInt		(TEXTURETYPE_CUBE_MAP,	GL_RGBA8I,	256,	256,	1,	9,	samplerNearestMipmap);
   1438 	static const TextureSpec texCubeMipmapUint		(TEXTURETYPE_CUBE_MAP,	GL_RGBA8UI,	256,	256,	1,	9,	samplerNearestMipmap);
   1439 
   1440 	static const TextureSpec texCubeShadow			(TEXTURETYPE_CUBE_MAP,	GL_DEPTH_COMPONENT16,	256,	256,	1,	1,	samplerShadowNoMipmap);
   1441 	static const TextureSpec texCubeMipmapShadow	(TEXTURETYPE_CUBE_MAP,	GL_DEPTH_COMPONENT16,	256,	256,	1,	9,	samplerShadowMipmap);
   1442 
   1443 	static const TextureSpec tex2DArrayFixed		(TEXTURETYPE_2D_ARRAY,	GL_RGBA8,	128,	128,	4,	1,	samplerLinearNoMipmap);
   1444 	static const TextureSpec tex2DArrayFloat		(TEXTURETYPE_2D_ARRAY,	GL_RGBA16F,	128,	128,	4,	1,	samplerLinearNoMipmap);
   1445 	static const TextureSpec tex2DArrayInt			(TEXTURETYPE_2D_ARRAY,	GL_RGBA8I,	128,	128,	4,	1,	samplerNearestNoMipmap);
   1446 	static const TextureSpec tex2DArrayUint			(TEXTURETYPE_2D_ARRAY,	GL_RGBA8UI,	128,	128,	4,	1,	samplerNearestNoMipmap);
   1447 	static const TextureSpec tex2DArrayMipmapFixed	(TEXTURETYPE_2D_ARRAY,	GL_RGBA8,	128,	128,	4,	8,	samplerLinearMipmap);
   1448 	static const TextureSpec tex2DArrayMipmapFloat	(TEXTURETYPE_2D_ARRAY,	GL_RGBA16F,	128,	128,	4,	8,	samplerLinearMipmap);
   1449 	static const TextureSpec tex2DArrayMipmapInt	(TEXTURETYPE_2D_ARRAY,	GL_RGBA8I,	128,	128,	4,	8,	samplerNearestMipmap);
   1450 	static const TextureSpec tex2DArrayMipmapUint	(TEXTURETYPE_2D_ARRAY,	GL_RGBA8UI,	128,	128,	4,	8,	samplerNearestMipmap);
   1451 
   1452 	static const TextureSpec tex2DArrayShadow		(TEXTURETYPE_2D_ARRAY,	GL_DEPTH_COMPONENT16,	128,	128,	4,	1,	samplerShadowNoMipmap);
   1453 	static const TextureSpec tex2DArrayMipmapShadow	(TEXTURETYPE_2D_ARRAY,	GL_DEPTH_COMPONENT16,	128,	128,	4,	8,	samplerShadowMipmap);
   1454 
   1455 	static const TextureSpec tex2DArrayTexelFetchFixed	(TEXTURETYPE_2D_ARRAY,	GL_RGBA8,	128,	128,	4,	8,	samplerTexelFetch);
   1456 	static const TextureSpec tex2DArrayTexelFetchFloat	(TEXTURETYPE_2D_ARRAY,	GL_RGBA16F,	128,	128,	4,	8,	samplerTexelFetch);
   1457 	static const TextureSpec tex2DArrayTexelFetchInt	(TEXTURETYPE_2D_ARRAY,	GL_RGBA8I,	128,	128,	4,	8,	samplerTexelFetch);
   1458 	static const TextureSpec tex2DArrayTexelFetchUint	(TEXTURETYPE_2D_ARRAY,	GL_RGBA8UI,	128,	128,	4,	8,	samplerTexelFetch);
   1459 
   1460 	static const TextureSpec tex3DFixed				(TEXTURETYPE_3D,		GL_RGBA8,	64,		32,		32,	1,	samplerLinearNoMipmap);
   1461 	static const TextureSpec tex3DFloat				(TEXTURETYPE_3D,		GL_RGBA16F,	64,		32,		32,	1,	samplerLinearNoMipmap);
   1462 	static const TextureSpec tex3DInt				(TEXTURETYPE_3D,		GL_RGBA8I,	64,		32,		32,	1,	samplerNearestNoMipmap);
   1463 	static const TextureSpec tex3DUint				(TEXTURETYPE_3D,		GL_RGBA8UI,	64,		32,		32,	1,	samplerNearestNoMipmap);
   1464 	static const TextureSpec tex3DMipmapFixed		(TEXTURETYPE_3D,		GL_RGBA8,	64,		32,		32,	7,	samplerLinearMipmap);
   1465 	static const TextureSpec tex3DMipmapFloat		(TEXTURETYPE_3D,		GL_RGBA16F,	64,		32,		32,	7,	samplerLinearMipmap);
   1466 	static const TextureSpec tex3DMipmapInt			(TEXTURETYPE_3D,		GL_RGBA8I,	64,		32,		32,	7,	samplerNearestMipmap);
   1467 	static const TextureSpec tex3DMipmapUint		(TEXTURETYPE_3D,		GL_RGBA8UI,	64,		32,		32,	7,	samplerNearestMipmap);
   1468 
   1469 	static const TextureSpec tex3DTexelFetchFixed	(TEXTURETYPE_3D,		GL_RGBA8,	64,		32,		32,	7,	samplerTexelFetch);
   1470 	static const TextureSpec tex3DTexelFetchFloat	(TEXTURETYPE_3D,		GL_RGBA16F,	64,		32,		32,	7,	samplerTexelFetch);
   1471 	static const TextureSpec tex3DTexelFetchInt		(TEXTURETYPE_3D,		GL_RGBA8I,	64,		32,		32,	7,	samplerTexelFetch);
   1472 	static const TextureSpec tex3DTexelFetchUint	(TEXTURETYPE_3D,		GL_RGBA8UI,	64,		32,		32,	7,	samplerTexelFetch);
   1473 
   1474 	// texture() cases
   1475 	static const TexFuncCaseSpec textureCases[] =
   1476 	{
   1477 		//		  Name							Function			MinCoord							MaxCoord							Bias?	MinLod	MaxLod	Offset?	Offset		Format					EvalFunc				Flags
   1478 		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),
   1479 		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),
   1480 		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),
   1481 		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),
   1482 		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),
   1483 		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),
   1484 		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),
   1485 		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),
   1486 
   1487 		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),
   1488 		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),
   1489 		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),
   1490 		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),
   1491 
   1492 		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),
   1493 		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),
   1494 		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),
   1495 		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),
   1496 		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),
   1497 		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),
   1498 		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),
   1499 		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),
   1500 
   1501 		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),
   1502 		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),
   1503 		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),
   1504 		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),
   1505 
   1506 		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),
   1507 		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),
   1508 		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),
   1509 		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),
   1510 		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),
   1511 		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),
   1512 		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),
   1513 		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),
   1514 
   1515 		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),
   1516 		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),
   1517 		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),
   1518 		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),
   1519 
   1520 		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),
   1521 		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),
   1522 		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),
   1523 		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),
   1524 		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),
   1525 		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),
   1526 		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),
   1527 		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),
   1528 
   1529 		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),
   1530 		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),
   1531 		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),
   1532 		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),
   1533 
   1534 		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),
   1535 		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),
   1536 		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),
   1537 
   1538 		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),
   1539 		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),
   1540 		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),
   1541 
   1542 		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),
   1543 		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)
   1544 
   1545 		// Not in spec.
   1546 //		CASE_SPEC(sampler2darrayshadow_bias,	(FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  1.0f),	true,	-2.0f,	2.0f,	Vec2(0.0f),	Vec2(0.0f), false,	IVec3(0)),	tex2DArrayMipmapShadow,	evalTexture2DArrayShadowBias,	FRAGMENT)
   1547 	};
   1548 	createCaseGroup(this, "texture", "texture() Tests", textureCases, DE_LENGTH_OF_ARRAY(textureCases));
   1549 
   1550 	// textureOffset() cases
   1551 	// \note _bias variants are not using mipmap thanks to wide allowed range for LOD computation
   1552 	static const TexFuncCaseSpec textureOffsetCases[] =
   1553 	{
   1554 		//		  Name							Function			MinCoord							MaxCoord							Bias?	MinLod	MaxLod	Offset?	Offset				Format					EvalFunc						Flags
   1555 		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),
   1556 		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),
   1557 		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),
   1558 		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),
   1559 		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),
   1560 		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),
   1561 		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),
   1562 		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),
   1563 
   1564 		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),
   1565 		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),
   1566 		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),
   1567 		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),
   1568 
   1569 		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),
   1570 		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),
   1571 		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),
   1572 		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),
   1573 		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),
   1574 		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),
   1575 		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),
   1576 		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),
   1577 
   1578 		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),
   1579 		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),
   1580 		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),
   1581 		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),
   1582 
   1583 		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,	true,	IVec3(-8, 7, 3),	tex3DFixed,				evalTexture3DOffset,			VERTEX),
   1584 		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,	true,	IVec3(7, 3, -8),	tex3DMipmapFixed,		evalTexture3DOffset,			FRAGMENT),
   1585 		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,	true,	IVec3(3, -8, 7),	tex3DFloat,				evalTexture3DOffset,			VERTEX),
   1586 		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,	true,	IVec3(-8, 7, 3),	tex3DMipmapFloat,		evalTexture3DOffset,			FRAGMENT),
   1587 		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,	true,	IVec3(7, 3, -8),	tex3DInt,				evalTexture3DOffset,			VERTEX),
   1588 		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,	true,	IVec3(3, -8, 7),	tex3DMipmapInt,			evalTexture3DOffset,			FRAGMENT),
   1589 		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,	true,	IVec3(-8, 7, 3),	tex3DUint,				evalTexture3DOffset,			VERTEX),
   1590 		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,	true,	IVec3(7, 3, -8),	tex3DMipmapUint,		evalTexture3DOffset,			FRAGMENT),
   1591 
   1592 		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),
   1593 		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),
   1594 		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),
   1595 		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),
   1596 
   1597 		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),
   1598 		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),
   1599 		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)
   1600 	};
   1601 	createCaseGroup(this, "textureoffset", "textureOffset() Tests", textureOffsetCases, DE_LENGTH_OF_ARRAY(textureOffsetCases));
   1602 
   1603 	// textureProj() cases
   1604 	// \note Currently uses constant divider!
   1605 	static const TexFuncCaseSpec textureProjCases[] =
   1606 	{
   1607 		//		  Name							Function				MinCoord							MaxCoord							Bias?	MinLod	MaxLod	Offset?	Offset		Format					EvalFunc				Flags
   1608 		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),
   1609 		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),
   1610 		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),
   1611 		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),
   1612 		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),
   1613 		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),
   1614 		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),
   1615 		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),
   1616 
   1617 		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),
   1618 		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),
   1619 		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),
   1620 		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),
   1621 
   1622 		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),
   1623 		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),
   1624 		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),
   1625 		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),
   1626 		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),
   1627 		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),
   1628 		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),
   1629 		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),
   1630 
   1631 		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),
   1632 		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),
   1633 		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),
   1634 		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),
   1635 
   1636 		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),
   1637 		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),
   1638 		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),
   1639 		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),
   1640 		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),
   1641 		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),
   1642 		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),
   1643 		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),
   1644 
   1645 		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),
   1646 		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),
   1647 		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),
   1648 		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),
   1649 
   1650 		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),
   1651 		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),
   1652 		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)
   1653 	};
   1654 	createCaseGroup(this, "textureproj", "textureProj() Tests", textureProjCases, DE_LENGTH_OF_ARRAY(textureProjCases));
   1655 
   1656 	// textureProjOffset() cases
   1657 	// \note Currently uses constant divider!
   1658 	static const TexFuncCaseSpec textureProjOffsetCases[] =
   1659 	{
   1660 		//		  Name							Function				MinCoord							MaxCoord							Bias?	MinLod	MaxLod	Offset?	Offset				Format					EvalFunc						Flags
   1661 		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),
   1662 		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),
   1663 		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),
   1664 		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),
   1665 		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),
   1666 		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),
   1667 		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),
   1668 		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),
   1669 
   1670 		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),
   1671 		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),
   1672 		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),
   1673 		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),
   1674 
   1675 		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),
   1676 		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),
   1677 		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),
   1678 		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),
   1679 		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),
   1680 		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),
   1681 		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),
   1682 		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),
   1683 
   1684 		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),
   1685 		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),
   1686 		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),
   1687 		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),
   1688 
   1689 		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,	true,	IVec3(-8, 7, 3),	tex3DFixed,				evalTexture3DProjOffset,		VERTEX),
   1690 		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,	true,	IVec3(7, 3, -8),	tex3DMipmapFixed,		evalTexture3DProjOffset,		FRAGMENT),
   1691 		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,	true,	IVec3(3, -8, 7),	tex3DFloat,				evalTexture3DProjOffset,		VERTEX),
   1692 		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,	true,	IVec3(-8, 7, 3),	tex3DMipmapFloat,		evalTexture3DProjOffset,		FRAGMENT),
   1693 		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,	true,	IVec3(7, 3, -8),	tex3DInt,				evalTexture3DProjOffset,		VERTEX),
   1694 		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,	true,	IVec3(3, -8, 7),	tex3DMipmapInt,			evalTexture3DProjOffset,		FRAGMENT),
   1695 		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,	true,	IVec3(-8, 7, 3),	tex3DUint,				evalTexture3DProjOffset,		VERTEX),
   1696 		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,	true,	IVec3(7, 3, -8),	tex3DMipmapUint,		evalTexture3DProjOffset,		FRAGMENT),
   1697 
   1698 		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),
   1699 		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),
   1700 		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),
   1701 		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),
   1702 
   1703 		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),
   1704 		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),
   1705 		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)
   1706 	};
   1707 	createCaseGroup(this, "textureprojoffset", "textureOffsetProj() Tests", textureProjOffsetCases, DE_LENGTH_OF_ARRAY(textureProjOffsetCases));
   1708 
   1709 	// textureLod() cases
   1710 	static const TexFuncCaseSpec textureLodCases[] =
   1711 	{
   1712 		//		  Name							Function				MinCoord							MaxCoord							Bias?	MinLod	MaxLod	Offset?	Offset		Format					EvalFunc				Flags
   1713 		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),
   1714 		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),
   1715 		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),
   1716 		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),
   1717 
   1718 		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),
   1719 		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),
   1720 		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),
   1721 		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),
   1722 
   1723 		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),
   1724 		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),
   1725 		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),
   1726 		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),
   1727 
   1728 		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),
   1729 		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),
   1730 		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),
   1731 		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),
   1732 
   1733 		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)
   1734 	};
   1735 	createCaseGroup(this, "texturelod", "textureLod() Tests", textureLodCases, DE_LENGTH_OF_ARRAY(textureLodCases));
   1736 
   1737 	// textureLodOffset() cases
   1738 	static const TexFuncCaseSpec textureLodOffsetCases[] =
   1739 	{
   1740 		//		  Name							Function				MinCoord							MaxCoord							Bias?	MinLod	MaxLod	Offset?	Offset				Format					EvalFunc						Flags
   1741 		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),
   1742 		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),
   1743 		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),
   1744 		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),
   1745 
   1746 		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),
   1747 		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),
   1748 		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),
   1749 		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),
   1750 
   1751 		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),
   1752 		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),
   1753 		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),
   1754 		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),
   1755 
   1756 		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)
   1757 	};
   1758 	createCaseGroup(this, "texturelodoffset", "textureLodOffset() Tests", textureLodOffsetCases, DE_LENGTH_OF_ARRAY(textureLodOffsetCases));
   1759 
   1760 	// textureProjLod() cases
   1761 	static const TexFuncCaseSpec textureProjLodCases[] =
   1762 	{
   1763 		//		  Name							Function					MinCoord							MaxCoord							Bias?	MinLod	MaxLod	Offset?	Offset		Format					EvalFunc					Flags
   1764 		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),
   1765 		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),
   1766 		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),
   1767 		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),
   1768 
   1769 		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),
   1770 		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),
   1771 		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),
   1772 		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),
   1773 
   1774 		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),
   1775 		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),
   1776 		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),
   1777 		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),
   1778 
   1779 		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)
   1780 	};
   1781 	createCaseGroup(this, "textureprojlod", "textureProjLod() Tests", textureProjLodCases, DE_LENGTH_OF_ARRAY(textureProjLodCases));
   1782 
   1783 	// textureProjLodOffset() cases
   1784 	static const TexFuncCaseSpec textureProjLodOffsetCases[] =
   1785 	{
   1786 		//		  Name							Function					MinCoord							MaxCoord							Bias?	MinLod	MaxLod	Offset?	Offset				Format					EvalFunc								Flags
   1787 		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),
   1788 		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),
   1789 		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),
   1790 		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),
   1791 
   1792 		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),
   1793 		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),
   1794 		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),
   1795 		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),
   1796 
   1797 		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),
   1798 		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),
   1799 		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),
   1800 		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),
   1801 
   1802 		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)
   1803 	};
   1804 	createCaseGroup(this, "textureprojlodoffset", "textureProjLodOffset() Tests", textureProjLodOffsetCases, DE_LENGTH_OF_ARRAY(textureProjLodOffsetCases));
   1805 
   1806 	// textureGrad() cases
   1807 	// \note Only one of dudx, dudy, dvdx, dvdy is non-zero since spec allows approximating p from derivates by various methods.
   1808 	static const TexFuncCaseSpec textureGradCases[] =
   1809 	{
   1810 		//		  Name							Function				MinCoord							MaxCoord							MinDx						MaxDx						MinDy						MaxDy						Offset?	Offset		Format					EvalFunc				Flags
   1811 		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),
   1812 		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),
   1813 		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),
   1814 		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),
   1815 
   1816 		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),
   1817 		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),
   1818 		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),
   1819 		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),
   1820 
   1821 		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),
   1822 		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),
   1823 		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),
   1824 		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),
   1825 
   1826 		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),
   1827 		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),
   1828 		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),
   1829 		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),
   1830 		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),
   1831 		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),
   1832 
   1833 		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),
   1834 		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),
   1835 		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),
   1836 		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)
   1837 	};
   1838 	createCaseGroup(this, "texturegrad", "textureGrad() Tests", textureGradCases, DE_LENGTH_OF_ARRAY(textureGradCases));
   1839 
   1840 	// textureGradOffset() cases
   1841 	static const TexFuncCaseSpec textureGradOffsetCases[] =
   1842 	{
   1843 		//		  Name							Function				MinCoord							MaxCoord							MinDx						MaxDx						MinDy						MaxDy						Offset?	Offset				Format					EvalFunc							Flags
   1844 		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),
   1845 		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),
   1846 		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),
   1847 		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),
   1848 
   1849 		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),
   1850 		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),
   1851 		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),
   1852 		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),
   1853 
   1854 		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),
   1855 		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),
   1856 		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),
   1857 		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),
   1858 		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),
   1859 		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),
   1860 
   1861 		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),
   1862 		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),
   1863 		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),
   1864 		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)
   1865 	};
   1866 	createCaseGroup(this, "texturegradoffset", "textureGradOffset() Tests", textureGradOffsetCases, DE_LENGTH_OF_ARRAY(textureGradOffsetCases));
   1867 
   1868 	// textureProjGrad() cases
   1869 	static const TexFuncCaseSpec textureProjGradCases[] =
   1870 	{
   1871 		//		  Name							Function					MinCoord							MaxCoord							MinDx						MaxDx						MinDy						MaxDy						Offset?	Offset		Format					EvalFunc					Flags
   1872 		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),
   1873 		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),
   1874 		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),
   1875 		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),
   1876 
   1877 		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),
   1878 		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),
   1879 		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),
   1880 		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),
   1881 
   1882 		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),
   1883 		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),
   1884 		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),
   1885 		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),
   1886 		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),
   1887 		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),
   1888 
   1889 		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),
   1890 		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)
   1891 	};
   1892 	createCaseGroup(this, "textureprojgrad", "textureProjGrad() Tests", textureProjGradCases, DE_LENGTH_OF_ARRAY(textureProjGradCases));
   1893 
   1894 	// textureProjGradOffset() cases
   1895 	static const TexFuncCaseSpec textureProjGradOffsetCases[] =
   1896 	{
   1897 		//		  Name							Function					MinCoord							MaxCoord							MinDx						MaxDx						MinDy						MaxDy						Offset?	Offset				Format					EvalFunc							Flags
   1898 		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),
   1899 		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),
   1900 		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),
   1901 		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),
   1902 
   1903 		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),
   1904 		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),
   1905 		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),
   1906 		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),
   1907 
   1908 		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),
   1909 		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),
   1910 		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),
   1911 		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),
   1912 		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),
   1913 		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),
   1914 
   1915 		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),
   1916 		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)
   1917 	};
   1918 	createCaseGroup(this, "textureprojgradoffset", "textureProjGradOffset() Tests", textureProjGradOffsetCases, DE_LENGTH_OF_ARRAY(textureProjGradOffsetCases));
   1919 
   1920 	// texelFetch() cases
   1921 	// \note Level is constant across quad
   1922 	static const TexFuncCaseSpec texelFetchCases[] =
   1923 	{
   1924 		//		  Name							Function				MinCoord							MaxCoord						Bias?	MinLod	MaxLod	Offset?	Offset		Format						EvalFunc				Flags
   1925 		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),
   1926 		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),
   1927 		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),
   1928 		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),
   1929 
   1930 		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),
   1931 		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),
   1932 		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),
   1933 		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),
   1934 
   1935 		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),
   1936 		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),
   1937 		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),
   1938 		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)
   1939 	};
   1940 	createCaseGroup(this, "texelfetch", "texelFetch() Tests", texelFetchCases, DE_LENGTH_OF_ARRAY(texelFetchCases));
   1941 
   1942 	// texelFetchOffset() cases
   1943 	static const TexFuncCaseSpec texelFetchOffsetCases[] =
   1944 	{
   1945 		//		  Name							Function				MinCoord							MaxCoord						Bias?	MinLod	MaxLod	Offset?	Offset		Format						EvalFunc				Flags
   1946 		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),
   1947 		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),
   1948 		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),
   1949 		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),
   1950 
   1951 		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),
   1952 		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),
   1953 		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),
   1954 		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),
   1955 
   1956 		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),
   1957 		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),
   1958 		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),
   1959 		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)
   1960 	};
   1961 	createCaseGroup(this, "texelfetchoffset", "texelFetchOffset() Tests", texelFetchOffsetCases, DE_LENGTH_OF_ARRAY(texelFetchOffsetCases));
   1962 
   1963 	// textureSize() cases
   1964 	{
   1965 		struct TextureSizeCaseSpec
   1966 		{
   1967 			const char* name;
   1968 			const char* samplerName;
   1969 			TextureSpec textureSpec;
   1970 		} textureSizeCases[] =
   1971 		{
   1972 			{ "sampler2d_fixed",			"sampler2D",				tex2DFixed			},
   1973 			{ "sampler2d_float",			"sampler2D",				tex2DFloat			},
   1974 			{ "isampler2d",					"isampler2D",				tex2DInt			},
   1975 			{ "usampler2d",					"usampler2D",				tex2DUint			},
   1976 			{ "sampler2dshadow",			"sampler2DShadow",			tex2DShadow			},
   1977 			{ "sampler3d_fixed",			"sampler3D",				tex3DFixed			},
   1978 			{ "sampler3d_float",			"sampler3D",				tex3DFloat			},
   1979 			{ "isampler3d",					"isampler3D",				tex3DInt			},
   1980 			{ "usampler3d",					"usampler3D",				tex3DUint			},
   1981 			{ "samplercube_fixed",			"samplerCube",				texCubeFixed		},
   1982 			{ "samplercube_float",			"samplerCube",				texCubeFloat		},
   1983 			{ "isamplercube",				"isamplerCube",				texCubeInt			},
   1984 			{ "usamplercube",				"usamplerCube",				texCubeUint			},
   1985 			{ "samplercubeshadow",			"samplerCubeShadow",		texCubeShadow		},
   1986 			{ "sampler2darray_fixed",		"sampler2DArray",			tex2DArrayFixed		},
   1987 			{ "sampler2darray_float",		"sampler2DArray",			tex2DArrayFloat		},
   1988 			{ "isampler2darray",			"isampler2DArray",			tex2DArrayInt		},
   1989 			{ "usampler2darray",			"usampler2DArray",			tex2DArrayUint		},
   1990 			{ "sampler2darrayshadow",		"sampler2DArrayShadow",		tex2DArrayShadow	},
   1991 		};
   1992 
   1993 		tcu::TestCaseGroup* group = new tcu::TestCaseGroup(m_testCtx, "texturesize", "textureSize() Tests");
   1994 		addChild(group);
   1995 
   1996 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(textureSizeCases); ++ndx)
   1997 		{
   1998 			group->addChild(new TextureSizeCase(m_context, (std::string(textureSizeCases[ndx].name) + "_vertex").c_str(),   "", textureSizeCases[ndx].samplerName, textureSizeCases[ndx].textureSpec, true));
   1999 			group->addChild(new TextureSizeCase(m_context, (std::string(textureSizeCases[ndx].name) + "_fragment").c_str(), "", textureSizeCases[ndx].samplerName, textureSizeCases[ndx].textureSpec, false));
   2000 		}
   2001 	}
   2002 
   2003 	// Negative cases.
   2004 	{
   2005 		gls::ShaderLibrary library(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo());
   2006 		std::vector<tcu::TestNode*> negativeCases = library.loadShaderFile("shaders/invalid_texture_functions.test");
   2007 
   2008 		tcu::TestCaseGroup* group = new tcu::TestCaseGroup(m_testCtx, "invalid", "Invalid texture function usage", negativeCases);
   2009 		addChild(group);
   2010 	}
   2011 }
   2012 
   2013 } // Functional
   2014 } // gles3
   2015 } // deqp
   2016