xref: /aosp_15_r20/external/angle/src/tests/gl_tests/PolygonOffsetClampTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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