Changeset 34140 in vbox for trunk/src/VBox/Devices/Graphics
- Timestamp:
- Nov 17, 2010 3:56:34 PM (14 years ago)
- svn:sync-xref-src-repo-rev:
- 67859
- Location:
- trunk/src/VBox/Devices/Graphics
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Graphics/DevVGASavedState.h
r33089 r34140 23 23 #define Graphics_DevVGASavedState_h 24 24 25 #define VGA_SAVEDSTATE_VERSION 725 #define VGA_SAVEDSTATE_VERSION 8 26 26 #define VGA_SAVEDSTATE_VERSION_WDDM 7 27 27 #define VGA_SAVEDSTATE_VERSION_PRE_WDDM 6 -
trunk/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp
r34129 r34140 726 726 #endif /* DEBUG_sunlover */ 727 727 728 int vboxVBVASaveStateExec (PPDMDEVINS pDevIns, PSSMHANDLE pSSM) 729 { 730 PVGASTATE pVGAState = PDMINS_2_DATA(pDevIns, PVGASTATE); 728 #define VBOXVBVASAVEDSTATE_VHWAAVAILABLE_MAGIC 0x12345678 729 #define VBOXVBVASAVEDSTATE_VHWAUNAVAILABLE_MAGIC 0x9abcdef0 730 731 #ifdef VBOX_WITH_VIDEOHWACCEL 732 static void vbvaVHWAHHCommandReinit(VBOXVHWACMD* pHdr, VBOXVHWACMD_TYPE enmCmd, int32_t iDisplay) 733 { 734 memset(pHdr, 0, VBOXVHWACMD_HEADSIZE()); 735 pHdr->cRefs = 1; 736 pHdr->iDisplay = iDisplay; 737 pHdr->rc = VERR_NOT_IMPLEMENTED; 738 pHdr->enmCmd = enmCmd; 739 pHdr->Flags = VBOXVHWACMD_FLAG_HH_CMD; 740 } 741 742 static VBOXVHWACMD* vbvaVHWAHHCommandCreate (PVGASTATE pVGAState, VBOXVHWACMD_TYPE enmCmd, int32_t iDisplay, VBOXVHWACMD_LENGTH cbCmd) 743 { 744 VBOXVHWACMD* pHdr = (VBOXVHWACMD*)RTMemAlloc(cbCmd + VBOXVHWACMD_HEADSIZE()); 745 Assert(pHdr); 746 if (pHdr) 747 vbvaVHWAHHCommandReinit(pHdr, enmCmd, iDisplay); 748 749 return pHdr; 750 } 751 752 DECLINLINE(void) vbvaVHWAHHCommandRelease (VBOXVHWACMD* pCmd) 753 { 754 uint32_t cRefs = ASMAtomicDecU32(&pCmd->cRefs); 755 if(!cRefs) 756 { 757 RTMemFree(pCmd); 758 } 759 } 760 761 DECLINLINE(void) vbvaVHWAHHCommandRetain (VBOXVHWACMD* pCmd) 762 { 763 ASMAtomicIncU32(&pCmd->cRefs); 764 } 765 766 static unsigned vbvaVHWAHandleCommand (PVGASTATE pVGAState, VBVACONTEXT *pCtx, PVBOXVHWACMD pCmd) 767 { 768 if (pVGAState->pDrv->pfnVHWACommandProcess) 769 pVGAState->pDrv->pfnVHWACommandProcess(pVGAState->pDrv, pCmd); 770 #ifdef DEBUG_misha 771 else 772 AssertFailed(); 773 #endif 774 return 0; 775 } 776 777 static DECLCALLBACK(void) vbvaVHWAHHCommandSetEventCallback(void * pContext) 778 { 779 RTSemEventSignal((RTSEMEVENT)pContext); 780 } 781 782 static int vbvaVHWAHHCommandPost(PVGASTATE pVGAState, VBOXVHWACMD* pCmd) 783 { 784 RTSEMEVENT hComplEvent; 785 int rc = RTSemEventCreate(&hComplEvent); 786 AssertRC(rc); 787 if(RT_SUCCESS(rc)) 788 { 789 /* ensure the cmd is not deleted until we process it */ 790 vbvaVHWAHHCommandRetain (pCmd); 791 VBOXVHWA_HH_CALLBACK_SET(pCmd, vbvaVHWAHHCommandSetEventCallback, (void*)hComplEvent); 792 vbvaVHWAHandleCommand(pVGAState, NULL, pCmd); 793 if((ASMAtomicReadU32((volatile uint32_t *)&pCmd->Flags) & VBOXVHWACMD_FLAG_HG_ASYNCH) != 0) 794 { 795 rc = RTSemEventWaitNoResume(hComplEvent, RT_INDEFINITE_WAIT); 796 } 797 else 798 { 799 /* the command is completed */ 800 } 801 802 AssertRC(rc); 803 if(RT_SUCCESS(rc)) 804 { 805 RTSemEventDestroy(hComplEvent); 806 } 807 vbvaVHWAHHCommandRelease(pCmd); 808 } 809 return rc; 810 } 811 812 int vbvaVHWAConstruct (PVGASTATE pVGAState) 813 { 814 VBOXVHWACMD *pCmd = vbvaVHWAHHCommandCreate(pVGAState, VBOXVHWACMD_TYPE_HH_CONSTRUCT, 0, sizeof(VBOXVHWACMD_HH_CONSTRUCT)); 815 Assert(pCmd); 816 if(pCmd) 817 { 818 uint32_t iDisplay = 0; 819 int rc = VINF_SUCCESS; 820 VBOXVHWACMD_HH_CONSTRUCT * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_HH_CONSTRUCT); 821 822 do 823 { 824 memset(pBody, 0, sizeof(VBOXVHWACMD_HH_CONSTRUCT)); 825 826 PPDMDEVINS pDevIns = pVGAState->pDevInsR3; 827 PVM pVM = PDMDevHlpGetVM(pDevIns); 828 829 pBody->pVM = pVM; 830 pBody->pvVRAM = pVGAState->vram_ptrR3; 831 pBody->cbVRAM = pVGAState->vram_size; 832 833 rc = vbvaVHWAHHCommandPost(pVGAState, pCmd); 834 AssertRC(rc); 835 if(RT_SUCCESS(rc)) 836 { 837 rc = pCmd->rc; 838 AssertMsg(RT_SUCCESS(rc) || rc == VERR_NOT_IMPLEMENTED, ("%Rrc\n", rc)); 839 if(rc == VERR_NOT_IMPLEMENTED) 840 { 841 /* @todo: set some flag in pVGAState indicating VHWA is not supported */ 842 /* VERR_NOT_IMPLEMENTED is not a failure, we just do not support it */ 843 rc = VINF_SUCCESS; 844 } 845 846 if (!RT_SUCCESS(rc)) 847 break; 848 } 849 else 850 break; 851 852 ++iDisplay; 853 if (iDisplay >= pVGAState->cMonitors) 854 break; 855 vbvaVHWAHHCommandReinit(pCmd, VBOXVHWACMD_TYPE_HH_CONSTRUCT, (int32_t)iDisplay); 856 } while (true); 857 858 vbvaVHWAHHCommandRelease(pCmd); 859 860 return rc; 861 } 862 return VERR_OUT_OF_RESOURCES; 863 } 864 865 int vbvaVHWAReset (PVGASTATE pVGAState) 866 { 867 /* ensure we have all pending cmds processed and h->g cmds disabled */ 868 VBOXVHWACMD *pCmd = vbvaVHWAHHCommandCreate(pVGAState, VBOXVHWACMD_TYPE_HH_RESET, 0, 0); 869 Assert(pCmd); 870 if(pCmd) 871 { 872 int rc = VINF_SUCCESS; 873 uint32_t iDisplay = 0; 874 875 do 876 { 877 rc =vbvaVHWAHHCommandPost(pVGAState, pCmd); 878 AssertRC(rc); 879 if(RT_SUCCESS(rc)) 880 { 881 rc = pCmd->rc; 882 AssertMsg(RT_SUCCESS(rc) || rc == VERR_NOT_IMPLEMENTED, ("%Rrc\n", rc)); 883 if (rc == VERR_NOT_IMPLEMENTED) 884 rc = VINF_SUCCESS; 885 } 886 887 if (!RT_SUCCESS(rc)) 888 break; 889 890 ++iDisplay; 891 if (iDisplay >= pVGAState->cMonitors) 892 break; 893 vbvaVHWAHHCommandReinit(pCmd, VBOXVHWACMD_TYPE_HH_RESET, (int32_t)iDisplay); 894 895 } while (true); 896 897 vbvaVHWAHHCommandRelease(pCmd); 898 899 return rc; 900 } 901 return VERR_OUT_OF_RESOURCES; 902 } 903 904 typedef DECLCALLBACK(bool) FNVBOXVHWAHHCMDPRECB(PVGASTATE pVGAState, VBOXVHWACMD *pCmd, uint32_t iDisplay, void *pvContext); 905 typedef FNVBOXVHWAHHCMDPRECB *PFNVBOXVHWAHHCMDPRECB; 906 907 typedef DECLCALLBACK(bool) FNVBOXVHWAHHCMDPOSTCB(PVGASTATE pVGAState, VBOXVHWACMD *pCmd, uint32_t iDisplay, int rc, void *pvContext); 908 typedef FNVBOXVHWAHHCMDPOSTCB *PFNVBOXVHWAHHCMDPOSTCB; 909 910 int vbvaVHWAHHPost(PVGASTATE pVGAState, VBOXVHWACMD *pCmd, PFNVBOXVHWAHHCMDPRECB pfnPre, PFNVBOXVHWAHHCMDPOSTCB pfnPost, void *pvContext) 911 { 912 const VBOXVHWACMD_TYPE enmType = pCmd->enmCmd; 913 int rc = VINF_SUCCESS; 914 uint32_t iDisplay = 0; 915 916 do 917 { 918 if (!pfnPre || pfnPre(pVGAState, pCmd, iDisplay, pvContext)) 919 { 920 rc = vbvaVHWAHHCommandPost(pVGAState, pCmd); 921 AssertRC(rc); 922 if (pfnPost) 923 { 924 if (!pfnPost(pVGAState, pCmd, iDisplay, rc, pvContext)) 925 { 926 rc = VINF_SUCCESS; 927 break; 928 } 929 rc = VINF_SUCCESS; 930 } 931 else if(RT_SUCCESS(rc)) 932 { 933 rc = pCmd->rc; 934 AssertMsg(RT_SUCCESS(rc) || rc == VERR_NOT_IMPLEMENTED, ("%Rrc\n", rc)); 935 if(rc == VERR_NOT_IMPLEMENTED) 936 { 937 rc = VINF_SUCCESS; 938 } 939 } 940 941 if (!RT_SUCCESS(rc)) 942 break; 943 } 944 945 ++iDisplay; 946 if (iDisplay >= pVGAState->cMonitors) 947 break; 948 vbvaVHWAHHCommandReinit(pCmd, enmType, (int32_t)iDisplay); 949 } while (true); 950 951 return rc; 952 } 953 954 /* @todo call this also on reset? */ 955 int vbvaVHWAEnable (PVGASTATE pVGAState, bool bEnable) 956 { 957 const VBOXVHWACMD_TYPE enmType = bEnable ? VBOXVHWACMD_TYPE_HH_ENABLE : VBOXVHWACMD_TYPE_HH_DISABLE; 958 VBOXVHWACMD *pCmd = vbvaVHWAHHCommandCreate(pVGAState, 959 enmType, 960 0, 0); 961 Assert(pCmd); 962 if(pCmd) 963 { 964 int rc = vbvaVHWAHHPost (pVGAState, pCmd, NULL, NULL, NULL); 965 vbvaVHWAHHCommandRelease(pCmd); 966 return rc; 967 } 968 return VERR_OUT_OF_RESOURCES; 969 } 970 971 int vboxVBVASaveStatePrep (PPDMDEVINS pDevIns, PSSMHANDLE pSSM) 972 { 973 /* ensure we have no pending commands */ 974 return vbvaVHWAEnable(PDMINS_2_DATA(pDevIns, PVGASTATE), false); 975 } 976 977 int vboxVBVASaveStateDone (PPDMDEVINS pDevIns, PSSMHANDLE pSSM) 978 { 979 /* ensure we have no pending commands */ 980 return vbvaVHWAEnable(PDMINS_2_DATA(pDevIns, PVGASTATE), true); 981 } 982 983 int vbvaVHWACommandCompleteAsynch(PPDMIDISPLAYVBVACALLBACKS pInterface, PVBOXVHWACMD pCmd) 984 { 985 int rc; 986 if((pCmd->Flags & VBOXVHWACMD_FLAG_HH_CMD) == 0) 987 { 988 PVGASTATE pVGAState = PPDMIDISPLAYVBVACALLBACKS_2_PVGASTATE(pInterface); 989 PHGSMIINSTANCE pIns = pVGAState->pHGSMI; 990 991 Assert(pCmd->Flags & VBOXVHWACMD_FLAG_HG_ASYNCH); 992 #ifdef VBOX_WITH_WDDM 993 if (pVGAState->fGuestCaps & VBVACAPS_COMPLETEGCMD_BY_IOREAD) 994 { 995 rc = HGSMICompleteGuestCommand(pIns, pCmd, !!(pCmd->Flags & VBOXVHWACMD_FLAG_GH_ASYNCH_IRQ)); 996 AssertRC(rc); 997 } 998 else 999 #endif 1000 { 1001 VBVAHOSTCMD *pHostCmd; 1002 int32_t iDisplay = pCmd->iDisplay; 1003 1004 if(pCmd->Flags & VBOXVHWACMD_FLAG_GH_ASYNCH_EVENT) 1005 { 1006 rc = HGSMIHostCommandAlloc (pIns, 1007 (void**)&pHostCmd, 1008 VBVAHOSTCMD_SIZE(sizeof(VBVAHOSTCMDEVENT)), 1009 HGSMI_CH_VBVA, 1010 VBVAHG_EVENT); 1011 AssertRC(rc); 1012 if(RT_SUCCESS(rc)) 1013 { 1014 memset(pHostCmd, 0 , VBVAHOSTCMD_SIZE(sizeof(VBVAHOSTCMDEVENT))); 1015 pHostCmd->iDstID = pCmd->iDisplay; 1016 pHostCmd->customOpCode = 0; 1017 VBVAHOSTCMDEVENT *pBody = VBVAHOSTCMD_BODY(pHostCmd, VBVAHOSTCMDEVENT); 1018 pBody->pEvent = pCmd->GuestVBVAReserved1; 1019 } 1020 } 1021 else 1022 { 1023 HGSMIOFFSET offCmd = HGSMIPointerToOffsetHost (pIns, pCmd); 1024 Assert(offCmd != HGSMIOFFSET_VOID); 1025 if(offCmd != HGSMIOFFSET_VOID) 1026 { 1027 rc = HGSMIHostCommandAlloc (pIns, 1028 (void**)&pHostCmd, 1029 VBVAHOSTCMD_SIZE(sizeof(VBVAHOSTCMDVHWACMDCOMPLETE)), 1030 HGSMI_CH_VBVA, 1031 VBVAHG_DISPLAY_CUSTOM); 1032 AssertRC(rc); 1033 if(RT_SUCCESS(rc)) 1034 { 1035 memset(pHostCmd, 0 , VBVAHOSTCMD_SIZE(sizeof(VBVAHOSTCMDVHWACMDCOMPLETE))); 1036 pHostCmd->iDstID = pCmd->iDisplay; 1037 pHostCmd->customOpCode = VBVAHG_DCUSTOM_VHWA_CMDCOMPLETE; 1038 VBVAHOSTCMDVHWACMDCOMPLETE *pBody = VBVAHOSTCMD_BODY(pHostCmd, VBVAHOSTCMDVHWACMDCOMPLETE); 1039 pBody->offCmd = offCmd; 1040 } 1041 } 1042 else 1043 { 1044 rc = VERR_INVALID_PARAMETER; 1045 } 1046 } 1047 1048 if(RT_SUCCESS(rc)) 1049 { 1050 rc = HGSMIHostCommandProcessAndFreeAsynch(pIns, pHostCmd, (pCmd->Flags & VBOXVHWACMD_FLAG_GH_ASYNCH_IRQ) != 0); 1051 AssertRC(rc); 1052 if(RT_SUCCESS(rc)) 1053 { 1054 return rc; 1055 } 1056 HGSMIHostCommandFree (pIns, pHostCmd); 1057 } 1058 } 1059 } 1060 else 1061 { 1062 PFNVBOXVHWA_HH_CALLBACK pfn = VBOXVHWA_HH_CALLBACK_GET(pCmd); 1063 if(pfn) 1064 { 1065 pfn(VBOXVHWA_HH_CALLBACK_GET_ARG(pCmd)); 1066 } 1067 rc = VINF_SUCCESS; 1068 } 1069 return rc; 1070 } 1071 1072 typedef struct VBOXVBVASAVEDSTATECBDATA 1073 { 1074 PSSMHANDLE pSSM; 1075 int rc; 1076 bool ab2DOn[VBOX_VIDEO_MAX_SCREENS]; 1077 } VBOXVBVASAVEDSTATECBDATA, *PVBOXVBVASAVEDSTATECBDATA; 1078 1079 static DECLCALLBACK(bool) vboxVBVASaveStateBeginPostCb(PVGASTATE pVGAState, VBOXVHWACMD *pCmd, uint32_t iDisplay, int rc, void *pvContext) 1080 { 1081 PVBOXVBVASAVEDSTATECBDATA pData = (PVBOXVBVASAVEDSTATECBDATA)pvContext; 1082 if (RT_FAILURE(pData->rc)) 1083 return false; 1084 if (RT_FAILURE(rc)) 1085 { 1086 pData->rc = rc; 1087 return false; 1088 } 1089 1090 Assert(iDisplay < RT_ELEMENTS(pData->ab2DOn)); 1091 if (iDisplay >= RT_ELEMENTS(pData->ab2DOn)) 1092 { 1093 pData->rc = VERR_INVALID_PARAMETER; 1094 return false; 1095 } 1096 1097 Assert(RT_SUCCESS(pCmd->rc) || pCmd->rc == VERR_NOT_IMPLEMENTED); 1098 if (RT_SUCCESS(pCmd->rc)) 1099 { 1100 pData->ab2DOn[iDisplay] = true; 1101 } 1102 else if (pCmd->rc != VERR_NOT_IMPLEMENTED) 1103 { 1104 pData->rc = pCmd->rc; 1105 return false; 1106 } 1107 1108 return true; 1109 } 1110 1111 static DECLCALLBACK(bool) vboxVBVASaveStatePerformPreCb(PVGASTATE pVGAState, VBOXVHWACMD *pCmd, uint32_t iDisplay, void *pvContext) 1112 { 1113 PVBOXVBVASAVEDSTATECBDATA pData = (PVBOXVBVASAVEDSTATECBDATA)pvContext; 1114 if (RT_FAILURE(pData->rc)) 1115 return false; 1116 1117 Assert(iDisplay < RT_ELEMENTS(pData->ab2DOn)); 1118 if (iDisplay >= RT_ELEMENTS(pData->ab2DOn)) 1119 { 1120 pData->rc = VERR_INVALID_PARAMETER; 1121 return false; 1122 } 1123 1124 int rc; 1125 1126 if (pData->ab2DOn[iDisplay]) 1127 { 1128 rc = SSMR3PutU32 (pData->pSSM, VBOXVBVASAVEDSTATE_VHWAAVAILABLE_MAGIC); AssertRC(rc); 1129 if (RT_FAILURE(rc)) 1130 { 1131 pData->rc = rc; 1132 return false; 1133 } 1134 return true; 1135 } 1136 1137 rc = SSMR3PutU32 (pData->pSSM, VBOXVBVASAVEDSTATE_VHWAUNAVAILABLE_MAGIC); AssertRC(rc); 1138 if (RT_FAILURE(rc)) 1139 { 1140 pData->rc = rc; 1141 return false; 1142 } 1143 1144 return false; 1145 } 1146 1147 static DECLCALLBACK(bool) vboxVBVASaveStateEndPreCb(PVGASTATE pVGAState, VBOXVHWACMD *pCmd, uint32_t iDisplay, void *pvContext) 1148 { 1149 PVBOXVBVASAVEDSTATECBDATA pData = (PVBOXVBVASAVEDSTATECBDATA)pvContext; 1150 Assert(iDisplay < RT_ELEMENTS(pData->ab2DOn)); 1151 if (pData->ab2DOn[iDisplay]) 1152 { 1153 return true; 1154 } 1155 1156 return false; 1157 } 1158 1159 static DECLCALLBACK(bool) vboxVBVALoadStatePerformPostCb(PVGASTATE pVGAState, VBOXVHWACMD *pCmd, uint32_t iDisplay, int rc, void *pvContext) 1160 { 1161 PVBOXVBVASAVEDSTATECBDATA pData = (PVBOXVBVASAVEDSTATECBDATA)pvContext; 1162 if (RT_FAILURE(pData->rc)) 1163 return false; 1164 if (RT_FAILURE(rc)) 1165 { 1166 pData->rc = rc; 1167 return false; 1168 } 1169 1170 Assert(iDisplay < RT_ELEMENTS(pData->ab2DOn)); 1171 if (iDisplay >= RT_ELEMENTS(pData->ab2DOn)) 1172 { 1173 pData->rc = VERR_INVALID_PARAMETER; 1174 return false; 1175 } 1176 1177 Assert(RT_SUCCESS(pCmd->rc) || pCmd->rc == VERR_NOT_IMPLEMENTED); 1178 if (pCmd->rc == VERR_NOT_IMPLEMENTED) 1179 { 1180 pData->rc = SSMR3SkipToEndOfUnit(pData->pSSM); 1181 AssertRC(pData->rc); 1182 return false; 1183 } 1184 if (RT_FAILURE(pCmd->rc)) 1185 { 1186 pData->rc = pCmd->rc; 1187 return false; 1188 } 1189 1190 return true; 1191 } 1192 1193 static DECLCALLBACK(bool) vboxVBVALoadStatePerformPreCb(PVGASTATE pVGAState, VBOXVHWACMD *pCmd, uint32_t iDisplay, void *pvContext) 1194 { 1195 PVBOXVBVASAVEDSTATECBDATA pData = (PVBOXVBVASAVEDSTATECBDATA)pvContext; 1196 if (RT_FAILURE(pData->rc)) 1197 return false; 1198 1199 Assert(iDisplay < RT_ELEMENTS(pData->ab2DOn)); 1200 if (iDisplay >= RT_ELEMENTS(pData->ab2DOn)) 1201 { 1202 pData->rc = VERR_INVALID_PARAMETER; 1203 return false; 1204 } 1205 1206 int rc; 1207 uint32_t u32; 1208 rc = SSMR3GetU32(pData->pSSM, &u32); AssertRC(rc); 1209 if (RT_FAILURE(rc)) 1210 { 1211 pData->rc = rc; 1212 return false; 1213 } 1214 1215 switch (u32) 1216 { 1217 case VBOXVBVASAVEDSTATE_VHWAAVAILABLE_MAGIC: 1218 return true; 1219 case VBOXVBVASAVEDSTATE_VHWAUNAVAILABLE_MAGIC: 1220 return false; 1221 default: 1222 pData->rc = VERR_INVALID_STATE; 1223 return false; 1224 } 1225 } 1226 #endif /* #ifdef VBOX_WITH_VIDEOHWACCEL */ 1227 1228 int vboxVBVASaveDevStateExec (PVGASTATE pVGAState, PSSMHANDLE pSSM) 1229 { 731 1230 PHGSMIINSTANCE pIns = pVGAState->pHGSMI; 732 733 1231 int rc = HGSMIHostSaveStateExec (pIns, pSSM); 734 1232 if (RT_SUCCESS(rc)) … … 832 1330 } 833 1331 1332 int vboxVBVASaveStateExec (PPDMDEVINS pDevIns, PSSMHANDLE pSSM) 1333 { 1334 PVGASTATE pVGAState = PDMINS_2_DATA(pDevIns, PVGASTATE); 1335 int rc; 1336 #ifdef VBOX_WITH_VIDEOHWACCEL 1337 VBOXVBVASAVEDSTATECBDATA VhwaData = {0}; 1338 VhwaData.pSSM = pSSM; 1339 uint32_t cbCmd = sizeof (VBOXVHWACMD_HH_SAVESTATE_SAVEPERFORM); /* maximum cmd size */ 1340 VBOXVHWACMD *pCmd = vbvaVHWAHHCommandCreate(pVGAState, VBOXVHWACMD_TYPE_HH_SAVESTATE_SAVEBEGIN, 0, cbCmd); 1341 Assert(pCmd); 1342 if(pCmd) 1343 { 1344 vbvaVHWAHHPost (pVGAState, pCmd, NULL, vboxVBVASaveStateBeginPostCb, &VhwaData); 1345 rc = VhwaData.rc; 1346 AssertRC(rc); 1347 if (RT_SUCCESS(rc)) 1348 { 1349 #endif 1350 rc = vboxVBVASaveDevStateExec (pVGAState, pSSM); 1351 AssertRC(rc); 1352 #ifdef VBOX_WITH_VIDEOHWACCEL 1353 if (RT_SUCCESS(rc)) 1354 { 1355 vbvaVHWAHHCommandReinit(pCmd, VBOXVHWACMD_TYPE_HH_SAVESTATE_SAVEPERFORM, 0); 1356 VBOXVHWACMD_HH_SAVESTATE_SAVEPERFORM *pSave = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_HH_SAVESTATE_SAVEPERFORM); 1357 pSave->pSSM = pSSM; 1358 vbvaVHWAHHPost (pVGAState, pCmd, vboxVBVASaveStatePerformPreCb, NULL, &VhwaData); 1359 rc = VhwaData.rc; 1360 AssertRC(rc); 1361 if (RT_SUCCESS(rc)) 1362 { 1363 vbvaVHWAHHCommandReinit(pCmd, VBOXVHWACMD_TYPE_HH_SAVESTATE_SAVEEND, 0); 1364 vbvaVHWAHHPost (pVGAState, pCmd, vboxVBVASaveStateEndPreCb, NULL, &VhwaData); 1365 rc = VhwaData.rc; 1366 AssertRC(rc); 1367 } 1368 } 1369 } 1370 1371 vbvaVHWAHHCommandRelease(pCmd); 1372 return rc; 1373 } 1374 #else 1375 for (UINT i = 0; i < pVGAState->cMonitors; ++i) 1376 { 1377 rc = SSMR3PutU32 (pSSM, VBOXVBVASAVEDSTATE_VHWAUNAVAILABLE_MAGIC); 1378 AssertRCReturn(rc, rc); 1379 } 1380 #endif 1381 return VERR_OUT_OF_RESOURCES; 1382 } 1383 834 1384 int vboxVBVALoadStateExec (PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t u32Version) 835 1385 { … … 980 1530 LogFlowFunc(("%d views loaded\n", pCtx->cViews)); 981 1531 1532 if (u32Version > VGA_SAVEDSTATE_VERSION_WDDM) 1533 { 1534 #ifdef VBOX_WITH_VIDEOHWACCEL 1535 uint32_t cbCmd = sizeof (VBOXVHWACMD_HH_SAVESTATE_LOADPERFORM); /* maximum cmd size */ 1536 VBOXVHWACMD *pCmd = vbvaVHWAHHCommandCreate(pVGAState, VBOXVHWACMD_TYPE_HH_SAVESTATE_LOADPERFORM, 0, cbCmd); 1537 Assert(pCmd); 1538 if(pCmd) 1539 { 1540 VBOXVBVASAVEDSTATECBDATA VhwaData = {0}; 1541 VhwaData.pSSM = pSSM; 1542 VBOXVHWACMD_HH_SAVESTATE_LOADPERFORM *pLoad = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_HH_SAVESTATE_LOADPERFORM); 1543 pLoad->pSSM = pSSM; 1544 vbvaVHWAHHPost (pVGAState, pCmd, vboxVBVALoadStatePerformPreCb, vboxVBVALoadStatePerformPostCb, &VhwaData); 1545 rc = VhwaData.rc; 1546 AssertRC(rc); 1547 vbvaVHWAHHCommandRelease(pCmd); 1548 } 1549 else 1550 { 1551 rc = VERR_OUT_OF_RESOURCES; 1552 } 1553 #else 1554 rc = SSMR3SkipToEndOfUnit(pSSM); 1555 AssertRCReturn(rc, rc); 1556 #endif 1557 } 1558 982 1559 #ifdef DEBUG_sunlover 983 1560 dumpctx(pCtx); … … 1016 1593 return VINF_SUCCESS; 1017 1594 } 1018 1019 #ifdef VBOX_WITH_VIDEOHWACCEL1020 static void vbvaVHWAHHCommandReinit(VBOXVHWACMD* pHdr, VBOXVHWACMD_TYPE enmCmd, int32_t iDisplay)1021 {1022 memset(pHdr, 0, VBOXVHWACMD_HEADSIZE());1023 pHdr->cRefs = 1;1024 pHdr->iDisplay = iDisplay;1025 pHdr->rc = VERR_NOT_IMPLEMENTED;1026 pHdr->enmCmd = enmCmd;1027 pHdr->Flags = VBOXVHWACMD_FLAG_HH_CMD;1028 }1029 1030 static VBOXVHWACMD* vbvaVHWAHHCommandCreate (PVGASTATE pVGAState, VBOXVHWACMD_TYPE enmCmd, int32_t iDisplay, VBOXVHWACMD_LENGTH cbCmd)1031 {1032 VBOXVHWACMD* pHdr = (VBOXVHWACMD*)RTMemAlloc(cbCmd + VBOXVHWACMD_HEADSIZE());1033 Assert(pHdr);1034 if (pHdr)1035 vbvaVHWAHHCommandReinit(pHdr, enmCmd, iDisplay);1036 1037 return pHdr;1038 }1039 1040 DECLINLINE(void) vbvaVHWAHHCommandRelease (VBOXVHWACMD* pCmd)1041 {1042 uint32_t cRefs = ASMAtomicDecU32(&pCmd->cRefs);1043 if(!cRefs)1044 {1045 RTMemFree(pCmd);1046 }1047 }1048 1049 DECLINLINE(void) vbvaVHWAHHCommandRetain (VBOXVHWACMD* pCmd)1050 {1051 ASMAtomicIncU32(&pCmd->cRefs);1052 }1053 1054 static unsigned vbvaVHWAHandleCommand (PVGASTATE pVGAState, VBVACONTEXT *pCtx, PVBOXVHWACMD pCmd)1055 {1056 if (pVGAState->pDrv->pfnVHWACommandProcess)1057 pVGAState->pDrv->pfnVHWACommandProcess(pVGAState->pDrv, pCmd);1058 #ifdef DEBUG_misha1059 else1060 AssertFailed();1061 #endif1062 return 0;1063 }1064 1065 static DECLCALLBACK(void) vbvaVHWAHHCommandSetEventCallback(void * pContext)1066 {1067 RTSemEventSignal((RTSEMEVENT)pContext);1068 }1069 1070 static int vbvaVHWAHHCommandPost(PVGASTATE pVGAState, VBOXVHWACMD* pCmd)1071 {1072 RTSEMEVENT hComplEvent;1073 int rc = RTSemEventCreate(&hComplEvent);1074 AssertRC(rc);1075 if(RT_SUCCESS(rc))1076 {1077 /* ensure the cmd is not deleted until we process it */1078 vbvaVHWAHHCommandRetain (pCmd);1079 VBOXVHWA_HH_CALLBACK_SET(pCmd, vbvaVHWAHHCommandSetEventCallback, (void*)hComplEvent);1080 vbvaVHWAHandleCommand(pVGAState, NULL, pCmd);1081 if((ASMAtomicReadU32((volatile uint32_t *)&pCmd->Flags) & VBOXVHWACMD_FLAG_HG_ASYNCH) != 0)1082 {1083 rc = RTSemEventWaitNoResume(hComplEvent, RT_INDEFINITE_WAIT);1084 }1085 else1086 {1087 /* the command is completed */1088 }1089 1090 AssertRC(rc);1091 if(RT_SUCCESS(rc))1092 {1093 RTSemEventDestroy(hComplEvent);1094 }1095 vbvaVHWAHHCommandRelease(pCmd);1096 }1097 return rc;1098 }1099 1100 int vbvaVHWAConstruct (PVGASTATE pVGAState)1101 {1102 VBOXVHWACMD *pCmd = vbvaVHWAHHCommandCreate(pVGAState, VBOXVHWACMD_TYPE_HH_CONSTRUCT, 0, sizeof(VBOXVHWACMD_HH_CONSTRUCT));1103 Assert(pCmd);1104 if(pCmd)1105 {1106 uint32_t iDisplay = 0;1107 int rc = VINF_SUCCESS;1108 VBOXVHWACMD_HH_CONSTRUCT * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_HH_CONSTRUCT);1109 1110 do1111 {1112 memset(pBody, 0, sizeof(VBOXVHWACMD_HH_CONSTRUCT));1113 1114 PPDMDEVINS pDevIns = pVGAState->pDevInsR3;1115 PVM pVM = PDMDevHlpGetVM(pDevIns);1116 1117 pBody->pVM = pVM;1118 pBody->pvVRAM = pVGAState->vram_ptrR3;1119 pBody->cbVRAM = pVGAState->vram_size;1120 1121 rc = vbvaVHWAHHCommandPost(pVGAState, pCmd);1122 AssertRC(rc);1123 if(RT_SUCCESS(rc))1124 {1125 rc = pCmd->rc;1126 AssertMsg(RT_SUCCESS(rc) || rc == VERR_NOT_IMPLEMENTED, ("%Rrc\n", rc));1127 if(rc == VERR_NOT_IMPLEMENTED)1128 {1129 /* @todo: set some flag in pVGAState indicating VHWA is not supported */1130 /* VERR_NOT_IMPLEMENTED is not a failure, we just do not support it */1131 rc = VINF_SUCCESS;1132 }1133 1134 if (!RT_SUCCESS(rc))1135 break;1136 }1137 else1138 break;1139 1140 ++iDisplay;1141 if (iDisplay >= pVGAState->cMonitors)1142 break;1143 vbvaVHWAHHCommandReinit(pCmd, VBOXVHWACMD_TYPE_HH_CONSTRUCT, (int32_t)iDisplay);1144 } while (true);1145 1146 vbvaVHWAHHCommandRelease(pCmd);1147 1148 return rc;1149 }1150 return VERR_OUT_OF_RESOURCES;1151 }1152 1153 int vbvaVHWAReset (PVGASTATE pVGAState)1154 {1155 /* ensure we have all pending cmds processed and h->g cmds disabled */1156 VBOXVHWACMD *pCmd = vbvaVHWAHHCommandCreate(pVGAState, VBOXVHWACMD_TYPE_HH_RESET, 0, 0);1157 Assert(pCmd);1158 if(pCmd)1159 {1160 int rc = VINF_SUCCESS;1161 uint32_t iDisplay = 0;1162 1163 do1164 {1165 rc =vbvaVHWAHHCommandPost(pVGAState, pCmd);1166 AssertRC(rc);1167 if(RT_SUCCESS(rc))1168 {1169 rc = pCmd->rc;1170 AssertMsg(RT_SUCCESS(rc) || rc == VERR_NOT_IMPLEMENTED, ("%Rrc\n", rc));1171 if (rc == VERR_NOT_IMPLEMENTED)1172 rc = VINF_SUCCESS;1173 }1174 1175 if (!RT_SUCCESS(rc))1176 break;1177 1178 ++iDisplay;1179 if (iDisplay >= pVGAState->cMonitors)1180 break;1181 vbvaVHWAHHCommandReinit(pCmd, VBOXVHWACMD_TYPE_HH_RESET, (int32_t)iDisplay);1182 1183 } while (true);1184 1185 vbvaVHWAHHCommandRelease(pCmd);1186 1187 return rc;1188 }1189 return VERR_OUT_OF_RESOURCES;1190 }1191 1192 /* @todo call this also on reset? */1193 int vbvaVHWAEnable (PVGASTATE pVGAState, bool bEnable)1194 {1195 const VBOXVHWACMD_TYPE enmType = bEnable ? VBOXVHWACMD_TYPE_HH_ENABLE : VBOXVHWACMD_TYPE_HH_DISABLE;1196 VBOXVHWACMD *pCmd = vbvaVHWAHHCommandCreate(pVGAState,1197 enmType,1198 0, 0);1199 Assert(pCmd);1200 if(pCmd)1201 {1202 int rc = VINF_SUCCESS;1203 uint32_t iDisplay = 0;1204 1205 do1206 {1207 rc = vbvaVHWAHHCommandPost(pVGAState, pCmd);1208 AssertRC(rc);1209 if(RT_SUCCESS(rc))1210 {1211 rc = pCmd->rc;1212 AssertMsg(RT_SUCCESS(rc) || rc == VERR_NOT_IMPLEMENTED, ("%Rrc\n", rc));1213 if(rc == VERR_NOT_IMPLEMENTED)1214 {1215 rc = VINF_SUCCESS;1216 }1217 }1218 1219 if (!RT_SUCCESS(rc))1220 break;1221 1222 ++iDisplay;1223 if (iDisplay >= pVGAState->cMonitors)1224 break;1225 vbvaVHWAHHCommandReinit(pCmd, enmType, (int32_t)iDisplay);1226 1227 } while (true);1228 1229 vbvaVHWAHHCommandRelease(pCmd);1230 1231 return rc;1232 }1233 return VERR_OUT_OF_RESOURCES;1234 }1235 1236 int vboxVBVASaveStatePrep (PPDMDEVINS pDevIns, PSSMHANDLE pSSM)1237 {1238 /* ensure we have no pending commands */1239 return vbvaVHWAEnable(PDMINS_2_DATA(pDevIns, PVGASTATE), false);1240 }1241 1242 int vboxVBVASaveStateDone (PPDMDEVINS pDevIns, PSSMHANDLE pSSM)1243 {1244 /* ensure we have no pending commands */1245 return vbvaVHWAEnable(PDMINS_2_DATA(pDevIns, PVGASTATE), true);1246 }1247 1248 int vbvaVHWACommandCompleteAsynch(PPDMIDISPLAYVBVACALLBACKS pInterface, PVBOXVHWACMD pCmd)1249 {1250 int rc;1251 if((pCmd->Flags & VBOXVHWACMD_FLAG_HH_CMD) == 0)1252 {1253 PVGASTATE pVGAState = PPDMIDISPLAYVBVACALLBACKS_2_PVGASTATE(pInterface);1254 PHGSMIINSTANCE pIns = pVGAState->pHGSMI;1255 1256 Assert(pCmd->Flags & VBOXVHWACMD_FLAG_HG_ASYNCH);1257 #ifdef VBOX_WITH_WDDM1258 if (pVGAState->fGuestCaps & VBVACAPS_COMPLETEGCMD_BY_IOREAD)1259 {1260 rc = HGSMICompleteGuestCommand(pIns, pCmd, !!(pCmd->Flags & VBOXVHWACMD_FLAG_GH_ASYNCH_IRQ));1261 AssertRC(rc);1262 }1263 else1264 #endif1265 {1266 VBVAHOSTCMD *pHostCmd;1267 int32_t iDisplay = pCmd->iDisplay;1268 1269 if(pCmd->Flags & VBOXVHWACMD_FLAG_GH_ASYNCH_EVENT)1270 {1271 rc = HGSMIHostCommandAlloc (pIns,1272 (void**)&pHostCmd,1273 VBVAHOSTCMD_SIZE(sizeof(VBVAHOSTCMDEVENT)),1274 HGSMI_CH_VBVA,1275 VBVAHG_EVENT);1276 AssertRC(rc);1277 if(RT_SUCCESS(rc))1278 {1279 memset(pHostCmd, 0 , VBVAHOSTCMD_SIZE(sizeof(VBVAHOSTCMDEVENT)));1280 pHostCmd->iDstID = pCmd->iDisplay;1281 pHostCmd->customOpCode = 0;1282 VBVAHOSTCMDEVENT *pBody = VBVAHOSTCMD_BODY(pHostCmd, VBVAHOSTCMDEVENT);1283 pBody->pEvent = pCmd->GuestVBVAReserved1;1284 }1285 }1286 else1287 {1288 HGSMIOFFSET offCmd = HGSMIPointerToOffsetHost (pIns, pCmd);1289 Assert(offCmd != HGSMIOFFSET_VOID);1290 if(offCmd != HGSMIOFFSET_VOID)1291 {1292 rc = HGSMIHostCommandAlloc (pIns,1293 (void**)&pHostCmd,1294 VBVAHOSTCMD_SIZE(sizeof(VBVAHOSTCMDVHWACMDCOMPLETE)),1295 HGSMI_CH_VBVA,1296 VBVAHG_DISPLAY_CUSTOM);1297 AssertRC(rc);1298 if(RT_SUCCESS(rc))1299 {1300 memset(pHostCmd, 0 , VBVAHOSTCMD_SIZE(sizeof(VBVAHOSTCMDVHWACMDCOMPLETE)));1301 pHostCmd->iDstID = pCmd->iDisplay;1302 pHostCmd->customOpCode = VBVAHG_DCUSTOM_VHWA_CMDCOMPLETE;1303 VBVAHOSTCMDVHWACMDCOMPLETE *pBody = VBVAHOSTCMD_BODY(pHostCmd, VBVAHOSTCMDVHWACMDCOMPLETE);1304 pBody->offCmd = offCmd;1305 }1306 }1307 else1308 {1309 rc = VERR_INVALID_PARAMETER;1310 }1311 }1312 1313 if(RT_SUCCESS(rc))1314 {1315 rc = HGSMIHostCommandProcessAndFreeAsynch(pIns, pHostCmd, (pCmd->Flags & VBOXVHWACMD_FLAG_GH_ASYNCH_IRQ) != 0);1316 AssertRC(rc);1317 if(RT_SUCCESS(rc))1318 {1319 return rc;1320 }1321 HGSMIHostCommandFree (pIns, pHostCmd);1322 }1323 }1324 }1325 else1326 {1327 PFNVBOXVHWA_HH_CALLBACK pfn = VBOXVHWA_HH_CALLBACK_GET(pCmd);1328 if(pfn)1329 {1330 pfn(VBOXVHWA_HH_CALLBACK_GET_ARG(pCmd));1331 }1332 rc = VINF_SUCCESS;1333 }1334 return rc;1335 }1336 #endif1337 1338 1595 1339 1596 /*
Note:
See TracChangeset
for help on using the changeset viewer.