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