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