Update tests to not trigger undefined behaviour in framebuffer_fetch cases
authorVihanakangas <venni.ihanakangas@siru.fi>
Fri, 28 Aug 2020 09:59:24 +0000 (12:59 +0300)
committerAlexander Galazin <Alexander.Galazin@arm.com>
Fri, 20 Nov 2020 11:03:29 +0000 (06:03 -0500)
Some framebuffer_fetch cases had an integer format conversion which
resulted in overflow. The shader and reference texture generation have been
modified to take this in to account when creating values
in such way that it doesn't overflow the max range of the format.

Affects:

dEQP-GLES31.functional.shaders.framebuffer_fetch.framebuffer_format.*

Components: OpenGL

VK-GL-CTS issue: 2016

Change-Id: I686f6548cafee13dd2a0f564bb302d269ca6b0a0

modules/gles31/functional/es31fShaderFramebufferFetchTests.cpp

index c8a0d86..226b05a 100644 (file)
@@ -370,8 +370,29 @@ string FramebufferFetchTestCase::genPassThroughVertSource (void)
 
 glu::ProgramSources FramebufferFetchTestCase::genShaderSources (void)
 {
-       const string            vecType = getColorOutputType(m_texFmt);
-       std::ostringstream      fragShaderSource;
+       const string                            vecType = getColorOutputType(m_texFmt);
+       std::ostringstream                      fragShaderSource;
+       tcu::TextureChannelClass        textureChannelClass = tcu::getTextureChannelClass(m_texFmt.type);
+       tcu::Vec4                                       maxValue = getTextureFormatInfo(m_texFmt).valueMax;
+       tcu::Vec4                                       minValue = getTextureFormatInfo(m_texFmt).valueMin;
+       string                                          maxStr;
+       string                                          minStr;
+
+       if (textureChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
+       {
+               maxStr = de::toString(maxValue.asUint());
+               minStr = de::toString(minValue.asUint());
+       }
+       else if (textureChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
+       {
+               maxStr = de::toString(maxValue.asInt());
+               minStr = de::toString(minValue.asInt());
+       }
+       else
+       {
+               maxStr = de::toString(maxValue);
+               minStr = de::toString(minValue);
+       }
 
        fragShaderSource        << "#version 310 es\n"
                                                << "#extension GL_EXT_shader_framebuffer_fetch : require\n"
@@ -380,7 +401,7 @@ glu::ProgramSources FramebufferFetchTestCase::genShaderSources (void)
                                                << "\n"
                                                << "void main (void)\n"
                                                << "{\n"
-                                               << "    o_color += u_color;\n"
+                                               << "    o_color = clamp(o_color + u_color, " << vecType << minStr << ", " << vecType << maxStr << ");\n"
                                                << "}\n";
 
        return glu::makeVtxFragSources(genPassThroughVertSource(), fragShaderSource.str());
@@ -568,24 +589,28 @@ tcu::TextureLevel TextureFormatTestCase::genReferenceTexture (const tcu::Vec4& f
        tcu::TextureLevel                       reference                       (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
        tcu::TextureChannelClass        textureChannelClass = tcu::getTextureChannelClass(m_texFmt.type);
 
+       tcu::Vec4 formatMaxValue = getTextureFormatInfo(m_texFmt).valueMax;
+       tcu::Vec4 formatMinValue = getTextureFormatInfo(m_texFmt).valueMin;
+
+
        if (textureChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
        {
-               tcu::clear(reference.getAccess(), fbColor.asUint() + uniformColor.asUint());
+               tcu::clear(reference.getAccess(), tcu::clamp(fbColor.asUint() + uniformColor.asUint(), formatMinValue.asUint(), formatMaxValue.asUint()));
        }
        else if (textureChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
        {
-               tcu::clear(reference.getAccess(), fbColor.asInt() + uniformColor.asInt());
+               tcu::clear(reference.getAccess(), tcu::clamp(fbColor.asInt() + uniformColor.asInt(), formatMinValue.asInt(), formatMaxValue.asInt()));
        }
        else
        {
                if (tcu::isSRGB(m_texFmt))
                {
-                       const tcu::Vec4 fragmentColor = tcu::sRGBToLinear(fbColor) + uniformColor;
+                       const tcu::Vec4 fragmentColor = tcu::clamp(tcu::sRGBToLinear(fbColor) + uniformColor, formatMinValue, formatMaxValue);
                        tcu::clear(reference.getAccess(), tcu::linearToSRGB(fragmentColor));
                }
                else
                {
-                       tcu::clear(reference.getAccess(), fbColor + uniformColor);
+                       tcu::clear(reference.getAccess(), tcu::clamp(fbColor + uniformColor, formatMinValue, formatMaxValue));
                }
        }