blob: 79d9113db7c392eea31f706b14eb0fbb3b566227 [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 Langaa3a5fa2015-05-20 14:10:46 -040039 void runTest(GLenum colorFormat)
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 Langaa3a5fa2015-05-20 14:10:46 -040047 SetUpFramebuffer(colorFormat);
48
Geoff Lang496123f2014-02-12 11:33:51 -050049 const size_t colorCount = 1024;
50 Color colors[colorCount];
51 for (size_t i = 0; i < colorCount; i++)
52 {
53 for (size_t j = 0; j < 4; j++)
54 {
55 colors[i].values[j] = (rand() % 255) / 255.0f;
56 }
57 }
58
59 GLubyte prevColor[4];
60 for (size_t i = 0; i < colorCount; i++)
61 {
62 const Color &color = colors[i];
63 glUseProgram(mProgram);
64 glUniform4f(mColorLocation, color.values[0], color.values[1], color.values[2], color.values[3]);
65
66 bool blendMin = (rand() % 2 == 0);
67 glBlendEquation(blendMin ? GL_MIN : GL_MAX);
68
69 drawQuad(mProgram, "aPosition", 0.5f);
70
71 if (i > 0)
72 {
73 EXPECT_PIXEL_EQ(0, 0,
74 getExpected(blendMin, color.values[0], prevColor[0]),
75 getExpected(blendMin, color.values[1], prevColor[1]),
76 getExpected(blendMin, color.values[2], prevColor[2]),
77 getExpected(blendMin, color.values[3], prevColor[3]));
78 }
79
80 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, prevColor);
81 }
82 }
83
84 virtual void SetUp()
85 {
86 ANGLETest::SetUp();
87
88 const std::string testVertexShaderSource = SHADER_SOURCE
89 (
90 attribute highp vec4 aPosition;
91
92 void main(void)
93 {
94 gl_Position = aPosition;
95 }
96 );
97
98 const std::string testFragmentShaderSource = SHADER_SOURCE
99 (
100 uniform highp vec4 color;
101 void main(void)
102 {
103 gl_FragColor = color;
104 }
105 );
106
Jamie Madill5599c8f2014-08-26 13:16:39 -0400107 mProgram = CompileProgram(testVertexShaderSource, testFragmentShaderSource);
Geoff Lang496123f2014-02-12 11:33:51 -0500108 if (mProgram == 0)
109 {
110 FAIL() << "shader compilation failed.";
111 }
112
113 mColorLocation = glGetUniformLocation(mProgram, "color");
114
115 glUseProgram(mProgram);
116
117 glClearColor(0, 0, 0, 0);
118 glClearDepthf(0.0);
119 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
120
121 glEnable(GL_BLEND);
122 glDisable(GL_DEPTH_TEST);
123 }
124
125 void SetUpFramebuffer(GLenum colorFormat)
126 {
127 glGenFramebuffers(1, &mFramebuffer);
128 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebuffer);
129 glBindFramebuffer(GL_READ_FRAMEBUFFER, mFramebuffer);
130
131 glGenRenderbuffers(1, &mColorRenderbuffer);
132 glBindRenderbuffer(GL_RENDERBUFFER, mColorRenderbuffer);
133 glRenderbufferStorage(GL_RENDERBUFFER, colorFormat, getWindowWidth(), getWindowHeight());
134 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mColorRenderbuffer);
135
136 ASSERT_GL_NO_ERROR();
137 }
138
139 virtual void TearDown()
140 {
141 glDeleteProgram(mProgram);
142 glDeleteFramebuffers(1, &mFramebuffer);
143 glDeleteRenderbuffers(1, &mColorRenderbuffer);
144
145 ANGLETest::TearDown();
146 }
147
148 GLuint mProgram;
149 GLint mColorLocation;
150
151 GLuint mFramebuffer;
152 GLuint mColorRenderbuffer;
153};
154
Jamie Madillfa05f602015-05-07 13:47:11 -0400155TEST_P(BlendMinMaxTest, RGBA8)
Geoff Lang496123f2014-02-12 11:33:51 -0500156{
Geoff Langaa3a5fa2015-05-20 14:10:46 -0400157 runTest(GL_RGBA8);
Geoff Lang496123f2014-02-12 11:33:51 -0500158}
159
Jamie Madillfa05f602015-05-07 13:47:11 -0400160TEST_P(BlendMinMaxTest, RGBA32f)
Geoff Lang496123f2014-02-12 11:33:51 -0500161{
Geoff Langa8091652015-04-27 10:53:55 -0400162 if (getClientVersion() < 3 && !extensionEnabled("GL_OES_texture_float"))
163 {
164 std::cout << "Test skipped because ES3 or GL_OES_texture_float is not available." << std::endl;
165 return;
166 }
167
Geoff Langaa3a5fa2015-05-20 14:10:46 -0400168 runTest(GL_RGBA32F);
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 Langaa3a5fa2015-05-20 14:10:46 -0400179 runTest(GL_RGBA16F);
Geoff Lang496123f2014-02-12 11:33:51 -0500180}
Jamie Madillfa05f602015-05-07 13:47:11 -0400181
182// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
183ANGLE_INSTANTIATE_TEST(BlendMinMaxTest, ES2_D3D9(), ES2_D3D11(), ES2_OPENGL());