1 //
2 // Copyright 2022 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // FragDepthTest:
7 // Tests the correctness of gl_FragDepth usage.
8 //
9
10 #include "test_utils/ANGLETest.h"
11 #include "test_utils/gl_raii.h"
12
13 using namespace angle;
14
15 class FragDepthTest : public ANGLETest
16 {
17 protected:
18 struct FragDepthTestResources
19 {
20 GLuint program;
21 GLint depthLocation;
22 GLTexture colorTexture;
23 GLTexture depthTexture;
24 GLFramebuffer framebuffer;
25 };
26
setupResources(FragDepthTestResources & resources)27 void setupResources(FragDepthTestResources &resources)
28 {
29
30 // Writes a fixed depth value and green.
31 constexpr char kFS[] =
32 R"(#version 300 es
33 precision highp float;
34 layout(location = 0) out vec4 fragColor;
35 uniform float u_depth;
36 void main(){
37 gl_FragDepth = u_depth;
38 fragColor = vec4(0.0, 1.0, 0.0, 1.0);
39 })";
40
41 resources.program = CompileProgram(essl3_shaders::vs::Simple(), kFS);
42 resources.depthLocation = glGetUniformLocation(resources.program, "u_depth");
43
44 glBindTexture(GL_TEXTURE_2D, resources.colorTexture);
45 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
46 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
47 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
48
49 glBindTexture(GL_TEXTURE_2D, resources.depthTexture);
50 glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT32F, 1, 1);
51 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
52 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
53
54 glBindFramebuffer(GL_FRAMEBUFFER, resources.framebuffer);
55 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
56 resources.colorTexture, 0);
57 }
58
cleanupResources(FragDepthTestResources & resources)59 void cleanupResources(FragDepthTestResources &resources) { glDeleteProgram(resources.program); }
60
checkDepthWritten(float expectedDepth,float fsDepth,bool bindDepthBuffer)61 void checkDepthWritten(float expectedDepth, float fsDepth, bool bindDepthBuffer)
62 {
63 FragDepthTestResources resources;
64 setupResources(resources);
65 ASSERT_NE(0u, resources.program);
66 ASSERT_NE(-1, resources.depthLocation);
67 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
68 ASSERT_GL_NO_ERROR();
69
70 glBindFramebuffer(GL_FRAMEBUFFER, resources.framebuffer);
71 if (bindDepthBuffer)
72 {
73 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
74 resources.depthTexture, 0);
75 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
76
77 // Clear to the expected depth so it will be compared to the FS depth with
78 // DepthFunc(GL_EQUAL)
79 glClearDepthf(expectedDepth);
80 glDepthFunc(GL_EQUAL);
81 glEnable(GL_DEPTH_TEST);
82 }
83 else
84 {
85 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
86 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
87 glDisable(GL_DEPTH_TEST);
88 }
89 glUseProgram(resources.program);
90
91 // Clear to red, the FS will write green on success
92 glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
93 // Clear to the expected depth so it will be compared to the FS depth with
94 // DepthFunc(GL_EQUAL)
95
96 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
97 glUniform1f(resources.depthLocation, fsDepth);
98
99 drawQuad(resources.program, "a_position", 0.0f);
100 EXPECT_GL_NO_ERROR();
101
102 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
103 cleanupResources(resources);
104 }
105 };
106
107 // Test that writing to gl_FragDepth works
TEST_P(FragDepthTest,DepthBufferBound)108 TEST_P(FragDepthTest, DepthBufferBound)
109 {
110 checkDepthWritten(0.5f, 0.5f, true);
111 }
112
113 // Test that writing to gl_FragDepth with no depth buffer works.
TEST_P(FragDepthTest,DepthBufferUnbound)114 TEST_P(FragDepthTest, DepthBufferUnbound)
115 {
116 // Depth test is disabled, so the expected depth should not matter.
117 checkDepthWritten(0.f, 0.5f, false);
118 }
119
120 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(FragDepthTest);
121 ANGLE_INSTANTIATE_TEST_ES3(FragDepthTest);
122