diff options
Diffstat (limited to 'modules/gles31/functional/es31fFboTestCase.cpp')
-rw-r--r-- | modules/gles31/functional/es31fFboTestCase.cpp | 369 |
1 files changed, 369 insertions, 0 deletions
diff --git a/modules/gles31/functional/es31fFboTestCase.cpp b/modules/gles31/functional/es31fFboTestCase.cpp new file mode 100644 index 000000000..4d03eab6d --- /dev/null +++ b/modules/gles31/functional/es31fFboTestCase.cpp @@ -0,0 +1,369 @@ +/*------------------------------------------------------------------------- + * drawElements Quality Program OpenGL ES 3.1 Module + * ------------------------------------------------- + * + * Copyright 2014 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 Base class for FBO tests. + *//*--------------------------------------------------------------------*/ + +#include "es31fFboTestCase.hpp" +#include "es31fFboTestUtil.hpp" +#include "tcuTestLog.hpp" +#include "tcuImageCompare.hpp" +#include "tcuRenderTarget.hpp" +#include "sglrGLContext.hpp" +#include "sglrReferenceContext.hpp" +#include "gluStrUtil.hpp" +#include "gluContextInfo.hpp" +#include "deRandom.hpp" +#include "glwEnums.hpp" +#include "glwFunctions.hpp" + +#include <algorithm> + +namespace deqp +{ +namespace gles31 +{ +namespace Functional +{ + +using tcu::TestLog; +using std::string; + +FboTestCase::FboTestCase (Context& context, const char* name, const char* description, bool useScreenSizedViewport) + : TestCase (context, name, description) + , m_viewportWidth (useScreenSizedViewport ? context.getRenderTarget().getWidth() : 128) + , m_viewportHeight (useScreenSizedViewport ? context.getRenderTarget().getHeight() : 128) +{ +} + +FboTestCase::~FboTestCase (void) +{ +} + +FboTestCase::IterateResult FboTestCase::iterate (void) +{ + glu::RenderContext& renderCtx = TestCase::m_context.getRenderContext(); + const tcu::RenderTarget& renderTarget = renderCtx.getRenderTarget(); + TestLog& log = m_testCtx.getLog(); + + // Viewport. + de::Random rnd (deStringHash(getName())); + int width = deMin32(renderTarget.getWidth(), m_viewportWidth); + int height = deMin32(renderTarget.getHeight(), m_viewportHeight); + int x = rnd.getInt(0, renderTarget.getWidth() - width); + int y = rnd.getInt(0, renderTarget.getHeight() - height); + + // Surface format and storage is choosen by render(). + tcu::Surface reference; + tcu::Surface result; + + // Call preCheck() that can throw exception if some requirement is not met. + preCheck(); + + log << TestLog::Message << "Rendering with GL driver" << TestLog::EndMessage; + + // Render using GLES3.1 + try + { + sglr::GLContext context(renderCtx, log, 0, tcu::IVec4(x, y, width, height)); + setContext(&context); + render(result); + + // Check error. + deUint32 err = glGetError(); + if (err != GL_NO_ERROR) + throw glu::Error(err, glu::getErrorStr(err).toString().c_str(), DE_NULL, __FILE__, __LINE__); + + setContext(DE_NULL); + } + catch (const FboTestUtil::FboIncompleteException& e) + { + if (e.getReason() == GL_FRAMEBUFFER_UNSUPPORTED) + { + log << e; + m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported"); + return STOP; + } + else + throw; + } + + log << TestLog::Message << "Rendering reference image" << TestLog::EndMessage; + + // Render reference. + { + sglr::ReferenceContextBuffers buffers (tcu::PixelFormat(8,8,8,renderTarget.getPixelFormat().alphaBits?8:0), renderTarget.getDepthBits(), renderTarget.getStencilBits(), width, height); + sglr::ReferenceContext context (sglr::ReferenceContextLimits(renderCtx), buffers.getColorbuffer(), buffers.getDepthbuffer(), buffers.getStencilbuffer()); + + setContext(&context); + render(reference); + setContext(DE_NULL); + } + + bool isOk = compare(reference, result); + m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, + isOk ? "Pass" : "Image comparison failed"); + return STOP; +} + +bool FboTestCase::compare (const tcu::Surface& reference, const tcu::Surface& result) +{ + return tcu::fuzzyCompare(m_testCtx.getLog(), "Result", "Image comparison result", reference, result, 0.05f, tcu::COMPARE_LOG_RESULT); +} + +void FboTestCase::readPixels (tcu::Surface& dst, int x, int y, int width, int height, const tcu::TextureFormat& format, const tcu::Vec4& scale, const tcu::Vec4& bias) +{ + FboTestUtil::readPixels(*getCurrentContext(), dst, x, y, width, height, format, scale, bias); +} + +void FboTestCase::readPixels (tcu::Surface& dst, int x, int y, int width, int height) +{ + getCurrentContext()->readPixels(dst, x, y, width, height); +} + +void FboTestCase::checkFramebufferStatus (deUint32 target) +{ + deUint32 status = glCheckFramebufferStatus(target); + if (status != GL_FRAMEBUFFER_COMPLETE) + throw FboTestUtil::FboIncompleteException(status, __FILE__, __LINE__); +} + +void FboTestCase::checkError (void) +{ + deUint32 err = glGetError(); + if (err != GL_NO_ERROR) + throw glu::Error((int)err, (string("Got ") + glu::getErrorStr(err).toString()).c_str(), DE_NULL, __FILE__, __LINE__); +} + +static bool isRequiredFormat (deUint32 format) +{ + 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; + + // Depth formats + case GL_DEPTH_COMPONENT32F: + case GL_DEPTH_COMPONENT24: + case GL_DEPTH_COMPONENT16: + return true; + + // Depth+stencil formats + case GL_DEPTH32F_STENCIL8: + case GL_DEPTH24_STENCIL8: + return true; + + // Stencil formats + case GL_STENCIL_INDEX8: + return true; + + default: + return false; + } +} + +static std::vector<std::string> getEnablingExtensions (deUint32 format) +{ + std::vector<std::string> out; + + DE_ASSERT(!isRequiredFormat(format)); + + 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"); + + case GL_RGBA32F: + case GL_RGB32F: + case GL_R11F_G11F_B10F: + case GL_RG32F: + case GL_R32F: + out.push_back("GL_EXT_color_buffer_float"); + break; + + default: + break; + } + + return out; +} + +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; +} + +void FboTestCase::checkFormatSupport (deUint32 sizedFormat) +{ + const bool isCoreFormat = isRequiredFormat(sizedFormat); + const std::vector<std::string> requiredExts = (!isCoreFormat) ? getEnablingExtensions(sizedFormat) : std::vector<std::string>(); + + // Check that we don't try to use invalid formats. + DE_ASSERT(isCoreFormat || !requiredExts.empty()); + + if (!requiredExts.empty() && !isAnyExtensionSupported(m_context, requiredExts)) + throw tcu::NotSupportedError("Format not supported"); +} + +static int getMinimumSampleCount (deUint32 format) +{ + switch (format) + { + // Core 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: + case GL_DEPTH_COMPONENT32F: + case GL_DEPTH_COMPONENT24: + case GL_DEPTH_COMPONENT16: + case GL_DEPTH32F_STENCIL8: + case GL_DEPTH24_STENCIL8: + case GL_STENCIL_INDEX8: + return 4; + + // GL_EXT_color_buffer_float + case GL_R11F_G11F_B10F: + case GL_RG16F: + case GL_R16F: + return 4; + + case GL_RGBA32F: + case GL_RGBA16F: + case GL_RG32F: + case GL_R32F: + return 0; + + // GL_EXT_color_buffer_half_float + case GL_RGB16F: + return 0; + + default: + DE_ASSERT(!"Unknown format"); + return 0; + } +} + +static std::vector<int> querySampleCounts (const glw::Functions& gl, deUint32 format) +{ + int numSampleCounts = 0; + std::vector<int> sampleCounts; + + gl.getInternalformativ(GL_RENDERBUFFER, format, GL_NUM_SAMPLE_COUNTS, 1, &numSampleCounts); + + if (numSampleCounts > 0) + { + sampleCounts.resize(numSampleCounts); + gl.getInternalformativ(GL_RENDERBUFFER, format, GL_SAMPLES, (glw::GLsizei)sampleCounts.size(), &sampleCounts[0]); + } + + GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to query sample counts for format"); + + return sampleCounts; +} + +void FboTestCase::checkSampleCount (deUint32 sizedFormat, int numSamples) +{ + const int minSampleCount = getMinimumSampleCount(sizedFormat); + + if (numSamples > minSampleCount) + { + // Exceeds spec-mandated minimum - need to check. + const std::vector<int> supportedSampleCounts = querySampleCounts(m_context.getRenderContext().getFunctions(), sizedFormat); + + if (std::find(supportedSampleCounts.begin(), supportedSampleCounts.end(), numSamples) == supportedSampleCounts.end()) + throw tcu::NotSupportedError("Sample count not supported"); + } +} + +void FboTestCase::clearColorBuffer (const tcu::TextureFormat& format, const tcu::Vec4& value) +{ + FboTestUtil::clearColorBuffer(*getCurrentContext(), format, value); +} + +} // Functional +} // gles31 +} // deqp |