Changeset 48070 in vbox for trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/common
- Timestamp:
- Aug 26, 2013 6:13:22 PM (12 years ago)
- svn:sync-xref-src-repo-rev:
- 88439
- Location:
- trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/common
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPCommon.h
r44529 r48070 42 42 43 43 #ifdef VBOX_WDDM_MINIPORT 44 void VBoxWddmInvalidateAllVideoModesInfos(PVBOXMP_DEVEXT pExt);45 void VBoxWddmInvalidateVideoModesInfo(PVBOXMP_DEVEXT pExt, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId);46 44 PVBOXWDDM_VIDEOMODES_INFO VBoxWddmUpdateVideoModesInfoByMask(PVBOXMP_DEVEXT pExt, uint8_t *pScreenIdMask); 47 PVBOXWDDM_VIDEOMODES_INFO VBoxWddmUpdateAllVideoModesInfos(PVBOXMP_DEVEXT pExt);45 void VBoxWddmInitVideoModes(PVBOXMP_DEVEXT pExt); 48 46 NTSTATUS VBoxWddmGetModesForResolution(VIDEO_MODE_INFORMATION *pAllModes, uint32_t cAllModes, int iSearchPreferredMode, 49 47 const D3DKMDT_2DREGION *pResolution, VIDEO_MODE_INFORMATION * pModes, -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPDevExt.h
r47070 r48070 100 100 101 101 VBOXVIDEOCM_MGR CmMgr; 102 VBOXVIDEOCM_MGR SeamlessCtxMgr; 102 103 /* hgsmi allocation manager */ 103 104 VBOXVIDEOCM_ALLOC_MGR AllocMgr; … … 110 111 volatile uint32_t cContexts3D; 111 112 volatile uint32_t cContexts2D; 113 volatile uint32_t cContextsDispIfResize; 112 114 volatile uint32_t cRenderFromShadowDisabledContexts; 113 115 volatile uint32_t cUnlockedVBVADisabled; 116 117 DWORD dwDrvCfgFlags; 114 118 /* this is examined and swicthed by DxgkDdiSubmitCommand only! */ 115 119 volatile BOOLEAN fRenderToShadowDisabled; -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPVidModes.cpp
r46876 r48070 900 900 #ifdef VBOX_WDDM_MINIPORT 901 901 static VBOXWDDM_VIDEOMODES_INFO g_aVBoxVideoModeInfos[VBOX_VIDEO_MAX_SCREENS] = {0}; 902 static VBOXWDDM_VIDEOMODES_INFO g_VBoxVideoModeTmp; 902 903 903 904 bool VBoxWddmFillMode(PVBOXMP_DEVEXT pExt, uint32_t iDisplay, VIDEO_MODE_INFORMATION *pInfo, D3DDDIFORMAT enmFormat, ULONG w, ULONG h) … … 954 955 955 956 *piPreferredResolution = -1; 957 *pcResolutions = 0; 956 958 957 959 for (uint32_t i=0; i<tableSize; ++i) … … 1003 1005 Assert(pModes->aResolutions[pModes->iPreferredResolution].cx == pModes->aModes[pModes->iPreferredMode].VisScreenWidth 1004 1006 && pModes->aResolutions[pModes->iPreferredResolution].cy == pModes->aModes[pModes->iPreferredMode].VisScreenHeight); 1007 Assert(pModes->cModes >= pModes->cResolutions); 1005 1008 } 1006 1009 … … 1225 1228 } 1226 1229 1227 void VBoxWddmInvalidateVideoModesInfo(PVBOXMP_DEVEXT pExt, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId) 1228 { 1229 if (VidPnTargetId != D3DDDI_ID_ALL) 1230 { 1231 if (VidPnTargetId >= RT_ELEMENTS(g_aVBoxVideoModeInfos)) 1232 { 1233 WARN(("VidPnTargetId (%d) must be less than (%d)", VidPnTargetId, RT_ELEMENTS(g_aVBoxVideoModeInfos))); 1234 return; 1235 } 1236 LOG(("invalidating videomede info for screen %d", VidPnTargetId)); 1237 g_aVBoxVideoModeInfos[VidPnTargetId].cModes = 0; 1230 static void VBoxWddmInitVideoMode(PVBOXMP_DEVEXT pExt, int i) 1231 { 1232 VBoxWddmBuildVideoModesInfo(pExt, (D3DDDI_VIDEO_PRESENT_TARGET_ID)i, &g_aVBoxVideoModeInfos[i], NULL, 0); 1233 } 1234 1235 void VBoxWddmInitVideoModes(PVBOXMP_DEVEXT pExt) 1236 { 1237 for (int i = 0; i < VBoxCommonFromDeviceExt(pExt)->cDisplays; ++i) 1238 { 1239 VBoxWddmInitVideoMode(pExt, i); 1240 } 1241 } 1242 1243 static NTSTATUS vboxWddmChildStatusReportPerform(PVBOXMP_DEVEXT pDevExt, PVBOXVDMA_CHILD_STATUS pChildStatus, D3DDDI_VIDEO_PRESENT_TARGET_ID iChild) 1244 { 1245 DXGK_CHILD_STATUS DdiChildStatus; 1246 1247 Assert(iChild < UINT32_MAX/2); 1248 Assert(iChild < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays); 1249 1250 PVBOXWDDM_TARGET pTarget = &pDevExt->aTargets[iChild]; 1251 1252 if ((pChildStatus->fFlags & VBOXVDMA_CHILD_STATUS_F_DISCONNECTED) 1253 && pTarget->fConnected) 1254 { 1255 /* report disconnected */ 1256 memset(&DdiChildStatus, 0, sizeof (DdiChildStatus)); 1257 DdiChildStatus.Type = StatusConnection; 1258 DdiChildStatus.ChildUid = iChild; 1259 DdiChildStatus.HotPlug.Connected = FALSE; 1260 1261 LOG(("Reporting DISCONNECT to child %d", DdiChildStatus.ChildUid)); 1262 1263 NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbIndicateChildStatus(pDevExt->u.primary.DxgkInterface.DeviceHandle, &DdiChildStatus); 1264 if (!NT_SUCCESS(Status)) 1265 { 1266 WARN(("DxgkCbIndicateChildStatus failed with Status (0x%x)", Status)); 1267 return Status; 1268 } 1269 pTarget->fConnected = FALSE; 1270 } 1271 1272 if ((pChildStatus->fFlags & VBOXVDMA_CHILD_STATUS_F_CONNECTED) 1273 && !pTarget->fConnected) 1274 { 1275 /* report disconnected */ 1276 memset(&DdiChildStatus, 0, sizeof (DdiChildStatus)); 1277 DdiChildStatus.Type = StatusConnection; 1278 DdiChildStatus.ChildUid = iChild; 1279 DdiChildStatus.HotPlug.Connected = TRUE; 1280 1281 LOG(("Reporting CONNECT to child %d", DdiChildStatus.ChildUid)); 1282 1283 NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbIndicateChildStatus(pDevExt->u.primary.DxgkInterface.DeviceHandle, &DdiChildStatus); 1284 if (!NT_SUCCESS(Status)) 1285 { 1286 WARN(("DxgkCbIndicateChildStatus failed with Status (0x%x)", Status)); 1287 return Status; 1288 } 1289 pTarget->fConnected = TRUE; 1290 } 1291 1292 if (pChildStatus->fFlags & VBOXVDMA_CHILD_STATUS_F_ROTATED) 1293 { 1294 /* report disconnected */ 1295 memset(&DdiChildStatus, 0, sizeof (DdiChildStatus)); 1296 DdiChildStatus.Type = StatusRotation; 1297 DdiChildStatus.ChildUid = iChild; 1298 DdiChildStatus.Rotation.Angle = pChildStatus->u8RotationAngle; 1299 1300 LOG(("Reporting ROTATED to child %d", DdiChildStatus.ChildUid)); 1301 1302 NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbIndicateChildStatus(pDevExt->u.primary.DxgkInterface.DeviceHandle, &DdiChildStatus); 1303 if (!NT_SUCCESS(Status)) 1304 { 1305 WARN(("DxgkCbIndicateChildStatus failed with Status (0x%x)", Status)); 1306 return Status; 1307 } 1308 } 1309 1310 return STATUS_SUCCESS; 1311 } 1312 1313 static NTSTATUS vboxWddmChildStatusHandleRequest(PVBOXMP_DEVEXT pDevExt, VBOXVDMACMD_CHILD_STATUS_IRQ *pBody) 1314 { 1315 NTSTATUS Status = STATUS_SUCCESS; 1316 1317 for (UINT i = 0; i < pBody->cInfos; ++i) 1318 { 1319 PVBOXVDMA_CHILD_STATUS pInfo = &pBody->aInfos[i]; 1320 if (pBody->fFlags & VBOXVDMACMD_CHILD_STATUS_IRQ_F_APPLY_TO_ALL) 1321 { 1322 for (D3DDDI_VIDEO_PRESENT_TARGET_ID iChild = 0; iChild < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++iChild) 1323 { 1324 Status = vboxWddmChildStatusReportPerform(pDevExt, pInfo, iChild); 1325 if (!NT_SUCCESS(Status)) 1326 { 1327 WARN(("vboxWddmChildStatusReportPerform failed with Status (0x%x)", Status)); 1328 break; 1329 } 1330 } 1331 } 1332 else 1333 { 1334 Status = vboxWddmChildStatusReportPerform(pDevExt, pInfo, pInfo->iChild); 1335 if (!NT_SUCCESS(Status)) 1336 { 1337 WARN(("vboxWddmChildStatusReportPerform failed with Status (0x%x)", Status)); 1338 break; 1339 } 1340 } 1341 } 1342 1343 return Status; 1344 } 1345 1346 #ifdef VBOX_WDDM_MONITOR_REPLUG_IRQ 1347 typedef struct VBOXWDDMCHILDSTATUSCB 1348 { 1349 PVBOXVDMACBUF_DR pDr; 1350 PKEVENT pEvent; 1351 } VBOXWDDMCHILDSTATUSCB, *PVBOXWDDMCHILDSTATUSCB; 1352 1353 static DECLCALLBACK(VOID) vboxWddmChildStatusReportCompletion(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pCmd, PVOID pvContext) 1354 { 1355 /* we should be called from our DPC routine */ 1356 Assert(KeGetCurrentIrql() == DISPATCH_LEVEL); 1357 1358 PVBOXWDDMCHILDSTATUSCB pCtx = (PVBOXWDDMCHILDSTATUSCB)pvContext; 1359 PVBOXVDMACBUF_DR pDr = pCtx->pDr; 1360 PVBOXVDMACMD pHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD); 1361 VBOXVDMACMD_CHILD_STATUS_IRQ *pBody = VBOXVDMACMD_BODY(pHdr, VBOXVDMACMD_CHILD_STATUS_IRQ); 1362 1363 vboxWddmChildStatusHandleRequest(pDevExt, pBody); 1364 1365 vboxVdmaCBufDrFree(&pDevExt->u.primary.Vdma, pDr); 1366 1367 if (pCtx->pEvent) 1368 { 1369 KeSetEvent(pCtx->pEvent, 0, FALSE); 1370 } 1371 } 1372 #endif 1373 1374 static NTSTATUS vboxWddmChildStatusReportReconnected(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_TARGET_ID idTarget) 1375 { 1376 #ifdef VBOX_WDDM_MONITOR_REPLUG_IRQ 1377 NTSTATUS Status = STATUS_UNSUCCESSFUL; 1378 UINT cbCmd = VBOXVDMACMD_SIZE_FROMBODYSIZE(sizeof (VBOXVDMACMD_CHILD_STATUS_IRQ)); 1379 1380 PVBOXVDMACBUF_DR pDr = vboxVdmaCBufDrCreate(&pDevExt->u.primary.Vdma, cbCmd); 1381 if (pDr) 1382 { 1383 // vboxVdmaCBufDrCreate zero initializes the pDr 1384 /* the command data follows the descriptor */ 1385 pDr->fFlags = VBOXVDMACBUF_FLAG_BUF_FOLLOWS_DR; 1386 pDr->cbBuf = cbCmd; 1387 pDr->rc = VERR_NOT_IMPLEMENTED; 1388 1389 PVBOXVDMACMD pHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD); 1390 pHdr->enmType = VBOXVDMACMD_TYPE_CHILD_STATUS_IRQ; 1391 pHdr->u32CmdSpecific = 0; 1392 PVBOXVDMACMD_CHILD_STATUS_IRQ pBody = VBOXVDMACMD_BODY(pHdr, VBOXVDMACMD_CHILD_STATUS_IRQ); 1393 pBody->cInfos = 1; 1394 if (idTarget == D3DDDI_ID_ALL) 1395 { 1396 pBody->fFlags |= VBOXVDMACMD_CHILD_STATUS_IRQ_F_APPLY_TO_ALL; 1397 } 1398 pBody->aInfos[0].iChild = idTarget; 1399 pBody->aInfos[0].fFlags = VBOXVDMA_CHILD_STATUS_F_DISCONNECTED | VBOXVDMA_CHILD_STATUS_F_CONNECTED; 1400 /* we're going to KeWaitForSingleObject */ 1401 Assert(KeGetCurrentIrql() < DISPATCH_LEVEL); 1402 1403 PVBOXVDMADDI_CMD pDdiCmd = VBOXVDMADDI_CMD_FROM_BUF_DR(pDr); 1404 VBOXWDDMCHILDSTATUSCB Ctx; 1405 KEVENT Event; 1406 KeInitializeEvent(&Event, NotificationEvent, FALSE); 1407 Ctx.pDr = pDr; 1408 Ctx.pEvent = &Event; 1409 vboxVdmaDdiCmdInit(pDdiCmd, 0, 0, vboxWddmChildStatusReportCompletion, &Ctx); 1410 /* mark command as submitted & invisible for the dx runtime since dx did not originate it */ 1411 vboxVdmaDdiCmdSubmittedNotDx(pDdiCmd); 1412 int rc = vboxVdmaCBufDrSubmit(pDevExt, &pDevExt->u.primary.Vdma, pDr); 1413 Assert(rc == VINF_SUCCESS); 1414 if (RT_SUCCESS(rc)) 1415 { 1416 Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); 1417 Assert(Status == STATUS_SUCCESS); 1418 return STATUS_SUCCESS; 1419 } 1420 1421 Status = STATUS_UNSUCCESSFUL; 1422 1423 vboxVdmaCBufDrFree(&pDevExt->u.primary.Vdma, pDr); 1424 } 1425 else 1426 { 1427 /* @todo: try flushing.. */ 1428 WARN(("vboxVdmaCBufDrCreate returned NULL")); 1429 Status = STATUS_INSUFFICIENT_RESOURCES; 1430 } 1431 1432 return Status; 1433 #else 1434 VBOXVDMACMD_CHILD_STATUS_IRQ Body = {0}; 1435 Body.cInfos = 1; 1436 if (idTarget == D3DDDI_ID_ALL) 1437 { 1438 Body.fFlags |= VBOXVDMACMD_CHILD_STATUS_IRQ_F_APPLY_TO_ALL; 1439 } 1440 Body.aInfos[0].iChild = idTarget; 1441 Body.aInfos[0].fFlags = VBOXVDMA_CHILD_STATUS_F_DISCONNECTED | VBOXVDMA_CHILD_STATUS_F_CONNECTED; 1442 Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL); 1443 return vboxWddmChildStatusHandleRequest(pDevExt, &Body); 1444 #endif 1445 } 1446 1447 NTSTATUS vboxWddmChildStatusConnect(PVBOXMP_DEVEXT pDevExt, uint32_t iChild, BOOLEAN fConnect) 1448 { 1449 #ifdef VBOX_WDDM_MONITOR_REPLUG_IRQ 1450 # error "port me!" 1451 #else 1452 Assert(iChild < (uint32_t)VBoxCommonFromDeviceExt(pDevExt)->cDisplays); 1453 NTSTATUS Status = STATUS_SUCCESS; 1454 VBOXVDMACMD_CHILD_STATUS_IRQ Body = {0}; 1455 Body.cInfos = 1; 1456 Body.aInfos[0].iChild = iChild; 1457 Body.aInfos[0].fFlags = fConnect ? VBOXVDMA_CHILD_STATUS_F_CONNECTED : VBOXVDMA_CHILD_STATUS_F_DISCONNECTED; 1458 Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL); 1459 Status = vboxWddmChildStatusHandleRequest(pDevExt, &Body); 1460 if (!NT_SUCCESS(Status)) 1461 WARN(("vboxWddmChildStatusHandleRequest failed Status 0x%x", Status)); 1462 1463 return Status; 1464 #endif 1465 } 1466 1467 void VBoxWddmUpdateVideoMode(PVBOXMP_DEVEXT pExt, int i) 1468 { 1469 g_VBoxVideoModeTmp = g_aVBoxVideoModeInfos[i]; 1470 1471 Assert(g_aVBoxVideoModeInfos[i].cModes); 1472 1473 VBoxWddmInitVideoMode(pExt, i); 1474 1475 if (!memcmp(&g_VBoxVideoModeTmp, &g_aVBoxVideoModeInfos[i], sizeof (g_VBoxVideoModeTmp))) 1238 1476 return; 1239 } 1240 1241 LOG(("invalidating ALL videomede infos")); 1242 1243 for (UINT i = 0; i < RT_ELEMENTS(g_aVBoxVideoModeInfos); ++i) 1244 { 1245 g_aVBoxVideoModeInfos[i].cModes = 0; 1246 } 1247 } 1248 1249 void VBoxWddmInvalidateAllVideoModesInfos(PVBOXMP_DEVEXT pExt) 1250 { 1251 VBoxWddmInvalidateVideoModesInfo(pExt, D3DDDI_ID_ALL); 1477 1478 #ifdef DEBUG_misha 1479 g_VBoxDbgBreakModes = 0; 1480 #endif 1481 1482 #ifdef DEBUG_misha 1483 LOGREL(("modes changed for target %d", i)); 1484 #else 1485 LOG(("modes changed for target %d", i)); 1486 #endif 1487 vboxWddmChildStatusReportReconnected(pExt, (D3DDDI_VIDEO_PRESENT_TARGET_ID)i); 1252 1488 } 1253 1489 … … 1256 1492 for (int i = 0; i < VBoxCommonFromDeviceExt(pExt)->cDisplays; ++i) 1257 1493 { 1258 if (ASMBitTest(pScreenIdMask, i)) 1259 VBoxWddmInvalidateVideoModesInfo(pExt, i); 1260 } 1261 1262 /* ensure we have all the rest populated */ 1263 VBoxWddmGetAllVideoModesInfos(pExt); 1264 return g_aVBoxVideoModeInfos; 1265 } 1266 1267 PVBOXWDDM_VIDEOMODES_INFO VBoxWddmUpdateAllVideoModesInfos(PVBOXMP_DEVEXT pExt) 1268 { 1269 VBoxWddmInvalidateAllVideoModesInfos(pExt); 1270 1271 /* ensure we have all the rest populated */ 1272 VBoxWddmGetAllVideoModesInfos(pExt); 1494 if (!pScreenIdMask || ASMBitTest(pScreenIdMask, i)) 1495 { 1496 VBoxWddmUpdateVideoMode(pExt, i); 1497 } 1498 } 1499 1273 1500 return g_aVBoxVideoModeInfos; 1274 1501 } … … 1364 1591 } 1365 1592 1366 static PVBOXWDDM_VIDEOMODES_INFO vboxWddmGetVideoModesInfoInternal(PVBOXMP_DEVEXT pExt, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)1367 {1368 Assert(VidPnTargetId < (D3DDDI_VIDEO_PRESENT_TARGET_ID)VBoxCommonFromDeviceExt(pExt)->cDisplays);1369 if (VidPnTargetId >= (D3DDDI_VIDEO_PRESENT_TARGET_ID)VBoxCommonFromDeviceExt(pExt)->cDisplays)1370 {1371 WARN(("video mode info for invalid screen (%d) requested", VidPnTargetId));1372 return NULL;1373 }1374 1375 PVBOXWDDM_VIDEOMODES_INFO pInfo = &g_aVBoxVideoModeInfos[VidPnTargetId];1376 1377 if (!pInfo->cModes)1378 {1379 VBoxWddmBuildVideoModesInfo(pExt, VidPnTargetId, pInfo, NULL, 0);1380 Assert(pInfo->cModes);1381 }1382 1383 return pInfo;1384 }1385 1386 static VOID vboxWddmAddVideoModes(PVBOXMP_DEVEXT pExt, PVBOXWDDM_VIDEOMODES_INFO pDstInfo, PVBOXWDDM_VIDEOMODES_INFO pSrcInfo)1387 {1388 for (int i = 0; i < (int)pSrcInfo->cModes; ++i)1389 {1390 int foundIdx = VBoxMPFindVideoMode(pDstInfo->aModes, pDstInfo->cModes, &pSrcInfo->aModes[i]);1391 if (foundIdx >= 0)1392 continue;1393 1394 Assert(0);1395 pDstInfo->aModes[pDstInfo->cModes] = pSrcInfo->aModes[i];1396 ++pDstInfo->cModes;1397 }1398 1399 VBoxWddmBuildResolutionTableForModes(pDstInfo);1400 }1401 1402 1593 PVBOXWDDM_VIDEOMODES_INFO VBoxWddmGetAllVideoModesInfos(PVBOXMP_DEVEXT pExt) 1403 1594 { 1404 /* ensure all modes are initialized */1405 for (int i = 0; i < VBoxCommonFromDeviceExt(pExt)->cDisplays; ++i)1406 {1407 vboxWddmGetVideoModesInfoInternal(pExt, (D3DDDI_VIDEO_PRESENT_TARGET_ID)i);1408 }1409 1410 1595 return g_aVBoxVideoModeInfos; 1411 1596 }
Note:
See TracChangeset
for help on using the changeset viewer.