Changeset 52136 in vbox for trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/common
- Timestamp:
- Jul 22, 2014 7:36:45 PM (11 years ago)
- svn:sync-xref-src-repo-rev:
- 95166
- Location:
- trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:mergeinfo changed
/branches/VBox-4.3 merged: 95154,95164
- Property svn:mergeinfo changed
-
trunk/src/VBox
- Property svn:mergeinfo changed
/branches/VBox-4.3/src/VBox merged: 95154,95164
- Property svn:mergeinfo changed
-
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPCommon.h
r50900 r52136 30 30 31 31 /* Video modes related */ 32 #ifdef VBOX_XPDM_MINIPORT 32 33 void VBoxMPCmnInitCustomVideoModes(PVBOXMP_DEVEXT pExt); 33 34 VIDEO_MODE_INFORMATION* VBoxMPCmnGetCustomVideoModeInfo(ULONG ulIndex); 34 35 #ifdef VBOX_XPDM_MINIPORT36 35 VIDEO_MODE_INFORMATION* VBoxMPCmnGetVideoModeInfo(PVBOXMP_DEVEXT pExt, ULONG ulIndex); 37 36 VIDEO_MODE_INFORMATION* VBoxMPXpdmCurrentVideoMode(PVBOXMP_DEVEXT pExt); 38 37 ULONG VBoxMPXpdmGetVideoModesCount(PVBOXMP_DEVEXT pExt); 39 38 void VBoxMPXpdmBuildVideoModesTable(PVBOXMP_DEVEXT pExt); 40 #endif41 42 #ifdef VBOX_WDDM_MINIPORT43 PVBOXWDDM_VIDEOMODES_INFO VBoxWddmUpdateVideoModesInfoByMask(PVBOXMP_DEVEXT pExt, uint8_t *pScreenIdMask);44 void VBoxWddmInitVideoModes(PVBOXMP_DEVEXT pExt);45 NTSTATUS VBoxWddmGetModesForResolution(VIDEO_MODE_INFORMATION *pAllModes, uint32_t cAllModes, int iSearchPreferredMode,46 const D3DKMDT_2DREGION *pResolution, VIDEO_MODE_INFORMATION * pModes,47 uint32_t cModes, uint32_t *pcModes, int32_t *piPreferrableMode);48 PVBOXWDDM_VIDEOMODES_INFO VBoxWddmGetAllVideoModesInfos(PVBOXMP_DEVEXT pExt);49 PVBOXWDDM_VIDEOMODES_INFO VBoxWddmGetVideoModesInfo(PVBOXMP_DEVEXT pExt, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId);50 bool VBoxWddmFillMode(VIDEO_MODE_INFORMATION *pInfo, D3DDDIFORMAT enmFormat, ULONG w, ULONG h);51 bool VBoxWddmFillMode(VIDEO_MODE_INFORMATION *pInfo, D3DDDIFORMAT enmFormat, ULONG w, ULONG h);52 void VBoxWddmAdjustMode(PVBOXMP_DEVEXT pExt, PVBOXWDDM_ADJUSTVIDEOMODE pMode);53 void VBoxWddmAdjustModes(PVBOXMP_DEVEXT pExt, uint32_t cModes, PVBOXWDDM_ADJUSTVIDEOMODE aModes);54 39 #endif 55 40 -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPDevExt.h
r51328 r52136 144 144 VBOXVTLIST VhwaCmdList; 145 145 #endif 146 BOOL bNotifyDxDpc; 146 BOOLEAN bNotifyDxDpc; 147 148 BOOLEAN fDisableTargetUpdate; 149 150 147 151 148 152 #ifdef VBOX_VDMA_WITH_WATCHDOG -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPVidModes.cpp
r51943 r52136 874 874 } 875 875 #endif /*VBOX_XPDM_MINIPORT*/ 876 877 #ifdef VBOX_WDDM_MINIPORT878 static VBOXWDDM_VIDEOMODES_INFO g_aVBoxVideoModeInfos[VBOX_VIDEO_MAX_SCREENS] = {0};879 static VBOXWDDM_VIDEOMODES_INFO g_VBoxVideoModeTmp;880 881 bool VBoxWddmFillMode(PVBOXMP_DEVEXT pExt, uint32_t iDisplay, VIDEO_MODE_INFORMATION *pInfo, D3DDDIFORMAT enmFormat, ULONG w, ULONG h)882 {883 switch (enmFormat)884 {885 case D3DDDIFMT_A8R8G8B8:886 if (!VBoxMPValidateVideoModeParamsGuest(pExt, iDisplay, w, h, 32))887 {888 WARN(("unsupported mode info for format(%d)", enmFormat));889 return false;890 }891 VBoxFillVidModeInfo(pInfo, w, h, 32, 0, 0);892 return true;893 case D3DDDIFMT_R8G8B8:894 if (!VBoxMPValidateVideoModeParamsGuest(pExt, iDisplay, w, h, 24))895 {896 WARN(("unsupported mode info for format(%d)", enmFormat));897 return false;898 }899 VBoxFillVidModeInfo(pInfo, w, h, 24, 0, 0);900 return true;901 case D3DDDIFMT_R5G6B5:902 if (!VBoxMPValidateVideoModeParamsGuest(pExt, iDisplay, w, h, 16))903 {904 WARN(("unsupported mode info for format(%d)", enmFormat));905 return false;906 }907 VBoxFillVidModeInfo(pInfo, w, h, 16, 0, 0);908 return true;909 case D3DDDIFMT_P8:910 if (!VBoxMPValidateVideoModeParamsGuest(pExt, iDisplay, w, h, 8))911 {912 WARN(("unsupported mode info for format(%d)", enmFormat));913 return false;914 }915 VBoxFillVidModeInfo(pInfo, w, h, 8, 0, 0);916 return true;917 default:918 WARN(("unsupported enmFormat(%d)", enmFormat));919 AssertBreakpoint();920 break;921 }922 923 return false;924 }925 926 static void927 VBoxWddmBuildResolutionTable(PVIDEO_MODE_INFORMATION pModesTable, size_t tableSize, int iPreferredMode,928 SIZE *pResolutions, uint32_t * pcResolutions, int *piPreferredResolution)929 {930 uint32_t cResolutionsArray = *pcResolutions;931 uint32_t cResolutions = 0;932 933 *piPreferredResolution = -1;934 *pcResolutions = 0;935 936 for (uint32_t i=0; i<tableSize; ++i)937 {938 PVIDEO_MODE_INFORMATION pMode = &pModesTable[i];939 int iResolution = -1;940 941 for (uint32_t j=0; j<cResolutions; ++j)942 {943 if (pResolutions[j].cx == pMode->VisScreenWidth944 && pResolutions[j].cy == pMode->VisScreenHeight)945 {946 iResolution = j;947 break;948 }949 }950 951 if (iResolution < 0)952 {953 if (cResolutions == cResolutionsArray)954 {955 WARN(("table overflow!"));956 break;957 }958 959 iResolution = cResolutions;960 pResolutions[cResolutions].cx = pMode->VisScreenWidth;961 pResolutions[cResolutions].cy = pMode->VisScreenHeight;962 ++cResolutions;963 }964 965 Assert(iResolution >= 0);966 if (i == iPreferredMode)967 {968 Assert(*piPreferredResolution == -1);969 *piPreferredResolution = iResolution;970 }971 }972 973 *pcResolutions = cResolutions;974 Assert(*piPreferredResolution >= 0);975 }976 977 static void VBoxWddmBuildResolutionTableForModes(PVBOXWDDM_VIDEOMODES_INFO pModes)978 {979 pModes->cResolutions = RT_ELEMENTS(pModes->aResolutions);980 VBoxWddmBuildResolutionTable(pModes->aModes, pModes->cModes, pModes->iPreferredMode,981 (SIZE*)((void*)pModes->aResolutions), &pModes->cResolutions, &pModes->iPreferredResolution);982 Assert(pModes->aResolutions[pModes->iPreferredResolution].cx == pModes->aModes[pModes->iPreferredMode].VisScreenWidth983 && pModes->aResolutions[pModes->iPreferredResolution].cy == pModes->aModes[pModes->iPreferredMode].VisScreenHeight);984 Assert(pModes->cModes >= pModes->cResolutions);985 }986 987 AssertCompile(sizeof (SIZE) == sizeof (D3DKMDT_2DREGION));988 AssertCompile(RT_OFFSETOF(SIZE, cx) == RT_OFFSETOF(D3DKMDT_2DREGION, cx));989 AssertCompile(RT_OFFSETOF(SIZE, cy) == RT_OFFSETOF(D3DKMDT_2DREGION, cy));990 static void991 VBoxWddmBuildVideoModesInfo(PVBOXMP_DEVEXT pExt, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId,992 PVBOXWDDM_VIDEOMODES_INFO pModes, VIDEO_MODE_INFORMATION *paAddlModes,993 UINT cAddlModes)994 {995 pModes->cResolutions = RT_ELEMENTS(pModes->aResolutions);996 997 /* Add default modes and ones read from registry. */998 pModes->cModes = VBoxMPFillModesTable(pExt, VidPnTargetId, pModes->aModes, RT_ELEMENTS(pModes->aModes), &pModes->iPreferredMode);999 Assert(pModes->cModes<=RT_ELEMENTS(pModes->aModes));1000 1001 if (!VBoxMPIsStartingUp(pExt, VidPnTargetId))1002 {1003 /* make sure we keep the current mode to avoid mode flickering */1004 PVBOXWDDM_ALLOC_DATA pAllocData = pExt->aSources[VidPnTargetId].pPrimaryAllocation ?1005 &pExt->aSources[VidPnTargetId].pPrimaryAllocation->AllocData1006 : &pExt->aSources[VidPnTargetId].AllocData;1007 if (pModes->cModes < RT_ELEMENTS(pModes->aModes))1008 {1009 /* VBox WDDM driver does not allow 24 modes since OS could choose the 24bit mode as default in that case,1010 * the pExt->aSources[iDisplay].AllocData.SurfDesc.bpp could be initially 24 though,1011 * i.e. when driver occurs the current mode on driver load via DxgkCbAcquirePostDisplayOwnership1012 * and until driver reports the supported modes1013 * This is true for Win8 Display-Only driver currently since DxgkCbAcquirePostDisplayOwnership is only used by it1014 *1015 * This is why we check the bpp to be supported here and add the current mode to the list only in that case */1016 if (VBoxMPIsSupportedBpp(pAllocData->SurfDesc.bpp))1017 {1018 int foundIdx;1019 VBoxFillVidModeInfo(&pModes->aModes[pModes->cModes], pAllocData->SurfDesc.width, pAllocData->SurfDesc.height, pAllocData->SurfDesc.bpp, 1/*index*/, 0);1020 if ((foundIdx=VBoxMPFindVideoMode(pModes->aModes, pModes->cModes, &pModes->aModes[pModes->cModes]))>=0)1021 {1022 pModes->iPreferredMode = foundIdx;1023 }1024 else1025 {1026 pModes->iPreferredMode = pModes->cModes;1027 ++pModes->cModes;1028 }1029 1030 #ifdef VBOX_WITH_8BPP_MODES1031 int bytesPerPixel=1;1032 #else1033 int bytesPerPixel=2;1034 #endif1035 for (; bytesPerPixel<=4; bytesPerPixel++)1036 {1037 int bpp = 8*bytesPerPixel;1038 1039 if (bpp == pAllocData->SurfDesc.bpp)1040 continue;1041 1042 if (!VBoxMPValidateVideoModeParamsGuest(pExt, VidPnTargetId,1043 pAllocData->SurfDesc.width, pAllocData->SurfDesc.height,1044 bpp))1045 continue;1046 1047 if (pModes->cModes >= RT_ELEMENTS(pModes->aModes))1048 {1049 WARN(("ran out of video modes 2"));1050 break;1051 }1052 1053 VBoxFillVidModeInfo(&pModes->aModes[pModes->cModes],1054 pAllocData->SurfDesc.width, pAllocData->SurfDesc.height,1055 bpp, pModes->cModes, 0);1056 if (VBoxMPFindVideoMode(pModes->aModes, pModes->cModes, &pModes->aModes[pModes->cModes]) < 0)1057 {1058 ++pModes->cModes;1059 }1060 }1061 }1062 }1063 else1064 {1065 WARN(("ran out of video modes 1"));1066 }1067 }1068 1069 /* Check if there's a pending display change request for this adapter */1070 VIDEO_MODE_INFORMATION specialMode;1071 if (VBoxMPCheckPendingVideoMode(pExt, &specialMode) && (specialMode.ModeIndex==VidPnTargetId))1072 {1073 /*Minor hack, ModeIndex!=0 Means this mode has been validated already and not just read from registry */1074 specialMode.ModeIndex = 1;1075 memcpy(&g_CustomVideoModes[VidPnTargetId], &specialMode, sizeof(VIDEO_MODE_INFORMATION));1076 1077 /* Save mode to registry */1078 VBoxMPRegSaveModeInfo(pExt, VidPnTargetId, &specialMode);1079 }1080 1081 /* Validate the mode which has been read from registry */1082 if (!g_CustomVideoModes[VidPnTargetId].ModeIndex)1083 {1084 uint32_t xres, yres, bpp;1085 1086 xres = g_CustomVideoModes[VidPnTargetId].VisScreenWidth;1087 yres = g_CustomVideoModes[VidPnTargetId].VisScreenHeight;1088 bpp = g_CustomVideoModes[VidPnTargetId].BitsPerPlane;1089 1090 if (VBoxMPValidateVideoModeParams(pExt, VidPnTargetId, xres, yres, bpp))1091 {1092 VBoxFillVidModeInfo(&g_CustomVideoModes[VidPnTargetId], xres, yres, bpp, 1/*index*/, 0);1093 Assert(g_CustomVideoModes[VidPnTargetId].ModeIndex == 1);1094 }1095 }1096 1097 /* Add custom mode to the table */1098 if (g_CustomVideoModes[VidPnTargetId].ModeIndex)1099 {1100 if (RT_ELEMENTS(pModes->aModes) > pModes->cModes)1101 {1102 g_CustomVideoModes[VidPnTargetId].ModeIndex = pModes->cModes;1103 pModes->aModes[pModes->cModes] = g_CustomVideoModes[VidPnTargetId];1104 1105 /* Check if we already have this mode in the table */1106 int foundIdx;1107 if ((foundIdx=VBoxMPFindVideoMode(pModes->aModes, pModes->cModes, &pModes->aModes[pModes->cModes]))>=0)1108 {1109 pModes->iPreferredMode = foundIdx;1110 }1111 else1112 {1113 pModes->iPreferredMode = pModes->cModes;1114 ++pModes->cModes;1115 }1116 1117 /* Add other bpp modes for this custom resolution */1118 #ifdef VBOX_WITH_8BPP_MODES1119 UINT bpp=8;1120 #else1121 UINT bpp=16;1122 #endif1123 for (; bpp<=32; bpp+=8)1124 {1125 if (RT_ELEMENTS(pModes->aModes) == pModes->cModes)1126 {1127 WARN(("table full, can't add other bpp for specail mode!"));1128 #ifdef DEBUG_misha1129 /* this is definitely something we do not expect */1130 AssertFailed();1131 #endif1132 break;1133 }1134 1135 AssertRelease(RT_ELEMENTS(pModes->aModes) > pModes->cModes); /* if not - the driver state is screwed up, @todo: better do KeBugCheckEx here */1136 1137 if (pModes->aModes[pModes->iPreferredMode].BitsPerPlane == bpp)1138 continue;1139 1140 if (!VBoxMPValidateVideoModeParamsGuest(pExt, VidPnTargetId,1141 pModes->aModes[pModes->iPreferredMode].VisScreenWidth,1142 pModes->aModes[pModes->iPreferredMode].VisScreenHeight,1143 bpp))1144 continue;1145 1146 VBoxFillVidModeInfo(&pModes->aModes[pModes->cModes],1147 pModes->aModes[pModes->iPreferredMode].VisScreenWidth,1148 pModes->aModes[pModes->iPreferredMode].VisScreenHeight,1149 bpp, pModes->cModes, 0);1150 if (VBoxMPFindVideoMode(pModes->aModes, pModes->cModes, &pModes->aModes[pModes->cModes]) < 0)1151 {1152 ++pModes->cModes;1153 }1154 }1155 }1156 else1157 {1158 AssertRelease(RT_ELEMENTS(pModes->aModes) == pModes->cModes); /* if not - the driver state is screwed up, @todo: better do KeBugCheckEx here */1159 WARN(("table full, can't add video mode for a host request!"));1160 #ifdef DEBUG_misha1161 /* this is definitely something we do not expect */1162 AssertFailed();1163 #endif1164 }1165 }1166 1167 /* Check and Add additional modes passed in paAddlModes */1168 for (UINT i=0; i<cAddlModes; ++i)1169 {1170 if (RT_ELEMENTS(pModes->aModes) == pModes->cModes)1171 {1172 WARN(("table full, can't add addl modes!"));1173 #ifdef DEBUG_misha1174 /* this is definitely something we do not expect */1175 AssertFailed();1176 #endif1177 break;1178 }1179 1180 AssertRelease(RT_ELEMENTS(pModes->aModes) > pModes->cModes); /* if not - the driver state is screwed up, @todo: better do KeBugCheckEx here */1181 1182 if (!VBoxCommonFromDeviceExt(pExt)->fAnyX)1183 {1184 paAddlModes[i].VisScreenWidth &= 0xFFF8;1185 }1186 1187 if (VBoxLikesVideoMode(VidPnTargetId, paAddlModes[i].VisScreenWidth, paAddlModes[i].VisScreenHeight, paAddlModes[i].BitsPerPlane))1188 {1189 int foundIdx;1190 if ((foundIdx=VBoxMPFindVideoMode(pModes->aModes, pModes->cModes, &paAddlModes[i]))>=0)1191 {1192 pModes->iPreferredMode = foundIdx;1193 }1194 else1195 {1196 memcpy(&pModes->aModes[pModes->cModes], &paAddlModes[i], sizeof(VIDEO_MODE_INFORMATION));1197 pModes->aModes[pModes->cModes].ModeIndex = pModes->cModes;1198 ++pModes->cModes;1199 }1200 }1201 }1202 1203 /* Build resolution table */1204 VBoxWddmBuildResolutionTableForModes(pModes);1205 }1206 1207 static void VBoxWddmInitVideoMode(PVBOXMP_DEVEXT pExt, int i)1208 {1209 VBoxWddmBuildVideoModesInfo(pExt, (D3DDDI_VIDEO_PRESENT_TARGET_ID)i, &g_aVBoxVideoModeInfos[i], NULL, 0);1210 }1211 1212 void VBoxWddmInitVideoModes(PVBOXMP_DEVEXT pExt)1213 {1214 for (int i = 0; i < VBoxCommonFromDeviceExt(pExt)->cDisplays; ++i)1215 {1216 VBoxWddmInitVideoMode(pExt, i);1217 }1218 }1219 1220 static NTSTATUS vboxWddmChildStatusReportPerform(PVBOXMP_DEVEXT pDevExt, PVBOXVDMA_CHILD_STATUS pChildStatus, D3DDDI_VIDEO_PRESENT_TARGET_ID iChild)1221 {1222 DXGK_CHILD_STATUS DdiChildStatus;1223 1224 Assert(iChild < UINT32_MAX/2);1225 Assert(iChild < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays);1226 1227 PVBOXWDDM_TARGET pTarget = &pDevExt->aTargets[iChild];1228 1229 if ((pChildStatus->fFlags & VBOXVDMA_CHILD_STATUS_F_DISCONNECTED)1230 && pTarget->fConnected)1231 {1232 /* report disconnected */1233 memset(&DdiChildStatus, 0, sizeof (DdiChildStatus));1234 DdiChildStatus.Type = StatusConnection;1235 DdiChildStatus.ChildUid = iChild;1236 DdiChildStatus.HotPlug.Connected = FALSE;1237 1238 LOG(("Reporting DISCONNECT to child %d", DdiChildStatus.ChildUid));1239 1240 NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbIndicateChildStatus(pDevExt->u.primary.DxgkInterface.DeviceHandle, &DdiChildStatus);1241 if (!NT_SUCCESS(Status))1242 {1243 WARN(("DxgkCbIndicateChildStatus failed with Status (0x%x)", Status));1244 return Status;1245 }1246 pTarget->fConnected = FALSE;1247 }1248 1249 if ((pChildStatus->fFlags & VBOXVDMA_CHILD_STATUS_F_CONNECTED)1250 && !pTarget->fConnected)1251 {1252 /* report disconnected */1253 memset(&DdiChildStatus, 0, sizeof (DdiChildStatus));1254 DdiChildStatus.Type = StatusConnection;1255 DdiChildStatus.ChildUid = iChild;1256 DdiChildStatus.HotPlug.Connected = TRUE;1257 1258 LOG(("Reporting CONNECT to child %d", DdiChildStatus.ChildUid));1259 1260 NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbIndicateChildStatus(pDevExt->u.primary.DxgkInterface.DeviceHandle, &DdiChildStatus);1261 if (!NT_SUCCESS(Status))1262 {1263 WARN(("DxgkCbIndicateChildStatus failed with Status (0x%x)", Status));1264 return Status;1265 }1266 pTarget->fConnected = TRUE;1267 }1268 1269 if (pChildStatus->fFlags & VBOXVDMA_CHILD_STATUS_F_ROTATED)1270 {1271 /* report disconnected */1272 memset(&DdiChildStatus, 0, sizeof (DdiChildStatus));1273 DdiChildStatus.Type = StatusRotation;1274 DdiChildStatus.ChildUid = iChild;1275 DdiChildStatus.Rotation.Angle = pChildStatus->u8RotationAngle;1276 1277 LOG(("Reporting ROTATED to child %d", DdiChildStatus.ChildUid));1278 1279 NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbIndicateChildStatus(pDevExt->u.primary.DxgkInterface.DeviceHandle, &DdiChildStatus);1280 if (!NT_SUCCESS(Status))1281 {1282 WARN(("DxgkCbIndicateChildStatus failed with Status (0x%x)", Status));1283 return Status;1284 }1285 }1286 1287 return STATUS_SUCCESS;1288 }1289 1290 static NTSTATUS vboxWddmChildStatusHandleRequest(PVBOXMP_DEVEXT pDevExt, VBOXVDMACMD_CHILD_STATUS_IRQ *pBody)1291 {1292 NTSTATUS Status = STATUS_SUCCESS;1293 1294 for (UINT i = 0; i < pBody->cInfos; ++i)1295 {1296 PVBOXVDMA_CHILD_STATUS pInfo = &pBody->aInfos[i];1297 if (pBody->fFlags & VBOXVDMACMD_CHILD_STATUS_IRQ_F_APPLY_TO_ALL)1298 {1299 for (D3DDDI_VIDEO_PRESENT_TARGET_ID iChild = 0; iChild < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++iChild)1300 {1301 Status = vboxWddmChildStatusReportPerform(pDevExt, pInfo, iChild);1302 if (!NT_SUCCESS(Status))1303 {1304 WARN(("vboxWddmChildStatusReportPerform failed with Status (0x%x)", Status));1305 break;1306 }1307 }1308 }1309 else1310 {1311 Status = vboxWddmChildStatusReportPerform(pDevExt, pInfo, pInfo->iChild);1312 if (!NT_SUCCESS(Status))1313 {1314 WARN(("vboxWddmChildStatusReportPerform failed with Status (0x%x)", Status));1315 break;1316 }1317 }1318 }1319 1320 return Status;1321 }1322 1323 #ifdef VBOX_WDDM_MONITOR_REPLUG_IRQ1324 typedef struct VBOXWDDMCHILDSTATUSCB1325 {1326 PVBOXVDMACBUF_DR pDr;1327 PKEVENT pEvent;1328 } VBOXWDDMCHILDSTATUSCB, *PVBOXWDDMCHILDSTATUSCB;1329 1330 static DECLCALLBACK(VOID) vboxWddmChildStatusReportCompletion(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pCmd, PVOID pvContext)1331 {1332 /* we should be called from our DPC routine */1333 Assert(KeGetCurrentIrql() == DISPATCH_LEVEL);1334 1335 PVBOXWDDMCHILDSTATUSCB pCtx = (PVBOXWDDMCHILDSTATUSCB)pvContext;1336 PVBOXVDMACBUF_DR pDr = pCtx->pDr;1337 PVBOXVDMACMD pHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD);1338 VBOXVDMACMD_CHILD_STATUS_IRQ *pBody = VBOXVDMACMD_BODY(pHdr, VBOXVDMACMD_CHILD_STATUS_IRQ);1339 1340 vboxWddmChildStatusHandleRequest(pDevExt, pBody);1341 1342 vboxVdmaCBufDrFree(&pDevExt->u.primary.Vdma, pDr);1343 1344 if (pCtx->pEvent)1345 {1346 KeSetEvent(pCtx->pEvent, 0, FALSE);1347 }1348 }1349 #endif1350 1351 static NTSTATUS vboxWddmChildStatusReportReconnected(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_TARGET_ID idTarget)1352 {1353 #ifdef VBOX_WDDM_MONITOR_REPLUG_IRQ1354 NTSTATUS Status = STATUS_UNSUCCESSFUL;1355 UINT cbCmd = VBOXVDMACMD_SIZE_FROMBODYSIZE(sizeof (VBOXVDMACMD_CHILD_STATUS_IRQ));1356 1357 PVBOXVDMACBUF_DR pDr = vboxVdmaCBufDrCreate(&pDevExt->u.primary.Vdma, cbCmd);1358 if (pDr)1359 {1360 // vboxVdmaCBufDrCreate zero initializes the pDr1361 /* the command data follows the descriptor */1362 pDr->fFlags = VBOXVDMACBUF_FLAG_BUF_FOLLOWS_DR;1363 pDr->cbBuf = cbCmd;1364 pDr->rc = VERR_NOT_IMPLEMENTED;1365 1366 PVBOXVDMACMD pHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD);1367 pHdr->enmType = VBOXVDMACMD_TYPE_CHILD_STATUS_IRQ;1368 pHdr->u32CmdSpecific = 0;1369 PVBOXVDMACMD_CHILD_STATUS_IRQ pBody = VBOXVDMACMD_BODY(pHdr, VBOXVDMACMD_CHILD_STATUS_IRQ);1370 pBody->cInfos = 1;1371 if (idTarget == D3DDDI_ID_ALL)1372 {1373 pBody->fFlags |= VBOXVDMACMD_CHILD_STATUS_IRQ_F_APPLY_TO_ALL;1374 }1375 pBody->aInfos[0].iChild = idTarget;1376 pBody->aInfos[0].fFlags = VBOXVDMA_CHILD_STATUS_F_DISCONNECTED | VBOXVDMA_CHILD_STATUS_F_CONNECTED;1377 /* we're going to KeWaitForSingleObject */1378 Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);1379 1380 PVBOXVDMADDI_CMD pDdiCmd = VBOXVDMADDI_CMD_FROM_BUF_DR(pDr);1381 VBOXWDDMCHILDSTATUSCB Ctx;1382 KEVENT Event;1383 KeInitializeEvent(&Event, NotificationEvent, FALSE);1384 Ctx.pDr = pDr;1385 Ctx.pEvent = &Event;1386 vboxVdmaDdiCmdInit(pDdiCmd, 0, 0, vboxWddmChildStatusReportCompletion, &Ctx);1387 /* mark command as submitted & invisible for the dx runtime since dx did not originate it */1388 vboxVdmaDdiCmdSubmittedNotDx(pDdiCmd);1389 int rc = vboxVdmaCBufDrSubmit(pDevExt, &pDevExt->u.primary.Vdma, pDr);1390 Assert(rc == VINF_SUCCESS);1391 if (RT_SUCCESS(rc))1392 {1393 Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);1394 Assert(Status == STATUS_SUCCESS);1395 return STATUS_SUCCESS;1396 }1397 1398 Status = STATUS_UNSUCCESSFUL;1399 1400 vboxVdmaCBufDrFree(&pDevExt->u.primary.Vdma, pDr);1401 }1402 else1403 {1404 /* @todo: try flushing.. */1405 WARN(("vboxVdmaCBufDrCreate returned NULL"));1406 Status = STATUS_INSUFFICIENT_RESOURCES;1407 }1408 1409 return Status;1410 #else1411 VBOXVDMACMD_CHILD_STATUS_IRQ Body = {0};1412 Body.cInfos = 1;1413 if (idTarget == D3DDDI_ID_ALL)1414 {1415 Body.fFlags |= VBOXVDMACMD_CHILD_STATUS_IRQ_F_APPLY_TO_ALL;1416 }1417 Body.aInfos[0].iChild = idTarget;1418 Body.aInfos[0].fFlags = VBOXVDMA_CHILD_STATUS_F_DISCONNECTED | VBOXVDMA_CHILD_STATUS_F_CONNECTED;1419 Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);1420 return vboxWddmChildStatusHandleRequest(pDevExt, &Body);1421 #endif1422 }1423 1424 NTSTATUS vboxWddmChildStatusConnect(PVBOXMP_DEVEXT pDevExt, uint32_t iChild, BOOLEAN fConnect)1425 {1426 #ifdef VBOX_WDDM_MONITOR_REPLUG_IRQ1427 # error "port me!"1428 #else1429 Assert(iChild < (uint32_t)VBoxCommonFromDeviceExt(pDevExt)->cDisplays);1430 NTSTATUS Status = STATUS_SUCCESS;1431 VBOXVDMACMD_CHILD_STATUS_IRQ Body = {0};1432 Body.cInfos = 1;1433 Body.aInfos[0].iChild = iChild;1434 Body.aInfos[0].fFlags = fConnect ? VBOXVDMA_CHILD_STATUS_F_CONNECTED : VBOXVDMA_CHILD_STATUS_F_DISCONNECTED;1435 Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);1436 Status = vboxWddmChildStatusHandleRequest(pDevExt, &Body);1437 if (!NT_SUCCESS(Status))1438 WARN(("vboxWddmChildStatusHandleRequest failed Status 0x%x", Status));1439 1440 return Status;1441 #endif1442 }1443 1444 void VBoxWddmUpdateVideoMode(PVBOXMP_DEVEXT pExt, int i)1445 {1446 g_VBoxVideoModeTmp = g_aVBoxVideoModeInfos[i];1447 1448 Assert(g_aVBoxVideoModeInfos[i].cModes);1449 1450 VBoxWddmInitVideoMode(pExt, i);1451 1452 if (!memcmp(&g_VBoxVideoModeTmp, &g_aVBoxVideoModeInfos[i], sizeof (g_VBoxVideoModeTmp)))1453 return;1454 1455 #ifdef DEBUG_misha1456 LOGREL(("modes changed for target %d", i));1457 #else1458 LOG(("modes changed for target %d", i));1459 #endif1460 vboxWddmChildStatusReportReconnected(pExt, (D3DDDI_VIDEO_PRESENT_TARGET_ID)i);1461 }1462 1463 PVBOXWDDM_VIDEOMODES_INFO VBoxWddmUpdateVideoModesInfoByMask(PVBOXMP_DEVEXT pExt, uint8_t *pScreenIdMask)1464 {1465 for (int i = 0; i < VBoxCommonFromDeviceExt(pExt)->cDisplays; ++i)1466 {1467 if (!pScreenIdMask || ASMBitTest(pScreenIdMask, i))1468 {1469 VBoxWddmUpdateVideoMode(pExt, i);1470 }1471 }1472 1473 return g_aVBoxVideoModeInfos;1474 }1475 1476 void VBoxWddmAdjustMode(PVBOXMP_DEVEXT pExt, PVBOXWDDM_ADJUSTVIDEOMODE pMode)1477 {1478 pMode->fFlags = 0;1479 1480 if (pMode->Mode.Id >= (UINT)VBoxCommonFromDeviceExt(pExt)->cDisplays)1481 {1482 WARN(("invalid screen id (%d)", pMode->Mode.Id));1483 pMode->fFlags = VBOXWDDM_ADJUSTVIDEOMODE_F_INVALISCREENID;1484 return;1485 }1486 1487 /* @todo: this info should go from the target actually */1488 PVBOXWDDM_SOURCE pSource = &pExt->aSources[pMode->Mode.Id];1489 1490 UINT newWidth = pMode->Mode.Width;1491 UINT newHeight = pMode->Mode.Height;1492 UINT newBpp = pMode->Mode.BitsPerPixel;1493 1494 if (!VBoxMPValidateVideoModeParams(pExt, pMode->Mode.Id, newWidth, newHeight, newBpp))1495 {1496 PVBOXWDDM_SOURCE pSource = &pExt->aSources[pMode->Mode.Id];1497 pMode->fFlags |= VBOXWDDM_ADJUSTVIDEOMODE_F_UNSUPPORTED;1498 }1499 1500 if (pMode->Mode.Width != newWidth1501 || pMode->Mode.Height != newHeight1502 || pMode->Mode.BitsPerPixel != newBpp)1503 {1504 pMode->fFlags |= VBOXWDDM_ADJUSTVIDEOMODE_F_ADJUSTED;1505 pMode->Mode.Width = newWidth;1506 pMode->Mode.Height = newHeight;1507 pMode->Mode.BitsPerPixel = newBpp;1508 }1509 1510 if (pSource->cTargets /* <- active */1511 && pSource->AllocData.SurfDesc.width == pMode->Mode.Width1512 && pSource->AllocData.SurfDesc.height == pMode->Mode.Height1513 && pSource->AllocData.SurfDesc.bpp == pMode->Mode.BitsPerPixel)1514 {1515 pMode->fFlags |= VBOXWDDM_ADJUSTVIDEOMODE_F_CURRENT;1516 if (pMode->fFlags & VBOXWDDM_ADJUSTVIDEOMODE_F_UNSUPPORTED)1517 {1518 WARN(("current mode is reported as unsupported"));1519 }1520 }1521 }1522 1523 void VBoxWddmAdjustModes(PVBOXMP_DEVEXT pExt, uint32_t cModes, PVBOXWDDM_ADJUSTVIDEOMODE aModes)1524 {1525 for (UINT i = 0; i < cModes; ++i)1526 {1527 PVBOXWDDM_ADJUSTVIDEOMODE pMode = &aModes[i];1528 VBoxWddmAdjustMode(pExt, pMode);1529 }1530 }1531 1532 NTSTATUS VBoxWddmGetModesForResolution(VIDEO_MODE_INFORMATION *pAllModes, uint32_t cAllModes, int iSearchPreferredMode,1533 const D3DKMDT_2DREGION *pResolution, VIDEO_MODE_INFORMATION * pModes, uint32_t cModes, uint32_t *pcModes, int32_t *piPreferrableMode)1534 {1535 NTSTATUS Status = STATUS_SUCCESS;1536 uint32_t cFound = 0;1537 int iFoundPreferrableMode = -1;1538 for (uint32_t i = 0; i < cAllModes; ++i)1539 {1540 VIDEO_MODE_INFORMATION *pCur = &pAllModes[i];1541 if (pResolution->cx == pCur->VisScreenWidth1542 && pResolution->cy == pCur->VisScreenHeight)1543 {1544 if (pModes && cModes > cFound)1545 memcpy(&pModes[cFound], pCur, sizeof(VIDEO_MODE_INFORMATION));1546 else1547 Status = STATUS_BUFFER_TOO_SMALL;1548 1549 if (i == iSearchPreferredMode)1550 iFoundPreferrableMode = cFound;1551 1552 ++cFound;1553 }1554 }1555 1556 Assert(iFoundPreferrableMode < 0 || cFound > (uint32_t)iFoundPreferrableMode);1557 1558 *pcModes = cFound;1559 if (piPreferrableMode)1560 *piPreferrableMode = iFoundPreferrableMode;1561 1562 return Status;1563 }1564 1565 PVBOXWDDM_VIDEOMODES_INFO VBoxWddmGetAllVideoModesInfos(PVBOXMP_DEVEXT pExt)1566 {1567 return g_aVBoxVideoModeInfos;1568 }1569 1570 PVBOXWDDM_VIDEOMODES_INFO VBoxWddmGetVideoModesInfo(PVBOXMP_DEVEXT pExt, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)1571 {1572 return &VBoxWddmGetAllVideoModesInfos(pExt)[VidPnTargetId];1573 }1574 1575 #endif /*VBOX_WDDM_MINIPORT*/
Note:
See TracChangeset
for help on using the changeset viewer.