xref: /aosp_15_r20/external/angle/src/tests/gl_tests/AdvancedBlendTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2024 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker 
7*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/ANGLETest.h"
8*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/gl_raii.h"
9*8975f5c5SAndroid Build Coastguard Worker 
10*8975f5c5SAndroid Build Coastguard Worker using namespace angle;
11*8975f5c5SAndroid Build Coastguard Worker 
12*8975f5c5SAndroid Build Coastguard Worker constexpr int kPixelColorThreshhold = 8;
13*8975f5c5SAndroid Build Coastguard Worker 
14*8975f5c5SAndroid Build Coastguard Worker class AdvancedBlendTest : public ANGLETest<>
15*8975f5c5SAndroid Build Coastguard Worker {
16*8975f5c5SAndroid Build Coastguard Worker   protected:
AdvancedBlendTest()17*8975f5c5SAndroid Build Coastguard Worker     AdvancedBlendTest()
18*8975f5c5SAndroid Build Coastguard Worker     {
19*8975f5c5SAndroid Build Coastguard Worker         setWindowWidth(128);
20*8975f5c5SAndroid Build Coastguard Worker         setWindowHeight(128);
21*8975f5c5SAndroid Build Coastguard Worker         setConfigRedBits(8);
22*8975f5c5SAndroid Build Coastguard Worker         setConfigGreenBits(8);
23*8975f5c5SAndroid Build Coastguard Worker         setConfigBlueBits(8);
24*8975f5c5SAndroid Build Coastguard Worker         setConfigAlphaBits(8);
25*8975f5c5SAndroid Build Coastguard Worker     }
26*8975f5c5SAndroid Build Coastguard Worker 
27*8975f5c5SAndroid Build Coastguard Worker     void callBlendBarrier(APIExtensionVersion usedExtension);
28*8975f5c5SAndroid Build Coastguard Worker     void testAdvancedBlendNotAppliedWhenBlendIsDisabled(APIExtensionVersion usedExtension);
29*8975f5c5SAndroid Build Coastguard Worker     void testAdvancedBlendDisabledAndThenEnabled(APIExtensionVersion usedExtension);
30*8975f5c5SAndroid Build Coastguard Worker     void testAdvancedBlendEnabledAndThenDisabled(APIExtensionVersion usedExtension);
31*8975f5c5SAndroid Build Coastguard Worker };
32*8975f5c5SAndroid Build Coastguard Worker 
33*8975f5c5SAndroid Build Coastguard Worker class AdvancedBlendTestES32 : public AdvancedBlendTest
34*8975f5c5SAndroid Build Coastguard Worker {};
35*8975f5c5SAndroid Build Coastguard Worker 
callBlendBarrier(APIExtensionVersion usedExtension)36*8975f5c5SAndroid Build Coastguard Worker void AdvancedBlendTest::callBlendBarrier(APIExtensionVersion usedExtension)
37*8975f5c5SAndroid Build Coastguard Worker {
38*8975f5c5SAndroid Build Coastguard Worker     ASSERT(usedExtension == APIExtensionVersion::Core || usedExtension == APIExtensionVersion::KHR);
39*8975f5c5SAndroid Build Coastguard Worker     if (usedExtension == APIExtensionVersion::KHR)
40*8975f5c5SAndroid Build Coastguard Worker     {
41*8975f5c5SAndroid Build Coastguard Worker         glBlendBarrierKHR();
42*8975f5c5SAndroid Build Coastguard Worker     }
43*8975f5c5SAndroid Build Coastguard Worker     else
44*8975f5c5SAndroid Build Coastguard Worker     {
45*8975f5c5SAndroid Build Coastguard Worker         glBlendBarrier();
46*8975f5c5SAndroid Build Coastguard Worker     }
47*8975f5c5SAndroid Build Coastguard Worker }
48*8975f5c5SAndroid Build Coastguard Worker 
testAdvancedBlendNotAppliedWhenBlendIsDisabled(APIExtensionVersion usedExtension)49*8975f5c5SAndroid Build Coastguard Worker void AdvancedBlendTest::testAdvancedBlendNotAppliedWhenBlendIsDisabled(
50*8975f5c5SAndroid Build Coastguard Worker     APIExtensionVersion usedExtension)
51*8975f5c5SAndroid Build Coastguard Worker {
52*8975f5c5SAndroid Build Coastguard Worker     ASSERT(usedExtension == APIExtensionVersion::Core || usedExtension == APIExtensionVersion::KHR);
53*8975f5c5SAndroid Build Coastguard Worker 
54*8975f5c5SAndroid Build Coastguard Worker     constexpr char kGLSLVersion31[] = R"(#version 310 es
55*8975f5c5SAndroid Build Coastguard Worker )";
56*8975f5c5SAndroid Build Coastguard Worker     constexpr char kGLSLVersion32[] = R"(#version 320 es
57*8975f5c5SAndroid Build Coastguard Worker )";
58*8975f5c5SAndroid Build Coastguard Worker     constexpr char kBlendKHR[]      = R"(#extension GL_KHR_blend_equation_advanced : require
59*8975f5c5SAndroid Build Coastguard Worker )";
60*8975f5c5SAndroid Build Coastguard Worker 
61*8975f5c5SAndroid Build Coastguard Worker     std::string vertSrc;
62*8975f5c5SAndroid Build Coastguard Worker     std::string fragSrc;
63*8975f5c5SAndroid Build Coastguard Worker 
64*8975f5c5SAndroid Build Coastguard Worker     if (usedExtension == APIExtensionVersion::KHR)
65*8975f5c5SAndroid Build Coastguard Worker     {
66*8975f5c5SAndroid Build Coastguard Worker         vertSrc.append(kGLSLVersion31);
67*8975f5c5SAndroid Build Coastguard Worker         fragSrc.append(kGLSLVersion31);
68*8975f5c5SAndroid Build Coastguard Worker         fragSrc.append(kBlendKHR);
69*8975f5c5SAndroid Build Coastguard Worker     }
70*8975f5c5SAndroid Build Coastguard Worker     else
71*8975f5c5SAndroid Build Coastguard Worker     {
72*8975f5c5SAndroid Build Coastguard Worker         vertSrc.append(kGLSLVersion32);
73*8975f5c5SAndroid Build Coastguard Worker         fragSrc.append(kGLSLVersion32);
74*8975f5c5SAndroid Build Coastguard Worker     }
75*8975f5c5SAndroid Build Coastguard Worker 
76*8975f5c5SAndroid Build Coastguard Worker     constexpr char kVertSrcBody[] = R"(
77*8975f5c5SAndroid Build Coastguard Worker         in highp vec4 a_position;
78*8975f5c5SAndroid Build Coastguard Worker         in mediump vec4 a_color;
79*8975f5c5SAndroid Build Coastguard Worker         out mediump vec4 v_color;
80*8975f5c5SAndroid Build Coastguard Worker         void main()
81*8975f5c5SAndroid Build Coastguard Worker         {
82*8975f5c5SAndroid Build Coastguard Worker             gl_Position = a_position;
83*8975f5c5SAndroid Build Coastguard Worker             v_color = a_color;
84*8975f5c5SAndroid Build Coastguard Worker         }
85*8975f5c5SAndroid Build Coastguard Worker     )";
86*8975f5c5SAndroid Build Coastguard Worker     vertSrc.append(kVertSrcBody);
87*8975f5c5SAndroid Build Coastguard Worker 
88*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFragSrcBody[] = R"(
89*8975f5c5SAndroid Build Coastguard Worker         in mediump vec4 v_color;
90*8975f5c5SAndroid Build Coastguard Worker         layout(blend_support_colorburn) out;
91*8975f5c5SAndroid Build Coastguard Worker         layout(location = 0) out mediump vec4 o_color;
92*8975f5c5SAndroid Build Coastguard Worker         void main()
93*8975f5c5SAndroid Build Coastguard Worker         {
94*8975f5c5SAndroid Build Coastguard Worker             o_color = v_color;
95*8975f5c5SAndroid Build Coastguard Worker         }
96*8975f5c5SAndroid Build Coastguard Worker     )";
97*8975f5c5SAndroid Build Coastguard Worker     fragSrc.append(kFragSrcBody);
98*8975f5c5SAndroid Build Coastguard Worker 
99*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, vertSrc.c_str(), fragSrc.c_str());
100*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
101*8975f5c5SAndroid Build Coastguard Worker 
102*8975f5c5SAndroid Build Coastguard Worker     std::array<GLfloat, 16> attribPosData = {1, 1,  0.5, 1, -1, 1,  0.5, 1,
103*8975f5c5SAndroid Build Coastguard Worker                                              1, -1, 0.5, 1, -1, -1, 0.5, 1};
104*8975f5c5SAndroid Build Coastguard Worker 
105*8975f5c5SAndroid Build Coastguard Worker     GLint attribPosLoc = glGetAttribLocation(1, "a_position");
106*8975f5c5SAndroid Build Coastguard Worker     ASSERT(attribPosLoc >= 0);
107*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(attribPosLoc);
108*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribPointer(attribPosLoc, 4, GL_FLOAT, GL_FALSE, 0, attribPosData.data());
109*8975f5c5SAndroid Build Coastguard Worker 
110*8975f5c5SAndroid Build Coastguard Worker     std::array<GLfloat, 16> attribColorData1 = {1, 0.2, 0.5, 1, 1, 0.2, 0.5, 1,
111*8975f5c5SAndroid Build Coastguard Worker                                                 1, 0.2, 0.5, 1, 1, 0.2, 0.5, 1};
112*8975f5c5SAndroid Build Coastguard Worker     GLint attribColorLoc                     = glGetAttribLocation(1, "a_color");
113*8975f5c5SAndroid Build Coastguard Worker     ASSERT(attribColorLoc >= 0);
114*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(attribColorLoc);
115*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribPointer(attribColorLoc, 4, GL_FLOAT, GL_FALSE, 0, attribColorData1.data());
116*8975f5c5SAndroid Build Coastguard Worker 
117*8975f5c5SAndroid Build Coastguard Worker     glBlendEquation(GL_COLORBURN);
118*8975f5c5SAndroid Build Coastguard Worker 
119*8975f5c5SAndroid Build Coastguard Worker     const uint16_t indices[] = {0, 1, 2, 2, 1, 3};
120*8975f5c5SAndroid Build Coastguard Worker     glClearColor(0.5, 0.5, 0.5, 1.0);
121*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
122*8975f5c5SAndroid Build Coastguard Worker 
123*8975f5c5SAndroid Build Coastguard Worker     // Disable the blend. The next glDrawElements() should not blend the a_color with clear color
124*8975f5c5SAndroid Build Coastguard Worker     glDisable(GL_BLEND);
125*8975f5c5SAndroid Build Coastguard Worker     glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, &indices[0]);
126*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(64, 64, GLColor(255, 51, 128, 255), kPixelColorThreshhold);
127*8975f5c5SAndroid Build Coastguard Worker }
128*8975f5c5SAndroid Build Coastguard Worker 
129*8975f5c5SAndroid Build Coastguard Worker // Test that when blending is disabled, advanced blend is not applied.
130*8975f5c5SAndroid Build Coastguard Worker // Regression test for a bug in the emulation path in the Vulkan backend.
TEST_P(AdvancedBlendTest,AdvancedBlendNotAppliedWhenBlendIsDisabledKHR)131*8975f5c5SAndroid Build Coastguard Worker TEST_P(AdvancedBlendTest, AdvancedBlendNotAppliedWhenBlendIsDisabledKHR)
132*8975f5c5SAndroid Build Coastguard Worker {
133*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_KHR_blend_equation_advanced"));
134*8975f5c5SAndroid Build Coastguard Worker     testAdvancedBlendNotAppliedWhenBlendIsDisabled(APIExtensionVersion::KHR);
135*8975f5c5SAndroid Build Coastguard Worker }
136*8975f5c5SAndroid Build Coastguard Worker 
137*8975f5c5SAndroid Build Coastguard Worker // Test that when blending is disabled, advanced blend is not applied (using ES 3.2).
TEST_P(AdvancedBlendTestES32,AdvancedBlendNotAppliedWhenBlendIsDisabled)138*8975f5c5SAndroid Build Coastguard Worker TEST_P(AdvancedBlendTestES32, AdvancedBlendNotAppliedWhenBlendIsDisabled)
139*8975f5c5SAndroid Build Coastguard Worker {
140*8975f5c5SAndroid Build Coastguard Worker     testAdvancedBlendNotAppliedWhenBlendIsDisabled(APIExtensionVersion::Core);
141*8975f5c5SAndroid Build Coastguard Worker }
142*8975f5c5SAndroid Build Coastguard Worker 
testAdvancedBlendDisabledAndThenEnabled(APIExtensionVersion usedExtension)143*8975f5c5SAndroid Build Coastguard Worker void AdvancedBlendTest::testAdvancedBlendDisabledAndThenEnabled(APIExtensionVersion usedExtension)
144*8975f5c5SAndroid Build Coastguard Worker {
145*8975f5c5SAndroid Build Coastguard Worker     ASSERT(usedExtension == APIExtensionVersion::Core || usedExtension == APIExtensionVersion::KHR);
146*8975f5c5SAndroid Build Coastguard Worker 
147*8975f5c5SAndroid Build Coastguard Worker     constexpr char kGLSLVersion31[] = R"(#version 310 es
148*8975f5c5SAndroid Build Coastguard Worker )";
149*8975f5c5SAndroid Build Coastguard Worker     constexpr char kGLSLVersion32[] = R"(#version 320 es
150*8975f5c5SAndroid Build Coastguard Worker )";
151*8975f5c5SAndroid Build Coastguard Worker     constexpr char kBlendKHR[]      = R"(#extension GL_KHR_blend_equation_advanced : require
152*8975f5c5SAndroid Build Coastguard Worker )";
153*8975f5c5SAndroid Build Coastguard Worker 
154*8975f5c5SAndroid Build Coastguard Worker     std::string vertSrc;
155*8975f5c5SAndroid Build Coastguard Worker     std::string fragSrc;
156*8975f5c5SAndroid Build Coastguard Worker 
157*8975f5c5SAndroid Build Coastguard Worker     if (usedExtension == APIExtensionVersion::KHR)
158*8975f5c5SAndroid Build Coastguard Worker     {
159*8975f5c5SAndroid Build Coastguard Worker         vertSrc.append(kGLSLVersion31);
160*8975f5c5SAndroid Build Coastguard Worker         fragSrc.append(kGLSLVersion31);
161*8975f5c5SAndroid Build Coastguard Worker         fragSrc.append(kBlendKHR);
162*8975f5c5SAndroid Build Coastguard Worker     }
163*8975f5c5SAndroid Build Coastguard Worker     else
164*8975f5c5SAndroid Build Coastguard Worker     {
165*8975f5c5SAndroid Build Coastguard Worker         vertSrc.append(kGLSLVersion32);
166*8975f5c5SAndroid Build Coastguard Worker         fragSrc.append(kGLSLVersion32);
167*8975f5c5SAndroid Build Coastguard Worker     }
168*8975f5c5SAndroid Build Coastguard Worker 
169*8975f5c5SAndroid Build Coastguard Worker     constexpr char kVertSrcBody[] = R"(
170*8975f5c5SAndroid Build Coastguard Worker         in highp vec4 a_position;
171*8975f5c5SAndroid Build Coastguard Worker         in mediump vec4 a_color;
172*8975f5c5SAndroid Build Coastguard Worker         out mediump vec4 v_color;
173*8975f5c5SAndroid Build Coastguard Worker         void main()
174*8975f5c5SAndroid Build Coastguard Worker         {
175*8975f5c5SAndroid Build Coastguard Worker             gl_Position = a_position;
176*8975f5c5SAndroid Build Coastguard Worker             v_color = a_color;
177*8975f5c5SAndroid Build Coastguard Worker         }
178*8975f5c5SAndroid Build Coastguard Worker     )";
179*8975f5c5SAndroid Build Coastguard Worker     vertSrc.append(kVertSrcBody);
180*8975f5c5SAndroid Build Coastguard Worker 
181*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFragSrcBody[] = R"(
182*8975f5c5SAndroid Build Coastguard Worker         in mediump vec4 v_color;
183*8975f5c5SAndroid Build Coastguard Worker         layout(blend_support_colorburn) out;
184*8975f5c5SAndroid Build Coastguard Worker         layout(location = 0) out mediump vec4 o_color;
185*8975f5c5SAndroid Build Coastguard Worker         void main()
186*8975f5c5SAndroid Build Coastguard Worker         {
187*8975f5c5SAndroid Build Coastguard Worker             o_color = v_color;
188*8975f5c5SAndroid Build Coastguard Worker         }
189*8975f5c5SAndroid Build Coastguard Worker     )";
190*8975f5c5SAndroid Build Coastguard Worker     fragSrc.append(kFragSrcBody);
191*8975f5c5SAndroid Build Coastguard Worker 
192*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, vertSrc.c_str(), fragSrc.c_str());
193*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
194*8975f5c5SAndroid Build Coastguard Worker 
195*8975f5c5SAndroid Build Coastguard Worker     std::array<GLfloat, 16> attribPosData = {1, 1,  0.5, 1, -1, 1,  0.5, 1,
196*8975f5c5SAndroid Build Coastguard Worker                                              1, -1, 0.5, 1, -1, -1, 0.5, 1};
197*8975f5c5SAndroid Build Coastguard Worker 
198*8975f5c5SAndroid Build Coastguard Worker     GLint attribPosLoc = glGetAttribLocation(1, "a_position");
199*8975f5c5SAndroid Build Coastguard Worker     ASSERT(attribPosLoc >= 0);
200*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(attribPosLoc);
201*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribPointer(attribPosLoc, 4, GL_FLOAT, GL_FALSE, 0, attribPosData.data());
202*8975f5c5SAndroid Build Coastguard Worker 
203*8975f5c5SAndroid Build Coastguard Worker     std::array<GLfloat, 16> attribColorData1 = {1, 0.2, 0.5, 1, 1, 0.2, 0.5, 1,
204*8975f5c5SAndroid Build Coastguard Worker                                                 1, 0.2, 0.5, 1, 1, 0.2, 0.5, 1};
205*8975f5c5SAndroid Build Coastguard Worker     GLint attribColorLoc                     = glGetAttribLocation(1, "a_color");
206*8975f5c5SAndroid Build Coastguard Worker     ASSERT(attribColorLoc >= 0);
207*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(attribColorLoc);
208*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribPointer(attribColorLoc, 4, GL_FLOAT, GL_FALSE, 0, attribColorData1.data());
209*8975f5c5SAndroid Build Coastguard Worker 
210*8975f5c5SAndroid Build Coastguard Worker     glBlendEquation(GL_COLORBURN);
211*8975f5c5SAndroid Build Coastguard Worker 
212*8975f5c5SAndroid Build Coastguard Worker     const uint16_t indices[] = {0, 1, 2, 2, 1, 3};
213*8975f5c5SAndroid Build Coastguard Worker     glClearColor(0.5, 0.5, 0.5, 1.0);
214*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
215*8975f5c5SAndroid Build Coastguard Worker 
216*8975f5c5SAndroid Build Coastguard Worker     // Disable the blend. The next glDrawElements() should not blend the a_color with clear color
217*8975f5c5SAndroid Build Coastguard Worker     glDisable(GL_BLEND);
218*8975f5c5SAndroid Build Coastguard Worker     glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, &indices[0]);
219*8975f5c5SAndroid Build Coastguard Worker 
220*8975f5c5SAndroid Build Coastguard Worker     // Enable the blend. The next glDrawElements() should blend a_color
221*8975f5c5SAndroid Build Coastguard Worker     // with the the existing framebuffer output with GL_COLORBURN blend mode
222*8975f5c5SAndroid Build Coastguard Worker     glEnable(GL_BLEND);
223*8975f5c5SAndroid Build Coastguard Worker     // Test the blend with coherent blend disabled. This make the test cover both devices that
224*8975f5c5SAndroid Build Coastguard Worker     // support / do not support GL_KHR_blend_equation_advanced_coherent
225*8975f5c5SAndroid Build Coastguard Worker     if (IsGLExtensionEnabled("GL_KHR_blend_equation_advanced_coherent"))
226*8975f5c5SAndroid Build Coastguard Worker     {
227*8975f5c5SAndroid Build Coastguard Worker         glDisable(GL_BLEND_ADVANCED_COHERENT_KHR);
228*8975f5c5SAndroid Build Coastguard Worker     }
229*8975f5c5SAndroid Build Coastguard Worker     callBlendBarrier(usedExtension);
230*8975f5c5SAndroid Build Coastguard Worker     std::array<GLfloat, 16> attribColorData2 = {0.5, 0.5, 0, 1, 0.5, 0.5, 0, 1,
231*8975f5c5SAndroid Build Coastguard Worker                                                 0.5, 0.5, 0, 1, 0.5, 0.5, 0, 1};
232*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(attribColorLoc);
233*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribPointer(attribColorLoc, 4, GL_FLOAT, GL_FALSE, 0, attribColorData2.data());
234*8975f5c5SAndroid Build Coastguard Worker     glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, &indices[0]);
235*8975f5c5SAndroid Build Coastguard Worker 
236*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(64, 64, GLColor(255, 0, 0, 255), kPixelColorThreshhold);
237*8975f5c5SAndroid Build Coastguard Worker }
238*8975f5c5SAndroid Build Coastguard Worker 
239*8975f5c5SAndroid Build Coastguard Worker // Test that when blending is disabled, advanced blend is not applied, but is applied after
240*8975f5c5SAndroid Build Coastguard Worker // it is enabled.
241*8975f5c5SAndroid Build Coastguard Worker // Regression test for a bug in the emulation path in the Vulkan backend.
TEST_P(AdvancedBlendTest,AdvancedBlendDisabledAndThenEnabledKHR)242*8975f5c5SAndroid Build Coastguard Worker TEST_P(AdvancedBlendTest, AdvancedBlendDisabledAndThenEnabledKHR)
243*8975f5c5SAndroid Build Coastguard Worker {
244*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_KHR_blend_equation_advanced"));
245*8975f5c5SAndroid Build Coastguard Worker     testAdvancedBlendDisabledAndThenEnabled(APIExtensionVersion::KHR);
246*8975f5c5SAndroid Build Coastguard Worker }
247*8975f5c5SAndroid Build Coastguard Worker 
248*8975f5c5SAndroid Build Coastguard Worker // Test that when blending is disabled, advanced blend is not applied, but is applied after
249*8975f5c5SAndroid Build Coastguard Worker // it is enabled (using ES 3.2).
TEST_P(AdvancedBlendTestES32,AdvancedBlendDisabledAndThenEnabled)250*8975f5c5SAndroid Build Coastguard Worker TEST_P(AdvancedBlendTestES32, AdvancedBlendDisabledAndThenEnabled)
251*8975f5c5SAndroid Build Coastguard Worker {
252*8975f5c5SAndroid Build Coastguard Worker     testAdvancedBlendDisabledAndThenEnabled(APIExtensionVersion::Core);
253*8975f5c5SAndroid Build Coastguard Worker }
254*8975f5c5SAndroid Build Coastguard Worker 
testAdvancedBlendEnabledAndThenDisabled(APIExtensionVersion usedExtension)255*8975f5c5SAndroid Build Coastguard Worker void AdvancedBlendTest::testAdvancedBlendEnabledAndThenDisabled(APIExtensionVersion usedExtension)
256*8975f5c5SAndroid Build Coastguard Worker {
257*8975f5c5SAndroid Build Coastguard Worker     ASSERT(usedExtension == APIExtensionVersion::Core || usedExtension == APIExtensionVersion::KHR);
258*8975f5c5SAndroid Build Coastguard Worker 
259*8975f5c5SAndroid Build Coastguard Worker     constexpr char kGLSLVersion31[] = R"(#version 310 es
260*8975f5c5SAndroid Build Coastguard Worker )";
261*8975f5c5SAndroid Build Coastguard Worker     constexpr char kGLSLVersion32[] = R"(#version 320 es
262*8975f5c5SAndroid Build Coastguard Worker )";
263*8975f5c5SAndroid Build Coastguard Worker     constexpr char kBlendKHR[]      = R"(#extension GL_KHR_blend_equation_advanced : require
264*8975f5c5SAndroid Build Coastguard Worker )";
265*8975f5c5SAndroid Build Coastguard Worker 
266*8975f5c5SAndroid Build Coastguard Worker     std::string vertSrc;
267*8975f5c5SAndroid Build Coastguard Worker     std::string fragSrc;
268*8975f5c5SAndroid Build Coastguard Worker 
269*8975f5c5SAndroid Build Coastguard Worker     if (usedExtension == APIExtensionVersion::KHR)
270*8975f5c5SAndroid Build Coastguard Worker     {
271*8975f5c5SAndroid Build Coastguard Worker         vertSrc.append(kGLSLVersion31);
272*8975f5c5SAndroid Build Coastguard Worker         fragSrc.append(kGLSLVersion31);
273*8975f5c5SAndroid Build Coastguard Worker         fragSrc.append(kBlendKHR);
274*8975f5c5SAndroid Build Coastguard Worker     }
275*8975f5c5SAndroid Build Coastguard Worker     else
276*8975f5c5SAndroid Build Coastguard Worker     {
277*8975f5c5SAndroid Build Coastguard Worker         vertSrc.append(kGLSLVersion32);
278*8975f5c5SAndroid Build Coastguard Worker         fragSrc.append(kGLSLVersion32);
279*8975f5c5SAndroid Build Coastguard Worker     }
280*8975f5c5SAndroid Build Coastguard Worker 
281*8975f5c5SAndroid Build Coastguard Worker     constexpr char kVertSrcBody[] = R"(
282*8975f5c5SAndroid Build Coastguard Worker         in highp vec4 a_position;
283*8975f5c5SAndroid Build Coastguard Worker         in mediump vec4 a_color;
284*8975f5c5SAndroid Build Coastguard Worker         out mediump vec4 v_color;
285*8975f5c5SAndroid Build Coastguard Worker         void main()
286*8975f5c5SAndroid Build Coastguard Worker         {
287*8975f5c5SAndroid Build Coastguard Worker             gl_Position = a_position;
288*8975f5c5SAndroid Build Coastguard Worker             v_color = a_color;
289*8975f5c5SAndroid Build Coastguard Worker         }
290*8975f5c5SAndroid Build Coastguard Worker     )";
291*8975f5c5SAndroid Build Coastguard Worker     vertSrc.append(kVertSrcBody);
292*8975f5c5SAndroid Build Coastguard Worker 
293*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFragSrcBody[] = R"(
294*8975f5c5SAndroid Build Coastguard Worker         in mediump vec4 v_color;
295*8975f5c5SAndroid Build Coastguard Worker         layout(blend_support_colorburn) out;
296*8975f5c5SAndroid Build Coastguard Worker         layout(location = 0) out mediump vec4 o_color;
297*8975f5c5SAndroid Build Coastguard Worker         void main()
298*8975f5c5SAndroid Build Coastguard Worker         {
299*8975f5c5SAndroid Build Coastguard Worker             o_color = v_color;
300*8975f5c5SAndroid Build Coastguard Worker         }
301*8975f5c5SAndroid Build Coastguard Worker     )";
302*8975f5c5SAndroid Build Coastguard Worker     fragSrc.append(kFragSrcBody);
303*8975f5c5SAndroid Build Coastguard Worker 
304*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, vertSrc.c_str(), fragSrc.c_str());
305*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
306*8975f5c5SAndroid Build Coastguard Worker 
307*8975f5c5SAndroid Build Coastguard Worker     std::array<GLfloat, 16> attribPosData = {1, 1,  0.5, 1, -1, 1,  0.5, 1,
308*8975f5c5SAndroid Build Coastguard Worker                                              1, -1, 0.5, 1, -1, -1, 0.5, 1};
309*8975f5c5SAndroid Build Coastguard Worker 
310*8975f5c5SAndroid Build Coastguard Worker     GLint attribPosLoc = glGetAttribLocation(1, "a_position");
311*8975f5c5SAndroid Build Coastguard Worker     ASSERT(attribPosLoc >= 0);
312*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(attribPosLoc);
313*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribPointer(attribPosLoc, 4, GL_FLOAT, GL_FALSE, 0, attribPosData.data());
314*8975f5c5SAndroid Build Coastguard Worker 
315*8975f5c5SAndroid Build Coastguard Worker     std::array<GLfloat, 16> attribColorData1 = {1, 0.2, 0.5, 1, 1, 0.2, 0.5, 1,
316*8975f5c5SAndroid Build Coastguard Worker                                                 1, 0.2, 0.5, 1, 1, 0.2, 0.5, 1};
317*8975f5c5SAndroid Build Coastguard Worker     GLint attribColorLoc                     = glGetAttribLocation(1, "a_color");
318*8975f5c5SAndroid Build Coastguard Worker     ASSERT(attribColorLoc >= 0);
319*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(attribColorLoc);
320*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribPointer(attribColorLoc, 4, GL_FLOAT, GL_FALSE, 0, attribColorData1.data());
321*8975f5c5SAndroid Build Coastguard Worker 
322*8975f5c5SAndroid Build Coastguard Worker     glBlendEquation(GL_COLORBURN);
323*8975f5c5SAndroid Build Coastguard Worker 
324*8975f5c5SAndroid Build Coastguard Worker     const uint16_t indices[] = {0, 1, 2, 2, 1, 3};
325*8975f5c5SAndroid Build Coastguard Worker     glClearColor(0.5, 0.5, 0.5, 1.0);
326*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
327*8975f5c5SAndroid Build Coastguard Worker 
328*8975f5c5SAndroid Build Coastguard Worker     // Enable the blend. The next glDrawElements() should blend the a_color with clear color
329*8975f5c5SAndroid Build Coastguard Worker     // using the GL_COLORBURN blend mode
330*8975f5c5SAndroid Build Coastguard Worker     glEnable(GL_BLEND);
331*8975f5c5SAndroid Build Coastguard Worker     // Test the blend with coherent blend disabled. This make the test cover both devices that
332*8975f5c5SAndroid Build Coastguard Worker     // support / do not support GL_KHR_blend_equation_advanced_coherent
333*8975f5c5SAndroid Build Coastguard Worker     if (IsGLExtensionEnabled("GL_KHR_blend_equation_advanced_coherent"))
334*8975f5c5SAndroid Build Coastguard Worker     {
335*8975f5c5SAndroid Build Coastguard Worker         glDisable(GL_BLEND_ADVANCED_COHERENT_KHR);
336*8975f5c5SAndroid Build Coastguard Worker     }
337*8975f5c5SAndroid Build Coastguard Worker     callBlendBarrier(usedExtension);
338*8975f5c5SAndroid Build Coastguard Worker     glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, &indices[0]);
339*8975f5c5SAndroid Build Coastguard Worker 
340*8975f5c5SAndroid Build Coastguard Worker     // Disable the blend. The next glDrawElements() should not blend the a_color with
341*8975f5c5SAndroid Build Coastguard Worker     // the existing framebuffer output with GL_COLORBURN blend mode
342*8975f5c5SAndroid Build Coastguard Worker     glDisable(GL_BLEND);
343*8975f5c5SAndroid Build Coastguard Worker     std::array<GLfloat, 16> attribColorData2 = {0.5, 0.5, 0, 1, 0.5, 0.5, 0, 1,
344*8975f5c5SAndroid Build Coastguard Worker                                                 0.5, 0.5, 0, 1, 0.5, 0.5, 0, 1};
345*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(attribColorLoc);
346*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribPointer(attribColorLoc, 4, GL_FLOAT, GL_FALSE, 0, attribColorData2.data());
347*8975f5c5SAndroid Build Coastguard Worker     glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, &indices[0]);
348*8975f5c5SAndroid Build Coastguard Worker 
349*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(64, 64, GLColor(128, 128, 0, 255), kPixelColorThreshhold);
350*8975f5c5SAndroid Build Coastguard Worker }
351*8975f5c5SAndroid Build Coastguard Worker 
352*8975f5c5SAndroid Build Coastguard Worker // Test that when blending is enabled, advanced blend is applied, but is not applied after
353*8975f5c5SAndroid Build Coastguard Worker // it is disabled.
354*8975f5c5SAndroid Build Coastguard Worker // Regression test for a bug in the emulation path in the Vulkan backend.
TEST_P(AdvancedBlendTest,AdvancedBlendEnabledAndThenDisabledKHR)355*8975f5c5SAndroid Build Coastguard Worker TEST_P(AdvancedBlendTest, AdvancedBlendEnabledAndThenDisabledKHR)
356*8975f5c5SAndroid Build Coastguard Worker {
357*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_KHR_blend_equation_advanced"));
358*8975f5c5SAndroid Build Coastguard Worker     testAdvancedBlendEnabledAndThenDisabled(APIExtensionVersion::KHR);
359*8975f5c5SAndroid Build Coastguard Worker }
360*8975f5c5SAndroid Build Coastguard Worker 
361*8975f5c5SAndroid Build Coastguard Worker // Test that when blending is enabled, advanced blend is applied, but is not applied after
362*8975f5c5SAndroid Build Coastguard Worker // it is disabled (using ES 3.2).
TEST_P(AdvancedBlendTestES32,AdvancedBlendEnabledAndThenDisabled)363*8975f5c5SAndroid Build Coastguard Worker TEST_P(AdvancedBlendTestES32, AdvancedBlendEnabledAndThenDisabled)
364*8975f5c5SAndroid Build Coastguard Worker {
365*8975f5c5SAndroid Build Coastguard Worker     testAdvancedBlendEnabledAndThenDisabled(APIExtensionVersion::Core);
366*8975f5c5SAndroid Build Coastguard Worker }
367*8975f5c5SAndroid Build Coastguard Worker 
368*8975f5c5SAndroid Build Coastguard Worker // Test querying advanced blend equation coherent on supported devices (enabled by default).
TEST_P(AdvancedBlendTest,AdvancedBlendCoherentQuery)369*8975f5c5SAndroid Build Coastguard Worker TEST_P(AdvancedBlendTest, AdvancedBlendCoherentQuery)
370*8975f5c5SAndroid Build Coastguard Worker {
371*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_KHR_blend_equation_advanced_coherent"));
372*8975f5c5SAndroid Build Coastguard Worker 
373*8975f5c5SAndroid Build Coastguard Worker     GLint status = -1;
374*8975f5c5SAndroid Build Coastguard Worker     glGetIntegerv(GL_BLEND_ADVANCED_COHERENT_KHR, &status);
375*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
376*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(status, 1);
377*8975f5c5SAndroid Build Coastguard Worker 
378*8975f5c5SAndroid Build Coastguard Worker     glDisable(GL_BLEND_ADVANCED_COHERENT_KHR);
379*8975f5c5SAndroid Build Coastguard Worker     glGetIntegerv(GL_BLEND_ADVANCED_COHERENT_KHR, &status);
380*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
381*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(status, 0);
382*8975f5c5SAndroid Build Coastguard Worker 
383*8975f5c5SAndroid Build Coastguard Worker     glEnable(GL_BLEND_ADVANCED_COHERENT_KHR);
384*8975f5c5SAndroid Build Coastguard Worker     glGetIntegerv(GL_BLEND_ADVANCED_COHERENT_KHR, &status);
385*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
386*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(status, 1);
387*8975f5c5SAndroid Build Coastguard Worker }
388*8975f5c5SAndroid Build Coastguard Worker 
389*8975f5c5SAndroid Build Coastguard Worker // Test that querying advanced blend equation coherent results in an error as if this enum does not
390*8975f5c5SAndroid Build Coastguard Worker // exist.
TEST_P(AdvancedBlendTest,AdvancedBlendCoherentQueryFailsIfNotSupported)391*8975f5c5SAndroid Build Coastguard Worker TEST_P(AdvancedBlendTest, AdvancedBlendCoherentQueryFailsIfNotSupported)
392*8975f5c5SAndroid Build Coastguard Worker {
393*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsGLExtensionEnabled("GL_KHR_blend_equation_advanced_coherent"));
394*8975f5c5SAndroid Build Coastguard Worker 
395*8975f5c5SAndroid Build Coastguard Worker     GLint status = -1;
396*8975f5c5SAndroid Build Coastguard Worker     glGetIntegerv(GL_BLEND_ADVANCED_COHERENT_KHR, &status);
397*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_ERROR(GL_INVALID_ENUM);
398*8975f5c5SAndroid Build Coastguard Worker }
399*8975f5c5SAndroid Build Coastguard Worker 
400*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AdvancedBlendTest);
401*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES31(AdvancedBlendTest);
402*8975f5c5SAndroid Build Coastguard Worker 
403*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AdvancedBlendTestES32);
404*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES32(AdvancedBlendTestES32);
405