blob: a5c892ab4694ffa086cb1ff294d029091c87e147 [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
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300126 const std::string testVertexShaderSource =
127 R"(attribute highp vec4 aPosition;
Geoff Lang496123f2014-02-12 11:33:51 -0500128 void main(void)
129 {
130 gl_Position = aPosition;
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300131 })";
Geoff Lang496123f2014-02-12 11:33:51 -0500132
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300133 const std::string testFragmentShaderSource =
134 R"(uniform highp vec4 color;
Geoff Lang496123f2014-02-12 11:33:51 -0500135 void main(void)
136 {
137 gl_FragColor = color;
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300138 })";
Geoff Lang496123f2014-02-12 11:33:51 -0500139
Jamie Madill5599c8f2014-08-26 13:16:39 -0400140 mProgram = CompileProgram(testVertexShaderSource, testFragmentShaderSource);
Geoff Lang496123f2014-02-12 11:33:51 -0500141 if (mProgram == 0)
142 {
143 FAIL() << "shader compilation failed.";
144 }
145
146 mColorLocation = glGetUniformLocation(mProgram, "color");
147
148 glUseProgram(mProgram);
149
150 glClearColor(0, 0, 0, 0);
151 glClearDepthf(0.0);
152 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
153
154 glEnable(GL_BLEND);
155 glDisable(GL_DEPTH_TEST);
156 }
157
158 void SetUpFramebuffer(GLenum colorFormat)
159 {
160 glGenFramebuffers(1, &mFramebuffer);
161 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebuffer);
162 glBindFramebuffer(GL_READ_FRAMEBUFFER, mFramebuffer);
163
164 glGenRenderbuffers(1, &mColorRenderbuffer);
165 glBindRenderbuffer(GL_RENDERBUFFER, mColorRenderbuffer);
166 glRenderbufferStorage(GL_RENDERBUFFER, colorFormat, getWindowWidth(), getWindowHeight());
167 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mColorRenderbuffer);
168
Geoff Langf607c602016-09-21 11:46:48 -0400169 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
170 glClear(GL_COLOR_BUFFER_BIT);
171
Geoff Lang496123f2014-02-12 11:33:51 -0500172 ASSERT_GL_NO_ERROR();
173 }
174
175 virtual void TearDown()
176 {
177 glDeleteProgram(mProgram);
178 glDeleteFramebuffers(1, &mFramebuffer);
179 glDeleteRenderbuffers(1, &mColorRenderbuffer);
180
181 ANGLETest::TearDown();
182 }
183
184 GLuint mProgram;
185 GLint mColorLocation;
186
187 GLuint mFramebuffer;
188 GLuint mColorRenderbuffer;
189};
190
Jamie Madillfa05f602015-05-07 13:47:11 -0400191TEST_P(BlendMinMaxTest, RGBA8)
Geoff Lang496123f2014-02-12 11:33:51 -0500192{
Geoff Langf607c602016-09-21 11:46:48 -0400193 runTest(GL_RGBA8, GL_UNSIGNED_BYTE);
Geoff Lang496123f2014-02-12 11:33:51 -0500194}
195
Geoff Langf607c602016-09-21 11:46:48 -0400196TEST_P(BlendMinMaxTest, RGBA32F)
Geoff Lang496123f2014-02-12 11:33:51 -0500197{
Martin Radev1be913c2016-07-11 17:59:16 +0300198 if (getClientMajorVersion() < 3 || !extensionEnabled("GL_EXT_color_buffer_float"))
Geoff Langa8091652015-04-27 10:53:55 -0400199 {
Geoff Lange0cc2a42016-01-20 10:58:17 -0500200 std::cout << "Test skipped because ES3 and GL_EXT_color_buffer_float are not available."
201 << std::endl;
Geoff Langa8091652015-04-27 10:53:55 -0400202 return;
203 }
204
Jamie Madill1ea9aaa2015-10-07 11:13:55 -0400205 // TODO(jmadill): Figure out why this is broken on Intel
Jamie Madill518b9fa2016-03-02 11:26:02 -0500206 if (IsIntel() && (GetParam() == ES2_D3D11() || GetParam() == ES2_D3D9()))
Jamie Madill1ea9aaa2015-10-07 11:13:55 -0400207 {
208 std::cout << "Test skipped on Intel OpenGL." << std::endl;
209 return;
210 }
211
Austin Kinrossd544cc92016-01-11 15:26:42 -0800212 // TODO (bug 1284): Investigate RGBA32f D3D SDK Layers messages on D3D11_FL9_3
Jamie Madill518b9fa2016-03-02 11:26:02 -0500213 if (IsD3D11_FL93())
Austin Kinrossd544cc92016-01-11 15:26:42 -0800214 {
215 std::cout << "Test skipped on Feature Level 9_3." << std::endl;
216 return;
217 }
218
Geoff Langf607c602016-09-21 11:46:48 -0400219 runTest(GL_RGBA32F, GL_FLOAT);
Geoff Lang496123f2014-02-12 11:33:51 -0500220}
221
Jamie Madillfa05f602015-05-07 13:47:11 -0400222TEST_P(BlendMinMaxTest, RGBA16F)
Geoff Lang496123f2014-02-12 11:33:51 -0500223{
Martin Radev1be913c2016-07-11 17:59:16 +0300224 if (getClientMajorVersion() < 3 && !extensionEnabled("GL_EXT_color_buffer_half_float"))
Geoff Langa8091652015-04-27 10:53:55 -0400225 {
Austin Kinrossff318af2015-12-22 15:34:45 -0800226 std::cout << "Test skipped because ES3 or GL_EXT_color_buffer_half_float is not available."
227 << std::endl;
Geoff Langa8091652015-04-27 10:53:55 -0400228 return;
229 }
230
Jamie Madill0962fc32015-09-09 10:40:28 -0400231 // TODO(jmadill): figure out why this fails
Jamie Madill518b9fa2016-03-02 11:26:02 -0500232 if (IsIntel() && (GetParam() == ES2_D3D11() || GetParam() == ES2_D3D9()))
Jamie Madill0962fc32015-09-09 10:40:28 -0400233 {
234 std::cout << "Test skipped on Intel due to failures." << std::endl;
235 return;
236 }
237
Geoff Langf607c602016-09-21 11:46:48 -0400238 runTest(GL_RGBA16F, GL_FLOAT);
Geoff Lang496123f2014-02-12 11:33:51 -0500239}
Jamie Madillfa05f602015-05-07 13:47:11 -0400240
241// 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 -0500242ANGLE_INSTANTIATE_TEST(BlendMinMaxTest,
243 ES2_D3D9(),
244 ES2_D3D11(),
Geoff Langf607c602016-09-21 11:46:48 -0400245 ES3_D3D11(),
Geoff Lange0cc2a42016-01-20 10:58:17 -0500246 ES2_D3D11_FL9_3(),
247 ES2_OPENGL(),
Geoff Langf607c602016-09-21 11:46:48 -0400248 ES3_OPENGL(),
249 ES2_OPENGLES(),
250 ES3_OPENGLES());