Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/tests/gl_tests/DiscardFramebufferEXTTest.cpp
1693 views
1
//
2
// Copyright 2015 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
7
#include "test_utils/ANGLETest.h"
8
#include "test_utils/gl_raii.h"
9
10
using namespace angle;
11
12
class DiscardFramebufferEXTTest : public ANGLETest
13
{
14
protected:
15
DiscardFramebufferEXTTest()
16
{
17
setWindowWidth(256);
18
setWindowHeight(256);
19
setConfigRedBits(8);
20
setConfigGreenBits(8);
21
setConfigBlueBits(8);
22
setConfigAlphaBits(8);
23
setConfigDepthBits(24);
24
setConfigStencilBits(8);
25
}
26
};
27
28
TEST_P(DiscardFramebufferEXTTest, DefaultFramebuffer)
29
{
30
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_discard_framebuffer"));
31
32
// TODO: fix crash issue. http://anglebug.com/4141
33
ANGLE_SKIP_TEST_IF(IsD3D11());
34
35
// These should succeed on the default framebuffer
36
const GLenum discards1[] = {GL_COLOR_EXT};
37
glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards1);
38
EXPECT_GL_NO_ERROR();
39
40
const GLenum discards2[] = {GL_DEPTH_EXT};
41
glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards2);
42
EXPECT_GL_NO_ERROR();
43
44
const GLenum discards3[] = {GL_STENCIL_EXT};
45
glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards3);
46
EXPECT_GL_NO_ERROR();
47
48
const GLenum discards4[] = {GL_STENCIL_EXT, GL_COLOR_EXT, GL_DEPTH_EXT};
49
glDiscardFramebufferEXT(GL_FRAMEBUFFER, 3, discards4);
50
EXPECT_GL_NO_ERROR();
51
52
// These should fail on the default framebuffer
53
const GLenum discards5[] = {GL_COLOR_ATTACHMENT0};
54
glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards5);
55
EXPECT_GL_ERROR(GL_INVALID_ENUM);
56
57
const GLenum discards6[] = {GL_DEPTH_ATTACHMENT};
58
glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards6);
59
EXPECT_GL_ERROR(GL_INVALID_ENUM);
60
61
const GLenum discards7[] = {GL_STENCIL_ATTACHMENT};
62
glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards7);
63
EXPECT_GL_ERROR(GL_INVALID_ENUM);
64
}
65
66
TEST_P(DiscardFramebufferEXTTest, NonDefaultFramebuffer)
67
{
68
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_discard_framebuffer"));
69
70
GLuint tex2D;
71
GLuint framebuffer;
72
73
// Create a basic off-screen framebuffer
74
// Don't create a depth/stencil texture, to ensure that also works correctly
75
glGenTextures(1, &tex2D);
76
glGenFramebuffers(1, &framebuffer);
77
glBindTexture(GL_TEXTURE_2D, tex2D);
78
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
79
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, getWindowWidth(), getWindowHeight(), 0, GL_RGB,
80
GL_UNSIGNED_BYTE, nullptr);
81
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
82
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
83
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex2D, 0);
84
ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
85
86
// These should fail on the non-default framebuffer
87
const GLenum discards1[] = {GL_COLOR_EXT};
88
glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards1);
89
EXPECT_GL_ERROR(GL_INVALID_ENUM);
90
91
const GLenum discards2[] = {GL_DEPTH_EXT};
92
glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards2);
93
EXPECT_GL_ERROR(GL_INVALID_ENUM);
94
95
const GLenum discards3[] = {GL_STENCIL_EXT};
96
glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards3);
97
EXPECT_GL_ERROR(GL_INVALID_ENUM);
98
99
const GLenum discards4[] = {GL_STENCIL_EXT, GL_COLOR_EXT, GL_DEPTH_EXT};
100
glDiscardFramebufferEXT(GL_FRAMEBUFFER, 3, discards4);
101
EXPECT_GL_ERROR(GL_INVALID_ENUM);
102
103
// These should succeed on the non-default framebuffer
104
const GLenum discards5[] = {GL_COLOR_ATTACHMENT0};
105
glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards5);
106
EXPECT_GL_NO_ERROR();
107
108
const GLenum discards6[] = {GL_DEPTH_ATTACHMENT};
109
glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards6);
110
EXPECT_GL_NO_ERROR();
111
112
const GLenum discards7[] = {GL_STENCIL_ATTACHMENT};
113
glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards7);
114
EXPECT_GL_NO_ERROR();
115
}
116
117
// ANGLE implements an optimization that if depth stencil buffer has not been used and not stored in
118
// the renderpass, the depth buffer clear will be dropped.
119
TEST_P(DiscardFramebufferEXTTest, ClearDepthThenDrawWithoutDepthTestThenDiscard)
120
{
121
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_discard_framebuffer"));
122
// TODO: fix crash issue. http://anglebug.com/4141
123
ANGLE_SKIP_TEST_IF(IsD3D11());
124
125
ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::UniformColor());
126
glUseProgram(program);
127
GLint colorUniformLocation =
128
glGetUniformLocation(program, angle::essl1_shaders::ColorUniform());
129
ASSERT_NE(-1, colorUniformLocation);
130
ASSERT_GL_NO_ERROR();
131
132
constexpr GLfloat kDepthClearValue = 0.5f;
133
// This depth value equals to kDepthClearValue after viewport transform
134
constexpr GLfloat depthDrawValue = kDepthClearValue * 2.0f - 1.0f;
135
136
// This depth clear should be optimized out. We do not have a good way to verify that it
137
// actually gets dropped, but at least we will ensure rendering is still correct.
138
glBindFramebuffer(GL_FRAMEBUFFER, 0);
139
glEnable(GL_DEPTH_TEST);
140
glClearDepthf(kDepthClearValue);
141
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
142
glDisable(GL_DEPTH_TEST);
143
glUniform4fv(colorUniformLocation, 1, GLColor::cyan.toNormalizedVector().data());
144
glViewport(0, 0, getWindowWidth(), getWindowHeight());
145
drawQuad(program, essl1_shaders::PositionAttrib(), depthDrawValue + 0.05f);
146
GLenum discards = GL_DEPTH_EXT;
147
glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, &discards);
148
ASSERT_GL_NO_ERROR();
149
EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::cyan);
150
}
151
152
// This test is try to ensure that if depth test has been used, depth clear does not get optimized
153
// out. It also tests that if the depth buffer has not been used, the rendering is still correct.
154
TEST_P(DiscardFramebufferEXTTest, ClearDepthThenDrawWithDepthTestThenDiscard)
155
{
156
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_discard_framebuffer"));
157
// http://anglebug.com/4914
158
ANGLE_SKIP_TEST_IF(IsVulkan() && IsIntel() && IsWindows());
159
160
GLTexture texture;
161
GLRenderbuffer renderbuffer;
162
GLFramebuffer framebuffer;
163
GLint colorUniformLocation;
164
constexpr GLsizei kTexWidth = 256;
165
constexpr GLsizei kTexHeight = 256;
166
167
glBindTexture(GL_TEXTURE_2D, texture);
168
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, kTexWidth, kTexHeight, 0, GL_RGB, GL_UNSIGNED_BYTE,
169
nullptr);
170
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
171
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
172
ASSERT_GL_NO_ERROR();
173
glBindTexture(GL_TEXTURE_2D, 0);
174
175
glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
176
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, kTexWidth, kTexWidth);
177
glBindRenderbuffer(GL_RENDERBUFFER, 0);
178
ASSERT_GL_NO_ERROR();
179
180
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
181
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
182
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderbuffer);
183
ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
184
ASSERT_GL_NO_ERROR();
185
186
ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::UniformColor());
187
glUseProgram(program);
188
colorUniformLocation = glGetUniformLocation(program, angle::essl1_shaders::ColorUniform());
189
ASSERT_NE(-1, colorUniformLocation);
190
ASSERT_GL_NO_ERROR();
191
192
// Draw into FBO0
193
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
194
glClearColor(0.0f, 1.0f, 0.0f, 1.0f); // clear to green
195
constexpr GLfloat kDepthClearValue = 0.5f;
196
// This depth value equals to kDepthClearValue after viewport transform
197
constexpr GLfloat depthDrawValue = kDepthClearValue * 2.0f - 1.0f;
198
glClearDepthf(kDepthClearValue);
199
glEnable(GL_DEPTH_TEST);
200
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
201
// Draw bottom left with depth test disabled. DepthValue should remain 0.5f with blue color.
202
glDepthFunc(GL_LESS);
203
glDisable(GL_DEPTH_TEST);
204
glViewport(0, 0, kTexWidth / 2, kTexHeight / 2);
205
glUniform4fv(colorUniformLocation, 1, GLColor::blue.toNormalizedVector().data());
206
drawQuad(program, essl1_shaders::PositionAttrib(), depthDrawValue - 0.1f);
207
// Draw bottom right with depth test enabled. DepthValue should be 0.45f with blue color.
208
glEnable(GL_DEPTH_TEST);
209
glViewport(kTexWidth / 2, 0, kTexWidth / 2, kTexHeight / 2);
210
drawQuad(program, essl1_shaders::PositionAttrib(), depthDrawValue - 0.1f);
211
// Draw to top left with depth test disabled. DepthValue should remain 0.5f with blue color
212
glDisable(GL_DEPTH_TEST);
213
glViewport(0, kTexHeight / 2, kTexWidth / 2, kTexHeight / 2);
214
drawQuad(program, essl1_shaders::PositionAttrib(), depthDrawValue + 0.1f);
215
// Draw to top right with depth test enabled. DepthValue should remain 0.5f with green color
216
glEnable(GL_DEPTH_TEST);
217
glViewport(kTexWidth / 2, kTexHeight / 2, kTexWidth / 2, kTexHeight / 2);
218
drawQuad(program, essl1_shaders::PositionAttrib(), depthDrawValue + 0.1f);
219
220
// Now draw the full quad with depth test enabled to verify the depth value is expected.
221
// It should fail depth test in bottom right which will keep it with blue color. All other
222
// quarters will pass depth test and draw a red quad.
223
glEnable(GL_DEPTH_TEST);
224
glUniform4fv(colorUniformLocation, 1, GLColor::red.toNormalizedVector().data());
225
glViewport(0, 0, kTexWidth, kTexHeight);
226
drawQuad(program, essl1_shaders::PositionAttrib(), depthDrawValue - 0.05f);
227
228
// Invalidate depth buffer. This will trigger depth value not been written to buffer but the
229
// depth load/clear should not optimize out
230
GLenum discards = GL_DEPTH_ATTACHMENT;
231
glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, &discards);
232
ASSERT_GL_NO_ERROR();
233
234
EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::red);
235
EXPECT_PIXEL_COLOR_EQ(kTexWidth / 2 + 1, 1, GLColor::blue);
236
EXPECT_PIXEL_COLOR_EQ(1, kTexHeight / 2 + 1, GLColor::red);
237
EXPECT_PIXEL_COLOR_EQ(kTexWidth / 2 + 1, kTexHeight / 2 + 1, GLColor::red);
238
}
239
240
// Use this to select which configurations (e.g. which renderer, which GLES major version) these
241
// tests should be run against.
242
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(DiscardFramebufferEXTTest);
243
244