/** * Hyper-V state-load operation, final pass. * * @returns VBox status code. * @param pVM Pointer to the VM. * @param pSSM Pointer to the SSM handle. * @param uSSMVersion The GIM saved-state version. */ VMMR3_INT_DECL(int) gimR3HvLoad(PVM pVM, PSSMHANDLE pSSM, uint32_t uSSMVersion) { PGIMHV pHv = &pVM->gim.s.u.Hv; /* * Load the Hyper-V SSM version first. */ uint32_t uHvSavedStatVersion; int rc = SSMR3GetU32(pSSM, &uHvSavedStatVersion); AssertRCReturn(rc, rc); if (uHvSavedStatVersion != GIM_HV_SAVED_STATE_VERSION) return SSMR3SetLoadError(pSSM, VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION, RT_SRC_POS, N_("Unsupported Hyper-V saved-state version %u (expected %u)."), uHvSavedStatVersion, GIM_HV_SAVED_STATE_VERSION); /* * Load per-VM MSRs. */ SSMR3GetU64(pSSM, &pHv->u64GuestOsIdMsr); SSMR3GetU64(pSSM, &pHv->u64HypercallMsr); SSMR3GetU64(pSSM, &pHv->u64TscPageMsr); /* * Load Hyper-V features / capabilities. */ SSMR3GetU32(pSSM, &pHv->uBaseFeat); SSMR3GetU32(pSSM, &pHv->uPartFlags); SSMR3GetU32(pSSM, &pHv->uPowMgmtFeat); SSMR3GetU32(pSSM, &pHv->uMiscFeat); SSMR3GetU32(pSSM, &pHv->uHyperHints); SSMR3GetU32(pSSM, &pHv->uHyperCaps); /* * Load and enable the Hypercall region. */ PGIMMMIO2REGION pRegion = &pHv->aMmio2Regions[GIM_HV_HYPERCALL_PAGE_REGION_IDX]; SSMR3GetU8(pSSM, &pRegion->iRegion); SSMR3GetBool(pSSM, &pRegion->fRCMapping); SSMR3GetU32(pSSM, &pRegion->cbRegion); SSMR3GetGCPhys(pSSM, &pRegion->GCPhysPage); rc = SSMR3GetStrZ(pSSM, pRegion->szDescription, sizeof(pRegion->szDescription)); AssertRCReturn(rc, rc); if (MSR_GIM_HV_HYPERCALL_IS_ENABLED(pHv->u64HypercallMsr)) { Assert(pRegion->GCPhysPage != NIL_RTGCPHYS); if (RT_LIKELY(pRegion->fRegistered)) { rc = gimR3HvEnableHypercallPage(pVM, pRegion->GCPhysPage); if (RT_FAILURE(rc)) return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Failed to enable the hypercall page. GCPhys=%#RGp rc=%Rrc"), pRegion->GCPhysPage, rc); } else return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Hypercall MMIO2 region not registered. Missing GIM device?!")); } /* * Load and enable the reference TSC region. */ uint32_t uTscSequence; pRegion = &pHv->aMmio2Regions[GIM_HV_REF_TSC_PAGE_REGION_IDX]; SSMR3GetU8(pSSM, &pRegion->iRegion); SSMR3GetBool(pSSM, &pRegion->fRCMapping); SSMR3GetU32(pSSM, &pRegion->cbRegion); SSMR3GetGCPhys(pSSM, &pRegion->GCPhysPage); SSMR3GetStrZ(pSSM, pRegion->szDescription, sizeof(pRegion->szDescription)); rc = SSMR3GetU32(pSSM, &uTscSequence); AssertRCReturn(rc, rc); if (MSR_GIM_HV_REF_TSC_IS_ENABLED(pHv->u64TscPageMsr)) { Assert(pRegion->GCPhysPage != NIL_RTGCPHYS); if (pRegion->fRegistered) { rc = gimR3HvEnableTscPage(pVM, pRegion->GCPhysPage, true /* fUseThisTscSeq */, uTscSequence); if (RT_FAILURE(rc)) return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Failed to enable the TSC page. GCPhys=%#RGp rc=%Rrc"), pRegion->GCPhysPage, rc); } else return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("TSC-page MMIO2 region not registered. Missing GIM device?!")); } 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; }
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; }