summaryrefslogtreecommitdiff
path: root/src/VBox/Devices/Graphics/HGSMI/HGSMIHost.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Devices/Graphics/HGSMI/HGSMIHost.cpp')
-rw-r--r--src/VBox/Devices/Graphics/HGSMI/HGSMIHost.cpp106
1 files changed, 93 insertions, 13 deletions
diff --git a/src/VBox/Devices/Graphics/HGSMI/HGSMIHost.cpp b/src/VBox/Devices/Graphics/HGSMI/HGSMIHost.cpp
index 84fe7b2c..c0d2c0b8 100644
--- a/src/VBox/Devices/Graphics/HGSMI/HGSMIHost.cpp
+++ b/src/VBox/Devices/Graphics/HGSMI/HGSMIHost.cpp
@@ -8,7 +8,7 @@
*/
/*
- * Copyright (C) 2006-2008 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -1039,19 +1039,12 @@ int HGSMIHostCommandProcessAndFreeAsynch (PHGSMIINSTANCE pIns,
{
LogFlowFunc(("pIns = %p, pvMem = %p\n", pIns, pvMem));
- VM_ASSERT_OTHER_THREAD(pIns->pVM);
-
#if 0
void *pvContext = NULL;
#endif
HGSMIOFFSET offBuffer = HGSMIHeapBufferOffset (&pIns->hostHeap, pvMem);
-// /* Have to forward to EMT because FIFO processing is there. */
-// int rc = VMR3ReqCallVoid (pIns->pVM, &pReq, RT_INDEFINITE_WAIT,
-// (PFNRT) hgsmiHostCommandProcess,
-// 3, pIns, offBuffer, &pvContext);
-
int rc = hgsmiHostCommandProcess (pIns, offBuffer,
#if 0
hgsmiHostCommandFreeCallback, &pvContext,
@@ -1192,6 +1185,32 @@ static int hgsmiHostSaveFifoLocked (HGSMILIST * pFifo, PSSMHANDLE pSSM)
return rc;
}
+static int hgsmiHostSaveGuestCmdCompletedFifoEntryLocked (HGSMIGUESTCOMPLENTRY *pEntry, PSSMHANDLE pSSM)
+{
+ return SSMR3PutU32 (pSSM, pEntry->offBuffer);
+}
+
+static int hgsmiHostSaveGuestCmdCompletedFifoLocked (HGSMILIST * pFifo, PSSMHANDLE pSSM)
+{
+ VBOXHGSMI_SAVE_FIFOSTART(pSSM);
+ uint32_t size = 0;
+ for(HGSMILISTENTRY * pEntry = pFifo->pHead; pEntry; pEntry = pEntry->pNext)
+ {
+ ++size;
+ }
+ int rc = SSMR3PutU32 (pSSM, size);
+
+ for(HGSMILISTENTRY * pEntry = pFifo->pHead; pEntry && RT_SUCCESS(rc); pEntry = pEntry->pNext)
+ {
+ HGSMIGUESTCOMPLENTRY *pFifoEntry = HGSMILISTENTRY_2_HGSMIGUESTCOMPLENTRY(pEntry);
+ rc = hgsmiHostSaveGuestCmdCompletedFifoEntryLocked (pFifoEntry, pSSM);
+ }
+
+ VBOXHGSMI_SAVE_FIFOSTOP(pSSM);
+
+ return rc;
+}
+
static int hgsmiHostLoadFifoEntryLocked (PHGSMIINSTANCE pIns, HGSMIHOSTFIFOENTRY **ppEntry, PSSMHANDLE pSSM)
{
HGSMIHOSTFIFOENTRY *pEntry;
@@ -1234,13 +1253,65 @@ static int hgsmiHostLoadFifoLocked (PHGSMIINSTANCE pIns, HGSMILIST * pFifo, PSSM
return rc;
}
+static int hgsmiHostLoadGuestCmdCompletedFifoEntryLocked (PHGSMIINSTANCE pIns, HGSMIGUESTCOMPLENTRY **ppEntry, PSSMHANDLE pSSM)
+{
+ HGSMIGUESTCOMPLENTRY *pEntry;
+ int rc = hgsmiGuestCompletionFIFOAlloc (pIns, &pEntry); AssertRC(rc);
+ if (RT_SUCCESS (rc))
+ {
+ rc = SSMR3GetU32 (pSSM, &pEntry->offBuffer); AssertRC(rc);
+ if (RT_SUCCESS (rc))
+ *ppEntry = pEntry;
+ else
+ hgsmiGuestCompletionFIFOFree (pIns, pEntry);
+ }
+ return rc;
+}
+
+static int hgsmiHostLoadGuestCmdCompletedFifoLocked (PHGSMIINSTANCE pIns, HGSMILIST * pFifo, PSSMHANDLE pSSM, uint32_t u32Version)
+{
+ VBOXHGSMI_LOAD_FIFOSTART(pSSM);
+
+ uint32_t size;
+ int rc = SSMR3GetU32 (pSSM, &size); AssertRC(rc);
+ if(RT_SUCCESS(rc) && size)
+ {
+ if (u32Version > VGA_SAVEDSTATE_VERSION_INV_GCMDFIFO)
+ {
+ for(uint32_t i = 0; i < size; ++i)
+ {
+ HGSMIGUESTCOMPLENTRY *pFifoEntry = NULL; /* initialized to shut up gcc */
+ rc = hgsmiHostLoadGuestCmdCompletedFifoEntryLocked (pIns, &pFifoEntry, pSSM);
+ AssertRCBreak(rc);
+ hgsmiListAppend (pFifo, &pFifoEntry->entry);
+ }
+ }
+ else
+ {
+ LogRel(("WARNING: the current saved state version has some 3D support data missing, "
+ "which may lead to some guest applications function improperly"));
+ /* just read out all invalid data and discard it */
+ for(uint32_t i = 0; i < size; ++i)
+ {
+ HGSMIHOSTFIFOENTRY *pFifoEntry = NULL; /* initialized to shut up gcc */
+ rc = hgsmiHostLoadFifoEntryLocked (pIns, &pFifoEntry, pSSM);
+ AssertRCBreak(rc);
+ hgsmiHostFIFOFree (pIns, pFifoEntry);
+ }
+ }
+ }
+
+ VBOXHGSMI_LOAD_FIFOSTOP(pSSM);
+
+ return rc;
+}
+
int HGSMIHostSaveStateExec (PHGSMIINSTANCE pIns, PSSMHANDLE pSSM)
{
VBOXHGSMI_SAVE_START(pSSM);
int rc;
-
HGSMIOFFSET off = pIns->pHGFlags ? HGSMIPointerToOffset(&pIns->area, (const HGSMIBUFFERHEADER *)pIns->pHGFlags) : HGSMIOFFSET_VOID;
SSMR3PutU32 (pSSM, off);
@@ -1251,7 +1322,7 @@ int HGSMIHostSaveStateExec (PHGSMIINSTANCE pIns, PSSMHANDLE pSSM)
SSMR3PutU32 (pSSM, HGSMIHeapOffset(&pIns->hostHeap));
SSMR3PutU32 (pSSM, HGSMIHeapSize(&pIns->hostHeap));
/* need save mem pointer to calculate offset on restore */
- SSMR3PutU64 (pSSM, (uint64_t)pIns->area.pu8Base);
+ SSMR3PutU64 (pSSM, (uint64_t)(uintptr_t)pIns->area.pu8Base);
rc = hgsmiFIFOLock (pIns);
if(RT_SUCCESS(rc))
{
@@ -1259,7 +1330,7 @@ int HGSMIHostSaveStateExec (PHGSMIINSTANCE pIns, PSSMHANDLE pSSM)
rc = hgsmiHostSaveFifoLocked (&pIns->hostFIFORead, pSSM); AssertRC(rc);
rc = hgsmiHostSaveFifoLocked (&pIns->hostFIFOProcessed, pSSM); AssertRC(rc);
#ifdef VBOX_WITH_WDDM
- rc = hgsmiHostSaveFifoLocked (&pIns->guestCmdCompleted, pSSM); AssertRC(rc);
+ rc = hgsmiHostSaveGuestCmdCompletedFifoLocked (&pIns->guestCmdCompleted, pSSM); AssertRC(rc);
#endif
hgsmiFIFOUnlock (pIns);
@@ -1326,7 +1397,7 @@ int HGSMIHostLoadStateExec (PHGSMIINSTANCE pIns, PSSMHANDLE pSSM, uint32_t u32Ve
rc = hgsmiHostLoadFifoLocked (pIns, &pIns->hostFIFOProcessed, pSSM);
#ifdef VBOX_WITH_WDDM
if (RT_SUCCESS(rc) && u32Version > VGA_SAVEDSTATE_VERSION_PRE_WDDM)
- rc = hgsmiHostLoadFifoLocked (pIns, &pIns->hostFIFOProcessed, pSSM);
+ rc = hgsmiHostLoadGuestCmdCompletedFifoLocked (pIns, &pIns->guestCmdCompleted, pSSM, u32Version);
#endif
hgsmiFIFOUnlock (pIns);
@@ -1729,6 +1800,12 @@ int hgsmiCompleteGuestCommand(PHGSMIINSTANCE pIns,
/* Now guest can read the FIFO, the notification is informational. */
hgsmiNotifyGuest (pIns);
}
+#ifdef DEBUG_misha
+ else
+ {
+ Assert(0);
+ }
+#endif
}
return rc;
}
@@ -1740,7 +1817,10 @@ int HGSMICompleteGuestCommand(PHGSMIINSTANCE pIns,
LogFlowFunc(("pIns = %p, pvMem = %p\n", pIns, pvMem));
int rc = VINF_SUCCESS;
- HGSMIOFFSET offBuffer = HGSMIHeapBufferOffset (&pIns->hostHeap, pvMem);
+
+ HGSMIBUFFERHEADER *pHeader = HGSMIBufferHeaderFromData(pvMem);
+ HGSMIOFFSET offBuffer = HGSMIPointerToOffset(&pIns->area, pHeader);
+
Assert(offBuffer != HGSMIOFFSET_VOID);
if (offBuffer != HGSMIOFFSET_VOID)
{