Fix issues in pipeline.timestamp.transfer_tests am: 0f672f2a20
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / shaderrender / vktShaderRenderTextureFunctionTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2016 The Khronos Group Inc.
6  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
7  * Copyright (c) 2016 The Android Open Source Project
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Texture access and query function tests.
24  *//*--------------------------------------------------------------------*/
25
26 #include "vktShaderRenderTextureFunctionTests.hpp"
27 #include "vktShaderRender.hpp"
28 #include "gluTextureUtil.hpp"
29 #include "tcuTexture.hpp"
30 #include "tcuTextureUtil.hpp"
31 #include "tcuTestLog.hpp"
32 #include "glwEnums.hpp"
33 #include "deMath.h"
34 #include "vkImageUtil.hpp"
35 #include "vkQueryUtil.hpp"
36
37 namespace vkt
38 {
39 namespace sr
40 {
41 namespace
42 {
43
44 using tcu::Vec2;
45 using tcu::Vec3;
46 using tcu::Vec4;
47 using tcu::IVec2;
48 using tcu::IVec3;
49 using tcu::IVec4;
50
51 using std::vector;
52
53 enum Function
54 {
55         FUNCTION_TEXTURE = 0,           //!< texture(), textureOffset()
56         FUNCTION_TEXTUREPROJ,           //!< textureProj(), textureProjOffset()
57         FUNCTION_TEXTUREPROJ3,          //!< textureProj(sampler2D, vec3)
58         FUNCTION_TEXTURELOD,            // ...
59         FUNCTION_TEXTUREPROJLOD,
60         FUNCTION_TEXTUREPROJLOD3,       //!< textureProjLod(sampler2D, vec3)
61         FUNCTION_TEXTUREGRAD,
62         FUNCTION_TEXTUREPROJGRAD,
63         FUNCTION_TEXTUREPROJGRAD3,      //!< textureProjGrad(sampler2D, vec3)
64         FUNCTION_TEXELFETCH,
65
66         FUNCTION_LAST
67 };
68
69 inline bool functionHasAutoLod (glu::ShaderType shaderType, Function function)
70 {
71         return shaderType == glu::SHADERTYPE_FRAGMENT &&
72                    (function == FUNCTION_TEXTURE                ||
73                         function == FUNCTION_TEXTUREPROJ        ||
74                         function == FUNCTION_TEXTUREPROJ3);
75 }
76
77 inline bool functionHasProj (Function function)
78 {
79         return function == FUNCTION_TEXTUREPROJ         ||
80                    function == FUNCTION_TEXTUREPROJ3    ||
81                    function == FUNCTION_TEXTUREPROJLOD  ||
82                    function == FUNCTION_TEXTUREPROJGRAD ||
83                    function == FUNCTION_TEXTUREPROJLOD3 ||
84                    function == FUNCTION_TEXTUREPROJGRAD3;
85 }
86
87 inline bool functionHasGrad (Function function)
88 {
89         return function == FUNCTION_TEXTUREGRAD || function == FUNCTION_TEXTUREPROJGRAD || function == FUNCTION_TEXTUREPROJGRAD3;
90 }
91
92 inline bool functionHasLod (Function function)
93 {
94         return function == FUNCTION_TEXTURELOD          ||
95                    function == FUNCTION_TEXTUREPROJLOD  ||
96                    function == FUNCTION_TEXTUREPROJLOD3 ||
97                    function == FUNCTION_TEXELFETCH;
98 }
99
100 struct TextureLookupSpec
101 {
102         Function                function;
103
104         tcu::Vec4               minCoord;
105         tcu::Vec4               maxCoord;
106
107         // Bias
108         bool                    useBias;
109
110         // Bias or Lod for *Lod* functions
111         float                   minLodBias;
112         float                   maxLodBias;
113
114         // For *Grad* functions
115         tcu::Vec3               minDX;
116         tcu::Vec3               maxDX;
117         tcu::Vec3               minDY;
118         tcu::Vec3               maxDY;
119
120         bool                    useOffset;
121         tcu::IVec3              offset;
122
123         TextureLookupSpec (void)
124                 : function              (FUNCTION_LAST)
125                 , minCoord              (0.0f)
126                 , maxCoord              (1.0f)
127                 , useBias               (false)
128                 , minLodBias    (0.0f)
129                 , maxLodBias    (0.0f)
130                 , minDX                 (0.0f)
131                 , maxDX                 (0.0f)
132                 , minDY                 (0.0f)
133                 , maxDY                 (0.0f)
134                 , useOffset             (false)
135                 , offset                (0)
136         {
137         }
138
139         TextureLookupSpec (Function                             function_,
140                                            const tcu::Vec4&             minCoord_,
141                                            const tcu::Vec4&             maxCoord_,
142                                            bool                                 useBias_,
143                                            float                                minLodBias_,
144                                            float                                maxLodBias_,
145                                            const tcu::Vec3&             minDX_,
146                                            const tcu::Vec3&             maxDX_,
147                                            const tcu::Vec3&             minDY_,
148                                            const tcu::Vec3&             maxDY_,
149                                            bool                                 useOffset_,
150                                            const tcu::IVec3&    offset_)
151                 : function              (function_)
152                 , minCoord              (minCoord_)
153                 , maxCoord              (maxCoord_)
154                 , useBias               (useBias_)
155                 , minLodBias    (minLodBias_)
156                 , maxLodBias    (maxLodBias_)
157                 , minDX                 (minDX_)
158                 , maxDX                 (maxDX_)
159                 , minDY                 (minDY_)
160                 , maxDY                 (maxDY_)
161                 , useOffset             (useOffset_)
162                 , offset                (offset_)
163         {
164         }
165 };
166
167 enum TextureType
168 {
169         TEXTURETYPE_1D = 0,
170         TEXTURETYPE_2D,
171         TEXTURETYPE_3D,
172         TEXTURETYPE_CUBE_MAP,
173         TEXTURETYPE_1D_ARRAY,
174         TEXTURETYPE_2D_ARRAY,
175         TEXTURETYPE_CUBE_ARRAY,
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 // \note LodMode and computeLodFromDerivates functions are copied from glsTextureTestUtil
235 namespace TextureTestUtil
236 {
237
238 enum LodMode
239 {
240         LODMODE_EXACT = 0,              //!< Ideal lod computation.
241         LODMODE_MIN_BOUND,              //!< Use estimation range minimum bound.
242         LODMODE_MAX_BOUND,              //!< Use estimation range maximum bound.
243
244         LODMODE_LAST
245 };
246
247 // 1D lookup LOD computation.
248
249 float computeLodFromDerivates (LodMode mode, float dudx, float dudy)
250 {
251         float p = 0.0f;
252         switch (mode)
253         {
254                 // \note [mika] Min and max bounds equal to exact with 1D textures
255                 case LODMODE_EXACT:
256                 case LODMODE_MIN_BOUND:
257                 case LODMODE_MAX_BOUND:
258                         p = de::max(deFloatAbs(dudx), deFloatAbs(dudy));
259                         break;
260
261                 default:
262                         DE_ASSERT(DE_FALSE);
263         }
264
265         return deFloatLog2(p);
266 }
267
268 // 2D lookup LOD computation.
269
270 float computeLodFromDerivates (LodMode mode, float dudx, float dvdx, float dudy, float dvdy)
271 {
272         float p = 0.0f;
273         switch (mode)
274         {
275                 case LODMODE_EXACT:
276                         p = de::max(deFloatSqrt(dudx*dudx + dvdx*dvdx), deFloatSqrt(dudy*dudy + dvdy*dvdy));
277                         break;
278
279                 case LODMODE_MIN_BOUND:
280                 case LODMODE_MAX_BOUND:
281                 {
282                         float mu = de::max(deFloatAbs(dudx), deFloatAbs(dudy));
283                         float mv = de::max(deFloatAbs(dvdx), deFloatAbs(dvdy));
284
285                         p = mode == LODMODE_MIN_BOUND ? de::max(mu, mv) : mu + mv;
286                         break;
287                 }
288
289                 default:
290                         DE_ASSERT(DE_FALSE);
291         }
292
293         return deFloatLog2(p);
294 }
295
296 // 3D lookup LOD computation.
297
298 float computeLodFromDerivates (LodMode mode, float dudx, float dvdx, float dwdx, float dudy, float dvdy, float dwdy)
299 {
300         float p = 0.0f;
301         switch (mode)
302         {
303                 case LODMODE_EXACT:
304                         p = de::max(deFloatSqrt(dudx*dudx + dvdx*dvdx + dwdx*dwdx), deFloatSqrt(dudy*dudy + dvdy*dvdy + dwdy*dwdy));
305                         break;
306
307                 case LODMODE_MIN_BOUND:
308                 case LODMODE_MAX_BOUND:
309                 {
310                         float mu = de::max(deFloatAbs(dudx), deFloatAbs(dudy));
311                         float mv = de::max(deFloatAbs(dvdx), deFloatAbs(dvdy));
312                         float mw = de::max(deFloatAbs(dwdx), deFloatAbs(dwdy));
313
314                         p = mode == LODMODE_MIN_BOUND ? de::max(de::max(mu, mv), mw) : (mu + mv + mw);
315                         break;
316                 }
317
318                 default:
319                         DE_ASSERT(DE_FALSE);
320         }
321
322         return deFloatLog2(p);
323 }
324
325 } // TextureTestUtil
326
327 using namespace TextureTestUtil;
328
329 static const LodMode DEFAULT_LOD_MODE = LODMODE_EXACT;
330
331 inline float computeLodFromGrad2D (const ShaderEvalContext& c)
332 {
333         float w = (float)c.textures[0].tex2D->getWidth();
334         float h = (float)c.textures[0].tex2D->getHeight();
335         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);
336 }
337
338 inline float computeLodFromGrad2DArray (const ShaderEvalContext& c)
339 {
340         float w = (float)c.textures[0].tex2DArray->getWidth();
341         float h = (float)c.textures[0].tex2DArray->getHeight();
342         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);
343 }
344
345 inline float computeLodFromGrad3D (const ShaderEvalContext& c)
346 {
347         float w = (float)c.textures[0].tex3D->getWidth();
348         float h = (float)c.textures[0].tex3D->getHeight();
349         float d = (float)c.textures[0].tex3D->getDepth();
350         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);
351 }
352
353 inline float computeLodFromGradCube (const ShaderEvalContext& c)
354 {
355         // \note Major axis is always -Z or +Z
356         float m = de::abs(c.in[0].z());
357         float d = (float)c.textures[0].texCube->getSize();
358         float s = d/(2.0f*m);
359         float t = d/(2.0f*m);
360         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);
361 }
362
363 typedef void (*TexEvalFunc) (ShaderEvalContext& c, const TexLookupParams& lookupParams);
364
365 inline Vec4 texture2D           (const ShaderEvalContext& c, float s, float t, float lod)                       { return c.textures[0].tex2D->sample(c.textures[0].sampler, s, t, lod);                 }
366 inline Vec4 textureCube         (const ShaderEvalContext& c, float s, float t, float r, float lod)      { return c.textures[0].texCube->sample(c.textures[0].sampler, s, t, r, lod);    }
367 inline Vec4 texture2DArray      (const ShaderEvalContext& c, float s, float t, float r, float lod)      { return c.textures[0].tex2DArray->sample(c.textures[0].sampler, s, t, r, lod); }
368 inline Vec4 texture3D           (const ShaderEvalContext& c, float s, float t, float r, float lod)      { return c.textures[0].tex3D->sample(c.textures[0].sampler, s, t, r, lod);              }
369
370 inline float texture2DShadow            (const ShaderEvalContext& c, float ref, float s, float t, float lod) { return c.textures[0].tex2D->sampleCompare(c.textures[0].sampler, ref, s, t, lod); }
371 inline float textureCubeShadow          (const ShaderEvalContext& c, float ref, float s, float t, float r, float lod) { return c.textures[0].texCube->sampleCompare(c.textures[0].sampler, ref, s, t, r, lod); }
372 inline float texture2DArrayShadow       (const ShaderEvalContext& c, float ref, float s, float t, float r, float lod) { return c.textures[0].tex2DArray->sampleCompare(c.textures[0].sampler, ref, s, t, r, lod); }
373
374 inline Vec4 texture2DOffset                     (const ShaderEvalContext& c, float s, float t, float lod, IVec2 offset)                 { return c.textures[0].tex2D->sampleOffset(c.textures[0].sampler, s, t, lod, offset);                   }
375 inline Vec4 texture2DArrayOffset        (const ShaderEvalContext& c, float s, float t, float r, float lod, IVec2 offset)        { return c.textures[0].tex2DArray->sampleOffset(c.textures[0].sampler, s, t, r, lod, offset);   }
376 inline Vec4 texture3DOffset                     (const ShaderEvalContext& c, float s, float t, float r, float lod, IVec3 offset)        { return c.textures[0].tex3D->sampleOffset(c.textures[0].sampler, s, t, r, lod, offset);                }
377
378 inline float texture2DShadowOffset              (const ShaderEvalContext& c, float ref, float s, float t, float lod, IVec2 offset)      { return c.textures[0].tex2D->sampleCompareOffset(c.textures[0].sampler, ref, s, t, lod, offset); }
379 inline float texture2DArrayShadowOffset (const ShaderEvalContext& c, float ref, float s, float t, float r, float lod, IVec2 offset) { return c.textures[0].tex2DArray->sampleCompareOffset(c.textures[0].sampler, ref, s, t, r, lod, offset); }
380
381 // Eval functions.
382 static void             evalTexture2D                   (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture2D(c, c.in[0].x(), c.in[0].y(), p.lod)*p.scale + p.bias; }
383 static void             evalTextureCube                 (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = textureCube(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod)*p.scale + p.bias; }
384 static void             evalTexture2DArray              (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture2DArray(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod)*p.scale + p.bias; }
385 static void             evalTexture3D                   (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture3D(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod)*p.scale + p.bias; }
386
387 static void             evalTexture2DBias               (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture2D(c, c.in[0].x(), c.in[0].y(), p.lod+c.in[1].x())*p.scale + p.bias; }
388 static void             evalTextureCubeBias             (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = textureCube(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod+c.in[1].x())*p.scale + p.bias; }
389 static void             evalTexture2DArrayBias  (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture2DArray(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod+c.in[1].x())*p.scale + p.bias; }
390 static void             evalTexture3DBias               (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture3D(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod+c.in[1].x())*p.scale + p.bias; }
391
392 static void             evalTexture2DProj3              (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture2D(c, c.in[0].x()/c.in[0].z(), c.in[0].y()/c.in[0].z(), p.lod)*p.scale + p.bias; }
393 static void             evalTexture2DProj3Bias  (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture2D(c, c.in[0].x()/c.in[0].z(), c.in[0].y()/c.in[0].z(), p.lod+c.in[1].x())*p.scale + p.bias; }
394 static void             evalTexture2DProj               (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture2D(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), p.lod)*p.scale + p.bias; }
395 static void             evalTexture2DProjBias   (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture2D(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), p.lod+c.in[1].x())*p.scale + p.bias; }
396 static void             evalTexture3DProj               (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture3D(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), c.in[0].z()/c.in[0].w(), p.lod)*p.scale + p.bias; }
397 static void             evalTexture3DProjBias   (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture3D(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), c.in[0].z()/c.in[0].w(), p.lod+c.in[1].x())*p.scale + p.bias; }
398
399 static void             evalTexture2DLod                (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture2D(c, c.in[0].x(), c.in[0].y(), c.in[1].x())*p.scale + p.bias; }
400 static void             evalTextureCubeLod              (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = textureCube(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), c.in[1].x())*p.scale + p.bias; }
401 static void             evalTexture2DArrayLod   (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture2DArray(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), c.in[1].x())*p.scale + p.bias; }
402 static void             evalTexture3DLod                (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture3D(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), c.in[1].x())*p.scale + p.bias; }
403
404 static void             evalTexture2DProjLod3   (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture2D(c, c.in[0].x()/c.in[0].z(), c.in[0].y()/c.in[0].z(), c.in[1].x())*p.scale + p.bias; }
405 static void             evalTexture2DProjLod    (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture2D(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), c.in[1].x())*p.scale + p.bias; }
406 static void             evalTexture3DProjLod    (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture3D(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), c.in[0].z()/c.in[0].w(), c.in[1].x())*p.scale + p.bias; }
407
408 // Offset variants
409
410 static void             evalTexture2DOffset                             (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture2DOffset(c, c.in[0].x(), c.in[0].y(), p.lod, p.offset.swizzle(0,1))*p.scale + p.bias; }
411 static void             evalTexture2DArrayOffset                (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture2DArrayOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod, p.offset.swizzle(0,1))*p.scale + p.bias; }
412 static void             evalTexture3DOffset                             (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture3DOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod, p.offset)*p.scale + p.bias; }
413
414 static void             evalTexture2DOffsetBias                 (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture2DOffset(c, c.in[0].x(), c.in[0].y(), p.lod+c.in[1].x(), p.offset.swizzle(0,1))*p.scale + p.bias; }
415 static void             evalTexture2DArrayOffsetBias    (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture2DArrayOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod+c.in[1].x(), p.offset.swizzle(0,1))*p.scale + p.bias; }
416 static void             evalTexture3DOffsetBias                 (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture3DOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod+c.in[1].x(), p.offset)*p.scale + p.bias; }
417
418 static void             evalTexture2DLodOffset                  (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture2DOffset(c, c.in[0].x(), c.in[0].y(), c.in[1].x(), p.offset.swizzle(0,1))*p.scale + p.bias; }
419 static void             evalTexture2DArrayLodOffset             (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture2DArrayOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), c.in[1].x(), p.offset.swizzle(0,1))*p.scale + p.bias; }
420 static void             evalTexture3DLodOffset                  (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture3DOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), c.in[1].x(), p.offset)*p.scale + p.bias; }
421
422 static void             evalTexture2DProj3Offset                (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture2DOffset(c, c.in[0].x()/c.in[0].z(), c.in[0].y()/c.in[0].z(), p.lod, p.offset.swizzle(0,1))*p.scale + p.bias; }
423 static void             evalTexture2DProj3OffsetBias    (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture2DOffset(c, c.in[0].x()/c.in[0].z(), c.in[0].y()/c.in[0].z(), p.lod+c.in[1].x(), p.offset.swizzle(0,1))*p.scale + p.bias; }
424 static void             evalTexture2DProjOffset                 (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture2DOffset(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), p.lod, p.offset.swizzle(0,1))*p.scale + p.bias; }
425 static void             evalTexture2DProjOffsetBias             (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture2DOffset(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), p.lod+c.in[1].x(), p.offset.swizzle(0,1))*p.scale + p.bias; }
426 static void             evalTexture3DProjOffset                 (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture3DOffset(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), c.in[0].z()/c.in[0].w(), p.lod, p.offset)*p.scale + p.bias; }
427 static void             evalTexture3DProjOffsetBias             (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture3DOffset(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), c.in[0].z()/c.in[0].w(), p.lod+c.in[1].x(), p.offset)*p.scale + p.bias; }
428
429 static void             evalTexture2DProjLod3Offset             (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture2DOffset(c, c.in[0].x()/c.in[0].z(), c.in[0].y()/c.in[0].z(), c.in[1].x(), p.offset.swizzle(0,1))*p.scale + p.bias; }
430 static void             evalTexture2DProjLodOffset              (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture2DOffset(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), c.in[1].x(), p.offset.swizzle(0,1))*p.scale + p.bias; }
431 static void             evalTexture3DProjLodOffset              (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture3DOffset(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), c.in[0].z()/c.in[0].w(), c.in[1].x(), p.offset)*p.scale + p.bias; }
432
433 // Shadow variants
434
435 static void             evalTexture2DShadow                             (ShaderEvalContext& c, const TexLookupParams& p)        { c.color.x() = texture2DShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), p.lod); }
436 static void             evalTexture2DShadowBias                 (ShaderEvalContext& c, const TexLookupParams& p)        { c.color.x() = texture2DShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), p.lod+c.in[1].x()); }
437
438 static void             evalTextureCubeShadow                   (ShaderEvalContext& c, const TexLookupParams& p)        { c.color.x() = textureCubeShadow(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod); }
439 static void             evalTextureCubeShadowBias               (ShaderEvalContext& c, const TexLookupParams& p)        { c.color.x() = textureCubeShadow(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod+c.in[1].x()); }
440
441 static void             evalTexture2DArrayShadow                (ShaderEvalContext& c, const TexLookupParams& p)        { c.color.x() = texture2DArrayShadow(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod); }
442
443 static void             evalTexture2DShadowLod                  (ShaderEvalContext& c, const TexLookupParams&)          { c.color.x() = texture2DShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), c.in[1].x()); }
444 static void             evalTexture2DShadowLodOffset    (ShaderEvalContext& c, const TexLookupParams& p)        { c.color.x() = texture2DShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), c.in[1].x(), p.offset.swizzle(0,1)); }
445
446 static void             evalTexture2DShadowProj                 (ShaderEvalContext& c, const TexLookupParams& p)        { c.color.x() = texture2DShadow(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), p.lod); }
447 static void             evalTexture2DShadowProjBias             (ShaderEvalContext& c, const TexLookupParams& p)        { c.color.x() = texture2DShadow(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), p.lod+c.in[1].x()); }
448
449 static void             evalTexture2DShadowProjLod              (ShaderEvalContext& c, const TexLookupParams&)          { c.color.x() = texture2DShadow(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), c.in[1].x()); }
450 static void             evalTexture2DShadowProjLodOffset(ShaderEvalContext& c, const TexLookupParams& p)        { c.color.x() = texture2DShadowOffset(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), c.in[1].x(), p.offset.swizzle(0,1)); }
451
452 static void             evalTexture2DShadowOffset               (ShaderEvalContext& c, const TexLookupParams& p)        { c.color.x() = texture2DShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), p.lod, p.offset.swizzle(0,1)); }
453 static void             evalTexture2DShadowOffsetBias   (ShaderEvalContext& c, const TexLookupParams& p)        { c.color.x() = texture2DShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), p.lod+c.in[1].x(), p.offset.swizzle(0,1)); }
454
455 static void             evalTexture2DShadowProjOffset           (ShaderEvalContext& c, const TexLookupParams& p)        { c.color.x() = texture2DShadowOffset(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), p.lod, p.offset.swizzle(0,1)); }
456 static void             evalTexture2DShadowProjOffsetBias       (ShaderEvalContext& c, const TexLookupParams& p)        { c.color.x() = texture2DShadowOffset(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), p.lod+c.in[1].x(), p.offset.swizzle(0,1)); }
457
458 // Gradient variarts
459
460 static void             evalTexture2DGrad               (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture2D(c, c.in[0].x(), c.in[0].y(), computeLodFromGrad2D(c))*p.scale + p.bias; }
461 static void             evalTextureCubeGrad             (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = textureCube(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), computeLodFromGradCube(c))*p.scale + p.bias; }
462 static void             evalTexture2DArrayGrad  (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture2DArray(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), computeLodFromGrad2DArray(c))*p.scale + p.bias; }
463 static void             evalTexture3DGrad               (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture3D(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), computeLodFromGrad3D(c))*p.scale + p.bias; }
464
465 static void             evalTexture2DShadowGrad                 (ShaderEvalContext& c, const TexLookupParams&)          { c.color.x() = texture2DShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), computeLodFromGrad2D(c)); }
466 static void             evalTextureCubeShadowGrad               (ShaderEvalContext& c, const TexLookupParams&)          { c.color.x() = textureCubeShadow(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(), computeLodFromGradCube(c)); }
467 static void             evalTexture2DArrayShadowGrad    (ShaderEvalContext& c, const TexLookupParams&)          { c.color.x() = texture2DArrayShadow(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(), computeLodFromGrad2DArray(c)); }
468
469 static void             evalTexture2DGradOffset                 (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture2DOffset(c, c.in[0].x(), c.in[0].y(), computeLodFromGrad2D(c), p.offset.swizzle(0,1))*p.scale + p.bias; }
470 static void             evalTexture2DArrayGradOffset    (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture2DArrayOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), computeLodFromGrad2DArray(c), p.offset.swizzle(0,1))*p.scale + p.bias; }
471 static void             evalTexture3DGradOffset                 (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture3DOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), computeLodFromGrad3D(c), p.offset)*p.scale + p.bias; }
472
473 static void             evalTexture2DShadowGradOffset           (ShaderEvalContext& c, const TexLookupParams& p)        { c.color.x() = texture2DShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), computeLodFromGrad2D(c), p.offset.swizzle(0,1)); }
474 static void             evalTexture2DArrayShadowGradOffset      (ShaderEvalContext& c, const TexLookupParams& p)        { c.color.x() = texture2DArrayShadowOffset(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(), computeLodFromGrad2DArray(c), p.offset.swizzle(0,1)); }
475
476 static void             evalTexture2DShadowProjGrad                     (ShaderEvalContext& c, const TexLookupParams&)          { c.color.x() = texture2DShadow(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), computeLodFromGrad2D(c)); }
477 static void             evalTexture2DShadowProjGradOffset       (ShaderEvalContext& c, const TexLookupParams& p)        { c.color.x() = texture2DShadowOffset(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), computeLodFromGrad2D(c), p.offset.swizzle(0,1)); }
478
479 static void             evalTexture2DProjGrad3                  (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture2D(c, c.in[0].x()/c.in[0].z(), c.in[0].y()/c.in[0].z(), computeLodFromGrad2D(c))*p.scale + p.bias; }
480 static void             evalTexture2DProjGrad                   (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture2D(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), computeLodFromGrad2D(c))*p.scale + p.bias; }
481 static void             evalTexture3DProjGrad                   (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture3D(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), c.in[0].z()/c.in[0].w(), computeLodFromGrad3D(c))*p.scale + p.bias; }
482
483 static void             evalTexture2DProjGrad3Offset    (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture2DOffset(c, c.in[0].x()/c.in[0].z(), c.in[0].y()/c.in[0].z(), computeLodFromGrad2D(c), p.offset.swizzle(0,1))*p.scale + p.bias; }
484 static void             evalTexture2DProjGradOffset             (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture2DOffset(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), computeLodFromGrad2D(c), p.offset.swizzle(0,1))*p.scale + p.bias; }
485 static void             evalTexture3DProjGradOffset             (ShaderEvalContext& c, const TexLookupParams& p)        { c.color = texture3DOffset(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), c.in[0].z()/c.in[0].w(), computeLodFromGrad3D(c), p.offset)*p.scale + p.bias; }
486
487 // Texel fetch variants
488
489 static void evalTexelFetch2D (ShaderEvalContext& c, const TexLookupParams& p)
490 {
491         int     x       = deChopFloatToInt32(c.in[0].x())+p.offset.x();
492         int     y       = deChopFloatToInt32(c.in[0].y())+p.offset.y();
493         int     lod = deChopFloatToInt32(c.in[1].x());
494         c.color = c.textures[0].tex2D->getLevel(lod).getPixel(x, y)*p.scale + p.bias;
495 }
496
497 static void evalTexelFetch2DArray (ShaderEvalContext& c, const TexLookupParams& p)
498 {
499         int     x       = deChopFloatToInt32(c.in[0].x())+p.offset.x();
500         int     y       = deChopFloatToInt32(c.in[0].y())+p.offset.y();
501         int     l       = deChopFloatToInt32(c.in[0].z());
502         int     lod = deChopFloatToInt32(c.in[1].x());
503         c.color = c.textures[0].tex2DArray->getLevel(lod).getPixel(x, y, l)*p.scale + p.bias;
504 }
505
506 static void evalTexelFetch3D (ShaderEvalContext& c, const TexLookupParams& p)
507 {
508         int     x       = deChopFloatToInt32(c.in[0].x())+p.offset.x();
509         int     y       = deChopFloatToInt32(c.in[0].y())+p.offset.y();
510         int     z       = deChopFloatToInt32(c.in[0].z())+p.offset.z();
511         int     lod = deChopFloatToInt32(c.in[1].x());
512         c.color = c.textures[0].tex3D->getLevel(lod).getPixel(x, y, z)*p.scale + p.bias;
513 }
514
515 class TexLookupEvaluator : public ShaderEvaluator
516 {
517 public:
518                                                         TexLookupEvaluator              (TexEvalFunc evalFunc, const TexLookupParams& lookupParams) : m_evalFunc(evalFunc), m_lookupParams(lookupParams) {}
519         virtual                                 ~TexLookupEvaluator             (void) {}
520
521         virtual void                    evaluate                                (ShaderEvalContext& ctx) const { m_evalFunc(ctx, m_lookupParams); }
522
523 private:
524         TexEvalFunc                             m_evalFunc;
525         const TexLookupParams&  m_lookupParams;
526 };
527
528 class ShaderTextureFunctionInstance : public ShaderRenderCaseInstance
529 {
530 public:
531                                                                 ShaderTextureFunctionInstance           (Context&                                       context,
532                                                                                                                                          const bool                                     isVertexCase,
533                                                                                                                                          const ShaderEvaluator&         evaluator,
534                                                                                                                                          const UniformSetup&            uniformSetup,
535                                                                                                                                          const TextureLookupSpec&       lookupSpec,
536                                                                                                                                          const TextureSpec&                     textureSpec,
537                                                                                                                                          const TexLookupParams&         lookupParams,
538                                                                                                                                          const ImageBackingMode         imageBackingMode = IMAGE_BACKING_MODE_REGULAR);
539         virtual                                         ~ShaderTextureFunctionInstance          (void);
540
541 protected:
542         virtual void                            setupUniforms                                           (const tcu::Vec4&);
543         void                                            initTexture                                                     (void);
544 private:
545         const TextureLookupSpec&        m_lookupSpec;
546         const TextureSpec&                      m_textureSpec;
547         const TexLookupParams&          m_lookupParams;
548 };
549
550 ShaderTextureFunctionInstance::ShaderTextureFunctionInstance (Context&                                          context,
551                                                                                                                           const bool                                    isVertexCase,
552                                                                                                                           const ShaderEvaluator&                evaluator,
553                                                                                                                           const UniformSetup&                   uniformSetup,
554                                                                                                                           const TextureLookupSpec&              lookupSpec,
555                                                                                                                           const TextureSpec&                    textureSpec,
556                                                                                                                           const TexLookupParams&                lookupParams,
557                                                                                                                           const ImageBackingMode                imageBackingMode)
558         : ShaderRenderCaseInstance      (context, isVertexCase, evaluator, uniformSetup, DE_NULL, imageBackingMode)
559         , m_lookupSpec                          (lookupSpec)
560         , m_textureSpec                         (textureSpec)
561         , m_lookupParams                        (lookupParams)
562 {
563         {
564                 // Base coord scale & bias
565                 Vec4 s = m_lookupSpec.maxCoord-m_lookupSpec.minCoord;
566                 Vec4 b = m_lookupSpec.minCoord;
567
568                 float baseCoordTrans[] =
569                 {
570                         s.x(),          0.0f,           0.f,    b.x(),
571                         0.f,            s.y(),          0.f,    b.y(),
572                         s.z()/2.f,      -s.z()/2.f,     0.f,    s.z()/2.f + b.z(),
573                         -s.w()/2.f,     s.w()/2.f,      0.f,    s.w()/2.f + b.w()
574                 };
575
576                 m_userAttribTransforms.push_back(tcu::Mat4(baseCoordTrans));
577
578                 useAttribute(4u, A_IN0);
579         }
580
581         bool hasLodBias = functionHasLod(m_lookupSpec.function) || m_lookupSpec.useBias;
582         bool isGrad             = functionHasGrad(m_lookupSpec.function);
583         DE_ASSERT(!isGrad || !hasLodBias);
584
585         if (hasLodBias)
586         {
587                 float s = m_lookupSpec.maxLodBias-m_lookupSpec.minLodBias;
588                 float b = m_lookupSpec.minLodBias;
589                 float lodCoordTrans[] =
590                 {
591                         s/2.0f,         s/2.0f,         0.f,    b,
592                         0.0f,           0.0f,           0.0f,   0.0f,
593                         0.0f,           0.0f,           0.0f,   0.0f,
594                         0.0f,           0.0f,           0.0f,   0.0f
595                 };
596
597                 m_userAttribTransforms.push_back(tcu::Mat4(lodCoordTrans));
598
599                 useAttribute(5u, A_IN1);
600         }
601         else if (isGrad)
602         {
603                 Vec3 sx = m_lookupSpec.maxDX-m_lookupSpec.minDX;
604                 Vec3 sy = m_lookupSpec.maxDY-m_lookupSpec.minDY;
605                 float gradDxTrans[] =
606                 {
607                         sx.x()/2.0f,    sx.x()/2.0f,    0.f,    m_lookupSpec.minDX.x(),
608                         sx.y()/2.0f,    sx.y()/2.0f,    0.0f,   m_lookupSpec.minDX.y(),
609                         sx.z()/2.0f,    sx.z()/2.0f,    0.0f,   m_lookupSpec.minDX.z(),
610                         0.0f,                   0.0f,                   0.0f,   0.0f
611                 };
612                 float gradDyTrans[] =
613                 {
614                         -sy.x()/2.0f,   -sy.x()/2.0f,   0.f,    m_lookupSpec.maxDY.x(),
615                         -sy.y()/2.0f,   -sy.y()/2.0f,   0.0f,   m_lookupSpec.maxDY.y(),
616                         -sy.z()/2.0f,   -sy.z()/2.0f,   0.0f,   m_lookupSpec.maxDY.z(),
617                         0.0f,                   0.0f,                   0.0f,   0.0f
618                 };
619
620                 m_userAttribTransforms.push_back(tcu::Mat4(gradDxTrans));
621                 m_userAttribTransforms.push_back(tcu::Mat4(gradDyTrans));
622
623                 useAttribute(5u, A_IN1);
624                 useAttribute(6u, A_IN2);
625         }
626
627         initTexture();
628 }
629
630 ShaderTextureFunctionInstance::~ShaderTextureFunctionInstance (void)
631 {
632 }
633
634 void ShaderTextureFunctionInstance::setupUniforms (const tcu::Vec4&)
635 {
636         useSampler(0u, 0u);
637         addUniform(1u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, sizeof(tcu::Vec4), m_lookupParams.scale.getPtr());
638         addUniform(2u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, sizeof(tcu::Vec4), m_lookupParams.bias.getPtr());
639 }
640
641 void ShaderTextureFunctionInstance::initTexture (void)
642 {
643         static const IVec4              texCubeSwz[] =
644         {
645                 IVec4(0,0,1,1),
646                 IVec4(1,1,0,0),
647                 IVec4(0,1,0,1),
648                 IVec4(1,0,1,0),
649                 IVec4(0,1,1,0),
650                 IVec4(1,0,0,1)
651         };
652         DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(texCubeSwz) == tcu::CUBEFACE_LAST);
653
654         tcu::TextureFormat              texFmt                  = glu::mapGLInternalFormat(m_textureSpec.format);
655         tcu::TextureFormatInfo  fmtInfo                 = tcu::getTextureFormatInfo(texFmt);
656         tcu::UVec2                              viewportSize    = getViewportSize();
657         bool                                    isProj                  = functionHasProj(m_lookupSpec.function);
658         bool                                    isAutoLod               = functionHasAutoLod(m_isVertexCase ? glu::SHADERTYPE_VERTEX : glu::SHADERTYPE_FRAGMENT,
659                                                                                                                                  m_lookupSpec.function); // LOD can vary significantly
660         float                                   proj                    = isProj ? 1.0f/m_lookupSpec.minCoord[m_lookupSpec.function == FUNCTION_TEXTUREPROJ3 ? 2 : 3] : 1.0f;
661         TexLookupParams                 lookupParams;
662
663         switch (m_textureSpec.type)
664         {
665                 case TEXTURETYPE_2D:
666                 {
667                         float                                                           levelStep               = isAutoLod ? 0.0f : 1.0f / (float)de::max(1, m_textureSpec.numLevels-1);
668                         Vec4                                                            cScale                  = fmtInfo.valueMax-fmtInfo.valueMin;
669                         Vec4                                                            cBias                   = fmtInfo.valueMin;
670                         int                                                                     baseCellSize    = de::min(m_textureSpec.width/4, m_textureSpec.height/4);
671                         de::MovePtr<tcu::Texture2D>                     texture2D;
672
673                         texture2D = de::MovePtr<tcu::Texture2D>(new tcu::Texture2D(texFmt, m_textureSpec.width, m_textureSpec.height));
674
675                         for (int level = 0; level < m_textureSpec.numLevels; level++)
676                         {
677                                 float   fA              = float(level)*levelStep;
678                                 float   fB              = 1.0f-fA;
679                                 Vec4    colorA  = cBias + cScale*Vec4(fA, fB, fA, fB);
680                                 Vec4    colorB  = cBias + cScale*Vec4(fB, fA, fB, fA);
681
682                                 texture2D->allocLevel(level);
683                                 tcu::fillWithGrid(texture2D->getLevel(level), de::max(1, baseCellSize>>level), colorA, colorB);
684                         }
685
686                         // Compute LOD.
687                         float   dudx    = (m_lookupSpec.maxCoord[0]-m_lookupSpec.minCoord[0])*proj*(float)m_textureSpec.width   / (float)viewportSize[0];
688                         float   dvdy    = (m_lookupSpec.maxCoord[1]-m_lookupSpec.minCoord[1])*proj*(float)m_textureSpec.height  / (float)viewportSize[1];
689                         lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f, 0.0f, dvdy);
690
691                         // Append to texture list.
692                         m_textures.push_back(TextureBindingSp(new TextureBinding(texture2D.release(), m_textureSpec.sampler)));
693                         break;
694                 }
695
696                 case TEXTURETYPE_CUBE_MAP:
697                 {
698                         float                                                           levelStep               = isAutoLod ? 0.0f : 1.0f / (float)de::max(1, m_textureSpec.numLevels-1);
699                         Vec4                                                            cScale                  = fmtInfo.valueMax-fmtInfo.valueMin;
700                         Vec4                                                            cBias                   = fmtInfo.valueMin;
701                         Vec4                                                            cCorner                 = cBias + cScale*0.5f;
702                         int                                                                     baseCellSize    = de::min(m_textureSpec.width/4, m_textureSpec.height/4);
703                         de::MovePtr<tcu::TextureCube>           textureCube;
704
705                         DE_ASSERT(m_textureSpec.width == m_textureSpec.height);
706                         textureCube = de::MovePtr<tcu::TextureCube>(new tcu::TextureCube(texFmt, m_textureSpec.width));
707
708                         for (int level = 0; level < m_textureSpec.numLevels; level++)
709                         {
710                                 float   fA              = float(level)*levelStep;
711                                 float   fB              = 1.0f-fA;
712                                 Vec2    f               (fA, fB);
713
714                                 for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
715                                 {
716                                         const IVec4&    swzA    = texCubeSwz[face];
717                                         IVec4                   swzB    = 1-swzA;
718                                         Vec4                    colorA  = cBias + cScale*f.swizzle(swzA[0], swzA[1], swzA[2], swzA[3]);
719                                         Vec4                    colorB  = cBias + cScale*f.swizzle(swzB[0], swzB[1], swzB[2], swzB[3]);
720
721                                         textureCube->allocLevel((tcu::CubeFace)face, level);
722
723                                         {
724                                                 const tcu::PixelBufferAccess    access          = textureCube->getLevelFace(level, (tcu::CubeFace)face);
725                                                 const int                                               lastPix         = access.getWidth()-1;
726
727                                                 tcu::fillWithGrid(access, de::max(1, baseCellSize>>level), colorA, colorB);
728
729                                                 // Ensure all corners have identical colors in order to avoid dealing with ambiguous corner texel filtering
730                                                 access.setPixel(cCorner, 0, 0);
731                                                 access.setPixel(cCorner, 0, lastPix);
732                                                 access.setPixel(cCorner, lastPix, 0);
733                                                 access.setPixel(cCorner, lastPix, lastPix);
734                                         }
735                                 }
736                         }
737
738                         // Compute LOD \note Assumes that only single side is accessed and R is constant major axis.
739                         DE_ASSERT(de::abs(m_lookupSpec.minCoord[2] - m_lookupSpec.maxCoord[2]) < 0.005);
740                         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]));
741                         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]));
742
743                         tcu::CubeFaceFloatCoords        c00             = tcu::getCubeFaceCoords(Vec3(m_lookupSpec.minCoord[0]*proj, m_lookupSpec.minCoord[1]*proj, m_lookupSpec.minCoord[2]*proj));
744                         tcu::CubeFaceFloatCoords        c10             = tcu::getCubeFaceCoords(Vec3(m_lookupSpec.maxCoord[0]*proj, m_lookupSpec.minCoord[1]*proj, m_lookupSpec.minCoord[2]*proj));
745                         tcu::CubeFaceFloatCoords        c01             = tcu::getCubeFaceCoords(Vec3(m_lookupSpec.minCoord[0]*proj, m_lookupSpec.maxCoord[1]*proj, m_lookupSpec.minCoord[2]*proj));
746                         float                                           dudx    = (c10.s - c00.s)*(float)m_textureSpec.width    / (float)viewportSize[0];
747                         float                                           dvdy    = (c01.t - c00.t)*(float)m_textureSpec.height   / (float)viewportSize[1];
748                         lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f, 0.0f, dvdy);
749
750                         // Append to texture list.
751                         m_textures.push_back(TextureBindingSp(new TextureBinding(textureCube.release(), m_textureSpec.sampler)));
752                         break;
753                 }
754
755                 case TEXTURETYPE_2D_ARRAY:
756                 {
757                         float                                                           layerStep               = 1.0f / (float)m_textureSpec.depth;
758                         float                                                           levelStep               = isAutoLod ? 0.0f : 1.0f / (float)(de::max(1, m_textureSpec.numLevels-1)*m_textureSpec.depth);
759                         Vec4                                                            cScale                  = fmtInfo.valueMax-fmtInfo.valueMin;
760                         Vec4                                                            cBias                   = fmtInfo.valueMin;
761                         int                                                                     baseCellSize    = de::min(m_textureSpec.width/4, m_textureSpec.height/4);
762                         de::MovePtr<tcu::Texture2DArray>        texture2DArray;
763
764                         texture2DArray = de::MovePtr<tcu::Texture2DArray>(new tcu::Texture2DArray(texFmt, m_textureSpec.width, m_textureSpec.height, m_textureSpec.depth));
765
766                         for (int level = 0; level < m_textureSpec.numLevels; level++)
767                         {
768                                 texture2DArray->allocLevel(level);
769                                 tcu::PixelBufferAccess levelAccess = texture2DArray->getLevel(level);
770
771                                 for (int layer = 0; layer < levelAccess.getDepth(); layer++)
772                                 {
773                                         float   fA              = (float)layer*layerStep + (float)level*levelStep;
774                                         float   fB              = 1.0f-fA;
775                                         Vec4    colorA  = cBias + cScale*Vec4(fA, fB, fA, fB);
776                                         Vec4    colorB  = cBias + cScale*Vec4(fB, fA, fB, fA);
777
778                                         tcu::fillWithGrid(tcu::getSubregion(levelAccess, 0, 0, layer, levelAccess.getWidth(), levelAccess.getHeight(), 1), de::max(1, baseCellSize>>level), colorA, colorB);
779                                 }
780                         }
781
782                         // Compute LOD.
783                         float   dudx    = (m_lookupSpec.maxCoord[0]-m_lookupSpec.minCoord[0])*proj*(float)m_textureSpec.width   / (float)viewportSize[0];
784                         float   dvdy    = (m_lookupSpec.maxCoord[1]-m_lookupSpec.minCoord[1])*proj*(float)m_textureSpec.height  / (float)viewportSize[1];
785                         lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f, 0.0f, dvdy);
786
787                         // Append to texture list.
788                         m_textures.push_back(TextureBindingSp(new TextureBinding(texture2DArray.release(), m_textureSpec.sampler)));
789                         break;
790                 }
791
792                 case TEXTURETYPE_3D:
793                 {
794                         float                                                           levelStep               = isAutoLod ? 0.0f : 1.0f / (float)de::max(1, m_textureSpec.numLevels-1);
795                         Vec4                                                            cScale                  = fmtInfo.valueMax-fmtInfo.valueMin;
796                         Vec4                                                            cBias                   = fmtInfo.valueMin;
797                         int                                                                     baseCellSize    = de::min(de::min(m_textureSpec.width/2, m_textureSpec.height/2), m_textureSpec.depth/2);
798                         de::MovePtr<tcu::Texture3D>                     texture3D;
799
800                         texture3D = de::MovePtr<tcu::Texture3D>(new tcu::Texture3D(texFmt, m_textureSpec.width, m_textureSpec.height, m_textureSpec.depth));
801
802                         for (int level = 0; level < m_textureSpec.numLevels; level++)
803                         {
804                                 float   fA              = (float)level*levelStep;
805                                 float   fB              = 1.0f-fA;
806                                 Vec4    colorA  = cBias + cScale*Vec4(fA, fB, fA, fB);
807                                 Vec4    colorB  = cBias + cScale*Vec4(fB, fA, fB, fA);
808
809                                 texture3D->allocLevel(level);
810                                 tcu::fillWithGrid(texture3D->getLevel(level), de::max(1, baseCellSize>>level), colorA, colorB);
811                         }
812
813                         // Compute LOD.
814                         float   dudx    = (m_lookupSpec.maxCoord[0]-m_lookupSpec.minCoord[0])*proj*(float)m_textureSpec.width           / (float)viewportSize[0];
815                         float   dvdy    = (m_lookupSpec.maxCoord[1]-m_lookupSpec.minCoord[1])*proj*(float)m_textureSpec.height          / (float)viewportSize[1];
816                         float   dwdx    = (m_lookupSpec.maxCoord[2]-m_lookupSpec.minCoord[2])*0.5f*proj*(float)m_textureSpec.depth      / (float)viewportSize[0];
817                         float   dwdy    = (m_lookupSpec.maxCoord[2]-m_lookupSpec.minCoord[2])*0.5f*proj*(float)m_textureSpec.depth      / (float)viewportSize[1];
818                         lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f, dwdx, 0.0f, dvdy, dwdy);
819
820                         // Append to texture list.
821                         m_textures.push_back(TextureBindingSp(new TextureBinding(texture3D.release(), m_textureSpec.sampler)));
822                         break;
823                 }
824
825                 default:
826                         DE_ASSERT(DE_FALSE);
827         }
828
829         // Set lookup scale & bias
830         lookupParams.scale              = fmtInfo.lookupScale;
831         lookupParams.bias               = fmtInfo.lookupBias;
832         lookupParams.offset             = m_lookupSpec.offset;
833
834         // \todo [dirnerakos] Avoid const cast somehow
835         const_cast<TexLookupParams&>(m_lookupParams) = lookupParams;
836 }
837
838 class ShaderTextureFunctionCase : public ShaderRenderCase
839 {
840 public:
841                                                                 ShaderTextureFunctionCase               (tcu::TestContext&                              testCtx,
842                                                                                                                                  const std::string&                             name,
843                                                                                                                                  const std::string&                             desc,
844                                                                                                                                  const TextureLookupSpec&               lookup,
845                                                                                                                                  const TextureSpec&                             texture,
846                                                                                                                                  TexEvalFunc                                    evalFunc,
847                                                                                                                                  bool                                                   isVertexCase);
848         virtual                                         ~ShaderTextureFunctionCase              (void);
849
850         virtual TestInstance*           createInstance                                  (Context& context) const;
851
852 protected:
853         const TextureLookupSpec         m_lookupSpec;
854         const TextureSpec                       m_textureSpec;
855         const TexLookupParams           m_lookupParams;
856
857         void                                            initShaderSources                               (void);
858 };
859
860 ShaderTextureFunctionCase::ShaderTextureFunctionCase (tcu::TestContext&                         testCtx,
861                                                                                                           const std::string&                    name,
862                                                                                                           const std::string&                    desc,
863                                                                                                           const TextureLookupSpec&              lookup,
864                                                                                                           const TextureSpec&                    texture,
865                                                                                                           TexEvalFunc                                   evalFunc,
866                                                                                                           bool                                                  isVertexCase)
867         : ShaderRenderCase              (testCtx, name, desc, isVertexCase, new TexLookupEvaluator(evalFunc, m_lookupParams), NULL, NULL)
868         , m_lookupSpec                  (lookup)
869         , m_textureSpec                 (texture)
870 {
871         initShaderSources();
872 }
873
874 ShaderTextureFunctionCase::~ShaderTextureFunctionCase (void)
875 {
876 }
877
878 TestInstance* ShaderTextureFunctionCase::createInstance (Context& context) const
879 {
880         DE_ASSERT(m_evaluator != DE_NULL);
881         DE_ASSERT(m_uniformSetup != DE_NULL);
882         return new ShaderTextureFunctionInstance(context, m_isVertexCase, *m_evaluator, *m_uniformSetup, m_lookupSpec, m_textureSpec, m_lookupParams);
883 }
884
885 void ShaderTextureFunctionCase::initShaderSources (void)
886 {
887         Function                        function                        = m_lookupSpec.function;
888         bool                            isVtxCase                       = m_isVertexCase;
889         bool                            isProj                          = functionHasProj(function);
890         bool                            isGrad                          = functionHasGrad(function);
891         bool                            isShadow                        = m_textureSpec.sampler.compare != tcu::Sampler::COMPAREMODE_NONE;
892         bool                            is2DProj4                       = !isShadow && m_textureSpec.type == TEXTURETYPE_2D && (function == FUNCTION_TEXTUREPROJ || function == FUNCTION_TEXTUREPROJLOD || function == FUNCTION_TEXTUREPROJGRAD);
893         bool                            isIntCoord                      = function == FUNCTION_TEXELFETCH;
894         bool                            hasLodBias                      = functionHasLod(m_lookupSpec.function) || m_lookupSpec.useBias;
895         int                                     texCoordComps           = m_textureSpec.type == TEXTURETYPE_2D ? 2 : 3;
896         int                                     extraCoordComps         = (isProj ? (is2DProj4 ? 2 : 1) : 0) + (isShadow ? 1 : 0);
897         glu::DataType           coordType                       = glu::getDataTypeFloatVec(texCoordComps+extraCoordComps);
898         glu::Precision          coordPrec                       = glu::PRECISION_HIGHP;
899         const char*                     coordTypeName           = glu::getDataTypeName(coordType);
900         const char*                     coordPrecName           = glu::getPrecisionName(coordPrec);
901         tcu::TextureFormat      texFmt                          = glu::mapGLInternalFormat(m_textureSpec.format);
902         glu::DataType           samplerType                     = glu::TYPE_LAST;
903         glu::DataType           gradType                        = (m_textureSpec.type == TEXTURETYPE_CUBE_MAP || m_textureSpec.type == TEXTURETYPE_3D) ? glu::TYPE_FLOAT_VEC3 : glu::TYPE_FLOAT_VEC2;
904         const char*                     gradTypeName            = glu::getDataTypeName(gradType);
905         const char*                     baseFuncName            = DE_NULL;
906
907         DE_ASSERT(!isGrad || !hasLodBias);
908
909         switch (m_textureSpec.type)
910         {
911                 case TEXTURETYPE_2D:            samplerType = isShadow ? glu::TYPE_SAMPLER_2D_SHADOW            : glu::getSampler2DType(texFmt);                break;
912                 case TEXTURETYPE_CUBE_MAP:      samplerType = isShadow ? glu::TYPE_SAMPLER_CUBE_SHADOW          : glu::getSamplerCubeType(texFmt);              break;
913                 case TEXTURETYPE_2D_ARRAY:      samplerType = isShadow ? glu::TYPE_SAMPLER_2D_ARRAY_SHADOW      : glu::getSampler2DArrayType(texFmt);   break;
914                 case TEXTURETYPE_3D:            DE_ASSERT(!isShadow); samplerType = glu::getSampler3DType(texFmt);                                                                      break;
915                 default:
916                         DE_ASSERT(DE_FALSE);
917         }
918
919         switch (m_lookupSpec.function)
920         {
921                 case FUNCTION_TEXTURE:                  baseFuncName = "texture";                       break;
922                 case FUNCTION_TEXTUREPROJ:              baseFuncName = "textureProj";           break;
923                 case FUNCTION_TEXTUREPROJ3:             baseFuncName = "textureProj";           break;
924                 case FUNCTION_TEXTURELOD:               baseFuncName = "textureLod";            break;
925                 case FUNCTION_TEXTUREPROJLOD:   baseFuncName = "textureProjLod";        break;
926                 case FUNCTION_TEXTUREPROJLOD3:  baseFuncName = "textureProjLod";        break;
927                 case FUNCTION_TEXTUREGRAD:              baseFuncName = "textureGrad";           break;
928                 case FUNCTION_TEXTUREPROJGRAD:  baseFuncName = "textureProjGrad";       break;
929                 case FUNCTION_TEXTUREPROJGRAD3: baseFuncName = "textureProjGrad";       break;
930                 case FUNCTION_TEXELFETCH:               baseFuncName = "texelFetch";            break;
931                 default:
932                         DE_ASSERT(DE_FALSE);
933         }
934
935         std::ostringstream      vert;
936         std::ostringstream      frag;
937         std::ostringstream&     op              = isVtxCase ? vert : frag;
938
939         vert << "#version 310 es\n"
940                  << "layout(location = 0) in highp vec4 a_position;\n"
941                  << "layout(location = 4) in " << coordPrecName << " " << coordTypeName << " a_in0;\n";
942
943         if (isGrad)
944         {
945                 vert << "layout(location = 5) in " << coordPrecName << " " << gradTypeName << " a_in1;\n";
946                 vert << "layout(location = 6) in " << coordPrecName << " " << gradTypeName << " a_in2;\n";
947         }
948         else if (hasLodBias)
949                 vert << "layout(location = 5) in " << coordPrecName << " float a_in1;\n";
950
951         frag << "#version 310 es\n"
952                  << "layout(location = 0) out mediump vec4 o_color;\n";
953
954         if (isVtxCase)
955         {
956                 vert << "layout(location = 0) out mediump vec4 v_color;\n";
957                 frag << "layout(location = 0) in mediump vec4 v_color;\n";
958         }
959         else
960         {
961                 vert << "layout(location = 0) out " << coordPrecName << " " << coordTypeName << " v_texCoord;\n";
962                 frag << "layout(location = 0) in " << coordPrecName << " " << coordTypeName << " v_texCoord;\n";
963
964                 if (isGrad)
965                 {
966                         vert << "layout(location = 1) out " << coordPrecName << " " << gradTypeName << " v_gradX;\n";
967                         vert << "layout(location = 2) out " << coordPrecName << " " << gradTypeName << " v_gradY;\n";
968                         frag << "layout(location = 1) in " << coordPrecName << " " << gradTypeName << " v_gradX;\n";
969                         frag << "layout(location = 2) in " << coordPrecName << " " << gradTypeName << " v_gradY;\n";
970                 }
971                 else if (hasLodBias)
972                 {
973                         vert << "layout(location = 1) out " << coordPrecName << " float v_lodBias;\n";
974                         frag << "layout(location = 1) in " << coordPrecName << " float v_lodBias;\n";
975                 }
976         }
977
978         // Uniforms
979         op << "layout(set = 0, binding = 0) uniform highp " << glu::getDataTypeName(samplerType) << " u_sampler;\n"
980            << "layout(set = 0, binding = 1) uniform buf0 { highp vec4 u_scale; };\n"
981            << "layout(set = 0, binding = 2) uniform buf1 { highp vec4 u_bias; };\n";
982
983         vert << "\nvoid main()\n{\n"
984                  << "\tgl_Position = a_position;\n";
985         frag << "\nvoid main()\n{\n";
986
987         if (isVtxCase)
988                 vert << "\tv_color = ";
989         else
990                 frag << "\to_color = ";
991
992         // Op.
993         {
994                 const char*     texCoord        = isVtxCase ? "a_in0" : "v_texCoord";
995                 const char* gradX               = isVtxCase ? "a_in1" : "v_gradX";
996                 const char* gradY               = isVtxCase ? "a_in2" : "v_gradY";
997                 const char*     lodBias         = isVtxCase ? "a_in1" : "v_lodBias";
998
999                 op << "vec4(" << baseFuncName;
1000                 if (m_lookupSpec.useOffset)
1001                         op << "Offset";
1002                 op << "(u_sampler, ";
1003
1004                 if (isIntCoord)
1005                         op << "ivec" << (texCoordComps+extraCoordComps) << "(";
1006
1007                 op << texCoord;
1008
1009                 if (isIntCoord)
1010                         op << ")";
1011
1012                 if (isGrad)
1013                         op << ", " << gradX << ", " << gradY;
1014
1015                 if (functionHasLod(function))
1016                 {
1017                         if (isIntCoord)
1018                                 op << ", int(" << lodBias << ")";
1019                         else
1020                                 op << ", " << lodBias;
1021                 }
1022
1023                 if (m_lookupSpec.useOffset)
1024                 {
1025                         int offsetComps = m_textureSpec.type == TEXTURETYPE_3D ? 3 : 2;
1026
1027                         op << ", ivec" << offsetComps << "(";
1028                         for (int ndx = 0; ndx < offsetComps; ndx++)
1029                         {
1030                                 if (ndx != 0)
1031                                         op << ", ";
1032                                 op << m_lookupSpec.offset[ndx];
1033                         }
1034                         op << ")";
1035                 }
1036
1037                 if (m_lookupSpec.useBias)
1038                         op << ", " << lodBias;
1039
1040                 op << ")";
1041
1042                 if (isShadow)
1043                         op << ", 0.0, 0.0, 1.0)";
1044                 else
1045                         op << ")*u_scale + u_bias";
1046
1047                 op << ";\n";
1048         }
1049
1050         if (isVtxCase)
1051                 frag << "\to_color = v_color;\n";
1052         else
1053         {
1054                 vert << "\tv_texCoord = a_in0;\n";
1055
1056                 if (isGrad)
1057                 {
1058                         vert << "\tv_gradX = a_in1;\n";
1059                         vert << "\tv_gradY = a_in2;\n";
1060                 }
1061                 else if (hasLodBias)
1062                         vert << "\tv_lodBias = a_in1;\n";
1063         }
1064
1065         vert << "}\n";
1066         frag << "}\n";
1067
1068         m_vertShaderSource = vert.str();
1069         m_fragShaderSource = frag.str();
1070 }
1071
1072 enum QueryFunction
1073 {
1074         QUERYFUNCTION_TEXTURESIZE = 0,
1075         QUERYFUNCTION_TEXTUREQUERYLOD,
1076         QUERYFUNCTION_TEXTUREQUERYLEVELS,
1077         QUERYFUNCTION_TEXTURESAMPLES,
1078
1079         QUERYFUNCTION_LAST
1080 };
1081
1082 static void checkDeviceFeatures (Context& context, TextureType textureType)
1083 {
1084         if (textureType == TEXTURETYPE_CUBE_ARRAY)
1085         {
1086                 const vk::VkPhysicalDeviceFeatures&     deviceFeatures  = context.getDeviceFeatures();
1087
1088                 if (!deviceFeatures.imageCubeArray)
1089                         TCU_THROW(NotSupportedError, "Cube array is not supported");
1090         }
1091 }
1092
1093 class TextureQueryInstance : public ShaderRenderCaseInstance
1094 {
1095 public:
1096                                                                 TextureQueryInstance                    (Context&                                       context,
1097                                                                                                                                  const bool                                     isVertexCase,
1098                                                                                                                                  const TextureSpec&                     textureSpec);
1099         virtual                                         ~TextureQueryInstance                   (void);
1100
1101 protected:
1102         virtual void                            setupDefaultInputs                              (void);
1103         virtual void                            setupUniforms                                   (const tcu::Vec4&);
1104
1105         void                                            render                                                  (void);
1106
1107 protected:
1108         const TextureSpec&                      m_textureSpec;
1109 };
1110
1111 TextureQueryInstance::TextureQueryInstance (Context&                            context,
1112                                                                                         const bool                              isVertexCase,
1113                                                                                         const TextureSpec&              textureSpec)
1114         : ShaderRenderCaseInstance      (context, isVertexCase, DE_NULL, DE_NULL, DE_NULL)
1115         , m_textureSpec                         (textureSpec)
1116 {
1117         m_colorFormat = vk::VK_FORMAT_R32G32B32A32_SFLOAT;
1118
1119         checkDeviceFeatures(m_context, m_textureSpec.type);
1120 }
1121
1122 TextureQueryInstance::~TextureQueryInstance (void)
1123 {
1124 }
1125
1126 void TextureQueryInstance::setupDefaultInputs (void)
1127 {
1128         const deUint32          numVertices             = 4;
1129         const float                     positions[]             =
1130         {
1131                 -1.0f, -1.0f, 0.0f, 1.0f,
1132                 -1.0f,  1.0f, 0.0f, 1.0f,
1133                  1.0f, -1.0f, 0.0f, 1.0f,
1134                  1.0f,  1.0f, 0.0f, 1.0f
1135         };
1136
1137         addAttribute(0u, vk::VK_FORMAT_R32G32B32A32_SFLOAT, 4 * (deUint32)sizeof(float), numVertices, positions);
1138 }
1139
1140 void TextureQueryInstance::setupUniforms (const tcu::Vec4&)
1141 {
1142         useSampler(0u, 0u);
1143 }
1144
1145 void TextureQueryInstance::render (void)
1146 {
1147         const deUint32          numVertices             = 4;
1148         const deUint32          numTriangles    = 2;
1149         const deUint16          indices[6]              = { 0, 1, 2, 2, 1, 3 };
1150
1151         ShaderRenderCaseInstance::setup();
1152
1153         ShaderRenderCaseInstance::render(numVertices, numTriangles, indices);
1154 }
1155
1156 static int getMaxTextureSize (TextureType type, const tcu::IVec3& textureSize)
1157 {
1158         int             maxSize         = 0;
1159
1160         switch (type)
1161         {
1162                 case TEXTURETYPE_1D:
1163                 case TEXTURETYPE_1D_ARRAY:
1164                         maxSize = textureSize.x();
1165                         break;
1166
1167                 case TEXTURETYPE_2D:
1168                 case TEXTURETYPE_2D_ARRAY:
1169                 case TEXTURETYPE_CUBE_MAP:
1170                 case TEXTURETYPE_CUBE_ARRAY:
1171                         maxSize = de::max(textureSize.x(), textureSize.y());
1172                         break;
1173
1174                 case TEXTURETYPE_3D:
1175                         maxSize = de::max(textureSize.x(), de::max(textureSize.y(), textureSize.z()));
1176                         break;
1177
1178                 default:
1179                         DE_ASSERT(false);
1180         }
1181
1182         return maxSize;
1183 }
1184
1185 static std::string getTextureSizeString (TextureType type, const tcu::IVec3& textureSize)
1186 {
1187         std::ostringstream      str;
1188
1189         switch (type)
1190         {
1191                 case TEXTURETYPE_1D:
1192                         str << textureSize.x() << "x1";
1193                         break;
1194
1195                 case TEXTURETYPE_2D:
1196                 case TEXTURETYPE_CUBE_MAP:
1197                         str << textureSize.x() << "x" << textureSize.y();
1198                         break;
1199
1200                 case TEXTURETYPE_3D:
1201                         str << textureSize.x() << "x" << textureSize.y() << "x" << textureSize.z();
1202                         break;
1203
1204                 case TEXTURETYPE_1D_ARRAY:
1205                         str << textureSize.x() << "x1 with " << textureSize.z() << " layer(s)";
1206                         break;
1207
1208                 case TEXTURETYPE_2D_ARRAY:
1209                 case TEXTURETYPE_CUBE_ARRAY:
1210                         str << textureSize.x() << "x" << textureSize.y() << " with " << textureSize.z() << " layers(s)";
1211                         break;
1212
1213                 default:
1214                         DE_ASSERT(false);
1215                         break;
1216         }
1217
1218         return str.str();
1219 }
1220
1221 static bool isValidCase (TextureType type, const tcu::IVec3& textureSize, int lod, int lodBase)
1222 {
1223         const bool              isSquare                = textureSize.x() == textureSize.y();
1224         const bool              isCubeArray             = isSquare && (textureSize.z() % 6) == 0;
1225         const int               maxSize                 = getMaxTextureSize(type, textureSize);
1226         const bool              isLodValid              = (maxSize >> (lod + lodBase)) != 0;
1227
1228         if (!isLodValid)
1229                 return false;
1230         if (type == TEXTURETYPE_CUBE_MAP && !isSquare)
1231                 return false;
1232         if (type == TEXTURETYPE_CUBE_ARRAY && !isCubeArray)
1233                 return false;
1234
1235         return true;
1236 }
1237
1238 static TextureBindingSp createEmptyTexture (deUint32                            format,
1239                                                                                         TextureType                             type,
1240                                                                                         const tcu::IVec3&               textureSize,
1241                                                                                         int                                             numLevels,
1242                                                                                         int                                             lodBase,
1243                                                                                         const tcu::Sampler&             sampler)
1244 {
1245         const tcu::TextureFormat                        texFmt                          = glu::mapGLInternalFormat(format);
1246         const TextureBinding::Parameters        params                          (lodBase);
1247         TextureBindingSp                                        textureBinding;
1248
1249         switch (type)
1250         {
1251
1252                 case TEXTURETYPE_1D:
1253                 {
1254                         de::MovePtr<tcu::Texture1D>                     texture         (new tcu::Texture1D(texFmt, textureSize.x()));
1255
1256                         for (int level = 0; level < numLevels; level++)
1257                                 texture->allocLevel(level);
1258
1259                         textureBinding = TextureBindingSp(new TextureBinding(texture.release(), sampler));
1260                         break;
1261                 }
1262
1263                 case TEXTURETYPE_2D:
1264                 {
1265                         de::MovePtr<tcu::Texture2D>                     texture         (new tcu::Texture2D(texFmt, textureSize.x(), textureSize.y()));
1266
1267                         for (int level = 0; level < numLevels; level++)
1268                                 texture->allocLevel(level);
1269
1270                         textureBinding = TextureBindingSp(new TextureBinding(texture.release(), sampler));
1271                         break;
1272                 }
1273
1274                 case TEXTURETYPE_3D:
1275                 {
1276                         de::MovePtr<tcu::Texture3D>                     texture         (new tcu::Texture3D(texFmt, textureSize.x(), textureSize.y(), textureSize.z()));
1277
1278                         for (int level = 0; level < numLevels; level++)
1279                                 texture->allocLevel(level);
1280
1281                         textureBinding = TextureBindingSp(new TextureBinding(texture.release(), sampler));
1282                         break;
1283                 }
1284
1285                 case TEXTURETYPE_CUBE_MAP:
1286                 {
1287                         de::MovePtr<tcu::TextureCube>           texture         (new tcu::TextureCube(texFmt, textureSize.x()));
1288
1289                         for (int level = 0; level < numLevels; level++)
1290                                 for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
1291                                         texture->allocLevel((tcu::CubeFace)face, level);
1292
1293                         textureBinding = TextureBindingSp(new TextureBinding(texture.release(), sampler));
1294                         break;
1295                 }
1296
1297                 case TEXTURETYPE_1D_ARRAY:
1298                 {
1299                         de::MovePtr<tcu::Texture1DArray>        texture         (new tcu::Texture1DArray(texFmt, textureSize.x(), textureSize.z()));
1300
1301                         for (int level = 0; level < numLevels; level++)
1302                                 texture->allocLevel(level);
1303
1304                         textureBinding = TextureBindingSp(new TextureBinding(texture.release(), sampler));
1305                         break;
1306                 }
1307
1308                 case TEXTURETYPE_2D_ARRAY:
1309                 {
1310                         de::MovePtr<tcu::Texture2DArray>        texture         (new tcu::Texture2DArray(texFmt, textureSize.x(), textureSize.y(), textureSize.z()));
1311
1312                         for (int level = 0; level < numLevels; level++)
1313                                 texture->allocLevel(level);
1314
1315                         textureBinding = TextureBindingSp(new TextureBinding(texture.release(), sampler));
1316                         break;
1317                 }
1318
1319                 case TEXTURETYPE_CUBE_ARRAY:
1320                 {
1321                         de::MovePtr<tcu::TextureCubeArray>      texture         (new tcu::TextureCubeArray(texFmt, textureSize.x(), textureSize.z()));
1322
1323                         for (int level = 0; level < numLevels; level++)
1324                                 texture->allocLevel(level);
1325
1326                         textureBinding = TextureBindingSp(new TextureBinding(texture.release(), sampler));
1327                         break;
1328                 }
1329
1330                 default:
1331                         DE_ASSERT(false);
1332                         break;
1333         }
1334
1335         textureBinding->setParameters(params);
1336         return textureBinding;
1337 }
1338
1339 static inline glu::DataType getTextureSizeFuncResultType (TextureType textureType)
1340 {
1341         switch (textureType)
1342         {
1343                 case TEXTURETYPE_1D:
1344                         return glu::TYPE_INT;
1345
1346                 case TEXTURETYPE_2D:
1347                 case TEXTURETYPE_CUBE_MAP:
1348                 case TEXTURETYPE_1D_ARRAY:
1349                         return glu::TYPE_INT_VEC2;
1350
1351                 case TEXTURETYPE_3D:
1352                 case TEXTURETYPE_2D_ARRAY:
1353                 case TEXTURETYPE_CUBE_ARRAY:
1354                         return glu::TYPE_INT_VEC3;
1355
1356                 default:
1357                         DE_ASSERT(false);
1358                         return glu::TYPE_LAST;
1359         }
1360 }
1361
1362 class TextureSizeInstance : public TextureQueryInstance
1363 {
1364 public:
1365                                                                 TextureSizeInstance                             (Context&                                       context,
1366                                                                                                                                  const bool                                     isVertexCase,
1367                                                                                                                                  const TextureSpec&                     textureSpec);
1368         virtual                                         ~TextureSizeInstance                    (void);
1369
1370         virtual tcu::TestStatus         iterate                                                 (void);
1371
1372 protected:
1373         virtual void                            setupUniforms                                   (const tcu::Vec4& constCoords);
1374
1375 private:
1376         struct TestSize
1377         {
1378                 tcu::IVec3      textureSize;
1379                 int                     lod;
1380                 int                     lodBase;
1381                 tcu::IVec3      expectedSize;
1382         };
1383
1384         void                                            initTexture                                             (void);
1385         bool                                            testTextureSize                                 (void);
1386
1387         TestSize                                        m_testSize;
1388         tcu::IVec3                                      m_expectedSize;
1389         int                                                     m_iterationCounter;
1390 };
1391
1392 TextureSizeInstance::TextureSizeInstance (Context&                                      context,
1393                                                                                   const bool                            isVertexCase,
1394                                                                                   const TextureSpec&            textureSpec)
1395         : TextureQueryInstance          (context, isVertexCase, textureSpec)
1396         , m_testSize                            ()
1397         , m_expectedSize                        ()
1398         , m_iterationCounter            (0)
1399 {
1400         deMemset(&m_testSize, 0, sizeof(TestSize));
1401
1402         m_renderSize = tcu::UVec2(1, 1);
1403 }
1404
1405 TextureSizeInstance::~TextureSizeInstance (void)
1406 {
1407 }
1408
1409 void TextureSizeInstance::setupUniforms (const tcu::Vec4& constCoords)
1410 {
1411         TextureQueryInstance::setupUniforms(constCoords);
1412         addUniform(1u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, sizeof(int), &m_testSize.lod);
1413 }
1414
1415 void TextureSizeInstance::initTexture (void)
1416 {
1417         tcu::TestLog&                   log                                     = m_context.getTestContext().getLog();
1418         const int                               numLevels                       = m_testSize.lod + m_testSize.lodBase + 1;
1419         TextureBindingSp                textureBinding;
1420
1421         log << tcu::TestLog::Message << "Testing image size " << getTextureSizeString(m_textureSpec.type, m_testSize.textureSize) << tcu::TestLog::EndMessage;
1422         log << tcu::TestLog::Message << "Lod: " << m_testSize.lod << ", base level: " << m_testSize.lodBase << tcu::TestLog::EndMessage;
1423
1424         switch (m_textureSpec.type)
1425         {
1426                 case TEXTURETYPE_3D:
1427                         log << tcu::TestLog::Message << "Expecting: " << m_testSize.expectedSize.x() << "x" << m_testSize.expectedSize.y() << "x" << m_testSize.expectedSize.z() << tcu::TestLog::EndMessage;
1428                         break;
1429
1430                 case TEXTURETYPE_2D:
1431                         log << tcu::TestLog::Message << "Expecting: " << m_testSize.expectedSize.x() << "x" << m_testSize.expectedSize.y() << tcu::TestLog::EndMessage;
1432                         break;
1433
1434                 case TEXTURETYPE_CUBE_MAP:
1435                         log << tcu::TestLog::Message << "Expecting: " << m_testSize.expectedSize.x() << "x" << m_testSize.expectedSize.y() << tcu::TestLog::EndMessage;
1436                         break;
1437
1438                 case TEXTURETYPE_2D_ARRAY:
1439                         log << tcu::TestLog::Message << "Expecting: " << m_testSize.expectedSize.x() << "x" << m_testSize.expectedSize.y() << " and " << m_testSize.textureSize.z() << " layer(s)" << tcu::TestLog::EndMessage;
1440                         break;
1441
1442                 case TEXTURETYPE_CUBE_ARRAY:
1443                         log << tcu::TestLog::Message << "Expecting: " << m_testSize.expectedSize.x() << "x" << m_testSize.expectedSize.y() << " and " << (m_testSize.textureSize.z() / 6) << " cube(s)" << tcu::TestLog::EndMessage;
1444                         break;
1445
1446                 case TEXTURETYPE_1D:
1447                         log << tcu::TestLog::Message << "Expecting: " << m_testSize.expectedSize.x() << tcu::TestLog::EndMessage;
1448                         break;
1449
1450                 case TEXTURETYPE_1D_ARRAY:
1451                         log << tcu::TestLog::Message << "Expecting: " << m_testSize.expectedSize.x() << " and " << m_testSize.textureSize.z() << " layer(s)" << tcu::TestLog::EndMessage;
1452                         break;
1453
1454                 default:
1455                         DE_ASSERT(false);
1456                         break;
1457         }
1458
1459         textureBinding = createEmptyTexture(m_textureSpec.format, m_textureSpec.type, m_testSize.textureSize, numLevels, m_testSize.lodBase, m_textureSpec.sampler);
1460
1461         m_textures.clear();
1462         m_textures.push_back(textureBinding);
1463 }
1464
1465 tcu::TestStatus TextureSizeInstance::iterate (void)
1466 {
1467         const TestSize testSizes[] =
1468         {
1469                 { tcu::IVec3(1, 2, 1),                  0,              0,      tcu::IVec3(1, 2, 1)                     },
1470                 { tcu::IVec3(1, 2, 1),                  1,              0,      tcu::IVec3(1, 1, 1)                     },
1471
1472                 { tcu::IVec3(1, 3, 2),                  0,              0,      tcu::IVec3(1, 3, 2)                     },
1473                 { tcu::IVec3(1, 3, 2),                  1,              0,      tcu::IVec3(1, 1, 1)                     },
1474
1475                 { tcu::IVec3(100, 31, 18),              0,              0,      tcu::IVec3(100, 31, 18)         },
1476                 { tcu::IVec3(100, 31, 18),              1,              0,      tcu::IVec3(50, 15, 9)           },
1477                 { tcu::IVec3(100, 31, 18),              2,              0,      tcu::IVec3(25, 7, 4)            },
1478                 { tcu::IVec3(100, 31, 18),              3,              0,      tcu::IVec3(12, 3, 2)            },
1479                 { tcu::IVec3(100, 31, 18),              4,              0,      tcu::IVec3(6, 1, 1)                     },
1480                 { tcu::IVec3(100, 31, 18),              5,              0,      tcu::IVec3(3, 1, 1)                     },
1481                 { tcu::IVec3(100, 31, 18),              6,              0,      tcu::IVec3(1, 1, 1)                     },
1482
1483                 { tcu::IVec3(100, 128, 32),             0,              0,      tcu::IVec3(100, 128, 32)        },
1484                 { tcu::IVec3(100, 128, 32),             1,              0,      tcu::IVec3(50, 64, 16)          },
1485                 { tcu::IVec3(100, 128, 32),             2,              0,      tcu::IVec3(25, 32, 8)           },
1486                 { tcu::IVec3(100, 128, 32),             3,              0,      tcu::IVec3(12, 16, 4)           },
1487                 { tcu::IVec3(100, 128, 32),             4,              0,      tcu::IVec3(6, 8, 2)                     },
1488                 { tcu::IVec3(100, 128, 32),             5,              0,      tcu::IVec3(3, 4, 1)                     },
1489                 { tcu::IVec3(100, 128, 32),             6,              0,      tcu::IVec3(1, 2, 1)                     },
1490                 { tcu::IVec3(100, 128, 32),             7,              0,      tcu::IVec3(1, 1, 1)                     },
1491
1492                 // pow 2
1493                 { tcu::IVec3(128, 64, 32),              0,              0,      tcu::IVec3(128, 64, 32)         },
1494                 { tcu::IVec3(128, 64, 32),              1,              0,      tcu::IVec3(64, 32, 16)          },
1495                 { tcu::IVec3(128, 64, 32),              2,              0,      tcu::IVec3(32, 16, 8)           },
1496                 { tcu::IVec3(128, 64, 32),              3,              0,      tcu::IVec3(16, 8, 4)            },
1497                 { tcu::IVec3(128, 64, 32),              4,              0,      tcu::IVec3(8, 4, 2)                     },
1498                 { tcu::IVec3(128, 64, 32),              5,              0,      tcu::IVec3(4, 2, 1)                     },
1499                 { tcu::IVec3(128, 64, 32),              6,              0,      tcu::IVec3(2, 1, 1)                     },
1500                 { tcu::IVec3(128, 64, 32),              7,              0,      tcu::IVec3(1, 1, 1)                     },
1501
1502                 // w == h
1503                 { tcu::IVec3(1, 1, 1),                  0,              0,      tcu::IVec3(1, 1, 1)                     },
1504                 { tcu::IVec3(64, 64, 64),               0,              0,      tcu::IVec3(64, 64, 64)          },
1505                 { tcu::IVec3(64, 64, 64),               1,              0,      tcu::IVec3(32, 32, 32)          },
1506                 { tcu::IVec3(64, 64, 64),               2,              0,      tcu::IVec3(16, 16, 16)          },
1507                 { tcu::IVec3(64, 64, 64),               3,              0,      tcu::IVec3(8, 8, 8)                     },
1508                 { tcu::IVec3(64, 64, 64),               4,              0,      tcu::IVec3(4, 4, 4)                     },
1509
1510                 // with lod base
1511                 { tcu::IVec3(100, 31, 18),              3,              1,      tcu::IVec3(6, 1, 1)                     },
1512                 { tcu::IVec3(128, 64, 32),              3,              1,      tcu::IVec3(8, 4, 2)                     },
1513                 { tcu::IVec3(64, 64, 64),               1,              1,      tcu::IVec3(16, 16, 16)          },
1514
1515                 // w == h and d % 6 == 0 (for cube array)
1516                 { tcu::IVec3(1, 1, 6),                  0,              0,      tcu::IVec3(1, 1, 6)                     },
1517                 { tcu::IVec3(32, 32, 12),               0,              0,      tcu::IVec3(32, 32, 12)          },
1518                 { tcu::IVec3(32, 32, 12),               0,              1,      tcu::IVec3(16, 16, 6)           },
1519                 { tcu::IVec3(32, 32, 12),               1,              0,      tcu::IVec3(16, 16, 6)           },
1520                 { tcu::IVec3(32, 32, 12),               2,              0,      tcu::IVec3(8, 8, 3)                     },
1521                 { tcu::IVec3(32, 32, 12),               3,              0,      tcu::IVec3(4, 4, 1)                     },
1522                 { tcu::IVec3(32, 32, 12),               4,              0,      tcu::IVec3(2, 2, 1)                     },
1523                 { tcu::IVec3(32, 32, 12),               5,              0,      tcu::IVec3(1, 1, 1)                     },
1524         };
1525         const int lastIterationIndex = DE_LENGTH_OF_ARRAY(testSizes) + 1;
1526
1527         m_iterationCounter++;
1528
1529         if (m_iterationCounter == lastIterationIndex)
1530                 return tcu::TestStatus::pass("Pass");
1531         else
1532         {
1533                 // set current test size
1534                 m_testSize = testSizes[m_iterationCounter - 1];
1535
1536                 if (!testTextureSize())
1537                         return tcu::TestStatus::fail("Got unexpected result");
1538
1539                 return tcu::TestStatus::incomplete();
1540         }
1541 }
1542
1543 bool TextureSizeInstance::testTextureSize (void)
1544 {
1545         tcu::TestLog&                   log                             = m_context.getTestContext().getLog();
1546         bool                                    success                 = true;
1547
1548         // skip incompatible cases
1549         if (!isValidCase(m_textureSpec.type, m_testSize.textureSize, m_testSize.lod, m_testSize.lodBase))
1550                 return true;
1551
1552         // setup texture
1553         initTexture();
1554
1555         // determine expected texture size
1556         switch (m_textureSpec.type)
1557         {
1558                 case TEXTURETYPE_1D:
1559                 case TEXTURETYPE_2D:
1560                 case TEXTURETYPE_3D:
1561                 case TEXTURETYPE_CUBE_MAP:
1562                         m_expectedSize = m_testSize.expectedSize;
1563                         break;
1564
1565                 case TEXTURETYPE_1D_ARRAY:
1566                         m_expectedSize = tcu::IVec3(m_testSize.expectedSize.x(), m_testSize.textureSize.z(), 0);
1567                         break;
1568
1569                 case TEXTURETYPE_2D_ARRAY:
1570                         m_expectedSize = tcu::IVec3(m_testSize.expectedSize.x(), m_testSize.expectedSize.y(), m_testSize.textureSize.z());
1571                         break;
1572
1573                 case TEXTURETYPE_CUBE_ARRAY:
1574                         m_expectedSize = tcu::IVec3(m_testSize.expectedSize.x(), m_testSize.expectedSize.y(), m_testSize.textureSize.z() / 6);
1575                         break;
1576
1577                 default:
1578                         DE_ASSERT(false);
1579                         break;
1580         }
1581
1582         // render
1583         TextureQueryInstance::render();
1584
1585         // test
1586         {
1587                 const tcu::TextureLevel&        result                          = getResultImage();
1588                 tcu::IVec4                                      output                          = result.getAccess().getPixelInt(0, 0);
1589                 const int                                       resultComponents        = glu::getDataTypeScalarSize(getTextureSizeFuncResultType(m_textureSpec.type));
1590
1591                 for (int ndx = 0; ndx < resultComponents; ndx++)
1592                 {
1593                         if (output[ndx] != m_expectedSize[ndx])
1594                         {
1595                                 success = false;
1596                                 break;
1597                         }
1598                 }
1599
1600                 if (success)
1601                 {
1602                         // success
1603                         log << tcu::TestLog::Message << "Passed" << tcu::TestLog::EndMessage;
1604                 }
1605                 else
1606                 {
1607                         // failure
1608                         std::stringstream       resultSizeStr;
1609                         switch (resultComponents)
1610                         {
1611                                 case 1:
1612                                         resultSizeStr << output[0];
1613                                         break;
1614                                 case 2:
1615                                         resultSizeStr << output.toWidth<2>();
1616                                         break;
1617                                 case 3:
1618                                         resultSizeStr << output.toWidth<3>();
1619                                         break;
1620                                 default:
1621                                         DE_ASSERT(false);
1622                                         break;
1623                         }
1624                         log << tcu::TestLog::Message << "Result: " << resultSizeStr.str() << tcu::TestLog::EndMessage;
1625                         log << tcu::TestLog::Message << "Failed" << tcu::TestLog::EndMessage;
1626                 }
1627         }
1628
1629         log << tcu::TestLog::Message << tcu::TestLog::EndMessage;
1630
1631         return success;
1632 }
1633
1634 static vk::VkImageType getVkImageType (TextureType type)
1635 {
1636         switch (type)
1637         {
1638                 case TEXTURETYPE_1D:
1639                 case TEXTURETYPE_1D_ARRAY:
1640                         return vk::VK_IMAGE_TYPE_1D;
1641
1642                 case TEXTURETYPE_2D:
1643                 case TEXTURETYPE_2D_ARRAY:
1644                 case TEXTURETYPE_CUBE_MAP:
1645                 case TEXTURETYPE_CUBE_ARRAY:
1646                         return vk::VK_IMAGE_TYPE_2D;
1647
1648                 case TEXTURETYPE_3D:
1649                         return vk::VK_IMAGE_TYPE_3D;
1650
1651                 default:
1652                         DE_ASSERT(false);
1653                         return (vk::VkImageType)0;
1654         }
1655 }
1656
1657 class TextureSamplesInstance : public TextureQueryInstance
1658 {
1659 public:
1660                                                                 TextureSamplesInstance                  (Context&                                       context,
1661                                                                                                                                  const bool                                     isVertexCase,
1662                                                                                                                                  const TextureSpec&                     textureSpec);
1663         virtual                                         ~TextureSamplesInstance                 (void);
1664
1665         virtual tcu::TestStatus         iterate                                                 (void);
1666
1667 private:
1668         void                                            initTexture                                             (void);
1669
1670         int                                                                             m_iterationCounter;
1671         vector<vk::VkSampleCountFlagBits>               m_iterations;
1672 };
1673
1674 TextureSamplesInstance::TextureSamplesInstance (Context&                                context,
1675                                                                                                 const bool                              isVertexCase,
1676                                                                                                 const TextureSpec&              textureSpec)
1677         : TextureQueryInstance          (context, isVertexCase, textureSpec)
1678         , m_iterationCounter            (0)
1679 {
1680         m_renderSize = tcu::UVec2(1, 1);
1681
1682         // determine available sample counts
1683         {
1684                 const vk::VkFormat                                              format                  = vk::mapTextureFormat(glu::mapGLInternalFormat(m_textureSpec.format));
1685                 const vk::VkImageType                                   imageType               = getVkImageType(m_textureSpec.type);
1686                 vk::VkImageFormatProperties                             properties;
1687
1688                 if (m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(m_context.getPhysicalDevice(),
1689                                                                                                                                                                         format,
1690                                                                                                                                                                         imageType,
1691                                                                                                                                                                         vk::VK_IMAGE_TILING_OPTIMAL,
1692                                                                                                                                                                         vk::VK_IMAGE_USAGE_SAMPLED_BIT | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1693                                                                                                                                                                         (vk::VkImageCreateFlags)0,
1694                                                                                                                                                                         &properties) == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
1695                         TCU_THROW(NotSupportedError, "Format not supported");
1696
1697                 // NOTE: The test case initializes MS images (for all supported N of samples), runs a program
1698                 //       which invokes OpImageQuerySamples against the image and checks the result.
1699                 //
1700                 //       Now, in the SPIR-V spec for the very operation we have the following language:
1701                 //
1702                 //       OpImageQuerySamples
1703                 //       Query the number of samples available per texel fetch in a multisample image.
1704                 //       Result Type must be a scalar integer type.
1705                 //       The result is the number of samples.
1706                 //       Image must be an object whose type is OpTypeImage.
1707                 //       Its Dim operand must be one of 2D and **MS of 1(multisampled).
1708                 //
1709                 //       "MS of 1" implies the image must not be single-sample, meaning we must exclude
1710                 //       VK_SAMPLE_COUNT_1_BIT in the sampleFlags array below, and may have to skip further testing.
1711                 static const vk::VkSampleCountFlagBits  sampleFlags[]   =
1712                 {
1713                         vk::VK_SAMPLE_COUNT_2_BIT,
1714                         vk::VK_SAMPLE_COUNT_4_BIT,
1715                         vk::VK_SAMPLE_COUNT_8_BIT,
1716                         vk::VK_SAMPLE_COUNT_16_BIT,
1717                         vk::VK_SAMPLE_COUNT_32_BIT,
1718                         vk::VK_SAMPLE_COUNT_64_BIT
1719                 };
1720
1721                 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(sampleFlags); samplesNdx++)
1722                 {
1723                         const vk::VkSampleCountFlagBits&        flag                    = sampleFlags[samplesNdx];
1724
1725                         if ((properties.sampleCounts & flag) != 0)
1726                                 m_iterations.push_back(flag);
1727                 }
1728
1729                 if (m_iterations.empty())
1730                 {
1731                         // Sampled images of integer formats may support only 1 sample. Exit the test with "Not supported" in these cases.
1732                         if (tcu::getTextureChannelClass(mapVkFormat(format).type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ||
1733                                 tcu::getTextureChannelClass(mapVkFormat(format).type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
1734                         {
1735                                 TCU_THROW(NotSupportedError, "Skipping validation of integer formats as only VK_SAMPLE_COUNT_1_BIT is supported.");
1736                         }
1737
1738                         DE_ASSERT(false);
1739                 }
1740         }
1741
1742         // setup texture
1743         initTexture();
1744 }
1745
1746 TextureSamplesInstance::~TextureSamplesInstance (void)
1747 {
1748 }
1749
1750 tcu::TestStatus TextureSamplesInstance::iterate (void)
1751 {
1752         tcu::TestLog&           log             = m_context.getTestContext().getLog();
1753
1754         // update samples count
1755         {
1756                 DE_ASSERT(m_textures.size() == 1);
1757
1758                 TextureBinding::Parameters      params  = m_textures[0]->getParameters();
1759
1760                 params.initialization   = TextureBinding::INIT_CLEAR;
1761                 params.samples                  = m_iterations[m_iterationCounter];
1762                 log << tcu::TestLog::Message << "Expected samples: " << m_iterations[m_iterationCounter] << tcu::TestLog::EndMessage;
1763
1764                 m_textures[0]->setParameters(params);
1765         }
1766
1767         // render
1768         TextureQueryInstance::render();
1769
1770         // test
1771         {
1772                 const tcu::TextureLevel&        result                          = getResultImage();
1773                 tcu::IVec4                                      output                          = result.getAccess().getPixelInt(0, 0);
1774
1775                 if (output.x() == (int)m_iterations[m_iterationCounter])
1776                 {
1777                         // success
1778                         log << tcu::TestLog::Message << "Passed" << tcu::TestLog::EndMessage;
1779                 }
1780                 else
1781                 {
1782                         // failure
1783                         log << tcu::TestLog::Message << "Result: " << output.x() << tcu::TestLog::EndMessage;
1784                         log << tcu::TestLog::Message << "Failed" << tcu::TestLog::EndMessage;
1785                         return tcu::TestStatus::fail("Got unexpected result");
1786                 }
1787
1788                 m_iterationCounter++;
1789                 if (m_iterationCounter == (int)m_iterations.size())
1790                         return tcu::TestStatus::pass("Pass");
1791                 else
1792                         return tcu::TestStatus::incomplete();
1793         }
1794 }
1795
1796 void TextureSamplesInstance::initTexture (void)
1797 {
1798         tcu::TestLog&                   log                                     = m_context.getTestContext().getLog();
1799         tcu::IVec3                              textureSize                     (m_textureSpec.width, m_textureSpec.height, m_textureSpec.depth);
1800         TextureBindingSp                textureBinding;
1801
1802         DE_ASSERT(m_textures.empty());
1803         DE_ASSERT(m_textureSpec.type == TEXTURETYPE_2D || m_textureSpec.type == TEXTURETYPE_2D_ARRAY);
1804
1805         log << tcu::TestLog::Message << "Image size: " << getTextureSizeString(m_textureSpec.type, textureSize) << tcu::TestLog::EndMessage;
1806
1807         textureBinding = createEmptyTexture(m_textureSpec.format, m_textureSpec.type, textureSize, m_textureSpec.numLevels, 0 /* lodBase */, m_textureSpec.sampler);
1808
1809         m_textures.push_back(textureBinding);
1810 }
1811
1812 class TextureQueryLevelsInstance : public TextureQueryInstance
1813 {
1814 public:
1815                                                                 TextureQueryLevelsInstance              (Context&                                       context,
1816                                                                                                                                  const bool                                     isVertexCase,
1817                                                                                                                                  const TextureSpec&                     textureSpec);
1818         virtual                                         ~TextureQueryLevelsInstance             (void);
1819
1820         virtual tcu::TestStatus         iterate                                                 (void);
1821
1822 private:
1823         struct TestSize
1824         {
1825                 tcu::IVec3      textureSize;
1826                 int                     lodBase;
1827         };
1828
1829         void                                            initTexture                                             (void);
1830         bool                                            testTextureLevels                               (void);
1831
1832         TestSize                                        m_testSize;
1833         int                                                     m_levels;
1834         int                                                     m_iterationCounter;
1835 };
1836
1837 TextureQueryLevelsInstance::TextureQueryLevelsInstance (Context&                                context,
1838                                                                                                                 const bool                              isVertexCase,
1839                                                                                                                 const TextureSpec&              textureSpec)
1840         : TextureQueryInstance          (context, isVertexCase, textureSpec)
1841         , m_testSize                            ()
1842         , m_levels                                      (0)
1843         , m_iterationCounter            (0)
1844 {
1845         deMemset(&m_testSize, 0, sizeof(TestSize));
1846
1847         m_renderSize = tcu::UVec2(1, 1);
1848 }
1849
1850 TextureQueryLevelsInstance::~TextureQueryLevelsInstance (void)
1851 {
1852 }
1853
1854 tcu::TestStatus TextureQueryLevelsInstance::iterate (void)
1855 {
1856         const TestSize testSizes[] =
1857         {
1858                 { tcu::IVec3(1, 2, 1),                  0       },
1859                 { tcu::IVec3(1, 2, 1),                  1       },
1860
1861                 { tcu::IVec3(1, 3, 2),                  0       },
1862                 { tcu::IVec3(1, 3, 2),                  1       },
1863
1864                 { tcu::IVec3(100, 31, 18),              0       },
1865                 { tcu::IVec3(100, 31, 18),              1       },
1866                 { tcu::IVec3(100, 31, 18),              2       },
1867                 { tcu::IVec3(100, 31, 18),              3       },
1868                 { tcu::IVec3(100, 31, 18),              4       },
1869                 { tcu::IVec3(100, 31, 18),              5       },
1870                 { tcu::IVec3(100, 31, 18),              6       },
1871
1872                 { tcu::IVec3(100, 128, 32),             0       },
1873                 { tcu::IVec3(100, 128, 32),             1       },
1874                 { tcu::IVec3(100, 128, 32),             2       },
1875                 { tcu::IVec3(100, 128, 32),             3       },
1876                 { tcu::IVec3(100, 128, 32),             4       },
1877                 { tcu::IVec3(100, 128, 32),             5       },
1878                 { tcu::IVec3(100, 128, 32),             6       },
1879                 { tcu::IVec3(100, 128, 32),             7       },
1880
1881                 // pow 2
1882                 { tcu::IVec3(128, 64, 32),              0       },
1883                 { tcu::IVec3(128, 64, 32),              1       },
1884                 { tcu::IVec3(128, 64, 32),              2       },
1885                 { tcu::IVec3(128, 64, 32),              3       },
1886                 { tcu::IVec3(128, 64, 32),              4       },
1887                 { tcu::IVec3(128, 64, 32),              5       },
1888                 { tcu::IVec3(128, 64, 32),              6       },
1889                 { tcu::IVec3(128, 64, 32),              7       },
1890
1891                 // w == h
1892                 { tcu::IVec3(1, 1, 1),                  0       },
1893                 { tcu::IVec3(64, 64, 64),               0       },
1894                 { tcu::IVec3(64, 64, 64),               1       },
1895                 { tcu::IVec3(64, 64, 64),               2       },
1896                 { tcu::IVec3(64, 64, 64),               3       },
1897                 { tcu::IVec3(64, 64, 64),               4       },
1898                 { tcu::IVec3(64, 64, 64),               5       },
1899                 { tcu::IVec3(64, 64, 64),               6       },
1900
1901                 // w == h and d % 6 == 0 (for cube array)
1902                 { tcu::IVec3(1, 1, 6),                  0       },
1903                 { tcu::IVec3(32, 32, 12),               0       },
1904                 { tcu::IVec3(32, 32, 12),               1       },
1905                 { tcu::IVec3(32, 32, 12),               2       },
1906                 { tcu::IVec3(32, 32, 12),               3       },
1907                 { tcu::IVec3(32, 32, 12),               4       },
1908                 { tcu::IVec3(32, 32, 12),               5       },
1909         };
1910         const int lastIterationIndex = DE_LENGTH_OF_ARRAY(testSizes) + 1;
1911
1912         m_iterationCounter++;
1913
1914         if (m_iterationCounter == lastIterationIndex)
1915                 return tcu::TestStatus::pass("Pass");
1916         else
1917         {
1918                 // set current test size
1919                 m_testSize = testSizes[m_iterationCounter - 1];
1920
1921                 if (!testTextureLevels())
1922                         return tcu::TestStatus::fail("Got unexpected result");
1923
1924                 return tcu::TestStatus::incomplete();
1925         }
1926 }
1927
1928 bool TextureQueryLevelsInstance::testTextureLevels (void)
1929 {
1930         tcu::TestLog&                   log                             = m_context.getTestContext().getLog();
1931         bool                                    success                 = true;
1932
1933         // skip incompatible cases
1934         if (!isValidCase(m_textureSpec.type, m_testSize.textureSize, 0, m_testSize.lodBase))
1935                 return true;
1936
1937         // setup texture
1938         initTexture();
1939
1940         // calculate accessible levels
1941         {
1942                 const int       mipLevels       = deLog2Floor32(getMaxTextureSize(m_textureSpec.type, m_testSize.textureSize)) + 1;
1943
1944                 m_levels = mipLevels - m_testSize.lodBase;
1945                 DE_ASSERT(m_levels > 0);
1946
1947                 log << tcu::TestLog::Message << "Expected levels: " << m_levels << tcu::TestLog::EndMessage;
1948         }
1949
1950         // render
1951         TextureQueryInstance::render();
1952
1953         // test
1954         {
1955                 const tcu::TextureLevel&        result                          = getResultImage();
1956                 tcu::IVec4                                      output                          = result.getAccess().getPixelInt(0, 0);
1957
1958                 if (output.x() == m_levels)
1959                 {
1960                         // success
1961                         log << tcu::TestLog::Message << "Passed" << tcu::TestLog::EndMessage;
1962                 }
1963                 else
1964                 {
1965                         // failure
1966                         log << tcu::TestLog::Message << "Result: " << output.x() << tcu::TestLog::EndMessage;
1967                         log << tcu::TestLog::Message << "Failed" << tcu::TestLog::EndMessage;
1968                         success = false;
1969                 }
1970         }
1971
1972         log << tcu::TestLog::Message << tcu::TestLog::EndMessage;
1973
1974         return success;
1975 }
1976
1977 void TextureQueryLevelsInstance::initTexture (void)
1978 {
1979         tcu::TestLog&                   log                                     = m_context.getTestContext().getLog();
1980         int                                             numLevels                       = m_testSize.lodBase + 1;
1981         TextureBindingSp                textureBinding;
1982
1983         log << tcu::TestLog::Message << "Image size: " << getTextureSizeString(m_textureSpec.type, m_testSize.textureSize) << tcu::TestLog::EndMessage;
1984         log << tcu::TestLog::Message << "Base level: " << m_testSize.lodBase << tcu::TestLog::EndMessage;
1985
1986         textureBinding = createEmptyTexture(m_textureSpec.format, m_textureSpec.type, m_testSize.textureSize, numLevels, m_testSize.lodBase, m_textureSpec.sampler);
1987
1988         m_textures.clear();
1989         m_textures.push_back(textureBinding);
1990 }
1991
1992 static int getQueryLodFuncTextCoordComps (TextureType type)
1993 {
1994         switch (type)
1995         {
1996                 case TEXTURETYPE_1D:
1997                 case TEXTURETYPE_1D_ARRAY:
1998                         return 1;
1999
2000                 case TEXTURETYPE_2D:
2001                 case TEXTURETYPE_2D_ARRAY:
2002                         return 2;
2003
2004                 case TEXTURETYPE_3D:
2005                 case TEXTURETYPE_CUBE_MAP:
2006                 case TEXTURETYPE_CUBE_ARRAY:
2007                         return 3;
2008
2009                 default:
2010                         DE_ASSERT(false);
2011                         return 0;
2012         }
2013 }
2014
2015 class TextureQueryLodInstance : public TextureQueryInstance
2016 {
2017 public:
2018                                                                 TextureQueryLodInstance                 (Context&                                       context,
2019                                                                                                                                  const bool                                     isVertexCase,
2020                                                                                                                                  const TextureSpec&                     textureSpec);
2021         virtual                                         ~TextureQueryLodInstance                (void);
2022
2023         virtual tcu::TestStatus         iterate                                                 (void);
2024
2025 protected:
2026         virtual void                            setupDefaultInputs                              (void);
2027
2028 private:
2029         void                                            initTexture                                             (void);
2030         float                                           computeLevelFromLod                             (float computedLod) const;
2031         vector<float>                           computeQuadTexCoord                             (void) const;
2032
2033         tcu::Vec4                                       m_minCoord;
2034         tcu::Vec4                                       m_maxCoord;
2035         tcu::Vec2                                       m_lodBounds;
2036         tcu::Vec2                                       m_levelBounds;
2037 };
2038
2039 TextureQueryLodInstance::TextureQueryLodInstance (Context&                                      context,
2040                                                                                                   const bool                            isVertexCase,
2041                                                                                                   const TextureSpec&            textureSpec)
2042         : TextureQueryInstance          (context, isVertexCase, textureSpec)
2043         , m_minCoord                            ()
2044         , m_maxCoord                            ()
2045         , m_lodBounds                           ()
2046         , m_levelBounds                         ()
2047 {
2048         // setup texture
2049         initTexture();
2050
2051         // init min/max coords
2052         switch (m_textureSpec.type)
2053         {
2054                 case TEXTURETYPE_1D:
2055                 case TEXTURETYPE_1D_ARRAY:
2056                         m_minCoord              = Vec4(-0.2f,  0.0f,  0.0f,  0.0f);
2057                         m_maxCoord              = Vec4( 1.5f,  0.0f,  0.0f,  0.0f);
2058                         break;
2059
2060                 case TEXTURETYPE_2D:
2061                 case TEXTURETYPE_2D_ARRAY:
2062                         m_minCoord              = Vec4(-0.2f, -0.4f,  0.0f,  0.0f);
2063                         m_maxCoord              = Vec4( 1.5f,  2.3f,  0.0f,  0.0f);
2064                         break;
2065
2066                 case TEXTURETYPE_3D:
2067                         m_minCoord              = Vec4(-1.2f, -1.4f,  0.1f,  0.0f);
2068                         m_maxCoord              = Vec4( 1.5f,  2.3f,  2.3f,  0.0f);
2069                         break;
2070
2071                 case TEXTURETYPE_CUBE_MAP:
2072                 case TEXTURETYPE_CUBE_ARRAY:
2073                         m_minCoord              = Vec4(-1.0f, -1.0f,  1.01f,  0.0f);
2074                         m_maxCoord              = Vec4( 1.0f,  1.0f,  1.01f,  0.0f);
2075                         break;
2076
2077                 default:
2078                         DE_ASSERT(false);
2079                         break;
2080         }
2081
2082         // calculate lod and accessed level
2083         {
2084                 const tcu::UVec2&               viewportSize            = getViewportSize();
2085                 const float                             lodEps                          = (1.0f / float(1u << m_context.getDeviceProperties().limits.mipmapPrecisionBits)) + 0.008f;
2086
2087                 switch (m_textureSpec.type)
2088                 {
2089                         case TEXTURETYPE_1D:
2090                         case TEXTURETYPE_1D_ARRAY:
2091                         {
2092                                 const float     dudx    = (m_maxCoord[0]-m_minCoord[0])*(float)m_textureSpec.width      / (float)viewportSize[0];
2093
2094                                 m_lodBounds[0]          = computeLodFromDerivates(LODMODE_MIN_BOUND, dudx, 0.0f)-lodEps;
2095                                 m_lodBounds[1]          = computeLodFromDerivates(LODMODE_MAX_BOUND, dudx, 0.0f)+lodEps;
2096                                 break;
2097                         }
2098
2099                         case TEXTURETYPE_2D:
2100                         case TEXTURETYPE_2D_ARRAY:
2101                         {
2102                                 const float     dudx    = (m_maxCoord[0]-m_minCoord[0])*(float)m_textureSpec.width      / (float)viewportSize[0];
2103                                 const float     dvdy    = (m_maxCoord[1]-m_minCoord[1])*(float)m_textureSpec.height     / (float)viewportSize[1];
2104
2105                                 m_lodBounds[0]          = computeLodFromDerivates(LODMODE_MIN_BOUND, dudx, 0.0f, 0.0f, dvdy)-lodEps;
2106                                 m_lodBounds[1]          = computeLodFromDerivates(LODMODE_MAX_BOUND, dudx, 0.0f, 0.0f, dvdy)+lodEps;
2107                                 break;
2108                         }
2109
2110                         case TEXTURETYPE_CUBE_MAP:
2111                         case TEXTURETYPE_CUBE_ARRAY:
2112                         {
2113                                 // Compute LOD \note Assumes that only single side is accessed and R is constant major axis.
2114                                 DE_ASSERT(de::abs(m_minCoord[2] - m_maxCoord[2]) < 0.005);
2115                                 DE_ASSERT(de::abs(m_minCoord[0]) < de::abs(m_minCoord[2]) && de::abs(m_maxCoord[0]) < de::abs(m_minCoord[2]));
2116                                 DE_ASSERT(de::abs(m_minCoord[1]) < de::abs(m_minCoord[2]) && de::abs(m_maxCoord[1]) < de::abs(m_minCoord[2]));
2117
2118                                 tcu::CubeFaceFloatCoords        c00             = tcu::getCubeFaceCoords(Vec3(m_minCoord[0], m_minCoord[1], m_minCoord[2]));
2119                                 tcu::CubeFaceFloatCoords        c10             = tcu::getCubeFaceCoords(Vec3(m_maxCoord[0], m_minCoord[1], m_minCoord[2]));
2120                                 tcu::CubeFaceFloatCoords        c01             = tcu::getCubeFaceCoords(Vec3(m_minCoord[0], m_maxCoord[1], m_minCoord[2]));
2121                                 float                                           dudx    = (c10.s - c00.s)*(float)m_textureSpec.width    / (float)viewportSize[0];
2122                                 float                                           dvdy    = (c01.t - c00.t)*(float)m_textureSpec.height   / (float)viewportSize[1];
2123
2124                                 m_lodBounds[0]          = computeLodFromDerivates(LODMODE_MIN_BOUND, dudx, 0.0f, 0.0f, dvdy)-lodEps;
2125                                 m_lodBounds[1]          = computeLodFromDerivates(LODMODE_MAX_BOUND, dudx, 0.0f, 0.0f, dvdy)+lodEps;
2126                                 break;
2127                         }
2128
2129                         case TEXTURETYPE_3D:
2130                         {
2131                                 const float     dudx    = (m_maxCoord[0]-m_minCoord[0])*(float)m_textureSpec.width              / (float)viewportSize[0];
2132                                 const float     dvdy    = (m_maxCoord[1]-m_minCoord[1])*(float)m_textureSpec.height             / (float)viewportSize[1];
2133                                 const float     dwdx    = (m_maxCoord[2]-m_minCoord[2])*0.5f*(float)m_textureSpec.depth / (float)viewportSize[0];
2134                                 const float     dwdy    = (m_maxCoord[2]-m_minCoord[2])*0.5f*(float)m_textureSpec.depth / (float)viewportSize[1];
2135
2136                                 m_lodBounds[0]          = computeLodFromDerivates(LODMODE_MIN_BOUND, dudx, 0.0f, dwdx, 0.0f, dvdy, dwdy)-lodEps;
2137                                 m_lodBounds[1]          = computeLodFromDerivates(LODMODE_MAX_BOUND, dudx, 0.0f, dwdx, 0.0f, dvdy, dwdy)+lodEps;
2138                                 break;
2139                         }
2140
2141                         default:
2142                                 DE_ASSERT(false);
2143                                 break;
2144                 }
2145
2146                 m_levelBounds[0] = computeLevelFromLod(m_lodBounds[0]);
2147                 m_levelBounds[1] = computeLevelFromLod(m_lodBounds[1]);
2148         }
2149 }
2150
2151 TextureQueryLodInstance::~TextureQueryLodInstance (void)
2152 {
2153 }
2154
2155 tcu::TestStatus TextureQueryLodInstance::iterate (void)
2156 {
2157         tcu::TestLog&           log             = m_context.getTestContext().getLog();
2158
2159         log << tcu::TestLog::Message << "Expected: level in range " << m_levelBounds << ", lod in range " << m_lodBounds << tcu::TestLog::EndMessage;
2160
2161         // render
2162         TextureQueryInstance::render();
2163
2164         // test
2165         {
2166                 const tcu::TextureLevel&        result          = getResultImage();
2167                 const tcu::Vec4                         output          = result.getAccess().getPixel(0, 0);
2168                 const float                                     resLevel        = output.x();
2169                 const float                                     resLod          = output.y();
2170
2171                 if (de::inRange(resLevel, m_levelBounds[0], m_levelBounds[1]) && de::inRange(resLod, m_lodBounds[0], m_lodBounds[1]))
2172                 {
2173                         // success
2174                         log << tcu::TestLog::Message << "Passed" << tcu::TestLog::EndMessage;
2175                         return tcu::TestStatus::pass("Pass");
2176                 }
2177                 else
2178                 {
2179                         // failure
2180                         log << tcu::TestLog::Message << "Result: level: " << resLevel << ", lod: " << resLod << tcu::TestLog::EndMessage;
2181                         log << tcu::TestLog::Message << "Failed" << tcu::TestLog::EndMessage;
2182                         return tcu::TestStatus::fail("Got unexpected result");
2183                 }
2184         }
2185 }
2186
2187 void TextureQueryLodInstance::setupDefaultInputs (void)
2188 {
2189         TextureQueryInstance::setupDefaultInputs();
2190
2191         const deUint32                  numVertices                     = 4;
2192         const vector<float>             texCoord                        = computeQuadTexCoord();
2193         const int                               texCoordComps           = getQueryLodFuncTextCoordComps(m_textureSpec.type);
2194         const vk::VkFormat              coordFormats[]          =
2195         {
2196                 vk::VK_FORMAT_R32_SFLOAT,
2197                 vk::VK_FORMAT_R32G32_SFLOAT,
2198                 vk::VK_FORMAT_R32G32B32_SFLOAT
2199         };
2200
2201         DE_ASSERT(de::inRange(texCoordComps, 1, 3));
2202         DE_ASSERT((int)texCoord.size() == texCoordComps * 4);
2203
2204         addAttribute(1u, coordFormats[texCoordComps - 1], (deUint32)(texCoordComps * sizeof(float)), numVertices, texCoord.data());
2205 }
2206
2207 void TextureQueryLodInstance::initTexture (void)
2208 {
2209         tcu::TestLog&                   log                                     = m_context.getTestContext().getLog();
2210         tcu::IVec3                              textureSize                     (m_textureSpec.width, m_textureSpec.height, m_textureSpec.depth);
2211         TextureBindingSp                textureBinding;
2212
2213         DE_ASSERT(m_textures.empty());
2214
2215         log << tcu::TestLog::Message << "Image size: " << getTextureSizeString(m_textureSpec.type, textureSize) << tcu::TestLog::EndMessage;
2216
2217         textureBinding = createEmptyTexture(m_textureSpec.format, m_textureSpec.type, textureSize, m_textureSpec.numLevels, 0 /* lodBase */, m_textureSpec.sampler);
2218
2219         m_textures.push_back(textureBinding);
2220 }
2221
2222 float TextureQueryLodInstance::computeLevelFromLod (float computedLod) const
2223 {
2224         const int       maxAccessibleLevel      = m_textureSpec.numLevels - 1;
2225
2226         // Clamp the computed LOD to the range of accessible levels.
2227         computedLod = deFloatClamp(computedLod, 0.0f, (float)maxAccessibleLevel);
2228
2229         // Return a value according to the min filter.
2230         switch (m_textureSpec.sampler.minFilter)
2231         {
2232                 case tcu::Sampler::LINEAR:
2233                 case tcu::Sampler::NEAREST:
2234                         return 0.0f;
2235
2236                 case tcu::Sampler::NEAREST_MIPMAP_NEAREST:
2237                 case tcu::Sampler::LINEAR_MIPMAP_NEAREST:
2238                         return deFloatClamp(deFloatCeil(computedLod + 0.5f) - 1.0f, 0.0f, (float)maxAccessibleLevel);
2239
2240                 case tcu::Sampler::NEAREST_MIPMAP_LINEAR:
2241                 case tcu::Sampler::LINEAR_MIPMAP_LINEAR:
2242                         return computedLod;
2243
2244                 default:
2245                         DE_ASSERT(false);
2246                         return 0.0f;
2247         }
2248 }
2249
2250 vector<float> TextureQueryLodInstance::computeQuadTexCoord (void) const
2251 {
2252         vector<float>   res;
2253         tcu::Mat4               coordTransMat;
2254
2255         {
2256                 Vec4 s = m_maxCoord - m_minCoord;
2257                 Vec4 b = m_minCoord;
2258
2259                 float baseCoordTrans[] =
2260                 {
2261                         s.x(),          0.0f,           0.f,    b.x(),
2262                         0.f,            s.y(),          0.f,    b.y(),
2263                         s.z()/2.f,      -s.z()/2.f,     0.f,    s.z()/2.f + b.z(),
2264                         -s.w()/2.f,     s.w()/2.f,      0.f,    s.w()/2.f + b.w()
2265                 };
2266
2267                 coordTransMat = tcu::Mat4(baseCoordTrans);
2268         }
2269
2270         const int               texCoordComps   = getQueryLodFuncTextCoordComps(m_textureSpec.type);
2271         Vec4                    coords[4]               =
2272         {
2273                 coordTransMat * tcu::Vec4(0, 0, 0, 1),
2274                 coordTransMat * tcu::Vec4(0, 1, 0, 1),
2275                 coordTransMat * tcu::Vec4(1, 0, 0, 1),
2276                 coordTransMat * tcu::Vec4(1, 1, 0, 1)
2277         };
2278
2279         res.resize(4 * texCoordComps);
2280
2281         for (int ndx = 0; ndx < 4; ndx++)
2282                 deMemcpy(&res[ndx * texCoordComps], coords[ndx].getPtr(), texCoordComps * sizeof(float));
2283
2284         return res;
2285 }
2286
2287 class TextureQueryCase : public ShaderRenderCase
2288 {
2289 public:
2290                                                                 TextureQueryCase                                (tcu::TestContext&                      testCtx,
2291                                                                                                                                  const std::string&                     name,
2292                                                                                                                                  const std::string&                     desc,
2293                                                                                                                                  const std::string&                     samplerType,
2294                                                                                                                                  const TextureSpec&                     texture,
2295                                                                                                                                  bool                                           isVertexCase,
2296                                                                                                                                  QueryFunction                          function);
2297         virtual                                         ~TextureQueryCase                               (void);
2298
2299         virtual TestInstance*           createInstance                                  (Context& context) const;
2300
2301 protected:
2302         void                                            initShaderSources                               (void);
2303
2304         const std::string                       m_samplerTypeStr;
2305         const TextureSpec                       m_textureSpec;
2306         const QueryFunction                     m_function;
2307 };
2308
2309 TextureQueryCase::TextureQueryCase (tcu::TestContext&           testCtx,
2310                                                                         const std::string&              name,
2311                                                                         const std::string&              desc,
2312                                                                         const std::string&              samplerType,
2313                                                                         const TextureSpec&              texture,
2314                                                                         bool                                    isVertexCase,
2315                                                                         QueryFunction                   function)
2316         : ShaderRenderCase      (testCtx, name, desc, isVertexCase, (ShaderEvaluator*)DE_NULL, DE_NULL, DE_NULL)
2317         , m_samplerTypeStr      (samplerType)
2318         , m_textureSpec         (texture)
2319         , m_function            (function)
2320 {
2321         initShaderSources();
2322 }
2323
2324 TextureQueryCase::~TextureQueryCase (void)
2325 {
2326 }
2327
2328 TestInstance* TextureQueryCase::createInstance (Context& context) const
2329 {
2330         switch (m_function)
2331         {
2332                 case QUERYFUNCTION_TEXTURESIZE:                         return new TextureSizeInstance(context, m_isVertexCase, m_textureSpec);
2333                 case QUERYFUNCTION_TEXTUREQUERYLOD:                     return new TextureQueryLodInstance(context, m_isVertexCase, m_textureSpec);
2334                 case QUERYFUNCTION_TEXTUREQUERYLEVELS:          return new TextureQueryLevelsInstance(context, m_isVertexCase, m_textureSpec);
2335                 case QUERYFUNCTION_TEXTURESAMPLES:                      return new TextureSamplesInstance(context, m_isVertexCase, m_textureSpec);
2336                 default:
2337                         DE_ASSERT(false);
2338                         return DE_NULL;
2339         }
2340 }
2341
2342 void TextureQueryCase::initShaderSources (void)
2343 {
2344         std::ostringstream              vert;
2345         std::ostringstream              frag;
2346         std::ostringstream&             op                      = m_isVertexCase ? vert : frag;
2347         glu::GLSLVersion                version         = glu::GLSL_VERSION_LAST;
2348
2349         DE_ASSERT(m_function != QUERYFUNCTION_TEXTUREQUERYLOD || !m_isVertexCase);
2350
2351         switch (m_function)
2352         {
2353                 case QUERYFUNCTION_TEXTURESIZE:
2354                         if (m_textureSpec.type == TEXTURETYPE_1D || m_textureSpec.type == TEXTURETYPE_1D_ARRAY || m_textureSpec.type == TEXTURETYPE_CUBE_ARRAY)
2355                                 version = glu::GLSL_VERSION_420;
2356                         else
2357                                 version = glu::GLSL_VERSION_310_ES;
2358                         break;
2359
2360                 case QUERYFUNCTION_TEXTUREQUERYLOD:
2361                         version = glu::GLSL_VERSION_420;
2362                         break;
2363
2364                 case QUERYFUNCTION_TEXTUREQUERYLEVELS:
2365                         version = glu::GLSL_VERSION_430;
2366                         break;
2367
2368                 case QUERYFUNCTION_TEXTURESAMPLES:
2369                         version = glu::GLSL_VERSION_450;
2370                         break;
2371
2372                 default:
2373                         DE_ASSERT(false);
2374                         break;
2375         }
2376
2377         vert << glu::getGLSLVersionDeclaration(version) << "\n"
2378                  << "layout(location = 0) in highp vec4 a_position;\n";
2379
2380         frag << glu::getGLSLVersionDeclaration(version) << "\n"
2381                  << "layout(location = 0) out mediump vec4 o_color;\n";
2382
2383         if (m_isVertexCase)
2384         {
2385                 vert << "layout(location = 0) out mediump vec4 v_color;\n";
2386                 frag << "layout(location = 0) in mediump vec4 v_color;\n";
2387         }
2388
2389         if (m_function == QUERYFUNCTION_TEXTUREQUERYLOD)
2390         {
2391                 const int               texCoordComps   = getQueryLodFuncTextCoordComps(m_textureSpec.type);
2392                 const char*             coordTypeName   = glu::getDataTypeName(glu::getDataTypeFloatVec(texCoordComps));
2393
2394                 vert << "layout (location = 1) in highp " << coordTypeName << " a_texCoord;\n";
2395                 vert << "layout (location = 0) out highp " << coordTypeName << " v_texCoord;\n";
2396                 frag << "layout (location = 0) in highp " << coordTypeName << " v_texCoord;\n";
2397         }
2398
2399         // uniforms
2400         op << "layout(set = 0, binding = 0) uniform highp " << m_samplerTypeStr << " u_sampler;\n";
2401         if (m_function == QUERYFUNCTION_TEXTURESIZE)
2402                 op << "layout(set = 0, binding = 1) uniform buf0 { highp int u_lod; };\n";
2403
2404         if (version != glu::GLSL_VERSION_310_ES)
2405                 vert << "out gl_PerVertex {\n"
2406                          << "\tvec4 gl_Position;\n"
2407                          << "};\n";
2408
2409         vert << "\nvoid main()\n{\n"
2410                  << "\tgl_Position = a_position;\n";
2411         frag << "\nvoid main()\n{\n";
2412
2413         if (m_isVertexCase)
2414                 vert << "\tv_color = ";
2415         else
2416                 frag << "\to_color = ";
2417
2418         // op
2419         {
2420                 op << "vec4(";
2421
2422                 switch (m_function)
2423                 {
2424                         case QUERYFUNCTION_TEXTURESIZE:
2425                         {
2426                                 const int               resultComponents        = glu::getDataTypeScalarSize(getTextureSizeFuncResultType(m_textureSpec.type));
2427
2428                                 op << "textureSize(u_sampler, u_lod)";
2429                                 for (int ndx = 0; ndx < 3 - resultComponents; ndx++)
2430                                         op << ", 0.0";
2431                                 op << ", 1.0";
2432
2433                                 break;
2434                         }
2435
2436                         case QUERYFUNCTION_TEXTUREQUERYLOD:
2437                                 op << "textureQueryLod(u_sampler, v_texCoord), 0.0, 1.0";
2438                                 break;
2439
2440                         case QUERYFUNCTION_TEXTUREQUERYLEVELS:
2441                                 op << "textureQueryLevels(u_sampler), 0.0, 0.0, 1.0";
2442                                 break;
2443
2444                         case QUERYFUNCTION_TEXTURESAMPLES:
2445                                 op << "textureSamples(u_sampler), 0.0, 0.0, 1.0";
2446                                 break;
2447
2448                         default:
2449                                 DE_ASSERT(false);
2450                                 break;
2451                 }
2452
2453                 op << ");\n";
2454         }
2455
2456         if (m_isVertexCase)
2457                 frag << "\to_color = v_color;\n";
2458
2459         if (m_function == QUERYFUNCTION_TEXTUREQUERYLOD)
2460                 vert << "\tv_texCoord = a_texCoord;\n";
2461
2462         vert << "}\n";
2463         frag << "}\n";
2464
2465         m_vertShaderSource = vert.str();
2466         m_fragShaderSource = frag.str();
2467 }
2468
2469 class ShaderTextureFunctionTests : public tcu::TestCaseGroup
2470 {
2471 public:
2472                                                                         ShaderTextureFunctionTests              (tcu::TestContext& context);
2473         virtual                                                 ~ShaderTextureFunctionTests             (void);
2474         virtual void                                    init                                                    (void);
2475
2476 private:
2477                                                                         ShaderTextureFunctionTests              (const ShaderTextureFunctionTests&);            // not allowed!
2478         ShaderTextureFunctionTests&             operator=                                               (const ShaderTextureFunctionTests&);            // not allowed!
2479 };
2480
2481 ShaderTextureFunctionTests::ShaderTextureFunctionTests (tcu::TestContext& context)
2482         : TestCaseGroup(context, "texture_functions", "Texture Access Function Tests")
2483 {
2484 }
2485
2486 ShaderTextureFunctionTests::~ShaderTextureFunctionTests (void)
2487 {
2488 }
2489
2490 enum CaseFlags
2491 {
2492         VERTEX          = (1<<0),
2493         FRAGMENT        = (1<<1),
2494         BOTH            = VERTEX|FRAGMENT
2495 };
2496
2497 struct TexFuncCaseSpec
2498 {
2499         const char*                     name;
2500         TextureLookupSpec       lookupSpec;
2501         TextureSpec                     texSpec;
2502         TexEvalFunc                     evalFunc;
2503         deUint32                        flags;
2504 };
2505
2506 #define CASE_SPEC(NAME, FUNC, MINCOORD, MAXCOORD, USEBIAS, MINLOD, MAXLOD, USEOFFSET, OFFSET, TEXSPEC, EVALFUNC, FLAGS) \
2507         { #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 }
2508 #define GRAD_CASE_SPEC(NAME, FUNC, MINCOORD, MAXCOORD, MINDX, MAXDX, MINDY, MAXDY, USEOFFSET, OFFSET, TEXSPEC, EVALFUNC, FLAGS) \
2509         { #NAME, TextureLookupSpec(FUNC, MINCOORD, MAXCOORD, false, 0.0f, 0.0f, MINDX, MAXDX, MINDY, MAXDY, USEOFFSET, OFFSET), TEXSPEC, EVALFUNC, FLAGS }
2510
2511 class SparseShaderTextureFunctionInstance : public ShaderTextureFunctionInstance
2512 {
2513 public:
2514                                 SparseShaderTextureFunctionInstance             (Context&                                       context,
2515                                                                                                                 const bool                                      isVertexCase,
2516                                                                                                                 const ShaderEvaluator&          evaluator,
2517                                                                                                                 const UniformSetup&                     uniformSetup,
2518                                                                                                                 const TextureLookupSpec&        lookupSpec,
2519                                                                                                                 const TextureSpec&                      textureSpec,
2520                                                                                                                 const TexLookupParams&          lookupParams,
2521                                                                                                                 const ImageBackingMode          imageBackingMode = IMAGE_BACKING_MODE_SPARSE);
2522         virtual         ~SparseShaderTextureFunctionInstance    (void);
2523 };
2524
2525 SparseShaderTextureFunctionInstance::SparseShaderTextureFunctionInstance (Context&                                      context,
2526                                                                                                                                                  const bool                                     isVertexCase,
2527                                                                                                                                                  const ShaderEvaluator&         evaluator,
2528                                                                                                                                                  const UniformSetup&            uniformSetup,
2529                                                                                                                                                  const TextureLookupSpec&       lookupSpec,
2530                                                                                                                                                  const TextureSpec&                     textureSpec,
2531                                                                                                                                                  const TexLookupParams&         lookupParams,
2532                                                                                                                                                  const ImageBackingMode         imageBackingMode)
2533         : ShaderTextureFunctionInstance (context, isVertexCase, evaluator, uniformSetup, lookupSpec, textureSpec, lookupParams, imageBackingMode)
2534 {
2535 }
2536
2537 SparseShaderTextureFunctionInstance::~SparseShaderTextureFunctionInstance (void)
2538 {
2539 }
2540
2541 class SparseShaderTextureFunctionCase : public ShaderTextureFunctionCase
2542 {
2543 public:
2544                                                         SparseShaderTextureFunctionCase         (tcu::TestContext&                      testCtx,
2545                                                                                                                                 const std::string&                      name,
2546                                                                                                                                 const std::string&                      desc,
2547                                                                                                                                 const TextureLookupSpec&        lookup,
2548                                                                                                                                 const TextureSpec&                      texture,
2549                                                                                                                                 TexEvalFunc                                     evalFunc,
2550                                                                                                                                 bool                                            isVertexCase);
2551
2552         virtual                                 ~SparseShaderTextureFunctionCase        (void);
2553
2554         virtual TestInstance*   createInstance                                          (Context& context) const;
2555 protected:
2556         void                                    initShaderSources                                       (void);
2557 };
2558
2559 SparseShaderTextureFunctionCase::SparseShaderTextureFunctionCase (tcu::TestContext&                             testCtx,
2560                                                                                                                                   const std::string&                    name,
2561                                                                                                                                   const std::string&                    desc,
2562                                                                                                                                   const TextureLookupSpec&              lookup,
2563                                                                                                                                   const TextureSpec&                    texture,
2564                                                                                                                                   TexEvalFunc                                   evalFunc,
2565                                                                                                                                   bool                                                  isVertexCase)
2566         : ShaderTextureFunctionCase             (testCtx, name, desc, lookup, texture, evalFunc, isVertexCase)
2567 {
2568         initShaderSources();
2569 }
2570
2571 void SparseShaderTextureFunctionCase::initShaderSources (void)
2572 {
2573         const Function                          function                        = m_lookupSpec.function;
2574         const bool                                      isVtxCase                       = m_isVertexCase;
2575         const bool                                      isProj                          = functionHasProj(function);
2576         const bool                                      isGrad                          = functionHasGrad(function);
2577         const bool                                      isShadow                        = m_textureSpec.sampler.compare != tcu::Sampler::COMPAREMODE_NONE;
2578         const bool                                      is2DProj4                       = !isShadow && m_textureSpec.type == TEXTURETYPE_2D && (function == FUNCTION_TEXTUREPROJ || function == FUNCTION_TEXTUREPROJLOD || function == FUNCTION_TEXTUREPROJGRAD);
2579         const bool                                      isIntCoord                      = function == FUNCTION_TEXELFETCH;
2580         const bool                                      hasLodBias                      = functionHasLod(m_lookupSpec.function) || m_lookupSpec.useBias;
2581         const int                                       texCoordComps           = m_textureSpec.type == TEXTURETYPE_2D ? 2 : 3;
2582         const int                                       extraCoordComps         = (isProj ? (is2DProj4 ? 2 : 1) : 0) + (isShadow ? 1 : 0);
2583         const glu::DataType                     coordType                       = glu::getDataTypeFloatVec(texCoordComps+extraCoordComps);
2584         const glu::Precision            coordPrec                       = glu::PRECISION_HIGHP;
2585         const char*                                     coordTypeName           = glu::getDataTypeName(coordType);
2586         const char*                                     coordPrecName           = glu::getPrecisionName(coordPrec);
2587         const tcu::TextureFormat        texFmt                          = glu::mapGLInternalFormat(m_textureSpec.format);
2588         glu::DataType                           samplerType                     = glu::TYPE_LAST;
2589         const glu::DataType                     gradType                        = (m_textureSpec.type == TEXTURETYPE_CUBE_MAP || m_textureSpec.type == TEXTURETYPE_3D) ? glu::TYPE_FLOAT_VEC3 : glu::TYPE_FLOAT_VEC2;
2590         const char*                                     gradTypeName            = glu::getDataTypeName(gradType);
2591         const char*                                     baseFuncName            = DE_NULL;
2592
2593         DE_ASSERT(!isGrad || !hasLodBias);
2594
2595         switch (m_textureSpec.type)
2596         {
2597                 case TEXTURETYPE_2D:            samplerType = isShadow ? glu::TYPE_SAMPLER_2D_SHADOW            : glu::getSampler2DType(texFmt);                break;
2598                 case TEXTURETYPE_CUBE_MAP:      samplerType = isShadow ? glu::TYPE_SAMPLER_CUBE_SHADOW          : glu::getSamplerCubeType(texFmt);              break;
2599                 case TEXTURETYPE_2D_ARRAY:      samplerType = isShadow ? glu::TYPE_SAMPLER_2D_ARRAY_SHADOW      : glu::getSampler2DArrayType(texFmt);   break;
2600                 case TEXTURETYPE_3D:            DE_ASSERT(!isShadow); samplerType = glu::getSampler3DType(texFmt);                                                                      break;
2601                 default:
2602                         DE_ASSERT(DE_FALSE);
2603         }
2604
2605         // Not supported cases
2606         switch (m_lookupSpec.function)
2607         {
2608                 case FUNCTION_TEXTURE:                  baseFuncName = "sparseTexture";                 break;
2609                 case FUNCTION_TEXTURELOD:               baseFuncName = "sparseTextureLod";              break;
2610                 case FUNCTION_TEXTUREGRAD:              baseFuncName = "sparseTextureGrad";             break;
2611                 case FUNCTION_TEXELFETCH:               baseFuncName = "sparseTexelFetch";              break;
2612                 default:
2613                         DE_ASSERT(DE_FALSE);
2614         }
2615
2616         std::ostringstream      vert;
2617         std::ostringstream      frag;
2618         std::ostringstream&     op              = isVtxCase ? vert : frag;
2619
2620         vert << "#version 450\n"
2621                  << "#extension GL_ARB_sparse_texture2 : require\n"
2622                  << "layout(location = 0) in highp vec4 a_position;\n"
2623                  << "layout(location = 4) in " << coordPrecName << " " << coordTypeName << " a_in0;\n";
2624
2625         if (isGrad)
2626         {
2627                 vert << "layout(location = 5) in " << coordPrecName << " " << gradTypeName << " a_in1;\n";
2628                 vert << "layout(location = 6) in " << coordPrecName << " " << gradTypeName << " a_in2;\n";
2629         }
2630         else if (hasLodBias)
2631                 vert << "layout(location = 5) in " << coordPrecName << " float a_in1;\n";
2632
2633         frag << "#version 450\n"
2634                  << "#extension GL_ARB_sparse_texture2 : require\n"
2635                  << "layout(location = 0) out mediump vec4 o_color;\n";
2636
2637         if (isVtxCase)
2638         {
2639                 vert << "layout(location = 0) out mediump vec4 v_color;\n";
2640                 frag << "layout(location = 0) in mediump vec4 v_color;\n";
2641         }
2642         else
2643         {
2644                 vert << "layout(location = 0) out " << coordPrecName << " " << coordTypeName << " v_texCoord;\n";
2645                 frag << "layout(location = 0) in " << coordPrecName << " " << coordTypeName << " v_texCoord;\n";
2646
2647                 if (isGrad)
2648                 {
2649                         vert << "layout(location = 1) out " << coordPrecName << " " << gradTypeName << " v_gradX;\n";
2650                         vert << "layout(location = 2) out " << coordPrecName << " " << gradTypeName << " v_gradY;\n";
2651                         frag << "layout(location = 1) in " << coordPrecName << " " << gradTypeName << " v_gradX;\n";
2652                         frag << "layout(location = 2) in " << coordPrecName << " " << gradTypeName << " v_gradY;\n";
2653                 }
2654                 else if (hasLodBias)
2655                 {
2656                         vert << "layout(location = 1) out " << coordPrecName << " float v_lodBias;\n";
2657                         frag << "layout(location = 1) in " << coordPrecName << " float v_lodBias;\n";
2658                 }
2659         }
2660
2661         // Uniforms
2662         op << "layout(set = 0, binding = 0) uniform highp " << glu::getDataTypeName(samplerType) << " u_sampler;\n"
2663            << "layout(set = 0, binding = 1) uniform buf0 { highp vec4 u_scale; };\n"
2664            << "layout(set = 0, binding = 2) uniform buf1 { highp vec4 u_bias; };\n";
2665
2666         vert << "out gl_PerVertex {\n"
2667                  << "   vec4 gl_Position;\n"
2668                  << "};\n";
2669         vert << "\nvoid main()\n{\n"
2670                  << "\tgl_Position = a_position;\n";
2671         frag << "\nvoid main()\n{\n";
2672
2673         // Op.
2674         {
2675                 // Texel declaration
2676                 if (isShadow)
2677                         op << "\tfloat texel;\n";
2678                 else
2679                         op << "\tvec4 texel;\n";
2680
2681                 const char*     const texCoord  = isVtxCase ? "a_in0" : "v_texCoord";
2682                 const char* const gradX         = isVtxCase ? "a_in1" : "v_gradX";
2683                 const char* const gradY         = isVtxCase ? "a_in2" : "v_gradY";
2684                 const char*     const lodBias   = isVtxCase ? "a_in1" : "v_lodBias";
2685
2686                 op << "\tint success = " << baseFuncName;
2687
2688                 if (m_lookupSpec.useOffset)
2689                         op << "Offset";
2690
2691                 op << "ARB(u_sampler, ";
2692
2693                 if (isIntCoord)
2694                         op << "ivec" << (texCoordComps+extraCoordComps) << "(";
2695
2696                 op << texCoord;
2697
2698                 if (isIntCoord)
2699                         op << ")";
2700
2701                 if (isGrad)
2702                         op << ", " << gradX << ", " << gradY;
2703
2704                 if (functionHasLod(function))
2705                 {
2706                         if (isIntCoord)
2707                                 op << ", int(" << lodBias << ")";
2708                         else
2709                                 op << ", " << lodBias;
2710                 }
2711
2712                 if (m_lookupSpec.useOffset)
2713                 {
2714                         int offsetComps = m_textureSpec.type == TEXTURETYPE_3D ? 3 : 2;
2715
2716                         op << ", ivec" << offsetComps << "(";
2717                         for (int ndx = 0; ndx < offsetComps; ndx++)
2718                         {
2719                                 if (ndx != 0)
2720                                         op << ", ";
2721                                 op << m_lookupSpec.offset[ndx];
2722                         }
2723                         op << ")";
2724                 }
2725
2726                 op << ", texel";
2727
2728                 if (m_lookupSpec.useBias)
2729                         op << ", " << lodBias;
2730
2731                 op << ");\n";
2732
2733                 // Check sparse validity, and handle each case
2734                 op << "\tif (sparseTexelsResidentARB(success))\n";
2735
2736                 if (isVtxCase)
2737                         vert << "\t\tv_color = ";
2738                 else
2739                         frag << "\t\to_color = ";
2740
2741                 if (isShadow)
2742                         op << "vec4(texel, 0.0, 0.0, 1.0);\n";
2743                 else
2744                         op << "vec4(texel * u_scale + u_bias);\n";
2745
2746                 op << "\telse\n";
2747
2748                 // This color differs from the used colors
2749                 if (isVtxCase)
2750                         vert << "\t\tv_color = vec4(0.54117647058, 0.16862745098, 0.8862745098, 1.0);\n";
2751                 else
2752                         frag << "\t\to_color = vec4(0.54117647058, 0.16862745098, 0.8862745098, 1.0);\n";
2753         }
2754
2755         if (isVtxCase)
2756                 frag << "\to_color = v_color;\n";
2757         else
2758         {
2759                 vert << "\tv_texCoord = a_in0;\n";
2760
2761                 if (isGrad)
2762                 {
2763                         vert << "\tv_gradX = a_in1;\n";
2764                         vert << "\tv_gradY = a_in2;\n";
2765                 }
2766                 else if (hasLodBias)
2767                         vert << "\tv_lodBias = a_in1;\n";
2768         }
2769
2770         vert << "}\n";
2771         frag << "}\n";
2772
2773         m_vertShaderSource = vert.str();
2774         m_fragShaderSource = frag.str();
2775 }
2776
2777 SparseShaderTextureFunctionCase::~SparseShaderTextureFunctionCase ()
2778 {
2779 }
2780
2781 TestInstance* SparseShaderTextureFunctionCase::createInstance (Context& context) const
2782 {
2783         DE_ASSERT(m_evaluator != DE_NULL);
2784         DE_ASSERT(m_uniformSetup != DE_NULL);
2785         return new SparseShaderTextureFunctionInstance(context, m_isVertexCase, *m_evaluator, *m_uniformSetup, m_lookupSpec, m_textureSpec, m_lookupParams);
2786 }
2787
2788 static void createCaseGroup (tcu::TestCaseGroup* parent, const char* groupName, const char* groupDesc, const TexFuncCaseSpec* cases, int numCases)
2789 {
2790         de::MovePtr<tcu::TestCaseGroup> group   (new tcu::TestCaseGroup(parent->getTestContext(), groupName, groupDesc));
2791
2792         for (int ndx = 0; ndx < numCases; ndx++)
2793         {
2794                 std::string name = cases[ndx].name;
2795                 if (cases[ndx].flags & VERTEX)
2796                 {
2797                         if (!functionHasProj(cases[ndx].lookupSpec.function))
2798                                 group->addChild(new SparseShaderTextureFunctionCase(parent->getTestContext(), ("sparse_" + name + "_vertex"),   "", cases[ndx].lookupSpec, cases[ndx].texSpec, cases[ndx].evalFunc, true ));
2799                         group->addChild(new ShaderTextureFunctionCase(parent->getTestContext(), (name + "_vertex"),   "", cases[ndx].lookupSpec, cases[ndx].texSpec, cases[ndx].evalFunc, true ));
2800                 }
2801
2802                 if (cases[ndx].flags & FRAGMENT)
2803                 {
2804                         if (!functionHasProj(cases[ndx].lookupSpec.function))
2805                                 group->addChild(new SparseShaderTextureFunctionCase(parent->getTestContext(), ("sparse_" + name + "_fragment"), "", cases[ndx].lookupSpec, cases[ndx].texSpec, cases[ndx].evalFunc, false));
2806                         group->addChild(new ShaderTextureFunctionCase(parent->getTestContext(), (name + "_fragment"), "", cases[ndx].lookupSpec, cases[ndx].texSpec, cases[ndx].evalFunc, false));
2807                 }
2808         }
2809
2810         parent->addChild(group.release());
2811 }
2812
2813 void ShaderTextureFunctionTests::init (void)
2814 {
2815         // Samplers
2816         static const tcu::Sampler       samplerNearestNoMipmap  (tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
2817                                                                                                                  tcu::Sampler::NEAREST, tcu::Sampler::NEAREST,
2818                                                                                                                  0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_NONE,
2819                                                                                                                  0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
2820         static const tcu::Sampler       samplerLinearNoMipmap   (tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
2821                                                                                                                  tcu::Sampler::LINEAR, tcu::Sampler::LINEAR,
2822                                                                                                                  0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_NONE,
2823                                                                                                                  0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
2824         static const tcu::Sampler       samplerNearestMipmap    (tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
2825                                                                                                                  tcu::Sampler::NEAREST_MIPMAP_NEAREST, tcu::Sampler::NEAREST,
2826                                                                                                                  0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_NONE,
2827                                                                                                                  0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
2828         static const tcu::Sampler       samplerLinearMipmap             (tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
2829                                                                                                                  tcu::Sampler::LINEAR_MIPMAP_NEAREST, tcu::Sampler::LINEAR,
2830                                                                                                                  0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_NONE,
2831                                                                                                                  0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
2832
2833         static const tcu::Sampler       samplerShadowNoMipmap   (tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
2834                                                                                                                  tcu::Sampler::NEAREST, tcu::Sampler::NEAREST,
2835                                                                                                                  0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_LESS,
2836                                                                                                                  0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
2837         static const tcu::Sampler       samplerShadowMipmap             (tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
2838                                                                                                                  tcu::Sampler::NEAREST_MIPMAP_NEAREST, tcu::Sampler::NEAREST,
2839                                                                                                                  0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_LESS,
2840                                                                                                                  0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
2841
2842         static const tcu::Sampler       samplerTexelFetch               (tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
2843                                                                                                                  tcu::Sampler::NEAREST_MIPMAP_NEAREST, tcu::Sampler::NEAREST,
2844                                                                                                                  00.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_NONE,
2845                                                                                                                  0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
2846
2847         // Default textures.
2848         //                                                                                              Type                                    Format                                  W               H               D       L       Sampler
2849         static const TextureSpec tex2DFixed                             (TEXTURETYPE_2D,                GL_RGBA8,                               256,    256,    1,      1,      samplerLinearNoMipmap);
2850         static const TextureSpec tex2DFloat                             (TEXTURETYPE_2D,                GL_RGBA16F,                             256,    256,    1,      1,      samplerLinearNoMipmap);
2851         static const TextureSpec tex2DInt                               (TEXTURETYPE_2D,                GL_RGBA8I,                              256,    256,    1,      1,      samplerNearestNoMipmap);
2852         static const TextureSpec tex2DUint                              (TEXTURETYPE_2D,                GL_RGBA8UI,                             256,    256,    1,      1,      samplerNearestNoMipmap);
2853         static const TextureSpec tex2DMipmapFixed               (TEXTURETYPE_2D,                GL_RGBA8,                               256,    256,    1,      9,      samplerLinearMipmap);
2854         static const TextureSpec tex2DMipmapFloat               (TEXTURETYPE_2D,                GL_RGBA16F,                             256,    256,    1,      9,      samplerLinearMipmap);
2855         static const TextureSpec tex2DMipmapInt                 (TEXTURETYPE_2D,                GL_RGBA8I,                              256,    256,    1,      9,      samplerNearestMipmap);
2856         static const TextureSpec tex2DMipmapUint                (TEXTURETYPE_2D,                GL_RGBA8UI,                             256,    256,    1,      9,      samplerNearestMipmap);
2857
2858         static const TextureSpec tex2DShadow                    (TEXTURETYPE_2D,                GL_DEPTH_COMPONENT16,   256,    256,    1,      1,      samplerShadowNoMipmap);
2859         static const TextureSpec tex2DMipmapShadow              (TEXTURETYPE_2D,                GL_DEPTH_COMPONENT16,   256,    256,    1,      9,      samplerShadowMipmap);
2860
2861         static const TextureSpec tex2DTexelFetchFixed   (TEXTURETYPE_2D,                GL_RGBA8,                               256,    256,    1,      9,      samplerTexelFetch);
2862         static const TextureSpec tex2DTexelFetchFloat   (TEXTURETYPE_2D,                GL_RGBA16F,                             256,    256,    1,      9,      samplerTexelFetch);
2863         static const TextureSpec tex2DTexelFetchInt             (TEXTURETYPE_2D,                GL_RGBA8I,                              256,    256,    1,      9,      samplerTexelFetch);
2864         static const TextureSpec tex2DTexelFetchUint    (TEXTURETYPE_2D,                GL_RGBA8UI,                             256,    256,    1,      9,      samplerTexelFetch);
2865
2866         static const TextureSpec texCubeFixed                   (TEXTURETYPE_CUBE_MAP,  GL_RGBA8,       256,    256,    1,      1,      samplerLinearNoMipmap);
2867         static const TextureSpec texCubeFloat                   (TEXTURETYPE_CUBE_MAP,  GL_RGBA16F,     256,    256,    1,      1,      samplerLinearNoMipmap);
2868         static const TextureSpec texCubeInt                             (TEXTURETYPE_CUBE_MAP,  GL_RGBA8I,      256,    256,    1,      1,      samplerNearestNoMipmap);
2869         static const TextureSpec texCubeUint                    (TEXTURETYPE_CUBE_MAP,  GL_RGBA8UI,     256,    256,    1,      1,      samplerNearestNoMipmap);
2870         static const TextureSpec texCubeMipmapFixed             (TEXTURETYPE_CUBE_MAP,  GL_RGBA8,       256,    256,    1,      9,      samplerLinearMipmap);
2871         static const TextureSpec texCubeMipmapFloat             (TEXTURETYPE_CUBE_MAP,  GL_RGBA16F,     128,    128,    1,      8,      samplerLinearMipmap);
2872         static const TextureSpec texCubeMipmapInt               (TEXTURETYPE_CUBE_MAP,  GL_RGBA8I,      256,    256,    1,      9,      samplerNearestMipmap);
2873         static const TextureSpec texCubeMipmapUint              (TEXTURETYPE_CUBE_MAP,  GL_RGBA8UI,     256,    256,    1,      9,      samplerNearestMipmap);
2874
2875         static const TextureSpec texCubeShadow                  (TEXTURETYPE_CUBE_MAP,  GL_DEPTH_COMPONENT16,   256,    256,    1,      1,      samplerShadowNoMipmap);
2876         static const TextureSpec texCubeMipmapShadow    (TEXTURETYPE_CUBE_MAP,  GL_DEPTH_COMPONENT16,   256,    256,    1,      9,      samplerShadowMipmap);
2877
2878         static const TextureSpec tex2DArrayFixed                (TEXTURETYPE_2D_ARRAY,  GL_RGBA8,       128,    128,    4,      1,      samplerLinearNoMipmap);
2879         static const TextureSpec tex2DArrayFloat                (TEXTURETYPE_2D_ARRAY,  GL_RGBA16F,     128,    128,    4,      1,      samplerLinearNoMipmap);
2880         static const TextureSpec tex2DArrayInt                  (TEXTURETYPE_2D_ARRAY,  GL_RGBA8I,      128,    128,    4,      1,      samplerNearestNoMipmap);
2881         static const TextureSpec tex2DArrayUint                 (TEXTURETYPE_2D_ARRAY,  GL_RGBA8UI,     128,    128,    4,      1,      samplerNearestNoMipmap);
2882         static const TextureSpec tex2DArrayMipmapFixed  (TEXTURETYPE_2D_ARRAY,  GL_RGBA8,       128,    128,    4,      8,      samplerLinearMipmap);
2883         static const TextureSpec tex2DArrayMipmapFloat  (TEXTURETYPE_2D_ARRAY,  GL_RGBA16F,     128,    128,    4,      8,      samplerLinearMipmap);
2884         static const TextureSpec tex2DArrayMipmapInt    (TEXTURETYPE_2D_ARRAY,  GL_RGBA8I,      128,    128,    4,      8,      samplerNearestMipmap);
2885         static const TextureSpec tex2DArrayMipmapUint   (TEXTURETYPE_2D_ARRAY,  GL_RGBA8UI,     128,    128,    4,      8,      samplerNearestMipmap);
2886
2887         static const TextureSpec tex2DArrayShadow               (TEXTURETYPE_2D_ARRAY,  GL_DEPTH_COMPONENT16,   128,    128,    4,      1,      samplerShadowNoMipmap);
2888         static const TextureSpec tex2DArrayMipmapShadow (TEXTURETYPE_2D_ARRAY,  GL_DEPTH_COMPONENT16,   128,    128,    4,      8,      samplerShadowMipmap);
2889
2890         static const TextureSpec tex2DArrayTexelFetchFixed      (TEXTURETYPE_2D_ARRAY,  GL_RGBA8,       128,    128,    4,      8,      samplerTexelFetch);
2891         static const TextureSpec tex2DArrayTexelFetchFloat      (TEXTURETYPE_2D_ARRAY,  GL_RGBA16F,     128,    128,    4,      8,      samplerTexelFetch);
2892         static const TextureSpec tex2DArrayTexelFetchInt        (TEXTURETYPE_2D_ARRAY,  GL_RGBA8I,      128,    128,    4,      8,      samplerTexelFetch);
2893         static const TextureSpec tex2DArrayTexelFetchUint       (TEXTURETYPE_2D_ARRAY,  GL_RGBA8UI,     128,    128,    4,      8,      samplerTexelFetch);
2894
2895         static const TextureSpec tex3DFixed                             (TEXTURETYPE_3D,                GL_RGBA8,       64,             32,             32,     1,      samplerLinearNoMipmap);
2896         static const TextureSpec tex3DFloat                             (TEXTURETYPE_3D,                GL_RGBA16F,     64,             32,             32,     1,      samplerLinearNoMipmap);
2897         static const TextureSpec tex3DInt                               (TEXTURETYPE_3D,                GL_RGBA8I,      64,             32,             32,     1,      samplerNearestNoMipmap);
2898         static const TextureSpec tex3DUint                              (TEXTURETYPE_3D,                GL_RGBA8UI,     64,             32,             32,     1,      samplerNearestNoMipmap);
2899         static const TextureSpec tex3DMipmapFixed               (TEXTURETYPE_3D,                GL_RGBA8,       64,             32,             32,     7,      samplerLinearMipmap);
2900         static const TextureSpec tex3DMipmapFloat               (TEXTURETYPE_3D,                GL_RGBA16F,     64,             32,             32,     7,      samplerLinearMipmap);
2901         static const TextureSpec tex3DMipmapInt                 (TEXTURETYPE_3D,                GL_RGBA8I,      64,             32,             32,     7,      samplerNearestMipmap);
2902         static const TextureSpec tex3DMipmapUint                (TEXTURETYPE_3D,                GL_RGBA8UI,     64,             32,             32,     7,      samplerNearestMipmap);
2903
2904         static const TextureSpec tex3DTexelFetchFixed   (TEXTURETYPE_3D,                GL_RGBA8,       64,             32,             32,     7,      samplerTexelFetch);
2905         static const TextureSpec tex3DTexelFetchFloat   (TEXTURETYPE_3D,                GL_RGBA16F,     64,             32,             32,     7,      samplerTexelFetch);
2906         static const TextureSpec tex3DTexelFetchInt             (TEXTURETYPE_3D,                GL_RGBA8I,      64,             32,             32,     7,      samplerTexelFetch);
2907         static const TextureSpec tex3DTexelFetchUint    (TEXTURETYPE_3D,                GL_RGBA8UI,     64,             32,             32,     7,      samplerTexelFetch);
2908
2909         static const TextureSpec tex1DFixed                             (TEXTURETYPE_1D,                GL_RGBA8,                               256,    1,      1,      1,      samplerLinearNoMipmap);
2910         static const TextureSpec tex1DFloat                             (TEXTURETYPE_1D,                GL_RGBA16F,                             256,    1,      1,      1,      samplerLinearNoMipmap);
2911         static const TextureSpec tex1DInt                               (TEXTURETYPE_1D,                GL_RGBA8I,                              256,    1,      1,      1,      samplerNearestNoMipmap);
2912         static const TextureSpec tex1DUint                              (TEXTURETYPE_1D,                GL_RGBA8UI,                             256,    1,      1,      1,      samplerNearestNoMipmap);
2913         static const TextureSpec tex1DMipmapFixed               (TEXTURETYPE_1D,                GL_RGBA8,                               256,    1,      1,      9,      samplerLinearMipmap);
2914         static const TextureSpec tex1DMipmapFloat               (TEXTURETYPE_1D,                GL_RGBA16F,                             256,    1,      1,      9,      samplerLinearMipmap);
2915         static const TextureSpec tex1DMipmapInt                 (TEXTURETYPE_1D,                GL_RGBA8I,                              256,    1,      1,      9,      samplerNearestMipmap);
2916         static const TextureSpec tex1DMipmapUint                (TEXTURETYPE_1D,                GL_RGBA8UI,                             256,    1,      1,      9,      samplerNearestMipmap);
2917
2918         static const TextureSpec tex1DShadow                    (TEXTURETYPE_1D,                GL_DEPTH_COMPONENT16,   256,    1,      1,      1,      samplerShadowNoMipmap);
2919         static const TextureSpec tex1DMipmapShadow              (TEXTURETYPE_1D,                GL_DEPTH_COMPONENT16,   256,    1,      1,      9,      samplerShadowMipmap);
2920
2921         static const TextureSpec tex1DArrayFixed                (TEXTURETYPE_1D_ARRAY,  GL_RGBA8,       256,    1,      4,      1,      samplerLinearNoMipmap);
2922         static const TextureSpec tex1DArrayFloat                (TEXTURETYPE_1D_ARRAY,  GL_RGBA16F,     256,    1,      4,      1,      samplerLinearNoMipmap);
2923         static const TextureSpec tex1DArrayInt                  (TEXTURETYPE_1D_ARRAY,  GL_RGBA8I,      256,    1,      4,      1,      samplerNearestNoMipmap);
2924         static const TextureSpec tex1DArrayUint                 (TEXTURETYPE_1D_ARRAY,  GL_RGBA8UI,     256,    1,      4,      1,      samplerNearestNoMipmap);
2925         static const TextureSpec tex1DArrayMipmapFixed  (TEXTURETYPE_1D_ARRAY,  GL_RGBA8,       256,    1,      4,      9,      samplerLinearMipmap);
2926         static const TextureSpec tex1DArrayMipmapFloat  (TEXTURETYPE_1D_ARRAY,  GL_RGBA16F,     256,    1,      4,      9,      samplerLinearMipmap);
2927         static const TextureSpec tex1DArrayMipmapInt    (TEXTURETYPE_1D_ARRAY,  GL_RGBA8I,      256,    1,      4,      9,      samplerNearestMipmap);
2928         static const TextureSpec tex1DArrayMipmapUint   (TEXTURETYPE_1D_ARRAY,  GL_RGBA8UI,     256,    1,      4,      9,      samplerNearestMipmap);
2929
2930         static const TextureSpec tex1DArrayShadow               (TEXTURETYPE_1D_ARRAY,  GL_DEPTH_COMPONENT16,   256,    1,      4,      1,      samplerShadowNoMipmap);
2931         static const TextureSpec tex1DArrayMipmapShadow (TEXTURETYPE_1D_ARRAY,  GL_DEPTH_COMPONENT16,   256,    1,      4,      9,      samplerShadowMipmap);
2932
2933         static const TextureSpec texCubeArrayFixed                      (TEXTURETYPE_CUBE_ARRAY,        GL_RGBA8,       256,    256,    12,     1,      samplerLinearNoMipmap);
2934         static const TextureSpec texCubeArrayFloat                      (TEXTURETYPE_CUBE_ARRAY,        GL_RGBA16F,     256,    256,    12,     1,      samplerLinearNoMipmap);
2935         static const TextureSpec texCubeArrayInt                        (TEXTURETYPE_CUBE_ARRAY,        GL_RGBA8I,      256,    256,    12,     1,      samplerNearestNoMipmap);
2936         static const TextureSpec texCubeArrayUint                       (TEXTURETYPE_CUBE_ARRAY,        GL_RGBA8UI,     256,    256,    12,     1,      samplerNearestNoMipmap);
2937         static const TextureSpec texCubeArrayMipmapFixed        (TEXTURETYPE_CUBE_ARRAY,        GL_RGBA8,       256,    256,    12,     9,      samplerLinearMipmap);
2938         static const TextureSpec texCubeArrayMipmapFloat        (TEXTURETYPE_CUBE_ARRAY,        GL_RGBA16F,     128,    128,    12,     8,      samplerLinearMipmap);
2939         static const TextureSpec texCubeArrayMipmapInt          (TEXTURETYPE_CUBE_ARRAY,        GL_RGBA8I,      256,    256,    12,     9,      samplerNearestMipmap);
2940         static const TextureSpec texCubeArrayMipmapUint         (TEXTURETYPE_CUBE_ARRAY,        GL_RGBA8UI,     256,    256,    12,     9,      samplerNearestMipmap);
2941
2942         static const TextureSpec texCubeArrayShadow                     (TEXTURETYPE_CUBE_ARRAY,        GL_DEPTH_COMPONENT16,   256,    256,    12,     1,      samplerShadowNoMipmap);
2943         static const TextureSpec texCubeArrayMipmapShadow       (TEXTURETYPE_CUBE_ARRAY,        GL_DEPTH_COMPONENT16,   256,    256,    12,     9,      samplerShadowMipmap);
2944
2945         // texture() cases
2946         static const TexFuncCaseSpec textureCases[] =
2947         {
2948                 //                Name                                                  Function                        MinCoord                                                        MaxCoord                                                        Bias?   MinLod  MaxLod  Offset? Offset          Format                                  EvalFunc                                Flags
2949                 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),
2950                 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),
2951                 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),
2952                 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),
2953                 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),
2954                 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),
2955                 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),
2956                 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),
2957
2958                 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),
2959                 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),
2960                 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),
2961                 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),
2962
2963                 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),
2964                 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),
2965                 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),
2966                 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),
2967                 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),
2968                 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),
2969                 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),
2970                 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),
2971
2972                 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),
2973                 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),
2974                 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),
2975                 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),
2976
2977                 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),
2978                 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),
2979                 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),
2980                 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),
2981                 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),
2982                 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),
2983                 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),
2984                 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),
2985
2986                 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),
2987                 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),
2988                 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),
2989                 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),
2990
2991                 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),
2992                 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),
2993                 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),
2994                 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),
2995                 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),
2996                 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),
2997                 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),
2998                 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),
2999
3000                 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),
3001                 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),
3002                 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),
3003                 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),
3004
3005                 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),
3006                 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),
3007                 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),
3008
3009                 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),
3010                 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),
3011                 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),
3012
3013                 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),
3014                 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)
3015
3016                 // Not in spec.
3017 //              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)
3018         };
3019         createCaseGroup(this, "texture", "texture() Tests", textureCases, DE_LENGTH_OF_ARRAY(textureCases));
3020
3021         // textureOffset() cases
3022         // \note _bias variants are not using mipmap thanks to wide allowed range for LOD computation
3023         static const TexFuncCaseSpec textureOffsetCases[] =
3024         {
3025                 //                Name                                                  Function                        MinCoord                                                        MaxCoord                                                        Bias?   MinLod  MaxLod  Offset? Offset                          Format                                  EvalFunc                                                Flags
3026                 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),
3027                 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),
3028                 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),
3029                 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),
3030                 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),
3031                 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),
3032                 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),
3033                 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),
3034
3035                 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),
3036                 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),
3037                 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),
3038                 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),
3039
3040                 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),
3041                 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),
3042                 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),
3043                 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),
3044                 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),
3045                 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),
3046                 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),
3047                 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),
3048
3049                 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),
3050                 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),
3051                 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),
3052                 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),
3053
3054                 CASE_SPEC(sampler3d_fixed,                              FUNCTION_TEXTURE,       Vec4(-0.2f, -0.4f,  0.1f,  0.0f),       Vec4( 1.5f,  2.3f,  2.3f,  0.0f),       false,  0.0f,   0.0f,   true,   IVec3(-8, 7, 3),        tex3DFixed,                             evalTexture3DOffset,                    VERTEX),
3055                 CASE_SPEC(sampler3d_fixed,                              FUNCTION_TEXTURE,       Vec4(-0.2f, -0.4f,  0.1f,  0.0f),       Vec4( 1.5f,  2.3f,  2.3f,  0.0f),       false,  0.0f,   0.0f,   true,   IVec3(7, 3, -8),        tex3DMipmapFixed,               evalTexture3DOffset,                    FRAGMENT),
3056                 CASE_SPEC(sampler3d_float,                              FUNCTION_TEXTURE,       Vec4(-0.2f, -0.4f,  0.1f,  0.0f),       Vec4( 1.5f,  2.3f,  2.3f,  0.0f),       false,  0.0f,   0.0f,   true,   IVec3(3, -8, 7),        tex3DFloat,                             evalTexture3DOffset,                    VERTEX),
3057                 CASE_SPEC(sampler3d_float,                              FUNCTION_TEXTURE,       Vec4(-0.2f, -0.4f,  0.1f,  0.0f),       Vec4( 1.5f,  2.3f,  2.3f,  0.0f),       false,  0.0f,   0.0f,   true,   IVec3(-8, 7, 3),        tex3DMipmapFloat,               evalTexture3DOffset,                    FRAGMENT),
3058                 CASE_SPEC(isampler3d,                                   FUNCTION_TEXTURE,       Vec4(-0.2f, -0.4f,  0.1f,  0.0f),       Vec4( 1.5f,  2.3f,  2.3f,  0.0f),       false,  0.0f,   0.0f,   true,   IVec3(7, 3, -8),        tex3DInt,                               evalTexture3DOffset,                    VERTEX),
3059                 CASE_SPEC(isampler3d,                                   FUNCTION_TEXTURE,       Vec4(-0.2f, -0.4f,  0.1f,  0.0f),       Vec4( 1.5f,  2.3f,  2.3f,  0.0f),       false,  0.0f,   0.0f,   true,   IVec3(3, -8, 7),        tex3DMipmapInt,                 evalTexture3DOffset,                    FRAGMENT),
3060                 CASE_SPEC(usampler3d,                                   FUNCTION_TEXTURE,       Vec4(-0.2f, -0.4f,  0.1f,  0.0f),       Vec4( 1.5f,  2.3f,  2.3f,  0.0f),       false,  0.0f,   0.0f,   true,   IVec3(-8, 7, 3),        tex3DUint,                              evalTexture3DOffset,                    VERTEX),
3061                 CASE_SPEC(usampler3d,                                   FUNCTION_TEXTURE,       Vec4(-0.2f, -0.4f,  0.1f,  0.0f),       Vec4( 1.5f,  2.3f,  2.3f,  0.0f),       false,  0.0f,   0.0f,   true,   IVec3(7, 3, -8),        tex3DMipmapUint,                evalTexture3DOffset,                    FRAGMENT),
3062
3063                 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),
3064                 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),
3065                 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),
3066                 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),
3067
3068                 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),
3069                 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),
3070                 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)
3071         };
3072         createCaseGroup(this, "textureoffset", "textureOffset() Tests", textureOffsetCases, DE_LENGTH_OF_ARRAY(textureOffsetCases));
3073
3074         // textureProj() cases
3075         // \note Currently uses constant divider!
3076         static const TexFuncCaseSpec textureProjCases[] =
3077         {
3078                 //                Name                                                  Function                                MinCoord                                                        MaxCoord                                                        Bias?   MinLod  MaxLod  Offset? Offset          Format                                  EvalFunc                                Flags
3079                 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),
3080                 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),
3081                 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),
3082                 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),
3083                 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),
3084                 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),
3085                 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),
3086                 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),
3087
3088                 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),
3089                 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),
3090                 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),
3091                 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),
3092
3093                 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),
3094                 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),
3095                 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),
3096                 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),
3097                 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),
3098                 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),
3099                 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),
3100                 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),
3101
3102                 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),
3103                 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),
3104                 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),
3105                 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),
3106
3107                 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),
3108                 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),
3109                 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),
3110                 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),
3111                 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),
3112                 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),
3113                 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),
3114                 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),
3115
3116                 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),
3117                 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),
3118                 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),
3119                 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),
3120
3121                 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),
3122                 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),
3123                 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)
3124         };
3125         createCaseGroup(this, "textureproj", "textureProj() Tests", textureProjCases, DE_LENGTH_OF_ARRAY(textureProjCases));
3126
3127         // textureProjOffset() cases
3128         // \note Currently uses constant divider!
3129         static const TexFuncCaseSpec textureProjOffsetCases[] =
3130         {
3131                 //                Name                                                  Function                                MinCoord                                                        MaxCoord                                                        Bias?   MinLod  MaxLod  Offset? Offset                          Format                                  EvalFunc                                                Flags
3132                 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),
3133                 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),
3134                 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),
3135                 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),
3136                 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),
3137                 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),
3138                 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),
3139                 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),
3140
3141                 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),
3142                 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),
3143                 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),
3144                 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),
3145
3146                 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),
3147                 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),
3148                 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),
3149                 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),
3150                 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),
3151                 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),
3152                 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),
3153                 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),
3154
3155                 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),
3156                 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),
3157                 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),
3158                 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),
3159
3160                 CASE_SPEC(sampler3d_fixed,                              FUNCTION_TEXTUREPROJ,   Vec4(-0.3f, -0.6f,  0.0f,  1.5f),       Vec4(2.25f, 3.45f,  2.0f,  1.5f),       false,  0.0f,   0.0f,   true,   IVec3(-8, 7, 3),        tex3DFixed,                             evalTexture3DProjOffset,                VERTEX),
3161                 CASE_SPEC(sampler3d_fixed,                              FUNCTION_TEXTUREPROJ,   Vec4(-0.3f, -0.6f,  0.0f,  1.5f),       Vec4(2.25f, 3.45f,  2.0f,  1.5f),       false,  0.0f,   0.0f,   true,   IVec3(7, 3, -8),        tex3DMipmapFixed,               evalTexture3DProjOffset,                FRAGMENT),
3162                 CASE_SPEC(sampler3d_float,                              FUNCTION_TEXTUREPROJ,   Vec4(-0.3f, -0.6f,  0.0f,  1.5f),       Vec4(2.25f, 3.45f,  2.0f,  1.5f),       false,  0.0f,   0.0f,   true,   IVec3(3, -8, 7),        tex3DFloat,                             evalTexture3DProjOffset,                VERTEX),
3163                 CASE_SPEC(sampler3d_float,                              FUNCTION_TEXTUREPROJ,   Vec4(-0.3f, -0.6f,  0.0f,  1.5f),       Vec4(2.25f, 3.45f,  2.0f,  1.5f),       false,  0.0f,   0.0f,   true,   IVec3(-8, 7, 3),        tex3DMipmapFloat,               evalTexture3DProjOffset,                FRAGMENT),
3164                 CASE_SPEC(isampler3d,                                   FUNCTION_TEXTUREPROJ,   Vec4(-0.3f, -0.6f,  0.0f,  1.5f),       Vec4(2.25f, 3.45f,  2.0f,  1.5f),       false,  0.0f,   0.0f,   true,   IVec3(7, 3, -8),        tex3DInt,                               evalTexture3DProjOffset,                VERTEX),
3165                 CASE_SPEC(isampler3d,                                   FUNCTION_TEXTUREPROJ,   Vec4(-0.3f, -0.6f,  0.0f,  1.5f),       Vec4(2.25f, 3.45f,  2.0f,  1.5f),       false,  0.0f,   0.0f,   true,   IVec3(3, -8, 7),        tex3DMipmapInt,                 evalTexture3DProjOffset,                FRAGMENT),
3166                 CASE_SPEC(usampler3d,                                   FUNCTION_TEXTUREPROJ,   Vec4(-0.3f, -0.6f,  0.0f,  1.5f),       Vec4(2.25f, 3.45f,  2.0f,  1.5f),       false,  0.0f,   0.0f,   true,   IVec3(-8, 7, 3),        tex3DUint,                              evalTexture3DProjOffset,                VERTEX),
3167                 CASE_SPEC(usampler3d,                                   FUNCTION_TEXTUREPROJ,   Vec4(-0.3f, -0.6f,  0.0f,  1.5f),       Vec4(2.25f, 3.45f,  2.0f,  1.5f),       false,  0.0f,   0.0f,   true,   IVec3(7, 3, -8),        tex3DMipmapUint,                evalTexture3DProjOffset,                FRAGMENT),
3168
3169                 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),
3170                 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),
3171                 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),
3172                 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),
3173
3174                 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),
3175                 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),
3176                 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)
3177         };
3178         createCaseGroup(this, "textureprojoffset", "textureOffsetProj() Tests", textureProjOffsetCases, DE_LENGTH_OF_ARRAY(textureProjOffsetCases));
3179
3180         // textureLod() cases
3181         static const TexFuncCaseSpec textureLodCases[] =
3182         {
3183                 //                Name                                                  Function                                MinCoord                                                        MaxCoord                                                        Bias?   MinLod  MaxLod  Offset? Offset          Format                                  EvalFunc                                Flags
3184                 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),
3185                 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),
3186                 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),
3187                 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),
3188
3189                 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),
3190                 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),
3191                 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),
3192                 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),
3193
3194                 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),
3195                 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),
3196                 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),
3197                 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),
3198
3199                 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),
3200                 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),
3201                 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),
3202                 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),
3203
3204                 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)
3205         };
3206         createCaseGroup(this, "texturelod", "textureLod() Tests", textureLodCases, DE_LENGTH_OF_ARRAY(textureLodCases));
3207
3208         // textureLodOffset() cases
3209         static const TexFuncCaseSpec textureLodOffsetCases[] =
3210         {
3211                 //                Name                                                  Function                                MinCoord                                                        MaxCoord                                                        Bias?   MinLod  MaxLod  Offset? Offset                          Format                                  EvalFunc                                                Flags
3212                 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),
3213                 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),
3214                 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),
3215                 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),
3216
3217                 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),
3218                 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),
3219                 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),
3220                 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),
3221
3222                 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),
3223                 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),
3224                 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),
3225                 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),
3226
3227                 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)
3228         };
3229         createCaseGroup(this, "texturelodoffset", "textureLodOffset() Tests", textureLodOffsetCases, DE_LENGTH_OF_ARRAY(textureLodOffsetCases));
3230
3231         // textureProjLod() cases
3232         static const TexFuncCaseSpec textureProjLodCases[] =
3233         {
3234                 //                Name                                                  Function                                        MinCoord                                                        MaxCoord                                                        Bias?   MinLod  MaxLod  Offset? Offset          Format                                  EvalFunc                                        Flags
3235                 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),
3236                 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),
3237                 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),
3238                 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),
3239
3240                 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),
3241                 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),
3242                 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),
3243                 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),
3244
3245                 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),
3246                 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),
3247                 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),
3248                 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),
3249
3250                 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)
3251         };
3252         createCaseGroup(this, "textureprojlod", "textureProjLod() Tests", textureProjLodCases, DE_LENGTH_OF_ARRAY(textureProjLodCases));
3253
3254         // textureProjLodOffset() cases
3255         static const TexFuncCaseSpec textureProjLodOffsetCases[] =
3256         {
3257                 //                Name                                                  Function                                        MinCoord                                                        MaxCoord                                                        Bias?   MinLod  MaxLod  Offset? Offset                          Format                                  EvalFunc                                                                Flags
3258                 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),
3259                 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),
3260                 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),
3261                 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),
3262
3263                 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),
3264                 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),
3265                 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),
3266                 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),
3267
3268                 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),
3269                 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),
3270                 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),
3271                 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),
3272
3273                 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)
3274         };
3275         createCaseGroup(this, "textureprojlodoffset", "textureProjLodOffset() Tests", textureProjLodOffsetCases, DE_LENGTH_OF_ARRAY(textureProjLodOffsetCases));
3276
3277         // textureGrad() cases
3278         // \note Only one of dudx, dudy, dvdx, dvdy is non-zero since spec allows approximating p from derivates by various methods.
3279         static const TexFuncCaseSpec textureGradCases[] =
3280         {
3281                 //                Name                                                  Function                                MinCoord                                                        MaxCoord                                                        MinDx                                           MaxDx                                           MinDy                                           MaxDy                                           Offset? Offset          Format                                  EvalFunc                                Flags
3282                 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),
3283                 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),
3284                 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),
3285                 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),
3286
3287                 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),
3288                 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),
3289                 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),
3290                 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),
3291
3292                 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),
3293                 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),
3294                 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),
3295                 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),
3296
3297                 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),
3298                 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),
3299                 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),
3300                 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),
3301                 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),
3302                 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),
3303
3304                 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),
3305                 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),
3306                 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),
3307                 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)
3308         };
3309         createCaseGroup(this, "texturegrad", "textureGrad() Tests", textureGradCases, DE_LENGTH_OF_ARRAY(textureGradCases));
3310
3311         // textureGradOffset() cases
3312         static const TexFuncCaseSpec textureGradOffsetCases[] =
3313         {
3314                 //                Name                                                  Function                                MinCoord                                                        MaxCoord                                                        MinDx                                           MaxDx                                           MinDy                                           MaxDy                                           Offset? Offset                          Format                                  EvalFunc                                                        Flags
3315                 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),
3316                 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),
3317                 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),
3318                 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),
3319
3320                 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),
3321                 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),
3322                 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),
3323                 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),
3324
3325                 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),
3326                 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),
3327                 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),
3328                 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),
3329                 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),
3330                 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),
3331
3332                 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),
3333                 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),
3334                 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),
3335                 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)
3336         };
3337         createCaseGroup(this, "texturegradoffset", "textureGradOffset() Tests", textureGradOffsetCases, DE_LENGTH_OF_ARRAY(textureGradOffsetCases));
3338
3339         // textureProjGrad() cases
3340         static const TexFuncCaseSpec textureProjGradCases[] =
3341         {
3342                 //                Name                                                  Function                                        MinCoord                                                        MaxCoord                                                        MinDx                                           MaxDx                                           MinDy                                           MaxDy                                           Offset? Offset          Format                                  EvalFunc                                        Flags
3343                 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),
3344                 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),
3345                 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),
3346                 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),
3347
3348                 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),
3349                 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),
3350                 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),
3351                 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),
3352
3353                 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),
3354                 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),
3355                 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),
3356                 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),
3357                 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),
3358                 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),
3359
3360                 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),
3361                 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)
3362         };
3363         createCaseGroup(this, "textureprojgrad", "textureProjGrad() Tests", textureProjGradCases, DE_LENGTH_OF_ARRAY(textureProjGradCases));
3364
3365         // textureProjGradOffset() cases
3366         static const TexFuncCaseSpec textureProjGradOffsetCases[] =
3367         {
3368                 //                Name                                                  Function                                        MinCoord                                                        MaxCoord                                                        MinDx                                           MaxDx                                           MinDy                                           MaxDy                                           Offset? Offset                          Format                                  EvalFunc                                                        Flags
3369                 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),
3370                 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),
3371                 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),
3372                 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),
3373
3374                 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),
3375                 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),
3376                 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),
3377                 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),
3378
3379                 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),
3380                 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),
3381                 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),
3382                 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),
3383                 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),
3384                 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),
3385
3386                 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),
3387                 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)
3388         };
3389         createCaseGroup(this, "textureprojgradoffset", "textureProjGradOffset() Tests", textureProjGradOffsetCases, DE_LENGTH_OF_ARRAY(textureProjGradOffsetCases));
3390
3391         // texelFetch() cases
3392         // \note Level is constant across quad
3393         static const TexFuncCaseSpec texelFetchCases[] =
3394         {
3395                 //                Name                                                  Function                                MinCoord                                                        MaxCoord                                                Bias?   MinLod  MaxLod  Offset? Offset          Format                                          EvalFunc                                Flags
3396                 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),
3397                 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),
3398                 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),
3399                 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),
3400
3401                 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),
3402                 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),
3403                 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),
3404                 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),
3405
3406                 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),
3407                 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),
3408                 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),
3409                 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)
3410         };
3411         createCaseGroup(this, "texelfetch", "texelFetch() Tests", texelFetchCases, DE_LENGTH_OF_ARRAY(texelFetchCases));
3412
3413         // texelFetchOffset() cases
3414         static const TexFuncCaseSpec texelFetchOffsetCases[] =
3415         {
3416                 //                Name                                                  Function                                MinCoord                                                        MaxCoord                                                Bias?   MinLod  MaxLod  Offset? Offset          Format                                          EvalFunc                                Flags
3417                 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),
3418                 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),
3419                 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),
3420                 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),
3421
3422                 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),
3423                 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),
3424                 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),
3425                 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),
3426
3427                 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),
3428                 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),
3429                 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),
3430                 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)
3431         };
3432         createCaseGroup(this, "texelfetchoffset", "texelFetchOffset() Tests", texelFetchOffsetCases, DE_LENGTH_OF_ARRAY(texelFetchOffsetCases));
3433
3434         // texture query functions
3435         {
3436                 struct TexQueryFuncCaseSpec
3437                 {
3438                         const char*             name;
3439                         const char*             samplerName;
3440                         TextureSpec             textureSpec;
3441                 };
3442
3443                 de::MovePtr<tcu::TestCaseGroup>                 queryGroup      (new tcu::TestCaseGroup(m_testCtx, "query", "Texture query function tests"));
3444
3445                 // textureSize() cases
3446                 {
3447                         const TexQueryFuncCaseSpec textureSizeCases[] =
3448                         {
3449                                 { "sampler2d_fixed",                    "sampler2D",                            tex2DFixed                      },
3450                                 { "sampler2d_float",                    "sampler2D",                            tex2DFloat                      },
3451                                 { "isampler2d",                                 "isampler2D",                           tex2DInt                        },
3452                                 { "usampler2d",                                 "usampler2D",                           tex2DUint                       },
3453                                 { "sampler2dshadow",                    "sampler2DShadow",                      tex2DShadow                     },
3454                                 { "sampler3d_fixed",                    "sampler3D",                            tex3DFixed                      },
3455                                 { "sampler3d_float",                    "sampler3D",                            tex3DFloat                      },
3456                                 { "isampler3d",                                 "isampler3D",                           tex3DInt                        },
3457                                 { "usampler3d",                                 "usampler3D",                           tex3DUint                       },
3458                                 { "samplercube_fixed",                  "samplerCube",                          texCubeFixed            },
3459                                 { "samplercube_float",                  "samplerCube",                          texCubeFloat            },
3460                                 { "isamplercube",                               "isamplerCube",                         texCubeInt                      },
3461                                 { "usamplercube",                               "usamplerCube",                         texCubeUint                     },
3462                                 { "samplercubeshadow",                  "samplerCubeShadow",            texCubeShadow           },
3463                                 { "sampler2darray_fixed",               "sampler2DArray",                       tex2DArrayFixed         },
3464                                 { "sampler2darray_float",               "sampler2DArray",                       tex2DArrayFloat         },
3465                                 { "isampler2darray",                    "isampler2DArray",                      tex2DArrayInt           },
3466                                 { "usampler2darray",                    "usampler2DArray",                      tex2DArrayUint          },
3467                                 { "sampler2darrayshadow",               "sampler2DArrayShadow",         tex2DArrayShadow        },
3468                                 { "samplercubearray_fixed",             "samplerCubeArray",                     texCubeArrayFixed       },
3469                                 { "samplercubearray_float",             "samplerCubeArray",                     texCubeArrayFloat       },
3470                                 { "isamplercubearray",                  "isamplerCubeArray",            texCubeArrayInt         },
3471                                 { "usamplercubearray",                  "usamplerCubeArray",            texCubeArrayUint        },
3472                                 { "samplercubearrayshadow",             "samplerCubeArrayShadow",       texCubeArrayShadow      },
3473                                 { "sampler1d_fixed",                    "sampler1D",                            tex1DFixed                      },
3474                                 { "sampler1d_float",                    "sampler1D",                            tex1DFloat                      },
3475                                 { "isampler1d",                                 "isampler1D",                           tex1DInt                        },
3476                                 { "usampler1d",                                 "usampler1D",                           tex1DUint                       },
3477                                 { "sampler1dshadow",                    "sampler1DShadow",                      tex1DShadow                     },
3478                                 { "sampler1darray_fixed",               "sampler1DArray",                       tex1DArrayFixed         },
3479                                 { "sampler1darray_float",               "sampler1DArray",                       tex1DArrayFloat         },
3480                                 { "isampler1darray",                    "isampler1DArray",                      tex1DArrayInt           },
3481                                 { "usampler1darray",                    "usampler1DArray",                      tex1DArrayUint          },
3482                                 { "sampler1darrayshadow",               "sampler1DArrayShadow",         tex1DArrayShadow        },
3483                         };
3484
3485                         de::MovePtr<tcu::TestCaseGroup>         group           (new tcu::TestCaseGroup(m_testCtx, "texturesize", "textureSize() Tests"));
3486
3487                         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(textureSizeCases); ++ndx)
3488                         {
3489                                 const TexQueryFuncCaseSpec&             caseSpec        = textureSizeCases[ndx];
3490
3491                                 group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_vertex"),   "", caseSpec.samplerName, caseSpec.textureSpec, true,  QUERYFUNCTION_TEXTURESIZE));
3492                                 group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_fragment"), "", caseSpec.samplerName, caseSpec.textureSpec, false, QUERYFUNCTION_TEXTURESIZE));
3493                         }
3494
3495                         queryGroup->addChild(group.release());
3496                 }
3497
3498                 // textureSamples() cases
3499                 {
3500                         const TexQueryFuncCaseSpec textureSamplesCases[] =
3501                         {
3502                                 { "sampler2dms_fixed",                  "sampler2DMS",                          tex2DFixed                      },
3503                                 { "sampler2dms_float",                  "sampler2DMS",                          tex2DFloat                      },
3504                                 { "isampler2dms",                               "isampler2DMS",                         tex2DInt                        },
3505                                 { "usampler2dms",                               "usampler2DMS",                         tex2DUint                       },
3506                                 { "sampler2dmsarray_fixed",             "sampler2DMSArray",                     tex2DArrayFixed         },
3507                                 { "sampler2dmsarray_float",             "sampler2DMSArray",                     tex2DArrayFloat         },
3508                                 { "isampler2dmsarray",                  "isampler2DMSArray",            tex2DArrayInt           },
3509                                 { "usampler2dmsarray",                  "usampler2DMSArray",            tex2DArrayUint          },
3510                         };
3511
3512                         de::MovePtr<tcu::TestCaseGroup>         group           (new tcu::TestCaseGroup(m_testCtx, "texturesamples", "textureSamples() Tests"));
3513
3514                         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(textureSamplesCases); ++ndx)
3515                         {
3516                                 const TexQueryFuncCaseSpec&             caseSpec        = textureSamplesCases[ndx];
3517
3518                                 group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_vertex"),   "", caseSpec.samplerName, caseSpec.textureSpec, true,  QUERYFUNCTION_TEXTURESAMPLES));
3519                                 group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_fragment"), "", caseSpec.samplerName, caseSpec.textureSpec, false, QUERYFUNCTION_TEXTURESAMPLES));
3520                         }
3521
3522                         queryGroup->addChild(group.release());
3523                 }
3524
3525                 // textureQueryLevels() cases
3526                 {
3527                         const TexQueryFuncCaseSpec textureQueryLevelsCases[] =
3528                         {
3529                                 { "sampler2d_fixed",                    "sampler2D",                            tex2DFixed                      },
3530                                 { "sampler2d_float",                    "sampler2D",                            tex2DFloat                      },
3531                                 { "isampler2d",                                 "isampler2D",                           tex2DInt                        },
3532                                 { "usampler2d",                                 "usampler2D",                           tex2DUint                       },
3533                                 { "sampler2dshadow",                    "sampler2DShadow",                      tex2DShadow                     },
3534                                 { "sampler3d_fixed",                    "sampler3D",                            tex3DFixed                      },
3535                                 { "sampler3d_float",                    "sampler3D",                            tex3DFloat                      },
3536                                 { "isampler3d",                                 "isampler3D",                           tex3DInt                        },
3537                                 { "usampler3d",                                 "usampler3D",                           tex3DUint                       },
3538                                 { "samplercube_fixed",                  "samplerCube",                          texCubeFixed            },
3539                                 { "samplercube_float",                  "samplerCube",                          texCubeFloat            },
3540                                 { "isamplercube",                               "isamplerCube",                         texCubeInt                      },
3541                                 { "usamplercube",                               "usamplerCube",                         texCubeUint                     },
3542                                 { "samplercubeshadow",                  "samplerCubeShadow",            texCubeShadow           },
3543                                 { "sampler2darray_fixed",               "sampler2DArray",                       tex2DArrayFixed         },
3544                                 { "sampler2darray_float",               "sampler2DArray",                       tex2DArrayFloat         },
3545                                 { "isampler2darray",                    "isampler2DArray",                      tex2DArrayInt           },
3546                                 { "usampler2darray",                    "usampler2DArray",                      tex2DArrayUint          },
3547                                 { "sampler2darrayshadow",               "sampler2DArrayShadow",         tex2DArrayShadow        },
3548                                 { "samplercubearray_fixed",             "samplerCubeArray",                     texCubeArrayFixed       },
3549                                 { "samplercubearray_float",             "samplerCubeArray",                     texCubeArrayFloat       },
3550                                 { "isamplercubearray",                  "isamplerCubeArray",            texCubeArrayInt         },
3551                                 { "usamplercubearray",                  "usamplerCubeArray",            texCubeArrayUint        },
3552                                 { "samplercubearrayshadow",             "samplerCubeArrayShadow",       texCubeArrayShadow      },
3553                                 { "sampler1d_fixed",                    "sampler1D",                            tex1DFixed                      },
3554                                 { "sampler1d_float",                    "sampler1D",                            tex1DFloat                      },
3555                                 { "isampler1d",                                 "isampler1D",                           tex1DInt                        },
3556                                 { "usampler1d",                                 "usampler1D",                           tex1DUint                       },
3557                                 { "sampler1dshadow",                    "sampler1DShadow",                      tex1DShadow                     },
3558                                 { "sampler1darray_fixed",               "sampler1DArray",                       tex1DArrayFixed         },
3559                                 { "sampler1darray_float",               "sampler1DArray",                       tex1DArrayFloat         },
3560                                 { "isampler1darray",                    "isampler1DArray",                      tex1DArrayInt           },
3561                                 { "usampler1darray",                    "usampler1DArray",                      tex1DArrayUint          },
3562                                 { "sampler1darrayshadow",               "sampler1DArrayShadow",         tex1DArrayShadow        },
3563                         };
3564
3565                         de::MovePtr<tcu::TestCaseGroup>         group           (new tcu::TestCaseGroup(m_testCtx, "texturequerylevels", "textureQueryLevels() Tests"));
3566
3567                         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(textureQueryLevelsCases); ++ndx)
3568                         {
3569                                 const TexQueryFuncCaseSpec&             caseSpec        = textureQueryLevelsCases[ndx];
3570
3571                                 group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_vertex"),   "", caseSpec.samplerName, caseSpec.textureSpec, true,  QUERYFUNCTION_TEXTUREQUERYLEVELS));
3572                                 group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_fragment"), "", caseSpec.samplerName, caseSpec.textureSpec, false, QUERYFUNCTION_TEXTUREQUERYLEVELS));
3573                         }
3574
3575                         queryGroup->addChild(group.release());
3576                 }
3577
3578                 // textureQueryLod() cases
3579                 {
3580                         const TexQueryFuncCaseSpec textureQueryLodCases[] =
3581                         {
3582                                 { "sampler2d_fixed",                    "sampler2D",                            tex2DMipmapFixed                        },
3583                                 { "sampler2d_float",                    "sampler2D",                            tex2DMipmapFloat                        },
3584                                 { "isampler2d",                                 "isampler2D",                           tex2DMipmapInt                          },
3585                                 { "usampler2d",                                 "usampler2D",                           tex2DMipmapUint                         },
3586                                 { "sampler2dshadow",                    "sampler2DShadow",                      tex2DMipmapShadow                       },
3587                                 { "sampler3d_fixed",                    "sampler3D",                            tex3DMipmapFixed                        },
3588                                 { "sampler3d_float",                    "sampler3D",                            tex3DMipmapFloat                        },
3589                                 { "isampler3d",                                 "isampler3D",                           tex3DMipmapInt                          },
3590                                 { "usampler3d",                                 "usampler3D",                           tex3DMipmapUint                         },
3591                                 { "samplercube_fixed",                  "samplerCube",                          texCubeMipmapFixed                      },
3592                                 { "samplercube_float",                  "samplerCube",                          texCubeMipmapFloat                      },
3593                                 { "isamplercube",                               "isamplerCube",                         texCubeMipmapInt                        },
3594                                 { "usamplercube",                               "usamplerCube",                         texCubeMipmapUint                       },
3595                                 { "samplercubeshadow",                  "samplerCubeShadow",            texCubeMipmapShadow                     },
3596                                 { "sampler2darray_fixed",               "sampler2DArray",                       tex2DArrayMipmapFixed           },
3597                                 { "sampler2darray_float",               "sampler2DArray",                       tex2DArrayMipmapFloat           },
3598                                 { "isampler2darray",                    "isampler2DArray",                      tex2DArrayMipmapInt                     },
3599                                 { "usampler2darray",                    "usampler2DArray",                      tex2DArrayMipmapUint            },
3600                                 { "sampler2darrayshadow",               "sampler2DArrayShadow",         tex2DArrayMipmapShadow          },
3601                                 { "samplercubearray_fixed",             "samplerCubeArray",                     texCubeArrayMipmapFixed         },
3602                                 { "samplercubearray_float",             "samplerCubeArray",                     texCubeArrayMipmapFloat         },
3603                                 { "isamplercubearray",                  "isamplerCubeArray",            texCubeArrayMipmapInt           },
3604                                 { "usamplercubearray",                  "usamplerCubeArray",            texCubeArrayMipmapUint          },
3605                                 { "samplercubearrayshadow",             "samplerCubeArrayShadow",       texCubeArrayMipmapShadow        },
3606                                 { "sampler1d_fixed",                    "sampler1D",                            tex1DMipmapFixed                        },
3607                                 { "sampler1d_float",                    "sampler1D",                            tex1DMipmapFloat                        },
3608                                 { "isampler1d",                                 "isampler1D",                           tex1DMipmapInt                          },
3609                                 { "usampler1d",                                 "usampler1D",                           tex1DMipmapUint                         },
3610                                 { "sampler1dshadow",                    "sampler1DShadow",                      tex1DMipmapShadow                       },
3611                                 { "sampler1darray_fixed",               "sampler1DArray",                       tex1DArrayMipmapFixed           },
3612                                 { "sampler1darray_float",               "sampler1DArray",                       tex1DArrayMipmapFloat           },
3613                                 { "isampler1darray",                    "isampler1DArray",                      tex1DArrayMipmapInt                     },
3614                                 { "usampler1darray",                    "usampler1DArray",                      tex1DArrayMipmapUint            },
3615                                 { "sampler1darrayshadow",               "sampler1DArrayShadow",         tex1DArrayMipmapShadow          },
3616                         };
3617
3618                         de::MovePtr<tcu::TestCaseGroup>         group           (new tcu::TestCaseGroup(m_testCtx, "texturequerylod", "textureQueryLod() Tests"));
3619
3620                         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(textureQueryLodCases); ++ndx)
3621                         {
3622                                 const TexQueryFuncCaseSpec&             caseSpec        = textureQueryLodCases[ndx];
3623
3624                                 // available only in fragment shader
3625                                 group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_fragment"), "", caseSpec.samplerName, caseSpec.textureSpec, false, QUERYFUNCTION_TEXTUREQUERYLOD));
3626                         }
3627
3628                         queryGroup->addChild(group.release());
3629                 }
3630
3631                 addChild(queryGroup.release());
3632         }
3633 }
3634
3635 } // anonymous
3636
3637 tcu::TestCaseGroup* createTextureFunctionTests (tcu::TestContext& testCtx)
3638 {
3639         return new ShaderTextureFunctionTests(testCtx);
3640 }
3641
3642 } // sr
3643 } // vkt