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::Vec2;
41 using tcu::Vec3;
42 using tcu::Vec4;
43 using tcu::IVec2;
44 using tcu::IVec3;
45 using tcu::IVec4;
46 using tcu::UVec4;
47 using namespace FboTestUtil;
48
49 class BasicFboDepthCase : public FboTestCase
50 {
51 public:
BasicFboDepthCase(Context & context,const char * name,const char * desc,deUint32 format,int width,int height)52 BasicFboDepthCase (Context& context, const char* name, const char* desc, deUint32 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 deUint32 colorFormat = GL_RGBA8;
69 deUint32 fbo = 0;
70 deUint32 colorRbo = 0;
71 deUint32 depthRbo = 0;
72 GradientShader gradShader (glu::TYPE_FLOAT_VEC4);
73 Texture2DShader texShader (DataTypes() << glu::TYPE_SAMPLER_2D, glu::TYPE_FLOAT_VEC4);
74 deUint32 gradShaderID = getCurrentContext()->createProgram(&gradShader);
75 deUint32 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 deUint32 format = GL_RGBA;
112 const deUint32 dataType = GL_UNSIGNED_BYTE;
113 const int texW = 128;
114 const int texH = 128;
115 deUint32 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 deUint32 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,deUint32 format,int width,int height)144 DepthWriteClampCase (Context& context, const char* name, const char* desc, deUint32 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 deUint32 colorFormat = GL_RGBA8;
161 deUint32 fbo = 0;
162 deUint32 colorRbo = 0;
163 deUint32 depthTexture = 0;
164 glu::TransferFormat transferFmt = glu::getTransferFormat(glu::mapGLInternalFormat(m_format));
165
166 DepthGradientShader depthGradShader (glu::TYPE_FLOAT_VEC4);
167 const deUint32 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, DE_NULL);
183 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
184 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
185
186 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
187 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo);
188 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
189 checkError();
190 checkFramebufferStatus(GL_FRAMEBUFFER);
191
192 glViewport(0, 0, m_width, m_height);
193
194 // Clear depth to 1
195 glClearBufferfv(GL_DEPTH, 0, &clearDepth);
196
197 // Test that invalid values are not written to the depth buffer
198
199 // Render green quad, depth gradient = [-1..2]
200 glEnable(GL_DEPTH_TEST);
201 glDepthFunc(GL_ALWAYS);
202
203 depthGradShader.setUniforms(*getCurrentContext(), depthGradShaderID, -1.0f, 2.0f, green);
204 sglr::drawQuad(*getCurrentContext(), depthGradShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));
205 glDepthMask(GL_FALSE);
206
207 // Test if any fragment has greater depth than 1; there should be none
208 glDepthFunc(GL_LESS); // (1 < depth) ?
209 depthGradShader.setUniforms(*getCurrentContext(), depthGradShaderID, 1.0f, 1.0f, red);
210 sglr::drawQuad(*getCurrentContext(), depthGradShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));
211
212 // Test if any fragment has smaller depth than 0; there should be none
213 glDepthFunc(GL_GREATER); // (0 > depth) ?
214 depthGradShader.setUniforms(*getCurrentContext(), depthGradShaderID, 0.0f, 0.0f, red);
215 sglr::drawQuad(*getCurrentContext(), depthGradShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));
216
217 // Read results.
218 readPixels(dst, 0, 0, m_width, m_height, glu::mapGLInternalFormat(colorFormat), Vec4(1.0f), Vec4(0.0f));
219 }
220
221 private:
222 const deUint32 m_format;
223 const int m_width;
224 const int m_height;
225 };
226
227 class DepthTestClampCase : public FboTestCase
228 {
229 public:
DepthTestClampCase(Context & context,const char * name,const char * desc,deUint32 format,int width,int height)230 DepthTestClampCase (Context& context, const char* name, const char* desc, deUint32 format, int width, int height)
231 : FboTestCase (context, name, desc)
232 , m_format (format)
233 , m_width (width)
234 , m_height (height)
235 {
236 }
237
238 protected:
preCheck(void)239 void preCheck (void)
240 {
241 checkFormatSupport(m_format);
242 }
243
render(tcu::Surface & dst)244 void render (tcu::Surface& dst)
245 {
246 const deUint32 colorFormat = GL_RGBA8;
247 deUint32 fbo = 0;
248 deUint32 colorRbo = 0;
249 deUint32 depthTexture = 0;
250 glu::TransferFormat transferFmt = glu::getTransferFormat(glu::mapGLInternalFormat(m_format));
251
252 DepthGradientShader depthGradShader (glu::TYPE_FLOAT_VEC4);
253 const deUint32 depthGradShaderID = getCurrentContext()->createProgram(&depthGradShader);
254 const float clearDepth = 1.0f;
255 const tcu::Vec4 yellow (1.0, 1.0, 0.0, 1.0);
256 const tcu::Vec4 green (0.0, 1.0, 0.0, 1.0);
257
258 // Setup FBO
259
260 glGenFramebuffers(1, &fbo);
261 glGenRenderbuffers(1, &colorRbo);
262 glGenTextures(1, &depthTexture);
263
264 glBindRenderbuffer(GL_RENDERBUFFER, colorRbo);
265 glRenderbufferStorage(GL_RENDERBUFFER, colorFormat, m_width, m_height);
266
267 glBindTexture(GL_TEXTURE_2D, depthTexture);
268 glTexImage2D(GL_TEXTURE_2D, 0, m_format, m_width, m_height, 0, transferFmt.format, transferFmt.dataType, DE_NULL);
269 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
270 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
271
272 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
273 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo);
274 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
275 checkError();
276 checkFramebufferStatus(GL_FRAMEBUFFER);
277
278 glViewport(0, 0, m_width, m_height);
279
280 // Clear depth to 1
281 glClearBufferfv(GL_DEPTH, 0, &clearDepth);
282
283 // Test values used in depth test are clamped
284
285 // Render green quad, depth gradient = [-1..2]
286 glEnable(GL_DEPTH_TEST);
287 glDepthFunc(GL_ALWAYS);
288
289 depthGradShader.setUniforms(*getCurrentContext(), depthGradShaderID, -1.0f, 2.0f, green);
290 sglr::drawQuad(*getCurrentContext(), depthGradShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));
291
292 // Render yellow quad, depth gradient = [-0.5..3]. Gradients have equal values only outside [0, 1] range due to clamping
293 glDepthFunc(GL_EQUAL);
294 depthGradShader.setUniforms(*getCurrentContext(), depthGradShaderID, -0.5f, 3.0f, yellow);
295 sglr::drawQuad(*getCurrentContext(), depthGradShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));
296
297 // Read results.
298 readPixels(dst, 0, 0, m_width, m_height, glu::mapGLInternalFormat(colorFormat), Vec4(1.0f), Vec4(0.0f));
299 }
300
301 private:
302 const deUint32 m_format;
303 const int m_width;
304 const int m_height;
305 };
306
FboDepthTests(Context & context)307 FboDepthTests::FboDepthTests (Context& context)
308 : TestCaseGroup(context, "depth", "Depth tests")
309 {
310 }
311
~FboDepthTests(void)312 FboDepthTests::~FboDepthTests (void)
313 {
314 }
315
init(void)316 void FboDepthTests::init (void)
317 {
318 static const deUint32 depthFormats[] =
319 {
320 GL_DEPTH_COMPONENT32F,
321 GL_DEPTH_COMPONENT24,
322 GL_DEPTH_COMPONENT16,
323 GL_DEPTH32F_STENCIL8,
324 GL_DEPTH24_STENCIL8
325 };
326
327 // .basic
328 {
329 tcu::TestCaseGroup* basicGroup = new tcu::TestCaseGroup(m_testCtx, "basic", "Basic depth tests");
330 addChild(basicGroup);
331
332 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(depthFormats); fmtNdx++)
333 basicGroup->addChild(new BasicFboDepthCase(m_context, getFormatName(depthFormats[fmtNdx]), "", depthFormats[fmtNdx], 119, 127));
334 }
335
336 // .depth_write_clamp
337 {
338 tcu::TestCaseGroup* depthClampGroup = new tcu::TestCaseGroup(m_testCtx, "depth_write_clamp", "Depth write clamping tests");
339 addChild(depthClampGroup);
340
341 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(depthFormats); fmtNdx++)
342 depthClampGroup->addChild(new DepthWriteClampCase(m_context, getFormatName(depthFormats[fmtNdx]), "", depthFormats[fmtNdx], 119, 127));
343 }
344
345 // .depth_test_clamp
346 {
347 tcu::TestCaseGroup* depthClampGroup = new tcu::TestCaseGroup(m_testCtx, "depth_test_clamp", "Depth test value clamping tests");
348 addChild(depthClampGroup);
349
350 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(depthFormats); fmtNdx++)
351 depthClampGroup->addChild(new DepthTestClampCase(m_context, getFormatName(depthFormats[fmtNdx]), "", depthFormats[fmtNdx], 119, 127));
352 }
353 }
354
355 } // Functional
356 } // gles3
357 } // deqp
358