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