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