blob: e84f20b9920b7cb7a60ebf77d234e61cefc65fdd [file] [log] [blame]
Geoff Lang496123f2014-02-12 11:33:51 -05001#include "ANGLETest.h"
2
Austin Kinross18b931d2014-09-29 12:58:31 -07003// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
Geoff Langa8091652015-04-27 10:53:55 -04004ANGLE_TYPED_TEST_CASE(BlendMinMaxTest, ES2_D3D9, ES2_D3D11, ES2_OPENGL);
Austin Kinross18b931d2014-09-29 12:58:31 -07005
6template<typename T>
Geoff Lang496123f2014-02-12 11:33:51 -05007class BlendMinMaxTest : public ANGLETest
8{
9protected:
Geoff Lang0d3683c2014-10-23 11:08:16 -040010 BlendMinMaxTest() : ANGLETest(T::GetGlesMajorVersion(), T::GetPlatform())
Geoff Lang496123f2014-02-12 11:33:51 -050011 {
12 setWindowWidth(128);
13 setWindowHeight(128);
14 setConfigRedBits(8);
15 setConfigGreenBits(8);
16 setConfigBlueBits(8);
17 setConfigAlphaBits(8);
18 setConfigDepthBits(24);
19
20 mProgram = 0;
21 mColorLocation = -1;
22 }
23
24 struct Color
25 {
26 float values[4];
27 };
28
29 static GLubyte getExpected(bool blendMin, float curColor, GLubyte prevColor)
30 {
Minmin Gong794e0002015-04-07 18:31:54 -070031 GLubyte curAsUbyte = static_cast<GLubyte>((curColor * std::numeric_limits<GLubyte>::max()) + 0.5f);
Geoff Lang496123f2014-02-12 11:33:51 -050032 return blendMin ? std::min<GLubyte>(curAsUbyte, prevColor) : std::max<GLubyte>(curAsUbyte, prevColor);
33 }
34
35 void runTest()
36 {
Geoff Langa8091652015-04-27 10:53:55 -040037 if (getClientVersion() < 3 && !extensionEnabled("GL_EXT_blend_minmax"))
38 {
39 std::cout << "Test skipped because ES3 or GL_EXT_blend_minmax is not available." << std::endl;
40 return;
41 }
42
Geoff Lang496123f2014-02-12 11:33:51 -050043 const size_t colorCount = 1024;
44 Color colors[colorCount];
45 for (size_t i = 0; i < colorCount; i++)
46 {
47 for (size_t j = 0; j < 4; j++)
48 {
49 colors[i].values[j] = (rand() % 255) / 255.0f;
50 }
51 }
52
53 GLubyte prevColor[4];
54 for (size_t i = 0; i < colorCount; i++)
55 {
56 const Color &color = colors[i];
57 glUseProgram(mProgram);
58 glUniform4f(mColorLocation, color.values[0], color.values[1], color.values[2], color.values[3]);
59
60 bool blendMin = (rand() % 2 == 0);
61 glBlendEquation(blendMin ? GL_MIN : GL_MAX);
62
63 drawQuad(mProgram, "aPosition", 0.5f);
64
65 if (i > 0)
66 {
67 EXPECT_PIXEL_EQ(0, 0,
68 getExpected(blendMin, color.values[0], prevColor[0]),
69 getExpected(blendMin, color.values[1], prevColor[1]),
70 getExpected(blendMin, color.values[2], prevColor[2]),
71 getExpected(blendMin, color.values[3], prevColor[3]));
72 }
73
74 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, prevColor);
75 }
76 }
77
78 virtual void SetUp()
79 {
80 ANGLETest::SetUp();
81
82 const std::string testVertexShaderSource = SHADER_SOURCE
83 (
84 attribute highp vec4 aPosition;
85
86 void main(void)
87 {
88 gl_Position = aPosition;
89 }
90 );
91
92 const std::string testFragmentShaderSource = SHADER_SOURCE
93 (
94 uniform highp vec4 color;
95 void main(void)
96 {
97 gl_FragColor = color;
98 }
99 );
100
Jamie Madill5599c8f2014-08-26 13:16:39 -0400101 mProgram = CompileProgram(testVertexShaderSource, testFragmentShaderSource);
Geoff Lang496123f2014-02-12 11:33:51 -0500102 if (mProgram == 0)
103 {
104 FAIL() << "shader compilation failed.";
105 }
106
107 mColorLocation = glGetUniformLocation(mProgram, "color");
108
109 glUseProgram(mProgram);
110
111 glClearColor(0, 0, 0, 0);
112 glClearDepthf(0.0);
113 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
114
115 glEnable(GL_BLEND);
116 glDisable(GL_DEPTH_TEST);
117 }
118
119 void SetUpFramebuffer(GLenum colorFormat)
120 {
121 glGenFramebuffers(1, &mFramebuffer);
122 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebuffer);
123 glBindFramebuffer(GL_READ_FRAMEBUFFER, mFramebuffer);
124
125 glGenRenderbuffers(1, &mColorRenderbuffer);
126 glBindRenderbuffer(GL_RENDERBUFFER, mColorRenderbuffer);
127 glRenderbufferStorage(GL_RENDERBUFFER, colorFormat, getWindowWidth(), getWindowHeight());
128 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mColorRenderbuffer);
129
130 ASSERT_GL_NO_ERROR();
131 }
132
133 virtual void TearDown()
134 {
135 glDeleteProgram(mProgram);
136 glDeleteFramebuffers(1, &mFramebuffer);
137 glDeleteRenderbuffers(1, &mColorRenderbuffer);
138
139 ANGLETest::TearDown();
140 }
141
142 GLuint mProgram;
143 GLint mColorLocation;
144
145 GLuint mFramebuffer;
146 GLuint mColorRenderbuffer;
147};
148
Austin Kinross18b931d2014-09-29 12:58:31 -0700149TYPED_TEST(BlendMinMaxTest, RGBA8)
Geoff Lang496123f2014-02-12 11:33:51 -0500150{
151 SetUpFramebuffer(GL_RGBA8);
152 runTest();
153}
154
Austin Kinross18b931d2014-09-29 12:58:31 -0700155TYPED_TEST(BlendMinMaxTest, RGBA32f)
Geoff Lang496123f2014-02-12 11:33:51 -0500156{
Geoff Langa8091652015-04-27 10:53:55 -0400157 if (getClientVersion() < 3 && !extensionEnabled("GL_OES_texture_float"))
158 {
159 std::cout << "Test skipped because ES3 or GL_OES_texture_float is not available." << std::endl;
160 return;
161 }
162
Geoff Lang496123f2014-02-12 11:33:51 -0500163 SetUpFramebuffer(GL_RGBA32F);
164 runTest();
165}
166
Austin Kinross18b931d2014-09-29 12:58:31 -0700167TYPED_TEST(BlendMinMaxTest, RGBA16F)
Geoff Lang496123f2014-02-12 11:33:51 -0500168{
Geoff Langa8091652015-04-27 10:53:55 -0400169 if (getClientVersion() < 3 && !extensionEnabled("GL_OES_texture_half_float"))
170 {
171 std::cout << "Test skipped because ES3 or GL_OES_texture_half_float is not available." << std::endl;
172 return;
173 }
174
Geoff Lang496123f2014-02-12 11:33:51 -0500175 SetUpFramebuffer(GL_RGBA16F);
176 runTest();
177}