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