1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2020 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 // ClipDistanceTest.cpp: Test cases for
7*8975f5c5SAndroid Build Coastguard Worker // GL_APPLE_clip_distance / GL_EXT_clip_cull_distance / GL_ANGLE_clip_cull_distance extensions.
8*8975f5c5SAndroid Build Coastguard Worker //
9*8975f5c5SAndroid Build Coastguard Worker
10*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/ANGLETest.h"
11*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/gl_raii.h"
12*8975f5c5SAndroid Build Coastguard Worker #include "util/EGLWindow.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "util/test_utils.h"
14*8975f5c5SAndroid Build Coastguard Worker
15*8975f5c5SAndroid Build Coastguard Worker using namespace angle;
16*8975f5c5SAndroid Build Coastguard Worker
17*8975f5c5SAndroid Build Coastguard Worker class ClipDistanceAPPLETest : public ANGLETest<>
18*8975f5c5SAndroid Build Coastguard Worker {
19*8975f5c5SAndroid Build Coastguard Worker protected:
ClipDistanceAPPLETest()20*8975f5c5SAndroid Build Coastguard Worker ClipDistanceAPPLETest()
21*8975f5c5SAndroid Build Coastguard Worker {
22*8975f5c5SAndroid Build Coastguard Worker setWindowWidth(64);
23*8975f5c5SAndroid Build Coastguard Worker setWindowHeight(64);
24*8975f5c5SAndroid Build Coastguard Worker setConfigRedBits(8);
25*8975f5c5SAndroid Build Coastguard Worker setConfigGreenBits(8);
26*8975f5c5SAndroid Build Coastguard Worker setConfigBlueBits(8);
27*8975f5c5SAndroid Build Coastguard Worker setConfigAlphaBits(8);
28*8975f5c5SAndroid Build Coastguard Worker setConfigDepthBits(24);
29*8975f5c5SAndroid Build Coastguard Worker setExtensionsEnabled(false);
30*8975f5c5SAndroid Build Coastguard Worker }
31*8975f5c5SAndroid Build Coastguard Worker };
32*8975f5c5SAndroid Build Coastguard Worker
33*8975f5c5SAndroid Build Coastguard Worker // Query max clip distances and enable, disable states of clip distances
TEST_P(ClipDistanceAPPLETest,StateQuery)34*8975f5c5SAndroid Build Coastguard Worker TEST_P(ClipDistanceAPPLETest, StateQuery)
35*8975f5c5SAndroid Build Coastguard Worker {
36*8975f5c5SAndroid Build Coastguard Worker GLint maxClipDistances = 0;
37*8975f5c5SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_CLIP_DISTANCES_APPLE, &maxClipDistances);
38*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(maxClipDistances, 0);
39*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_ERROR(GL_INVALID_ENUM);
40*8975f5c5SAndroid Build Coastguard Worker
41*8975f5c5SAndroid Build Coastguard Worker auto assertState = [](GLenum pname, bool valid, bool expectedState) {
42*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(glIsEnabled(pname), valid ? expectedState : false);
43*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_ERROR(valid ? GL_NO_ERROR : GL_INVALID_ENUM);
44*8975f5c5SAndroid Build Coastguard Worker
45*8975f5c5SAndroid Build Coastguard Worker GLboolean result = false;
46*8975f5c5SAndroid Build Coastguard Worker glGetBooleanv(pname, &result);
47*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(result, valid ? expectedState : false);
48*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_ERROR(valid ? GL_NO_ERROR : GL_INVALID_ENUM);
49*8975f5c5SAndroid Build Coastguard Worker };
50*8975f5c5SAndroid Build Coastguard Worker
51*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < 8; i++)
52*8975f5c5SAndroid Build Coastguard Worker {
53*8975f5c5SAndroid Build Coastguard Worker assertState(GL_CLIP_DISTANCE0_APPLE + i, false, false);
54*8975f5c5SAndroid Build Coastguard Worker
55*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE0_APPLE + i);
56*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_ERROR(GL_INVALID_ENUM);
57*8975f5c5SAndroid Build Coastguard Worker
58*8975f5c5SAndroid Build Coastguard Worker assertState(GL_CLIP_DISTANCE0_APPLE + i, false, false);
59*8975f5c5SAndroid Build Coastguard Worker
60*8975f5c5SAndroid Build Coastguard Worker glDisable(GL_CLIP_DISTANCE0_APPLE + i);
61*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_ERROR(GL_INVALID_ENUM);
62*8975f5c5SAndroid Build Coastguard Worker
63*8975f5c5SAndroid Build Coastguard Worker assertState(GL_CLIP_DISTANCE0_APPLE + i, false, false);
64*8975f5c5SAndroid Build Coastguard Worker }
65*8975f5c5SAndroid Build Coastguard Worker
66*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_APPLE_clip_distance"));
67*8975f5c5SAndroid Build Coastguard Worker
68*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
69*8975f5c5SAndroid Build Coastguard Worker
70*8975f5c5SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_CLIP_DISTANCES_APPLE, &maxClipDistances);
71*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(maxClipDistances, 8);
72*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
73*8975f5c5SAndroid Build Coastguard Worker
74*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < 8; i++)
75*8975f5c5SAndroid Build Coastguard Worker {
76*8975f5c5SAndroid Build Coastguard Worker assertState(GL_CLIP_DISTANCE0_APPLE + i, true, false);
77*8975f5c5SAndroid Build Coastguard Worker
78*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE0_APPLE + i);
79*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
80*8975f5c5SAndroid Build Coastguard Worker
81*8975f5c5SAndroid Build Coastguard Worker assertState(GL_CLIP_DISTANCE0_APPLE + i, true, true);
82*8975f5c5SAndroid Build Coastguard Worker
83*8975f5c5SAndroid Build Coastguard Worker glDisable(GL_CLIP_DISTANCE0_APPLE + i);
84*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
85*8975f5c5SAndroid Build Coastguard Worker
86*8975f5c5SAndroid Build Coastguard Worker assertState(GL_CLIP_DISTANCE0_APPLE + i, true, false);
87*8975f5c5SAndroid Build Coastguard Worker }
88*8975f5c5SAndroid Build Coastguard Worker }
89*8975f5c5SAndroid Build Coastguard Worker
90*8975f5c5SAndroid Build Coastguard Worker // Check that gl_ClipDistance is not defined for fragment shaders
TEST_P(ClipDistanceAPPLETest,FragmentShader)91*8975f5c5SAndroid Build Coastguard Worker TEST_P(ClipDistanceAPPLETest, FragmentShader)
92*8975f5c5SAndroid Build Coastguard Worker {
93*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_APPLE_clip_distance"));
94*8975f5c5SAndroid Build Coastguard Worker
95*8975f5c5SAndroid Build Coastguard Worker constexpr char kVS[] = R"(
96*8975f5c5SAndroid Build Coastguard Worker #extension GL_APPLE_clip_distance : require
97*8975f5c5SAndroid Build Coastguard Worker
98*8975f5c5SAndroid Build Coastguard Worker void main()
99*8975f5c5SAndroid Build Coastguard Worker {
100*8975f5c5SAndroid Build Coastguard Worker gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
101*8975f5c5SAndroid Build Coastguard Worker
102*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[0] = gl_Position.w;
103*8975f5c5SAndroid Build Coastguard Worker })";
104*8975f5c5SAndroid Build Coastguard Worker
105*8975f5c5SAndroid Build Coastguard Worker constexpr char kFS[] = R"(
106*8975f5c5SAndroid Build Coastguard Worker #extension GL_APPLE_clip_distance : require
107*8975f5c5SAndroid Build Coastguard Worker
108*8975f5c5SAndroid Build Coastguard Worker void main()
109*8975f5c5SAndroid Build Coastguard Worker {
110*8975f5c5SAndroid Build Coastguard Worker gl_FragColor = vec4(gl_ClipDistance[0], 1.0, 1.0, 1.0);
111*8975f5c5SAndroid Build Coastguard Worker })";
112*8975f5c5SAndroid Build Coastguard Worker
113*8975f5c5SAndroid Build Coastguard Worker GLProgram prg;
114*8975f5c5SAndroid Build Coastguard Worker prg.makeRaster(kVS, kFS);
115*8975f5c5SAndroid Build Coastguard Worker EXPECT_FALSE(prg.valid());
116*8975f5c5SAndroid Build Coastguard Worker }
117*8975f5c5SAndroid Build Coastguard Worker
118*8975f5c5SAndroid Build Coastguard Worker // Check that gl_ClipDistance cannot be redeclared as a global
TEST_P(ClipDistanceAPPLETest,NotVarying)119*8975f5c5SAndroid Build Coastguard Worker TEST_P(ClipDistanceAPPLETest, NotVarying)
120*8975f5c5SAndroid Build Coastguard Worker {
121*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_APPLE_clip_distance"));
122*8975f5c5SAndroid Build Coastguard Worker
123*8975f5c5SAndroid Build Coastguard Worker constexpr char kVS[] = R"(
124*8975f5c5SAndroid Build Coastguard Worker #extension GL_APPLE_clip_distance : require
125*8975f5c5SAndroid Build Coastguard Worker
126*8975f5c5SAndroid Build Coastguard Worker highp float gl_ClipDistance[1];
127*8975f5c5SAndroid Build Coastguard Worker
128*8975f5c5SAndroid Build Coastguard Worker void main()
129*8975f5c5SAndroid Build Coastguard Worker {
130*8975f5c5SAndroid Build Coastguard Worker gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
131*8975f5c5SAndroid Build Coastguard Worker
132*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[0] = gl_Position.w;
133*8975f5c5SAndroid Build Coastguard Worker })";
134*8975f5c5SAndroid Build Coastguard Worker
135*8975f5c5SAndroid Build Coastguard Worker GLProgram prg;
136*8975f5c5SAndroid Build Coastguard Worker prg.makeRaster(kVS, essl1_shaders::fs::Red());
137*8975f5c5SAndroid Build Coastguard Worker EXPECT_FALSE(prg.valid());
138*8975f5c5SAndroid Build Coastguard Worker }
139*8975f5c5SAndroid Build Coastguard Worker
140*8975f5c5SAndroid Build Coastguard Worker // Check that gl_ClipDistance size cannot be undefined
TEST_P(ClipDistanceAPPLETest,UndefinedArraySize)141*8975f5c5SAndroid Build Coastguard Worker TEST_P(ClipDistanceAPPLETest, UndefinedArraySize)
142*8975f5c5SAndroid Build Coastguard Worker {
143*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_APPLE_clip_distance"));
144*8975f5c5SAndroid Build Coastguard Worker
145*8975f5c5SAndroid Build Coastguard Worker constexpr char kVS[] = R"(
146*8975f5c5SAndroid Build Coastguard Worker #extension GL_APPLE_clip_distance : require
147*8975f5c5SAndroid Build Coastguard Worker
148*8975f5c5SAndroid Build Coastguard Worker void main()
149*8975f5c5SAndroid Build Coastguard Worker {
150*8975f5c5SAndroid Build Coastguard Worker gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
151*8975f5c5SAndroid Build Coastguard Worker for (int i = 0; i < 8; i++)
152*8975f5c5SAndroid Build Coastguard Worker {
153*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[i] = gl_Position.w;
154*8975f5c5SAndroid Build Coastguard Worker }
155*8975f5c5SAndroid Build Coastguard Worker })";
156*8975f5c5SAndroid Build Coastguard Worker
157*8975f5c5SAndroid Build Coastguard Worker GLProgram prg;
158*8975f5c5SAndroid Build Coastguard Worker prg.makeRaster(kVS, essl1_shaders::fs::Red());
159*8975f5c5SAndroid Build Coastguard Worker EXPECT_FALSE(prg.valid());
160*8975f5c5SAndroid Build Coastguard Worker }
161*8975f5c5SAndroid Build Coastguard Worker
162*8975f5c5SAndroid Build Coastguard Worker // Check that gl_ClipDistance size cannot be more than maximum
TEST_P(ClipDistanceAPPLETest,OutOfRangeArraySize)163*8975f5c5SAndroid Build Coastguard Worker TEST_P(ClipDistanceAPPLETest, OutOfRangeArraySize)
164*8975f5c5SAndroid Build Coastguard Worker {
165*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_APPLE_clip_distance"));
166*8975f5c5SAndroid Build Coastguard Worker
167*8975f5c5SAndroid Build Coastguard Worker GLint maxClipDistances = 0;
168*8975f5c5SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_CLIP_DISTANCES_APPLE, &maxClipDistances);
169*8975f5c5SAndroid Build Coastguard Worker
170*8975f5c5SAndroid Build Coastguard Worker std::stringstream vsImplicit;
171*8975f5c5SAndroid Build Coastguard Worker vsImplicit << R"(#extension GL_APPLE_clip_distance : require
172*8975f5c5SAndroid Build Coastguard Worker void main()
173*8975f5c5SAndroid Build Coastguard Worker {
174*8975f5c5SAndroid Build Coastguard Worker gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
175*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[)"
176*8975f5c5SAndroid Build Coastguard Worker << maxClipDistances << R"(] = gl_Position.w;
177*8975f5c5SAndroid Build Coastguard Worker })";
178*8975f5c5SAndroid Build Coastguard Worker
179*8975f5c5SAndroid Build Coastguard Worker std::stringstream vsRedeclared;
180*8975f5c5SAndroid Build Coastguard Worker vsRedeclared << R"(#extension GL_APPLE_clip_distance : require
181*8975f5c5SAndroid Build Coastguard Worker varying highp float gl_ClipDistance[)"
182*8975f5c5SAndroid Build Coastguard Worker << (maxClipDistances + 1) << R"(];
183*8975f5c5SAndroid Build Coastguard Worker void main()
184*8975f5c5SAndroid Build Coastguard Worker {
185*8975f5c5SAndroid Build Coastguard Worker gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
186*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[)"
187*8975f5c5SAndroid Build Coastguard Worker << (maxClipDistances - 1) << R"(] = gl_Position.w;
188*8975f5c5SAndroid Build Coastguard Worker })";
189*8975f5c5SAndroid Build Coastguard Worker
190*8975f5c5SAndroid Build Coastguard Worker std::stringstream vsRedeclaredInvalidIndex;
191*8975f5c5SAndroid Build Coastguard Worker vsRedeclaredInvalidIndex << R"(#extension GL_APPLE_clip_distance : require
192*8975f5c5SAndroid Build Coastguard Worker varying highp float gl_ClipDistance[)"
193*8975f5c5SAndroid Build Coastguard Worker << (maxClipDistances - 2) << R"(];
194*8975f5c5SAndroid Build Coastguard Worker void main()
195*8975f5c5SAndroid Build Coastguard Worker {
196*8975f5c5SAndroid Build Coastguard Worker gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
197*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[)" << (maxClipDistances - 1)
198*8975f5c5SAndroid Build Coastguard Worker << R"(] = gl_Position.w;
199*8975f5c5SAndroid Build Coastguard Worker })";
200*8975f5c5SAndroid Build Coastguard Worker
201*8975f5c5SAndroid Build Coastguard Worker for (auto stream : {&vsImplicit, &vsRedeclared, &vsRedeclaredInvalidIndex})
202*8975f5c5SAndroid Build Coastguard Worker {
203*8975f5c5SAndroid Build Coastguard Worker GLProgram prg;
204*8975f5c5SAndroid Build Coastguard Worker prg.makeRaster(stream->str().c_str(), essl1_shaders::fs::Red());
205*8975f5c5SAndroid Build Coastguard Worker EXPECT_FALSE(prg.valid());
206*8975f5c5SAndroid Build Coastguard Worker }
207*8975f5c5SAndroid Build Coastguard Worker }
208*8975f5c5SAndroid Build Coastguard Worker
209*8975f5c5SAndroid Build Coastguard Worker // Write to one gl_ClipDistance element
TEST_P(ClipDistanceAPPLETest,OneClipDistance)210*8975f5c5SAndroid Build Coastguard Worker TEST_P(ClipDistanceAPPLETest, OneClipDistance)
211*8975f5c5SAndroid Build Coastguard Worker {
212*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_APPLE_clip_distance"));
213*8975f5c5SAndroid Build Coastguard Worker
214*8975f5c5SAndroid Build Coastguard Worker constexpr char kVS[] = R"(
215*8975f5c5SAndroid Build Coastguard Worker #extension GL_APPLE_clip_distance : require
216*8975f5c5SAndroid Build Coastguard Worker
217*8975f5c5SAndroid Build Coastguard Worker uniform vec4 u_plane;
218*8975f5c5SAndroid Build Coastguard Worker
219*8975f5c5SAndroid Build Coastguard Worker attribute vec2 a_position;
220*8975f5c5SAndroid Build Coastguard Worker
221*8975f5c5SAndroid Build Coastguard Worker void main()
222*8975f5c5SAndroid Build Coastguard Worker {
223*8975f5c5SAndroid Build Coastguard Worker gl_Position = vec4(a_position, 0.0, 1.0);
224*8975f5c5SAndroid Build Coastguard Worker
225*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[0] = dot(gl_Position, u_plane);
226*8975f5c5SAndroid Build Coastguard Worker })";
227*8975f5c5SAndroid Build Coastguard Worker
228*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_PROGRAM(programRed, kVS, essl1_shaders::fs::Red());
229*8975f5c5SAndroid Build Coastguard Worker glUseProgram(programRed);
230*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
231*8975f5c5SAndroid Build Coastguard Worker
232*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE0_APPLE);
233*8975f5c5SAndroid Build Coastguard Worker
234*8975f5c5SAndroid Build Coastguard Worker // Clear to blue
235*8975f5c5SAndroid Build Coastguard Worker glClearColor(0, 0, 1, 1);
236*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
237*8975f5c5SAndroid Build Coastguard Worker
238*8975f5c5SAndroid Build Coastguard Worker // Draw full screen quad with color red
239*8975f5c5SAndroid Build Coastguard Worker glUniform4f(glGetUniformLocation(programRed, "u_plane"), 1, 0, 0, 0.5);
240*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
241*8975f5c5SAndroid Build Coastguard Worker drawQuad(programRed, "a_position", 0);
242*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
243*8975f5c5SAndroid Build Coastguard Worker
244*8975f5c5SAndroid Build Coastguard Worker // All pixels on the left of the plane x = -0.5 must be blue
245*8975f5c5SAndroid Build Coastguard Worker GLuint x = 0;
246*8975f5c5SAndroid Build Coastguard Worker GLuint y = 0;
247*8975f5c5SAndroid Build Coastguard Worker GLuint width = getWindowWidth() / 4 - 1;
248*8975f5c5SAndroid Build Coastguard Worker GLuint height = getWindowHeight();
249*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_RECT_EQ(x, y, width, height, GLColor::blue);
250*8975f5c5SAndroid Build Coastguard Worker
251*8975f5c5SAndroid Build Coastguard Worker // All pixels on the right of the plane x = -0.5 must be red
252*8975f5c5SAndroid Build Coastguard Worker x = getWindowWidth() / 4 + 2;
253*8975f5c5SAndroid Build Coastguard Worker y = 0;
254*8975f5c5SAndroid Build Coastguard Worker width = getWindowWidth() - x;
255*8975f5c5SAndroid Build Coastguard Worker height = getWindowHeight();
256*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_RECT_EQ(x, y, width, height, GLColor::red);
257*8975f5c5SAndroid Build Coastguard Worker
258*8975f5c5SAndroid Build Coastguard Worker // Clear to green
259*8975f5c5SAndroid Build Coastguard Worker glClearColor(0, 1, 0, 1);
260*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
261*8975f5c5SAndroid Build Coastguard Worker
262*8975f5c5SAndroid Build Coastguard Worker // Draw full screen quad with color red
263*8975f5c5SAndroid Build Coastguard Worker glUniform4f(glGetUniformLocation(programRed, "u_plane"), -1, 0, 0, -0.5);
264*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
265*8975f5c5SAndroid Build Coastguard Worker drawQuad(programRed, "a_position", 0);
266*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
267*8975f5c5SAndroid Build Coastguard Worker
268*8975f5c5SAndroid Build Coastguard Worker // All pixels on the left of the plane x = -0.5 must be red
269*8975f5c5SAndroid Build Coastguard Worker x = 0;
270*8975f5c5SAndroid Build Coastguard Worker y = 0;
271*8975f5c5SAndroid Build Coastguard Worker width = getWindowWidth() / 4 - 1;
272*8975f5c5SAndroid Build Coastguard Worker height = getWindowHeight();
273*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_RECT_EQ(x, y, width, height, GLColor::red);
274*8975f5c5SAndroid Build Coastguard Worker
275*8975f5c5SAndroid Build Coastguard Worker // All pixels on the right of the plane x = -0.5 must be green
276*8975f5c5SAndroid Build Coastguard Worker x = getWindowWidth() / 4 + 2;
277*8975f5c5SAndroid Build Coastguard Worker y = 0;
278*8975f5c5SAndroid Build Coastguard Worker width = getWindowWidth() - x;
279*8975f5c5SAndroid Build Coastguard Worker height = getWindowHeight();
280*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_RECT_EQ(x, y, width, height, GLColor::green);
281*8975f5c5SAndroid Build Coastguard Worker
282*8975f5c5SAndroid Build Coastguard Worker // Disable GL_CLIP_DISTANCE
283*8975f5c5SAndroid Build Coastguard Worker glDisable(GL_CLIP_DISTANCE0_APPLE);
284*8975f5c5SAndroid Build Coastguard Worker drawQuad(programRed, "a_position", 0);
285*8975f5c5SAndroid Build Coastguard Worker
286*8975f5c5SAndroid Build Coastguard Worker // All pixels must be red
287*8975f5c5SAndroid Build Coastguard Worker x = 0;
288*8975f5c5SAndroid Build Coastguard Worker y = 0;
289*8975f5c5SAndroid Build Coastguard Worker width = getWindowWidth();
290*8975f5c5SAndroid Build Coastguard Worker height = getWindowHeight();
291*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_RECT_EQ(x, y, width, height, GLColor::red);
292*8975f5c5SAndroid Build Coastguard Worker }
293*8975f5c5SAndroid Build Coastguard Worker
294*8975f5c5SAndroid Build Coastguard Worker // Write to each gl_ClipDistance element
TEST_P(ClipDistanceAPPLETest,EachClipDistance)295*8975f5c5SAndroid Build Coastguard Worker TEST_P(ClipDistanceAPPLETest, EachClipDistance)
296*8975f5c5SAndroid Build Coastguard Worker {
297*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_APPLE_clip_distance"));
298*8975f5c5SAndroid Build Coastguard Worker
299*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < 8; i++)
300*8975f5c5SAndroid Build Coastguard Worker {
301*8975f5c5SAndroid Build Coastguard Worker std::stringstream vertexShaderStr;
302*8975f5c5SAndroid Build Coastguard Worker vertexShaderStr << "#extension GL_APPLE_clip_distance : require\n"
303*8975f5c5SAndroid Build Coastguard Worker << "uniform vec4 u_plane;\n"
304*8975f5c5SAndroid Build Coastguard Worker << "attribute vec2 a_position;\n"
305*8975f5c5SAndroid Build Coastguard Worker << "void main()\n"
306*8975f5c5SAndroid Build Coastguard Worker << "{\n"
307*8975f5c5SAndroid Build Coastguard Worker << " gl_Position = vec4(a_position, 0.0, 1.0);\n"
308*8975f5c5SAndroid Build Coastguard Worker << " gl_ClipDistance[" << i << "] = dot(gl_Position, u_plane);\n"
309*8975f5c5SAndroid Build Coastguard Worker << "}";
310*8975f5c5SAndroid Build Coastguard Worker
311*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_PROGRAM(programRed, vertexShaderStr.str().c_str(), essl1_shaders::fs::Red());
312*8975f5c5SAndroid Build Coastguard Worker glUseProgram(programRed);
313*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
314*8975f5c5SAndroid Build Coastguard Worker
315*8975f5c5SAndroid Build Coastguard Worker // Enable the current clip distance, disable all others.
316*8975f5c5SAndroid Build Coastguard Worker for (size_t j = 0; j < 8; j++)
317*8975f5c5SAndroid Build Coastguard Worker {
318*8975f5c5SAndroid Build Coastguard Worker if (j == i)
319*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE0_APPLE + j);
320*8975f5c5SAndroid Build Coastguard Worker else
321*8975f5c5SAndroid Build Coastguard Worker glDisable(GL_CLIP_DISTANCE0_APPLE + j);
322*8975f5c5SAndroid Build Coastguard Worker }
323*8975f5c5SAndroid Build Coastguard Worker
324*8975f5c5SAndroid Build Coastguard Worker // Clear to blue
325*8975f5c5SAndroid Build Coastguard Worker glClearColor(0, 0, 1, 1);
326*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
327*8975f5c5SAndroid Build Coastguard Worker
328*8975f5c5SAndroid Build Coastguard Worker // Draw full screen quad with color red
329*8975f5c5SAndroid Build Coastguard Worker glUniform4f(glGetUniformLocation(programRed, "u_plane"), 1, 0, 0, 0.5);
330*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
331*8975f5c5SAndroid Build Coastguard Worker drawQuad(programRed, "a_position", 0);
332*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
333*8975f5c5SAndroid Build Coastguard Worker
334*8975f5c5SAndroid Build Coastguard Worker // All pixels on the left of the plane x = -0.5 must be blue
335*8975f5c5SAndroid Build Coastguard Worker GLuint x = 0;
336*8975f5c5SAndroid Build Coastguard Worker GLuint y = 0;
337*8975f5c5SAndroid Build Coastguard Worker GLuint width = getWindowWidth() / 4 - 1;
338*8975f5c5SAndroid Build Coastguard Worker GLuint height = getWindowHeight();
339*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_RECT_EQ(x, y, width, height, GLColor::blue);
340*8975f5c5SAndroid Build Coastguard Worker
341*8975f5c5SAndroid Build Coastguard Worker // All pixels on the right of the plane x = -0.5 must be red
342*8975f5c5SAndroid Build Coastguard Worker x = getWindowWidth() / 4 + 2;
343*8975f5c5SAndroid Build Coastguard Worker y = 0;
344*8975f5c5SAndroid Build Coastguard Worker width = getWindowWidth() - x;
345*8975f5c5SAndroid Build Coastguard Worker height = getWindowHeight();
346*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_RECT_EQ(x, y, width, height, GLColor::red);
347*8975f5c5SAndroid Build Coastguard Worker
348*8975f5c5SAndroid Build Coastguard Worker // Clear to green
349*8975f5c5SAndroid Build Coastguard Worker glClearColor(0, 1, 0, 1);
350*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
351*8975f5c5SAndroid Build Coastguard Worker
352*8975f5c5SAndroid Build Coastguard Worker // Draw full screen quad with color red
353*8975f5c5SAndroid Build Coastguard Worker glUniform4f(glGetUniformLocation(programRed, "u_plane"), -1, 0, 0, -0.5);
354*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
355*8975f5c5SAndroid Build Coastguard Worker drawQuad(programRed, "a_position", 0);
356*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
357*8975f5c5SAndroid Build Coastguard Worker
358*8975f5c5SAndroid Build Coastguard Worker // All pixels on the left of the plane x = -0.5 must be red
359*8975f5c5SAndroid Build Coastguard Worker x = 0;
360*8975f5c5SAndroid Build Coastguard Worker y = 0;
361*8975f5c5SAndroid Build Coastguard Worker width = getWindowWidth() / 4 - 1;
362*8975f5c5SAndroid Build Coastguard Worker height = getWindowHeight();
363*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_RECT_EQ(x, y, width, height, GLColor::red);
364*8975f5c5SAndroid Build Coastguard Worker
365*8975f5c5SAndroid Build Coastguard Worker // All pixels on the right of the plane x = -0.5 must be green
366*8975f5c5SAndroid Build Coastguard Worker x = getWindowWidth() / 4 + 2;
367*8975f5c5SAndroid Build Coastguard Worker y = 0;
368*8975f5c5SAndroid Build Coastguard Worker width = getWindowWidth() - x;
369*8975f5c5SAndroid Build Coastguard Worker height = getWindowHeight();
370*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_RECT_EQ(x, y, width, height, GLColor::green);
371*8975f5c5SAndroid Build Coastguard Worker
372*8975f5c5SAndroid Build Coastguard Worker // Disable GL_CLIP_DISTANCE
373*8975f5c5SAndroid Build Coastguard Worker glDisable(GL_CLIP_DISTANCE0_APPLE + i);
374*8975f5c5SAndroid Build Coastguard Worker drawQuad(programRed, "a_position", 0);
375*8975f5c5SAndroid Build Coastguard Worker
376*8975f5c5SAndroid Build Coastguard Worker // All pixels must be red
377*8975f5c5SAndroid Build Coastguard Worker x = 0;
378*8975f5c5SAndroid Build Coastguard Worker y = 0;
379*8975f5c5SAndroid Build Coastguard Worker width = getWindowWidth();
380*8975f5c5SAndroid Build Coastguard Worker height = getWindowHeight();
381*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_RECT_EQ(x, y, width, height, GLColor::red);
382*8975f5c5SAndroid Build Coastguard Worker }
383*8975f5c5SAndroid Build Coastguard Worker }
384*8975f5c5SAndroid Build Coastguard Worker
385*8975f5c5SAndroid Build Coastguard Worker // Use 8 clip distances to draw an octagon
TEST_P(ClipDistanceAPPLETest,Octagon)386*8975f5c5SAndroid Build Coastguard Worker TEST_P(ClipDistanceAPPLETest, Octagon)
387*8975f5c5SAndroid Build Coastguard Worker {
388*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_APPLE_clip_distance"));
389*8975f5c5SAndroid Build Coastguard Worker
390*8975f5c5SAndroid Build Coastguard Worker constexpr char kVS[] = R"(
391*8975f5c5SAndroid Build Coastguard Worker #extension GL_APPLE_clip_distance : require
392*8975f5c5SAndroid Build Coastguard Worker
393*8975f5c5SAndroid Build Coastguard Worker attribute vec2 a_position;
394*8975f5c5SAndroid Build Coastguard Worker
395*8975f5c5SAndroid Build Coastguard Worker void main()
396*8975f5c5SAndroid Build Coastguard Worker {
397*8975f5c5SAndroid Build Coastguard Worker gl_Position = vec4(a_position, 0.0, 1.0);
398*8975f5c5SAndroid Build Coastguard Worker
399*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[0] = dot(gl_Position, vec4( 1, 0, 0, 0.5));
400*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[1] = dot(gl_Position, vec4(-1, 0, 0, 0.5));
401*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[2] = dot(gl_Position, vec4( 0, 1, 0, 0.5));
402*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[3] = dot(gl_Position, vec4( 0, -1, 0, 0.5));
403*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[4] = dot(gl_Position, vec4( 1, 1, 0, 0.70710678));
404*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[5] = dot(gl_Position, vec4( 1, -1, 0, 0.70710678));
405*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[6] = dot(gl_Position, vec4(-1, 1, 0, 0.70710678));
406*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[7] = dot(gl_Position, vec4(-1, -1, 0, 0.70710678));
407*8975f5c5SAndroid Build Coastguard Worker })";
408*8975f5c5SAndroid Build Coastguard Worker
409*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_PROGRAM(programRed, kVS, essl1_shaders::fs::Red());
410*8975f5c5SAndroid Build Coastguard Worker glUseProgram(programRed);
411*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
412*8975f5c5SAndroid Build Coastguard Worker
413*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE0_APPLE);
414*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE1_APPLE);
415*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE2_APPLE);
416*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE3_APPLE);
417*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE4_APPLE);
418*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE5_APPLE);
419*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE6_APPLE);
420*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE7_APPLE);
421*8975f5c5SAndroid Build Coastguard Worker
422*8975f5c5SAndroid Build Coastguard Worker // Clear to blue
423*8975f5c5SAndroid Build Coastguard Worker glClearColor(0, 0, 1, 1);
424*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
425*8975f5c5SAndroid Build Coastguard Worker
426*8975f5c5SAndroid Build Coastguard Worker // Draw full screen quad with color red
427*8975f5c5SAndroid Build Coastguard Worker drawQuad(programRed, "a_position", 0);
428*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
429*8975f5c5SAndroid Build Coastguard Worker
430*8975f5c5SAndroid Build Coastguard Worker // Top edge
431*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(32, 56, GLColor::blue);
432*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(32, 40, GLColor::red);
433*8975f5c5SAndroid Build Coastguard Worker
434*8975f5c5SAndroid Build Coastguard Worker // Top-right edge
435*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(48, 48, GLColor::blue);
436*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(40, 40, GLColor::red);
437*8975f5c5SAndroid Build Coastguard Worker
438*8975f5c5SAndroid Build Coastguard Worker // Right edge
439*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(56, 32, GLColor::blue);
440*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(40, 32, GLColor::red);
441*8975f5c5SAndroid Build Coastguard Worker
442*8975f5c5SAndroid Build Coastguard Worker // Bottom-right edge
443*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(48, 16, GLColor::blue);
444*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(40, 24, GLColor::red);
445*8975f5c5SAndroid Build Coastguard Worker
446*8975f5c5SAndroid Build Coastguard Worker // Bottom edge
447*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(32, 8, GLColor::blue);
448*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(32, 24, GLColor::red);
449*8975f5c5SAndroid Build Coastguard Worker
450*8975f5c5SAndroid Build Coastguard Worker // Bottom-left edge
451*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(16, 16, GLColor::blue);
452*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(24, 24, GLColor::red);
453*8975f5c5SAndroid Build Coastguard Worker
454*8975f5c5SAndroid Build Coastguard Worker // Left edge
455*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(8, 32, GLColor::blue);
456*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(24, 32, GLColor::red);
457*8975f5c5SAndroid Build Coastguard Worker
458*8975f5c5SAndroid Build Coastguard Worker // Top-left edge
459*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(16, 48, GLColor::blue);
460*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(24, 40, GLColor::red);
461*8975f5c5SAndroid Build Coastguard Worker }
462*8975f5c5SAndroid Build Coastguard Worker
463*8975f5c5SAndroid Build Coastguard Worker // Write to 3 clip distances
TEST_P(ClipDistanceAPPLETest,ThreeClipDistances)464*8975f5c5SAndroid Build Coastguard Worker TEST_P(ClipDistanceAPPLETest, ThreeClipDistances)
465*8975f5c5SAndroid Build Coastguard Worker {
466*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_APPLE_clip_distance"));
467*8975f5c5SAndroid Build Coastguard Worker
468*8975f5c5SAndroid Build Coastguard Worker constexpr char kVS[] = R"(
469*8975f5c5SAndroid Build Coastguard Worker #extension GL_APPLE_clip_distance : require
470*8975f5c5SAndroid Build Coastguard Worker
471*8975f5c5SAndroid Build Coastguard Worker uniform vec4 u_plane[3];
472*8975f5c5SAndroid Build Coastguard Worker
473*8975f5c5SAndroid Build Coastguard Worker attribute vec2 a_position;
474*8975f5c5SAndroid Build Coastguard Worker
475*8975f5c5SAndroid Build Coastguard Worker void main()
476*8975f5c5SAndroid Build Coastguard Worker {
477*8975f5c5SAndroid Build Coastguard Worker gl_Position = vec4(a_position, 0.0, 1.0);
478*8975f5c5SAndroid Build Coastguard Worker
479*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[0] = dot(gl_Position, u_plane[0]);
480*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[3] = dot(gl_Position, u_plane[1]);
481*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[7] = dot(gl_Position, u_plane[2]);
482*8975f5c5SAndroid Build Coastguard Worker })";
483*8975f5c5SAndroid Build Coastguard Worker
484*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_PROGRAM(programRed, kVS, essl1_shaders::fs::Red());
485*8975f5c5SAndroid Build Coastguard Worker glUseProgram(programRed);
486*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
487*8975f5c5SAndroid Build Coastguard Worker
488*8975f5c5SAndroid Build Coastguard Worker // Enable 3 clip distances
489*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE0_APPLE);
490*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE3_APPLE);
491*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE7_APPLE);
492*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
493*8975f5c5SAndroid Build Coastguard Worker
494*8975f5c5SAndroid Build Coastguard Worker // Clear to blue
495*8975f5c5SAndroid Build Coastguard Worker glClearColor(0, 0, 1, 1);
496*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
497*8975f5c5SAndroid Build Coastguard Worker
498*8975f5c5SAndroid Build Coastguard Worker // Draw full screen quad with color red
499*8975f5c5SAndroid Build Coastguard Worker // x = -0.5
500*8975f5c5SAndroid Build Coastguard Worker glUniform4f(glGetUniformLocation(programRed, "u_plane[0]"), 1, 0, 0, 0.5);
501*8975f5c5SAndroid Build Coastguard Worker // x = 0.5
502*8975f5c5SAndroid Build Coastguard Worker glUniform4f(glGetUniformLocation(programRed, "u_plane[1]"), -1, 0, 0, 0.5);
503*8975f5c5SAndroid Build Coastguard Worker // x + y = 1
504*8975f5c5SAndroid Build Coastguard Worker glUniform4f(glGetUniformLocation(programRed, "u_plane[2]"), -1, -1, 0, 1);
505*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
506*8975f5c5SAndroid Build Coastguard Worker drawQuad(programRed, "a_position", 0);
507*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
508*8975f5c5SAndroid Build Coastguard Worker
509*8975f5c5SAndroid Build Coastguard Worker {
510*8975f5c5SAndroid Build Coastguard Worker // All pixels on the left of the plane x = -0.5 must be blue
511*8975f5c5SAndroid Build Coastguard Worker GLuint x = 0;
512*8975f5c5SAndroid Build Coastguard Worker GLuint y = 0;
513*8975f5c5SAndroid Build Coastguard Worker GLuint width = getWindowWidth() / 4 - 1;
514*8975f5c5SAndroid Build Coastguard Worker GLuint height = getWindowHeight();
515*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_RECT_EQ(x, y, width, height, GLColor::blue);
516*8975f5c5SAndroid Build Coastguard Worker
517*8975f5c5SAndroid Build Coastguard Worker // All pixels from the plane x = -0.5 to the plane x = 0 must be red
518*8975f5c5SAndroid Build Coastguard Worker x = getWindowWidth() / 4 + 2;
519*8975f5c5SAndroid Build Coastguard Worker y = 0;
520*8975f5c5SAndroid Build Coastguard Worker width = getWindowWidth() / 2 - x;
521*8975f5c5SAndroid Build Coastguard Worker height = getWindowHeight();
522*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_RECT_EQ(x, y, width, height, GLColor::red);
523*8975f5c5SAndroid Build Coastguard Worker }
524*8975f5c5SAndroid Build Coastguard Worker
525*8975f5c5SAndroid Build Coastguard Worker {
526*8975f5c5SAndroid Build Coastguard Worker // Check pixels to the right of the plane x = 0
527*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> actualColors(getWindowWidth() * getWindowHeight());
528*8975f5c5SAndroid Build Coastguard Worker glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
529*8975f5c5SAndroid Build Coastguard Worker actualColors.data());
530*8975f5c5SAndroid Build Coastguard Worker for (int y = 0; y < getWindowHeight(); ++y)
531*8975f5c5SAndroid Build Coastguard Worker {
532*8975f5c5SAndroid Build Coastguard Worker for (int x = getWindowWidth() / 2; x < getWindowWidth(); ++x)
533*8975f5c5SAndroid Build Coastguard Worker {
534*8975f5c5SAndroid Build Coastguard Worker const int currentPosition = y * getWindowHeight() + x;
535*8975f5c5SAndroid Build Coastguard Worker
536*8975f5c5SAndroid Build Coastguard Worker if (x < getWindowWidth() * 3 / 2 - y - 1 && x < getWindowWidth() * 3 / 4 - 1)
537*8975f5c5SAndroid Build Coastguard Worker {
538*8975f5c5SAndroid Build Coastguard Worker // Bottom of the plane x + y = 1 clipped by x = 0.5 plane
539*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(GLColor::red, actualColors[currentPosition]);
540*8975f5c5SAndroid Build Coastguard Worker }
541*8975f5c5SAndroid Build Coastguard Worker else if (x > getWindowWidth() * 3 / 2 - y + 1 || x > getWindowWidth() * 3 / 4 + 1)
542*8975f5c5SAndroid Build Coastguard Worker {
543*8975f5c5SAndroid Build Coastguard Worker // Top of the plane x + y = 1 plus right of x = 0.5 plane
544*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(GLColor::blue, actualColors[currentPosition]);
545*8975f5c5SAndroid Build Coastguard Worker }
546*8975f5c5SAndroid Build Coastguard Worker }
547*8975f5c5SAndroid Build Coastguard Worker }
548*8975f5c5SAndroid Build Coastguard Worker }
549*8975f5c5SAndroid Build Coastguard Worker
550*8975f5c5SAndroid Build Coastguard Worker // Clear to green
551*8975f5c5SAndroid Build Coastguard Worker glClearColor(0, 1, 0, 1);
552*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
553*8975f5c5SAndroid Build Coastguard Worker
554*8975f5c5SAndroid Build Coastguard Worker // Disable gl_ClipDistance[3]
555*8975f5c5SAndroid Build Coastguard Worker glDisable(GL_CLIP_DISTANCE3_APPLE);
556*8975f5c5SAndroid Build Coastguard Worker
557*8975f5c5SAndroid Build Coastguard Worker // Draw full screen quad with color red
558*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
559*8975f5c5SAndroid Build Coastguard Worker drawQuad(programRed, "a_position", 0);
560*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
561*8975f5c5SAndroid Build Coastguard Worker
562*8975f5c5SAndroid Build Coastguard Worker {
563*8975f5c5SAndroid Build Coastguard Worker // All pixels on the left of the plane x = -0.5 must be green
564*8975f5c5SAndroid Build Coastguard Worker GLuint x = 0;
565*8975f5c5SAndroid Build Coastguard Worker GLuint y = 0;
566*8975f5c5SAndroid Build Coastguard Worker GLuint width = getWindowWidth() / 4 - 1;
567*8975f5c5SAndroid Build Coastguard Worker GLuint height = getWindowHeight();
568*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_RECT_EQ(x, y, width, height, GLColor::green);
569*8975f5c5SAndroid Build Coastguard Worker
570*8975f5c5SAndroid Build Coastguard Worker // All pixels from the plane x = -0.5 to the plane x = 0 must be red
571*8975f5c5SAndroid Build Coastguard Worker x = getWindowWidth() / 4 + 2;
572*8975f5c5SAndroid Build Coastguard Worker y = 0;
573*8975f5c5SAndroid Build Coastguard Worker width = getWindowWidth() / 2 - x;
574*8975f5c5SAndroid Build Coastguard Worker height = getWindowHeight();
575*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_RECT_EQ(x, y, width, height, GLColor::red);
576*8975f5c5SAndroid Build Coastguard Worker }
577*8975f5c5SAndroid Build Coastguard Worker
578*8975f5c5SAndroid Build Coastguard Worker // Check pixels to the right of the plane x = 0
579*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> actualColors(getWindowWidth() * getWindowHeight());
580*8975f5c5SAndroid Build Coastguard Worker glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
581*8975f5c5SAndroid Build Coastguard Worker actualColors.data());
582*8975f5c5SAndroid Build Coastguard Worker for (int y = 0; y < getWindowHeight(); ++y)
583*8975f5c5SAndroid Build Coastguard Worker {
584*8975f5c5SAndroid Build Coastguard Worker for (int x = getWindowWidth() / 2; x < getWindowWidth(); ++x)
585*8975f5c5SAndroid Build Coastguard Worker {
586*8975f5c5SAndroid Build Coastguard Worker const int currentPosition = y * getWindowHeight() + x;
587*8975f5c5SAndroid Build Coastguard Worker
588*8975f5c5SAndroid Build Coastguard Worker if (x < getWindowWidth() * 3 / 2 - y - 1)
589*8975f5c5SAndroid Build Coastguard Worker {
590*8975f5c5SAndroid Build Coastguard Worker // Bottom of the plane x + y = 1
591*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(GLColor::red, actualColors[currentPosition]);
592*8975f5c5SAndroid Build Coastguard Worker }
593*8975f5c5SAndroid Build Coastguard Worker else if (x > getWindowWidth() * 3 / 2 - y + 1)
594*8975f5c5SAndroid Build Coastguard Worker {
595*8975f5c5SAndroid Build Coastguard Worker // Top of the plane x + y = 1
596*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(GLColor::green, actualColors[currentPosition]);
597*8975f5c5SAndroid Build Coastguard Worker }
598*8975f5c5SAndroid Build Coastguard Worker }
599*8975f5c5SAndroid Build Coastguard Worker }
600*8975f5c5SAndroid Build Coastguard Worker }
601*8975f5c5SAndroid Build Coastguard Worker
602*8975f5c5SAndroid Build Coastguard Worker // Redeclare gl_ClipDistance in shader with explicit size, also use it in a global function
603*8975f5c5SAndroid Build Coastguard Worker // outside main()
TEST_P(ClipDistanceAPPLETest,ThreeClipDistancesRedeclared)604*8975f5c5SAndroid Build Coastguard Worker TEST_P(ClipDistanceAPPLETest, ThreeClipDistancesRedeclared)
605*8975f5c5SAndroid Build Coastguard Worker {
606*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_APPLE_clip_distance"));
607*8975f5c5SAndroid Build Coastguard Worker
608*8975f5c5SAndroid Build Coastguard Worker constexpr char kVS[] = R"(
609*8975f5c5SAndroid Build Coastguard Worker #extension GL_APPLE_clip_distance : require
610*8975f5c5SAndroid Build Coastguard Worker
611*8975f5c5SAndroid Build Coastguard Worker varying highp float gl_ClipDistance[3];
612*8975f5c5SAndroid Build Coastguard Worker
613*8975f5c5SAndroid Build Coastguard Worker void computeClipDistances(in vec4 position, in vec4 plane[3])
614*8975f5c5SAndroid Build Coastguard Worker {
615*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[0] = dot(position, plane[0]);
616*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[1] = dot(position, plane[1]);
617*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[2] = dot(position, plane[2]);
618*8975f5c5SAndroid Build Coastguard Worker }
619*8975f5c5SAndroid Build Coastguard Worker
620*8975f5c5SAndroid Build Coastguard Worker uniform vec4 u_plane[3];
621*8975f5c5SAndroid Build Coastguard Worker
622*8975f5c5SAndroid Build Coastguard Worker attribute vec2 a_position;
623*8975f5c5SAndroid Build Coastguard Worker
624*8975f5c5SAndroid Build Coastguard Worker void main()
625*8975f5c5SAndroid Build Coastguard Worker {
626*8975f5c5SAndroid Build Coastguard Worker gl_Position = vec4(a_position, 0.0, 1.0);
627*8975f5c5SAndroid Build Coastguard Worker
628*8975f5c5SAndroid Build Coastguard Worker computeClipDistances(gl_Position, u_plane);
629*8975f5c5SAndroid Build Coastguard Worker })";
630*8975f5c5SAndroid Build Coastguard Worker
631*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_PROGRAM(programRed, kVS, essl1_shaders::fs::Red());
632*8975f5c5SAndroid Build Coastguard Worker glUseProgram(programRed);
633*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
634*8975f5c5SAndroid Build Coastguard Worker
635*8975f5c5SAndroid Build Coastguard Worker // Enable 3 clip distances
636*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE0_APPLE);
637*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE1_APPLE);
638*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE2_APPLE);
639*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
640*8975f5c5SAndroid Build Coastguard Worker
641*8975f5c5SAndroid Build Coastguard Worker // Clear to blue
642*8975f5c5SAndroid Build Coastguard Worker glClearColor(0, 0, 1, 1);
643*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
644*8975f5c5SAndroid Build Coastguard Worker
645*8975f5c5SAndroid Build Coastguard Worker // Draw full screen quad with color red
646*8975f5c5SAndroid Build Coastguard Worker // x = -0.5
647*8975f5c5SAndroid Build Coastguard Worker glUniform4f(glGetUniformLocation(programRed, "u_plane[0]"), 1, 0, 0, 0.5);
648*8975f5c5SAndroid Build Coastguard Worker // x = 0.5
649*8975f5c5SAndroid Build Coastguard Worker glUniform4f(glGetUniformLocation(programRed, "u_plane[1]"), -1, 0, 0, 0.5);
650*8975f5c5SAndroid Build Coastguard Worker // x + y = 1
651*8975f5c5SAndroid Build Coastguard Worker glUniform4f(glGetUniformLocation(programRed, "u_plane[2]"), -1, -1, 0, 1);
652*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
653*8975f5c5SAndroid Build Coastguard Worker drawQuad(programRed, "a_position", 0);
654*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
655*8975f5c5SAndroid Build Coastguard Worker
656*8975f5c5SAndroid Build Coastguard Worker {
657*8975f5c5SAndroid Build Coastguard Worker // All pixels on the left of the plane x = -0.5 must be blue
658*8975f5c5SAndroid Build Coastguard Worker GLuint x = 0;
659*8975f5c5SAndroid Build Coastguard Worker GLuint y = 0;
660*8975f5c5SAndroid Build Coastguard Worker GLuint width = getWindowWidth() / 4 - 1;
661*8975f5c5SAndroid Build Coastguard Worker GLuint height = getWindowHeight();
662*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_RECT_EQ(x, y, width, height, GLColor::blue);
663*8975f5c5SAndroid Build Coastguard Worker
664*8975f5c5SAndroid Build Coastguard Worker // All pixels from the plane x = -0.5 to the plane x = 0 must be red
665*8975f5c5SAndroid Build Coastguard Worker x = getWindowWidth() / 4 + 2;
666*8975f5c5SAndroid Build Coastguard Worker y = 0;
667*8975f5c5SAndroid Build Coastguard Worker width = getWindowWidth() / 2 - x;
668*8975f5c5SAndroid Build Coastguard Worker height = getWindowHeight();
669*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_RECT_EQ(x, y, width, height, GLColor::red);
670*8975f5c5SAndroid Build Coastguard Worker }
671*8975f5c5SAndroid Build Coastguard Worker
672*8975f5c5SAndroid Build Coastguard Worker // Check pixels to the right of the plane x = 0
673*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> actualColors(getWindowWidth() * getWindowHeight());
674*8975f5c5SAndroid Build Coastguard Worker glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
675*8975f5c5SAndroid Build Coastguard Worker actualColors.data());
676*8975f5c5SAndroid Build Coastguard Worker for (int y = 0; y < getWindowHeight(); ++y)
677*8975f5c5SAndroid Build Coastguard Worker {
678*8975f5c5SAndroid Build Coastguard Worker for (int x = getWindowWidth() / 2; x < getWindowWidth(); ++x)
679*8975f5c5SAndroid Build Coastguard Worker {
680*8975f5c5SAndroid Build Coastguard Worker const int currentPosition = y * getWindowHeight() + x;
681*8975f5c5SAndroid Build Coastguard Worker
682*8975f5c5SAndroid Build Coastguard Worker if (x < getWindowWidth() * 3 / 2 - y - 1 && x < getWindowWidth() * 3 / 4 - 1)
683*8975f5c5SAndroid Build Coastguard Worker {
684*8975f5c5SAndroid Build Coastguard Worker // Bottom of the plane x + y = 1 clipped by x = 0.5 plane
685*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(GLColor::red, actualColors[currentPosition]);
686*8975f5c5SAndroid Build Coastguard Worker }
687*8975f5c5SAndroid Build Coastguard Worker else if (x > getWindowWidth() * 3 / 2 - y + 1 || x > getWindowWidth() * 3 / 4 + 1)
688*8975f5c5SAndroid Build Coastguard Worker {
689*8975f5c5SAndroid Build Coastguard Worker // Top of the plane x + y = 1 plus right of x = 0.5 plane
690*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(GLColor::blue, actualColors[currentPosition]);
691*8975f5c5SAndroid Build Coastguard Worker }
692*8975f5c5SAndroid Build Coastguard Worker }
693*8975f5c5SAndroid Build Coastguard Worker }
694*8975f5c5SAndroid Build Coastguard Worker }
695*8975f5c5SAndroid Build Coastguard Worker
696*8975f5c5SAndroid Build Coastguard Worker using ClipCullDistanceTestParams = std::tuple<angle::PlatformParameters, bool>;
697*8975f5c5SAndroid Build Coastguard Worker
PrintToStringParamName(const::testing::TestParamInfo<ClipCullDistanceTestParams> & info)698*8975f5c5SAndroid Build Coastguard Worker std::string PrintToStringParamName(const ::testing::TestParamInfo<ClipCullDistanceTestParams> &info)
699*8975f5c5SAndroid Build Coastguard Worker {
700*8975f5c5SAndroid Build Coastguard Worker std::stringstream ss;
701*8975f5c5SAndroid Build Coastguard Worker ss << std::get<0>(info.param);
702*8975f5c5SAndroid Build Coastguard Worker if (std::get<1>(info.param))
703*8975f5c5SAndroid Build Coastguard Worker {
704*8975f5c5SAndroid Build Coastguard Worker ss << "__EXT";
705*8975f5c5SAndroid Build Coastguard Worker }
706*8975f5c5SAndroid Build Coastguard Worker else
707*8975f5c5SAndroid Build Coastguard Worker {
708*8975f5c5SAndroid Build Coastguard Worker ss << "__ANGLE";
709*8975f5c5SAndroid Build Coastguard Worker }
710*8975f5c5SAndroid Build Coastguard Worker return ss.str();
711*8975f5c5SAndroid Build Coastguard Worker }
712*8975f5c5SAndroid Build Coastguard Worker
713*8975f5c5SAndroid Build Coastguard Worker class ClipCullDistanceTest : public ANGLETest<ClipCullDistanceTestParams>
714*8975f5c5SAndroid Build Coastguard Worker {
715*8975f5c5SAndroid Build Coastguard Worker protected:
716*8975f5c5SAndroid Build Coastguard Worker const bool mCullDistanceSupportRequired;
717*8975f5c5SAndroid Build Coastguard Worker const std::string kExtensionName;
718*8975f5c5SAndroid Build Coastguard Worker
ClipCullDistanceTest()719*8975f5c5SAndroid Build Coastguard Worker ClipCullDistanceTest()
720*8975f5c5SAndroid Build Coastguard Worker : mCullDistanceSupportRequired(::testing::get<1>(GetParam())),
721*8975f5c5SAndroid Build Coastguard Worker kExtensionName(::testing::get<1>(GetParam()) ? "GL_EXT_clip_cull_distance"
722*8975f5c5SAndroid Build Coastguard Worker : "GL_ANGLE_clip_cull_distance")
723*8975f5c5SAndroid Build Coastguard Worker {
724*8975f5c5SAndroid Build Coastguard Worker setWindowWidth(64);
725*8975f5c5SAndroid Build Coastguard Worker setWindowHeight(64);
726*8975f5c5SAndroid Build Coastguard Worker setConfigRedBits(8);
727*8975f5c5SAndroid Build Coastguard Worker setConfigGreenBits(8);
728*8975f5c5SAndroid Build Coastguard Worker setConfigBlueBits(8);
729*8975f5c5SAndroid Build Coastguard Worker setConfigAlphaBits(8);
730*8975f5c5SAndroid Build Coastguard Worker setConfigDepthBits(24);
731*8975f5c5SAndroid Build Coastguard Worker setExtensionsEnabled(false);
732*8975f5c5SAndroid Build Coastguard Worker }
733*8975f5c5SAndroid Build Coastguard Worker };
734*8975f5c5SAndroid Build Coastguard Worker
735*8975f5c5SAndroid Build Coastguard Worker // Query max clip distances and enable, disable states of clip distances
TEST_P(ClipCullDistanceTest,StateQuery)736*8975f5c5SAndroid Build Coastguard Worker TEST_P(ClipCullDistanceTest, StateQuery)
737*8975f5c5SAndroid Build Coastguard Worker {
738*8975f5c5SAndroid Build Coastguard Worker GLint maxClipDistances = 0;
739*8975f5c5SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_CLIP_DISTANCES_EXT, &maxClipDistances);
740*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(maxClipDistances, 0);
741*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_ERROR(GL_INVALID_ENUM);
742*8975f5c5SAndroid Build Coastguard Worker
743*8975f5c5SAndroid Build Coastguard Worker GLint maxCullDistances = 0;
744*8975f5c5SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_CULL_DISTANCES_EXT, &maxCullDistances);
745*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(maxCullDistances, 0);
746*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_ERROR(GL_INVALID_ENUM);
747*8975f5c5SAndroid Build Coastguard Worker
748*8975f5c5SAndroid Build Coastguard Worker GLint maxCombinedClipAndCullDistances = 0;
749*8975f5c5SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES_EXT, &maxCombinedClipAndCullDistances);
750*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(maxCombinedClipAndCullDistances, 0);
751*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_ERROR(GL_INVALID_ENUM);
752*8975f5c5SAndroid Build Coastguard Worker
753*8975f5c5SAndroid Build Coastguard Worker auto assertState = [](GLenum pname, bool valid, bool expectedState) {
754*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(glIsEnabled(pname), valid ? expectedState : false);
755*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_ERROR(valid ? GL_NO_ERROR : GL_INVALID_ENUM);
756*8975f5c5SAndroid Build Coastguard Worker
757*8975f5c5SAndroid Build Coastguard Worker GLboolean result = false;
758*8975f5c5SAndroid Build Coastguard Worker glGetBooleanv(pname, &result);
759*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(result, valid ? expectedState : false);
760*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_ERROR(valid ? GL_NO_ERROR : GL_INVALID_ENUM);
761*8975f5c5SAndroid Build Coastguard Worker };
762*8975f5c5SAndroid Build Coastguard Worker
763*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < 8; i++)
764*8975f5c5SAndroid Build Coastguard Worker {
765*8975f5c5SAndroid Build Coastguard Worker assertState(GL_CLIP_DISTANCE0_EXT + i, false, false);
766*8975f5c5SAndroid Build Coastguard Worker
767*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE0_EXT + i);
768*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_ERROR(GL_INVALID_ENUM);
769*8975f5c5SAndroid Build Coastguard Worker
770*8975f5c5SAndroid Build Coastguard Worker assertState(GL_CLIP_DISTANCE0_EXT + i, false, false);
771*8975f5c5SAndroid Build Coastguard Worker
772*8975f5c5SAndroid Build Coastguard Worker glDisable(GL_CLIP_DISTANCE0_EXT + i);
773*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_ERROR(GL_INVALID_ENUM);
774*8975f5c5SAndroid Build Coastguard Worker
775*8975f5c5SAndroid Build Coastguard Worker assertState(GL_CLIP_DISTANCE0_EXT + i, false, false);
776*8975f5c5SAndroid Build Coastguard Worker }
777*8975f5c5SAndroid Build Coastguard Worker
778*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled(kExtensionName));
779*8975f5c5SAndroid Build Coastguard Worker
780*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
781*8975f5c5SAndroid Build Coastguard Worker
782*8975f5c5SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_CLIP_DISTANCES_EXT, &maxClipDistances);
783*8975f5c5SAndroid Build Coastguard Worker EXPECT_GE(maxClipDistances, 8);
784*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
785*8975f5c5SAndroid Build Coastguard Worker
786*8975f5c5SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_CULL_DISTANCES_EXT, &maxCullDistances);
787*8975f5c5SAndroid Build Coastguard Worker if (mCullDistanceSupportRequired)
788*8975f5c5SAndroid Build Coastguard Worker {
789*8975f5c5SAndroid Build Coastguard Worker EXPECT_GE(maxCullDistances, 8);
790*8975f5c5SAndroid Build Coastguard Worker }
791*8975f5c5SAndroid Build Coastguard Worker else
792*8975f5c5SAndroid Build Coastguard Worker {
793*8975f5c5SAndroid Build Coastguard Worker EXPECT_TRUE(maxCullDistances == 0 || maxCullDistances >= 8);
794*8975f5c5SAndroid Build Coastguard Worker }
795*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
796*8975f5c5SAndroid Build Coastguard Worker
797*8975f5c5SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES_EXT, &maxCombinedClipAndCullDistances);
798*8975f5c5SAndroid Build Coastguard Worker if (mCullDistanceSupportRequired)
799*8975f5c5SAndroid Build Coastguard Worker {
800*8975f5c5SAndroid Build Coastguard Worker EXPECT_GE(maxCombinedClipAndCullDistances, 8);
801*8975f5c5SAndroid Build Coastguard Worker }
802*8975f5c5SAndroid Build Coastguard Worker else
803*8975f5c5SAndroid Build Coastguard Worker {
804*8975f5c5SAndroid Build Coastguard Worker EXPECT_TRUE(maxCombinedClipAndCullDistances == 0 || maxCombinedClipAndCullDistances >= 8);
805*8975f5c5SAndroid Build Coastguard Worker }
806*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
807*8975f5c5SAndroid Build Coastguard Worker
808*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < 8; i++)
809*8975f5c5SAndroid Build Coastguard Worker {
810*8975f5c5SAndroid Build Coastguard Worker assertState(GL_CLIP_DISTANCE0_EXT + i, true, false);
811*8975f5c5SAndroid Build Coastguard Worker
812*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE0_EXT + i);
813*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
814*8975f5c5SAndroid Build Coastguard Worker
815*8975f5c5SAndroid Build Coastguard Worker assertState(GL_CLIP_DISTANCE0_EXT + i, true, true);
816*8975f5c5SAndroid Build Coastguard Worker
817*8975f5c5SAndroid Build Coastguard Worker glDisable(GL_CLIP_DISTANCE0_EXT + i);
818*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
819*8975f5c5SAndroid Build Coastguard Worker
820*8975f5c5SAndroid Build Coastguard Worker assertState(GL_CLIP_DISTANCE0_EXT + i, true, false);
821*8975f5c5SAndroid Build Coastguard Worker }
822*8975f5c5SAndroid Build Coastguard Worker }
823*8975f5c5SAndroid Build Coastguard Worker
824*8975f5c5SAndroid Build Coastguard Worker // Check that gl_ClipDistance and gl_CullDistance sizes cannot be undefined
TEST_P(ClipCullDistanceTest,UndefinedArraySize)825*8975f5c5SAndroid Build Coastguard Worker TEST_P(ClipCullDistanceTest, UndefinedArraySize)
826*8975f5c5SAndroid Build Coastguard Worker {
827*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled(kExtensionName));
828*8975f5c5SAndroid Build Coastguard Worker
829*8975f5c5SAndroid Build Coastguard Worker std::string kVSClip = R"(#version 300 es
830*8975f5c5SAndroid Build Coastguard Worker #extension )" + kExtensionName +
831*8975f5c5SAndroid Build Coastguard Worker R"( : require
832*8975f5c5SAndroid Build Coastguard Worker
833*8975f5c5SAndroid Build Coastguard Worker void main()
834*8975f5c5SAndroid Build Coastguard Worker {
835*8975f5c5SAndroid Build Coastguard Worker gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
836*8975f5c5SAndroid Build Coastguard Worker for (int i = 0; i < gl_MaxClipDistances; i++)
837*8975f5c5SAndroid Build Coastguard Worker {
838*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[i] = gl_Position.w;
839*8975f5c5SAndroid Build Coastguard Worker }
840*8975f5c5SAndroid Build Coastguard Worker })";
841*8975f5c5SAndroid Build Coastguard Worker
842*8975f5c5SAndroid Build Coastguard Worker std::string kVSCull = R"(#version 300 es
843*8975f5c5SAndroid Build Coastguard Worker #extension )" + kExtensionName +
844*8975f5c5SAndroid Build Coastguard Worker R"( : require
845*8975f5c5SAndroid Build Coastguard Worker
846*8975f5c5SAndroid Build Coastguard Worker void main()
847*8975f5c5SAndroid Build Coastguard Worker {
848*8975f5c5SAndroid Build Coastguard Worker gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
849*8975f5c5SAndroid Build Coastguard Worker for (int i = 0; i < gl_MaxCullDistances; i++)
850*8975f5c5SAndroid Build Coastguard Worker {
851*8975f5c5SAndroid Build Coastguard Worker gl_CullDistance[i] = gl_Position.w;
852*8975f5c5SAndroid Build Coastguard Worker }
853*8975f5c5SAndroid Build Coastguard Worker })";
854*8975f5c5SAndroid Build Coastguard Worker
855*8975f5c5SAndroid Build Coastguard Worker for (auto vs : {kVSClip, kVSCull})
856*8975f5c5SAndroid Build Coastguard Worker {
857*8975f5c5SAndroid Build Coastguard Worker GLProgram prg;
858*8975f5c5SAndroid Build Coastguard Worker prg.makeRaster(vs.c_str(), essl1_shaders::fs::Red());
859*8975f5c5SAndroid Build Coastguard Worker EXPECT_FALSE(prg.valid());
860*8975f5c5SAndroid Build Coastguard Worker }
861*8975f5c5SAndroid Build Coastguard Worker }
862*8975f5c5SAndroid Build Coastguard Worker
863*8975f5c5SAndroid Build Coastguard Worker // Check that shaders with invalid or missing storage qualifiers are rejected
TEST_P(ClipCullDistanceTest,StorageQualifiers)864*8975f5c5SAndroid Build Coastguard Worker TEST_P(ClipCullDistanceTest, StorageQualifiers)
865*8975f5c5SAndroid Build Coastguard Worker {
866*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled(kExtensionName));
867*8975f5c5SAndroid Build Coastguard Worker
868*8975f5c5SAndroid Build Coastguard Worker std::stringstream vertexSource;
869*8975f5c5SAndroid Build Coastguard Worker auto vs = [this, &vertexSource](std::string name, std::string qualifier) {
870*8975f5c5SAndroid Build Coastguard Worker vertexSource.str(std::string());
871*8975f5c5SAndroid Build Coastguard Worker vertexSource.clear();
872*8975f5c5SAndroid Build Coastguard Worker vertexSource << "#version 300 es\n"
873*8975f5c5SAndroid Build Coastguard Worker << "#extension " << kExtensionName << " : require\n"
874*8975f5c5SAndroid Build Coastguard Worker << qualifier << " highp float " << name << "[1];\n"
875*8975f5c5SAndroid Build Coastguard Worker << "void main()\n"
876*8975f5c5SAndroid Build Coastguard Worker << "{\n"
877*8975f5c5SAndroid Build Coastguard Worker << " gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
878*8975f5c5SAndroid Build Coastguard Worker << " " << name << "[0] = 1.0;\n"
879*8975f5c5SAndroid Build Coastguard Worker << "}";
880*8975f5c5SAndroid Build Coastguard Worker };
881*8975f5c5SAndroid Build Coastguard Worker
882*8975f5c5SAndroid Build Coastguard Worker std::stringstream fragmentSource;
883*8975f5c5SAndroid Build Coastguard Worker auto fs = [this, &fragmentSource](std::string name, std::string qualifier) {
884*8975f5c5SAndroid Build Coastguard Worker fragmentSource.str(std::string());
885*8975f5c5SAndroid Build Coastguard Worker fragmentSource.clear();
886*8975f5c5SAndroid Build Coastguard Worker fragmentSource << "#version 300 es\n"
887*8975f5c5SAndroid Build Coastguard Worker << "#extension " << kExtensionName << " : require\n"
888*8975f5c5SAndroid Build Coastguard Worker << qualifier << " highp float " << name << "[1];\n"
889*8975f5c5SAndroid Build Coastguard Worker << "out highp vec4 my_FragColor;\n"
890*8975f5c5SAndroid Build Coastguard Worker << "void main()\n"
891*8975f5c5SAndroid Build Coastguard Worker << "{\n"
892*8975f5c5SAndroid Build Coastguard Worker << " my_FragColor = vec4(" << name << "[0], 0.0, 0.0, 1.0);\n"
893*8975f5c5SAndroid Build Coastguard Worker << "}";
894*8975f5c5SAndroid Build Coastguard Worker };
895*8975f5c5SAndroid Build Coastguard Worker
896*8975f5c5SAndroid Build Coastguard Worker auto checkProgram = [=, &vertexSource, &fragmentSource](std::string name,
897*8975f5c5SAndroid Build Coastguard Worker std::string qualifierVertex,
898*8975f5c5SAndroid Build Coastguard Worker std::string qualifierFragment) {
899*8975f5c5SAndroid Build Coastguard Worker GLProgram program;
900*8975f5c5SAndroid Build Coastguard Worker vs(name, qualifierVertex);
901*8975f5c5SAndroid Build Coastguard Worker fs(name, qualifierFragment);
902*8975f5c5SAndroid Build Coastguard Worker program.makeRaster(vertexSource.str().c_str(), fragmentSource.str().c_str());
903*8975f5c5SAndroid Build Coastguard Worker return program.valid();
904*8975f5c5SAndroid Build Coastguard Worker };
905*8975f5c5SAndroid Build Coastguard Worker
906*8975f5c5SAndroid Build Coastguard Worker GLint maxClipDistances = 0;
907*8975f5c5SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_CLIP_DISTANCES_EXT, &maxClipDistances);
908*8975f5c5SAndroid Build Coastguard Worker ASSERT_GT(maxClipDistances, 0);
909*8975f5c5SAndroid Build Coastguard Worker
910*8975f5c5SAndroid Build Coastguard Worker GLint maxCullDistances = 0;
911*8975f5c5SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_CULL_DISTANCES_EXT, &maxCullDistances);
912*8975f5c5SAndroid Build Coastguard Worker if (mCullDistanceSupportRequired)
913*8975f5c5SAndroid Build Coastguard Worker {
914*8975f5c5SAndroid Build Coastguard Worker ASSERT_GT(maxCullDistances, 0);
915*8975f5c5SAndroid Build Coastguard Worker }
916*8975f5c5SAndroid Build Coastguard Worker else
917*8975f5c5SAndroid Build Coastguard Worker {
918*8975f5c5SAndroid Build Coastguard Worker ASSERT_GE(maxCullDistances, 0);
919*8975f5c5SAndroid Build Coastguard Worker }
920*8975f5c5SAndroid Build Coastguard Worker
921*8975f5c5SAndroid Build Coastguard Worker std::pair<std::string, int> entries[2] = {{"gl_ClipDistance", maxClipDistances},
922*8975f5c5SAndroid Build Coastguard Worker {"gl_CullDistance", maxCullDistances}};
923*8975f5c5SAndroid Build Coastguard Worker for (auto entry : entries)
924*8975f5c5SAndroid Build Coastguard Worker {
925*8975f5c5SAndroid Build Coastguard Worker if (entry.second == 0)
926*8975f5c5SAndroid Build Coastguard Worker continue;
927*8975f5c5SAndroid Build Coastguard Worker
928*8975f5c5SAndroid Build Coastguard Worker EXPECT_TRUE(checkProgram(entry.first, "out", "in"));
929*8975f5c5SAndroid Build Coastguard Worker
930*8975f5c5SAndroid Build Coastguard Worker EXPECT_FALSE(checkProgram(entry.first, "", ""));
931*8975f5c5SAndroid Build Coastguard Worker EXPECT_FALSE(checkProgram(entry.first, "", "in"));
932*8975f5c5SAndroid Build Coastguard Worker EXPECT_FALSE(checkProgram(entry.first, "", "out"));
933*8975f5c5SAndroid Build Coastguard Worker EXPECT_FALSE(checkProgram(entry.first, "in", ""));
934*8975f5c5SAndroid Build Coastguard Worker EXPECT_FALSE(checkProgram(entry.first, "in", "in"));
935*8975f5c5SAndroid Build Coastguard Worker EXPECT_FALSE(checkProgram(entry.first, "in", "out"));
936*8975f5c5SAndroid Build Coastguard Worker EXPECT_FALSE(checkProgram(entry.first, "out", ""));
937*8975f5c5SAndroid Build Coastguard Worker EXPECT_FALSE(checkProgram(entry.first, "out", "out"));
938*8975f5c5SAndroid Build Coastguard Worker }
939*8975f5c5SAndroid Build Coastguard Worker }
940*8975f5c5SAndroid Build Coastguard Worker
941*8975f5c5SAndroid Build Coastguard Worker // Check that array sizes cannot be more than maximum
TEST_P(ClipCullDistanceTest,OutOfRangeArraySize)942*8975f5c5SAndroid Build Coastguard Worker TEST_P(ClipCullDistanceTest, OutOfRangeArraySize)
943*8975f5c5SAndroid Build Coastguard Worker {
944*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled(kExtensionName));
945*8975f5c5SAndroid Build Coastguard Worker
946*8975f5c5SAndroid Build Coastguard Worker auto test = [this](std::string name, int maxSize) {
947*8975f5c5SAndroid Build Coastguard Worker std::stringstream vsImplicit;
948*8975f5c5SAndroid Build Coastguard Worker vsImplicit << R"(#version 300 es
949*8975f5c5SAndroid Build Coastguard Worker #extension )"
950*8975f5c5SAndroid Build Coastguard Worker << kExtensionName << R"( : require
951*8975f5c5SAndroid Build Coastguard Worker void main()
952*8975f5c5SAndroid Build Coastguard Worker {
953*8975f5c5SAndroid Build Coastguard Worker gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
954*8975f5c5SAndroid Build Coastguard Worker )" << name << "["
955*8975f5c5SAndroid Build Coastguard Worker << maxSize << R"(] = gl_Position.w;
956*8975f5c5SAndroid Build Coastguard Worker })";
957*8975f5c5SAndroid Build Coastguard Worker
958*8975f5c5SAndroid Build Coastguard Worker std::stringstream vsRedeclared;
959*8975f5c5SAndroid Build Coastguard Worker vsRedeclared << R"(#version 300 es
960*8975f5c5SAndroid Build Coastguard Worker #extension )" << kExtensionName
961*8975f5c5SAndroid Build Coastguard Worker << R"( : require
962*8975f5c5SAndroid Build Coastguard Worker out highp float )" << name
963*8975f5c5SAndroid Build Coastguard Worker << "[" << (maxSize + 1) << R"(];
964*8975f5c5SAndroid Build Coastguard Worker void main()
965*8975f5c5SAndroid Build Coastguard Worker {
966*8975f5c5SAndroid Build Coastguard Worker gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
967*8975f5c5SAndroid Build Coastguard Worker )" << name << "[" << (maxSize ? maxSize - 1 : 0)
968*8975f5c5SAndroid Build Coastguard Worker << R"(] = gl_Position.w;
969*8975f5c5SAndroid Build Coastguard Worker })";
970*8975f5c5SAndroid Build Coastguard Worker
971*8975f5c5SAndroid Build Coastguard Worker std::stringstream vsRedeclaredInvalidIndex;
972*8975f5c5SAndroid Build Coastguard Worker vsRedeclaredInvalidIndex << R"(#version 300 es
973*8975f5c5SAndroid Build Coastguard Worker #extension )" << kExtensionName << R"( : require
974*8975f5c5SAndroid Build Coastguard Worker out highp float )" << name << "[" << (maxSize ? maxSize - 2 : 0)
975*8975f5c5SAndroid Build Coastguard Worker << R"(];
976*8975f5c5SAndroid Build Coastguard Worker void main()
977*8975f5c5SAndroid Build Coastguard Worker {
978*8975f5c5SAndroid Build Coastguard Worker gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
979*8975f5c5SAndroid Build Coastguard Worker )" << name << "[" << (maxSize ? maxSize - 1 : 0)
980*8975f5c5SAndroid Build Coastguard Worker << R"(] = gl_Position.w;
981*8975f5c5SAndroid Build Coastguard Worker })";
982*8975f5c5SAndroid Build Coastguard Worker
983*8975f5c5SAndroid Build Coastguard Worker for (auto stream : {&vsImplicit, &vsRedeclared, &vsRedeclaredInvalidIndex})
984*8975f5c5SAndroid Build Coastguard Worker {
985*8975f5c5SAndroid Build Coastguard Worker GLProgram prg;
986*8975f5c5SAndroid Build Coastguard Worker prg.makeRaster(stream->str().c_str(), essl1_shaders::fs::Red());
987*8975f5c5SAndroid Build Coastguard Worker EXPECT_FALSE(prg.valid());
988*8975f5c5SAndroid Build Coastguard Worker }
989*8975f5c5SAndroid Build Coastguard Worker };
990*8975f5c5SAndroid Build Coastguard Worker
991*8975f5c5SAndroid Build Coastguard Worker GLint maxClipDistances = 0;
992*8975f5c5SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_CLIP_DISTANCES_EXT, &maxClipDistances);
993*8975f5c5SAndroid Build Coastguard Worker ASSERT_GT(maxClipDistances, 0);
994*8975f5c5SAndroid Build Coastguard Worker
995*8975f5c5SAndroid Build Coastguard Worker GLint maxCullDistances = 0;
996*8975f5c5SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_CULL_DISTANCES_EXT, &maxCullDistances);
997*8975f5c5SAndroid Build Coastguard Worker if (mCullDistanceSupportRequired)
998*8975f5c5SAndroid Build Coastguard Worker {
999*8975f5c5SAndroid Build Coastguard Worker ASSERT_GT(maxCullDistances, 0);
1000*8975f5c5SAndroid Build Coastguard Worker }
1001*8975f5c5SAndroid Build Coastguard Worker else
1002*8975f5c5SAndroid Build Coastguard Worker {
1003*8975f5c5SAndroid Build Coastguard Worker ASSERT_GE(maxCullDistances, 0);
1004*8975f5c5SAndroid Build Coastguard Worker }
1005*8975f5c5SAndroid Build Coastguard Worker
1006*8975f5c5SAndroid Build Coastguard Worker test("gl_ClipDistance", maxClipDistances);
1007*8975f5c5SAndroid Build Coastguard Worker test("gl_CullDistance", maxCullDistances);
1008*8975f5c5SAndroid Build Coastguard Worker }
1009*8975f5c5SAndroid Build Coastguard Worker
1010*8975f5c5SAndroid Build Coastguard Worker // Check that shader validation enforces matching array sizes between shader stages
TEST_P(ClipCullDistanceTest,SizeCheck)1011*8975f5c5SAndroid Build Coastguard Worker TEST_P(ClipCullDistanceTest, SizeCheck)
1012*8975f5c5SAndroid Build Coastguard Worker {
1013*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled(kExtensionName));
1014*8975f5c5SAndroid Build Coastguard Worker
1015*8975f5c5SAndroid Build Coastguard Worker std::stringstream vertexSource;
1016*8975f5c5SAndroid Build Coastguard Worker auto vs = [this, &vertexSource](std::string name, bool declare, int size) {
1017*8975f5c5SAndroid Build Coastguard Worker vertexSource.str(std::string());
1018*8975f5c5SAndroid Build Coastguard Worker vertexSource.clear();
1019*8975f5c5SAndroid Build Coastguard Worker vertexSource << "#version 300 es\n";
1020*8975f5c5SAndroid Build Coastguard Worker vertexSource << "#extension " << kExtensionName << " : require\n";
1021*8975f5c5SAndroid Build Coastguard Worker if (declare)
1022*8975f5c5SAndroid Build Coastguard Worker {
1023*8975f5c5SAndroid Build Coastguard Worker ASSERT(size);
1024*8975f5c5SAndroid Build Coastguard Worker vertexSource << "out highp float " << name << "[" << size << "];\n";
1025*8975f5c5SAndroid Build Coastguard Worker }
1026*8975f5c5SAndroid Build Coastguard Worker vertexSource << "void main()\n";
1027*8975f5c5SAndroid Build Coastguard Worker vertexSource << "{\n";
1028*8975f5c5SAndroid Build Coastguard Worker vertexSource << " gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n";
1029*8975f5c5SAndroid Build Coastguard Worker if (size)
1030*8975f5c5SAndroid Build Coastguard Worker {
1031*8975f5c5SAndroid Build Coastguard Worker vertexSource << " " << name << "[" << (size - 1) << "] = 1.0;\n";
1032*8975f5c5SAndroid Build Coastguard Worker }
1033*8975f5c5SAndroid Build Coastguard Worker vertexSource << "}";
1034*8975f5c5SAndroid Build Coastguard Worker };
1035*8975f5c5SAndroid Build Coastguard Worker
1036*8975f5c5SAndroid Build Coastguard Worker std::stringstream fragmentSource;
1037*8975f5c5SAndroid Build Coastguard Worker auto fs = [this, &fragmentSource](std::string name, bool declare, int size) {
1038*8975f5c5SAndroid Build Coastguard Worker fragmentSource.str(std::string());
1039*8975f5c5SAndroid Build Coastguard Worker fragmentSource.clear();
1040*8975f5c5SAndroid Build Coastguard Worker fragmentSource << "#version 300 es\n";
1041*8975f5c5SAndroid Build Coastguard Worker fragmentSource << "#extension " << kExtensionName << " : require\n";
1042*8975f5c5SAndroid Build Coastguard Worker if (declare)
1043*8975f5c5SAndroid Build Coastguard Worker {
1044*8975f5c5SAndroid Build Coastguard Worker ASSERT(size);
1045*8975f5c5SAndroid Build Coastguard Worker fragmentSource << "in highp float " << name << "[" << size << "];\n";
1046*8975f5c5SAndroid Build Coastguard Worker }
1047*8975f5c5SAndroid Build Coastguard Worker fragmentSource << "out highp vec4 my_FragColor;\n"
1048*8975f5c5SAndroid Build Coastguard Worker << "void main()\n"
1049*8975f5c5SAndroid Build Coastguard Worker << "{\n"
1050*8975f5c5SAndroid Build Coastguard Worker << " my_FragColor = vec4(";
1051*8975f5c5SAndroid Build Coastguard Worker if (size)
1052*8975f5c5SAndroid Build Coastguard Worker {
1053*8975f5c5SAndroid Build Coastguard Worker fragmentSource << name << "[" << (size - 1) << "]";
1054*8975f5c5SAndroid Build Coastguard Worker }
1055*8975f5c5SAndroid Build Coastguard Worker else
1056*8975f5c5SAndroid Build Coastguard Worker {
1057*8975f5c5SAndroid Build Coastguard Worker fragmentSource << "1.0";
1058*8975f5c5SAndroid Build Coastguard Worker }
1059*8975f5c5SAndroid Build Coastguard Worker fragmentSource << ", 0.0, 0.0, 1.0);\n";
1060*8975f5c5SAndroid Build Coastguard Worker fragmentSource << "}\n";
1061*8975f5c5SAndroid Build Coastguard Worker };
1062*8975f5c5SAndroid Build Coastguard Worker
1063*8975f5c5SAndroid Build Coastguard Worker auto checkProgram = [=, &vertexSource, &fragmentSource](std::string name, bool declareVertex,
1064*8975f5c5SAndroid Build Coastguard Worker int sizeVertex, bool declareFragment,
1065*8975f5c5SAndroid Build Coastguard Worker int sizeFragment) {
1066*8975f5c5SAndroid Build Coastguard Worker GLProgram program;
1067*8975f5c5SAndroid Build Coastguard Worker vs(name, declareVertex, sizeVertex);
1068*8975f5c5SAndroid Build Coastguard Worker fs(name, declareFragment, sizeFragment);
1069*8975f5c5SAndroid Build Coastguard Worker program.makeRaster(vertexSource.str().c_str(), fragmentSource.str().c_str());
1070*8975f5c5SAndroid Build Coastguard Worker return program.valid();
1071*8975f5c5SAndroid Build Coastguard Worker };
1072*8975f5c5SAndroid Build Coastguard Worker
1073*8975f5c5SAndroid Build Coastguard Worker GLint maxClipDistances = 0;
1074*8975f5c5SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_CLIP_DISTANCES_EXT, &maxClipDistances);
1075*8975f5c5SAndroid Build Coastguard Worker ASSERT_GT(maxClipDistances, 0);
1076*8975f5c5SAndroid Build Coastguard Worker
1077*8975f5c5SAndroid Build Coastguard Worker GLint maxCullDistances = 0;
1078*8975f5c5SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_CULL_DISTANCES_EXT, &maxCullDistances);
1079*8975f5c5SAndroid Build Coastguard Worker if (mCullDistanceSupportRequired)
1080*8975f5c5SAndroid Build Coastguard Worker {
1081*8975f5c5SAndroid Build Coastguard Worker ASSERT_GT(maxCullDistances, 0);
1082*8975f5c5SAndroid Build Coastguard Worker }
1083*8975f5c5SAndroid Build Coastguard Worker else
1084*8975f5c5SAndroid Build Coastguard Worker {
1085*8975f5c5SAndroid Build Coastguard Worker ASSERT_GE(maxCullDistances, 0);
1086*8975f5c5SAndroid Build Coastguard Worker }
1087*8975f5c5SAndroid Build Coastguard Worker
1088*8975f5c5SAndroid Build Coastguard Worker std::pair<std::string, int> entries[2] = {{"gl_ClipDistance", maxClipDistances},
1089*8975f5c5SAndroid Build Coastguard Worker {"gl_CullDistance", maxCullDistances}};
1090*8975f5c5SAndroid Build Coastguard Worker for (auto entry : entries)
1091*8975f5c5SAndroid Build Coastguard Worker {
1092*8975f5c5SAndroid Build Coastguard Worker const std::string name = entry.first;
1093*8975f5c5SAndroid Build Coastguard Worker const int maxSize = entry.second;
1094*8975f5c5SAndroid Build Coastguard Worker
1095*8975f5c5SAndroid Build Coastguard Worker // Any VS array size is valid when the value is not accessed in the fragment shader
1096*8975f5c5SAndroid Build Coastguard Worker for (int i = 1; i <= maxSize; i++)
1097*8975f5c5SAndroid Build Coastguard Worker {
1098*8975f5c5SAndroid Build Coastguard Worker EXPECT_TRUE(checkProgram(name, false, i, false, 0));
1099*8975f5c5SAndroid Build Coastguard Worker EXPECT_TRUE(checkProgram(name, true, i, false, 0));
1100*8975f5c5SAndroid Build Coastguard Worker }
1101*8975f5c5SAndroid Build Coastguard Worker
1102*8975f5c5SAndroid Build Coastguard Worker // Any FS array size is invalid when the value is not written in the vertex shader
1103*8975f5c5SAndroid Build Coastguard Worker for (int i = 1; i <= maxSize; i++)
1104*8975f5c5SAndroid Build Coastguard Worker {
1105*8975f5c5SAndroid Build Coastguard Worker EXPECT_FALSE(checkProgram(name, false, 0, false, i));
1106*8975f5c5SAndroid Build Coastguard Worker EXPECT_FALSE(checkProgram(name, false, 0, true, i));
1107*8975f5c5SAndroid Build Coastguard Worker }
1108*8975f5c5SAndroid Build Coastguard Worker
1109*8975f5c5SAndroid Build Coastguard Worker // Matching sizes are valid both for redeclared and implicitly sized arrays
1110*8975f5c5SAndroid Build Coastguard Worker for (int i = 1; i <= maxSize; i++)
1111*8975f5c5SAndroid Build Coastguard Worker {
1112*8975f5c5SAndroid Build Coastguard Worker EXPECT_TRUE(checkProgram(name, false, i, false, i));
1113*8975f5c5SAndroid Build Coastguard Worker EXPECT_TRUE(checkProgram(name, false, i, true, i));
1114*8975f5c5SAndroid Build Coastguard Worker EXPECT_TRUE(checkProgram(name, true, i, false, i));
1115*8975f5c5SAndroid Build Coastguard Worker EXPECT_TRUE(checkProgram(name, true, i, true, i));
1116*8975f5c5SAndroid Build Coastguard Worker }
1117*8975f5c5SAndroid Build Coastguard Worker
1118*8975f5c5SAndroid Build Coastguard Worker // Non-matching sizes are invalid both for redeclared and implicitly sized arrays
1119*8975f5c5SAndroid Build Coastguard Worker for (int i = 2; i <= maxSize; i++)
1120*8975f5c5SAndroid Build Coastguard Worker {
1121*8975f5c5SAndroid Build Coastguard Worker EXPECT_FALSE(checkProgram(name, false, i - 1, false, i));
1122*8975f5c5SAndroid Build Coastguard Worker EXPECT_FALSE(checkProgram(name, false, i - 1, true, i));
1123*8975f5c5SAndroid Build Coastguard Worker EXPECT_FALSE(checkProgram(name, true, i - 1, false, i));
1124*8975f5c5SAndroid Build Coastguard Worker EXPECT_FALSE(checkProgram(name, true, i - 1, true, i));
1125*8975f5c5SAndroid Build Coastguard Worker
1126*8975f5c5SAndroid Build Coastguard Worker EXPECT_FALSE(checkProgram(name, false, i, false, i - 1));
1127*8975f5c5SAndroid Build Coastguard Worker EXPECT_FALSE(checkProgram(name, false, i, true, i - 1));
1128*8975f5c5SAndroid Build Coastguard Worker EXPECT_FALSE(checkProgram(name, true, i, false, i - 1));
1129*8975f5c5SAndroid Build Coastguard Worker EXPECT_FALSE(checkProgram(name, true, i, true, i - 1));
1130*8975f5c5SAndroid Build Coastguard Worker }
1131*8975f5c5SAndroid Build Coastguard Worker
1132*8975f5c5SAndroid Build Coastguard Worker // Out-of-range sizes are invalid
1133*8975f5c5SAndroid Build Coastguard Worker {
1134*8975f5c5SAndroid Build Coastguard Worker EXPECT_FALSE(checkProgram(name, false, 0, false, maxSize + 1));
1135*8975f5c5SAndroid Build Coastguard Worker EXPECT_FALSE(checkProgram(name, false, maxSize + 1, false, 0));
1136*8975f5c5SAndroid Build Coastguard Worker EXPECT_FALSE(checkProgram(name, false, maxSize + 1, false, maxSize + 1));
1137*8975f5c5SAndroid Build Coastguard Worker EXPECT_FALSE(checkProgram(name, false, 0, true, maxSize + 1));
1138*8975f5c5SAndroid Build Coastguard Worker EXPECT_FALSE(checkProgram(name, false, maxSize + 1, true, maxSize + 1));
1139*8975f5c5SAndroid Build Coastguard Worker EXPECT_FALSE(checkProgram(name, true, maxSize + 1, false, 0));
1140*8975f5c5SAndroid Build Coastguard Worker EXPECT_FALSE(checkProgram(name, true, maxSize + 1, false, maxSize + 1));
1141*8975f5c5SAndroid Build Coastguard Worker EXPECT_FALSE(checkProgram(name, true, maxSize + 1, true, maxSize + 1));
1142*8975f5c5SAndroid Build Coastguard Worker }
1143*8975f5c5SAndroid Build Coastguard Worker }
1144*8975f5c5SAndroid Build Coastguard Worker }
1145*8975f5c5SAndroid Build Coastguard Worker
1146*8975f5c5SAndroid Build Coastguard Worker // Check that the sum of clip and cull distance array sizes is valid
TEST_P(ClipCullDistanceTest,SizeCheckCombined)1147*8975f5c5SAndroid Build Coastguard Worker TEST_P(ClipCullDistanceTest, SizeCheckCombined)
1148*8975f5c5SAndroid Build Coastguard Worker {
1149*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled(kExtensionName));
1150*8975f5c5SAndroid Build Coastguard Worker
1151*8975f5c5SAndroid Build Coastguard Worker std::stringstream vertexSource;
1152*8975f5c5SAndroid Build Coastguard Worker auto vs = [this, &vertexSource](bool declareClip, int sizeClip, bool declareCull,
1153*8975f5c5SAndroid Build Coastguard Worker int sizeCull) {
1154*8975f5c5SAndroid Build Coastguard Worker vertexSource.str(std::string());
1155*8975f5c5SAndroid Build Coastguard Worker vertexSource.clear();
1156*8975f5c5SAndroid Build Coastguard Worker vertexSource << "#version 300 es\n";
1157*8975f5c5SAndroid Build Coastguard Worker vertexSource << "#extension " << kExtensionName << " : require\n";
1158*8975f5c5SAndroid Build Coastguard Worker if (declareClip)
1159*8975f5c5SAndroid Build Coastguard Worker {
1160*8975f5c5SAndroid Build Coastguard Worker ASSERT(sizeClip);
1161*8975f5c5SAndroid Build Coastguard Worker vertexSource << "out highp float gl_ClipDistance[" << sizeClip << "];\n";
1162*8975f5c5SAndroid Build Coastguard Worker }
1163*8975f5c5SAndroid Build Coastguard Worker if (declareCull)
1164*8975f5c5SAndroid Build Coastguard Worker {
1165*8975f5c5SAndroid Build Coastguard Worker ASSERT(sizeCull);
1166*8975f5c5SAndroid Build Coastguard Worker vertexSource << "out highp float gl_CullDistance[" << sizeCull << "];\n";
1167*8975f5c5SAndroid Build Coastguard Worker }
1168*8975f5c5SAndroid Build Coastguard Worker vertexSource << "void main()\n"
1169*8975f5c5SAndroid Build Coastguard Worker << "{\n"
1170*8975f5c5SAndroid Build Coastguard Worker << " gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
1171*8975f5c5SAndroid Build Coastguard Worker << " gl_ClipDistance[" << (sizeClip - 1) << "] = 1.0;\n"
1172*8975f5c5SAndroid Build Coastguard Worker << " gl_CullDistance[" << (sizeCull - 1) << "] = 1.0;\n"
1173*8975f5c5SAndroid Build Coastguard Worker << "}";
1174*8975f5c5SAndroid Build Coastguard Worker };
1175*8975f5c5SAndroid Build Coastguard Worker
1176*8975f5c5SAndroid Build Coastguard Worker std::stringstream fragmentSource;
1177*8975f5c5SAndroid Build Coastguard Worker auto fs = [this, &fragmentSource](bool declareClip, int sizeClip, bool declareCull,
1178*8975f5c5SAndroid Build Coastguard Worker int sizeCull) {
1179*8975f5c5SAndroid Build Coastguard Worker fragmentSource.str(std::string());
1180*8975f5c5SAndroid Build Coastguard Worker fragmentSource.clear();
1181*8975f5c5SAndroid Build Coastguard Worker fragmentSource << "#version 300 es\n";
1182*8975f5c5SAndroid Build Coastguard Worker fragmentSource << "#extension " << kExtensionName << " : require\n";
1183*8975f5c5SAndroid Build Coastguard Worker if (declareClip)
1184*8975f5c5SAndroid Build Coastguard Worker {
1185*8975f5c5SAndroid Build Coastguard Worker ASSERT(sizeClip);
1186*8975f5c5SAndroid Build Coastguard Worker fragmentSource << "in highp float gl_ClipDistance[" << sizeClip << "];\n";
1187*8975f5c5SAndroid Build Coastguard Worker }
1188*8975f5c5SAndroid Build Coastguard Worker if (declareCull)
1189*8975f5c5SAndroid Build Coastguard Worker {
1190*8975f5c5SAndroid Build Coastguard Worker ASSERT(sizeClip);
1191*8975f5c5SAndroid Build Coastguard Worker fragmentSource << "in highp float gl_CullDistance[" << sizeCull << "];\n";
1192*8975f5c5SAndroid Build Coastguard Worker }
1193*8975f5c5SAndroid Build Coastguard Worker fragmentSource << "out highp vec4 my_FragColor;\n"
1194*8975f5c5SAndroid Build Coastguard Worker << "void main()\n"
1195*8975f5c5SAndroid Build Coastguard Worker << "{\n"
1196*8975f5c5SAndroid Build Coastguard Worker << " my_FragColor = vec4(\n"
1197*8975f5c5SAndroid Build Coastguard Worker << " gl_ClipDistance[" << (sizeClip - 1) << "],\n"
1198*8975f5c5SAndroid Build Coastguard Worker << " gl_CullDistance[" << (sizeCull - 1) << "],\n"
1199*8975f5c5SAndroid Build Coastguard Worker << " 0.0, 1.0);\n"
1200*8975f5c5SAndroid Build Coastguard Worker << "}\n";
1201*8975f5c5SAndroid Build Coastguard Worker };
1202*8975f5c5SAndroid Build Coastguard Worker
1203*8975f5c5SAndroid Build Coastguard Worker auto checkProgram = [=, &vertexSource, &fragmentSource](
1204*8975f5c5SAndroid Build Coastguard Worker bool declareVertexClip, bool declareFragmentClip, int sizeClip,
1205*8975f5c5SAndroid Build Coastguard Worker bool declareVertexCull, bool declareFragmentCull, int sizeCull) {
1206*8975f5c5SAndroid Build Coastguard Worker GLProgram program;
1207*8975f5c5SAndroid Build Coastguard Worker vs(declareVertexClip, sizeClip, declareVertexCull, sizeCull);
1208*8975f5c5SAndroid Build Coastguard Worker fs(declareVertexClip, sizeClip, declareVertexCull, sizeCull);
1209*8975f5c5SAndroid Build Coastguard Worker program.makeRaster(vertexSource.str().c_str(), fragmentSource.str().c_str());
1210*8975f5c5SAndroid Build Coastguard Worker return program.valid();
1211*8975f5c5SAndroid Build Coastguard Worker };
1212*8975f5c5SAndroid Build Coastguard Worker
1213*8975f5c5SAndroid Build Coastguard Worker GLint maxClipDistances = 0;
1214*8975f5c5SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_CLIP_DISTANCES_EXT, &maxClipDistances);
1215*8975f5c5SAndroid Build Coastguard Worker ASSERT_GT(maxClipDistances, 0);
1216*8975f5c5SAndroid Build Coastguard Worker
1217*8975f5c5SAndroid Build Coastguard Worker GLint maxCullDistances = 0;
1218*8975f5c5SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_CULL_DISTANCES_EXT, &maxCullDistances);
1219*8975f5c5SAndroid Build Coastguard Worker if (mCullDistanceSupportRequired)
1220*8975f5c5SAndroid Build Coastguard Worker {
1221*8975f5c5SAndroid Build Coastguard Worker ASSERT_GT(maxCullDistances, 0);
1222*8975f5c5SAndroid Build Coastguard Worker }
1223*8975f5c5SAndroid Build Coastguard Worker else
1224*8975f5c5SAndroid Build Coastguard Worker {
1225*8975f5c5SAndroid Build Coastguard Worker ASSERT_GE(maxCullDistances, 0);
1226*8975f5c5SAndroid Build Coastguard Worker }
1227*8975f5c5SAndroid Build Coastguard Worker
1228*8975f5c5SAndroid Build Coastguard Worker GLint maxCombinedClipAndCullDistances = 0;
1229*8975f5c5SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES_EXT, &maxCombinedClipAndCullDistances);
1230*8975f5c5SAndroid Build Coastguard Worker if (mCullDistanceSupportRequired)
1231*8975f5c5SAndroid Build Coastguard Worker {
1232*8975f5c5SAndroid Build Coastguard Worker ASSERT_GT(maxCombinedClipAndCullDistances, 0);
1233*8975f5c5SAndroid Build Coastguard Worker }
1234*8975f5c5SAndroid Build Coastguard Worker else
1235*8975f5c5SAndroid Build Coastguard Worker {
1236*8975f5c5SAndroid Build Coastguard Worker ASSERT_GE(maxCombinedClipAndCullDistances, 0);
1237*8975f5c5SAndroid Build Coastguard Worker }
1238*8975f5c5SAndroid Build Coastguard Worker
1239*8975f5c5SAndroid Build Coastguard Worker for (int sizeClip = 1; sizeClip <= maxClipDistances; sizeClip++)
1240*8975f5c5SAndroid Build Coastguard Worker {
1241*8975f5c5SAndroid Build Coastguard Worker for (int sizeCull = 1; sizeCull <= maxCullDistances; sizeCull++)
1242*8975f5c5SAndroid Build Coastguard Worker {
1243*8975f5c5SAndroid Build Coastguard Worker // clang-format off
1244*8975f5c5SAndroid Build Coastguard Worker const bool valid = sizeClip + sizeCull <= maxCombinedClipAndCullDistances;
1245*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(checkProgram(false, false, sizeClip, false, false, sizeCull), valid);
1246*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(checkProgram(false, false, sizeClip, false, true, sizeCull), valid);
1247*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(checkProgram(false, false, sizeClip, true, false, sizeCull), valid);
1248*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(checkProgram(false, false, sizeClip, true, true, sizeCull), valid);
1249*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(checkProgram(false, true, sizeClip, false, false, sizeCull), valid);
1250*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(checkProgram(false, true, sizeClip, false, true, sizeCull), valid);
1251*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(checkProgram(false, true, sizeClip, true, false, sizeCull), valid);
1252*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(checkProgram(false, true, sizeClip, true, true, sizeCull), valid);
1253*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(checkProgram(true, false, sizeClip, false, false, sizeCull), valid);
1254*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(checkProgram(true, false, sizeClip, false, true, sizeCull), valid);
1255*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(checkProgram(true, false, sizeClip, true, false, sizeCull), valid);
1256*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(checkProgram(true, false, sizeClip, true, true, sizeCull), valid);
1257*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(checkProgram(true, true, sizeClip, false, false, sizeCull), valid);
1258*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(checkProgram(true, true, sizeClip, false, true, sizeCull), valid);
1259*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(checkProgram(true, true, sizeClip, true, false, sizeCull), valid);
1260*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(checkProgram(true, true, sizeClip, true, true, sizeCull), valid);
1261*8975f5c5SAndroid Build Coastguard Worker // clang-format on
1262*8975f5c5SAndroid Build Coastguard Worker }
1263*8975f5c5SAndroid Build Coastguard Worker }
1264*8975f5c5SAndroid Build Coastguard Worker }
1265*8975f5c5SAndroid Build Coastguard Worker
1266*8975f5c5SAndroid Build Coastguard Worker // Test that declared but unused built-ins do not cause frontend failures. The internal uniform,
1267*8975f5c5SAndroid Build Coastguard Worker // which is used for passing GL state on some platforms, could be removed when built-ins are not
1268*8975f5c5SAndroid Build Coastguard Worker // accessed.
TEST_P(ClipCullDistanceTest,Unused)1269*8975f5c5SAndroid Build Coastguard Worker TEST_P(ClipCullDistanceTest, Unused)
1270*8975f5c5SAndroid Build Coastguard Worker {
1271*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled(kExtensionName));
1272*8975f5c5SAndroid Build Coastguard Worker
1273*8975f5c5SAndroid Build Coastguard Worker std::stringstream vertexSource;
1274*8975f5c5SAndroid Build Coastguard Worker auto vs = [this, &vertexSource](std::string name) {
1275*8975f5c5SAndroid Build Coastguard Worker vertexSource.str(std::string());
1276*8975f5c5SAndroid Build Coastguard Worker vertexSource.clear();
1277*8975f5c5SAndroid Build Coastguard Worker vertexSource << "#version 300 es\n"
1278*8975f5c5SAndroid Build Coastguard Worker << "#extension " << kExtensionName << " : require\n"
1279*8975f5c5SAndroid Build Coastguard Worker << "out highp float " << name << "[8];\n"
1280*8975f5c5SAndroid Build Coastguard Worker << "void main() { gl_Position = vec4(0.0, 0.0, 0.0, 1.0); }";
1281*8975f5c5SAndroid Build Coastguard Worker };
1282*8975f5c5SAndroid Build Coastguard Worker
1283*8975f5c5SAndroid Build Coastguard Worker std::stringstream fragmentSource;
1284*8975f5c5SAndroid Build Coastguard Worker auto fs = [this, &fragmentSource](std::string name, bool declare) {
1285*8975f5c5SAndroid Build Coastguard Worker fragmentSource.str(std::string());
1286*8975f5c5SAndroid Build Coastguard Worker fragmentSource.clear();
1287*8975f5c5SAndroid Build Coastguard Worker fragmentSource << "#version 300 es\n";
1288*8975f5c5SAndroid Build Coastguard Worker fragmentSource << "#extension " << kExtensionName << " : require\n";
1289*8975f5c5SAndroid Build Coastguard Worker if (declare)
1290*8975f5c5SAndroid Build Coastguard Worker {
1291*8975f5c5SAndroid Build Coastguard Worker fragmentSource << "in highp float " << name << "[8];\n";
1292*8975f5c5SAndroid Build Coastguard Worker }
1293*8975f5c5SAndroid Build Coastguard Worker fragmentSource << "out highp vec4 my_FragColor;\n"
1294*8975f5c5SAndroid Build Coastguard Worker << "void main() { my_FragColor = vec4(1.0, 0.0, 0.0, 1.0); }\n";
1295*8975f5c5SAndroid Build Coastguard Worker };
1296*8975f5c5SAndroid Build Coastguard Worker
1297*8975f5c5SAndroid Build Coastguard Worker auto checkProgram = [=, &vertexSource, &fragmentSource](std::string name,
1298*8975f5c5SAndroid Build Coastguard Worker bool declareFragment) {
1299*8975f5c5SAndroid Build Coastguard Worker GLProgram program;
1300*8975f5c5SAndroid Build Coastguard Worker vs(name);
1301*8975f5c5SAndroid Build Coastguard Worker fs(name, declareFragment);
1302*8975f5c5SAndroid Build Coastguard Worker program.makeRaster(vertexSource.str().c_str(), fragmentSource.str().c_str());
1303*8975f5c5SAndroid Build Coastguard Worker return program.valid();
1304*8975f5c5SAndroid Build Coastguard Worker };
1305*8975f5c5SAndroid Build Coastguard Worker
1306*8975f5c5SAndroid Build Coastguard Worker GLint maxClipDistances = 0;
1307*8975f5c5SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_CLIP_DISTANCES_EXT, &maxClipDistances);
1308*8975f5c5SAndroid Build Coastguard Worker ASSERT_GT(maxClipDistances, 0);
1309*8975f5c5SAndroid Build Coastguard Worker
1310*8975f5c5SAndroid Build Coastguard Worker GLint maxCullDistances = 0;
1311*8975f5c5SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_CULL_DISTANCES_EXT, &maxCullDistances);
1312*8975f5c5SAndroid Build Coastguard Worker if (mCullDistanceSupportRequired)
1313*8975f5c5SAndroid Build Coastguard Worker {
1314*8975f5c5SAndroid Build Coastguard Worker ASSERT_GT(maxCullDistances, 0);
1315*8975f5c5SAndroid Build Coastguard Worker }
1316*8975f5c5SAndroid Build Coastguard Worker else
1317*8975f5c5SAndroid Build Coastguard Worker {
1318*8975f5c5SAndroid Build Coastguard Worker ASSERT_GE(maxCullDistances, 0);
1319*8975f5c5SAndroid Build Coastguard Worker }
1320*8975f5c5SAndroid Build Coastguard Worker
1321*8975f5c5SAndroid Build Coastguard Worker std::pair<std::string, int> entries[2] = {{"gl_ClipDistance", maxClipDistances},
1322*8975f5c5SAndroid Build Coastguard Worker {"gl_CullDistance", maxCullDistances}};
1323*8975f5c5SAndroid Build Coastguard Worker for (auto entry : entries)
1324*8975f5c5SAndroid Build Coastguard Worker {
1325*8975f5c5SAndroid Build Coastguard Worker if (entry.second == 0)
1326*8975f5c5SAndroid Build Coastguard Worker continue;
1327*8975f5c5SAndroid Build Coastguard Worker
1328*8975f5c5SAndroid Build Coastguard Worker EXPECT_TRUE(checkProgram(entry.first, false));
1329*8975f5c5SAndroid Build Coastguard Worker EXPECT_TRUE(checkProgram(entry.first, true));
1330*8975f5c5SAndroid Build Coastguard Worker }
1331*8975f5c5SAndroid Build Coastguard Worker }
1332*8975f5c5SAndroid Build Coastguard Worker
1333*8975f5c5SAndroid Build Coastguard Worker // Test that unused gl_ClipDistance does not cause a translator crash
TEST_P(ClipCullDistanceTest,UnusedVertexVaryingNoCrash)1334*8975f5c5SAndroid Build Coastguard Worker TEST_P(ClipCullDistanceTest, UnusedVertexVaryingNoCrash)
1335*8975f5c5SAndroid Build Coastguard Worker {
1336*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled(kExtensionName));
1337*8975f5c5SAndroid Build Coastguard Worker
1338*8975f5c5SAndroid Build Coastguard Worker std::string kVS = R"(#version 300 es
1339*8975f5c5SAndroid Build Coastguard Worker #extension )" + kExtensionName +
1340*8975f5c5SAndroid Build Coastguard Worker R"( : require
1341*8975f5c5SAndroid Build Coastguard Worker precision highp float;
1342*8975f5c5SAndroid Build Coastguard Worker void main()
1343*8975f5c5SAndroid Build Coastguard Worker {
1344*8975f5c5SAndroid Build Coastguard Worker float r = gl_ClipDistance[1] + 0.5;
1345*8975f5c5SAndroid Build Coastguard Worker })";
1346*8975f5c5SAndroid Build Coastguard Worker
1347*8975f5c5SAndroid Build Coastguard Worker GLProgram prg;
1348*8975f5c5SAndroid Build Coastguard Worker prg.makeRaster(kVS.c_str(), essl3_shaders::fs::Red());
1349*8975f5c5SAndroid Build Coastguard Worker
1350*8975f5c5SAndroid Build Coastguard Worker EXPECT_TRUE(prg.valid());
1351*8975f5c5SAndroid Build Coastguard Worker }
1352*8975f5c5SAndroid Build Coastguard Worker
1353*8975f5c5SAndroid Build Coastguard Worker // Test that unused gl_ClipDistance does not cause a translator crash
TEST_P(ClipCullDistanceTest,UnusedFragmentVaryingNoCrash)1354*8975f5c5SAndroid Build Coastguard Worker TEST_P(ClipCullDistanceTest, UnusedFragmentVaryingNoCrash)
1355*8975f5c5SAndroid Build Coastguard Worker {
1356*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled(kExtensionName));
1357*8975f5c5SAndroid Build Coastguard Worker
1358*8975f5c5SAndroid Build Coastguard Worker std::string kFS = R"(#version 300 es
1359*8975f5c5SAndroid Build Coastguard Worker #extension )" + kExtensionName +
1360*8975f5c5SAndroid Build Coastguard Worker R"( : require
1361*8975f5c5SAndroid Build Coastguard Worker precision highp float;
1362*8975f5c5SAndroid Build Coastguard Worker out vec4 my_FragColor;
1363*8975f5c5SAndroid Build Coastguard Worker void main()
1364*8975f5c5SAndroid Build Coastguard Worker {
1365*8975f5c5SAndroid Build Coastguard Worker float r = gl_ClipDistance[1] + 0.5;
1366*8975f5c5SAndroid Build Coastguard Worker })";
1367*8975f5c5SAndroid Build Coastguard Worker
1368*8975f5c5SAndroid Build Coastguard Worker GLProgram prg;
1369*8975f5c5SAndroid Build Coastguard Worker prg.makeRaster(essl3_shaders::vs::Simple(), kFS.c_str());
1370*8975f5c5SAndroid Build Coastguard Worker
1371*8975f5c5SAndroid Build Coastguard Worker EXPECT_FALSE(prg.valid());
1372*8975f5c5SAndroid Build Coastguard Worker }
1373*8975f5c5SAndroid Build Coastguard Worker
1374*8975f5c5SAndroid Build Coastguard Worker // Test that length() does not compile for unsized arrays
TEST_P(ClipCullDistanceTest,UnsizedArrayLength)1375*8975f5c5SAndroid Build Coastguard Worker TEST_P(ClipCullDistanceTest, UnsizedArrayLength)
1376*8975f5c5SAndroid Build Coastguard Worker {
1377*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled(kExtensionName));
1378*8975f5c5SAndroid Build Coastguard Worker
1379*8975f5c5SAndroid Build Coastguard Worker for (std::string name : {"gl_ClipDistance", "gl_CullDistance"})
1380*8975f5c5SAndroid Build Coastguard Worker {
1381*8975f5c5SAndroid Build Coastguard Worker std::stringstream vertexSource;
1382*8975f5c5SAndroid Build Coastguard Worker vertexSource << "#version 300 es\n"
1383*8975f5c5SAndroid Build Coastguard Worker << "#extension " << kExtensionName << " : require\n"
1384*8975f5c5SAndroid Build Coastguard Worker << "void main() { " << name << ".length(); }";
1385*8975f5c5SAndroid Build Coastguard Worker
1386*8975f5c5SAndroid Build Coastguard Worker GLProgram program;
1387*8975f5c5SAndroid Build Coastguard Worker program.makeRaster(vertexSource.str().c_str(), essl3_shaders::fs::Red());
1388*8975f5c5SAndroid Build Coastguard Worker EXPECT_FALSE(program.valid()) << name;
1389*8975f5c5SAndroid Build Coastguard Worker }
1390*8975f5c5SAndroid Build Coastguard Worker }
1391*8975f5c5SAndroid Build Coastguard Worker
1392*8975f5c5SAndroid Build Coastguard Worker // Test that length() returns correct values for sized arrays
TEST_P(ClipCullDistanceTest,SizedArrayLength)1393*8975f5c5SAndroid Build Coastguard Worker TEST_P(ClipCullDistanceTest, SizedArrayLength)
1394*8975f5c5SAndroid Build Coastguard Worker {
1395*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled(kExtensionName));
1396*8975f5c5SAndroid Build Coastguard Worker
1397*8975f5c5SAndroid Build Coastguard Worker std::stringstream vertexSource;
1398*8975f5c5SAndroid Build Coastguard Worker auto vs = [this, &vertexSource](std::string name, bool declare, int size) {
1399*8975f5c5SAndroid Build Coastguard Worker vertexSource.str(std::string());
1400*8975f5c5SAndroid Build Coastguard Worker vertexSource.clear();
1401*8975f5c5SAndroid Build Coastguard Worker vertexSource << "#version 300 es\n";
1402*8975f5c5SAndroid Build Coastguard Worker vertexSource << "#extension " << kExtensionName << " : require\n";
1403*8975f5c5SAndroid Build Coastguard Worker if (declare)
1404*8975f5c5SAndroid Build Coastguard Worker {
1405*8975f5c5SAndroid Build Coastguard Worker vertexSource << "out highp float " << name << "[" << size << "];\n";
1406*8975f5c5SAndroid Build Coastguard Worker }
1407*8975f5c5SAndroid Build Coastguard Worker vertexSource << "in vec4 a_position;\n"
1408*8975f5c5SAndroid Build Coastguard Worker << "out float v_length;\n"
1409*8975f5c5SAndroid Build Coastguard Worker << "void main()\n"
1410*8975f5c5SAndroid Build Coastguard Worker << "{\n"
1411*8975f5c5SAndroid Build Coastguard Worker << " gl_Position = a_position;\n"
1412*8975f5c5SAndroid Build Coastguard Worker << " v_length = float(" << name << ".length()) / 16.0;\n";
1413*8975f5c5SAndroid Build Coastguard Worker // Assign all elements to avoid undefined behavior
1414*8975f5c5SAndroid Build Coastguard Worker for (int i = 0; i < size; ++i)
1415*8975f5c5SAndroid Build Coastguard Worker {
1416*8975f5c5SAndroid Build Coastguard Worker vertexSource << " " << name << "[" << i << "] = 1.0;\n";
1417*8975f5c5SAndroid Build Coastguard Worker }
1418*8975f5c5SAndroid Build Coastguard Worker vertexSource << "}";
1419*8975f5c5SAndroid Build Coastguard Worker };
1420*8975f5c5SAndroid Build Coastguard Worker
1421*8975f5c5SAndroid Build Coastguard Worker std::string kFS = R"(#version 300 es
1422*8975f5c5SAndroid Build Coastguard Worker #extension )" + kExtensionName +
1423*8975f5c5SAndroid Build Coastguard Worker R"( : require
1424*8975f5c5SAndroid Build Coastguard Worker in mediump float v_length;
1425*8975f5c5SAndroid Build Coastguard Worker out mediump vec4 my_FragColor;
1426*8975f5c5SAndroid Build Coastguard Worker void main()
1427*8975f5c5SAndroid Build Coastguard Worker {
1428*8975f5c5SAndroid Build Coastguard Worker my_FragColor = vec4(v_length, 0.0, 0.0, 1.0);
1429*8975f5c5SAndroid Build Coastguard Worker })";
1430*8975f5c5SAndroid Build Coastguard Worker
1431*8975f5c5SAndroid Build Coastguard Worker auto checkLength = [this, vs, kFS, &vertexSource](std::string name, bool declare, int size) {
1432*8975f5c5SAndroid Build Coastguard Worker GLProgram program;
1433*8975f5c5SAndroid Build Coastguard Worker vs(name, declare, size);
1434*8975f5c5SAndroid Build Coastguard Worker program.makeRaster(vertexSource.str().c_str(), kFS.c_str());
1435*8975f5c5SAndroid Build Coastguard Worker ASSERT_TRUE(program.valid()) << name;
1436*8975f5c5SAndroid Build Coastguard Worker
1437*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
1438*8975f5c5SAndroid Build Coastguard Worker drawQuad(program, "a_position", 0);
1439*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_NEAR(0, 0, size * 16, 0, 0, 255, 1);
1440*8975f5c5SAndroid Build Coastguard Worker };
1441*8975f5c5SAndroid Build Coastguard Worker
1442*8975f5c5SAndroid Build Coastguard Worker GLint maxClipDistances = 0;
1443*8975f5c5SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_CLIP_DISTANCES_EXT, &maxClipDistances);
1444*8975f5c5SAndroid Build Coastguard Worker ASSERT_GT(maxClipDistances, 0);
1445*8975f5c5SAndroid Build Coastguard Worker
1446*8975f5c5SAndroid Build Coastguard Worker GLint maxCullDistances = 0;
1447*8975f5c5SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_CULL_DISTANCES_EXT, &maxCullDistances);
1448*8975f5c5SAndroid Build Coastguard Worker if (mCullDistanceSupportRequired)
1449*8975f5c5SAndroid Build Coastguard Worker {
1450*8975f5c5SAndroid Build Coastguard Worker ASSERT_GT(maxCullDistances, 0);
1451*8975f5c5SAndroid Build Coastguard Worker }
1452*8975f5c5SAndroid Build Coastguard Worker else
1453*8975f5c5SAndroid Build Coastguard Worker {
1454*8975f5c5SAndroid Build Coastguard Worker ASSERT_GE(maxCullDistances, 0);
1455*8975f5c5SAndroid Build Coastguard Worker }
1456*8975f5c5SAndroid Build Coastguard Worker
1457*8975f5c5SAndroid Build Coastguard Worker std::pair<std::string, int> entries[2] = {{"gl_ClipDistance", maxClipDistances},
1458*8975f5c5SAndroid Build Coastguard Worker {"gl_CullDistance", maxCullDistances}};
1459*8975f5c5SAndroid Build Coastguard Worker for (auto entry : entries)
1460*8975f5c5SAndroid Build Coastguard Worker {
1461*8975f5c5SAndroid Build Coastguard Worker const std::string name = entry.first;
1462*8975f5c5SAndroid Build Coastguard Worker const int maxSize = entry.second;
1463*8975f5c5SAndroid Build Coastguard Worker for (int i = 1; i <= maxSize; i++)
1464*8975f5c5SAndroid Build Coastguard Worker {
1465*8975f5c5SAndroid Build Coastguard Worker checkLength(name, false, i);
1466*8975f5c5SAndroid Build Coastguard Worker checkLength(name, true, i);
1467*8975f5c5SAndroid Build Coastguard Worker }
1468*8975f5c5SAndroid Build Coastguard Worker }
1469*8975f5c5SAndroid Build Coastguard Worker }
1470*8975f5c5SAndroid Build Coastguard Worker
1471*8975f5c5SAndroid Build Coastguard Worker // Test that pruning clip/cull distance variables does not cause a translator crash
TEST_P(ClipCullDistanceTest,Pruned)1472*8975f5c5SAndroid Build Coastguard Worker TEST_P(ClipCullDistanceTest, Pruned)
1473*8975f5c5SAndroid Build Coastguard Worker {
1474*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled(kExtensionName));
1475*8975f5c5SAndroid Build Coastguard Worker
1476*8975f5c5SAndroid Build Coastguard Worker std::stringstream vertexSource;
1477*8975f5c5SAndroid Build Coastguard Worker auto vs = [this, &vertexSource](std::string name, bool doReturn) {
1478*8975f5c5SAndroid Build Coastguard Worker vertexSource.str(std::string());
1479*8975f5c5SAndroid Build Coastguard Worker vertexSource.clear();
1480*8975f5c5SAndroid Build Coastguard Worker vertexSource << "#version 300 es\n";
1481*8975f5c5SAndroid Build Coastguard Worker vertexSource << "#extension " << kExtensionName << " : require\n";
1482*8975f5c5SAndroid Build Coastguard Worker vertexSource << "void main()\n"
1483*8975f5c5SAndroid Build Coastguard Worker << "{\n"
1484*8975f5c5SAndroid Build Coastguard Worker << " " << (doReturn ? "return;\n" : "") << " " << name << "[1];\n";
1485*8975f5c5SAndroid Build Coastguard Worker vertexSource << "}";
1486*8975f5c5SAndroid Build Coastguard Worker };
1487*8975f5c5SAndroid Build Coastguard Worker
1488*8975f5c5SAndroid Build Coastguard Worker std::stringstream fragmentSource;
1489*8975f5c5SAndroid Build Coastguard Worker auto fs = [this, &fragmentSource](std::string name) {
1490*8975f5c5SAndroid Build Coastguard Worker fragmentSource.str(std::string());
1491*8975f5c5SAndroid Build Coastguard Worker fragmentSource.clear();
1492*8975f5c5SAndroid Build Coastguard Worker fragmentSource << "#version 300 es\n";
1493*8975f5c5SAndroid Build Coastguard Worker fragmentSource << "#extension " << kExtensionName << " : require\n";
1494*8975f5c5SAndroid Build Coastguard Worker fragmentSource << "out mediump vec4 my_FragColor;\n"
1495*8975f5c5SAndroid Build Coastguard Worker << "void main()\n"
1496*8975f5c5SAndroid Build Coastguard Worker << "{\n"
1497*8975f5c5SAndroid Build Coastguard Worker << " my_FragColor = vec4(" << name << "[1]);\n";
1498*8975f5c5SAndroid Build Coastguard Worker fragmentSource << "}";
1499*8975f5c5SAndroid Build Coastguard Worker };
1500*8975f5c5SAndroid Build Coastguard Worker
1501*8975f5c5SAndroid Build Coastguard Worker auto checkPruning = [vs, fs, &vertexSource, &fragmentSource](std::string name, bool doReturn) {
1502*8975f5c5SAndroid Build Coastguard Worker GLProgram program;
1503*8975f5c5SAndroid Build Coastguard Worker vs(name, doReturn);
1504*8975f5c5SAndroid Build Coastguard Worker fs(name);
1505*8975f5c5SAndroid Build Coastguard Worker program.makeRaster(vertexSource.str().c_str(), fragmentSource.str().c_str());
1506*8975f5c5SAndroid Build Coastguard Worker ASSERT_TRUE(program.valid()) << name << (doReturn ? " after return" : "");
1507*8975f5c5SAndroid Build Coastguard Worker };
1508*8975f5c5SAndroid Build Coastguard Worker
1509*8975f5c5SAndroid Build Coastguard Worker GLint maxClipDistances = 0;
1510*8975f5c5SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_CLIP_DISTANCES_EXT, &maxClipDistances);
1511*8975f5c5SAndroid Build Coastguard Worker ASSERT_GT(maxClipDistances, 0);
1512*8975f5c5SAndroid Build Coastguard Worker checkPruning("gl_ClipDistance", false);
1513*8975f5c5SAndroid Build Coastguard Worker checkPruning("gl_ClipDistance", true);
1514*8975f5c5SAndroid Build Coastguard Worker
1515*8975f5c5SAndroid Build Coastguard Worker GLint maxCullDistances = 0;
1516*8975f5c5SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_CULL_DISTANCES_EXT, &maxCullDistances);
1517*8975f5c5SAndroid Build Coastguard Worker if (mCullDistanceSupportRequired)
1518*8975f5c5SAndroid Build Coastguard Worker {
1519*8975f5c5SAndroid Build Coastguard Worker ASSERT_GT(maxCullDistances, 0);
1520*8975f5c5SAndroid Build Coastguard Worker checkPruning("gl_CullDistance", false);
1521*8975f5c5SAndroid Build Coastguard Worker checkPruning("gl_CullDistance", true);
1522*8975f5c5SAndroid Build Coastguard Worker }
1523*8975f5c5SAndroid Build Coastguard Worker }
1524*8975f5c5SAndroid Build Coastguard Worker
1525*8975f5c5SAndroid Build Coastguard Worker // Write to one gl_ClipDistance element
TEST_P(ClipCullDistanceTest,OneClipDistance)1526*8975f5c5SAndroid Build Coastguard Worker TEST_P(ClipCullDistanceTest, OneClipDistance)
1527*8975f5c5SAndroid Build Coastguard Worker {
1528*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled(kExtensionName));
1529*8975f5c5SAndroid Build Coastguard Worker
1530*8975f5c5SAndroid Build Coastguard Worker std::string kVS = R"(#version 300 es
1531*8975f5c5SAndroid Build Coastguard Worker #extension )" + kExtensionName +
1532*8975f5c5SAndroid Build Coastguard Worker R"( : require
1533*8975f5c5SAndroid Build Coastguard Worker
1534*8975f5c5SAndroid Build Coastguard Worker uniform vec4 u_plane;
1535*8975f5c5SAndroid Build Coastguard Worker
1536*8975f5c5SAndroid Build Coastguard Worker in vec2 a_position;
1537*8975f5c5SAndroid Build Coastguard Worker
1538*8975f5c5SAndroid Build Coastguard Worker void main()
1539*8975f5c5SAndroid Build Coastguard Worker {
1540*8975f5c5SAndroid Build Coastguard Worker gl_Position = vec4(a_position, 0.0, 1.0);
1541*8975f5c5SAndroid Build Coastguard Worker
1542*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[0] = dot(gl_Position, u_plane);
1543*8975f5c5SAndroid Build Coastguard Worker })";
1544*8975f5c5SAndroid Build Coastguard Worker
1545*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_PROGRAM(programRed, kVS.c_str(), essl3_shaders::fs::Red());
1546*8975f5c5SAndroid Build Coastguard Worker glUseProgram(programRed);
1547*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
1548*8975f5c5SAndroid Build Coastguard Worker
1549*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE0_EXT);
1550*8975f5c5SAndroid Build Coastguard Worker
1551*8975f5c5SAndroid Build Coastguard Worker // Clear to blue
1552*8975f5c5SAndroid Build Coastguard Worker glClearColor(0, 0, 1, 1);
1553*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
1554*8975f5c5SAndroid Build Coastguard Worker
1555*8975f5c5SAndroid Build Coastguard Worker // Draw full screen quad with color red
1556*8975f5c5SAndroid Build Coastguard Worker glUniform4f(glGetUniformLocation(programRed, "u_plane"), 1, 0, 0, 0.5);
1557*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1558*8975f5c5SAndroid Build Coastguard Worker drawQuad(programRed, "a_position", 0);
1559*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1560*8975f5c5SAndroid Build Coastguard Worker
1561*8975f5c5SAndroid Build Coastguard Worker // All pixels on the left of the plane x = -0.5 must be blue
1562*8975f5c5SAndroid Build Coastguard Worker GLuint x = 0;
1563*8975f5c5SAndroid Build Coastguard Worker GLuint y = 0;
1564*8975f5c5SAndroid Build Coastguard Worker GLuint width = getWindowWidth() / 4 - 1;
1565*8975f5c5SAndroid Build Coastguard Worker GLuint height = getWindowHeight();
1566*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_RECT_EQ(x, y, width, height, GLColor::blue);
1567*8975f5c5SAndroid Build Coastguard Worker
1568*8975f5c5SAndroid Build Coastguard Worker // All pixels on the right of the plane x = -0.5 must be red
1569*8975f5c5SAndroid Build Coastguard Worker x = getWindowWidth() / 4 + 2;
1570*8975f5c5SAndroid Build Coastguard Worker y = 0;
1571*8975f5c5SAndroid Build Coastguard Worker width = getWindowWidth() - x;
1572*8975f5c5SAndroid Build Coastguard Worker height = getWindowHeight();
1573*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_RECT_EQ(x, y, width, height, GLColor::red);
1574*8975f5c5SAndroid Build Coastguard Worker
1575*8975f5c5SAndroid Build Coastguard Worker // Clear to green
1576*8975f5c5SAndroid Build Coastguard Worker glClearColor(0, 1, 0, 1);
1577*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
1578*8975f5c5SAndroid Build Coastguard Worker
1579*8975f5c5SAndroid Build Coastguard Worker // Draw full screen quad with color red
1580*8975f5c5SAndroid Build Coastguard Worker glUniform4f(glGetUniformLocation(programRed, "u_plane"), -1, 0, 0, -0.5);
1581*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1582*8975f5c5SAndroid Build Coastguard Worker drawQuad(programRed, "a_position", 0);
1583*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1584*8975f5c5SAndroid Build Coastguard Worker
1585*8975f5c5SAndroid Build Coastguard Worker // All pixels on the left of the plane x = -0.5 must be red
1586*8975f5c5SAndroid Build Coastguard Worker x = 0;
1587*8975f5c5SAndroid Build Coastguard Worker y = 0;
1588*8975f5c5SAndroid Build Coastguard Worker width = getWindowWidth() / 4 - 1;
1589*8975f5c5SAndroid Build Coastguard Worker height = getWindowHeight();
1590*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_RECT_EQ(x, y, width, height, GLColor::red);
1591*8975f5c5SAndroid Build Coastguard Worker
1592*8975f5c5SAndroid Build Coastguard Worker // All pixels on the right of the plane x = -0.5 must be green
1593*8975f5c5SAndroid Build Coastguard Worker x = getWindowWidth() / 4 + 2;
1594*8975f5c5SAndroid Build Coastguard Worker y = 0;
1595*8975f5c5SAndroid Build Coastguard Worker width = getWindowWidth() - x;
1596*8975f5c5SAndroid Build Coastguard Worker height = getWindowHeight();
1597*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_RECT_EQ(x, y, width, height, GLColor::green);
1598*8975f5c5SAndroid Build Coastguard Worker
1599*8975f5c5SAndroid Build Coastguard Worker // Disable GL_CLIP_DISTANCE
1600*8975f5c5SAndroid Build Coastguard Worker glDisable(GL_CLIP_DISTANCE0_EXT);
1601*8975f5c5SAndroid Build Coastguard Worker drawQuad(programRed, "a_position", 0);
1602*8975f5c5SAndroid Build Coastguard Worker
1603*8975f5c5SAndroid Build Coastguard Worker // All pixels must be red
1604*8975f5c5SAndroid Build Coastguard Worker x = 0;
1605*8975f5c5SAndroid Build Coastguard Worker y = 0;
1606*8975f5c5SAndroid Build Coastguard Worker width = getWindowWidth();
1607*8975f5c5SAndroid Build Coastguard Worker height = getWindowHeight();
1608*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_RECT_EQ(x, y, width, height, GLColor::red);
1609*8975f5c5SAndroid Build Coastguard Worker }
1610*8975f5c5SAndroid Build Coastguard Worker
1611*8975f5c5SAndroid Build Coastguard Worker // Write to each gl_ClipDistance element
TEST_P(ClipCullDistanceTest,EachClipDistance)1612*8975f5c5SAndroid Build Coastguard Worker TEST_P(ClipCullDistanceTest, EachClipDistance)
1613*8975f5c5SAndroid Build Coastguard Worker {
1614*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled(kExtensionName));
1615*8975f5c5SAndroid Build Coastguard Worker
1616*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < 8; i++)
1617*8975f5c5SAndroid Build Coastguard Worker {
1618*8975f5c5SAndroid Build Coastguard Worker std::stringstream vertexShaderStr;
1619*8975f5c5SAndroid Build Coastguard Worker vertexShaderStr << "#version 300 es\n"
1620*8975f5c5SAndroid Build Coastguard Worker << "#extension " << kExtensionName << " : require\n"
1621*8975f5c5SAndroid Build Coastguard Worker << "uniform vec4 u_plane;\n"
1622*8975f5c5SAndroid Build Coastguard Worker << "in vec2 a_position;\n"
1623*8975f5c5SAndroid Build Coastguard Worker << "void main()\n"
1624*8975f5c5SAndroid Build Coastguard Worker << "{\n"
1625*8975f5c5SAndroid Build Coastguard Worker << " gl_Position = vec4(a_position, 0.0, 1.0);\n"
1626*8975f5c5SAndroid Build Coastguard Worker << " gl_ClipDistance[" << i << "] = dot(gl_Position, u_plane);\n"
1627*8975f5c5SAndroid Build Coastguard Worker << "}";
1628*8975f5c5SAndroid Build Coastguard Worker
1629*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_PROGRAM(programRed, vertexShaderStr.str().c_str(), essl3_shaders::fs::Red());
1630*8975f5c5SAndroid Build Coastguard Worker glUseProgram(programRed);
1631*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
1632*8975f5c5SAndroid Build Coastguard Worker
1633*8975f5c5SAndroid Build Coastguard Worker // Enable the current clip distance, disable all others.
1634*8975f5c5SAndroid Build Coastguard Worker for (size_t j = 0; j < 8; j++)
1635*8975f5c5SAndroid Build Coastguard Worker {
1636*8975f5c5SAndroid Build Coastguard Worker if (j == i)
1637*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE0_EXT + j);
1638*8975f5c5SAndroid Build Coastguard Worker else
1639*8975f5c5SAndroid Build Coastguard Worker glDisable(GL_CLIP_DISTANCE0_EXT + j);
1640*8975f5c5SAndroid Build Coastguard Worker }
1641*8975f5c5SAndroid Build Coastguard Worker
1642*8975f5c5SAndroid Build Coastguard Worker // Clear to blue
1643*8975f5c5SAndroid Build Coastguard Worker glClearColor(0, 0, 1, 1);
1644*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
1645*8975f5c5SAndroid Build Coastguard Worker
1646*8975f5c5SAndroid Build Coastguard Worker // Draw full screen quad with color red
1647*8975f5c5SAndroid Build Coastguard Worker glUniform4f(glGetUniformLocation(programRed, "u_plane"), 1, 0, 0, 0.5);
1648*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1649*8975f5c5SAndroid Build Coastguard Worker drawQuad(programRed, "a_position", 0);
1650*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1651*8975f5c5SAndroid Build Coastguard Worker
1652*8975f5c5SAndroid Build Coastguard Worker // All pixels on the left of the plane x = -0.5 must be blue
1653*8975f5c5SAndroid Build Coastguard Worker GLuint x = 0;
1654*8975f5c5SAndroid Build Coastguard Worker GLuint y = 0;
1655*8975f5c5SAndroid Build Coastguard Worker GLuint width = getWindowWidth() / 4 - 1;
1656*8975f5c5SAndroid Build Coastguard Worker GLuint height = getWindowHeight();
1657*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_RECT_EQ(x, y, width, height, GLColor::blue);
1658*8975f5c5SAndroid Build Coastguard Worker
1659*8975f5c5SAndroid Build Coastguard Worker // All pixels on the right of the plane x = -0.5 must be red
1660*8975f5c5SAndroid Build Coastguard Worker x = getWindowWidth() / 4 + 2;
1661*8975f5c5SAndroid Build Coastguard Worker y = 0;
1662*8975f5c5SAndroid Build Coastguard Worker width = getWindowWidth() - x;
1663*8975f5c5SAndroid Build Coastguard Worker height = getWindowHeight();
1664*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_RECT_EQ(x, y, width, height, GLColor::red);
1665*8975f5c5SAndroid Build Coastguard Worker
1666*8975f5c5SAndroid Build Coastguard Worker // Clear to green
1667*8975f5c5SAndroid Build Coastguard Worker glClearColor(0, 1, 0, 1);
1668*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
1669*8975f5c5SAndroid Build Coastguard Worker
1670*8975f5c5SAndroid Build Coastguard Worker // Draw full screen quad with color red
1671*8975f5c5SAndroid Build Coastguard Worker glUniform4f(glGetUniformLocation(programRed, "u_plane"), -1, 0, 0, -0.5);
1672*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1673*8975f5c5SAndroid Build Coastguard Worker drawQuad(programRed, "a_position", 0);
1674*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1675*8975f5c5SAndroid Build Coastguard Worker
1676*8975f5c5SAndroid Build Coastguard Worker // All pixels on the left of the plane x = -0.5 must be red
1677*8975f5c5SAndroid Build Coastguard Worker x = 0;
1678*8975f5c5SAndroid Build Coastguard Worker y = 0;
1679*8975f5c5SAndroid Build Coastguard Worker width = getWindowWidth() / 4 - 1;
1680*8975f5c5SAndroid Build Coastguard Worker height = getWindowHeight();
1681*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_RECT_EQ(x, y, width, height, GLColor::red);
1682*8975f5c5SAndroid Build Coastguard Worker
1683*8975f5c5SAndroid Build Coastguard Worker // All pixels on the right of the plane x = -0.5 must be green
1684*8975f5c5SAndroid Build Coastguard Worker x = getWindowWidth() / 4 + 2;
1685*8975f5c5SAndroid Build Coastguard Worker y = 0;
1686*8975f5c5SAndroid Build Coastguard Worker width = getWindowWidth() - x;
1687*8975f5c5SAndroid Build Coastguard Worker height = getWindowHeight();
1688*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_RECT_EQ(x, y, width, height, GLColor::green);
1689*8975f5c5SAndroid Build Coastguard Worker
1690*8975f5c5SAndroid Build Coastguard Worker // Disable GL_CLIP_DISTANCE
1691*8975f5c5SAndroid Build Coastguard Worker glDisable(GL_CLIP_DISTANCE0_EXT + i);
1692*8975f5c5SAndroid Build Coastguard Worker drawQuad(programRed, "a_position", 0);
1693*8975f5c5SAndroid Build Coastguard Worker
1694*8975f5c5SAndroid Build Coastguard Worker // All pixels must be red
1695*8975f5c5SAndroid Build Coastguard Worker x = 0;
1696*8975f5c5SAndroid Build Coastguard Worker y = 0;
1697*8975f5c5SAndroid Build Coastguard Worker width = getWindowWidth();
1698*8975f5c5SAndroid Build Coastguard Worker height = getWindowHeight();
1699*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_RECT_EQ(x, y, width, height, GLColor::red);
1700*8975f5c5SAndroid Build Coastguard Worker }
1701*8975f5c5SAndroid Build Coastguard Worker }
1702*8975f5c5SAndroid Build Coastguard Worker
1703*8975f5c5SAndroid Build Coastguard Worker // Use 8 clip distances to draw an octagon
TEST_P(ClipCullDistanceTest,Octagon)1704*8975f5c5SAndroid Build Coastguard Worker TEST_P(ClipCullDistanceTest, Octagon)
1705*8975f5c5SAndroid Build Coastguard Worker {
1706*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled(kExtensionName));
1707*8975f5c5SAndroid Build Coastguard Worker
1708*8975f5c5SAndroid Build Coastguard Worker std::string kVS = R"(#version 300 es
1709*8975f5c5SAndroid Build Coastguard Worker #extension )" + kExtensionName +
1710*8975f5c5SAndroid Build Coastguard Worker R"( : require
1711*8975f5c5SAndroid Build Coastguard Worker
1712*8975f5c5SAndroid Build Coastguard Worker in vec2 a_position;
1713*8975f5c5SAndroid Build Coastguard Worker
1714*8975f5c5SAndroid Build Coastguard Worker void main()
1715*8975f5c5SAndroid Build Coastguard Worker {
1716*8975f5c5SAndroid Build Coastguard Worker gl_Position = vec4(a_position, 0.0, 1.0);
1717*8975f5c5SAndroid Build Coastguard Worker
1718*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[0] = dot(gl_Position, vec4( 1, 0, 0, 0.5));
1719*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[1] = dot(gl_Position, vec4(-1, 0, 0, 0.5));
1720*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[2] = dot(gl_Position, vec4( 0, 1, 0, 0.5));
1721*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[3] = dot(gl_Position, vec4( 0, -1, 0, 0.5));
1722*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[4] = dot(gl_Position, vec4( 1, 1, 0, 0.70710678));
1723*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[5] = dot(gl_Position, vec4( 1, -1, 0, 0.70710678));
1724*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[6] = dot(gl_Position, vec4(-1, 1, 0, 0.70710678));
1725*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[7] = dot(gl_Position, vec4(-1, -1, 0, 0.70710678));
1726*8975f5c5SAndroid Build Coastguard Worker })";
1727*8975f5c5SAndroid Build Coastguard Worker
1728*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_PROGRAM(programRed, kVS.c_str(), essl3_shaders::fs::Red());
1729*8975f5c5SAndroid Build Coastguard Worker glUseProgram(programRed);
1730*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
1731*8975f5c5SAndroid Build Coastguard Worker
1732*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE0_EXT);
1733*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE1_EXT);
1734*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE2_EXT);
1735*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE3_EXT);
1736*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE4_EXT);
1737*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE5_EXT);
1738*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE6_EXT);
1739*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE7_EXT);
1740*8975f5c5SAndroid Build Coastguard Worker
1741*8975f5c5SAndroid Build Coastguard Worker // Clear to blue
1742*8975f5c5SAndroid Build Coastguard Worker glClearColor(0, 0, 1, 1);
1743*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
1744*8975f5c5SAndroid Build Coastguard Worker
1745*8975f5c5SAndroid Build Coastguard Worker // Draw full screen quad with color red
1746*8975f5c5SAndroid Build Coastguard Worker drawQuad(programRed, "a_position", 0);
1747*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1748*8975f5c5SAndroid Build Coastguard Worker
1749*8975f5c5SAndroid Build Coastguard Worker // Top edge
1750*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(32, 56, GLColor::blue);
1751*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(32, 40, GLColor::red);
1752*8975f5c5SAndroid Build Coastguard Worker
1753*8975f5c5SAndroid Build Coastguard Worker // Top-right edge
1754*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(48, 48, GLColor::blue);
1755*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(40, 40, GLColor::red);
1756*8975f5c5SAndroid Build Coastguard Worker
1757*8975f5c5SAndroid Build Coastguard Worker // Right edge
1758*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(56, 32, GLColor::blue);
1759*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(40, 32, GLColor::red);
1760*8975f5c5SAndroid Build Coastguard Worker
1761*8975f5c5SAndroid Build Coastguard Worker // Bottom-right edge
1762*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(48, 16, GLColor::blue);
1763*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(40, 24, GLColor::red);
1764*8975f5c5SAndroid Build Coastguard Worker
1765*8975f5c5SAndroid Build Coastguard Worker // Bottom edge
1766*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(32, 8, GLColor::blue);
1767*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(32, 24, GLColor::red);
1768*8975f5c5SAndroid Build Coastguard Worker
1769*8975f5c5SAndroid Build Coastguard Worker // Bottom-left edge
1770*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(16, 16, GLColor::blue);
1771*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(24, 24, GLColor::red);
1772*8975f5c5SAndroid Build Coastguard Worker
1773*8975f5c5SAndroid Build Coastguard Worker // Left edge
1774*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(8, 32, GLColor::blue);
1775*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(24, 32, GLColor::red);
1776*8975f5c5SAndroid Build Coastguard Worker
1777*8975f5c5SAndroid Build Coastguard Worker // Top-left edge
1778*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(16, 48, GLColor::blue);
1779*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(24, 40, GLColor::red);
1780*8975f5c5SAndroid Build Coastguard Worker }
1781*8975f5c5SAndroid Build Coastguard Worker
1782*8975f5c5SAndroid Build Coastguard Worker // Write to 3 clip distances
TEST_P(ClipCullDistanceTest,ThreeClipDistances)1783*8975f5c5SAndroid Build Coastguard Worker TEST_P(ClipCullDistanceTest, ThreeClipDistances)
1784*8975f5c5SAndroid Build Coastguard Worker {
1785*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled(kExtensionName));
1786*8975f5c5SAndroid Build Coastguard Worker
1787*8975f5c5SAndroid Build Coastguard Worker std::string kVS = R"(#version 300 es
1788*8975f5c5SAndroid Build Coastguard Worker #extension )" + kExtensionName +
1789*8975f5c5SAndroid Build Coastguard Worker R"( : require
1790*8975f5c5SAndroid Build Coastguard Worker
1791*8975f5c5SAndroid Build Coastguard Worker uniform vec4 u_plane[3];
1792*8975f5c5SAndroid Build Coastguard Worker
1793*8975f5c5SAndroid Build Coastguard Worker in vec2 a_position;
1794*8975f5c5SAndroid Build Coastguard Worker
1795*8975f5c5SAndroid Build Coastguard Worker void main()
1796*8975f5c5SAndroid Build Coastguard Worker {
1797*8975f5c5SAndroid Build Coastguard Worker gl_Position = vec4(a_position, 0.0, 1.0);
1798*8975f5c5SAndroid Build Coastguard Worker
1799*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[0] = dot(gl_Position, u_plane[0]);
1800*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[3] = dot(gl_Position, u_plane[1]);
1801*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[7] = dot(gl_Position, u_plane[2]);
1802*8975f5c5SAndroid Build Coastguard Worker })";
1803*8975f5c5SAndroid Build Coastguard Worker
1804*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_PROGRAM(programRed, kVS.c_str(), essl3_shaders::fs::Red());
1805*8975f5c5SAndroid Build Coastguard Worker glUseProgram(programRed);
1806*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
1807*8975f5c5SAndroid Build Coastguard Worker
1808*8975f5c5SAndroid Build Coastguard Worker // Enable 3 clip distances
1809*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE0_EXT);
1810*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE3_EXT);
1811*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE7_EXT);
1812*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
1813*8975f5c5SAndroid Build Coastguard Worker
1814*8975f5c5SAndroid Build Coastguard Worker // Clear to blue
1815*8975f5c5SAndroid Build Coastguard Worker glClearColor(0, 0, 1, 1);
1816*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
1817*8975f5c5SAndroid Build Coastguard Worker
1818*8975f5c5SAndroid Build Coastguard Worker // Draw full screen quad with color red
1819*8975f5c5SAndroid Build Coastguard Worker // x = -0.5
1820*8975f5c5SAndroid Build Coastguard Worker glUniform4f(glGetUniformLocation(programRed, "u_plane[0]"), 1, 0, 0, 0.5);
1821*8975f5c5SAndroid Build Coastguard Worker // x = 0.5
1822*8975f5c5SAndroid Build Coastguard Worker glUniform4f(glGetUniformLocation(programRed, "u_plane[1]"), -1, 0, 0, 0.5);
1823*8975f5c5SAndroid Build Coastguard Worker // x + y = 1
1824*8975f5c5SAndroid Build Coastguard Worker glUniform4f(glGetUniformLocation(programRed, "u_plane[2]"), -1, -1, 0, 1);
1825*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1826*8975f5c5SAndroid Build Coastguard Worker drawQuad(programRed, "a_position", 0);
1827*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1828*8975f5c5SAndroid Build Coastguard Worker
1829*8975f5c5SAndroid Build Coastguard Worker {
1830*8975f5c5SAndroid Build Coastguard Worker // All pixels on the left of the plane x = -0.5 must be blue
1831*8975f5c5SAndroid Build Coastguard Worker GLuint x = 0;
1832*8975f5c5SAndroid Build Coastguard Worker GLuint y = 0;
1833*8975f5c5SAndroid Build Coastguard Worker GLuint width = getWindowWidth() / 4 - 1;
1834*8975f5c5SAndroid Build Coastguard Worker GLuint height = getWindowHeight();
1835*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_RECT_EQ(x, y, width, height, GLColor::blue);
1836*8975f5c5SAndroid Build Coastguard Worker
1837*8975f5c5SAndroid Build Coastguard Worker // All pixels from the plane x = -0.5 to the plane x = 0 must be red
1838*8975f5c5SAndroid Build Coastguard Worker x = getWindowWidth() / 4 + 2;
1839*8975f5c5SAndroid Build Coastguard Worker y = 0;
1840*8975f5c5SAndroid Build Coastguard Worker width = getWindowWidth() / 2 - x;
1841*8975f5c5SAndroid Build Coastguard Worker height = getWindowHeight();
1842*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_RECT_EQ(x, y, width, height, GLColor::red);
1843*8975f5c5SAndroid Build Coastguard Worker }
1844*8975f5c5SAndroid Build Coastguard Worker
1845*8975f5c5SAndroid Build Coastguard Worker {
1846*8975f5c5SAndroid Build Coastguard Worker // Check pixels to the right of the plane x = 0
1847*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> actualColors(getWindowWidth() * getWindowHeight());
1848*8975f5c5SAndroid Build Coastguard Worker glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
1849*8975f5c5SAndroid Build Coastguard Worker actualColors.data());
1850*8975f5c5SAndroid Build Coastguard Worker for (int y = 0; y < getWindowHeight(); ++y)
1851*8975f5c5SAndroid Build Coastguard Worker {
1852*8975f5c5SAndroid Build Coastguard Worker for (int x = getWindowWidth() / 2; x < getWindowWidth(); ++x)
1853*8975f5c5SAndroid Build Coastguard Worker {
1854*8975f5c5SAndroid Build Coastguard Worker const int currentPosition = y * getWindowHeight() + x;
1855*8975f5c5SAndroid Build Coastguard Worker
1856*8975f5c5SAndroid Build Coastguard Worker if (x < getWindowWidth() * 3 / 2 - y - 1 && x < getWindowWidth() * 3 / 4 - 1)
1857*8975f5c5SAndroid Build Coastguard Worker {
1858*8975f5c5SAndroid Build Coastguard Worker // Bottom of the plane x + y = 1 clipped by x = 0.5 plane
1859*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(GLColor::red, actualColors[currentPosition]);
1860*8975f5c5SAndroid Build Coastguard Worker }
1861*8975f5c5SAndroid Build Coastguard Worker else if (x > getWindowWidth() * 3 / 2 - y + 1 || x > getWindowWidth() * 3 / 4 + 1)
1862*8975f5c5SAndroid Build Coastguard Worker {
1863*8975f5c5SAndroid Build Coastguard Worker // Top of the plane x + y = 1 plus right of x = 0.5 plane
1864*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(GLColor::blue, actualColors[currentPosition]);
1865*8975f5c5SAndroid Build Coastguard Worker }
1866*8975f5c5SAndroid Build Coastguard Worker }
1867*8975f5c5SAndroid Build Coastguard Worker }
1868*8975f5c5SAndroid Build Coastguard Worker }
1869*8975f5c5SAndroid Build Coastguard Worker
1870*8975f5c5SAndroid Build Coastguard Worker // Clear to green
1871*8975f5c5SAndroid Build Coastguard Worker glClearColor(0, 1, 0, 1);
1872*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
1873*8975f5c5SAndroid Build Coastguard Worker
1874*8975f5c5SAndroid Build Coastguard Worker // Disable gl_ClipDistance[3]
1875*8975f5c5SAndroid Build Coastguard Worker glDisable(GL_CLIP_DISTANCE3_EXT);
1876*8975f5c5SAndroid Build Coastguard Worker
1877*8975f5c5SAndroid Build Coastguard Worker // Draw full screen quad with color red
1878*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1879*8975f5c5SAndroid Build Coastguard Worker drawQuad(programRed, "a_position", 0);
1880*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1881*8975f5c5SAndroid Build Coastguard Worker
1882*8975f5c5SAndroid Build Coastguard Worker {
1883*8975f5c5SAndroid Build Coastguard Worker // All pixels on the left of the plane x = -0.5 must be green
1884*8975f5c5SAndroid Build Coastguard Worker GLuint x = 0;
1885*8975f5c5SAndroid Build Coastguard Worker GLuint y = 0;
1886*8975f5c5SAndroid Build Coastguard Worker GLuint width = getWindowWidth() / 4 - 1;
1887*8975f5c5SAndroid Build Coastguard Worker GLuint height = getWindowHeight();
1888*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_RECT_EQ(x, y, width, height, GLColor::green);
1889*8975f5c5SAndroid Build Coastguard Worker
1890*8975f5c5SAndroid Build Coastguard Worker // All pixels from the plane x = -0.5 to the plane x = 0 must be red
1891*8975f5c5SAndroid Build Coastguard Worker x = getWindowWidth() / 4 + 2;
1892*8975f5c5SAndroid Build Coastguard Worker y = 0;
1893*8975f5c5SAndroid Build Coastguard Worker width = getWindowWidth() / 2 - x;
1894*8975f5c5SAndroid Build Coastguard Worker height = getWindowHeight();
1895*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_RECT_EQ(x, y, width, height, GLColor::red);
1896*8975f5c5SAndroid Build Coastguard Worker }
1897*8975f5c5SAndroid Build Coastguard Worker
1898*8975f5c5SAndroid Build Coastguard Worker // Check pixels to the right of the plane x = 0
1899*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> actualColors(getWindowWidth() * getWindowHeight());
1900*8975f5c5SAndroid Build Coastguard Worker glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
1901*8975f5c5SAndroid Build Coastguard Worker actualColors.data());
1902*8975f5c5SAndroid Build Coastguard Worker for (int y = 0; y < getWindowHeight(); ++y)
1903*8975f5c5SAndroid Build Coastguard Worker {
1904*8975f5c5SAndroid Build Coastguard Worker for (int x = getWindowWidth() / 2; x < getWindowWidth(); ++x)
1905*8975f5c5SAndroid Build Coastguard Worker {
1906*8975f5c5SAndroid Build Coastguard Worker const int currentPosition = y * getWindowHeight() + x;
1907*8975f5c5SAndroid Build Coastguard Worker
1908*8975f5c5SAndroid Build Coastguard Worker if (x < getWindowWidth() * 3 / 2 - y - 1)
1909*8975f5c5SAndroid Build Coastguard Worker {
1910*8975f5c5SAndroid Build Coastguard Worker // Bottom of the plane x + y = 1
1911*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(GLColor::red, actualColors[currentPosition]);
1912*8975f5c5SAndroid Build Coastguard Worker }
1913*8975f5c5SAndroid Build Coastguard Worker else if (x > getWindowWidth() * 3 / 2 - y + 1)
1914*8975f5c5SAndroid Build Coastguard Worker {
1915*8975f5c5SAndroid Build Coastguard Worker // Top of the plane x + y = 1
1916*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(GLColor::green, actualColors[currentPosition]);
1917*8975f5c5SAndroid Build Coastguard Worker }
1918*8975f5c5SAndroid Build Coastguard Worker }
1919*8975f5c5SAndroid Build Coastguard Worker }
1920*8975f5c5SAndroid Build Coastguard Worker }
1921*8975f5c5SAndroid Build Coastguard Worker
1922*8975f5c5SAndroid Build Coastguard Worker // Redeclare gl_ClipDistance in shader with explicit size, also use it in a global function
1923*8975f5c5SAndroid Build Coastguard Worker // outside main()
TEST_P(ClipCullDistanceTest,ThreeClipDistancesRedeclared)1924*8975f5c5SAndroid Build Coastguard Worker TEST_P(ClipCullDistanceTest, ThreeClipDistancesRedeclared)
1925*8975f5c5SAndroid Build Coastguard Worker {
1926*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled(kExtensionName));
1927*8975f5c5SAndroid Build Coastguard Worker
1928*8975f5c5SAndroid Build Coastguard Worker std::string kVS = R"(#version 300 es
1929*8975f5c5SAndroid Build Coastguard Worker #extension )" + kExtensionName +
1930*8975f5c5SAndroid Build Coastguard Worker R"( : require
1931*8975f5c5SAndroid Build Coastguard Worker
1932*8975f5c5SAndroid Build Coastguard Worker out highp float gl_ClipDistance[3];
1933*8975f5c5SAndroid Build Coastguard Worker
1934*8975f5c5SAndroid Build Coastguard Worker void computeClipDistances(in vec4 position, in vec4 plane[3])
1935*8975f5c5SAndroid Build Coastguard Worker {
1936*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[0] = dot(position, plane[0]);
1937*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[1] = dot(position, plane[1]);
1938*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[2] = dot(position, plane[2]);
1939*8975f5c5SAndroid Build Coastguard Worker }
1940*8975f5c5SAndroid Build Coastguard Worker
1941*8975f5c5SAndroid Build Coastguard Worker uniform vec4 u_plane[3];
1942*8975f5c5SAndroid Build Coastguard Worker
1943*8975f5c5SAndroid Build Coastguard Worker in vec2 a_position;
1944*8975f5c5SAndroid Build Coastguard Worker
1945*8975f5c5SAndroid Build Coastguard Worker void main()
1946*8975f5c5SAndroid Build Coastguard Worker {
1947*8975f5c5SAndroid Build Coastguard Worker gl_Position = vec4(a_position, 0.0, 1.0);
1948*8975f5c5SAndroid Build Coastguard Worker
1949*8975f5c5SAndroid Build Coastguard Worker computeClipDistances(gl_Position, u_plane);
1950*8975f5c5SAndroid Build Coastguard Worker })";
1951*8975f5c5SAndroid Build Coastguard Worker
1952*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_PROGRAM(programRed, kVS.c_str(), essl3_shaders::fs::Red());
1953*8975f5c5SAndroid Build Coastguard Worker glUseProgram(programRed);
1954*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
1955*8975f5c5SAndroid Build Coastguard Worker
1956*8975f5c5SAndroid Build Coastguard Worker // Enable 3 clip distances
1957*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE0_EXT);
1958*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE1_EXT);
1959*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE2_EXT);
1960*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
1961*8975f5c5SAndroid Build Coastguard Worker
1962*8975f5c5SAndroid Build Coastguard Worker // Clear to blue
1963*8975f5c5SAndroid Build Coastguard Worker glClearColor(0, 0, 1, 1);
1964*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
1965*8975f5c5SAndroid Build Coastguard Worker
1966*8975f5c5SAndroid Build Coastguard Worker // Draw full screen quad with color red
1967*8975f5c5SAndroid Build Coastguard Worker // x = -0.5
1968*8975f5c5SAndroid Build Coastguard Worker glUniform4f(glGetUniformLocation(programRed, "u_plane[0]"), 1, 0, 0, 0.5);
1969*8975f5c5SAndroid Build Coastguard Worker // x = 0.5
1970*8975f5c5SAndroid Build Coastguard Worker glUniform4f(glGetUniformLocation(programRed, "u_plane[1]"), -1, 0, 0, 0.5);
1971*8975f5c5SAndroid Build Coastguard Worker // x + y = 1
1972*8975f5c5SAndroid Build Coastguard Worker glUniform4f(glGetUniformLocation(programRed, "u_plane[2]"), -1, -1, 0, 1);
1973*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1974*8975f5c5SAndroid Build Coastguard Worker drawQuad(programRed, "a_position", 0);
1975*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
1976*8975f5c5SAndroid Build Coastguard Worker
1977*8975f5c5SAndroid Build Coastguard Worker {
1978*8975f5c5SAndroid Build Coastguard Worker // All pixels on the left of the plane x = -0.5 must be blue
1979*8975f5c5SAndroid Build Coastguard Worker GLuint x = 0;
1980*8975f5c5SAndroid Build Coastguard Worker GLuint y = 0;
1981*8975f5c5SAndroid Build Coastguard Worker GLuint width = getWindowWidth() / 4 - 1;
1982*8975f5c5SAndroid Build Coastguard Worker GLuint height = getWindowHeight();
1983*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_RECT_EQ(x, y, width, height, GLColor::blue);
1984*8975f5c5SAndroid Build Coastguard Worker
1985*8975f5c5SAndroid Build Coastguard Worker // All pixels from the plane x = -0.5 to the plane x = 0 must be red
1986*8975f5c5SAndroid Build Coastguard Worker x = getWindowWidth() / 4 + 2;
1987*8975f5c5SAndroid Build Coastguard Worker y = 0;
1988*8975f5c5SAndroid Build Coastguard Worker width = getWindowWidth() / 2 - x;
1989*8975f5c5SAndroid Build Coastguard Worker height = getWindowHeight();
1990*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_RECT_EQ(x, y, width, height, GLColor::red);
1991*8975f5c5SAndroid Build Coastguard Worker }
1992*8975f5c5SAndroid Build Coastguard Worker
1993*8975f5c5SAndroid Build Coastguard Worker // Check pixels to the right of the plane x = 0
1994*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> actualColors(getWindowWidth() * getWindowHeight());
1995*8975f5c5SAndroid Build Coastguard Worker glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
1996*8975f5c5SAndroid Build Coastguard Worker actualColors.data());
1997*8975f5c5SAndroid Build Coastguard Worker for (int y = 0; y < getWindowHeight(); ++y)
1998*8975f5c5SAndroid Build Coastguard Worker {
1999*8975f5c5SAndroid Build Coastguard Worker for (int x = getWindowWidth() / 2; x < getWindowWidth(); ++x)
2000*8975f5c5SAndroid Build Coastguard Worker {
2001*8975f5c5SAndroid Build Coastguard Worker const int currentPosition = y * getWindowHeight() + x;
2002*8975f5c5SAndroid Build Coastguard Worker
2003*8975f5c5SAndroid Build Coastguard Worker if (x < getWindowWidth() * 3 / 2 - y - 1 && x < getWindowWidth() * 3 / 4 - 1)
2004*8975f5c5SAndroid Build Coastguard Worker {
2005*8975f5c5SAndroid Build Coastguard Worker // Bottom of the plane x + y = 1 clipped by x = 0.5 plane
2006*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(GLColor::red, actualColors[currentPosition]);
2007*8975f5c5SAndroid Build Coastguard Worker }
2008*8975f5c5SAndroid Build Coastguard Worker else if (x > getWindowWidth() * 3 / 2 - y + 1 || x > getWindowWidth() * 3 / 4 + 1)
2009*8975f5c5SAndroid Build Coastguard Worker {
2010*8975f5c5SAndroid Build Coastguard Worker // Top of the plane x + y = 1 plus right of x = 0.5 plane
2011*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(GLColor::blue, actualColors[currentPosition]);
2012*8975f5c5SAndroid Build Coastguard Worker }
2013*8975f5c5SAndroid Build Coastguard Worker }
2014*8975f5c5SAndroid Build Coastguard Worker }
2015*8975f5c5SAndroid Build Coastguard Worker }
2016*8975f5c5SAndroid Build Coastguard Worker
2017*8975f5c5SAndroid Build Coastguard Worker // Read clip distance varyings in fragment shaders
TEST_P(ClipCullDistanceTest,ClipInterpolation)2018*8975f5c5SAndroid Build Coastguard Worker TEST_P(ClipCullDistanceTest, ClipInterpolation)
2019*8975f5c5SAndroid Build Coastguard Worker {
2020*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled(kExtensionName));
2021*8975f5c5SAndroid Build Coastguard Worker
2022*8975f5c5SAndroid Build Coastguard Worker std::string kVS = R"(#version 300 es
2023*8975f5c5SAndroid Build Coastguard Worker #extension )" + kExtensionName +
2024*8975f5c5SAndroid Build Coastguard Worker R"( : require
2025*8975f5c5SAndroid Build Coastguard Worker in vec2 a_position;
2026*8975f5c5SAndroid Build Coastguard Worker void main()
2027*8975f5c5SAndroid Build Coastguard Worker {
2028*8975f5c5SAndroid Build Coastguard Worker gl_Position = vec4(a_position, 0.0, 1.0);
2029*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[0] = dot(gl_Position, vec4( 1, 0, 0, 0.5));
2030*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[1] = dot(gl_Position, vec4(-1, 0, 0, 0.5));
2031*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[2] = dot(gl_Position, vec4( 0, 1, 0, 0.5));
2032*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[3] = dot(gl_Position, vec4( 0, -1, 0, 0.5));
2033*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[4] = gl_ClipDistance[0];
2034*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[5] = gl_ClipDistance[1];
2035*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[6] = gl_ClipDistance[2];
2036*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[7] = gl_ClipDistance[3];
2037*8975f5c5SAndroid Build Coastguard Worker })";
2038*8975f5c5SAndroid Build Coastguard Worker
2039*8975f5c5SAndroid Build Coastguard Worker std::string kFS = R"(#version 300 es
2040*8975f5c5SAndroid Build Coastguard Worker #extension )" + kExtensionName +
2041*8975f5c5SAndroid Build Coastguard Worker R"( : require
2042*8975f5c5SAndroid Build Coastguard Worker precision highp float;
2043*8975f5c5SAndroid Build Coastguard Worker out vec4 my_FragColor;
2044*8975f5c5SAndroid Build Coastguard Worker void main()
2045*8975f5c5SAndroid Build Coastguard Worker {
2046*8975f5c5SAndroid Build Coastguard Worker float r = gl_ClipDistance[0] + gl_ClipDistance[1];
2047*8975f5c5SAndroid Build Coastguard Worker float g = gl_ClipDistance[2] + gl_ClipDistance[3];
2048*8975f5c5SAndroid Build Coastguard Worker float b = gl_ClipDistance[4] + gl_ClipDistance[5];
2049*8975f5c5SAndroid Build Coastguard Worker float a = gl_ClipDistance[6] + gl_ClipDistance[7];
2050*8975f5c5SAndroid Build Coastguard Worker my_FragColor = vec4(r, g, b, a) * 0.5;
2051*8975f5c5SAndroid Build Coastguard Worker })";
2052*8975f5c5SAndroid Build Coastguard Worker
2053*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_PROGRAM(programRed, kVS.c_str(), kFS.c_str());
2054*8975f5c5SAndroid Build Coastguard Worker glUseProgram(programRed);
2055*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
2056*8975f5c5SAndroid Build Coastguard Worker
2057*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE0_EXT);
2058*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE1_EXT);
2059*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE2_EXT);
2060*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE3_EXT);
2061*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE4_EXT);
2062*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE5_EXT);
2063*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE6_EXT);
2064*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE7_EXT);
2065*8975f5c5SAndroid Build Coastguard Worker
2066*8975f5c5SAndroid Build Coastguard Worker // Clear to blue
2067*8975f5c5SAndroid Build Coastguard Worker glClearColor(0, 0, 1, 1);
2068*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
2069*8975f5c5SAndroid Build Coastguard Worker
2070*8975f5c5SAndroid Build Coastguard Worker // Draw full screen quad with color red
2071*8975f5c5SAndroid Build Coastguard Worker drawQuad(programRed, "a_position", 0);
2072*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
2073*8975f5c5SAndroid Build Coastguard Worker
2074*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> actualColors(getWindowWidth() * getWindowHeight());
2075*8975f5c5SAndroid Build Coastguard Worker glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
2076*8975f5c5SAndroid Build Coastguard Worker actualColors.data());
2077*8975f5c5SAndroid Build Coastguard Worker for (int x = 0; x < getWindowWidth(); x++)
2078*8975f5c5SAndroid Build Coastguard Worker {
2079*8975f5c5SAndroid Build Coastguard Worker for (int y = 0; y < getWindowHeight(); y++)
2080*8975f5c5SAndroid Build Coastguard Worker {
2081*8975f5c5SAndroid Build Coastguard Worker const int currentPosition = y * getWindowHeight() + x;
2082*8975f5c5SAndroid Build Coastguard Worker
2083*8975f5c5SAndroid Build Coastguard Worker if (x >= getWindowWidth() / 4 && x < getWindowWidth() * 3 / 4 &&
2084*8975f5c5SAndroid Build Coastguard Worker y >= getWindowHeight() / 4 && y < getWindowHeight() * 3 / 4)
2085*8975f5c5SAndroid Build Coastguard Worker {
2086*8975f5c5SAndroid Build Coastguard Worker EXPECT_COLOR_NEAR(GLColor(127, 127, 127, 127), actualColors[currentPosition], 1);
2087*8975f5c5SAndroid Build Coastguard Worker }
2088*8975f5c5SAndroid Build Coastguard Worker else
2089*8975f5c5SAndroid Build Coastguard Worker {
2090*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(GLColor::blue, actualColors[currentPosition]);
2091*8975f5c5SAndroid Build Coastguard Worker }
2092*8975f5c5SAndroid Build Coastguard Worker }
2093*8975f5c5SAndroid Build Coastguard Worker }
2094*8975f5c5SAndroid Build Coastguard Worker }
2095*8975f5c5SAndroid Build Coastguard Worker
2096*8975f5c5SAndroid Build Coastguard Worker // Write to one gl_CullDistance element
TEST_P(ClipCullDistanceTest,OneCullDistance)2097*8975f5c5SAndroid Build Coastguard Worker TEST_P(ClipCullDistanceTest, OneCullDistance)
2098*8975f5c5SAndroid Build Coastguard Worker {
2099*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled(kExtensionName));
2100*8975f5c5SAndroid Build Coastguard Worker
2101*8975f5c5SAndroid Build Coastguard Worker std::string kVS = R"(#version 300 es
2102*8975f5c5SAndroid Build Coastguard Worker #extension )" + kExtensionName +
2103*8975f5c5SAndroid Build Coastguard Worker R"( : require
2104*8975f5c5SAndroid Build Coastguard Worker
2105*8975f5c5SAndroid Build Coastguard Worker uniform vec4 u_plane;
2106*8975f5c5SAndroid Build Coastguard Worker
2107*8975f5c5SAndroid Build Coastguard Worker in vec2 a_position;
2108*8975f5c5SAndroid Build Coastguard Worker
2109*8975f5c5SAndroid Build Coastguard Worker void main()
2110*8975f5c5SAndroid Build Coastguard Worker {
2111*8975f5c5SAndroid Build Coastguard Worker gl_Position = vec4(a_position, 0.0, 1.0);
2112*8975f5c5SAndroid Build Coastguard Worker
2113*8975f5c5SAndroid Build Coastguard Worker gl_CullDistance[0] = dot(gl_Position, u_plane);
2114*8975f5c5SAndroid Build Coastguard Worker })";
2115*8975f5c5SAndroid Build Coastguard Worker
2116*8975f5c5SAndroid Build Coastguard Worker GLProgram programRed;
2117*8975f5c5SAndroid Build Coastguard Worker programRed.makeRaster(kVS.c_str(), essl3_shaders::fs::Red());
2118*8975f5c5SAndroid Build Coastguard Worker if (!mCullDistanceSupportRequired)
2119*8975f5c5SAndroid Build Coastguard Worker {
2120*8975f5c5SAndroid Build Coastguard Worker GLint maxCullDistances;
2121*8975f5c5SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_CULL_DISTANCES_EXT, &maxCullDistances);
2122*8975f5c5SAndroid Build Coastguard Worker if (maxCullDistances == 0)
2123*8975f5c5SAndroid Build Coastguard Worker {
2124*8975f5c5SAndroid Build Coastguard Worker ASSERT_FALSE(programRed.valid());
2125*8975f5c5SAndroid Build Coastguard Worker return;
2126*8975f5c5SAndroid Build Coastguard Worker }
2127*8975f5c5SAndroid Build Coastguard Worker }
2128*8975f5c5SAndroid Build Coastguard Worker glUseProgram(programRed);
2129*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
2130*8975f5c5SAndroid Build Coastguard Worker
2131*8975f5c5SAndroid Build Coastguard Worker // Clear to blue
2132*8975f5c5SAndroid Build Coastguard Worker glClearColor(0, 0, 1, 1);
2133*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
2134*8975f5c5SAndroid Build Coastguard Worker
2135*8975f5c5SAndroid Build Coastguard Worker // Draw full screen quad with color red
2136*8975f5c5SAndroid Build Coastguard Worker glUniform4f(glGetUniformLocation(programRed, "u_plane"), 1, 0, 0, 0.5);
2137*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
2138*8975f5c5SAndroid Build Coastguard Worker drawQuad(programRed, "a_position", 0);
2139*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
2140*8975f5c5SAndroid Build Coastguard Worker
2141*8975f5c5SAndroid Build Coastguard Worker {
2142*8975f5c5SAndroid Build Coastguard Worker // All pixels must be red
2143*8975f5c5SAndroid Build Coastguard Worker GLuint x = 0;
2144*8975f5c5SAndroid Build Coastguard Worker GLuint y = 0;
2145*8975f5c5SAndroid Build Coastguard Worker GLuint width = getWindowWidth();
2146*8975f5c5SAndroid Build Coastguard Worker GLuint height = getWindowHeight();
2147*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_RECT_EQ(x, y, width, height, GLColor::red);
2148*8975f5c5SAndroid Build Coastguard Worker }
2149*8975f5c5SAndroid Build Coastguard Worker
2150*8975f5c5SAndroid Build Coastguard Worker // Clear to green
2151*8975f5c5SAndroid Build Coastguard Worker glClearColor(0, 1, 0, 1);
2152*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
2153*8975f5c5SAndroid Build Coastguard Worker
2154*8975f5c5SAndroid Build Coastguard Worker // Draw full screen quad with color red
2155*8975f5c5SAndroid Build Coastguard Worker glUniform4f(glGetUniformLocation(programRed, "u_plane"), 1, 1, 0, 0);
2156*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
2157*8975f5c5SAndroid Build Coastguard Worker drawQuad(programRed, "a_position", 0);
2158*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
2159*8975f5c5SAndroid Build Coastguard Worker
2160*8975f5c5SAndroid Build Coastguard Worker // All pixels on the plane y >= -x must be red
2161*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> actualColors(getWindowWidth() * getWindowHeight());
2162*8975f5c5SAndroid Build Coastguard Worker glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
2163*8975f5c5SAndroid Build Coastguard Worker actualColors.data());
2164*8975f5c5SAndroid Build Coastguard Worker for (int x = 0; x < getWindowWidth(); ++x)
2165*8975f5c5SAndroid Build Coastguard Worker {
2166*8975f5c5SAndroid Build Coastguard Worker for (int y = 0; y < getWindowHeight(); ++y)
2167*8975f5c5SAndroid Build Coastguard Worker {
2168*8975f5c5SAndroid Build Coastguard Worker const int currentPosition = y * getWindowHeight() + x;
2169*8975f5c5SAndroid Build Coastguard Worker
2170*8975f5c5SAndroid Build Coastguard Worker if ((x + y) >= 0)
2171*8975f5c5SAndroid Build Coastguard Worker {
2172*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(GLColor::red, actualColors[currentPosition]);
2173*8975f5c5SAndroid Build Coastguard Worker }
2174*8975f5c5SAndroid Build Coastguard Worker else
2175*8975f5c5SAndroid Build Coastguard Worker {
2176*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(GLColor::green, actualColors[currentPosition]);
2177*8975f5c5SAndroid Build Coastguard Worker }
2178*8975f5c5SAndroid Build Coastguard Worker }
2179*8975f5c5SAndroid Build Coastguard Worker }
2180*8975f5c5SAndroid Build Coastguard Worker }
2181*8975f5c5SAndroid Build Coastguard Worker
2182*8975f5c5SAndroid Build Coastguard Worker // Read cull distance varyings in fragment shaders
TEST_P(ClipCullDistanceTest,CullInterpolation)2183*8975f5c5SAndroid Build Coastguard Worker TEST_P(ClipCullDistanceTest, CullInterpolation)
2184*8975f5c5SAndroid Build Coastguard Worker {
2185*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled(kExtensionName));
2186*8975f5c5SAndroid Build Coastguard Worker
2187*8975f5c5SAndroid Build Coastguard Worker std::string kVS = R"(#version 300 es
2188*8975f5c5SAndroid Build Coastguard Worker #extension )" + kExtensionName +
2189*8975f5c5SAndroid Build Coastguard Worker R"( : require
2190*8975f5c5SAndroid Build Coastguard Worker in vec2 a_position;
2191*8975f5c5SAndroid Build Coastguard Worker void main()
2192*8975f5c5SAndroid Build Coastguard Worker {
2193*8975f5c5SAndroid Build Coastguard Worker gl_Position = vec4(a_position, 0.0, 1.0);
2194*8975f5c5SAndroid Build Coastguard Worker gl_CullDistance[0] = dot(gl_Position, vec4( 1, 0, 0, 1));
2195*8975f5c5SAndroid Build Coastguard Worker gl_CullDistance[1] = dot(gl_Position, vec4(-1, 0, 0, 1));
2196*8975f5c5SAndroid Build Coastguard Worker gl_CullDistance[2] = dot(gl_Position, vec4( 0, 1, 0, 1));
2197*8975f5c5SAndroid Build Coastguard Worker gl_CullDistance[3] = dot(gl_Position, vec4( 0, -1, 0, 1));
2198*8975f5c5SAndroid Build Coastguard Worker gl_CullDistance[4] = gl_CullDistance[0];
2199*8975f5c5SAndroid Build Coastguard Worker gl_CullDistance[5] = gl_CullDistance[1];
2200*8975f5c5SAndroid Build Coastguard Worker gl_CullDistance[6] = gl_CullDistance[2];
2201*8975f5c5SAndroid Build Coastguard Worker gl_CullDistance[7] = gl_CullDistance[3];
2202*8975f5c5SAndroid Build Coastguard Worker })";
2203*8975f5c5SAndroid Build Coastguard Worker
2204*8975f5c5SAndroid Build Coastguard Worker std::string kFS = R"(#version 300 es
2205*8975f5c5SAndroid Build Coastguard Worker #extension )" + kExtensionName +
2206*8975f5c5SAndroid Build Coastguard Worker R"( : require
2207*8975f5c5SAndroid Build Coastguard Worker precision highp float;
2208*8975f5c5SAndroid Build Coastguard Worker out vec4 my_FragColor;
2209*8975f5c5SAndroid Build Coastguard Worker void main()
2210*8975f5c5SAndroid Build Coastguard Worker {
2211*8975f5c5SAndroid Build Coastguard Worker float r = gl_CullDistance[0] + gl_CullDistance[1];
2212*8975f5c5SAndroid Build Coastguard Worker float g = gl_CullDistance[2] + gl_CullDistance[3];
2213*8975f5c5SAndroid Build Coastguard Worker float b = gl_CullDistance[4] + gl_CullDistance[5];
2214*8975f5c5SAndroid Build Coastguard Worker float a = gl_CullDistance[6] + gl_CullDistance[7];
2215*8975f5c5SAndroid Build Coastguard Worker my_FragColor = vec4(r, g, b, a) * 0.25;
2216*8975f5c5SAndroid Build Coastguard Worker })";
2217*8975f5c5SAndroid Build Coastguard Worker
2218*8975f5c5SAndroid Build Coastguard Worker GLProgram programRed;
2219*8975f5c5SAndroid Build Coastguard Worker programRed.makeRaster(kVS.c_str(), kFS.c_str());
2220*8975f5c5SAndroid Build Coastguard Worker if (!mCullDistanceSupportRequired)
2221*8975f5c5SAndroid Build Coastguard Worker {
2222*8975f5c5SAndroid Build Coastguard Worker GLint maxCullDistances;
2223*8975f5c5SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_CULL_DISTANCES_EXT, &maxCullDistances);
2224*8975f5c5SAndroid Build Coastguard Worker if (maxCullDistances == 0)
2225*8975f5c5SAndroid Build Coastguard Worker {
2226*8975f5c5SAndroid Build Coastguard Worker ASSERT_FALSE(programRed.valid());
2227*8975f5c5SAndroid Build Coastguard Worker return;
2228*8975f5c5SAndroid Build Coastguard Worker }
2229*8975f5c5SAndroid Build Coastguard Worker }
2230*8975f5c5SAndroid Build Coastguard Worker glUseProgram(programRed);
2231*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
2232*8975f5c5SAndroid Build Coastguard Worker
2233*8975f5c5SAndroid Build Coastguard Worker // Clear to blue
2234*8975f5c5SAndroid Build Coastguard Worker glClearColor(0, 0, 1, 1);
2235*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
2236*8975f5c5SAndroid Build Coastguard Worker
2237*8975f5c5SAndroid Build Coastguard Worker // Draw full screen quad with color red
2238*8975f5c5SAndroid Build Coastguard Worker drawQuad(programRed, "a_position", 0, 0.5);
2239*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
2240*8975f5c5SAndroid Build Coastguard Worker
2241*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> actualColors(getWindowWidth() * getWindowHeight());
2242*8975f5c5SAndroid Build Coastguard Worker glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
2243*8975f5c5SAndroid Build Coastguard Worker actualColors.data());
2244*8975f5c5SAndroid Build Coastguard Worker for (int x = 0; x < getWindowWidth(); x++)
2245*8975f5c5SAndroid Build Coastguard Worker {
2246*8975f5c5SAndroid Build Coastguard Worker for (int y = 0; y < getWindowHeight(); y++)
2247*8975f5c5SAndroid Build Coastguard Worker {
2248*8975f5c5SAndroid Build Coastguard Worker const int currentPosition = y * getWindowHeight() + x;
2249*8975f5c5SAndroid Build Coastguard Worker
2250*8975f5c5SAndroid Build Coastguard Worker if (x >= getWindowWidth() / 4 && x < getWindowWidth() * 3 / 4 &&
2251*8975f5c5SAndroid Build Coastguard Worker y >= getWindowHeight() / 4 && y < getWindowHeight() * 3 / 4)
2252*8975f5c5SAndroid Build Coastguard Worker {
2253*8975f5c5SAndroid Build Coastguard Worker EXPECT_COLOR_NEAR(GLColor(127, 127, 127, 127), actualColors[currentPosition], 1);
2254*8975f5c5SAndroid Build Coastguard Worker }
2255*8975f5c5SAndroid Build Coastguard Worker else
2256*8975f5c5SAndroid Build Coastguard Worker {
2257*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(GLColor::blue, actualColors[currentPosition]);
2258*8975f5c5SAndroid Build Coastguard Worker }
2259*8975f5c5SAndroid Build Coastguard Worker }
2260*8975f5c5SAndroid Build Coastguard Worker }
2261*8975f5c5SAndroid Build Coastguard Worker }
2262*8975f5c5SAndroid Build Coastguard Worker
2263*8975f5c5SAndroid Build Coastguard Worker // Read both clip and cull distance varyings in fragment shaders
TEST_P(ClipCullDistanceTest,ClipCullInterpolation)2264*8975f5c5SAndroid Build Coastguard Worker TEST_P(ClipCullDistanceTest, ClipCullInterpolation)
2265*8975f5c5SAndroid Build Coastguard Worker {
2266*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled(kExtensionName));
2267*8975f5c5SAndroid Build Coastguard Worker
2268*8975f5c5SAndroid Build Coastguard Worker std::string kVS = R"(#version 300 es
2269*8975f5c5SAndroid Build Coastguard Worker #extension )" + kExtensionName +
2270*8975f5c5SAndroid Build Coastguard Worker R"( : require
2271*8975f5c5SAndroid Build Coastguard Worker in vec2 a_position;
2272*8975f5c5SAndroid Build Coastguard Worker void main()
2273*8975f5c5SAndroid Build Coastguard Worker {
2274*8975f5c5SAndroid Build Coastguard Worker gl_Position = vec4(a_position, 0.0, 1.0);
2275*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[0] = dot(gl_Position, vec4( 1, 0, 0, 0.5));
2276*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[1] = dot(gl_Position, vec4(-1, 0, 0, 0.5));
2277*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[2] = dot(gl_Position, vec4( 0, 1, 0, 0.5));
2278*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[3] = dot(gl_Position, vec4( 0, -1, 0, 0.5));
2279*8975f5c5SAndroid Build Coastguard Worker gl_CullDistance[0] = dot(gl_Position, vec4( 1, 0, 0, 1));
2280*8975f5c5SAndroid Build Coastguard Worker gl_CullDistance[1] = dot(gl_Position, vec4(-1, 0, 0, 1));
2281*8975f5c5SAndroid Build Coastguard Worker gl_CullDistance[2] = dot(gl_Position, vec4( 0, 1, 0, 1));
2282*8975f5c5SAndroid Build Coastguard Worker gl_CullDistance[3] = dot(gl_Position, vec4( 0, -1, 0, 1));
2283*8975f5c5SAndroid Build Coastguard Worker })";
2284*8975f5c5SAndroid Build Coastguard Worker
2285*8975f5c5SAndroid Build Coastguard Worker std::string kFS = R"(#version 300 es
2286*8975f5c5SAndroid Build Coastguard Worker #extension )" + kExtensionName +
2287*8975f5c5SAndroid Build Coastguard Worker R"( : require
2288*8975f5c5SAndroid Build Coastguard Worker precision highp float;
2289*8975f5c5SAndroid Build Coastguard Worker out vec4 my_FragColor;
2290*8975f5c5SAndroid Build Coastguard Worker void main()
2291*8975f5c5SAndroid Build Coastguard Worker {
2292*8975f5c5SAndroid Build Coastguard Worker my_FragColor =
2293*8975f5c5SAndroid Build Coastguard Worker vec4(gl_ClipDistance[0] + gl_ClipDistance[1],
2294*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[2] + gl_ClipDistance[3],
2295*8975f5c5SAndroid Build Coastguard Worker gl_CullDistance[0] + gl_CullDistance[1],
2296*8975f5c5SAndroid Build Coastguard Worker gl_CullDistance[2] + gl_CullDistance[3]) *
2297*8975f5c5SAndroid Build Coastguard Worker vec4(0.5, 0.5, 0.25, 0.25);
2298*8975f5c5SAndroid Build Coastguard Worker })";
2299*8975f5c5SAndroid Build Coastguard Worker
2300*8975f5c5SAndroid Build Coastguard Worker GLProgram programRed;
2301*8975f5c5SAndroid Build Coastguard Worker programRed.makeRaster(kVS.c_str(), kFS.c_str());
2302*8975f5c5SAndroid Build Coastguard Worker if (!mCullDistanceSupportRequired)
2303*8975f5c5SAndroid Build Coastguard Worker {
2304*8975f5c5SAndroid Build Coastguard Worker GLint maxCullDistances;
2305*8975f5c5SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_CULL_DISTANCES_EXT, &maxCullDistances);
2306*8975f5c5SAndroid Build Coastguard Worker if (maxCullDistances == 0)
2307*8975f5c5SAndroid Build Coastguard Worker {
2308*8975f5c5SAndroid Build Coastguard Worker ASSERT_FALSE(programRed.valid());
2309*8975f5c5SAndroid Build Coastguard Worker return;
2310*8975f5c5SAndroid Build Coastguard Worker }
2311*8975f5c5SAndroid Build Coastguard Worker }
2312*8975f5c5SAndroid Build Coastguard Worker glUseProgram(programRed);
2313*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
2314*8975f5c5SAndroid Build Coastguard Worker
2315*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE0_EXT);
2316*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE1_EXT);
2317*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE2_EXT);
2318*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE3_EXT);
2319*8975f5c5SAndroid Build Coastguard Worker
2320*8975f5c5SAndroid Build Coastguard Worker // Clear to blue
2321*8975f5c5SAndroid Build Coastguard Worker glClearColor(0, 0, 1, 1);
2322*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
2323*8975f5c5SAndroid Build Coastguard Worker
2324*8975f5c5SAndroid Build Coastguard Worker // Draw full screen quad with color red
2325*8975f5c5SAndroid Build Coastguard Worker drawQuad(programRed, "a_position", 0);
2326*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
2327*8975f5c5SAndroid Build Coastguard Worker
2328*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> actualColors(getWindowWidth() * getWindowHeight());
2329*8975f5c5SAndroid Build Coastguard Worker glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
2330*8975f5c5SAndroid Build Coastguard Worker actualColors.data());
2331*8975f5c5SAndroid Build Coastguard Worker for (int x = 0; x < getWindowWidth(); x++)
2332*8975f5c5SAndroid Build Coastguard Worker {
2333*8975f5c5SAndroid Build Coastguard Worker for (int y = 0; y < getWindowHeight(); y++)
2334*8975f5c5SAndroid Build Coastguard Worker {
2335*8975f5c5SAndroid Build Coastguard Worker const int currentPosition = y * getWindowHeight() + x;
2336*8975f5c5SAndroid Build Coastguard Worker
2337*8975f5c5SAndroid Build Coastguard Worker if (x >= getWindowWidth() / 4 && x < getWindowWidth() * 3 / 4 &&
2338*8975f5c5SAndroid Build Coastguard Worker y >= getWindowHeight() / 4 && y < getWindowHeight() * 3 / 4)
2339*8975f5c5SAndroid Build Coastguard Worker {
2340*8975f5c5SAndroid Build Coastguard Worker EXPECT_COLOR_NEAR(GLColor(127, 127, 127, 127), actualColors[currentPosition], 1);
2341*8975f5c5SAndroid Build Coastguard Worker }
2342*8975f5c5SAndroid Build Coastguard Worker else
2343*8975f5c5SAndroid Build Coastguard Worker {
2344*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(GLColor::blue, actualColors[currentPosition]);
2345*8975f5c5SAndroid Build Coastguard Worker }
2346*8975f5c5SAndroid Build Coastguard Worker }
2347*8975f5c5SAndroid Build Coastguard Worker }
2348*8975f5c5SAndroid Build Coastguard Worker }
2349*8975f5c5SAndroid Build Coastguard Worker
2350*8975f5c5SAndroid Build Coastguard Worker // Write to 4 clip distances
TEST_P(ClipCullDistanceTest,FourClipDistances)2351*8975f5c5SAndroid Build Coastguard Worker TEST_P(ClipCullDistanceTest, FourClipDistances)
2352*8975f5c5SAndroid Build Coastguard Worker {
2353*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled(kExtensionName));
2354*8975f5c5SAndroid Build Coastguard Worker
2355*8975f5c5SAndroid Build Coastguard Worker std::string kVS = R"(#version 300 es
2356*8975f5c5SAndroid Build Coastguard Worker #extension )" + kExtensionName +
2357*8975f5c5SAndroid Build Coastguard Worker R"( : require
2358*8975f5c5SAndroid Build Coastguard Worker
2359*8975f5c5SAndroid Build Coastguard Worker in vec2 a_position;
2360*8975f5c5SAndroid Build Coastguard Worker uniform vec4 u_plane[4];
2361*8975f5c5SAndroid Build Coastguard Worker
2362*8975f5c5SAndroid Build Coastguard Worker void main()
2363*8975f5c5SAndroid Build Coastguard Worker {
2364*8975f5c5SAndroid Build Coastguard Worker gl_Position = vec4(a_position, 0.0, 1.0);
2365*8975f5c5SAndroid Build Coastguard Worker
2366*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[0] = dot(gl_Position, u_plane[0]);
2367*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[1] = dot(gl_Position, u_plane[1]);
2368*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[2] = dot(gl_Position, u_plane[2]);
2369*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[3] = dot(gl_Position, u_plane[3]);
2370*8975f5c5SAndroid Build Coastguard Worker })";
2371*8975f5c5SAndroid Build Coastguard Worker
2372*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_PROGRAM(programRed, kVS.c_str(), essl3_shaders::fs::Red());
2373*8975f5c5SAndroid Build Coastguard Worker glUseProgram(programRed);
2374*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
2375*8975f5c5SAndroid Build Coastguard Worker
2376*8975f5c5SAndroid Build Coastguard Worker // Enable 3 clip distances
2377*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE0_EXT);
2378*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE2_EXT);
2379*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE3_EXT);
2380*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
2381*8975f5c5SAndroid Build Coastguard Worker
2382*8975f5c5SAndroid Build Coastguard Worker // Disable 1 clip distances
2383*8975f5c5SAndroid Build Coastguard Worker glDisable(GL_CLIP_DISTANCE1_EXT);
2384*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
2385*8975f5c5SAndroid Build Coastguard Worker
2386*8975f5c5SAndroid Build Coastguard Worker // Clear to blue
2387*8975f5c5SAndroid Build Coastguard Worker glClearColor(0, 0, 1, 1);
2388*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
2389*8975f5c5SAndroid Build Coastguard Worker
2390*8975f5c5SAndroid Build Coastguard Worker constexpr unsigned int kNumVertices = 12;
2391*8975f5c5SAndroid Build Coastguard Worker const std::array<Vector3, kNumVertices> quadVertices = {
2392*8975f5c5SAndroid Build Coastguard Worker {Vector3(-1.0f, 1.0f, 0.0f), Vector3(0.0f, 0.0f, 0.0f), Vector3(1.0f, 1.0f, 0.0f),
2393*8975f5c5SAndroid Build Coastguard Worker Vector3(1.0f, 1.0f, 0.0f), Vector3(0.0f, 0.0f, 0.0f), Vector3(1.0f, -1.0f, 0.0f),
2394*8975f5c5SAndroid Build Coastguard Worker Vector3(1.0f, -1.0f, 0.0f), Vector3(0.0f, 0.0f, 0.0f), Vector3(-1.0f, -1.0f, 0.0f),
2395*8975f5c5SAndroid Build Coastguard Worker Vector3(-1.0f, -1.0f, 0.0f), Vector3(0.0f, 0.0f, 0.0f), Vector3(-1.0f, 1.0f, 0.0f)}};
2396*8975f5c5SAndroid Build Coastguard Worker
2397*8975f5c5SAndroid Build Coastguard Worker GLBuffer vertexBuffer;
2398*8975f5c5SAndroid Build Coastguard Worker glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
2399*8975f5c5SAndroid Build Coastguard Worker glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * kNumVertices, quadVertices.data(),
2400*8975f5c5SAndroid Build Coastguard Worker GL_STATIC_DRAW);
2401*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
2402*8975f5c5SAndroid Build Coastguard Worker
2403*8975f5c5SAndroid Build Coastguard Worker GLint positionLocation = glGetAttribLocation(programRed, "a_position");
2404*8975f5c5SAndroid Build Coastguard Worker glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
2405*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
2406*8975f5c5SAndroid Build Coastguard Worker
2407*8975f5c5SAndroid Build Coastguard Worker glEnableVertexAttribArray(positionLocation);
2408*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
2409*8975f5c5SAndroid Build Coastguard Worker
2410*8975f5c5SAndroid Build Coastguard Worker // Draw full screen quad and small size triangle with color red
2411*8975f5c5SAndroid Build Coastguard Worker // y <= 1.0f
2412*8975f5c5SAndroid Build Coastguard Worker glUniform4f(glGetUniformLocation(programRed, "u_plane[0]"), 0, -1, 0, 1);
2413*8975f5c5SAndroid Build Coastguard Worker // y >= 0.5f
2414*8975f5c5SAndroid Build Coastguard Worker glUniform4f(glGetUniformLocation(programRed, "u_plane[1]"), 0, 1, 0, -0.5);
2415*8975f5c5SAndroid Build Coastguard Worker // y >= 3x-0.5f
2416*8975f5c5SAndroid Build Coastguard Worker glUniform4f(glGetUniformLocation(programRed, "u_plane[2]"), -3, 1, 0, 0.5);
2417*8975f5c5SAndroid Build Coastguard Worker // y >= -3x-0.5f
2418*8975f5c5SAndroid Build Coastguard Worker glUniform4f(glGetUniformLocation(programRed, "u_plane[3]"), 3, 1, 0, 0.5);
2419*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
2420*8975f5c5SAndroid Build Coastguard Worker
2421*8975f5c5SAndroid Build Coastguard Worker glDrawArrays(GL_TRIANGLES, 0, kNumVertices);
2422*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
2423*8975f5c5SAndroid Build Coastguard Worker
2424*8975f5c5SAndroid Build Coastguard Worker const int windowWidth = getWindowWidth();
2425*8975f5c5SAndroid Build Coastguard Worker const int windowHeight = getWindowHeight();
2426*8975f5c5SAndroid Build Coastguard Worker auto checkLeftPlaneFunc = [windowWidth, windowHeight](int x, int y) -> float {
2427*8975f5c5SAndroid Build Coastguard Worker return (3 * (x - (windowWidth / 2 - 1)) - (windowHeight / 4 + 1) + y);
2428*8975f5c5SAndroid Build Coastguard Worker };
2429*8975f5c5SAndroid Build Coastguard Worker auto checkRightPlaneFunc = [windowWidth, windowHeight](int x, int y) -> float {
2430*8975f5c5SAndroid Build Coastguard Worker return (-3 * (x - (windowWidth / 2)) - (windowHeight / 4 + 1) + y);
2431*8975f5c5SAndroid Build Coastguard Worker };
2432*8975f5c5SAndroid Build Coastguard Worker
2433*8975f5c5SAndroid Build Coastguard Worker // Only pixels in the triangle must be red
2434*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> actualColors(getWindowWidth() * getWindowHeight());
2435*8975f5c5SAndroid Build Coastguard Worker glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
2436*8975f5c5SAndroid Build Coastguard Worker actualColors.data());
2437*8975f5c5SAndroid Build Coastguard Worker for (int x = 0; x < getWindowWidth(); ++x)
2438*8975f5c5SAndroid Build Coastguard Worker {
2439*8975f5c5SAndroid Build Coastguard Worker for (int y = 0; y < getWindowHeight(); ++y)
2440*8975f5c5SAndroid Build Coastguard Worker {
2441*8975f5c5SAndroid Build Coastguard Worker // The drawing method of Swiftshader and Native graphic card is different. So the
2442*8975f5c5SAndroid Build Coastguard Worker // compare function doesn't check the value on the line.
2443*8975f5c5SAndroid Build Coastguard Worker const int currentPosition = y * getWindowHeight() + x;
2444*8975f5c5SAndroid Build Coastguard Worker
2445*8975f5c5SAndroid Build Coastguard Worker if (checkLeftPlaneFunc(x, y) > 0 && checkRightPlaneFunc(x, y) > 0)
2446*8975f5c5SAndroid Build Coastguard Worker {
2447*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(GLColor::red, actualColors[currentPosition]);
2448*8975f5c5SAndroid Build Coastguard Worker }
2449*8975f5c5SAndroid Build Coastguard Worker else if (checkLeftPlaneFunc(x, y) < 0 || checkRightPlaneFunc(x, y) < 0)
2450*8975f5c5SAndroid Build Coastguard Worker {
2451*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(GLColor::blue, actualColors[currentPosition]);
2452*8975f5c5SAndroid Build Coastguard Worker }
2453*8975f5c5SAndroid Build Coastguard Worker }
2454*8975f5c5SAndroid Build Coastguard Worker }
2455*8975f5c5SAndroid Build Coastguard Worker }
2456*8975f5c5SAndroid Build Coastguard Worker
2457*8975f5c5SAndroid Build Coastguard Worker // Write to 4 cull distances
TEST_P(ClipCullDistanceTest,FourCullDistances)2458*8975f5c5SAndroid Build Coastguard Worker TEST_P(ClipCullDistanceTest, FourCullDistances)
2459*8975f5c5SAndroid Build Coastguard Worker {
2460*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled(kExtensionName));
2461*8975f5c5SAndroid Build Coastguard Worker
2462*8975f5c5SAndroid Build Coastguard Worker // SwiftShader bug: http://anglebug.com/42263990
2463*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(isSwiftshader());
2464*8975f5c5SAndroid Build Coastguard Worker
2465*8975f5c5SAndroid Build Coastguard Worker std::string kVS = R"(#version 300 es
2466*8975f5c5SAndroid Build Coastguard Worker #extension )" + kExtensionName +
2467*8975f5c5SAndroid Build Coastguard Worker R"( : require
2468*8975f5c5SAndroid Build Coastguard Worker
2469*8975f5c5SAndroid Build Coastguard Worker uniform vec4 u_plane[4];
2470*8975f5c5SAndroid Build Coastguard Worker
2471*8975f5c5SAndroid Build Coastguard Worker in vec2 a_position;
2472*8975f5c5SAndroid Build Coastguard Worker
2473*8975f5c5SAndroid Build Coastguard Worker void main()
2474*8975f5c5SAndroid Build Coastguard Worker {
2475*8975f5c5SAndroid Build Coastguard Worker gl_Position = vec4(a_position, 0.0, 1.0);
2476*8975f5c5SAndroid Build Coastguard Worker
2477*8975f5c5SAndroid Build Coastguard Worker gl_CullDistance[0] = dot(gl_Position, u_plane[0]);
2478*8975f5c5SAndroid Build Coastguard Worker gl_CullDistance[1] = dot(gl_Position, u_plane[1]);
2479*8975f5c5SAndroid Build Coastguard Worker gl_CullDistance[2] = dot(gl_Position, u_plane[2]);
2480*8975f5c5SAndroid Build Coastguard Worker gl_CullDistance[3] = dot(gl_Position, u_plane[3]);
2481*8975f5c5SAndroid Build Coastguard Worker })";
2482*8975f5c5SAndroid Build Coastguard Worker
2483*8975f5c5SAndroid Build Coastguard Worker GLProgram programRed;
2484*8975f5c5SAndroid Build Coastguard Worker programRed.makeRaster(kVS.c_str(), essl3_shaders::fs::Red());
2485*8975f5c5SAndroid Build Coastguard Worker if (!mCullDistanceSupportRequired)
2486*8975f5c5SAndroid Build Coastguard Worker {
2487*8975f5c5SAndroid Build Coastguard Worker GLint maxCullDistances;
2488*8975f5c5SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_CULL_DISTANCES_EXT, &maxCullDistances);
2489*8975f5c5SAndroid Build Coastguard Worker if (maxCullDistances == 0)
2490*8975f5c5SAndroid Build Coastguard Worker {
2491*8975f5c5SAndroid Build Coastguard Worker ASSERT_FALSE(programRed.valid());
2492*8975f5c5SAndroid Build Coastguard Worker return;
2493*8975f5c5SAndroid Build Coastguard Worker }
2494*8975f5c5SAndroid Build Coastguard Worker }
2495*8975f5c5SAndroid Build Coastguard Worker glUseProgram(programRed);
2496*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
2497*8975f5c5SAndroid Build Coastguard Worker
2498*8975f5c5SAndroid Build Coastguard Worker // Clear to blue
2499*8975f5c5SAndroid Build Coastguard Worker glClearColor(0, 0, 1, 1);
2500*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
2501*8975f5c5SAndroid Build Coastguard Worker
2502*8975f5c5SAndroid Build Coastguard Worker constexpr unsigned int kNumVertices = 12;
2503*8975f5c5SAndroid Build Coastguard Worker const std::array<Vector2, kNumVertices> quadVertices = {
2504*8975f5c5SAndroid Build Coastguard Worker {Vector2(-1.0f, 1.0f), Vector2(0.0f, 0.0f), Vector2(1.0f, 1.0f), Vector2(1.0f, 1.0f),
2505*8975f5c5SAndroid Build Coastguard Worker Vector2(0.0f, 0.0f), Vector2(1.0f, -1.0f), Vector2(1.0f, -1.0f), Vector2(0.0f, 0.0f),
2506*8975f5c5SAndroid Build Coastguard Worker Vector2(-1.0f, -1.0f), Vector2(-1.0f, -1.0f), Vector2(0.0f, 0.0f), Vector2(-1.0f, 1.0f)}};
2507*8975f5c5SAndroid Build Coastguard Worker
2508*8975f5c5SAndroid Build Coastguard Worker GLBuffer vertexBuffer;
2509*8975f5c5SAndroid Build Coastguard Worker glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
2510*8975f5c5SAndroid Build Coastguard Worker glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 2 * kNumVertices, quadVertices.data(),
2511*8975f5c5SAndroid Build Coastguard Worker GL_STATIC_DRAW);
2512*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
2513*8975f5c5SAndroid Build Coastguard Worker
2514*8975f5c5SAndroid Build Coastguard Worker GLint positionLocation = glGetAttribLocation(programRed, "a_position");
2515*8975f5c5SAndroid Build Coastguard Worker glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, 0);
2516*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
2517*8975f5c5SAndroid Build Coastguard Worker
2518*8975f5c5SAndroid Build Coastguard Worker glEnableVertexAttribArray(positionLocation);
2519*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
2520*8975f5c5SAndroid Build Coastguard Worker
2521*8975f5c5SAndroid Build Coastguard Worker // Draw full screen quad and small size triangle with color red
2522*8975f5c5SAndroid Build Coastguard Worker // y <= 1.0f
2523*8975f5c5SAndroid Build Coastguard Worker glUniform4f(glGetUniformLocation(programRed, "u_plane[0]"), 0, -1, 0, 1);
2524*8975f5c5SAndroid Build Coastguard Worker // y >= 0.5f
2525*8975f5c5SAndroid Build Coastguard Worker glUniform4f(glGetUniformLocation(programRed, "u_plane[1]"), 0, 1, 0, -0.5);
2526*8975f5c5SAndroid Build Coastguard Worker // y >= 3x-0.5f
2527*8975f5c5SAndroid Build Coastguard Worker glUniform4f(glGetUniformLocation(programRed, "u_plane[2]"), -3, 1, 0, 0.5);
2528*8975f5c5SAndroid Build Coastguard Worker // y >= -3x-0.5f
2529*8975f5c5SAndroid Build Coastguard Worker glUniform4f(glGetUniformLocation(programRed, "u_plane[3]"), 3, 1, 0, 0.5);
2530*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
2531*8975f5c5SAndroid Build Coastguard Worker
2532*8975f5c5SAndroid Build Coastguard Worker glDrawArrays(GL_TRIANGLES, 0, kNumVertices);
2533*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
2534*8975f5c5SAndroid Build Coastguard Worker
2535*8975f5c5SAndroid Build Coastguard Worker // Only the bottom triangle must be culled
2536*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> actualColors(getWindowWidth() * getWindowHeight());
2537*8975f5c5SAndroid Build Coastguard Worker glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
2538*8975f5c5SAndroid Build Coastguard Worker actualColors.data());
2539*8975f5c5SAndroid Build Coastguard Worker for (int x = 0; x < getWindowWidth(); ++x)
2540*8975f5c5SAndroid Build Coastguard Worker {
2541*8975f5c5SAndroid Build Coastguard Worker for (int y = 0; y < getWindowHeight(); ++y)
2542*8975f5c5SAndroid Build Coastguard Worker {
2543*8975f5c5SAndroid Build Coastguard Worker const int currentPosition = y * getWindowHeight() + x;
2544*8975f5c5SAndroid Build Coastguard Worker
2545*8975f5c5SAndroid Build Coastguard Worker if (y > x || y >= -x + getWindowHeight() - 1)
2546*8975f5c5SAndroid Build Coastguard Worker {
2547*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(GLColor::red, actualColors[currentPosition]);
2548*8975f5c5SAndroid Build Coastguard Worker }
2549*8975f5c5SAndroid Build Coastguard Worker else
2550*8975f5c5SAndroid Build Coastguard Worker {
2551*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(GLColor::blue, actualColors[currentPosition]);
2552*8975f5c5SAndroid Build Coastguard Worker }
2553*8975f5c5SAndroid Build Coastguard Worker }
2554*8975f5c5SAndroid Build Coastguard Worker }
2555*8975f5c5SAndroid Build Coastguard Worker }
2556*8975f5c5SAndroid Build Coastguard Worker
2557*8975f5c5SAndroid Build Coastguard Worker // Verify that EXT_clip_cull_distance works with EXT_geometry_shader
TEST_P(ClipCullDistanceTest,ClipDistanceInteractWithGeometryShader)2558*8975f5c5SAndroid Build Coastguard Worker TEST_P(ClipCullDistanceTest, ClipDistanceInteractWithGeometryShader)
2559*8975f5c5SAndroid Build Coastguard Worker {
2560*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled(kExtensionName) ||
2561*8975f5c5SAndroid Build Coastguard Worker !EnsureGLExtensionEnabled("GL_EXT_geometry_shader"));
2562*8975f5c5SAndroid Build Coastguard Worker
2563*8975f5c5SAndroid Build Coastguard Worker std::string kVS = R"(#version 310 es
2564*8975f5c5SAndroid Build Coastguard Worker #extension )" + kExtensionName +
2565*8975f5c5SAndroid Build Coastguard Worker R"( : require
2566*8975f5c5SAndroid Build Coastguard Worker #extension GL_EXT_geometry_shader : require
2567*8975f5c5SAndroid Build Coastguard Worker
2568*8975f5c5SAndroid Build Coastguard Worker in vec2 a_position;
2569*8975f5c5SAndroid Build Coastguard Worker uniform vec4 u_plane[4];
2570*8975f5c5SAndroid Build Coastguard Worker
2571*8975f5c5SAndroid Build Coastguard Worker void main()
2572*8975f5c5SAndroid Build Coastguard Worker {
2573*8975f5c5SAndroid Build Coastguard Worker gl_Position = vec4(a_position, 0.0, 1.0);
2574*8975f5c5SAndroid Build Coastguard Worker
2575*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[0] = dot(gl_Position, u_plane[0]);
2576*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[1] = dot(gl_Position, u_plane[1]);
2577*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[2] = dot(gl_Position, u_plane[2]);
2578*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[3] = dot(gl_Position, u_plane[3]);
2579*8975f5c5SAndroid Build Coastguard Worker })";
2580*8975f5c5SAndroid Build Coastguard Worker
2581*8975f5c5SAndroid Build Coastguard Worker std::string kGS = R"(#version 310 es
2582*8975f5c5SAndroid Build Coastguard Worker #extension )" + kExtensionName +
2583*8975f5c5SAndroid Build Coastguard Worker R"( : require
2584*8975f5c5SAndroid Build Coastguard Worker #extension GL_EXT_geometry_shader : require
2585*8975f5c5SAndroid Build Coastguard Worker
2586*8975f5c5SAndroid Build Coastguard Worker layout (triangles) in;
2587*8975f5c5SAndroid Build Coastguard Worker layout (triangle_strip, max_vertices = 3) out;
2588*8975f5c5SAndroid Build Coastguard Worker
2589*8975f5c5SAndroid Build Coastguard Worker in gl_PerVertex {
2590*8975f5c5SAndroid Build Coastguard Worker highp vec4 gl_Position;
2591*8975f5c5SAndroid Build Coastguard Worker highp float gl_ClipDistance[];
2592*8975f5c5SAndroid Build Coastguard Worker } gl_in[];
2593*8975f5c5SAndroid Build Coastguard Worker
2594*8975f5c5SAndroid Build Coastguard Worker out gl_PerVertex {
2595*8975f5c5SAndroid Build Coastguard Worker highp vec4 gl_Position;
2596*8975f5c5SAndroid Build Coastguard Worker highp float gl_ClipDistance[];
2597*8975f5c5SAndroid Build Coastguard Worker };
2598*8975f5c5SAndroid Build Coastguard Worker
2599*8975f5c5SAndroid Build Coastguard Worker uniform vec4 u_plane[4];
2600*8975f5c5SAndroid Build Coastguard Worker
2601*8975f5c5SAndroid Build Coastguard Worker void GetNewPosition(int i)
2602*8975f5c5SAndroid Build Coastguard Worker {
2603*8975f5c5SAndroid Build Coastguard Worker gl_Position = 2.0f * gl_in[i].gl_Position;
2604*8975f5c5SAndroid Build Coastguard Worker
2605*8975f5c5SAndroid Build Coastguard Worker for (int index = 0 ; index < 4 ; index++)
2606*8975f5c5SAndroid Build Coastguard Worker {
2607*8975f5c5SAndroid Build Coastguard Worker if (gl_in[i].gl_ClipDistance[index] < 0.0f)
2608*8975f5c5SAndroid Build Coastguard Worker {
2609*8975f5c5SAndroid Build Coastguard Worker gl_ClipDistance[index] = dot(gl_Position, u_plane[index]);
2610*8975f5c5SAndroid Build Coastguard Worker }
2611*8975f5c5SAndroid Build Coastguard Worker }
2612*8975f5c5SAndroid Build Coastguard Worker EmitVertex();
2613*8975f5c5SAndroid Build Coastguard Worker }
2614*8975f5c5SAndroid Build Coastguard Worker
2615*8975f5c5SAndroid Build Coastguard Worker void main()
2616*8975f5c5SAndroid Build Coastguard Worker {
2617*8975f5c5SAndroid Build Coastguard Worker for (int i = 0 ; i < 3 ; i++)
2618*8975f5c5SAndroid Build Coastguard Worker {
2619*8975f5c5SAndroid Build Coastguard Worker GetNewPosition(i);
2620*8975f5c5SAndroid Build Coastguard Worker }
2621*8975f5c5SAndroid Build Coastguard Worker EndPrimitive();
2622*8975f5c5SAndroid Build Coastguard Worker })";
2623*8975f5c5SAndroid Build Coastguard Worker
2624*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_PROGRAM_WITH_GS(programRed, kVS.c_str(), kGS.c_str(), essl31_shaders::fs::Red());
2625*8975f5c5SAndroid Build Coastguard Worker glUseProgram(programRed);
2626*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
2627*8975f5c5SAndroid Build Coastguard Worker
2628*8975f5c5SAndroid Build Coastguard Worker // Enable 3 clip distances
2629*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE0_EXT);
2630*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE2_EXT);
2631*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_CLIP_DISTANCE3_EXT);
2632*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
2633*8975f5c5SAndroid Build Coastguard Worker
2634*8975f5c5SAndroid Build Coastguard Worker // Disable 1 clip distances
2635*8975f5c5SAndroid Build Coastguard Worker glDisable(GL_CLIP_DISTANCE1_EXT);
2636*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
2637*8975f5c5SAndroid Build Coastguard Worker
2638*8975f5c5SAndroid Build Coastguard Worker // Clear to blue
2639*8975f5c5SAndroid Build Coastguard Worker glClearColor(0, 0, 1, 1);
2640*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
2641*8975f5c5SAndroid Build Coastguard Worker
2642*8975f5c5SAndroid Build Coastguard Worker constexpr unsigned int kNumVertices = 12;
2643*8975f5c5SAndroid Build Coastguard Worker const std::array<Vector3, kNumVertices> quadVertices = {
2644*8975f5c5SAndroid Build Coastguard Worker {Vector3(-0.5f, 0.5f, 0.0f), Vector3(0.0f, 0.0f, 0.0f), Vector3(0.5f, 0.5f, 0.0f),
2645*8975f5c5SAndroid Build Coastguard Worker Vector3(0.5f, 0.5f, 0.0f), Vector3(0.0f, 0.0f, 0.0f), Vector3(0.5f, -0.5f, 0.0f),
2646*8975f5c5SAndroid Build Coastguard Worker Vector3(0.5f, -0.5f, 0.0f), Vector3(0.0f, 0.0f, 0.0f), Vector3(-0.5f, -0.5f, 0.0f),
2647*8975f5c5SAndroid Build Coastguard Worker Vector3(-0.5f, -0.5f, 0.0f), Vector3(0.0f, 0.0f, 0.0f), Vector3(-0.5f, 0.5f, 0.0f)}};
2648*8975f5c5SAndroid Build Coastguard Worker
2649*8975f5c5SAndroid Build Coastguard Worker GLBuffer vertexBuffer;
2650*8975f5c5SAndroid Build Coastguard Worker glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
2651*8975f5c5SAndroid Build Coastguard Worker glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * kNumVertices, quadVertices.data(),
2652*8975f5c5SAndroid Build Coastguard Worker GL_STATIC_DRAW);
2653*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
2654*8975f5c5SAndroid Build Coastguard Worker
2655*8975f5c5SAndroid Build Coastguard Worker GLint positionLocation = glGetAttribLocation(programRed, "a_position");
2656*8975f5c5SAndroid Build Coastguard Worker glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
2657*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
2658*8975f5c5SAndroid Build Coastguard Worker
2659*8975f5c5SAndroid Build Coastguard Worker glEnableVertexAttribArray(positionLocation);
2660*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
2661*8975f5c5SAndroid Build Coastguard Worker
2662*8975f5c5SAndroid Build Coastguard Worker // Draw full screen quad and small size triangle with color red
2663*8975f5c5SAndroid Build Coastguard Worker // y <= 1.0f
2664*8975f5c5SAndroid Build Coastguard Worker glUniform4f(glGetUniformLocation(programRed, "u_plane[0]"), 0, -1, 0, 1);
2665*8975f5c5SAndroid Build Coastguard Worker // y >= 0.5f
2666*8975f5c5SAndroid Build Coastguard Worker glUniform4f(glGetUniformLocation(programRed, "u_plane[1]"), 0, 1, 0, -0.5);
2667*8975f5c5SAndroid Build Coastguard Worker // y >= 3x-0.5f
2668*8975f5c5SAndroid Build Coastguard Worker glUniform4f(glGetUniformLocation(programRed, "u_plane[2]"), -3, 1, 0, 0.5);
2669*8975f5c5SAndroid Build Coastguard Worker // y >= -3x-0.5f
2670*8975f5c5SAndroid Build Coastguard Worker glUniform4f(glGetUniformLocation(programRed, "u_plane[3]"), 3, 1, 0, 0.5);
2671*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
2672*8975f5c5SAndroid Build Coastguard Worker
2673*8975f5c5SAndroid Build Coastguard Worker glDrawArrays(GL_TRIANGLES, 0, kNumVertices);
2674*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
2675*8975f5c5SAndroid Build Coastguard Worker
2676*8975f5c5SAndroid Build Coastguard Worker const int windowWidth = getWindowWidth();
2677*8975f5c5SAndroid Build Coastguard Worker const int windowHeight = getWindowHeight();
2678*8975f5c5SAndroid Build Coastguard Worker auto checkLeftPlaneFunc = [windowWidth, windowHeight](int x, int y) -> float {
2679*8975f5c5SAndroid Build Coastguard Worker return (3 * (x - (windowWidth / 2 - 1)) - (windowHeight / 4 + 1) + y);
2680*8975f5c5SAndroid Build Coastguard Worker };
2681*8975f5c5SAndroid Build Coastguard Worker auto checkRightPlaneFunc = [windowWidth, windowHeight](int x, int y) -> float {
2682*8975f5c5SAndroid Build Coastguard Worker return (-3 * (x - (windowWidth / 2)) - (windowHeight / 4 + 1) + y);
2683*8975f5c5SAndroid Build Coastguard Worker };
2684*8975f5c5SAndroid Build Coastguard Worker
2685*8975f5c5SAndroid Build Coastguard Worker // Only pixels in the triangle must be red
2686*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> actualColors(getWindowWidth() * getWindowHeight());
2687*8975f5c5SAndroid Build Coastguard Worker glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
2688*8975f5c5SAndroid Build Coastguard Worker actualColors.data());
2689*8975f5c5SAndroid Build Coastguard Worker for (int x = 0; x < getWindowWidth(); ++x)
2690*8975f5c5SAndroid Build Coastguard Worker {
2691*8975f5c5SAndroid Build Coastguard Worker for (int y = 0; y < getWindowHeight(); ++y)
2692*8975f5c5SAndroid Build Coastguard Worker {
2693*8975f5c5SAndroid Build Coastguard Worker // The drawing method of Swiftshader and Native graphic card is different. So the
2694*8975f5c5SAndroid Build Coastguard Worker // compare function doesn't check the value on the line.
2695*8975f5c5SAndroid Build Coastguard Worker const int currentPosition = y * getWindowHeight() + x;
2696*8975f5c5SAndroid Build Coastguard Worker
2697*8975f5c5SAndroid Build Coastguard Worker if (checkLeftPlaneFunc(x, y) > 0 && checkRightPlaneFunc(x, y) > 0)
2698*8975f5c5SAndroid Build Coastguard Worker {
2699*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(GLColor::red, actualColors[currentPosition]);
2700*8975f5c5SAndroid Build Coastguard Worker }
2701*8975f5c5SAndroid Build Coastguard Worker else if (checkLeftPlaneFunc(x, y) < 0 || checkRightPlaneFunc(x, y) < 0)
2702*8975f5c5SAndroid Build Coastguard Worker {
2703*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(GLColor::blue, actualColors[currentPosition]);
2704*8975f5c5SAndroid Build Coastguard Worker }
2705*8975f5c5SAndroid Build Coastguard Worker }
2706*8975f5c5SAndroid Build Coastguard Worker }
2707*8975f5c5SAndroid Build Coastguard Worker }
2708*8975f5c5SAndroid Build Coastguard Worker
2709*8975f5c5SAndroid Build Coastguard Worker // Verify that EXT_clip_cull_distance works with EXT_geometry_shader
TEST_P(ClipCullDistanceTest,CullDistanceInteractWithGeometryShader)2710*8975f5c5SAndroid Build Coastguard Worker TEST_P(ClipCullDistanceTest, CullDistanceInteractWithGeometryShader)
2711*8975f5c5SAndroid Build Coastguard Worker {
2712*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled(kExtensionName) ||
2713*8975f5c5SAndroid Build Coastguard Worker !EnsureGLExtensionEnabled("GL_EXT_geometry_shader"));
2714*8975f5c5SAndroid Build Coastguard Worker
2715*8975f5c5SAndroid Build Coastguard Worker std::string kVS = R"(#version 310 es
2716*8975f5c5SAndroid Build Coastguard Worker #extension )" + kExtensionName +
2717*8975f5c5SAndroid Build Coastguard Worker R"( : require
2718*8975f5c5SAndroid Build Coastguard Worker #extension GL_EXT_geometry_shader : require
2719*8975f5c5SAndroid Build Coastguard Worker
2720*8975f5c5SAndroid Build Coastguard Worker in vec2 a_position;
2721*8975f5c5SAndroid Build Coastguard Worker uniform vec4 u_plane[4];
2722*8975f5c5SAndroid Build Coastguard Worker
2723*8975f5c5SAndroid Build Coastguard Worker void main()
2724*8975f5c5SAndroid Build Coastguard Worker {
2725*8975f5c5SAndroid Build Coastguard Worker gl_Position = vec4(a_position, 0.0, 1.0);
2726*8975f5c5SAndroid Build Coastguard Worker
2727*8975f5c5SAndroid Build Coastguard Worker gl_CullDistance[0] = dot(gl_Position, u_plane[0]);
2728*8975f5c5SAndroid Build Coastguard Worker gl_CullDistance[1] = dot(gl_Position, u_plane[1]);
2729*8975f5c5SAndroid Build Coastguard Worker gl_CullDistance[2] = dot(gl_Position, u_plane[2]);
2730*8975f5c5SAndroid Build Coastguard Worker gl_CullDistance[3] = dot(gl_Position, u_plane[3]);
2731*8975f5c5SAndroid Build Coastguard Worker })";
2732*8975f5c5SAndroid Build Coastguard Worker
2733*8975f5c5SAndroid Build Coastguard Worker std::string kGS = R"(#version 310 es
2734*8975f5c5SAndroid Build Coastguard Worker #extension )" + kExtensionName +
2735*8975f5c5SAndroid Build Coastguard Worker R"( : require
2736*8975f5c5SAndroid Build Coastguard Worker #extension GL_EXT_geometry_shader : require
2737*8975f5c5SAndroid Build Coastguard Worker
2738*8975f5c5SAndroid Build Coastguard Worker layout (triangles) in;
2739*8975f5c5SAndroid Build Coastguard Worker layout (triangle_strip, max_vertices = 3) out;
2740*8975f5c5SAndroid Build Coastguard Worker
2741*8975f5c5SAndroid Build Coastguard Worker in gl_PerVertex {
2742*8975f5c5SAndroid Build Coastguard Worker highp vec4 gl_Position;
2743*8975f5c5SAndroid Build Coastguard Worker highp float gl_CullDistance[];
2744*8975f5c5SAndroid Build Coastguard Worker } gl_in[];
2745*8975f5c5SAndroid Build Coastguard Worker
2746*8975f5c5SAndroid Build Coastguard Worker out gl_PerVertex {
2747*8975f5c5SAndroid Build Coastguard Worker highp vec4 gl_Position;
2748*8975f5c5SAndroid Build Coastguard Worker highp float gl_CullDistance[];
2749*8975f5c5SAndroid Build Coastguard Worker };
2750*8975f5c5SAndroid Build Coastguard Worker
2751*8975f5c5SAndroid Build Coastguard Worker uniform vec4 u_plane[4];
2752*8975f5c5SAndroid Build Coastguard Worker
2753*8975f5c5SAndroid Build Coastguard Worker void GetNewPosition(int i)
2754*8975f5c5SAndroid Build Coastguard Worker {
2755*8975f5c5SAndroid Build Coastguard Worker gl_Position = 2.0f * gl_in[i].gl_Position;
2756*8975f5c5SAndroid Build Coastguard Worker
2757*8975f5c5SAndroid Build Coastguard Worker for (int index = 0 ; index < 4 ; index++)
2758*8975f5c5SAndroid Build Coastguard Worker {
2759*8975f5c5SAndroid Build Coastguard Worker if (gl_in[i].gl_CullDistance[index] < 0.0f)
2760*8975f5c5SAndroid Build Coastguard Worker {
2761*8975f5c5SAndroid Build Coastguard Worker gl_CullDistance[index] = dot(gl_Position, u_plane[index]);
2762*8975f5c5SAndroid Build Coastguard Worker }
2763*8975f5c5SAndroid Build Coastguard Worker }
2764*8975f5c5SAndroid Build Coastguard Worker EmitVertex();
2765*8975f5c5SAndroid Build Coastguard Worker }
2766*8975f5c5SAndroid Build Coastguard Worker
2767*8975f5c5SAndroid Build Coastguard Worker void main()
2768*8975f5c5SAndroid Build Coastguard Worker {
2769*8975f5c5SAndroid Build Coastguard Worker for (int i = 0 ; i < 3 ; i++)
2770*8975f5c5SAndroid Build Coastguard Worker {
2771*8975f5c5SAndroid Build Coastguard Worker GetNewPosition(i);
2772*8975f5c5SAndroid Build Coastguard Worker }
2773*8975f5c5SAndroid Build Coastguard Worker EndPrimitive();
2774*8975f5c5SAndroid Build Coastguard Worker })";
2775*8975f5c5SAndroid Build Coastguard Worker
2776*8975f5c5SAndroid Build Coastguard Worker GLProgram programRed;
2777*8975f5c5SAndroid Build Coastguard Worker programRed.makeRaster(kVS.c_str(), kGS.c_str(), essl3_shaders::fs::Red());
2778*8975f5c5SAndroid Build Coastguard Worker if (!mCullDistanceSupportRequired)
2779*8975f5c5SAndroid Build Coastguard Worker {
2780*8975f5c5SAndroid Build Coastguard Worker GLint maxCullDistances;
2781*8975f5c5SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_CULL_DISTANCES_EXT, &maxCullDistances);
2782*8975f5c5SAndroid Build Coastguard Worker if (maxCullDistances == 0)
2783*8975f5c5SAndroid Build Coastguard Worker {
2784*8975f5c5SAndroid Build Coastguard Worker ASSERT_FALSE(programRed.valid());
2785*8975f5c5SAndroid Build Coastguard Worker return;
2786*8975f5c5SAndroid Build Coastguard Worker }
2787*8975f5c5SAndroid Build Coastguard Worker }
2788*8975f5c5SAndroid Build Coastguard Worker glUseProgram(programRed);
2789*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
2790*8975f5c5SAndroid Build Coastguard Worker
2791*8975f5c5SAndroid Build Coastguard Worker // Clear to blue
2792*8975f5c5SAndroid Build Coastguard Worker glClearColor(0, 0, 1, 1);
2793*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
2794*8975f5c5SAndroid Build Coastguard Worker
2795*8975f5c5SAndroid Build Coastguard Worker constexpr unsigned int kNumVertices = 12;
2796*8975f5c5SAndroid Build Coastguard Worker const std::array<Vector3, kNumVertices> quadVertices = {
2797*8975f5c5SAndroid Build Coastguard Worker {Vector3(-0.5f, 0.5f, 0.0f), Vector3(0.0f, 0.0f, 0.0f), Vector3(0.5f, 0.5f, 0.0f),
2798*8975f5c5SAndroid Build Coastguard Worker Vector3(0.5f, 0.5f, 0.0f), Vector3(0.0f, 0.0f, 0.0f), Vector3(0.5f, -0.5f, 0.0f),
2799*8975f5c5SAndroid Build Coastguard Worker Vector3(0.5f, -0.5f, 0.0f), Vector3(0.0f, 0.0f, 0.0f), Vector3(-0.5f, -0.5f, 0.0f),
2800*8975f5c5SAndroid Build Coastguard Worker Vector3(-0.5f, -0.5f, 0.0f), Vector3(0.0f, 0.0f, 0.0f), Vector3(-0.5f, 0.5f, 0.0f)}};
2801*8975f5c5SAndroid Build Coastguard Worker
2802*8975f5c5SAndroid Build Coastguard Worker GLBuffer vertexBuffer;
2803*8975f5c5SAndroid Build Coastguard Worker glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
2804*8975f5c5SAndroid Build Coastguard Worker glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * kNumVertices, quadVertices.data(),
2805*8975f5c5SAndroid Build Coastguard Worker GL_STATIC_DRAW);
2806*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
2807*8975f5c5SAndroid Build Coastguard Worker
2808*8975f5c5SAndroid Build Coastguard Worker GLint positionLocation = glGetAttribLocation(programRed, "a_position");
2809*8975f5c5SAndroid Build Coastguard Worker glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
2810*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
2811*8975f5c5SAndroid Build Coastguard Worker
2812*8975f5c5SAndroid Build Coastguard Worker glEnableVertexAttribArray(positionLocation);
2813*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
2814*8975f5c5SAndroid Build Coastguard Worker
2815*8975f5c5SAndroid Build Coastguard Worker // Draw full screen quad and small size triangle with color red
2816*8975f5c5SAndroid Build Coastguard Worker // y <= 1.0f
2817*8975f5c5SAndroid Build Coastguard Worker glUniform4f(glGetUniformLocation(programRed, "u_plane[0]"), 0, -1, 0, 1);
2818*8975f5c5SAndroid Build Coastguard Worker // y >= 0.5f
2819*8975f5c5SAndroid Build Coastguard Worker glUniform4f(glGetUniformLocation(programRed, "u_plane[1]"), 0, 1, 0, -0.5);
2820*8975f5c5SAndroid Build Coastguard Worker // y >= 3x-0.5f
2821*8975f5c5SAndroid Build Coastguard Worker glUniform4f(glGetUniformLocation(programRed, "u_plane[2]"), -3, 1, 0, 0.5);
2822*8975f5c5SAndroid Build Coastguard Worker // y >= -3x-0.5f
2823*8975f5c5SAndroid Build Coastguard Worker glUniform4f(glGetUniformLocation(programRed, "u_plane[3]"), 3, 1, 0, 0.5);
2824*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
2825*8975f5c5SAndroid Build Coastguard Worker
2826*8975f5c5SAndroid Build Coastguard Worker glDrawArrays(GL_TRIANGLES, 0, kNumVertices);
2827*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
2828*8975f5c5SAndroid Build Coastguard Worker
2829*8975f5c5SAndroid Build Coastguard Worker // Only pixels in the triangle must be red
2830*8975f5c5SAndroid Build Coastguard Worker std::vector<GLColor> actualColors(getWindowWidth() * getWindowHeight());
2831*8975f5c5SAndroid Build Coastguard Worker glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
2832*8975f5c5SAndroid Build Coastguard Worker actualColors.data());
2833*8975f5c5SAndroid Build Coastguard Worker for (int x = 0; x < getWindowWidth(); ++x)
2834*8975f5c5SAndroid Build Coastguard Worker {
2835*8975f5c5SAndroid Build Coastguard Worker for (int y = 0; y < getWindowHeight(); ++y)
2836*8975f5c5SAndroid Build Coastguard Worker {
2837*8975f5c5SAndroid Build Coastguard Worker const int currentPosition = y * getWindowHeight() + x;
2838*8975f5c5SAndroid Build Coastguard Worker
2839*8975f5c5SAndroid Build Coastguard Worker if (y > x || y >= -x + getWindowHeight() - 1)
2840*8975f5c5SAndroid Build Coastguard Worker {
2841*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(GLColor::red, actualColors[currentPosition]);
2842*8975f5c5SAndroid Build Coastguard Worker }
2843*8975f5c5SAndroid Build Coastguard Worker else
2844*8975f5c5SAndroid Build Coastguard Worker {
2845*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(GLColor::blue, actualColors[currentPosition]);
2846*8975f5c5SAndroid Build Coastguard Worker }
2847*8975f5c5SAndroid Build Coastguard Worker }
2848*8975f5c5SAndroid Build Coastguard Worker }
2849*8975f5c5SAndroid Build Coastguard Worker }
2850*8975f5c5SAndroid Build Coastguard Worker
2851*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(ClipDistanceAPPLETest);
2852*8975f5c5SAndroid Build Coastguard Worker
2853*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ClipCullDistanceTest);
2854*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_COMBINE_1(ClipCullDistanceTest,
2855*8975f5c5SAndroid Build Coastguard Worker PrintToStringParamName,
2856*8975f5c5SAndroid Build Coastguard Worker testing::Bool(),
2857*8975f5c5SAndroid Build Coastguard Worker ANGLE_ALL_TEST_PLATFORMS_ES3,
2858*8975f5c5SAndroid Build Coastguard Worker ANGLE_ALL_TEST_PLATFORMS_ES31);
2859