xref: /aosp_15_r20/external/angle/src/tests/gl_tests/DepthWriteTest.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 // The tests assert OpenGL behavior for all combinations of the following states
7*8975f5c5SAndroid Build Coastguard Worker // - Depth Range
8*8975f5c5SAndroid Build Coastguard Worker //   - Full (0, 1)
9*8975f5c5SAndroid Build Coastguard Worker //   - Reduced
10*8975f5c5SAndroid Build Coastguard Worker // - Depth Clamp
11*8975f5c5SAndroid Build Coastguard Worker //   - Enabled (if supported)
12*8975f5c5SAndroid Build Coastguard Worker //   - Disabled
13*8975f5c5SAndroid Build Coastguard Worker // - Vertex Depth
14*8975f5c5SAndroid Build Coastguard Worker //   - Inside clip volume
15*8975f5c5SAndroid Build Coastguard Worker //   - Less than -1
16*8975f5c5SAndroid Build Coastguard Worker //   - Greater than +1
17*8975f5c5SAndroid Build Coastguard Worker // - gl_FragDepth
18*8975f5c5SAndroid Build Coastguard Worker //   - Unused
19*8975f5c5SAndroid Build Coastguard Worker //   - Passthrough (gl_FragCoord.z)
20*8975f5c5SAndroid Build Coastguard Worker //   - Within the depth range
21*8975f5c5SAndroid Build Coastguard Worker //   - Between 0 and near clipping plane
22*8975f5c5SAndroid Build Coastguard Worker //   - Between 1 and far clipping plane
23*8975f5c5SAndroid Build Coastguard Worker //   - Negative
24*8975f5c5SAndroid Build Coastguard Worker //   - Greater than 1
25*8975f5c5SAndroid Build Coastguard Worker // - Depth buffer format
26*8975f5c5SAndroid Build Coastguard Worker //   - DEPTH_COMPONENT16
27*8975f5c5SAndroid Build Coastguard Worker //   - DEPTH_COMPONENT32F (ES 3.x only)
28*8975f5c5SAndroid Build Coastguard Worker 
29*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/ANGLETest.h"
30*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/gl_raii.h"
31*8975f5c5SAndroid Build Coastguard Worker 
32*8975f5c5SAndroid Build Coastguard Worker using namespace angle;
33*8975f5c5SAndroid Build Coastguard Worker 
34*8975f5c5SAndroid Build Coastguard Worker namespace
35*8975f5c5SAndroid Build Coastguard Worker {
36*8975f5c5SAndroid Build Coastguard Worker 
37*8975f5c5SAndroid Build Coastguard Worker enum class DepthRange
38*8975f5c5SAndroid Build Coastguard Worker {
39*8975f5c5SAndroid Build Coastguard Worker     Full,
40*8975f5c5SAndroid Build Coastguard Worker     Reduced,
41*8975f5c5SAndroid Build Coastguard Worker };
42*8975f5c5SAndroid Build Coastguard Worker 
43*8975f5c5SAndroid Build Coastguard Worker enum class VertexDepth
44*8975f5c5SAndroid Build Coastguard Worker {
45*8975f5c5SAndroid Build Coastguard Worker     InsideClipVolume,
46*8975f5c5SAndroid Build Coastguard Worker     LessThanMinusOne,
47*8975f5c5SAndroid Build Coastguard Worker     GreaterThanOne,
48*8975f5c5SAndroid Build Coastguard Worker };
49*8975f5c5SAndroid Build Coastguard Worker 
50*8975f5c5SAndroid Build Coastguard Worker enum class FragmentDepth
51*8975f5c5SAndroid Build Coastguard Worker {
52*8975f5c5SAndroid Build Coastguard Worker     Unused,
53*8975f5c5SAndroid Build Coastguard Worker     Passthrough,
54*8975f5c5SAndroid Build Coastguard Worker     WithinDepthRange,
55*8975f5c5SAndroid Build Coastguard Worker     BetweenZeroAndNearPlane,
56*8975f5c5SAndroid Build Coastguard Worker     BetweenFarPlaneAndOne,
57*8975f5c5SAndroid Build Coastguard Worker     Negative,
58*8975f5c5SAndroid Build Coastguard Worker     GreaterThanOne,
59*8975f5c5SAndroid Build Coastguard Worker };
60*8975f5c5SAndroid Build Coastguard Worker 
61*8975f5c5SAndroid Build Coastguard Worker // Variations corresponding to enums above.
62*8975f5c5SAndroid Build Coastguard Worker using DepthWriteVariationsTestParams =
63*8975f5c5SAndroid Build Coastguard Worker     std::tuple<angle::PlatformParameters, DepthRange, bool, VertexDepth, FragmentDepth, GLenum>;
64*8975f5c5SAndroid Build Coastguard Worker 
operator <<(std::ostream & out,DepthRange depthRange)65*8975f5c5SAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &out, DepthRange depthRange)
66*8975f5c5SAndroid Build Coastguard Worker {
67*8975f5c5SAndroid Build Coastguard Worker     switch (depthRange)
68*8975f5c5SAndroid Build Coastguard Worker     {
69*8975f5c5SAndroid Build Coastguard Worker         case DepthRange::Full:
70*8975f5c5SAndroid Build Coastguard Worker             out << "Full";
71*8975f5c5SAndroid Build Coastguard Worker             break;
72*8975f5c5SAndroid Build Coastguard Worker         case DepthRange::Reduced:
73*8975f5c5SAndroid Build Coastguard Worker             out << "Reduced";
74*8975f5c5SAndroid Build Coastguard Worker             break;
75*8975f5c5SAndroid Build Coastguard Worker     }
76*8975f5c5SAndroid Build Coastguard Worker 
77*8975f5c5SAndroid Build Coastguard Worker     return out;
78*8975f5c5SAndroid Build Coastguard Worker }
79*8975f5c5SAndroid Build Coastguard Worker 
operator <<(std::ostream & out,VertexDepth vertexDepth)80*8975f5c5SAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &out, VertexDepth vertexDepth)
81*8975f5c5SAndroid Build Coastguard Worker {
82*8975f5c5SAndroid Build Coastguard Worker     switch (vertexDepth)
83*8975f5c5SAndroid Build Coastguard Worker     {
84*8975f5c5SAndroid Build Coastguard Worker         case VertexDepth::InsideClipVolume:
85*8975f5c5SAndroid Build Coastguard Worker             out << "InsideClipVolume";
86*8975f5c5SAndroid Build Coastguard Worker             break;
87*8975f5c5SAndroid Build Coastguard Worker         case VertexDepth::LessThanMinusOne:
88*8975f5c5SAndroid Build Coastguard Worker             out << "LessThanMinusOne";
89*8975f5c5SAndroid Build Coastguard Worker             break;
90*8975f5c5SAndroid Build Coastguard Worker         case VertexDepth::GreaterThanOne:
91*8975f5c5SAndroid Build Coastguard Worker             out << "GreaterThanOne";
92*8975f5c5SAndroid Build Coastguard Worker             break;
93*8975f5c5SAndroid Build Coastguard Worker     }
94*8975f5c5SAndroid Build Coastguard Worker 
95*8975f5c5SAndroid Build Coastguard Worker     return out;
96*8975f5c5SAndroid Build Coastguard Worker }
97*8975f5c5SAndroid Build Coastguard Worker 
operator <<(std::ostream & out,FragmentDepth fragmentDepth)98*8975f5c5SAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &out, FragmentDepth fragmentDepth)
99*8975f5c5SAndroid Build Coastguard Worker {
100*8975f5c5SAndroid Build Coastguard Worker     switch (fragmentDepth)
101*8975f5c5SAndroid Build Coastguard Worker     {
102*8975f5c5SAndroid Build Coastguard Worker         case FragmentDepth::Unused:
103*8975f5c5SAndroid Build Coastguard Worker             out << "Unused";
104*8975f5c5SAndroid Build Coastguard Worker             break;
105*8975f5c5SAndroid Build Coastguard Worker         case FragmentDepth::Passthrough:
106*8975f5c5SAndroid Build Coastguard Worker             out << "Passthrough";
107*8975f5c5SAndroid Build Coastguard Worker             break;
108*8975f5c5SAndroid Build Coastguard Worker         case FragmentDepth::WithinDepthRange:
109*8975f5c5SAndroid Build Coastguard Worker             out << "WithinDepthRange";
110*8975f5c5SAndroid Build Coastguard Worker             break;
111*8975f5c5SAndroid Build Coastguard Worker         case FragmentDepth::BetweenZeroAndNearPlane:
112*8975f5c5SAndroid Build Coastguard Worker             out << "BetweenZeroAndNearPlane";
113*8975f5c5SAndroid Build Coastguard Worker             break;
114*8975f5c5SAndroid Build Coastguard Worker         case FragmentDepth::BetweenFarPlaneAndOne:
115*8975f5c5SAndroid Build Coastguard Worker             out << "BetweenFarPlaneAndOne";
116*8975f5c5SAndroid Build Coastguard Worker             break;
117*8975f5c5SAndroid Build Coastguard Worker         case FragmentDepth::Negative:
118*8975f5c5SAndroid Build Coastguard Worker             out << "Negative";
119*8975f5c5SAndroid Build Coastguard Worker             break;
120*8975f5c5SAndroid Build Coastguard Worker         case FragmentDepth::GreaterThanOne:
121*8975f5c5SAndroid Build Coastguard Worker             out << "GreaterThanOne";
122*8975f5c5SAndroid Build Coastguard Worker             break;
123*8975f5c5SAndroid Build Coastguard Worker     }
124*8975f5c5SAndroid Build Coastguard Worker 
125*8975f5c5SAndroid Build Coastguard Worker     return out;
126*8975f5c5SAndroid Build Coastguard Worker }
127*8975f5c5SAndroid Build Coastguard Worker 
BufferFormatToString(GLenum format)128*8975f5c5SAndroid Build Coastguard Worker std::string BufferFormatToString(GLenum format)
129*8975f5c5SAndroid Build Coastguard Worker {
130*8975f5c5SAndroid Build Coastguard Worker     switch (format)
131*8975f5c5SAndroid Build Coastguard Worker     {
132*8975f5c5SAndroid Build Coastguard Worker         case GL_DEPTH_COMPONENT16:
133*8975f5c5SAndroid Build Coastguard Worker             return "Depth16Unorm";
134*8975f5c5SAndroid Build Coastguard Worker         case GL_DEPTH_COMPONENT32F:
135*8975f5c5SAndroid Build Coastguard Worker             return "Depth32Float";
136*8975f5c5SAndroid Build Coastguard Worker         default:
137*8975f5c5SAndroid Build Coastguard Worker             return nullptr;
138*8975f5c5SAndroid Build Coastguard Worker     }
139*8975f5c5SAndroid Build Coastguard Worker }
140*8975f5c5SAndroid Build Coastguard Worker 
ParseDepthWriteVariationsTestParams(const DepthWriteVariationsTestParams & params,DepthRange * depthRangeOut,bool * depthClampEnabledOut,VertexDepth * vertexDepthOut,FragmentDepth * fragmentDepthOut,GLenum * depthBufferFormatOut)141*8975f5c5SAndroid Build Coastguard Worker void ParseDepthWriteVariationsTestParams(const DepthWriteVariationsTestParams &params,
142*8975f5c5SAndroid Build Coastguard Worker                                          DepthRange *depthRangeOut,
143*8975f5c5SAndroid Build Coastguard Worker                                          bool *depthClampEnabledOut,
144*8975f5c5SAndroid Build Coastguard Worker                                          VertexDepth *vertexDepthOut,
145*8975f5c5SAndroid Build Coastguard Worker                                          FragmentDepth *fragmentDepthOut,
146*8975f5c5SAndroid Build Coastguard Worker                                          GLenum *depthBufferFormatOut)
147*8975f5c5SAndroid Build Coastguard Worker {
148*8975f5c5SAndroid Build Coastguard Worker     *depthRangeOut        = std::get<1>(params);
149*8975f5c5SAndroid Build Coastguard Worker     *depthClampEnabledOut = std::get<2>(params);
150*8975f5c5SAndroid Build Coastguard Worker     *vertexDepthOut       = std::get<3>(params);
151*8975f5c5SAndroid Build Coastguard Worker     *fragmentDepthOut     = std::get<4>(params);
152*8975f5c5SAndroid Build Coastguard Worker     *depthBufferFormatOut = std::get<5>(params);
153*8975f5c5SAndroid Build Coastguard Worker }
154*8975f5c5SAndroid Build Coastguard Worker 
DepthWriteVariationsTestPrint(const::testing::TestParamInfo<DepthWriteVariationsTestParams> & paramsInfo)155*8975f5c5SAndroid Build Coastguard Worker std::string DepthWriteVariationsTestPrint(
156*8975f5c5SAndroid Build Coastguard Worker     const ::testing::TestParamInfo<DepthWriteVariationsTestParams> &paramsInfo)
157*8975f5c5SAndroid Build Coastguard Worker {
158*8975f5c5SAndroid Build Coastguard Worker     const DepthWriteVariationsTestParams &params = paramsInfo.param;
159*8975f5c5SAndroid Build Coastguard Worker     std::ostringstream out;
160*8975f5c5SAndroid Build Coastguard Worker 
161*8975f5c5SAndroid Build Coastguard Worker     out << std::get<0>(params);
162*8975f5c5SAndroid Build Coastguard Worker 
163*8975f5c5SAndroid Build Coastguard Worker     DepthRange depthRange;
164*8975f5c5SAndroid Build Coastguard Worker     bool depthClampEnabled;
165*8975f5c5SAndroid Build Coastguard Worker     VertexDepth vertexDepth;
166*8975f5c5SAndroid Build Coastguard Worker     FragmentDepth fragmentDepth;
167*8975f5c5SAndroid Build Coastguard Worker     GLenum depthBufferFormat;
168*8975f5c5SAndroid Build Coastguard Worker     ParseDepthWriteVariationsTestParams(params, &depthRange, &depthClampEnabled, &vertexDepth,
169*8975f5c5SAndroid Build Coastguard Worker                                         &fragmentDepth, &depthBufferFormat);
170*8975f5c5SAndroid Build Coastguard Worker 
171*8975f5c5SAndroid Build Coastguard Worker     out << "__"
172*8975f5c5SAndroid Build Coastguard Worker         << "DepthRange" << depthRange << "_" << (depthClampEnabled ? "Clamped" : "Clipped") << "_"
173*8975f5c5SAndroid Build Coastguard Worker         << "VertexDepth" << vertexDepth << "_"
174*8975f5c5SAndroid Build Coastguard Worker         << "FragmentDepth" << fragmentDepth << "_" << BufferFormatToString(depthBufferFormat);
175*8975f5c5SAndroid Build Coastguard Worker     return out.str();
176*8975f5c5SAndroid Build Coastguard Worker }
177*8975f5c5SAndroid Build Coastguard Worker 
178*8975f5c5SAndroid Build Coastguard Worker class DepthWriteTest : public ANGLETest<DepthWriteVariationsTestParams>
179*8975f5c5SAndroid Build Coastguard Worker {};
180*8975f5c5SAndroid Build Coastguard Worker 
181*8975f5c5SAndroid Build Coastguard Worker // Test correctness of depth writes
TEST_P(DepthWriteTest,Test)182*8975f5c5SAndroid Build Coastguard Worker TEST_P(DepthWriteTest, Test)
183*8975f5c5SAndroid Build Coastguard Worker {
184*8975f5c5SAndroid Build Coastguard Worker     if (getClientMajorVersion() < 3)
185*8975f5c5SAndroid Build Coastguard Worker     {
186*8975f5c5SAndroid Build Coastguard Worker         ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_depth_texture"));
187*8975f5c5SAndroid Build Coastguard Worker         ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_half_float"));
188*8975f5c5SAndroid Build Coastguard Worker     }
189*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_color_buffer_half_float") &&
190*8975f5c5SAndroid Build Coastguard Worker                        !IsGLExtensionEnabled("GL_EXT_color_buffer_float"));
191*8975f5c5SAndroid Build Coastguard Worker 
192*8975f5c5SAndroid Build Coastguard Worker     DepthRange depthRange;
193*8975f5c5SAndroid Build Coastguard Worker     bool depthClampEnabled;
194*8975f5c5SAndroid Build Coastguard Worker     VertexDepth vertexDepth;
195*8975f5c5SAndroid Build Coastguard Worker     FragmentDepth fragmentDepth;
196*8975f5c5SAndroid Build Coastguard Worker     GLenum depthBufferFormat;
197*8975f5c5SAndroid Build Coastguard Worker     ParseDepthWriteVariationsTestParams(GetParam(), &depthRange, &depthClampEnabled, &vertexDepth,
198*8975f5c5SAndroid Build Coastguard Worker                                         &fragmentDepth, &depthBufferFormat);
199*8975f5c5SAndroid Build Coastguard Worker 
200*8975f5c5SAndroid Build Coastguard Worker     if (getClientMajorVersion() < 3)
201*8975f5c5SAndroid Build Coastguard Worker     {
202*8975f5c5SAndroid Build Coastguard Worker         ANGLE_SKIP_TEST_IF(fragmentDepth != FragmentDepth::Unused &&
203*8975f5c5SAndroid Build Coastguard Worker                            !IsGLExtensionEnabled("GL_EXT_frag_depth"));
204*8975f5c5SAndroid Build Coastguard Worker         ANGLE_SKIP_TEST_IF(depthBufferFormat == GL_DEPTH_COMPONENT32F);
205*8975f5c5SAndroid Build Coastguard Worker     }
206*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(depthClampEnabled && !IsGLExtensionEnabled("GL_EXT_depth_clamp"));
207*8975f5c5SAndroid Build Coastguard Worker 
208*8975f5c5SAndroid Build Coastguard Worker     const float near = depthRange == DepthRange::Full ? 0.0 : 0.25;
209*8975f5c5SAndroid Build Coastguard Worker     const float far  = depthRange == DepthRange::Full ? 1.0 : 0.75;
210*8975f5c5SAndroid Build Coastguard Worker     glDepthRangef(near, far);
211*8975f5c5SAndroid Build Coastguard Worker 
212*8975f5c5SAndroid Build Coastguard Worker     if (depthClampEnabled)
213*8975f5c5SAndroid Build Coastguard Worker     {
214*8975f5c5SAndroid Build Coastguard Worker         glEnable(GL_DEPTH_CLAMP_EXT);
215*8975f5c5SAndroid Build Coastguard Worker     }
216*8975f5c5SAndroid Build Coastguard Worker 
217*8975f5c5SAndroid Build Coastguard Worker     float vertexDepthValue = 0.0;
218*8975f5c5SAndroid Build Coastguard Worker     switch (vertexDepth)
219*8975f5c5SAndroid Build Coastguard Worker     {
220*8975f5c5SAndroid Build Coastguard Worker         case VertexDepth::InsideClipVolume:
221*8975f5c5SAndroid Build Coastguard Worker             vertexDepthValue = 0.25;  // maps to 0.625
222*8975f5c5SAndroid Build Coastguard Worker             break;
223*8975f5c5SAndroid Build Coastguard Worker         case VertexDepth::LessThanMinusOne:
224*8975f5c5SAndroid Build Coastguard Worker             vertexDepthValue = -1.5;
225*8975f5c5SAndroid Build Coastguard Worker             break;
226*8975f5c5SAndroid Build Coastguard Worker         case VertexDepth::GreaterThanOne:
227*8975f5c5SAndroid Build Coastguard Worker             vertexDepthValue = 1.5;
228*8975f5c5SAndroid Build Coastguard Worker             break;
229*8975f5c5SAndroid Build Coastguard Worker     }
230*8975f5c5SAndroid Build Coastguard Worker 
231*8975f5c5SAndroid Build Coastguard Worker     float fragmentDepthValue = 0.0;
232*8975f5c5SAndroid Build Coastguard Worker     switch (fragmentDepth)
233*8975f5c5SAndroid Build Coastguard Worker     {
234*8975f5c5SAndroid Build Coastguard Worker         case FragmentDepth::Unused:
235*8975f5c5SAndroid Build Coastguard Worker         case FragmentDepth::Passthrough:
236*8975f5c5SAndroid Build Coastguard Worker             break;
237*8975f5c5SAndroid Build Coastguard Worker         case FragmentDepth::WithinDepthRange:
238*8975f5c5SAndroid Build Coastguard Worker             fragmentDepthValue = 0.375;
239*8975f5c5SAndroid Build Coastguard Worker             break;
240*8975f5c5SAndroid Build Coastguard Worker         case FragmentDepth::BetweenZeroAndNearPlane:
241*8975f5c5SAndroid Build Coastguard Worker             fragmentDepthValue = depthRange == DepthRange::Reduced ? 0.125 : 0.0;
242*8975f5c5SAndroid Build Coastguard Worker             break;
243*8975f5c5SAndroid Build Coastguard Worker         case FragmentDepth::BetweenFarPlaneAndOne:
244*8975f5c5SAndroid Build Coastguard Worker             fragmentDepthValue = depthRange == DepthRange::Reduced ? 0.875 : 1.0;
245*8975f5c5SAndroid Build Coastguard Worker             break;
246*8975f5c5SAndroid Build Coastguard Worker         case FragmentDepth::Negative:
247*8975f5c5SAndroid Build Coastguard Worker             fragmentDepthValue = -0.25;
248*8975f5c5SAndroid Build Coastguard Worker             break;
249*8975f5c5SAndroid Build Coastguard Worker         case FragmentDepth::GreaterThanOne:
250*8975f5c5SAndroid Build Coastguard Worker             fragmentDepthValue = 1.25;
251*8975f5c5SAndroid Build Coastguard Worker             break;
252*8975f5c5SAndroid Build Coastguard Worker     }
253*8975f5c5SAndroid Build Coastguard Worker 
254*8975f5c5SAndroid Build Coastguard Worker     glEnable(GL_DEPTH_TEST);
255*8975f5c5SAndroid Build Coastguard Worker     glDepthFunc(GL_ALWAYS);
256*8975f5c5SAndroid Build Coastguard Worker 
257*8975f5c5SAndroid Build Coastguard Worker     const int w = getWindowWidth();
258*8975f5c5SAndroid Build Coastguard Worker     const int h = getWindowHeight();
259*8975f5c5SAndroid Build Coastguard Worker 
260*8975f5c5SAndroid Build Coastguard Worker     const bool es2       = getClientMajorVersion() < 3;
261*8975f5c5SAndroid Build Coastguard Worker     const bool fragCoord = fragmentDepth == FragmentDepth::Passthrough;
262*8975f5c5SAndroid Build Coastguard Worker     std::stringstream fragmentSource;
263*8975f5c5SAndroid Build Coastguard Worker     fragmentSource << (es2 ? "#extension GL_EXT_frag_depth : require\n" : "#version 300 es\n")
264*8975f5c5SAndroid Build Coastguard Worker                    << (es2 ? "" : "out mediump vec4 fragColor;\n")
265*8975f5c5SAndroid Build Coastguard Worker                    << (fragCoord ? "" : "uniform mediump float u_depth;\n") << "void main()\n"
266*8975f5c5SAndroid Build Coastguard Worker                    << "{\n"
267*8975f5c5SAndroid Build Coastguard Worker                    << (es2 ? "    gl_FragColor" : "    fragColor")
268*8975f5c5SAndroid Build Coastguard Worker                    << " = vec4(1.0, 0.0, 0.0, 1.0);\n"
269*8975f5c5SAndroid Build Coastguard Worker                    << "    gl_FragDepth" << (es2 ? "EXT" : "")
270*8975f5c5SAndroid Build Coastguard Worker                    << (fragCoord ? " = gl_FragCoord.z;\n" : " = u_depth;\n") << "}";
271*8975f5c5SAndroid Build Coastguard Worker 
272*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, es2 ? essl1_shaders::vs::Simple() : essl3_shaders::vs::Simple(),
273*8975f5c5SAndroid Build Coastguard Worker                      fragmentDepth == FragmentDepth::Unused
274*8975f5c5SAndroid Build Coastguard Worker                          ? (es2 ? essl1_shaders::fs::Red() : essl3_shaders::fs::Red())
275*8975f5c5SAndroid Build Coastguard Worker                          : fragmentSource.str().c_str());
276*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
277*8975f5c5SAndroid Build Coastguard Worker     if (fragmentDepth != FragmentDepth::Unused && fragmentDepth != FragmentDepth::Passthrough)
278*8975f5c5SAndroid Build Coastguard Worker     {
279*8975f5c5SAndroid Build Coastguard Worker         glUniform1f(glGetUniformLocation(program, "u_depth"), fragmentDepthValue);
280*8975f5c5SAndroid Build Coastguard Worker     }
281*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
282*8975f5c5SAndroid Build Coastguard Worker 
283*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer fb;
284*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, fb);
285*8975f5c5SAndroid Build Coastguard Worker 
286*8975f5c5SAndroid Build Coastguard Worker     GLRenderbuffer rb;
287*8975f5c5SAndroid Build Coastguard Worker     glBindRenderbuffer(GL_RENDERBUFFER, rb);
288*8975f5c5SAndroid Build Coastguard Worker     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB565, w, h);
289*8975f5c5SAndroid Build Coastguard Worker     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rb);
290*8975f5c5SAndroid Build Coastguard Worker 
291*8975f5c5SAndroid Build Coastguard Worker     GLTexture texDepth;
292*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, texDepth);
293*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
294*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
295*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(
296*8975f5c5SAndroid Build Coastguard Worker         GL_TEXTURE_2D, 0,
297*8975f5c5SAndroid Build Coastguard Worker         depthBufferFormat == GL_DEPTH_COMPONENT32F ? GL_DEPTH_COMPONENT32F : GL_DEPTH_COMPONENT, w,
298*8975f5c5SAndroid Build Coastguard Worker         h, 0, GL_DEPTH_COMPONENT,
299*8975f5c5SAndroid Build Coastguard Worker         depthBufferFormat == GL_DEPTH_COMPONENT32F ? GL_FLOAT : GL_UNSIGNED_SHORT, nullptr);
300*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texDepth, 0);
301*8975f5c5SAndroid Build Coastguard Worker 
302*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
303*8975f5c5SAndroid Build Coastguard Worker 
304*8975f5c5SAndroid Build Coastguard Worker     glEnable(GL_DEPTH_TEST);
305*8975f5c5SAndroid Build Coastguard Worker     glDepthFunc(GL_ALWAYS);
306*8975f5c5SAndroid Build Coastguard Worker 
307*8975f5c5SAndroid Build Coastguard Worker     glClearDepthf(0.33333333);
308*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_DEPTH_BUFFER_BIT);
309*8975f5c5SAndroid Build Coastguard Worker 
310*8975f5c5SAndroid Build Coastguard Worker     drawQuad(program, essl1_shaders::PositionAttrib(), vertexDepthValue);
311*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
312*8975f5c5SAndroid Build Coastguard Worker 
313*8975f5c5SAndroid Build Coastguard Worker     auto getExpectedValue = [&]() {
314*8975f5c5SAndroid Build Coastguard Worker         auto clamp = [](float x, float min, float max) {
315*8975f5c5SAndroid Build Coastguard Worker             return x < min ? min : (x > max ? max : x);
316*8975f5c5SAndroid Build Coastguard Worker         };
317*8975f5c5SAndroid Build Coastguard Worker 
318*8975f5c5SAndroid Build Coastguard Worker         if (depthClampEnabled)
319*8975f5c5SAndroid Build Coastguard Worker         {
320*8975f5c5SAndroid Build Coastguard Worker             if (fragmentDepth != FragmentDepth::Unused &&
321*8975f5c5SAndroid Build Coastguard Worker                 fragmentDepth != FragmentDepth::Passthrough)
322*8975f5c5SAndroid Build Coastguard Worker             {
323*8975f5c5SAndroid Build Coastguard Worker                 // Fragment value clamped to the depth range
324*8975f5c5SAndroid Build Coastguard Worker                 return clamp(fragmentDepthValue, near, far);
325*8975f5c5SAndroid Build Coastguard Worker             }
326*8975f5c5SAndroid Build Coastguard Worker             else
327*8975f5c5SAndroid Build Coastguard Worker             {
328*8975f5c5SAndroid Build Coastguard Worker                 // Vertex value transformed to window coordinates and clamped to the depth range
329*8975f5c5SAndroid Build Coastguard Worker                 return clamp(0.5f * ((far - near) * vertexDepthValue + (far + near)), near, far);
330*8975f5c5SAndroid Build Coastguard Worker             }
331*8975f5c5SAndroid Build Coastguard Worker         }
332*8975f5c5SAndroid Build Coastguard Worker         else if (vertexDepthValue >= -1.0f && vertexDepthValue <= 1.0f)
333*8975f5c5SAndroid Build Coastguard Worker         {
334*8975f5c5SAndroid Build Coastguard Worker             if (fragmentDepth != FragmentDepth::Unused &&
335*8975f5c5SAndroid Build Coastguard Worker                 fragmentDepth != FragmentDepth::Passthrough)
336*8975f5c5SAndroid Build Coastguard Worker             {
337*8975f5c5SAndroid Build Coastguard Worker                 // Fragment value clamped to [0, 1]
338*8975f5c5SAndroid Build Coastguard Worker                 return clamp(fragmentDepthValue, 0.0f, 1.0f);
339*8975f5c5SAndroid Build Coastguard Worker             }
340*8975f5c5SAndroid Build Coastguard Worker             else
341*8975f5c5SAndroid Build Coastguard Worker             {
342*8975f5c5SAndroid Build Coastguard Worker                 // Vertex value transformed to window coordinates
343*8975f5c5SAndroid Build Coastguard Worker                 return 0.5f * ((far - near) * vertexDepthValue + (far + near));
344*8975f5c5SAndroid Build Coastguard Worker             }
345*8975f5c5SAndroid Build Coastguard Worker         }
346*8975f5c5SAndroid Build Coastguard Worker         return 0.33333333f;
347*8975f5c5SAndroid Build Coastguard Worker     };
348*8975f5c5SAndroid Build Coastguard Worker 
349*8975f5c5SAndroid Build Coastguard Worker     // Second pass to read written depth value
350*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(readProgram, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
351*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(readProgram);
352*8975f5c5SAndroid Build Coastguard Worker     glUniform1i(glGetUniformLocation(readProgram, essl1_shaders::Texture2DUniform()), 0);
353*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
354*8975f5c5SAndroid Build Coastguard Worker 
355*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer readFb;
356*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, readFb);
357*8975f5c5SAndroid Build Coastguard Worker 
358*8975f5c5SAndroid Build Coastguard Worker     GLRenderbuffer readRb;
359*8975f5c5SAndroid Build Coastguard Worker     glBindRenderbuffer(GL_RENDERBUFFER, readRb);
360*8975f5c5SAndroid Build Coastguard Worker     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA16F, w, h);
361*8975f5c5SAndroid Build Coastguard Worker     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, readRb);
362*8975f5c5SAndroid Build Coastguard Worker 
363*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
364*8975f5c5SAndroid Build Coastguard Worker 
365*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
366*8975f5c5SAndroid Build Coastguard Worker     drawQuad(readProgram, essl1_shaders::PositionAttrib(), 0.0f);
367*8975f5c5SAndroid Build Coastguard Worker 
368*8975f5c5SAndroid Build Coastguard Worker     float writtenValue[4] = {std::numeric_limits<float>::quiet_NaN()};
369*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, writtenValue);
370*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
371*8975f5c5SAndroid Build Coastguard Worker 
372*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NEAR(getExpectedValue(), writtenValue[0], 0.001);
373*8975f5c5SAndroid Build Coastguard Worker }
374*8975f5c5SAndroid Build Coastguard Worker 
375*8975f5c5SAndroid Build Coastguard Worker constexpr DepthRange kDepthRanges[] = {
376*8975f5c5SAndroid Build Coastguard Worker     DepthRange::Full,
377*8975f5c5SAndroid Build Coastguard Worker     DepthRange::Reduced,
378*8975f5c5SAndroid Build Coastguard Worker };
379*8975f5c5SAndroid Build Coastguard Worker constexpr VertexDepth kVertexDepths[] = {
380*8975f5c5SAndroid Build Coastguard Worker     VertexDepth::InsideClipVolume,
381*8975f5c5SAndroid Build Coastguard Worker     VertexDepth::LessThanMinusOne,
382*8975f5c5SAndroid Build Coastguard Worker     VertexDepth::GreaterThanOne,
383*8975f5c5SAndroid Build Coastguard Worker };
384*8975f5c5SAndroid Build Coastguard Worker constexpr FragmentDepth kFragmentDepths[] = {
385*8975f5c5SAndroid Build Coastguard Worker     FragmentDepth::Unused,
386*8975f5c5SAndroid Build Coastguard Worker     FragmentDepth::Passthrough,
387*8975f5c5SAndroid Build Coastguard Worker     FragmentDepth::WithinDepthRange,
388*8975f5c5SAndroid Build Coastguard Worker     FragmentDepth::BetweenZeroAndNearPlane,
389*8975f5c5SAndroid Build Coastguard Worker     FragmentDepth::BetweenFarPlaneAndOne,
390*8975f5c5SAndroid Build Coastguard Worker     FragmentDepth::Negative,
391*8975f5c5SAndroid Build Coastguard Worker     FragmentDepth::GreaterThanOne,
392*8975f5c5SAndroid Build Coastguard Worker };
393*8975f5c5SAndroid Build Coastguard Worker constexpr GLenum kDepthBufferFormats[] = {
394*8975f5c5SAndroid Build Coastguard Worker     GL_DEPTH_COMPONENT16,
395*8975f5c5SAndroid Build Coastguard Worker     GL_DEPTH_COMPONENT32F,
396*8975f5c5SAndroid Build Coastguard Worker };
397*8975f5c5SAndroid Build Coastguard Worker 
398*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DepthWriteTest);
399*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_COMBINE_5(DepthWriteTest,
400*8975f5c5SAndroid Build Coastguard Worker                                  DepthWriteVariationsTestPrint,
401*8975f5c5SAndroid Build Coastguard Worker                                  testing::ValuesIn(kDepthRanges),
402*8975f5c5SAndroid Build Coastguard Worker                                  testing::Bool(),
403*8975f5c5SAndroid Build Coastguard Worker                                  testing::ValuesIn(kVertexDepths),
404*8975f5c5SAndroid Build Coastguard Worker                                  testing::ValuesIn(kFragmentDepths),
405*8975f5c5SAndroid Build Coastguard Worker                                  testing::ValuesIn(kDepthBufferFormats),
406*8975f5c5SAndroid Build Coastguard Worker                                  ANGLE_ALL_TEST_PLATFORMS_ES2,
407*8975f5c5SAndroid Build Coastguard Worker                                  ANGLE_ALL_TEST_PLATFORMS_ES3);
408*8975f5c5SAndroid Build Coastguard Worker 
409*8975f5c5SAndroid Build Coastguard Worker }  // anonymous namespace
410