vogleditor_stateTreeContextInfoItem::vogleditor_stateTreeContextInfoItem(QString name, QString value, vogleditor_stateTreeItem* parent, const vogl_context_info& info)
    : vogleditor_stateTreeItem(name, value, parent),
      m_pState(&info),
      m_pDiffBaseState(NULL)
{
    QString tmp;

    if (info.is_valid())
    {
       tmp = "valid";
    }
    else
    {
       tmp = "Never made current";
    }

    this->setValue(tmp);

    if (info.is_valid())
    {
        { vogleditor_stateTreeContextInfoBoolItem* pItem = new vogleditor_stateTreeContextInfoBoolItem("Forward compatible", &vogl_context_info::is_forward_compatible, this, info); m_diffableItems.push_back(pItem); this->appendChild(pItem); }
        { vogleditor_stateTreeContextInfoBoolItem* pItem = new vogleditor_stateTreeContextInfoBoolItem("Core profile", &vogl_context_info::is_core_profile, this, info); m_diffableItems.push_back(pItem); this->appendChild(pItem); }
        { vogleditor_stateTreeContextInfoBoolItem* pItem = new vogleditor_stateTreeContextInfoBoolItem("Compatibility Profile", &vogl_context_info::is_compatibility_profile, this, info); m_diffableItems.push_back(pItem); this->appendChild(pItem); }
        { vogleditor_stateTreeContextInfoBoolItem* pItem = new vogleditor_stateTreeContextInfoBoolItem("Debug context", &vogl_context_info::is_debug_context, this, info); m_diffableItems.push_back(pItem); this->appendChild(pItem); }

        { vogleditor_stateTreeContextInfoStringItem* pItem = new vogleditor_stateTreeContextInfoStringItem("GL_RENDERER", &vogl_context_info::get_renderer_str, this, info); m_diffableItems.push_back(pItem); this->appendChild(pItem); }
        { vogleditor_stateTreeContextInfoStringItem* pItem = new vogleditor_stateTreeContextInfoStringItem("GL_VENDOR", &vogl_context_info::get_vendor_str, this, info); m_diffableItems.push_back(pItem); this->appendChild(pItem); }
        { vogleditor_stateTreeContextInfoStringItem* pItem = new vogleditor_stateTreeContextInfoStringItem("GL_VERSION", &vogl_context_info::get_version_str, this, info); m_diffableItems.push_back(pItem); this->appendChild(pItem); }
        { vogleditor_stateTreeContextInfoStringItem* pItem = new vogleditor_stateTreeContextInfoStringItem("GL_SHADING_LANGUAGE_VERSION", &vogl_context_info::get_glsl_version_str, this, info); m_diffableItems.push_back(pItem); this->appendChild(pItem); }

        vogleditor_stateTreeItem* pExtNode = new vogleditor_stateTreeItem("GL_EXTENSIONS", "", this);
        this->appendChild(pExtNode);
        const dynamic_string_array& extList = info.get_extensions();
        for (uint e = 0; e < extList.size(); e++)
        {
            vogleditor_stateTreeContextInfoExtensionItem* pItem = new vogleditor_stateTreeContextInfoExtensionItem(tmp.sprintf("%d", e), extList[e].c_str(), pExtNode, info);
            m_diffableItems.push_back(pItem);
            pExtNode->appendChild(pItem);
        }
        pExtNode->setValue(tmp.sprintf("[%d]", pExtNode->childCount()));

        { vogleditor_stateTreeContextInfoUIntItem* pItem = new vogleditor_stateTreeContextInfoUIntItem("GL_MAX_PROGRAM_ENV_PARAMETERS_ARB GL_VERTEX_PROGRAM_ARB", &vogl_context_info::get_max_arb_vertex_program_env_params, this, info); m_diffableItems.push_back(pItem); this->appendChild(pItem); }
        { vogleditor_stateTreeContextInfoUIntItem* pItem = new vogleditor_stateTreeContextInfoUIntItem("GL_MAX_PROGRAM_ENV_PARAMETERS_ARB GL_FRAGMENT_PROGRAM_ARB", &vogl_context_info::get_max_arb_fragment_program_env_params, this, info); m_diffableItems.push_back(pItem); this->appendChild(pItem); }
        { vogleditor_stateTreeContextInfoUIntItem* pItem = new vogleditor_stateTreeContextInfoUIntItem("GL_MAX_PROGRAM_MATRICES_ARB", &vogl_context_info::get_max_arb_program_matrices, this, info); m_diffableItems.push_back(pItem); this->appendChild(pItem); }
        { vogleditor_stateTreeContextInfoUIntItem* pItem = new vogleditor_stateTreeContextInfoUIntItem("GL_MAX_COMBINED_TEXTURE_COORDS", &vogl_context_info::get_max_combined_texture_coords, this, info); m_diffableItems.push_back(pItem); this->appendChild(pItem); }
        { vogleditor_stateTreeContextInfoUIntItem* pItem = new vogleditor_stateTreeContextInfoUIntItem("GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS", &vogl_context_info::get_max_transform_feedback_separate_attribs, this, info); m_diffableItems.push_back(pItem); this->appendChild(pItem); }


//       this->appendChild(new vogleditor_stateTreeItem("GL_MAX_DRAW_BUFFERS", STR_INT(info.get_max_draw_buffers()), this));
//       this->appendChild(new vogleditor_stateTreeItem("GL_MAX_LIGHTS", STR_INT(info.get_max_lights()), this));
//       this->appendChild(new vogleditor_stateTreeItem("GL_MAX_TEXTURE_COORDS", STR_INT(info.get_max_texture_coords()), this));
//       this->appendChild(new vogleditor_stateTreeItem("GL_MAX_TEXTURE_IMAGE_UNITS", STR_INT(info.get_max_texture_image_units()), this));
//       this->appendChild(new vogleditor_stateTreeItem("GL_MAX_TEXTURE_UNITS", STR_INT(info.get_max_texture_units()), this));
//       this->appendChild(new vogleditor_stateTreeItem("GL_MAX_UNIFORM_BUFFER_BINDINGS", STR_INT(info.get_max_uniform_buffer_bindings()), this));
//       this->appendChild(new vogleditor_stateTreeItem("GL_MAX_VERTEX_ATTRIBS", STR_INT(info.get_max_vertex_attribs()), this));
    }
}
Beispiel #2
0
bool vogl_vao_state::snapshot(const vogl_context_info &context_info, vogl_handle_remapper &remapper, GLuint64 handle, GLenum target)
{
    VOGL_FUNC_TRACER

    VOGL_NOTE_UNUSED(target);
    VOGL_NOTE_UNUSED(remapper);

    VOGL_CHECK_GL_ERROR;

    clear();

    VOGL_ASSERT(handle <= cUINT32_MAX);

    m_snapshot_handle = static_cast<GLuint>(handle);

    // TODO: Core profile support
    m_has_been_bound = handle ? (GL_ENTRYPOINT(glIsVertexArray)(static_cast<GLuint>(handle)) != 0) : true;

    if (m_has_been_bound)
    {
        vogl_scoped_binding_state orig_binding(GL_VERTEX_ARRAY);

        GL_ENTRYPOINT(glBindVertexArray)(m_snapshot_handle);
        VOGL_CHECK_GL_ERROR;

        m_element_array_binding = vogl_get_gl_integer(GL_ELEMENT_ARRAY_BUFFER_BINDING);

        m_vertex_attribs.resize(context_info.get_max_vertex_attribs());

        for (uint32_t i = 0; i < context_info.get_max_vertex_attribs(); i++)
        {
            vogl_vertex_attrib_desc &desc = m_vertex_attribs[i];

            desc.m_array_binding = vogl_get_vertex_attrib_int(i, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING);
            desc.m_enabled = vogl_get_vertex_attrib_int(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED) != 0;
            desc.m_size = vogl_get_vertex_attrib_int(i, GL_VERTEX_ATTRIB_ARRAY_SIZE);
            desc.m_type = vogl_get_vertex_attrib_int(i, GL_VERTEX_ATTRIB_ARRAY_TYPE);
            desc.m_normalized = vogl_get_vertex_attrib_int(i, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED) != 0;
            desc.m_stride = vogl_get_vertex_attrib_int(i, GL_VERTEX_ATTRIB_ARRAY_STRIDE);
            desc.m_integer = vogl_get_vertex_attrib_int(i, GL_VERTEX_ATTRIB_ARRAY_INTEGER) != 0;
            desc.m_divisor = vogl_get_vertex_attrib_uint(i, GL_VERTEX_ATTRIB_ARRAY_DIVISOR);

            GLvoid *ptr = NULL;
            GL_ENTRYPOINT(glGetVertexAttribPointerv)(i, GL_VERTEX_ATTRIB_ARRAY_POINTER, &ptr);
            desc.m_pointer = reinterpret_cast<vogl_trace_ptr_value>(ptr);

            VOGL_CHECK_GL_ERROR;
        }
    }

    m_is_valid = true;

    return true;
}
Beispiel #3
0
bool vogl_matrix_state::snapshot(const vogl_context_info &context_info)
{
    VOGL_FUNC_TRACER

    clear();

    bool any_errors = false;

    VOGL_CHECK_GL_ERROR;

    vogl_scoped_state_saver state_saver(cGSTActiveTexture, cGSTMatrixMode);

    if (vogl_check_gl_error())
        any_errors = true;

    if (!save_matrix_stack(context_info, GL_PROJECTION, 0, GL_PROJECTION_STACK_DEPTH, GL_PROJECTION_MATRIX))
        any_errors = true;

    if (!save_matrix_stack(context_info, GL_MODELVIEW, 0, GL_MODELVIEW_STACK_DEPTH, GL_MODELVIEW_MATRIX))
        any_errors = true;

    if (!save_matrix_stack(context_info, GL_COLOR, 0, GL_COLOR_MATRIX_STACK_DEPTH, GL_COLOR_MATRIX))
        any_errors = true;

    for (uint32_t texcoord_index = 0; texcoord_index < context_info.get_max_texture_coords(); texcoord_index++)
    {
        GL_ENTRYPOINT(glActiveTexture)(GL_TEXTURE0 + texcoord_index);

        if (vogl_check_gl_error())
            any_errors = true;

        if (!save_matrix_stack(context_info, GL_TEXTURE, texcoord_index, GL_TEXTURE_STACK_DEPTH, GL_TEXTURE_MATRIX))
            any_errors = true;
    }

    for (uint32_t i = 0; i < context_info.get_max_arb_program_matrices(); i++)
    {
        if (!save_matrix_stack(context_info, GL_MATRIX0_ARB + i, 0, GL_CURRENT_MATRIX_STACK_DEPTH_ARB, GL_CURRENT_MATRIX_ARB))
            any_errors = true;
    }

    if (any_errors)
        clear();
    else
        m_valid = true;

    return !any_errors;
}
vogleditor_stateTreeVertexArrayItem::vogleditor_stateTreeVertexArrayItem(QString name, QString value, GLuint64 handle, vogleditor_stateTreeItem* parent, vogl_vao_state& state, const vogl_context_info& info)
    : vogleditor_stateTreeItem(name, value, parent),
      m_pState(&state),
      m_handle(handle),
      m_pDiffBaseState(NULL)
{
    static QString tmp;
    for (uint i = 0; i < info.get_max_vertex_attribs(); i++)
    {
       vogleditor_stateTreeItem* pAttribNode = new vogleditor_stateTreeItem(tmp.sprintf("GL_VERTEX_ATTRIB %u", i), "", this);
       this->appendChild(pAttribNode);

       const vogl_vertex_attrib_desc& desc = state.get_vertex_attrib_desc(i);

       // Peter: FIXME, this is now vao state
       //{ vogleditor_stateTreeVertexArrayUIntItem* pItem = new vogleditor_stateTreeVertexArrayUIntItem("GL_ELEMENT_ARRAY_BUFFER_BINDING", &vogl_vertex_attrib_desc::m_element_array_binding, pAttribNode, desc, i); m_diffableItems.push_back(pItem); pAttribNode->appendChild(pItem); }
       { vogleditor_stateTreeVertexArrayUIntItem* pItem = new vogleditor_stateTreeVertexArrayUIntItem("GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING", &vogl_vertex_attrib_desc::m_array_binding, pAttribNode, desc, i); m_diffableItems.push_back(pItem); pAttribNode->appendChild(pItem); }
       { vogleditor_stateTreeVertexArrayBoolItem* pItem = new vogleditor_stateTreeVertexArrayBoolItem("GL_VERTEX_ATTRIB_ARRAY_ENABLED", &vogl_vertex_attrib_desc::m_enabled, pAttribNode, desc, i); m_diffableItems.push_back(pItem); pAttribNode->appendChild(pItem); }
       { vogleditor_stateTreeVertexArrayIntItem* pItem = new vogleditor_stateTreeVertexArrayIntItem("GL_VERTEX_ATTRIB_ARRAY_SIZE", &vogl_vertex_attrib_desc::m_size, pAttribNode, desc, i); m_diffableItems.push_back(pItem); pAttribNode->appendChild(pItem); }
       { vogleditor_stateTreeVertexArrayEnumItem* pItem = new vogleditor_stateTreeVertexArrayEnumItem("GL_VERTEX_ATTRIB_ARRAY_TYPE", &vogl_vertex_attrib_desc::m_type, pAttribNode, desc, i); m_diffableItems.push_back(pItem); pAttribNode->appendChild(pItem); }
       { vogleditor_stateTreeVertexArrayBoolItem* pItem = new vogleditor_stateTreeVertexArrayBoolItem("GL_VERTEX_ATTRIB_ARRAY_NORMALIZED", &vogl_vertex_attrib_desc::m_normalized, pAttribNode, desc, i); m_diffableItems.push_back(pItem); pAttribNode->appendChild(pItem); }
       { vogleditor_stateTreeVertexArrayIntItem* pItem = new vogleditor_stateTreeVertexArrayIntItem("GL_VERTEX_ATTRIB_ARRAY_STRIDE", &vogl_vertex_attrib_desc::m_stride, pAttribNode, desc, i); m_diffableItems.push_back(pItem); pAttribNode->appendChild(pItem); }
       { vogleditor_stateTreeVertexArrayBoolItem* pItem = new vogleditor_stateTreeVertexArrayBoolItem("GL_VERTEX_ATTRIB_ARRAY_INTEGER", &vogl_vertex_attrib_desc::m_integer, pAttribNode, desc, i); m_diffableItems.push_back(pItem); pAttribNode->appendChild(pItem); }
       { vogleditor_stateTreeVertexArrayUIntItem* pItem = new vogleditor_stateTreeVertexArrayUIntItem("GL_VERTEX_ATTRIB_ARRAY_DIVISOR", &vogl_vertex_attrib_desc::m_divisor, pAttribNode, desc, i); m_diffableItems.push_back(pItem); pAttribNode->appendChild(pItem); }
       { vogleditor_stateTreeVertexArrayPtrItem* pItem = new vogleditor_stateTreeVertexArrayPtrItem("GL_VERTEX_ATTRIB_ARRAY_POINTER", &vogl_vertex_attrib_desc::m_pointer, pAttribNode, desc, i); m_diffableItems.push_back(pItem); pAttribNode->appendChild(pItem); }
    }
}
bool vogl_renderbuffer_desc::snapshot(const vogl_context_info &context_info)
{
    VOGL_FUNC_TRACER

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

    VOGL_CHECK_GL_ERROR;

#define GET_STATE(e, x)                                                                               \
    do                                                                                                \
    {                                                                                                 \
        GL_ENTRYPOINT(glGetRenderbufferParameteriv)(GL_RENDERBUFFER, e, reinterpret_cast<int *>(&x)); \
        VOGL_CHECK_GL_ERROR;                                                                           \
    } while (0)
    GET_STATE(GL_RENDERBUFFER_WIDTH, m_width);
    GET_STATE(GL_RENDERBUFFER_HEIGHT, m_height);
    GET_STATE(GL_RENDERBUFFER_SAMPLES, m_samples);
    GET_STATE(GL_RENDERBUFFER_INTERNAL_FORMAT, m_internal_format);
    GET_STATE(GL_RENDERBUFFER_RED_SIZE, m_red_size);
    GET_STATE(GL_RENDERBUFFER_GREEN_SIZE, m_green_size);
    GET_STATE(GL_RENDERBUFFER_BLUE_SIZE, m_blue_size);
    GET_STATE(GL_RENDERBUFFER_ALPHA_SIZE, m_alpha_size);
    GET_STATE(GL_RENDERBUFFER_DEPTH_SIZE, m_depth_size);
    GET_STATE(GL_RENDERBUFFER_STENCIL_SIZE, m_stencil_size);
#undef GET_STATE

    return true;
}
Beispiel #6
0
bool vogl_framebuffer_attachment::snapshot(const vogl_context_info &context_info, vogl_handle_remapper &remapper, GLenum attachment, GLenum type)
{
    VOGL_FUNC_TRACER

    VOGL_NOTE_UNUSED(remapper);
    VOGL_NOTE_UNUSED(context_info);

    clear();

    m_attachment = attachment;

    m_type = type;

#define DO_QUERY(e)                                                                                \
    do                                                                                             \
    {                                                                                              \
        int val = 0;                                                                               \
        GL_ENTRYPOINT(glGetFramebufferAttachmentParameteriv)(GL_FRAMEBUFFER, attachment, e, &val); \
        VOGL_CHECK_GL_ERROR;                                                                        \
        m_params.insert(e, val);                                                                   \
    } while (0)

    // TODO: Is this query really valid on default framebuffer FBO's?
    DO_QUERY(GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME);

    static const GLenum s_common_queries[] =
        {
            GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE, GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE, GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE,
            GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE, GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING
        };

    for (uint32_t i = 0; i < VOGL_ARRAY_SIZE(s_common_queries); i++)
    {
        DO_QUERY(s_common_queries[i]);
    }

    if (m_type == GL_TEXTURE)
    {
        DO_QUERY(GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL);
        DO_QUERY(GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE);
        DO_QUERY(GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER);
        // only need to query LAYERED if GS supported
        if (context_info.supports_extension("GL_ARB_geometry_shader4"))
            DO_QUERY(GL_FRAMEBUFFER_ATTACHMENT_LAYERED);
    }

#undef DO_QUERY

    return true;
}
bool vogl_renderbuffer_desc::restore(const vogl_context_info &context_info) const
{
    VOGL_FUNC_TRACER

    VOGL_NOTE_UNUSED(context_info);

    if (!m_width)
        return false;

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

    VOGL_CHECK_GL_ERROR;

    GL_ENTRYPOINT(glRenderbufferStorageMultisample)(GL_RENDERBUFFER, m_samples, m_internal_format, m_width, m_height);

    bool prev_gl_error = vogl_check_gl_error();
    VOGL_ASSERT(!prev_gl_error);

    return !prev_gl_error;
}
Beispiel #8
0
bool vogl_query_state::snapshot(const vogl_context_info &context_info, vogl_handle_remapper &remapper, GLuint64 handle, GLenum target)
{
    VOGL_FUNC_TRACER

    VOGL_NOTE_UNUSED(remapper);
    VOGL_CHECK_GL_ERROR;

    clear();

    VOGL_ASSERT(handle <= cUINT32_MAX);

    m_snapshot_handle = static_cast<GLuint>(handle);
    m_target = target;
    m_has_been_begun = GL_ENTRYPOINT(glIsQuery)(static_cast<GLuint>(handle)) != 0;

    if (target != GL_NONE)
    {
        if (context_info.supports_extension("GL_ARB_timer_query") && GL_ENTRYPOINT(glGetQueryObjecti64v))
        {
            GLint64 result = 0;
            GL_ENTRYPOINT(glGetQueryObjecti64v)(m_snapshot_handle, GL_QUERY_RESULT, &result);
            m_prev_result = result;
        }
        else
        {
            GLuint prev_result32;
            GL_ENTRYPOINT(glGetQueryObjectuiv)(m_snapshot_handle, GL_QUERY_RESULT, &prev_result32);
            m_prev_result = prev_result32;
        }
    }

    m_get_result_status = vogl_check_gl_error();

    m_is_valid = true;

    return true;
}
vogleditor_stateTreeProgramItem::vogleditor_stateTreeProgramItem(QString name, QString value, vogleditor_stateTreeItem* parentNode, vogl_program_state& state, const vogl_context_info& info)
   : vogleditor_stateTreeItem(name, value, parentNode),
     m_pState(&state)
{
   QString tmp;

   // basic info
   this->appendChild(new vogleditor_stateTreeProgramBoolItem("GL_LINK_STATUS", &vogl_program_state::get_link_status, this, state));
   if (info.supports_extension("GL_ARB_separate_shader_objects"))
       this->appendChild(new vogleditor_stateTreeProgramBoolItem("GL_PROGRAM_SEPARABLE", &vogl_program_state::get_separable, this, state));
   this->appendChild(new vogleditor_stateTreeProgramBoolItem("GL_DELETE_STATUS", &vogl_program_state::get_marked_for_deletion, this, state));
   this->appendChild(new vogleditor_stateTreeProgramBoolItem("GL_VALIDATE_STATUS", &vogl_program_state::get_verify_status, this, state));
   if (info.get_version() >= VOGL_GL_VERSION_3_1)
   {
      this->appendChild(new vogleditor_stateTreeProgramUIntItem("GL_ACTIVE_UNIFORM_BLOCKS", &vogl_program_state::get_num_active_uniform_blocks, this, state));
   }

   // program binary
   this->appendChild(new vogleditor_stateTreeItem("GL_PROGRAM_BINARY_RETRIEVABLE_HINT", "TODO", this));
   this->appendChild(new vogleditor_stateTreeProgramUIntItem("GL_PROGRAM_BINARY_LENGTH", &vogl_program_state::get_program_binary_size, this, state));
   this->appendChild(new vogleditor_stateTreeProgramEnumItem("GL_PROGRAM_BINARY_FORMAT", &vogl_program_state::get_program_binary_format, this, state));
   if (m_pState->get_program_binary().size() > 0)
   {
      this->appendChild(new vogleditor_stateTreeItem("Program Binary", "TODO: open in a new tab", this));
   }

   // info log
   this->appendChild(new vogleditor_stateTreeProgramLogItem("GL_INFO_LOG_LENGTH", &vogl_program_state::get_info_log, this, state));

   // linked shaders
   const vogl_unique_ptr<vogl_program_state> &linked_program = m_pState->get_link_time_snapshot();
   if (linked_program.get())
   {
      uint num_attached_shaders = linked_program->get_shaders().size();
      vogleditor_stateTreeItem* pLinkedShadersNode = new vogleditor_stateTreeItem("Linked Shaders", tmp.sprintf("[%u]", num_attached_shaders), this);
      this->appendChild(pLinkedShadersNode);

      for (uint i = 0; i < num_attached_shaders; i++)
      {
         vogl_shader_state& shader = const_cast<vogl_shader_state&>(linked_program->get_shaders()[i]);
         GLuint64 shaderId = shader.get_snapshot_handle();
         pLinkedShadersNode->appendChild(new vogleditor_stateTreeShaderItem(tmp.sprintf("%" PRIu64, shaderId), enum_to_string(shader.get_shader_type()), pLinkedShadersNode, shader));
      }
   }

    // attached shaders
    uint num_attached_shaders = m_pState->get_shaders().size();
    vogleditor_stateTreeItem* pAttachedShadersNode = new vogleditor_stateTreeItem("GL_ATTACHED_SHADERS", tmp.sprintf("[%u]", num_attached_shaders), this);
    this->appendChild(pAttachedShadersNode);
    for (uint i = 0; i < num_attached_shaders; i++)
    {
        vogl_shader_state& shader = const_cast<vogl_shader_state&>(m_pState->get_shaders()[i]);
        GLuint64 shaderId = shader.get_snapshot_handle();
        pAttachedShadersNode->appendChild(new vogleditor_stateTreeShaderItem(tmp.sprintf("%" PRIu64, shaderId), enum_to_string(shader.get_shader_type()), pAttachedShadersNode, shader));
    }

   // active attribs
   vogleditor_stateTreeItem* pAttribsNode = new vogleditor_stateTreeItem("GL_ACTIVE_ATTRIBUTES", tmp.sprintf("[%u]", m_pState->get_num_active_attribs()), this);
   this->appendChild(pAttribsNode);
   uint num_active_attributes = m_pState->get_attrib_state_vec().size();
   for (uint i = 0; i < num_active_attributes; i++)
   {
      const vogl_program_attrib_state& attrib = m_pState->get_attrib_state_vec()[i];
      vogleditor_stateTreeProgramAttribItem* pItem = new vogleditor_stateTreeProgramAttribItem(tmp.sprintf("%s", attrib.m_name.get_ptr()), pAttribsNode, attrib);
      m_attribItems.push_back(pItem);
      pAttribsNode->appendChild(pItem);
   }

   // uniforms
   vogleditor_stateTreeItem* pUniformsNode = new vogleditor_stateTreeItem("GL_ACTIVE_UNIFORMS", tmp.sprintf("[%u]", m_pState->get_num_active_uniforms()), this);
   this->appendChild(pUniformsNode);
   uint num_uniforms = m_pState->get_uniform_state_vec().size();
   for (uint i = 0; i < num_uniforms; i++)
   {
      const vogl_program_uniform_state& uniform = m_pState->get_uniform_state_vec()[i];
//      pUniformsNode->appendChild(new vogleditor_stateTreeItem(QString(uniform.m_name.get_ptr()), tmp.sprintf("Loc: %d, Size: %d, Type: %s", uniform.m_base_location, uniform.m_size, enum_to_string(uniform.m_type).toStdString().c_str()), pUniformsNode));
      vogleditor_stateTreeProgramUniformItem* pItem = new vogleditor_stateTreeProgramUniformItem(QString(uniform.m_name.get_ptr()), pUniformsNode, uniform);
      m_uniformItems.push_back(pItem);
      pUniformsNode->appendChild(pItem);
   }

   // uniform blocks
}
vogleditor_stateTreeTexEnvItem::vogleditor_stateTreeTexEnvItem(QString name, vogleditor_stateTreeItem *parent, vogl_texenv_state &state, const vogl_context_info &info)
    : vogleditor_stateTreeItem(name, "", parent),
      m_pState(&state),
      m_pDiffBaseState(NULL),
      m_pDiffBaseInfo(NULL)
{
    QString tmp;
    for (uint texcoord_index = 0; texcoord_index < info.get_max_texture_coords(); texcoord_index++)
    {
        vogleditor_stateTreeItem *pTexNode = new vogleditor_stateTreeItem(tmp.sprintf("GL_TEXTURE%u", texcoord_index), "", this);
        this->appendChild(pTexNode);

        int iVals[4] = { 0, 0, 0, 0 };
        float fVals[4] = { 0, 0, 0, 0 };
#define GET_ENUM(target, idx, name, num)                                                                                                                               \
    if (m_pState->get_state(target).get<int>(name, idx, iVals, num))                                                                                                   \
    {                                                                                                                                                                  \
        vogleditor_stateTreeTexEnvStateVecEnumItem *pItem = new vogleditor_stateTreeTexEnvStateVecEnumItem(target, #name, name, idx, iVals, num, pTexNode, *m_pState); \
        m_diffableItems.push_back(pItem);                                                                                                                              \
        pTexNode->appendChild(pItem);                                                                                                                                  \
    }
#define GET_FLOAT(target, idx, name, num)                                                                                                                                \
    if (m_pState->get_state(target).get<float>(name, idx, fVals, num))                                                                                                   \
    {                                                                                                                                                                    \
        vogleditor_stateTreeTexEnvStateVecFloatItem *pItem = new vogleditor_stateTreeTexEnvStateVecFloatItem(target, #name, name, idx, fVals, num, pTexNode, *m_pState); \
        m_diffableItems.push_back(pItem);                                                                                                                                \
        pTexNode->appendChild(pItem);                                                                                                                                    \
    }

        GET_FLOAT(GL_TEXTURE_FILTER_CONTROL, texcoord_index, GL_TEXTURE_LOD_BIAS, 1);
        GET_ENUM(GL_POINT_SPRITE, texcoord_index, GL_COORD_REPLACE, 1);
        GET_ENUM(GL_TEXTURE_ENV, texcoord_index, GL_TEXTURE_ENV_MODE, 1);
        GET_FLOAT(GL_TEXTURE_ENV, texcoord_index, GL_TEXTURE_ENV_COLOR, 4);
        GET_ENUM(GL_TEXTURE_ENV, texcoord_index, GL_COMBINE_RGB, 1);
        GET_ENUM(GL_TEXTURE_ENV, texcoord_index, GL_COMBINE_ALPHA, 1);
        GET_FLOAT(GL_TEXTURE_ENV, texcoord_index, GL_RGB_SCALE, 1);
        GET_FLOAT(GL_TEXTURE_ENV, texcoord_index, GL_ALPHA_SCALE, 1);
        GET_ENUM(GL_TEXTURE_ENV, texcoord_index, GL_SRC0_RGB, 1);
        GET_ENUM(GL_TEXTURE_ENV, texcoord_index, GL_SRC1_RGB, 1);
        GET_ENUM(GL_TEXTURE_ENV, texcoord_index, GL_SRC2_RGB, 1);
        GET_ENUM(GL_TEXTURE_ENV, texcoord_index, GL_SRC0_ALPHA, 1);
        GET_ENUM(GL_TEXTURE_ENV, texcoord_index, GL_SRC1_ALPHA, 1);
        GET_ENUM(GL_TEXTURE_ENV, texcoord_index, GL_SRC2_ALPHA, 1);
        GET_ENUM(GL_TEXTURE_ENV, texcoord_index, GL_OPERAND0_RGB, 1);
        GET_ENUM(GL_TEXTURE_ENV, texcoord_index, GL_OPERAND1_RGB, 1);
        GET_ENUM(GL_TEXTURE_ENV, texcoord_index, GL_OPERAND2_RGB, 1);
        GET_ENUM(GL_TEXTURE_ENV, texcoord_index, GL_OPERAND0_ALPHA, 1);
        GET_ENUM(GL_TEXTURE_ENV, texcoord_index, GL_OPERAND1_ALPHA, 1);
        GET_ENUM(GL_TEXTURE_ENV, texcoord_index, GL_OPERAND2_ALPHA, 1);

// TODO:
//{ "glGetTexEnv",	'E',	1,	"GL_SOURCE3_RGB_NV",  0x8583},
//{ "glGetTexEnv",	'E',	1,	"GL_SOURCE3_ALPHA_NV",  0x858B},
//{ "glGetTexEnv",	'E',	1,	"GL_OPERAND3_RGB_NV",  0x8593},
//{ "glGetTexEnv",	'E',	1,	"GL_OPERAND3_ALPHA_NV",  0x859B},
//{ "glGetTexEnv",	'E',	1,	"GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV",  0x86D9},
//{ "glGetTexEnv",	'E',	1,	"GL_SHADER_OPERATION_NV",  0x86DF},
//{ "glGetTexEnv",	'E',	4,	"GL_CULL_MODES_NV",  0x86E0},
//{ "glGetTexEnv",	'F',	4,	"GL_OFFSET_TEXTURE_MATRIX_NV",  0x86E1},
//{ "glGetTexEnv",	'F',	1,	"GL_OFFSET_TEXTURE_SCALE_NV",  0x86E2},
//{ "glGetTexEnv",	'F',	1,	"GL_OFFSET_TEXTURE_BIAS_NV",  0x86E3},
//{ "glGetTexEnv",	'E',	1,	"GL_PREVIOUS_TEXTURE_INPUT_NV",  0x86E4},
//{ "glGetTexEnv",	'F',	3,	"GL_CONST_EYE_NV",  0x86E5},
//{ "glGetTexEnv",	'E',	1,	"GL_BUMP_TARGET_ATI",  0x877C},

#undef GET_FLOAT
#undef GET_ENUM
#define GET_ENUM(target, idx, name, num)                                                                                                                                           \
    if (m_pState->get_state(target).get<int>(name, idx, iVals, num))                                                                                                               \
    {                                                                                                                                                                              \
        vogleditor_stateTreeTexEnvStateVecEnumItem *pItem = new vogleditor_stateTreeTexEnvStateVecEnumItem(target, #target " " #name, name, idx, iVals, num, pTexNode, *m_pState); \
        m_diffableItems.push_back(pItem);                                                                                                                                          \
        pTexNode->appendChild(pItem);                                                                                                                                              \
    }
#define GET_FLOAT(target, idx, name, num)                                                                                                                                            \
    if (m_pState->get_state(target).get<float>(name, idx, fVals, num))                                                                                                               \
    {                                                                                                                                                                                \
        vogleditor_stateTreeTexEnvStateVecFloatItem *pItem = new vogleditor_stateTreeTexEnvStateVecFloatItem(target, #target " " #name, name, idx, fVals, num, pTexNode, *m_pState); \
        m_diffableItems.push_back(pItem);                                                                                                                                            \
        pTexNode->appendChild(pItem);                                                                                                                                                \
    }

        GET_ENUM(GL_S, texcoord_index, GL_TEXTURE_GEN_MODE, 1);
        GET_FLOAT(GL_S, texcoord_index, GL_OBJECT_PLANE, 4);
        GET_FLOAT(GL_S, texcoord_index, GL_EYE_PLANE, 4);

        GET_ENUM(GL_T, texcoord_index, GL_TEXTURE_GEN_MODE, 1);
        GET_FLOAT(GL_T, texcoord_index, GL_OBJECT_PLANE, 4);
        GET_FLOAT(GL_T, texcoord_index, GL_EYE_PLANE, 4);

        GET_ENUM(GL_R, texcoord_index, GL_TEXTURE_GEN_MODE, 1);
        GET_FLOAT(GL_R, texcoord_index, GL_OBJECT_PLANE, 4);
        GET_FLOAT(GL_R, texcoord_index, GL_EYE_PLANE, 4);

        GET_ENUM(GL_Q, texcoord_index, GL_TEXTURE_GEN_MODE, 1);
        GET_FLOAT(GL_Q, texcoord_index, GL_OBJECT_PLANE, 4);
        GET_FLOAT(GL_Q, texcoord_index, GL_EYE_PLANE, 4);
#undef GET_FLOAT
#undef GET_ENUM
    }
}
Beispiel #11
0
bool vogl_vao_state::restore(const vogl_context_info &context_info, vogl_handle_remapper &remapper, GLuint64 &handle) const
{
    VOGL_FUNC_TRACER

    VOGL_CHECK_GL_ERROR;

    if (!m_is_valid)
        return false;

    vogl_scoped_binding_state orig_binding(GL_VERTEX_ARRAY, GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER);

    if ((!m_snapshot_handle) && (!handle))
    {
        GL_ENTRYPOINT(glBindVertexArray)(0);
        VOGL_CHECK_GL_ERROR;
    }
    else
    {
        if (!handle)
        {
            GLuint handle32 = 0;
            GL_ENTRYPOINT(glGenVertexArrays)(1, &handle32);
            if ((vogl_check_gl_error()) || (!handle32))
                return false;
            handle = handle32;

            if (m_snapshot_handle)
            {
                remapper.declare_handle(VOGL_NAMESPACE_VERTEX_ARRAYS, m_snapshot_handle, handle, GL_NONE);
                VOGL_ASSERT(remapper.remap_handle(VOGL_NAMESPACE_VERTEX_ARRAYS, m_snapshot_handle) == handle);
            }
        }

        if (m_has_been_bound)
        {
            GL_ENTRYPOINT(glBindVertexArray)(static_cast<GLuint>(handle));
            VOGL_CHECK_GL_ERROR;
        }
    }

    if (m_has_been_bound)
    {
        GL_ENTRYPOINT(glBindBuffer)(GL_ELEMENT_ARRAY_BUFFER, static_cast<GLuint>(remapper.remap_handle(VOGL_NAMESPACE_BUFFERS, m_element_array_binding)));
        VOGL_CHECK_GL_ERROR;

        if (m_vertex_attribs.size() > context_info.get_max_vertex_attribs())
        {
            vogl_warning_printf("Saved VAO state has %u attribs, but context only allows %u attribs\n", m_vertex_attribs.size(), context_info.get_max_vertex_attribs());
        }

        for (uint32_t i = 0; i < math::minimum<uint32_t>(context_info.get_max_vertex_attribs(), m_vertex_attribs.size()); i++)
        {
            const vogl_vertex_attrib_desc &desc = m_vertex_attribs[i];

            GL_ENTRYPOINT(glBindBuffer)(GL_ARRAY_BUFFER, static_cast<GLuint>(remapper.remap_handle(VOGL_NAMESPACE_BUFFERS, desc.m_array_binding)));
            VOGL_CHECK_GL_ERROR;

            vogl_trace_ptr_value trace_ptr_val = desc.m_pointer;

            vogl_trace_ptr_value restore_ptr_val = trace_ptr_val;
            if ((!desc.m_array_binding) && (trace_ptr_val) && (context_info.is_compatibility_profile()))
                restore_ptr_val = remapper.remap_vertex_attrib_ptr(i, trace_ptr_val);

            void *pRestore_ptr = reinterpret_cast<void *>(restore_ptr_val);

            if ((handle) && (desc.m_array_binding == 0))
            {
                // If it's a non-default VAO, and there's no array binding, we can't call glVertexAttribPointer() because it's not allowed by AMD drivers (it thinks we're trying to set client side array data)
                // "OpenGL: glVertexAttribPointer failed because it is not allowed to specify a client-side vertex or element array when a non-default vertex array object is bound (GL_INVALID_OPERATION) [source=API type=ERROR severity=HIGH id=2100]"

                // Sanity checks.
                if ((pRestore_ptr != NULL) || (desc.m_stride) || (desc.m_enabled))
                {
                    vogl_warning_printf("Can't bind client side vertex array data on a non-default VAO, trace handle %u GL handle %u, restore ptr %p, size %i stride %i enabled %u\n",
                                        m_snapshot_handle, static_cast<uint32_t>(handle), pRestore_ptr, desc.m_size, desc.m_stride, desc.m_enabled);
                }
            }
            else
            {
                if (desc.m_integer)
                {
                    GL_ENTRYPOINT(glVertexAttribIPointer)(i, desc.m_size, desc.m_type, desc.m_stride, pRestore_ptr);
                    VOGL_CHECK_GL_ERROR;
                }
                else
                {
                    GL_ENTRYPOINT(glVertexAttribPointer)(i, desc.m_size, desc.m_type, desc.m_normalized, desc.m_stride, pRestore_ptr);
                    VOGL_CHECK_GL_ERROR;
                }
            }

            GL_ENTRYPOINT(glVertexAttribDivisor)(i, desc.m_divisor);
            VOGL_CHECK_GL_ERROR;

            if (desc.m_enabled)
            {
                GL_ENTRYPOINT(glEnableVertexAttribArray)(i);
                VOGL_CHECK_GL_ERROR;
            }
            else
            {
                GL_ENTRYPOINT(glDisableVertexAttribArray)(i);
                VOGL_CHECK_GL_ERROR;
            }
        }
    }

    return true;
}
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;
}
bool vogl_renderbuffer_state::snapshot(const vogl_context_info &context_info, vogl_handle_remapper &remapper, GLuint64 handle, GLenum target)
{
    VOGL_FUNC_TRACER

    VOGL_NOTE_UNUSED(remapper);
    VOGL_ASSERT(context_info.get_version() >= VOGL_GL_VERSION_3_0);
    VOGL_CHECK_GL_ERROR;
    VOGL_NOTE_UNUSED(target);

    clear();

    VOGL_ASSERT(handle <= cUINT32_MAX);

    m_snapshot_handle = static_cast<GLuint>(handle);

    vogl_scoped_binding_state orig_renderbuffer(GL_RENDERBUFFER);

    GL_ENTRYPOINT(glBindRenderbuffer)(GL_RENDERBUFFER, m_snapshot_handle);
    VOGL_CHECK_GL_ERROR;

    if (!m_desc.snapshot(context_info))
        return false;

    if ((!m_desc.m_width) || (!m_desc.m_height) || (!m_desc.m_internal_format))
    {
        // Renderbuffer was only genned - no need to spit out warning
        //vogl_warning_printf("%s: Unable to retrieve description renderbuffer %" PRIu64 "\n", VOGL_METHOD_NAME, static_cast<uint64_t>(handle));
    }
    else
    {
        vogl_scoped_state_saver framebuffer_state_saver(cGSTReadBuffer, cGSTDrawBuffer);
        vogl_scoped_binding_state orig_framebuffers(GL_DRAW_FRAMEBUFFER, GL_READ_FRAMEBUFFER, GL_TEXTURE_2D, GL_TEXTURE_2D_MULTISAMPLE);

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

        bool capture_status = false;

        GLenum internal_fmt = m_desc.m_internal_format;
        const vogl_internal_tex_format *pInternal_tex_fmt = vogl_find_internal_texture_format(internal_fmt);
        if ((pInternal_tex_fmt) && (pInternal_tex_fmt->m_optimum_get_image_fmt != GL_NONE) && (pInternal_tex_fmt->m_optimum_get_image_type != GL_NONE))
        {
            // Create texture
            GLuint tex_handle = 0;
            GL_ENTRYPOINT(glGenTextures)(1, &tex_handle);
            VOGL_CHECK_GL_ERROR;

            GL_ENTRYPOINT(glBindTexture)(tex_target, tex_handle);
            VOGL_CHECK_GL_ERROR;

            if (m_desc.m_samples > 1)
            {
                GL_ENTRYPOINT(glTexImage2DMultisample)(tex_target,
                    m_desc.m_samples,
                    internal_fmt,
                    m_desc.m_width,
                    m_desc.m_height,
                    GL_TRUE);
            }
            else
            {
                GL_ENTRYPOINT(glTexImage2D)(tex_target,
                    0,
                    internal_fmt,
                    m_desc.m_width,
                    m_desc.m_height,
                    0,
                    pInternal_tex_fmt->m_optimum_get_image_fmt,
                    pInternal_tex_fmt->m_optimum_get_image_type,
                    NULL);
            }

            if (!vogl_check_gl_error_internal())
            {
                GL_ENTRYPOINT(glTexParameteri)(tex_target, GL_TEXTURE_MAX_LEVEL, 0);
                VOGL_CHECK_GL_ERROR;

                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;
                }

                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(glFramebufferRenderbuffer)(GL_READ_FRAMEBUFFER, attachment, GL_RENDERBUFFER, m_snapshot_handle);
                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(glFramebufferTexture2D)(GL_DRAW_FRAMEBUFFER, attachment, tex_target, tex_handle, 0);
                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))
                {
                    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())
                    {
                        vogl_handle_remapper def_handle_remapper;
                        if (m_texture.snapshot(context_info, def_handle_remapper, tex_handle, tex_target))
                            capture_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(glBindTexture)(tex_target, 0);
            VOGL_CHECK_GL_ERROR;

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

        if (!capture_status)
        {
            vogl_error_printf("%s: Failed blitting renderbuffer data to texture for renderbuffer %" PRIu64 "\n", VOGL_METHOD_NAME, static_cast<uint64_t>(handle));
        }
    }

    m_is_valid = true;

    return true;
}
Beispiel #14
0
bool vogl_sampler_state::snapshot(const vogl_context_info &context_info, vogl_handle_remapper &remapper, GLuint64 handle, GLenum target)
{
    VOGL_FUNC_TRACER

    VOGL_NOTE_UNUSED(remapper);
    VOGL_CHECK_GL_ERROR;
    (void)target;

    clear();

    VOGL_ASSERT(handle <= cUINT32_MAX);

    m_snapshot_handle = static_cast<uint32>(handle);

    bool any_gl_errors = false;

#define GET_INT(pname)                                                            \
    do                                                                            \
    {                                                                             \
        int values[4] = { 0, 0, 0, 0 };                                           \
        GL_ENTRYPOINT(glGetSamplerParameteriv)(m_snapshot_handle, pname, values); \
        if (vogl_check_gl_error())                                                 \
            any_gl_errors = true;                                                 \
        m_params.insert(pname, 0, values, sizeof(values[0]));                     \
    } while (0)
#define GET_FLOAT(pname)                                                          \
    do                                                                            \
    {                                                                             \
        float values[4] = { 0, 0, 0, 0 };                                         \
        GL_ENTRYPOINT(glGetSamplerParameterfv)(m_snapshot_handle, pname, values); \
        if (vogl_check_gl_error())                                                 \
            any_gl_errors = true;                                                 \
        m_params.insert(pname, 0, values, sizeof(values[0]));                     \
    } while (0)

    GET_INT(GL_TEXTURE_MAG_FILTER);
    GET_INT(GL_TEXTURE_MIN_FILTER);
    GET_FLOAT(GL_TEXTURE_MIN_LOD);
    GET_FLOAT(GL_TEXTURE_MAX_LOD);
    GET_INT(GL_TEXTURE_WRAP_S);
    GET_INT(GL_TEXTURE_WRAP_T);
    GET_INT(GL_TEXTURE_WRAP_R);
    GET_FLOAT(GL_TEXTURE_BORDER_COLOR);
    GET_INT(GL_TEXTURE_COMPARE_MODE);
    GET_INT(GL_TEXTURE_COMPARE_FUNC);

    if (context_info.supports_extension("GL_EXT_texture_filter_anisotropic"))
    {
        GET_FLOAT(GL_TEXTURE_MAX_ANISOTROPY_EXT);
    }

    if (context_info.supports_extension("GL_EXT_texture_sRGB_decode"))
    {
        GET_INT(GL_TEXTURE_SRGB_DECODE_EXT);
    }

#undef GET_INT
#undef GET_FLOAT

    if (any_gl_errors)
    {
        clear();

        vogl_error_printf("%s: GL error while enumerating sampler %" PRIu64 "'s' params\n", VOGL_METHOD_NAME, (uint64_t)handle);
        return false;
    }

    m_is_valid = true;

    return true;
}
vogleditor_stateTreeTextureItem::vogleditor_stateTreeTextureItem(QString name, QString value, vogleditor_stateTreeItem* parentNode, vogl_texture_state* pState, const vogl_context_info& info)
   : vogleditor_stateTreeItem(name, value, parentNode),
     m_pTexture(pState),
     m_pDiffBaseState(NULL)
{
   QString tmp;

   float fVals[16];
   int iVals[16];

#define STR_INT1(val) tmp.sprintf("%d", val[0])


#define GET_INT(name, num) if (m_pTexture->get_params().get<int>(name, 0, iVals, num)) { vogleditor_stateTreeStateVecIntItem* pItem = new vogleditor_stateTreeStateVecIntItem(#name, name, 0, m_pTexture->get_params(), iVals, num, false, this); m_diffableItems.push_back(pItem); this->appendChild(pItem); }
#define GET_ENUM(name, num) if (m_pTexture->get_params().get<int>(name, 0, iVals, num)) { vogleditor_stateTreeStateVecEnumItem* pItem = new vogleditor_stateTreeStateVecEnumItem(#name, name, 0, m_pTexture->get_params(), iVals, num, false, this); m_diffableItems.push_back(pItem); this->appendChild(pItem); }
#define GET_FLOAT(name, num) if (m_pTexture->get_params().get<float>(name, 0, fVals, num)) { vogleditor_stateTreeStateVecFloatItem* pItem = new vogleditor_stateTreeStateVecFloatItem(#name, name, 0, m_pTexture->get_params(), fVals, num, false, this); m_diffableItems.push_back(pItem); this->appendChild(pItem); }
                  GET_INT(GL_TEXTURE_BASE_LEVEL, 1);
                  int base_level = iVals[0];
                  GET_INT(GL_TEXTURE_MAX_LEVEL, 1);
                  GET_FLOAT(GL_TEXTURE_BORDER_COLOR, 4);
                  GET_ENUM(GL_TEXTURE_COMPARE_MODE, 1);
                  GET_ENUM(GL_TEXTURE_COMPARE_FUNC, 1);
                  GET_FLOAT(GL_TEXTURE_LOD_BIAS, 1);
                  GET_ENUM(GL_TEXTURE_MIN_FILTER, 1);
                  GET_ENUM(GL_TEXTURE_MAG_FILTER, 1);
                  GET_FLOAT(GL_TEXTURE_MIN_LOD, 1);
                  GET_FLOAT(GL_TEXTURE_MAX_LOD, 1);
                  GET_ENUM(GL_TEXTURE_SWIZZLE_R, 1);
                  GET_ENUM(GL_TEXTURE_SWIZZLE_G, 1);
                  GET_ENUM(GL_TEXTURE_SWIZZLE_B, 1);
                  GET_ENUM(GL_TEXTURE_SWIZZLE_A, 1);
                  GET_ENUM(GL_TEXTURE_SWIZZLE_RGBA, 4);
                  GET_ENUM(GL_TEXTURE_WRAP_S, 1);
                  GET_ENUM(GL_TEXTURE_WRAP_T, 1);
                  GET_ENUM(GL_TEXTURE_WRAP_R, 1);

                  if (!info.is_core_profile())
                  {
                     GET_ENUM(GL_GENERATE_MIPMAP, 1);
                  }

                  GET_INT(GL_TEXTURE_IMMUTABLE_FORMAT, 1);

                  if (info.supports_extension("GL_EXT_texture_filter_anisotropic"))
                  {
                     GET_FLOAT(GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
                  }

                  if (info.supports_extension("GL_EXT_texture_sRGB_decode"))
                  {
                     GET_ENUM(GL_TEXTURE_SRGB_DECODE_EXT, 1);
                  }

                  if (!info.is_core_profile() && info.supports_extension("GL_ARB_shadow_ambient"))
                  {
                     GET_FLOAT(GL_TEXTURE_COMPARE_FAIL_VALUE_ARB, 1);
                  }

                  if (!info.is_core_profile())
                  {
                     GET_ENUM(GL_DEPTH_TEXTURE_MODE, 1);
                     // TODO
                     //GL_TEXTURE_PRIORITY
                     //GL_TEXTURE_RESIDENT
                  }

                  int num_actual_levels = m_pTexture->get_num_levels();
                  uint num_faces = (m_pTexture->get_target() == GL_TEXTURE_CUBE_MAP) ? 6 : 1;

                  for (uint face = 0; face < num_faces; face++)
                  {
                     GLenum face_target_to_query = m_pTexture->get_target();
                     if (m_pTexture->get_target() == GL_TEXTURE_CUBE_MAP)
                        face_target_to_query = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face;

                     vogleditor_stateTreeItem* pFaceNode = this;

                     if (m_pTexture->get_target() == GL_TEXTURE_CUBE_MAP)
                     {
                        pFaceNode = new vogleditor_stateTreeItem(enum_to_string(face_target_to_query), "", this);
                        this->appendChild(pFaceNode);
                     }

                     for (int level = base_level; level < num_actual_levels; level++)
                     {
                        vogleditor_stateTreeItem* pLevelNode = new vogleditor_stateTreeItem(tmp.sprintf("Mip level %d", level), "", pFaceNode);
                        pFaceNode->appendChild(pLevelNode);

                        const vogl_state_vector& level_params = m_pTexture->get_level_params(face, level);

                        // TODO: Check for core vs. compat profiles and not query the old stuff
#undef GET_INT
#undef GET_ENUM
#define GET_INT(name, num) if (level_params.get<int>(name, 0, iVals, num)) { pLevelNode->appendChild(new vogleditor_stateTreeStateVecIntItem(#name, name, 0, level_params, iVals, num, false, pLevelNode)); }
#define GET_ENUM(name, num) if (level_params.get<int>(name, 0, iVals, num)) { pLevelNode->appendChild(new vogleditor_stateTreeStateVecEnumItem(#name, name, 0, level_params, iVals, num, false, pLevelNode)); }
                        GET_INT(GL_TEXTURE_WIDTH, 1);
                        GET_INT(GL_TEXTURE_HEIGHT, 1);
                        GET_INT(GL_TEXTURE_DEPTH, 1);
                        GET_ENUM(GL_TEXTURE_INTERNAL_FORMAT, 1);

                        GET_INT(GL_TEXTURE_SAMPLES, 1);
                        GET_ENUM(GL_TEXTURE_FIXED_SAMPLE_LOCATIONS, 1);

                        GET_INT(GL_TEXTURE_RED_SIZE, 1);
                        GET_INT(GL_TEXTURE_GREEN_SIZE, 1);
                        GET_INT(GL_TEXTURE_BLUE_SIZE, 1);
                        GET_INT(GL_TEXTURE_ALPHA_SIZE, 1);
                        GET_INT(GL_TEXTURE_DEPTH_SIZE, 1);
                        GET_INT(GL_TEXTURE_STENCIL_SIZE, 1);
                        GET_INT(GL_TEXTURE_LUMINANCE_SIZE, 1);
                        GET_INT(GL_TEXTURE_INTENSITY_SIZE, 1);
                        GET_INT(GL_TEXTURE_SHARED_SIZE, 1);
                        GET_INT(GL_TEXTURE_COMPRESSED, 1);
                        bool is_compressed = (bool)iVals[0];

                        if (info.supports_extension("GL_ARB_depth_texture"))
                        {
                           GET_INT(GL_TEXTURE_DEPTH_SIZE, 1);
                           GET_INT(GL_TEXTURE_DEPTH_TYPE, 1);
                        }

                        if (info.supports_extension("GL_EXT_packed_depth_stencil"))
                           GET_INT(GL_TEXTURE_STENCIL_SIZE_EXT, 1);

                        if (m_pTexture->get_target() == GL_TEXTURE_BUFFER)
                        {
                           GET_INT(GL_TEXTURE_BUFFER_DATA_STORE_BINDING, 1);
                           GET_INT(GL_TEXTURE_BUFFER_OFFSET, 1);
                           GET_INT(GL_TEXTURE_BUFFER_SIZE, 1);
                        }

                        if (is_compressed)
                        {
                           GET_INT(GL_TEXTURE_COMPRESSED_IMAGE_SIZE, 1);
                        }
                     }
                  }
#undef GET_FLOAT
#undef GET_ENUM
#undef GET_INT

}
bool vogl_default_framebuffer_state::snapshot(const vogl_context_info &context_info, const vogl_default_framebuffer_attribs &fb_attribs)
{
    VOGL_NOTE_UNUSED(context_info);

    clear();

    m_fb_attribs = fb_attribs;

    // Create compatible GL texture
    // Attach this texture to an FBO
    // Blit default framebuffer to this FBO
    // Capture this texture's state

    vogl_scoped_state_saver framebuffer_state_saver(cGSTReadBuffer, cGSTDrawBuffer);

    vogl_scoped_binding_state orig_framebuffers(GL_DRAW_FRAMEBUFFER, GL_READ_FRAMEBUFFER, GL_TEXTURE_2D, GL_TEXTURE_2D_MULTISAMPLE);

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

    vogl_scoped_binding_state orig_bindings(GL_PIXEL_PACK_BUFFER, GL_PIXEL_UNPACK_BUFFER);

    GL_ENTRYPOINT(glBindBuffer)(GL_PIXEL_PACK_BUFFER, 0);
    VOGL_CHECK_GL_ERROR;

    GL_ENTRYPOINT(glBindBuffer)(GL_PIXEL_UNPACK_BUFFER, 0);
    VOGL_CHECK_GL_ERROR;

    vogl_scoped_state_saver pixelstore_state_saver(cGSTPixelStore);

    vogl_scoped_state_saver pixeltransfer_state_saver;
    if (!context_info.is_core_profile())
        pixeltransfer_state_saver.save(cGSTPixelTransfer);

    vogl_reset_pixel_store_states();
    if (!context_info.is_core_profile())
        vogl_reset_pixel_transfer_states();

    // TODO: Test multisampled default framebuffers
    const GLenum tex_target = (fb_attribs.m_samples > 1) ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D;

    for (uint i = 0; i < cDefFramebufferTotal; i++)
    {
        GLenum internal_fmt, pixel_fmt, pixel_type;

        // TODO: This uses fixed pixel formats, and assumes there's always a depth/stencil buffer.
        if (i == cDefFramebufferDepthStencil)
        {
            if ((fb_attribs.m_depth_size + fb_attribs.m_stencil_size) == 0)
                continue;

            GL_ENTRYPOINT(glReadBuffer)(fb_attribs.m_double_buffered ? GL_BACK_LEFT : GL_FRONT_LEFT);

            internal_fmt = GL_DEPTH_STENCIL;
            pixel_fmt = GL_DEPTH_STENCIL;
            pixel_type = GL_UNSIGNED_INT_24_8;
        }
        else
        {
            if ((fb_attribs.m_r_size + fb_attribs.m_g_size + fb_attribs.m_b_size + fb_attribs.m_a_size) == 0)
                continue;

            GL_ENTRYPOINT(glReadBuffer)(g_def_framebuffer_enums[i]);

            internal_fmt = GL_RGBA;
            pixel_fmt = GL_RGBA;
            pixel_type = GL_UNSIGNED_INT_8_8_8_8_REV;
        }

        if (vogl_check_gl_error_internal(true))
            continue;

        // Create texture
        GLuint tex_handle = 0;
        GL_ENTRYPOINT(glGenTextures)(1, &tex_handle);
        VOGL_CHECK_GL_ERROR;

        GL_ENTRYPOINT(glBindTexture)(tex_target, tex_handle);
        VOGL_CHECK_GL_ERROR;

        if (fb_attribs.m_samples > 1)
        {
            GL_ENTRYPOINT(glTexImage2DMultisample)(tex_target,
                fb_attribs.m_samples,
                internal_fmt,
                fb_attribs.m_width,
                fb_attribs.m_height,
                GL_TRUE);
        }
        else
        {
            GL_ENTRYPOINT(glTexImage2D)(tex_target,
                0,
                internal_fmt,
                fb_attribs.m_width,
                fb_attribs.m_height,
                0,
                pixel_fmt,
                pixel_type,
                NULL);
        }

        if (vogl_check_gl_error_internal())
        {
            GL_ENTRYPOINT(glBindTexture)(tex_target, 0);
            VOGL_CHECK_GL_ERROR;

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

            continue;
        }

        GL_ENTRYPOINT(glTexParameteri)(tex_target, GL_TEXTURE_MAX_LEVEL, 0);
        VOGL_CHECK_GL_ERROR;

        // Create FBO
        GLuint fbo_handle = 0;
        GL_ENTRYPOINT(glGenFramebuffers)(1, &fbo_handle);
        VOGL_CHECK_GL_ERROR;

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

        GL_ENTRYPOINT(glFramebufferTexture2D)(GL_DRAW_FRAMEBUFFER, (i == cDefFramebufferDepthStencil) ? GL_DEPTH_STENCIL_ATTACHMENT : GL_COLOR_ATTACHMENT0, tex_target, tex_handle, 0);
        VOGL_CHECK_GL_ERROR;

        GLenum draw_buf = (i == cDefFramebufferDepthStencil) ? GL_NONE : GL_COLOR_ATTACHMENT0;
        GL_ENTRYPOINT(glDrawBuffers)(1, &draw_buf);
        VOGL_CHECK_GL_ERROR;

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

        bool status = true;

        if (cur_status == GL_FRAMEBUFFER_COMPLETE)
        {
            GL_ENTRYPOINT(glBlitFramebuffer)(
                0, 0, fb_attribs.m_width, fb_attribs.m_height,
                0, 0, fb_attribs.m_width, fb_attribs.m_height,
                (i == cDefFramebufferDepthStencil) ? (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT) : GL_COLOR_BUFFER_BIT,
                GL_NEAREST);

            if (vogl_check_gl_error_internal())
            {
                status = false;
            }
        }

        if (status)
        {
            vogl_handle_remapper def_handle_remapper;
            status = m_textures[i].snapshot(context_info, def_handle_remapper, tex_handle, tex_target);

            if (!status)
            {
                vogl_error_printf("%s: Failed snapshotting texture for default framebuffer %s\n", VOGL_METHOD_NAME, g_gl_enums.find_gl_name(g_def_framebuffer_enums[i]));
            }
        }
        else
        {
            vogl_warning_printf("%s: Failed blitting framebuffer %u\n", VOGL_METHOD_NAME, i);
        }

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

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

        GL_ENTRYPOINT(glDrawBuffer)(GL_FRONT_LEFT);
        VOGL_CHECK_GL_ERROR;

        GL_ENTRYPOINT(glBindTexture)(tex_target, 0);
        VOGL_CHECK_GL_ERROR;

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

    m_valid = true;

    return true;
}