You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1459 lines
50 KiB
1459 lines
50 KiB
/*-------------------------------------------------------------------------
|
|
* drawElements Quality Program OpenGL ES 3.1 Module
|
|
* -------------------------------------------------
|
|
*
|
|
* Copyright 2017 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*
|
|
*//*!
|
|
* \file
|
|
* \brief EXT Shader Framebuffer Fetch Tests.
|
|
*//*--------------------------------------------------------------------*/
|
|
|
|
#include "es31fShaderFramebufferFetchTests.hpp"
|
|
#include "es31fFboTestUtil.hpp"
|
|
|
|
#include "tcuTestLog.hpp"
|
|
#include "tcuSurface.hpp"
|
|
#include "tcuTextureUtil.hpp"
|
|
#include "tcuImageCompare.hpp"
|
|
#include "tcuVectorUtil.hpp"
|
|
|
|
#include "gluShaderProgram.hpp"
|
|
#include "gluPixelTransfer.hpp"
|
|
#include "gluTextureUtil.hpp"
|
|
#include "gluContextInfo.hpp"
|
|
#include "gluObjectWrapper.hpp"
|
|
|
|
#include "glwFunctions.hpp"
|
|
#include "glwEnums.hpp"
|
|
|
|
#include "deStringUtil.hpp"
|
|
|
|
#include <vector>
|
|
|
|
namespace deqp
|
|
{
|
|
namespace gles31
|
|
{
|
|
namespace Functional
|
|
{
|
|
namespace
|
|
{
|
|
|
|
using std::vector;
|
|
using std::string;
|
|
using tcu::TestLog;
|
|
|
|
using namespace glw;
|
|
using namespace FboTestUtil;
|
|
|
|
static void checkExtensionSupport (Context& context, const char* extName)
|
|
{
|
|
if (!context.getContextInfo().isExtensionSupported(extName))
|
|
throw tcu::NotSupportedError(string(extName) + " not supported");
|
|
}
|
|
|
|
static void checkFramebufferFetchSupport (Context& context)
|
|
{
|
|
checkExtensionSupport(context, "GL_EXT_shader_framebuffer_fetch");
|
|
}
|
|
|
|
static bool isRequiredFormat (deUint32 format, glu::RenderContext& renderContext)
|
|
{
|
|
const bool isES32 = glu::contextSupports(renderContext.getType(), glu::ApiType::es(3, 2));
|
|
switch (format)
|
|
{
|
|
// Color-renderable formats
|
|
case GL_RGBA32I:
|
|
case GL_RGBA32UI:
|
|
case GL_RGBA16I:
|
|
case GL_RGBA16UI:
|
|
case GL_RGBA8:
|
|
case GL_RGBA8I:
|
|
case GL_RGBA8UI:
|
|
case GL_SRGB8_ALPHA8:
|
|
case GL_RGB10_A2:
|
|
case GL_RGB10_A2UI:
|
|
case GL_RGBA4:
|
|
case GL_RGB5_A1:
|
|
case GL_RGB8:
|
|
case GL_RGB565:
|
|
case GL_RG32I:
|
|
case GL_RG32UI:
|
|
case GL_RG16I:
|
|
case GL_RG16UI:
|
|
case GL_RG8:
|
|
case GL_RG8I:
|
|
case GL_RG8UI:
|
|
case GL_R32I:
|
|
case GL_R32UI:
|
|
case GL_R16I:
|
|
case GL_R16UI:
|
|
case GL_R8:
|
|
case GL_R8I:
|
|
case GL_R8UI:
|
|
return true;
|
|
|
|
// Float format
|
|
case GL_RGBA32F:
|
|
case GL_RGB32F:
|
|
case GL_R11F_G11F_B10F:
|
|
case GL_RG32F:
|
|
case GL_R32F:
|
|
return isES32;
|
|
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
tcu::TextureFormat getReadPixelFormat (const tcu::TextureFormat& format)
|
|
{
|
|
switch (tcu::getTextureChannelClass(format.type))
|
|
{
|
|
case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
|
|
return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT32);
|
|
|
|
case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
|
|
return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::SIGNED_INT32);
|
|
|
|
case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
|
|
case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
|
|
return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8);
|
|
|
|
case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
|
|
return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT);
|
|
|
|
default:
|
|
DE_ASSERT(false);
|
|
return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8);
|
|
}
|
|
}
|
|
|
|
tcu::Vec4 getFixedPointFormatThreshold (const tcu::TextureFormat& sourceFormat, const tcu::TextureFormat& readPixelsFormat)
|
|
{
|
|
DE_ASSERT(tcu::getTextureChannelClass(sourceFormat.type) != tcu::TEXTURECHANNELCLASS_FLOATING_POINT);
|
|
DE_ASSERT(tcu::getTextureChannelClass(readPixelsFormat.type) != tcu::TEXTURECHANNELCLASS_FLOATING_POINT);
|
|
|
|
DE_ASSERT(tcu::getTextureChannelClass(sourceFormat.type) != tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER);
|
|
DE_ASSERT(tcu::getTextureChannelClass(readPixelsFormat.type) != tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER);
|
|
|
|
DE_ASSERT(tcu::getTextureChannelClass(sourceFormat.type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER);
|
|
DE_ASSERT(tcu::getTextureChannelClass(readPixelsFormat.type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER);
|
|
|
|
const tcu::IVec4 srcBits = tcu::getTextureFormatBitDepth(sourceFormat);
|
|
const tcu::IVec4 readBits = tcu::getTextureFormatBitDepth(readPixelsFormat);
|
|
|
|
return tcu::Vec4(3.0f) / ((tcu::Vector<deUint64, 4>(1) << (tcu::min(srcBits, readBits).cast<deUint64>())) - tcu::Vector<deUint64, 4>(1)).cast<float>();
|
|
}
|
|
|
|
tcu::UVec4 getFloatULPThreshold (const tcu::TextureFormat& sourceFormat, const tcu::TextureFormat& readPixelsFormat)
|
|
{
|
|
const tcu::IVec4 srcMantissaBits = tcu::getTextureFormatMantissaBitDepth(sourceFormat);
|
|
const tcu::IVec4 readMantissaBits = tcu::getTextureFormatMantissaBitDepth(readPixelsFormat);
|
|
tcu::IVec4 ULPDiff(0);
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
if (readMantissaBits[i] >= srcMantissaBits[i])
|
|
ULPDiff[i] = readMantissaBits[i] - srcMantissaBits[i];
|
|
|
|
return tcu::UVec4(4) * (tcu::UVec4(1) << (ULPDiff.cast<deUint32>()));
|
|
}
|
|
|
|
static bool isAnyExtensionSupported (Context& context, const std::vector<std::string>& requiredExts)
|
|
{
|
|
for (std::vector<std::string>::const_iterator iter = requiredExts.begin(); iter != requiredExts.end(); iter++)
|
|
{
|
|
const std::string& extension = *iter;
|
|
|
|
if (context.getContextInfo().isExtensionSupported(extension.c_str()))
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
static std::string getColorOutputType(tcu::TextureFormat format)
|
|
{
|
|
switch (tcu::getTextureChannelClass(format.type))
|
|
{
|
|
case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: return "uvec4";
|
|
case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: return "ivec4";
|
|
case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
|
|
case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
|
|
case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: return "vec4";
|
|
default:
|
|
DE_FATAL("Unsupported TEXTURECHANNELCLASS");
|
|
return "";
|
|
}
|
|
}
|
|
|
|
static std::vector<std::string> getEnablingExtensions (deUint32 format, glu::RenderContext& renderContext)
|
|
{
|
|
const bool isES32 = glu::contextSupports(renderContext.getType(), glu::ApiType::es(3, 2));
|
|
std::vector<std::string> out;
|
|
|
|
DE_ASSERT(!isRequiredFormat(format, renderContext));
|
|
|
|
switch (format)
|
|
{
|
|
case GL_RGB16F:
|
|
out.push_back("GL_EXT_color_buffer_half_float");
|
|
break;
|
|
|
|
case GL_RGBA16F:
|
|
case GL_RG16F:
|
|
case GL_R16F:
|
|
out.push_back("GL_EXT_color_buffer_half_float");
|
|
// Fallthrough
|
|
|
|
case GL_RGBA32F:
|
|
case GL_RGB32F:
|
|
case GL_R11F_G11F_B10F:
|
|
case GL_RG32F:
|
|
case GL_R32F:
|
|
if (!isES32)
|
|
out.push_back("GL_EXT_color_buffer_float");
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return out;
|
|
}
|
|
|
|
void checkFormatSupport (Context& context, deUint32 sizedFormat)
|
|
{
|
|
const bool isCoreFormat = isRequiredFormat(sizedFormat, context.getRenderContext());
|
|
const std::vector<std::string> requiredExts = (!isCoreFormat) ? getEnablingExtensions(sizedFormat, context.getRenderContext()) : std::vector<std::string>();
|
|
|
|
// Check that we don't try to use invalid formats.
|
|
DE_ASSERT(isCoreFormat || !requiredExts.empty());
|
|
|
|
if (!requiredExts.empty() && !isAnyExtensionSupported(context, requiredExts))
|
|
throw tcu::NotSupportedError("Format not supported");
|
|
}
|
|
|
|
tcu::Vec4 scaleColorValue (tcu::TextureFormat format, const tcu::Vec4& color)
|
|
{
|
|
const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(format);
|
|
const tcu::Vec4 cScale = fmtInfo.valueMax-fmtInfo.valueMin;
|
|
const tcu::Vec4 cBias = fmtInfo.valueMin;
|
|
|
|
return tcu::RGBA(color).toVec() * cScale + cBias;
|
|
}
|
|
|
|
// Base class for framebuffer fetch test cases
|
|
|
|
class FramebufferFetchTestCase : public TestCase
|
|
{
|
|
public:
|
|
FramebufferFetchTestCase (Context& context, const char* name, const char* desc, deUint32 format);
|
|
~FramebufferFetchTestCase (void);
|
|
|
|
void init (void);
|
|
void deinit (void);
|
|
|
|
protected:
|
|
string genPassThroughVertSource (void);
|
|
virtual glu::ProgramSources genShaderSources (void);
|
|
|
|
void genFramebufferWithTexture (const tcu::Vec4& color);
|
|
void genAttachementTexture (const tcu::Vec4& color);
|
|
void genUniformColor (const tcu::Vec4& color);
|
|
|
|
void render (void);
|
|
void verifyRenderbuffer (TestLog& log, const tcu::TextureFormat& format, const tcu::TextureLevel& reference, const tcu::TextureLevel& result);
|
|
|
|
const glw::Functions& m_gl;
|
|
const deUint32 m_format;
|
|
|
|
glu::ShaderProgram* m_program;
|
|
GLuint m_framebuffer;
|
|
GLuint m_texColorBuffer;
|
|
|
|
tcu::TextureFormat m_texFmt;
|
|
glu::TransferFormat m_transferFmt;
|
|
bool m_isFilterable;
|
|
|
|
enum
|
|
{
|
|
VIEWPORT_WIDTH = 64,
|
|
VIEWPORT_HEIGHT = 64,
|
|
};
|
|
};
|
|
|
|
FramebufferFetchTestCase::FramebufferFetchTestCase (Context& context, const char* name, const char* desc, deUint32 format)
|
|
: TestCase (context, name, desc)
|
|
, m_gl (m_context.getRenderContext().getFunctions())
|
|
, m_format (format)
|
|
, m_program (DE_NULL)
|
|
, m_framebuffer (0)
|
|
, m_texColorBuffer (0)
|
|
, m_texFmt (glu::mapGLInternalFormat(m_format))
|
|
, m_transferFmt (glu::getTransferFormat(m_texFmt))
|
|
, m_isFilterable (glu::isGLInternalColorFormatFilterable(m_format))
|
|
{
|
|
}
|
|
|
|
FramebufferFetchTestCase::~FramebufferFetchTestCase (void)
|
|
{
|
|
FramebufferFetchTestCase::deinit();
|
|
}
|
|
|
|
void FramebufferFetchTestCase::init (void)
|
|
{
|
|
checkFramebufferFetchSupport (m_context);
|
|
checkFormatSupport(m_context, m_format);
|
|
|
|
DE_ASSERT(!m_program);
|
|
m_program = new glu::ShaderProgram(m_context.getRenderContext(), genShaderSources());
|
|
|
|
m_testCtx.getLog() << *m_program;
|
|
|
|
if (!m_program->isOk())
|
|
{
|
|
delete m_program;
|
|
m_program = DE_NULL;
|
|
TCU_FAIL("Failed to compile shader program");
|
|
}
|
|
|
|
m_gl.useProgram(m_program->getProgram());
|
|
}
|
|
|
|
void FramebufferFetchTestCase::deinit (void)
|
|
{
|
|
delete m_program;
|
|
m_program = DE_NULL;
|
|
|
|
if (m_framebuffer)
|
|
{
|
|
m_gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
m_gl.deleteFramebuffers(1, &m_framebuffer);
|
|
m_framebuffer = 0;
|
|
}
|
|
|
|
if (m_texColorBuffer)
|
|
{
|
|
m_gl.deleteTextures(1, &m_texColorBuffer);
|
|
m_texColorBuffer = 0;
|
|
}
|
|
}
|
|
|
|
string FramebufferFetchTestCase::genPassThroughVertSource (void)
|
|
{
|
|
std::ostringstream vertShaderSource;
|
|
|
|
vertShaderSource << "#version 310 es\n"
|
|
<< "in highp vec4 a_position;\n"
|
|
<< "\n"
|
|
<< "void main (void)\n"
|
|
<< "{\n"
|
|
<< " gl_Position = a_position;\n"
|
|
<< "}\n";
|
|
|
|
return vertShaderSource.str();
|
|
}
|
|
|
|
glu::ProgramSources FramebufferFetchTestCase::genShaderSources (void)
|
|
{
|
|
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"
|
|
<< "layout(location = 0) inout highp " << vecType << " o_color;\n"
|
|
<< "uniform highp " << vecType << " u_color;\n"
|
|
<< "\n"
|
|
<< "void main (void)\n"
|
|
<< "{\n"
|
|
<< " o_color = clamp(o_color + u_color, " << vecType << minStr << ", " << vecType << maxStr << ");\n"
|
|
<< "}\n";
|
|
|
|
return glu::makeVtxFragSources(genPassThroughVertSource(), fragShaderSource.str());
|
|
}
|
|
|
|
void FramebufferFetchTestCase::genFramebufferWithTexture (const tcu::Vec4& color)
|
|
{
|
|
m_gl.genFramebuffers(1, &m_framebuffer);
|
|
m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
|
|
|
|
genAttachementTexture(color);
|
|
GLU_EXPECT_NO_ERROR(m_gl.getError(), "genAttachementTexture()");
|
|
|
|
m_gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texColorBuffer, 0);
|
|
TCU_CHECK(m_gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
|
|
}
|
|
|
|
void FramebufferFetchTestCase::genAttachementTexture (const tcu::Vec4& color)
|
|
{
|
|
tcu::TextureLevel data (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
|
|
tcu::TextureChannelClass textureChannelClass = tcu::getTextureChannelClass(m_texFmt.type);
|
|
|
|
m_gl.genTextures(1, &m_texColorBuffer);
|
|
m_gl.bindTexture(GL_TEXTURE_2D, m_texColorBuffer);
|
|
|
|
m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
|
m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_isFilterable ? GL_LINEAR : GL_NEAREST);
|
|
m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, m_isFilterable ? GL_LINEAR : GL_NEAREST);
|
|
|
|
if (textureChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
|
|
tcu::clear(data.getAccess(), color.asUint());
|
|
else if (textureChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
|
|
tcu::clear(data.getAccess(), color.asInt());
|
|
else
|
|
tcu::clear(data.getAccess(), color);
|
|
|
|
m_gl.texImage2D(GL_TEXTURE_2D, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 0, m_transferFmt.format, m_transferFmt.dataType, data.getAccess().getDataPtr());
|
|
m_gl.bindTexture(GL_TEXTURE_2D, 0);
|
|
}
|
|
|
|
void FramebufferFetchTestCase::verifyRenderbuffer (TestLog& log, const tcu::TextureFormat& format, const tcu::TextureLevel& reference, const tcu::TextureLevel& result)
|
|
{
|
|
m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
|
|
|
|
switch (tcu::getTextureChannelClass(format.type))
|
|
{
|
|
case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
|
|
{
|
|
const string name = "Renderbuffer";
|
|
const string desc = "Compare renderbuffer (floating_point)";
|
|
const tcu::UVec4 threshold = getFloatULPThreshold(format, result.getFormat());
|
|
|
|
if (!tcu::floatUlpThresholdCompare(log, name.c_str(), desc.c_str(), reference, result, threshold, tcu::COMPARE_LOG_RESULT))
|
|
m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
|
|
|
|
break;
|
|
}
|
|
|
|
case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
|
|
case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
|
|
{
|
|
const string name = "Renderbuffer";
|
|
const string desc = "Compare renderbuffer (integer)";
|
|
const tcu::UVec4 threshold (1, 1, 1, 1);
|
|
|
|
if (!tcu::intThresholdCompare(log, name.c_str(), desc.c_str(), reference, result, threshold, tcu::COMPARE_LOG_RESULT))
|
|
m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
|
|
|
|
break;
|
|
}
|
|
|
|
case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
|
|
case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
|
|
{
|
|
const string name = "Renderbuffer";
|
|
const string desc = "Compare renderbuffer (fixed point)";
|
|
const tcu::Vec4 threshold = getFixedPointFormatThreshold(format, result.getFormat());
|
|
|
|
if (!tcu::floatThresholdCompare(log, name.c_str(), desc.c_str(), reference, result, threshold, tcu::COMPARE_LOG_RESULT))
|
|
m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
|
|
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
DE_ASSERT(DE_FALSE);
|
|
m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
|
|
}
|
|
}
|
|
}
|
|
|
|
void FramebufferFetchTestCase::genUniformColor (const tcu::Vec4& color)
|
|
{
|
|
const GLuint colorLocation = m_gl.getUniformLocation(m_program->getProgram(), "u_color");
|
|
|
|
switch (tcu::getTextureChannelClass(m_texFmt.type))
|
|
{
|
|
case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
|
|
{
|
|
m_gl.uniform4uiv(colorLocation, 1, color.asUint().getPtr());
|
|
break;
|
|
}
|
|
|
|
case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
|
|
{
|
|
m_gl.uniform4iv(colorLocation, 1, color.asInt().getPtr());
|
|
break;
|
|
}
|
|
case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
|
|
case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
|
|
case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
|
|
{
|
|
m_gl.uniform4fv(colorLocation, 1, color.asFloat().getPtr());
|
|
break;
|
|
}
|
|
default:
|
|
DE_ASSERT(DE_FALSE);
|
|
}
|
|
|
|
GLU_EXPECT_NO_ERROR(m_gl.getError(), "genUniformColor()");
|
|
}
|
|
|
|
void FramebufferFetchTestCase::render (void)
|
|
{
|
|
const GLfloat coords[] =
|
|
{
|
|
-1.0f, -1.0f,
|
|
+1.0f, -1.0f,
|
|
+1.0f, +1.0f,
|
|
-1.0f, +1.0f,
|
|
};
|
|
|
|
const GLushort indices[] =
|
|
{
|
|
0, 1, 2, 2, 3, 0,
|
|
};
|
|
|
|
GLuint vaoID;
|
|
m_gl.genVertexArrays(1, &vaoID);
|
|
m_gl.bindVertexArray(vaoID);
|
|
|
|
const GLuint coordLocation = m_gl.getAttribLocation(m_program->getProgram(), "a_position");
|
|
|
|
m_gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
|
|
|
|
glu::Buffer coordinatesBuffer(m_context.getRenderContext());
|
|
glu::Buffer elementsBuffer(m_context.getRenderContext());
|
|
|
|
m_gl.bindBuffer(GL_ARRAY_BUFFER, *coordinatesBuffer);
|
|
m_gl.bufferData(GL_ARRAY_BUFFER, (GLsizeiptr)sizeof(coords), coords, GL_STATIC_DRAW);
|
|
m_gl.enableVertexAttribArray(coordLocation);
|
|
m_gl.vertexAttribPointer(coordLocation, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL);
|
|
|
|
m_gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, *elementsBuffer);
|
|
m_gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)sizeof(indices), &indices[0], GL_STATIC_DRAW);
|
|
|
|
m_gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, DE_NULL);
|
|
GLU_EXPECT_NO_ERROR(m_gl.getError(), "render()");
|
|
|
|
m_gl.deleteVertexArrays(1, &vaoID);
|
|
}
|
|
|
|
// Test description:
|
|
// - Attach texture containing solid color to framebuffer.
|
|
// - Draw full quad covering the entire viewport.
|
|
// - Sum framebuffer read color with passed in uniform color.
|
|
// - Compare resulting surface with reference.
|
|
|
|
class TextureFormatTestCase : public FramebufferFetchTestCase
|
|
{
|
|
public:
|
|
TextureFormatTestCase (Context& context, const char* name, const char* desc, deUint32 format);
|
|
~TextureFormatTestCase (void) {};
|
|
|
|
IterateResult iterate (void);
|
|
|
|
private:
|
|
tcu::TextureLevel genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor);
|
|
};
|
|
|
|
TextureFormatTestCase::TextureFormatTestCase (Context& context, const char* name, const char* desc, deUint32 format)
|
|
: FramebufferFetchTestCase(context, name, desc, format)
|
|
{
|
|
}
|
|
|
|
tcu::TextureLevel TextureFormatTestCase::genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor)
|
|
{
|
|
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(), tcu::clamp(fbColor.asUint() + uniformColor.asUint(), formatMinValue.asUint(), formatMaxValue.asUint()));
|
|
}
|
|
else if (textureChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
|
|
{
|
|
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::clamp(tcu::sRGBToLinear(fbColor) + uniformColor, formatMinValue, formatMaxValue);
|
|
tcu::clear(reference.getAccess(), tcu::linearToSRGB(fragmentColor));
|
|
}
|
|
else
|
|
{
|
|
tcu::clear(reference.getAccess(), tcu::clamp(fbColor + uniformColor, formatMinValue, formatMaxValue));
|
|
}
|
|
}
|
|
|
|
return reference;
|
|
}
|
|
|
|
TextureFormatTestCase::IterateResult TextureFormatTestCase::iterate (void)
|
|
{
|
|
const tcu::Vec4 uniformColor = scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.1f, 0.1f, 1.0f));
|
|
const tcu::Vec4 fbColor = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f));
|
|
|
|
tcu::TextureLevel reference = genReferenceTexture(fbColor, uniformColor);
|
|
tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
|
|
|
|
genFramebufferWithTexture(fbColor);
|
|
genUniformColor(uniformColor);
|
|
render();
|
|
|
|
glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
|
|
verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
|
|
|
|
return STOP;
|
|
}
|
|
|
|
// Test description:
|
|
// - Attach multiple textures containing solid colors to framebuffer.
|
|
// - Draw full quad covering the entire viewport.
|
|
// - For each render target sum framebuffer read color with passed in uniform color.
|
|
// - Compare resulting surfaces with references.
|
|
|
|
class MultipleRenderTargetsTestCase : public FramebufferFetchTestCase
|
|
{
|
|
public:
|
|
MultipleRenderTargetsTestCase (Context& context, const char* name, const char* desc, deUint32 format);
|
|
~MultipleRenderTargetsTestCase (void);
|
|
|
|
IterateResult iterate (void);
|
|
void deinit (void);
|
|
|
|
private:
|
|
void genFramebufferWithTextures (const vector<tcu::Vec4>& colors);
|
|
void genAttachmentTextures (const vector<tcu::Vec4>& colors);
|
|
tcu::TextureLevel genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor);
|
|
glu::ProgramSources genShaderSources (void);
|
|
|
|
enum
|
|
{
|
|
MAX_COLOR_BUFFERS = 4
|
|
};
|
|
|
|
GLuint m_texColorBuffers [MAX_COLOR_BUFFERS];
|
|
GLenum m_colorBuffers [MAX_COLOR_BUFFERS];
|
|
};
|
|
|
|
MultipleRenderTargetsTestCase::MultipleRenderTargetsTestCase (Context& context, const char* name, const char* desc, deUint32 format)
|
|
: FramebufferFetchTestCase(context, name, desc, format)
|
|
, m_texColorBuffers ()
|
|
{
|
|
m_colorBuffers[0] = GL_COLOR_ATTACHMENT0;
|
|
m_colorBuffers[1] = GL_COLOR_ATTACHMENT1;
|
|
m_colorBuffers[2] = GL_COLOR_ATTACHMENT2;
|
|
m_colorBuffers[3] = GL_COLOR_ATTACHMENT3;
|
|
}
|
|
|
|
MultipleRenderTargetsTestCase::~MultipleRenderTargetsTestCase (void)
|
|
{
|
|
MultipleRenderTargetsTestCase::deinit();
|
|
}
|
|
|
|
void MultipleRenderTargetsTestCase::deinit (void)
|
|
{
|
|
// Clean up texture data
|
|
for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_texColorBuffers); ++i)
|
|
{
|
|
if (m_texColorBuffers[i])
|
|
m_context.getRenderContext().getFunctions().deleteTextures(1, &m_texColorBuffers[i]);
|
|
}
|
|
|
|
FramebufferFetchTestCase::deinit();
|
|
}
|
|
|
|
void MultipleRenderTargetsTestCase::genFramebufferWithTextures (const vector<tcu::Vec4>& colors)
|
|
{
|
|
m_gl.genFramebuffers(1, &m_framebuffer);
|
|
m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
|
|
|
|
genAttachmentTextures(colors);
|
|
|
|
for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_texColorBuffers); ++i)
|
|
m_gl.framebufferTexture2D(GL_FRAMEBUFFER, m_colorBuffers[i], GL_TEXTURE_2D, m_texColorBuffers[i], 0);
|
|
|
|
TCU_CHECK(m_gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
|
|
|
|
m_gl.drawBuffers((glw::GLsizei)MAX_COLOR_BUFFERS, &m_colorBuffers[0]);
|
|
GLU_EXPECT_NO_ERROR(m_gl.getError(), "genFramebufferWithTextures()");
|
|
}
|
|
|
|
void MultipleRenderTargetsTestCase::genAttachmentTextures (const vector<tcu::Vec4>& colors)
|
|
{
|
|
tcu::TextureLevel data (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
|
|
|
|
m_gl.genTextures(MAX_COLOR_BUFFERS, m_texColorBuffers);
|
|
|
|
for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_texColorBuffers); ++i)
|
|
{
|
|
m_gl.bindTexture(GL_TEXTURE_2D, m_texColorBuffers[i]);
|
|
|
|
m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
|
m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_isFilterable ? GL_LINEAR : GL_NEAREST);
|
|
m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, m_isFilterable ? GL_LINEAR : GL_NEAREST);
|
|
|
|
clear(data.getAccess(), colors[i]);
|
|
m_gl.texImage2D(GL_TEXTURE_2D, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 0, m_transferFmt.format, m_transferFmt.dataType, data.getAccess().getDataPtr());
|
|
}
|
|
|
|
m_gl.bindTexture(GL_TEXTURE_2D, 0);
|
|
GLU_EXPECT_NO_ERROR(m_gl.getError(), "genAttachmentTextures()");
|
|
}
|
|
|
|
tcu::TextureLevel MultipleRenderTargetsTestCase::genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor)
|
|
{
|
|
tcu::TextureLevel reference (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
|
|
tcu::clear(reference.getAccess(), fbColor + uniformColor);
|
|
|
|
return reference;
|
|
}
|
|
|
|
glu::ProgramSources MultipleRenderTargetsTestCase::genShaderSources (void)
|
|
{
|
|
const string vecType = getColorOutputType(m_texFmt);
|
|
std::ostringstream fragShaderSource;
|
|
|
|
fragShaderSource << "#version 310 es\n"
|
|
<< "#extension GL_EXT_shader_framebuffer_fetch : require\n"
|
|
<< "layout(location = 0) inout highp " << vecType << " o_color0;\n"
|
|
<< "layout(location = 1) inout highp " << vecType << " o_color1;\n"
|
|
<< "layout(location = 2) inout highp " << vecType << " o_color2;\n"
|
|
<< "layout(location = 3) inout highp " << vecType << " o_color3;\n"
|
|
<< "uniform highp " << vecType << " u_color;\n"
|
|
<< "\n"
|
|
<< "void main (void)\n"
|
|
<< "{\n"
|
|
<< " o_color0 += u_color;\n"
|
|
<< " o_color1 += u_color;\n"
|
|
<< " o_color2 += u_color;\n"
|
|
<< " o_color3 += u_color;\n"
|
|
<< "}\n";
|
|
|
|
return glu::makeVtxFragSources(genPassThroughVertSource(), fragShaderSource.str());
|
|
}
|
|
|
|
MultipleRenderTargetsTestCase::IterateResult MultipleRenderTargetsTestCase::iterate (void)
|
|
{
|
|
const tcu::Vec4 uniformColor = scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.1f, 0.1f, 1.0f));
|
|
tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
|
|
|
|
vector<tcu::Vec4> colors;
|
|
colors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.9f, 0.0f, 0.0f, 1.0f)));
|
|
colors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.9f, 0.0f, 1.0f)));
|
|
colors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.0f, 0.9f, 1.0f)));
|
|
colors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.9f, 0.9f, 1.0f)));
|
|
|
|
genFramebufferWithTextures(colors);
|
|
genUniformColor(uniformColor);
|
|
render();
|
|
|
|
for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_colorBuffers); ++i)
|
|
{
|
|
tcu::TextureLevel reference = genReferenceTexture(colors[i], uniformColor);
|
|
|
|
m_gl.readBuffer(m_colorBuffers[i]);
|
|
glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
|
|
verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
|
|
}
|
|
|
|
return STOP;
|
|
}
|
|
|
|
// Test description:
|
|
// - Same as TextureFormatTestCase except uses built-in fragment output of ES 2.0
|
|
|
|
class LastFragDataTestCase : public FramebufferFetchTestCase
|
|
{
|
|
public:
|
|
LastFragDataTestCase (Context& context, const char* name, const char* desc, deUint32 format);
|
|
~LastFragDataTestCase (void) {};
|
|
|
|
IterateResult iterate (void);
|
|
|
|
private:
|
|
glu::ProgramSources genShaderSources (void);
|
|
tcu::TextureLevel genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor);
|
|
};
|
|
|
|
LastFragDataTestCase::LastFragDataTestCase (Context& context, const char* name, const char* desc, deUint32 format)
|
|
: FramebufferFetchTestCase(context, name, desc, format)
|
|
{
|
|
}
|
|
|
|
glu::ProgramSources LastFragDataTestCase::genShaderSources (void)
|
|
{
|
|
const string vecType = getColorOutputType(m_texFmt);
|
|
std::ostringstream vertShaderSource;
|
|
std::ostringstream fragShaderSource;
|
|
|
|
vertShaderSource << "#version 100\n"
|
|
<< "attribute vec4 a_position;\n"
|
|
<< "\n"
|
|
<< "void main (void)\n"
|
|
<< "{\n"
|
|
<< " gl_Position = a_position;\n"
|
|
<< "}\n";
|
|
|
|
fragShaderSource << "#version 100\n"
|
|
<< "#extension GL_EXT_shader_framebuffer_fetch : require\n"
|
|
<< "uniform highp " << vecType << " u_color;\n"
|
|
<< "\n"
|
|
<< "void main (void)\n"
|
|
<< "{\n"
|
|
<< " gl_FragColor = u_color + gl_LastFragData[0];\n"
|
|
<< "}\n";
|
|
|
|
return glu::makeVtxFragSources(vertShaderSource.str(), fragShaderSource.str());
|
|
}
|
|
|
|
tcu::TextureLevel LastFragDataTestCase::genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor)
|
|
{
|
|
tcu::TextureLevel reference (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
|
|
tcu::clear(reference.getAccess(), fbColor + uniformColor);
|
|
|
|
return reference;
|
|
}
|
|
|
|
LastFragDataTestCase::IterateResult LastFragDataTestCase::iterate (void)
|
|
{
|
|
const tcu::Vec4 uniformColor = scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.1f, 0.1f, 1.0f));
|
|
const tcu::Vec4 fbColor = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f));
|
|
|
|
tcu::TextureLevel reference = genReferenceTexture(fbColor, uniformColor);
|
|
tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
|
|
|
|
genFramebufferWithTexture(fbColor);
|
|
genUniformColor(uniformColor);
|
|
render();
|
|
|
|
glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
|
|
verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
|
|
|
|
return STOP;
|
|
}
|
|
|
|
// Test description:
|
|
// - Attach texture containing solid color to framebuffer.
|
|
// - Create one 2D texture for sampler with a grid pattern
|
|
// - Draw full screen quad covering the entire viewport.
|
|
// - Sum color values taken from framebuffer texture and sampled texture
|
|
// - Compare resulting surface with reference.
|
|
|
|
class TexelFetchTestCase : public FramebufferFetchTestCase
|
|
{
|
|
public:
|
|
TexelFetchTestCase (Context& context, const char* name, const char* desc, deUint32 format);
|
|
~TexelFetchTestCase (void) {}
|
|
|
|
IterateResult iterate (void);
|
|
|
|
private:
|
|
glu::ProgramSources genShaderSources (void);
|
|
tcu::TextureLevel genReferenceTexture (const tcu::Vec4& colorEven, const tcu::Vec4& colorOdd, const tcu::Vec4& fbColor);
|
|
void genSamplerTexture (const tcu::Vec4& colorEven, const tcu::Vec4& colorOdd);
|
|
|
|
GLuint m_samplerTexture;
|
|
};
|
|
|
|
TexelFetchTestCase::TexelFetchTestCase (Context& context, const char* name, const char* desc, deUint32 format)
|
|
: FramebufferFetchTestCase(context, name, desc, format)
|
|
, m_samplerTexture(0)
|
|
{
|
|
}
|
|
|
|
void TexelFetchTestCase::genSamplerTexture (const tcu::Vec4& colorEven, const tcu::Vec4& colorOdd)
|
|
{
|
|
tcu::TextureLevel data (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
|
|
|
|
m_gl.activeTexture(GL_TEXTURE1);
|
|
|
|
m_gl.genTextures(1, &m_samplerTexture);
|
|
m_gl.bindTexture(GL_TEXTURE_2D, m_texColorBuffer);
|
|
m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
|
|
tcu::fillWithGrid(data.getAccess(), 8, colorEven, colorOdd);
|
|
|
|
m_gl.texImage2D(GL_TEXTURE_2D, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 0, m_transferFmt.format, m_transferFmt.dataType, data.getAccess().getDataPtr());
|
|
m_gl.bindTexture(GL_TEXTURE_2D, 0);
|
|
|
|
const GLuint samplerLocation = m_gl.getUniformLocation(m_program->getProgram(), "u_sampler");
|
|
m_gl.uniform1i(samplerLocation, 1);
|
|
|
|
GLU_EXPECT_NO_ERROR(m_gl.getError(), "genSamplerTexture()");
|
|
}
|
|
|
|
glu::ProgramSources TexelFetchTestCase::genShaderSources (void)
|
|
{
|
|
const string vecType = getColorOutputType(m_texFmt);
|
|
std::ostringstream fragShaderSource;
|
|
|
|
fragShaderSource << "#version 310 es\n"
|
|
<< "#extension GL_EXT_shader_framebuffer_fetch : require\n"
|
|
<< "layout(location = 0) inout highp " << vecType << " o_color;\n"
|
|
<< "\n"
|
|
<< "uniform sampler2D u_sampler;\n"
|
|
<< "void main (void)\n"
|
|
<< "{\n"
|
|
<< " o_color += texelFetch(u_sampler, ivec2(gl_FragCoord), 0);\n"
|
|
<< "}\n";
|
|
|
|
return glu::makeVtxFragSources(genPassThroughVertSource(), fragShaderSource.str());
|
|
}
|
|
|
|
tcu::TextureLevel TexelFetchTestCase::genReferenceTexture (const tcu::Vec4& colorEven, const tcu::Vec4& colorOdd, const tcu::Vec4& fbColor)
|
|
{
|
|
tcu::TextureLevel reference (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
|
|
tcu::fillWithGrid(reference.getAccess(), 8, colorEven + fbColor, colorOdd + fbColor);
|
|
|
|
return reference;
|
|
}
|
|
|
|
TexelFetchTestCase::IterateResult TexelFetchTestCase::iterate (void)
|
|
{
|
|
const tcu::Vec4 fbColor = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.5f, 1.0f));
|
|
const tcu::Vec4 colorEven = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.5f, 0.0f, 1.0f));
|
|
const tcu::Vec4 colorOdd = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.5f, 1.0f));
|
|
|
|
genSamplerTexture(colorEven, colorOdd);
|
|
tcu::TextureLevel reference = genReferenceTexture(colorEven, colorOdd, fbColor);
|
|
tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
|
|
|
|
genFramebufferWithTexture(fbColor);
|
|
render();
|
|
|
|
glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
|
|
verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
|
|
|
|
// cleanup
|
|
m_gl.deleteTextures(1, &m_samplerTexture);
|
|
|
|
return STOP;
|
|
}
|
|
|
|
// Test description:
|
|
// - Attach texture containing solid color to framebuffer.
|
|
// - Draw full screen quad covering the entire viewport.
|
|
// - Multiple assignments are made to the output color for fragments on the right vertical half of the screen.
|
|
// - A single assignment is made to the output color for fragments on the left vertical centre of the screen.
|
|
// - Values are calculated using the sum of the passed in uniform color and the previous framebuffer color.
|
|
// - Compare resulting surface with reference.
|
|
|
|
class MultipleAssignmentTestCase : public FramebufferFetchTestCase
|
|
{
|
|
public:
|
|
MultipleAssignmentTestCase (Context& context, const char* name, const char* desc, deUint32 format);
|
|
~MultipleAssignmentTestCase (void) {}
|
|
|
|
IterateResult iterate (void);
|
|
|
|
private:
|
|
glu::ProgramSources genShaderSources (void);
|
|
tcu::TextureLevel genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor);
|
|
};
|
|
|
|
MultipleAssignmentTestCase::MultipleAssignmentTestCase (Context& context, const char* name, const char* desc, deUint32 format)
|
|
: FramebufferFetchTestCase(context, name, desc, format)
|
|
{
|
|
}
|
|
|
|
glu::ProgramSources MultipleAssignmentTestCase::genShaderSources (void)
|
|
{
|
|
const string vecType = getColorOutputType(m_texFmt);
|
|
std::ostringstream vertShaderSource;
|
|
std::ostringstream fragShaderSource;
|
|
|
|
vertShaderSource << "#version 310 es\n"
|
|
<< "in highp vec4 a_position;\n"
|
|
<< "out highp vec4 v_position;\n"
|
|
<< "\n"
|
|
<< "void main (void)\n"
|
|
<< "{\n"
|
|
<< " gl_Position = a_position;\n"
|
|
<< " v_position = gl_Position;\n"
|
|
<< "}\n";
|
|
|
|
fragShaderSource << "#version 310 es\n"
|
|
<< "#extension GL_EXT_shader_framebuffer_fetch : require\n"
|
|
<< "in highp vec4 v_position;\n"
|
|
<< "layout(location = 0) inout highp " << vecType << " o_color;\n"
|
|
<< "uniform highp " << vecType << " u_color;\n"
|
|
<< "\n"
|
|
<< "void main (void)\n"
|
|
<< "{\n"
|
|
<< " if (v_position.x > 0.0f)\n"
|
|
<< " o_color += u_color;\n"
|
|
<< "\n"
|
|
<< " o_color += u_color;\n"
|
|
<< "}\n";
|
|
|
|
return glu::makeVtxFragSources(vertShaderSource.str(), fragShaderSource.str());
|
|
}
|
|
|
|
tcu::TextureLevel MultipleAssignmentTestCase::genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor)
|
|
{
|
|
tcu::TextureLevel reference (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
|
|
|
|
int width = reference.getAccess().getWidth();
|
|
int height = reference.getAccess().getHeight();
|
|
int left = width /2;
|
|
int top = height/2;
|
|
|
|
tcu::Vec4 compositeColor(uniformColor * 2.0f);
|
|
|
|
tcu::clear(getSubregion(reference.getAccess(), left, 0, 0, width-left, top, 1), fbColor + compositeColor);
|
|
tcu::clear(getSubregion(reference.getAccess(), 0, top, 0, left, height-top, 1), fbColor + uniformColor);
|
|
tcu::clear(getSubregion(reference.getAccess(), left, top, 0, width-left, height-top, 1), fbColor + compositeColor);
|
|
tcu::clear(getSubregion(reference.getAccess(), 0, 0, 0, left, top, 1), fbColor + uniformColor);
|
|
|
|
return reference;
|
|
}
|
|
|
|
MultipleAssignmentTestCase::IterateResult MultipleAssignmentTestCase::iterate (void)
|
|
{
|
|
const tcu::Vec4 fbColor = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f));
|
|
const tcu::Vec4 uniformColor = scaleColorValue(m_texFmt, tcu::Vec4(0.25f, 0.0f, 0.0f, 1.0f));
|
|
|
|
tcu::TextureLevel reference = genReferenceTexture(fbColor, uniformColor);
|
|
tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
|
|
|
|
genFramebufferWithTexture(fbColor);
|
|
genUniformColor(uniformColor);
|
|
render();
|
|
|
|
glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
|
|
verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
|
|
|
|
return STOP;
|
|
}
|
|
|
|
// Test description:
|
|
// - Attach texture containing grid pattern to framebuffer.
|
|
// - Using framebuffer reads discard odd squares in the grid.
|
|
// - The even squares framebuffer color is added to the passed in uniform color.
|
|
|
|
class FragmentDiscardTestCase : public FramebufferFetchTestCase
|
|
{
|
|
public:
|
|
FragmentDiscardTestCase (Context& context, const char* name, const char* desc, deUint32 format);
|
|
~FragmentDiscardTestCase (void) {}
|
|
|
|
IterateResult iterate (void);
|
|
|
|
private:
|
|
glu::ProgramSources genShaderSources (void);
|
|
void genFramebufferWithGrid (const tcu::Vec4& fbColorEven, const tcu::Vec4& fbColorOdd);
|
|
tcu::TextureLevel genReferenceTexture (const tcu::Vec4& fbColorEven, const tcu::Vec4& fbColorOdd);
|
|
};
|
|
|
|
FragmentDiscardTestCase::FragmentDiscardTestCase (Context& context, const char* name, const char* desc, deUint32 format)
|
|
: FramebufferFetchTestCase(context, name, desc, format)
|
|
{
|
|
}
|
|
|
|
glu::ProgramSources FragmentDiscardTestCase::genShaderSources (void)
|
|
{
|
|
const string vecType = getColorOutputType(m_texFmt);
|
|
std::ostringstream fragShaderSource;
|
|
|
|
fragShaderSource << "#version 310 es\n"
|
|
<< "#extension GL_EXT_shader_framebuffer_fetch : require\n"
|
|
<< "layout(location = 0) inout highp " << vecType << " o_color;\n"
|
|
<< "uniform highp " << vecType << " u_color;\n"
|
|
<< "\n"
|
|
<< "void main (void)\n"
|
|
<< "{\n"
|
|
<< " const highp float threshold = 0.0005f;\n"
|
|
<< " bool valuesEqual = all(lessThan(abs(o_color - u_color), vec4(threshold)));\n\n"
|
|
<< " if (valuesEqual)\n"
|
|
<< " o_color += u_color;\n"
|
|
<< " else\n"
|
|
<< " discard;\n"
|
|
<< "}\n";
|
|
|
|
return glu::makeVtxFragSources(genPassThroughVertSource(), fragShaderSource.str());
|
|
}
|
|
|
|
void FragmentDiscardTestCase::genFramebufferWithGrid (const tcu::Vec4& fbColorEven, const tcu::Vec4& fbColorOdd)
|
|
{
|
|
tcu::TextureLevel data (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
|
|
|
|
m_gl.genFramebuffers(1, &m_framebuffer);
|
|
m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
|
|
|
|
m_gl.genTextures(1, &m_texColorBuffer);
|
|
m_gl.bindTexture(GL_TEXTURE_2D, m_texColorBuffer);
|
|
|
|
tcu::fillWithGrid(data.getAccess(), 8, fbColorEven, fbColorOdd);
|
|
|
|
m_gl.texImage2D(GL_TEXTURE_2D, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 0, m_transferFmt.format, m_transferFmt.dataType, data.getAccess().getDataPtr());
|
|
m_gl.bindTexture(GL_TEXTURE_2D, 0);
|
|
|
|
m_gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texColorBuffer, 0);
|
|
TCU_CHECK(m_gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
|
|
}
|
|
|
|
tcu::TextureLevel FragmentDiscardTestCase::genReferenceTexture (const tcu::Vec4& fbColorEven, const tcu::Vec4& fbColorOdd)
|
|
{
|
|
tcu::TextureLevel reference (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
|
|
tcu::fillWithGrid(reference.getAccess(), 8, fbColorEven + fbColorEven, fbColorOdd);
|
|
|
|
return reference;
|
|
}
|
|
|
|
FragmentDiscardTestCase::IterateResult FragmentDiscardTestCase::iterate (void)
|
|
{
|
|
const tcu::Vec4 fbColorEven = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 1.0f, 1.0f));
|
|
const tcu::Vec4 fbColorOdd = scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 1.0f, 1.0f, 1.0f));
|
|
|
|
tcu::TextureLevel reference = genReferenceTexture(fbColorEven, fbColorOdd);
|
|
tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
|
|
genFramebufferWithGrid(fbColorEven, fbColorOdd);
|
|
|
|
genUniformColor(fbColorEven);
|
|
render();
|
|
|
|
glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
|
|
verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
|
|
|
|
return STOP;
|
|
}
|
|
|
|
// Test description:
|
|
// - Create 2D texture array containing three mipmaps.
|
|
// - Each mipmap level is assigned a different color.
|
|
// - Attach single mipmap level to framebuffer and draw full screen quad.
|
|
// - Sum framebuffer read color with passed in uniform color.
|
|
// - Compare resulting surface with reference.
|
|
// - Repeat for subsequent mipmap levels.
|
|
|
|
class TextureLevelTestCase : public FramebufferFetchTestCase
|
|
{
|
|
public:
|
|
TextureLevelTestCase (Context& context, const char* name, const char* desc, deUint32 format);
|
|
~TextureLevelTestCase (void) {}
|
|
|
|
IterateResult iterate (void);
|
|
|
|
private:
|
|
void create2DTextureArrayMipMaps (const vector<tcu::Vec4>& colors);
|
|
tcu::TextureLevel genReferenceTexture (int level, const vector<tcu::Vec4>& colors, const tcu::Vec4& uniformColor);
|
|
void genReferenceMipmap (const tcu::Vec4& color, tcu::TextureLevel& reference);
|
|
};
|
|
|
|
TextureLevelTestCase::TextureLevelTestCase (Context& context, const char* name, const char* desc, deUint32 format)
|
|
: FramebufferFetchTestCase(context, name, desc, format)
|
|
{
|
|
}
|
|
|
|
void TextureLevelTestCase::create2DTextureArrayMipMaps (const vector<tcu::Vec4>& colors)
|
|
{
|
|
int numLevels = (int)colors.size();
|
|
tcu::TextureLevel levelData (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType));
|
|
|
|
m_gl.genTextures(1, &m_texColorBuffer);
|
|
m_gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_texColorBuffer);
|
|
|
|
m_gl.texImage3D(GL_TEXTURE_2D_ARRAY, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1, 0, m_transferFmt.format, m_transferFmt.dataType, DE_NULL);
|
|
m_gl.generateMipmap(GL_TEXTURE_2D_ARRAY);
|
|
|
|
for (int level = 0; level < numLevels; level++)
|
|
{
|
|
int levelW = de::max(1, VIEWPORT_WIDTH >> level);
|
|
int levelH = de::max(1, VIEWPORT_HEIGHT >> level);
|
|
|
|
levelData.setSize(levelW, levelH, 1);
|
|
|
|
clear(levelData.getAccess(), colors[level]);
|
|
m_gl.texImage3D(GL_TEXTURE_2D_ARRAY, level, m_format, levelW, levelH, 1, 0, m_transferFmt.format, m_transferFmt.dataType, levelData.getAccess().getDataPtr());
|
|
}
|
|
|
|
m_gl.bindTexture(GL_TEXTURE_2D_ARRAY, 0);
|
|
GLU_EXPECT_NO_ERROR(m_gl.getError(), "create2DTextureArrayMipMaps()");
|
|
}
|
|
|
|
tcu::TextureLevel TextureLevelTestCase::genReferenceTexture (int level, const vector<tcu::Vec4>& colors, const tcu::Vec4& uniformColor)
|
|
{
|
|
tcu::TextureLevel reference (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH >> level, VIEWPORT_HEIGHT >> level, 1);
|
|
|
|
genReferenceMipmap(colors[level] + uniformColor, reference);
|
|
|
|
return reference;
|
|
}
|
|
|
|
void TextureLevelTestCase::genReferenceMipmap (const tcu::Vec4& color, tcu::TextureLevel& reference)
|
|
{
|
|
const int width = reference.getAccess().getWidth();
|
|
const int height = reference.getAccess().getHeight();
|
|
const int left = width / 2;
|
|
const int top = height / 2;
|
|
|
|
clear(getSubregion(reference.getAccess(), left, 0, 0, width-left, top, 1), color);
|
|
clear(getSubregion(reference.getAccess(), 0, top, 0, left, height-top, 1), color);
|
|
clear(getSubregion(reference.getAccess(), left, top, 0, width-left, height-top, 1), color);
|
|
clear(getSubregion(reference.getAccess(), 0, 0, 0, left, top, 1), color);
|
|
}
|
|
|
|
TextureLevelTestCase::IterateResult TextureLevelTestCase::iterate (void)
|
|
{
|
|
const tcu::Vec4 uniformColor = scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.0f, 0.0f, 1.0f));
|
|
vector<tcu::Vec4> levelColors;
|
|
|
|
levelColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.4f, 0.0f, 0.0f, 1.0f)));
|
|
levelColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.2f, 0.0f, 0.0f, 1.0f)));
|
|
levelColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
|
|
|
|
m_gl.genFramebuffers(1, &m_framebuffer);
|
|
m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
|
|
|
|
create2DTextureArrayMipMaps(levelColors);
|
|
|
|
// attach successive mipmap layers to framebuffer and render
|
|
for (int level = 0; level < (int)levelColors.size(); ++level)
|
|
{
|
|
std::ostringstream name, desc;
|
|
name << "Level " << level;
|
|
desc << "Mipmap level " << level;
|
|
|
|
const tcu::ScopedLogSection section (m_testCtx.getLog(), name.str(), desc.str());
|
|
tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH >> level, VIEWPORT_HEIGHT >> level);
|
|
tcu::TextureLevel reference = genReferenceTexture(level, levelColors, uniformColor);
|
|
|
|
m_gl.framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_texColorBuffer, level, 0);
|
|
|
|
genUniformColor(uniformColor);
|
|
render();
|
|
|
|
glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
|
|
verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
|
|
|
|
if (m_testCtx.getTestResult() != QP_TEST_RESULT_PASS)
|
|
return STOP;
|
|
}
|
|
|
|
return STOP;
|
|
}
|
|
|
|
class TextureLayerTestCase : public FramebufferFetchTestCase
|
|
{
|
|
public:
|
|
TextureLayerTestCase (Context& context, const char* name, const char* desc, deUint32 format);
|
|
~TextureLayerTestCase (void) {}
|
|
|
|
IterateResult iterate (void);
|
|
|
|
private:
|
|
void create2DTextureArrayLayers (const vector<tcu::Vec4>& colors);
|
|
tcu::TextureLevel genReferenceTexture (int layer, const vector<tcu::Vec4>& colors, const tcu::Vec4& uniformColor);
|
|
};
|
|
|
|
TextureLayerTestCase::TextureLayerTestCase (Context& context, const char* name, const char* desc, deUint32 format)
|
|
: FramebufferFetchTestCase(context, name, desc, format)
|
|
{
|
|
}
|
|
|
|
void TextureLayerTestCase::create2DTextureArrayLayers (const vector<tcu::Vec4>& colors)
|
|
{
|
|
int numLayers = (int)colors.size();
|
|
tcu::TextureLevel layerData (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType));
|
|
|
|
m_gl.genTextures(1, &m_texColorBuffer);
|
|
m_gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_texColorBuffer);
|
|
m_gl.texStorage3D(GL_TEXTURE_2D_ARRAY, 1, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, numLayers);
|
|
m_gl.bindImageTexture(0, m_texColorBuffer, 0, GL_FALSE, 0, GL_READ_ONLY, m_format);
|
|
|
|
layerData.setSize(VIEWPORT_WIDTH, VIEWPORT_HEIGHT, numLayers);
|
|
|
|
for (int layer = 0; layer < numLayers; layer++)
|
|
{
|
|
clear(layerData.getAccess(), colors[layer]);
|
|
m_gl.texSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, layer, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1, m_transferFmt.format, m_transferFmt.dataType, layerData.getAccess().getDataPtr());
|
|
}
|
|
|
|
m_gl.bindTexture(GL_TEXTURE_2D_ARRAY, 0);
|
|
GLU_EXPECT_NO_ERROR(m_gl.getError(), "create2DTextureArrayLayers()");
|
|
}
|
|
|
|
tcu::TextureLevel TextureLayerTestCase::genReferenceTexture (int layer, const vector<tcu::Vec4>& colors, const tcu::Vec4& uniformColor)
|
|
{
|
|
tcu::TextureLevel reference (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
|
|
clear(reference.getAccess(), colors[layer] + uniformColor);
|
|
|
|
return reference;
|
|
}
|
|
|
|
// Test description
|
|
// - Create 2D texture array containing three layers.
|
|
// - Each layer is assigned a different color.
|
|
// - Attach single layer to framebuffer and draw full screen quad.
|
|
// - Sum framebuffer read color with passed in uniform color.
|
|
// - Compare resulting surface with reference.
|
|
// - Repeat for subsequent texture layers.
|
|
|
|
TextureLayerTestCase::IterateResult TextureLayerTestCase::iterate (void)
|
|
{
|
|
const tcu::Vec4 uniformColor = scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.1f, 0.1f, 1.0f));
|
|
tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
|
|
vector<tcu::Vec4> layerColors;
|
|
|
|
layerColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.4f, 0.0f, 0.0f, 1.0f)));
|
|
layerColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.2f, 0.0f, 0.0f, 1.0f)));
|
|
layerColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
|
|
|
|
m_gl.genFramebuffers(1, &m_framebuffer);
|
|
m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
|
|
|
|
create2DTextureArrayLayers(layerColors);
|
|
|
|
for (int layer = 0; layer < (int)layerColors.size(); ++layer)
|
|
{
|
|
std::ostringstream name, desc;
|
|
name << "Layer " << layer;
|
|
desc << "Layer " << layer;
|
|
|
|
const tcu::ScopedLogSection section (m_testCtx.getLog(), name.str(), desc.str());
|
|
tcu::TextureLevel reference = genReferenceTexture(layer, layerColors, uniformColor);
|
|
|
|
m_gl.framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_texColorBuffer, 0, layer);
|
|
|
|
genUniformColor(uniformColor);
|
|
render();
|
|
|
|
glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
|
|
verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
|
|
|
|
if (m_testCtx.getTestResult() != QP_TEST_RESULT_PASS)
|
|
return STOP;
|
|
}
|
|
|
|
return STOP;
|
|
}
|
|
|
|
} // Anonymous
|
|
|
|
ShaderFramebufferFetchTests::ShaderFramebufferFetchTests (Context& context)
|
|
: TestCaseGroup (context, "framebuffer_fetch", "GL_EXT_shader_framebuffer_fetch tests")
|
|
{
|
|
}
|
|
|
|
ShaderFramebufferFetchTests::~ShaderFramebufferFetchTests (void)
|
|
{
|
|
}
|
|
|
|
void ShaderFramebufferFetchTests::init (void)
|
|
{
|
|
tcu::TestCaseGroup* const basicTestGroup = new tcu::TestCaseGroup(m_testCtx, "basic", "Basic framebuffer shader fetch tests");
|
|
tcu::TestCaseGroup* const framebufferFormatTestGroup = new tcu::TestCaseGroup(m_testCtx, "framebuffer_format", "Texture render target formats tests");
|
|
|
|
// basic
|
|
{
|
|
basicTestGroup->addChild(new TexelFetchTestCase (m_context, "texel_fetch", "Framebuffer fetches in conjunction with shader texel fetches", GL_RGBA8));
|
|
basicTestGroup->addChild(new LastFragDataTestCase (m_context, "last_frag_data", "Framebuffer fetches with built-in fragment output of ES 2.0", GL_RGBA8));
|
|
basicTestGroup->addChild(new FragmentDiscardTestCase (m_context, "fragment_discard", "Framebuffer fetches in combination with fragment discards", GL_RGBA8));
|
|
basicTestGroup->addChild(new MultipleAssignmentTestCase (m_context, "multiple_assignment", "Multiple assignments to fragment color inout", GL_RGBA8));
|
|
basicTestGroup->addChild(new MultipleRenderTargetsTestCase (m_context, "multiple_render_targets", "Framebuffer fetches used in combination with multiple render targets", GL_RGBA8));
|
|
basicTestGroup->addChild(new TextureLevelTestCase (m_context, "framebuffer_texture_level", "Framebuffer fetches with individual texture render target mipmaps", GL_RGBA8));
|
|
basicTestGroup->addChild(new TextureLayerTestCase (m_context, "framebuffer_texture_layer", "Framebuffer fetches with individual texture render target layers", GL_RGBA8));
|
|
}
|
|
|
|
// framebuffer formats
|
|
{
|
|
static const deUint32 colorFormats[] =
|
|
{
|
|
// RGBA formats
|
|
GL_RGBA32I,
|
|
GL_RGBA32UI,
|
|
GL_RGBA16I,
|
|
GL_RGBA16UI,
|
|
GL_RGBA8,
|
|
GL_RGBA8I,
|
|
GL_RGBA8UI,
|
|
GL_SRGB8_ALPHA8,
|
|
GL_RGB10_A2,
|
|
GL_RGB10_A2UI, GL_RGBA4, GL_RGB5_A1,
|
|
|
|
// RGB formats
|
|
GL_RGB8,
|
|
GL_RGB565,
|
|
|
|
// RG formats
|
|
GL_RG32I,
|
|
GL_RG32UI,
|
|
GL_RG16I,
|
|
GL_RG16UI,
|
|
GL_RG8,
|
|
GL_RG8I,
|
|
GL_RG8UI,
|
|
|
|
// R formats
|
|
GL_R32I,
|
|
GL_R32UI,
|
|
GL_R16I,
|
|
GL_R16UI,
|
|
GL_R8,
|
|
GL_R8I,
|
|
GL_R8UI,
|
|
|
|
// GL_EXT_color_buffer_float
|
|
GL_RGBA32F,
|
|
GL_RGBA16F,
|
|
GL_R11F_G11F_B10F,
|
|
GL_RG32F,
|
|
GL_RG16F,
|
|
GL_R32F,
|
|
GL_R16F,
|
|
|
|
// GL_EXT_color_buffer_half_float
|
|
GL_RGB16F
|
|
};
|
|
|
|
for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorFormats); ndx++)
|
|
framebufferFormatTestGroup->addChild(new TextureFormatTestCase(m_context, getFormatName(colorFormats[ndx]), "Framebuffer fetches from texture attachments with varying formats", colorFormats[ndx]));
|
|
}
|
|
|
|
addChild(basicTestGroup);
|
|
addChild(framebufferFormatTestGroup);
|
|
}
|
|
|
|
} // Functional
|
|
} // gles31
|
|
} // deqp
|