1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 3.0 Module
3 * -------------------------------------------------
4 *
5 * Copyright 2014 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief FBO depthbuffer tests.
22 *//*--------------------------------------------------------------------*/
23
24 #include "es3fFboDepthbufferTests.hpp"
25 #include "es3fFboTestCase.hpp"
26 #include "es3fFboTestUtil.hpp"
27 #include "gluTextureUtil.hpp"
28 #include "tcuTextureUtil.hpp"
29 #include "sglrContextUtil.hpp"
30 #include "glwEnums.hpp"
31
32 namespace deqp
33 {
34 namespace gles3
35 {
36 namespace Functional
37 {
38
39 using std::string;
40 using tcu::IVec2;
41 using tcu::IVec3;
42 using tcu::IVec4;
43 using tcu::UVec4;
44 using tcu::Vec2;
45 using tcu::Vec3;
46 using tcu::Vec4;
47 using namespace FboTestUtil;
48
49 class BasicFboDepthCase : public FboTestCase
50 {
51 public:
BasicFboDepthCase(Context & context,const char * name,const char * desc,uint32_t format,int width,int height)52 BasicFboDepthCase(Context &context, const char *name, const char *desc, uint32_t format, int width, int height)
53 : FboTestCase(context, name, desc)
54 , m_format(format)
55 , m_width(width)
56 , m_height(height)
57 {
58 }
59
60 protected:
preCheck(void)61 void preCheck(void)
62 {
63 checkFormatSupport(m_format);
64 }
65
render(tcu::Surface & dst)66 void render(tcu::Surface &dst)
67 {
68 const uint32_t colorFormat = GL_RGBA8;
69 uint32_t fbo = 0;
70 uint32_t colorRbo = 0;
71 uint32_t depthRbo = 0;
72 GradientShader gradShader(glu::TYPE_FLOAT_VEC4);
73 Texture2DShader texShader(DataTypes() << glu::TYPE_SAMPLER_2D, glu::TYPE_FLOAT_VEC4);
74 uint32_t gradShaderID = getCurrentContext()->createProgram(&gradShader);
75 uint32_t texShaderID = getCurrentContext()->createProgram(&texShader);
76 float clearDepth = 1.0f;
77
78 // Setup shaders
79 gradShader.setGradient(*getCurrentContext(), gradShaderID, tcu::Vec4(0.0f), tcu::Vec4(1.0f));
80 texShader.setUniforms(*getCurrentContext(), texShaderID);
81
82 // Setup FBO
83
84 glGenFramebuffers(1, &fbo);
85 glGenRenderbuffers(1, &colorRbo);
86 glGenRenderbuffers(1, &depthRbo);
87
88 glBindRenderbuffer(GL_RENDERBUFFER, colorRbo);
89 glRenderbufferStorage(GL_RENDERBUFFER, colorFormat, m_width, m_height);
90
91 glBindRenderbuffer(GL_RENDERBUFFER, depthRbo);
92 glRenderbufferStorage(GL_RENDERBUFFER, m_format, m_width, m_height);
93
94 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
95 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo);
96 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRbo);
97 checkError();
98 checkFramebufferStatus(GL_FRAMEBUFFER);
99
100 glViewport(0, 0, m_width, m_height);
101
102 // Clear depth to 1
103 glClearBufferfv(GL_DEPTH, 0, &clearDepth);
104
105 // Render gradient with depth = [-1..1]
106 glEnable(GL_DEPTH_TEST);
107 sglr::drawQuad(*getCurrentContext(), gradShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));
108
109 // Render grid pattern with depth = 0
110 {
111 const uint32_t format = GL_RGBA;
112 const uint32_t dataType = GL_UNSIGNED_BYTE;
113 const int texW = 128;
114 const int texH = 128;
115 uint32_t gridTex = 0;
116 tcu::TextureLevel data(glu::mapGLTransferFormat(format, dataType), texW, texH, 1);
117
118 tcu::fillWithGrid(data.getAccess(), 8, Vec4(0.2f, 0.7f, 0.1f, 1.0f), Vec4(0.7f, 0.1f, 0.5f, 0.8f));
119
120 glGenTextures(1, &gridTex);
121 glBindTexture(GL_TEXTURE_2D, gridTex);
122 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
123 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
124 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
125 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
126 glTexImage2D(GL_TEXTURE_2D, 0, format, texW, texH, 0, format, dataType, data.getAccess().getDataPtr());
127
128 sglr::drawQuad(*getCurrentContext(), texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
129 }
130
131 // Read results.
132 readPixels(dst, 0, 0, m_width, m_height, glu::mapGLInternalFormat(colorFormat), Vec4(1.0f), Vec4(0.0f));
133 }
134
135 private:
136 uint32_t m_format;
137 int m_width;
138 int m_height;
139 };
140
141 class DepthWriteClampCase : public FboTestCase
142 {
143 public:
DepthWriteClampCase(Context & context,const char * name,const char * desc,uint32_t format,int width,int height)144 DepthWriteClampCase(Context &context, const char *name, const char *desc, uint32_t format, int width, int height)
145 : FboTestCase(context, name, desc)
146 , m_format(format)
147 , m_width(width)
148 , m_height(height)
149 {
150 }
151
152 protected:
preCheck(void)153 void preCheck(void)
154 {
155 checkFormatSupport(m_format);
156 }
157
render(tcu::Surface & dst)158 void render(tcu::Surface &dst)
159 {
160 const uint32_t colorFormat = GL_RGBA8;
161 uint32_t fbo = 0;
162 uint32_t colorRbo = 0;
163 uint32_t depthTexture = 0;
164 glu::TransferFormat transferFmt = glu::getTransferFormat(glu::mapGLInternalFormat(m_format));
165
166 DepthGradientShader depthGradShader(glu::TYPE_FLOAT_VEC4);
167 const uint32_t depthGradShaderID = getCurrentContext()->createProgram(&depthGradShader);
168 const float clearDepth = 1.0f;
169 const tcu::Vec4 red(1.0, 0.0, 0.0, 1.0);
170 const tcu::Vec4 green(0.0, 1.0, 0.0, 1.0);
171
172 // Setup FBO
173
174 glGenFramebuffers(1, &fbo);
175 glGenRenderbuffers(1, &colorRbo);
176 glGenTextures(1, &depthTexture);
177
178 glBindRenderbuffer(GL_RENDERBUFFER, colorRbo);
179 glRenderbufferStorage(GL_RENDERBUFFER, colorFormat, m_width, m_height);
180
181 glBindTexture(GL_TEXTURE_2D, depthTexture);
182 glTexImage2D(GL_TEXTURE_2D, 0, m_format, m_width, m_height, 0, transferFmt.format, transferFmt.dataType,
183 DE_NULL);
184 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
185 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
186
187 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
188 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo);
189 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
190 checkError();
191 checkFramebufferStatus(GL_FRAMEBUFFER);
192
193 glViewport(0, 0, m_width, m_height);
194
195 // Clear depth to 1
196 glClearBufferfv(GL_DEPTH, 0, &clearDepth);
197
198 // Test that invalid values are not written to the depth buffer
199
200 // Render green quad, depth gradient = [-1..2]
201 glEnable(GL_DEPTH_TEST);
202 glDepthFunc(GL_ALWAYS);
203
204 depthGradShader.setUniforms(*getCurrentContext(), depthGradShaderID, -1.0f, 2.0f, green);
205 sglr::drawQuad(*getCurrentContext(), depthGradShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));
206 glDepthMask(GL_FALSE);
207
208 // Test if any fragment has greater depth than 1; there should be none
209 glDepthFunc(GL_LESS); // (1 < depth) ?
210 depthGradShader.setUniforms(*getCurrentContext(), depthGradShaderID, 1.0f, 1.0f, red);
211 sglr::drawQuad(*getCurrentContext(), depthGradShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));
212
213 // Test if any fragment has smaller depth than 0; there should be none
214 glDepthFunc(GL_GREATER); // (0 > depth) ?
215 depthGradShader.setUniforms(*getCurrentContext(), depthGradShaderID, 0.0f, 0.0f, red);
216 sglr::drawQuad(*getCurrentContext(), depthGradShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));
217
218 // Read results.
219 readPixels(dst, 0, 0, m_width, m_height, glu::mapGLInternalFormat(colorFormat), Vec4(1.0f), Vec4(0.0f));
220 }
221
222 private:
223 const uint32_t m_format;
224 const int m_width;
225 const int m_height;
226 };
227
228 class DepthTestClampCase : public FboTestCase
229 {
230 public:
DepthTestClampCase(Context & context,const char * name,const char * desc,uint32_t format,int width,int height)231 DepthTestClampCase(Context &context, const char *name, const char *desc, uint32_t format, int width, int height)
232 : FboTestCase(context, name, desc)
233 , m_format(format)
234 , m_width(width)
235 , m_height(height)
236 {
237 }
238
239 protected:
preCheck(void)240 void preCheck(void)
241 {
242 checkFormatSupport(m_format);
243 }
244
render(tcu::Surface & dst)245 void render(tcu::Surface &dst)
246 {
247 const uint32_t colorFormat = GL_RGBA8;
248 uint32_t fbo = 0;
249 uint32_t colorRbo = 0;
250 uint32_t depthTexture = 0;
251 glu::TransferFormat transferFmt = glu::getTransferFormat(glu::mapGLInternalFormat(m_format));
252
253 DepthGradientShader depthGradShader(glu::TYPE_FLOAT_VEC4);
254 const uint32_t depthGradShaderID = getCurrentContext()->createProgram(&depthGradShader);
255 const float clearDepth = 1.0f;
256 const tcu::Vec4 yellow(1.0, 1.0, 0.0, 1.0);
257 const tcu::Vec4 green(0.0, 1.0, 0.0, 1.0);
258
259 // Setup FBO
260
261 glGenFramebuffers(1, &fbo);
262 glGenRenderbuffers(1, &colorRbo);
263 glGenTextures(1, &depthTexture);
264
265 glBindRenderbuffer(GL_RENDERBUFFER, colorRbo);
266 glRenderbufferStorage(GL_RENDERBUFFER, colorFormat, m_width, m_height);
267
268 glBindTexture(GL_TEXTURE_2D, depthTexture);
269 glTexImage2D(GL_TEXTURE_2D, 0, m_format, m_width, m_height, 0, transferFmt.format, transferFmt.dataType,
270 DE_NULL);
271 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
272 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
273
274 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
275 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo);
276 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
277 checkError();
278 checkFramebufferStatus(GL_FRAMEBUFFER);
279
280 glViewport(0, 0, m_width, m_height);
281
282 // Clear depth to 1
283 glClearBufferfv(GL_DEPTH, 0, &clearDepth);
284
285 // Test values used in depth test are clamped
286
287 // Render green quad, depth gradient = [-1..2]
288 glEnable(GL_DEPTH_TEST);
289 glDepthFunc(GL_ALWAYS);
290
291 depthGradShader.setUniforms(*getCurrentContext(), depthGradShaderID, -1.0f, 2.0f, green);
292 sglr::drawQuad(*getCurrentContext(), depthGradShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));
293
294 // Render yellow quad, depth gradient = [-0.5..3]. Gradients have equal values only outside [0, 1] range due to clamping
295 glDepthFunc(GL_EQUAL);
296 depthGradShader.setUniforms(*getCurrentContext(), depthGradShaderID, -0.5f, 3.0f, yellow);
297 sglr::drawQuad(*getCurrentContext(), depthGradShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));
298
299 // Read results.
300 readPixels(dst, 0, 0, m_width, m_height, glu::mapGLInternalFormat(colorFormat), Vec4(1.0f), Vec4(0.0f));
301 }
302
303 private:
304 const uint32_t m_format;
305 const int m_width;
306 const int m_height;
307 };
308
FboDepthTests(Context & context)309 FboDepthTests::FboDepthTests(Context &context) : TestCaseGroup(context, "depth", "Depth tests")
310 {
311 }
312
~FboDepthTests(void)313 FboDepthTests::~FboDepthTests(void)
314 {
315 }
316
init(void)317 void FboDepthTests::init(void)
318 {
319 static const uint32_t depthFormats[] = {GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT16,
320 GL_DEPTH32F_STENCIL8, GL_DEPTH24_STENCIL8};
321
322 // .basic
323 {
324 tcu::TestCaseGroup *basicGroup = new tcu::TestCaseGroup(m_testCtx, "basic", "Basic depth tests");
325 addChild(basicGroup);
326
327 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(depthFormats); fmtNdx++)
328 basicGroup->addChild(new BasicFboDepthCase(m_context, getFormatName(depthFormats[fmtNdx]), "",
329 depthFormats[fmtNdx], 119, 127));
330 }
331
332 // .depth_write_clamp
333 {
334 tcu::TestCaseGroup *depthClampGroup =
335 new tcu::TestCaseGroup(m_testCtx, "depth_write_clamp", "Depth write clamping tests");
336 addChild(depthClampGroup);
337
338 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(depthFormats); fmtNdx++)
339 depthClampGroup->addChild(new DepthWriteClampCase(m_context, getFormatName(depthFormats[fmtNdx]), "",
340 depthFormats[fmtNdx], 119, 127));
341 }
342
343 // .depth_test_clamp
344 {
345 tcu::TestCaseGroup *depthClampGroup =
346 new tcu::TestCaseGroup(m_testCtx, "depth_test_clamp", "Depth test value clamping tests");
347 addChild(depthClampGroup);
348
349 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(depthFormats); fmtNdx++)
350 depthClampGroup->addChild(new DepthTestClampCase(m_context, getFormatName(depthFormats[fmtNdx]), "",
351 depthFormats[fmtNdx], 119, 127));
352 }
353 }
354
355 } // namespace Functional
356 } // namespace gles3
357 } // namespace deqp
358