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