Beispiel #1
0
static bool
crDLMLoadListInstance(PSSMHANDLE pSSM, DLMListInfo *pListInfo, SPUDispatchTable *dispatchTable)
{
    uint32_t         cbInstance = 0;
    DLMInstanceList *pInstance;
    int32_t          rc;

    /* Get Display List item size. */
    rc = SSMR3GetU32(pSSM, &cbInstance);
    if (RT_SUCCESS(rc))
    {
        /* Allocate memory for the item, initialize it and put into the list. */
        pInstance = crCalloc(cbInstance);
        if (pInstance)
        {
            crMemset(pInstance, 0, cbInstance);

            rc = SSMR3GetMem(pSSM, pInstance, cbInstance); AssertRCReturn(rc, rc);
            if (RT_SUCCESS(rc))
            {
                pInstance->execute = crDLMGetExecuteRoutine(pInstance->iVBoxOpCode);
                if (pInstance->execute)
                {
                    pInstance->execute(pInstance, dispatchTable);

                    pInstance->next         = NULL;
                    pInstance->stateNext    = NULL;
                    pInstance->cbInstance   = cbInstance;

                    pListInfo->numInstances++;

                    if (!pListInfo->first)
                        pListInfo->first = pInstance;

                    if (pListInfo->last)
                        pListInfo->last->next = pInstance;

                    pListInfo->last = pInstance;

                    return true;
                }
                else
                    crError("Restoring Display Lists: unknown list item (opcode=%u).", pInstance->iVBoxOpCode);
            }
            else
                crError("Restoring Display Lists: can't read list element size.");
        }
        else
            crError("Restoring Display Lists: not enough memory, aborting.");
    }
    else
        crError("Restoring Display Lists: saved state file might be corrupted.");

    return false;
}
Beispiel #2
0
/**
 * Load a queue state.
 *
 * @param   pSSM                SSM handle to read the state from.
 * @param   pQ                  Pointer to the queue.
 *
 * @return  int                 VBox status/error code.
 */
static int ps2kLoadQueue(PSSMHANDLE pSSM, GeneriQ *pQ)
{
    int         rc;

    /* On load, always put the read pointer at zero. */
    SSMR3GetU32(pSSM, &pQ->cUsed);

    LogFlow(("Loading %d items to queue %p\n", pQ->cUsed, pQ));

    if (pQ->cUsed > pQ->cSize)
    {
        AssertMsgFailed(("Saved size=%u, actual=%u\n", pQ->cUsed, pQ->cSize));
        return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
    }

    /* Recalculate queue positions and load data in one go. */
    pQ->rpos = 0;
    pQ->wpos = pQ->cUsed;
    rc = SSMR3GetMem(pSSM, pQ->abQueue, pQ->cUsed);

    return rc;
}
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;
}
Beispiel #4
0
/**
 * Restore previously saved PHY state.
 *
 * @remarks Since PHY is aggregated into E1K it does not currently supports
 *          versioning of its own.
 *
 * @returns VBox status code.
 * @param   pSSMHandle  The handle to save the state to.
 * @param   pPhy        The pointer to this instance.
 */
int Phy::loadState(PSSMHANDLE pSSMHandle, PPHY pPhy)
{
    return SSMR3GetMem(pSSMHandle, pPhy->au16Regs, sizeof(pPhy->au16Regs));
}
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;
}
int readSavedDisplayScreenshot(const Utf8Str &strStateFilePath, uint32_t u32Type, uint8_t **ppu8Data, uint32_t *pcbData, uint32_t *pu32Width, uint32_t *pu32Height)
{
    LogFlowFunc(("u32Type = %d [%s]\n", u32Type, strStateFilePath.c_str()));

    /* @todo cache read data */
    if (strStateFilePath.isEmpty())
    {
        /* No saved state data. */
        return VERR_NOT_SUPPORTED;
    }

    uint8_t *pu8Data = NULL;
    uint32_t cbData = 0;
    uint32_t u32Width = 0;
    uint32_t u32Height = 0;

    PSSMHANDLE pSSM;
    int vrc = SSMR3Open(strStateFilePath.c_str(), 0 /*fFlags*/, &pSSM);
    if (RT_SUCCESS(vrc))
    {
        uint32_t uVersion;
        vrc = SSMR3Seek(pSSM, "DisplayScreenshot", 1100 /*iInstance*/, &uVersion);
        if (RT_SUCCESS(vrc))
        {
            if (uVersion == sSSMDisplayScreenshotVer)
            {
                uint32_t cBlocks;
                vrc = SSMR3GetU32(pSSM, &cBlocks);
                AssertRCReturn(vrc, vrc);

                for (uint32_t i = 0; i < cBlocks; i++)
                {
                    uint32_t cbBlock;
                    vrc = SSMR3GetU32(pSSM, &cbBlock);
                    AssertRCBreak(vrc);

                    uint32_t typeOfBlock;
                    vrc = SSMR3GetU32(pSSM, &typeOfBlock);
                    AssertRCBreak(vrc);

                    LogFlowFunc(("[%d] type %d, size %d bytes\n", i, typeOfBlock, cbBlock));

                    if (typeOfBlock == u32Type)
                    {
                        if (cbBlock > 2 * sizeof(uint32_t))
                        {
                            cbData = cbBlock - 2 * sizeof(uint32_t);
                            pu8Data = (uint8_t *)RTMemAlloc(cbData);
                            if (pu8Data == NULL)
                            {
                                vrc = VERR_NO_MEMORY;
                                break;
                            }

                            vrc = SSMR3GetU32(pSSM, &u32Width);
                            AssertRCBreak(vrc);
                            vrc = SSMR3GetU32(pSSM, &u32Height);
                            AssertRCBreak(vrc);
                            vrc = SSMR3GetMem(pSSM, pu8Data, cbData);
                            AssertRCBreak(vrc);
                        }
                        else
                        {
                            /* No saved state data. */
                            vrc = VERR_NOT_SUPPORTED;
                        }

                        break;
                    }
                    else
                    {
                        /* displaySSMSaveScreenshot did not write any data, if
                         * cbBlock was == 2 * sizeof (uint32_t).
                         */
                        if (cbBlock > 2 * sizeof (uint32_t))
                        {
                            vrc = SSMR3Skip(pSSM, cbBlock);
                            AssertRCBreak(vrc);
                        }
                    }
                }
            }
            else
            {
                vrc = VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
            }
        }

        SSMR3Close(pSSM);
    }

    if (RT_SUCCESS(vrc))
    {
        if (u32Type == 0 && cbData % 4 != 0)
        {
            /* Bitmap is 32bpp, so data is invalid. */
            vrc = VERR_SSM_UNEXPECTED_DATA;
        }
    }

    if (RT_SUCCESS(vrc))
    {
        *ppu8Data = pu8Data;
        *pcbData = cbData;
        *pu32Width = u32Width;
        *pu32Height = u32Height;
        LogFlowFunc(("cbData %d, u32Width %d, u32Height %d\n", cbData, u32Width, u32Height));
    }

    LogFlowFunc(("vrc %Rrc\n", vrc));
    return vrc;
}
Beispiel #7
0
DECLEXPORT(int32_t) crVBoxServerLoadState(PSSMHANDLE pSSM, uint32_t version)
{
    int32_t  rc, i;
    uint32_t ui, uiNumElems;
    unsigned long key;

    if (!cr_server.bIsInLoadingState)
    {
        /* AssertRCReturn(...) will leave us in loading state, but it doesn't matter as we'd be failing anyway */
        cr_server.bIsInLoadingState = GL_TRUE;

        /* Read number of clients */
        rc = SSMR3GetU32(pSSM, &g_hackVBoxServerSaveLoadCallsLeft);
        AssertRCReturn(rc, rc);
    }

    g_hackVBoxServerSaveLoadCallsLeft--;

    /* Do nothing until we're being called last time */
    if (g_hackVBoxServerSaveLoadCallsLeft>0)
    {
        return VINF_SUCCESS;
    }

    if (version!=SHCROGL_SSM_VERSION)
    {
        return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
    }

    /* Load and recreate rendering contexts */
    rc = SSMR3GetU32(pSSM, &uiNumElems);
    AssertRCReturn(rc, rc);
    for (ui=0; ui<uiNumElems; ++ui)
    {
        CRCreateInfo_t createInfo;
        char psz[200];
        GLint ctxID;
        CRContext* pContext;

        rc = SSMR3GetMem(pSSM, &key, sizeof(key));
        AssertRCReturn(rc, rc);
        rc = SSMR3GetMem(pSSM, &createInfo, sizeof(createInfo));
        AssertRCReturn(rc, rc);

        if (createInfo.pszDpyName)
        {
            rc = SSMR3GetStrZEx(pSSM, psz, 200, NULL);
            AssertRCReturn(rc, rc);
            createInfo.pszDpyName = psz;
        }

        ctxID = crServerDispatchCreateContextEx(createInfo.pszDpyName, createInfo.visualBits, 0, key, createInfo.internalID);
        CRASSERT((int64_t)ctxID == (int64_t)key);

        pContext = (CRContext*) crHashtableSearch(cr_server.contextTable, key);
        CRASSERT(pContext);
        pContext->shared->id=-1;
    }

    /* Restore context state data */
    for (ui=0; ui<uiNumElems; ++ui)
    {
        CRContext *pContext;

        rc = SSMR3GetMem(pSSM, &key, sizeof(key));
        AssertRCReturn(rc, rc);

        pContext = (CRContext*) crHashtableSearch(cr_server.contextTable, key);
        CRASSERT(pContext);

        rc = crStateLoadContext(pContext, cr_server.contextTable, pSSM);
        AssertRCReturn(rc, rc);
    }

    /* Load windows */
    rc = SSMR3GetU32(pSSM, &uiNumElems);
    AssertRCReturn(rc, rc);
    for (ui=0; ui<uiNumElems; ++ui)
    {
        CRCreateInfo_t createInfo;
        char psz[200];
        GLint winID;
        unsigned long key;

        rc = SSMR3GetMem(pSSM, &key, sizeof(key));
        AssertRCReturn(rc, rc);
        rc = SSMR3GetMem(pSSM, &createInfo, sizeof(createInfo));
        AssertRCReturn(rc, rc);

        if (createInfo.pszDpyName)
        {
            rc = SSMR3GetStrZEx(pSSM, psz, 200, NULL);
            AssertRCReturn(rc, rc);
            createInfo.pszDpyName = psz;
        }

        winID = crServerDispatchWindowCreateEx(createInfo.pszDpyName, createInfo.visualBits, key);
        CRASSERT((int64_t)winID == (int64_t)key);
    }

    /* Load cr_server.muralTable */
    rc = SSMR3GetU32(pSSM, &uiNumElems);
    AssertRCReturn(rc, rc);
    for (ui=0; ui<uiNumElems; ++ui)
    {
        CRMuralInfo muralInfo;

        rc = SSMR3GetMem(pSSM, &key, sizeof(key));
        AssertRCReturn(rc, rc);
        rc = SSMR3GetMem(pSSM, &muralInfo, sizeof(muralInfo));
        AssertRCReturn(rc, rc);

        if (muralInfo.pVisibleRects)
        {
            muralInfo.pVisibleRects = crAlloc(4*sizeof(GLint)*muralInfo.cVisibleRects);
            if (!muralInfo.pVisibleRects)
            {
                return VERR_NO_MEMORY;
            }

            rc = SSMR3GetMem(pSSM, muralInfo.pVisibleRects, 4*sizeof(GLint)*muralInfo.cVisibleRects);
            AssertRCReturn(rc, rc);
        }

        /* Restore windows geometry info */
        crServerDispatchWindowSize(key, muralInfo.width, muralInfo.height);
        crServerDispatchWindowPosition(key, muralInfo.gX, muralInfo.gY);
        /* Same workaround as described in stub.c:stubUpdateWindowVisibileRegions for compiz on a freshly booted VM*/
        if (muralInfo.bReceivedRects)
        {
            crServerDispatchWindowVisibleRegion(key, muralInfo.cVisibleRects, muralInfo.pVisibleRects);
        }
        crServerDispatchWindowShow(key, muralInfo.bVisible);

        if (muralInfo.pVisibleRects)
        {
            crFree(muralInfo.pVisibleRects);
        }
    }

    /* Load starting free context and window IDs */
    rc = SSMR3GetMem(pSSM, &cr_server.idsPool, sizeof(cr_server.idsPool));
    CRASSERT(rc == VINF_SUCCESS);

    /* Load clients info */
    for (i = 0; i < cr_server.numClients; i++)
    {
        if (cr_server.clients[i] && cr_server.clients[i]->conn)
        {
            CRClient *pClient = cr_server.clients[i];
            CRClient client;
            unsigned long ctxID=-1, winID=-1;

            rc = SSMR3GetU32(pSSM, &ui);
            AssertRCReturn(rc, rc);
            /* If this assert fires, then we should search correct client in the list first*/
            CRASSERT(ui == pClient->conn->u32ClientID);

            if (version>=4)
            {
                rc = SSMR3GetU32(pSSM, &pClient->conn->vMajor);
                AssertRCReturn(rc, rc);

                rc = SSMR3GetU32(pSSM, &pClient->conn->vMinor);
                AssertRCReturn(rc, rc);
            }

            rc = SSMR3GetMem(pSSM, &client, sizeof(client));
            CRASSERT(rc == VINF_SUCCESS);

            client.conn = pClient->conn;
            /* We can't reassign client number, as we'd get wrong results in TranslateTextureID
             * and fail to bind old textures.
             */
            /*client.number = pClient->number;*/
            *pClient = client;

            pClient->currentContextNumber = -1;
            pClient->currentCtx = cr_server.DummyContext;
            pClient->currentMural = NULL;
            pClient->currentWindow = -1;

            cr_server.curClient = pClient;

            if (client.currentCtx && client.currentContextNumber>=0)
            {
                rc = SSMR3GetMem(pSSM, &ctxID, sizeof(ctxID));
                AssertRCReturn(rc, rc);
                client.currentCtx = (CRContext*) crHashtableSearch(cr_server.contextTable, ctxID);
                CRASSERT(client.currentCtx);
                //pClient->currentCtx = client.currentCtx;
                //pClient->currentContextNumber = ctxID;
            }

            if (client.currentMural && client.currentWindow>=0)
            {
                rc = SSMR3GetMem(pSSM, &winID, sizeof(winID));
                AssertRCReturn(rc, rc);
                client.currentMural = (CRMuralInfo*) crHashtableSearch(cr_server.muralTable, winID);
                CRASSERT(client.currentMural);
                //pClient->currentMural = client.currentMural;
                //pClient->currentWindow = winID;
            }

            /* Restore client active context and window */
            crServerDispatchMakeCurrent(winID, 0, ctxID);

            if (0)
            {
            CRContext *tmpCtx;
            CRCreateInfo_t *createInfo;
            GLfloat one[4] = { 1, 1, 1, 1 };
            GLfloat amb[4] = { 0.4f, 0.4f, 0.4f, 1.0f };

            crServerDispatchMakeCurrent(winID, 0, ctxID);

            crHashtableWalk(client.currentCtx->shared->textureTable, crVBoxServerSyncTextureCB, client.currentCtx);

            crStateTextureObjectDiff(client.currentCtx, NULL, NULL, &client.currentCtx->texture.base1D, GL_TRUE);
            crStateTextureObjectDiff(client.currentCtx, NULL, NULL, &client.currentCtx->texture.base2D, GL_TRUE);
            crStateTextureObjectDiff(client.currentCtx, NULL, NULL, &client.currentCtx->texture.base3D, GL_TRUE);
#ifdef CR_ARB_texture_cube_map
            crStateTextureObjectDiff(client.currentCtx, NULL, NULL, &client.currentCtx->texture.baseCubeMap, GL_TRUE);
#endif
#ifdef CR_NV_texture_rectangle
            //@todo this doesn't work as expected
            //crStateTextureObjectDiff(client.currentCtx, NULL, NULL, &client.currentCtx->texture.baseRect, GL_TRUE);
#endif
            /*cr_server.head_spu->dispatch_table.Materialfv(GL_FRONT_AND_BACK, GL_AMBIENT, amb);
            cr_server.head_spu->dispatch_table.LightModelfv(GL_LIGHT_MODEL_AMBIENT, amb);
            cr_server.head_spu->dispatch_table.Lightfv(GL_LIGHT1, GL_DIFFUSE, one);

            cr_server.head_spu->dispatch_table.Enable(GL_LIGHTING);
            cr_server.head_spu->dispatch_table.Enable(GL_LIGHT0);
            cr_server.head_spu->dispatch_table.Enable(GL_LIGHT1);

            cr_server.head_spu->dispatch_table.Enable(GL_CULL_FACE);
            cr_server.head_spu->dispatch_table.Enable(GL_TEXTURE_2D);*/

            //crStateViewport( 0, 0, 600, 600 );
            //pClient->currentMural->viewportValidated = GL_FALSE;
            //cr_server.head_spu->dispatch_table.Viewport( 0, 0, 600, 600 );

            //crStateMatrixMode(GL_PROJECTION);
            //cr_server.head_spu->dispatch_table.MatrixMode(GL_PROJECTION);

            //crStateLoadIdentity();
            //cr_server.head_spu->dispatch_table.LoadIdentity();

            //crStateFrustum(-0.5, 0.5, -0.5, 0.5, 1.5, 150.0);
            //cr_server.head_spu->dispatch_table.Frustum(-0.5, 0.5, -0.5, 0.5, 1.5, 150.0);

            //crStateMatrixMode(GL_MODELVIEW);
            //cr_server.head_spu->dispatch_table.MatrixMode(GL_MODELVIEW);
            //crServerDispatchLoadIdentity();
            //crStateFrustum(-0.5, 0.5, -0.5, 0.5, 1.5, 150.0);
            //cr_server.head_spu->dispatch_table.Frustum(-0.5, 0.5, -0.5, 0.5, 1.5, 150.0);
            //crServerDispatchLoadIdentity();

                /*createInfo = (CRCreateInfo_t *) crHashtableSearch(cr_server.pContextCreateInfoTable, ctxID);
                CRASSERT(createInfo);
                tmpCtx = crStateCreateContext(NULL, createInfo->visualBits, NULL);
                CRASSERT(tmpCtx);
                crStateDiffContext(tmpCtx, client.currentCtx);
                crStateDestroyContext(tmpCtx);*/
            }
        }
    }

    //crServerDispatchMakeCurrent(-1, 0, -1);

    cr_server.curClient = NULL;

    {
        GLenum err = crServerDispatchGetError();

        if (err != GL_NO_ERROR)
        {
            crWarning("crServer: glGetError %d after loading snapshot", err);
        }
    }

    cr_server.bIsInLoadingState = GL_FALSE;

    return VINF_SUCCESS;
}