| /*------------------------------------------------------------------------- |
| * drawElements Quality Program OpenGL ES 3.0 Module |
| * ------------------------------------------------- |
| * |
| * Copyright 2014 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| *//*! |
| * \file |
| * \brief Framebuffer Object API Tests. |
| * |
| * Notes: |
| * All gl calls are passed thru sglr::Context class. Reasons: |
| * + Name, object allocation is tracked and live resources are freed |
| * when Context is destroyed. |
| * + Makes it possible to easily log all relevant calls into test log. |
| * \todo [pyry] This is not implemented yet |
| *//*--------------------------------------------------------------------*/ |
| |
| #include "es3fFboApiTests.hpp" |
| #include "sglrGLContext.hpp" |
| #include "gluDefs.hpp" |
| #include "gluStrUtil.hpp" |
| #include "tcuRenderTarget.hpp" |
| #include "deString.h" |
| #include "glwFunctions.hpp" |
| #include "glwEnums.hpp" |
| |
| namespace deqp |
| { |
| namespace gles3 |
| { |
| namespace Functional |
| { |
| |
| using std::string; |
| using std::vector; |
| using tcu::TestLog; |
| |
| using glw::GLenum; |
| using glw::GLint; |
| |
| static void logComment(tcu::TestContext &testCtx, const char *comment) |
| { |
| testCtx.getLog() << TestLog::Message << "// " << comment << TestLog::EndMessage; |
| } |
| |
| static void checkError(tcu::TestContext &testCtx, sglr::Context &ctx, GLenum expect) |
| { |
| GLenum result = ctx.getError(); |
| testCtx.getLog() << TestLog::Message << "// " << (result == expect ? "Pass" : "Fail") << ", expected " |
| << glu::getErrorStr(expect) << TestLog::EndMessage; |
| |
| if (result != expect) |
| testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Error code mismatch"); |
| } |
| |
| static void checkEitherError(tcu::TestContext &testCtx, sglr::Context &ctx, GLenum expectA, GLenum expectB) |
| { |
| GLenum result = ctx.getError(); |
| bool isOk = (result == expectA || result == expectB); |
| |
| testCtx.getLog() << TestLog::Message << "// " << (isOk ? "Pass" : "Fail") << ", expected " |
| << glu::getErrorStr(expectA) << " or " << glu::getErrorStr(expectB) << TestLog::EndMessage; |
| |
| if (!isOk) |
| testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Error code mismatch"); |
| } |
| |
| static const char *getAttachmentName(GLenum attachment) |
| { |
| switch (attachment) |
| { |
| case GL_COLOR_ATTACHMENT0: |
| return "GL_COLOR_ATTACHMENT0"; |
| case GL_DEPTH_ATTACHMENT: |
| return "GL_DEPTH_ATTACHMENT"; |
| case GL_STENCIL_ATTACHMENT: |
| return "GL_STENCIL_ATTACHMENT"; |
| default: |
| throw tcu::InternalError("Unknown attachment", "", __FILE__, __LINE__); |
| } |
| } |
| |
| static const char *getAttachmentParameterName(GLenum pname) |
| { |
| switch (pname) |
| { |
| case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: |
| return "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE"; |
| case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: |
| return "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME"; |
| case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: |
| return "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL"; |
| case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: |
| return "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE"; |
| default: |
| throw tcu::InternalError("Unknown parameter", "", __FILE__, __LINE__); |
| } |
| } |
| |
| static string getAttachmentParameterValueName(GLint value) |
| { |
| switch (value) |
| { |
| case 0: |
| return "GL_NONE(0)"; |
| case GL_TEXTURE: |
| return "GL_TEXTURE"; |
| case GL_RENDERBUFFER: |
| return "GL_RENDERBUFFER"; |
| case GL_TEXTURE_CUBE_MAP_POSITIVE_X: |
| return "GL_TEXTURE_CUBE_MAP_POSITIVE_X"; |
| case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: |
| return "GL_TEXTURE_CUBE_MAP_NEGATIVE_X"; |
| case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: |
| return "GL_TEXTURE_CUBE_MAP_POSITIVE_Y"; |
| case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: |
| return "GL_TEXTURE_CUBE_MAP_NEGATIVE_Y"; |
| case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: |
| return "GL_TEXTURE_CUBE_MAP_POSITIVE_Z"; |
| case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: |
| return "GL_TEXTURE_CUBE_MAP_NEGATIVE_Z"; |
| default: |
| { |
| char tmp[64]; |
| deSprintf(tmp, sizeof(tmp), "0x%x", value); |
| return string(tmp); |
| } |
| } |
| } |
| |
| static void checkFboAttachmentParam(tcu::TestContext &testCtx, sglr::Context &ctx, GLenum attachment, GLenum pname, |
| GLint expectedValue) |
| { |
| TestLog &log = testCtx.getLog(); |
| log << TestLog::Message << "// Querying " << getAttachmentName(attachment) << " " |
| << getAttachmentParameterName(pname) << TestLog::EndMessage; |
| |
| GLint value = 0xcdcdcdcd; |
| ctx.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, attachment, pname, &value); |
| |
| GLenum err = ctx.getError(); |
| |
| if (value == expectedValue && err == GL_NO_ERROR) |
| log << TestLog::Message << "// Pass" << TestLog::EndMessage; |
| else |
| { |
| log << TestLog::Message << "// Fail, expected " << getAttachmentParameterValueName(expectedValue) |
| << " without error" << TestLog::EndMessage; |
| testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid result for attachment param query"); |
| } |
| } |
| |
| static void textureLevelsTest(tcu::TestContext &testCtx, sglr::Context &context) |
| { |
| uint32_t tex = 1; |
| uint32_t fbo = 1; |
| GLint maxTexSize; |
| int log2MaxTexSize; |
| |
| context.getIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize); |
| log2MaxTexSize = deLog2Floor32(maxTexSize); |
| |
| testCtx.getLog() << TestLog::Message << "// GL_MAX_TEXTURE_SIZE is " << maxTexSize << ", floor(log2(" << maxTexSize |
| << ")) = " << log2MaxTexSize << TestLog::EndMessage; |
| |
| context.bindTexture(GL_TEXTURE_2D, tex); |
| context.texImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256, 256); |
| context.texImage2D(GL_TEXTURE_2D, 1, GL_RGB, 128, 128); |
| |
| context.bindFramebuffer(GL_FRAMEBUFFER, fbo); |
| |
| const int levels[] = {2, |
| 1, |
| 0, |
| -1, |
| 0x7fffffff, |
| 0, |
| log2MaxTexSize - 2, |
| log2MaxTexSize - 1, |
| log2MaxTexSize, |
| log2MaxTexSize + 1, |
| log2MaxTexSize + 2, |
| 1}; |
| |
| for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(levels); ndx++) |
| { |
| context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, levels[ndx]); |
| checkError(testCtx, context, |
| levels[ndx] >= 0 && levels[ndx] <= log2MaxTexSize ? GL_NO_ERROR : GL_INVALID_VALUE); |
| } |
| } |
| |
| static void validTex2DAttachmentsTest(tcu::TestContext &testCtx, sglr::Context &context) |
| { |
| context.bindFramebuffer(GL_FRAMEBUFFER, 1); |
| static const GLenum attachmentPoints[] = {GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT}; |
| |
| // Texture2D |
| uint32_t tex2D = 1; |
| context.bindTexture(GL_TEXTURE_2D, tex2D); |
| for (int pointNdx = 0; pointNdx < DE_LENGTH_OF_ARRAY(attachmentPoints); pointNdx++) |
| { |
| context.framebufferTexture2D(GL_FRAMEBUFFER, attachmentPoints[pointNdx], GL_TEXTURE_2D, tex2D, 0); |
| checkError(testCtx, context, GL_NO_ERROR); |
| } |
| } |
| |
| static void validTexCubeAttachmentsTest(tcu::TestContext &testCtx, sglr::Context &context) |
| { |
| static const GLenum attachmentPoints[] = {GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT}; |
| static const GLenum cubeTargets[] = {GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, |
| GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, |
| GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z}; |
| |
| context.bindFramebuffer(GL_FRAMEBUFFER, 1); |
| |
| // TextureCube |
| uint32_t texCube = 2; |
| context.bindTexture(GL_TEXTURE_CUBE_MAP, texCube); |
| for (int pointNdx = 0; pointNdx < DE_LENGTH_OF_ARRAY(attachmentPoints); pointNdx++) |
| { |
| for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(cubeTargets); targetNdx++) |
| { |
| context.framebufferTexture2D(GL_FRAMEBUFFER, attachmentPoints[pointNdx], cubeTargets[targetNdx], texCube, |
| 0); |
| checkError(testCtx, context, GL_NO_ERROR); |
| } |
| } |
| } |
| |
| static void validRboAttachmentsTest(tcu::TestContext &testCtx, sglr::Context &context) |
| { |
| static const GLenum attachmentPoints[] = {GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT}; |
| |
| context.bindFramebuffer(GL_FRAMEBUFFER, 1); |
| |
| // Renderbuffer |
| uint32_t rbo = 3; |
| context.bindRenderbuffer(GL_RENDERBUFFER, rbo); |
| for (int pointNdx = 0; pointNdx < DE_LENGTH_OF_ARRAY(attachmentPoints); pointNdx++) |
| { |
| context.framebufferRenderbuffer(GL_FRAMEBUFFER, attachmentPoints[pointNdx], GL_RENDERBUFFER, rbo); |
| checkError(testCtx, context, GL_NO_ERROR); |
| } |
| } |
| |
| static void attachToDefaultFramebufferTest(tcu::TestContext &testCtx, sglr::Context &context) |
| { |
| logComment(testCtx, "Attaching 2D texture to default framebuffer"); |
| |
| uint32_t tex2D = 1; |
| context.bindTexture(GL_TEXTURE_2D, tex2D); |
| context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex2D, 0); |
| checkError(testCtx, context, GL_INVALID_OPERATION); |
| |
| logComment(testCtx, "Attaching renderbuffer to default framebuffer"); |
| |
| uint32_t rbo = 1; |
| context.bindRenderbuffer(GL_RENDERBUFFER, rbo); |
| context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo); |
| checkError(testCtx, context, GL_INVALID_OPERATION); |
| } |
| |
| static void invalidTex2DAttachmentTest(tcu::TestContext &testCtx, sglr::Context &context) |
| { |
| context.bindFramebuffer(GL_FRAMEBUFFER, 1); |
| |
| logComment(testCtx, "Attaching 2D texture using GL_TEXTURE_CUBE_MAP_NEGATIVE_X texture target"); |
| |
| uint32_t tex2D = 1; |
| context.bindTexture(GL_TEXTURE_2D, tex2D); |
| context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, tex2D, 0); |
| checkError(testCtx, context, GL_INVALID_OPERATION); |
| |
| logComment(testCtx, "Attaching deleted 2D texture object"); |
| context.deleteTextures(1, &tex2D); |
| context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex2D, 0); |
| checkError(testCtx, context, GL_INVALID_OPERATION); |
| } |
| |
| static void invalidTexCubeAttachmentTest(tcu::TestContext &testCtx, sglr::Context &context) |
| { |
| context.bindFramebuffer(GL_FRAMEBUFFER, 1); |
| |
| logComment(testCtx, "Attaching cube texture using GL_TEXTURE_2D texture target"); |
| uint32_t texCube = 2; |
| context.bindTexture(GL_TEXTURE_CUBE_MAP, texCube); |
| context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texCube, 0); |
| checkError(testCtx, context, GL_INVALID_OPERATION); |
| |
| logComment(testCtx, "Attaching deleted cube texture object"); |
| context.deleteTextures(1, &texCube); |
| context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X, texCube, 0); |
| checkError(testCtx, context, GL_INVALID_OPERATION); |
| } |
| |
| static void invalidRboAttachmentTest(tcu::TestContext &testCtx, sglr::Context &context) |
| { |
| context.bindFramebuffer(GL_FRAMEBUFFER, 1); |
| |
| logComment(testCtx, "Attaching renderbuffer using GL_FRAMEBUFFER renderbuffer target"); |
| uint32_t rbo = 3; |
| context.bindRenderbuffer(GL_RENDERBUFFER, rbo); |
| context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER, rbo); |
| checkError(testCtx, context, GL_INVALID_ENUM); |
| |
| logComment(testCtx, "Attaching deleted renderbuffer object"); |
| context.deleteRenderbuffers(1, &rbo); |
| context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo); |
| checkError(testCtx, context, GL_INVALID_OPERATION); |
| } |
| |
| static void attachNamesTest(tcu::TestContext &testCtx, sglr::Context &context) |
| { |
| context.bindFramebuffer(GL_FRAMEBUFFER, 1); |
| |
| // Just allocate some names, don't bind for storage |
| uint32_t reservedTexName; |
| context.genTextures(1, &reservedTexName); |
| |
| logComment(testCtx, "Attaching allocated texture name to 2D target"); |
| context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, reservedTexName, 0); |
| checkError(testCtx, context, GL_INVALID_OPERATION); |
| |
| logComment(testCtx, "Attaching allocated texture name to cube target"); |
| context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, reservedTexName, |
| 0); |
| checkError(testCtx, context, GL_INVALID_OPERATION); |
| |
| uint32_t reservedRboName; |
| context.genRenderbuffers(1, &reservedRboName); |
| |
| logComment(testCtx, "Attaching allocated renderbuffer name"); |
| context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, reservedRboName); |
| checkError(testCtx, context, GL_INVALID_OPERATION); |
| } |
| |
| static void attachmentQueryDefaultFboTest(tcu::TestContext &testCtx, sglr::Context &ctx) |
| { |
| // Check that proper error codes are returned |
| GLint unused = -1; |
| ctx.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, |
| &unused); |
| checkEitherError(testCtx, ctx, GL_INVALID_ENUM, GL_INVALID_OPERATION); |
| ctx.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, |
| &unused); |
| checkEitherError(testCtx, ctx, GL_INVALID_ENUM, GL_INVALID_OPERATION); |
| ctx.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, |
| GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, &unused); |
| checkEitherError(testCtx, ctx, GL_INVALID_ENUM, GL_INVALID_OPERATION); |
| ctx.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, |
| GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, &unused); |
| checkEitherError(testCtx, ctx, GL_INVALID_ENUM, GL_INVALID_OPERATION); |
| } |
| |
| static void attachmentQueryEmptyFboTest(tcu::TestContext &testCtx, sglr::Context &ctx) |
| { |
| static const GLenum attachmentPoints[] = {GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT}; |
| |
| ctx.bindFramebuffer(GL_FRAMEBUFFER, 1); |
| |
| for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(attachmentPoints); ndx++) |
| checkFboAttachmentParam(testCtx, ctx, attachmentPoints[ndx], GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, GL_NONE); |
| |
| checkFboAttachmentParam(testCtx, ctx, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, 0); |
| |
| // Check that proper error codes are returned |
| GLint unused = -1; |
| ctx.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, |
| GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, &unused); |
| checkError(testCtx, ctx, GL_INVALID_OPERATION); |
| ctx.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, |
| GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, &unused); |
| checkError(testCtx, ctx, GL_INVALID_OPERATION); |
| } |
| |
| static void attachmentQueryTex2DTest(tcu::TestContext &testCtx, sglr::Context &ctx) |
| { |
| ctx.bindFramebuffer(GL_FRAMEBUFFER, 1); |
| |
| ctx.bindTexture(GL_TEXTURE_2D, 1); |
| ctx.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 1, 0); |
| |
| checkFboAttachmentParam(testCtx, ctx, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, GL_TEXTURE); |
| checkFboAttachmentParam(testCtx, ctx, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, 1); |
| checkFboAttachmentParam(testCtx, ctx, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, 0); |
| checkFboAttachmentParam(testCtx, ctx, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, 0); |
| } |
| |
| static void attachmentQueryTexCubeTest(tcu::TestContext &testCtx, sglr::Context &ctx) |
| { |
| ctx.bindFramebuffer(GL_FRAMEBUFFER, 1); |
| |
| ctx.bindTexture(GL_TEXTURE_CUBE_MAP, 2); |
| ctx.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 2, 0); |
| |
| checkFboAttachmentParam(testCtx, ctx, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, GL_TEXTURE); |
| checkFboAttachmentParam(testCtx, ctx, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, 2); |
| checkFboAttachmentParam(testCtx, ctx, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, 0); |
| checkFboAttachmentParam(testCtx, ctx, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, |
| GL_TEXTURE_CUBE_MAP_NEGATIVE_Y); |
| } |
| |
| static void attachmentQueryRboTest(tcu::TestContext &testCtx, sglr::Context &ctx) |
| { |
| ctx.bindFramebuffer(GL_FRAMEBUFFER, 1); |
| |
| ctx.bindRenderbuffer(GL_RENDERBUFFER, 3); |
| ctx.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 3); |
| |
| checkFboAttachmentParam(testCtx, ctx, GL_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, |
| GL_RENDERBUFFER); |
| checkFboAttachmentParam(testCtx, ctx, GL_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, 3); |
| |
| GLint unused = 0; |
| ctx.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, |
| GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, &unused); |
| checkError(testCtx, ctx, GL_INVALID_ENUM); |
| ctx.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, |
| GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, &unused); |
| checkError(testCtx, ctx, GL_INVALID_ENUM); |
| } |
| |
| static void deleteTex2DAttachedToBoundFboTest(tcu::TestContext &testCtx, sglr::Context &ctx) |
| { |
| ctx.bindFramebuffer(GL_FRAMEBUFFER, 1); |
| |
| uint32_t tex2D = 1; |
| ctx.bindTexture(GL_TEXTURE_2D, tex2D); |
| ctx.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex2D, 0); |
| |
| checkFboAttachmentParam(testCtx, ctx, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, GL_TEXTURE); |
| checkFboAttachmentParam(testCtx, ctx, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, tex2D); |
| |
| ctx.deleteTextures(1, &tex2D); |
| |
| checkFboAttachmentParam(testCtx, ctx, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, GL_NONE); |
| } |
| |
| static void deleteTexCubeAttachedToBoundFboTest(tcu::TestContext &testCtx, sglr::Context &ctx) |
| { |
| ctx.bindFramebuffer(GL_FRAMEBUFFER, 1); |
| |
| uint32_t texCube = 1; |
| ctx.bindTexture(GL_TEXTURE_CUBE_MAP, texCube); |
| ctx.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X, texCube, 0); |
| |
| checkFboAttachmentParam(testCtx, ctx, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, GL_TEXTURE); |
| checkFboAttachmentParam(testCtx, ctx, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, texCube); |
| |
| ctx.deleteTextures(1, &texCube); |
| |
| checkFboAttachmentParam(testCtx, ctx, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, GL_NONE); |
| } |
| |
| static void deleteRboAttachedToBoundFboTest(tcu::TestContext &testCtx, sglr::Context &ctx) |
| { |
| ctx.bindFramebuffer(GL_FRAMEBUFFER, 1); |
| |
| uint32_t rbo = 1; |
| ctx.bindRenderbuffer(GL_RENDERBUFFER, rbo); |
| ctx.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo); |
| |
| checkFboAttachmentParam(testCtx, ctx, GL_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, |
| GL_RENDERBUFFER); |
| checkFboAttachmentParam(testCtx, ctx, GL_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, rbo); |
| |
| ctx.deleteRenderbuffers(1, &rbo); |
| |
| checkFboAttachmentParam(testCtx, ctx, GL_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, GL_NONE); |
| } |
| |
| static void deleteTex2DAttachedToNotBoundFboTest(tcu::TestContext &testCtx, sglr::Context &ctx) |
| { |
| ctx.bindFramebuffer(GL_FRAMEBUFFER, 1); |
| |
| uint32_t tex2D = 1; |
| ctx.bindTexture(GL_TEXTURE_2D, tex2D); |
| ctx.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex2D, 0); |
| |
| checkFboAttachmentParam(testCtx, ctx, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, GL_TEXTURE); |
| checkFboAttachmentParam(testCtx, ctx, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, tex2D); |
| |
| ctx.bindFramebuffer(GL_FRAMEBUFFER, 0); |
| |
| ctx.deleteTextures(1, &tex2D); |
| |
| ctx.bindFramebuffer(GL_FRAMEBUFFER, 1); |
| |
| checkFboAttachmentParam(testCtx, ctx, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, GL_TEXTURE); |
| checkFboAttachmentParam(testCtx, ctx, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, tex2D); |
| } |
| |
| static void deleteTexCubeAttachedToNotBoundFboTest(tcu::TestContext &testCtx, sglr::Context &ctx) |
| { |
| ctx.bindFramebuffer(GL_FRAMEBUFFER, 1); |
| |
| uint32_t texCube = 1; |
| ctx.bindTexture(GL_TEXTURE_CUBE_MAP, texCube); |
| ctx.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X, texCube, 0); |
| |
| checkFboAttachmentParam(testCtx, ctx, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, GL_TEXTURE); |
| checkFboAttachmentParam(testCtx, ctx, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, texCube); |
| |
| ctx.bindFramebuffer(GL_FRAMEBUFFER, 0); |
| |
| ctx.deleteTextures(1, &texCube); |
| |
| ctx.bindFramebuffer(GL_FRAMEBUFFER, 1); |
| |
| checkFboAttachmentParam(testCtx, ctx, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, GL_TEXTURE); |
| checkFboAttachmentParam(testCtx, ctx, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, texCube); |
| } |
| |
| static void deleteRboAttachedToNotBoundFboTest(tcu::TestContext &testCtx, sglr::Context &ctx) |
| { |
| ctx.bindFramebuffer(GL_FRAMEBUFFER, 1); |
| |
| uint32_t rbo = 1; |
| ctx.bindRenderbuffer(GL_RENDERBUFFER, rbo); |
| ctx.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo); |
| |
| checkFboAttachmentParam(testCtx, ctx, GL_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, |
| GL_RENDERBUFFER); |
| checkFboAttachmentParam(testCtx, ctx, GL_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, rbo); |
| |
| ctx.bindFramebuffer(GL_FRAMEBUFFER, 0); |
| |
| ctx.deleteRenderbuffers(1, &rbo); |
| |
| ctx.bindFramebuffer(GL_FRAMEBUFFER, 1); |
| |
| checkFboAttachmentParam(testCtx, ctx, GL_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, |
| GL_RENDERBUFFER); |
| checkFboAttachmentParam(testCtx, ctx, GL_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, rbo); |
| } |
| |
| class FboApiCase : public TestCase |
| { |
| public: |
| typedef void (*TestFunc)(tcu::TestContext &testCtx, sglr::Context &context); |
| |
| FboApiCase(Context &context, const char *name, const char *description, TestFunc test); |
| virtual ~FboApiCase(void); |
| |
| virtual IterateResult iterate(void); |
| |
| private: |
| FboApiCase(const FboApiCase &other); |
| FboApiCase &operator=(const FboApiCase &other); |
| |
| TestFunc m_testFunc; |
| }; |
| |
| FboApiCase::FboApiCase(Context &context, const char *name, const char *description, TestFunc test) |
| : TestCase(context, name, description) |
| , m_testFunc(test) |
| { |
| } |
| |
| FboApiCase::~FboApiCase(void) |
| { |
| } |
| |
| TestCase::IterateResult FboApiCase::iterate(void) |
| { |
| const glw::Functions &gl = m_context.getRenderContext().getFunctions(); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Before test case"); |
| |
| // Initialize result to PASS |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| |
| // Execute test case |
| { |
| tcu::TestLog &log = m_context.getTestContext().getLog(); |
| 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())); |
| m_testFunc(m_testCtx, context); |
| } |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "After test case"); |
| |
| return STOP; |
| } |
| |
| FboApiTests::FboApiTests(Context &context) : TestCaseGroup(context, "api", "API Tests") |
| { |
| } |
| |
| FboApiTests::~FboApiTests(void) |
| { |
| } |
| |
| void FboApiTests::init(void) |
| { |
| // Valid attachments |
| addChild(new FboApiCase(m_context, "valid_tex2d_attachments", "Valid 2D texture attachments", |
| validTex2DAttachmentsTest)); |
| addChild(new FboApiCase(m_context, "valid_texcube_attachments", "Valid cubemap attachments", |
| validTexCubeAttachmentsTest)); |
| addChild( |
| new FboApiCase(m_context, "valid_rbo_attachments", "Valid renderbuffer attachments", validRboAttachmentsTest)); |
| |
| // Invalid attachments |
| addChild(new FboApiCase(m_context, "attach_to_default_fbo", "Invalid usage: attaching to default FBO", |
| attachToDefaultFramebufferTest)); |
| addChild(new FboApiCase(m_context, "invalid_tex2d_attachments", "Invalid 2D texture attachments", |
| invalidTex2DAttachmentTest)); |
| addChild(new FboApiCase(m_context, "invalid_texcube_attachments", "Invalid cubemap attachments", |
| invalidTexCubeAttachmentTest)); |
| addChild(new FboApiCase(m_context, "invalid_rbo_attachments", "Invalid renderbuffer attachments", |
| invalidRboAttachmentTest)); |
| addChild(new FboApiCase(m_context, "attach_names", "Attach allocated names without objects", attachNamesTest)); |
| |
| addChild(new FboApiCase(m_context, "texture_levels", "Valid and invalid texturel levels", textureLevelsTest)); |
| |
| // Attachment queries |
| addChild(new FboApiCase(m_context, "attachment_query_default_fbo", "Query attachments from default FBO", |
| attachmentQueryDefaultFboTest)); |
| addChild(new FboApiCase(m_context, "attachment_query_empty_fbo", "Query attachments from empty FBO", |
| attachmentQueryEmptyFboTest)); |
| addChild(new FboApiCase(m_context, "attachment_query_tex2d", "Query 2d texture attachment properties", |
| attachmentQueryTex2DTest)); |
| addChild(new FboApiCase(m_context, "attachment_query_texcube", "Query cubemap attachment properties", |
| attachmentQueryTexCubeTest)); |
| addChild(new FboApiCase(m_context, "attachment_query_rbo", "Query renderbuffer attachment properties", |
| attachmentQueryRboTest)); |
| |
| // Delete attachments |
| addChild(new FboApiCase(m_context, "delete_tex_2d_attached_to_bound_fbo", |
| "Delete 2d texture attached to currently bound FBO", deleteTex2DAttachedToBoundFboTest)); |
| addChild(new FboApiCase(m_context, "delete_tex_cube_attached_to_bound_fbo", |
| "Delete cubemap attached to currently bound FBO", deleteTexCubeAttachedToBoundFboTest)); |
| addChild(new FboApiCase(m_context, "delete_rbo_attached_to_bound_fbo", |
| "Delete renderbuffer attached to currently bound FBO", deleteRboAttachedToBoundFboTest)); |
| |
| addChild(new FboApiCase(m_context, "delete_tex_2d_attached_to_not_bound_fbo", "Delete 2d texture attached to FBO", |
| deleteTex2DAttachedToNotBoundFboTest)); |
| addChild(new FboApiCase(m_context, "delete_tex_cube_attached_to_not_bound_fbo", "Delete cubemap attached to FBO", |
| deleteTexCubeAttachedToNotBoundFboTest)); |
| addChild(new FboApiCase(m_context, "delete_rbo_attached_to_not_bound_fbo", "Delete renderbuffer attached to FBO", |
| deleteRboAttachedToNotBoundFboTest)); |
| } |
| |
| } // namespace Functional |
| } // namespace gles3 |
| } // namespace deqp |