Index: /trunk/src/VBox/GuestHost/OpenGL/include/cr_glstate.h
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/include/cr_glstate.h	(revision 44107)
+++ /trunk/src/VBox/GuestHost/OpenGL/include/cr_glstate.h	(revision 44108)
@@ -58,5 +58,6 @@
 # define CR_STATE_SHAREDOBJ_USAGE_INIT(_pObj) (crMemset((_pObj)->ctxUsage, 0, sizeof ((_pObj)->ctxUsage)))
 # define CR_STATE_SHAREDOBJ_USAGE_SET(_pObj, _pCtx) (ASMBitSet((_pObj)->ctxUsage, (_pCtx)->id))
-# define CR_STATE_SHAREDOBJ_USAGE_CLEAR(_pObj, _pCtx) (ASMBitClear((_pObj)->ctxUsage, (_pCtx)->id))
+# define CR_STATE_SHAREDOBJ_USAGE_CLEAR_IDX(_pObj, _i) (ASMBitClear((_pObj)->ctxUsage, (_i)))
+# define CR_STATE_SHAREDOBJ_USAGE_CLEAR(_pObj, _pCtx) (CR_STATE_SHAREDOBJ_USAGE_CLEAR_IDX((_pObj), (_pCtx)->id))
 # define CR_STATE_SHAREDOBJ_USAGE_IS_USED(_pObj) (ASMBitFirstSet((_pObj)->ctxUsage, sizeof ((_pObj)->ctxUsage)<<3) >= 0)
 # define CR_STATE_SHAREDOBJ_USAGE_GET_FIRST_USED_IDX(_pObj) (ASMBitFirstSet((_pObj)->ctxUsage, sizeof ((_pObj)->ctxUsage)<<3))
@@ -65,4 +66,5 @@
 # define CR_STATE_SHAREDOBJ_USAGE_INIT(_pObj) do {} while (0)
 # define CR_STATE_SHAREDOBJ_USAGE_SET(_pObj, _pCtx) do {} while (0)
+# define CR_STATE_SHAREDOBJ_USAGE_CLEAR_IDX(_pObj, _i) do {} while (0)
 # define CR_STATE_SHAREDOBJ_USAGE_CLEAR(_pObj, _pCtx) do {} while (0)
 # define CR_STATE_SHAREDOBJ_USAGE_IS_USED(_pObj) (GL_FALSE)
Index: /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_bufferobject.c
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_bufferobject.c	(revision 44107)
+++ /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_bufferobject.c	(revision 44108)
@@ -372,8 +372,16 @@
                 CR_STATE_SHAREDOBJ_USAGE_FOREACH_USED_IDX(obj, j)
                 {
+                    /* saved state version <= SHCROGL_SSM_VERSION_BEFORE_CTXUSAGE_BITS does not have usage bits info,
+                     * so on restore, we set mark bits as used.
+                     * This is why g_pAvailableContexts[j] could be NULL
+                     * also g_pAvailableContexts[0] will hold default context, which we should discard */
                     CRContext *ctx = g_pAvailableContexts[j];
-                    CRASSERT(ctx);
-                    ctStateBuffersRefsCleanup(ctx, obj, g->neg_bitid); /* <- yes, use g->neg_bitid, i.e. neg_bitid of the current context to ensure others bits get dirtified,
-                                                                        * but not the current context ones*/
+                    if (j && ctx)
+                    {
+                        ctStateBuffersRefsCleanup(ctx, obj, g->neg_bitid); /* <- yes, use g->neg_bitid, i.e. neg_bitid of the current context to ensure others bits get dirtified,
+                                                                            * but not the current context ones*/
+                    }
+                    else
+                        CR_STATE_SHAREDOBJ_USAGE_CLEAR_IDX(obj, j);
                 }
 
Index: /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_client.c
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_client.c	(revision 44107)
+++ /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_client.c	(revision 44108)
@@ -111,7 +111,7 @@
 }
 
-void crStateClientInit(CRContext *g)
-{
-    CRClientState *c = &(g->client);
+void crStateClientInit(CRContext *ctx)
+{
+    CRClientState *c = &(ctx->client);
     unsigned int i;
 
@@ -153,5 +153,5 @@
     c->array.v.enabled = 0;
 #ifdef CR_ARB_vertex_buffer_object
-    c->array.v.buffer = g ? g->bufferobject.arrayBuffer : NULL;
+    c->array.v.buffer = ctx->bufferobject.arrayBuffer;
     if (c->array.v.buffer)
         ++c->array.v.buffer->refCount;
@@ -170,5 +170,5 @@
     c->array.c.enabled = 0;
 #ifdef CR_ARB_vertex_buffer_object
-    c->array.c.buffer = g ? g->bufferobject.arrayBuffer : NULL;
+    c->array.c.buffer = ctx->bufferobject.arrayBuffer;
     if (c->array.c.buffer)
         ++c->array.c.buffer->refCount;
@@ -187,5 +187,5 @@
     c->array.f.enabled = 0;
 #ifdef CR_ARB_vertex_buffer_object
-    c->array.f.buffer = g ? g->bufferobject.arrayBuffer : NULL;
+    c->array.f.buffer = ctx->bufferobject.arrayBuffer;
     if (c->array.f.buffer)
         ++c->array.f.buffer->refCount;
@@ -204,5 +204,5 @@
     c->array.s.enabled = 0;
 #ifdef CR_ARB_vertex_buffer_object
-    c->array.s.buffer = g ? g->bufferobject.arrayBuffer : NULL;
+    c->array.s.buffer = ctx->bufferobject.arrayBuffer;
     if (c->array.s.buffer)
         ++c->array.s.buffer->refCount;
@@ -221,5 +221,5 @@
     c->array.e.enabled = 0;
 #ifdef CR_ARB_vertex_buffer_object
-    c->array.e.buffer = g ? g->bufferobject.arrayBuffer : NULL;
+    c->array.e.buffer = ctx->bufferobject.arrayBuffer;
     if (c->array.e.buffer)
         ++c->array.e.buffer->refCount;
@@ -238,5 +238,5 @@
     c->array.i.enabled = 0;
 #ifdef CR_ARB_vertex_buffer_object
-    c->array.i.buffer = g ? g->bufferobject.arrayBuffer : NULL;
+    c->array.i.buffer = ctx->bufferobject.arrayBuffer;
     if (c->array.i.buffer)
         ++c->array.i.buffer->refCount;
@@ -255,5 +255,5 @@
     c->array.n.enabled = 0;
 #ifdef CR_ARB_vertex_buffer_object
-    c->array.n.buffer = g ? g->bufferobject.arrayBuffer : NULL;
+    c->array.n.buffer = ctx->bufferobject.arrayBuffer;
     if (c->array.n.buffer)
         ++c->array.n.buffer->refCount;
@@ -274,5 +274,5 @@
         c->array.t[i].enabled = 0;
 #ifdef CR_ARB_vertex_buffer_object
-        c->array.t[i].buffer = g ? g->bufferobject.arrayBuffer : NULL;
+        c->array.t[i].buffer = ctx->bufferobject.arrayBuffer;
         if (c->array.t[i].buffer)
             ++c->array.t[i].buffer->refCount;
@@ -293,5 +293,5 @@
         c->array.a[i].stride = 0;
 #ifdef CR_ARB_vertex_buffer_object
-        c->array.a[i].buffer = g ? g->bufferobject.arrayBuffer : NULL;
+        c->array.a[i].buffer = ctx->bufferobject.arrayBuffer;
         if (c->array.a[i].buffer)
             ++c->array.a[i].buffer->refCount;
Index: /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_framebuffer.c
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_framebuffer.c	(revision 44107)
+++ /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_framebuffer.c	(revision 44108)
@@ -203,4 +203,22 @@
 }
 
+static void ctStateRenderbufferRefsCleanup(CRContext *g, GLuint fboId, CRRenderbufferObject *rbo)
+{
+    CRFramebufferObjectState *fbo = &g->framebufferobject;
+
+    if (fbo->renderbuffer==rbo)
+    {
+        fbo->renderbuffer = NULL;
+    }
+
+    /* check the attachments of current framebuffers */
+    crStateCheckFBOAttachments(fbo->readFB, fboId, GL_READ_FRAMEBUFFER);
+    crStateCheckFBOAttachments(fbo->drawFB, fboId, GL_DRAW_FRAMEBUFFER);
+
+#ifndef IN_GUEST
+    CR_STATE_SHAREDOBJ_USAGE_CLEAR(rbo, g);
+#endif
+}
+
 DECLEXPORT(void) STATE_APIENTRY
 crStateDeleteRenderbuffersEXT(GLsizei n, const GLuint *renderbuffers)
@@ -221,13 +239,30 @@
             if (rbo)
             {
-                if (fbo->renderbuffer==rbo)
+#ifndef IN_GUEST
+                int j;
+#endif
+                ctStateRenderbufferRefsCleanup(g, renderbuffers[i], rbo);
+#ifndef IN_GUEST
+                CR_STATE_SHAREDOBJ_USAGE_FOREACH_USED_IDX(rbo, j)
                 {
-                    fbo->renderbuffer = NULL;
+                    /* saved state version <= SHCROGL_SSM_VERSION_BEFORE_CTXUSAGE_BITS does not have usage bits info,
+                     * so on restore, we set mark bits as used.
+                     * This is why g_pAvailableContexts[j] could be NULL
+                     * also g_pAvailableContexts[0] will hold default context, which we should discard */
+                    CRContext *ctx = g_pAvailableContexts[j];
+                    if (j && ctx)
+                    {
+                        CRFramebufferObjectState *ctxFbo;
+                        CRASSERT(ctx);
+                        ctxFbo = &ctx->framebufferobject;
+                        if (ctxFbo->renderbuffer==rbo)
+                            crWarning("deleting RBO being used by another context %d", ctx->id);
+
+                        ctStateRenderbufferRefsCleanup(ctx, renderbuffers[i], rbo);
+                    }
+                    else
+                        CR_STATE_SHAREDOBJ_USAGE_CLEAR_IDX(rbo, j);
                 }
-
-                /* check the attachments of current framebuffers */
-                crStateCheckFBOAttachments(fbo->readFB, renderbuffers[i], GL_READ_FRAMEBUFFER);
-                crStateCheckFBOAttachments(fbo->drawFB, renderbuffers[i], GL_DRAW_FRAMEBUFFER);
-
+#endif
                 crHashtableDelete(g->shared->rbTable, renderbuffers[i], crStateFreeRBO);
             }
@@ -380,9 +415,23 @@
 }
 
+static void ctStateFramebufferRefsCleanup(CRContext *g, CRFramebufferObject *fb)
+{
+    CRFramebufferObjectState *fbo = &g->framebufferobject;
+    if (fbo->readFB==fb)
+    {
+        fbo->readFB = NULL;
+    }
+    if (fbo->drawFB==fb)
+    {
+        fbo->drawFB = NULL;
+    }
+
+    CR_STATE_SHAREDOBJ_USAGE_CLEAR(fb, g);
+}
+
 DECLEXPORT(void) STATE_APIENTRY
 crStateDeleteFramebuffersEXT(GLsizei n, const GLuint *framebuffers)
 {
     CRContext *g = GetCurrentContext();
-    CRFramebufferObjectState *fbo = &g->framebufferobject;
     int i;
 
@@ -398,12 +447,33 @@
             if (fb)
             {
-                if (fbo->readFB==fb)
+#ifndef IN_GUEST
+                int j;
+#endif
+                ctStateFramebufferRefsCleanup(g, fb);
+#ifndef IN_GUEST
+                CR_STATE_SHAREDOBJ_USAGE_FOREACH_USED_IDX(fb, j)
                 {
-                    fbo->readFB = NULL;
+                    /* saved state version <= SHCROGL_SSM_VERSION_BEFORE_CTXUSAGE_BITS does not have usage bits info,
+                     * so on restore, we set mark bits as used.
+                     * This is why g_pAvailableContexts[j] could be NULL
+                     * also g_pAvailableContexts[0] will hold default context, which we should discard */
+                    CRContext *ctx = g_pAvailableContexts[j];
+                    if (j && ctx)
+                    {
+                        CRFramebufferObjectState *ctxFbo;
+                        CRASSERT(ctx);
+                        ctxFbo = &ctx->framebufferobject;
+                        if (ctxFbo->readFB==fb)
+                            crWarning("deleting FBO being used as read buffer by another context %d", ctx->id);
+
+                        if (ctxFbo->drawFB==fb)
+                            crWarning("deleting FBO being used as draw buffer by another context %d", ctx->id);
+
+                        ctStateFramebufferRefsCleanup(ctx, fb);
+                    }
+                    else
+                        CR_STATE_SHAREDOBJ_USAGE_CLEAR_IDX(fb, j);
                 }
-                if (fbo->drawFB==fb)
-                {
-                    fbo->drawFB = NULL;
-                }
+#endif
                 crHashtableDelete(g->shared->fbTable, framebuffers[i], crStateFreeFBO);
             }
@@ -470,7 +540,6 @@
     CRFramebufferObjectState *fbo = &g->framebufferobject;
     CRFramebufferObject *apFBOs[2];
-    GLuint cPBOs = 0, i;
+    GLuint cFBOs = 0, i;
     GLuint maxtexsizelog2;
-
 
     CRSTATE_CHECKERR_RET(g->current.inBeginEnd, GL_INVALID_OPERATION, "called in begin/end", 0);
@@ -478,13 +547,16 @@
                          GL_INVALID_ENUM, "invalid target", 0);
 
-    cPBOs = crStateFramebufferGet(fbo, target, apFBOs);
-    CRSTATE_CHECKERR_RET(!cPBOs, GL_INVALID_ENUM, "unexpected target", 0);
-
-    Assert(cPBOs);
-    Assert(cPBOs <= 2);
-
-   for (i = 0; i < cPBOs; ++i)
-    {
-        CRSTATE_CHECKERR_RET(!apFBOs[i], GL_INVALID_OPERATION, "no fbo bound", 0);
+    cFBOs = crStateFramebufferGet(fbo, target, apFBOs);
+    CRSTATE_CHECKERR_RET(!cFBOs, GL_INVALID_ENUM, "unexpected target", 0);
+    for (i = 0; i < cFBOs; ++i)
+    {
+        CRSTATE_CHECKERR_RET(!apFBOs[i], GL_INVALID_OPERATION, "zero fbo bound", 0);
+    }
+
+    Assert(cFBOs);
+    Assert(cFBOs <= 2);
+
+    for (i = 0; i < cFBOs; ++i)
+    {
         CRSTATE_CHECKERR_RET(!crStateGetFBOAttachmentPoint(apFBOs[i], attachment, &aap[i]), GL_INVALID_ENUM, "invalid attachment", 0);
     }
@@ -492,5 +564,5 @@
     if (!texture)
     {
-        return cPBOs;
+        return cFBOs;
     }
 
@@ -534,5 +606,5 @@
 
 #ifdef IN_GUEST
-    for (i = 0; i < cPBOs; ++i)
+    for (i = 0; i < cFBOs; ++i)
     {
         if ((aap[i])->type!=GL_TEXTURE || (aap[i])->name!=texture || (aap[i])->level!=level)
@@ -543,8 +615,8 @@
 #endif
 
-    Assert(cPBOs);
-    Assert(cPBOs <= 2);
-
-    return cPBOs;
+    Assert(cFBOs);
+    Assert(cFBOs <= 2);
+
+    return cFBOs;
 }
 
@@ -668,6 +740,7 @@
     CRContext *g = GetCurrentContext();
     CRFramebufferObjectState *fbo = &g->framebufferobject;
-    CRFramebufferObject *pFBO;
-    CRFBOAttachmentPoint *ap;
+    CRFramebufferObject *apFBOs[2];
+    GLuint cFBOs, i;
+    CRFBOAttachmentPoint *aap[2];
     CRRenderbufferObject *rb;
 
@@ -675,17 +748,28 @@
     CRSTATE_CHECKERR(((target!=GL_FRAMEBUFFER_EXT) && (target!=GL_READ_FRAMEBUFFER) && (target!=GL_DRAW_FRAMEBUFFER)),
                          GL_INVALID_ENUM, "invalid target");
-    pFBO = GL_READ_FRAMEBUFFER==target ? fbo->readFB : fbo->drawFB;
-    CRSTATE_CHECKERR(!pFBO, GL_INVALID_OPERATION, "no fbo bound");
-    CRSTATE_CHECKERR(!crStateGetFBOAttachmentPoint(pFBO, attachment, &ap), GL_INVALID_ENUM, "invalid attachment");
+    cFBOs = crStateFramebufferGet(fbo, target, apFBOs);
+    CRSTATE_CHECKERR(!cFBOs, GL_INVALID_OPERATION, "no fbo bound");
+    for (i = 0; i < cFBOs; ++i)
+    {
+        CRSTATE_CHECKERR(!apFBOs[i], GL_INVALID_OPERATION, "zero fbo bound");
+    }
+
+    for (i = 0; i < cFBOs; ++i)
+    {
+        CRSTATE_CHECKERR(!crStateGetFBOAttachmentPoint(apFBOs[i], attachment, &aap[i]), GL_INVALID_ENUM, "invalid attachment");
+    }
 
     if (!renderbuffer)
     {
+        for (i = 0; i < cFBOs; ++i)
+        {
 #ifdef IN_GUEST
-        if (ap->type!=GL_NONE)
-        {
-            pFBO->status = GL_FRAMEBUFFER_UNDEFINED;
-        }
-#endif
-        crStateInitFBOAttachmentPoint(ap);
+            if (&aap[i]->type!=GL_NONE)
+            {
+                apFBOs[i]->status = GL_FRAMEBUFFER_UNDEFINED;
+            }
+#endif
+            crStateInitFBOAttachmentPoint(aap[i]);
+        }
         return;
     }
@@ -698,13 +782,20 @@
     }
 
+#ifndef IN_GUEST
+    CR_STATE_SHAREDOBJ_USAGE_SET(rb, g);
+#endif
+
+    for (i = 0; i < cFBOs; ++i)
+    {
 #ifdef IN_GUEST
-        if (ap->type!=GL_RENDERBUFFER_EXT || ap->name!=renderbuffer)
-        {
-            pFBO->status = GL_FRAMEBUFFER_UNDEFINED;
-        }
-#endif
-    crStateInitFBOAttachmentPoint(ap);
-    ap->type = GL_RENDERBUFFER_EXT;
-    ap->name = renderbuffer;
+        if (aap[i]->type!=GL_RENDERBUFFER_EXT || aap[i]->name!=renderbuffer)
+        {
+            apFBOs[i]->status = GL_FRAMEBUFFER_UNDEFINED;
+        }
+#endif
+        crStateInitFBOAttachmentPoint(aap[i]);
+        aap[i]->type = GL_RENDERBUFFER_EXT;
+        aap[i]->name = renderbuffer;
+    }
 }
 
@@ -725,6 +816,15 @@
 
     CRSTATE_CHECKERR(!cFBOs, GL_INVALID_OPERATION, "no fbo bound");
-
     for (i = 0; i < cFBOs; ++i)
+    {
+        CRSTATE_CHECKERR(!apFBOs[i], GL_INVALID_OPERATION, "zero fbo bound");
+    }
+
+    if(cFBOs != 1)
+    {
+        crWarning("different FBPs attached to draw and read buffers, returning info for the read buffer");
+    }
+
+    for (i = 0; i < 1; ++i)
     {
         CRSTATE_CHECKERR(!crStateGetFBOAttachmentPoint(apFBOs[i], attachment, &ap), GL_INVALID_ENUM, "invalid attachment");
Index: /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_texture.c
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_texture.c	(revision 44107)
+++ /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_texture.c	(revision 44108)
@@ -776,6 +776,13 @@
             CR_STATE_SHAREDOBJ_USAGE_FOREACH_USED_IDX(tObj, j)
             {
+                /* saved state version <= SHCROGL_SSM_VERSION_BEFORE_CTXUSAGE_BITS does not have usage bits info,
+                 * so on restore, we set mark bits as used.
+                 * This is why g_pAvailableContexts[j] could be NULL
+                 * also g_pAvailableContexts[0] will hold default context, which we should discard */
                 CRContext *ctx = g_pAvailableContexts[j];
-                crStateCleanupTextureRefs(ctx, tObj);
+                if (j && ctx)
+                    crStateCleanupTextureRefs(ctx, tObj);
+                else
+                    CR_STATE_SHAREDOBJ_USAGE_CLEAR_IDX(tObj, j);
             }
 
