blob: 39f5251e565b8dab3105744b21441a4e6a6e7477 [file] [log] [blame]
Jamie Madillfa05f602015-05-07 13:47:11 -04001//
2// Copyright 2015 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
Corentin Wallezd3970de2015-05-14 11:07:48 -04007#include "test_utils/ANGLETest.h"
Geoff Lang496123f2014-02-12 11:33:51 -05008
Jamie Madillfa05f602015-05-07 13:47:11 -04009using namespace angle;
Austin Kinross18b931d2014-09-29 12:58:31 -070010
Geoff Lang496123f2014-02-12 11:33:51 -050011class BlendMinMaxTest : public ANGLETest
12{
Jamie Madillfa05f602015-05-07 13:47:11 -040013 protected:
14 BlendMinMaxTest()
Geoff Lang496123f2014-02-12 11:33:51 -050015 {
16 setWindowWidth(128);
17 setWindowHeight(128);
18 setConfigRedBits(8);
19 setConfigGreenBits(8);
20 setConfigBlueBits(8);
21 setConfigAlphaBits(8);
22 setConfigDepthBits(24);
23
24 mProgram = 0;
25 mColorLocation = -1;
Sami Väisänenc4433f42016-07-12 16:56:43 +030026 mFramebuffer = 0;
27 mColorRenderbuffer = 0;
Geoff Lang496123f2014-02-12 11:33:51 -050028 }
29
30 struct Color
31 {
32 float values[4];
33 };
34
Geoff Langf607c602016-09-21 11:46:48 -040035 static float getExpected(bool blendMin, float curColor, float prevColor)
Geoff Lang496123f2014-02-12 11:33:51 -050036 {
Geoff Langf607c602016-09-21 11:46:48 -040037 return blendMin ? std::min(curColor, prevColor) : std::max(curColor, prevColor);
Geoff Lang496123f2014-02-12 11:33:51 -050038 }
39
Geoff Langf607c602016-09-21 11:46:48 -040040 void runTest(GLenum colorFormat, GLenum type)
Geoff Lang496123f2014-02-12 11:33:51 -050041 {
Martin Radev1be913c2016-07-11 17:59:16 +030042 if (getClientMajorVersion() < 3 && !extensionEnabled("GL_EXT_blend_minmax"))
Geoff Langa8091652015-04-27 10:53:55 -040043 {
44 std::cout << "Test skipped because ES3 or GL_EXT_blend_minmax is not available." << std::endl;
45 return;
46 }
47
Geoff Langddf4d392015-09-29 13:00:14 -040048 // TODO(geofflang): figure out why this fails
Jamie Madill518b9fa2016-03-02 11:26:02 -050049 if (IsIntel() && GetParam() == ES2_OPENGL())
Geoff Langddf4d392015-09-29 13:00:14 -040050 {
51 std::cout << "Test skipped on OpenGL Intel due to flakyness." << std::endl;
52 return;
53 }
54
Geoff Langf34d1db2015-05-20 14:10:46 -040055 SetUpFramebuffer(colorFormat);
56
Geoff Langf607c602016-09-21 11:46:48 -040057 int minValue = 0;
58 int maxValue = 1;
59 if (type == GL_FLOAT)
60 {
61 minValue = -1024;
62 maxValue = 1024;
63 }
64
65 const size_t colorCount = 128;
Geoff Lang496123f2014-02-12 11:33:51 -050066 Color colors[colorCount];
67 for (size_t i = 0; i < colorCount; i++)
68 {
69 for (size_t j = 0; j < 4; j++)
70 {
Geoff Langf607c602016-09-21 11:46:48 -040071 colors[i].values[j] =
72 static_cast<float>(minValue + (rand() % (maxValue - minValue)));
Geoff Lang496123f2014-02-12 11:33:51 -050073 }
74 }
75
Geoff Langf607c602016-09-21 11:46:48 -040076 float prevColor[4];
Geoff Lang496123f2014-02-12 11:33:51 -050077 for (size_t i = 0; i < colorCount; i++)
78 {
79 const Color &color = colors[i];
80 glUseProgram(mProgram);
81 glUniform4f(mColorLocation, color.values[0], color.values[1], color.values[2], color.values[3]);
82
83 bool blendMin = (rand() % 2 == 0);
84 glBlendEquation(blendMin ? GL_MIN : GL_MAX);
85
86 drawQuad(mProgram, "aPosition", 0.5f);
87
Geoff Langf607c602016-09-21 11:46:48 -040088 float pixel[4];
89 if (type == GL_UNSIGNED_BYTE)
Geoff Lang496123f2014-02-12 11:33:51 -050090 {
Geoff Langf607c602016-09-21 11:46:48 -040091 GLubyte ubytePixel[4];
92 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, ubytePixel);
93 for (size_t componentIdx = 0; componentIdx < ArraySize(pixel); componentIdx++)
94 {
95 pixel[componentIdx] = ubytePixel[componentIdx] / 255.0f;
96 }
97 }
98 else if (type == GL_FLOAT)
99 {
100 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, pixel);
101 }
102 else
103 {
104 FAIL() << "Unexpected pixel type";
Geoff Lang496123f2014-02-12 11:33:51 -0500105 }
106
Geoff Langf607c602016-09-21 11:46:48 -0400107 if (i > 0)
108 {
109 const float errorRange = 1.0f / 255.0f;
110 for (size_t componentIdx = 0; componentIdx < ArraySize(pixel); componentIdx++)
111 {
112 EXPECT_NEAR(
113 getExpected(blendMin, color.values[componentIdx], prevColor[componentIdx]),
114 pixel[componentIdx], errorRange);
115 }
116 }
117
118 memcpy(prevColor, pixel, sizeof(pixel));
Geoff Lang496123f2014-02-12 11:33:51 -0500119 }
120 }
121
122 virtual void SetUp()
123 {
124 ANGLETest::SetUp();
125
126 const std::string testVertexShaderSource = SHADER_SOURCE
127 (
128 attribute highp vec4 aPosition;
129
130 void main(void)
131 {
132 gl_Position = aPosition;
133 }
134 );
135
136 const std::string testFragmentShaderSource = SHADER_SOURCE
137 (
138 uniform highp vec4 color;
139 void main(void)
140 {
141 gl_FragColor = color;
142 }
143 );
144
Jamie Madill5599c8f2014-08-26 13:16:39 -0400145 mProgram = CompileProgram(testVertexShaderSource, testFragmentShaderSource);
Geoff Lang496123f2014-02-12 11:33:51 -0500146 if (mProgram == 0)
147 {
148 FAIL() << "shader compilation failed.";
149 }
150
151 mColorLocation = glGetUniformLocation(mProgram, "color");
152
153 glUseProgram(mProgram);
154
155 glClearColor(0, 0, 0, 0);
156 glClearDepthf(0.0);
157 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
158
159 glEnable(GL_BLEND);
160 glDisable(GL_DEPTH_TEST);
161 }
162
163 void SetUpFramebuffer(GLenum colorFormat)
164 {
165 glGenFramebuffers(1, &mFramebuffer);
166 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebuffer);
167 glBindFramebuffer(GL_READ_FRAMEBUFFER, mFramebuffer);
168
169 glGenRenderbuffers(1, &mColorRenderbuffer);
170 glBindRenderbuffer(GL_RENDERBUFFER, mColorRenderbuffer);
171 glRenderbufferStorage(GL_RENDERBUFFER, colorFormat, getWindowWidth(), getWindowHeight());
172 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mColorRenderbuffer);
173
Geoff Langf607c602016-09-21 11:46:48 -0400174 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
175 glClear(GL_COLOR_BUFFER_BIT);
176
Geoff Lang496123f2014-02-12 11:33:51 -0500177 ASSERT_GL_NO_ERROR();
178 }
179
180 virtual void TearDown()
181 {
182 glDeleteProgram(mProgram);
183 glDeleteFramebuffers(1, &mFramebuffer);
184 glDeleteRenderbuffers(1, &mColorRenderbuffer);
185
186 ANGLETest::TearDown();
187 }
188
189 GLuint mProgram;
190 GLint mColorLocation;
191
192 GLuint mFramebuffer;
193 GLuint mColorRenderbuffer;
194};
195
Jamie Madillfa05f602015-05-07 13:47:11 -0400196TEST_P(BlendMinMaxTest, RGBA8)
Geoff Lang496123f2014-02-12 11:33:51 -0500197{
Geoff Langf607c602016-09-21 11:46:48 -0400198 runTest(GL_RGBA8, GL_UNSIGNED_BYTE);
Geoff Lang496123f2014-02-12 11:33:51 -0500199}
200
Geoff Langf607c602016-09-21 11:46:48 -0400201TEST_P(BlendMinMaxTest, RGBA32F)
Geoff Lang496123f2014-02-12 11:33:51 -0500202{
Martin Radev1be913c2016-07-11 17:59:16 +0300203 if (getClientMajorVersion() < 3 || !extensionEnabled("GL_EXT_color_buffer_float"))
Geoff Langa8091652015-04-27 10:53:55 -0400204 {
Geoff Lange0cc2a42016-01-20 10:58:17 -0500205 std::cout << "Test skipped because ES3 and GL_EXT_color_buffer_float are not available."
206 << std::endl;
Geoff Langa8091652015-04-27 10:53:55 -0400207 return;
208 }
209
Jamie Madill1ea9aaa2015-10-07 11:13:55 -0400210 // TODO(jmadill): Figure out why this is broken on Intel
Jamie Madill518b9fa2016-03-02 11:26:02 -0500211 if (IsIntel() && (GetParam() == ES2_D3D11() || GetParam() == ES2_D3D9()))
Jamie Madill1ea9aaa2015-10-07 11:13:55 -0400212 {
213 std::cout << "Test skipped on Intel OpenGL." << std::endl;
214 return;
215 }
216
Austin Kinrossd544cc92016-01-11 15:26:42 -0800217 // TODO (bug 1284): Investigate RGBA32f D3D SDK Layers messages on D3D11_FL9_3
Jamie Madill518b9fa2016-03-02 11:26:02 -0500218 if (IsD3D11_FL93())
Austin Kinrossd544cc92016-01-11 15:26:42 -0800219 {
220 std::cout << "Test skipped on Feature Level 9_3." << std::endl;
221 return;
222 }
223
Geoff Langf607c602016-09-21 11:46:48 -0400224 runTest(GL_RGBA32F, GL_FLOAT);
Geoff Lang496123f2014-02-12 11:33:51 -0500225}
226
Jamie Madillfa05f602015-05-07 13:47:11 -0400227TEST_P(BlendMinMaxTest, RGBA16F)
Geoff Lang496123f2014-02-12 11:33:51 -0500228{
Martin Radev1be913c2016-07-11 17:59:16 +0300229 if (getClientMajorVersion() < 3 && !extensionEnabled("GL_EXT_color_buffer_half_float"))
Geoff Langa8091652015-04-27 10:53:55 -0400230 {
Austin Kinrossff318af2015-12-22 15:34:45 -0800231 std::cout << "Test skipped because ES3 or GL_EXT_color_buffer_half_float is not available."
232 << std::endl;
Geoff Langa8091652015-04-27 10:53:55 -0400233 return;
234 }
235
Jamie Madill0962fc32015-09-09 10:40:28 -0400236 // TODO(jmadill): figure out why this fails
Jamie Madill518b9fa2016-03-02 11:26:02 -0500237 if (IsIntel() && (GetParam() == ES2_D3D11() || GetParam() == ES2_D3D9()))
Jamie Madill0962fc32015-09-09 10:40:28 -0400238 {
239 std::cout << "Test skipped on Intel due to failures." << std::endl;
240 return;
241 }
242
Geoff Langf607c602016-09-21 11:46:48 -0400243 runTest(GL_RGBA16F, GL_FLOAT);
Geoff Lang496123f2014-02-12 11:33:51 -0500244}
Jamie Madillfa05f602015-05-07 13:47:11 -0400245
246// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
Geoff Lange0cc2a42016-01-20 10:58:17 -0500247ANGLE_INSTANTIATE_TEST(BlendMinMaxTest,
248 ES2_D3D9(),
249 ES2_D3D11(),
Geoff Langf607c602016-09-21 11:46:48 -0400250 ES3_D3D11(),
Geoff Lange0cc2a42016-01-20 10:58:17 -0500251 ES2_D3D11_FL9_3(),
252 ES2_OPENGL(),
Geoff Langf607c602016-09-21 11:46:48 -0400253 ES3_OPENGL(),
254 ES2_OPENGLES(),
255 ES3_OPENGLES());