• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 Framebuffer Object API Tests.
22  *
23  * Notes:
24  *   All gl calls are passed thru sglr::Context class. Reasons:
25  *    + Name, object allocation is tracked and live resources are freed
26  *      when Context is destroyed.
27  *    + Makes it possible to easily log all relevant calls into test log.
28  *      \todo [pyry] This is not implemented yet
29  *//*--------------------------------------------------------------------*/
30 
31 #include "es3fFboApiTests.hpp"
32 #include "sglrGLContext.hpp"
33 #include "gluDefs.hpp"
34 #include "gluStrUtil.hpp"
35 #include "tcuRenderTarget.hpp"
36 #include "deString.h"
37 #include "glwFunctions.hpp"
38 #include "glwEnums.hpp"
39 
40 namespace deqp
41 {
42 namespace gles3
43 {
44 namespace Functional
45 {
46 
47 using std::string;
48 using std::vector;
49 using tcu::TestLog;
50 
51 using glw::GLenum;
52 using glw::GLint;
53 
logComment(tcu::TestContext & testCtx,const char * comment)54 static void logComment (tcu::TestContext& testCtx, const char* comment)
55 {
56 	testCtx.getLog() << TestLog::Message << "// " << comment << TestLog::EndMessage;
57 }
58 
checkError(tcu::TestContext & testCtx,sglr::Context & ctx,GLenum expect)59 static void checkError (tcu::TestContext& testCtx, sglr::Context& ctx, GLenum expect)
60 {
61 	GLenum result = ctx.getError();
62 	testCtx.getLog() << TestLog::Message << "// " << (result == expect ? "Pass" : "Fail") << ", expected " << glu::getErrorStr(expect) << TestLog::EndMessage;
63 
64 	if (result != expect)
65 		testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Error code mismatch");
66 }
67 
getAttachmentName(GLenum attachment)68 static const char* getAttachmentName (GLenum attachment)
69 {
70 	switch (attachment)
71 	{
72 		case GL_COLOR_ATTACHMENT0:	return "GL_COLOR_ATTACHMENT0";
73 		case GL_DEPTH_ATTACHMENT:	return "GL_DEPTH_ATTACHMENT";
74 		case GL_STENCIL_ATTACHMENT:	return "GL_STENCIL_ATTACHMENT";
75 		default: throw tcu::InternalError("Unknown attachment", "", __FILE__, __LINE__);
76 	}
77 }
78 
getAttachmentParameterName(GLenum pname)79 static const char* getAttachmentParameterName (GLenum pname)
80 {
81 	switch (pname)
82 	{
83 		case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:				return "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE";
84 		case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:				return "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME";
85 		case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:			return "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL";
86 		case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:	return "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE";
87 		default: throw tcu::InternalError("Unknown parameter", "", __FILE__, __LINE__);
88 	}
89 }
90 
getAttachmentParameterValueName(GLint value)91 static string getAttachmentParameterValueName (GLint value)
92 {
93 	switch (value)
94 	{
95 		case 0:									return "GL_NONE(0)";
96 		case GL_TEXTURE:						return "GL_TEXTURE";
97 		case GL_RENDERBUFFER:					return "GL_RENDERBUFFER";
98 		case GL_TEXTURE_CUBE_MAP_POSITIVE_X:	return "GL_TEXTURE_CUBE_MAP_POSITIVE_X";
99 		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:	return "GL_TEXTURE_CUBE_MAP_NEGATIVE_X";
100 		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:	return "GL_TEXTURE_CUBE_MAP_POSITIVE_Y";
101 		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:	return "GL_TEXTURE_CUBE_MAP_NEGATIVE_Y";
102 		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:	return "GL_TEXTURE_CUBE_MAP_POSITIVE_Z";
103 		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:	return "GL_TEXTURE_CUBE_MAP_NEGATIVE_Z";
104 		default:
105 		{
106 			char tmp[64];
107 			deSprintf(tmp, sizeof(tmp), "0x%x", value);
108 			return string(tmp);
109 		}
110 	}
111 }
112 
checkFboAttachmentParam(tcu::TestContext & testCtx,sglr::Context & ctx,GLenum attachment,GLenum pname,GLint expectedValue)113 static void checkFboAttachmentParam (tcu::TestContext& testCtx, sglr::Context& ctx, GLenum attachment, GLenum pname, GLint expectedValue)
114 {
115 	TestLog& log = testCtx.getLog();
116 	log << TestLog::Message << "// Querying " << getAttachmentName(attachment) << " " << getAttachmentParameterName(pname) << TestLog::EndMessage;
117 
118 	GLint value = 0xcdcdcdcd;
119 	ctx.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, attachment, pname, &value);
120 
121 	GLenum err = ctx.getError();
122 
123 	if (value == expectedValue && err == GL_NO_ERROR)
124 		log << TestLog::Message << "// Pass" << TestLog::EndMessage;
125 	else
126 	{
127 		log << TestLog::Message << "// Fail, expected " << getAttachmentParameterValueName(expectedValue) << " without error" << TestLog::EndMessage;
128 		testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid result for attachment param query");
129 	}
130 }
131 
textureLevelsTest(tcu::TestContext & testCtx,sglr::Context & context)132 static void textureLevelsTest (tcu::TestContext& testCtx, sglr::Context& context)
133 {
134 	deUint32	tex		= 1;
135 	deUint32	fbo		= 1;
136 	GLint		maxTexSize;
137 	int			log2MaxTexSize;
138 
139 	context.getIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize);
140 	log2MaxTexSize = deLog2Floor32(maxTexSize);
141 
142 	testCtx.getLog() << TestLog::Message << "// GL_MAX_TEXTURE_SIZE is " << maxTexSize << ", floor(log2(" << maxTexSize << ")) = " << log2MaxTexSize << TestLog::EndMessage;
143 
144 	context.bindTexture(GL_TEXTURE_2D, tex);
145 	context.texImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256, 256);
146 	context.texImage2D(GL_TEXTURE_2D, 1, GL_RGB, 128, 128);
147 
148 	context.bindFramebuffer(GL_FRAMEBUFFER, fbo);
149 
150 	const int levels[] = { 2, 1, 0, -1, 0x7fffffff, 0, log2MaxTexSize-2, log2MaxTexSize-1, log2MaxTexSize, log2MaxTexSize+1, log2MaxTexSize+2, 1 };
151 
152 	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(levels); ndx++)
153 	{
154 		context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, levels[ndx]);
155 		checkError(testCtx, context, levels[ndx] >= 0 && levels[ndx] <= log2MaxTexSize ? GL_NO_ERROR : GL_INVALID_VALUE);
156 	}
157 }
158 
validTex2DAttachmentsTest(tcu::TestContext & testCtx,sglr::Context & context)159 static void validTex2DAttachmentsTest (tcu::TestContext& testCtx, sglr::Context& context)
160 {
161 	context.bindFramebuffer(GL_FRAMEBUFFER, 1);
162 	static const GLenum attachmentPoints[] =
163 	{
164 		GL_COLOR_ATTACHMENT0,
165 		GL_DEPTH_ATTACHMENT,
166 		GL_STENCIL_ATTACHMENT
167 	};
168 
169 	// Texture2D
170 	deUint32 tex2D = 1;
171 	context.bindTexture(GL_TEXTURE_2D, tex2D);
172 	for (int pointNdx = 0; pointNdx < DE_LENGTH_OF_ARRAY(attachmentPoints); pointNdx++)
173 	{
174 		context.framebufferTexture2D(GL_FRAMEBUFFER, attachmentPoints[pointNdx], GL_TEXTURE_2D, tex2D, 0);
175 		checkError(testCtx, context, GL_NO_ERROR);
176 	}
177 }
178 
validTexCubeAttachmentsTest(tcu::TestContext & testCtx,sglr::Context & context)179 static void validTexCubeAttachmentsTest (tcu::TestContext& testCtx, sglr::Context& context)
180 {
181 	static const GLenum attachmentPoints[] =
182 	{
183 		GL_COLOR_ATTACHMENT0,
184 		GL_DEPTH_ATTACHMENT,
185 		GL_STENCIL_ATTACHMENT
186 	};
187 	static const GLenum cubeTargets[] =
188 	{
189 		GL_TEXTURE_CUBE_MAP_POSITIVE_X,
190 		GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
191 		GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
192 		GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
193 		GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
194 		GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
195 	};
196 
197 	context.bindFramebuffer(GL_FRAMEBUFFER, 1);
198 
199 	// TextureCube
200 	deUint32 texCube = 2;
201 	context.bindTexture(GL_TEXTURE_CUBE_MAP, texCube);
202 	for (int pointNdx = 0; pointNdx < DE_LENGTH_OF_ARRAY(attachmentPoints); pointNdx++)
203 	{
204 		for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(cubeTargets); targetNdx++)
205 		{
206 			context.framebufferTexture2D(GL_FRAMEBUFFER, attachmentPoints[pointNdx], cubeTargets[targetNdx], texCube, 0);
207 			checkError(testCtx, context, GL_NO_ERROR);
208 		}
209 	}
210 }
211 
validRboAttachmentsTest(tcu::TestContext & testCtx,sglr::Context & context)212 static void validRboAttachmentsTest (tcu::TestContext& testCtx, sglr::Context& context)
213 {
214 	static const GLenum attachmentPoints[] =
215 	{
216 		GL_COLOR_ATTACHMENT0,
217 		GL_DEPTH_ATTACHMENT,
218 		GL_STENCIL_ATTACHMENT
219 	};
220 
221 	context.bindFramebuffer(GL_FRAMEBUFFER, 1);
222 
223 	// Renderbuffer
224 	deUint32 rbo = 3;
225 	context.bindRenderbuffer(GL_RENDERBUFFER, rbo);
226 	for (int pointNdx = 0; pointNdx < DE_LENGTH_OF_ARRAY(attachmentPoints); pointNdx++)
227 	{
228 		context.framebufferRenderbuffer(GL_FRAMEBUFFER, attachmentPoints[pointNdx], GL_RENDERBUFFER, rbo);
229 		checkError(testCtx, context, GL_NO_ERROR);
230 	}
231 }
232 
attachToDefaultFramebufferTest(tcu::TestContext & testCtx,sglr::Context & context)233 static void attachToDefaultFramebufferTest (tcu::TestContext& testCtx, sglr::Context& context)
234 {
235 	logComment(testCtx, "Attaching 2D texture to default framebuffer");
236 
237 	deUint32 tex2D = 1;
238 	context.bindTexture(GL_TEXTURE_2D, tex2D);
239 	context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex2D, 0);
240 	checkError(testCtx, context, GL_INVALID_OPERATION);
241 
242 	logComment(testCtx, "Attaching renderbuffer to default framebuffer");
243 
244 	deUint32 rbo = 1;
245 	context.bindRenderbuffer(GL_RENDERBUFFER, rbo);
246 	context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo);
247 	checkError(testCtx, context, GL_INVALID_OPERATION);
248 }
249 
invalidTex2DAttachmentTest(tcu::TestContext & testCtx,sglr::Context & context)250 static void invalidTex2DAttachmentTest (tcu::TestContext& testCtx, sglr::Context& context)
251 {
252 	context.bindFramebuffer(GL_FRAMEBUFFER, 1);
253 
254 	logComment(testCtx, "Attaching 2D texture using GL_TEXTURE_CUBE_MAP_NEGATIVE_X texture target");
255 
256 	deUint32 tex2D = 1;
257 	context.bindTexture(GL_TEXTURE_2D, tex2D);
258 	context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, tex2D, 0);
259 	checkError(testCtx, context, GL_INVALID_OPERATION);
260 
261 	logComment(testCtx, "Attaching deleted 2D texture object");
262 	context.deleteTextures(1, &tex2D);
263 	context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex2D, 0);
264 	checkError(testCtx, context, GL_INVALID_OPERATION);
265 }
266 
invalidTexCubeAttachmentTest(tcu::TestContext & testCtx,sglr::Context & context)267 static void invalidTexCubeAttachmentTest (tcu::TestContext& testCtx, sglr::Context& context)
268 {
269 	context.bindFramebuffer(GL_FRAMEBUFFER, 1);
270 
271 	logComment(testCtx, "Attaching cube texture using GL_TEXTURE_2D texture target");
272 	deUint32 texCube = 2;
273 	context.bindTexture(GL_TEXTURE_CUBE_MAP, texCube);
274 	context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texCube, 0);
275 	checkError(testCtx, context, GL_INVALID_OPERATION);
276 
277 	logComment(testCtx, "Attaching deleted cube texture object");
278 	context.deleteTextures(1, &texCube);
279 	context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X, texCube, 0);
280 	checkError(testCtx, context, GL_INVALID_OPERATION);
281 }
282 
invalidRboAttachmentTest(tcu::TestContext & testCtx,sglr::Context & context)283 static void invalidRboAttachmentTest (tcu::TestContext& testCtx, sglr::Context& context)
284 {
285 	context.bindFramebuffer(GL_FRAMEBUFFER, 1);
286 
287 	logComment(testCtx, "Attaching renderbuffer using GL_FRAMEBUFFER renderbuffer target");
288 	deUint32 rbo = 3;
289 	context.bindRenderbuffer(GL_RENDERBUFFER, rbo);
290 	context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER, rbo);
291 	checkError(testCtx, context, GL_INVALID_ENUM);
292 
293 	logComment(testCtx, "Attaching deleted renderbuffer object");
294 	context.deleteRenderbuffers(1, &rbo);
295 	context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);
296 	checkError(testCtx, context, GL_INVALID_OPERATION);
297 }
298 
attachNamesTest(tcu::TestContext & testCtx,sglr::Context & context)299 static void attachNamesTest (tcu::TestContext& testCtx, sglr::Context& context)
300 {
301 	context.bindFramebuffer(GL_FRAMEBUFFER, 1);
302 
303 	// Just allocate some names, don't bind for storage
304 	deUint32 reservedTexName;
305 	context.genTextures(1, &reservedTexName);
306 
307 	logComment(testCtx, "Attaching allocated texture name to 2D target");
308 	context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, reservedTexName, 0);
309 	checkError(testCtx, context, GL_INVALID_OPERATION);
310 
311 	logComment(testCtx, "Attaching allocated texture name to cube target");
312 	context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, reservedTexName, 0);
313 	checkError(testCtx, context, GL_INVALID_OPERATION);
314 
315 	deUint32 reservedRboName;
316 	context.genRenderbuffers(1, &reservedRboName);
317 
318 	logComment(testCtx, "Attaching allocated renderbuffer name");
319 	context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, reservedRboName);
320 	checkError(testCtx, context, GL_INVALID_OPERATION);
321 }
322 
attachmentQueryDefaultFboTest(tcu::TestContext & testCtx,sglr::Context & ctx)323 static void attachmentQueryDefaultFboTest (tcu::TestContext& testCtx, sglr::Context& ctx)
324 {
325 	// Check that proper error codes are returned
326 	GLint unused = -1;
327 	ctx.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &unused);
328 	checkError(testCtx, ctx, GL_INVALID_ENUM);
329 	ctx.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &unused);
330 	checkError(testCtx, ctx, GL_INVALID_ENUM);
331 	ctx.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, &unused);
332 	checkError(testCtx, ctx, GL_INVALID_ENUM);
333 	ctx.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, &unused);
334 	checkError(testCtx, ctx, GL_INVALID_ENUM);
335 }
336 
attachmentQueryEmptyFboTest(tcu::TestContext & testCtx,sglr::Context & ctx)337 static void attachmentQueryEmptyFboTest (tcu::TestContext& testCtx, sglr::Context& ctx)
338 {
339 	static const GLenum attachmentPoints[] =
340 	{
341 		GL_COLOR_ATTACHMENT0,
342 		GL_DEPTH_ATTACHMENT,
343 		GL_STENCIL_ATTACHMENT
344 	};
345 
346 	ctx.bindFramebuffer(GL_FRAMEBUFFER, 1);
347 
348 	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(attachmentPoints); ndx++)
349 		checkFboAttachmentParam(testCtx, ctx, attachmentPoints[ndx], GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, GL_NONE);
350 
351 	checkFboAttachmentParam(testCtx, ctx, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, 0);
352 
353 	// Check that proper error codes are returned
354 	GLint unused = -1;
355 	ctx.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, &unused);
356 	checkError(testCtx, ctx, GL_INVALID_OPERATION);
357 	ctx.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, &unused);
358 	checkError(testCtx, ctx, GL_INVALID_OPERATION);
359 }
360 
attachmentQueryTex2DTest(tcu::TestContext & testCtx,sglr::Context & ctx)361 static void attachmentQueryTex2DTest (tcu::TestContext& testCtx, sglr::Context& ctx)
362 {
363 	ctx.bindFramebuffer(GL_FRAMEBUFFER, 1);
364 
365 	ctx.bindTexture(GL_TEXTURE_2D, 1);
366 	ctx.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 1, 0);
367 
368 	checkFboAttachmentParam(testCtx, ctx, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, GL_TEXTURE);
369 	checkFboAttachmentParam(testCtx, ctx, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, 1);
370 	checkFboAttachmentParam(testCtx, ctx, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, 0);
371 	checkFboAttachmentParam(testCtx, ctx, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, 0);
372 }
373 
attachmentQueryTexCubeTest(tcu::TestContext & testCtx,sglr::Context & ctx)374 static void attachmentQueryTexCubeTest (tcu::TestContext& testCtx, sglr::Context& ctx)
375 {
376 	ctx.bindFramebuffer(GL_FRAMEBUFFER, 1);
377 
378 	ctx.bindTexture(GL_TEXTURE_CUBE_MAP, 2);
379 	ctx.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 2, 0);
380 
381 	checkFboAttachmentParam(testCtx, ctx, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, GL_TEXTURE);
382 	checkFboAttachmentParam(testCtx, ctx, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, 2);
383 	checkFboAttachmentParam(testCtx, ctx, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, 0);
384 	checkFboAttachmentParam(testCtx, ctx, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y);
385 }
386 
attachmentQueryRboTest(tcu::TestContext & testCtx,sglr::Context & ctx)387 static void attachmentQueryRboTest (tcu::TestContext& testCtx, sglr::Context& ctx)
388 {
389 	ctx.bindFramebuffer(GL_FRAMEBUFFER, 1);
390 
391 	ctx.bindRenderbuffer(GL_RENDERBUFFER, 3);
392 	ctx.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 3);
393 
394 	checkFboAttachmentParam(testCtx, ctx, GL_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, GL_RENDERBUFFER);
395 	checkFboAttachmentParam(testCtx, ctx, GL_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, 3);
396 
397 	GLint unused = 0;
398 	ctx.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, &unused);
399 	checkError(testCtx, ctx, GL_INVALID_ENUM);
400 	ctx.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, &unused);
401 	checkError(testCtx, ctx, GL_INVALID_ENUM);
402 }
403 
deleteTex2DAttachedToBoundFboTest(tcu::TestContext & testCtx,sglr::Context & ctx)404 static void deleteTex2DAttachedToBoundFboTest (tcu::TestContext& testCtx, sglr::Context& ctx)
405 {
406 	ctx.bindFramebuffer(GL_FRAMEBUFFER, 1);
407 
408 	deUint32 tex2D = 1;
409 	ctx.bindTexture(GL_TEXTURE_2D, tex2D);
410 	ctx.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex2D, 0);
411 
412 	checkFboAttachmentParam(testCtx, ctx, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, GL_TEXTURE);
413 	checkFboAttachmentParam(testCtx, ctx, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, tex2D);
414 
415 	ctx.deleteTextures(1, &tex2D);
416 
417 	checkFboAttachmentParam(testCtx, ctx, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, GL_NONE);
418 }
419 
deleteTexCubeAttachedToBoundFboTest(tcu::TestContext & testCtx,sglr::Context & ctx)420 static void deleteTexCubeAttachedToBoundFboTest (tcu::TestContext& testCtx, sglr::Context& ctx)
421 {
422 	ctx.bindFramebuffer(GL_FRAMEBUFFER, 1);
423 
424 	deUint32 texCube = 1;
425 	ctx.bindTexture(GL_TEXTURE_CUBE_MAP, texCube);
426 	ctx.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X, texCube, 0);
427 
428 	checkFboAttachmentParam(testCtx, ctx, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, GL_TEXTURE);
429 	checkFboAttachmentParam(testCtx, ctx, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, texCube);
430 
431 	ctx.deleteTextures(1, &texCube);
432 
433 	checkFboAttachmentParam(testCtx, ctx, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, GL_NONE);
434 }
435 
deleteRboAttachedToBoundFboTest(tcu::TestContext & testCtx,sglr::Context & ctx)436 static void deleteRboAttachedToBoundFboTest (tcu::TestContext& testCtx, sglr::Context& ctx)
437 {
438 	ctx.bindFramebuffer(GL_FRAMEBUFFER, 1);
439 
440 	deUint32 rbo = 1;
441 	ctx.bindRenderbuffer(GL_RENDERBUFFER, rbo);
442 	ctx.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);
443 
444 	checkFboAttachmentParam(testCtx, ctx, GL_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, GL_RENDERBUFFER);
445 	checkFboAttachmentParam(testCtx, ctx, GL_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, rbo);
446 
447 	ctx.deleteRenderbuffers(1, &rbo);
448 
449 	checkFboAttachmentParam(testCtx, ctx, GL_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, GL_NONE);
450 }
451 
deleteTex2DAttachedToNotBoundFboTest(tcu::TestContext & testCtx,sglr::Context & ctx)452 static void deleteTex2DAttachedToNotBoundFboTest (tcu::TestContext& testCtx, sglr::Context& ctx)
453 {
454 	ctx.bindFramebuffer(GL_FRAMEBUFFER, 1);
455 
456 	deUint32 tex2D = 1;
457 	ctx.bindTexture(GL_TEXTURE_2D, tex2D);
458 	ctx.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex2D, 0);
459 
460 	checkFboAttachmentParam(testCtx, ctx, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, GL_TEXTURE);
461 	checkFboAttachmentParam(testCtx, ctx, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, tex2D);
462 
463 	ctx.bindFramebuffer(GL_FRAMEBUFFER, 0);
464 
465 	ctx.deleteTextures(1, &tex2D);
466 
467 	ctx.bindFramebuffer(GL_FRAMEBUFFER, 1);
468 
469 	checkFboAttachmentParam(testCtx, ctx, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, GL_TEXTURE);
470 	checkFboAttachmentParam(testCtx, ctx, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, tex2D);
471 }
472 
deleteTexCubeAttachedToNotBoundFboTest(tcu::TestContext & testCtx,sglr::Context & ctx)473 static void deleteTexCubeAttachedToNotBoundFboTest (tcu::TestContext& testCtx, sglr::Context& ctx)
474 {
475 	ctx.bindFramebuffer(GL_FRAMEBUFFER, 1);
476 
477 	deUint32 texCube = 1;
478 	ctx.bindTexture(GL_TEXTURE_CUBE_MAP, texCube);
479 	ctx.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X, texCube, 0);
480 
481 	checkFboAttachmentParam(testCtx, ctx, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, GL_TEXTURE);
482 	checkFboAttachmentParam(testCtx, ctx, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, texCube);
483 
484 	ctx.bindFramebuffer(GL_FRAMEBUFFER, 0);
485 
486 	ctx.deleteTextures(1, &texCube);
487 
488 	ctx.bindFramebuffer(GL_FRAMEBUFFER, 1);
489 
490 	checkFboAttachmentParam(testCtx, ctx, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, GL_TEXTURE);
491 	checkFboAttachmentParam(testCtx, ctx, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, texCube);
492 }
493 
deleteRboAttachedToNotBoundFboTest(tcu::TestContext & testCtx,sglr::Context & ctx)494 static void deleteRboAttachedToNotBoundFboTest (tcu::TestContext& testCtx, sglr::Context& ctx)
495 {
496 	ctx.bindFramebuffer(GL_FRAMEBUFFER, 1);
497 
498 	deUint32 rbo = 1;
499 	ctx.bindRenderbuffer(GL_RENDERBUFFER, rbo);
500 	ctx.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);
501 
502 	checkFboAttachmentParam(testCtx, ctx, GL_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, GL_RENDERBUFFER);
503 	checkFboAttachmentParam(testCtx, ctx, GL_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, rbo);
504 
505 	ctx.bindFramebuffer(GL_FRAMEBUFFER, 0);
506 
507 	ctx.deleteRenderbuffers(1, &rbo);
508 
509 	ctx.bindFramebuffer(GL_FRAMEBUFFER, 1);
510 
511 	checkFboAttachmentParam(testCtx, ctx, GL_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, GL_RENDERBUFFER);
512 	checkFboAttachmentParam(testCtx, ctx, GL_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, rbo);
513 }
514 
515 class FboApiCase : public TestCase
516 {
517 public:
518 	typedef void (*TestFunc) (tcu::TestContext& testCtx, sglr::Context& context);
519 
520 								FboApiCase				(Context& context, const char* name, const char* description, TestFunc test);
521 	virtual						~FboApiCase				(void);
522 
523 	virtual IterateResult		iterate					(void);
524 
525 private:
526 								FboApiCase				(const FboApiCase& other);
527 	FboApiCase&					operator=				(const FboApiCase& other);
528 
529 	TestFunc					m_testFunc;
530 };
531 
FboApiCase(Context & context,const char * name,const char * description,TestFunc test)532 FboApiCase::FboApiCase (Context& context, const char* name, const char* description, TestFunc test)
533 	: TestCase		(context, name, description)
534 	, m_testFunc	(test)
535 {
536 }
537 
~FboApiCase(void)538 FboApiCase::~FboApiCase (void)
539 {
540 }
541 
iterate(void)542 TestCase::IterateResult FboApiCase::iterate (void)
543 {
544 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
545 
546 	GLU_EXPECT_NO_ERROR(gl.getError(), "Before test case");
547 
548 	// Initialize result to PASS
549 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
550 
551 	// Execute test case
552 	{
553 		tcu::TestLog& log = m_context.getTestContext().getLog();
554 		sglr::GLContext context(m_context.getRenderContext(), log, sglr::GLCONTEXT_LOG_CALLS, tcu::IVec4(0, 0, m_context.getRenderContext().getRenderTarget().getWidth(), m_context.getRenderContext().getRenderTarget().getHeight()));
555 		m_testFunc(m_testCtx, context);
556 	}
557 
558 	GLU_EXPECT_NO_ERROR(gl.getError(), "After test case");
559 
560 	return STOP;
561 }
562 
FboApiTests(Context & context)563 FboApiTests::FboApiTests (Context& context)
564 	: TestCaseGroup(context, "api", "API Tests")
565 {
566 }
567 
~FboApiTests(void)568 FboApiTests::~FboApiTests (void)
569 {
570 }
571 
init(void)572 void FboApiTests::init (void)
573 {
574 	// Valid attachments
575 	addChild(new FboApiCase(m_context, "valid_tex2d_attachments",					"Valid 2D texture attachments",							validTex2DAttachmentsTest));
576 	addChild(new FboApiCase(m_context, "valid_texcube_attachments",					"Valid cubemap attachments",							validTexCubeAttachmentsTest));
577 	addChild(new FboApiCase(m_context, "valid_rbo_attachments",						"Valid renderbuffer attachments",						validRboAttachmentsTest));
578 
579 	// Invalid attachments
580 	addChild(new FboApiCase(m_context, "attach_to_default_fbo",						"Invalid usage: attaching to default FBO",				attachToDefaultFramebufferTest));
581 	addChild(new FboApiCase(m_context, "invalid_tex2d_attachments",					"Invalid 2D texture attachments",						invalidTex2DAttachmentTest));
582 	addChild(new FboApiCase(m_context, "invalid_texcube_attachments",				"Invalid cubemap attachments",							invalidTexCubeAttachmentTest));
583 	addChild(new FboApiCase(m_context, "invalid_rbo_attachments",					"Invalid renderbuffer attachments",						invalidRboAttachmentTest));
584 	addChild(new FboApiCase(m_context, "attach_names",								"Attach allocated names without objects",				attachNamesTest));
585 
586 	addChild(new FboApiCase(m_context, "texture_levels",							"Valid and invalid texturel levels",					textureLevelsTest));
587 
588 	// Attachment queries
589 	addChild(new FboApiCase(m_context, "attachment_query_default_fbo",				"Query attachments from default FBO",					attachmentQueryDefaultFboTest));
590 	addChild(new FboApiCase(m_context, "attachment_query_empty_fbo",				"Query attachments from empty FBO",						attachmentQueryEmptyFboTest));
591 	addChild(new FboApiCase(m_context, "attachment_query_tex2d",					"Query 2d texture attachment properties",				attachmentQueryTex2DTest));
592 	addChild(new FboApiCase(m_context, "attachment_query_texcube",					"Query cubemap attachment properties",					attachmentQueryTexCubeTest));
593 	addChild(new FboApiCase(m_context, "attachment_query_rbo",						"Query renderbuffer attachment properties",				attachmentQueryRboTest));
594 
595 	// Delete attachments
596 	addChild(new FboApiCase(m_context, "delete_tex_2d_attached_to_bound_fbo",		"Delete 2d texture attached to currently bound FBO",	deleteTex2DAttachedToBoundFboTest));
597 	addChild(new FboApiCase(m_context, "delete_tex_cube_attached_to_bound_fbo",		"Delete cubemap attached to currently bound FBO",		deleteTexCubeAttachedToBoundFboTest));
598 	addChild(new FboApiCase(m_context, "delete_rbo_attached_to_bound_fbo",			"Delete renderbuffer attached to currently bound FBO",	deleteRboAttachedToBoundFboTest));
599 
600 	addChild(new FboApiCase(m_context, "delete_tex_2d_attached_to_not_bound_fbo",	"Delete 2d texture attached to FBO",					deleteTex2DAttachedToNotBoundFboTest));
601 	addChild(new FboApiCase(m_context, "delete_tex_cube_attached_to_not_bound_fbo",	"Delete cubemap attached to FBO",						deleteTexCubeAttachedToNotBoundFboTest));
602 	addChild(new FboApiCase(m_context, "delete_rbo_attached_to_not_bound_fbo",		"Delete renderbuffer attached to FBO",					deleteRboAttachedToNotBoundFboTest));
603 }
604 
605 } // Functional
606 } // gles3
607 } // deqp
608