diff options
Diffstat (limited to 'gfx/angle/src/tests/gl_tests/BlendMinMaxTest.cpp')
-rwxr-xr-x | gfx/angle/src/tests/gl_tests/BlendMinMaxTest.cpp | 255 |
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()); |