• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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