1 #include "test_utils/ANGLETest.h"
2 #include "test_utils/gl_raii.h"
3
4 using namespace angle;
5
6 constexpr int kPixelColorThreshhold = 8;
7
8 class AdvancedBlendTest : public ANGLETest<>
9 {
10 protected:
AdvancedBlendTest()11 AdvancedBlendTest()
12 {
13 setWindowWidth(128);
14 setWindowHeight(128);
15 setConfigRedBits(8);
16 setConfigGreenBits(8);
17 setConfigBlueBits(8);
18 setConfigAlphaBits(8);
19 }
20 };
21
22 // Test that when blending is disabled, advanced blend is not applied.
23 // Regression test for a bug in the emulation path in the Vulkan backend.
TEST_P(AdvancedBlendTest,advancedBlendNotAppliedWhenBlendIsDisabled)24 TEST_P(AdvancedBlendTest, advancedBlendNotAppliedWhenBlendIsDisabled)
25 {
26 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_KHR_blend_equation_advanced"));
27
28 const char *vertSrc = R"(#version 320 es
29 in highp vec4 a_position;
30 in mediump vec4 a_color;
31 out mediump vec4 v_color;
32 void main()
33 {
34 gl_Position = a_position;
35 v_color = a_color;
36 }
37 )";
38
39 const char *fragSrc = R"(#version 320 es
40 in mediump vec4 v_color;
41 layout(blend_support_colorburn) out;
42 layout(location = 0) out mediump vec4 o_color;
43 void main()
44 {
45 o_color = v_color;
46 }
47 )";
48
49 ANGLE_GL_PROGRAM(program, vertSrc, fragSrc);
50 glUseProgram(program);
51
52 std::array<GLfloat, 16> attribPosData = {1, 1, 0.5, 1, -1, 1, 0.5, 1,
53 1, -1, 0.5, 1, -1, -1, 0.5, 1};
54
55 GLint attribPosLoc = glGetAttribLocation(1, "a_position");
56 ASSERT(attribPosLoc >= 0);
57 glEnableVertexAttribArray(attribPosLoc);
58 glVertexAttribPointer(attribPosLoc, 4, GL_FLOAT, GL_FALSE, 0, attribPosData.data());
59
60 std::array<GLfloat, 16> attribColorData1 = {1, 0.2, 0.5, 1, 1, 0.2, 0.5, 1,
61 1, 0.2, 0.5, 1, 1, 0.2, 0.5, 1};
62 GLint attribColorLoc = glGetAttribLocation(1, "a_color");
63 ASSERT(attribColorLoc >= 0);
64 glEnableVertexAttribArray(attribColorLoc);
65 glVertexAttribPointer(attribColorLoc, 4, GL_FLOAT, GL_FALSE, 0, attribColorData1.data());
66
67 glBlendEquation(GL_COLORBURN);
68
69 const uint16_t indices[] = {0, 1, 2, 2, 1, 3};
70 glClearColor(0.5, 0.5, 0.5, 1.0);
71 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
72
73 // Disable the blend. The next glDrawElements() should not blend the a_color with clear color
74 glDisable(GL_BLEND);
75 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, &indices[0]);
76 EXPECT_PIXEL_COLOR_NEAR(64, 64, GLColor(255, 51, 128, 255), kPixelColorThreshhold);
77 }
78
79 // Test that when blending is disabled, advanced blend is not applied, but is applied after
80 // it is enabled.
81 // Regression test for a bug in the emulation path in the Vulkan backend.
TEST_P(AdvancedBlendTest,advancedBlendDisabledAndThenEnabled)82 TEST_P(AdvancedBlendTest, advancedBlendDisabledAndThenEnabled)
83 {
84 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_KHR_blend_equation_advanced"));
85
86 const char *vertSrc = R"(#version 320 es
87 in highp vec4 a_position;
88 in mediump vec4 a_color;
89 out mediump vec4 v_color;
90 void main()
91 {
92 gl_Position = a_position;
93 v_color = a_color;
94 }
95 )";
96
97 const char *fragSrc = R"(#version 320 es
98 in mediump vec4 v_color;
99 layout(blend_support_colorburn) out;
100 layout(location = 0) out mediump vec4 o_color;
101 void main()
102 {
103 o_color = v_color;
104 }
105 )";
106
107 ANGLE_GL_PROGRAM(program, vertSrc, fragSrc);
108 glUseProgram(program);
109
110 std::array<GLfloat, 16> attribPosData = {1, 1, 0.5, 1, -1, 1, 0.5, 1,
111 1, -1, 0.5, 1, -1, -1, 0.5, 1};
112
113 GLint attribPosLoc = glGetAttribLocation(1, "a_position");
114 ASSERT(attribPosLoc >= 0);
115 glEnableVertexAttribArray(attribPosLoc);
116 glVertexAttribPointer(attribPosLoc, 4, GL_FLOAT, GL_FALSE, 0, attribPosData.data());
117
118 std::array<GLfloat, 16> attribColorData1 = {1, 0.2, 0.5, 1, 1, 0.2, 0.5, 1,
119 1, 0.2, 0.5, 1, 1, 0.2, 0.5, 1};
120 GLint attribColorLoc = glGetAttribLocation(1, "a_color");
121 ASSERT(attribColorLoc >= 0);
122 glEnableVertexAttribArray(attribColorLoc);
123 glVertexAttribPointer(attribColorLoc, 4, GL_FLOAT, GL_FALSE, 0, attribColorData1.data());
124
125 glBlendEquation(GL_COLORBURN);
126
127 const uint16_t indices[] = {0, 1, 2, 2, 1, 3};
128 glClearColor(0.5, 0.5, 0.5, 1.0);
129 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
130
131 // Disable the blend. The next glDrawElements() should not blend the a_color with clear color
132 glDisable(GL_BLEND);
133 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, &indices[0]);
134
135 // Enable the blend. The next glDrawElements() should blend a_color
136 // with the the existing framebuffer output with GL_COLORBURN blend mode
137 glEnable(GL_BLEND);
138 // Test the blend with coherent blend disabled. This make the test cover both devices that
139 // support / do not support GL_KHR_blend_equation_advanced_coherent
140 if (IsGLExtensionEnabled("GL_KHR_blend_equation_advanced_coherent"))
141 {
142 glDisable(GL_BLEND_ADVANCED_COHERENT_KHR);
143 }
144 glBlendBarrier();
145 std::array<GLfloat, 16> attribColorData2 = {0.5, 0.5, 0, 1, 0.5, 0.5, 0, 1,
146 0.5, 0.5, 0, 1, 0.5, 0.5, 0, 1};
147 glEnableVertexAttribArray(attribColorLoc);
148 glVertexAttribPointer(attribColorLoc, 4, GL_FLOAT, GL_FALSE, 0, attribColorData2.data());
149 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, &indices[0]);
150
151 EXPECT_PIXEL_COLOR_NEAR(64, 64, GLColor(255, 0, 0, 255), kPixelColorThreshhold);
152 }
153
154 // Test that when blending is enabled, advanced blend is applied, but is not applied after
155 // it is disabled.
156 // Regression test for a bug in the emulation path in the Vulkan backend.
TEST_P(AdvancedBlendTest,advancedBlendEnabledAndThenDisabled)157 TEST_P(AdvancedBlendTest, advancedBlendEnabledAndThenDisabled)
158 {
159 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_KHR_blend_equation_advanced"));
160
161 const char *vertSrc = R"(#version 320 es
162 in highp vec4 a_position;
163 in mediump vec4 a_color;
164 out mediump vec4 v_color;
165 void main()
166 {
167 gl_Position = a_position;
168 v_color = a_color;
169 }
170 )";
171
172 const char *fragSrc = R"(#version 320 es
173 in mediump vec4 v_color;
174 layout(blend_support_colorburn) out;
175 layout(location = 0) out mediump vec4 o_color;
176 void main()
177 {
178 o_color = v_color;
179 }
180 )";
181
182 ANGLE_GL_PROGRAM(program, vertSrc, fragSrc);
183 glUseProgram(program);
184
185 std::array<GLfloat, 16> attribPosData = {1, 1, 0.5, 1, -1, 1, 0.5, 1,
186 1, -1, 0.5, 1, -1, -1, 0.5, 1};
187
188 GLint attribPosLoc = glGetAttribLocation(1, "a_position");
189 ASSERT(attribPosLoc >= 0);
190 glEnableVertexAttribArray(attribPosLoc);
191 glVertexAttribPointer(attribPosLoc, 4, GL_FLOAT, GL_FALSE, 0, attribPosData.data());
192
193 std::array<GLfloat, 16> attribColorData1 = {1, 0.2, 0.5, 1, 1, 0.2, 0.5, 1,
194 1, 0.2, 0.5, 1, 1, 0.2, 0.5, 1};
195 GLint attribColorLoc = glGetAttribLocation(1, "a_color");
196 ASSERT(attribColorLoc >= 0);
197 glEnableVertexAttribArray(attribColorLoc);
198 glVertexAttribPointer(attribColorLoc, 4, GL_FLOAT, GL_FALSE, 0, attribColorData1.data());
199
200 glBlendEquation(GL_COLORBURN);
201
202 const uint16_t indices[] = {0, 1, 2, 2, 1, 3};
203 glClearColor(0.5, 0.5, 0.5, 1.0);
204 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
205
206 // Enable the blend. The next glDrawElements() should blend the a_color with clear color
207 // using the GL_COLORBURN blend mode
208 glEnable(GL_BLEND);
209 // Test the blend with coherent blend disabled. This make the test cover both devices that
210 // support / do not support GL_KHR_blend_equation_advanced_coherent
211 if (IsGLExtensionEnabled("GL_KHR_blend_equation_advanced_coherent"))
212 {
213 glDisable(GL_BLEND_ADVANCED_COHERENT_KHR);
214 }
215 glBlendBarrier();
216 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, &indices[0]);
217
218 // Disable the blend. The next glDrawElements() should not blend the a_color with
219 // the existing framebuffer output with GL_COLORBURN blend mode
220 glDisable(GL_BLEND);
221 std::array<GLfloat, 16> attribColorData2 = {0.5, 0.5, 0, 1, 0.5, 0.5, 0, 1,
222 0.5, 0.5, 0, 1, 0.5, 0.5, 0, 1};
223 glEnableVertexAttribArray(attribColorLoc);
224 glVertexAttribPointer(attribColorLoc, 4, GL_FLOAT, GL_FALSE, 0, attribColorData2.data());
225 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, &indices[0]);
226
227 EXPECT_PIXEL_COLOR_NEAR(64, 64, GLColor(128, 128, 0, 255), kPixelColorThreshhold);
228 }
229
230 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AdvancedBlendTest);
231 ANGLE_INSTANTIATE_TEST_ES32(AdvancedBlendTest);
232