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