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