Changeset 49420 in vbox for trunk/src/VBox/Devices/Graphics
- Timestamp:
- Nov 8, 2013 3:54:02 PM (11 years ago)
- Location:
- trunk/src/VBox/Devices/Graphics
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Graphics/DevVGA.cpp
r48468 r49420 4965 4965 if (pThis->cMilliesRefreshInterval) 4966 4966 TMTimerSetMillies(pTimer, pThis->cMilliesRefreshInterval); 4967 4968 #ifdef VBOX_WITH_VIDEOHWACCEL 4969 vbvaTimerCb(pThis); 4970 #endif 4971 4967 4972 } 4968 4973 -
trunk/src/VBox/Devices/Graphics/DevVGA.h
r45808 r49420 64 64 #endif /* VBOX_WITH_HGSMI */ 65 65 #include "DevVGASavedState.h" 66 67 # include <iprt/list.h> 66 68 67 69 #define MSR_COLOR_EMULATION 0x01 … … 196 198 #endif 197 199 200 #ifdef VBOX_WITH_VIDEOHWACCEL 201 #define VBOX_VHWA_MAX_PENDING_COMMANDS 1000 202 203 typedef struct _VBOX_VHWA_PENDINGCMD 204 { 205 RTLISTNODE Node; 206 PVBOXVHWACMD pCommand; 207 } VBOX_VHWA_PENDINGCMD; 208 #endif 209 198 210 typedef struct VGAState { 199 211 #ifndef VBOX … … 420 432 # endif 421 433 # endif /* VBOX_WITH_HGSMI */ 434 435 struct { 436 uint32_t cPending; 437 uint32_t Padding1; 438 union 439 { 440 RTLISTNODE PendingList; 441 /* make sure the structure sized cross different contexts correctly */ 442 struct 443 { 444 R3PTRTYPE(void *) dummy1; 445 R3PTRTYPE(void *) dummy2; 446 } dummy; 447 }; 448 } pendingVhwaCommands; 422 449 #endif /* VBOX */ 423 450 } VGAState; … … 496 523 int vbvaVHWAReset (PVGASTATE pVGAState); 497 524 525 void vbvaTimerCb(PVGASTATE pVGAState); 526 498 527 int vboxVBVASaveStatePrep (PPDMDEVINS pDevIns, PSSMHANDLE pSSM); 499 528 int vboxVBVASaveStateDone (PPDMDEVINS pDevIns, PSSMHANDLE pSSM); -
trunk/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp
r49366 r49420 767 767 static VBOXVHWACMD* vbvaVHWAHHCommandCreate (PVGASTATE pVGAState, VBOXVHWACMD_TYPE enmCmd, int32_t iDisplay, VBOXVHWACMD_LENGTH cbCmd) 768 768 { 769 VBOXVHWACMD* pHdr = (VBOXVHWACMD*)RTMemAlloc (cbCmd + VBOXVHWACMD_HEADSIZE());769 VBOXVHWACMD* pHdr = (VBOXVHWACMD*)RTMemAllocZ(cbCmd + VBOXVHWACMD_HEADSIZE()); 770 770 Assert(pHdr); 771 771 if (pHdr) … … 789 789 } 790 790 791 static unsigned vbvaVHWAHandleCommand (PVGASTATE pVGAState, VBVACONTEXT *pCtx, PVBOXVHWACMD pCmd) 792 { 791 static void vbvaVHWACommandComplete(PVGASTATE pVGAState, PVBOXVHWACMD pCommand, bool fAsyncCommand) 792 { 793 if (fAsyncCommand) 794 { 795 Assert(pCommand->Flags & VBOXVHWACMD_FLAG_HG_ASYNCH); 796 vbvaVHWACommandCompleteAsynch(&pVGAState->IVBVACallbacks, pCommand); 797 } 798 else 799 { 800 Log(("VGA Command <<< Sync rc %d %#p, %d\n", pCommand->rc, pCommand, pCommand->enmCmd)); 801 pCommand->Flags &= (~VBOXVHWACMD_FLAG_HG_ASYNCH); 802 } 803 804 } 805 806 static void vbvaVHWACommandCompleteAllPending(PVGASTATE pVGAState, int rc) 807 { 808 if (!pVGAState->pendingVhwaCommands.cPending) 809 return; 810 811 VBOX_VHWA_PENDINGCMD *pIter, *pNext; 812 RTListForEachSafe(&pVGAState->pendingVhwaCommands.PendingList, pIter, pNext, VBOX_VHWA_PENDINGCMD, Node) 813 { 814 pIter->pCommand->rc = rc; 815 vbvaVHWACommandComplete(pVGAState, pIter->pCommand, true); 816 817 /* the command is submitted/processed, remove from the pend list */ 818 RTListNodeRemove(&pIter->Node); 819 --pVGAState->pendingVhwaCommands.cPending; 820 RTMemFree(pIter); 821 } 822 } 823 824 static void vbvaVHWACommandCClearAllPending(PVGASTATE pVGAState) 825 { 826 if (!pVGAState->pendingVhwaCommands.cPending) 827 return; 828 829 VBOX_VHWA_PENDINGCMD *pIter, *pNext; 830 RTListForEachSafe(&pVGAState->pendingVhwaCommands.PendingList, pIter, pNext, VBOX_VHWA_PENDINGCMD, Node) 831 { 832 RTListNodeRemove(&pIter->Node); 833 --pVGAState->pendingVhwaCommands.cPending; 834 RTMemFree(pIter); 835 } 836 } 837 838 static void vbvaVHWACommandPend(PVGASTATE pVGAState, PVBOXVHWACMD pCommand) 839 { 840 int rc = VERR_BUFFER_OVERFLOW; 841 842 if (pVGAState->pendingVhwaCommands.cPending < VBOX_VHWA_MAX_PENDING_COMMANDS) 843 { 844 VBOX_VHWA_PENDINGCMD *pPend = (VBOX_VHWA_PENDINGCMD*)RTMemAlloc(sizeof (*pPend)); 845 if (pPend) 846 { 847 pCommand->Flags |= VBOXVHWACMD_FLAG_HG_ASYNCH; 848 pPend->pCommand = pCommand; 849 RTListAppend(&pVGAState->pendingVhwaCommands.PendingList, &pPend->Node); 850 ++pVGAState->pendingVhwaCommands.cPending; 851 return; 852 } 853 else 854 rc = VERR_NO_MEMORY; 855 } 856 else 857 { 858 LogRel(("Pending command count has reached its threshold, completing them all..")); 859 } 860 861 vbvaVHWACommandCompleteAllPending(pVGAState, rc); 862 863 pCommand->rc = rc; 864 865 vbvaVHWACommandComplete(pVGAState, pCommand, false); 866 } 867 868 static bool vbvaVHWACommandCanPend(PVBOXVHWACMD pCommand) 869 { 870 switch (pCommand->enmCmd) 871 { 872 case VBOXVHWACMD_TYPE_HH_CONSTRUCT: 873 case VBOXVHWACMD_TYPE_HH_SAVESTATE_SAVEBEGIN: 874 case VBOXVHWACMD_TYPE_HH_SAVESTATE_SAVEEND: 875 case VBOXVHWACMD_TYPE_HH_SAVESTATE_SAVEPERFORM: 876 case VBOXVHWACMD_TYPE_HH_SAVESTATE_LOADPERFORM: 877 return false; 878 default: 879 return true; 880 } 881 } 882 883 static int vbvaVHWACommandSavePending(PVGASTATE pVGAState, PSSMHANDLE pSSM) 884 { 885 int rc = SSMR3PutU32(pSSM, pVGAState->pendingVhwaCommands.cPending); 886 AssertRCReturn(rc, rc); 887 VBOX_VHWA_PENDINGCMD *pIter; 888 RTListForEach(&pVGAState->pendingVhwaCommands.PendingList, pIter, VBOX_VHWA_PENDINGCMD, Node) 889 { 890 rc = SSMR3PutU32(pSSM, (uint32_t)(((uint8_t*)pIter->pCommand) - ((uint8_t*)pVGAState->vram_ptrR3))); 891 AssertRCReturn(rc, rc); 892 } 893 return rc; 894 } 895 896 static int vbvaVHWACommandLoadPending(PVGASTATE pVGAState, PSSMHANDLE pSSM, uint32_t u32Version) 897 { 898 if (u32Version < VGA_SAVEDSTATE_VERSION_WITH_PENDVHWA) 899 return VINF_SUCCESS; 900 901 int rc; 902 uint32_t u32; 903 rc = SSMR3GetU32(pSSM, &u32); 904 AssertRCReturn(rc, rc); 905 for (uint32_t i = 0; i < u32; ++i) 906 { 907 uint32_t off32; 908 rc = SSMR3GetU32(pSSM, &off32); 909 AssertRCReturn(rc, rc); 910 PVBOXVHWACMD pCommand = (PVBOXVHWACMD)(((uint8_t*)pVGAState->vram_ptrR3) + off32); 911 vbvaVHWACommandPend(pVGAState, pCommand); 912 } 913 return rc; 914 } 915 916 917 static bool vbvaVHWACommandSubmit(PVGASTATE pVGAState, PVBOXVHWACMD pCommand, bool fAsyncCommand) 918 { 919 unsigned id = (unsigned)pCommand->iDisplay; 920 int rc = VINF_SUCCESS; 921 bool fPend = false; 922 793 923 if (pVGAState->pDrv->pfnVHWACommandProcess) 794 pVGAState->pDrv->pfnVHWACommandProcess(pVGAState->pDrv, pCmd); 795 #ifdef DEBUG_misha 924 { 925 Log(("VGA Command >>> %#p, %d\n", pCommand, pCommand->enmCmd)); 926 int rc = pVGAState->pDrv->pfnVHWACommandProcess(pVGAState->pDrv, pCommand); 927 if (rc == VINF_CALLBACK_RETURN) 928 { 929 Log(("VGA Command --- Going Async %#p, %d\n", pCommand, pCommand->enmCmd)); 930 return true; /* command will be completed asynchronously, return right away */ 931 } 932 else if (rc == VERR_INVALID_STATE) 933 { 934 Log(("VGA Command --- Trying Pend %#p, %d\n", pCommand, pCommand->enmCmd)); 935 fPend = vbvaVHWACommandCanPend(pCommand); 936 if (!fPend) 937 { 938 Log(("VGA Command --- Can NOT Pend %#p, %d\n", pCommand, pCommand->enmCmd)); 939 pCommand->rc = rc; 940 } 941 else 942 Log(("VGA Command --- Can Pend %#p, %d\n", pCommand, pCommand->enmCmd)); 943 } 944 else 945 { 946 Log(("VGA Command --- Going Complete Sync rc %d %#p, %d\n", rc, pCommand, pCommand->enmCmd)); 947 pCommand->rc = rc; 948 } 949 950 /* the command was completed, take a special care about it (seee below) */ 951 } 796 952 else 953 { 797 954 AssertFailed(); 798 #endif 799 return 0; 955 pCommand->rc = VERR_INVALID_STATE; 956 } 957 958 if (fPend) 959 return false; 960 961 vbvaVHWACommandComplete(pVGAState, pCommand, fAsyncCommand); 962 963 return true; 964 } 965 966 static bool vbvaVHWACheckPendingCommands(PVGASTATE pVGAState) 967 { 968 if (!pVGAState->pendingVhwaCommands.cPending) 969 return true; 970 971 VBOX_VHWA_PENDINGCMD *pIter, *pNext; 972 RTListForEachSafe(&pVGAState->pendingVhwaCommands.PendingList, pIter, pNext, VBOX_VHWA_PENDINGCMD, Node) 973 { 974 if (!vbvaVHWACommandSubmit(pVGAState, pIter->pCommand, true)) 975 return false; /* the command should be pended still */ 976 977 /* the command is submitted/processed, remove from the pend list */ 978 RTListNodeRemove(&pIter->Node); 979 --pVGAState->pendingVhwaCommands.cPending; 980 RTMemFree(pIter); 981 } 982 983 return true; 984 } 985 986 void vbvaTimerCb(PVGASTATE pVGAState) 987 { 988 vbvaVHWACheckPendingCommands(pVGAState); 989 } 990 static void vbvaVHWAHandleCommand(PVGASTATE pVGAState, PVBOXVHWACMD pCmd) 991 { 992 if (vbvaVHWACheckPendingCommands(pVGAState)) 993 { 994 if (vbvaVHWACommandSubmit(pVGAState, pCmd, false)) 995 return; 996 } 997 998 vbvaVHWACommandPend(pVGAState, pCmd); 800 999 } 801 1000 … … 815 1014 vbvaVHWAHHCommandRetain (pCmd); 816 1015 VBOXVHWA_HH_CALLBACK_SET(pCmd, vbvaVHWAHHCommandSetEventCallback, (void*)hComplEvent); 817 vbvaVHWAHandleCommand(pVGAState, NULL,pCmd);1016 vbvaVHWAHandleCommand(pVGAState, pCmd); 818 1017 if((ASMAtomicReadU32((volatile uint32_t *)&pCmd->Flags) & VBOXVHWACMD_FLAG_HG_ASYNCH) != 0) 819 1018 { … … 837 1036 int vbvaVHWAConstruct (PVGASTATE pVGAState) 838 1037 { 1038 pVGAState->pendingVhwaCommands.cPending = 0; 1039 RTListInit(&pVGAState->pendingVhwaCommands.PendingList); 839 1040 VBOXVHWACMD *pCmd = vbvaVHWAHHCommandCreate(pVGAState, VBOXVHWACMD_TYPE_HH_CONSTRUCT, 0, sizeof(VBOXVHWACMD_HH_CONSTRUCT)); 840 1041 Assert(pCmd); … … 890 1091 int vbvaVHWAReset (PVGASTATE pVGAState) 891 1092 { 1093 vbvaVHWACommandCClearAllPending(pVGAState); 1094 892 1095 /* ensure we have all pending cmds processed and h->g cmds disabled */ 893 1096 VBOXVHWACMD *pCmd = vbvaVHWAHHCommandCreate(pVGAState, VBOXVHWACMD_TYPE_HH_RESET, 0, 0); … … 1009 1212 { 1010 1213 int rc; 1214 Log(("VGA Command <<< Async rc %d %#p, %d\n", pCmd->rc, pCmd, pCmd->enmCmd)); 1215 1011 1216 if((pCmd->Flags & VBOXVHWACMD_FLAG_HH_CMD) == 0) 1012 1217 { … … 1394 1599 if (RT_SUCCESS(rc)) 1395 1600 { 1601 rc = vbvaVHWACommandSavePending(pVGAState, pSSM); 1602 AssertRCReturn(rc, rc); 1603 1396 1604 vbvaVHWAHHCommandReinit(pCmd, VBOXVHWACMD_TYPE_HH_SAVESTATE_SAVEEND, 0); 1397 1605 vbvaVHWAHHPost (pVGAState, pCmd, vboxVBVASaveStateEndPreCb, NULL, &VhwaData); … … 1588 1796 vbvaVHWAHHPost (pVGAState, pCmd, vboxVBVALoadStatePerformPreCb, vboxVBVALoadStatePerformPostCb, &VhwaData); 1589 1797 rc = VhwaData.rc; 1590 AssertRC(rc);1591 1798 vbvaVHWAHHCommandRelease(pCmd); 1799 AssertRCReturn(rc, rc); 1800 1801 rc = vbvaVHWACommandLoadPending(pVGAState, pSSM, u32Version); 1802 AssertRCReturn(rc, rc); 1592 1803 } 1593 1804 else … … 1973 2184 case VBVA_VHWA_CMD: 1974 2185 { 1975 rc = vbvaVHWAHandleCommand (pVGAState, pCtx, (PVBOXVHWACMD)pvBuffer); 2186 if (cbBuffer < sizeof (VBOXVHWACMD)) 2187 { 2188 rc = VERR_INVALID_PARAMETER; 2189 break; 2190 } 2191 vbvaVHWAHandleCommand(pVGAState, (PVBOXVHWACMD)pvBuffer); 2192 rc = VINF_SUCCESS; 2193 break; 1976 2194 } break; 1977 2195 #endif
Note:
See TracChangeset
for help on using the changeset viewer.