int vmsvga3dLoadExec(PVGASTATE pThis, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
{
    RT_NOREF(uPass);
    PVMSVGA3DSTATE pState = pThis->svga.p3dState;
    AssertReturn(pState, VERR_NO_MEMORY);
    int            rc;
    uint32_t       cContexts, cSurfaces;
    LogFlow(("vmsvga3dLoadExec:\n"));

#ifndef RT_OS_DARWIN /** @todo r=bird: this is normally done on the EMT, so for DARWIN we do that when loading saved state too now. See DevVGA-SVGA.cpp */
    /* Must initialize now as the recreation calls below rely on an initialized 3d subsystem. */
    vmsvga3dPowerOn(pThis);
#endif

    /* Get the generic 3d state first. */
    rc = SSMR3GetStructEx(pSSM, pState, sizeof(*pState), 0, g_aVMSVGA3DSTATEFields, NULL);
    AssertRCReturn(rc, rc);

    cContexts                           = pState->cContexts;
    cSurfaces                           = pState->cSurfaces;
    pState->cContexts                   = 0;
    pState->cSurfaces                   = 0;

    /* Fetch all active contexts. */
    for (uint32_t i = 0; i < cContexts; i++)
    {
        PVMSVGA3DCONTEXT pContext;
        uint32_t         cid;

        /* Get the context id */
        rc = SSMR3GetU32(pSSM, &cid);
        AssertRCReturn(rc, rc);

        if (cid != SVGA3D_INVALID_ID)
        {
            uint32_t cPixelShaderConst, cVertexShaderConst, cPixelShaders, cVertexShaders;
            LogFlow(("vmsvga3dLoadExec: Loading cid=%#x\n", cid));

#ifdef VMSVGA3D_OPENGL
            if (cid == VMSVGA3D_SHARED_CTX_ID)
            {
                i--; /* Not included in cContexts. */
                pContext = &pState->SharedCtx;
                if (pContext->id != VMSVGA3D_SHARED_CTX_ID)
                {
                    rc = vmsvga3dContextDefineOgl(pThis, VMSVGA3D_SHARED_CTX_ID, VMSVGA3D_DEF_CTX_F_SHARED_CTX);
                    AssertRCReturn(rc, rc);
                }
            }
            else
#endif
            {
                rc = vmsvga3dContextDefine(pThis, cid);
                AssertRCReturn(rc, rc);

                pContext = pState->papContexts[i];
            }
            AssertReturn(pContext->id == cid, VERR_INTERNAL_ERROR);

            rc = SSMR3GetStructEx(pSSM, pContext, sizeof(*pContext), 0, g_aVMSVGA3DCONTEXTFields, NULL);
            AssertRCReturn(rc, rc);

            cPixelShaders                       = pContext->cPixelShaders;
            cVertexShaders                      = pContext->cVertexShaders;
            cPixelShaderConst                   = pContext->state.cPixelShaderConst;
            cVertexShaderConst                  = pContext->state.cVertexShaderConst;
            pContext->cPixelShaders             = 0;
            pContext->cVertexShaders            = 0;
            pContext->state.cPixelShaderConst   = 0;
            pContext->state.cVertexShaderConst  = 0;

            /* Fetch all pixel shaders. */
            for (uint32_t j = 0; j < cPixelShaders; j++)
            {
                VMSVGA3DSHADER  shader;
                uint32_t        shid;

                /* Fetch the id first. */
                rc = SSMR3GetU32(pSSM, &shid);
                AssertRCReturn(rc, rc);

                if (shid != SVGA3D_INVALID_ID)
                {
                    uint32_t *pData;

                    /* Fetch a copy of the shader struct. */
                    rc = SSMR3GetStructEx(pSSM, &shader, sizeof(shader), 0, g_aVMSVGA3DSHADERFields, NULL);
                    AssertRCReturn(rc, rc);

                    pData = (uint32_t *)RTMemAlloc(shader.cbData);
                    AssertReturn(pData, VERR_NO_MEMORY);

                    rc = SSMR3GetMem(pSSM, pData, shader.cbData);
                    AssertRCReturn(rc, rc);

                    rc = vmsvga3dShaderDefine(pThis, cid, shid, shader.type, shader.cbData, pData);
                    AssertRCReturn(rc, rc);

                    RTMemFree(pData);
                }
            }

            /* Fetch all vertex shaders. */
            for (uint32_t j = 0; j < cVertexShaders; j++)
            {
                VMSVGA3DSHADER  shader;
                uint32_t        shid;

                /* Fetch the id first. */
                rc = SSMR3GetU32(pSSM, &shid);
                AssertRCReturn(rc, rc);

                if (shid != SVGA3D_INVALID_ID)
                {
                    uint32_t *pData;

                    /* Fetch a copy of the shader struct. */
                    rc = SSMR3GetStructEx(pSSM, &shader, sizeof(shader), 0, g_aVMSVGA3DSHADERFields, NULL);
                    AssertRCReturn(rc, rc);

                    pData = (uint32_t *)RTMemAlloc(shader.cbData);
                    AssertReturn(pData, VERR_NO_MEMORY);

                    rc = SSMR3GetMem(pSSM, pData, shader.cbData);
                    AssertRCReturn(rc, rc);

                    rc = vmsvga3dShaderDefine(pThis, cid, shid, shader.type, shader.cbData, pData);
                    AssertRCReturn(rc, rc);

                    RTMemFree(pData);
                }
            }

            /* Fetch pixel shader constants. */
            for (uint32_t j = 0; j < cPixelShaderConst; j++)
            {
                VMSVGASHADERCONST ShaderConst;

                rc = SSMR3GetStructEx(pSSM, &ShaderConst, sizeof(ShaderConst), 0, g_aVMSVGASHADERCONSTFields, NULL);
                AssertRCReturn(rc, rc);

                if (ShaderConst.fValid)
                {
                    rc = vmsvga3dShaderSetConst(pThis, cid, j, SVGA3D_SHADERTYPE_PS, ShaderConst.ctype, 1, ShaderConst.value);
                    AssertRCReturn(rc, rc);
                }
            }

            /* Fetch vertex shader constants. */
            for (uint32_t j = 0; j < cVertexShaderConst; j++)
            {
                VMSVGASHADERCONST ShaderConst;

                rc = SSMR3GetStructEx(pSSM, &ShaderConst, sizeof(ShaderConst), 0, g_aVMSVGASHADERCONSTFields, NULL);
                AssertRCReturn(rc, rc);

                if (ShaderConst.fValid)
                {
                    rc = vmsvga3dShaderSetConst(pThis, cid, j, SVGA3D_SHADERTYPE_VS, ShaderConst.ctype, 1, ShaderConst.value);
                    AssertRCReturn(rc, rc);
                }
            }

            if (uVersion >= VGA_SAVEDSTATE_VERSION_VMSVGA_TEX_STAGES)
            {
                /* Load texture stage and samplers state. */

                /* Number of stages/samplers. */
                uint32_t cStages;
                rc = SSMR3GetU32(pSSM, &cStages);
                AssertRCReturn(rc, rc);

                /* Number of states. */
                uint32_t cTextureStates;
                rc = SSMR3GetU32(pSSM, &cTextureStates);
                AssertRCReturn(rc, rc);

                for (uint32_t iStage = 0; iStage < cStages; ++iStage)
                {
                    for (uint32_t j = 0; j < cTextureStates; ++j)
                    {
                        SVGA3dTextureState textureState;
                        SSMR3GetU32(pSSM, &textureState.stage);
                        uint32_t u32Name;
                        SSMR3GetU32(pSSM, &u32Name);
                        textureState.name = (SVGA3dTextureStateName)u32Name;
                        rc = SSMR3GetU32(pSSM, &textureState.value);
                        AssertRCReturn(rc, rc);

                        if (   iStage < RT_ELEMENTS(pContext->state.aTextureStates)
                            && j < RT_ELEMENTS(pContext->state.aTextureStates[0]))
                        {
                            pContext->state.aTextureStates[iStage][j] = textureState;
                        }
                    }
                }
            }

            if (uVersion >= VGA_SAVEDSTATE_VERSION_VMSVGA)
            {
                VMSVGA3DQUERY query;
                RT_ZERO(query);

                rc = SSMR3GetStructEx(pSSM, &query, sizeof(query), 0, g_aVMSVGA3DQUERYFields, NULL);
                AssertRCReturn(rc, rc);

                switch (query.enmQueryState)
                {
                    case VMSVGA3DQUERYSTATE_BUILDING:
                        /* Start collecting data. */
                        vmsvga3dQueryBegin(pThis, cid, SVGA3D_QUERYTYPE_OCCLUSION);
                        /* Partial result. */
                        pContext->occlusion.u32QueryResult = query.u32QueryResult;
                        break;

                    case VMSVGA3DQUERYSTATE_ISSUED:
                        /* Guest ended the query but did not read result. Result is restored. */
                        query.enmQueryState = VMSVGA3DQUERYSTATE_SIGNALED;
                        RT_FALL_THRU();
                    case VMSVGA3DQUERYSTATE_SIGNALED:
                        /* Create the query object. */
                        vmsvga3dOcclusionQueryCreate(pState, pContext);

                        /* Update result and state. */
                        pContext->occlusion.enmQueryState = query.enmQueryState;
                        pContext->occlusion.u32QueryResult = query.u32QueryResult;
                        break;

                    default:
                        AssertFailed();
                        RT_FALL_THRU();
                    case VMSVGA3DQUERYSTATE_NULL:
                        RT_ZERO(pContext->occlusion);
                        break;
                }
            }
        }
    }

#ifdef VMSVGA3D_OPENGL
    /* Make the shared context the current one. */
    if (pState->SharedCtx.id == VMSVGA3D_SHARED_CTX_ID)
        VMSVGA3D_SET_CURRENT_CONTEXT(pState, &pState->SharedCtx);
#endif

    /* Fetch all surfaces. */
    for (uint32_t i = 0; i < cSurfaces; i++)
    {
        uint32_t sid;

        /* Fetch the id first. */
        rc = SSMR3GetU32(pSSM, &sid);
        AssertRCReturn(rc, rc);

        if (sid != SVGA3D_INVALID_ID)
        {
            VMSVGA3DSURFACE  surface;
            LogFlow(("vmsvga3dLoadExec: Loading sid=%#x\n", sid));

            /* Fetch the surface structure first. */
            rc = SSMR3GetStructEx(pSSM, &surface, sizeof(surface), 0, g_aVMSVGA3DSURFACEFields, NULL);
            AssertRCReturn(rc, rc);

            {
                uint32_t             cMipLevels = surface.faces[0].numMipLevels * surface.cFaces;
                PVMSVGA3DMIPMAPLEVEL pMipmapLevel = (PVMSVGA3DMIPMAPLEVEL)RTMemAlloc(cMipLevels * sizeof(VMSVGA3DMIPMAPLEVEL));
                AssertReturn(pMipmapLevel, VERR_NO_MEMORY);
                SVGA3dSize *pMipmapLevelSize = (SVGA3dSize *)RTMemAlloc(cMipLevels * sizeof(SVGA3dSize));
                AssertReturn(pMipmapLevelSize, VERR_NO_MEMORY);

                /* Load the mip map level info. */
                for (uint32_t face=0; face < surface.cFaces; face++)
                {
                    for (uint32_t j = 0; j < surface.faces[0].numMipLevels; j++)
                    {
                        uint32_t idx = j + face * surface.faces[0].numMipLevels;
                        /* Load the mip map level struct. */
                        rc = SSMR3GetStructEx(pSSM, &pMipmapLevel[idx], sizeof(pMipmapLevel[idx]), 0, g_aVMSVGA3DMIPMAPLEVELFields, NULL);
                        AssertRCReturn(rc, rc);

                        pMipmapLevelSize[idx] = pMipmapLevel[idx].mipmapSize;
                    }
                }

                rc = vmsvga3dSurfaceDefine(pThis, sid, surface.surfaceFlags, surface.format, surface.faces, surface.multiSampleCount, surface.autogenFilter, cMipLevels, pMipmapLevelSize);
                AssertRCReturn(rc, rc);

                RTMemFree(pMipmapLevelSize);
                RTMemFree(pMipmapLevel);
            }

            PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
            Assert(pSurface->id == sid);

            pSurface->fDirty = false;

            /* Load the mip map level data. */
            for (uint32_t j = 0; j < pSurface->faces[0].numMipLevels * pSurface->cFaces; j++)
            {
                PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->pMipmapLevels[j];
                bool fDataPresent = false;

                /* vmsvga3dSurfaceDefine already allocated the surface data buffer. */
                Assert(pMipmapLevel->cbSurface);
                AssertReturn(pMipmapLevel->pSurfaceData, VERR_INTERNAL_ERROR);

                /* Fetch the data present boolean first. */
                rc = SSMR3GetBool(pSSM, &fDataPresent);
                AssertRCReturn(rc, rc);

                Log(("Surface sid=%x: load mipmap level %d with %x bytes data (present=%d).\n", sid, j, pMipmapLevel->cbSurface, fDataPresent));

                if (fDataPresent)
                {
                    rc = SSMR3GetMem(pSSM, pMipmapLevel->pSurfaceData, pMipmapLevel->cbSurface);
                    AssertRCReturn(rc, rc);
                    pMipmapLevel->fDirty = true;
                    pSurface->fDirty     = true;
                }
                else
                {
                    pMipmapLevel->fDirty = false;
                }
            }
        }
    }

#ifdef VMSVGA3D_OPENGL
    /* Reinitialize the shared context. */
    LogFlow(("vmsvga3dLoadExec: pState->SharedCtx.id=%#x\n", pState->SharedCtx.id));
    if (pState->SharedCtx.id == VMSVGA3D_SHARED_CTX_ID)
    {
        rc = vmsvga3dLoadReinitContext(pThis, &pState->SharedCtx);
        AssertRCReturn(rc, rc);
    }
#endif

    /* Reinitialize all active contexts. */
    for (uint32_t i = 0; i < pState->cContexts; i++)
    {
        PVMSVGA3DCONTEXT pContext = pState->papContexts[i];
        if (pContext->id != SVGA3D_INVALID_ID)
        {
            rc = vmsvga3dLoadReinitContext(pThis, pContext);
            AssertRCReturn(rc, rc);
        }
    }

    LogFlow(("vmsvga3dLoadExec: return success\n"));
    return VINF_SUCCESS;
}
Ejemplo n.º 2
0
int vmsvga3dLoadExec(PVGASTATE pThis, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
{
    PVMSVGA3DSTATE pState = pThis->svga.p3dState;
    AssertReturn(pState, VERR_NO_MEMORY);
    int            rc;
    uint32_t       cContexts, cSurfaces;
    LogFlow(("vmsvga3dLoadExec:\n"));

#ifndef RT_OS_DARWIN /** @todo r=bird: this is normally done on the EMT, so for DARWIN we do that when loading saved state too now. See DevVGA-SVGA.cpp */
    /* Must initialize now as the recreation calls below rely on an initialized 3d subsystem. */
    vmsvga3dPowerOn(pThis);
#endif

    /* Get the generic 3d state first. */
    rc = SSMR3GetStructEx(pSSM, pState, sizeof(*pState), 0, g_aVMSVGA3DSTATEFields, NULL);
    AssertRCReturn(rc, rc);

    cContexts                           = pState->cContexts;
    cSurfaces                           = pState->cSurfaces;
    pState->cContexts                   = 0;
    pState->cSurfaces                   = 0;

    /* Fetch all active contexts. */
    for (uint32_t i = 0; i < cContexts; i++)
    {
        PVMSVGA3DCONTEXT pContext;
        uint32_t         cid;

        /* Get the context id */
        rc = SSMR3GetU32(pSSM, &cid);
        AssertRCReturn(rc, rc);

        if (cid != SVGA3D_INVALID_ID)
        {
            uint32_t cPixelShaderConst, cVertexShaderConst, cPixelShaders, cVertexShaders;
            LogFlow(("vmsvga3dLoadExec: Loading cid=%#x\n", cid));

#ifdef VMSVGA3D_OPENGL
            if (cid == VMSVGA3D_SHARED_CTX_ID)
            {
                i--; /* Not included in cContexts. */
                pContext = &pState->SharedCtx;
                if (pContext->id != VMSVGA3D_SHARED_CTX_ID)
                {
                    rc = vmsvga3dContextDefineOgl(pThis, VMSVGA3D_SHARED_CTX_ID, VMSVGA3D_DEF_CTX_F_SHARED_CTX);
                    AssertRCReturn(rc, rc);
                }
            }
            else
#endif
            {
                rc = vmsvga3dContextDefine(pThis, cid);
                AssertRCReturn(rc, rc);

                pContext = pState->papContexts[i];
            }
            AssertReturn(pContext->id == cid, VERR_INTERNAL_ERROR);

            rc = SSMR3GetStructEx(pSSM, pContext, sizeof(*pContext), 0, g_aVMSVGA3DCONTEXTFields, NULL);
            AssertRCReturn(rc, rc);

            cPixelShaders                       = pContext->cPixelShaders;
            cVertexShaders                      = pContext->cVertexShaders;
            cPixelShaderConst                   = pContext->state.cPixelShaderConst;
            cVertexShaderConst                  = pContext->state.cVertexShaderConst;
            pContext->cPixelShaders             = 0;
            pContext->cVertexShaders            = 0;
            pContext->state.cPixelShaderConst   = 0;
            pContext->state.cVertexShaderConst  = 0;

            /* Fetch all pixel shaders. */
            for (uint32_t j = 0; j < cPixelShaders; j++)
            {
                VMSVGA3DSHADER  shader;
                uint32_t        shid;

                /* Fetch the id first. */
                rc = SSMR3GetU32(pSSM, &shid);
                AssertRCReturn(rc, rc);

                if (shid != SVGA3D_INVALID_ID)
                {
                    uint32_t *pData;

                    /* Fetch a copy of the shader struct. */
                    rc = SSMR3GetStructEx(pSSM, &shader, sizeof(shader), 0, g_aVMSVGA3DSHADERFields, NULL);
                    AssertRCReturn(rc, rc);

                    pData = (uint32_t *)RTMemAlloc(shader.cbData);
                    AssertReturn(pData, VERR_NO_MEMORY);

                    rc = SSMR3GetMem(pSSM, pData, shader.cbData);
                    AssertRCReturn(rc, rc);

                    rc = vmsvga3dShaderDefine(pThis, cid, shid, shader.type, shader.cbData, pData);
                    AssertRCReturn(rc, rc);

                    RTMemFree(pData);
                }
            }

            /* Fetch all vertex shaders. */
            for (uint32_t j = 0; j < cVertexShaders; j++)
            {
                VMSVGA3DSHADER  shader;
                uint32_t        shid;

                /* Fetch the id first. */
                rc = SSMR3GetU32(pSSM, &shid);
                AssertRCReturn(rc, rc);

                if (shid != SVGA3D_INVALID_ID)
                {
                    uint32_t *pData;

                    /* Fetch a copy of the shader struct. */
                    rc = SSMR3GetStructEx(pSSM, &shader, sizeof(shader), 0, g_aVMSVGA3DSHADERFields, NULL);
                    AssertRCReturn(rc, rc);

                    pData = (uint32_t *)RTMemAlloc(shader.cbData);
                    AssertReturn(pData, VERR_NO_MEMORY);

                    rc = SSMR3GetMem(pSSM, pData, shader.cbData);
                    AssertRCReturn(rc, rc);

                    rc = vmsvga3dShaderDefine(pThis, cid, shid, shader.type, shader.cbData, pData);
                    AssertRCReturn(rc, rc);

                    RTMemFree(pData);
                }
            }

            /* Fetch pixel shader constants. */
            for (uint32_t j = 0; j < cPixelShaderConst; j++)
            {
                VMSVGASHADERCONST ShaderConst;

                rc = SSMR3GetStructEx(pSSM, &ShaderConst, sizeof(ShaderConst), 0, g_aVMSVGASHADERCONSTFields, NULL);
                AssertRCReturn(rc, rc);

                if (ShaderConst.fValid)
                {
                    rc = vmsvga3dShaderSetConst(pThis, cid, j, SVGA3D_SHADERTYPE_PS, ShaderConst.ctype, 1, ShaderConst.value);
                    AssertRCReturn(rc, rc);
                }
            }

            /* Fetch vertex shader constants. */
            for (uint32_t j = 0; j < cVertexShaderConst; j++)
            {
                VMSVGASHADERCONST ShaderConst;

                rc = SSMR3GetStructEx(pSSM, &ShaderConst, sizeof(ShaderConst), 0, g_aVMSVGASHADERCONSTFields, NULL);
                AssertRCReturn(rc, rc);

                if (ShaderConst.fValid)
                {
                    rc = vmsvga3dShaderSetConst(pThis, cid, j, SVGA3D_SHADERTYPE_VS, ShaderConst.ctype, 1, ShaderConst.value);
                    AssertRCReturn(rc, rc);
                }
            }
        }
    }

#ifdef VMSVGA3D_OPENGL
    /* Make the shared context the current one. */
    if (pState->SharedCtx.id == VMSVGA3D_SHARED_CTX_ID)
        VMSVGA3D_SET_CURRENT_CONTEXT(pState, &pState->SharedCtx);
#endif

    /* Fetch all surfaces. */
    for (uint32_t i = 0; i < cSurfaces; i++)
    {
        uint32_t sid;

        /* Fetch the id first. */
        rc = SSMR3GetU32(pSSM, &sid);
        AssertRCReturn(rc, rc);

        if (sid != SVGA3D_INVALID_ID)
        {
            VMSVGA3DSURFACE  surface;
            LogFlow(("vmsvga3dLoadExec: Loading sid=%#x\n", sid));

            /* Fetch the surface structure first. */
            rc = SSMR3GetStructEx(pSSM, &surface, sizeof(surface), 0, g_aVMSVGA3DSURFACEFields, NULL);
            AssertRCReturn(rc, rc);

            {
                uint32_t             cMipLevels = surface.faces[0].numMipLevels * surface.cFaces;
                PVMSVGA3DMIPMAPLEVEL pMipmapLevel = (PVMSVGA3DMIPMAPLEVEL)RTMemAlloc(cMipLevels * sizeof(VMSVGA3DMIPMAPLEVEL));
                AssertReturn(pMipmapLevel, VERR_NO_MEMORY);
                SVGA3dSize *pMipmapLevelSize = (SVGA3dSize *)RTMemAlloc(cMipLevels * sizeof(SVGA3dSize));
                AssertReturn(pMipmapLevelSize, VERR_NO_MEMORY);

                /* Load the mip map level info. */
                for (uint32_t face=0; face < surface.cFaces; face++)
                {
                    for (uint32_t j = 0; j < surface.faces[0].numMipLevels; j++)
                    {
                        uint32_t idx = j + face * surface.faces[0].numMipLevels;
                        /* Load the mip map level struct. */
                        rc = SSMR3GetStructEx(pSSM, &pMipmapLevel[idx], sizeof(pMipmapLevel[idx]), 0, g_aVMSVGA3DMIPMAPLEVELFields, NULL);
                        AssertRCReturn(rc, rc);

                        pMipmapLevelSize[idx] = pMipmapLevel[idx].size;
                    }
                }

                rc = vmsvga3dSurfaceDefine(pThis, sid, surface.flags, surface.format, surface.faces, surface.multiSampleCount, surface.autogenFilter, cMipLevels, pMipmapLevelSize);
                AssertRCReturn(rc, rc);

                RTMemFree(pMipmapLevelSize);
                RTMemFree(pMipmapLevel);
            }

            PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
            Assert(pSurface->id == sid);

            pSurface->fDirty = false;

            /* Load the mip map level data. */
            for (uint32_t j = 0; j < pSurface->faces[0].numMipLevels * pSurface->cFaces; j++)
            {
                PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->pMipmapLevels[j];
                bool fDataPresent = false;

                Assert(pMipmapLevel->cbSurface);
                pMipmapLevel->pSurfaceData = RTMemAllocZ(pMipmapLevel->cbSurface);
                AssertReturn(pMipmapLevel->pSurfaceData, VERR_NO_MEMORY);

                /* Fetch the data present boolean first. */
                rc = SSMR3GetBool(pSSM, &fDataPresent);
                AssertRCReturn(rc, rc);

                Log(("Surface sid=%x: load mipmap level %d with %x bytes data (present=%d).\n", sid, j, pMipmapLevel->cbSurface, fDataPresent));

                if (fDataPresent)
                {
                    rc = SSMR3GetMem(pSSM, pMipmapLevel->pSurfaceData, pMipmapLevel->cbSurface);
                    AssertRCReturn(rc, rc);
                    pMipmapLevel->fDirty = true;
                    pSurface->fDirty     = true;
                }
                else
                {
                    pMipmapLevel->fDirty = false;
                }
            }
        }
    }

#ifdef VMSVGA3D_OPENGL
    /* Reinitialize the shared context. */
    LogFlow(("vmsvga3dLoadExec: pState->SharedCtx.id=%#x\n", pState->SharedCtx.id));
    if (pState->SharedCtx.id == VMSVGA3D_SHARED_CTX_ID)
    {
        rc = vmsvga3dLoadReinitContext(pThis, &pState->SharedCtx);
        AssertRCReturn(rc, rc);
    }
#endif

    /* Reinitialize all active contexts. */
    for (uint32_t i = 0; i < pState->cContexts; i++)
    {
        PVMSVGA3DCONTEXT pContext = pState->papContexts[i];
        if (pContext->id != SVGA3D_INVALID_ID)
        {
            rc = vmsvga3dLoadReinitContext(pThis, pContext);
            AssertRCReturn(rc, rc);
        }
    }

    LogFlow(("vmsvga3dLoadExec: return success\n"));
    return VINF_SUCCESS;
}