xref: /aosp_15_r20/external/angle/src/tests/gl_tests/BlendFuncExtendedTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2018 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 // BlendFuncExtendedTest
7*8975f5c5SAndroid Build Coastguard Worker //   Test EXT_blend_func_extended
8*8975f5c5SAndroid Build Coastguard Worker 
9*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/ANGLETest.h"
10*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/gl_raii.h"
11*8975f5c5SAndroid Build Coastguard Worker 
12*8975f5c5SAndroid Build Coastguard Worker #include "util/shader_utils.h"
13*8975f5c5SAndroid Build Coastguard Worker 
14*8975f5c5SAndroid Build Coastguard Worker #include <algorithm>
15*8975f5c5SAndroid Build Coastguard Worker #include <cmath>
16*8975f5c5SAndroid Build Coastguard Worker #include <fstream>
17*8975f5c5SAndroid Build Coastguard Worker 
18*8975f5c5SAndroid Build Coastguard Worker using namespace angle;
19*8975f5c5SAndroid Build Coastguard Worker 
20*8975f5c5SAndroid Build Coastguard Worker namespace
21*8975f5c5SAndroid Build Coastguard Worker {
22*8975f5c5SAndroid Build Coastguard Worker 
23*8975f5c5SAndroid Build Coastguard Worker // Partial implementation of weight function for GLES 2 blend equation that
24*8975f5c5SAndroid Build Coastguard Worker // is dual-source aware.
25*8975f5c5SAndroid Build Coastguard Worker template <int factor, int index>
Weight(const float[4],const float src[4],const float src1[4])26*8975f5c5SAndroid Build Coastguard Worker float Weight(const float /*dst*/[4], const float src[4], const float src1[4])
27*8975f5c5SAndroid Build Coastguard Worker {
28*8975f5c5SAndroid Build Coastguard Worker     if (factor == GL_SRC_COLOR)
29*8975f5c5SAndroid Build Coastguard Worker         return src[index];
30*8975f5c5SAndroid Build Coastguard Worker     if (factor == GL_SRC_ALPHA)
31*8975f5c5SAndroid Build Coastguard Worker         return src[3];
32*8975f5c5SAndroid Build Coastguard Worker     if (factor == GL_SRC1_COLOR_EXT)
33*8975f5c5SAndroid Build Coastguard Worker         return src1[index];
34*8975f5c5SAndroid Build Coastguard Worker     if (factor == GL_SRC1_ALPHA_EXT)
35*8975f5c5SAndroid Build Coastguard Worker         return src1[3];
36*8975f5c5SAndroid Build Coastguard Worker     if (factor == GL_ONE_MINUS_SRC1_COLOR_EXT)
37*8975f5c5SAndroid Build Coastguard Worker         return 1.0f - src1[index];
38*8975f5c5SAndroid Build Coastguard Worker     if (factor == GL_ONE_MINUS_SRC1_ALPHA_EXT)
39*8975f5c5SAndroid Build Coastguard Worker         return 1.0f - src1[3];
40*8975f5c5SAndroid Build Coastguard Worker     return 0.0f;
41*8975f5c5SAndroid Build Coastguard Worker }
42*8975f5c5SAndroid Build Coastguard Worker 
ScaleChannel(float weight)43*8975f5c5SAndroid Build Coastguard Worker GLubyte ScaleChannel(float weight)
44*8975f5c5SAndroid Build Coastguard Worker {
45*8975f5c5SAndroid Build Coastguard Worker     return static_cast<GLubyte>(std::floor(std::max(0.0f, std::min(1.0f, weight)) * 255.0f));
46*8975f5c5SAndroid Build Coastguard Worker }
47*8975f5c5SAndroid Build Coastguard Worker 
48*8975f5c5SAndroid Build Coastguard Worker // Implementation of GLES 2 blend equation that is dual-source aware.
49*8975f5c5SAndroid Build Coastguard Worker template <int RGBs, int RGBd, int As, int Ad>
BlendEquationFuncAdd(const float dst[4],const float src[4],const float src1[4],angle::GLColor * result)50*8975f5c5SAndroid Build Coastguard Worker void BlendEquationFuncAdd(const float dst[4],
51*8975f5c5SAndroid Build Coastguard Worker                           const float src[4],
52*8975f5c5SAndroid Build Coastguard Worker                           const float src1[4],
53*8975f5c5SAndroid Build Coastguard Worker                           angle::GLColor *result)
54*8975f5c5SAndroid Build Coastguard Worker {
55*8975f5c5SAndroid Build Coastguard Worker     float r[4];
56*8975f5c5SAndroid Build Coastguard Worker     r[0] = src[0] * Weight<RGBs, 0>(dst, src, src1) + dst[0] * Weight<RGBd, 0>(dst, src, src1);
57*8975f5c5SAndroid Build Coastguard Worker     r[1] = src[1] * Weight<RGBs, 1>(dst, src, src1) + dst[1] * Weight<RGBd, 1>(dst, src, src1);
58*8975f5c5SAndroid Build Coastguard Worker     r[2] = src[2] * Weight<RGBs, 2>(dst, src, src1) + dst[2] * Weight<RGBd, 2>(dst, src, src1);
59*8975f5c5SAndroid Build Coastguard Worker     r[3] = src[3] * Weight<As, 3>(dst, src, src1) + dst[3] * Weight<Ad, 3>(dst, src, src1);
60*8975f5c5SAndroid Build Coastguard Worker 
61*8975f5c5SAndroid Build Coastguard Worker     result->R = ScaleChannel(r[0]);
62*8975f5c5SAndroid Build Coastguard Worker     result->G = ScaleChannel(r[1]);
63*8975f5c5SAndroid Build Coastguard Worker     result->B = ScaleChannel(r[2]);
64*8975f5c5SAndroid Build Coastguard Worker     result->A = ScaleChannel(r[3]);
65*8975f5c5SAndroid Build Coastguard Worker }
66*8975f5c5SAndroid Build Coastguard Worker 
CheckPixels(GLint x,GLint y,GLsizei width,GLsizei height,GLint tolerance,const angle::GLColor & color)67*8975f5c5SAndroid Build Coastguard Worker void CheckPixels(GLint x,
68*8975f5c5SAndroid Build Coastguard Worker                  GLint y,
69*8975f5c5SAndroid Build Coastguard Worker                  GLsizei width,
70*8975f5c5SAndroid Build Coastguard Worker                  GLsizei height,
71*8975f5c5SAndroid Build Coastguard Worker                  GLint tolerance,
72*8975f5c5SAndroid Build Coastguard Worker                  const angle::GLColor &color)
73*8975f5c5SAndroid Build Coastguard Worker {
74*8975f5c5SAndroid Build Coastguard Worker     for (GLint yy = 0; yy < height; ++yy)
75*8975f5c5SAndroid Build Coastguard Worker     {
76*8975f5c5SAndroid Build Coastguard Worker         for (GLint xx = 0; xx < width; ++xx)
77*8975f5c5SAndroid Build Coastguard Worker         {
78*8975f5c5SAndroid Build Coastguard Worker             const auto px = x + xx;
79*8975f5c5SAndroid Build Coastguard Worker             const auto py = y + yy;
80*8975f5c5SAndroid Build Coastguard Worker             EXPECT_PIXEL_COLOR_NEAR(px, py, color, 2);
81*8975f5c5SAndroid Build Coastguard Worker         }
82*8975f5c5SAndroid Build Coastguard Worker     }
83*8975f5c5SAndroid Build Coastguard Worker }
84*8975f5c5SAndroid Build Coastguard Worker 
85*8975f5c5SAndroid Build Coastguard Worker const GLuint kWidth  = 100;
86*8975f5c5SAndroid Build Coastguard Worker const GLuint kHeight = 100;
87*8975f5c5SAndroid Build Coastguard Worker 
88*8975f5c5SAndroid Build Coastguard Worker class EXTBlendFuncExtendedTest : public ANGLETest<>
89*8975f5c5SAndroid Build Coastguard Worker {};
90*8975f5c5SAndroid Build Coastguard Worker 
91*8975f5c5SAndroid Build Coastguard Worker class EXTBlendFuncExtendedTestES3 : public ANGLETest<>
92*8975f5c5SAndroid Build Coastguard Worker {};
93*8975f5c5SAndroid Build Coastguard Worker 
94*8975f5c5SAndroid Build Coastguard Worker class EXTBlendFuncExtendedDrawTest : public ANGLETest<>
95*8975f5c5SAndroid Build Coastguard Worker {
96*8975f5c5SAndroid Build Coastguard Worker   protected:
EXTBlendFuncExtendedDrawTest()97*8975f5c5SAndroid Build Coastguard Worker     EXTBlendFuncExtendedDrawTest() : mProgram(0)
98*8975f5c5SAndroid Build Coastguard Worker     {
99*8975f5c5SAndroid Build Coastguard Worker         setWindowWidth(kWidth);
100*8975f5c5SAndroid Build Coastguard Worker         setWindowHeight(kHeight);
101*8975f5c5SAndroid Build Coastguard Worker         setConfigRedBits(8);
102*8975f5c5SAndroid Build Coastguard Worker         setConfigGreenBits(8);
103*8975f5c5SAndroid Build Coastguard Worker         setConfigBlueBits(8);
104*8975f5c5SAndroid Build Coastguard Worker         setConfigAlphaBits(8);
105*8975f5c5SAndroid Build Coastguard Worker     }
106*8975f5c5SAndroid Build Coastguard Worker 
testSetUp()107*8975f5c5SAndroid Build Coastguard Worker     void testSetUp() override
108*8975f5c5SAndroid Build Coastguard Worker     {
109*8975f5c5SAndroid Build Coastguard Worker         glGenBuffers(1, &mVBO);
110*8975f5c5SAndroid Build Coastguard Worker         glBindBuffer(GL_ARRAY_BUFFER, mVBO);
111*8975f5c5SAndroid Build Coastguard Worker 
112*8975f5c5SAndroid Build Coastguard Worker         static const float vertices[] = {
113*8975f5c5SAndroid Build Coastguard Worker             1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f,
114*8975f5c5SAndroid Build Coastguard Worker         };
115*8975f5c5SAndroid Build Coastguard Worker         glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
116*8975f5c5SAndroid Build Coastguard Worker 
117*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
118*8975f5c5SAndroid Build Coastguard Worker     }
119*8975f5c5SAndroid Build Coastguard Worker 
testTearDown()120*8975f5c5SAndroid Build Coastguard Worker     void testTearDown() override
121*8975f5c5SAndroid Build Coastguard Worker     {
122*8975f5c5SAndroid Build Coastguard Worker         glDeleteBuffers(1, &mVBO);
123*8975f5c5SAndroid Build Coastguard Worker         if (mProgram)
124*8975f5c5SAndroid Build Coastguard Worker         {
125*8975f5c5SAndroid Build Coastguard Worker             glDeleteProgram(mProgram);
126*8975f5c5SAndroid Build Coastguard Worker         }
127*8975f5c5SAndroid Build Coastguard Worker 
128*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
129*8975f5c5SAndroid Build Coastguard Worker     }
130*8975f5c5SAndroid Build Coastguard Worker 
makeProgram(const char * vertSource,const char * fragSource)131*8975f5c5SAndroid Build Coastguard Worker     void makeProgram(const char *vertSource, const char *fragSource)
132*8975f5c5SAndroid Build Coastguard Worker     {
133*8975f5c5SAndroid Build Coastguard Worker         mProgram = CompileProgram(vertSource, fragSource);
134*8975f5c5SAndroid Build Coastguard Worker 
135*8975f5c5SAndroid Build Coastguard Worker         ASSERT_NE(0u, mProgram);
136*8975f5c5SAndroid Build Coastguard Worker     }
137*8975f5c5SAndroid Build Coastguard Worker 
getVertexAttribLocation(const char * name)138*8975f5c5SAndroid Build Coastguard Worker     virtual GLint getVertexAttribLocation(const char *name)
139*8975f5c5SAndroid Build Coastguard Worker     {
140*8975f5c5SAndroid Build Coastguard Worker         return glGetAttribLocation(mProgram, name);
141*8975f5c5SAndroid Build Coastguard Worker     }
142*8975f5c5SAndroid Build Coastguard Worker 
getFragmentUniformLocation(const char * name)143*8975f5c5SAndroid Build Coastguard Worker     virtual GLint getFragmentUniformLocation(const char *name)
144*8975f5c5SAndroid Build Coastguard Worker     {
145*8975f5c5SAndroid Build Coastguard Worker         return glGetUniformLocation(mProgram, name);
146*8975f5c5SAndroid Build Coastguard Worker     }
147*8975f5c5SAndroid Build Coastguard Worker 
setUniform4f(GLint location,GLfloat v0,GLfloat v1,GLfloat v2,GLfloat v3)148*8975f5c5SAndroid Build Coastguard Worker     virtual void setUniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
149*8975f5c5SAndroid Build Coastguard Worker     {
150*8975f5c5SAndroid Build Coastguard Worker         glUniform4f(location, v0, v1, v2, v3);
151*8975f5c5SAndroid Build Coastguard Worker     }
152*8975f5c5SAndroid Build Coastguard Worker 
drawTest()153*8975f5c5SAndroid Build Coastguard Worker     void drawTest()
154*8975f5c5SAndroid Build Coastguard Worker     {
155*8975f5c5SAndroid Build Coastguard Worker         glUseProgram(mProgram);
156*8975f5c5SAndroid Build Coastguard Worker 
157*8975f5c5SAndroid Build Coastguard Worker         GLint position = getVertexAttribLocation(essl1_shaders::PositionAttrib());
158*8975f5c5SAndroid Build Coastguard Worker         GLint src0     = getFragmentUniformLocation("src0");
159*8975f5c5SAndroid Build Coastguard Worker         GLint src1     = getFragmentUniformLocation("src1");
160*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
161*8975f5c5SAndroid Build Coastguard Worker 
162*8975f5c5SAndroid Build Coastguard Worker         glBindBuffer(GL_ARRAY_BUFFER, mVBO);
163*8975f5c5SAndroid Build Coastguard Worker         glEnableVertexAttribArray(position);
164*8975f5c5SAndroid Build Coastguard Worker         glVertexAttribPointer(position, 2, GL_FLOAT, GL_FALSE, 0, 0);
165*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
166*8975f5c5SAndroid Build Coastguard Worker 
167*8975f5c5SAndroid Build Coastguard Worker         static const float kDst[4]  = {0.5f, 0.5f, 0.5f, 0.5f};
168*8975f5c5SAndroid Build Coastguard Worker         static const float kSrc0[4] = {1.0f, 1.0f, 1.0f, 1.0f};
169*8975f5c5SAndroid Build Coastguard Worker         static const float kSrc1[4] = {0.3f, 0.6f, 0.9f, 0.7f};
170*8975f5c5SAndroid Build Coastguard Worker 
171*8975f5c5SAndroid Build Coastguard Worker         setUniform4f(src0, kSrc0[0], kSrc0[1], kSrc0[2], kSrc0[3]);
172*8975f5c5SAndroid Build Coastguard Worker         setUniform4f(src1, kSrc1[0], kSrc1[1], kSrc1[2], kSrc1[3]);
173*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
174*8975f5c5SAndroid Build Coastguard Worker 
175*8975f5c5SAndroid Build Coastguard Worker         glEnable(GL_BLEND);
176*8975f5c5SAndroid Build Coastguard Worker         glBlendEquation(GL_FUNC_ADD);
177*8975f5c5SAndroid Build Coastguard Worker         glViewport(0, 0, kWidth, kHeight);
178*8975f5c5SAndroid Build Coastguard Worker         glClearColor(kDst[0], kDst[1], kDst[2], kDst[3]);
179*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
180*8975f5c5SAndroid Build Coastguard Worker 
181*8975f5c5SAndroid Build Coastguard Worker         {
182*8975f5c5SAndroid Build Coastguard Worker             glBlendFuncSeparate(GL_SRC1_COLOR_EXT, GL_SRC_ALPHA, GL_ONE_MINUS_SRC1_COLOR_EXT,
183*8975f5c5SAndroid Build Coastguard Worker                                 GL_ONE_MINUS_SRC1_ALPHA_EXT);
184*8975f5c5SAndroid Build Coastguard Worker 
185*8975f5c5SAndroid Build Coastguard Worker             glClear(GL_COLOR_BUFFER_BIT);
186*8975f5c5SAndroid Build Coastguard Worker             glDrawArrays(GL_TRIANGLES, 0, 6);
187*8975f5c5SAndroid Build Coastguard Worker             ASSERT_GL_NO_ERROR();
188*8975f5c5SAndroid Build Coastguard Worker 
189*8975f5c5SAndroid Build Coastguard Worker             // verify
190*8975f5c5SAndroid Build Coastguard Worker             angle::GLColor color;
191*8975f5c5SAndroid Build Coastguard Worker             BlendEquationFuncAdd<GL_SRC1_COLOR_EXT, GL_SRC_ALPHA, GL_ONE_MINUS_SRC1_COLOR_EXT,
192*8975f5c5SAndroid Build Coastguard Worker                                  GL_ONE_MINUS_SRC1_ALPHA_EXT>(kDst, kSrc0, kSrc1, &color);
193*8975f5c5SAndroid Build Coastguard Worker 
194*8975f5c5SAndroid Build Coastguard Worker             CheckPixels(kWidth / 4, (3 * kHeight) / 4, 1, 1, 1, color);
195*8975f5c5SAndroid Build Coastguard Worker             CheckPixels(kWidth - 1, 0, 1, 1, 1, color);
196*8975f5c5SAndroid Build Coastguard Worker         }
197*8975f5c5SAndroid Build Coastguard Worker 
198*8975f5c5SAndroid Build Coastguard Worker         {
199*8975f5c5SAndroid Build Coastguard Worker             glBlendFuncSeparate(GL_ONE_MINUS_SRC1_COLOR_EXT, GL_ONE_MINUS_SRC_ALPHA,
200*8975f5c5SAndroid Build Coastguard Worker                                 GL_ONE_MINUS_SRC_COLOR, GL_SRC1_ALPHA_EXT);
201*8975f5c5SAndroid Build Coastguard Worker 
202*8975f5c5SAndroid Build Coastguard Worker             glClear(GL_COLOR_BUFFER_BIT);
203*8975f5c5SAndroid Build Coastguard Worker             glDrawArrays(GL_TRIANGLES, 0, 6);
204*8975f5c5SAndroid Build Coastguard Worker             ASSERT_GL_NO_ERROR();
205*8975f5c5SAndroid Build Coastguard Worker 
206*8975f5c5SAndroid Build Coastguard Worker             // verify
207*8975f5c5SAndroid Build Coastguard Worker             angle::GLColor color;
208*8975f5c5SAndroid Build Coastguard Worker             BlendEquationFuncAdd<GL_ONE_MINUS_SRC1_COLOR_EXT, GL_ONE_MINUS_SRC_ALPHA,
209*8975f5c5SAndroid Build Coastguard Worker                                  GL_ONE_MINUS_SRC_COLOR, GL_SRC1_ALPHA_EXT>(kDst, kSrc0, kSrc1,
210*8975f5c5SAndroid Build Coastguard Worker                                                                             &color);
211*8975f5c5SAndroid Build Coastguard Worker 
212*8975f5c5SAndroid Build Coastguard Worker             CheckPixels(kWidth / 4, (3 * kHeight) / 4, 1, 1, 1, color);
213*8975f5c5SAndroid Build Coastguard Worker             CheckPixels(kWidth - 1, 0, 1, 1, 1, color);
214*8975f5c5SAndroid Build Coastguard Worker         }
215*8975f5c5SAndroid Build Coastguard Worker     }
216*8975f5c5SAndroid Build Coastguard Worker 
217*8975f5c5SAndroid Build Coastguard Worker     GLuint mVBO;
218*8975f5c5SAndroid Build Coastguard Worker     GLuint mProgram;
219*8975f5c5SAndroid Build Coastguard Worker };
220*8975f5c5SAndroid Build Coastguard Worker 
221*8975f5c5SAndroid Build Coastguard Worker class EXTBlendFuncExtendedDrawTestES3 : public EXTBlendFuncExtendedDrawTest
222*8975f5c5SAndroid Build Coastguard Worker {
223*8975f5c5SAndroid Build Coastguard Worker   protected:
EXTBlendFuncExtendedDrawTestES3()224*8975f5c5SAndroid Build Coastguard Worker     EXTBlendFuncExtendedDrawTestES3() : EXTBlendFuncExtendedDrawTest(), mIsES31OrNewer(false) {}
225*8975f5c5SAndroid Build Coastguard Worker 
testSetUp()226*8975f5c5SAndroid Build Coastguard Worker     void testSetUp() override
227*8975f5c5SAndroid Build Coastguard Worker     {
228*8975f5c5SAndroid Build Coastguard Worker         EXTBlendFuncExtendedDrawTest::testSetUp();
229*8975f5c5SAndroid Build Coastguard Worker         if (getClientMajorVersion() > 3 ||
230*8975f5c5SAndroid Build Coastguard Worker             (getClientMajorVersion() == 3 && getClientMinorVersion() >= 1))
231*8975f5c5SAndroid Build Coastguard Worker         {
232*8975f5c5SAndroid Build Coastguard Worker             mIsES31OrNewer = true;
233*8975f5c5SAndroid Build Coastguard Worker         }
234*8975f5c5SAndroid Build Coastguard Worker     }
235*8975f5c5SAndroid Build Coastguard Worker 
checkOutputIndexQuery(const char * name,GLint expectedIndex)236*8975f5c5SAndroid Build Coastguard Worker     virtual void checkOutputIndexQuery(const char *name, GLint expectedIndex)
237*8975f5c5SAndroid Build Coastguard Worker     {
238*8975f5c5SAndroid Build Coastguard Worker         GLint index = glGetFragDataIndexEXT(mProgram, name);
239*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(expectedIndex, index);
240*8975f5c5SAndroid Build Coastguard Worker         if (mIsES31OrNewer)
241*8975f5c5SAndroid Build Coastguard Worker         {
242*8975f5c5SAndroid Build Coastguard Worker             index = glGetProgramResourceLocationIndexEXT(mProgram, GL_PROGRAM_OUTPUT, name);
243*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(expectedIndex, index);
244*8975f5c5SAndroid Build Coastguard Worker         }
245*8975f5c5SAndroid Build Coastguard Worker         else
246*8975f5c5SAndroid Build Coastguard Worker         {
247*8975f5c5SAndroid Build Coastguard Worker             glGetProgramResourceLocationIndexEXT(mProgram, GL_PROGRAM_OUTPUT, name);
248*8975f5c5SAndroid Build Coastguard Worker             EXPECT_GL_ERROR(GL_INVALID_OPERATION);
249*8975f5c5SAndroid Build Coastguard Worker         }
250*8975f5c5SAndroid Build Coastguard Worker     }
251*8975f5c5SAndroid Build Coastguard Worker 
LinkProgram()252*8975f5c5SAndroid Build Coastguard Worker     void LinkProgram()
253*8975f5c5SAndroid Build Coastguard Worker     {
254*8975f5c5SAndroid Build Coastguard Worker         glLinkProgram(mProgram);
255*8975f5c5SAndroid Build Coastguard Worker         GLint linked = 0;
256*8975f5c5SAndroid Build Coastguard Worker         glGetProgramiv(mProgram, GL_LINK_STATUS, &linked);
257*8975f5c5SAndroid Build Coastguard Worker         EXPECT_NE(0, linked);
258*8975f5c5SAndroid Build Coastguard Worker         glUseProgram(mProgram);
259*8975f5c5SAndroid Build Coastguard Worker         return;
260*8975f5c5SAndroid Build Coastguard Worker     }
261*8975f5c5SAndroid Build Coastguard Worker 
262*8975f5c5SAndroid Build Coastguard Worker   private:
263*8975f5c5SAndroid Build Coastguard Worker     bool mIsES31OrNewer;
264*8975f5c5SAndroid Build Coastguard Worker };
265*8975f5c5SAndroid Build Coastguard Worker 
266*8975f5c5SAndroid Build Coastguard Worker class EXTBlendFuncExtendedDrawTestES31 : public EXTBlendFuncExtendedDrawTestES3
267*8975f5c5SAndroid Build Coastguard Worker {
268*8975f5c5SAndroid Build Coastguard Worker   protected:
EXTBlendFuncExtendedDrawTestES31()269*8975f5c5SAndroid Build Coastguard Worker     EXTBlendFuncExtendedDrawTestES31()
270*8975f5c5SAndroid Build Coastguard Worker         : EXTBlendFuncExtendedDrawTestES3(), mPipeline(0), mVertexProgram(0), mFragProgram(0)
271*8975f5c5SAndroid Build Coastguard Worker     {}
272*8975f5c5SAndroid Build Coastguard Worker 
getVertexAttribLocation(const char * name)273*8975f5c5SAndroid Build Coastguard Worker     GLint getVertexAttribLocation(const char *name) override
274*8975f5c5SAndroid Build Coastguard Worker     {
275*8975f5c5SAndroid Build Coastguard Worker         return glGetAttribLocation(mVertexProgram, name);
276*8975f5c5SAndroid Build Coastguard Worker     }
277*8975f5c5SAndroid Build Coastguard Worker 
getFragmentUniformLocation(const char * name)278*8975f5c5SAndroid Build Coastguard Worker     GLint getFragmentUniformLocation(const char *name) override
279*8975f5c5SAndroid Build Coastguard Worker     {
280*8975f5c5SAndroid Build Coastguard Worker         return glGetUniformLocation(mFragProgram, name);
281*8975f5c5SAndroid Build Coastguard Worker     }
282*8975f5c5SAndroid Build Coastguard Worker 
setUniform4f(GLint location,GLfloat v0,GLfloat v1,GLfloat v2,GLfloat v3)283*8975f5c5SAndroid Build Coastguard Worker     void setUniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) override
284*8975f5c5SAndroid Build Coastguard Worker     {
285*8975f5c5SAndroid Build Coastguard Worker         glActiveShaderProgram(mPipeline, mFragProgram);
286*8975f5c5SAndroid Build Coastguard Worker         EXTBlendFuncExtendedDrawTest::setUniform4f(location, v0, v1, v2, v3);
287*8975f5c5SAndroid Build Coastguard Worker     }
288*8975f5c5SAndroid Build Coastguard Worker 
checkOutputIndexQuery(const char * name,GLint expectedIndex)289*8975f5c5SAndroid Build Coastguard Worker     void checkOutputIndexQuery(const char *name, GLint expectedIndex) override
290*8975f5c5SAndroid Build Coastguard Worker     {
291*8975f5c5SAndroid Build Coastguard Worker         GLint index = glGetFragDataIndexEXT(mFragProgram, name);
292*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(expectedIndex, index);
293*8975f5c5SAndroid Build Coastguard Worker         index = glGetProgramResourceLocationIndexEXT(mFragProgram, GL_PROGRAM_OUTPUT, name);
294*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(expectedIndex, index);
295*8975f5c5SAndroid Build Coastguard Worker     }
296*8975f5c5SAndroid Build Coastguard Worker 
setupProgramPipeline(const char * vertexSource,const char * fragmentSource)297*8975f5c5SAndroid Build Coastguard Worker     void setupProgramPipeline(const char *vertexSource, const char *fragmentSource)
298*8975f5c5SAndroid Build Coastguard Worker     {
299*8975f5c5SAndroid Build Coastguard Worker         mVertexProgram = createShaderProgram(GL_VERTEX_SHADER, vertexSource);
300*8975f5c5SAndroid Build Coastguard Worker         ASSERT_NE(mVertexProgram, 0u);
301*8975f5c5SAndroid Build Coastguard Worker         mFragProgram = createShaderProgram(GL_FRAGMENT_SHADER, fragmentSource);
302*8975f5c5SAndroid Build Coastguard Worker         ASSERT_NE(mFragProgram, 0u);
303*8975f5c5SAndroid Build Coastguard Worker 
304*8975f5c5SAndroid Build Coastguard Worker         // Generate a program pipeline and attach the programs to their respective stages
305*8975f5c5SAndroid Build Coastguard Worker         glGenProgramPipelines(1, &mPipeline);
306*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
307*8975f5c5SAndroid Build Coastguard Worker         glUseProgramStages(mPipeline, GL_VERTEX_SHADER_BIT, mVertexProgram);
308*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
309*8975f5c5SAndroid Build Coastguard Worker         glUseProgramStages(mPipeline, GL_FRAGMENT_SHADER_BIT, mFragProgram);
310*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
311*8975f5c5SAndroid Build Coastguard Worker         glBindProgramPipeline(mPipeline);
312*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
313*8975f5c5SAndroid Build Coastguard Worker     }
314*8975f5c5SAndroid Build Coastguard Worker 
createShaderProgram(GLenum type,const GLchar * shaderString)315*8975f5c5SAndroid Build Coastguard Worker     GLuint createShaderProgram(GLenum type, const GLchar *shaderString)
316*8975f5c5SAndroid Build Coastguard Worker     {
317*8975f5c5SAndroid Build Coastguard Worker         GLShader shader(type);
318*8975f5c5SAndroid Build Coastguard Worker         if (!shader)
319*8975f5c5SAndroid Build Coastguard Worker         {
320*8975f5c5SAndroid Build Coastguard Worker             return 0;
321*8975f5c5SAndroid Build Coastguard Worker         }
322*8975f5c5SAndroid Build Coastguard Worker 
323*8975f5c5SAndroid Build Coastguard Worker         glShaderSource(shader, 1, &shaderString, nullptr);
324*8975f5c5SAndroid Build Coastguard Worker         glCompileShader(shader);
325*8975f5c5SAndroid Build Coastguard Worker 
326*8975f5c5SAndroid Build Coastguard Worker         GLuint program = glCreateProgram();
327*8975f5c5SAndroid Build Coastguard Worker 
328*8975f5c5SAndroid Build Coastguard Worker         if (program)
329*8975f5c5SAndroid Build Coastguard Worker         {
330*8975f5c5SAndroid Build Coastguard Worker             GLint compiled;
331*8975f5c5SAndroid Build Coastguard Worker             glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
332*8975f5c5SAndroid Build Coastguard Worker             glProgramParameteri(program, GL_PROGRAM_SEPARABLE, GL_TRUE);
333*8975f5c5SAndroid Build Coastguard Worker             if (compiled)
334*8975f5c5SAndroid Build Coastguard Worker             {
335*8975f5c5SAndroid Build Coastguard Worker                 glAttachShader(program, shader);
336*8975f5c5SAndroid Build Coastguard Worker                 glLinkProgram(program);
337*8975f5c5SAndroid Build Coastguard Worker                 glDetachShader(program, shader);
338*8975f5c5SAndroid Build Coastguard Worker             }
339*8975f5c5SAndroid Build Coastguard Worker         }
340*8975f5c5SAndroid Build Coastguard Worker 
341*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
342*8975f5c5SAndroid Build Coastguard Worker 
343*8975f5c5SAndroid Build Coastguard Worker         return program;
344*8975f5c5SAndroid Build Coastguard Worker     }
345*8975f5c5SAndroid Build Coastguard Worker 
testTearDown()346*8975f5c5SAndroid Build Coastguard Worker     void testTearDown() override
347*8975f5c5SAndroid Build Coastguard Worker     {
348*8975f5c5SAndroid Build Coastguard Worker         EXTBlendFuncExtendedDrawTest::testTearDown();
349*8975f5c5SAndroid Build Coastguard Worker         if (mVertexProgram)
350*8975f5c5SAndroid Build Coastguard Worker         {
351*8975f5c5SAndroid Build Coastguard Worker             glDeleteProgram(mVertexProgram);
352*8975f5c5SAndroid Build Coastguard Worker         }
353*8975f5c5SAndroid Build Coastguard Worker         if (mFragProgram)
354*8975f5c5SAndroid Build Coastguard Worker         {
355*8975f5c5SAndroid Build Coastguard Worker             glDeleteProgram(mFragProgram);
356*8975f5c5SAndroid Build Coastguard Worker         }
357*8975f5c5SAndroid Build Coastguard Worker         if (mPipeline)
358*8975f5c5SAndroid Build Coastguard Worker         {
359*8975f5c5SAndroid Build Coastguard Worker             glDeleteProgramPipelines(1, &mPipeline);
360*8975f5c5SAndroid Build Coastguard Worker         }
361*8975f5c5SAndroid Build Coastguard Worker 
362*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
363*8975f5c5SAndroid Build Coastguard Worker     }
364*8975f5c5SAndroid Build Coastguard Worker 
365*8975f5c5SAndroid Build Coastguard Worker     GLuint mPipeline;
366*8975f5c5SAndroid Build Coastguard Worker     GLuint mVertexProgram;
367*8975f5c5SAndroid Build Coastguard Worker     GLuint mFragProgram;
368*8975f5c5SAndroid Build Coastguard Worker };
369*8975f5c5SAndroid Build Coastguard Worker }  // namespace
370*8975f5c5SAndroid Build Coastguard Worker 
371*8975f5c5SAndroid Build Coastguard Worker // Test EXT_blend_func_extended related gets.
TEST_P(EXTBlendFuncExtendedTest,TestMaxDualSourceDrawBuffers)372*8975f5c5SAndroid Build Coastguard Worker TEST_P(EXTBlendFuncExtendedTest, TestMaxDualSourceDrawBuffers)
373*8975f5c5SAndroid Build Coastguard Worker {
374*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_blend_func_extended"));
375*8975f5c5SAndroid Build Coastguard Worker 
376*8975f5c5SAndroid Build Coastguard Worker     GLint maxDualSourceDrawBuffers = 0;
377*8975f5c5SAndroid Build Coastguard Worker     glGetIntegerv(GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT, &maxDualSourceDrawBuffers);
378*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GT(maxDualSourceDrawBuffers, 0);
379*8975f5c5SAndroid Build Coastguard Worker 
380*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
381*8975f5c5SAndroid Build Coastguard Worker }
382*8975f5c5SAndroid Build Coastguard Worker 
383*8975f5c5SAndroid Build Coastguard Worker // Test that SRC1 factors limit the number of allowed draw buffers.
TEST_P(EXTBlendFuncExtendedTest,MaxDualSourceDrawBuffersError)384*8975f5c5SAndroid Build Coastguard Worker TEST_P(EXTBlendFuncExtendedTest, MaxDualSourceDrawBuffersError)
385*8975f5c5SAndroid Build Coastguard Worker {
386*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_blend_func_extended"));
387*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_draw_buffers"));
388*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_rgb8_rgba8"));
389*8975f5c5SAndroid Build Coastguard Worker 
390*8975f5c5SAndroid Build Coastguard Worker     GLint maxDualSourceDrawBuffers = 0;
391*8975f5c5SAndroid Build Coastguard Worker     glGetIntegerv(GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT, &maxDualSourceDrawBuffers);
392*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(maxDualSourceDrawBuffers != 1);
393*8975f5c5SAndroid Build Coastguard Worker 
394*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(redProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
395*8975f5c5SAndroid Build Coastguard Worker 
396*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer fbo;
397*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
398*8975f5c5SAndroid Build Coastguard Worker 
399*8975f5c5SAndroid Build Coastguard Worker     GLRenderbuffer rb0;
400*8975f5c5SAndroid Build Coastguard Worker     glBindRenderbuffer(GL_RENDERBUFFER, rb0);
401*8975f5c5SAndroid Build Coastguard Worker     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8_OES, 1, 1);
402*8975f5c5SAndroid Build Coastguard Worker     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER, rb0);
403*8975f5c5SAndroid Build Coastguard Worker 
404*8975f5c5SAndroid Build Coastguard Worker     GLRenderbuffer rb1;
405*8975f5c5SAndroid Build Coastguard Worker     glBindRenderbuffer(GL_RENDERBUFFER, rb1);
406*8975f5c5SAndroid Build Coastguard Worker     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8_OES, 1, 1);
407*8975f5c5SAndroid Build Coastguard Worker     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1_EXT, GL_RENDERBUFFER, rb1);
408*8975f5c5SAndroid Build Coastguard Worker 
409*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
410*8975f5c5SAndroid Build Coastguard Worker 
411*8975f5c5SAndroid Build Coastguard Worker     const GLenum bufs[] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT};
412*8975f5c5SAndroid Build Coastguard Worker     glDrawBuffersEXT(2, bufs);
413*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
414*8975f5c5SAndroid Build Coastguard Worker 
415*8975f5c5SAndroid Build Coastguard Worker     for (const GLenum func : {GL_SRC1_COLOR_EXT, GL_ONE_MINUS_SRC1_COLOR_EXT, GL_SRC1_ALPHA_EXT,
416*8975f5c5SAndroid Build Coastguard Worker                               GL_ONE_MINUS_SRC1_ALPHA_EXT})
417*8975f5c5SAndroid Build Coastguard Worker     {
418*8975f5c5SAndroid Build Coastguard Worker         for (size_t slot = 0; slot < 4; slot++)
419*8975f5c5SAndroid Build Coastguard Worker         {
420*8975f5c5SAndroid Build Coastguard Worker             switch (slot)
421*8975f5c5SAndroid Build Coastguard Worker             {
422*8975f5c5SAndroid Build Coastguard Worker                 case 0:
423*8975f5c5SAndroid Build Coastguard Worker                     glBlendFuncSeparate(func, GL_ONE, GL_ONE, GL_ONE);
424*8975f5c5SAndroid Build Coastguard Worker                     break;
425*8975f5c5SAndroid Build Coastguard Worker                 case 1:
426*8975f5c5SAndroid Build Coastguard Worker                     glBlendFuncSeparate(GL_ONE, func, GL_ONE, GL_ONE);
427*8975f5c5SAndroid Build Coastguard Worker                     break;
428*8975f5c5SAndroid Build Coastguard Worker                 case 2:
429*8975f5c5SAndroid Build Coastguard Worker                     glBlendFuncSeparate(GL_ONE, GL_ONE, func, GL_ONE);
430*8975f5c5SAndroid Build Coastguard Worker                     break;
431*8975f5c5SAndroid Build Coastguard Worker                 case 3:
432*8975f5c5SAndroid Build Coastguard Worker                     glBlendFuncSeparate(GL_ONE, GL_ONE, GL_ONE, func);
433*8975f5c5SAndroid Build Coastguard Worker                     break;
434*8975f5c5SAndroid Build Coastguard Worker             }
435*8975f5c5SAndroid Build Coastguard Worker             // Limit must be applied even with blending disabled
436*8975f5c5SAndroid Build Coastguard Worker             glDisable(GL_BLEND);
437*8975f5c5SAndroid Build Coastguard Worker             drawQuad(redProgram, essl1_shaders::PositionAttrib(), 0.0);
438*8975f5c5SAndroid Build Coastguard Worker             EXPECT_GL_ERROR(GL_INVALID_OPERATION);
439*8975f5c5SAndroid Build Coastguard Worker 
440*8975f5c5SAndroid Build Coastguard Worker             glEnable(GL_BLEND);
441*8975f5c5SAndroid Build Coastguard Worker             drawQuad(redProgram, essl1_shaders::PositionAttrib(), 0.0);
442*8975f5c5SAndroid Build Coastguard Worker             EXPECT_GL_ERROR(GL_INVALID_OPERATION);
443*8975f5c5SAndroid Build Coastguard Worker 
444*8975f5c5SAndroid Build Coastguard Worker             // Limit must be applied even when an attachment is missing
445*8975f5c5SAndroid Build Coastguard Worker             glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1_EXT, GL_RENDERBUFFER, 0);
446*8975f5c5SAndroid Build Coastguard Worker             drawQuad(redProgram, essl1_shaders::PositionAttrib(), 0.0);
447*8975f5c5SAndroid Build Coastguard Worker             EXPECT_GL_ERROR(GL_INVALID_OPERATION);
448*8975f5c5SAndroid Build Coastguard Worker 
449*8975f5c5SAndroid Build Coastguard Worker             // Restore the attachment for the next iteration
450*8975f5c5SAndroid Build Coastguard Worker             glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1_EXT, GL_RENDERBUFFER,
451*8975f5c5SAndroid Build Coastguard Worker                                       rb1);
452*8975f5c5SAndroid Build Coastguard Worker 
453*8975f5c5SAndroid Build Coastguard Worker             // Limit is not applied when non-SRC1 funcs are used
454*8975f5c5SAndroid Build Coastguard Worker             glBlendFunc(GL_ONE, GL_ONE);
455*8975f5c5SAndroid Build Coastguard Worker             drawQuad(redProgram, essl1_shaders::PositionAttrib(), 0.0);
456*8975f5c5SAndroid Build Coastguard Worker             EXPECT_GL_NO_ERROR();
457*8975f5c5SAndroid Build Coastguard Worker         }
458*8975f5c5SAndroid Build Coastguard Worker     }
459*8975f5c5SAndroid Build Coastguard Worker }
460*8975f5c5SAndroid Build Coastguard Worker 
461*8975f5c5SAndroid Build Coastguard Worker // Test a shader with EXT_blend_func_extended and gl_SecondaryFragColorEXT.
462*8975f5c5SAndroid Build Coastguard Worker // Outputs to primary color buffer using primary and secondary colors.
TEST_P(EXTBlendFuncExtendedDrawTest,FragColor)463*8975f5c5SAndroid Build Coastguard Worker TEST_P(EXTBlendFuncExtendedDrawTest, FragColor)
464*8975f5c5SAndroid Build Coastguard Worker {
465*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_blend_func_extended"));
466*8975f5c5SAndroid Build Coastguard Worker 
467*8975f5c5SAndroid Build Coastguard Worker     const char *kFragColorShader =
468*8975f5c5SAndroid Build Coastguard Worker         "#extension GL_EXT_blend_func_extended : require\n"
469*8975f5c5SAndroid Build Coastguard Worker         "precision mediump float;\n"
470*8975f5c5SAndroid Build Coastguard Worker         "uniform vec4 src0;\n"
471*8975f5c5SAndroid Build Coastguard Worker         "uniform vec4 src1;\n"
472*8975f5c5SAndroid Build Coastguard Worker         "void main() {\n"
473*8975f5c5SAndroid Build Coastguard Worker         "  gl_FragColor = src0;\n"
474*8975f5c5SAndroid Build Coastguard Worker         "  gl_SecondaryFragColorEXT = src1;\n"
475*8975f5c5SAndroid Build Coastguard Worker         "}\n";
476*8975f5c5SAndroid Build Coastguard Worker 
477*8975f5c5SAndroid Build Coastguard Worker     makeProgram(essl1_shaders::vs::Simple(), kFragColorShader);
478*8975f5c5SAndroid Build Coastguard Worker 
479*8975f5c5SAndroid Build Coastguard Worker     drawTest();
480*8975f5c5SAndroid Build Coastguard Worker }
481*8975f5c5SAndroid Build Coastguard Worker 
482*8975f5c5SAndroid Build Coastguard Worker // Test a shader with EXT_blend_func_extended and EXT_draw_buffers enabled at the same time.
TEST_P(EXTBlendFuncExtendedDrawTest,FragColorBroadcast)483*8975f5c5SAndroid Build Coastguard Worker TEST_P(EXTBlendFuncExtendedDrawTest, FragColorBroadcast)
484*8975f5c5SAndroid Build Coastguard Worker {
485*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_blend_func_extended"));
486*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_draw_buffers"));
487*8975f5c5SAndroid Build Coastguard Worker 
488*8975f5c5SAndroid Build Coastguard Worker     const char *kFragColorShader =
489*8975f5c5SAndroid Build Coastguard Worker         "#extension GL_EXT_blend_func_extended : require\n"
490*8975f5c5SAndroid Build Coastguard Worker         "#extension GL_EXT_draw_buffers : require\n"
491*8975f5c5SAndroid Build Coastguard Worker         "precision mediump float;\n"
492*8975f5c5SAndroid Build Coastguard Worker         "uniform vec4 src0;\n"
493*8975f5c5SAndroid Build Coastguard Worker         "uniform vec4 src1;\n"
494*8975f5c5SAndroid Build Coastguard Worker         "void main() {\n"
495*8975f5c5SAndroid Build Coastguard Worker         "  gl_FragColor = src0;\n"
496*8975f5c5SAndroid Build Coastguard Worker         "  gl_SecondaryFragColorEXT = src1;\n"
497*8975f5c5SAndroid Build Coastguard Worker         "}\n";
498*8975f5c5SAndroid Build Coastguard Worker 
499*8975f5c5SAndroid Build Coastguard Worker     makeProgram(essl1_shaders::vs::Simple(), kFragColorShader);
500*8975f5c5SAndroid Build Coastguard Worker 
501*8975f5c5SAndroid Build Coastguard Worker     drawTest();
502*8975f5c5SAndroid Build Coastguard Worker }
503*8975f5c5SAndroid Build Coastguard Worker 
504*8975f5c5SAndroid Build Coastguard Worker // Test a shader with EXT_blend_func_extended and gl_FragData.
505*8975f5c5SAndroid Build Coastguard Worker // Outputs to a color buffer using primary and secondary frag data.
TEST_P(EXTBlendFuncExtendedDrawTest,FragData)506*8975f5c5SAndroid Build Coastguard Worker TEST_P(EXTBlendFuncExtendedDrawTest, FragData)
507*8975f5c5SAndroid Build Coastguard Worker {
508*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_blend_func_extended"));
509*8975f5c5SAndroid Build Coastguard Worker 
510*8975f5c5SAndroid Build Coastguard Worker     const char *kFragColorShader =
511*8975f5c5SAndroid Build Coastguard Worker         "#extension GL_EXT_blend_func_extended : require\n"
512*8975f5c5SAndroid Build Coastguard Worker         "precision mediump float;\n"
513*8975f5c5SAndroid Build Coastguard Worker         "uniform vec4 src0;\n"
514*8975f5c5SAndroid Build Coastguard Worker         "uniform vec4 src1;\n"
515*8975f5c5SAndroid Build Coastguard Worker         "void main() {\n"
516*8975f5c5SAndroid Build Coastguard Worker         "  gl_FragData[0] = src0;\n"
517*8975f5c5SAndroid Build Coastguard Worker         "  gl_SecondaryFragDataEXT[0] = src1;\n"
518*8975f5c5SAndroid Build Coastguard Worker         "}\n";
519*8975f5c5SAndroid Build Coastguard Worker 
520*8975f5c5SAndroid Build Coastguard Worker     makeProgram(essl1_shaders::vs::Simple(), kFragColorShader);
521*8975f5c5SAndroid Build Coastguard Worker 
522*8975f5c5SAndroid Build Coastguard Worker     drawTest();
523*8975f5c5SAndroid Build Coastguard Worker }
524*8975f5c5SAndroid Build Coastguard Worker 
525*8975f5c5SAndroid Build Coastguard Worker // Test that min/max blending works correctly with SRC1 factors.
TEST_P(EXTBlendFuncExtendedDrawTest,MinMax)526*8975f5c5SAndroid Build Coastguard Worker TEST_P(EXTBlendFuncExtendedDrawTest, MinMax)
527*8975f5c5SAndroid Build Coastguard Worker {
528*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_blend_func_extended"));
529*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_blend_minmax"));
530*8975f5c5SAndroid Build Coastguard Worker 
531*8975f5c5SAndroid Build Coastguard Worker     const char *kFragColorShader = R"(#extension GL_EXT_blend_func_extended : require
532*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
533*8975f5c5SAndroid Build Coastguard Worker void main() {
534*8975f5c5SAndroid Build Coastguard Worker     gl_FragColor             = vec4(0.125, 0.25, 0.75, 0.875);
535*8975f5c5SAndroid Build Coastguard Worker     gl_SecondaryFragColorEXT = vec4(0.0, 0.0, 0.0, 0.0);
536*8975f5c5SAndroid Build Coastguard Worker })";
537*8975f5c5SAndroid Build Coastguard Worker     makeProgram(essl1_shaders::vs::Simple(), kFragColorShader);
538*8975f5c5SAndroid Build Coastguard Worker 
539*8975f5c5SAndroid Build Coastguard Worker     glEnable(GL_BLEND);
540*8975f5c5SAndroid Build Coastguard Worker     glBlendFuncSeparate(GL_SRC1_COLOR_EXT, GL_ONE_MINUS_SRC1_COLOR_EXT, GL_SRC1_ALPHA_EXT,
541*8975f5c5SAndroid Build Coastguard Worker                         GL_ONE_MINUS_SRC1_ALPHA_EXT);
542*8975f5c5SAndroid Build Coastguard Worker     glClearColor(0.5, 0.5, 0.5, 0.5);
543*8975f5c5SAndroid Build Coastguard Worker 
544*8975f5c5SAndroid Build Coastguard Worker     auto test = [&](GLenum colorOp, GLenum alphaOp, GLColor color) {
545*8975f5c5SAndroid Build Coastguard Worker         glBlendEquationSeparate(colorOp, alphaOp);
546*8975f5c5SAndroid Build Coastguard Worker         glClear(GL_COLOR_BUFFER_BIT);
547*8975f5c5SAndroid Build Coastguard Worker         drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.0);
548*8975f5c5SAndroid Build Coastguard Worker         EXPECT_PIXEL_COLOR_NEAR(0, 0, color, 2);
549*8975f5c5SAndroid Build Coastguard Worker     };
550*8975f5c5SAndroid Build Coastguard Worker     test(GL_MIN_EXT, GL_MIN_EXT, GLColor(32, 64, 128, 128));
551*8975f5c5SAndroid Build Coastguard Worker     test(GL_MIN_EXT, GL_MAX_EXT, GLColor(32, 64, 128, 224));
552*8975f5c5SAndroid Build Coastguard Worker     test(GL_MAX_EXT, GL_MIN_EXT, GLColor(128, 128, 192, 128));
553*8975f5c5SAndroid Build Coastguard Worker     test(GL_MAX_EXT, GL_MAX_EXT, GLColor(128, 128, 192, 224));
554*8975f5c5SAndroid Build Coastguard Worker }
555*8975f5c5SAndroid Build Coastguard Worker 
556*8975f5c5SAndroid Build Coastguard Worker // Test an ESSL 3.00 shader that uses two fragment outputs with locations specified in the shader.
TEST_P(EXTBlendFuncExtendedDrawTestES3,FragmentOutputLocationsInShader)557*8975f5c5SAndroid Build Coastguard Worker TEST_P(EXTBlendFuncExtendedDrawTestES3, FragmentOutputLocationsInShader)
558*8975f5c5SAndroid Build Coastguard Worker {
559*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_blend_func_extended"));
560*8975f5c5SAndroid Build Coastguard Worker 
561*8975f5c5SAndroid Build Coastguard Worker     const char *kFragColorShader = R"(#version 300 es
562*8975f5c5SAndroid Build Coastguard Worker #extension GL_EXT_blend_func_extended : require
563*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
564*8975f5c5SAndroid Build Coastguard Worker uniform vec4 src0;
565*8975f5c5SAndroid Build Coastguard Worker uniform vec4 src1;
566*8975f5c5SAndroid Build Coastguard Worker layout(location = 0, index = 1) out vec4 outSrc1;
567*8975f5c5SAndroid Build Coastguard Worker layout(location = 0, index = 0) out vec4 outSrc0;
568*8975f5c5SAndroid Build Coastguard Worker void main() {
569*8975f5c5SAndroid Build Coastguard Worker     outSrc0 = src0;
570*8975f5c5SAndroid Build Coastguard Worker     outSrc1 = src1;
571*8975f5c5SAndroid Build Coastguard Worker })";
572*8975f5c5SAndroid Build Coastguard Worker 
573*8975f5c5SAndroid Build Coastguard Worker     makeProgram(essl3_shaders::vs::Simple(), kFragColorShader);
574*8975f5c5SAndroid Build Coastguard Worker 
575*8975f5c5SAndroid Build Coastguard Worker     checkOutputIndexQuery("outSrc0", 0);
576*8975f5c5SAndroid Build Coastguard Worker     checkOutputIndexQuery("outSrc1", 1);
577*8975f5c5SAndroid Build Coastguard Worker 
578*8975f5c5SAndroid Build Coastguard Worker     drawTest();
579*8975f5c5SAndroid Build Coastguard Worker }
580*8975f5c5SAndroid Build Coastguard Worker 
581*8975f5c5SAndroid Build Coastguard Worker // Test an ESSL 3.00 shader that uses two fragment outputs with locations specified through the API.
TEST_P(EXTBlendFuncExtendedDrawTestES3,FragmentOutputLocationsAPI)582*8975f5c5SAndroid Build Coastguard Worker TEST_P(EXTBlendFuncExtendedDrawTestES3, FragmentOutputLocationsAPI)
583*8975f5c5SAndroid Build Coastguard Worker {
584*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_blend_func_extended"));
585*8975f5c5SAndroid Build Coastguard Worker 
586*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFS[] = R"(#version 300 es
587*8975f5c5SAndroid Build Coastguard Worker #extension GL_EXT_blend_func_extended : require
588*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
589*8975f5c5SAndroid Build Coastguard Worker uniform vec4 src0;
590*8975f5c5SAndroid Build Coastguard Worker uniform vec4 src1;
591*8975f5c5SAndroid Build Coastguard Worker out vec4 outSrc1;
592*8975f5c5SAndroid Build Coastguard Worker out vec4 outSrc0;
593*8975f5c5SAndroid Build Coastguard Worker void main() {
594*8975f5c5SAndroid Build Coastguard Worker     outSrc0 = src0;
595*8975f5c5SAndroid Build Coastguard Worker     outSrc1 = src1;
596*8975f5c5SAndroid Build Coastguard Worker })";
597*8975f5c5SAndroid Build Coastguard Worker 
598*8975f5c5SAndroid Build Coastguard Worker     mProgram = CompileProgram(essl3_shaders::vs::Simple(), kFS, [](GLuint program) {
599*8975f5c5SAndroid Build Coastguard Worker         glBindFragDataLocationIndexedEXT(program, 0, 0, "outSrc0");
600*8975f5c5SAndroid Build Coastguard Worker         glBindFragDataLocationIndexedEXT(program, 0, 1, "outSrc1");
601*8975f5c5SAndroid Build Coastguard Worker     });
602*8975f5c5SAndroid Build Coastguard Worker 
603*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(0u, mProgram);
604*8975f5c5SAndroid Build Coastguard Worker 
605*8975f5c5SAndroid Build Coastguard Worker     checkOutputIndexQuery("outSrc0", 0);
606*8975f5c5SAndroid Build Coastguard Worker     checkOutputIndexQuery("outSrc1", 1);
607*8975f5c5SAndroid Build Coastguard Worker 
608*8975f5c5SAndroid Build Coastguard Worker     drawTest();
609*8975f5c5SAndroid Build Coastguard Worker }
610*8975f5c5SAndroid Build Coastguard Worker 
611*8975f5c5SAndroid Build Coastguard Worker // Test an ESSL 3.00 shader that uses two fragment outputs, with location for one specified through
612*8975f5c5SAndroid Build Coastguard Worker // the API and location for another being set automatically.
TEST_P(EXTBlendFuncExtendedDrawTestES3,FragmentOutputLocationsAPIAndAutomatic)613*8975f5c5SAndroid Build Coastguard Worker TEST_P(EXTBlendFuncExtendedDrawTestES3, FragmentOutputLocationsAPIAndAutomatic)
614*8975f5c5SAndroid Build Coastguard Worker {
615*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_blend_func_extended"));
616*8975f5c5SAndroid Build Coastguard Worker 
617*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFS[] = R"(#version 300 es
618*8975f5c5SAndroid Build Coastguard Worker #extension GL_EXT_blend_func_extended : require
619*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
620*8975f5c5SAndroid Build Coastguard Worker uniform vec4 src0;
621*8975f5c5SAndroid Build Coastguard Worker uniform vec4 src1;
622*8975f5c5SAndroid Build Coastguard Worker out vec4 outSrc1;
623*8975f5c5SAndroid Build Coastguard Worker out vec4 outSrc0;
624*8975f5c5SAndroid Build Coastguard Worker void main() {
625*8975f5c5SAndroid Build Coastguard Worker     outSrc0 = src0;
626*8975f5c5SAndroid Build Coastguard Worker     outSrc1 = src1;
627*8975f5c5SAndroid Build Coastguard Worker })";
628*8975f5c5SAndroid Build Coastguard Worker 
629*8975f5c5SAndroid Build Coastguard Worker     mProgram = CompileProgram(essl3_shaders::vs::Simple(), kFS, [](GLuint program) {
630*8975f5c5SAndroid Build Coastguard Worker         glBindFragDataLocationIndexedEXT(program, 0, 1, "outSrc1");
631*8975f5c5SAndroid Build Coastguard Worker     });
632*8975f5c5SAndroid Build Coastguard Worker 
633*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(0u, mProgram);
634*8975f5c5SAndroid Build Coastguard Worker 
635*8975f5c5SAndroid Build Coastguard Worker     checkOutputIndexQuery("outSrc0", 0);
636*8975f5c5SAndroid Build Coastguard Worker     checkOutputIndexQuery("outSrc1", 1);
637*8975f5c5SAndroid Build Coastguard Worker 
638*8975f5c5SAndroid Build Coastguard Worker     drawTest();
639*8975f5c5SAndroid Build Coastguard Worker }
640*8975f5c5SAndroid Build Coastguard Worker 
641*8975f5c5SAndroid Build Coastguard Worker // Test an ESSL 3.00 shader that uses two array fragment outputs with locations
642*8975f5c5SAndroid Build Coastguard Worker // specified in the shader.
TEST_P(EXTBlendFuncExtendedDrawTestES3,FragmentArrayOutputLocationsInShader)643*8975f5c5SAndroid Build Coastguard Worker TEST_P(EXTBlendFuncExtendedDrawTestES3, FragmentArrayOutputLocationsInShader)
644*8975f5c5SAndroid Build Coastguard Worker {
645*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_blend_func_extended"));
646*8975f5c5SAndroid Build Coastguard Worker 
647*8975f5c5SAndroid Build Coastguard Worker     const char *kFragColorShader = R"(#version 300 es
648*8975f5c5SAndroid Build Coastguard Worker #extension GL_EXT_blend_func_extended : require
649*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
650*8975f5c5SAndroid Build Coastguard Worker uniform vec4 src0;
651*8975f5c5SAndroid Build Coastguard Worker uniform vec4 src1;
652*8975f5c5SAndroid Build Coastguard Worker layout(location = 0, index = 1) out vec4 outSrc1[1];
653*8975f5c5SAndroid Build Coastguard Worker layout(location = 0, index = 0) out vec4 outSrc0[1];
654*8975f5c5SAndroid Build Coastguard Worker void main() {
655*8975f5c5SAndroid Build Coastguard Worker     outSrc0[0] = src0;
656*8975f5c5SAndroid Build Coastguard Worker     outSrc1[0] = src1;
657*8975f5c5SAndroid Build Coastguard Worker })";
658*8975f5c5SAndroid Build Coastguard Worker 
659*8975f5c5SAndroid Build Coastguard Worker     makeProgram(essl3_shaders::vs::Simple(), kFragColorShader);
660*8975f5c5SAndroid Build Coastguard Worker 
661*8975f5c5SAndroid Build Coastguard Worker     checkOutputIndexQuery("outSrc0[0]", 0);
662*8975f5c5SAndroid Build Coastguard Worker     checkOutputIndexQuery("outSrc1[0]", 1);
663*8975f5c5SAndroid Build Coastguard Worker     checkOutputIndexQuery("outSrc0", 0);
664*8975f5c5SAndroid Build Coastguard Worker     checkOutputIndexQuery("outSrc1", 1);
665*8975f5c5SAndroid Build Coastguard Worker 
666*8975f5c5SAndroid Build Coastguard Worker     // These queries use an out of range array index so they should return -1.
667*8975f5c5SAndroid Build Coastguard Worker     checkOutputIndexQuery("outSrc0[1]", -1);
668*8975f5c5SAndroid Build Coastguard Worker     checkOutputIndexQuery("outSrc1[1]", -1);
669*8975f5c5SAndroid Build Coastguard Worker 
670*8975f5c5SAndroid Build Coastguard Worker     drawTest();
671*8975f5c5SAndroid Build Coastguard Worker }
672*8975f5c5SAndroid Build Coastguard Worker 
673*8975f5c5SAndroid Build Coastguard Worker // Test an ESSL 3.00 shader that uses two array fragment outputs with locations specified through
674*8975f5c5SAndroid Build Coastguard Worker // the API.
TEST_P(EXTBlendFuncExtendedDrawTestES3,FragmentArrayOutputLocationsAPI)675*8975f5c5SAndroid Build Coastguard Worker TEST_P(EXTBlendFuncExtendedDrawTestES3, FragmentArrayOutputLocationsAPI)
676*8975f5c5SAndroid Build Coastguard Worker {
677*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_blend_func_extended"));
678*8975f5c5SAndroid Build Coastguard Worker 
679*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFS[] = R"(#version 300 es
680*8975f5c5SAndroid Build Coastguard Worker #extension GL_EXT_blend_func_extended : require
681*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
682*8975f5c5SAndroid Build Coastguard Worker uniform vec4 src0;
683*8975f5c5SAndroid Build Coastguard Worker uniform vec4 src1;
684*8975f5c5SAndroid Build Coastguard Worker out vec4 outSrc1[1];
685*8975f5c5SAndroid Build Coastguard Worker out vec4 outSrc0[1];
686*8975f5c5SAndroid Build Coastguard Worker void main() {
687*8975f5c5SAndroid Build Coastguard Worker     outSrc0[0] = src0;
688*8975f5c5SAndroid Build Coastguard Worker     outSrc1[0] = src1;
689*8975f5c5SAndroid Build Coastguard Worker })";
690*8975f5c5SAndroid Build Coastguard Worker 
691*8975f5c5SAndroid Build Coastguard Worker     mProgram = CompileProgram(essl3_shaders::vs::Simple(), kFS, [](GLuint program) {
692*8975f5c5SAndroid Build Coastguard Worker         // Specs aren't very clear on what kind of name should be used when binding location for
693*8975f5c5SAndroid Build Coastguard Worker         // array variables. We only allow names that do include the "[0]" suffix.
694*8975f5c5SAndroid Build Coastguard Worker         glBindFragDataLocationIndexedEXT(program, 0, 0, "outSrc0[0]");
695*8975f5c5SAndroid Build Coastguard Worker         glBindFragDataLocationIndexedEXT(program, 0, 1, "outSrc1[0]");
696*8975f5c5SAndroid Build Coastguard Worker     });
697*8975f5c5SAndroid Build Coastguard Worker 
698*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(0u, mProgram);
699*8975f5c5SAndroid Build Coastguard Worker 
700*8975f5c5SAndroid Build Coastguard Worker     // The extension spec is not very clear on what name can be used for the queries for array
701*8975f5c5SAndroid Build Coastguard Worker     // variables. We're checking that the queries work in the same way as specified in OpenGL 4.4
702*8975f5c5SAndroid Build Coastguard Worker     // page 107.
703*8975f5c5SAndroid Build Coastguard Worker     checkOutputIndexQuery("outSrc0[0]", 0);
704*8975f5c5SAndroid Build Coastguard Worker     checkOutputIndexQuery("outSrc1[0]", 1);
705*8975f5c5SAndroid Build Coastguard Worker     checkOutputIndexQuery("outSrc0", 0);
706*8975f5c5SAndroid Build Coastguard Worker     checkOutputIndexQuery("outSrc1", 1);
707*8975f5c5SAndroid Build Coastguard Worker 
708*8975f5c5SAndroid Build Coastguard Worker     // These queries use an out of range array index so they should return -1.
709*8975f5c5SAndroid Build Coastguard Worker     checkOutputIndexQuery("outSrc0[1]", -1);
710*8975f5c5SAndroid Build Coastguard Worker     checkOutputIndexQuery("outSrc1[1]", -1);
711*8975f5c5SAndroid Build Coastguard Worker 
712*8975f5c5SAndroid Build Coastguard Worker     drawTest();
713*8975f5c5SAndroid Build Coastguard Worker }
714*8975f5c5SAndroid Build Coastguard Worker 
715*8975f5c5SAndroid Build Coastguard Worker // Ported from TranslatorVariants/EXTBlendFuncExtendedES3DrawTest
716*8975f5c5SAndroid Build Coastguard Worker // Test that tests glBindFragDataLocationEXT, glBindFragDataLocationIndexedEXT,
717*8975f5c5SAndroid Build Coastguard Worker // glGetFragDataLocation, glGetFragDataIndexEXT work correctly with
718*8975f5c5SAndroid Build Coastguard Worker // GLSL array output variables. The output variable can be bound by
719*8975f5c5SAndroid Build Coastguard Worker // referring to the variable name with or without the first element array
720*8975f5c5SAndroid Build Coastguard Worker // accessor. The getters can query location of the individual elements in
721*8975f5c5SAndroid Build Coastguard Worker // the array. The test does not actually use the base test drawing,
722*8975f5c5SAndroid Build Coastguard Worker // since the drivers at the time of writing do not support multiple
723*8975f5c5SAndroid Build Coastguard Worker // buffers and dual source blending.
TEST_P(EXTBlendFuncExtendedDrawTestES3,ES3GettersArray)724*8975f5c5SAndroid Build Coastguard Worker TEST_P(EXTBlendFuncExtendedDrawTestES3, ES3GettersArray)
725*8975f5c5SAndroid Build Coastguard Worker {
726*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_blend_func_extended"));
727*8975f5c5SAndroid Build Coastguard Worker 
728*8975f5c5SAndroid Build Coastguard Worker     const GLint kTestArraySize     = 2;
729*8975f5c5SAndroid Build Coastguard Worker     const GLint kFragData0Location = 2;
730*8975f5c5SAndroid Build Coastguard Worker     const GLint kFragData1Location = 1;
731*8975f5c5SAndroid Build Coastguard Worker     const GLint kUnusedLocation    = 5;
732*8975f5c5SAndroid Build Coastguard Worker 
733*8975f5c5SAndroid Build Coastguard Worker     // The test binds kTestArraySize -sized array to location 1 for test purposes.
734*8975f5c5SAndroid Build Coastguard Worker     // The GL_MAX_DRAW_BUFFERS must be > kTestArraySize, since an
735*8975f5c5SAndroid Build Coastguard Worker     // array will be bound to continuous locations, starting from the first
736*8975f5c5SAndroid Build Coastguard Worker     // location.
737*8975f5c5SAndroid Build Coastguard Worker     GLint maxDrawBuffers = 0;
738*8975f5c5SAndroid Build Coastguard Worker     glGetIntegerv(GL_MAX_DRAW_BUFFERS_EXT, &maxDrawBuffers);
739*8975f5c5SAndroid Build Coastguard Worker     EXPECT_LT(kTestArraySize, maxDrawBuffers);
740*8975f5c5SAndroid Build Coastguard Worker 
741*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFragColorShader[] = R"(#version 300 es
742*8975f5c5SAndroid Build Coastguard Worker #extension GL_EXT_blend_func_extended : require
743*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
744*8975f5c5SAndroid Build Coastguard Worker uniform vec4 src;
745*8975f5c5SAndroid Build Coastguard Worker uniform vec4 src1;
746*8975f5c5SAndroid Build Coastguard Worker out vec4 FragData[2];
747*8975f5c5SAndroid Build Coastguard Worker void main() {
748*8975f5c5SAndroid Build Coastguard Worker     FragData[0] = src;
749*8975f5c5SAndroid Build Coastguard Worker     FragData[1] = src1;
750*8975f5c5SAndroid Build Coastguard Worker })";
751*8975f5c5SAndroid Build Coastguard Worker 
752*8975f5c5SAndroid Build Coastguard Worker     struct testCase
753*8975f5c5SAndroid Build Coastguard Worker     {
754*8975f5c5SAndroid Build Coastguard Worker         std::string unusedLocationName;
755*8975f5c5SAndroid Build Coastguard Worker         std::string fragData0LocationName;
756*8975f5c5SAndroid Build Coastguard Worker         std::string fragData1LocationName;
757*8975f5c5SAndroid Build Coastguard Worker     };
758*8975f5c5SAndroid Build Coastguard Worker 
759*8975f5c5SAndroid Build Coastguard Worker     testCase testCases[4]{{"FragData[0]", "FragData", "FragData[1]"},
760*8975f5c5SAndroid Build Coastguard Worker                           {"FragData", "FragData[0]", "FragData[1]"},
761*8975f5c5SAndroid Build Coastguard Worker                           {"FragData[0]", "FragData", "FragData[1]"},
762*8975f5c5SAndroid Build Coastguard Worker                           {"FragData", "FragData[0]", "FragData[1]"}};
763*8975f5c5SAndroid Build Coastguard Worker 
764*8975f5c5SAndroid Build Coastguard Worker     for (const testCase &test : testCases)
765*8975f5c5SAndroid Build Coastguard Worker     {
766*8975f5c5SAndroid Build Coastguard Worker         mProgram =
767*8975f5c5SAndroid Build Coastguard Worker             CompileProgram(essl3_shaders::vs::Simple(), kFragColorShader, [&](GLuint program) {
768*8975f5c5SAndroid Build Coastguard Worker                 glBindFragDataLocationEXT(program, kUnusedLocation,
769*8975f5c5SAndroid Build Coastguard Worker                                           test.unusedLocationName.c_str());
770*8975f5c5SAndroid Build Coastguard Worker                 glBindFragDataLocationEXT(program, kFragData0Location,
771*8975f5c5SAndroid Build Coastguard Worker                                           test.fragData0LocationName.c_str());
772*8975f5c5SAndroid Build Coastguard Worker                 glBindFragDataLocationEXT(program, kFragData1Location,
773*8975f5c5SAndroid Build Coastguard Worker                                           test.fragData1LocationName.c_str());
774*8975f5c5SAndroid Build Coastguard Worker             });
775*8975f5c5SAndroid Build Coastguard Worker 
776*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
777*8975f5c5SAndroid Build Coastguard Worker         LinkProgram();
778*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(kFragData0Location, glGetFragDataLocation(mProgram, "FragData"));
779*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(0, glGetFragDataIndexEXT(mProgram, "FragData"));
780*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(kFragData0Location, glGetFragDataLocation(mProgram, "FragData[0]"));
781*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(0, glGetFragDataIndexEXT(mProgram, "FragData[0]"));
782*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(kFragData1Location, glGetFragDataLocation(mProgram, "FragData[1]"));
783*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(0, glGetFragDataIndexEXT(mProgram, "FragData[1]"));
784*8975f5c5SAndroid Build Coastguard Worker         // Index bigger than the GLSL variable array length does not find anything.
785*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(-1, glGetFragDataLocation(mProgram, "FragData[3]"));
786*8975f5c5SAndroid Build Coastguard Worker     }
787*8975f5c5SAndroid Build Coastguard Worker }
788*8975f5c5SAndroid Build Coastguard Worker 
789*8975f5c5SAndroid Build Coastguard Worker // Ported from TranslatorVariants/EXTBlendFuncExtendedES3DrawTest
TEST_P(EXTBlendFuncExtendedDrawTestES3,ESSL3BindSimpleVarAsArrayNoBind)790*8975f5c5SAndroid Build Coastguard Worker TEST_P(EXTBlendFuncExtendedDrawTestES3, ESSL3BindSimpleVarAsArrayNoBind)
791*8975f5c5SAndroid Build Coastguard Worker {
792*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_blend_func_extended"));
793*8975f5c5SAndroid Build Coastguard Worker 
794*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFragDataShader[] = R"(#version 300 es
795*8975f5c5SAndroid Build Coastguard Worker #extension GL_EXT_blend_func_extended : require
796*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
797*8975f5c5SAndroid Build Coastguard Worker uniform vec4 src;
798*8975f5c5SAndroid Build Coastguard Worker uniform vec4 src1;
799*8975f5c5SAndroid Build Coastguard Worker out vec4 FragData;
800*8975f5c5SAndroid Build Coastguard Worker out vec4 SecondaryFragData;
801*8975f5c5SAndroid Build Coastguard Worker void main() {
802*8975f5c5SAndroid Build Coastguard Worker     FragData = src;
803*8975f5c5SAndroid Build Coastguard Worker     SecondaryFragData = src1;
804*8975f5c5SAndroid Build Coastguard Worker })";
805*8975f5c5SAndroid Build Coastguard Worker 
806*8975f5c5SAndroid Build Coastguard Worker     mProgram = CompileProgram(essl3_shaders::vs::Simple(), kFragDataShader, [](GLuint program) {
807*8975f5c5SAndroid Build Coastguard Worker         glBindFragDataLocationEXT(program, 0, "FragData[0]");
808*8975f5c5SAndroid Build Coastguard Worker         glBindFragDataLocationIndexedEXT(program, 0, 1, "SecondaryFragData[0]");
809*8975f5c5SAndroid Build Coastguard Worker     });
810*8975f5c5SAndroid Build Coastguard Worker 
811*8975f5c5SAndroid Build Coastguard Worker     LinkProgram();
812*8975f5c5SAndroid Build Coastguard Worker 
813*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(-1, glGetFragDataLocation(mProgram, "FragData[0]"));
814*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(0, glGetFragDataLocation(mProgram, "FragData"));
815*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(1, glGetFragDataLocation(mProgram, "SecondaryFragData"));
816*8975f5c5SAndroid Build Coastguard Worker     // Did not bind index.
817*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(0, glGetFragDataIndexEXT(mProgram, "SecondaryFragData"));
818*8975f5c5SAndroid Build Coastguard Worker 
819*8975f5c5SAndroid Build Coastguard Worker     glBindFragDataLocationEXT(mProgram, 0, "FragData");
820*8975f5c5SAndroid Build Coastguard Worker     glBindFragDataLocationIndexedEXT(mProgram, 0, 1, "SecondaryFragData");
821*8975f5c5SAndroid Build Coastguard Worker     LinkProgram();
822*8975f5c5SAndroid Build Coastguard Worker }
823*8975f5c5SAndroid Build Coastguard Worker 
824*8975f5c5SAndroid Build Coastguard Worker // Test an ESSL 3.00 program with a link-time fragment output location conflict.
TEST_P(EXTBlendFuncExtendedTestES3,FragmentOutputLocationConflict)825*8975f5c5SAndroid Build Coastguard Worker TEST_P(EXTBlendFuncExtendedTestES3, FragmentOutputLocationConflict)
826*8975f5c5SAndroid Build Coastguard Worker {
827*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_blend_func_extended"));
828*8975f5c5SAndroid Build Coastguard Worker 
829*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFS[] = R"(#version 300 es
830*8975f5c5SAndroid Build Coastguard Worker #extension GL_EXT_blend_func_extended : require
831*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
832*8975f5c5SAndroid Build Coastguard Worker uniform vec4 src0;
833*8975f5c5SAndroid Build Coastguard Worker uniform vec4 src1;
834*8975f5c5SAndroid Build Coastguard Worker out vec4 out0;
835*8975f5c5SAndroid Build Coastguard Worker out vec4 out1;
836*8975f5c5SAndroid Build Coastguard Worker void main() {
837*8975f5c5SAndroid Build Coastguard Worker     out0 = src0;
838*8975f5c5SAndroid Build Coastguard Worker     out1 = src1;
839*8975f5c5SAndroid Build Coastguard Worker })";
840*8975f5c5SAndroid Build Coastguard Worker 
841*8975f5c5SAndroid Build Coastguard Worker     GLuint vs = CompileShader(GL_VERTEX_SHADER, essl3_shaders::vs::Simple());
842*8975f5c5SAndroid Build Coastguard Worker     GLuint fs = CompileShader(GL_FRAGMENT_SHADER, kFS);
843*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(0u, vs);
844*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(0u, fs);
845*8975f5c5SAndroid Build Coastguard Worker 
846*8975f5c5SAndroid Build Coastguard Worker     GLuint program = glCreateProgram();
847*8975f5c5SAndroid Build Coastguard Worker     glAttachShader(program, vs);
848*8975f5c5SAndroid Build Coastguard Worker     glDeleteShader(vs);
849*8975f5c5SAndroid Build Coastguard Worker     glAttachShader(program, fs);
850*8975f5c5SAndroid Build Coastguard Worker     glDeleteShader(fs);
851*8975f5c5SAndroid Build Coastguard Worker 
852*8975f5c5SAndroid Build Coastguard Worker     glBindFragDataLocationIndexedEXT(program, 0, 0, "out0");
853*8975f5c5SAndroid Build Coastguard Worker     glBindFragDataLocationIndexedEXT(program, 0, 0, "out1");
854*8975f5c5SAndroid Build Coastguard Worker 
855*8975f5c5SAndroid Build Coastguard Worker     // The program should fail to link.
856*8975f5c5SAndroid Build Coastguard Worker     glLinkProgram(program);
857*8975f5c5SAndroid Build Coastguard Worker     GLint linkStatus;
858*8975f5c5SAndroid Build Coastguard Worker     glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
859*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(0, linkStatus);
860*8975f5c5SAndroid Build Coastguard Worker 
861*8975f5c5SAndroid Build Coastguard Worker     glDeleteProgram(program);
862*8975f5c5SAndroid Build Coastguard Worker }
863*8975f5c5SAndroid Build Coastguard Worker 
864*8975f5c5SAndroid Build Coastguard Worker // Test an ESSL 3.00 program with some bindings set for nonexistent variables. These should not
865*8975f5c5SAndroid Build Coastguard Worker // create link-time conflicts.
TEST_P(EXTBlendFuncExtendedTestES3,FragmentOutputLocationForNonexistentOutput)866*8975f5c5SAndroid Build Coastguard Worker TEST_P(EXTBlendFuncExtendedTestES3, FragmentOutputLocationForNonexistentOutput)
867*8975f5c5SAndroid Build Coastguard Worker {
868*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_blend_func_extended"));
869*8975f5c5SAndroid Build Coastguard Worker 
870*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFS[] = R"(#version 300 es
871*8975f5c5SAndroid Build Coastguard Worker #extension GL_EXT_blend_func_extended : require
872*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
873*8975f5c5SAndroid Build Coastguard Worker uniform vec4 src0;
874*8975f5c5SAndroid Build Coastguard Worker out vec4 out0;
875*8975f5c5SAndroid Build Coastguard Worker void main() {
876*8975f5c5SAndroid Build Coastguard Worker     out0 = src0;
877*8975f5c5SAndroid Build Coastguard Worker })";
878*8975f5c5SAndroid Build Coastguard Worker 
879*8975f5c5SAndroid Build Coastguard Worker     GLuint vs = CompileShader(GL_VERTEX_SHADER, essl3_shaders::vs::Simple());
880*8975f5c5SAndroid Build Coastguard Worker     GLuint fs = CompileShader(GL_FRAGMENT_SHADER, kFS);
881*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(0u, vs);
882*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(0u, fs);
883*8975f5c5SAndroid Build Coastguard Worker 
884*8975f5c5SAndroid Build Coastguard Worker     GLuint program = glCreateProgram();
885*8975f5c5SAndroid Build Coastguard Worker     glAttachShader(program, vs);
886*8975f5c5SAndroid Build Coastguard Worker     glDeleteShader(vs);
887*8975f5c5SAndroid Build Coastguard Worker     glAttachShader(program, fs);
888*8975f5c5SAndroid Build Coastguard Worker     glDeleteShader(fs);
889*8975f5c5SAndroid Build Coastguard Worker 
890*8975f5c5SAndroid Build Coastguard Worker     glBindFragDataLocationIndexedEXT(program, 0, 0, "out0");
891*8975f5c5SAndroid Build Coastguard Worker     glBindFragDataLocationIndexedEXT(program, 0, 0, "out1");
892*8975f5c5SAndroid Build Coastguard Worker     glBindFragDataLocationIndexedEXT(program, 0, 0, "out2[0]");
893*8975f5c5SAndroid Build Coastguard Worker 
894*8975f5c5SAndroid Build Coastguard Worker     // The program should link successfully - conflicting location for nonexistent variables out1 or
895*8975f5c5SAndroid Build Coastguard Worker     // out2 should not be an issue.
896*8975f5c5SAndroid Build Coastguard Worker     glLinkProgram(program);
897*8975f5c5SAndroid Build Coastguard Worker     GLint linkStatus;
898*8975f5c5SAndroid Build Coastguard Worker     glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
899*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(0, linkStatus);
900*8975f5c5SAndroid Build Coastguard Worker 
901*8975f5c5SAndroid Build Coastguard Worker     glDeleteProgram(program);
902*8975f5c5SAndroid Build Coastguard Worker }
903*8975f5c5SAndroid Build Coastguard Worker 
904*8975f5c5SAndroid Build Coastguard Worker // Test mixing shader-assigned and automatic output locations.
TEST_P(EXTBlendFuncExtendedTestES3,FragmentOutputLocationsPartiallyAutomatic)905*8975f5c5SAndroid Build Coastguard Worker TEST_P(EXTBlendFuncExtendedTestES3, FragmentOutputLocationsPartiallyAutomatic)
906*8975f5c5SAndroid Build Coastguard Worker {
907*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_blend_func_extended"));
908*8975f5c5SAndroid Build Coastguard Worker 
909*8975f5c5SAndroid Build Coastguard Worker     GLint maxDrawBuffers;
910*8975f5c5SAndroid Build Coastguard Worker     glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
911*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(maxDrawBuffers < 4);
912*8975f5c5SAndroid Build Coastguard Worker 
913*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFS[] = R"(#version 300 es
914*8975f5c5SAndroid Build Coastguard Worker #extension GL_EXT_blend_func_extended : require
915*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
916*8975f5c5SAndroid Build Coastguard Worker uniform vec4 src0;
917*8975f5c5SAndroid Build Coastguard Worker uniform vec4 src1;
918*8975f5c5SAndroid Build Coastguard Worker uniform vec4 src2;
919*8975f5c5SAndroid Build Coastguard Worker uniform vec4 src3;
920*8975f5c5SAndroid Build Coastguard Worker layout(location=0) out vec4 out0;
921*8975f5c5SAndroid Build Coastguard Worker layout(location=3) out vec4 out3;
922*8975f5c5SAndroid Build Coastguard Worker out vec4 out12[2];
923*8975f5c5SAndroid Build Coastguard Worker void main() {
924*8975f5c5SAndroid Build Coastguard Worker     out0 = src0;
925*8975f5c5SAndroid Build Coastguard Worker     out12[0] = src1;
926*8975f5c5SAndroid Build Coastguard Worker     out12[1] = src2;
927*8975f5c5SAndroid Build Coastguard Worker     out3 = src3;
928*8975f5c5SAndroid Build Coastguard Worker })";
929*8975f5c5SAndroid Build Coastguard Worker 
930*8975f5c5SAndroid Build Coastguard Worker     GLuint program = CompileProgram(essl3_shaders::vs::Simple(), kFS);
931*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(0u, program);
932*8975f5c5SAndroid Build Coastguard Worker 
933*8975f5c5SAndroid Build Coastguard Worker     GLint location = glGetFragDataLocation(program, "out0");
934*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(0, location);
935*8975f5c5SAndroid Build Coastguard Worker     location = glGetFragDataLocation(program, "out12");
936*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(1, location);
937*8975f5c5SAndroid Build Coastguard Worker     location = glGetFragDataLocation(program, "out3");
938*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(3, location);
939*8975f5c5SAndroid Build Coastguard Worker 
940*8975f5c5SAndroid Build Coastguard Worker     glDeleteProgram(program);
941*8975f5c5SAndroid Build Coastguard Worker }
942*8975f5c5SAndroid Build Coastguard Worker 
943*8975f5c5SAndroid Build Coastguard Worker // Test a fragment output array that doesn't fit because contiguous locations are not available.
TEST_P(EXTBlendFuncExtendedTestES3,FragmentOutputArrayDoesntFit)944*8975f5c5SAndroid Build Coastguard Worker TEST_P(EXTBlendFuncExtendedTestES3, FragmentOutputArrayDoesntFit)
945*8975f5c5SAndroid Build Coastguard Worker {
946*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_blend_func_extended"));
947*8975f5c5SAndroid Build Coastguard Worker 
948*8975f5c5SAndroid Build Coastguard Worker     GLint maxDrawBuffers;
949*8975f5c5SAndroid Build Coastguard Worker     glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
950*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(maxDrawBuffers < 4);
951*8975f5c5SAndroid Build Coastguard Worker 
952*8975f5c5SAndroid Build Coastguard Worker     std::stringstream fragShader;
953*8975f5c5SAndroid Build Coastguard Worker     fragShader << R"(#version 300 es
954*8975f5c5SAndroid Build Coastguard Worker #extension GL_EXT_blend_func_extended : require
955*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
956*8975f5c5SAndroid Build Coastguard Worker layout(location=2) out vec4 out0;
957*8975f5c5SAndroid Build Coastguard Worker out vec4 outArray[)"
958*8975f5c5SAndroid Build Coastguard Worker                << (maxDrawBuffers - 1) << R"(];
959*8975f5c5SAndroid Build Coastguard Worker void main() {
960*8975f5c5SAndroid Build Coastguard Worker     out0 = vec4(1.0);
961*8975f5c5SAndroid Build Coastguard Worker     outArray[0] = vec4(1.0);
962*8975f5c5SAndroid Build Coastguard Worker })";
963*8975f5c5SAndroid Build Coastguard Worker 
964*8975f5c5SAndroid Build Coastguard Worker     GLuint vs = CompileShader(GL_VERTEX_SHADER, essl3_shaders::vs::Simple());
965*8975f5c5SAndroid Build Coastguard Worker     GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fragShader.str().c_str());
966*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(0u, vs);
967*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(0u, fs);
968*8975f5c5SAndroid Build Coastguard Worker 
969*8975f5c5SAndroid Build Coastguard Worker     GLuint program = glCreateProgram();
970*8975f5c5SAndroid Build Coastguard Worker     glAttachShader(program, vs);
971*8975f5c5SAndroid Build Coastguard Worker     glDeleteShader(vs);
972*8975f5c5SAndroid Build Coastguard Worker     glAttachShader(program, fs);
973*8975f5c5SAndroid Build Coastguard Worker     glDeleteShader(fs);
974*8975f5c5SAndroid Build Coastguard Worker 
975*8975f5c5SAndroid Build Coastguard Worker     // The program should not link - there's no way to fit "outArray" into available output
976*8975f5c5SAndroid Build Coastguard Worker     // locations.
977*8975f5c5SAndroid Build Coastguard Worker     glLinkProgram(program);
978*8975f5c5SAndroid Build Coastguard Worker     GLint linkStatus;
979*8975f5c5SAndroid Build Coastguard Worker     glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
980*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(0, linkStatus);
981*8975f5c5SAndroid Build Coastguard Worker 
982*8975f5c5SAndroid Build Coastguard Worker     glDeleteProgram(program);
983*8975f5c5SAndroid Build Coastguard Worker }
984*8975f5c5SAndroid Build Coastguard Worker 
985*8975f5c5SAndroid Build Coastguard Worker // Test that a secondary blending source limits the number of primary outputs.
TEST_P(EXTBlendFuncExtendedTestES3,TooManyFragmentOutputsForDualSourceBlending)986*8975f5c5SAndroid Build Coastguard Worker TEST_P(EXTBlendFuncExtendedTestES3, TooManyFragmentOutputsForDualSourceBlending)
987*8975f5c5SAndroid Build Coastguard Worker {
988*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_blend_func_extended"));
989*8975f5c5SAndroid Build Coastguard Worker 
990*8975f5c5SAndroid Build Coastguard Worker     GLint maxDualSourceDrawBuffers;
991*8975f5c5SAndroid Build Coastguard Worker     glGetIntegerv(GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT, &maxDualSourceDrawBuffers);
992*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GE(maxDualSourceDrawBuffers, 1);
993*8975f5c5SAndroid Build Coastguard Worker 
994*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFS[] = R"(#version 300 es
995*8975f5c5SAndroid Build Coastguard Worker #extension GL_EXT_blend_func_extended : require
996*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
997*8975f5c5SAndroid Build Coastguard Worker out vec4 outSrc0;
998*8975f5c5SAndroid Build Coastguard Worker out vec4 outSrc1;
999*8975f5c5SAndroid Build Coastguard Worker void main() {
1000*8975f5c5SAndroid Build Coastguard Worker     outSrc0 = vec4(0.5);
1001*8975f5c5SAndroid Build Coastguard Worker     outSrc1 = vec4(1.0);
1002*8975f5c5SAndroid Build Coastguard Worker })";
1003*8975f5c5SAndroid Build Coastguard Worker 
1004*8975f5c5SAndroid Build Coastguard Worker     GLuint vs = CompileShader(GL_VERTEX_SHADER, essl3_shaders::vs::Simple());
1005*8975f5c5SAndroid Build Coastguard Worker     GLuint fs = CompileShader(GL_FRAGMENT_SHADER, kFS);
1006*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(0u, vs);
1007*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(0u, fs);
1008*8975f5c5SAndroid Build Coastguard Worker 
1009*8975f5c5SAndroid Build Coastguard Worker     GLuint program = glCreateProgram();
1010*8975f5c5SAndroid Build Coastguard Worker     glAttachShader(program, vs);
1011*8975f5c5SAndroid Build Coastguard Worker     glDeleteShader(vs);
1012*8975f5c5SAndroid Build Coastguard Worker     glAttachShader(program, fs);
1013*8975f5c5SAndroid Build Coastguard Worker     glDeleteShader(fs);
1014*8975f5c5SAndroid Build Coastguard Worker 
1015*8975f5c5SAndroid Build Coastguard Worker     glBindFragDataLocationIndexedEXT(program, maxDualSourceDrawBuffers, 0, "outSrc0");
1016*8975f5c5SAndroid Build Coastguard Worker     glBindFragDataLocationIndexedEXT(program, 0, 1, "outSrc1");
1017*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1018*8975f5c5SAndroid Build Coastguard Worker 
1019*8975f5c5SAndroid Build Coastguard Worker     GLint linkStatus;
1020*8975f5c5SAndroid Build Coastguard Worker     glLinkProgram(program);
1021*8975f5c5SAndroid Build Coastguard Worker     glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
1022*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(0, linkStatus);
1023*8975f5c5SAndroid Build Coastguard Worker 
1024*8975f5c5SAndroid Build Coastguard Worker     glDeleteProgram(program);
1025*8975f5c5SAndroid Build Coastguard Worker }
1026*8975f5c5SAndroid Build Coastguard Worker 
1027*8975f5c5SAndroid Build Coastguard Worker // Test that fragment outputs bound to the same location must have the same type.
TEST_P(EXTBlendFuncExtendedTestES3,InconsistentTypesForLocationAPI)1028*8975f5c5SAndroid Build Coastguard Worker TEST_P(EXTBlendFuncExtendedTestES3, InconsistentTypesForLocationAPI)
1029*8975f5c5SAndroid Build Coastguard Worker {
1030*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_blend_func_extended"));
1031*8975f5c5SAndroid Build Coastguard Worker 
1032*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFS[] = R"(#version 300 es
1033*8975f5c5SAndroid Build Coastguard Worker #extension GL_EXT_blend_func_extended : require
1034*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
1035*8975f5c5SAndroid Build Coastguard Worker out vec4 outSrc0;
1036*8975f5c5SAndroid Build Coastguard Worker out ivec4 outSrc1;
1037*8975f5c5SAndroid Build Coastguard Worker void main() {
1038*8975f5c5SAndroid Build Coastguard Worker     outSrc0 = vec4(0.5);
1039*8975f5c5SAndroid Build Coastguard Worker     outSrc1 = ivec4(1.0);
1040*8975f5c5SAndroid Build Coastguard Worker })";
1041*8975f5c5SAndroid Build Coastguard Worker 
1042*8975f5c5SAndroid Build Coastguard Worker     GLuint vs = CompileShader(GL_VERTEX_SHADER, essl3_shaders::vs::Simple());
1043*8975f5c5SAndroid Build Coastguard Worker     GLuint fs = CompileShader(GL_FRAGMENT_SHADER, kFS);
1044*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(0u, vs);
1045*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(0u, fs);
1046*8975f5c5SAndroid Build Coastguard Worker 
1047*8975f5c5SAndroid Build Coastguard Worker     GLuint program = glCreateProgram();
1048*8975f5c5SAndroid Build Coastguard Worker     glAttachShader(program, vs);
1049*8975f5c5SAndroid Build Coastguard Worker     glDeleteShader(vs);
1050*8975f5c5SAndroid Build Coastguard Worker     glAttachShader(program, fs);
1051*8975f5c5SAndroid Build Coastguard Worker     glDeleteShader(fs);
1052*8975f5c5SAndroid Build Coastguard Worker 
1053*8975f5c5SAndroid Build Coastguard Worker     glBindFragDataLocationIndexedEXT(program, 0, 0, "outSrc0");
1054*8975f5c5SAndroid Build Coastguard Worker     glBindFragDataLocationIndexedEXT(program, 0, 1, "outSrc1");
1055*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1056*8975f5c5SAndroid Build Coastguard Worker 
1057*8975f5c5SAndroid Build Coastguard Worker     GLint linkStatus;
1058*8975f5c5SAndroid Build Coastguard Worker     glLinkProgram(program);
1059*8975f5c5SAndroid Build Coastguard Worker     glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
1060*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(0, linkStatus);
1061*8975f5c5SAndroid Build Coastguard Worker 
1062*8975f5c5SAndroid Build Coastguard Worker     glDeleteProgram(program);
1063*8975f5c5SAndroid Build Coastguard Worker }
1064*8975f5c5SAndroid Build Coastguard Worker 
1065*8975f5c5SAndroid Build Coastguard Worker // Test that rendering to multiple fragment outputs bound via API works.
TEST_P(EXTBlendFuncExtendedDrawTestES3,MultipleDrawBuffersAPI)1066*8975f5c5SAndroid Build Coastguard Worker TEST_P(EXTBlendFuncExtendedDrawTestES3, MultipleDrawBuffersAPI)
1067*8975f5c5SAndroid Build Coastguard Worker {
1068*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_blend_func_extended"));
1069*8975f5c5SAndroid Build Coastguard Worker 
1070*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFS[] = R"(#version 300 es
1071*8975f5c5SAndroid Build Coastguard Worker #extension GL_EXT_blend_func_extended : require
1072*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
1073*8975f5c5SAndroid Build Coastguard Worker out vec4 outSrc0;
1074*8975f5c5SAndroid Build Coastguard Worker out ivec4 outSrc1;
1075*8975f5c5SAndroid Build Coastguard Worker void main() {
1076*8975f5c5SAndroid Build Coastguard Worker     outSrc0 = vec4(0.0, 1.0, 0.0, 1.0);
1077*8975f5c5SAndroid Build Coastguard Worker     outSrc1 = ivec4(1, 2, 3, 4);
1078*8975f5c5SAndroid Build Coastguard Worker })";
1079*8975f5c5SAndroid Build Coastguard Worker 
1080*8975f5c5SAndroid Build Coastguard Worker     mProgram = CompileProgram(essl3_shaders::vs::Simple(), kFS, [](GLuint program) {
1081*8975f5c5SAndroid Build Coastguard Worker         glBindFragDataLocationEXT(program, 0, "outSrc0");
1082*8975f5c5SAndroid Build Coastguard Worker         glBindFragDataLocationEXT(program, 1, "outSrc1");
1083*8975f5c5SAndroid Build Coastguard Worker     });
1084*8975f5c5SAndroid Build Coastguard Worker 
1085*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(0u, mProgram);
1086*8975f5c5SAndroid Build Coastguard Worker 
1087*8975f5c5SAndroid Build Coastguard Worker     GLRenderbuffer rb0;
1088*8975f5c5SAndroid Build Coastguard Worker     glBindRenderbuffer(GL_RENDERBUFFER, rb0);
1089*8975f5c5SAndroid Build Coastguard Worker     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
1090*8975f5c5SAndroid Build Coastguard Worker 
1091*8975f5c5SAndroid Build Coastguard Worker     GLRenderbuffer rb1;
1092*8975f5c5SAndroid Build Coastguard Worker     glBindRenderbuffer(GL_RENDERBUFFER, rb1);
1093*8975f5c5SAndroid Build Coastguard Worker     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8I, 1, 1);
1094*8975f5c5SAndroid Build Coastguard Worker 
1095*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer fbo;
1096*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1097*8975f5c5SAndroid Build Coastguard Worker 
1098*8975f5c5SAndroid Build Coastguard Worker     const GLenum bufs[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
1099*8975f5c5SAndroid Build Coastguard Worker     glDrawBuffers(2, bufs);
1100*8975f5c5SAndroid Build Coastguard Worker 
1101*8975f5c5SAndroid Build Coastguard Worker     GLfloat clearF[] = {0.0, 0.0, 0.0, 0.0};
1102*8975f5c5SAndroid Build Coastguard Worker     GLint clearI[]   = {0, 0, 0, 0};
1103*8975f5c5SAndroid Build Coastguard Worker 
1104*8975f5c5SAndroid Build Coastguard Worker     // FBO: rb0 (rgba8), rb1 (rgba8i)
1105*8975f5c5SAndroid Build Coastguard Worker     glBindRenderbuffer(GL_RENDERBUFFER, rb0);
1106*8975f5c5SAndroid Build Coastguard Worker     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rb0);
1107*8975f5c5SAndroid Build Coastguard Worker     glBindRenderbuffer(GL_RENDERBUFFER, rb1);
1108*8975f5c5SAndroid Build Coastguard Worker     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, rb1);
1109*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1110*8975f5c5SAndroid Build Coastguard Worker 
1111*8975f5c5SAndroid Build Coastguard Worker     glClearBufferfv(GL_COLOR, 0, clearF);
1112*8975f5c5SAndroid Build Coastguard Worker     glClearBufferiv(GL_COLOR, 1, clearI);
1113*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1114*8975f5c5SAndroid Build Coastguard Worker 
1115*8975f5c5SAndroid Build Coastguard Worker     glReadBuffer(GL_COLOR_ATTACHMENT0);
1116*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_EQ(0, 0, 0, 0, 0, 0);
1117*8975f5c5SAndroid Build Coastguard Worker     glReadBuffer(GL_COLOR_ATTACHMENT1);
1118*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_8I(0, 0, 0, 0, 0, 0);
1119*8975f5c5SAndroid Build Coastguard Worker 
1120*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.0);
1121*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1122*8975f5c5SAndroid Build Coastguard Worker 
1123*8975f5c5SAndroid Build Coastguard Worker     glReadBuffer(GL_COLOR_ATTACHMENT0);
1124*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1125*8975f5c5SAndroid Build Coastguard Worker     glReadBuffer(GL_COLOR_ATTACHMENT1);
1126*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_8I(0, 0, 1, 2, 3, 4);
1127*8975f5c5SAndroid Build Coastguard Worker 
1128*8975f5c5SAndroid Build Coastguard Worker     // FBO: rb1 (rgba8i), rb0 (rgba8)
1129*8975f5c5SAndroid Build Coastguard Worker     glBindRenderbuffer(GL_RENDERBUFFER, rb0);
1130*8975f5c5SAndroid Build Coastguard Worker     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, rb0);
1131*8975f5c5SAndroid Build Coastguard Worker     glBindRenderbuffer(GL_RENDERBUFFER, rb1);
1132*8975f5c5SAndroid Build Coastguard Worker     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rb1);
1133*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1134*8975f5c5SAndroid Build Coastguard Worker 
1135*8975f5c5SAndroid Build Coastguard Worker     // Rebind fragment outputs
1136*8975f5c5SAndroid Build Coastguard Worker     glBindFragDataLocationEXT(mProgram, 0, "outSrc1");
1137*8975f5c5SAndroid Build Coastguard Worker     glBindFragDataLocationEXT(mProgram, 1, "outSrc0");
1138*8975f5c5SAndroid Build Coastguard Worker     glLinkProgram(mProgram);
1139*8975f5c5SAndroid Build Coastguard Worker 
1140*8975f5c5SAndroid Build Coastguard Worker     glClearBufferfv(GL_COLOR, 1, clearF);
1141*8975f5c5SAndroid Build Coastguard Worker     glClearBufferiv(GL_COLOR, 0, clearI);
1142*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1143*8975f5c5SAndroid Build Coastguard Worker 
1144*8975f5c5SAndroid Build Coastguard Worker     glReadBuffer(GL_COLOR_ATTACHMENT1);
1145*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_EQ(0, 0, 0, 0, 0, 0);
1146*8975f5c5SAndroid Build Coastguard Worker     glReadBuffer(GL_COLOR_ATTACHMENT0);
1147*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_8I(0, 0, 0, 0, 0, 0);
1148*8975f5c5SAndroid Build Coastguard Worker 
1149*8975f5c5SAndroid Build Coastguard Worker     drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.0);
1150*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1151*8975f5c5SAndroid Build Coastguard Worker 
1152*8975f5c5SAndroid Build Coastguard Worker     glReadBuffer(GL_COLOR_ATTACHMENT1);
1153*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1154*8975f5c5SAndroid Build Coastguard Worker     glReadBuffer(GL_COLOR_ATTACHMENT0);
1155*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_8I(0, 0, 1, 2, 3, 4);
1156*8975f5c5SAndroid Build Coastguard Worker }
1157*8975f5c5SAndroid Build Coastguard Worker 
1158*8975f5c5SAndroid Build Coastguard Worker // Use a program pipeline with EXT_blend_func_extended
TEST_P(EXTBlendFuncExtendedDrawTestES31,UseProgramPipeline)1159*8975f5c5SAndroid Build Coastguard Worker TEST_P(EXTBlendFuncExtendedDrawTestES31, UseProgramPipeline)
1160*8975f5c5SAndroid Build Coastguard Worker {
1161*8975f5c5SAndroid Build Coastguard Worker     // Only the Vulkan backend supports PPO
1162*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsVulkan());
1163*8975f5c5SAndroid Build Coastguard Worker 
1164*8975f5c5SAndroid Build Coastguard Worker     // Create two separable program objects from a
1165*8975f5c5SAndroid Build Coastguard Worker     // single source string respectively (vertSrc and fragSrc)
1166*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_blend_func_extended"));
1167*8975f5c5SAndroid Build Coastguard Worker 
1168*8975f5c5SAndroid Build Coastguard Worker     const char *kFragColorShader = R"(#version 300 es
1169*8975f5c5SAndroid Build Coastguard Worker #extension GL_EXT_blend_func_extended : require
1170*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
1171*8975f5c5SAndroid Build Coastguard Worker uniform vec4 src0;
1172*8975f5c5SAndroid Build Coastguard Worker uniform vec4 src1;
1173*8975f5c5SAndroid Build Coastguard Worker layout(location = 0, index = 1) out vec4 outSrc1;
1174*8975f5c5SAndroid Build Coastguard Worker layout(location = 0, index = 0) out vec4 outSrc0;
1175*8975f5c5SAndroid Build Coastguard Worker void main() {
1176*8975f5c5SAndroid Build Coastguard Worker     outSrc0 = src0;
1177*8975f5c5SAndroid Build Coastguard Worker     outSrc1 = src1;
1178*8975f5c5SAndroid Build Coastguard Worker })";
1179*8975f5c5SAndroid Build Coastguard Worker 
1180*8975f5c5SAndroid Build Coastguard Worker     setupProgramPipeline(essl3_shaders::vs::Simple(), kFragColorShader);
1181*8975f5c5SAndroid Build Coastguard Worker 
1182*8975f5c5SAndroid Build Coastguard Worker     checkOutputIndexQuery("outSrc0", 0);
1183*8975f5c5SAndroid Build Coastguard Worker     checkOutputIndexQuery("outSrc1", 1);
1184*8975f5c5SAndroid Build Coastguard Worker 
1185*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EQ(mProgram, 0u);
1186*8975f5c5SAndroid Build Coastguard Worker     drawTest();
1187*8975f5c5SAndroid Build Coastguard Worker 
1188*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1189*8975f5c5SAndroid Build Coastguard Worker }
1190*8975f5c5SAndroid Build Coastguard Worker 
1191*8975f5c5SAndroid Build Coastguard Worker // Use program pipeline where the fragment program is changed
TEST_P(EXTBlendFuncExtendedDrawTestES31,UseTwoProgramStages)1192*8975f5c5SAndroid Build Coastguard Worker TEST_P(EXTBlendFuncExtendedDrawTestES31, UseTwoProgramStages)
1193*8975f5c5SAndroid Build Coastguard Worker {
1194*8975f5c5SAndroid Build Coastguard Worker     // Only the Vulkan backend supports PPO
1195*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsVulkan());
1196*8975f5c5SAndroid Build Coastguard Worker 
1197*8975f5c5SAndroid Build Coastguard Worker     // Create two separable program objects from a
1198*8975f5c5SAndroid Build Coastguard Worker     // single source string respectively (vertSrc and fragSrc)
1199*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_blend_func_extended"));
1200*8975f5c5SAndroid Build Coastguard Worker 
1201*8975f5c5SAndroid Build Coastguard Worker     const char *kFragColorShaderFlipped = R"(#version 300 es
1202*8975f5c5SAndroid Build Coastguard Worker #extension GL_EXT_blend_func_extended : require
1203*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
1204*8975f5c5SAndroid Build Coastguard Worker uniform vec4 src0;
1205*8975f5c5SAndroid Build Coastguard Worker uniform vec4 src1;
1206*8975f5c5SAndroid Build Coastguard Worker layout(location = 0, index = 0) out vec4 outSrc1;
1207*8975f5c5SAndroid Build Coastguard Worker layout(location = 0, index = 1) out vec4 outSrc0;
1208*8975f5c5SAndroid Build Coastguard Worker void main() {
1209*8975f5c5SAndroid Build Coastguard Worker     outSrc0 = src0;
1210*8975f5c5SAndroid Build Coastguard Worker     outSrc1 = src1;
1211*8975f5c5SAndroid Build Coastguard Worker })";
1212*8975f5c5SAndroid Build Coastguard Worker 
1213*8975f5c5SAndroid Build Coastguard Worker     const char *kFragColorShader = R"(#version 300 es
1214*8975f5c5SAndroid Build Coastguard Worker #extension GL_EXT_blend_func_extended : require
1215*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
1216*8975f5c5SAndroid Build Coastguard Worker uniform vec4 src0;
1217*8975f5c5SAndroid Build Coastguard Worker uniform vec4 src1;
1218*8975f5c5SAndroid Build Coastguard Worker layout(location = 0, index = 1) out vec4 outSrc1;
1219*8975f5c5SAndroid Build Coastguard Worker layout(location = 0, index = 0) out vec4 outSrc0;
1220*8975f5c5SAndroid Build Coastguard Worker void main() {
1221*8975f5c5SAndroid Build Coastguard Worker     outSrc0 = src0;
1222*8975f5c5SAndroid Build Coastguard Worker     outSrc1 = src1;
1223*8975f5c5SAndroid Build Coastguard Worker })";
1224*8975f5c5SAndroid Build Coastguard Worker 
1225*8975f5c5SAndroid Build Coastguard Worker     setupProgramPipeline(essl3_shaders::vs::Simple(), kFragColorShaderFlipped);
1226*8975f5c5SAndroid Build Coastguard Worker 
1227*8975f5c5SAndroid Build Coastguard Worker     // Check index values frag shader with the "flipped" index values
1228*8975f5c5SAndroid Build Coastguard Worker     checkOutputIndexQuery("outSrc0", 1);
1229*8975f5c5SAndroid Build Coastguard Worker     checkOutputIndexQuery("outSrc1", 0);
1230*8975f5c5SAndroid Build Coastguard Worker 
1231*8975f5c5SAndroid Build Coastguard Worker     GLuint previousProgram = mFragProgram;
1232*8975f5c5SAndroid Build Coastguard Worker     mFragProgram           = createShaderProgram(GL_FRAGMENT_SHADER, kFragColorShader);
1233*8975f5c5SAndroid Build Coastguard Worker     ASSERT_NE(mFragProgram, 0u);
1234*8975f5c5SAndroid Build Coastguard Worker 
1235*8975f5c5SAndroid Build Coastguard Worker     // Change the Fragment program of the pipeline
1236*8975f5c5SAndroid Build Coastguard Worker     glUseProgramStages(mPipeline, GL_FRAGMENT_SHADER_BIT, mFragProgram);
1237*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
1238*8975f5c5SAndroid Build Coastguard Worker 
1239*8975f5c5SAndroid Build Coastguard Worker     checkOutputIndexQuery("outSrc0", 0);
1240*8975f5c5SAndroid Build Coastguard Worker     checkOutputIndexQuery("outSrc1", 1);
1241*8975f5c5SAndroid Build Coastguard Worker 
1242*8975f5c5SAndroid Build Coastguard Worker     ASSERT_EQ(mProgram, 0u);
1243*8975f5c5SAndroid Build Coastguard Worker     drawTest();
1244*8975f5c5SAndroid Build Coastguard Worker 
1245*8975f5c5SAndroid Build Coastguard Worker     if (previousProgram)
1246*8975f5c5SAndroid Build Coastguard Worker     {
1247*8975f5c5SAndroid Build Coastguard Worker         glDeleteProgram(previousProgram);
1248*8975f5c5SAndroid Build Coastguard Worker     }
1249*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1250*8975f5c5SAndroid Build Coastguard Worker }
1251*8975f5c5SAndroid Build Coastguard Worker 
1252*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES2(EXTBlendFuncExtendedTest);
1253*8975f5c5SAndroid Build Coastguard Worker 
1254*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EXTBlendFuncExtendedTestES3);
1255*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES3_AND_ES31(EXTBlendFuncExtendedTestES3);
1256*8975f5c5SAndroid Build Coastguard Worker 
1257*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES2(EXTBlendFuncExtendedDrawTest);
1258*8975f5c5SAndroid Build Coastguard Worker 
1259*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EXTBlendFuncExtendedDrawTestES3);
1260*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES3_AND_ES31(EXTBlendFuncExtendedDrawTestES3);
1261*8975f5c5SAndroid Build Coastguard Worker 
1262*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EXTBlendFuncExtendedDrawTestES31);
1263*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES31(EXTBlendFuncExtendedDrawTestES31);
1264