1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2023 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 // PolygonOffsetClampTest.cpp: Test cases for GL_EXT_polygon_offset_clamp
7*8975f5c5SAndroid Build Coastguard Worker //
8*8975f5c5SAndroid Build Coastguard Worker
9*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/ANGLETest.h"
10*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/gl_raii.h"
11*8975f5c5SAndroid Build Coastguard Worker #include "util/EGLWindow.h"
12*8975f5c5SAndroid Build Coastguard Worker #include "util/test_utils.h"
13*8975f5c5SAndroid Build Coastguard Worker
14*8975f5c5SAndroid Build Coastguard Worker using namespace angle;
15*8975f5c5SAndroid Build Coastguard Worker
16*8975f5c5SAndroid Build Coastguard Worker class PolygonOffsetClampTest : public ANGLETest<>
17*8975f5c5SAndroid Build Coastguard Worker {
18*8975f5c5SAndroid Build Coastguard Worker protected:
PolygonOffsetClampTest()19*8975f5c5SAndroid Build Coastguard Worker PolygonOffsetClampTest()
20*8975f5c5SAndroid Build Coastguard Worker {
21*8975f5c5SAndroid Build Coastguard Worker setConfigRedBits(8);
22*8975f5c5SAndroid Build Coastguard Worker setConfigGreenBits(8);
23*8975f5c5SAndroid Build Coastguard Worker setConfigBlueBits(8);
24*8975f5c5SAndroid Build Coastguard Worker setConfigAlphaBits(8);
25*8975f5c5SAndroid Build Coastguard Worker setConfigDepthBits(24);
26*8975f5c5SAndroid Build Coastguard Worker setExtensionsEnabled(false);
27*8975f5c5SAndroid Build Coastguard Worker }
28*8975f5c5SAndroid Build Coastguard Worker };
29*8975f5c5SAndroid Build Coastguard Worker
30*8975f5c5SAndroid Build Coastguard Worker // Test state queries and updates
TEST_P(PolygonOffsetClampTest,State)31*8975f5c5SAndroid Build Coastguard Worker TEST_P(PolygonOffsetClampTest, State)
32*8975f5c5SAndroid Build Coastguard Worker {
33*8975f5c5SAndroid Build Coastguard Worker // New state query fails without the extension
34*8975f5c5SAndroid Build Coastguard Worker {
35*8975f5c5SAndroid Build Coastguard Worker GLfloat clamp = -1.0f;
36*8975f5c5SAndroid Build Coastguard Worker glGetFloatv(GL_POLYGON_OFFSET_CLAMP_EXT, &clamp);
37*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_ERROR(GL_INVALID_ENUM);
38*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(clamp, -1.0f);
39*8975f5c5SAndroid Build Coastguard Worker
40*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
41*8975f5c5SAndroid Build Coastguard Worker }
42*8975f5c5SAndroid Build Coastguard Worker
43*8975f5c5SAndroid Build Coastguard Worker // New function does nothing without enabling the extension
44*8975f5c5SAndroid Build Coastguard Worker {
45*8975f5c5SAndroid Build Coastguard Worker glPolygonOffsetClampEXT(1.0f, 2.0f, 3.0f);
46*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_ERROR(GL_INVALID_OPERATION);
47*8975f5c5SAndroid Build Coastguard Worker
48*8975f5c5SAndroid Build Coastguard Worker GLfloat factor = -1.0f;
49*8975f5c5SAndroid Build Coastguard Worker glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &factor);
50*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(factor, 0.0f);
51*8975f5c5SAndroid Build Coastguard Worker
52*8975f5c5SAndroid Build Coastguard Worker GLfloat units = -1.0f;
53*8975f5c5SAndroid Build Coastguard Worker glGetFloatv(GL_POLYGON_OFFSET_UNITS, &units);
54*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(units, 0.0f);
55*8975f5c5SAndroid Build Coastguard Worker
56*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
57*8975f5c5SAndroid Build Coastguard Worker }
58*8975f5c5SAndroid Build Coastguard Worker
59*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_polygon_offset_clamp"));
60*8975f5c5SAndroid Build Coastguard Worker
61*8975f5c5SAndroid Build Coastguard Worker // Default state
62*8975f5c5SAndroid Build Coastguard Worker {
63*8975f5c5SAndroid Build Coastguard Worker GLfloat factor = -1.0f;
64*8975f5c5SAndroid Build Coastguard Worker glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &factor);
65*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(factor, 0.0f);
66*8975f5c5SAndroid Build Coastguard Worker
67*8975f5c5SAndroid Build Coastguard Worker GLfloat units = -1.0f;
68*8975f5c5SAndroid Build Coastguard Worker glGetFloatv(GL_POLYGON_OFFSET_UNITS, &units);
69*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(units, 0.0f);
70*8975f5c5SAndroid Build Coastguard Worker
71*8975f5c5SAndroid Build Coastguard Worker GLfloat clamp = -1.0f;
72*8975f5c5SAndroid Build Coastguard Worker glGetFloatv(GL_POLYGON_OFFSET_CLAMP_EXT, &clamp);
73*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(clamp, 0.0f);
74*8975f5c5SAndroid Build Coastguard Worker
75*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
76*8975f5c5SAndroid Build Coastguard Worker }
77*8975f5c5SAndroid Build Coastguard Worker
78*8975f5c5SAndroid Build Coastguard Worker // Full state update using the new function
79*8975f5c5SAndroid Build Coastguard Worker {
80*8975f5c5SAndroid Build Coastguard Worker glPolygonOffsetClampEXT(1.0f, 2.0f, 3.0f);
81*8975f5c5SAndroid Build Coastguard Worker
82*8975f5c5SAndroid Build Coastguard Worker GLfloat factor = -1.0f;
83*8975f5c5SAndroid Build Coastguard Worker glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &factor);
84*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(factor, 1.0f);
85*8975f5c5SAndroid Build Coastguard Worker
86*8975f5c5SAndroid Build Coastguard Worker GLfloat units = -1.0f;
87*8975f5c5SAndroid Build Coastguard Worker glGetFloatv(GL_POLYGON_OFFSET_UNITS, &units);
88*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(units, 2.0f);
89*8975f5c5SAndroid Build Coastguard Worker
90*8975f5c5SAndroid Build Coastguard Worker GLfloat clamp = -1.0f;
91*8975f5c5SAndroid Build Coastguard Worker glGetFloatv(GL_POLYGON_OFFSET_CLAMP_EXT, &clamp);
92*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(clamp, 3.0f);
93*8975f5c5SAndroid Build Coastguard Worker
94*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
95*8975f5c5SAndroid Build Coastguard Worker }
96*8975f5c5SAndroid Build Coastguard Worker
97*8975f5c5SAndroid Build Coastguard Worker // Core function resets the clamp value to zero
98*8975f5c5SAndroid Build Coastguard Worker {
99*8975f5c5SAndroid Build Coastguard Worker glPolygonOffset(4.0f, 5.0f);
100*8975f5c5SAndroid Build Coastguard Worker
101*8975f5c5SAndroid Build Coastguard Worker GLfloat factor = -1.0f;
102*8975f5c5SAndroid Build Coastguard Worker glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &factor);
103*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(factor, 4.0f);
104*8975f5c5SAndroid Build Coastguard Worker
105*8975f5c5SAndroid Build Coastguard Worker GLfloat units = -1.0f;
106*8975f5c5SAndroid Build Coastguard Worker glGetFloatv(GL_POLYGON_OFFSET_UNITS, &units);
107*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(units, 5.0f);
108*8975f5c5SAndroid Build Coastguard Worker
109*8975f5c5SAndroid Build Coastguard Worker GLfloat clamp = -1.0f;
110*8975f5c5SAndroid Build Coastguard Worker glGetFloatv(GL_POLYGON_OFFSET_CLAMP_EXT, &clamp);
111*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(clamp, 0.0f);
112*8975f5c5SAndroid Build Coastguard Worker
113*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
114*8975f5c5SAndroid Build Coastguard Worker }
115*8975f5c5SAndroid Build Coastguard Worker
116*8975f5c5SAndroid Build Coastguard Worker // NaNs must be accepted and replaced with zeros
117*8975f5c5SAndroid Build Coastguard Worker {
118*8975f5c5SAndroid Build Coastguard Worker glPolygonOffsetClampEXT(6.0f, 7.0f, 8.0f);
119*8975f5c5SAndroid Build Coastguard Worker
120*8975f5c5SAndroid Build Coastguard Worker float nan = std::numeric_limits<float>::quiet_NaN();
121*8975f5c5SAndroid Build Coastguard Worker glPolygonOffsetClampEXT(nan, nan, nan);
122*8975f5c5SAndroid Build Coastguard Worker
123*8975f5c5SAndroid Build Coastguard Worker GLfloat factor = -1.0f;
124*8975f5c5SAndroid Build Coastguard Worker glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &factor);
125*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(factor, 0.0f);
126*8975f5c5SAndroid Build Coastguard Worker
127*8975f5c5SAndroid Build Coastguard Worker GLfloat units = -1.0f;
128*8975f5c5SAndroid Build Coastguard Worker glGetFloatv(GL_POLYGON_OFFSET_UNITS, &units);
129*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(units, 0.0f);
130*8975f5c5SAndroid Build Coastguard Worker
131*8975f5c5SAndroid Build Coastguard Worker GLfloat clamp = -1.0f;
132*8975f5c5SAndroid Build Coastguard Worker glGetFloatv(GL_POLYGON_OFFSET_CLAMP_EXT, &clamp);
133*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(clamp, 0.0f);
134*8975f5c5SAndroid Build Coastguard Worker
135*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
136*8975f5c5SAndroid Build Coastguard Worker }
137*8975f5c5SAndroid Build Coastguard Worker }
138*8975f5c5SAndroid Build Coastguard Worker
139*8975f5c5SAndroid Build Coastguard Worker // Test polygon offset clamping behavior. Ported from dEQP.
TEST_P(PolygonOffsetClampTest,Operation)140*8975f5c5SAndroid Build Coastguard Worker TEST_P(PolygonOffsetClampTest, Operation)
141*8975f5c5SAndroid Build Coastguard Worker {
142*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_polygon_offset_clamp"));
143*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_depth_texture"));
144*8975f5c5SAndroid Build Coastguard Worker
145*8975f5c5SAndroid Build Coastguard Worker GLTexture depthTexture;
146*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, depthTexture);
147*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 64, 64, 0, GL_DEPTH_COMPONENT,
148*8975f5c5SAndroid Build Coastguard Worker GL_UNSIGNED_SHORT, nullptr);
149*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
150*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
151*8975f5c5SAndroid Build Coastguard Worker
152*8975f5c5SAndroid Build Coastguard Worker GLTexture colorTexture;
153*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, colorTexture);
154*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
155*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
156*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
157*8975f5c5SAndroid Build Coastguard Worker
158*8975f5c5SAndroid Build Coastguard Worker GLFramebuffer fbo;
159*8975f5c5SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, fbo);
160*8975f5c5SAndroid Build Coastguard Worker glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
161*8975f5c5SAndroid Build Coastguard Worker glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
162*8975f5c5SAndroid Build Coastguard Worker
163*8975f5c5SAndroid Build Coastguard Worker GLTexture colorReadbackTexture;
164*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, colorReadbackTexture);
165*8975f5c5SAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
166*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
167*8975f5c5SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
168*8975f5c5SAndroid Build Coastguard Worker
169*8975f5c5SAndroid Build Coastguard Worker GLFramebuffer fboReadback;
170*8975f5c5SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, fboReadback);
171*8975f5c5SAndroid Build Coastguard Worker glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
172*8975f5c5SAndroid Build Coastguard Worker colorReadbackTexture, 0);
173*8975f5c5SAndroid Build Coastguard Worker
174*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_PROGRAM(testProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
175*8975f5c5SAndroid Build Coastguard Worker
176*8975f5c5SAndroid Build Coastguard Worker constexpr char kFS[] = R"(
177*8975f5c5SAndroid Build Coastguard Worker varying highp vec2 v_texCoord;
178*8975f5c5SAndroid Build Coastguard Worker uniform highp sampler2D tex;
179*8975f5c5SAndroid Build Coastguard Worker void main()
180*8975f5c5SAndroid Build Coastguard Worker {
181*8975f5c5SAndroid Build Coastguard Worker // Store as unorm24
182*8975f5c5SAndroid Build Coastguard Worker highp float d = floor(texture2D(tex, v_texCoord).r * 16777215.0);
183*8975f5c5SAndroid Build Coastguard Worker highp float r = floor(d / 65536.0);
184*8975f5c5SAndroid Build Coastguard Worker highp float g = floor(mod(d, 65536.0) / 256.0);
185*8975f5c5SAndroid Build Coastguard Worker highp float b = mod(d, 256.0);
186*8975f5c5SAndroid Build Coastguard Worker gl_FragColor = vec4(r, g, b, 1.0) / 255.0;
187*8975f5c5SAndroid Build Coastguard Worker })";
188*8975f5c5SAndroid Build Coastguard Worker
189*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_PROGRAM(readDepthProgram, essl1_shaders::vs::Texture2D(), kFS);
190*8975f5c5SAndroid Build Coastguard Worker
191*8975f5c5SAndroid Build Coastguard Worker // Setup depth testing
192*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_DEPTH_TEST);
193*8975f5c5SAndroid Build Coastguard Worker glDepthFunc(GL_ALWAYS);
194*8975f5c5SAndroid Build Coastguard Worker
195*8975f5c5SAndroid Build Coastguard Worker // Bind framebuffer for drawing
196*8975f5c5SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, fbo);
197*8975f5c5SAndroid Build Coastguard Worker
198*8975f5c5SAndroid Build Coastguard Worker // Offset units and clamp values. Should work with all depth buffer formats.
199*8975f5c5SAndroid Build Coastguard Worker const std::vector<std::array<GLfloat, 2>> testValues = {
200*8975f5c5SAndroid Build Coastguard Worker {-5000.0f, -0.0001f},
201*8975f5c5SAndroid Build Coastguard Worker {+5000.0f, +0.0001f},
202*8975f5c5SAndroid Build Coastguard Worker {-5000.0f, 0.0f},
203*8975f5c5SAndroid Build Coastguard Worker {+5000.0f, 0.0f},
204*8975f5c5SAndroid Build Coastguard Worker {-5000.0f, -std::numeric_limits<float>::infinity()},
205*8975f5c5SAndroid Build Coastguard Worker {+5000.0f, +std::numeric_limits<float>::infinity()}};
206*8975f5c5SAndroid Build Coastguard Worker
207*8975f5c5SAndroid Build Coastguard Worker auto readDepthValue = [&]() {
208*8975f5c5SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, fboReadback);
209*8975f5c5SAndroid Build Coastguard Worker glDisable(GL_DEPTH_TEST);
210*8975f5c5SAndroid Build Coastguard Worker glUseProgram(readDepthProgram);
211*8975f5c5SAndroid Build Coastguard Worker glUniform1i(glGetUniformLocation(readDepthProgram, "tex"), 0);
212*8975f5c5SAndroid Build Coastguard Worker
213*8975f5c5SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, depthTexture);
214*8975f5c5SAndroid Build Coastguard Worker drawQuad(readDepthProgram, "a_position", 0.5);
215*8975f5c5SAndroid Build Coastguard Worker
216*8975f5c5SAndroid Build Coastguard Worker GLubyte pixels[4];
217*8975f5c5SAndroid Build Coastguard Worker glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
218*8975f5c5SAndroid Build Coastguard Worker
219*8975f5c5SAndroid Build Coastguard Worker // Convert read depth value to GLfloat normalized
220*8975f5c5SAndroid Build Coastguard Worker GLfloat depthValue = (GLfloat)(pixels[0] * 65536 + pixels[1] * 256 + pixels[2]) / 0xFFFFFF;
221*8975f5c5SAndroid Build Coastguard Worker
222*8975f5c5SAndroid Build Coastguard Worker // Restore state
223*8975f5c5SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, fbo);
224*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_DEPTH_TEST);
225*8975f5c5SAndroid Build Coastguard Worker glUseProgram(testProgram);
226*8975f5c5SAndroid Build Coastguard Worker
227*8975f5c5SAndroid Build Coastguard Worker return depthValue;
228*8975f5c5SAndroid Build Coastguard Worker };
229*8975f5c5SAndroid Build Coastguard Worker
230*8975f5c5SAndroid Build Coastguard Worker for (auto testValue : testValues)
231*8975f5c5SAndroid Build Coastguard Worker {
232*8975f5c5SAndroid Build Coastguard Worker const GLfloat units = testValue[0];
233*8975f5c5SAndroid Build Coastguard Worker const GLfloat clamp = testValue[1];
234*8975f5c5SAndroid Build Coastguard Worker
235*8975f5c5SAndroid Build Coastguard Worker // Draw reference polygon
236*8975f5c5SAndroid Build Coastguard Worker glDisable(GL_POLYGON_OFFSET_FILL);
237*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
238*8975f5c5SAndroid Build Coastguard Worker drawQuad(testProgram, "a_position", 0.0);
239*8975f5c5SAndroid Build Coastguard Worker
240*8975f5c5SAndroid Build Coastguard Worker // Get reference depth value
241*8975f5c5SAndroid Build Coastguard Worker const GLfloat depthValue = readDepthValue();
242*8975f5c5SAndroid Build Coastguard Worker
243*8975f5c5SAndroid Build Coastguard Worker // Draw polygon with depth offset
244*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_POLYGON_OFFSET_FILL);
245*8975f5c5SAndroid Build Coastguard Worker glPolygonOffset(0.0f, units);
246*8975f5c5SAndroid Build Coastguard Worker drawQuad(testProgram, "a_position", 0.0);
247*8975f5c5SAndroid Build Coastguard Worker
248*8975f5c5SAndroid Build Coastguard Worker // Get depth value with offset
249*8975f5c5SAndroid Build Coastguard Worker const GLfloat depthValueOffset = readDepthValue();
250*8975f5c5SAndroid Build Coastguard Worker
251*8975f5c5SAndroid Build Coastguard Worker // Draw reference polygon
252*8975f5c5SAndroid Build Coastguard Worker glDisable(GL_POLYGON_OFFSET_FILL);
253*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
254*8975f5c5SAndroid Build Coastguard Worker drawQuad(testProgram, "a_position", 0.0);
255*8975f5c5SAndroid Build Coastguard Worker
256*8975f5c5SAndroid Build Coastguard Worker // Draw polygon with depth offset
257*8975f5c5SAndroid Build Coastguard Worker glEnable(GL_POLYGON_OFFSET_FILL);
258*8975f5c5SAndroid Build Coastguard Worker glPolygonOffsetClampEXT(0.0f, units, clamp);
259*8975f5c5SAndroid Build Coastguard Worker drawQuad(testProgram, "a_position", 0.0);
260*8975f5c5SAndroid Build Coastguard Worker
261*8975f5c5SAndroid Build Coastguard Worker // Get depth value with clamped offset
262*8975f5c5SAndroid Build Coastguard Worker const GLfloat depthValueOffsetClamp = readDepthValue();
263*8975f5c5SAndroid Build Coastguard Worker
264*8975f5c5SAndroid Build Coastguard Worker // Check depth values
265*8975f5c5SAndroid Build Coastguard Worker {
266*8975f5c5SAndroid Build Coastguard Worker if (clamp == 0.0f || isinf(clamp))
267*8975f5c5SAndroid Build Coastguard Worker {
268*8975f5c5SAndroid Build Coastguard Worker ASSERT_NE(units, 0.0f);
269*8975f5c5SAndroid Build Coastguard Worker
270*8975f5c5SAndroid Build Coastguard Worker // Ensure that offset works
271*8975f5c5SAndroid Build Coastguard Worker if (units > 0.0f)
272*8975f5c5SAndroid Build Coastguard Worker {
273*8975f5c5SAndroid Build Coastguard Worker EXPECT_LT(depthValue, depthValueOffset);
274*8975f5c5SAndroid Build Coastguard Worker EXPECT_LT(depthValue, depthValueOffsetClamp);
275*8975f5c5SAndroid Build Coastguard Worker }
276*8975f5c5SAndroid Build Coastguard Worker else if (units < 0.0f)
277*8975f5c5SAndroid Build Coastguard Worker {
278*8975f5c5SAndroid Build Coastguard Worker EXPECT_GT(depthValue, depthValueOffset);
279*8975f5c5SAndroid Build Coastguard Worker EXPECT_GT(depthValue, depthValueOffsetClamp);
280*8975f5c5SAndroid Build Coastguard Worker }
281*8975f5c5SAndroid Build Coastguard Worker
282*8975f5c5SAndroid Build Coastguard Worker // Clamping must have no effect
283*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(depthValueOffset, depthValueOffsetClamp);
284*8975f5c5SAndroid Build Coastguard Worker }
285*8975f5c5SAndroid Build Coastguard Worker else if (clamp < 0.0f)
286*8975f5c5SAndroid Build Coastguard Worker {
287*8975f5c5SAndroid Build Coastguard Worker ASSERT_LT(units, 0);
288*8975f5c5SAndroid Build Coastguard Worker
289*8975f5c5SAndroid Build Coastguard Worker // Negative clamp value sets effective offset to max(offset, clamp)
290*8975f5c5SAndroid Build Coastguard Worker EXPECT_GT(depthValue, depthValueOffset);
291*8975f5c5SAndroid Build Coastguard Worker EXPECT_GT(depthValue, depthValueOffsetClamp);
292*8975f5c5SAndroid Build Coastguard Worker EXPECT_LT(depthValueOffset, depthValueOffsetClamp);
293*8975f5c5SAndroid Build Coastguard Worker }
294*8975f5c5SAndroid Build Coastguard Worker else if (clamp > 0.0f)
295*8975f5c5SAndroid Build Coastguard Worker {
296*8975f5c5SAndroid Build Coastguard Worker ASSERT_GT(units, 0);
297*8975f5c5SAndroid Build Coastguard Worker
298*8975f5c5SAndroid Build Coastguard Worker // Positive clamp value sets effective offset to min(offset, clamp)
299*8975f5c5SAndroid Build Coastguard Worker EXPECT_LT(depthValue, depthValueOffset);
300*8975f5c5SAndroid Build Coastguard Worker EXPECT_LT(depthValue, depthValueOffsetClamp);
301*8975f5c5SAndroid Build Coastguard Worker EXPECT_GT(depthValueOffset, depthValueOffsetClamp);
302*8975f5c5SAndroid Build Coastguard Worker }
303*8975f5c5SAndroid Build Coastguard Worker }
304*8975f5c5SAndroid Build Coastguard Worker }
305*8975f5c5SAndroid Build Coastguard Worker }
306*8975f5c5SAndroid Build Coastguard Worker
307*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(PolygonOffsetClampTest);
308