Merge "Fix extension support checks in negative api tests" into nougat-cts-dev am...
[platform/upstream/VK-GL-CTS.git] / modules / gles31 / functional / es31fTextureBorderClampTests.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 3.1 Module
3  * -------------------------------------------------
4  *
5  * Copyright 2015 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Texture border clamp tests.
22  *//*--------------------------------------------------------------------*/
23
24 #include "es31fTextureBorderClampTests.hpp"
25
26 #include "glsTextureTestUtil.hpp"
27
28 #include "tcuTextureUtil.hpp"
29 #include "tcuTexLookupVerifier.hpp"
30 #include "tcuTexCompareVerifier.hpp"
31 #include "tcuCompressedTexture.hpp"
32 #include "tcuResultCollector.hpp"
33 #include "tcuSurface.hpp"
34 #include "tcuSeedBuilder.hpp"
35 #include "tcuVectorUtil.hpp"
36
37 #include "rrGenericVector.hpp"
38
39 #include "gluContextInfo.hpp"
40 #include "gluTexture.hpp"
41 #include "gluTextureUtil.hpp"
42 #include "gluPixelTransfer.hpp"
43 #include "gluStrUtil.hpp"
44 #include "gluObjectWrapper.hpp"
45 #include "gluShaderProgram.hpp"
46 #include "gluDrawUtil.hpp"
47
48 #include "glwEnums.hpp"
49 #include "glwFunctions.hpp"
50
51 #include "deStringUtil.hpp"
52 #include "deUniquePtr.hpp"
53 #include "deRandom.hpp"
54
55 #include <limits>
56
57
58 namespace deqp
59 {
60 namespace gles31
61 {
62 namespace Functional
63 {
64 namespace
65 {
66
67 enum SizeType
68 {
69         SIZE_POT = 0,
70         SIZE_NPOT
71 };
72
73 bool filterRequiresFilterability (deUint32 filter)
74 {
75         switch (filter)
76         {
77                 case GL_NEAREST:
78                 case GL_NEAREST_MIPMAP_NEAREST:
79                         return false;
80
81                 case GL_LINEAR:
82                 case GL_LINEAR_MIPMAP_NEAREST:
83                 case GL_NEAREST_MIPMAP_LINEAR:
84                 case GL_LINEAR_MIPMAP_LINEAR:
85                         return true;
86
87                 default:
88                         DE_ASSERT(false);
89                         return false;
90         }
91 }
92
93 bool isDepthFormat (deUint32 format, tcu::Sampler::DepthStencilMode mode)
94 {
95         if (format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA || format == GL_ALPHA || format == GL_BGRA)
96         {
97                 // Unsized formats are a special case
98                 return false;
99         }
100         else if (glu::isCompressedFormat(format))
101         {
102                 // no known compressed depth formats
103                 return false;
104         }
105         else
106         {
107                 const tcu::TextureFormat fmt = glu::mapGLInternalFormat(format);
108
109                 if (fmt.order == tcu::TextureFormat::D)
110                 {
111                         DE_ASSERT(mode == tcu::Sampler::MODE_DEPTH);
112                         return true;
113                 }
114                 else if (fmt.order == tcu::TextureFormat::DS && mode == tcu::Sampler::MODE_DEPTH)
115                         return true;
116                 else
117                         return false;
118         }
119 }
120
121 bool isStencilFormat (deUint32 format, tcu::Sampler::DepthStencilMode mode)
122 {
123         if (format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA || format == GL_ALPHA || format == GL_BGRA)
124         {
125                 // Unsized formats are a special case
126                 return false;
127         }
128         else if (glu::isCompressedFormat(format))
129         {
130                 // no known compressed stencil formats
131                 return false;
132         }
133         else
134         {
135                 const tcu::TextureFormat fmt = glu::mapGLInternalFormat(format);
136
137                 if (fmt.order == tcu::TextureFormat::S)
138                 {
139                         DE_ASSERT(mode == tcu::Sampler::MODE_STENCIL);
140                         return true;
141                 }
142                 else if (fmt.order == tcu::TextureFormat::DS && mode == tcu::Sampler::MODE_STENCIL)
143                         return true;
144                 else
145                         return false;
146         }
147 }
148
149 tcu::TextureChannelClass getFormatChannelClass (deUint32 format, tcu::Sampler::DepthStencilMode mode)
150 {
151         if (format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA || format == GL_ALPHA || format == GL_BGRA)
152         {
153                 // Unsized formats are a special c, use UNORM8
154                 return tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT;
155         }
156         else if (glu::isCompressedFormat(format))
157         {
158                 const tcu::CompressedTexFormat  compressedFmt   = glu::mapGLCompressedTexFormat(format);
159                 const tcu::TextureFormat                uncompressedFmt = tcu::getUncompressedFormat(compressedFmt);
160                 return tcu::getTextureChannelClass(uncompressedFmt.type);
161         }
162         else
163         {
164                 const tcu::TextureFormat fmt                    = glu::mapGLInternalFormat(format);
165                 const tcu::TextureFormat effectiveFmt   = tcu::getEffectiveDepthStencilTextureFormat(fmt, mode);
166
167                 return tcu::getTextureChannelClass(effectiveFmt.type);
168         }
169 }
170
171 int getDimensionNumBlocks (int dimensionSize, int blockSize)
172 {
173         // ceil( a / b )
174         return (dimensionSize + blockSize - 1) / blockSize;
175 }
176
177 void generateDummyCompressedData (tcu::CompressedTexture& dst, const tcu::CompressedTexFormat& format)
178 {
179         const int                       blockByteSize   = tcu::getBlockSize(format);
180         const tcu::IVec3        blockPixelSize  = tcu::getBlockPixelSize(format);
181         const tcu::IVec3        numBlocks               (getDimensionNumBlocks(dst.getWidth(),    blockPixelSize.x()),
182                                                                                  getDimensionNumBlocks(dst.getHeight(),   blockPixelSize.y()),
183                                                                                  getDimensionNumBlocks(dst.getDepth(),    blockPixelSize.z()));
184         const int                       numTotalBlocks  = numBlocks.x() * numBlocks.y() * numBlocks.z();
185         const int                       dataSize                = numTotalBlocks * blockByteSize;
186
187         DE_ASSERT(dst.getDataSize() == dataSize);
188
189         if (tcu::isAstcFormat(format))
190         {
191                 // generate data that is valid in LDR mode
192                 const int               BLOCK_SIZE                      = 16;
193                 const deUint8   block[BLOCK_SIZE]       = { 252, 253, 255, 255, 255, 255, 255, 255, 223, 251, 28, 206, 54, 251, 160, 174 };
194
195                 DE_ASSERT(blockByteSize == BLOCK_SIZE);
196                 for (int ndx = 0; ndx < numTotalBlocks; ++ndx)
197                         deMemcpy((deUint8*)dst.getData() + ndx * BLOCK_SIZE, block, BLOCK_SIZE);
198         }
199         else
200         {
201                 // any data is ok
202                 de::Random rnd(0xabc);
203
204                 for (int ndx = 0; ndx < dataSize; ++ndx)
205                         ((deUint8*)dst.getData())[ndx] = rnd.getUint8();
206         }
207 }
208
209 template <typename T>
210 struct TextureTraits
211 {
212 };
213
214 template <>
215 struct TextureTraits<glu::Texture2D>
216 {
217         typedef tcu::IVec2 SizeType;
218
219         static de::MovePtr<glu::Texture2D> createTextureFromInternalFormat (glu::RenderContext& renderCtx, deUint32 texFormat, const tcu::IVec2& size)
220         {
221                 return de::MovePtr<glu::Texture2D>(new glu::Texture2D(renderCtx, texFormat, size.x(), size.y()));
222         }
223
224         static de::MovePtr<glu::Texture2D> createTextureFromFormatAndType (glu::RenderContext& renderCtx, deUint32 texFormat, deUint32 type, const tcu::IVec2& size)
225         {
226                 return de::MovePtr<glu::Texture2D>(new glu::Texture2D(renderCtx, texFormat, type, size.x(), size.y()));
227         }
228
229         static de::MovePtr<glu::Texture2D> createTextureFromCompressedData (glu::RenderContext&                                 renderCtx,
230                                                                                                                                                 const glu::ContextInfo&                         ctxInfo,
231                                                                                                                                                 const tcu::CompressedTexture&           compressedLevel,
232                                                                                                                                                 const tcu::TexDecompressionParams&      decompressionParams)
233         {
234                 return de::MovePtr<glu::Texture2D>(new glu::Texture2D(renderCtx,
235                                                                                                                           ctxInfo,
236                                                                                                                           1,
237                                                                                                                           &compressedLevel,
238                                                                                                                           decompressionParams));
239         }
240
241         static int getTextureNumLayers (const tcu::IVec2& size)
242         {
243                 // 2D textures have one layer
244                 DE_UNREF(size);
245                 return 1;
246         }
247 };
248
249 template <>
250 struct TextureTraits<glu::Texture3D>
251 {
252         typedef tcu::IVec3 SizeType;
253
254         static de::MovePtr<glu::Texture3D> createTextureFromInternalFormat (glu::RenderContext& renderCtx, deUint32 texFormat, const tcu::IVec3& size)
255         {
256                 return de::MovePtr<glu::Texture3D>(new glu::Texture3D(renderCtx, texFormat, size.x(), size.y(), size.z()));
257         }
258
259         static de::MovePtr<glu::Texture3D> createTextureFromFormatAndType (glu::RenderContext& renderCtx, deUint32 texFormat, deUint32 type, const tcu::IVec3& size)
260         {
261                 return de::MovePtr<glu::Texture3D>(new glu::Texture3D(renderCtx, texFormat, type, size.x(), size.y(), size.z()));
262         }
263
264         static de::MovePtr<glu::Texture3D> createTextureFromCompressedData (glu::RenderContext&                                 renderCtx,
265                                                                                                                                                 const glu::ContextInfo&                         ctxInfo,
266                                                                                                                                                 const tcu::CompressedTexture&           compressedLevel,
267                                                                                                                                                 const tcu::TexDecompressionParams&      decompressionParams)
268         {
269                 return de::MovePtr<glu::Texture3D>(new glu::Texture3D(renderCtx,
270                                                                                                                           ctxInfo,
271                                                                                                                           1,
272                                                                                                                           &compressedLevel,
273                                                                                                                           decompressionParams));
274         }
275
276         static int getTextureNumLayers (const tcu::IVec3& size)
277         {
278                 // 3D textures have Z layers
279                 return size.z();
280         }
281 };
282
283 template <typename T>
284 de::MovePtr<T> genDummyTexture (glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, deUint32 texFormat, const typename TextureTraits<T>::SizeType& size)
285 {
286         de::MovePtr<T> texture;
287
288         if (isDepthFormat(texFormat, tcu::Sampler::MODE_DEPTH) || isStencilFormat(texFormat, tcu::Sampler::MODE_STENCIL))
289         {
290                 // fill different channels with different gradients
291                 texture = TextureTraits<T>::createTextureFromInternalFormat(renderCtx, texFormat, size);
292                 texture->getRefTexture().allocLevel(0);
293
294                 if (isDepthFormat(texFormat, tcu::Sampler::MODE_DEPTH))
295                 {
296                         // fill depth with 0 -> 1
297                         const tcu::PixelBufferAccess depthAccess = tcu::getEffectiveDepthStencilAccess(texture->getRefTexture().getLevel(0), tcu::Sampler::MODE_DEPTH);
298                         tcu::fillWithComponentGradients(depthAccess, tcu::Vec4(0.0f), tcu::Vec4(1.0f));
299                 }
300
301                 if (isStencilFormat(texFormat, tcu::Sampler::MODE_STENCIL))
302                 {
303                         // fill stencil with 0 -> max
304                         const tcu::PixelBufferAccess    stencilAccess   = tcu::getEffectiveDepthStencilAccess(texture->getRefTexture().getLevel(0), tcu::Sampler::MODE_STENCIL);
305                         const tcu::TextureFormatInfo    texFormatInfo   = tcu::getTextureFormatInfo(stencilAccess.getFormat());
306
307                         // Flip y to make stencil and depth cases not look identical
308                         tcu::fillWithComponentGradients(tcu::flipYAccess(stencilAccess), texFormatInfo.valueMax, texFormatInfo.valueMin);
309                 }
310
311                 texture->upload();
312         }
313         else if (!glu::isCompressedFormat(texFormat))
314         {
315                 if (texFormat == GL_LUMINANCE || texFormat == GL_LUMINANCE_ALPHA || texFormat == GL_ALPHA || texFormat == GL_BGRA)
316                         texture = TextureTraits<T>::createTextureFromFormatAndType(renderCtx, texFormat, GL_UNSIGNED_BYTE, size);
317                 else
318                         texture = TextureTraits<T>::createTextureFromInternalFormat(renderCtx, texFormat, size);
319
320                 // Fill level 0.
321                 texture->getRefTexture().allocLevel(0);
322
323                 // fill with gradient min -> max
324                 {
325                         const tcu::TextureFormatInfo    texFormatInfo   = tcu::getTextureFormatInfo(texture->getRefTexture().getFormat());
326                         const tcu::Vec4                                 rampLow                 = texFormatInfo.valueMin;
327                         const tcu::Vec4                                 rampHigh                = texFormatInfo.valueMax;
328                         tcu::fillWithComponentGradients(texture->getRefTexture().getLevel(0), rampLow, rampHigh);
329                 }
330
331                 texture->upload();
332         }
333         else
334         {
335                 const tcu::CompressedTexFormat  compressedFormat        = glu::mapGLCompressedTexFormat(texFormat);
336                 const int                                               numLayers                       = TextureTraits<T>::getTextureNumLayers(size);
337                 tcu::CompressedTexture                  compressedLevel         (compressedFormat, size.x(), size.y(), numLayers);
338                 const bool                                              isAstcFormat            = tcu::isAstcFormat(compressedFormat);
339                 tcu::TexDecompressionParams             decompressionParams     ((isAstcFormat) ? (tcu::TexDecompressionParams::ASTCMODE_LDR) : (tcu::TexDecompressionParams::ASTCMODE_LAST));
340
341                 generateDummyCompressedData(compressedLevel, compressedFormat);
342
343                 texture = TextureTraits<T>::createTextureFromCompressedData(renderCtx,
344                                                                                                                                         ctxInfo,
345                                                                                                                                         compressedLevel,
346                                                                                                                                         decompressionParams);
347         }
348
349         return texture;
350 }
351
352 int getNBitIntegerMaxValue (bool isSigned, int numBits)
353 {
354         DE_ASSERT(numBits < 32);
355
356         if (numBits == 0)
357                 return 0;
358         else if (isSigned)
359                 return deIntMaxValue32(numBits);
360         else
361                 return deUintMaxValue32(numBits);
362 }
363
364 int getNBitIntegerMinValue (bool isSigned, int numBits)
365 {
366         DE_ASSERT(numBits < 32);
367
368         if (numBits == 0)
369                 return 0;
370         else if (isSigned)
371                 return deIntMinValue32(numBits);
372         else
373                 return 0;
374 }
375
376 tcu::IVec4 getNBitIntegerVec4MaxValue (bool isSigned, const tcu::IVec4& numBits)
377 {
378         return tcu::IVec4(getNBitIntegerMaxValue(isSigned, numBits[0]),
379                                           getNBitIntegerMaxValue(isSigned, numBits[1]),
380                                           getNBitIntegerMaxValue(isSigned, numBits[2]),
381                                           getNBitIntegerMaxValue(isSigned, numBits[3]));
382 }
383
384 tcu::IVec4 getNBitIntegerVec4MinValue (bool isSigned, const tcu::IVec4& numBits)
385 {
386         return tcu::IVec4(getNBitIntegerMinValue(isSigned, numBits[0]),
387                                           getNBitIntegerMinValue(isSigned, numBits[1]),
388                                           getNBitIntegerMinValue(isSigned, numBits[2]),
389                                           getNBitIntegerMinValue(isSigned, numBits[3]));
390 }
391
392 rr::GenericVec4 mapToFormatColorUnits (const tcu::TextureFormat& texFormat, const tcu::Vec4& normalizedRange)
393 {
394         const tcu::TextureFormatInfo texFormatInfo = tcu::getTextureFormatInfo(texFormat);
395
396         switch (tcu::getTextureChannelClass(texFormat.type))
397         {
398                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:             return rr::GenericVec4(normalizedRange);
399                 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:               return rr::GenericVec4(normalizedRange * 2.0f - 1.0f);
400                 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:                   return rr::GenericVec4(texFormatInfo.valueMin + normalizedRange * texFormatInfo.valueMax);
401                 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:                   return rr::GenericVec4(tcu::mix(texFormatInfo.valueMin, texFormatInfo.valueMax, normalizedRange).cast<deInt32>());
402                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:                 return rr::GenericVec4(tcu::mix(texFormatInfo.valueMin, texFormatInfo.valueMax, normalizedRange).cast<deUint32>());
403
404                 default:
405                         DE_ASSERT(false);
406                         return rr::GenericVec4();
407         }
408 }
409
410 rr::GenericVec4 mapToFormatColorRepresentable (const tcu::TextureFormat& texFormat, const tcu::Vec4& normalizedRange)
411 {
412         // make sure value is representable in the target format and clear channels
413         // not present in the target format.
414
415         const rr::GenericVec4           inFormatUnits   = mapToFormatColorUnits(texFormat, normalizedRange);
416         const tcu::BVec4                        channelMask             = tcu::getTextureFormatChannelMask(texFormat);
417         de::ArrayBuffer<deUint8, 4>     buffer                  (texFormat.getPixelSize());
418         tcu::PixelBufferAccess          access                  (texFormat, tcu::IVec3(1, 1, 1), buffer.getPtr());
419
420         if (tcu::isSRGB(texFormat))
421         {
422                 DE_ASSERT(texFormat.type == tcu::TextureFormat::UNORM_INT8);
423
424                 // make sure border color (in linear space) can be converted to 8-bit sRGB space without
425                 // significant loss.
426                 const tcu::Vec4         sRGB            = tcu::linearToSRGB(normalizedRange);
427                 const tcu::IVec4        sRGB8           = tcu::IVec4(tcu::floatToU8(sRGB[0]),
428                                                                                                          tcu::floatToU8(sRGB[1]),
429                                                                                                          tcu::floatToU8(sRGB[2]),
430                                                                                                          tcu::floatToU8(sRGB[3]));
431                 const tcu::Vec4         linearized      = tcu::sRGBToLinear(tcu::Vec4((float)sRGB8[0] / 255.0f,
432                                                                                                                                           (float)sRGB8[1] / 255.0f,
433                                                                                                                                           (float)sRGB8[2] / 255.0f,
434                                                                                                                                           (float)sRGB8[3] / 255.0f));
435
436                 return rr::GenericVec4(tcu::select(linearized, tcu::Vec4(0.0f), channelMask));
437         }
438
439         switch (tcu::getTextureChannelClass(texFormat.type))
440         {
441                 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
442                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
443                 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
444                 {
445                         access.setPixel(inFormatUnits.get<float>(), 0, 0);
446                         return rr::GenericVec4(tcu::select(access.getPixel(0, 0), tcu::Vec4(0.0f), channelMask));
447                 }
448                 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
449                 {
450                         access.setPixel(inFormatUnits.get<deInt32>(), 0, 0);
451                         return rr::GenericVec4(tcu::select(access.getPixelInt(0, 0), tcu::IVec4(0), channelMask));
452                 }
453                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
454                 {
455                         access.setPixel(inFormatUnits.get<deUint32>(), 0, 0);
456                         return rr::GenericVec4(tcu::select(access.getPixelUint(0, 0), tcu::UVec4(0u), channelMask));
457                 }
458                 default:
459                 {
460                         DE_ASSERT(false);
461                         return rr::GenericVec4();
462                 }
463         }
464 }
465
466 bool isCoreFilterableFormat (deUint32 format, tcu::Sampler::DepthStencilMode mode)
467 {
468         const bool      isLuminanceOrAlpha              = (format == GL_LUMINANCE || format == GL_ALPHA || format == GL_LUMINANCE_ALPHA); // special case for luminance/alpha
469         const bool      isUnsizedColorFormat    = (format == GL_BGRA);
470         const bool      isCompressed                    = glu::isCompressedFormat(format);
471         const bool      isDepth                                 = isDepthFormat(format, mode);
472         const bool      isStencil                               = isStencilFormat(format, mode);
473
474         // special cases
475         if (isLuminanceOrAlpha || isUnsizedColorFormat || isCompressed)
476                 return true;
477         if (isStencil || isDepth)
478                 return false;
479
480         // color case
481         return glu::isGLInternalColorFormatFilterable(format);
482 }
483
484 class TextureBorderClampTest : public TestCase
485 {
486 public:
487         enum StateType
488         {
489                 STATE_SAMPLER_PARAM = 0,
490                 STATE_TEXTURE_PARAM,
491
492                 STATE_LAST
493         };
494
495         enum SamplingFunction
496         {
497                 SAMPLE_FILTER = 0,
498                 SAMPLE_GATHER,
499
500                 SAMPLE_LAST
501         };
502
503         enum Flag
504         {
505                 FLAG_USE_SHADOW_SAMPLER = (1u << 0),
506         };
507
508         struct IterationConfig
509         {
510                 tcu::Vec2               p0;
511                 tcu::Vec2               p1;
512                 rr::GenericVec4 borderColor;
513                 tcu::Vec4               lookupScale;
514                 tcu::Vec4               lookupBias;
515                 deUint32                minFilter;
516                 deUint32                magFilter;
517                 std::string             description;
518                 deUint32                sWrapMode;
519                 deUint32                tWrapMode;
520                 deUint32                compareMode;
521                 float                   compareRef;
522         };
523
524                                                                                                                 TextureBorderClampTest          (Context&                                               context,
525                                                                                                                                                                          const char*                                    name,
526                                                                                                                                                                          const char*                                    description,
527                                                                                                                                                                          deUint32                                               texFormat,
528                                                                                                                                                                          tcu::Sampler::DepthStencilMode mode,
529                                                                                                                                                                          StateType                                              stateType,
530                                                                                                                                                                          int                                                    texWidth,
531                                                                                                                                                                          int                                                    texHeight,
532                                                                                                                                                                          SamplingFunction                               samplingFunction,
533                                                                                                                                                                          deUint32                                               flags                           = 0);
534                                                                                                                 ~TextureBorderClampTest         (void);
535
536 protected:
537         void                                                                                            init                                            (void);
538         void                                                                                            deinit                                          (void);
539
540 private:
541         IterateResult                                                                           iterate                                         (void);
542
543         void                                                                                            logParams                                       (const IterationConfig&                                                 config,
544                                                                                                                                                                          const glu::TextureTestUtil::ReferenceParams&   samplerParams);
545
546         void                                                                                            renderTo                                        (tcu::Surface&                                                                  surface,
547                                                                                                                                                                          const IterationConfig&                                                 config,
548                                                                                                                                                                          const glu::TextureTestUtil::ReferenceParams&   samplerParams);
549         void                                                                                            renderQuad                                      (const float*                                                                   texCoord,
550                                                                                                                                                                          const glu::TextureTestUtil::ReferenceParams&   samplerParams);
551
552         void                                                                                            verifyImage                                     (const tcu::Surface&                                                    image,
553                                                                                                                                                                          const IterationConfig&                                                 config,
554                                                                                                                                                                          const glu::TextureTestUtil::ReferenceParams&   samplerParams);
555
556         bool                                                                                            verifyTextureSampleResult       (const tcu::ConstPixelBufferAccess&                             renderedFrame,
557                                                                                                                                                                          const float*                                                                   texCoord,
558                                                                                                                                                                          const glu::TextureTestUtil::ReferenceParams&   samplerParams,
559                                                                                                                                                                          const tcu::LodPrecision&                                               lodPrecision,
560                                                                                                                                                                          const tcu::LookupPrecision&                                    lookupPrecision);
561
562         bool                                                                                            verifyTextureCompareResult      (const tcu::ConstPixelBufferAccess&                             renderedFrame,
563                                                                                                                                                                          const float*                                                                   texCoord,
564                                                                                                                                                                          const glu::TextureTestUtil::ReferenceParams&   samplerParams,
565                                                                                                                                                                          const tcu::TexComparePrecision&                                texComparePrecision,
566                                                                                                                                                                          const tcu::TexComparePrecision&                                lowQualityTexComparePrecision,
567                                                                                                                                                                          const tcu::LodPrecision&                                               lodPrecision,
568                                                                                                                                                                          const tcu::LodPrecision&                                               lowQualityLodPrecision);
569
570         bool                                                                                            verifyTextureGatherResult       (const tcu::ConstPixelBufferAccess&                             renderedFrame,
571                                                                                                                                                                          const float*                                                                   texCoord,
572                                                                                                                                                                          const glu::TextureTestUtil::ReferenceParams&   samplerParams,
573                                                                                                                                                                          const tcu::LookupPrecision&                                    lookupPrecision);
574
575         bool                                                                                            verifyTextureGatherCmpResult(const tcu::ConstPixelBufferAccess&                         renderedFrame,
576                                                                                                                                                                          const float*                                                                   texCoord,
577                                                                                                                                                                          const glu::TextureTestUtil::ReferenceParams&   samplerParams,
578                                                                                                                                                                          const tcu::TexComparePrecision&                                texComparePrecision,
579                                                                                                                                                                          const tcu::TexComparePrecision&                                lowQualityTexComparePrecision);
580
581         deUint32                                                                                        getIterationSeed                        (const IterationConfig& config) const;
582         glu::TextureTestUtil::ReferenceParams                           genSamplerParams                        (const IterationConfig& config) const;
583         glu::ShaderProgram*                                                                     genGatherProgram                        (void) const;
584
585         virtual int                                                                                     getNumIterations                        (void) const = 0;
586         virtual IterationConfig                                                         getIteration                            (int ndx) const = 0;
587
588 protected:
589         const glu::Texture2D*                                                           getTexture                                              (void) const;
590
591         const deUint32                                                                          m_texFormat;
592         const tcu::Sampler::DepthStencilMode                            m_sampleMode;
593         const tcu::TextureChannelClass                                          m_channelClass;
594         const StateType                                                                         m_stateType;
595
596         const int                                                                                       m_texHeight;
597         const int                                                                                       m_texWidth;
598
599         const SamplingFunction                                                          m_samplingFunction;
600         const bool                                                                                      m_useShadowSampler;
601 private:
602         enum
603         {
604                 VIEWPORT_WIDTH          = 128,
605                 VIEWPORT_HEIGHT         = 128,
606         };
607
608         de::MovePtr<glu::Texture2D>                                                     m_texture;
609         de::MovePtr<gls::TextureTestUtil::TextureRenderer>      m_renderer;
610         de::MovePtr<glu::ShaderProgram>                                         m_gatherProgram;
611
612         int                                                                                                     m_iterationNdx;
613         tcu::ResultCollector                                                            m_result;
614 };
615
616 TextureBorderClampTest::TextureBorderClampTest (Context&                                                context,
617                                                                                                 const char*                                             name,
618                                                                                                 const char*                                             description,
619                                                                                                 deUint32                                                texFormat,
620                                                                                                 tcu::Sampler::DepthStencilMode  mode,
621                                                                                                 StateType                                               stateType,
622                                                                                                 int                                                             texWidth,
623                                                                                                 int                                                             texHeight,
624                                                                                                 SamplingFunction                                samplingFunction,
625                                                                                                 deUint32                                                flags)
626         : TestCase                              (context, name, description)
627         , m_texFormat                   (texFormat)
628         , m_sampleMode                  (mode)
629         , m_channelClass                (getFormatChannelClass(texFormat, mode))
630         , m_stateType                   (stateType)
631         , m_texHeight                   (texHeight)
632         , m_texWidth                    (texWidth)
633         , m_samplingFunction    (samplingFunction)
634         , m_useShadowSampler    ((flags & FLAG_USE_SHADOW_SAMPLER) != 0)
635         , m_iterationNdx                (0)
636         , m_result                              (context.getTestContext().getLog())
637 {
638         DE_ASSERT(stateType < STATE_LAST);
639         DE_ASSERT(samplingFunction < SAMPLE_LAST);
640         // mode must be set for combined depth-stencil formats
641         DE_ASSERT(m_channelClass != tcu::TEXTURECHANNELCLASS_LAST || mode != tcu::Sampler::MODE_LAST);
642 }
643
644 TextureBorderClampTest::~TextureBorderClampTest (void)
645 {
646         deinit();
647 }
648
649 void TextureBorderClampTest::init (void)
650 {
651         // requirements
652         const bool supportsES32 = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
653
654         if (!supportsES32 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_border_clamp"))
655                 throw tcu::NotSupportedError("Test requires GL_EXT_texture_border_clamp extension");
656
657         if (glu::isCompressedFormat(m_texFormat)                                                                                                        &&
658                 !supportsES32                                                                                                                                                   &&
659                 tcu::isAstcFormat(glu::mapGLCompressedTexFormat(m_texFormat))                                                   &&
660                 !m_context.getContextInfo().isExtensionSupported("GL_KHR_texture_compression_astc_ldr"))
661         {
662                 throw tcu::NotSupportedError("Test requires GL_KHR_texture_compression_astc_ldr extension");
663         }
664
665         if (m_texFormat == GL_BGRA && !m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_format_BGRA8888"))
666                 throw tcu::NotSupportedError("Test requires GL_EXT_texture_format_BGRA8888 extension");
667
668         if (m_context.getRenderTarget().getWidth() < VIEWPORT_WIDTH ||
669                 m_context.getRenderTarget().getHeight() < VIEWPORT_HEIGHT)
670         {
671                 throw tcu::NotSupportedError("Test requires " + de::toString<int>(VIEWPORT_WIDTH) + "x" + de::toString<int>(VIEWPORT_HEIGHT) + " viewport");
672         }
673
674         // resources
675
676         m_texture = genDummyTexture<glu::Texture2D>(m_context.getRenderContext(), m_context.getContextInfo(), m_texFormat, tcu::IVec2(m_texWidth, m_texHeight));
677
678         m_testCtx.getLog()      << tcu::TestLog::Message
679                                                 << "Created texture with format " << glu::getTextureFormatName(m_texFormat)
680                                                 << ", size (" << m_texture->getRefTexture().getWidth() << ", " << m_texture->getRefTexture().getHeight() << ")\n"
681                                                 << "Setting sampling state using " << ((m_stateType == STATE_TEXTURE_PARAM) ? ("texture state") : ("sampler state"))
682                                                 << tcu::TestLog::EndMessage;
683
684         if (m_samplingFunction == SAMPLE_FILTER)
685         {
686                 const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
687
688                 m_renderer = de::MovePtr<gls::TextureTestUtil::TextureRenderer>(new gls::TextureTestUtil::TextureRenderer(m_context.getRenderContext(), m_testCtx.getLog(), glslVersion, glu::PRECISION_HIGHP));
689         }
690         else
691         {
692                 m_gatherProgram = de::MovePtr<glu::ShaderProgram>(genGatherProgram());
693
694                 m_testCtx.getLog()      << tcu::TestLog::Message
695                                                         << "Using texture gather to sample texture"
696                                                         << tcu::TestLog::EndMessage
697                                                         << *m_gatherProgram;
698
699                 if (!m_gatherProgram->isOk())
700                         throw tcu::TestError("failed to build program");
701         }
702 }
703
704 void TextureBorderClampTest::deinit (void)
705 {
706         m_texture.clear();
707         m_renderer.clear();
708         m_gatherProgram.clear();
709 }
710
711 TextureBorderClampTest::IterateResult TextureBorderClampTest::iterate (void)
712 {
713         const IterationConfig                                           iterationConfig         = getIteration(m_iterationNdx);
714         const std::string                                                       iterationDesc           = "Iteration " + de::toString(m_iterationNdx+1) + (iterationConfig.description.empty() ? ("") : (" - " + iterationConfig.description));
715         const tcu::ScopedLogSection                                     section                         (m_testCtx.getLog(), "Iteration", iterationDesc);
716         tcu::Surface                                                            renderedFrame           (VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
717         const glu::TextureTestUtil::ReferenceParams     samplerParams           = genSamplerParams(iterationConfig);
718
719         logParams(iterationConfig, samplerParams);
720         renderTo(renderedFrame, iterationConfig, samplerParams);
721         verifyImage(renderedFrame, iterationConfig, samplerParams);
722
723         if (++m_iterationNdx == getNumIterations())
724         {
725                 m_result.setTestContextResult(m_testCtx);
726                 return STOP;
727         }
728         return CONTINUE;
729 }
730
731 void TextureBorderClampTest::logParams (const IterationConfig& config, const glu::TextureTestUtil::ReferenceParams& samplerParams)
732 {
733         const std::string                               borderColorString       = (m_channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)   ? (de::toString(config.borderColor.get<deInt32>()))
734                                                                                                                 : (m_channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER) ? (de::toString(config.borderColor.get<deUint32>()))
735                                                                                                                 :                                                                                                                                 (de::toString(config.borderColor.get<float>()));
736
737         m_testCtx.getLog()      << tcu::TestLog::Message
738                                                 << "Rendering full screen quad, tex coords bottom-left: " << config.p0 << ", top-right " << config.p1 << "\n"
739                                                 << "Border color is " << borderColorString << "\n"
740                                                 << "Texture lookup bias: " << samplerParams.colorBias << "\n"
741                                                 << "Texture lookup scale: " << samplerParams.colorScale << "\n"
742                                                 << "Filters: min = " << glu::getTextureFilterName(glu::getGLFilterMode(samplerParams.sampler.minFilter))
743                                                         << ", mag = " << glu::getTextureFilterName(glu::getGLFilterMode(samplerParams.sampler.magFilter)) << "\n"
744                                                 << "Wrap mode: s = " << glu::getRepeatModeStr(config.sWrapMode)
745                                                         << ", t = " << glu::getRepeatModeStr(config.tWrapMode) << "\n"
746                                                 << tcu::TestLog::EndMessage;
747
748         if (m_sampleMode == tcu::Sampler::MODE_DEPTH)
749                 m_testCtx.getLog() << tcu::TestLog::Message << "Depth stencil texture mode is DEPTH_COMPONENT" << tcu::TestLog::EndMessage;
750         else if (m_sampleMode == tcu::Sampler::MODE_STENCIL)
751                 m_testCtx.getLog() << tcu::TestLog::Message << "Depth stencil texture mode is STENCIL_INDEX" << tcu::TestLog::EndMessage;
752
753         if (config.compareMode != GL_NONE)
754         {
755                 m_testCtx.getLog()      << tcu::TestLog::Message
756                                                         << "Texture mode is COMPARE_REF_TO_TEXTURE, mode = " << glu::getCompareFuncStr(config.compareMode) << "\n"
757                                                         << "Compare reference value = " << config.compareRef << "\n"
758                                                         << tcu::TestLog::EndMessage;
759         }
760 }
761
762 void TextureBorderClampTest::renderTo (tcu::Surface&                                                            surface,
763                                                                            const IterationConfig&                                               config,
764                                                                            const glu::TextureTestUtil::ReferenceParams& samplerParams)
765 {
766         const glw::Functions&                                           gl                      = m_context.getRenderContext().getFunctions();
767         const gls::TextureTestUtil::RandomViewport      viewport        (m_context.getRenderTarget(), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, getIterationSeed(config));
768         std::vector<float>                                                      texCoord;
769         de::MovePtr<glu::Sampler>                                       sampler;
770
771         glu::TextureTestUtil::computeQuadTexCoord2D(texCoord, config.p0, config.p1);
772
773         // Bind to unit 0.
774         gl.activeTexture(GL_TEXTURE0);
775         gl.bindTexture(GL_TEXTURE_2D, m_texture->getGLTexture());
776
777         if (m_sampleMode == tcu::Sampler::MODE_DEPTH)
778                 gl.texParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_DEPTH_COMPONENT);
779         else if (m_sampleMode == tcu::Sampler::MODE_STENCIL)
780                 gl.texParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX);
781
782         if (config.compareMode == GL_NONE)
783         {
784                 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
785                 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_ALWAYS);
786         }
787         else
788         {
789                 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
790                 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, config.compareMode);
791         }
792
793         if (m_stateType == STATE_TEXTURE_PARAM)
794         {
795                 // Setup filtering and wrap modes.
796                 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,              glu::getGLWrapMode(samplerParams.sampler.wrapS));
797                 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,              glu::getGLWrapMode(samplerParams.sampler.wrapT));
798                 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,  glu::getGLFilterMode(samplerParams.sampler.minFilter));
799                 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,  glu::getGLFilterMode(samplerParams.sampler.magFilter));
800
801                 switch (m_channelClass)
802                 {
803                         case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
804                         case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
805                         case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
806                                 gl.texParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, config.borderColor.getAccess<float>());
807                                 break;
808
809                         case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
810                                 gl.texParameterIiv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, config.borderColor.getAccess<deInt32>());
811                                 break;
812
813                         case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
814                                 gl.texParameterIuiv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, config.borderColor.getAccess<deUint32>());
815                                 break;
816
817                         default:
818                                 DE_ASSERT(false);
819                 }
820         }
821         else if (m_stateType == STATE_SAMPLER_PARAM)
822         {
823                 const tcu::Vec4 blue(0.0f, 0.0f, 1.0f, 1.0f);
824
825                 // Setup filtering and wrap modes to bad values
826                 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,              GL_REPEAT);
827                 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,              GL_REPEAT);
828                 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,  GL_NEAREST);
829                 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,  GL_NEAREST);
830                 gl.texParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, blue.getPtr()); // just set some unlikely color
831
832                 // setup sampler to correct values
833                 sampler = de::MovePtr<glu::Sampler>(new glu::Sampler(m_context.getRenderContext()));
834
835                 gl.samplerParameteri(**sampler, GL_TEXTURE_WRAP_S,              glu::getGLWrapMode(samplerParams.sampler.wrapS));
836                 gl.samplerParameteri(**sampler, GL_TEXTURE_WRAP_T,              glu::getGLWrapMode(samplerParams.sampler.wrapT));
837                 gl.samplerParameteri(**sampler, GL_TEXTURE_MIN_FILTER,  glu::getGLFilterMode(samplerParams.sampler.minFilter));
838                 gl.samplerParameteri(**sampler, GL_TEXTURE_MAG_FILTER,  glu::getGLFilterMode(samplerParams.sampler.magFilter));
839
840                 switch (m_channelClass)
841                 {
842                         case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
843                         case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
844                         case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
845                                 gl.samplerParameterfv(**sampler, GL_TEXTURE_BORDER_COLOR, config.borderColor.getAccess<float>());
846                                 break;
847
848                         case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
849                                 gl.samplerParameterIiv(**sampler, GL_TEXTURE_BORDER_COLOR, config.borderColor.getAccess<deInt32>());
850                                 break;
851
852                         case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
853                                 gl.samplerParameterIuiv(**sampler, GL_TEXTURE_BORDER_COLOR, config.borderColor.getAccess<deUint32>());
854                                 break;
855
856                         default:
857                                 DE_ASSERT(false);
858                 }
859
860                 gl.bindSampler(0, **sampler);
861         }
862
863         GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");
864
865         gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
866         renderQuad(&texCoord[0], samplerParams);
867         glu::readPixels(m_context.getRenderContext(), viewport.x, viewport.y, surface.getAccess());
868 }
869
870 void TextureBorderClampTest::renderQuad (const float* texCoord, const glu::TextureTestUtil::ReferenceParams& samplerParams)
871 {
872         // use TextureRenderer for basic rendering, use custom for gather
873         if (m_samplingFunction == SAMPLE_FILTER)
874                 m_renderer->renderQuad(0, texCoord, samplerParams);
875         else
876         {
877                 static const float position[] =
878                 {
879                         -1.0f, -1.0f, 0.0f, 1.0f,
880                         -1.0f, +1.0f, 0.0f, 1.0f,
881                         +1.0f, -1.0f, 0.0f, 1.0f,
882                         +1.0f, +1.0f, 0.0f, 1.0f
883                 };
884                 static const deUint16 indices[] =
885                 {
886                         0, 1, 2, 2, 1, 3
887                 };
888                 const glu::VertexArrayBinding vertexArrays[] =
889                 {
890                         glu::va::Float("a_position",    4,      4, 0, &position[0]),
891                         glu::va::Float("a_texcoord",    2,      4, 0, texCoord)
892                 };
893
894                 const glw::Functions&   gl              = m_context.getRenderContext().getFunctions();
895                 const deUint32                  progId  = m_gatherProgram->getProgram();
896
897                 gl.useProgram(progId);
898                 gl.uniform1i(gl.getUniformLocation(progId, "u_sampler"), 0);
899                 if (m_useShadowSampler)
900                         gl.uniform1f(gl.getUniformLocation(progId, "u_ref"), samplerParams.ref);
901                 gl.uniform4fv(gl.getUniformLocation(progId, "u_colorScale"), 1, samplerParams.colorScale.getPtr());
902                 gl.uniform4fv(gl.getUniformLocation(progId, "u_colorBias"), 1, samplerParams.colorBias.getPtr());
903
904                 glu::draw(m_context.getRenderContext(), progId, DE_LENGTH_OF_ARRAY(vertexArrays), &vertexArrays[0],
905                                         glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
906         }
907 }
908
909 void TextureBorderClampTest::verifyImage (const tcu::Surface&                                                   renderedFrame,
910                                                                                   const IterationConfig&                                                config,
911                                                                                   const glu::TextureTestUtil::ReferenceParams&  samplerParams)
912 {
913         const tcu::PixelFormat  pixelFormat             = m_context.getRenderTarget().getPixelFormat();
914
915         tcu::LodPrecision               lodPrecision;
916         std::vector<float>              texCoord;
917         bool                                    verificationOk;
918
919         glu::TextureTestUtil::computeQuadTexCoord2D(texCoord, config.p0, config.p1);
920
921         lodPrecision.derivateBits               = 18;
922         lodPrecision.lodBits                    = 5;
923
924         if (samplerParams.sampler.compare == tcu::Sampler::COMPAREMODE_NONE)
925         {
926                 const tcu::TextureFormat                texFormat                       = tcu::getEffectiveDepthStencilTextureFormat(m_texture->getRefTexture().getFormat(), m_sampleMode);
927                 const bool                                              isNearestMinFilter      = samplerParams.sampler.minFilter == tcu::Sampler::NEAREST || samplerParams.sampler.minFilter == tcu::Sampler::NEAREST_MIPMAP_NEAREST;
928                 const bool                                              isNearestMagFilter      = samplerParams.sampler.magFilter == tcu::Sampler::NEAREST;
929                 const bool                                              isNearestOnly           = isNearestMinFilter && isNearestMagFilter;
930                 const bool                                              isSRGB                          = texFormat.order == tcu::TextureFormat::sRGB || texFormat.order == tcu::TextureFormat::sRGBA;
931                 const int                                               colorErrorBits          = (isNearestOnly && !isSRGB) ? (1) : (2);
932                 const tcu::IVec4                                colorBits                       = tcu::max(glu::TextureTestUtil::getBitsVec(pixelFormat) - tcu::IVec4(colorErrorBits), tcu::IVec4(0));
933                 tcu::LookupPrecision                    lookupPrecision;
934
935                 lookupPrecision.colorThreshold  = tcu::computeFixedPointThreshold(colorBits) / samplerParams.colorScale;
936                 lookupPrecision.coordBits               = tcu::IVec3(20,20,0);
937                 lookupPrecision.uvwBits                 = tcu::IVec3(5,5,0);
938                 lookupPrecision.colorMask               = glu::TextureTestUtil::getCompareMask(pixelFormat);
939
940                 if (m_samplingFunction == SAMPLE_FILTER)
941                 {
942                         verificationOk = verifyTextureSampleResult(renderedFrame.getAccess(),
943                                                                                                            &texCoord[0],
944                                                                                                            samplerParams,
945                                                                                                            lodPrecision,
946                                                                                                            lookupPrecision);
947                 }
948                 else if (m_samplingFunction == SAMPLE_GATHER)
949                 {
950                         verificationOk = verifyTextureGatherResult(renderedFrame.getAccess(),
951                                                                                                            &texCoord[0],
952                                                                                                            samplerParams,
953                                                                                                            lookupPrecision);
954                 }
955                 else
956                 {
957                         DE_ASSERT(false);
958                         verificationOk = false;
959                 }
960         }
961         else
962         {
963                 tcu::TexComparePrecision        texComparePrecision;
964                 tcu::TexComparePrecision        lowQualityTexComparePrecision;
965                 tcu::LodPrecision                       lowQualityLodPrecision                  = lodPrecision;
966
967                 texComparePrecision.coordBits                                   = tcu::IVec3(20,20,0);
968                 texComparePrecision.uvwBits                                             = tcu::IVec3(7,7,0);
969                 texComparePrecision.pcfBits                                             = 5;
970                 texComparePrecision.referenceBits                               = 16;
971                 texComparePrecision.resultBits                                  = de::max(0, pixelFormat.redBits - 1);
972
973                 lowQualityTexComparePrecision.coordBits                 = tcu::IVec3(20,20,0);
974                 lowQualityTexComparePrecision.uvwBits                   = tcu::IVec3(4,4,0);
975                 lowQualityTexComparePrecision.pcfBits                   = 0;
976                 lowQualityTexComparePrecision.referenceBits             = 16;
977                 lowQualityTexComparePrecision.resultBits                = de::max(0, pixelFormat.redBits - 1);
978
979                 lowQualityLodPrecision.lodBits                                  = 4;
980
981                 if (m_samplingFunction == SAMPLE_FILTER)
982                 {
983                         verificationOk = verifyTextureCompareResult(renderedFrame.getAccess(),
984                                                                                                                 &texCoord[0],
985                                                                                                                 samplerParams,
986                                                                                                                 texComparePrecision,
987                                                                                                                 lowQualityTexComparePrecision,
988                                                                                                                 lodPrecision,
989                                                                                                                 lowQualityLodPrecision);
990                 }
991                 else if (m_samplingFunction == SAMPLE_GATHER)
992                 {
993                         verificationOk = verifyTextureGatherCmpResult(renderedFrame.getAccess(),
994                                                                                                                   &texCoord[0],
995                                                                                                                   samplerParams,
996                                                                                                                   texComparePrecision,
997                                                                                                                   lowQualityTexComparePrecision);
998                 }
999                 else
1000                 {
1001                         DE_ASSERT(false);
1002                         verificationOk = false;
1003                 }
1004         }
1005
1006         if (!verificationOk)
1007                 m_result.fail("Image verification failed");
1008 }
1009
1010 bool TextureBorderClampTest::verifyTextureSampleResult (const tcu::ConstPixelBufferAccess&                              renderedFrame,
1011                                                                                                                 const float*                                                                    texCoord,
1012                                                                                                                 const glu::TextureTestUtil::ReferenceParams&    samplerParams,
1013                                                                                                                 const tcu::LodPrecision&                                                lodPrecision,
1014                                                                                                             const tcu::LookupPrecision&                                         lookupPrecision)
1015 {
1016         const tcu::PixelFormat                  pixelFormat                     = m_context.getRenderTarget().getPixelFormat();
1017         tcu::Surface                                    reference                       (renderedFrame.getWidth(), renderedFrame.getHeight());
1018         tcu::Surface                                    errorMask                       (renderedFrame.getWidth(), renderedFrame.getHeight());
1019         int                                                             numFailedPixels;
1020
1021         glu::TextureTestUtil::sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), m_texture->getRefTexture(), texCoord, samplerParams);
1022
1023         numFailedPixels = glu::TextureTestUtil::computeTextureLookupDiff(renderedFrame, reference.getAccess(), errorMask.getAccess(), m_texture->getRefTexture(),
1024                                                                                                                                          texCoord, samplerParams, lookupPrecision, lodPrecision, m_testCtx.getWatchDog());
1025
1026         if (numFailedPixels > 0)
1027                 m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage;
1028         m_testCtx.getLog()      << tcu::TestLog::ImageSet("VerifyResult", "Verification result")
1029                                                 << tcu::TestLog::Image("Rendered", "Rendered image", renderedFrame);
1030         if (numFailedPixels > 0)
1031         {
1032                 m_testCtx.getLog()      << tcu::TestLog::Image("Reference", "Ideal reference image", reference)
1033                                                         << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask);
1034         }
1035         m_testCtx.getLog() << tcu::TestLog::EndImageSet;
1036
1037         return (numFailedPixels == 0);
1038 }
1039
1040 bool TextureBorderClampTest::verifyTextureCompareResult (const tcu::ConstPixelBufferAccess&                             renderedFrame,
1041                                                                                                                  const float*                                                                   texCoord,
1042                                                                                                                  const glu::TextureTestUtil::ReferenceParams&   samplerParams,
1043                                                                                                              const tcu::TexComparePrecision&                            texComparePrecision,
1044                                                                                                              const tcu::TexComparePrecision&                            lowQualityTexComparePrecision,
1045                                                                                                                  const tcu::LodPrecision&                                               lodPrecision,
1046                                                                                                                  const tcu::LodPrecision&                                               lowQualityLodPrecision)
1047 {
1048         const tcu::PixelFormat                                          pixelFormat                             = m_context.getRenderTarget().getPixelFormat();
1049         const int                                                                       colorErrorBits                  = 1;
1050         const tcu::IVec4                                                        nonShadowBits                   = tcu::max(glu::TextureTestUtil::getBitsVec(pixelFormat) - tcu::IVec4(colorErrorBits), tcu::IVec4(0));
1051         const tcu::Vec3                                                         nonShadowThreshold              = tcu::computeFixedPointThreshold(nonShadowBits).swizzle(1,2,3);
1052         std::vector<tcu::ConstPixelBufferAccess>        srcLevelStorage;
1053         const tcu::Texture2DView                                        effectiveView                   = tcu::getEffectiveTextureView(m_texture->getRefTexture(), srcLevelStorage, samplerParams.sampler);
1054         tcu::Surface                                                            reference                               (renderedFrame.getWidth(), renderedFrame.getHeight());
1055         tcu::Surface                                                            errorMask                               (renderedFrame.getWidth(), renderedFrame.getHeight());
1056         int                                                                                     numFailedPixels;
1057
1058         glu::TextureTestUtil::sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), effectiveView, texCoord, samplerParams);
1059
1060         numFailedPixels = glu::TextureTestUtil::computeTextureCompareDiff(renderedFrame, reference.getAccess(), errorMask.getAccess(), effectiveView,
1061                                                                                                                                           texCoord, samplerParams, texComparePrecision, lodPrecision, nonShadowThreshold);
1062
1063         if (numFailedPixels > 0)
1064         {
1065                 m_testCtx.getLog()      << tcu::TestLog::Message
1066                                                         << "Warning: Verification assuming high-quality PCF filtering failed."
1067                                                         << tcu::TestLog::EndMessage;
1068
1069                 numFailedPixels = glu::TextureTestUtil::computeTextureCompareDiff(renderedFrame, reference.getAccess(), errorMask.getAccess(), effectiveView,
1070                                                                                                                                                   texCoord, samplerParams, lowQualityTexComparePrecision, lowQualityLodPrecision, nonShadowThreshold);
1071
1072                 if (numFailedPixels > 0)
1073                         m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: Verification against low precision requirements failed, failing test case." << tcu::TestLog::EndMessage;
1074                 else if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
1075                         m_result.addResult(QP_TEST_RESULT_QUALITY_WARNING, "Low-quality result");
1076         }
1077
1078         if (numFailedPixels > 0)
1079                 m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage;
1080         m_testCtx.getLog()      << tcu::TestLog::ImageSet("VerifyResult", "Verification result")
1081                                                 << tcu::TestLog::Image("Rendered", "Rendered image", renderedFrame);
1082         if (numFailedPixels > 0)
1083         {
1084                 m_testCtx.getLog()      << tcu::TestLog::Image("Reference", "Ideal reference image", reference)
1085                                                         << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask);
1086         }
1087         m_testCtx.getLog() << tcu::TestLog::EndImageSet;
1088
1089         return (numFailedPixels == 0);
1090 }
1091
1092 template <typename T>
1093 static inline T triQuadInterpolate (const T (&values)[4], float xFactor, float yFactor)
1094 {
1095         if (xFactor + yFactor < 1.0f)
1096                 return values[0] + (values[2]-values[0])*xFactor                + (values[1]-values[0])*yFactor;
1097         else
1098                 return values[3] + (values[1]-values[3])*(1.0f-xFactor) + (values[2]-values[3])*(1.0f-yFactor);
1099 }
1100
1101 bool TextureBorderClampTest::verifyTextureGatherResult (const tcu::ConstPixelBufferAccess&                              renderedFrame,
1102                                                                                                                 const float*                                                                    texCoordArray,
1103                                                                                                                 const glu::TextureTestUtil::ReferenceParams&    samplerParams,
1104                                                                                                                 const tcu::LookupPrecision&                                             lookupPrecision)
1105 {
1106         const tcu::Vec2 texCoords[4] =
1107         {
1108                 tcu::Vec2(texCoordArray[0], texCoordArray[1]),
1109                 tcu::Vec2(texCoordArray[2], texCoordArray[3]),
1110                 tcu::Vec2(texCoordArray[4], texCoordArray[5]),
1111                 tcu::Vec2(texCoordArray[6], texCoordArray[7]),
1112         };
1113
1114         const tcu::PixelFormat                                          pixelFormat                     = m_context.getRenderTarget().getPixelFormat();
1115         const deUint8                                                           fbColormask                     = tcu::getColorMask(pixelFormat);
1116
1117         std::vector<tcu::ConstPixelBufferAccess>        srcLevelStorage;
1118         const tcu::Texture2DView                                        effectiveView           = tcu::getEffectiveTextureView(m_texture->getRefTexture(), srcLevelStorage, samplerParams.sampler);
1119
1120         tcu::Surface                                                            reference                       (renderedFrame.getWidth(), renderedFrame.getHeight());
1121         tcu::Surface                                                            errorMask                       (renderedFrame.getWidth(), renderedFrame.getHeight());
1122         int                                                                                     numFailedPixels         = 0;
1123
1124         tcu::clear(errorMask.getAccess(), tcu::RGBA::green().toVec());
1125
1126         for (int py = 0; py < reference.getHeight(); ++py)
1127         for (int px = 0; px < reference.getWidth(); ++px)
1128         {
1129                 const tcu::Vec2                 viewportCoord   = (tcu::Vec2((float)px, (float)py) + tcu::Vec2(0.5f)) / tcu::Vec2((float)reference.getWidth(), (float)reference.getHeight());
1130                 const tcu::Vec2                 texCoord                = triQuadInterpolate(texCoords, viewportCoord.x(), viewportCoord.y());
1131                 const tcu::Vec4                 referenceValue  = effectiveView.gatherOffsets(samplerParams.sampler, texCoord.x(), texCoord.y(), 0, glu::getDefaultGatherOffsets());
1132                 const tcu::Vec4                 referencePixel  = referenceValue * samplerParams.colorScale + samplerParams.colorBias;
1133                 const tcu::Vec4                 resultPixel             = renderedFrame.getPixel(px, py);
1134                 const tcu::Vec4                 resultValue             = (resultPixel - samplerParams.colorBias) / samplerParams.colorScale;
1135
1136                 reference.setPixel(px, py, tcu::toRGBAMasked(referenceValue, fbColormask));
1137
1138                 if (tcu::boolAny(tcu::logicalAnd(lookupPrecision.colorMask,
1139                                                                                  tcu::greaterThan(tcu::absDiff(resultPixel, referencePixel),
1140                                                                                                                   lookupPrecision.colorThreshold))))
1141                 {
1142                         if (!tcu::isGatherOffsetsResultValid(effectiveView, samplerParams.sampler, lookupPrecision, texCoord, 0, glu::getDefaultGatherOffsets(), resultValue))
1143                         {
1144                                 errorMask.setPixel(px, py, tcu::RGBA::red());
1145                                 ++numFailedPixels;
1146                         }
1147                 }
1148         }
1149
1150         if (numFailedPixels > 0)
1151                 m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage;
1152         m_testCtx.getLog()      << tcu::TestLog::ImageSet("VerifyResult", "Verification result")
1153                                                 << tcu::TestLog::Image("Rendered", "Rendered image", renderedFrame);
1154         if (numFailedPixels > 0)
1155         {
1156                 m_testCtx.getLog()      << tcu::TestLog::Image("Reference", "Ideal reference image", reference)
1157                                                         << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask);
1158         }
1159         m_testCtx.getLog() << tcu::TestLog::EndImageSet;
1160
1161         return (numFailedPixels == 0);
1162 }
1163
1164 bool TextureBorderClampTest::verifyTextureGatherCmpResult (const tcu::ConstPixelBufferAccess&                   renderedFrame,
1165                                                                                                                    const float*                                                                 texCoordArray,
1166                                                                                                                    const glu::TextureTestUtil::ReferenceParams& samplerParams,
1167                                                                                                                    const tcu::TexComparePrecision&                              texComparePrecision,
1168                                                                                                                    const tcu::TexComparePrecision&                              lowQualityTexComparePrecision)
1169 {
1170         const tcu::Vec2 texCoords[4] =
1171         {
1172                 tcu::Vec2(texCoordArray[0], texCoordArray[1]),
1173                 tcu::Vec2(texCoordArray[2], texCoordArray[3]),
1174                 tcu::Vec2(texCoordArray[4], texCoordArray[5]),
1175                 tcu::Vec2(texCoordArray[6], texCoordArray[7]),
1176         };
1177
1178         std::vector<tcu::ConstPixelBufferAccess>        srcLevelStorage;
1179         const tcu::Texture2DView                                        effectiveView           = tcu::getEffectiveTextureView(m_texture->getRefTexture(), srcLevelStorage, samplerParams.sampler);
1180
1181         const tcu::PixelFormat                                          pixelFormat                     = m_context.getRenderTarget().getPixelFormat();
1182         const tcu::BVec4                                                        colorMask                       = glu::TextureTestUtil::getCompareMask(pixelFormat);
1183         const deUint8                                                           fbColormask                     = tcu::getColorMask(pixelFormat);
1184         tcu::Surface                                                            reference                       (renderedFrame.getWidth(), renderedFrame.getHeight());
1185         tcu::Surface                                                            errorMask                       (renderedFrame.getWidth(), renderedFrame.getHeight());
1186         int                                                                                     numFailedPixels         = 0;
1187         bool                                                                            lowQuality                      = false;
1188
1189         tcu::clear(errorMask.getAccess(), tcu::RGBA::green().toVec());
1190
1191         for (int py = 0; py < reference.getHeight(); ++py)
1192         for (int px = 0; px < reference.getWidth(); ++px)
1193         {
1194                 const tcu::Vec2                 viewportCoord   = (tcu::Vec2((float)px, (float)py) + tcu::Vec2(0.5f)) / tcu::Vec2((float)reference.getWidth(), (float)reference.getHeight());
1195                 const tcu::Vec2                 texCoord                = triQuadInterpolate(texCoords, viewportCoord.x(), viewportCoord.y());
1196                 const float                             refZ                    = samplerParams.ref;
1197                 const tcu::Vec4                 referenceValue  = effectiveView.gatherOffsetsCompare(samplerParams.sampler, refZ, texCoord.x(), texCoord.y(), glu::getDefaultGatherOffsets());
1198                 const tcu::Vec4                 resultValue             = renderedFrame.getPixel(px, py);
1199
1200                 reference.setPixel(px, py, tcu::toRGBAMasked(referenceValue, fbColormask));
1201
1202                 if (tcu::boolAny(tcu::logicalAnd(colorMask, tcu::notEqual(referenceValue, resultValue))))
1203                 {
1204                         if (!tcu::isGatherOffsetsCompareResultValid(effectiveView, samplerParams.sampler, texComparePrecision, texCoord, glu::getDefaultGatherOffsets(), refZ, resultValue))
1205                         {
1206                                 lowQuality = true;
1207
1208                                 // fall back to low quality verification
1209                                 if (!tcu::isGatherOffsetsCompareResultValid(effectiveView, samplerParams.sampler, lowQualityTexComparePrecision, texCoord, glu::getDefaultGatherOffsets(), refZ, resultValue))
1210                                 {
1211                                         errorMask.setPixel(px, py, tcu::RGBA::red());
1212                                         ++numFailedPixels;
1213                                 }
1214                         }
1215                 }
1216         }
1217
1218         if (numFailedPixels > 0)
1219                 m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage;
1220         else if (lowQuality)
1221         {
1222                 m_testCtx.getLog() << tcu::TestLog::Message << "Warning: Verification assuming high-quality PCF filtering failed." << tcu::TestLog::EndMessage;
1223                 m_result.addResult(QP_TEST_RESULT_QUALITY_WARNING, "Low-quality result");
1224         }
1225
1226         m_testCtx.getLog()      << tcu::TestLog::ImageSet("VerifyResult", "Verification result")
1227                                                 << tcu::TestLog::Image("Rendered", "Rendered image", renderedFrame);
1228         if (numFailedPixels > 0)
1229         {
1230                 m_testCtx.getLog()      << tcu::TestLog::Image("Reference", "Ideal reference image", reference)
1231                                                         << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask);
1232         }
1233         m_testCtx.getLog() << tcu::TestLog::EndImageSet;
1234
1235         return (numFailedPixels == 0);
1236 }
1237
1238 const glu::Texture2D* TextureBorderClampTest::getTexture (void) const
1239 {
1240         return m_texture.get();
1241 }
1242
1243 deUint32 TextureBorderClampTest::getIterationSeed (const IterationConfig& config) const
1244 {
1245         tcu::SeedBuilder builder;
1246         builder << std::string(getName())
1247                         << m_iterationNdx
1248                         << m_texFormat
1249                         << config.minFilter << config.magFilter
1250                         << m_texture->getRefTexture().getWidth() << m_texture->getRefTexture().getHeight();
1251         return builder.get();
1252 }
1253
1254 glu::TextureTestUtil::ReferenceParams TextureBorderClampTest::genSamplerParams (const IterationConfig& config) const
1255 {
1256         const tcu::TextureFormat                                texFormat               = tcu::getEffectiveDepthStencilTextureFormat(m_texture->getRefTexture().getFormat(), m_sampleMode);
1257         glu::TextureTestUtil::ReferenceParams   refParams               (glu::TextureTestUtil::TEXTURETYPE_2D);
1258
1259         refParams.sampler                                       = glu::mapGLSampler(config.sWrapMode, config.tWrapMode, config.minFilter, config.magFilter);
1260         refParams.sampler.borderColor           = config.borderColor;
1261         refParams.sampler.compare                       = (!m_useShadowSampler) ? (tcu::Sampler::COMPAREMODE_NONE) : (glu::mapGLCompareFunc(config.compareMode));
1262         refParams.sampler.depthStencilMode      = m_sampleMode;
1263         refParams.lodMode                                       = glu::TextureTestUtil::LODMODE_EXACT;
1264         refParams.samplerType                           = (!m_useShadowSampler) ? (glu::TextureTestUtil::getSamplerType(texFormat)) : (glu::TextureTestUtil::SAMPLERTYPE_SHADOW);
1265         refParams.colorScale                            = config.lookupScale;
1266         refParams.colorBias                                     = config.lookupBias;
1267         refParams.ref                                           = config.compareRef;
1268
1269         // compare can only be used with depth textures
1270         if (!isDepthFormat(m_texFormat, m_sampleMode))
1271                 DE_ASSERT(refParams.sampler.compare == tcu::Sampler::COMPAREMODE_NONE);
1272
1273         // sampler type must match compare mode
1274         DE_ASSERT(m_useShadowSampler == (config.compareMode != GL_NONE));
1275
1276         // in gather, weird mapping is most likely an error
1277         if (m_samplingFunction == SAMPLE_GATHER)
1278         {
1279                 DE_ASSERT(refParams.colorScale == tcu::Vec4(refParams.colorScale.x()));
1280                 DE_ASSERT(refParams.colorBias == tcu::Vec4(refParams.colorBias.x()));
1281         }
1282
1283         return refParams;
1284 }
1285
1286 glu::ShaderProgram* TextureBorderClampTest::genGatherProgram (void) const
1287 {
1288         const std::string       glslVersionDecl = glu::getGLSLVersionDeclaration(glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType()));
1289         const std::string       vtxSource               = glslVersionDecl + "\n"
1290                                                                                 "in highp vec4 a_position;\n"
1291                                                                                 "in highp vec2 a_texcoord;\n"
1292                                                                                 "out highp vec2 v_texcoord;\n"
1293                                                                                 "void main()\n"
1294                                                                                 "{\n"
1295                                                                                 "       gl_Position = a_position;\n"
1296                                                                                 "       v_texcoord = a_texcoord;\n"
1297                                                                                 "}\n";
1298         const char*                     samplerType;
1299         const char*                     lookup;
1300         std::ostringstream      fragSource;
1301
1302         if (m_useShadowSampler)
1303         {
1304                 samplerType     = "sampler2DShadow";
1305                 lookup          = "textureGather(u_sampler, v_texcoord, u_ref)";
1306         }
1307         else
1308         {
1309                 switch (m_channelClass)
1310                 {
1311                         case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1312                         case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1313                         case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1314                                 samplerType     = "sampler2D";
1315                                 lookup          = "textureGather(u_sampler, v_texcoord)";
1316                                 break;
1317
1318                         case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1319                                 samplerType     = "isampler2D";
1320                                 lookup          = "vec4(textureGather(u_sampler, v_texcoord))";
1321                                 break;
1322
1323                         case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1324                                 samplerType     = "usampler2D";
1325                                 lookup          = "vec4(textureGather(u_sampler, v_texcoord))";
1326                                 break;
1327
1328                         default:
1329                                 samplerType     = "";
1330                                 lookup          = "";
1331                                 DE_ASSERT(false);
1332                 }
1333         }
1334
1335         fragSource      <<      glslVersionDecl + "\n"
1336                                         "uniform highp " << samplerType << " u_sampler;\n"
1337                                         "uniform highp vec4 u_colorScale;\n"
1338                                         "uniform highp vec4 u_colorBias;\n"
1339                                 <<      ((m_useShadowSampler) ? ("uniform highp float u_ref;\n") : (""))
1340                                 <<      "in highp vec2 v_texcoord;\n"
1341                                         "layout(location=0) out highp vec4 o_color;\n"
1342                                         "void main()\n"
1343                                         "{\n"
1344                                         "       o_color = " << lookup << " * u_colorScale + u_colorBias;\n"
1345                                         "}\n";
1346
1347         return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(vtxSource) << glu::FragmentSource(fragSource.str()));
1348 }
1349
1350 class TextureBorderClampFormatCase : public TextureBorderClampTest
1351 {
1352 public:
1353                                                                         TextureBorderClampFormatCase    (Context&                                               context,
1354                                                                                                                                          const char*                                    name,
1355                                                                                                                                          const char*                                    description,
1356                                                                                                                                          deUint32                                               texFormat,
1357                                                                                                                                          tcu::Sampler::DepthStencilMode mode,
1358                                                                                                                                          StateType                                              stateType,
1359                                                                                                                                          SizeType                                               sizeType,
1360                                                                                                                                          deUint32                                               filter,
1361                                                                                                                                          SamplingFunction                               samplingFunction);
1362
1363 private:
1364         void                                                    init                                                    (void);
1365
1366         int                                                             getNumIterations                                (void) const;
1367         IterationConfig                                 getIteration                                    (int ndx) const;
1368
1369         const SizeType                                  m_sizeType;
1370         const deUint32                                  m_filter;
1371
1372         std::vector<IterationConfig>    m_iterations;
1373 };
1374
1375
1376 TextureBorderClampFormatCase::TextureBorderClampFormatCase      (Context&                                               context,
1377                                                                                                                          const char*                                    name,
1378                                                                                                                          const char*                                    description,
1379                                                                                                                          deUint32                                               texFormat,
1380                                                                                                                          tcu::Sampler::DepthStencilMode mode,
1381                                                                                                                          StateType                                              stateType,
1382                                                                                                                          SizeType                                               sizeType,
1383                                                                                                                          deUint32                                               filter,
1384                                                                                                                          SamplingFunction                               samplingFunction)
1385         : TextureBorderClampTest(context,
1386                                                          name,
1387                                                          description,
1388                                                          texFormat,
1389                                                          mode,
1390                                                          stateType,
1391                                                          (sizeType == SIZE_POT) ? (32) : (17),
1392                                                          (sizeType == SIZE_POT) ? (16) : (31),
1393                                                          samplingFunction)
1394         , m_sizeType                    (sizeType)
1395         , m_filter                              (filter)
1396 {
1397         if (m_sizeType == SIZE_POT)
1398                 DE_ASSERT(deIsPowerOfTwo32(m_texWidth) && deIsPowerOfTwo32(m_texHeight));
1399         else
1400                 DE_ASSERT(!deIsPowerOfTwo32(m_texWidth) && !deIsPowerOfTwo32(m_texHeight));
1401
1402         if (glu::isCompressedFormat(texFormat))
1403         {
1404                 const tcu::CompressedTexFormat  compressedFormat        = glu::mapGLCompressedTexFormat(texFormat);
1405                 const tcu::IVec3                                blockPixelSize          = tcu::getBlockPixelSize(compressedFormat);
1406
1407                 // is (not) multiple of a block size
1408                 if (m_sizeType == SIZE_POT)
1409                         DE_ASSERT((m_texWidth % blockPixelSize.x()) == 0 && (m_texHeight % blockPixelSize.y()) == 0);
1410                 else
1411                         DE_ASSERT((m_texWidth % blockPixelSize.x()) != 0 && (m_texHeight % blockPixelSize.y()) != 0);
1412
1413                 DE_UNREF(blockPixelSize);
1414         }
1415 }
1416
1417 void TextureBorderClampFormatCase::init (void)
1418 {
1419         TextureBorderClampTest::init();
1420
1421         // \note TextureBorderClampTest::init() creates texture
1422         const tcu::TextureFormat                texFormat               = tcu::getEffectiveDepthStencilTextureFormat(getTexture()->getRefTexture().getFormat(), m_sampleMode);
1423         const tcu::TextureFormatInfo    texFormatInfo   = tcu::getTextureFormatInfo(texFormat);
1424
1425         // iterations
1426
1427         {
1428                 IterationConfig iteration;
1429                 iteration.p0                    = tcu::Vec2(-1.5f, -3.0f);
1430                 iteration.p1                    = tcu::Vec2( 1.5f,  2.5f);
1431                 iteration.borderColor   = mapToFormatColorRepresentable(texFormat, tcu::Vec4(0.3f, 0.7f, 0.2f, 0.5f));
1432                 m_iterations.push_back(iteration);
1433         }
1434         {
1435                 IterationConfig iteration;
1436                 iteration.p0                    = tcu::Vec2(-0.5f, 0.75f);
1437                 iteration.p1                    = tcu::Vec2(0.25f, 1.25f);
1438                 iteration.borderColor   = mapToFormatColorRepresentable(texFormat, tcu::Vec4(0.9f, 0.2f, 0.4f, 0.6f));
1439                 m_iterations.push_back(iteration);
1440         }
1441
1442         // common parameters
1443         for (int ndx = 0; ndx < (int)m_iterations.size(); ++ndx)
1444         {
1445                 IterationConfig& iteration = m_iterations[ndx];
1446
1447                 if (m_samplingFunction == SAMPLE_GATHER)
1448                 {
1449                         iteration.lookupScale   = tcu::Vec4(texFormatInfo.lookupScale.x());
1450                         iteration.lookupBias    = tcu::Vec4(texFormatInfo.lookupBias.x());
1451                 }
1452                 else
1453                 {
1454                         iteration.lookupScale   = texFormatInfo.lookupScale;
1455                         iteration.lookupBias    = texFormatInfo.lookupBias;
1456                 }
1457
1458                 iteration.minFilter             = m_filter;
1459                 iteration.magFilter             = m_filter;
1460                 iteration.sWrapMode             = GL_CLAMP_TO_BORDER;
1461                 iteration.tWrapMode             = GL_CLAMP_TO_BORDER;
1462                 iteration.compareMode   = GL_NONE;
1463                 iteration.compareRef    = 0.0f;
1464         }
1465 }
1466
1467 int TextureBorderClampFormatCase::getNumIterations      (void) const
1468 {
1469         return (int)m_iterations.size();
1470 }
1471
1472 TextureBorderClampTest::IterationConfig TextureBorderClampFormatCase::getIteration (int ndx) const
1473 {
1474         return m_iterations[ndx];
1475 }
1476
1477 class TextureBorderClampRangeClampCase : public TextureBorderClampTest
1478 {
1479 public:
1480                                                                         TextureBorderClampRangeClampCase        (Context&                                               context,
1481                                                                                                                                                  const char*                                    name,
1482                                                                                                                                                  const char*                                    description,
1483                                                                                                                                                  deUint32                                               texFormat,
1484                                                                                                                                                  tcu::Sampler::DepthStencilMode mode,
1485                                                                                                                                                  deUint32                                               filter);
1486
1487 private:
1488         void                                                    init                                                            (void);
1489
1490         int                                                             getNumIterations                                        (void) const;
1491         IterationConfig                                 getIteration                                            (int ndx) const;
1492
1493         const deUint32                                  m_filter;
1494         std::vector<IterationConfig>    m_iterations;
1495 };
1496
1497 TextureBorderClampRangeClampCase::TextureBorderClampRangeClampCase      (Context&                                               context,
1498                                                                                                                                          const char*                                    name,
1499                                                                                                                                          const char*                                    description,
1500                                                                                                                                          deUint32                                               texFormat,
1501                                                                                                                                          tcu::Sampler::DepthStencilMode mode,
1502                                                                                                                                          deUint32                                               filter)
1503         : TextureBorderClampTest(context, name, description, texFormat, mode, TextureBorderClampTest::STATE_TEXTURE_PARAM, 8, 32, SAMPLE_FILTER)
1504         , m_filter                              (filter)
1505 {
1506 }
1507
1508 void TextureBorderClampRangeClampCase::init (void)
1509 {
1510         TextureBorderClampTest::init();
1511
1512         const tcu::TextureFormat        texFormat               = tcu::getEffectiveDepthStencilTextureFormat(getTexture()->getRefTexture().getFormat(), m_sampleMode);
1513         const bool                                      isDepth                 = isDepthFormat(m_texFormat, m_sampleMode);
1514         const bool                                      isFloat                 = m_channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT;
1515         const bool                                      isFixed                 = m_channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT || m_channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT;
1516         const bool                                      isPureInteger   = m_channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || m_channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
1517
1518         if (isDepth || isFloat)
1519         {
1520                 // infinities are commonly used values on depth/float borders
1521                 {
1522                         IterationConfig iteration;
1523                         iteration.p0                    = tcu::Vec2(-1.2f, -3.0f);
1524                         iteration.p1                    = tcu::Vec2( 1.2f,  2.5f);
1525                         iteration.borderColor   = rr::GenericVec4(tcu::Vec4(std::numeric_limits<float>::infinity()));
1526                         iteration.lookupScale   = tcu::Vec4(0.5f); // scale & bias to [0.25, 0.5] range to make out-of-range values visible
1527                         iteration.lookupBias    = tcu::Vec4(0.25f);
1528                         iteration.description   = "border value infinity";
1529                         m_iterations.push_back(iteration);
1530                 }
1531                 {
1532                         IterationConfig iteration;
1533                         iteration.p0                    = tcu::Vec2(-0.25f, -0.75f);
1534                         iteration.p1                    = tcu::Vec2( 2.25f,  1.25f);
1535                         iteration.borderColor   = rr::GenericVec4(tcu::Vec4(-std::numeric_limits<float>::infinity()));
1536                         iteration.lookupScale   = tcu::Vec4(0.5f);
1537                         iteration.lookupBias    = tcu::Vec4(0.25f);
1538                         iteration.description   = "border value negative infinity";
1539                         m_iterations.push_back(iteration);
1540                 }
1541         }
1542         else if (isPureInteger)
1543         {
1544                 const tcu::IVec4                        numBits         = tcu::getTextureFormatBitDepth(texFormat);
1545                 const bool                                      isSigned        = m_channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER;
1546
1547                 // can't overflow 32bit integers with 32bit integers
1548                 for (int ndx = 0; ndx < 4; ++ndx)
1549                         DE_ASSERT(numBits[ndx] == 0 || numBits[ndx] == 8 || numBits[ndx] == 16);
1550
1551                 const tcu::IVec4        minValue                = getNBitIntegerVec4MinValue(isSigned, numBits);
1552                 const tcu::IVec4        maxValue                = getNBitIntegerVec4MaxValue(isSigned, numBits);
1553                 const tcu::IVec4        valueRange              = maxValue - minValue;
1554                 const tcu::IVec4        divSafeRange    ((valueRange[0]==0) ? (1) : (valueRange[0]),
1555                                                                                          (valueRange[1]==0) ? (1) : (valueRange[1]),
1556                                                                                          (valueRange[2]==0) ? (1) : (valueRange[2]),
1557                                                                                          (valueRange[3]==0) ? (1) : (valueRange[3]));
1558
1559                 // format max
1560                 {
1561                         const tcu::IVec4 value = maxValue + tcu::IVec4(1);
1562
1563                         IterationConfig iteration;
1564                         iteration.p0                    = tcu::Vec2(-1.2f, -3.0f);
1565                         iteration.p1                    = tcu::Vec2( 1.2f,  2.5f);
1566                         iteration.borderColor   = (isSigned) ? (rr::GenericVec4(value)) : (rr::GenericVec4(value.cast<deUint32>()));
1567                         iteration.lookupScale   = tcu::Vec4(0.5f) / divSafeRange.cast<float>();
1568                         iteration.lookupBias    = (isSigned) ? (tcu::Vec4(0.5f)) : (tcu::Vec4(0.25f));
1569                         iteration.description   = "border values one larger than maximum";
1570                         m_iterations.push_back(iteration);
1571                 }
1572                 // format min
1573                 if (isSigned)
1574                 {
1575                         const tcu::IVec4 value = minValue - tcu::IVec4(1);
1576
1577                         IterationConfig iteration;
1578                         iteration.p0                    = tcu::Vec2(-0.25f, -0.75f);
1579                         iteration.p1                    = tcu::Vec2( 2.25f,  1.25f);
1580                         iteration.borderColor   = rr::GenericVec4(value);
1581                         iteration.lookupScale   = tcu::Vec4(0.5f) / divSafeRange.cast<float>();
1582                         iteration.lookupBias    = tcu::Vec4(0.5f);
1583                         iteration.description   = "border values one less than minimum";
1584                         m_iterations.push_back(iteration);
1585                 }
1586                 // (u)int32 max
1587                 {
1588                         const tcu::IVec4 value = (isSigned) ? (tcu::IVec4(std::numeric_limits<deInt32>::max())) : (tcu::IVec4(std::numeric_limits<deUint32>::max()));
1589
1590                         IterationConfig iteration;
1591                         iteration.p0                    = tcu::Vec2(-1.6f, -2.1f);
1592                         iteration.p1                    = tcu::Vec2( 1.2f,  3.5f);
1593                         iteration.borderColor   = (isSigned) ? (rr::GenericVec4(value)) : (rr::GenericVec4(value.cast<deUint32>()));
1594                         iteration.lookupScale   = tcu::Vec4(0.5f) / divSafeRange.cast<float>();
1595                         iteration.lookupBias    = tcu::Vec4(0.25f);
1596                         iteration.description   = "border values 32-bit maximum";
1597                         m_iterations.push_back(iteration);
1598                 }
1599                 // int32 min
1600                 if (isSigned)
1601                 {
1602                         const tcu::IVec4 value = tcu::IVec4(std::numeric_limits<deInt32>::min());
1603
1604                         IterationConfig iteration;
1605                         iteration.p0                    = tcu::Vec2(-2.6f, -4.0f);
1606                         iteration.p1                    = tcu::Vec2( 1.1f,  1.5f);
1607                         iteration.borderColor   = rr::GenericVec4(value);
1608                         iteration.lookupScale   = tcu::Vec4(0.5f) / divSafeRange.cast<float>();
1609                         iteration.lookupBias    = tcu::Vec4(0.25f);
1610                         iteration.description   = "border values 0";
1611                         m_iterations.push_back(iteration);
1612                 }
1613         }
1614         else if (isFixed)
1615         {
1616                 const bool              isSigned        = m_channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT;;
1617                 const tcu::Vec4 lookupBias      = (isSigned) ? (tcu::Vec4(0.5f))    : (tcu::Vec4(0.25f)); // scale & bias to [0.25, 0.5] range to make out-of-range values visible
1618                 const tcu::Vec4 lookupScale     = (isSigned) ? (tcu::Vec4(0.25f))   : (tcu::Vec4(0.5f));
1619
1620                 {
1621                         IterationConfig iteration;
1622                         iteration.p0                    = tcu::Vec2(-1.2f, -3.0f);
1623                         iteration.p1                    = tcu::Vec2( 1.2f,  2.5f);
1624                         iteration.borderColor   = mapToFormatColorUnits(texFormat, tcu::Vec4(1.1f, 1.3f, 2.2f, 1.3f));
1625                         iteration.lookupScale   = lookupScale;
1626                         iteration.lookupBias    = lookupBias;
1627                         iteration.description   = "border values larger than maximum";
1628                         m_iterations.push_back(iteration);
1629                 }
1630                 {
1631                         IterationConfig iteration;
1632                         iteration.p0                    = tcu::Vec2(-0.25f, -0.75f);
1633                         iteration.p1                    = tcu::Vec2( 2.25f,  1.25f);
1634                         iteration.borderColor   = mapToFormatColorUnits(texFormat, tcu::Vec4(-0.2f, -0.9f, -2.4f, -0.6f));
1635                         iteration.lookupScale   = lookupScale;
1636                         iteration.lookupBias    = lookupBias;
1637                         iteration.description   = "border values less than minimum";
1638                         m_iterations.push_back(iteration);
1639                 }
1640         }
1641         else
1642                 DE_ASSERT(false);
1643
1644         // common parameters
1645         for (int ndx = 0; ndx < (int)m_iterations.size(); ++ndx)
1646         {
1647                 IterationConfig& iteration = m_iterations[ndx];
1648
1649                 iteration.minFilter             = m_filter;
1650                 iteration.magFilter             = m_filter;
1651                 iteration.sWrapMode             = GL_CLAMP_TO_BORDER;
1652                 iteration.tWrapMode             = GL_CLAMP_TO_BORDER;
1653                 iteration.compareMode   = GL_NONE;
1654                 iteration.compareRef    = 0.0f;
1655         }
1656 }
1657
1658 int TextureBorderClampRangeClampCase::getNumIterations  (void) const
1659 {
1660         return (int)m_iterations.size();
1661 }
1662
1663 TextureBorderClampTest::IterationConfig TextureBorderClampRangeClampCase::getIteration (int ndx) const
1664 {
1665         return m_iterations[ndx];
1666 }
1667
1668 class TextureBorderClampPerAxisCase2D : public TextureBorderClampTest
1669 {
1670 public:
1671                                                                         TextureBorderClampPerAxisCase2D (Context&                                               context,
1672                                                                                                                                          const char*                                    name,
1673                                                                                                                                          const char*                                    description,
1674                                                                                                                                          deUint32                                               texFormat,
1675                                                                                                                                          tcu::Sampler::DepthStencilMode mode,
1676                                                                                                                                          SizeType                                               sizeType,
1677                                                                                                                                          deUint32                                               filter,
1678                                                                                                                                          deUint32                                               texSWrap,
1679                                                                                                                                          deUint32                                               texTWrap,
1680                                                                                                                                          SamplingFunction                               samplingFunction);
1681
1682 private:
1683         void                                                    init                                                    (void);
1684
1685         int                                                             getNumIterations                                (void) const;
1686         IterationConfig                                 getIteration                                    (int ndx) const;
1687
1688         const deUint32                                  m_texSWrap;
1689         const deUint32                                  m_texTWrap;
1690         const deUint32                                  m_filter;
1691
1692         std::vector<IterationConfig>    m_iterations;
1693 };
1694
1695 TextureBorderClampPerAxisCase2D::TextureBorderClampPerAxisCase2D (Context&                                                      context,
1696                                                                                                                                   const char*                                           name,
1697                                                                                                                                   const char*                                           description,
1698                                                                                                                                   deUint32                                                      texFormat,
1699                                                                                                                                   tcu::Sampler::DepthStencilMode        mode,
1700                                                                                                                                   SizeType                                                      sizeType,
1701                                                                                                                                   deUint32                                                      filter,
1702                                                                                                                                   deUint32                                                      texSWrap,
1703                                                                                                                                   deUint32                                                      texTWrap,
1704                                                                                                                                   SamplingFunction                                      samplingFunction)
1705         : TextureBorderClampTest(context,
1706                                                          name,
1707                                                          description,
1708                                                          texFormat,
1709                                                          mode,
1710                                                          TextureBorderClampTest::STATE_TEXTURE_PARAM,
1711                                                          (sizeType == SIZE_POT) ? (16) : (7),
1712                                                          (sizeType == SIZE_POT) ? (8) : (9),
1713                                                          samplingFunction)
1714         , m_texSWrap                    (texSWrap)
1715         , m_texTWrap                    (texTWrap)
1716         , m_filter                              (filter)
1717 {
1718 }
1719
1720 void TextureBorderClampPerAxisCase2D::init (void)
1721 {
1722         TextureBorderClampTest::init();
1723
1724         // \note TextureBorderClampTest::init() creates texture
1725         const tcu::TextureFormat                texFormat               = tcu::getEffectiveDepthStencilTextureFormat(getTexture()->getRefTexture().getFormat(), m_sampleMode);
1726         const tcu::TextureFormatInfo    texFormatInfo   = tcu::getTextureFormatInfo(texFormat);
1727
1728         IterationConfig iteration;
1729         iteration.p0                    = tcu::Vec2(-0.25f, -0.75f);
1730         iteration.p1                    = tcu::Vec2( 2.25f,  1.25f);
1731         iteration.borderColor   = mapToFormatColorRepresentable(texFormat, tcu::Vec4(0.4f, 0.9f, 0.1f, 0.2f));
1732
1733         if (m_samplingFunction == SAMPLE_GATHER)
1734         {
1735                 iteration.lookupScale   = tcu::Vec4(texFormatInfo.lookupScale.x());
1736                 iteration.lookupBias    = tcu::Vec4(texFormatInfo.lookupBias.x());
1737         }
1738         else
1739         {
1740                 iteration.lookupScale   = texFormatInfo.lookupScale;
1741                 iteration.lookupBias    = texFormatInfo.lookupBias;
1742         }
1743
1744         iteration.minFilter             = m_filter;
1745         iteration.magFilter             = m_filter;
1746         iteration.sWrapMode             = m_texSWrap;
1747         iteration.tWrapMode             = m_texTWrap;
1748         iteration.compareMode   = GL_NONE;
1749         iteration.compareRef    = 0.0f;
1750
1751         m_iterations.push_back(iteration);
1752 }
1753
1754 int TextureBorderClampPerAxisCase2D::getNumIterations   (void) const
1755 {
1756         return (int)m_iterations.size();
1757 }
1758
1759 TextureBorderClampTest::IterationConfig TextureBorderClampPerAxisCase2D::getIteration (int ndx) const
1760 {
1761         return m_iterations[ndx];
1762 }
1763
1764 class TextureBorderClampDepthCompareCase : public TextureBorderClampTest
1765 {
1766 public:
1767                                                                         TextureBorderClampDepthCompareCase      (Context&                       context,
1768                                                                                                                                                  const char*            name,
1769                                                                                                                                                  const char*            description,
1770                                                                                                                                                  deUint32                       texFormat,
1771                                                                                                                                                  SizeType                       sizeType,
1772                                                                                                                                                  deUint32                       filter,
1773                                                                                                                                                  SamplingFunction       samplingFunction);
1774
1775 private:
1776         void                                                    init                                                            (void);
1777
1778         int                                                             getNumIterations                                        (void) const;
1779         IterationConfig                                 getIteration                                            (int ndx) const;
1780
1781         const deUint32                                  m_filter;
1782         std::vector<IterationConfig>    m_iterations;
1783 };
1784
1785 TextureBorderClampDepthCompareCase::TextureBorderClampDepthCompareCase (Context&                        context,
1786                                                                                                                                                 const char*                     name,
1787                                                                                                                                                 const char*                     description,
1788                                                                                                                                                 deUint32                        texFormat,
1789                                                                                                                                                 SizeType                        sizeType,
1790                                                                                                                                                 deUint32                        filter,
1791                                                                                                                                                 SamplingFunction        samplingFunction)
1792         : TextureBorderClampTest(context,
1793                                                          name,
1794                                                          description,
1795                                                          texFormat,
1796                                                          tcu::Sampler::MODE_DEPTH,
1797                                                          TextureBorderClampTest::STATE_TEXTURE_PARAM,
1798                                                          (sizeType == SIZE_POT) ? (32) : (13),
1799                                                          (sizeType == SIZE_POT) ? (16) : (17),
1800                                                          samplingFunction,
1801                                                          FLAG_USE_SHADOW_SAMPLER)
1802         , m_filter                              (filter)
1803 {
1804 }
1805
1806 void TextureBorderClampDepthCompareCase::init (void)
1807 {
1808         TextureBorderClampTest::init();
1809
1810         // 0.5 <= 0.7
1811         {
1812                 IterationConfig iteration;
1813                 iteration.p0                    = tcu::Vec2(-0.15f, -0.35f);
1814                 iteration.p1                    = tcu::Vec2( 1.25f,  1.1f);
1815                 iteration.borderColor   = rr::GenericVec4(tcu::Vec4(0.7f, 0.0f, 0.0f, 0.0f));
1816                 iteration.description   = "Border color in [0, 1] range";
1817                 iteration.compareMode   = GL_LEQUAL;
1818                 iteration.compareRef    = 0.5f;
1819                 m_iterations.push_back(iteration);
1820         }
1821
1822         // 1.5 <= 1.0
1823         {
1824                 IterationConfig iteration;
1825                 iteration.p0                    = tcu::Vec2(-0.15f, -0.35f);
1826                 iteration.p1                    = tcu::Vec2( 1.25f,  1.1f);
1827                 iteration.borderColor   = rr::GenericVec4(tcu::Vec4(1.5f, 0.0f, 0.0f, 0.0f));
1828                 iteration.description   = "Border color > 1, should be clamped";
1829                 iteration.compareMode   = GL_LEQUAL;
1830                 iteration.compareRef    = 1.0f;
1831                 m_iterations.push_back(iteration);
1832         }
1833
1834         // -0.5 >= 0.0
1835         {
1836                 IterationConfig iteration;
1837                 iteration.p0                    = tcu::Vec2(-0.15f, -0.35f);
1838                 iteration.p1                    = tcu::Vec2( 1.25f,  1.1f);
1839                 iteration.borderColor   = rr::GenericVec4(tcu::Vec4(-0.5f, 0.0f, 0.0f, 0.0f));
1840                 iteration.description   = "Border color < 0, should be clamped";
1841                 iteration.compareMode   = GL_GEQUAL;
1842                 iteration.compareRef    = 0.0f;
1843                 m_iterations.push_back(iteration);
1844         }
1845
1846         // inf < 1.25
1847         {
1848                 IterationConfig iteration;
1849                 iteration.p0                    = tcu::Vec2(-0.15f, -0.35f);
1850                 iteration.p1                    = tcu::Vec2( 1.25f,  1.1f);
1851                 iteration.borderColor   = rr::GenericVec4(tcu::Vec4(std::numeric_limits<float>::infinity(), 0.0f, 0.0f, 0.0f));
1852                 iteration.description   = "Border color == inf, should be clamped; ref > 1";
1853                 iteration.compareMode   = GL_LESS;
1854                 iteration.compareRef    = 1.25f;
1855                 m_iterations.push_back(iteration);
1856         }
1857
1858         // -inf > -0.5
1859         {
1860                 IterationConfig iteration;
1861                 iteration.p0                    = tcu::Vec2(-0.15f, -0.35f);
1862                 iteration.p1                    = tcu::Vec2( 1.25f,  1.1f);
1863                 iteration.borderColor   = rr::GenericVec4(tcu::Vec4(-std::numeric_limits<float>::infinity(), 0.0f, 0.0f, 0.0f));
1864                 iteration.description   = "Border color == inf, should be clamped; ref < 0";
1865                 iteration.compareMode   = GL_GREATER;
1866                 iteration.compareRef    = -0.5f;
1867                 m_iterations.push_back(iteration);
1868         }
1869
1870         // common parameters
1871         for (int ndx = 0; ndx < (int)m_iterations.size(); ++ndx)
1872         {
1873                 IterationConfig& iteration = m_iterations[ndx];
1874
1875                 iteration.lookupScale   = tcu::Vec4(1.0);
1876                 iteration.lookupBias    = tcu::Vec4(0.0);
1877                 iteration.minFilter             = m_filter;
1878                 iteration.magFilter             = m_filter;
1879                 iteration.sWrapMode             = GL_CLAMP_TO_BORDER;
1880                 iteration.tWrapMode             = GL_CLAMP_TO_BORDER;
1881         }
1882 }
1883
1884 int TextureBorderClampDepthCompareCase::getNumIterations        (void) const
1885 {
1886         return (int)m_iterations.size();
1887 }
1888
1889 TextureBorderClampTest::IterationConfig TextureBorderClampDepthCompareCase::getIteration (int ndx) const
1890 {
1891         return m_iterations[ndx];
1892 }
1893
1894 class TextureBorderClampUnusedChannelCase : public TextureBorderClampTest
1895 {
1896 public:
1897                                                                         TextureBorderClampUnusedChannelCase     (Context&                                               context,
1898                                                                                                                                                  const char*                                    name,
1899                                                                                                                                                  const char*                                    description,
1900                                                                                                                                                  deUint32                                               texFormat,
1901                                                                                                                                                  tcu::Sampler::DepthStencilMode depthStencilMode);
1902
1903 private:
1904         void                                                    init                                                            (void);
1905
1906         int                                                             getNumIterations                                        (void) const;
1907         IterationConfig                                 getIteration                                            (int ndx) const;
1908
1909         std::vector<IterationConfig>    m_iterations;
1910 };
1911
1912 TextureBorderClampUnusedChannelCase::TextureBorderClampUnusedChannelCase (Context&                                                      context,
1913                                                                                                                                                   const char*                                           name,
1914                                                                                                                                                   const char*                                           description,
1915                                                                                                                                                   deUint32                                                      texFormat,
1916                                                                                                                                                   tcu::Sampler::DepthStencilMode        depthStencilMode)
1917         : TextureBorderClampTest(context,
1918                                                          name,
1919                                                          description,
1920                                                          texFormat,
1921                                                          depthStencilMode,
1922                                                          TextureBorderClampTest::STATE_TEXTURE_PARAM,
1923                                                          8,
1924                                                          8,
1925                                                          SAMPLE_FILTER)
1926 {
1927 }
1928
1929 static rr::GenericVec4 selectComponents (const rr::GenericVec4& trueComponents, const rr::GenericVec4& falseComponents, const tcu::BVec4& m)
1930 {
1931         return rr::GenericVec4(tcu::select(trueComponents.get<deUint32>(), falseComponents.get<deUint32>(), m));
1932 }
1933
1934 void TextureBorderClampUnusedChannelCase::init (void)
1935 {
1936         TextureBorderClampTest::init();
1937
1938         // \note TextureBorderClampTest::init() creates texture
1939         const tcu::TextureFormat                texFormat                       = tcu::getEffectiveDepthStencilTextureFormat(getTexture()->getRefTexture().getFormat(), m_sampleMode);
1940         const tcu::TextureFormatInfo    texFormatInfo           = tcu::getTextureFormatInfo(texFormat);
1941         const tcu::BVec4                                channelMask                     = tcu::getTextureFormatChannelMask(texFormat);
1942         const float                                             maxChannelValue         = (channelMask[0]) ? (texFormatInfo.valueMax[0])
1943                                                                                                                 : (channelMask[1]) ? (texFormatInfo.valueMax[1])
1944                                                                                                                 : (channelMask[2]) ? (texFormatInfo.valueMax[2])
1945                                                                                                                 :                    (texFormatInfo.valueMax[3]);
1946
1947         const rr::GenericVec4                   effectiveColors         = mapToFormatColorRepresentable(texFormat, tcu::Vec4(0.6f));
1948         rr::GenericVec4                                 nonEffectiveColors;
1949
1950         switch (m_channelClass)
1951         {
1952                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1953                 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1954                 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1955                         nonEffectiveColors = rr::GenericVec4(tcu::Vec4(maxChannelValue * 0.8f));
1956                         break;
1957
1958                 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1959                         nonEffectiveColors = rr::GenericVec4(tcu::Vec4(maxChannelValue * 0.8f).cast<deInt32>());
1960                         break;
1961
1962                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1963                         nonEffectiveColors = rr::GenericVec4(tcu::Vec4(maxChannelValue * 0.8f).cast<deUint32>());
1964                         break;
1965                 default:
1966                         DE_ASSERT(false);
1967         }
1968
1969         IterationConfig iteration;
1970         iteration.p0                    = tcu::Vec2(-0.25f, -0.75f);
1971         iteration.p1                    = tcu::Vec2( 2.25f,  1.25f);
1972         iteration.borderColor   = selectComponents(effectiveColors, nonEffectiveColors, channelMask);
1973         iteration.lookupScale   = texFormatInfo.lookupScale;
1974         iteration.lookupBias    = texFormatInfo.lookupBias;
1975         iteration.minFilter             = GL_NEAREST;
1976         iteration.magFilter             = GL_NEAREST;
1977         iteration.sWrapMode             = GL_CLAMP_TO_BORDER;
1978         iteration.tWrapMode             = GL_CLAMP_TO_BORDER;
1979         iteration.compareMode   = GL_NONE;
1980         iteration.compareRef    = 0.0f;
1981         iteration.description   = "Setting values to unused border color components";
1982
1983         m_iterations.push_back(iteration);
1984 }
1985
1986 int TextureBorderClampUnusedChannelCase::getNumIterations       (void) const
1987 {
1988         return (int)m_iterations.size();
1989 }
1990
1991 TextureBorderClampTest::IterationConfig TextureBorderClampUnusedChannelCase::getIteration (int ndx) const
1992 {
1993         return m_iterations[ndx];
1994 }
1995
1996 class TextureBorderClampPerAxisCase3D : public TestCase
1997 {
1998 public:
1999                                                                                                                 TextureBorderClampPerAxisCase3D (Context&               context,
2000                                                                                                                                                                                  const char*    name,
2001                                                                                                                                                                                  const char*    description,
2002                                                                                                                                                                                  deUint32               texFormat,
2003                                                                                                                                                                                  SizeType               size,
2004                                                                                                                                                                                  deUint32               filter,
2005                                                                                                                                                                                  deUint32               sWrap,
2006                                                                                                                                                                                  deUint32               tWrap,
2007                                                                                                                                                                                  deUint32               rWrap);
2008
2009 private:
2010         void                                                                                            init                                                    (void);
2011         void                                                                                            deinit                                                  (void);
2012         IterateResult                                                                           iterate                                                 (void);
2013
2014         void                                                                                            renderTo                                                (tcu::Surface&                                                                  surface,
2015                                                                                                                                                                                  const glu::TextureTestUtil::ReferenceParams&   samplerParams);
2016
2017         void                                                                                            logParams                                               (const glu::TextureTestUtil::ReferenceParams&   samplerParams);
2018
2019         void                                                                                            verifyImage                                             (const tcu::Surface&                                                    image,
2020                                                                                                                                                                                  const glu::TextureTestUtil::ReferenceParams&   samplerParams);
2021
2022         glu::TextureTestUtil::ReferenceParams                           getSamplerParams                                (void) const;
2023         deUint32                                                                                        getCaseSeed                                             (void) const;
2024
2025         enum
2026         {
2027                 VIEWPORT_WIDTH          = 128,
2028                 VIEWPORT_HEIGHT         = 128,
2029         };
2030
2031         const deUint32                                                                          m_texFormat;
2032         const tcu::TextureChannelClass                                          m_channelClass;
2033         const tcu::IVec3                                                                        m_size;
2034         const deUint32                                                                          m_filter;
2035         const deUint32                                                                          m_sWrap;
2036         const deUint32                                                                          m_tWrap;
2037         const deUint32                                                                          m_rWrap;
2038
2039         de::MovePtr<glu::Texture3D>                                                     m_texture;
2040         de::MovePtr<gls::TextureTestUtil::TextureRenderer>      m_renderer;
2041
2042         rr::GenericVec4                                                                         m_borderColor;
2043         std::vector<float>                                                                      m_texCoords;
2044         tcu::Vec4                                                                                       m_lookupScale;
2045         tcu::Vec4                                                                                       m_lookupBias;
2046 };
2047
2048 TextureBorderClampPerAxisCase3D::TextureBorderClampPerAxisCase3D (Context&              context,
2049                                                                                                                                   const char*   name,
2050                                                                                                                                   const char*   description,
2051                                                                                                                                   deUint32              texFormat,
2052                                                                                                                                   SizeType              size,
2053                                                                                                                                   deUint32              filter,
2054                                                                                                                                   deUint32              sWrap,
2055                                                                                                                                   deUint32              tWrap,
2056                                                                                                                                   deUint32              rWrap)
2057         : TestCase                      (context, name, description)
2058         , m_texFormat           (texFormat)
2059         , m_channelClass        (getFormatChannelClass(texFormat, tcu::Sampler::MODE_LAST))
2060         , m_size                        ((size == SIZE_POT) ? (tcu::IVec3(8, 16, 4)) : (tcu::IVec3(13, 5, 7)))
2061         , m_filter                      (filter)
2062         , m_sWrap                       (sWrap)
2063         , m_tWrap                       (tWrap)
2064         , m_rWrap                       (rWrap)
2065 {
2066 }
2067
2068 void TextureBorderClampPerAxisCase3D::init (void)
2069 {
2070         const bool                              supportsES32    = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
2071         const glu::GLSLVersion  glslVersion             = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
2072
2073         if (!supportsES32 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_border_clamp"))
2074                 throw tcu::NotSupportedError("Test requires GL_EXT_texture_border_clamp extension");
2075
2076         if (glu::isCompressedFormat(m_texFormat)                                                                                                        &&
2077                 !supportsES32                                                                                                                                                   &&
2078                 tcu::isAstcFormat(glu::mapGLCompressedTexFormat(m_texFormat))                                                   &&
2079                 !m_context.getContextInfo().isExtensionSupported("GL_KHR_texture_compression_astc_ldr"))
2080         {
2081                 throw tcu::NotSupportedError("Test requires GL_KHR_texture_compression_astc_ldr extension");
2082         }
2083         if (m_texFormat == GL_BGRA && !m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_format_BGRA8888"))
2084                 throw tcu::NotSupportedError("Test requires GL_EXT_texture_format_BGRA8888 extension");
2085         if (m_context.getRenderTarget().getWidth() < VIEWPORT_WIDTH ||
2086                 m_context.getRenderTarget().getHeight() < VIEWPORT_HEIGHT)
2087         {
2088                 throw tcu::NotSupportedError("Test requires " + de::toString<int>(VIEWPORT_WIDTH) + "x" + de::toString<int>(VIEWPORT_HEIGHT) + " viewport");
2089         }
2090
2091         // resources
2092         m_texture = genDummyTexture<glu::Texture3D>(m_context.getRenderContext(), m_context.getContextInfo(), m_texFormat, m_size);
2093         m_renderer = de::MovePtr<gls::TextureTestUtil::TextureRenderer>(new gls::TextureTestUtil::TextureRenderer(m_context.getRenderContext(), m_testCtx.getLog(), glslVersion, glu::PRECISION_HIGHP));
2094
2095         // texture info
2096         m_testCtx.getLog()      << tcu::TestLog::Message
2097                                                 << "Created 3D texture with format " << glu::getTextureFormatName(m_texFormat)
2098                                                 << ", size (" << m_texture->getRefTexture().getWidth() << ", " << m_texture->getRefTexture().getHeight() << ", " << m_texture->getRefTexture().getDepth() << ")\n"
2099                                                 << tcu::TestLog::EndMessage;
2100
2101         // tex coord
2102         {
2103                 m_testCtx.getLog()      << tcu::TestLog::Message
2104                                                         << "Setting tex coords bottom-left: (-1, -1, -1.5), top-right (2, 2, 2.5)\n"
2105                                                         << tcu::TestLog::EndMessage;
2106
2107                 m_texCoords.resize(4*3);
2108
2109                 m_texCoords[0] = -1.0f; m_texCoords[ 1] = -1.0f; m_texCoords[ 2] = -1.5f;
2110                 m_texCoords[3] = -1.0f; m_texCoords[ 4] =  2.0f; m_texCoords[ 5] = 0.5f;
2111                 m_texCoords[6] =  2.0f; m_texCoords[ 7] = -1.0f; m_texCoords[ 8] = 0.5f;
2112                 m_texCoords[9] =  2.0f; m_texCoords[10] =  2.0f; m_texCoords[11] =  2.5f;
2113         }
2114
2115         // set render params
2116         {
2117                 const tcu::TextureFormat                texFormat               = m_texture->getRefTexture().getFormat();
2118                 const tcu::TextureFormatInfo    texFormatInfo   = tcu::getTextureFormatInfo(texFormat);
2119
2120                 m_borderColor   = mapToFormatColorRepresentable(texFormat, tcu::Vec4(0.2f, 0.6f, 0.9f, 0.4f));
2121
2122                 m_lookupScale   = texFormatInfo.lookupScale;
2123                 m_lookupBias    = texFormatInfo.lookupBias;
2124         }
2125 }
2126
2127 void TextureBorderClampPerAxisCase3D::deinit (void)
2128 {
2129         m_texture.clear();
2130         m_renderer.clear();
2131 }
2132
2133 TextureBorderClampPerAxisCase3D::IterateResult TextureBorderClampPerAxisCase3D::iterate (void)
2134 {
2135         tcu::Surface                                                            renderedFrame           (VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
2136         const glu::TextureTestUtil::ReferenceParams     samplerParams           = getSamplerParams();
2137
2138         logParams(samplerParams);
2139         renderTo(renderedFrame, samplerParams);
2140         verifyImage(renderedFrame, samplerParams);
2141
2142         return STOP;
2143 }
2144
2145 void TextureBorderClampPerAxisCase3D::logParams (const glu::TextureTestUtil::ReferenceParams& samplerParams)
2146 {
2147         const std::string       borderColorString       = (m_channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)   ? (de::toString(m_borderColor.get<deInt32>()))
2148                                                                                         : (m_channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER) ? (de::toString(m_borderColor.get<deUint32>()))
2149                                                                                         :                                                                                                                                 (de::toString(m_borderColor.get<float>()));
2150
2151         m_testCtx.getLog()      << tcu::TestLog::Message
2152                                                 << "Border color is " << borderColorString << "\n"
2153                                                 << "Texture lookup bias: " << samplerParams.colorBias << "\n"
2154                                                 << "Texture lookup scale: " << samplerParams.colorScale << "\n"
2155                                                 << "Filter: " << glu::getTextureFilterName(m_filter) << "\n"
2156                                                 << "Wrap mode: s = " << glu::getRepeatModeStr(m_sWrap)
2157                                                         << ", t = " << glu::getRepeatModeStr(m_tWrap)
2158                                                         << ", r = " << glu::getRepeatModeStr(m_rWrap) << "\n"
2159                                                 << tcu::TestLog::EndMessage;
2160 }
2161
2162 void TextureBorderClampPerAxisCase3D::renderTo (tcu::Surface&                                                                   surface,
2163                                                                                                 const glu::TextureTestUtil::ReferenceParams&    samplerParams)
2164 {
2165         const glw::Functions&                                           gl                      = m_context.getRenderContext().getFunctions();
2166         const gls::TextureTestUtil::RandomViewport      viewport        (m_context.getRenderTarget(), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, getCaseSeed());
2167
2168         // Bind to unit 0.
2169         gl.activeTexture(GL_TEXTURE0);
2170         gl.bindTexture(GL_TEXTURE_3D, m_texture->getGLTexture());
2171
2172         // Setup filtering and wrap modes.
2173         gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S,              glu::getGLWrapMode(samplerParams.sampler.wrapS));
2174         gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T,              glu::getGLWrapMode(samplerParams.sampler.wrapT));
2175         gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R,              glu::getGLWrapMode(samplerParams.sampler.wrapR));
2176         gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER,  glu::getGLFilterMode(samplerParams.sampler.minFilter));
2177         gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER,  glu::getGLFilterMode(samplerParams.sampler.magFilter));
2178
2179         switch (m_channelClass)
2180         {
2181                 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
2182                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
2183                 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
2184                         gl.texParameterfv(GL_TEXTURE_3D, GL_TEXTURE_BORDER_COLOR, m_borderColor.getAccess<float>());
2185                         break;
2186
2187                 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
2188                         gl.texParameterIiv(GL_TEXTURE_3D, GL_TEXTURE_BORDER_COLOR, m_borderColor.getAccess<deInt32>());
2189                         break;
2190
2191                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
2192                         gl.texParameterIuiv(GL_TEXTURE_3D, GL_TEXTURE_BORDER_COLOR, m_borderColor.getAccess<deUint32>());
2193                         break;
2194
2195                 default:
2196                         DE_ASSERT(false);
2197         }
2198
2199         GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");
2200
2201         gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
2202         m_renderer->renderQuad(0, &m_texCoords[0], samplerParams);
2203         glu::readPixels(m_context.getRenderContext(), viewport.x, viewport.y, surface.getAccess());
2204 }
2205
2206 void TextureBorderClampPerAxisCase3D::verifyImage (const tcu::Surface&                                                  renderedFrame,
2207                                                                                                    const glu::TextureTestUtil::ReferenceParams& samplerParams)
2208 {
2209         const tcu::PixelFormat                  pixelFormat                     = m_context.getRenderTarget().getPixelFormat();
2210         const int                                               colorErrorBits          = 2;
2211         const tcu::IVec4                                colorBits                       = tcu::max(glu::TextureTestUtil::getBitsVec(pixelFormat) - tcu::IVec4(colorErrorBits), tcu::IVec4(0));
2212         tcu::Surface                                    reference                       (renderedFrame.getWidth(), renderedFrame.getHeight());
2213         tcu::Surface                                    errorMask                       (renderedFrame.getWidth(), renderedFrame.getHeight());
2214         tcu::LodPrecision                               lodPrecision;
2215         tcu::LookupPrecision                    lookupPrecision;
2216         int                                                             numFailedPixels;
2217
2218         lodPrecision.derivateBits               = 18;
2219         lodPrecision.lodBits                    = 5;
2220
2221         lookupPrecision.colorThreshold  = tcu::computeFixedPointThreshold(colorBits) / samplerParams.colorScale;
2222         lookupPrecision.coordBits               = tcu::IVec3(20,20,0);
2223         lookupPrecision.uvwBits                 = tcu::IVec3(5,5,0);
2224         lookupPrecision.colorMask               = glu::TextureTestUtil::getCompareMask(pixelFormat);
2225
2226         glu::TextureTestUtil::sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), m_texture->getRefTexture(), &m_texCoords[0], samplerParams);
2227
2228         numFailedPixels = glu::TextureTestUtil::computeTextureLookupDiff(renderedFrame.getAccess(), reference.getAccess(), errorMask.getAccess(), m_texture->getRefTexture(),
2229                                                                                                                                          &m_texCoords[0], samplerParams, lookupPrecision, lodPrecision, m_testCtx.getWatchDog());
2230
2231         if (numFailedPixels > 0)
2232                 m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage;
2233         m_testCtx.getLog()      << tcu::TestLog::ImageSet("VerifyResult", "Verification result")
2234                                                 << tcu::TestLog::Image("Rendered", "Rendered image", renderedFrame);
2235         if (numFailedPixels > 0)
2236         {
2237                 m_testCtx.getLog()      << tcu::TestLog::Image("Reference", "Ideal reference image", reference)
2238                                                         << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask);
2239         }
2240         m_testCtx.getLog() << tcu::TestLog::EndImageSet;
2241
2242         if (numFailedPixels == 0)
2243                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2244         else
2245                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
2246 }
2247
2248 glu::TextureTestUtil::ReferenceParams TextureBorderClampPerAxisCase3D::getSamplerParams (void) const
2249 {
2250         const tcu::TextureFormat                                texFormat               = m_texture->getRefTexture().getFormat();
2251         glu::TextureTestUtil::ReferenceParams   refParams               (glu::TextureTestUtil::TEXTURETYPE_3D);
2252
2253         refParams.sampler                                       = glu::mapGLSampler(m_sWrap, m_tWrap, m_rWrap, m_filter, m_filter);
2254         refParams.sampler.borderColor           = m_borderColor;
2255         refParams.lodMode                                       = glu::TextureTestUtil::LODMODE_EXACT;
2256         refParams.samplerType                           = glu::TextureTestUtil::getSamplerType(texFormat);
2257         refParams.colorScale                            = m_lookupScale;
2258         refParams.colorBias                                     = m_lookupBias;
2259
2260         return refParams;
2261 }
2262
2263 deUint32 TextureBorderClampPerAxisCase3D::getCaseSeed (void) const
2264 {
2265         tcu::SeedBuilder builder;
2266         builder << std::string(getName())
2267                         << m_texFormat
2268                         << m_filter
2269                         << m_sWrap
2270                         << m_tWrap
2271                         << m_rWrap
2272                         << m_texture->getRefTexture().getWidth()
2273                         << m_texture->getRefTexture().getHeight()
2274                         << m_texture->getRefTexture().getDepth();
2275         return builder.get();
2276 }
2277
2278 } // anonymous
2279
2280 TextureBorderClampTests::TextureBorderClampTests (Context& context)
2281         : TestCaseGroup(context, "border_clamp", "EXT_texture_border_clamp tests")
2282 {
2283 }
2284
2285 TextureBorderClampTests::~TextureBorderClampTests (void)
2286 {
2287 }
2288
2289 void TextureBorderClampTests::init (void)
2290 {
2291         static const struct
2292         {
2293                 const char*                                                                     name;
2294                 deUint32                                                                        filter;
2295                 TextureBorderClampTest::SamplingFunction        sampling;
2296         } s_filters[] =
2297         {
2298                 { "nearest",    GL_NEAREST,     TextureBorderClampTest::SAMPLE_FILTER   },
2299                 { "linear",             GL_LINEAR,      TextureBorderClampTest::SAMPLE_FILTER   },
2300                 { "gather",             GL_NEAREST,     TextureBorderClampTest::SAMPLE_GATHER   },
2301         };
2302
2303         // .formats
2304         {
2305                 static const struct
2306                 {
2307                         const char*                                             name;
2308                         deUint32                                                format;
2309                         tcu::Sampler::DepthStencilMode  mode;
2310                 } formats[] =
2311                 {
2312                         { "luminance",                                                                  GL_LUMINANCE,                                                                   tcu::Sampler::MODE_LAST         },
2313                         { "alpha",                                                                              GL_ALPHA,                                                                               tcu::Sampler::MODE_LAST         },
2314                         { "luminance_alpha",                                                    GL_LUMINANCE_ALPHA,                                                             tcu::Sampler::MODE_LAST         },
2315                         { "bgra",                                                                               GL_BGRA,                                                                                tcu::Sampler::MODE_LAST         },
2316                         { "r8",                                                                                 GL_R8,                                                                                  tcu::Sampler::MODE_LAST         },
2317                         { "r8_snorm",                                                                   GL_R8_SNORM,                                                                    tcu::Sampler::MODE_LAST         },
2318                         { "rg8",                                                                                GL_RG8,                                                                                 tcu::Sampler::MODE_LAST         },
2319                         { "rg8_snorm",                                                                  GL_RG8_SNORM,                                                                   tcu::Sampler::MODE_LAST         },
2320                         { "rgb8",                                                                               GL_RGB8,                                                                                tcu::Sampler::MODE_LAST         },
2321                         { "rgb8_snorm",                                                                 GL_RGB8_SNORM,                                                                  tcu::Sampler::MODE_LAST         },
2322                         { "rgb565",                                                                             GL_RGB565,                                                                              tcu::Sampler::MODE_LAST         },
2323                         { "rgba4",                                                                              GL_RGBA4,                                                                               tcu::Sampler::MODE_LAST         },
2324                         { "rgb5_a1",                                                                    GL_RGB5_A1,                                                                             tcu::Sampler::MODE_LAST         },
2325                         { "rgba8",                                                                              GL_RGBA8,                                                                               tcu::Sampler::MODE_LAST         },
2326                         { "rgba8_snorm",                                                                GL_RGBA8_SNORM,                                                                 tcu::Sampler::MODE_LAST         },
2327                         { "rgb10_a2",                                                                   GL_RGB10_A2,                                                                    tcu::Sampler::MODE_LAST         },
2328                         { "rgb10_a2ui",                                                                 GL_RGB10_A2UI,                                                                  tcu::Sampler::MODE_LAST         },
2329                         { "srgb8",                                                                              GL_SRGB8,                                                                               tcu::Sampler::MODE_LAST         },
2330                         { "srgb8_alpha8",                                                               GL_SRGB8_ALPHA8,                                                                tcu::Sampler::MODE_LAST         },
2331                         { "r16f",                                                                               GL_R16F,                                                                                tcu::Sampler::MODE_LAST         },
2332                         { "rg16f",                                                                              GL_RG16F,                                                                               tcu::Sampler::MODE_LAST         },
2333                         { "rgb16f",                                                                             GL_RGB16F,                                                                              tcu::Sampler::MODE_LAST         },
2334                         { "rgba16f",                                                                    GL_RGBA16F,                                                                             tcu::Sampler::MODE_LAST         },
2335                         { "r32f",                                                                               GL_R32F,                                                                                tcu::Sampler::MODE_LAST         },
2336                         { "rg32f",                                                                              GL_RG32F,                                                                               tcu::Sampler::MODE_LAST         },
2337                         { "rgb32f",                                                                             GL_RGB32F,                                                                              tcu::Sampler::MODE_LAST         },
2338                         { "rgba32f",                                                                    GL_RGBA32F,                                                                             tcu::Sampler::MODE_LAST         },
2339                         { "r11f_g11f_b10f",                                                             GL_R11F_G11F_B10F,                                                              tcu::Sampler::MODE_LAST         },
2340                         { "rgb9_e5",                                                                    GL_RGB9_E5,                                                                             tcu::Sampler::MODE_LAST         },
2341                         { "r8i",                                                                                GL_R8I,                                                                                 tcu::Sampler::MODE_LAST         },
2342                         { "r8ui",                                                                               GL_R8UI,                                                                                tcu::Sampler::MODE_LAST         },
2343                         { "r16i",                                                                               GL_R16I,                                                                                tcu::Sampler::MODE_LAST         },
2344                         { "r16ui",                                                                              GL_R16UI,                                                                               tcu::Sampler::MODE_LAST         },
2345                         { "r32i",                                                                               GL_R32I,                                                                                tcu::Sampler::MODE_LAST         },
2346                         { "r32ui",                                                                              GL_R32UI,                                                                               tcu::Sampler::MODE_LAST         },
2347                         { "rg8i",                                                                               GL_RG8I,                                                                                tcu::Sampler::MODE_LAST         },
2348                         { "rg8ui",                                                                              GL_RG8UI,                                                                               tcu::Sampler::MODE_LAST         },
2349                         { "rg16i",                                                                              GL_RG16I,                                                                               tcu::Sampler::MODE_LAST         },
2350                         { "rg16ui",                                                                             GL_RG16UI,                                                                              tcu::Sampler::MODE_LAST         },
2351                         { "rg32i",                                                                              GL_RG32I,                                                                               tcu::Sampler::MODE_LAST         },
2352                         { "rg32ui",                                                                             GL_RG32UI,                                                                              tcu::Sampler::MODE_LAST         },
2353                         { "rgb8i",                                                                              GL_RGB8I,                                                                               tcu::Sampler::MODE_LAST         },
2354                         { "rgb8ui",                                                                             GL_RGB8UI,                                                                              tcu::Sampler::MODE_LAST         },
2355                         { "rgb16i",                                                                             GL_RGB16I,                                                                              tcu::Sampler::MODE_LAST         },
2356                         { "rgb16ui",                                                                    GL_RGB16UI,                                                                             tcu::Sampler::MODE_LAST         },
2357                         { "rgb32i",                                                                             GL_RGB32I,                                                                              tcu::Sampler::MODE_LAST         },
2358                         { "rgb32ui",                                                                    GL_RGB32UI,                                                                             tcu::Sampler::MODE_LAST         },
2359                         { "rgba8i",                                                                             GL_RGBA8I,                                                                              tcu::Sampler::MODE_LAST         },
2360                         { "rgba8ui",                                                                    GL_RGBA8UI,                                                                             tcu::Sampler::MODE_LAST         },
2361                         { "rgba16i",                                                                    GL_RGBA16I,                                                                             tcu::Sampler::MODE_LAST         },
2362                         { "rgba16ui",                                                                   GL_RGBA16UI,                                                                    tcu::Sampler::MODE_LAST         },
2363                         { "rgba32i",                                                                    GL_RGBA32I,                                                                             tcu::Sampler::MODE_LAST         },
2364                         { "rgba32ui",                                                                   GL_RGBA32UI,                                                                    tcu::Sampler::MODE_LAST         },
2365                         { "depth_component16",                                                  GL_DEPTH_COMPONENT16,                                                   tcu::Sampler::MODE_DEPTH        },
2366                         { "depth_component24",                                                  GL_DEPTH_COMPONENT24,                                                   tcu::Sampler::MODE_DEPTH        },
2367                         { "depth_component32f",                                                 GL_DEPTH_COMPONENT32F,                                                  tcu::Sampler::MODE_DEPTH        },
2368                         { "stencil_index8",                                                             GL_STENCIL_INDEX8,                                                              tcu::Sampler::MODE_STENCIL      },
2369                         { "depth24_stencil8_sample_depth",                              GL_DEPTH24_STENCIL8,                                                    tcu::Sampler::MODE_DEPTH        },
2370                         { "depth32f_stencil8_sample_depth",                             GL_DEPTH32F_STENCIL8,                                                   tcu::Sampler::MODE_DEPTH        },
2371                         { "depth24_stencil8_sample_stencil",                    GL_DEPTH24_STENCIL8,                                                    tcu::Sampler::MODE_STENCIL      },
2372                         { "depth32f_stencil8_sample_stencil",                   GL_DEPTH32F_STENCIL8,                                                   tcu::Sampler::MODE_STENCIL      },
2373                         { "compressed_r11_eac",                                                 GL_COMPRESSED_R11_EAC,                                                  tcu::Sampler::MODE_LAST         },
2374                         { "compressed_signed_r11_eac",                                  GL_COMPRESSED_SIGNED_R11_EAC,                                   tcu::Sampler::MODE_LAST         },
2375                         { "compressed_rg11_eac",                                                GL_COMPRESSED_RG11_EAC,                                                 tcu::Sampler::MODE_LAST         },
2376                         { "compressed_signed_rg11_eac",                                 GL_COMPRESSED_SIGNED_RG11_EAC,                                  tcu::Sampler::MODE_LAST         },
2377                         { "compressed_rgb8_etc2",                                               GL_COMPRESSED_RGB8_ETC2,                                                tcu::Sampler::MODE_LAST         },
2378                         { "compressed_srgb8_etc2",                                              GL_COMPRESSED_SRGB8_ETC2,                                               tcu::Sampler::MODE_LAST         },
2379                         { "compressed_rgb8_punchthrough_alpha1_etc2",   GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,    tcu::Sampler::MODE_LAST         },
2380                         { "compressed_srgb8_punchthrough_alpha1_etc2",  GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,   tcu::Sampler::MODE_LAST         },
2381                         { "compressed_rgba8_etc2_eac",                                  GL_COMPRESSED_RGBA8_ETC2_EAC,                                   tcu::Sampler::MODE_LAST         },
2382                         { "compressed_srgb8_alpha8_etc2_eac",                   GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,                    tcu::Sampler::MODE_LAST         },
2383                 };
2384
2385                 tcu::TestCaseGroup* const formatsGroup = new tcu::TestCaseGroup(m_testCtx, "formats", "Format tests");
2386                 addChild(formatsGroup);
2387
2388                 // .format
2389                 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx)
2390                 {
2391                         const deUint32                                                  format                  = formats[formatNdx].format;
2392                         const tcu::Sampler::DepthStencilMode    sampleMode              = formats[formatNdx].mode;
2393                         const bool                                                              isCompressed    = glu::isCompressedFormat(format);
2394                         const bool                                                              coreFilterable  = isCoreFilterableFormat(format, sampleMode);
2395                         tcu::TestCaseGroup* const                               formatGroup             = new tcu::TestCaseGroup(m_testCtx, formats[formatNdx].name, "Format test");
2396
2397                         formatsGroup->addChild(formatGroup);
2398
2399                         // .nearest
2400                         // .linear
2401                         for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(s_filters); ++filterNdx)
2402                         {
2403                                 // [not-compressed]
2404                                 // .size_pot
2405                                 // .size_npot
2406                                 // [compressed]
2407                                 // .size_tile_multiple (also pot)
2408                                 // .size_not_tile_multiple (also npot)
2409                                 for (int sizeNdx = 0; sizeNdx < 2; ++sizeNdx)
2410                                 {
2411                                         const bool                              isNpotCase              = (sizeNdx == 1);
2412                                         const char* const               sizePotName             = (!isCompressed) ? ("size_pot") : ("size_tile_multiple");
2413                                         const char* const               sizeNpotName    = (!isCompressed) ? ("size_npot") : ("size_not_tile_multiple");
2414                                         const char* const               sizeName                = (isNpotCase) ? (sizeNpotName) : (sizePotName);
2415                                         const SizeType                  sizeType                = (isNpotCase) ? (SIZE_NPOT) : (SIZE_POT);
2416                                         const std::string               caseName                = std::string() + s_filters[filterNdx].name + "_" + sizeName;
2417                                         const deUint32                  filter                  = s_filters[filterNdx].filter;
2418
2419                                         if (coreFilterable || !filterRequiresFilterability(filter))
2420                                                 formatGroup->addChild(new TextureBorderClampFormatCase(m_context,
2421                                                                                                                                                            caseName.c_str(),
2422                                                                                                                                                            "",
2423                                                                                                                                                            format,
2424                                                                                                                                                            sampleMode,
2425                                                                                                                                                            TextureBorderClampFormatCase::STATE_TEXTURE_PARAM,
2426                                                                                                                                                            sizeType,
2427                                                                                                                                                            filter,
2428                                                                                                                                                            s_filters[filterNdx].sampling));
2429                                 }
2430                         }
2431                 }
2432         }
2433
2434         // .range_clamp
2435         {
2436                 static const struct
2437                 {
2438                         const char*                                             name;
2439                         deUint32                                                format;
2440                         tcu::Sampler::DepthStencilMode  mode;
2441                 } formats[] =
2442                 {
2443                         { "unorm_color",                                                                GL_R8,                                  tcu::Sampler::MODE_LAST         },
2444                         { "snorm_color",                                                                GL_R8_SNORM,                    tcu::Sampler::MODE_LAST         },
2445                         { "float_color",                                                                GL_RG32F,                               tcu::Sampler::MODE_LAST         },
2446                         { "int_color",                                                                  GL_R8I,                                 tcu::Sampler::MODE_LAST         },
2447                         { "uint_color",                                                                 GL_R16UI,                               tcu::Sampler::MODE_LAST         },
2448                         { "srgb_color",                                                                 GL_SRGB8_ALPHA8,                tcu::Sampler::MODE_LAST         },
2449                         { "unorm_depth",                                                                GL_DEPTH_COMPONENT24,   tcu::Sampler::MODE_DEPTH        },
2450                         { "float_depth",                                                                GL_DEPTH_COMPONENT32F,  tcu::Sampler::MODE_DEPTH        },
2451                         { "uint_stencil",                                                               GL_STENCIL_INDEX8,              tcu::Sampler::MODE_STENCIL      },
2452                         { "float_depth_uint_stencil_sample_depth",              GL_DEPTH32F_STENCIL8,   tcu::Sampler::MODE_DEPTH        },
2453                         { "float_depth_uint_stencil_sample_stencil",    GL_DEPTH32F_STENCIL8,   tcu::Sampler::MODE_STENCIL      },
2454                         { "unorm_depth_uint_stencil_sample_depth",              GL_DEPTH24_STENCIL8,    tcu::Sampler::MODE_DEPTH        },
2455                         { "unorm_depth_uint_stencil_sample_stencil",    GL_DEPTH24_STENCIL8,    tcu::Sampler::MODE_STENCIL      },
2456                         { "compressed_color",                                                   GL_COMPRESSED_RG11_EAC, tcu::Sampler::MODE_LAST         },
2457                 };
2458
2459                 tcu::TestCaseGroup* const rangeClampGroup = new tcu::TestCaseGroup(m_testCtx, "range_clamp", "Range clamp tests");
2460                 addChild(rangeClampGroup);
2461
2462                 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx)
2463                 for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(s_filters); ++filterNdx)
2464                 {
2465                         const deUint32                                                  format                  = formats[formatNdx].format;
2466                         const tcu::Sampler::DepthStencilMode    sampleMode              = formats[formatNdx].mode;
2467                         const std::string                                               caseName                = std::string() + s_filters[filterNdx].name + "_" + formats[formatNdx].name;
2468                         const deUint32                                                  filter                  = s_filters[filterNdx].filter;
2469                         const bool                                                              coreFilterable  = isCoreFilterableFormat(format, sampleMode);
2470
2471                         if (s_filters[filterNdx].sampling == TextureBorderClampTest::SAMPLE_GATHER)
2472                                 continue;
2473
2474                         if (coreFilterable || !filterRequiresFilterability(filter))
2475                                 rangeClampGroup->addChild(new TextureBorderClampRangeClampCase(m_context, caseName.c_str(), "", format, sampleMode, filter));
2476                 }
2477         }
2478
2479         // .sampler
2480         {
2481                 static const struct
2482                 {
2483                         const char*                                             name;
2484                         deUint32                                                format;
2485                         tcu::Sampler::DepthStencilMode  mode;
2486                 } formats[] =
2487                 {
2488                         { "unorm_color",                GL_R8,                                  tcu::Sampler::MODE_LAST         },
2489                         { "snorm_color",                GL_R8_SNORM,                    tcu::Sampler::MODE_LAST         },
2490                         { "float_color",                GL_RG32F,                               tcu::Sampler::MODE_LAST         },
2491                         { "int_color",                  GL_R8I,                                 tcu::Sampler::MODE_LAST         },
2492                         { "uint_color",                 GL_R16UI,                               tcu::Sampler::MODE_LAST         },
2493                         { "unorm_depth",                GL_DEPTH_COMPONENT24,   tcu::Sampler::MODE_DEPTH        },
2494                         { "float_depth",                GL_DEPTH_COMPONENT32F,  tcu::Sampler::MODE_DEPTH        },
2495                         { "uint_stencil",               GL_STENCIL_INDEX8,              tcu::Sampler::MODE_STENCIL      },
2496                         { "compressed_color",   GL_COMPRESSED_RG11_EAC, tcu::Sampler::MODE_LAST         },
2497                 };
2498
2499                 tcu::TestCaseGroup* const samplerGroup = new tcu::TestCaseGroup(m_testCtx, "sampler", "Sampler param tests");
2500                 addChild(samplerGroup);
2501
2502                 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx)
2503                 {
2504                         const deUint32                                                  format          = formats[formatNdx].format;
2505                         const tcu::Sampler::DepthStencilMode    sampleMode      = formats[formatNdx].mode;
2506                         const char*                                                             caseName        = formats[formatNdx].name;
2507
2508                         samplerGroup->addChild(new TextureBorderClampFormatCase(m_context,
2509                                                                                                                                         caseName,
2510                                                                                                                                         "",
2511                                                                                                                                         format,
2512                                                                                                                                         sampleMode,
2513                                                                                                                                         TextureBorderClampFormatCase::STATE_SAMPLER_PARAM,
2514                                                                                                                                         SIZE_POT,
2515                                                                                                                                         GL_NEAREST,
2516                                                                                                                                         TextureBorderClampFormatCase::SAMPLE_FILTER));
2517                 }
2518         }
2519
2520         // .per_axis_wrap_mode
2521         {
2522                 static const struct
2523                 {
2524                         const char*                                             name;
2525                         bool                                                    is3D;
2526                 } targets[] =
2527                 {
2528                         { "texture_2d", false   },
2529                         { "texture_3d", true    },
2530                 };
2531                 static const struct
2532                 {
2533                         const char*                                             name;
2534                         deUint32                                                format;
2535                         tcu::Sampler::DepthStencilMode  mode;
2536                         bool                                                    supports3D;
2537                 } formats[] =
2538                 {
2539                         { "unorm_color",                GL_RG8,                                         tcu::Sampler::MODE_LAST,        true    },
2540                         { "snorm_color",                GL_RG8_SNORM,                           tcu::Sampler::MODE_LAST,        true    },
2541                         { "float_color",                GL_R32F,                                        tcu::Sampler::MODE_LAST,        true    },
2542                         { "int_color",                  GL_RG16I,                                       tcu::Sampler::MODE_LAST,        true    },
2543                         { "uint_color",                 GL_R8UI,                                        tcu::Sampler::MODE_LAST,        true    },
2544                         { "unorm_depth",                GL_DEPTH_COMPONENT16,           tcu::Sampler::MODE_DEPTH,       false   },
2545                         { "float_depth",                GL_DEPTH32F_STENCIL8,           tcu::Sampler::MODE_DEPTH,       false   },
2546                         { "uint_stencil",               GL_DEPTH32F_STENCIL8,           tcu::Sampler::MODE_STENCIL,     false   },
2547                         { "compressed_color",   GL_COMPRESSED_RGB8_ETC2,        tcu::Sampler::MODE_LAST,        false   },
2548                 };
2549                 static const struct
2550                 {
2551                         const char*     name;
2552                         deUint32        sWrap;
2553                         deUint32        tWrap;
2554                         deUint32        rWrap;
2555                         bool            is3D;
2556                 } wrapConfigs[] =
2557                 {
2558                         // 2d configs
2559                         { "s_clamp_to_edge_t_clamp_to_border",                                          GL_CLAMP_TO_EDGE,       GL_CLAMP_TO_BORDER,     GL_NONE,                        false   },
2560                         { "s_repeat_t_clamp_to_border",                                                         GL_REPEAT,                      GL_CLAMP_TO_BORDER,     GL_NONE,                        false   },
2561                         { "s_mirrored_repeat_t_clamp_to_border",                                        GL_MIRRORED_REPEAT,     GL_CLAMP_TO_BORDER,     GL_NONE,                        false   },
2562
2563                         // 3d configs
2564                         { "s_clamp_to_border_t_clamp_to_border_r_clamp_to_border",      GL_CLAMP_TO_BORDER,     GL_CLAMP_TO_BORDER,     GL_CLAMP_TO_BORDER,     true    },
2565                         { "s_clamp_to_border_t_clamp_to_border_r_repeat",                       GL_CLAMP_TO_BORDER,     GL_CLAMP_TO_BORDER,     GL_REPEAT,                      true    },
2566                         { "s_mirrored_repeat_t_clamp_to_border_r_repeat",                       GL_MIRRORED_REPEAT,     GL_CLAMP_TO_BORDER,     GL_REPEAT,                      true    },
2567                         { "s_repeat_t_mirrored_repeat_r_clamp_to_border",                       GL_REPEAT,                      GL_MIRRORED_REPEAT,     GL_CLAMP_TO_BORDER,     true    },
2568                 };
2569
2570                 tcu::TestCaseGroup* const perAxisGroup = new tcu::TestCaseGroup(m_testCtx, "per_axis_wrap_mode", "Per-axis wrapping modes");
2571                 addChild(perAxisGroup);
2572
2573                 // .texture_nd
2574                 for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(targets); ++targetNdx)
2575                 {
2576                         tcu::TestCaseGroup* const targetGroup = new tcu::TestCaseGroup(m_testCtx, targets[targetNdx].name, "Texture target test");
2577                         perAxisGroup->addChild(targetGroup);
2578
2579                         // .format
2580                         for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx)
2581                         {
2582                                 if (targets[targetNdx].is3D && !formats[formatNdx].supports3D)
2583                                         continue;
2584                                 else
2585                                 {
2586                                         const deUint32                                                  format                  = formats[formatNdx].format;
2587                                         const tcu::Sampler::DepthStencilMode    sampleMode              = formats[formatNdx].mode;
2588                                         const bool                                                              coreFilterable  = isCoreFilterableFormat(format, sampleMode);
2589                                         tcu::TestCaseGroup* const                               formatGroup             = new tcu::TestCaseGroup(m_testCtx, formats[formatNdx].name, "Format test");
2590                                         targetGroup->addChild(formatGroup);
2591
2592                                         // .linear
2593                                         // .nearest
2594                                         // .gather
2595                                         for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(s_filters); ++filterNdx)
2596                                         {
2597                                                 const deUint32 filter = s_filters[filterNdx].filter;
2598
2599                                                 if (!coreFilterable && filterRequiresFilterability(filter))
2600                                                 {
2601                                                         // skip linear on pure integers
2602                                                         continue;
2603                                                 }
2604                                                 else if (s_filters[filterNdx].sampling == TextureBorderClampTest::SAMPLE_GATHER && targets[targetNdx].is3D)
2605                                                 {
2606                                                         // skip gather on 3d
2607                                                         continue;
2608                                                 }
2609                                                 else
2610                                                 {
2611                                                         tcu::TestCaseGroup* const filteringGroup = new tcu::TestCaseGroup(m_testCtx, s_filters[filterNdx].name, "Tests with specific filter");
2612                                                         formatGroup->addChild(filteringGroup);
2613
2614                                                         // .s_XXX_t_XXX(_r_XXX)
2615                                                         for (int wrapNdx = 0; wrapNdx < DE_LENGTH_OF_ARRAY(wrapConfigs); ++wrapNdx)
2616                                                         {
2617                                                                 if (wrapConfigs[wrapNdx].is3D != targets[targetNdx].is3D)
2618                                                                         continue;
2619                                                                 else
2620                                                                 {
2621                                                                         for (int sizeNdx = 0; sizeNdx < 2; ++sizeNdx)
2622                                                                         {
2623                                                                                 const char* const               wrapName                        = wrapConfigs[wrapNdx].name;
2624                                                                                 const bool                              isNpotCase                      = (sizeNdx == 1);
2625                                                                                 const char* const               sizeNameExtension       = (isNpotCase) ? ("_npot") : ("_pot");
2626                                                                                 const SizeType                  size                            = (isNpotCase) ? (SIZE_NPOT) : (SIZE_POT);
2627
2628                                                                                 if (!targets[targetNdx].is3D)
2629                                                                                         filteringGroup->addChild(new TextureBorderClampPerAxisCase2D(m_context,
2630                                                                                                                                                                                                                  (std::string() + wrapName + sizeNameExtension).c_str(),
2631                                                                                                                                                                                                                  "",
2632                                                                                                                                                                                                                  format,
2633                                                                                                                                                                                                                  sampleMode,
2634                                                                                                                                                                                                                  size,
2635                                                                                                                                                                                                                  filter,
2636                                                                                                                                                                                                                  wrapConfigs[wrapNdx].sWrap,
2637                                                                                                                                                                                                                  wrapConfigs[wrapNdx].tWrap,
2638                                                                                                                                                                                                                  s_filters[filterNdx].sampling));
2639                                                                                 else
2640                                                                                 {
2641                                                                                         DE_ASSERT(sampleMode == tcu::Sampler::MODE_LAST);
2642                                                                                         filteringGroup->addChild(new TextureBorderClampPerAxisCase3D(m_context,
2643                                                                                                                                                                                                                  (std::string() + wrapName + sizeNameExtension).c_str(),
2644                                                                                                                                                                                                                  "",
2645                                                                                                                                                                                                                  format,
2646                                                                                                                                                                                                                  size,
2647                                                                                                                                                                                                                  filter,
2648                                                                                                                                                                                                                  wrapConfigs[wrapNdx].sWrap,
2649                                                                                                                                                                                                                  wrapConfigs[wrapNdx].tWrap,
2650                                                                                                                                                                                                                  wrapConfigs[wrapNdx].rWrap));
2651                                                                                 }
2652                                                                         }
2653                                                                 }
2654                                                         }
2655                                                 }
2656                                         }
2657                                 }
2658                         }
2659                 }
2660         }
2661
2662         // .depth_compare_mode
2663         {
2664                 static const struct
2665                 {
2666                         const char*                                             name;
2667                         deUint32                                                format;
2668                 } formats[] =
2669                 {
2670                         { "depth_component16",          GL_DEPTH_COMPONENT16    },
2671                         { "depth_component24",          GL_DEPTH_COMPONENT24    },
2672                         { "depth24_stencil8",           GL_DEPTH24_STENCIL8             },
2673                         { "depth32f_stencil8",          GL_DEPTH32F_STENCIL8    },
2674                 };
2675
2676                 tcu::TestCaseGroup* const compareGroup = new tcu::TestCaseGroup(m_testCtx, "depth_compare_mode", "Tests depth compare mode");
2677                 addChild(compareGroup);
2678
2679                 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx)
2680                 {
2681                         const deUint32                                                  format                  = formats[formatNdx].format;
2682                         tcu::TestCaseGroup* const                               formatGroup             = new tcu::TestCaseGroup(m_testCtx, formats[formatNdx].name, "Format test");
2683
2684                         compareGroup->addChild(formatGroup);
2685
2686                         // (format).(linear|nearest|gather)_(pot|npot)
2687                         for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(s_filters); ++filterNdx)
2688                         for (int sizeNdx = 0; sizeNdx < 2; ++sizeNdx)
2689                         {
2690                                         const bool                              isNpotCase              = (sizeNdx == 1);
2691                                         const char* const               sizeName                = (isNpotCase) ? ("size_npot") : ("size_pot");
2692                                         const SizeType                  sizeType                = (isNpotCase) ? (SIZE_NPOT) : (SIZE_POT);
2693                                         const std::string               caseName                = std::string() + s_filters[filterNdx].name + "_" + sizeName;
2694                                         const deUint32                  filter                  = s_filters[filterNdx].filter;
2695
2696                                         formatGroup->addChild(new TextureBorderClampDepthCompareCase(m_context,
2697                                                                                                                                                                  caseName.c_str(),
2698                                                                                                                                                                  "",
2699                                                                                                                                                                  format,
2700                                                                                                                                                                  sizeType,
2701                                                                                                                                                                  filter,
2702                                                                                                                                                                  s_filters[filterNdx].sampling));
2703                         }
2704                 }
2705         }
2706
2707         // unused channels (A in rgb, G in stencil etc.)
2708         {
2709                 static const struct
2710                 {
2711                         const char*                                             name;
2712                         deUint32                                                format;
2713                         tcu::Sampler::DepthStencilMode  mode;
2714                 } formats[] =
2715                 {
2716                         { "r8",                                                                         GL_R8,                                          tcu::Sampler::MODE_LAST         },
2717                         { "rg8_snorm",                                                          GL_RG8_SNORM,                           tcu::Sampler::MODE_LAST         },
2718                         { "rgb8",                                                                       GL_RGB8,                                        tcu::Sampler::MODE_LAST         },
2719                         { "rg32f",                                                                      GL_RG32F,                                       tcu::Sampler::MODE_LAST         },
2720                         { "r16i",                                                                       GL_RG16I,                                       tcu::Sampler::MODE_LAST         },
2721                         { "luminance",                                                          GL_LUMINANCE,                           tcu::Sampler::MODE_LAST         },
2722                         { "alpha",                                                                      GL_ALPHA,                                       tcu::Sampler::MODE_LAST         },
2723                         { "luminance_alpha",                                            GL_LUMINANCE_ALPHA,                     tcu::Sampler::MODE_LAST         },
2724                         { "depth_component16",                                          GL_DEPTH_COMPONENT16,           tcu::Sampler::MODE_DEPTH        },
2725                         { "depth_component32f",                                         GL_DEPTH_COMPONENT32F,          tcu::Sampler::MODE_DEPTH        },
2726                         { "stencil_index8",                                                     GL_STENCIL_INDEX8,                      tcu::Sampler::MODE_STENCIL      },
2727                         { "depth32f_stencil8_sample_depth",                     GL_DEPTH32F_STENCIL8,           tcu::Sampler::MODE_DEPTH        },
2728                         { "depth32f_stencil8_sample_stencil",           GL_DEPTH32F_STENCIL8,           tcu::Sampler::MODE_STENCIL      },
2729                         { "depth24_stencil8_sample_depth",                      GL_DEPTH24_STENCIL8,            tcu::Sampler::MODE_DEPTH        },
2730                         { "depth24_stencil8_sample_stencil",            GL_DEPTH24_STENCIL8,            tcu::Sampler::MODE_STENCIL      },
2731                         { "compressed_r11_eac",                                         GL_COMPRESSED_R11_EAC,          tcu::Sampler::MODE_LAST         },
2732                 };
2733
2734                 tcu::TestCaseGroup* const unusedGroup = new tcu::TestCaseGroup(m_testCtx, "unused_channels", "Tests channels that are not present in the internal format");
2735                 addChild(unusedGroup);
2736
2737                 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx)
2738                 {
2739                         unusedGroup->addChild(new TextureBorderClampUnusedChannelCase(m_context,
2740                                                                                                                                                   formats[formatNdx].name,
2741                                                                                                                                                   "",
2742                                                                                                                                                   formats[formatNdx].format,
2743                                                                                                                                                   formats[formatNdx].mode));
2744                 }
2745         }
2746 }
2747
2748 } // Functional
2749 } // gles31
2750 } // deqp