blob: 260f45a34134c9de02735f71bce629398b619423 [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;
26 }
27
28 struct Color
29 {
30 float values[4];
31 };
32
33 static GLubyte getExpected(bool blendMin, float curColor, GLubyte prevColor)
34 {
Minmin Gong794e0002015-04-07 18:31:54 -070035 GLubyte curAsUbyte = static_cast<GLubyte>((curColor * std::numeric_limits<GLubyte>::max()) + 0.5f);
Geoff Lang496123f2014-02-12 11:33:51 -050036 return blendMin ? std::min<GLubyte>(curAsUbyte, prevColor) : std::max<GLubyte>(curAsUbyte, prevColor);
37 }
38
Geoff Lang859dcb82015-05-25 15:12:54 +000039 void runTest()
Geoff Lang496123f2014-02-12 11:33:51 -050040 {
Geoff Langa8091652015-04-27 10:53:55 -040041 if (getClientVersion() < 3 && !extensionEnabled("GL_EXT_blend_minmax"))
42 {
43 std::cout << "Test skipped because ES3 or GL_EXT_blend_minmax is not available." << std::endl;
44 return;
45 }
46
Geoff Lang496123f2014-02-12 11:33:51 -050047 const size_t colorCount = 1024;
48 Color colors[colorCount];
49 for (size_t i = 0; i < colorCount; i++)
50 {
51 for (size_t j = 0; j < 4; j++)
52 {
53 colors[i].values[j] = (rand() % 255) / 255.0f;
54 }
55 }
56
57 GLubyte prevColor[4];
58 for (size_t i = 0; i < colorCount; i++)
59 {
60 const Color &color = colors[i];
61 glUseProgram(mProgram);
62 glUniform4f(mColorLocation, color.values[0], color.values[1], color.values[2], color.values[3]);
63
64 bool blendMin = (rand() % 2 == 0);
65 glBlendEquation(blendMin ? GL_MIN : GL_MAX);
66
67 drawQuad(mProgram, "aPosition", 0.5f);
68
69 if (i > 0)
70 {
71 EXPECT_PIXEL_EQ(0, 0,
72 getExpected(blendMin, color.values[0], prevColor[0]),
73 getExpected(blendMin, color.values[1], prevColor[1]),
74 getExpected(blendMin, color.values[2], prevColor[2]),
75 getExpected(blendMin, color.values[3], prevColor[3]));
76 }
77
78 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, prevColor);
79 }
80 }
81
82 virtual void SetUp()
83 {
84 ANGLETest::SetUp();
85
86 const std::string testVertexShaderSource = SHADER_SOURCE
87 (
88 attribute highp vec4 aPosition;
89
90 void main(void)
91 {
92 gl_Position = aPosition;
93 }
94 );
95
96 const std::string testFragmentShaderSource = SHADER_SOURCE
97 (
98 uniform highp vec4 color;
99 void main(void)
100 {
101 gl_FragColor = color;
102 }
103 );
104
Jamie Madill5599c8f2014-08-26 13:16:39 -0400105 mProgram = CompileProgram(testVertexShaderSource, testFragmentShaderSource);
Geoff Lang496123f2014-02-12 11:33:51 -0500106 if (mProgram == 0)
107 {
108 FAIL() << "shader compilation failed.";
109 }
110
111 mColorLocation = glGetUniformLocation(mProgram, "color");
112
113 glUseProgram(mProgram);
114
115 glClearColor(0, 0, 0, 0);
116 glClearDepthf(0.0);
117 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
118
119 glEnable(GL_BLEND);
120 glDisable(GL_DEPTH_TEST);
121 }
122
123 void SetUpFramebuffer(GLenum colorFormat)
124 {
125 glGenFramebuffers(1, &mFramebuffer);
126 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebuffer);
127 glBindFramebuffer(GL_READ_FRAMEBUFFER, mFramebuffer);
128
129 glGenRenderbuffers(1, &mColorRenderbuffer);
130 glBindRenderbuffer(GL_RENDERBUFFER, mColorRenderbuffer);
131 glRenderbufferStorage(GL_RENDERBUFFER, colorFormat, getWindowWidth(), getWindowHeight());
132 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mColorRenderbuffer);
133
134 ASSERT_GL_NO_ERROR();
135 }
136
137 virtual void TearDown()
138 {
139 glDeleteProgram(mProgram);
140 glDeleteFramebuffers(1, &mFramebuffer);
141 glDeleteRenderbuffers(1, &mColorRenderbuffer);
142
143 ANGLETest::TearDown();
144 }
145
146 GLuint mProgram;
147 GLint mColorLocation;
148
149 GLuint mFramebuffer;
150 GLuint mColorRenderbuffer;
151};
152
Jamie Madillfa05f602015-05-07 13:47:11 -0400153TEST_P(BlendMinMaxTest, RGBA8)
Geoff Lang496123f2014-02-12 11:33:51 -0500154{
Geoff Lang859dcb82015-05-25 15:12:54 +0000155 SetUpFramebuffer(GL_RGBA8);
156 runTest();
Geoff Lang496123f2014-02-12 11:33:51 -0500157}
158
Jamie Madillfa05f602015-05-07 13:47:11 -0400159TEST_P(BlendMinMaxTest, RGBA32f)
Geoff Lang496123f2014-02-12 11:33:51 -0500160{
Geoff Langa8091652015-04-27 10:53:55 -0400161 if (getClientVersion() < 3 && !extensionEnabled("GL_OES_texture_float"))
162 {
163 std::cout << "Test skipped because ES3 or GL_OES_texture_float is not available." << std::endl;
164 return;
165 }
166
Geoff Lang859dcb82015-05-25 15:12:54 +0000167 SetUpFramebuffer(GL_RGBA32F);
168 runTest();
Geoff Lang496123f2014-02-12 11:33:51 -0500169}
170
Jamie Madillfa05f602015-05-07 13:47:11 -0400171TEST_P(BlendMinMaxTest, RGBA16F)
Geoff Lang496123f2014-02-12 11:33:51 -0500172{
Geoff Langa8091652015-04-27 10:53:55 -0400173 if (getClientVersion() < 3 && !extensionEnabled("GL_OES_texture_half_float"))
174 {
175 std::cout << "Test skipped because ES3 or GL_OES_texture_half_float is not available." << std::endl;
176 return;
177 }
178
Geoff Lang859dcb82015-05-25 15:12:54 +0000179 SetUpFramebuffer(GL_RGBA16F);
180 runTest();
Geoff Lang496123f2014-02-12 11:33:51 -0500181}
Jamie Madillfa05f602015-05-07 13:47:11 -0400182
183// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
184ANGLE_INSTANTIATE_TEST(BlendMinMaxTest, ES2_D3D9(), ES2_D3D11(), ES2_OPENGL());