1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 3.0 Module
3 * -------------------------------------------------
5 * Copyright 2014 The Android Open Source Project
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * \brief FBO depthbuffer tests.
22 *//*--------------------------------------------------------------------*/
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"
47 using namespace FboTestUtil;
49 class BasicFboDepthCase : public FboTestCase
52 BasicFboDepthCase (Context& context, const char* name, const char* desc, deUint32 format, int width, int height)
53 : FboTestCase (context, name, desc)
63 checkFormatSupport(m_format);
66 void render (tcu::Surface& dst)
68 const deUint32 colorFormat = GL_RGBA8;
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;
79 gradShader.setGradient(*getCurrentContext(), gradShaderID, tcu::Vec4(0.0f), tcu::Vec4(1.0f));
80 texShader.setUniforms (*getCurrentContext(), texShaderID);
84 glGenFramebuffers(1, &fbo);
85 glGenRenderbuffers(1, &colorRbo);
86 glGenRenderbuffers(1, &depthRbo);
88 glBindRenderbuffer(GL_RENDERBUFFER, colorRbo);
89 glRenderbufferStorage(GL_RENDERBUFFER, colorFormat, m_width, m_height);
91 glBindRenderbuffer(GL_RENDERBUFFER, depthRbo);
92 glRenderbufferStorage(GL_RENDERBUFFER, m_format, m_width, m_height);
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);
98 checkFramebufferStatus(GL_FRAMEBUFFER);
100 glViewport(0, 0, m_width, m_height);
103 glClearBufferfv(GL_DEPTH, 0, &clearDepth);
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));
109 // Render grid pattern with depth = 0
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);
118 tcu::fillWithGrid(data.getAccess(), 8, Vec4(0.2f, 0.7f, 0.1f, 1.0f), Vec4(0.7f, 0.1f, 0.5f, 0.8f));
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());
128 sglr::drawQuad(*getCurrentContext(), texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
132 readPixels(dst, 0, 0, m_width, m_height, glu::mapGLInternalFormat(colorFormat), Vec4(1.0f), Vec4(0.0f));
141 class DepthWriteClampCase : public FboTestCase
144 DepthWriteClampCase (Context& context, const char* name, const char* desc, deUint32 format, int width, int height)
145 : FboTestCase (context, name, desc)
155 checkFormatSupport(m_format);
158 void render (tcu::Surface& dst)
160 const deUint32 colorFormat = GL_RGBA8;
162 deUint32 colorRbo = 0;
163 deUint32 depthTexture = 0;
164 glu::TransferFormat transferFmt = glu::getTransferFormat(glu::mapGLInternalFormat(m_format));
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);
174 glGenFramebuffers(1, &fbo);
175 glGenRenderbuffers(1, &colorRbo);
176 glGenTextures(1, &depthTexture);
178 glBindRenderbuffer(GL_RENDERBUFFER, colorRbo);
179 glRenderbufferStorage(GL_RENDERBUFFER, colorFormat, m_width, m_height);
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);
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);
190 checkFramebufferStatus(GL_FRAMEBUFFER);
192 glViewport(0, 0, m_width, m_height);
195 glClearBufferfv(GL_DEPTH, 0, &clearDepth);
197 // Test that invalid values are not written to the depth buffer
199 // Render green quad, depth gradient = [-1..2]
200 glEnable(GL_DEPTH_TEST);
201 glDepthFunc(GL_ALWAYS);
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);
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));
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));
218 readPixels(dst, 0, 0, m_width, m_height, glu::mapGLInternalFormat(colorFormat), Vec4(1.0f), Vec4(0.0f));
222 const deUint32 m_format;
227 class DepthTestClampCase : public FboTestCase
230 DepthTestClampCase (Context& context, const char* name, const char* desc, deUint32 format, int width, int height)
231 : FboTestCase (context, name, desc)
241 checkFormatSupport(m_format);
244 void render (tcu::Surface& dst)
246 const deUint32 colorFormat = GL_RGBA8;
248 deUint32 colorRbo = 0;
249 deUint32 depthTexture = 0;
250 glu::TransferFormat transferFmt = glu::getTransferFormat(glu::mapGLInternalFormat(m_format));
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);
260 glGenFramebuffers(1, &fbo);
261 glGenRenderbuffers(1, &colorRbo);
262 glGenTextures(1, &depthTexture);
264 glBindRenderbuffer(GL_RENDERBUFFER, colorRbo);
265 glRenderbufferStorage(GL_RENDERBUFFER, colorFormat, m_width, m_height);
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);
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);
276 checkFramebufferStatus(GL_FRAMEBUFFER);
278 glViewport(0, 0, m_width, m_height);
281 glClearBufferfv(GL_DEPTH, 0, &clearDepth);
283 // Test values used in depth test are clamped
285 // Render green quad, depth gradient = [-1..2]
286 glEnable(GL_DEPTH_TEST);
287 glDepthFunc(GL_ALWAYS);
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));
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));
298 readPixels(dst, 0, 0, m_width, m_height, glu::mapGLInternalFormat(colorFormat), Vec4(1.0f), Vec4(0.0f));
302 const deUint32 m_format;
307 FboDepthTests::FboDepthTests (Context& context)
308 : TestCaseGroup(context, "depth", "Depth tests")
312 FboDepthTests::~FboDepthTests (void)
316 void FboDepthTests::init (void)
318 static const deUint32 depthFormats[] =
320 GL_DEPTH_COMPONENT32F,
321 GL_DEPTH_COMPONENT24,
322 GL_DEPTH_COMPONENT16,
323 GL_DEPTH32F_STENCIL8,
329 tcu::TestCaseGroup* basicGroup = new tcu::TestCaseGroup(m_testCtx, "basic", "Basic depth tests");
330 addChild(basicGroup);
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));
336 // .depth_write_clamp
338 tcu::TestCaseGroup* depthClampGroup = new tcu::TestCaseGroup(m_testCtx, "depth_write_clamp", "Depth write clamping tests");
339 addChild(depthClampGroup);
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));
347 tcu::TestCaseGroup* depthClampGroup = new tcu::TestCaseGroup(m_testCtx, "depth_test_clamp", "Depth test value clamping tests");
348 addChild(depthClampGroup);
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));