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