Exemplo n.º 1
0
bool vogl_query_state::restore(const vogl_context_info &context_info, vogl_handle_remapper &remapper, GLuint64 &handle) const
{
    VOGL_FUNC_TRACER

    VOGL_NOTE_UNUSED(context_info);

    if (!m_is_valid)
        return false;

    bool created_handle = false;

    if (!handle)
    {
        GLuint handle32 = 0;
        GL_ENTRYPOINT(glGenQueries)(1, &handle32);
        if ((vogl_check_gl_error()) || (!handle32))
            return false;
        handle = handle32;

        remapper.declare_handle(VOGL_NAMESPACE_QUERIES, m_snapshot_handle, handle, m_target);
        VOGL_ASSERT(remapper.remap_handle(VOGL_NAMESPACE_QUERIES, m_snapshot_handle) == handle);

        created_handle = true;
    }

    // m_target will be GL_NONE if the query has been genned but not begun up to this point.
    if ((m_target != GL_NONE) && (m_has_been_begun))
    {
        GLuint prev_query = 0;
        GL_ENTRYPOINT(glGetQueryiv)(m_target, GL_CURRENT_QUERY, reinterpret_cast<GLint *>(&prev_query));
        VOGL_CHECK_GL_ERROR;

        VOGL_ASSERT(handle <= cUINT32_MAX);

        // Begin end the restore query, so it becomes a valid name.
        GL_ENTRYPOINT(glBeginQuery)(m_target, static_cast<GLuint>(handle));
        if (vogl_check_gl_error())
            goto handle_error;

        GL_ENTRYPOINT(glEndQuery)(m_target);
        if (vogl_check_gl_error())
            goto handle_error;

        if (prev_query)
        {
            // Now begin/end the original query so it's active again. The query API sucks.
            GL_ENTRYPOINT(glBeginQuery)(m_target, prev_query);
            VOGL_CHECK_GL_ERROR;

            GL_ENTRYPOINT(glEndQuery)(m_target);
            VOGL_CHECK_GL_ERROR;
        }
    }

    return true;

handle_error:
    if ((handle) && (created_handle))
    {
        remapper.delete_handle_and_object(VOGL_NAMESPACE_QUERIES, m_snapshot_handle, handle);

        //GLuint handle32 = static_cast<GLuint>(handle);
        //GL_ENTRYPOINT(glDeleteQueries)(1, &handle32);
        //VOGL_CHECK_GL_ERROR;

        handle = 0;
    }

    return false;
}
Exemplo n.º 2
0
bool vogl_renderbuffer_state::restore(const vogl_context_info &context_info, vogl_handle_remapper &remapper, GLuint64 &handle) const
{
    VOGL_FUNC_TRACER

    VOGL_ASSERT(context_info.get_version() >= VOGL_GL_VERSION_3_0);

    if (!m_is_valid)
        return false;

    vogl_scoped_binding_state orig_renderbuffer(GL_RENDERBUFFER);

    bool created_handle = false;

    if (!handle)
    {
        GLuint handle32 = 0;
        GL_ENTRYPOINT(glGenRenderbuffers)(1, &handle32);
        if ((vogl_check_gl_error()) || (!handle32))
            return false;
        handle = handle32;

        remapper.declare_handle(VOGL_NAMESPACE_RENDER_BUFFERS, m_snapshot_handle, handle, GL_NONE);
        VOGL_ASSERT(remapper.remap_handle(VOGL_NAMESPACE_RENDER_BUFFERS, m_snapshot_handle) == handle);

        created_handle = true;
    }

    GL_ENTRYPOINT(glBindRenderbuffer)(GL_RENDERBUFFER, static_cast<GLuint>(handle));
    if (vogl_check_gl_error())
        goto handle_error;

    if ((m_desc.m_width) && (m_desc.m_height) && (m_desc.m_internal_format))
    {
        if (!m_desc.restore(context_info))
            goto handle_error;

        if (m_texture.is_valid())
        {
            GLenum attachment = GL_COLOR_ATTACHMENT0;
            GLenum draw_and_read_buf = GL_COLOR_ATTACHMENT0;
            GLenum blit_type = GL_COLOR_BUFFER_BIT;

            if ((m_desc.m_depth_size) && (m_desc.m_stencil_size))
            {
                attachment = GL_DEPTH_STENCIL_ATTACHMENT;
                draw_and_read_buf = GL_NONE;
                blit_type = GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
            }
            else if (m_desc.m_depth_size)
            {
                attachment = GL_DEPTH_ATTACHMENT;
                draw_and_read_buf = GL_NONE;
                blit_type = GL_DEPTH_BUFFER_BIT;
            }
            else if (m_desc.m_stencil_size)
            {
                attachment = GL_STENCIL_ATTACHMENT;
                draw_and_read_buf = GL_NONE;
                blit_type = GL_STENCIL_BUFFER_BIT;
            }

            bool restore_status = false;

            GLuint64 tex_handle64 = 0;
            vogl_handle_remapper def_handle_remapper;
            if (m_texture.restore(context_info, def_handle_remapper, tex_handle64))
            {
                GLuint tex_handle = static_cast<GLuint>(tex_handle64);

                const GLenum tex_target = (m_desc.m_samples > 1) ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D;

                GLuint src_fbo_handle = 0, dst_fbo_handle = 0;

                // Source FBO
                GL_ENTRYPOINT(glGenFramebuffers)(1, &src_fbo_handle);
                VOGL_CHECK_GL_ERROR;

                GL_ENTRYPOINT(glBindFramebuffer)(GL_READ_FRAMEBUFFER, src_fbo_handle);
                VOGL_CHECK_GL_ERROR;

                GL_ENTRYPOINT(glFramebufferTexture2D)(GL_READ_FRAMEBUFFER, attachment, tex_target, tex_handle, 0);
                VOGL_CHECK_GL_ERROR;

                GL_ENTRYPOINT(glReadBuffer)(draw_and_read_buf);
                VOGL_CHECK_GL_ERROR;

                // Dest FBO
                GL_ENTRYPOINT(glGenFramebuffers)(1, &dst_fbo_handle);
                VOGL_CHECK_GL_ERROR;

                GL_ENTRYPOINT(glBindFramebuffer)(GL_DRAW_FRAMEBUFFER, dst_fbo_handle);
                VOGL_CHECK_GL_ERROR;

                GL_ENTRYPOINT(glFramebufferRenderbuffer)(GL_DRAW_FRAMEBUFFER, attachment, GL_RENDERBUFFER, static_cast<GLuint>(handle));
                VOGL_CHECK_GL_ERROR;

                GL_ENTRYPOINT(glDrawBuffers)(1, &draw_and_read_buf);
                VOGL_CHECK_GL_ERROR;

                GLenum read_status = GL_ENTRYPOINT(glCheckFramebufferStatus)(GL_READ_FRAMEBUFFER);
                VOGL_CHECK_GL_ERROR;

                GLenum draw_status = GL_ENTRYPOINT(glCheckFramebufferStatus)(GL_DRAW_FRAMEBUFFER);
                VOGL_CHECK_GL_ERROR;

                if ((read_status = GL_FRAMEBUFFER_COMPLETE) && (draw_status == GL_FRAMEBUFFER_COMPLETE))
                {
    #if 0
                    // HACK HACK HACK
                    if (m_texture.get_num_samples() > 1)
                    {
                        uint base_level = m_texture.get_params().get_value<GLenum>(GL_TEXTURE_BASE_LEVEL);

                        if (base_level < m_texture.get_num_levels())
                        {
                            const vogl_state_vector &state_vec = m_texture.get_level_params(0, base_level);

                            uint clear_mask = 0;
                            if (state_vec.get_value<GLenum>(GL_TEXTURE_DEPTH_SIZE))
                            {
                                clear_mask |= GL_DEPTH_BUFFER_BIT;
                            }
                            if (state_vec.get_value<GLenum>(GL_TEXTURE_STENCIL_SIZE))
                            {
                                clear_mask |= GL_STENCIL_BUFFER_BIT;
                            }
                            if (state_vec.get_value<GLenum>(GL_TEXTURE_RED_SIZE) + state_vec.get_value<GLenum>(GL_TEXTURE_GREEN_SIZE) + state_vec.get_value<GLenum>(GL_TEXTURE_BLUE_SIZE) + state_vec.get_value<GLenum>(GL_TEXTURE_ALPHA_SIZE) +
                                state_vec.get_value<GLenum>(GL_TEXTURE_INTENSITY_SIZE) + state_vec.get_value<GLenum>(GL_TEXTURE_LUMINANCE_SIZE))
                            {
                                clear_mask |= GL_COLOR_BUFFER_BIT;
                            }

                            GL_ENTRYPOINT(glClearColor)(1.0f, 0.0f, 1.0f, 1.0f);
                            GL_ENTRYPOINT(glClearDepth)(.5f);
                            GL_ENTRYPOINT(glClearStencil)(128);
                            GL_ENTRYPOINT(glClear)(clear_mask);

                            VOGL_CHECK_GL_ERROR;
                        }
                    }
                    else
    #endif
                    {
                        GL_ENTRYPOINT(glBlitFramebuffer)(
                            0, 0, m_desc.m_width, m_desc.m_height,
                            0, 0, m_desc.m_width, m_desc.m_height,
                            blit_type,
                            GL_NEAREST);

                        if (!vogl_check_gl_error_internal())
                        {
                            restore_status = true;
                        }
                    }
                }

                // Delete FBO
                GL_ENTRYPOINT(glBindFramebuffer)(GL_DRAW_FRAMEBUFFER, 0);
                VOGL_CHECK_GL_ERROR;

                GL_ENTRYPOINT(glDeleteFramebuffers)(1, &dst_fbo_handle);
                VOGL_CHECK_GL_ERROR;

                GL_ENTRYPOINT(glBindFramebuffer)(GL_READ_FRAMEBUFFER, 0);
                VOGL_CHECK_GL_ERROR;

                GL_ENTRYPOINT(glDeleteFramebuffers)(1, &src_fbo_handle);
                VOGL_CHECK_GL_ERROR;

                GL_ENTRYPOINT(glDeleteTextures)(1, &tex_handle);
                VOGL_CHECK_GL_ERROR;
            }

            if (!restore_status)
            {
                vogl_error_printf("%s: Failed restoring contents of renderbuffer %u\n", VOGL_METHOD_NAME, static_cast<GLuint>(handle));
            }
        }
    }

    return true;

handle_error:
    if (created_handle)
    {
        GL_ENTRYPOINT(glBindRenderbuffer)(GL_RENDERBUFFER, 0);
        VOGL_CHECK_GL_ERROR;

        remapper.delete_handle_and_object(VOGL_NAMESPACE_RENDER_BUFFERS, m_snapshot_handle, handle);

        //GLuint handle32 = static_cast<GLuint>(handle);
        //GL_ENTRYPOINT(glDeleteRenderbuffers)(1, &handle32);
        //VOGL_CHECK_GL_ERROR;

        handle = 0;
    }

    return false;
}