summaryrefslogtreecommitdiffstats
path: root/gfx/angle/src/tests/gl_tests/BlendMinMaxTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/src/tests/gl_tests/BlendMinMaxTest.cpp')
-rwxr-xr-xgfx/angle/src/tests/gl_tests/BlendMinMaxTest.cpp255
1 files changed, 255 insertions, 0 deletions
diff --git a/gfx/angle/src/tests/gl_tests/BlendMinMaxTest.cpp b/gfx/angle/src/tests/gl_tests/BlendMinMaxTest.cpp
new file mode 100755
index 000000000..39f5251e5
--- /dev/null
+++ b/gfx/angle/src/tests/gl_tests/BlendMinMaxTest.cpp
@@ -0,0 +1,255 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "test_utils/ANGLETest.h"
+
+using namespace angle;
+
+class BlendMinMaxTest : public ANGLETest
+{
+ protected:
+ BlendMinMaxTest()
+ {
+ setWindowWidth(128);
+ setWindowHeight(128);
+ setConfigRedBits(8);
+ setConfigGreenBits(8);
+ setConfigBlueBits(8);
+ setConfigAlphaBits(8);
+ setConfigDepthBits(24);
+
+ mProgram = 0;
+ mColorLocation = -1;
+ mFramebuffer = 0;
+ mColorRenderbuffer = 0;
+ }
+
+ struct Color
+ {
+ float values[4];
+ };
+
+ static float getExpected(bool blendMin, float curColor, float prevColor)
+ {
+ return blendMin ? std::min(curColor, prevColor) : std::max(curColor, prevColor);
+ }
+
+ void runTest(GLenum colorFormat, GLenum type)
+ {
+ if (getClientMajorVersion() < 3 && !extensionEnabled("GL_EXT_blend_minmax"))
+ {
+ std::cout << "Test skipped because ES3 or GL_EXT_blend_minmax is not available." << std::endl;
+ return;
+ }
+
+ // TODO(geofflang): figure out why this fails
+ if (IsIntel() && GetParam() == ES2_OPENGL())
+ {
+ std::cout << "Test skipped on OpenGL Intel due to flakyness." << std::endl;
+ return;
+ }
+
+ SetUpFramebuffer(colorFormat);
+
+ int minValue = 0;
+ int maxValue = 1;
+ if (type == GL_FLOAT)
+ {
+ minValue = -1024;
+ maxValue = 1024;
+ }
+
+ const size_t colorCount = 128;
+ Color colors[colorCount];
+ for (size_t i = 0; i < colorCount; i++)
+ {
+ for (size_t j = 0; j < 4; j++)
+ {
+ colors[i].values[j] =
+ static_cast<float>(minValue + (rand() % (maxValue - minValue)));
+ }
+ }
+
+ float prevColor[4];
+ for (size_t i = 0; i < colorCount; i++)
+ {
+ const Color &color = colors[i];
+ glUseProgram(mProgram);
+ glUniform4f(mColorLocation, color.values[0], color.values[1], color.values[2], color.values[3]);
+
+ bool blendMin = (rand() % 2 == 0);
+ glBlendEquation(blendMin ? GL_MIN : GL_MAX);
+
+ drawQuad(mProgram, "aPosition", 0.5f);
+
+ float pixel[4];
+ if (type == GL_UNSIGNED_BYTE)
+ {
+ GLubyte ubytePixel[4];
+ glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, ubytePixel);
+ for (size_t componentIdx = 0; componentIdx < ArraySize(pixel); componentIdx++)
+ {
+ pixel[componentIdx] = ubytePixel[componentIdx] / 255.0f;
+ }
+ }
+ else if (type == GL_FLOAT)
+ {
+ glReadPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, pixel);
+ }
+ else
+ {
+ FAIL() << "Unexpected pixel type";
+ }
+
+ if (i > 0)
+ {
+ const float errorRange = 1.0f / 255.0f;
+ for (size_t componentIdx = 0; componentIdx < ArraySize(pixel); componentIdx++)
+ {
+ EXPECT_NEAR(
+ getExpected(blendMin, color.values[componentIdx], prevColor[componentIdx]),
+ pixel[componentIdx], errorRange);
+ }
+ }
+
+ memcpy(prevColor, pixel, sizeof(pixel));
+ }
+ }
+
+ virtual void SetUp()
+ {
+ ANGLETest::SetUp();
+
+ const std::string testVertexShaderSource = SHADER_SOURCE
+ (
+ attribute highp vec4 aPosition;
+
+ void main(void)
+ {
+ gl_Position = aPosition;
+ }
+ );
+
+ const std::string testFragmentShaderSource = SHADER_SOURCE
+ (
+ uniform highp vec4 color;
+ void main(void)
+ {
+ gl_FragColor = color;
+ }
+ );
+
+ mProgram = CompileProgram(testVertexShaderSource, testFragmentShaderSource);
+ if (mProgram == 0)
+ {
+ FAIL() << "shader compilation failed.";
+ }
+
+ mColorLocation = glGetUniformLocation(mProgram, "color");
+
+ glUseProgram(mProgram);
+
+ glClearColor(0, 0, 0, 0);
+ glClearDepthf(0.0);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glEnable(GL_BLEND);
+ glDisable(GL_DEPTH_TEST);
+ }
+
+ void SetUpFramebuffer(GLenum colorFormat)
+ {
+ glGenFramebuffers(1, &mFramebuffer);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebuffer);
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, mFramebuffer);
+
+ glGenRenderbuffers(1, &mColorRenderbuffer);
+ glBindRenderbuffer(GL_RENDERBUFFER, mColorRenderbuffer);
+ glRenderbufferStorage(GL_RENDERBUFFER, colorFormat, getWindowWidth(), getWindowHeight());
+ glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mColorRenderbuffer);
+
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ ASSERT_GL_NO_ERROR();
+ }
+
+ virtual void TearDown()
+ {
+ glDeleteProgram(mProgram);
+ glDeleteFramebuffers(1, &mFramebuffer);
+ glDeleteRenderbuffers(1, &mColorRenderbuffer);
+
+ ANGLETest::TearDown();
+ }
+
+ GLuint mProgram;
+ GLint mColorLocation;
+
+ GLuint mFramebuffer;
+ GLuint mColorRenderbuffer;
+};
+
+TEST_P(BlendMinMaxTest, RGBA8)
+{
+ runTest(GL_RGBA8, GL_UNSIGNED_BYTE);
+}
+
+TEST_P(BlendMinMaxTest, RGBA32F)
+{
+ if (getClientMajorVersion() < 3 || !extensionEnabled("GL_EXT_color_buffer_float"))
+ {
+ std::cout << "Test skipped because ES3 and GL_EXT_color_buffer_float are not available."
+ << std::endl;
+ return;
+ }
+
+ // TODO(jmadill): Figure out why this is broken on Intel
+ if (IsIntel() && (GetParam() == ES2_D3D11() || GetParam() == ES2_D3D9()))
+ {
+ std::cout << "Test skipped on Intel OpenGL." << std::endl;
+ return;
+ }
+
+ // TODO (bug 1284): Investigate RGBA32f D3D SDK Layers messages on D3D11_FL9_3
+ if (IsD3D11_FL93())
+ {
+ std::cout << "Test skipped on Feature Level 9_3." << std::endl;
+ return;
+ }
+
+ runTest(GL_RGBA32F, GL_FLOAT);
+}
+
+TEST_P(BlendMinMaxTest, RGBA16F)
+{
+ if (getClientMajorVersion() < 3 && !extensionEnabled("GL_EXT_color_buffer_half_float"))
+ {
+ std::cout << "Test skipped because ES3 or GL_EXT_color_buffer_half_float is not available."
+ << std::endl;
+ return;
+ }
+
+ // TODO(jmadill): figure out why this fails
+ if (IsIntel() && (GetParam() == ES2_D3D11() || GetParam() == ES2_D3D9()))
+ {
+ std::cout << "Test skipped on Intel due to failures." << std::endl;
+ return;
+ }
+
+ runTest(GL_RGBA16F, GL_FLOAT);
+}
+
+// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
+ANGLE_INSTANTIATE_TEST(BlendMinMaxTest,
+ ES2_D3D9(),
+ ES2_D3D11(),
+ ES3_D3D11(),
+ ES2_D3D11_FL9_3(),
+ ES2_OPENGL(),
+ ES3_OPENGL(),
+ ES2_OPENGLES(),
+ ES3_OPENGLES());