1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 3.1 Module
3 * -------------------------------------------------
5 * Copyright 2015 The Android Open Source Project
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * \brief Texture border clamp tests.
22 *//*--------------------------------------------------------------------*/
24 #include "es31fTextureBorderClampTests.hpp"
26 #include "glsTextureTestUtil.hpp"
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"
37 #include "rrGenericVector.hpp"
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"
48 #include "glwEnums.hpp"
49 #include "glwFunctions.hpp"
51 #include "deStringUtil.hpp"
52 #include "deUniquePtr.hpp"
53 #include "deRandom.hpp"
73 bool filterRequiresFilterability (deUint32 filter)
78 case GL_NEAREST_MIPMAP_NEAREST:
82 case GL_LINEAR_MIPMAP_NEAREST:
83 case GL_NEAREST_MIPMAP_LINEAR:
84 case GL_LINEAR_MIPMAP_LINEAR:
93 bool isDepthFormat (deUint32 format, tcu::Sampler::DepthStencilMode mode)
95 if (format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA || format == GL_ALPHA || format == GL_BGRA)
97 // Unsized formats are a special case
100 else if (glu::isCompressedFormat(format))
102 // no known compressed depth formats
107 const tcu::TextureFormat fmt = glu::mapGLInternalFormat(format);
109 if (fmt.order == tcu::TextureFormat::D)
111 DE_ASSERT(mode == tcu::Sampler::MODE_DEPTH);
114 else if (fmt.order == tcu::TextureFormat::DS && mode == tcu::Sampler::MODE_DEPTH)
121 bool isStencilFormat (deUint32 format, tcu::Sampler::DepthStencilMode mode)
123 if (format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA || format == GL_ALPHA || format == GL_BGRA)
125 // Unsized formats are a special case
128 else if (glu::isCompressedFormat(format))
130 // no known compressed stencil formats
135 const tcu::TextureFormat fmt = glu::mapGLInternalFormat(format);
137 if (fmt.order == tcu::TextureFormat::S)
139 DE_ASSERT(mode == tcu::Sampler::MODE_STENCIL);
142 else if (fmt.order == tcu::TextureFormat::DS && mode == tcu::Sampler::MODE_STENCIL)
149 tcu::TextureChannelClass getFormatChannelClass (deUint32 format, tcu::Sampler::DepthStencilMode mode)
151 if (format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA || format == GL_ALPHA || format == GL_BGRA)
153 // Unsized formats are a special c, use UNORM8
154 return tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT;
156 else if (glu::isCompressedFormat(format))
158 const tcu::CompressedTexFormat compressedFmt = glu::mapGLCompressedTexFormat(format);
159 const tcu::TextureFormat uncompressedFmt = tcu::getUncompressedFormat(compressedFmt);
160 return tcu::getTextureChannelClass(uncompressedFmt.type);
164 const tcu::TextureFormat fmt = glu::mapGLInternalFormat(format);
165 const tcu::TextureFormat effectiveFmt = tcu::getEffectiveDepthStencilTextureFormat(fmt, mode);
167 return tcu::getTextureChannelClass(effectiveFmt.type);
171 int getDimensionNumBlocks (int dimensionSize, int blockSize)
174 return (dimensionSize + blockSize - 1) / blockSize;
177 void generateDummyCompressedData (tcu::CompressedTexture& dst, const tcu::CompressedTexFormat& format)
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;
187 DE_ASSERT(dst.getDataSize() == dataSize);
189 if (tcu::isAstcFormat(format))
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 };
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);
202 de::Random rnd(0xabc);
204 for (int ndx = 0; ndx < dataSize; ++ndx)
205 ((deUint8*)dst.getData())[ndx] = rnd.getUint8();
209 template <typename T>
215 struct TextureTraits<glu::Texture2D>
217 typedef tcu::IVec2 SizeType;
219 static de::MovePtr<glu::Texture2D> createTextureFromInternalFormat (glu::RenderContext& renderCtx, deUint32 texFormat, const tcu::IVec2& size)
221 return de::MovePtr<glu::Texture2D>(new glu::Texture2D(renderCtx, texFormat, size.x(), size.y()));
224 static de::MovePtr<glu::Texture2D> createTextureFromFormatAndType (glu::RenderContext& renderCtx, deUint32 texFormat, deUint32 type, const tcu::IVec2& size)
226 return de::MovePtr<glu::Texture2D>(new glu::Texture2D(renderCtx, texFormat, type, size.x(), size.y()));
229 static de::MovePtr<glu::Texture2D> createTextureFromCompressedData (glu::RenderContext& renderCtx,
230 const glu::ContextInfo& ctxInfo,
231 const tcu::CompressedTexture& compressedLevel,
232 const tcu::TexDecompressionParams& decompressionParams)
234 return de::MovePtr<glu::Texture2D>(new glu::Texture2D(renderCtx,
238 decompressionParams));
241 static int getTextureNumLayers (const tcu::IVec2& size)
243 // 2D textures have one layer
250 struct TextureTraits<glu::Texture3D>
252 typedef tcu::IVec3 SizeType;
254 static de::MovePtr<glu::Texture3D> createTextureFromInternalFormat (glu::RenderContext& renderCtx, deUint32 texFormat, const tcu::IVec3& size)
256 return de::MovePtr<glu::Texture3D>(new glu::Texture3D(renderCtx, texFormat, size.x(), size.y(), size.z()));
259 static de::MovePtr<glu::Texture3D> createTextureFromFormatAndType (glu::RenderContext& renderCtx, deUint32 texFormat, deUint32 type, const tcu::IVec3& size)
261 return de::MovePtr<glu::Texture3D>(new glu::Texture3D(renderCtx, texFormat, type, size.x(), size.y(), size.z()));
264 static de::MovePtr<glu::Texture3D> createTextureFromCompressedData (glu::RenderContext& renderCtx,
265 const glu::ContextInfo& ctxInfo,
266 const tcu::CompressedTexture& compressedLevel,
267 const tcu::TexDecompressionParams& decompressionParams)
269 return de::MovePtr<glu::Texture3D>(new glu::Texture3D(renderCtx,
273 decompressionParams));
276 static int getTextureNumLayers (const tcu::IVec3& size)
278 // 3D textures have Z layers
283 template <typename T>
284 de::MovePtr<T> genDummyTexture (glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, deUint32 texFormat, const typename TextureTraits<T>::SizeType& size)
286 de::MovePtr<T> texture;
288 if (isDepthFormat(texFormat, tcu::Sampler::MODE_DEPTH) || isStencilFormat(texFormat, tcu::Sampler::MODE_STENCIL))
290 // fill different channels with different gradients
291 texture = TextureTraits<T>::createTextureFromInternalFormat(renderCtx, texFormat, size);
292 texture->getRefTexture().allocLevel(0);
294 if (isDepthFormat(texFormat, tcu::Sampler::MODE_DEPTH))
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));
301 if (isStencilFormat(texFormat, tcu::Sampler::MODE_STENCIL))
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());
307 // Flip y to make stencil and depth cases not look identical
308 tcu::fillWithComponentGradients(tcu::flipYAccess(stencilAccess), texFormatInfo.valueMax, texFormatInfo.valueMin);
313 else if (!glu::isCompressedFormat(texFormat))
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);
318 texture = TextureTraits<T>::createTextureFromInternalFormat(renderCtx, texFormat, size);
321 texture->getRefTexture().allocLevel(0);
323 // fill with gradient min -> max
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);
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));
341 generateDummyCompressedData(compressedLevel, compressedFormat);
343 texture = TextureTraits<T>::createTextureFromCompressedData(renderCtx,
346 decompressionParams);
352 int getNBitIntegerMaxValue (bool isSigned, int numBits)
354 DE_ASSERT(numBits < 32);
359 return deIntMaxValue32(numBits);
361 return deUintMaxValue32(numBits);
364 int getNBitIntegerMinValue (bool isSigned, int numBits)
366 DE_ASSERT(numBits < 32);
371 return deIntMinValue32(numBits);
376 tcu::IVec4 getNBitIntegerVec4MaxValue (bool isSigned, const tcu::IVec4& numBits)
378 return tcu::IVec4(getNBitIntegerMaxValue(isSigned, numBits[0]),
379 getNBitIntegerMaxValue(isSigned, numBits[1]),
380 getNBitIntegerMaxValue(isSigned, numBits[2]),
381 getNBitIntegerMaxValue(isSigned, numBits[3]));
384 tcu::IVec4 getNBitIntegerVec4MinValue (bool isSigned, const tcu::IVec4& numBits)
386 return tcu::IVec4(getNBitIntegerMinValue(isSigned, numBits[0]),
387 getNBitIntegerMinValue(isSigned, numBits[1]),
388 getNBitIntegerMinValue(isSigned, numBits[2]),
389 getNBitIntegerMinValue(isSigned, numBits[3]));
392 rr::GenericVec4 mapToFormatColorUnits (const tcu::TextureFormat& texFormat, const tcu::Vec4& normalizedRange)
394 const tcu::TextureFormatInfo texFormatInfo = tcu::getTextureFormatInfo(texFormat);
396 switch (tcu::getTextureChannelClass(texFormat.type))
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>());
406 return rr::GenericVec4();
410 rr::GenericVec4 mapToFormatColorRepresentable (const tcu::TextureFormat& texFormat, const tcu::Vec4& normalizedRange)
412 // make sure value is representable in the target format and clear channels
413 // not present in the target format.
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());
420 if (tcu::isSRGB(texFormat))
422 DE_ASSERT(texFormat.type == tcu::TextureFormat::UNORM_INT8);
424 // make sure border color (in linear space) can be converted to 8-bit sRGB space without
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));
436 return rr::GenericVec4(tcu::select(linearized, tcu::Vec4(0.0f), channelMask));
439 switch (tcu::getTextureChannelClass(texFormat.type))
441 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
442 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
443 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
445 access.setPixel(inFormatUnits.get<float>(), 0, 0);
446 return rr::GenericVec4(tcu::select(access.getPixel(0, 0), tcu::Vec4(0.0f), channelMask));
448 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
450 access.setPixel(inFormatUnits.get<deInt32>(), 0, 0);
451 return rr::GenericVec4(tcu::select(access.getPixelInt(0, 0), tcu::IVec4(0), channelMask));
453 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
455 access.setPixel(inFormatUnits.get<deUint32>(), 0, 0);
456 return rr::GenericVec4(tcu::select(access.getPixelUint(0, 0), tcu::UVec4(0u), channelMask));
461 return rr::GenericVec4();
466 bool isCoreFilterableFormat (deUint32 format, tcu::Sampler::DepthStencilMode mode)
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);
475 if (isLuminanceOrAlpha || isUnsizedColorFormat || isCompressed)
477 if (isStencil || isDepth)
481 return glu::isGLInternalColorFormatFilterable(format);
484 class TextureBorderClampTest : public TestCase
489 STATE_SAMPLER_PARAM = 0,
495 enum SamplingFunction
505 FLAG_USE_SHADOW_SAMPLER = (1u << 0),
508 struct IterationConfig
512 rr::GenericVec4 borderColor;
513 tcu::Vec4 lookupScale;
514 tcu::Vec4 lookupBias;
517 std::string description;
520 deUint32 compareMode;
524 TextureBorderClampTest (Context& context,
526 const char* description,
528 tcu::Sampler::DepthStencilMode mode,
532 SamplingFunction samplingFunction,
534 ~TextureBorderClampTest (void);
541 IterateResult iterate (void);
543 void logParams (const IterationConfig& config,
544 const glu::TextureTestUtil::ReferenceParams& samplerParams);
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);
552 void verifyImage (const tcu::Surface& image,
553 const IterationConfig& config,
554 const glu::TextureTestUtil::ReferenceParams& samplerParams);
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);
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);
570 bool verifyTextureGatherResult (const tcu::ConstPixelBufferAccess& renderedFrame,
571 const float* texCoord,
572 const glu::TextureTestUtil::ReferenceParams& samplerParams,
573 const tcu::LookupPrecision& lookupPrecision);
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);
581 deUint32 getIterationSeed (const IterationConfig& config) const;
582 glu::TextureTestUtil::ReferenceParams genSamplerParams (const IterationConfig& config) const;
583 glu::ShaderProgram* genGatherProgram (void) const;
585 virtual int getNumIterations (void) const = 0;
586 virtual IterationConfig getIteration (int ndx) const = 0;
589 const glu::Texture2D* getTexture (void) const;
591 const deUint32 m_texFormat;
592 const tcu::Sampler::DepthStencilMode m_sampleMode;
593 const tcu::TextureChannelClass m_channelClass;
594 const StateType m_stateType;
596 const int m_texHeight;
597 const int m_texWidth;
599 const SamplingFunction m_samplingFunction;
600 const bool m_useShadowSampler;
604 VIEWPORT_WIDTH = 128,
605 VIEWPORT_HEIGHT = 128,
608 de::MovePtr<glu::Texture2D> m_texture;
609 de::MovePtr<gls::TextureTestUtil::TextureRenderer> m_renderer;
610 de::MovePtr<glu::ShaderProgram> m_gatherProgram;
613 tcu::ResultCollector m_result;
616 TextureBorderClampTest::TextureBorderClampTest (Context& context,
618 const char* description,
620 tcu::Sampler::DepthStencilMode mode,
624 SamplingFunction samplingFunction,
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)
636 , m_result (context.getTestContext().getLog())
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);
644 TextureBorderClampTest::~TextureBorderClampTest (void)
649 void TextureBorderClampTest::init (void)
652 const bool supportsES32 = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
654 if (!supportsES32 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_border_clamp"))
655 throw tcu::NotSupportedError("Test requires GL_EXT_texture_border_clamp extension");
657 if (glu::isCompressedFormat(m_texFormat) &&
659 tcu::isAstcFormat(glu::mapGLCompressedTexFormat(m_texFormat)) &&
660 !m_context.getContextInfo().isExtensionSupported("GL_KHR_texture_compression_astc_ldr"))
662 throw tcu::NotSupportedError("Test requires GL_KHR_texture_compression_astc_ldr extension");
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");
668 if (m_context.getRenderTarget().getWidth() < VIEWPORT_WIDTH ||
669 m_context.getRenderTarget().getHeight() < VIEWPORT_HEIGHT)
671 throw tcu::NotSupportedError("Test requires " + de::toString<int>(VIEWPORT_WIDTH) + "x" + de::toString<int>(VIEWPORT_HEIGHT) + " viewport");
676 m_texture = genDummyTexture<glu::Texture2D>(m_context.getRenderContext(), m_context.getContextInfo(), m_texFormat, tcu::IVec2(m_texWidth, m_texHeight));
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;
684 if (m_samplingFunction == SAMPLE_FILTER)
686 const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
688 m_renderer = de::MovePtr<gls::TextureTestUtil::TextureRenderer>(new gls::TextureTestUtil::TextureRenderer(m_context.getRenderContext(), m_testCtx.getLog(), glslVersion, glu::PRECISION_HIGHP));
692 m_gatherProgram = de::MovePtr<glu::ShaderProgram>(genGatherProgram());
694 m_testCtx.getLog() << tcu::TestLog::Message
695 << "Using texture gather to sample texture"
696 << tcu::TestLog::EndMessage
699 if (!m_gatherProgram->isOk())
700 throw tcu::TestError("failed to build program");
704 void TextureBorderClampTest::deinit (void)
708 m_gatherProgram.clear();
711 TextureBorderClampTest::IterateResult TextureBorderClampTest::iterate (void)
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);
719 logParams(iterationConfig, samplerParams);
720 renderTo(renderedFrame, iterationConfig, samplerParams);
721 verifyImage(renderedFrame, iterationConfig, samplerParams);
723 if (++m_iterationNdx == getNumIterations())
725 m_result.setTestContextResult(m_testCtx);
731 void TextureBorderClampTest::logParams (const IterationConfig& config, const glu::TextureTestUtil::ReferenceParams& samplerParams)
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>()));
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;
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;
753 if (config.compareMode != GL_NONE)
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;
762 void TextureBorderClampTest::renderTo (tcu::Surface& surface,
763 const IterationConfig& config,
764 const glu::TextureTestUtil::ReferenceParams& samplerParams)
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;
771 glu::TextureTestUtil::computeQuadTexCoord2D(texCoord, config.p0, config.p1);
774 gl.activeTexture(GL_TEXTURE0);
775 gl.bindTexture(GL_TEXTURE_2D, m_texture->getGLTexture());
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);
782 if (config.compareMode == GL_NONE)
784 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
785 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_ALWAYS);
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);
793 if (m_stateType == STATE_TEXTURE_PARAM)
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));
801 switch (m_channelClass)
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>());
809 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
810 gl.texParameterIiv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, config.borderColor.getAccess<deInt32>());
813 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
814 gl.texParameterIuiv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, config.borderColor.getAccess<deUint32>());
821 else if (m_stateType == STATE_SAMPLER_PARAM)
823 const tcu::Vec4 blue(0.0f, 0.0f, 1.0f, 1.0f);
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
832 // setup sampler to correct values
833 sampler = de::MovePtr<glu::Sampler>(new glu::Sampler(m_context.getRenderContext()));
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));
840 switch (m_channelClass)
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>());
848 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
849 gl.samplerParameterIiv(**sampler, GL_TEXTURE_BORDER_COLOR, config.borderColor.getAccess<deInt32>());
852 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
853 gl.samplerParameterIuiv(**sampler, GL_TEXTURE_BORDER_COLOR, config.borderColor.getAccess<deUint32>());
860 gl.bindSampler(0, **sampler);
863 GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");
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());
870 void TextureBorderClampTest::renderQuad (const float* texCoord, const glu::TextureTestUtil::ReferenceParams& samplerParams)
872 // use TextureRenderer for basic rendering, use custom for gather
873 if (m_samplingFunction == SAMPLE_FILTER)
874 m_renderer->renderQuad(0, texCoord, samplerParams);
877 static const float position[] =
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
884 static const deUint16 indices[] =
888 const glu::VertexArrayBinding vertexArrays[] =
890 glu::va::Float("a_position", 4, 4, 0, &position[0]),
891 glu::va::Float("a_texcoord", 2, 4, 0, texCoord)
894 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
895 const deUint32 progId = m_gatherProgram->getProgram();
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());
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]));
909 void TextureBorderClampTest::verifyImage (const tcu::Surface& renderedFrame,
910 const IterationConfig& config,
911 const glu::TextureTestUtil::ReferenceParams& samplerParams)
913 const tcu::PixelFormat pixelFormat = m_context.getRenderTarget().getPixelFormat();
915 tcu::LodPrecision lodPrecision;
916 std::vector<float> texCoord;
919 glu::TextureTestUtil::computeQuadTexCoord2D(texCoord, config.p0, config.p1);
921 lodPrecision.derivateBits = 18;
922 lodPrecision.lodBits = 5;
924 if (samplerParams.sampler.compare == tcu::Sampler::COMPAREMODE_NONE)
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;
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);
940 if (m_samplingFunction == SAMPLE_FILTER)
942 verificationOk = verifyTextureSampleResult(renderedFrame.getAccess(),
948 else if (m_samplingFunction == SAMPLE_GATHER)
950 verificationOk = verifyTextureGatherResult(renderedFrame.getAccess(),
958 verificationOk = false;
963 tcu::TexComparePrecision texComparePrecision;
964 tcu::TexComparePrecision lowQualityTexComparePrecision;
965 tcu::LodPrecision lowQualityLodPrecision = lodPrecision;
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);
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);
979 lowQualityLodPrecision.lodBits = 4;
981 if (m_samplingFunction == SAMPLE_FILTER)
983 verificationOk = verifyTextureCompareResult(renderedFrame.getAccess(),
987 lowQualityTexComparePrecision,
989 lowQualityLodPrecision);
991 else if (m_samplingFunction == SAMPLE_GATHER)
993 verificationOk = verifyTextureGatherCmpResult(renderedFrame.getAccess(),
997 lowQualityTexComparePrecision);
1002 verificationOk = false;
1006 if (!verificationOk)
1007 m_result.fail("Image verification failed");
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)
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;
1021 glu::TextureTestUtil::sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), m_texture->getRefTexture(), texCoord, samplerParams);
1023 numFailedPixels = glu::TextureTestUtil::computeTextureLookupDiff(renderedFrame, reference.getAccess(), errorMask.getAccess(), m_texture->getRefTexture(),
1024 texCoord, samplerParams, lookupPrecision, lodPrecision, m_testCtx.getWatchDog());
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)
1032 m_testCtx.getLog() << tcu::TestLog::Image("Reference", "Ideal reference image", reference)
1033 << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask);
1035 m_testCtx.getLog() << tcu::TestLog::EndImageSet;
1037 return (numFailedPixels == 0);
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)
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;
1058 glu::TextureTestUtil::sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), effectiveView, texCoord, samplerParams);
1060 numFailedPixels = glu::TextureTestUtil::computeTextureCompareDiff(renderedFrame, reference.getAccess(), errorMask.getAccess(), effectiveView,
1061 texCoord, samplerParams, texComparePrecision, lodPrecision, nonShadowThreshold);
1063 if (numFailedPixels > 0)
1065 m_testCtx.getLog() << tcu::TestLog::Message
1066 << "Warning: Verification assuming high-quality PCF filtering failed."
1067 << tcu::TestLog::EndMessage;
1069 numFailedPixels = glu::TextureTestUtil::computeTextureCompareDiff(renderedFrame, reference.getAccess(), errorMask.getAccess(), effectiveView,
1070 texCoord, samplerParams, lowQualityTexComparePrecision, lowQualityLodPrecision, nonShadowThreshold);
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");
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)
1084 m_testCtx.getLog() << tcu::TestLog::Image("Reference", "Ideal reference image", reference)
1085 << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask);
1087 m_testCtx.getLog() << tcu::TestLog::EndImageSet;
1089 return (numFailedPixels == 0);
1092 template <typename T>
1093 static inline T triQuadInterpolate (const T (&values)[4], float xFactor, float yFactor)
1095 if (xFactor + yFactor < 1.0f)
1096 return values[0] + (values[2]-values[0])*xFactor + (values[1]-values[0])*yFactor;
1098 return values[3] + (values[1]-values[3])*(1.0f-xFactor) + (values[2]-values[3])*(1.0f-yFactor);
1101 bool TextureBorderClampTest::verifyTextureGatherResult (const tcu::ConstPixelBufferAccess& renderedFrame,
1102 const float* texCoordArray,
1103 const glu::TextureTestUtil::ReferenceParams& samplerParams,
1104 const tcu::LookupPrecision& lookupPrecision)
1106 const tcu::Vec2 texCoords[4] =
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]),
1114 const tcu::PixelFormat pixelFormat = m_context.getRenderTarget().getPixelFormat();
1115 const deUint8 fbColormask = tcu::getColorMask(pixelFormat);
1117 std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage;
1118 const tcu::Texture2DView effectiveView = tcu::getEffectiveTextureView(m_texture->getRefTexture(), srcLevelStorage, samplerParams.sampler);
1120 tcu::Surface reference (renderedFrame.getWidth(), renderedFrame.getHeight());
1121 tcu::Surface errorMask (renderedFrame.getWidth(), renderedFrame.getHeight());
1122 int numFailedPixels = 0;
1124 tcu::clear(errorMask.getAccess(), tcu::RGBA::green().toVec());
1126 for (int py = 0; py < reference.getHeight(); ++py)
1127 for (int px = 0; px < reference.getWidth(); ++px)
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;
1136 reference.setPixel(px, py, tcu::toRGBAMasked(referenceValue, fbColormask));
1138 if (tcu::boolAny(tcu::logicalAnd(lookupPrecision.colorMask,
1139 tcu::greaterThan(tcu::absDiff(resultPixel, referencePixel),
1140 lookupPrecision.colorThreshold))))
1142 if (!tcu::isGatherOffsetsResultValid(effectiveView, samplerParams.sampler, lookupPrecision, texCoord, 0, glu::getDefaultGatherOffsets(), resultValue))
1144 errorMask.setPixel(px, py, tcu::RGBA::red());
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)
1156 m_testCtx.getLog() << tcu::TestLog::Image("Reference", "Ideal reference image", reference)
1157 << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask);
1159 m_testCtx.getLog() << tcu::TestLog::EndImageSet;
1161 return (numFailedPixels == 0);
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)
1170 const tcu::Vec2 texCoords[4] =
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]),
1178 std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage;
1179 const tcu::Texture2DView effectiveView = tcu::getEffectiveTextureView(m_texture->getRefTexture(), srcLevelStorage, samplerParams.sampler);
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;
1189 tcu::clear(errorMask.getAccess(), tcu::RGBA::green().toVec());
1191 for (int py = 0; py < reference.getHeight(); ++py)
1192 for (int px = 0; px < reference.getWidth(); ++px)
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);
1200 reference.setPixel(px, py, tcu::toRGBAMasked(referenceValue, fbColormask));
1202 if (tcu::boolAny(tcu::logicalAnd(colorMask, tcu::notEqual(referenceValue, resultValue))))
1204 if (!tcu::isGatherOffsetsCompareResultValid(effectiveView, samplerParams.sampler, texComparePrecision, texCoord, glu::getDefaultGatherOffsets(), refZ, resultValue))
1208 // fall back to low quality verification
1209 if (!tcu::isGatherOffsetsCompareResultValid(effectiveView, samplerParams.sampler, lowQualityTexComparePrecision, texCoord, glu::getDefaultGatherOffsets(), refZ, resultValue))
1211 errorMask.setPixel(px, py, tcu::RGBA::red());
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)
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");
1226 m_testCtx.getLog() << tcu::TestLog::ImageSet("VerifyResult", "Verification result")
1227 << tcu::TestLog::Image("Rendered", "Rendered image", renderedFrame);
1228 if (numFailedPixels > 0)
1230 m_testCtx.getLog() << tcu::TestLog::Image("Reference", "Ideal reference image", reference)
1231 << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask);
1233 m_testCtx.getLog() << tcu::TestLog::EndImageSet;
1235 return (numFailedPixels == 0);
1238 const glu::Texture2D* TextureBorderClampTest::getTexture (void) const
1240 return m_texture.get();
1243 deUint32 TextureBorderClampTest::getIterationSeed (const IterationConfig& config) const
1245 tcu::SeedBuilder builder;
1246 builder << std::string(getName())
1249 << config.minFilter << config.magFilter
1250 << m_texture->getRefTexture().getWidth() << m_texture->getRefTexture().getHeight();
1251 return builder.get();
1254 glu::TextureTestUtil::ReferenceParams TextureBorderClampTest::genSamplerParams (const IterationConfig& config) const
1256 const tcu::TextureFormat texFormat = tcu::getEffectiveDepthStencilTextureFormat(m_texture->getRefTexture().getFormat(), m_sampleMode);
1257 glu::TextureTestUtil::ReferenceParams refParams (glu::TextureTestUtil::TEXTURETYPE_2D);
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;
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);
1273 // sampler type must match compare mode
1274 DE_ASSERT(m_useShadowSampler == (config.compareMode != GL_NONE));
1276 // in gather, weird mapping is most likely an error
1277 if (m_samplingFunction == SAMPLE_GATHER)
1279 DE_ASSERT(refParams.colorScale == tcu::Vec4(refParams.colorScale.x()));
1280 DE_ASSERT(refParams.colorBias == tcu::Vec4(refParams.colorBias.x()));
1286 glu::ShaderProgram* TextureBorderClampTest::genGatherProgram (void) const
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"
1295 " gl_Position = a_position;\n"
1296 " v_texcoord = a_texcoord;\n"
1298 const char* samplerType;
1300 std::ostringstream fragSource;
1302 if (m_useShadowSampler)
1304 samplerType = "sampler2DShadow";
1305 lookup = "textureGather(u_sampler, v_texcoord, u_ref)";
1309 switch (m_channelClass)
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)";
1318 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1319 samplerType = "isampler2D";
1320 lookup = "vec4(textureGather(u_sampler, v_texcoord))";
1323 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1324 samplerType = "usampler2D";
1325 lookup = "vec4(textureGather(u_sampler, v_texcoord))";
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"
1344 " o_color = " << lookup << " * u_colorScale + u_colorBias;\n"
1347 return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(vtxSource) << glu::FragmentSource(fragSource.str()));
1350 class TextureBorderClampFormatCase : public TextureBorderClampTest
1353 TextureBorderClampFormatCase (Context& context,
1355 const char* description,
1357 tcu::Sampler::DepthStencilMode mode,
1358 StateType stateType,
1361 SamplingFunction samplingFunction);
1366 int getNumIterations (void) const;
1367 IterationConfig getIteration (int ndx) const;
1369 const SizeType m_sizeType;
1370 const deUint32 m_filter;
1372 std::vector<IterationConfig> m_iterations;
1376 TextureBorderClampFormatCase::TextureBorderClampFormatCase (Context& context,
1378 const char* description,
1380 tcu::Sampler::DepthStencilMode mode,
1381 StateType stateType,
1384 SamplingFunction samplingFunction)
1385 : TextureBorderClampTest(context,
1391 (sizeType == SIZE_POT) ? (32) : (17),
1392 (sizeType == SIZE_POT) ? (16) : (31),
1394 , m_sizeType (sizeType)
1397 if (m_sizeType == SIZE_POT)
1398 DE_ASSERT(deIsPowerOfTwo32(m_texWidth) && deIsPowerOfTwo32(m_texHeight));
1400 DE_ASSERT(!deIsPowerOfTwo32(m_texWidth) && !deIsPowerOfTwo32(m_texHeight));
1402 if (glu::isCompressedFormat(texFormat))
1404 const tcu::CompressedTexFormat compressedFormat = glu::mapGLCompressedTexFormat(texFormat);
1405 const tcu::IVec3 blockPixelSize = tcu::getBlockPixelSize(compressedFormat);
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);
1411 DE_ASSERT((m_texWidth % blockPixelSize.x()) != 0 && (m_texHeight % blockPixelSize.y()) != 0);
1413 DE_UNREF(blockPixelSize);
1417 void TextureBorderClampFormatCase::init (void)
1419 TextureBorderClampTest::init();
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);
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);
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);
1442 // common parameters
1443 for (int ndx = 0; ndx < (int)m_iterations.size(); ++ndx)
1445 IterationConfig& iteration = m_iterations[ndx];
1447 if (m_samplingFunction == SAMPLE_GATHER)
1449 iteration.lookupScale = tcu::Vec4(texFormatInfo.lookupScale.x());
1450 iteration.lookupBias = tcu::Vec4(texFormatInfo.lookupBias.x());
1454 iteration.lookupScale = texFormatInfo.lookupScale;
1455 iteration.lookupBias = texFormatInfo.lookupBias;
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;
1467 int TextureBorderClampFormatCase::getNumIterations (void) const
1469 return (int)m_iterations.size();
1472 TextureBorderClampTest::IterationConfig TextureBorderClampFormatCase::getIteration (int ndx) const
1474 return m_iterations[ndx];
1477 class TextureBorderClampRangeClampCase : public TextureBorderClampTest
1480 TextureBorderClampRangeClampCase (Context& context,
1482 const char* description,
1484 tcu::Sampler::DepthStencilMode mode,
1490 int getNumIterations (void) const;
1491 IterationConfig getIteration (int ndx) const;
1493 const deUint32 m_filter;
1494 std::vector<IterationConfig> m_iterations;
1497 TextureBorderClampRangeClampCase::TextureBorderClampRangeClampCase (Context& context,
1499 const char* description,
1501 tcu::Sampler::DepthStencilMode mode,
1503 : TextureBorderClampTest(context, name, description, texFormat, mode, TextureBorderClampTest::STATE_TEXTURE_PARAM, 8, 32, SAMPLE_FILTER)
1508 void TextureBorderClampRangeClampCase::init (void)
1510 TextureBorderClampTest::init();
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;
1518 if (isDepth || isFloat)
1520 // infinities are commonly used values on depth/float borders
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);
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);
1542 else if (isPureInteger)
1544 const tcu::IVec4 numBits = tcu::getTextureFormatBitDepth(texFormat);
1545 const bool isSigned = m_channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER;
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);
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]));
1561 const tcu::IVec4 value = maxValue + tcu::IVec4(1);
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);
1575 const tcu::IVec4 value = minValue - tcu::IVec4(1);
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);
1588 const tcu::IVec4 value = (isSigned) ? (tcu::IVec4(std::numeric_limits<deInt32>::max())) : (tcu::IVec4(std::numeric_limits<deUint32>::max()));
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);
1602 const tcu::IVec4 value = tcu::IVec4(std::numeric_limits<deInt32>::min());
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);
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));
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);
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);
1644 // common parameters
1645 for (int ndx = 0; ndx < (int)m_iterations.size(); ++ndx)
1647 IterationConfig& iteration = m_iterations[ndx];
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;
1658 int TextureBorderClampRangeClampCase::getNumIterations (void) const
1660 return (int)m_iterations.size();
1663 TextureBorderClampTest::IterationConfig TextureBorderClampRangeClampCase::getIteration (int ndx) const
1665 return m_iterations[ndx];
1668 class TextureBorderClampPerAxisCase2D : public TextureBorderClampTest
1671 TextureBorderClampPerAxisCase2D (Context& context,
1673 const char* description,
1675 tcu::Sampler::DepthStencilMode mode,
1680 SamplingFunction samplingFunction);
1685 int getNumIterations (void) const;
1686 IterationConfig getIteration (int ndx) const;
1688 const deUint32 m_texSWrap;
1689 const deUint32 m_texTWrap;
1690 const deUint32 m_filter;
1692 std::vector<IterationConfig> m_iterations;
1695 TextureBorderClampPerAxisCase2D::TextureBorderClampPerAxisCase2D (Context& context,
1697 const char* description,
1699 tcu::Sampler::DepthStencilMode mode,
1704 SamplingFunction samplingFunction)
1705 : TextureBorderClampTest(context,
1710 TextureBorderClampTest::STATE_TEXTURE_PARAM,
1711 (sizeType == SIZE_POT) ? (16) : (7),
1712 (sizeType == SIZE_POT) ? (8) : (9),
1714 , m_texSWrap (texSWrap)
1715 , m_texTWrap (texTWrap)
1720 void TextureBorderClampPerAxisCase2D::init (void)
1722 TextureBorderClampTest::init();
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);
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));
1733 if (m_samplingFunction == SAMPLE_GATHER)
1735 iteration.lookupScale = tcu::Vec4(texFormatInfo.lookupScale.x());
1736 iteration.lookupBias = tcu::Vec4(texFormatInfo.lookupBias.x());
1740 iteration.lookupScale = texFormatInfo.lookupScale;
1741 iteration.lookupBias = texFormatInfo.lookupBias;
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;
1751 m_iterations.push_back(iteration);
1754 int TextureBorderClampPerAxisCase2D::getNumIterations (void) const
1756 return (int)m_iterations.size();
1759 TextureBorderClampTest::IterationConfig TextureBorderClampPerAxisCase2D::getIteration (int ndx) const
1761 return m_iterations[ndx];
1764 class TextureBorderClampDepthCompareCase : public TextureBorderClampTest
1767 TextureBorderClampDepthCompareCase (Context& context,
1769 const char* description,
1773 SamplingFunction samplingFunction);
1778 int getNumIterations (void) const;
1779 IterationConfig getIteration (int ndx) const;
1781 const deUint32 m_filter;
1782 std::vector<IterationConfig> m_iterations;
1785 TextureBorderClampDepthCompareCase::TextureBorderClampDepthCompareCase (Context& context,
1787 const char* description,
1791 SamplingFunction samplingFunction)
1792 : TextureBorderClampTest(context,
1796 tcu::Sampler::MODE_DEPTH,
1797 TextureBorderClampTest::STATE_TEXTURE_PARAM,
1798 (sizeType == SIZE_POT) ? (32) : (13),
1799 (sizeType == SIZE_POT) ? (16) : (17),
1801 FLAG_USE_SHADOW_SAMPLER)
1806 void TextureBorderClampDepthCompareCase::init (void)
1808 TextureBorderClampTest::init();
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);
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);
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);
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);
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);
1870 // common parameters
1871 for (int ndx = 0; ndx < (int)m_iterations.size(); ++ndx)
1873 IterationConfig& iteration = m_iterations[ndx];
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;
1884 int TextureBorderClampDepthCompareCase::getNumIterations (void) const
1886 return (int)m_iterations.size();
1889 TextureBorderClampTest::IterationConfig TextureBorderClampDepthCompareCase::getIteration (int ndx) const
1891 return m_iterations[ndx];
1894 class TextureBorderClampUnusedChannelCase : public TextureBorderClampTest
1897 TextureBorderClampUnusedChannelCase (Context& context,
1899 const char* description,
1901 tcu::Sampler::DepthStencilMode depthStencilMode);
1906 int getNumIterations (void) const;
1907 IterationConfig getIteration (int ndx) const;
1909 std::vector<IterationConfig> m_iterations;
1912 TextureBorderClampUnusedChannelCase::TextureBorderClampUnusedChannelCase (Context& context,
1914 const char* description,
1916 tcu::Sampler::DepthStencilMode depthStencilMode)
1917 : TextureBorderClampTest(context,
1922 TextureBorderClampTest::STATE_TEXTURE_PARAM,
1929 static rr::GenericVec4 selectComponents (const rr::GenericVec4& trueComponents, const rr::GenericVec4& falseComponents, const tcu::BVec4& m)
1931 return rr::GenericVec4(tcu::select(trueComponents.get<deUint32>(), falseComponents.get<deUint32>(), m));
1934 void TextureBorderClampUnusedChannelCase::init (void)
1936 TextureBorderClampTest::init();
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]);
1947 const rr::GenericVec4 effectiveColors = mapToFormatColorRepresentable(texFormat, tcu::Vec4(0.6f));
1948 rr::GenericVec4 nonEffectiveColors;
1950 switch (m_channelClass)
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));
1958 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1959 nonEffectiveColors = rr::GenericVec4(tcu::Vec4(maxChannelValue * 0.8f).cast<deInt32>());
1962 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1963 nonEffectiveColors = rr::GenericVec4(tcu::Vec4(maxChannelValue * 0.8f).cast<deUint32>());
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";
1983 m_iterations.push_back(iteration);
1986 int TextureBorderClampUnusedChannelCase::getNumIterations (void) const
1988 return (int)m_iterations.size();
1991 TextureBorderClampTest::IterationConfig TextureBorderClampUnusedChannelCase::getIteration (int ndx) const
1993 return m_iterations[ndx];
1996 class TextureBorderClampPerAxisCase3D : public TestCase
1999 TextureBorderClampPerAxisCase3D (Context& context,
2001 const char* description,
2012 IterateResult iterate (void);
2014 void renderTo (tcu::Surface& surface,
2015 const glu::TextureTestUtil::ReferenceParams& samplerParams);
2017 void logParams (const glu::TextureTestUtil::ReferenceParams& samplerParams);
2019 void verifyImage (const tcu::Surface& image,
2020 const glu::TextureTestUtil::ReferenceParams& samplerParams);
2022 glu::TextureTestUtil::ReferenceParams getSamplerParams (void) const;
2023 deUint32 getCaseSeed (void) const;
2027 VIEWPORT_WIDTH = 128,
2028 VIEWPORT_HEIGHT = 128,
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;
2039 de::MovePtr<glu::Texture3D> m_texture;
2040 de::MovePtr<gls::TextureTestUtil::TextureRenderer> m_renderer;
2042 rr::GenericVec4 m_borderColor;
2043 std::vector<float> m_texCoords;
2044 tcu::Vec4 m_lookupScale;
2045 tcu::Vec4 m_lookupBias;
2048 TextureBorderClampPerAxisCase3D::TextureBorderClampPerAxisCase3D (Context& context,
2050 const char* description,
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)))
2068 void TextureBorderClampPerAxisCase3D::init (void)
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());
2073 if (!supportsES32 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_border_clamp"))
2074 throw tcu::NotSupportedError("Test requires GL_EXT_texture_border_clamp extension");
2076 if (glu::isCompressedFormat(m_texFormat) &&
2078 tcu::isAstcFormat(glu::mapGLCompressedTexFormat(m_texFormat)) &&
2079 !m_context.getContextInfo().isExtensionSupported("GL_KHR_texture_compression_astc_ldr"))
2081 throw tcu::NotSupportedError("Test requires GL_KHR_texture_compression_astc_ldr extension");
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)
2088 throw tcu::NotSupportedError("Test requires " + de::toString<int>(VIEWPORT_WIDTH) + "x" + de::toString<int>(VIEWPORT_HEIGHT) + " viewport");
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));
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;
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;
2107 m_texCoords.resize(4*3);
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;
2115 // set render params
2117 const tcu::TextureFormat texFormat = m_texture->getRefTexture().getFormat();
2118 const tcu::TextureFormatInfo texFormatInfo = tcu::getTextureFormatInfo(texFormat);
2120 m_borderColor = mapToFormatColorRepresentable(texFormat, tcu::Vec4(0.2f, 0.6f, 0.9f, 0.4f));
2122 m_lookupScale = texFormatInfo.lookupScale;
2123 m_lookupBias = texFormatInfo.lookupBias;
2127 void TextureBorderClampPerAxisCase3D::deinit (void)
2133 TextureBorderClampPerAxisCase3D::IterateResult TextureBorderClampPerAxisCase3D::iterate (void)
2135 tcu::Surface renderedFrame (VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
2136 const glu::TextureTestUtil::ReferenceParams samplerParams = getSamplerParams();
2138 logParams(samplerParams);
2139 renderTo(renderedFrame, samplerParams);
2140 verifyImage(renderedFrame, samplerParams);
2145 void TextureBorderClampPerAxisCase3D::logParams (const glu::TextureTestUtil::ReferenceParams& samplerParams)
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>()));
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;
2162 void TextureBorderClampPerAxisCase3D::renderTo (tcu::Surface& surface,
2163 const glu::TextureTestUtil::ReferenceParams& samplerParams)
2165 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2166 const gls::TextureTestUtil::RandomViewport viewport (m_context.getRenderTarget(), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, getCaseSeed());
2169 gl.activeTexture(GL_TEXTURE0);
2170 gl.bindTexture(GL_TEXTURE_3D, m_texture->getGLTexture());
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));
2179 switch (m_channelClass)
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>());
2187 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
2188 gl.texParameterIiv(GL_TEXTURE_3D, GL_TEXTURE_BORDER_COLOR, m_borderColor.getAccess<deInt32>());
2191 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
2192 gl.texParameterIuiv(GL_TEXTURE_3D, GL_TEXTURE_BORDER_COLOR, m_borderColor.getAccess<deUint32>());
2199 GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");
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());
2206 void TextureBorderClampPerAxisCase3D::verifyImage (const tcu::Surface& renderedFrame,
2207 const glu::TextureTestUtil::ReferenceParams& samplerParams)
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;
2218 lodPrecision.derivateBits = 18;
2219 lodPrecision.lodBits = 5;
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);
2226 glu::TextureTestUtil::sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), m_texture->getRefTexture(), &m_texCoords[0], samplerParams);
2228 numFailedPixels = glu::TextureTestUtil::computeTextureLookupDiff(renderedFrame.getAccess(), reference.getAccess(), errorMask.getAccess(), m_texture->getRefTexture(),
2229 &m_texCoords[0], samplerParams, lookupPrecision, lodPrecision, m_testCtx.getWatchDog());
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)
2237 m_testCtx.getLog() << tcu::TestLog::Image("Reference", "Ideal reference image", reference)
2238 << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask);
2240 m_testCtx.getLog() << tcu::TestLog::EndImageSet;
2242 if (numFailedPixels == 0)
2243 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2245 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
2248 glu::TextureTestUtil::ReferenceParams TextureBorderClampPerAxisCase3D::getSamplerParams (void) const
2250 const tcu::TextureFormat texFormat = m_texture->getRefTexture().getFormat();
2251 glu::TextureTestUtil::ReferenceParams refParams (glu::TextureTestUtil::TEXTURETYPE_3D);
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;
2263 deUint32 TextureBorderClampPerAxisCase3D::getCaseSeed (void) const
2265 tcu::SeedBuilder builder;
2266 builder << std::string(getName())
2272 << m_texture->getRefTexture().getWidth()
2273 << m_texture->getRefTexture().getHeight()
2274 << m_texture->getRefTexture().getDepth();
2275 return builder.get();
2280 TextureBorderClampTests::TextureBorderClampTests (Context& context)
2281 : TestCaseGroup(context, "border_clamp", "EXT_texture_border_clamp tests")
2285 TextureBorderClampTests::~TextureBorderClampTests (void)
2289 void TextureBorderClampTests::init (void)
2295 TextureBorderClampTest::SamplingFunction sampling;
2298 { "nearest", GL_NEAREST, TextureBorderClampTest::SAMPLE_FILTER },
2299 { "linear", GL_LINEAR, TextureBorderClampTest::SAMPLE_FILTER },
2300 { "gather", GL_NEAREST, TextureBorderClampTest::SAMPLE_GATHER },
2309 tcu::Sampler::DepthStencilMode mode;
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 },
2385 tcu::TestCaseGroup* const formatsGroup = new tcu::TestCaseGroup(m_testCtx, "formats", "Format tests");
2386 addChild(formatsGroup);
2389 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx)
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");
2397 formatsGroup->addChild(formatGroup);
2401 for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(s_filters); ++filterNdx)
2407 // .size_tile_multiple (also pot)
2408 // .size_not_tile_multiple (also npot)
2409 for (int sizeNdx = 0; sizeNdx < 2; ++sizeNdx)
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;
2419 if (coreFilterable || !filterRequiresFilterability(filter))
2420 formatGroup->addChild(new TextureBorderClampFormatCase(m_context,
2425 TextureBorderClampFormatCase::STATE_TEXTURE_PARAM,
2428 s_filters[filterNdx].sampling));
2440 tcu::Sampler::DepthStencilMode mode;
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 },
2459 tcu::TestCaseGroup* const rangeClampGroup = new tcu::TestCaseGroup(m_testCtx, "range_clamp", "Range clamp tests");
2460 addChild(rangeClampGroup);
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)
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);
2471 if (s_filters[filterNdx].sampling == TextureBorderClampTest::SAMPLE_GATHER)
2474 if (coreFilterable || !filterRequiresFilterability(filter))
2475 rangeClampGroup->addChild(new TextureBorderClampRangeClampCase(m_context, caseName.c_str(), "", format, sampleMode, filter));
2485 tcu::Sampler::DepthStencilMode mode;
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 },
2499 tcu::TestCaseGroup* const samplerGroup = new tcu::TestCaseGroup(m_testCtx, "sampler", "Sampler param tests");
2500 addChild(samplerGroup);
2502 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx)
2504 const deUint32 format = formats[formatNdx].format;
2505 const tcu::Sampler::DepthStencilMode sampleMode = formats[formatNdx].mode;
2506 const char* caseName = formats[formatNdx].name;
2508 samplerGroup->addChild(new TextureBorderClampFormatCase(m_context,
2513 TextureBorderClampFormatCase::STATE_SAMPLER_PARAM,
2516 TextureBorderClampFormatCase::SAMPLE_FILTER));
2520 // .per_axis_wrap_mode
2528 { "texture_2d", false },
2529 { "texture_3d", true },
2535 tcu::Sampler::DepthStencilMode mode;
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 },
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 },
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 },
2570 tcu::TestCaseGroup* const perAxisGroup = new tcu::TestCaseGroup(m_testCtx, "per_axis_wrap_mode", "Per-axis wrapping modes");
2571 addChild(perAxisGroup);
2574 for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(targets); ++targetNdx)
2576 tcu::TestCaseGroup* const targetGroup = new tcu::TestCaseGroup(m_testCtx, targets[targetNdx].name, "Texture target test");
2577 perAxisGroup->addChild(targetGroup);
2580 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx)
2582 if (targets[targetNdx].is3D && !formats[formatNdx].supports3D)
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);
2595 for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(s_filters); ++filterNdx)
2597 const deUint32 filter = s_filters[filterNdx].filter;
2599 if (!coreFilterable && filterRequiresFilterability(filter))
2601 // skip linear on pure integers
2604 else if (s_filters[filterNdx].sampling == TextureBorderClampTest::SAMPLE_GATHER && targets[targetNdx].is3D)
2606 // skip gather on 3d
2611 tcu::TestCaseGroup* const filteringGroup = new tcu::TestCaseGroup(m_testCtx, s_filters[filterNdx].name, "Tests with specific filter");
2612 formatGroup->addChild(filteringGroup);
2614 // .s_XXX_t_XXX(_r_XXX)
2615 for (int wrapNdx = 0; wrapNdx < DE_LENGTH_OF_ARRAY(wrapConfigs); ++wrapNdx)
2617 if (wrapConfigs[wrapNdx].is3D != targets[targetNdx].is3D)
2621 for (int sizeNdx = 0; sizeNdx < 2; ++sizeNdx)
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);
2628 if (!targets[targetNdx].is3D)
2629 filteringGroup->addChild(new TextureBorderClampPerAxisCase2D(m_context,
2630 (std::string() + wrapName + sizeNameExtension).c_str(),
2636 wrapConfigs[wrapNdx].sWrap,
2637 wrapConfigs[wrapNdx].tWrap,
2638 s_filters[filterNdx].sampling));
2641 DE_ASSERT(sampleMode == tcu::Sampler::MODE_LAST);
2642 filteringGroup->addChild(new TextureBorderClampPerAxisCase3D(m_context,
2643 (std::string() + wrapName + sizeNameExtension).c_str(),
2648 wrapConfigs[wrapNdx].sWrap,
2649 wrapConfigs[wrapNdx].tWrap,
2650 wrapConfigs[wrapNdx].rWrap));
2662 // .depth_compare_mode
2670 { "depth_component16", GL_DEPTH_COMPONENT16 },
2671 { "depth_component24", GL_DEPTH_COMPONENT24 },
2672 { "depth24_stencil8", GL_DEPTH24_STENCIL8 },
2673 { "depth32f_stencil8", GL_DEPTH32F_STENCIL8 },
2676 tcu::TestCaseGroup* const compareGroup = new tcu::TestCaseGroup(m_testCtx, "depth_compare_mode", "Tests depth compare mode");
2677 addChild(compareGroup);
2679 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx)
2681 const deUint32 format = formats[formatNdx].format;
2682 tcu::TestCaseGroup* const formatGroup = new tcu::TestCaseGroup(m_testCtx, formats[formatNdx].name, "Format test");
2684 compareGroup->addChild(formatGroup);
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)
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;
2696 formatGroup->addChild(new TextureBorderClampDepthCompareCase(m_context,
2702 s_filters[filterNdx].sampling));
2707 // unused channels (A in rgb, G in stencil etc.)
2713 tcu::Sampler::DepthStencilMode mode;
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 },
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);
2737 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx)
2739 unusedGroup->addChild(new TextureBorderClampUnusedChannelCase(m_context,
2740 formats[formatNdx].name,
2742 formats[formatNdx].format,
2743 formats[formatNdx].mode));