summaryrefslogtreecommitdiff
path: root/modules/gles31/functional/es31fFboTestCase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/gles31/functional/es31fFboTestCase.cpp')
-rw-r--r--modules/gles31/functional/es31fFboTestCase.cpp369
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