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