/** \return GL_TRUE for pass, GL_FALSE for fail */
static bool
test_fbo(const struct format_info *info)
{
    const int comps = num_components(info->BaseFormat);
    const GLenum type = get_datatype(info);
    GLint f;
    GLuint fbo, texObj;
    GLenum status;
    GLboolean intMode;
    GLint buf;
    bool pass = true;

    if (0)
        fprintf(stderr, "============ Testing format = %s ========\n", info->Name);

    /* Create texture */
    glGenTextures(1, &texObj);
    glBindTexture(GL_TEXTURE_2D, texObj);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    glTexImage2D(GL_TEXTURE_2D, 0, info->IntFormat, TexWidth, TexHeight, 0,
                 info->BaseFormat, type, NULL);

    if (check_error(__FILE__, __LINE__))
        return GL_FALSE;

    glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &f);
    assert(f == info->IntFormat);


    /* Create FBO to render to texture */
    glGenFramebuffers(1, &fbo);
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
                           GL_TEXTURE_2D, texObj, 0);

    if (check_error(__FILE__, __LINE__))
        return GL_FALSE;

    status = glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT);
    if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
        fprintf(stderr, "%s: failure: framebuffer incomplete.\n", TestName);
        return GL_FALSE;
    }


    glGetBooleanv(GL_RGBA_INTEGER_MODE_EXT, &intMode);
    if (check_error(__FILE__, __LINE__))
        return GL_FALSE;
    if (!intMode) {
        fprintf(stderr, "%s: GL_RGBA_INTEGER_MODE_EXT return GL_FALSE\n",
                TestName);
        return GL_FALSE;
    }

    glGetIntegerv(GL_READ_BUFFER, &buf);
    assert(buf == GL_COLOR_ATTACHMENT0_EXT);
    glGetIntegerv(GL_DRAW_BUFFER, &buf);
    assert(buf == GL_COLOR_ATTACHMENT0_EXT);


    /* test clearing */
    if (1) {
        /* clear with an integer - exp unsigned int */
        static const GLint clr_i[4] = { 300000005, -7, 6, 5 };
        static const GLuint exp_ui[4] = { 300000005, 0, 6, 5 };
        /* clear with an unsigned integer - exp int */
        static const GLuint clr_ui[4] = { 300000005, 0x80000007, 6, 5 };
        static const GLint exp_i[4] = { 300000005, 0x7fffffff, 6, 5 };
        GLint pix[4], i;
        GLuint pix_ui[4];

        if (info->Signed)
            glClearColorIiEXT(clr_i[0], clr_i[1], clr_i[2], clr_i[3]);
        else
            glClearColorIuiEXT(clr_ui[0], clr_ui[1], clr_ui[2], clr_ui[3]);
        glClear(GL_COLOR_BUFFER_BIT);

        if (info->Signed)
            glReadPixels(5, 5, 1, 1, GL_RGBA_INTEGER_EXT, GL_UNSIGNED_INT, pix_ui);
        else
            glReadPixels(5, 5, 1, 1, GL_RGBA_INTEGER_EXT, GL_INT, pix);

        if (info->Signed) {
            for (i = 0; i < comps; i++) {
                if (pix_ui[i] != exp_ui[i]) {
                    fprintf(stderr, "%s: glClear failed\n", TestName);
                    fprintf(stderr, "  Texture format = %s\n", info->Name);
                    fprintf(stderr, "  Expected %u, %u, %u, %u\n",
                            exp_ui[0], exp_ui[1], exp_ui[2], exp_ui[3]);
                    fprintf(stderr, "  Found %u, %u, %u, %u\n",
                            pix_ui[0], pix_ui[1], pix_ui[2], pix_ui[3]);
                    pass = false;
                    break;
                }
            }
        } else {
            for (i = 0; i < comps; i++) {
                if (pix[i] != exp_i[i]) {
                    fprintf(stderr, "%s: glClear failed\n", TestName);
                    fprintf(stderr, "  Texture format = %s\n", info->Name);
                    fprintf(stderr, "  Expected %d, %d, %d, %d\n",
                            exp_i[0], exp_i[1], exp_i[2], exp_i[3]);
                    fprintf(stderr, "  Found %d, %d, %d, %d\n",
                            pix[0], pix[1], pix[2], pix[3]);
                    pass = false;
                    break;
                }
            }
        }
    }

    glutSwapBuffers();

    glDeleteTextures(1, &texObj);
    glDeleteFramebuffers(1, &fbo);

    return pass;
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_EXTTextureInteger_nglClearColorIuiEXT(JNIEnv *env, jclass clazz, jint r, jint g, jint b, jint a, jlong function_pointer) {
	glClearColorIuiEXTPROC glClearColorIuiEXT = (glClearColorIuiEXTPROC)((intptr_t)function_pointer);
	glClearColorIuiEXT(r, g, b, a);
}