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
filterRequiresFilterability(deUint32 filter)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
isDepthFormat(deUint32 format,tcu::Sampler::DepthStencilMode mode)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
isStencilFormat(deUint32 format,tcu::Sampler::DepthStencilMode mode)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
getFormatChannelClass(deUint32 format,tcu::Sampler::DepthStencilMode mode)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
getDimensionNumBlocks(int dimensionSize,int blockSize)171 int getDimensionNumBlocks (int dimensionSize, int blockSize)
172 {
173 // ceil( a / b )
174 return (dimensionSize + blockSize - 1) / blockSize;
175 }
176
generateDefaultCompressedData(tcu::CompressedTexture & dst,const tcu::CompressedTexFormat & format)177 void generateDefaultCompressedData (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
createTextureFromInternalFormatdeqp::gles31::Functional::__anonec341bb20111::TextureTraits219 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
createTextureFromFormatAndTypedeqp::gles31::Functional::__anonec341bb20111::TextureTraits224 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
createTextureFromCompressedDatadeqp::gles31::Functional::__anonec341bb20111::TextureTraits229 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
getTextureNumLayersdeqp::gles31::Functional::__anonec341bb20111::TextureTraits241 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
createTextureFromInternalFormatdeqp::gles31::Functional::__anonec341bb20111::TextureTraits254 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
createTextureFromFormatAndTypedeqp::gles31::Functional::__anonec341bb20111::TextureTraits259 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
createTextureFromCompressedDatadeqp::gles31::Functional::__anonec341bb20111::TextureTraits264 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
getTextureNumLayersdeqp::gles31::Functional::__anonec341bb20111::TextureTraits276 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>
genDefaultTexture(glu::RenderContext & renderCtx,const glu::ContextInfo & ctxInfo,deUint32 texFormat,const typename TextureTraits<T>::SizeType & size)284 de::MovePtr<T> genDefaultTexture (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 generateDefaultCompressedData(compressedLevel, compressedFormat);
342
343 texture = TextureTraits<T>::createTextureFromCompressedData(renderCtx,
344 ctxInfo,
345 compressedLevel,
346 decompressionParams);
347 }
348
349 return texture;
350 }
351
getNBitIntegerMaxValue(bool isSigned,int numBits)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
getNBitIntegerMinValue(bool isSigned,int numBits)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
getNBitIntegerVec4MaxValue(bool isSigned,const tcu::IVec4 & numBits)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
getNBitIntegerVec4MinValue(bool isSigned,const tcu::IVec4 & numBits)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
mapToFormatColorUnits(const tcu::TextureFormat & texFormat,const tcu::Vec4 & normalizedRange)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
mapToFormatColorRepresentable(const tcu::TextureFormat & texFormat,const tcu::Vec4 & normalizedRange)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
isCoreFilterableFormat(deUint32 format,tcu::Sampler::DepthStencilMode mode)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
TextureBorderClampTest(Context & context,const char * name,const char * description,deUint32 texFormat,tcu::Sampler::DepthStencilMode mode,StateType stateType,int texWidth,int texHeight,SamplingFunction samplingFunction,deUint32 flags)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
~TextureBorderClampTest(void)644 TextureBorderClampTest::~TextureBorderClampTest (void)
645 {
646 deinit();
647 }
648
init(void)649 void TextureBorderClampTest::init (void)
650 {
651 // requirements
652 const bool supportsGL45 = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5));
653 const bool supportsES32orGL45 = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)) || supportsGL45;
654
655 if (!supportsES32orGL45 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_border_clamp"))
656 throw tcu::NotSupportedError("Test requires GL_EXT_texture_border_clamp extension");
657
658 if (glu::isCompressedFormat(m_texFormat) &&
659 !supportsES32orGL45 &&
660 tcu::isAstcFormat(glu::mapGLCompressedTexFormat(m_texFormat)) &&
661 !m_context.getContextInfo().isExtensionSupported("GL_KHR_texture_compression_astc_ldr"))
662 {
663 throw tcu::NotSupportedError("Test requires GL_KHR_texture_compression_astc_ldr extension");
664 }
665
666 if (m_texFormat == GL_BGRA && !m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_format_BGRA8888"))
667 throw tcu::NotSupportedError("Test requires GL_EXT_texture_format_BGRA8888 extension");
668
669 if (m_context.getRenderTarget().getWidth() < VIEWPORT_WIDTH ||
670 m_context.getRenderTarget().getHeight() < VIEWPORT_HEIGHT)
671 {
672 throw tcu::NotSupportedError("Test requires " + de::toString<int>(VIEWPORT_WIDTH) + "x" + de::toString<int>(VIEWPORT_HEIGHT) + " viewport");
673 }
674
675 // resources
676
677 m_texture = genDefaultTexture<glu::Texture2D>(m_context.getRenderContext(), m_context.getContextInfo(), m_texFormat, tcu::IVec2(m_texWidth, m_texHeight));
678
679 m_testCtx.getLog() << tcu::TestLog::Message
680 << "Created texture with format " << glu::getTextureFormatName(m_texFormat)
681 << ", size (" << m_texture->getRefTexture().getWidth() << ", " << m_texture->getRefTexture().getHeight() << ")\n"
682 << "Setting sampling state using " << ((m_stateType == STATE_TEXTURE_PARAM) ? ("texture state") : ("sampler state"))
683 << tcu::TestLog::EndMessage;
684
685 if (m_samplingFunction == SAMPLE_FILTER)
686 {
687 const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
688
689 m_renderer = de::MovePtr<gls::TextureTestUtil::TextureRenderer>(new gls::TextureTestUtil::TextureRenderer(m_context.getRenderContext(), m_testCtx.getLog(), glslVersion, glu::PRECISION_HIGHP));
690 }
691 else
692 {
693 m_gatherProgram = de::MovePtr<glu::ShaderProgram>(genGatherProgram());
694
695 m_testCtx.getLog() << tcu::TestLog::Message
696 << "Using texture gather to sample texture"
697 << tcu::TestLog::EndMessage
698 << *m_gatherProgram;
699
700 if (!m_gatherProgram->isOk())
701 throw tcu::TestError("failed to build program");
702 }
703 }
704
deinit(void)705 void TextureBorderClampTest::deinit (void)
706 {
707 m_texture.clear();
708 m_renderer.clear();
709 m_gatherProgram.clear();
710 }
711
iterate(void)712 TextureBorderClampTest::IterateResult TextureBorderClampTest::iterate (void)
713 {
714 const IterationConfig iterationConfig = getIteration(m_iterationNdx);
715 const std::string iterationDesc = "Iteration " + de::toString(m_iterationNdx+1) + (iterationConfig.description.empty() ? ("") : (" - " + iterationConfig.description));
716 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Iteration", iterationDesc);
717 tcu::Surface renderedFrame (VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
718 const glu::TextureTestUtil::ReferenceParams samplerParams = genSamplerParams(iterationConfig);
719
720 logParams(iterationConfig, samplerParams);
721 renderTo(renderedFrame, iterationConfig, samplerParams);
722 verifyImage(renderedFrame, iterationConfig, samplerParams);
723
724 if (++m_iterationNdx == getNumIterations())
725 {
726 m_result.setTestContextResult(m_testCtx);
727 return STOP;
728 }
729 return CONTINUE;
730 }
731
logParams(const IterationConfig & config,const glu::TextureTestUtil::ReferenceParams & samplerParams)732 void TextureBorderClampTest::logParams (const IterationConfig& config, const glu::TextureTestUtil::ReferenceParams& samplerParams)
733 {
734 const std::string borderColorString = (m_channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER) ? (de::toString(config.borderColor.get<deInt32>()))
735 : (m_channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER) ? (de::toString(config.borderColor.get<deUint32>()))
736 : (de::toString(config.borderColor.get<float>()));
737
738 m_testCtx.getLog() << tcu::TestLog::Message
739 << "Rendering full screen quad, tex coords bottom-left: " << config.p0 << ", top-right " << config.p1 << "\n"
740 << "Border color is " << borderColorString << "\n"
741 << "Texture lookup bias: " << samplerParams.colorBias << "\n"
742 << "Texture lookup scale: " << samplerParams.colorScale << "\n"
743 << "Filters: min = " << glu::getTextureFilterName(glu::getGLFilterMode(samplerParams.sampler.minFilter))
744 << ", mag = " << glu::getTextureFilterName(glu::getGLFilterMode(samplerParams.sampler.magFilter)) << "\n"
745 << "Wrap mode: s = " << glu::getRepeatModeStr(config.sWrapMode)
746 << ", t = " << glu::getRepeatModeStr(config.tWrapMode) << "\n"
747 << tcu::TestLog::EndMessage;
748
749 if (m_sampleMode == tcu::Sampler::MODE_DEPTH)
750 m_testCtx.getLog() << tcu::TestLog::Message << "Depth stencil texture mode is DEPTH_COMPONENT" << tcu::TestLog::EndMessage;
751 else if (m_sampleMode == tcu::Sampler::MODE_STENCIL)
752 m_testCtx.getLog() << tcu::TestLog::Message << "Depth stencil texture mode is STENCIL_INDEX" << tcu::TestLog::EndMessage;
753
754 if (config.compareMode != GL_NONE)
755 {
756 m_testCtx.getLog() << tcu::TestLog::Message
757 << "Texture mode is COMPARE_REF_TO_TEXTURE, mode = " << glu::getCompareFuncStr(config.compareMode) << "\n"
758 << "Compare reference value = " << config.compareRef << "\n"
759 << tcu::TestLog::EndMessage;
760 }
761 }
762
renderTo(tcu::Surface & surface,const IterationConfig & config,const glu::TextureTestUtil::ReferenceParams & samplerParams)763 void TextureBorderClampTest::renderTo (tcu::Surface& surface,
764 const IterationConfig& config,
765 const glu::TextureTestUtil::ReferenceParams& samplerParams)
766 {
767 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
768 const gls::TextureTestUtil::RandomViewport viewport (m_context.getRenderTarget(), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, getIterationSeed(config));
769 std::vector<float> texCoord;
770 de::MovePtr<glu::Sampler> sampler;
771
772 glu::TextureTestUtil::computeQuadTexCoord2D(texCoord, config.p0, config.p1);
773
774 // Bind to unit 0.
775 gl.activeTexture(GL_TEXTURE0);
776 gl.bindTexture(GL_TEXTURE_2D, m_texture->getGLTexture());
777
778 if (m_sampleMode == tcu::Sampler::MODE_DEPTH)
779 gl.texParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_DEPTH_COMPONENT);
780 else if (m_sampleMode == tcu::Sampler::MODE_STENCIL)
781 gl.texParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX);
782
783 if (config.compareMode == GL_NONE)
784 {
785 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
786 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_ALWAYS);
787 }
788 else
789 {
790 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
791 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, config.compareMode);
792 }
793
794 if (m_stateType == STATE_TEXTURE_PARAM)
795 {
796 // Setup filtering and wrap modes.
797 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, glu::getGLWrapMode(samplerParams.sampler.wrapS));
798 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, glu::getGLWrapMode(samplerParams.sampler.wrapT));
799 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glu::getGLFilterMode(samplerParams.sampler.minFilter));
800 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glu::getGLFilterMode(samplerParams.sampler.magFilter));
801
802 switch (m_channelClass)
803 {
804 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
805 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
806 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
807 gl.texParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, config.borderColor.getAccess<float>());
808 break;
809
810 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
811 gl.texParameterIiv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, config.borderColor.getAccess<deInt32>());
812 break;
813
814 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
815 gl.texParameterIuiv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, config.borderColor.getAccess<deUint32>());
816 break;
817
818 default:
819 DE_ASSERT(false);
820 }
821 }
822 else if (m_stateType == STATE_SAMPLER_PARAM)
823 {
824 const tcu::Vec4 blue(0.0f, 0.0f, 1.0f, 1.0f);
825
826 // Setup filtering and wrap modes to bad values
827 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
828 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
829 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
830 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
831 gl.texParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, blue.getPtr()); // just set some unlikely color
832
833 // setup sampler to correct values
834 sampler = de::MovePtr<glu::Sampler>(new glu::Sampler(m_context.getRenderContext()));
835
836 gl.samplerParameteri(**sampler, GL_TEXTURE_WRAP_S, glu::getGLWrapMode(samplerParams.sampler.wrapS));
837 gl.samplerParameteri(**sampler, GL_TEXTURE_WRAP_T, glu::getGLWrapMode(samplerParams.sampler.wrapT));
838 gl.samplerParameteri(**sampler, GL_TEXTURE_MIN_FILTER, glu::getGLFilterMode(samplerParams.sampler.minFilter));
839 gl.samplerParameteri(**sampler, GL_TEXTURE_MAG_FILTER, glu::getGLFilterMode(samplerParams.sampler.magFilter));
840
841 switch (m_channelClass)
842 {
843 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
844 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
845 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
846 gl.samplerParameterfv(**sampler, GL_TEXTURE_BORDER_COLOR, config.borderColor.getAccess<float>());
847 break;
848
849 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
850 gl.samplerParameterIiv(**sampler, GL_TEXTURE_BORDER_COLOR, config.borderColor.getAccess<deInt32>());
851 break;
852
853 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
854 gl.samplerParameterIuiv(**sampler, GL_TEXTURE_BORDER_COLOR, config.borderColor.getAccess<deUint32>());
855 break;
856
857 default:
858 DE_ASSERT(false);
859 }
860
861 gl.bindSampler(0, **sampler);
862 }
863
864 GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");
865
866 gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
867 renderQuad(&texCoord[0], samplerParams);
868 glu::readPixels(m_context.getRenderContext(), viewport.x, viewport.y, surface.getAccess());
869 }
870
renderQuad(const float * texCoord,const glu::TextureTestUtil::ReferenceParams & samplerParams)871 void TextureBorderClampTest::renderQuad (const float* texCoord, const glu::TextureTestUtil::ReferenceParams& samplerParams)
872 {
873 // use TextureRenderer for basic rendering, use custom for gather
874 if (m_samplingFunction == SAMPLE_FILTER)
875 m_renderer->renderQuad(0, texCoord, samplerParams);
876 else
877 {
878 static const float position[] =
879 {
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 +1.0f, +1.0f, 0.0f, 1.0f
884 };
885 static const deUint16 indices[] =
886 {
887 0, 1, 2, 2, 1, 3
888 };
889 const glu::VertexArrayBinding vertexArrays[] =
890 {
891 glu::va::Float("a_position", 4, 4, 0, &position[0]),
892 glu::va::Float("a_texcoord", 2, 4, 0, texCoord)
893 };
894
895 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
896 const deUint32 progId = m_gatherProgram->getProgram();
897
898 gl.useProgram(progId);
899 gl.uniform1i(gl.getUniformLocation(progId, "u_sampler"), 0);
900 if (m_useShadowSampler)
901 gl.uniform1f(gl.getUniformLocation(progId, "u_ref"), samplerParams.ref);
902 gl.uniform4fv(gl.getUniformLocation(progId, "u_colorScale"), 1, samplerParams.colorScale.getPtr());
903 gl.uniform4fv(gl.getUniformLocation(progId, "u_colorBias"), 1, samplerParams.colorBias.getPtr());
904
905 glu::draw(m_context.getRenderContext(), progId, DE_LENGTH_OF_ARRAY(vertexArrays), &vertexArrays[0],
906 glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
907 }
908 }
909
verifyImage(const tcu::Surface & renderedFrame,const IterationConfig & config,const glu::TextureTestUtil::ReferenceParams & samplerParams)910 void TextureBorderClampTest::verifyImage (const tcu::Surface& renderedFrame,
911 const IterationConfig& config,
912 const glu::TextureTestUtil::ReferenceParams& samplerParams)
913 {
914 const tcu::PixelFormat pixelFormat = m_context.getRenderTarget().getPixelFormat();
915
916 tcu::LodPrecision lodPrecision;
917 std::vector<float> texCoord;
918 bool verificationOk;
919
920 glu::TextureTestUtil::computeQuadTexCoord2D(texCoord, config.p0, config.p1);
921
922 lodPrecision.derivateBits = 18;
923 lodPrecision.lodBits = 5;
924
925 if (samplerParams.sampler.compare == tcu::Sampler::COMPAREMODE_NONE)
926 {
927 const tcu::TextureFormat texFormat = tcu::getEffectiveDepthStencilTextureFormat(m_texture->getRefTexture().getFormat(), m_sampleMode);
928 const bool isNearestMinFilter = samplerParams.sampler.minFilter == tcu::Sampler::NEAREST || samplerParams.sampler.minFilter == tcu::Sampler::NEAREST_MIPMAP_NEAREST;
929 const bool isNearestMagFilter = samplerParams.sampler.magFilter == tcu::Sampler::NEAREST;
930 const bool isNearestOnly = isNearestMinFilter && isNearestMagFilter;
931 const bool isSRGB = texFormat.order == tcu::TextureFormat::sRGB || texFormat.order == tcu::TextureFormat::sRGBA;
932 const int colorErrorBits = (isNearestOnly && !isSRGB) ? (1) : (2);
933 const tcu::IVec4 colorBits = tcu::max(glu::TextureTestUtil::getBitsVec(pixelFormat) - tcu::IVec4(colorErrorBits), tcu::IVec4(0));
934 tcu::LookupPrecision lookupPrecision;
935
936 lookupPrecision.colorThreshold = tcu::computeFixedPointThreshold(colorBits) / samplerParams.colorScale;
937 lookupPrecision.coordBits = tcu::IVec3(20,20,0);
938 lookupPrecision.uvwBits = tcu::IVec3(5,5,0);
939 lookupPrecision.colorMask = glu::TextureTestUtil::getCompareMask(pixelFormat);
940
941 if (m_samplingFunction == SAMPLE_FILTER)
942 {
943 verificationOk = verifyTextureSampleResult(renderedFrame.getAccess(),
944 &texCoord[0],
945 samplerParams,
946 lodPrecision,
947 lookupPrecision);
948 }
949 else if (m_samplingFunction == SAMPLE_GATHER)
950 {
951 verificationOk = verifyTextureGatherResult(renderedFrame.getAccess(),
952 &texCoord[0],
953 samplerParams,
954 lookupPrecision);
955 }
956 else
957 {
958 DE_ASSERT(false);
959 verificationOk = false;
960 }
961 }
962 else
963 {
964 tcu::TexComparePrecision texComparePrecision;
965 tcu::TexComparePrecision lowQualityTexComparePrecision;
966 tcu::LodPrecision lowQualityLodPrecision = lodPrecision;
967
968 texComparePrecision.coordBits = tcu::IVec3(20,20,0);
969 texComparePrecision.uvwBits = tcu::IVec3(7,7,0);
970 texComparePrecision.pcfBits = 5;
971 texComparePrecision.referenceBits = 16;
972 texComparePrecision.resultBits = de::max(0, pixelFormat.redBits - 1);
973
974 lowQualityTexComparePrecision.coordBits = tcu::IVec3(20,20,0);
975 lowQualityTexComparePrecision.uvwBits = tcu::IVec3(4,4,0);
976 lowQualityTexComparePrecision.pcfBits = 0;
977 lowQualityTexComparePrecision.referenceBits = 16;
978 lowQualityTexComparePrecision.resultBits = de::max(0, pixelFormat.redBits - 1);
979
980 lowQualityLodPrecision.lodBits = 4;
981
982 if (m_samplingFunction == SAMPLE_FILTER)
983 {
984 verificationOk = verifyTextureCompareResult(renderedFrame.getAccess(),
985 &texCoord[0],
986 samplerParams,
987 texComparePrecision,
988 lowQualityTexComparePrecision,
989 lodPrecision,
990 lowQualityLodPrecision);
991 }
992 else if (m_samplingFunction == SAMPLE_GATHER)
993 {
994 verificationOk = verifyTextureGatherCmpResult(renderedFrame.getAccess(),
995 &texCoord[0],
996 samplerParams,
997 texComparePrecision,
998 lowQualityTexComparePrecision);
999 }
1000 else
1001 {
1002 DE_ASSERT(false);
1003 verificationOk = false;
1004 }
1005 }
1006
1007 if (!verificationOk)
1008 m_result.fail("Image verification failed");
1009 }
1010
verifyTextureSampleResult(const tcu::ConstPixelBufferAccess & renderedFrame,const float * texCoord,const glu::TextureTestUtil::ReferenceParams & samplerParams,const tcu::LodPrecision & lodPrecision,const tcu::LookupPrecision & lookupPrecision)1011 bool TextureBorderClampTest::verifyTextureSampleResult (const tcu::ConstPixelBufferAccess& renderedFrame,
1012 const float* texCoord,
1013 const glu::TextureTestUtil::ReferenceParams& samplerParams,
1014 const tcu::LodPrecision& lodPrecision,
1015 const tcu::LookupPrecision& lookupPrecision)
1016 {
1017 const tcu::PixelFormat pixelFormat = m_context.getRenderTarget().getPixelFormat();
1018 tcu::Surface reference (renderedFrame.getWidth(), renderedFrame.getHeight());
1019 tcu::Surface errorMask (renderedFrame.getWidth(), renderedFrame.getHeight());
1020 int numFailedPixels;
1021
1022 glu::TextureTestUtil::sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), m_texture->getRefTexture(), texCoord, samplerParams);
1023
1024 numFailedPixels = glu::TextureTestUtil::computeTextureLookupDiff(renderedFrame, reference.getAccess(), errorMask.getAccess(), m_texture->getRefTexture(),
1025 texCoord, samplerParams, lookupPrecision, lodPrecision, m_testCtx.getWatchDog());
1026
1027 if (numFailedPixels > 0)
1028 m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage;
1029 m_testCtx.getLog() << tcu::TestLog::ImageSet("VerifyResult", "Verification result")
1030 << tcu::TestLog::Image("Rendered", "Rendered image", renderedFrame);
1031 if (numFailedPixels > 0)
1032 {
1033 m_testCtx.getLog() << tcu::TestLog::Image("Reference", "Ideal reference image", reference)
1034 << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask);
1035 }
1036 m_testCtx.getLog() << tcu::TestLog::EndImageSet;
1037
1038 return (numFailedPixels == 0);
1039 }
1040
verifyTextureCompareResult(const tcu::ConstPixelBufferAccess & renderedFrame,const float * texCoord,const glu::TextureTestUtil::ReferenceParams & samplerParams,const tcu::TexComparePrecision & texComparePrecision,const tcu::TexComparePrecision & lowQualityTexComparePrecision,const tcu::LodPrecision & lodPrecision,const tcu::LodPrecision & lowQualityLodPrecision)1041 bool TextureBorderClampTest::verifyTextureCompareResult (const tcu::ConstPixelBufferAccess& renderedFrame,
1042 const float* texCoord,
1043 const glu::TextureTestUtil::ReferenceParams& samplerParams,
1044 const tcu::TexComparePrecision& texComparePrecision,
1045 const tcu::TexComparePrecision& lowQualityTexComparePrecision,
1046 const tcu::LodPrecision& lodPrecision,
1047 const tcu::LodPrecision& lowQualityLodPrecision)
1048 {
1049 const tcu::PixelFormat pixelFormat = m_context.getRenderTarget().getPixelFormat();
1050 const int colorErrorBits = 1;
1051 const tcu::IVec4 nonShadowBits = tcu::max(glu::TextureTestUtil::getBitsVec(pixelFormat) - tcu::IVec4(colorErrorBits), tcu::IVec4(0));
1052 const tcu::Vec3 nonShadowThreshold = tcu::computeFixedPointThreshold(nonShadowBits).swizzle(1,2,3);
1053 std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage;
1054 const tcu::Texture2DView effectiveView = tcu::getEffectiveTextureView(m_texture->getRefTexture(), srcLevelStorage, samplerParams.sampler);
1055 tcu::Surface reference (renderedFrame.getWidth(), renderedFrame.getHeight());
1056 tcu::Surface errorMask (renderedFrame.getWidth(), renderedFrame.getHeight());
1057 int numFailedPixels;
1058
1059 glu::TextureTestUtil::sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), effectiveView, texCoord, samplerParams);
1060
1061 numFailedPixels = glu::TextureTestUtil::computeTextureCompareDiff(renderedFrame, reference.getAccess(), errorMask.getAccess(), effectiveView,
1062 texCoord, samplerParams, texComparePrecision, lodPrecision, nonShadowThreshold);
1063
1064 if (numFailedPixels > 0)
1065 {
1066 m_testCtx.getLog() << tcu::TestLog::Message
1067 << "Warning: Verification assuming high-quality PCF filtering failed."
1068 << tcu::TestLog::EndMessage;
1069
1070 numFailedPixels = glu::TextureTestUtil::computeTextureCompareDiff(renderedFrame, reference.getAccess(), errorMask.getAccess(), effectiveView,
1071 texCoord, samplerParams, lowQualityTexComparePrecision, lowQualityLodPrecision, nonShadowThreshold);
1072
1073 if (numFailedPixels > 0)
1074 m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: Verification against low precision requirements failed, failing test case." << tcu::TestLog::EndMessage;
1075 else if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
1076 m_result.addResult(QP_TEST_RESULT_QUALITY_WARNING, "Low-quality result");
1077 }
1078
1079 if (numFailedPixels > 0)
1080 m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage;
1081 m_testCtx.getLog() << tcu::TestLog::ImageSet("VerifyResult", "Verification result")
1082 << tcu::TestLog::Image("Rendered", "Rendered image", renderedFrame);
1083 if (numFailedPixels > 0)
1084 {
1085 m_testCtx.getLog() << tcu::TestLog::Image("Reference", "Ideal reference image", reference)
1086 << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask);
1087 }
1088 m_testCtx.getLog() << tcu::TestLog::EndImageSet;
1089
1090 return (numFailedPixels == 0);
1091 }
1092
1093 template <typename T>
triQuadInterpolate(const T (& values)[4],float xFactor,float yFactor)1094 static inline T triQuadInterpolate (const T (&values)[4], float xFactor, float yFactor)
1095 {
1096 if (xFactor + yFactor < 1.0f)
1097 return values[0] + (values[2]-values[0])*xFactor + (values[1]-values[0])*yFactor;
1098 else
1099 return values[3] + (values[1]-values[3])*(1.0f-xFactor) + (values[2]-values[3])*(1.0f-yFactor);
1100 }
1101
verifyTextureGatherResult(const tcu::ConstPixelBufferAccess & renderedFrame,const float * texCoordArray,const glu::TextureTestUtil::ReferenceParams & samplerParams,const tcu::LookupPrecision & lookupPrecision)1102 bool TextureBorderClampTest::verifyTextureGatherResult (const tcu::ConstPixelBufferAccess& renderedFrame,
1103 const float* texCoordArray,
1104 const glu::TextureTestUtil::ReferenceParams& samplerParams,
1105 const tcu::LookupPrecision& lookupPrecision)
1106 {
1107 const tcu::Vec2 texCoords[4] =
1108 {
1109 tcu::Vec2(texCoordArray[0], texCoordArray[1]),
1110 tcu::Vec2(texCoordArray[2], texCoordArray[3]),
1111 tcu::Vec2(texCoordArray[4], texCoordArray[5]),
1112 tcu::Vec2(texCoordArray[6], texCoordArray[7]),
1113 };
1114
1115 const tcu::PixelFormat pixelFormat = m_context.getRenderTarget().getPixelFormat();
1116 const deUint8 fbColormask = tcu::getColorMask(pixelFormat);
1117
1118 std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage;
1119 const tcu::Texture2DView effectiveView = tcu::getEffectiveTextureView(m_texture->getRefTexture(), srcLevelStorage, samplerParams.sampler);
1120
1121 tcu::Surface reference (renderedFrame.getWidth(), renderedFrame.getHeight());
1122 tcu::Surface errorMask (renderedFrame.getWidth(), renderedFrame.getHeight());
1123 int numFailedPixels = 0;
1124
1125 tcu::clear(errorMask.getAccess(), tcu::RGBA::green().toVec());
1126
1127 for (int py = 0; py < reference.getHeight(); ++py)
1128 for (int px = 0; px < reference.getWidth(); ++px)
1129 {
1130 const tcu::Vec2 viewportCoord = (tcu::Vec2((float)px, (float)py) + tcu::Vec2(0.5f)) / tcu::Vec2((float)reference.getWidth(), (float)reference.getHeight());
1131 const tcu::Vec2 texCoord = triQuadInterpolate(texCoords, viewportCoord.x(), viewportCoord.y());
1132 const tcu::Vec4 referenceValue = effectiveView.gatherOffsets(samplerParams.sampler, texCoord.x(), texCoord.y(), 0, glu::getDefaultGatherOffsets());
1133 const tcu::Vec4 referencePixel = referenceValue * samplerParams.colorScale + samplerParams.colorBias;
1134 const tcu::Vec4 resultPixel = renderedFrame.getPixel(px, py);
1135 const tcu::Vec4 resultValue = (resultPixel - samplerParams.colorBias) / samplerParams.colorScale;
1136
1137 reference.setPixel(px, py, tcu::toRGBAMasked(referenceValue, fbColormask));
1138
1139 if (tcu::boolAny(tcu::logicalAnd(lookupPrecision.colorMask,
1140 tcu::greaterThan(tcu::absDiff(resultPixel, referencePixel),
1141 lookupPrecision.colorThreshold))))
1142 {
1143 if (!tcu::isGatherOffsetsResultValid(effectiveView, samplerParams.sampler, lookupPrecision, texCoord, 0, glu::getDefaultGatherOffsets(), resultValue))
1144 {
1145 errorMask.setPixel(px, py, tcu::RGBA::red());
1146 ++numFailedPixels;
1147 }
1148 }
1149 }
1150
1151 if (numFailedPixels > 0)
1152 m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage;
1153 m_testCtx.getLog() << tcu::TestLog::ImageSet("VerifyResult", "Verification result")
1154 << tcu::TestLog::Image("Rendered", "Rendered image", renderedFrame);
1155 if (numFailedPixels > 0)
1156 {
1157 m_testCtx.getLog() << tcu::TestLog::Image("Reference", "Ideal reference image", reference)
1158 << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask);
1159 }
1160 m_testCtx.getLog() << tcu::TestLog::EndImageSet;
1161
1162 return (numFailedPixels == 0);
1163 }
1164
verifyTextureGatherCmpResult(const tcu::ConstPixelBufferAccess & renderedFrame,const float * texCoordArray,const glu::TextureTestUtil::ReferenceParams & samplerParams,const tcu::TexComparePrecision & texComparePrecision,const tcu::TexComparePrecision & lowQualityTexComparePrecision)1165 bool TextureBorderClampTest::verifyTextureGatherCmpResult (const tcu::ConstPixelBufferAccess& renderedFrame,
1166 const float* texCoordArray,
1167 const glu::TextureTestUtil::ReferenceParams& samplerParams,
1168 const tcu::TexComparePrecision& texComparePrecision,
1169 const tcu::TexComparePrecision& lowQualityTexComparePrecision)
1170 {
1171 const tcu::Vec2 texCoords[4] =
1172 {
1173 tcu::Vec2(texCoordArray[0], texCoordArray[1]),
1174 tcu::Vec2(texCoordArray[2], texCoordArray[3]),
1175 tcu::Vec2(texCoordArray[4], texCoordArray[5]),
1176 tcu::Vec2(texCoordArray[6], texCoordArray[7]),
1177 };
1178
1179 std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage;
1180 const tcu::Texture2DView effectiveView = tcu::getEffectiveTextureView(m_texture->getRefTexture(), srcLevelStorage, samplerParams.sampler);
1181
1182 const tcu::PixelFormat pixelFormat = m_context.getRenderTarget().getPixelFormat();
1183 const tcu::BVec4 colorMask = glu::TextureTestUtil::getCompareMask(pixelFormat);
1184 const deUint8 fbColormask = tcu::getColorMask(pixelFormat);
1185 tcu::Surface reference (renderedFrame.getWidth(), renderedFrame.getHeight());
1186 tcu::Surface errorMask (renderedFrame.getWidth(), renderedFrame.getHeight());
1187 int numFailedPixels = 0;
1188 bool lowQuality = false;
1189
1190 tcu::clear(errorMask.getAccess(), tcu::RGBA::green().toVec());
1191
1192 for (int py = 0; py < reference.getHeight(); ++py)
1193 for (int px = 0; px < reference.getWidth(); ++px)
1194 {
1195 const tcu::Vec2 viewportCoord = (tcu::Vec2((float)px, (float)py) + tcu::Vec2(0.5f)) / tcu::Vec2((float)reference.getWidth(), (float)reference.getHeight());
1196 const tcu::Vec2 texCoord = triQuadInterpolate(texCoords, viewportCoord.x(), viewportCoord.y());
1197 const float refZ = samplerParams.ref;
1198 const tcu::Vec4 referenceValue = effectiveView.gatherOffsetsCompare(samplerParams.sampler, refZ, texCoord.x(), texCoord.y(), glu::getDefaultGatherOffsets());
1199 const tcu::Vec4 resultValue = renderedFrame.getPixel(px, py);
1200
1201 reference.setPixel(px, py, tcu::toRGBAMasked(referenceValue, fbColormask));
1202
1203 if (tcu::boolAny(tcu::logicalAnd(colorMask, tcu::notEqual(referenceValue, resultValue))))
1204 {
1205 if (!tcu::isGatherOffsetsCompareResultValid(effectiveView, samplerParams.sampler, texComparePrecision, texCoord, glu::getDefaultGatherOffsets(), refZ, resultValue))
1206 {
1207 lowQuality = true;
1208
1209 // fall back to low quality verification
1210 if (!tcu::isGatherOffsetsCompareResultValid(effectiveView, samplerParams.sampler, lowQualityTexComparePrecision, texCoord, glu::getDefaultGatherOffsets(), refZ, resultValue))
1211 {
1212 errorMask.setPixel(px, py, tcu::RGBA::red());
1213 ++numFailedPixels;
1214 }
1215 }
1216 }
1217 }
1218
1219 if (numFailedPixels > 0)
1220 m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage;
1221 else if (lowQuality)
1222 {
1223 m_testCtx.getLog() << tcu::TestLog::Message << "Warning: Verification assuming high-quality PCF filtering failed." << tcu::TestLog::EndMessage;
1224 m_result.addResult(QP_TEST_RESULT_QUALITY_WARNING, "Low-quality result");
1225 }
1226
1227 m_testCtx.getLog() << tcu::TestLog::ImageSet("VerifyResult", "Verification result")
1228 << tcu::TestLog::Image("Rendered", "Rendered image", renderedFrame);
1229 if (numFailedPixels > 0)
1230 {
1231 m_testCtx.getLog() << tcu::TestLog::Image("Reference", "Ideal reference image", reference)
1232 << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask);
1233 }
1234 m_testCtx.getLog() << tcu::TestLog::EndImageSet;
1235
1236 return (numFailedPixels == 0);
1237 }
1238
getTexture(void) const1239 const glu::Texture2D* TextureBorderClampTest::getTexture (void) const
1240 {
1241 return m_texture.get();
1242 }
1243
getIterationSeed(const IterationConfig & config) const1244 deUint32 TextureBorderClampTest::getIterationSeed (const IterationConfig& config) const
1245 {
1246 tcu::SeedBuilder builder;
1247 builder << std::string(getName())
1248 << m_iterationNdx
1249 << m_texFormat
1250 << config.minFilter << config.magFilter
1251 << m_texture->getRefTexture().getWidth() << m_texture->getRefTexture().getHeight();
1252 return builder.get();
1253 }
1254
genSamplerParams(const IterationConfig & config) const1255 glu::TextureTestUtil::ReferenceParams TextureBorderClampTest::genSamplerParams (const IterationConfig& config) const
1256 {
1257 const tcu::TextureFormat texFormat = tcu::getEffectiveDepthStencilTextureFormat(m_texture->getRefTexture().getFormat(), m_sampleMode);
1258 glu::TextureTestUtil::ReferenceParams refParams (glu::TextureTestUtil::TEXTURETYPE_2D);
1259
1260 refParams.sampler = glu::mapGLSampler(config.sWrapMode, config.tWrapMode, config.minFilter, config.magFilter);
1261 refParams.sampler.borderColor = config.borderColor;
1262 refParams.sampler.compare = (!m_useShadowSampler) ? (tcu::Sampler::COMPAREMODE_NONE) : (glu::mapGLCompareFunc(config.compareMode));
1263 refParams.sampler.depthStencilMode = m_sampleMode;
1264 refParams.lodMode = glu::TextureTestUtil::LODMODE_EXACT;
1265 refParams.samplerType = (!m_useShadowSampler) ? (glu::TextureTestUtil::getSamplerType(texFormat)) : (glu::TextureTestUtil::SAMPLERTYPE_SHADOW);
1266 refParams.colorScale = config.lookupScale;
1267 refParams.colorBias = config.lookupBias;
1268 refParams.ref = config.compareRef;
1269
1270 // compare can only be used with depth textures
1271 if (!isDepthFormat(m_texFormat, m_sampleMode))
1272 DE_ASSERT(refParams.sampler.compare == tcu::Sampler::COMPAREMODE_NONE);
1273
1274 // sampler type must match compare mode
1275 DE_ASSERT(m_useShadowSampler == (config.compareMode != GL_NONE));
1276
1277 // in gather, weird mapping is most likely an error
1278 if (m_samplingFunction == SAMPLE_GATHER)
1279 {
1280 DE_ASSERT(refParams.colorScale == tcu::Vec4(refParams.colorScale.x()));
1281 DE_ASSERT(refParams.colorBias == tcu::Vec4(refParams.colorBias.x()));
1282 }
1283
1284 return refParams;
1285 }
1286
genGatherProgram(void) const1287 glu::ShaderProgram* TextureBorderClampTest::genGatherProgram (void) const
1288 {
1289 const std::string glslVersionDecl = glu::getGLSLVersionDeclaration(glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType()));
1290 const std::string vtxSource = glslVersionDecl + "\n"
1291 "in highp vec4 a_position;\n"
1292 "in highp vec2 a_texcoord;\n"
1293 "out highp vec2 v_texcoord;\n"
1294 "void main()\n"
1295 "{\n"
1296 " gl_Position = a_position;\n"
1297 " v_texcoord = a_texcoord;\n"
1298 "}\n";
1299 const char* samplerType;
1300 const char* lookup;
1301 std::ostringstream fragSource;
1302
1303 if (m_useShadowSampler)
1304 {
1305 samplerType = "sampler2DShadow";
1306 lookup = "textureGather(u_sampler, v_texcoord, u_ref)";
1307 }
1308 else
1309 {
1310 switch (m_channelClass)
1311 {
1312 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1313 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1314 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1315 samplerType = "sampler2D";
1316 lookup = "textureGather(u_sampler, v_texcoord)";
1317 break;
1318
1319 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1320 samplerType = "isampler2D";
1321 lookup = "vec4(textureGather(u_sampler, v_texcoord))";
1322 break;
1323
1324 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1325 samplerType = "usampler2D";
1326 lookup = "vec4(textureGather(u_sampler, v_texcoord))";
1327 break;
1328
1329 default:
1330 samplerType = "";
1331 lookup = "";
1332 DE_ASSERT(false);
1333 }
1334 }
1335
1336 fragSource << glslVersionDecl + "\n"
1337 "uniform highp " << samplerType << " u_sampler;\n"
1338 "uniform highp vec4 u_colorScale;\n"
1339 "uniform highp vec4 u_colorBias;\n"
1340 << ((m_useShadowSampler) ? ("uniform highp float u_ref;\n") : (""))
1341 << "in highp vec2 v_texcoord;\n"
1342 "layout(location=0) out highp vec4 o_color;\n"
1343 "void main()\n"
1344 "{\n"
1345 " o_color = " << lookup << " * u_colorScale + u_colorBias;\n"
1346 "}\n";
1347
1348 return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(vtxSource) << glu::FragmentSource(fragSource.str()));
1349 }
1350
1351 class TextureBorderClampFormatCase : public TextureBorderClampTest
1352 {
1353 public:
1354 TextureBorderClampFormatCase (Context& context,
1355 const char* name,
1356 const char* description,
1357 deUint32 texFormat,
1358 tcu::Sampler::DepthStencilMode mode,
1359 StateType stateType,
1360 SizeType sizeType,
1361 deUint32 filter,
1362 SamplingFunction samplingFunction);
1363
1364 private:
1365 void init (void);
1366
1367 int getNumIterations (void) const;
1368 IterationConfig getIteration (int ndx) const;
1369
1370 const SizeType m_sizeType;
1371 const deUint32 m_filter;
1372
1373 std::vector<IterationConfig> m_iterations;
1374 };
1375
1376
TextureBorderClampFormatCase(Context & context,const char * name,const char * description,deUint32 texFormat,tcu::Sampler::DepthStencilMode mode,StateType stateType,SizeType sizeType,deUint32 filter,SamplingFunction samplingFunction)1377 TextureBorderClampFormatCase::TextureBorderClampFormatCase (Context& context,
1378 const char* name,
1379 const char* description,
1380 deUint32 texFormat,
1381 tcu::Sampler::DepthStencilMode mode,
1382 StateType stateType,
1383 SizeType sizeType,
1384 deUint32 filter,
1385 SamplingFunction samplingFunction)
1386 : TextureBorderClampTest(context,
1387 name,
1388 description,
1389 texFormat,
1390 mode,
1391 stateType,
1392 (sizeType == SIZE_POT) ? (32) : (17),
1393 (sizeType == SIZE_POT) ? (16) : (31),
1394 samplingFunction)
1395 , m_sizeType (sizeType)
1396 , m_filter (filter)
1397 {
1398 if (m_sizeType == SIZE_POT)
1399 DE_ASSERT(deIsPowerOfTwo32(m_texWidth) && deIsPowerOfTwo32(m_texHeight));
1400 else
1401 DE_ASSERT(!deIsPowerOfTwo32(m_texWidth) && !deIsPowerOfTwo32(m_texHeight));
1402
1403 if (glu::isCompressedFormat(texFormat))
1404 {
1405 const tcu::CompressedTexFormat compressedFormat = glu::mapGLCompressedTexFormat(texFormat);
1406 const tcu::IVec3 blockPixelSize = tcu::getBlockPixelSize(compressedFormat);
1407
1408 // is (not) multiple of a block size
1409 if (m_sizeType == SIZE_POT)
1410 DE_ASSERT((m_texWidth % blockPixelSize.x()) == 0 && (m_texHeight % blockPixelSize.y()) == 0);
1411 else
1412 DE_ASSERT((m_texWidth % blockPixelSize.x()) != 0 && (m_texHeight % blockPixelSize.y()) != 0);
1413
1414 DE_UNREF(blockPixelSize);
1415 }
1416 }
1417
init(void)1418 void TextureBorderClampFormatCase::init (void)
1419 {
1420 TextureBorderClampTest::init();
1421
1422 // \note TextureBorderClampTest::init() creates texture
1423 const tcu::TextureFormat texFormat = tcu::getEffectiveDepthStencilTextureFormat(getTexture()->getRefTexture().getFormat(), m_sampleMode);
1424 const tcu::TextureFormatInfo texFormatInfo = tcu::getTextureFormatInfo(texFormat);
1425
1426 // iterations
1427
1428 {
1429 IterationConfig iteration;
1430 iteration.p0 = tcu::Vec2(-1.5f, -3.0f);
1431 iteration.p1 = tcu::Vec2( 1.5f, 2.5f);
1432 iteration.borderColor = mapToFormatColorRepresentable(texFormat, tcu::Vec4(0.3f, 0.7f, 0.2f, 0.5f));
1433 m_iterations.push_back(iteration);
1434 }
1435 {
1436 IterationConfig iteration;
1437 iteration.p0 = tcu::Vec2(-0.5f, 0.75f);
1438 iteration.p1 = tcu::Vec2(0.25f, 1.25f);
1439 iteration.borderColor = mapToFormatColorRepresentable(texFormat, tcu::Vec4(0.9f, 0.2f, 0.4f, 0.6f));
1440 m_iterations.push_back(iteration);
1441 }
1442
1443 // common parameters
1444 for (int ndx = 0; ndx < (int)m_iterations.size(); ++ndx)
1445 {
1446 IterationConfig& iteration = m_iterations[ndx];
1447
1448 if (m_samplingFunction == SAMPLE_GATHER)
1449 {
1450 iteration.lookupScale = tcu::Vec4(texFormatInfo.lookupScale.x());
1451 iteration.lookupBias = tcu::Vec4(texFormatInfo.lookupBias.x());
1452 }
1453 else
1454 {
1455 iteration.lookupScale = texFormatInfo.lookupScale;
1456 iteration.lookupBias = texFormatInfo.lookupBias;
1457 }
1458
1459 iteration.minFilter = m_filter;
1460 iteration.magFilter = m_filter;
1461 iteration.sWrapMode = GL_CLAMP_TO_BORDER;
1462 iteration.tWrapMode = GL_CLAMP_TO_BORDER;
1463 iteration.compareMode = GL_NONE;
1464 iteration.compareRef = 0.0f;
1465 }
1466 }
1467
getNumIterations(void) const1468 int TextureBorderClampFormatCase::getNumIterations (void) const
1469 {
1470 return (int)m_iterations.size();
1471 }
1472
getIteration(int ndx) const1473 TextureBorderClampTest::IterationConfig TextureBorderClampFormatCase::getIteration (int ndx) const
1474 {
1475 return m_iterations[ndx];
1476 }
1477
1478 class TextureBorderClampRangeClampCase : public TextureBorderClampTest
1479 {
1480 public:
1481 TextureBorderClampRangeClampCase (Context& context,
1482 const char* name,
1483 const char* description,
1484 deUint32 texFormat,
1485 tcu::Sampler::DepthStencilMode mode,
1486 deUint32 filter);
1487
1488 private:
1489 void init (void);
1490
1491 int getNumIterations (void) const;
1492 IterationConfig getIteration (int ndx) const;
1493
1494 const deUint32 m_filter;
1495 std::vector<IterationConfig> m_iterations;
1496 };
1497
TextureBorderClampRangeClampCase(Context & context,const char * name,const char * description,deUint32 texFormat,tcu::Sampler::DepthStencilMode mode,deUint32 filter)1498 TextureBorderClampRangeClampCase::TextureBorderClampRangeClampCase (Context& context,
1499 const char* name,
1500 const char* description,
1501 deUint32 texFormat,
1502 tcu::Sampler::DepthStencilMode mode,
1503 deUint32 filter)
1504 : TextureBorderClampTest(context, name, description, texFormat, mode, TextureBorderClampTest::STATE_TEXTURE_PARAM, 8, 32, SAMPLE_FILTER)
1505 , m_filter (filter)
1506 {
1507 }
1508
init(void)1509 void TextureBorderClampRangeClampCase::init (void)
1510 {
1511 TextureBorderClampTest::init();
1512
1513 const tcu::TextureFormat texFormat = tcu::getEffectiveDepthStencilTextureFormat(getTexture()->getRefTexture().getFormat(), m_sampleMode);
1514 const bool isDepth = isDepthFormat(m_texFormat, m_sampleMode);
1515 const bool isFloat = m_channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT;
1516 const bool isFixed = m_channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT || m_channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT;
1517 const bool isPureInteger = m_channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || m_channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
1518
1519 if (isDepth || isFloat)
1520 {
1521 // infinities are commonly used values on depth/float borders
1522 {
1523 IterationConfig iteration;
1524 iteration.p0 = tcu::Vec2(-1.2f, -3.0f);
1525 iteration.p1 = tcu::Vec2( 1.2f, 2.5f);
1526 iteration.borderColor = rr::GenericVec4(tcu::Vec4(std::numeric_limits<float>::infinity()));
1527 iteration.lookupScale = tcu::Vec4(0.5f); // scale & bias to [0.25, 0.5] range to make out-of-range values visible
1528 iteration.lookupBias = tcu::Vec4(0.25f);
1529 iteration.description = "border value infinity";
1530 m_iterations.push_back(iteration);
1531 }
1532 {
1533 IterationConfig iteration;
1534 iteration.p0 = tcu::Vec2(-0.25f, -0.75f);
1535 iteration.p1 = tcu::Vec2( 2.25f, 1.25f);
1536 iteration.borderColor = rr::GenericVec4(tcu::Vec4(-std::numeric_limits<float>::infinity()));
1537 iteration.lookupScale = tcu::Vec4(0.5f);
1538 iteration.lookupBias = tcu::Vec4(0.25f);
1539 iteration.description = "border value negative infinity";
1540 m_iterations.push_back(iteration);
1541 }
1542 }
1543 else if (isPureInteger)
1544 {
1545 const tcu::IVec4 numBits = tcu::getTextureFormatBitDepth(texFormat);
1546 const bool isSigned = m_channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER;
1547
1548 // can't overflow 32bit integers with 32bit integers
1549 for (int ndx = 0; ndx < 4; ++ndx)
1550 DE_ASSERT(numBits[ndx] == 0 || numBits[ndx] == 8 || numBits[ndx] == 16);
1551
1552 const tcu::IVec4 minValue = getNBitIntegerVec4MinValue(isSigned, numBits);
1553 const tcu::IVec4 maxValue = getNBitIntegerVec4MaxValue(isSigned, numBits);
1554 const tcu::IVec4 valueRange = maxValue - minValue;
1555 const tcu::IVec4 divSafeRange ((valueRange[0]==0) ? (1) : (valueRange[0]),
1556 (valueRange[1]==0) ? (1) : (valueRange[1]),
1557 (valueRange[2]==0) ? (1) : (valueRange[2]),
1558 (valueRange[3]==0) ? (1) : (valueRange[3]));
1559
1560 // format max
1561 {
1562 const tcu::IVec4 value = maxValue + tcu::IVec4(1);
1563
1564 IterationConfig iteration;
1565 iteration.p0 = tcu::Vec2(-1.2f, -3.0f);
1566 iteration.p1 = tcu::Vec2( 1.2f, 2.5f);
1567 iteration.borderColor = (isSigned) ? (rr::GenericVec4(value)) : (rr::GenericVec4(value.cast<deUint32>()));
1568 iteration.lookupScale = tcu::Vec4(0.5f) / divSafeRange.cast<float>();
1569 iteration.lookupBias = (isSigned) ? (tcu::Vec4(0.5f)) : (tcu::Vec4(0.25f));
1570 iteration.description = "border values one larger than maximum";
1571 m_iterations.push_back(iteration);
1572 }
1573 // format min
1574 if (isSigned)
1575 {
1576 const tcu::IVec4 value = minValue - tcu::IVec4(1);
1577
1578 IterationConfig iteration;
1579 iteration.p0 = tcu::Vec2(-0.25f, -0.75f);
1580 iteration.p1 = tcu::Vec2( 2.25f, 1.25f);
1581 iteration.borderColor = rr::GenericVec4(value);
1582 iteration.lookupScale = tcu::Vec4(0.5f) / divSafeRange.cast<float>();
1583 iteration.lookupBias = tcu::Vec4(0.5f);
1584 iteration.description = "border values one less than minimum";
1585 m_iterations.push_back(iteration);
1586 }
1587 // (u)int32 max
1588 {
1589 const tcu::IVec4 value = (isSigned) ? (tcu::IVec4(std::numeric_limits<deInt32>::max())) : (tcu::IVec4(std::numeric_limits<deUint32>::max()));
1590
1591 IterationConfig iteration;
1592 iteration.p0 = tcu::Vec2(-1.6f, -2.1f);
1593 iteration.p1 = tcu::Vec2( 1.2f, 3.5f);
1594 iteration.borderColor = (isSigned) ? (rr::GenericVec4(value)) : (rr::GenericVec4(value.cast<deUint32>()));
1595 iteration.lookupScale = tcu::Vec4(0.5f) / divSafeRange.cast<float>();
1596 iteration.lookupBias = tcu::Vec4(0.25f);
1597 iteration.description = "border values 32-bit maximum";
1598 m_iterations.push_back(iteration);
1599 }
1600 // int32 min
1601 if (isSigned)
1602 {
1603 const tcu::IVec4 value = tcu::IVec4(std::numeric_limits<deInt32>::min());
1604
1605 IterationConfig iteration;
1606 iteration.p0 = tcu::Vec2(-2.6f, -4.0f);
1607 iteration.p1 = tcu::Vec2( 1.1f, 1.5f);
1608 iteration.borderColor = rr::GenericVec4(value);
1609 iteration.lookupScale = tcu::Vec4(0.5f) / divSafeRange.cast<float>();
1610 iteration.lookupBias = tcu::Vec4(0.25f);
1611 iteration.description = "border values 0";
1612 m_iterations.push_back(iteration);
1613 }
1614 }
1615 else if (isFixed)
1616 {
1617 const bool isSigned = m_channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT;
1618 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
1619 const tcu::Vec4 lookupScale = (isSigned) ? (tcu::Vec4(0.25f)) : (tcu::Vec4(0.5f));
1620
1621 {
1622 IterationConfig iteration;
1623 iteration.p0 = tcu::Vec2(-1.2f, -3.0f);
1624 iteration.p1 = tcu::Vec2( 1.2f, 2.5f);
1625 iteration.borderColor = mapToFormatColorUnits(texFormat, tcu::Vec4(1.1f, 1.3f, 2.2f, 1.3f));
1626 iteration.lookupScale = lookupScale;
1627 iteration.lookupBias = lookupBias;
1628 iteration.description = "border values larger than maximum";
1629 m_iterations.push_back(iteration);
1630 }
1631 {
1632 IterationConfig iteration;
1633 iteration.p0 = tcu::Vec2(-0.25f, -0.75f);
1634 iteration.p1 = tcu::Vec2( 2.25f, 1.25f);
1635 iteration.borderColor = mapToFormatColorUnits(texFormat, tcu::Vec4(-0.2f, -0.9f, -2.4f, -0.6f));
1636 iteration.lookupScale = lookupScale;
1637 iteration.lookupBias = lookupBias;
1638 iteration.description = "border values less than minimum";
1639 m_iterations.push_back(iteration);
1640 }
1641 }
1642 else
1643 DE_ASSERT(false);
1644
1645 // common parameters
1646 for (int ndx = 0; ndx < (int)m_iterations.size(); ++ndx)
1647 {
1648 IterationConfig& iteration = m_iterations[ndx];
1649
1650 iteration.minFilter = m_filter;
1651 iteration.magFilter = m_filter;
1652 iteration.sWrapMode = GL_CLAMP_TO_BORDER;
1653 iteration.tWrapMode = GL_CLAMP_TO_BORDER;
1654 iteration.compareMode = GL_NONE;
1655 iteration.compareRef = 0.0f;
1656 }
1657 }
1658
getNumIterations(void) const1659 int TextureBorderClampRangeClampCase::getNumIterations (void) const
1660 {
1661 return (int)m_iterations.size();
1662 }
1663
getIteration(int ndx) const1664 TextureBorderClampTest::IterationConfig TextureBorderClampRangeClampCase::getIteration (int ndx) const
1665 {
1666 return m_iterations[ndx];
1667 }
1668
1669 class TextureBorderClampPerAxisCase2D : public TextureBorderClampTest
1670 {
1671 public:
1672 TextureBorderClampPerAxisCase2D (Context& context,
1673 const char* name,
1674 const char* description,
1675 deUint32 texFormat,
1676 tcu::Sampler::DepthStencilMode mode,
1677 SizeType sizeType,
1678 deUint32 filter,
1679 deUint32 texSWrap,
1680 deUint32 texTWrap,
1681 SamplingFunction samplingFunction);
1682
1683 private:
1684 void init (void);
1685
1686 int getNumIterations (void) const;
1687 IterationConfig getIteration (int ndx) const;
1688
1689 const deUint32 m_texSWrap;
1690 const deUint32 m_texTWrap;
1691 const deUint32 m_filter;
1692
1693 std::vector<IterationConfig> m_iterations;
1694 };
1695
TextureBorderClampPerAxisCase2D(Context & context,const char * name,const char * description,deUint32 texFormat,tcu::Sampler::DepthStencilMode mode,SizeType sizeType,deUint32 filter,deUint32 texSWrap,deUint32 texTWrap,SamplingFunction samplingFunction)1696 TextureBorderClampPerAxisCase2D::TextureBorderClampPerAxisCase2D (Context& context,
1697 const char* name,
1698 const char* description,
1699 deUint32 texFormat,
1700 tcu::Sampler::DepthStencilMode mode,
1701 SizeType sizeType,
1702 deUint32 filter,
1703 deUint32 texSWrap,
1704 deUint32 texTWrap,
1705 SamplingFunction samplingFunction)
1706 : TextureBorderClampTest(context,
1707 name,
1708 description,
1709 texFormat,
1710 mode,
1711 TextureBorderClampTest::STATE_TEXTURE_PARAM,
1712 (sizeType == SIZE_POT) ? (16) : (7),
1713 (sizeType == SIZE_POT) ? (8) : (9),
1714 samplingFunction)
1715 , m_texSWrap (texSWrap)
1716 , m_texTWrap (texTWrap)
1717 , m_filter (filter)
1718 {
1719 }
1720
init(void)1721 void TextureBorderClampPerAxisCase2D::init (void)
1722 {
1723 TextureBorderClampTest::init();
1724
1725 // \note TextureBorderClampTest::init() creates texture
1726 const tcu::TextureFormat texFormat = tcu::getEffectiveDepthStencilTextureFormat(getTexture()->getRefTexture().getFormat(), m_sampleMode);
1727 const tcu::TextureFormatInfo texFormatInfo = tcu::getTextureFormatInfo(texFormat);
1728
1729 IterationConfig iteration;
1730 iteration.p0 = tcu::Vec2(-0.25f, -0.75f);
1731 iteration.p1 = tcu::Vec2( 2.25f, 1.25f);
1732 iteration.borderColor = mapToFormatColorRepresentable(texFormat, tcu::Vec4(0.4f, 0.9f, 0.1f, 0.2f));
1733
1734 if (m_samplingFunction == SAMPLE_GATHER)
1735 {
1736 iteration.lookupScale = tcu::Vec4(texFormatInfo.lookupScale.x());
1737 iteration.lookupBias = tcu::Vec4(texFormatInfo.lookupBias.x());
1738 }
1739 else
1740 {
1741 iteration.lookupScale = texFormatInfo.lookupScale;
1742 iteration.lookupBias = texFormatInfo.lookupBias;
1743 }
1744
1745 iteration.minFilter = m_filter;
1746 iteration.magFilter = m_filter;
1747 iteration.sWrapMode = m_texSWrap;
1748 iteration.tWrapMode = m_texTWrap;
1749 iteration.compareMode = GL_NONE;
1750 iteration.compareRef = 0.0f;
1751
1752 m_iterations.push_back(iteration);
1753 }
1754
getNumIterations(void) const1755 int TextureBorderClampPerAxisCase2D::getNumIterations (void) const
1756 {
1757 return (int)m_iterations.size();
1758 }
1759
getIteration(int ndx) const1760 TextureBorderClampTest::IterationConfig TextureBorderClampPerAxisCase2D::getIteration (int ndx) const
1761 {
1762 return m_iterations[ndx];
1763 }
1764
1765 class TextureBorderClampDepthCompareCase : public TextureBorderClampTest
1766 {
1767 public:
1768 TextureBorderClampDepthCompareCase (Context& context,
1769 const char* name,
1770 const char* description,
1771 deUint32 texFormat,
1772 SizeType sizeType,
1773 deUint32 filter,
1774 SamplingFunction samplingFunction);
1775
1776 private:
1777 void init (void);
1778
1779 int getNumIterations (void) const;
1780 IterationConfig getIteration (int ndx) const;
1781
1782 const deUint32 m_filter;
1783 std::vector<IterationConfig> m_iterations;
1784 };
1785
TextureBorderClampDepthCompareCase(Context & context,const char * name,const char * description,deUint32 texFormat,SizeType sizeType,deUint32 filter,SamplingFunction samplingFunction)1786 TextureBorderClampDepthCompareCase::TextureBorderClampDepthCompareCase (Context& context,
1787 const char* name,
1788 const char* description,
1789 deUint32 texFormat,
1790 SizeType sizeType,
1791 deUint32 filter,
1792 SamplingFunction samplingFunction)
1793 : TextureBorderClampTest(context,
1794 name,
1795 description,
1796 texFormat,
1797 tcu::Sampler::MODE_DEPTH,
1798 TextureBorderClampTest::STATE_TEXTURE_PARAM,
1799 (sizeType == SIZE_POT) ? (32) : (13),
1800 (sizeType == SIZE_POT) ? (16) : (17),
1801 samplingFunction,
1802 FLAG_USE_SHADOW_SAMPLER)
1803 , m_filter (filter)
1804 {
1805 }
1806
init(void)1807 void TextureBorderClampDepthCompareCase::init (void)
1808 {
1809 TextureBorderClampTest::init();
1810
1811 // 0.5 <= 0.7
1812 {
1813 IterationConfig iteration;
1814 iteration.p0 = tcu::Vec2(-0.15f, -0.35f);
1815 iteration.p1 = tcu::Vec2( 1.25f, 1.1f);
1816 iteration.borderColor = rr::GenericVec4(tcu::Vec4(0.7f, 0.0f, 0.0f, 0.0f));
1817 iteration.description = "Border color in [0, 1] range";
1818 iteration.compareMode = GL_LEQUAL;
1819 iteration.compareRef = 0.5f;
1820 m_iterations.push_back(iteration);
1821 }
1822
1823 // 1.5 <= 1.0
1824 {
1825 IterationConfig iteration;
1826 iteration.p0 = tcu::Vec2(-0.15f, -0.35f);
1827 iteration.p1 = tcu::Vec2( 1.25f, 1.1f);
1828 iteration.borderColor = rr::GenericVec4(tcu::Vec4(1.5f, 0.0f, 0.0f, 0.0f));
1829 iteration.description = "Border color > 1, should be clamped";
1830 iteration.compareMode = GL_LEQUAL;
1831 iteration.compareRef = 1.0f;
1832 m_iterations.push_back(iteration);
1833 }
1834
1835 // -0.5 >= 0.0
1836 {
1837 IterationConfig iteration;
1838 iteration.p0 = tcu::Vec2(-0.15f, -0.35f);
1839 iteration.p1 = tcu::Vec2( 1.25f, 1.1f);
1840 iteration.borderColor = rr::GenericVec4(tcu::Vec4(-0.5f, 0.0f, 0.0f, 0.0f));
1841 iteration.description = "Border color < 0, should be clamped";
1842 iteration.compareMode = GL_GEQUAL;
1843 iteration.compareRef = 0.0f;
1844 m_iterations.push_back(iteration);
1845 }
1846
1847 // inf < 1.25
1848 {
1849 IterationConfig iteration;
1850 iteration.p0 = tcu::Vec2(-0.15f, -0.35f);
1851 iteration.p1 = tcu::Vec2( 1.25f, 1.1f);
1852 iteration.borderColor = rr::GenericVec4(tcu::Vec4(std::numeric_limits<float>::infinity(), 0.0f, 0.0f, 0.0f));
1853 iteration.description = "Border color == inf, should be clamped; ref > 1";
1854 iteration.compareMode = GL_LESS;
1855 iteration.compareRef = 1.25f;
1856 m_iterations.push_back(iteration);
1857 }
1858
1859 // -inf > -0.5
1860 {
1861 IterationConfig iteration;
1862 iteration.p0 = tcu::Vec2(-0.15f, -0.35f);
1863 iteration.p1 = tcu::Vec2( 1.25f, 1.1f);
1864 iteration.borderColor = rr::GenericVec4(tcu::Vec4(-std::numeric_limits<float>::infinity(), 0.0f, 0.0f, 0.0f));
1865 iteration.description = "Border color == inf, should be clamped; ref < 0";
1866 iteration.compareMode = GL_GREATER;
1867 iteration.compareRef = -0.5f;
1868 m_iterations.push_back(iteration);
1869 }
1870
1871 // common parameters
1872 for (int ndx = 0; ndx < (int)m_iterations.size(); ++ndx)
1873 {
1874 IterationConfig& iteration = m_iterations[ndx];
1875
1876 iteration.lookupScale = tcu::Vec4(1.0);
1877 iteration.lookupBias = tcu::Vec4(0.0);
1878 iteration.minFilter = m_filter;
1879 iteration.magFilter = m_filter;
1880 iteration.sWrapMode = GL_CLAMP_TO_BORDER;
1881 iteration.tWrapMode = GL_CLAMP_TO_BORDER;
1882 }
1883 }
1884
getNumIterations(void) const1885 int TextureBorderClampDepthCompareCase::getNumIterations (void) const
1886 {
1887 return (int)m_iterations.size();
1888 }
1889
getIteration(int ndx) const1890 TextureBorderClampTest::IterationConfig TextureBorderClampDepthCompareCase::getIteration (int ndx) const
1891 {
1892 return m_iterations[ndx];
1893 }
1894
1895 class TextureBorderClampUnusedChannelCase : public TextureBorderClampTest
1896 {
1897 public:
1898 TextureBorderClampUnusedChannelCase (Context& context,
1899 const char* name,
1900 const char* description,
1901 deUint32 texFormat,
1902 tcu::Sampler::DepthStencilMode depthStencilMode);
1903
1904 private:
1905 void init (void);
1906
1907 int getNumIterations (void) const;
1908 IterationConfig getIteration (int ndx) const;
1909
1910 std::vector<IterationConfig> m_iterations;
1911 };
1912
TextureBorderClampUnusedChannelCase(Context & context,const char * name,const char * description,deUint32 texFormat,tcu::Sampler::DepthStencilMode depthStencilMode)1913 TextureBorderClampUnusedChannelCase::TextureBorderClampUnusedChannelCase (Context& context,
1914 const char* name,
1915 const char* description,
1916 deUint32 texFormat,
1917 tcu::Sampler::DepthStencilMode depthStencilMode)
1918 : TextureBorderClampTest(context,
1919 name,
1920 description,
1921 texFormat,
1922 depthStencilMode,
1923 TextureBorderClampTest::STATE_TEXTURE_PARAM,
1924 8,
1925 8,
1926 SAMPLE_FILTER)
1927 {
1928 }
1929
selectComponents(const rr::GenericVec4 & trueComponents,const rr::GenericVec4 & falseComponents,const tcu::BVec4 & m)1930 static rr::GenericVec4 selectComponents (const rr::GenericVec4& trueComponents, const rr::GenericVec4& falseComponents, const tcu::BVec4& m)
1931 {
1932 return rr::GenericVec4(tcu::select(trueComponents.get<deUint32>(), falseComponents.get<deUint32>(), m));
1933 }
1934
init(void)1935 void TextureBorderClampUnusedChannelCase::init (void)
1936 {
1937 TextureBorderClampTest::init();
1938
1939 // \note TextureBorderClampTest::init() creates texture
1940 const tcu::TextureFormat texFormat = tcu::getEffectiveDepthStencilTextureFormat(getTexture()->getRefTexture().getFormat(), m_sampleMode);
1941 const tcu::TextureFormatInfo texFormatInfo = tcu::getTextureFormatInfo(texFormat);
1942 const tcu::BVec4 channelMask = tcu::getTextureFormatChannelMask(texFormat);
1943 const float maxChannelValue = (channelMask[0]) ? (texFormatInfo.valueMax[0])
1944 : (channelMask[1]) ? (texFormatInfo.valueMax[1])
1945 : (channelMask[2]) ? (texFormatInfo.valueMax[2])
1946 : (texFormatInfo.valueMax[3]);
1947
1948 const rr::GenericVec4 effectiveColors = mapToFormatColorRepresentable(texFormat, tcu::Vec4(0.6f));
1949 rr::GenericVec4 nonEffectiveColors;
1950
1951 switch (m_channelClass)
1952 {
1953 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1954 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1955 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1956 nonEffectiveColors = rr::GenericVec4(tcu::Vec4(maxChannelValue * 0.8f));
1957 break;
1958
1959 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1960 nonEffectiveColors = rr::GenericVec4(tcu::Vec4(maxChannelValue * 0.8f).cast<deInt32>());
1961 break;
1962
1963 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1964 nonEffectiveColors = rr::GenericVec4(tcu::Vec4(maxChannelValue * 0.8f).cast<deUint32>());
1965 break;
1966 default:
1967 DE_ASSERT(false);
1968 }
1969
1970 IterationConfig iteration;
1971 iteration.p0 = tcu::Vec2(-0.25f, -0.75f);
1972 iteration.p1 = tcu::Vec2( 2.25f, 1.25f);
1973 iteration.borderColor = selectComponents(effectiveColors, nonEffectiveColors, channelMask);
1974 iteration.lookupScale = texFormatInfo.lookupScale;
1975 iteration.lookupBias = texFormatInfo.lookupBias;
1976 iteration.minFilter = GL_NEAREST;
1977 iteration.magFilter = GL_NEAREST;
1978 iteration.sWrapMode = GL_CLAMP_TO_BORDER;
1979 iteration.tWrapMode = GL_CLAMP_TO_BORDER;
1980 iteration.compareMode = GL_NONE;
1981 iteration.compareRef = 0.0f;
1982 iteration.description = "Setting values to unused border color components";
1983
1984 m_iterations.push_back(iteration);
1985 }
1986
getNumIterations(void) const1987 int TextureBorderClampUnusedChannelCase::getNumIterations (void) const
1988 {
1989 return (int)m_iterations.size();
1990 }
1991
getIteration(int ndx) const1992 TextureBorderClampTest::IterationConfig TextureBorderClampUnusedChannelCase::getIteration (int ndx) const
1993 {
1994 return m_iterations[ndx];
1995 }
1996
1997 class TextureBorderClampPerAxisCase3D : public TestCase
1998 {
1999 public:
2000 TextureBorderClampPerAxisCase3D (Context& context,
2001 const char* name,
2002 const char* description,
2003 deUint32 texFormat,
2004 SizeType size,
2005 deUint32 filter,
2006 deUint32 sWrap,
2007 deUint32 tWrap,
2008 deUint32 rWrap);
2009
2010 private:
2011 void init (void);
2012 void deinit (void);
2013 IterateResult iterate (void);
2014
2015 void renderTo (tcu::Surface& surface,
2016 const glu::TextureTestUtil::ReferenceParams& samplerParams);
2017
2018 void logParams (const glu::TextureTestUtil::ReferenceParams& samplerParams);
2019
2020 void verifyImage (const tcu::Surface& image,
2021 const glu::TextureTestUtil::ReferenceParams& samplerParams);
2022
2023 glu::TextureTestUtil::ReferenceParams getSamplerParams (void) const;
2024 deUint32 getCaseSeed (void) const;
2025
2026 enum
2027 {
2028 VIEWPORT_WIDTH = 128,
2029 VIEWPORT_HEIGHT = 128,
2030 };
2031
2032 const deUint32 m_texFormat;
2033 const tcu::TextureChannelClass m_channelClass;
2034 const tcu::IVec3 m_size;
2035 const deUint32 m_filter;
2036 const deUint32 m_sWrap;
2037 const deUint32 m_tWrap;
2038 const deUint32 m_rWrap;
2039
2040 de::MovePtr<glu::Texture3D> m_texture;
2041 de::MovePtr<gls::TextureTestUtil::TextureRenderer> m_renderer;
2042
2043 rr::GenericVec4 m_borderColor;
2044 std::vector<float> m_texCoords;
2045 tcu::Vec4 m_lookupScale;
2046 tcu::Vec4 m_lookupBias;
2047 };
2048
TextureBorderClampPerAxisCase3D(Context & context,const char * name,const char * description,deUint32 texFormat,SizeType size,deUint32 filter,deUint32 sWrap,deUint32 tWrap,deUint32 rWrap)2049 TextureBorderClampPerAxisCase3D::TextureBorderClampPerAxisCase3D (Context& context,
2050 const char* name,
2051 const char* description,
2052 deUint32 texFormat,
2053 SizeType size,
2054 deUint32 filter,
2055 deUint32 sWrap,
2056 deUint32 tWrap,
2057 deUint32 rWrap)
2058 : TestCase (context, name, description)
2059 , m_texFormat (texFormat)
2060 , m_channelClass (getFormatChannelClass(texFormat, tcu::Sampler::MODE_LAST))
2061 , m_size ((size == SIZE_POT) ? (tcu::IVec3(8, 16, 4)) : (tcu::IVec3(13, 5, 7)))
2062 , m_filter (filter)
2063 , m_sWrap (sWrap)
2064 , m_tWrap (tWrap)
2065 , m_rWrap (rWrap)
2066 {
2067 }
2068
init(void)2069 void TextureBorderClampPerAxisCase3D::init (void)
2070 {
2071 auto ctxType = m_context.getRenderContext().getType();
2072 const bool isES32orGL45 = glu::contextSupports(ctxType, glu::ApiType::es(3, 2)) ||
2073 glu::contextSupports(ctxType, glu::ApiType::core(4, 5));
2074 const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(ctxType);
2075
2076 if (!isES32orGL45 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_border_clamp"))
2077 throw tcu::NotSupportedError("Test requires GL_EXT_texture_border_clamp extension");
2078
2079 if (glu::isCompressedFormat(m_texFormat) &&
2080 !isES32orGL45 &&
2081 tcu::isAstcFormat(glu::mapGLCompressedTexFormat(m_texFormat)) &&
2082 !m_context.getContextInfo().isExtensionSupported("GL_KHR_texture_compression_astc_ldr"))
2083 {
2084 throw tcu::NotSupportedError("Test requires GL_KHR_texture_compression_astc_ldr extension");
2085 }
2086 if (m_texFormat == GL_BGRA && !m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_format_BGRA8888"))
2087 throw tcu::NotSupportedError("Test requires GL_EXT_texture_format_BGRA8888 extension");
2088 if (m_context.getRenderTarget().getWidth() < VIEWPORT_WIDTH ||
2089 m_context.getRenderTarget().getHeight() < VIEWPORT_HEIGHT)
2090 {
2091 throw tcu::NotSupportedError("Test requires " + de::toString<int>(VIEWPORT_WIDTH) + "x" + de::toString<int>(VIEWPORT_HEIGHT) + " viewport");
2092 }
2093
2094 // resources
2095 m_texture = genDefaultTexture<glu::Texture3D>(m_context.getRenderContext(), m_context.getContextInfo(), m_texFormat, m_size);
2096 m_renderer = de::MovePtr<gls::TextureTestUtil::TextureRenderer>(new gls::TextureTestUtil::TextureRenderer(m_context.getRenderContext(), m_testCtx.getLog(), glslVersion, glu::PRECISION_HIGHP));
2097
2098 // texture info
2099 m_testCtx.getLog() << tcu::TestLog::Message
2100 << "Created 3D texture with format " << glu::getTextureFormatName(m_texFormat)
2101 << ", size (" << m_texture->getRefTexture().getWidth() << ", " << m_texture->getRefTexture().getHeight() << ", " << m_texture->getRefTexture().getDepth() << ")\n"
2102 << tcu::TestLog::EndMessage;
2103
2104 // tex coord
2105 {
2106 m_testCtx.getLog() << tcu::TestLog::Message
2107 << "Setting tex coords bottom-left: (-1, -1, -1.5), top-right (2, 2, 2.5)\n"
2108 << tcu::TestLog::EndMessage;
2109
2110 m_texCoords.resize(4*3);
2111
2112 m_texCoords[0] = -1.0f; m_texCoords[ 1] = -1.0f; m_texCoords[ 2] = -1.5f;
2113 m_texCoords[3] = -1.0f; m_texCoords[ 4] = 2.0f; m_texCoords[ 5] = 0.5f;
2114 m_texCoords[6] = 2.0f; m_texCoords[ 7] = -1.0f; m_texCoords[ 8] = 0.5f;
2115 m_texCoords[9] = 2.0f; m_texCoords[10] = 2.0f; m_texCoords[11] = 2.5f;
2116 }
2117
2118 // set render params
2119 {
2120 const tcu::TextureFormat texFormat = m_texture->getRefTexture().getFormat();
2121 const tcu::TextureFormatInfo texFormatInfo = tcu::getTextureFormatInfo(texFormat);
2122
2123 m_borderColor = mapToFormatColorRepresentable(texFormat, tcu::Vec4(0.2f, 0.6f, 0.9f, 0.4f));
2124
2125 m_lookupScale = texFormatInfo.lookupScale;
2126 m_lookupBias = texFormatInfo.lookupBias;
2127 }
2128 }
2129
deinit(void)2130 void TextureBorderClampPerAxisCase3D::deinit (void)
2131 {
2132 m_texture.clear();
2133 m_renderer.clear();
2134 }
2135
iterate(void)2136 TextureBorderClampPerAxisCase3D::IterateResult TextureBorderClampPerAxisCase3D::iterate (void)
2137 {
2138 tcu::Surface renderedFrame (VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
2139 const glu::TextureTestUtil::ReferenceParams samplerParams = getSamplerParams();
2140
2141 logParams(samplerParams);
2142 renderTo(renderedFrame, samplerParams);
2143 verifyImage(renderedFrame, samplerParams);
2144
2145 return STOP;
2146 }
2147
logParams(const glu::TextureTestUtil::ReferenceParams & samplerParams)2148 void TextureBorderClampPerAxisCase3D::logParams (const glu::TextureTestUtil::ReferenceParams& samplerParams)
2149 {
2150 const std::string borderColorString = (m_channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER) ? (de::toString(m_borderColor.get<deInt32>()))
2151 : (m_channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER) ? (de::toString(m_borderColor.get<deUint32>()))
2152 : (de::toString(m_borderColor.get<float>()));
2153
2154 m_testCtx.getLog() << tcu::TestLog::Message
2155 << "Border color is " << borderColorString << "\n"
2156 << "Texture lookup bias: " << samplerParams.colorBias << "\n"
2157 << "Texture lookup scale: " << samplerParams.colorScale << "\n"
2158 << "Filter: " << glu::getTextureFilterName(m_filter) << "\n"
2159 << "Wrap mode: s = " << glu::getRepeatModeStr(m_sWrap)
2160 << ", t = " << glu::getRepeatModeStr(m_tWrap)
2161 << ", r = " << glu::getRepeatModeStr(m_rWrap) << "\n"
2162 << tcu::TestLog::EndMessage;
2163 }
2164
renderTo(tcu::Surface & surface,const glu::TextureTestUtil::ReferenceParams & samplerParams)2165 void TextureBorderClampPerAxisCase3D::renderTo (tcu::Surface& surface,
2166 const glu::TextureTestUtil::ReferenceParams& samplerParams)
2167 {
2168 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2169 const gls::TextureTestUtil::RandomViewport viewport (m_context.getRenderTarget(), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, getCaseSeed());
2170
2171 // Bind to unit 0.
2172 gl.activeTexture(GL_TEXTURE0);
2173 gl.bindTexture(GL_TEXTURE_3D, m_texture->getGLTexture());
2174
2175 // Setup filtering and wrap modes.
2176 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, glu::getGLWrapMode(samplerParams.sampler.wrapS));
2177 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, glu::getGLWrapMode(samplerParams.sampler.wrapT));
2178 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, glu::getGLWrapMode(samplerParams.sampler.wrapR));
2179 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, glu::getGLFilterMode(samplerParams.sampler.minFilter));
2180 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, glu::getGLFilterMode(samplerParams.sampler.magFilter));
2181
2182 switch (m_channelClass)
2183 {
2184 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
2185 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
2186 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
2187 gl.texParameterfv(GL_TEXTURE_3D, GL_TEXTURE_BORDER_COLOR, m_borderColor.getAccess<float>());
2188 break;
2189
2190 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
2191 gl.texParameterIiv(GL_TEXTURE_3D, GL_TEXTURE_BORDER_COLOR, m_borderColor.getAccess<deInt32>());
2192 break;
2193
2194 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
2195 gl.texParameterIuiv(GL_TEXTURE_3D, GL_TEXTURE_BORDER_COLOR, m_borderColor.getAccess<deUint32>());
2196 break;
2197
2198 default:
2199 DE_ASSERT(false);
2200 }
2201
2202 GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");
2203
2204 gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
2205 m_renderer->renderQuad(0, &m_texCoords[0], samplerParams);
2206 glu::readPixels(m_context.getRenderContext(), viewport.x, viewport.y, surface.getAccess());
2207 }
2208
verifyImage(const tcu::Surface & renderedFrame,const glu::TextureTestUtil::ReferenceParams & samplerParams)2209 void TextureBorderClampPerAxisCase3D::verifyImage (const tcu::Surface& renderedFrame,
2210 const glu::TextureTestUtil::ReferenceParams& samplerParams)
2211 {
2212 const tcu::PixelFormat pixelFormat = m_context.getRenderTarget().getPixelFormat();
2213 const int colorErrorBits = 2;
2214 const tcu::IVec4 colorBits = tcu::max(glu::TextureTestUtil::getBitsVec(pixelFormat) - tcu::IVec4(colorErrorBits), tcu::IVec4(0));
2215 tcu::Surface reference (renderedFrame.getWidth(), renderedFrame.getHeight());
2216 tcu::Surface errorMask (renderedFrame.getWidth(), renderedFrame.getHeight());
2217 tcu::LodPrecision lodPrecision;
2218 tcu::LookupPrecision lookupPrecision;
2219 int numFailedPixels;
2220
2221 lodPrecision.derivateBits = 18;
2222 lodPrecision.lodBits = 5;
2223
2224 lookupPrecision.colorThreshold = tcu::computeFixedPointThreshold(colorBits) / samplerParams.colorScale;
2225 lookupPrecision.coordBits = tcu::IVec3(20,20,0);
2226 lookupPrecision.uvwBits = tcu::IVec3(5,5,0);
2227 lookupPrecision.colorMask = glu::TextureTestUtil::getCompareMask(pixelFormat);
2228
2229 glu::TextureTestUtil::sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), m_texture->getRefTexture(), &m_texCoords[0], samplerParams);
2230
2231 numFailedPixels = glu::TextureTestUtil::computeTextureLookupDiff(renderedFrame.getAccess(), reference.getAccess(), errorMask.getAccess(), m_texture->getRefTexture(),
2232 &m_texCoords[0], samplerParams, lookupPrecision, lodPrecision, m_testCtx.getWatchDog());
2233
2234 if (numFailedPixels > 0)
2235 m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage;
2236 m_testCtx.getLog() << tcu::TestLog::ImageSet("VerifyResult", "Verification result")
2237 << tcu::TestLog::Image("Rendered", "Rendered image", renderedFrame);
2238 if (numFailedPixels > 0)
2239 {
2240 m_testCtx.getLog() << tcu::TestLog::Image("Reference", "Ideal reference image", reference)
2241 << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask);
2242 }
2243 m_testCtx.getLog() << tcu::TestLog::EndImageSet;
2244
2245 if (numFailedPixels == 0)
2246 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2247 else
2248 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
2249 }
2250
getSamplerParams(void) const2251 glu::TextureTestUtil::ReferenceParams TextureBorderClampPerAxisCase3D::getSamplerParams (void) const
2252 {
2253 const tcu::TextureFormat texFormat = m_texture->getRefTexture().getFormat();
2254 glu::TextureTestUtil::ReferenceParams refParams (glu::TextureTestUtil::TEXTURETYPE_3D);
2255
2256 refParams.sampler = glu::mapGLSampler(m_sWrap, m_tWrap, m_rWrap, m_filter, m_filter);
2257 refParams.sampler.borderColor = m_borderColor;
2258 refParams.lodMode = glu::TextureTestUtil::LODMODE_EXACT;
2259 refParams.samplerType = glu::TextureTestUtil::getSamplerType(texFormat);
2260 refParams.colorScale = m_lookupScale;
2261 refParams.colorBias = m_lookupBias;
2262
2263 return refParams;
2264 }
2265
getCaseSeed(void) const2266 deUint32 TextureBorderClampPerAxisCase3D::getCaseSeed (void) const
2267 {
2268 tcu::SeedBuilder builder;
2269 builder << std::string(getName())
2270 << m_texFormat
2271 << m_filter
2272 << m_sWrap
2273 << m_tWrap
2274 << m_rWrap
2275 << m_texture->getRefTexture().getWidth()
2276 << m_texture->getRefTexture().getHeight()
2277 << m_texture->getRefTexture().getDepth();
2278 return builder.get();
2279 }
2280
isFormatSupported(deUint32 format,bool isGL45)2281 static bool isFormatSupported(deUint32 format, bool isGL45)
2282 {
2283 if (isGL45 && (format == GL_LUMINANCE || format == GL_ALPHA || format == GL_LUMINANCE_ALPHA))
2284 return false;
2285
2286 return true;
2287 }
2288
2289 } // anonymous
2290
TextureBorderClampTests(Context & context,bool isGL45)2291 TextureBorderClampTests::TextureBorderClampTests (Context& context, bool isGL45)
2292 : TestCaseGroup(context, "border_clamp", "EXT_texture_border_clamp tests")
2293 , m_isGL45(isGL45)
2294 {
2295 }
2296
~TextureBorderClampTests(void)2297 TextureBorderClampTests::~TextureBorderClampTests (void)
2298 {
2299 }
2300
init(void)2301 void TextureBorderClampTests::init (void)
2302 {
2303 static const struct
2304 {
2305 const char* name;
2306 deUint32 filter;
2307 TextureBorderClampTest::SamplingFunction sampling;
2308 } s_filters[] =
2309 {
2310 { "nearest", GL_NEAREST, TextureBorderClampTest::SAMPLE_FILTER },
2311 { "linear", GL_LINEAR, TextureBorderClampTest::SAMPLE_FILTER },
2312 { "gather", GL_NEAREST, TextureBorderClampTest::SAMPLE_GATHER },
2313 };
2314
2315 // .formats
2316 {
2317 static const struct
2318 {
2319 const char* name;
2320 deUint32 format;
2321 tcu::Sampler::DepthStencilMode mode;
2322 } formats[] =
2323 {
2324 { "luminance", GL_LUMINANCE, tcu::Sampler::MODE_LAST },
2325 { "alpha", GL_ALPHA, tcu::Sampler::MODE_LAST },
2326 { "luminance_alpha", GL_LUMINANCE_ALPHA, tcu::Sampler::MODE_LAST },
2327 { "bgra", GL_BGRA, tcu::Sampler::MODE_LAST },
2328 { "r8", GL_R8, tcu::Sampler::MODE_LAST },
2329 { "r8_snorm", GL_R8_SNORM, tcu::Sampler::MODE_LAST },
2330 { "rg8", GL_RG8, tcu::Sampler::MODE_LAST },
2331 { "rg8_snorm", GL_RG8_SNORM, tcu::Sampler::MODE_LAST },
2332 { "rgb8", GL_RGB8, tcu::Sampler::MODE_LAST },
2333 { "rgb8_snorm", GL_RGB8_SNORM, tcu::Sampler::MODE_LAST },
2334 { "rgb565", GL_RGB565, tcu::Sampler::MODE_LAST },
2335 { "rgba4", GL_RGBA4, tcu::Sampler::MODE_LAST },
2336 { "rgb5_a1", GL_RGB5_A1, tcu::Sampler::MODE_LAST },
2337 { "rgba8", GL_RGBA8, tcu::Sampler::MODE_LAST },
2338 { "rgba8_snorm", GL_RGBA8_SNORM, tcu::Sampler::MODE_LAST },
2339 { "rgb10_a2", GL_RGB10_A2, tcu::Sampler::MODE_LAST },
2340 { "rgb10_a2ui", GL_RGB10_A2UI, tcu::Sampler::MODE_LAST },
2341 { "srgb8", GL_SRGB8, tcu::Sampler::MODE_LAST },
2342 { "srgb8_alpha8", GL_SRGB8_ALPHA8, tcu::Sampler::MODE_LAST },
2343 { "r16f", GL_R16F, tcu::Sampler::MODE_LAST },
2344 { "rg16f", GL_RG16F, tcu::Sampler::MODE_LAST },
2345 { "rgb16f", GL_RGB16F, tcu::Sampler::MODE_LAST },
2346 { "rgba16f", GL_RGBA16F, tcu::Sampler::MODE_LAST },
2347 { "r32f", GL_R32F, tcu::Sampler::MODE_LAST },
2348 { "rg32f", GL_RG32F, tcu::Sampler::MODE_LAST },
2349 { "rgb32f", GL_RGB32F, tcu::Sampler::MODE_LAST },
2350 { "rgba32f", GL_RGBA32F, tcu::Sampler::MODE_LAST },
2351 { "r11f_g11f_b10f", GL_R11F_G11F_B10F, tcu::Sampler::MODE_LAST },
2352 { "rgb9_e5", GL_RGB9_E5, tcu::Sampler::MODE_LAST },
2353 { "r8i", GL_R8I, tcu::Sampler::MODE_LAST },
2354 { "r8ui", GL_R8UI, tcu::Sampler::MODE_LAST },
2355 { "r16i", GL_R16I, tcu::Sampler::MODE_LAST },
2356 { "r16ui", GL_R16UI, tcu::Sampler::MODE_LAST },
2357 { "r32i", GL_R32I, tcu::Sampler::MODE_LAST },
2358 { "r32ui", GL_R32UI, tcu::Sampler::MODE_LAST },
2359 { "rg8i", GL_RG8I, tcu::Sampler::MODE_LAST },
2360 { "rg8ui", GL_RG8UI, tcu::Sampler::MODE_LAST },
2361 { "rg16i", GL_RG16I, tcu::Sampler::MODE_LAST },
2362 { "rg16ui", GL_RG16UI, tcu::Sampler::MODE_LAST },
2363 { "rg32i", GL_RG32I, tcu::Sampler::MODE_LAST },
2364 { "rg32ui", GL_RG32UI, tcu::Sampler::MODE_LAST },
2365 { "rgb8i", GL_RGB8I, tcu::Sampler::MODE_LAST },
2366 { "rgb8ui", GL_RGB8UI, tcu::Sampler::MODE_LAST },
2367 { "rgb16i", GL_RGB16I, tcu::Sampler::MODE_LAST },
2368 { "rgb16ui", GL_RGB16UI, tcu::Sampler::MODE_LAST },
2369 { "rgb32i", GL_RGB32I, tcu::Sampler::MODE_LAST },
2370 { "rgb32ui", GL_RGB32UI, tcu::Sampler::MODE_LAST },
2371 { "rgba8i", GL_RGBA8I, tcu::Sampler::MODE_LAST },
2372 { "rgba8ui", GL_RGBA8UI, tcu::Sampler::MODE_LAST },
2373 { "rgba16i", GL_RGBA16I, tcu::Sampler::MODE_LAST },
2374 { "rgba16ui", GL_RGBA16UI, tcu::Sampler::MODE_LAST },
2375 { "rgba32i", GL_RGBA32I, tcu::Sampler::MODE_LAST },
2376 { "rgba32ui", GL_RGBA32UI, tcu::Sampler::MODE_LAST },
2377 { "depth_component16", GL_DEPTH_COMPONENT16, tcu::Sampler::MODE_DEPTH },
2378 { "depth_component24", GL_DEPTH_COMPONENT24, tcu::Sampler::MODE_DEPTH },
2379 { "depth_component32f", GL_DEPTH_COMPONENT32F, tcu::Sampler::MODE_DEPTH },
2380 { "stencil_index8", GL_STENCIL_INDEX8, tcu::Sampler::MODE_STENCIL },
2381 { "depth24_stencil8_sample_depth", GL_DEPTH24_STENCIL8, tcu::Sampler::MODE_DEPTH },
2382 { "depth32f_stencil8_sample_depth", GL_DEPTH32F_STENCIL8, tcu::Sampler::MODE_DEPTH },
2383 { "depth24_stencil8_sample_stencil", GL_DEPTH24_STENCIL8, tcu::Sampler::MODE_STENCIL },
2384 { "depth32f_stencil8_sample_stencil", GL_DEPTH32F_STENCIL8, tcu::Sampler::MODE_STENCIL },
2385 { "compressed_r11_eac", GL_COMPRESSED_R11_EAC, tcu::Sampler::MODE_LAST },
2386 { "compressed_signed_r11_eac", GL_COMPRESSED_SIGNED_R11_EAC, tcu::Sampler::MODE_LAST },
2387 { "compressed_rg11_eac", GL_COMPRESSED_RG11_EAC, tcu::Sampler::MODE_LAST },
2388 { "compressed_signed_rg11_eac", GL_COMPRESSED_SIGNED_RG11_EAC, tcu::Sampler::MODE_LAST },
2389 { "compressed_rgb8_etc2", GL_COMPRESSED_RGB8_ETC2, tcu::Sampler::MODE_LAST },
2390 { "compressed_srgb8_etc2", GL_COMPRESSED_SRGB8_ETC2, tcu::Sampler::MODE_LAST },
2391 { "compressed_rgb8_punchthrough_alpha1_etc2", GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, tcu::Sampler::MODE_LAST },
2392 { "compressed_srgb8_punchthrough_alpha1_etc2", GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, tcu::Sampler::MODE_LAST },
2393 { "compressed_rgba8_etc2_eac", GL_COMPRESSED_RGBA8_ETC2_EAC, tcu::Sampler::MODE_LAST },
2394 { "compressed_srgb8_alpha8_etc2_eac", GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, tcu::Sampler::MODE_LAST },
2395 };
2396
2397 tcu::TestCaseGroup* const formatsGroup = new tcu::TestCaseGroup(m_testCtx, "formats", "Format tests");
2398 addChild(formatsGroup);
2399
2400 // .format
2401 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx)
2402 {
2403 const deUint32 format = formats[formatNdx].format;
2404 const tcu::Sampler::DepthStencilMode sampleMode = formats[formatNdx].mode;
2405 const bool isCompressed = glu::isCompressedFormat(format);
2406 const bool coreFilterable = isCoreFilterableFormat(format, sampleMode);
2407 tcu::TestCaseGroup* const formatGroup = new tcu::TestCaseGroup(m_testCtx, formats[formatNdx].name, "Format test");
2408
2409 formatsGroup->addChild(formatGroup);
2410
2411 // .nearest
2412 // .linear
2413 for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(s_filters); ++filterNdx)
2414 {
2415 // [not-compressed]
2416 // .size_pot
2417 // .size_npot
2418 // [compressed]
2419 // .size_tile_multiple (also pot)
2420 // .size_not_tile_multiple (also npot)
2421 for (int sizeNdx = 0; sizeNdx < 2; ++sizeNdx)
2422 {
2423 const bool isNpotCase = (sizeNdx == 1);
2424 const char* const sizePotName = (!isCompressed) ? ("size_pot") : ("size_tile_multiple");
2425 const char* const sizeNpotName = (!isCompressed) ? ("size_npot") : ("size_not_tile_multiple");
2426 const char* const sizeName = (isNpotCase) ? (sizeNpotName) : (sizePotName);
2427 const SizeType sizeType = (isNpotCase) ? (SIZE_NPOT) : (SIZE_POT);
2428 const std::string caseName = std::string() + s_filters[filterNdx].name + "_" + sizeName;
2429 const deUint32 filter = s_filters[filterNdx].filter;
2430
2431 if ((coreFilterable || !filterRequiresFilterability(filter)) && isFormatSupported(format, m_isGL45))
2432 formatGroup->addChild(new TextureBorderClampFormatCase(m_context,
2433 caseName.c_str(),
2434 "",
2435 format,
2436 sampleMode,
2437 TextureBorderClampFormatCase::STATE_TEXTURE_PARAM,
2438 sizeType,
2439 filter,
2440 s_filters[filterNdx].sampling));
2441 }
2442 }
2443 }
2444 }
2445
2446 // .range_clamp
2447 {
2448 static const struct
2449 {
2450 const char* name;
2451 deUint32 format;
2452 tcu::Sampler::DepthStencilMode mode;
2453 } formats[] =
2454 {
2455 { "unorm_color", GL_R8, tcu::Sampler::MODE_LAST },
2456 { "snorm_color", GL_R8_SNORM, tcu::Sampler::MODE_LAST },
2457 { "float_color", GL_RG32F, tcu::Sampler::MODE_LAST },
2458 { "int_color", GL_R8I, tcu::Sampler::MODE_LAST },
2459 { "uint_color", GL_R16UI, tcu::Sampler::MODE_LAST },
2460 { "srgb_color", GL_SRGB8_ALPHA8, tcu::Sampler::MODE_LAST },
2461 { "unorm_depth", GL_DEPTH_COMPONENT24, tcu::Sampler::MODE_DEPTH },
2462 { "float_depth", GL_DEPTH_COMPONENT32F, tcu::Sampler::MODE_DEPTH },
2463 { "uint_stencil", GL_STENCIL_INDEX8, tcu::Sampler::MODE_STENCIL },
2464 { "float_depth_uint_stencil_sample_depth", GL_DEPTH32F_STENCIL8, tcu::Sampler::MODE_DEPTH },
2465 { "float_depth_uint_stencil_sample_stencil", GL_DEPTH32F_STENCIL8, tcu::Sampler::MODE_STENCIL },
2466 { "unorm_depth_uint_stencil_sample_depth", GL_DEPTH24_STENCIL8, tcu::Sampler::MODE_DEPTH },
2467 { "unorm_depth_uint_stencil_sample_stencil", GL_DEPTH24_STENCIL8, tcu::Sampler::MODE_STENCIL },
2468 { "compressed_color", GL_COMPRESSED_RG11_EAC, tcu::Sampler::MODE_LAST },
2469 };
2470
2471 tcu::TestCaseGroup* const rangeClampGroup = new tcu::TestCaseGroup(m_testCtx, "range_clamp", "Range clamp tests");
2472 addChild(rangeClampGroup);
2473
2474 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx)
2475 for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(s_filters); ++filterNdx)
2476 {
2477 const deUint32 format = formats[formatNdx].format;
2478 const tcu::Sampler::DepthStencilMode sampleMode = formats[formatNdx].mode;
2479 const std::string caseName = std::string() + s_filters[filterNdx].name + "_" + formats[formatNdx].name;
2480 const deUint32 filter = s_filters[filterNdx].filter;
2481 const bool coreFilterable = isCoreFilterableFormat(format, sampleMode);
2482
2483 if (s_filters[filterNdx].sampling == TextureBorderClampTest::SAMPLE_GATHER)
2484 continue;
2485
2486 if (coreFilterable || !filterRequiresFilterability(filter))
2487 rangeClampGroup->addChild(new TextureBorderClampRangeClampCase(m_context, caseName.c_str(), "", format, sampleMode, filter));
2488 }
2489 }
2490
2491 // .sampler
2492 {
2493 static const struct
2494 {
2495 const char* name;
2496 deUint32 format;
2497 tcu::Sampler::DepthStencilMode mode;
2498 } formats[] =
2499 {
2500 { "unorm_color", GL_R8, tcu::Sampler::MODE_LAST },
2501 { "snorm_color", GL_R8_SNORM, tcu::Sampler::MODE_LAST },
2502 { "float_color", GL_RG32F, tcu::Sampler::MODE_LAST },
2503 { "int_color", GL_R8I, tcu::Sampler::MODE_LAST },
2504 { "uint_color", GL_R16UI, tcu::Sampler::MODE_LAST },
2505 { "unorm_depth", GL_DEPTH_COMPONENT24, tcu::Sampler::MODE_DEPTH },
2506 { "float_depth", GL_DEPTH_COMPONENT32F, tcu::Sampler::MODE_DEPTH },
2507 { "uint_stencil", GL_STENCIL_INDEX8, tcu::Sampler::MODE_STENCIL },
2508 { "compressed_color", GL_COMPRESSED_RG11_EAC, tcu::Sampler::MODE_LAST },
2509 };
2510
2511 tcu::TestCaseGroup* const samplerGroup = new tcu::TestCaseGroup(m_testCtx, "sampler", "Sampler param tests");
2512 addChild(samplerGroup);
2513
2514 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx)
2515 {
2516 const deUint32 format = formats[formatNdx].format;
2517 const tcu::Sampler::DepthStencilMode sampleMode = formats[formatNdx].mode;
2518 const char* caseName = formats[formatNdx].name;
2519
2520 samplerGroup->addChild(new TextureBorderClampFormatCase(m_context,
2521 caseName,
2522 "",
2523 format,
2524 sampleMode,
2525 TextureBorderClampFormatCase::STATE_SAMPLER_PARAM,
2526 SIZE_POT,
2527 GL_NEAREST,
2528 TextureBorderClampFormatCase::SAMPLE_FILTER));
2529 }
2530 }
2531
2532 // .per_axis_wrap_mode
2533 {
2534 static const struct
2535 {
2536 const char* name;
2537 bool is3D;
2538 } targets[] =
2539 {
2540 { "texture_2d", false },
2541 { "texture_3d", true },
2542 };
2543 static const struct
2544 {
2545 const char* name;
2546 deUint32 format;
2547 tcu::Sampler::DepthStencilMode mode;
2548 bool supports3D;
2549 } formats[] =
2550 {
2551 { "unorm_color", GL_RG8, tcu::Sampler::MODE_LAST, true },
2552 { "snorm_color", GL_RG8_SNORM, tcu::Sampler::MODE_LAST, true },
2553 { "float_color", GL_R32F, tcu::Sampler::MODE_LAST, true },
2554 { "int_color", GL_RG16I, tcu::Sampler::MODE_LAST, true },
2555 { "uint_color", GL_R8UI, tcu::Sampler::MODE_LAST, true },
2556 { "unorm_depth", GL_DEPTH_COMPONENT16, tcu::Sampler::MODE_DEPTH, false },
2557 { "float_depth", GL_DEPTH32F_STENCIL8, tcu::Sampler::MODE_DEPTH, false },
2558 { "uint_stencil", GL_DEPTH32F_STENCIL8, tcu::Sampler::MODE_STENCIL, false },
2559 { "compressed_color", GL_COMPRESSED_RGB8_ETC2, tcu::Sampler::MODE_LAST, false },
2560 };
2561 static const struct
2562 {
2563 const char* name;
2564 deUint32 sWrap;
2565 deUint32 tWrap;
2566 deUint32 rWrap;
2567 bool is3D;
2568 } wrapConfigs[] =
2569 {
2570 // 2d configs
2571 { "s_clamp_to_edge_t_clamp_to_border", GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER, GL_NONE, false },
2572 { "s_repeat_t_clamp_to_border", GL_REPEAT, GL_CLAMP_TO_BORDER, GL_NONE, false },
2573 { "s_mirrored_repeat_t_clamp_to_border", GL_MIRRORED_REPEAT, GL_CLAMP_TO_BORDER, GL_NONE, false },
2574
2575 // 3d configs
2576 { "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 },
2577 { "s_clamp_to_border_t_clamp_to_border_r_repeat", GL_CLAMP_TO_BORDER, GL_CLAMP_TO_BORDER, GL_REPEAT, true },
2578 { "s_mirrored_repeat_t_clamp_to_border_r_repeat", GL_MIRRORED_REPEAT, GL_CLAMP_TO_BORDER, GL_REPEAT, true },
2579 { "s_repeat_t_mirrored_repeat_r_clamp_to_border", GL_REPEAT, GL_MIRRORED_REPEAT, GL_CLAMP_TO_BORDER, true },
2580 };
2581
2582 tcu::TestCaseGroup* const perAxisGroup = new tcu::TestCaseGroup(m_testCtx, "per_axis_wrap_mode", "Per-axis wrapping modes");
2583 addChild(perAxisGroup);
2584
2585 // .texture_nd
2586 for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(targets); ++targetNdx)
2587 {
2588 tcu::TestCaseGroup* const targetGroup = new tcu::TestCaseGroup(m_testCtx, targets[targetNdx].name, "Texture target test");
2589 perAxisGroup->addChild(targetGroup);
2590
2591 // .format
2592 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx)
2593 {
2594 if (targets[targetNdx].is3D && !formats[formatNdx].supports3D)
2595 continue;
2596 else
2597 {
2598 const deUint32 format = formats[formatNdx].format;
2599 const tcu::Sampler::DepthStencilMode sampleMode = formats[formatNdx].mode;
2600 const bool coreFilterable = isCoreFilterableFormat(format, sampleMode);
2601 tcu::TestCaseGroup* const formatGroup = new tcu::TestCaseGroup(m_testCtx, formats[formatNdx].name, "Format test");
2602 targetGroup->addChild(formatGroup);
2603
2604 // .linear
2605 // .nearest
2606 // .gather
2607 for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(s_filters); ++filterNdx)
2608 {
2609 const deUint32 filter = s_filters[filterNdx].filter;
2610
2611 if (!coreFilterable && filterRequiresFilterability(filter))
2612 {
2613 // skip linear on pure integers
2614 continue;
2615 }
2616 else if (s_filters[filterNdx].sampling == TextureBorderClampTest::SAMPLE_GATHER && targets[targetNdx].is3D)
2617 {
2618 // skip gather on 3d
2619 continue;
2620 }
2621 else
2622 {
2623 tcu::TestCaseGroup* const filteringGroup = new tcu::TestCaseGroup(m_testCtx, s_filters[filterNdx].name, "Tests with specific filter");
2624 formatGroup->addChild(filteringGroup);
2625
2626 // .s_XXX_t_XXX(_r_XXX)
2627 for (int wrapNdx = 0; wrapNdx < DE_LENGTH_OF_ARRAY(wrapConfigs); ++wrapNdx)
2628 {
2629 if (wrapConfigs[wrapNdx].is3D != targets[targetNdx].is3D)
2630 continue;
2631 else
2632 {
2633 for (int sizeNdx = 0; sizeNdx < 2; ++sizeNdx)
2634 {
2635 const char* const wrapName = wrapConfigs[wrapNdx].name;
2636 const bool isNpotCase = (sizeNdx == 1);
2637 const char* const sizeNameExtension = (isNpotCase) ? ("_npot") : ("_pot");
2638 const SizeType size = (isNpotCase) ? (SIZE_NPOT) : (SIZE_POT);
2639
2640 if (!targets[targetNdx].is3D)
2641 filteringGroup->addChild(new TextureBorderClampPerAxisCase2D(m_context,
2642 (std::string() + wrapName + sizeNameExtension).c_str(),
2643 "",
2644 format,
2645 sampleMode,
2646 size,
2647 filter,
2648 wrapConfigs[wrapNdx].sWrap,
2649 wrapConfigs[wrapNdx].tWrap,
2650 s_filters[filterNdx].sampling));
2651 else
2652 {
2653 DE_ASSERT(sampleMode == tcu::Sampler::MODE_LAST);
2654 filteringGroup->addChild(new TextureBorderClampPerAxisCase3D(m_context,
2655 (std::string() + wrapName + sizeNameExtension).c_str(),
2656 "",
2657 format,
2658 size,
2659 filter,
2660 wrapConfigs[wrapNdx].sWrap,
2661 wrapConfigs[wrapNdx].tWrap,
2662 wrapConfigs[wrapNdx].rWrap));
2663 }
2664 }
2665 }
2666 }
2667 }
2668 }
2669 }
2670 }
2671 }
2672 }
2673
2674 // .depth_compare_mode
2675 {
2676 static const struct
2677 {
2678 const char* name;
2679 deUint32 format;
2680 } formats[] =
2681 {
2682 { "depth_component16", GL_DEPTH_COMPONENT16 },
2683 { "depth_component24", GL_DEPTH_COMPONENT24 },
2684 { "depth24_stencil8", GL_DEPTH24_STENCIL8 },
2685 { "depth32f_stencil8", GL_DEPTH32F_STENCIL8 },
2686 };
2687
2688 tcu::TestCaseGroup* const compareGroup = new tcu::TestCaseGroup(m_testCtx, "depth_compare_mode", "Tests depth compare mode");
2689 addChild(compareGroup);
2690
2691 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx)
2692 {
2693 const deUint32 format = formats[formatNdx].format;
2694 tcu::TestCaseGroup* const formatGroup = new tcu::TestCaseGroup(m_testCtx, formats[formatNdx].name, "Format test");
2695
2696 compareGroup->addChild(formatGroup);
2697
2698 // (format).(linear|nearest|gather)_(pot|npot)
2699 for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(s_filters); ++filterNdx)
2700 for (int sizeNdx = 0; sizeNdx < 2; ++sizeNdx)
2701 {
2702 const bool isNpotCase = (sizeNdx == 1);
2703 const char* const sizeName = (isNpotCase) ? ("size_npot") : ("size_pot");
2704 const SizeType sizeType = (isNpotCase) ? (SIZE_NPOT) : (SIZE_POT);
2705 const std::string caseName = std::string() + s_filters[filterNdx].name + "_" + sizeName;
2706 const deUint32 filter = s_filters[filterNdx].filter;
2707
2708 formatGroup->addChild(new TextureBorderClampDepthCompareCase(m_context,
2709 caseName.c_str(),
2710 "",
2711 format,
2712 sizeType,
2713 filter,
2714 s_filters[filterNdx].sampling));
2715 }
2716 }
2717 }
2718
2719 // unused channels (A in rgb, G in stencil etc.)
2720 {
2721 static const struct
2722 {
2723 const char* name;
2724 deUint32 format;
2725 tcu::Sampler::DepthStencilMode mode;
2726 } formats[] =
2727 {
2728 { "r8", GL_R8, tcu::Sampler::MODE_LAST },
2729 { "rg8_snorm", GL_RG8_SNORM, tcu::Sampler::MODE_LAST },
2730 { "rgb8", GL_RGB8, tcu::Sampler::MODE_LAST },
2731 { "rg32f", GL_RG32F, tcu::Sampler::MODE_LAST },
2732 { "r16i", GL_RG16I, tcu::Sampler::MODE_LAST },
2733 { "luminance", GL_LUMINANCE, tcu::Sampler::MODE_LAST },
2734 { "alpha", GL_ALPHA, tcu::Sampler::MODE_LAST },
2735 { "luminance_alpha", GL_LUMINANCE_ALPHA, tcu::Sampler::MODE_LAST },
2736 { "depth_component16", GL_DEPTH_COMPONENT16, tcu::Sampler::MODE_DEPTH },
2737 { "depth_component32f", GL_DEPTH_COMPONENT32F, tcu::Sampler::MODE_DEPTH },
2738 { "stencil_index8", GL_STENCIL_INDEX8, tcu::Sampler::MODE_STENCIL },
2739 { "depth32f_stencil8_sample_depth", GL_DEPTH32F_STENCIL8, tcu::Sampler::MODE_DEPTH },
2740 { "depth32f_stencil8_sample_stencil", GL_DEPTH32F_STENCIL8, tcu::Sampler::MODE_STENCIL },
2741 { "depth24_stencil8_sample_depth", GL_DEPTH24_STENCIL8, tcu::Sampler::MODE_DEPTH },
2742 { "depth24_stencil8_sample_stencil", GL_DEPTH24_STENCIL8, tcu::Sampler::MODE_STENCIL },
2743 { "compressed_r11_eac", GL_COMPRESSED_R11_EAC, tcu::Sampler::MODE_LAST },
2744 };
2745
2746 tcu::TestCaseGroup* const unusedGroup = new tcu::TestCaseGroup(m_testCtx, "unused_channels", "Tests channels that are not present in the internal format");
2747 addChild(unusedGroup);
2748
2749 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx)
2750 {
2751 if (isFormatSupported(formats[formatNdx].format, m_isGL45))
2752 {
2753 unusedGroup->addChild(new TextureBorderClampUnusedChannelCase(m_context,
2754 formats[formatNdx].name,
2755 "",
2756 formats[formatNdx].format,
2757 formats[formatNdx].mode));
2758 }
2759 }
2760 }
2761 }
2762
2763 } // Functional
2764 } // gles31
2765 } // deqp
2766