- Timestamp:
- Aug 26, 2013 6:13:22 PM (12 years ago)
- svn:sync-xref-src-repo-rev:
- 88439
- Location:
- trunk/src/VBox
- Files:
-
- 31 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/Graphics/Video/common/wddm/VBoxMPIf.h
r46966 r48070 252 252 VBOXWDDM_CONTEXT_TYPE_CUSTOM_UHGSMI_GL, 253 253 /* context created by the kernel->user communication mechanism for visible rects reporting, etc. */ 254 VBOXWDDM_CONTEXT_TYPE_CUSTOM_SESSION 254 VBOXWDDM_CONTEXT_TYPE_CUSTOM_SESSION, 255 /* context created by VBoxTray to handle resize operations */ 256 VBOXWDDM_CONTEXT_TYPE_CUSTOM_DISPIF_RESIZE, 257 /* context created by VBoxTray to handle seamless operations */ 258 VBOXWDDM_CONTEXT_TYPE_CUSTOM_DISPIF_SEAMLESS 255 259 } VBOXWDDM_CONTEXT_TYPE; 256 260 -
trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.h
r46783 r48070 21 21 22 22 #include "VBoxDispD3DIf.h" 23 #include " common/wddm/VBoxMPIf.h"23 #include "../../common/wddm/VBoxMPIf.h" 24 24 #ifdef VBOX_WITH_CRHGSMI 25 25 #include "VBoxUhgsmiDisp.h" -
trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DCmn.h
r46783 r48070 19 19 #define ___VBoxDispD3DCmn_h___ 20 20 21 # define _InterlockedExchange _InterlockedExchange_StupidDDKVsCompilerCrap 22 # define _InterlockedExchangeAdd _InterlockedExchangeAdd_StupidDDKVsCompilerCrap 23 # define _InterlockedCompareExchange _InterlockedCompareExchange_StupidDDKVsCompilerCrap 24 # define _InterlockedAddLargeStatistic _InterlockedAddLargeStatistic_StupidDDKVsCompilerCrap 25 # define _interlockedbittestandset _interlockedbittestandset_StupidDDKVsCompilerCrap 26 # define _interlockedbittestandreset _interlockedbittestandreset_StupidDDKVsCompilerCrap 27 # define _interlockedbittestandset64 _interlockedbittestandset64_StupidDDKVsCompilerCrap 28 # define _interlockedbittestandreset64 _interlockedbittestandreset64_StupidDDKVsCompilerCrap 29 # pragma warning(disable : 4163) 30 #include <windows.h> 31 # pragma warning(default : 4163) 32 # undef _InterlockedExchange 33 # undef _InterlockedExchangeAdd 34 # undef _InterlockedCompareExchange 35 # undef _InterlockedAddLargeStatistic 36 # undef _interlockedbittestandset 37 # undef _interlockedbittestandreset 38 # undef _interlockedbittestandset64 39 # undef _interlockedbittestandreset64 40 41 #include <d3d9types.h> 42 //#include <d3dtypes.h> 43 #include <D3dumddi.h> 44 #include <d3dhal.h> 21 #include "VBoxDispD3DBase.h" 45 22 46 23 #include <iprt/initterm.h> … … 54 31 #include "VBoxDispDbg.h" 55 32 #include "VBoxDispD3DIf.h" 56 #include " common/wddm/VBoxMPIf.h"33 #include "../../common/wddm/VBoxMPIf.h" 57 34 #include "VBoxDispCm.h" 58 35 #include "VBoxDispMpInternal.h" -
trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispKmt.cpp
r46593 r48070 17 17 */ 18 18 19 #include "VBoxDispD3DCmn.h" 19 #include "VBoxDispD3DBase.h" 20 #include "VBoxDispKmt.h" 21 22 #include <iprt/assert.h> 23 #include <iprt/log.h> 20 24 21 25 #ifndef NT_SUCCESS … … 103 107 Log((__FUNCTION__": pfnD3DKMTUnlock = %p\n", pCallbacks->pfnD3DKMTUnlock)); 104 108 bSupported &= !!(pCallbacks->pfnD3DKMTUnlock); 109 110 pCallbacks->pfnD3DKMTInvalidateActiveVidPn = (PFND3DKMT_INVALIDATEACTIVEVIDPN)GetProcAddress(pCallbacks->hGdi32, "D3DKMTInvalidateActiveVidPn"); 111 Log((__FUNCTION__": pfnD3DKMTInvalidateActiveVidPn = %p\n", pCallbacks->pfnD3DKMTInvalidateActiveVidPn)); 112 bSupported &= !!(pCallbacks->pfnD3DKMTInvalidateActiveVidPn); 113 114 pCallbacks->pfnD3DKMTPollDisplayChildren = (PFND3DKMT_POLLDISPLAYCHILDREN)GetProcAddress(pCallbacks->hGdi32, "D3DKMTPollDisplayChildren"); 115 Log((__FUNCTION__": pfnD3DKMTPollDisplayChildren = %p\n", pCallbacks->pfnD3DKMTPollDisplayChildren)); 116 bSupported &= !!(pCallbacks->pfnD3DKMTPollDisplayChildren); 105 117 106 118 pCallbacks->pfnD3DKMTEnumAdapters = (PFND3DKMT_ENUMADAPTERS)GetProcAddress(pCallbacks->hGdi32, "D3DKMTEnumAdapters"); … … 204 216 } 205 217 206 static HRESULT vboxDispKmtOpenAdapterViaHdc( PVBOXDISPKMT_CALLBACKSpCallbacks, PVBOXDISPKMT_ADAPTER pAdapter)218 static HRESULT vboxDispKmtOpenAdapterViaHdc(const VBOXDISPKMT_CALLBACKS *pCallbacks, PVBOXDISPKMT_ADAPTER pAdapter) 207 219 { 208 220 D3DKMT_OPENADAPTERFROMHDC OpenAdapterData = {0}; … … 232 244 } 233 245 234 static HRESULT vboxDispKmtOpenAdapterViaLuid( PVBOXDISPKMT_CALLBACKSpCallbacks, PVBOXDISPKMT_ADAPTER pAdapter)246 static HRESULT vboxDispKmtOpenAdapterViaLuid(const VBOXDISPKMT_CALLBACKS *pCallbacks, PVBOXDISPKMT_ADAPTER pAdapter) 235 247 { 236 248 if (pCallbacks->enmVersion < VBOXDISPKMT_CALLBACKS_VERSION_WIN8) … … 281 293 } 282 294 283 HRESULT vboxDispKmtOpenAdapter( PVBOXDISPKMT_CALLBACKSpCallbacks, PVBOXDISPKMT_ADAPTER pAdapter)295 HRESULT vboxDispKmtOpenAdapter(const VBOXDISPKMT_CALLBACKS *pCallbacks, PVBOXDISPKMT_ADAPTER pAdapter) 284 296 { 285 297 HRESULT hr = vboxDispKmtOpenAdapterViaHdc(pCallbacks, pAdapter); -
trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispKmt.h
r44529 r48070 21 21 22 22 #include <D3dkmthk.h> 23 24 #include "../../common/wddm/VBoxMPIf.h" 23 25 24 26 /* win8 release preview-specific stuff */ … … 82 84 PFND3DKMT_UNLOCK pfnD3DKMTUnlock; 83 85 86 /* auto resize support */ 87 PFND3DKMT_INVALIDATEACTIVEVIDPN pfnD3DKMTInvalidateActiveVidPn; 88 PFND3DKMT_POLLDISPLAYCHILDREN pfnD3DKMTPollDisplayChildren; 89 90 /* win8 specifics */ 84 91 PFND3DKMT_ENUMADAPTERS pfnD3DKMTEnumAdapters; 85 92 PFND3DKMT_OPENADAPTERFROMLUID pfnD3DKMTOpenAdapterFromLuid; … … 91 98 HDC hDc; 92 99 LUID Luid; 93 PVBOXDISPKMT_CALLBACKSpCallbacks;100 const VBOXDISPKMT_CALLBACKS *pCallbacks; 94 101 }VBOXDISPKMT_ADAPTER, *PVBOXDISPKMT_ADAPTER; 95 102 … … 121 128 HRESULT vboxDispKmtCallbacksTerm(PVBOXDISPKMT_CALLBACKS pCallbacks); 122 129 123 HRESULT vboxDispKmtOpenAdapter( PVBOXDISPKMT_CALLBACKSpCallbacks, PVBOXDISPKMT_ADAPTER pAdapter);130 HRESULT vboxDispKmtOpenAdapter(const VBOXDISPKMT_CALLBACKS *pCallbacks, PVBOXDISPKMT_ADAPTER pAdapter); 124 131 HRESULT vboxDispKmtCloseAdapter(PVBOXDISPKMT_ADAPTER pAdapter); 125 132 HRESULT vboxDispKmtCreateDevice(PVBOXDISPKMT_ADAPTER pAdapter, PVBOXDISPKMT_DEVICE pDevice); -
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 } -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCm.cpp
r38112 r48070 72 72 PKEVENT pUmEvent; 73 73 /* sync lock */ 74 FAST_MUTEX Mutex;74 KSPIN_LOCK SynchLock; 75 75 /* indicates whether event signaling is needed on cmd add */ 76 76 bool bEventNeeded; … … 181 181 } 182 182 183 Assert(KeGetCurrentIrql() < DISPATCH_LEVEL); 184 ExAcquireFastMutex(&pSession->Mutex); 183 Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL); 184 185 KIRQL OldIrql; 186 KeAcquireSpinLock(&pSession->SynchLock, &OldIrql); 185 187 186 188 InsertHeadList(&pSession->CommandsList, &pHdr->QueueList); … … 191 193 } 192 194 193 ExReleaseFastMutex(&pSession->Mutex);195 KeReleaseSpinLock(&pSession->SynchLock, OldIrql); 194 196 195 197 if (bSignalEvent) … … 225 227 PVBOXVIDEOCM_CMD_DR pHdr; 226 228 227 ExAcquireFastMutex(&pSession->Mutex); 229 KIRQL OldIrql; 230 KeAcquireSpinLock(&pSession->SynchLock, &OldIrql); 228 231 229 232 pCurEntry = pSession->CommandsList.Blink; … … 260 263 261 264 262 ExReleaseFastMutex(&pSession->Mutex);265 KeReleaseSpinLock(&pSession->SynchLock, OldIrql); 263 266 264 267 return STATUS_SUCCESS; … … 280 283 void vboxVideoCmSessionCtxAdd(PVBOXVIDEOCM_SESSION pSession, PVBOXVIDEOCM_CTX pContext) 281 284 { 282 Assert(KeGetCurrentIrql() < DISPATCH_LEVEL); 283 ExAcquireFastMutex(&pSession->Mutex); 285 Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL); 286 KIRQL OldIrql; 287 KeAcquireSpinLock(&pSession->SynchLock, &OldIrql); 288 284 289 vboxVideoCmSessionCtxAddLocked(pSession, pContext); 285 ExReleaseFastMutex(&pSession->Mutex); 286 290 291 KeReleaseSpinLock(&pSession->SynchLock, OldIrql); 292 } 293 294 void vboxVideoCmSessionSignalEvent(PVBOXVIDEOCM_SESSION pSession) 295 { 296 Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL); 297 if (pSession->pUmEvent) 298 KeSetEvent(pSession->pUmEvent, 0, FALSE); 287 299 } 288 300 … … 346 358 InitializeListHead(&RemainedList); 347 359 InitializeListHead(&RemainedPpList); 348 Assert(KeGetCurrentIrql() < DISPATCH_LEVEL); 349 ExAcquireFastMutex(&pSession->Mutex); 360 Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL); 361 KIRQL OldIrql; 362 KeAcquireSpinLock(&pSession->SynchLock, &OldIrql); 363 350 364 pContext->pSession = NULL; 351 365 RemoveEntryList(&pContext->SessionEntry); … … 362 376 vboxVideoCmSessionCtxDetachCmdsLocked(&pSession->PpCommandsList, pContext, &RemainedPpList); 363 377 } 364 ExReleaseFastMutex(&pSession->Mutex); 378 379 KeReleaseSpinLock(&pSession->SynchLock, OldIrql); 365 380 366 381 for (pCur = RemainedList.Flink; pCur != &RemainedList; pCur = RemainedList.Flink) … … 393 408 InitializeListHead(&pSession->PpCommandsList); 394 409 pSession->pUmEvent = pUmEvent; 395 Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);396 ExInitializeFastMutex(&pSession->Mutex);410 Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL); 411 KeInitializeSpinLock(&pSession->SynchLock); 397 412 pSession->bEventNeeded = true; 398 413 vboxVideoCmSessionCtxAddLocked(pSession, pContext); … … 421 436 if (Status == STATUS_SUCCESS) 422 437 { 423 Status = KeWaitForSingleObject(&pMgr->SynchEvent, Executive, KernelMode, 424 FALSE, /* BOOLEAN Alertable */ 425 NULL /* PLARGE_INTEGER Timeout */ 426 ); 427 Assert(Status == STATUS_SUCCESS); 438 KIRQL OldIrql; 439 KeAcquireSpinLock(&pMgr->SynchLock, &OldIrql); 440 441 bool bFound = false; 442 PVBOXVIDEOCM_SESSION pSession = NULL; 443 for (PLIST_ENTRY pEntry = pMgr->SessionList.Flink; pEntry != &pMgr->SessionList; pEntry = pEntry->Flink) 444 { 445 pSession = VBOXCMENTRY_2_SESSION(pEntry); 446 if (pSession->pUmEvent == pUmEvent) 447 { 448 bFound = true; 449 break; 450 } 451 } 452 453 pContext->u64UmData = u64UmData; 454 455 if (!bFound) 456 { 457 Status = vboxVideoCmSessionCreateLocked(pMgr, &pSession, pUmEvent, pContext); 458 Assert(Status == STATUS_SUCCESS); 459 } 460 else 461 { 462 /* Status = */vboxVideoCmSessionCtxAdd(pSession, pContext); 463 /*Assert(Status == STATUS_SUCCESS);*/ 464 } 465 466 KeReleaseSpinLock(&pMgr->SynchLock, OldIrql); 467 428 468 if (Status == STATUS_SUCCESS) 429 469 { 430 bool bFound = false; 431 PVBOXVIDEOCM_SESSION pSession = NULL; 432 for (PLIST_ENTRY pEntry = pMgr->SessionList.Flink; pEntry != &pMgr->SessionList; pEntry = pEntry->Flink) 433 { 434 pSession = VBOXCMENTRY_2_SESSION(pEntry); 435 if (pSession->pUmEvent == pUmEvent) 436 { 437 bFound = true; 438 break; 439 } 440 } 441 442 pContext->u64UmData = u64UmData; 443 444 if (!bFound) 445 { 446 Status = vboxVideoCmSessionCreateLocked(pMgr, &pSession, pUmEvent, pContext); 447 Assert(Status == STATUS_SUCCESS); 448 } 449 else 450 { 451 /* Status = */vboxVideoCmSessionCtxAdd(pSession, pContext); 452 /*Assert(Status == STATUS_SUCCESS);*/ 453 } 454 LONG tstL = KeSetEvent(&pMgr->SynchEvent, 0, FALSE); 455 Assert(!tstL); 456 457 if (Status == STATUS_SUCCESS) 458 { 459 return STATUS_SUCCESS; 460 } 470 return STATUS_SUCCESS; 461 471 } 462 472 … … 472 482 return STATUS_SUCCESS; 473 483 474 NTSTATUS Status = KeWaitForSingleObject(&pMgr->SynchEvent, Executive, KernelMode, 475 FALSE, /* BOOLEAN Alertable */ 476 NULL /* PLARGE_INTEGER Timeout */ 477 ); 478 Assert(Status == STATUS_SUCCESS); 479 if (Status == STATUS_SUCCESS) 480 { 481 vboxVideoCmSessionCtxRemoveLocked(pSession, pContext); 482 LONG tstL = KeSetEvent(&pMgr->SynchEvent, 0, FALSE); 483 Assert(!tstL); 484 } 485 486 return Status; 484 KIRQL OldIrql; 485 KeAcquireSpinLock(&pMgr->SynchLock, &OldIrql); 486 487 vboxVideoCmSessionCtxRemoveLocked(pSession, pContext); 488 489 KeReleaseSpinLock(&pMgr->SynchLock, OldIrql); 490 491 return STATUS_SUCCESS; 487 492 } 488 493 489 494 NTSTATUS vboxVideoCmInit(PVBOXVIDEOCM_MGR pMgr) 490 495 { 491 KeInitialize Event(&pMgr->SynchEvent, SynchronizationEvent, TRUE);496 KeInitializeSpinLock(&pMgr->SynchLock); 492 497 InitializeListHead(&pMgr->SessionList); 493 498 return STATUS_SUCCESS; … … 500 505 } 501 506 507 NTSTATUS vboxVideoCmSignalEvents(PVBOXVIDEOCM_MGR pMgr) 508 { 509 Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL); 510 PVBOXVIDEOCM_SESSION pSession = NULL; 511 512 KIRQL OldIrql; 513 KeAcquireSpinLock(&pMgr->SynchLock, &OldIrql); 514 515 for (PLIST_ENTRY pEntry = pMgr->SessionList.Flink; pEntry != &pMgr->SessionList; pEntry = pEntry->Flink) 516 { 517 pSession = VBOXCMENTRY_2_SESSION(pEntry); 518 vboxVideoCmSessionSignalEvent(pSession); 519 } 520 521 KeReleaseSpinLock(&pMgr->SynchLock, OldIrql); 522 523 return STATUS_SUCCESS; 524 } 525 502 526 VOID vboxVideoCmProcessKm(PVBOXVIDEOCM_CTX pContext, PVBOXVIDEOCM_CMD_CTL_KM pCmd) 503 527 { … … 515 539 { 516 540 PVBOXVIDEOCM_CMD_DR pHdr = VBOXVIDEOCM_HEAD(pCmd); 517 ExAcquireFastMutex(&pSession->Mutex); 541 KIRQL OldIrql; 542 KeAcquireSpinLock(&pSession->SynchLock, &OldIrql); 518 543 InsertTailList(&pSession->PpCommandsList, &pHdr->QueueList); 519 ExReleaseFastMutex(&pSession->Mutex);544 KeReleaseSpinLock(&pSession->SynchLock, OldIrql); 520 545 break; 521 546 } … … 550 575 // PVBOXWDDM_GETVBOXVIDEOCMCMD_HDR *pvCmd 551 576 552 Assert(KeGetCurrentIrql() < DISPATCH_LEVEL); 553 ExAcquireFastMutex(&pSession->Mutex); 577 Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL); 578 KIRQL OldIrql; 579 KeAcquireSpinLock(&pSession->SynchLock, &OldIrql); 554 580 555 581 vboxVideoCmSessionCtxDetachCmdsLocked(&pSession->PpCommandsList, pContext, &DetachedPpList); … … 606 632 } while (1); 607 633 608 ExReleaseFastMutex(&pSession->Mutex);634 KeReleaseSpinLock(&pSession->SynchLock, OldIrql); 609 635 610 636 vboxVideoCmSessionCtxPpList(pContext, &DetachedPpList); … … 647 673 } 648 674 649 VOID vboxVideoCmLock(PVBOXVIDEOCM_CTX pContext)650 {651 ExAcquireFastMutex(&pContext->pSession->Mutex);652 }653 654 VOID vboxVideoCmUnlock(PVBOXVIDEOCM_CTX pContext)655 {656 ExReleaseFastMutex(&pContext->pSession->Mutex);657 }658 659 675 static BOOLEAN vboxVideoCmHasUncompletedCmdsLocked(PVBOXVIDEOCM_MGR pMgr) 660 676 { … … 663 679 { 664 680 pSession = VBOXCMENTRY_2_SESSION(pEntry); 665 ExAcquireFastMutex(&pSession->Mutex); 681 KIRQL OldIrql; 682 KeAcquireSpinLock(&pSession->SynchLock, &OldIrql); 683 666 684 if (pSession->bEventNeeded) 667 685 { 668 686 /* commands still being processed */ 669 ExReleaseFastMutex(&pSession->Mutex);687 KeReleaseSpinLock(&pSession->SynchLock, OldIrql); 670 688 return TRUE; 671 689 } 672 ExReleaseFastMutex(&pSession->Mutex);690 KeReleaseSpinLock(&pSession->SynchLock, OldIrql); 673 691 } 674 692 return FALSE; 675 693 } 676 677 /* waits for all outstanding commands to completed by client678 * assumptions here are:679 * 1. no new commands are submitted while we are waiting680 * 2. it is assumed that a client completes all previously received commands681 * once it queries for the new set of commands */682 NTSTATUS vboxVideoCmWaitCompletedCmds(PVBOXVIDEOCM_MGR pMgr, uint32_t msTimeout)683 {684 LARGE_INTEGER Timeout;685 PLARGE_INTEGER pTimeout;686 uint32_t cIters;687 688 if (msTimeout != RT_INDEFINITE_WAIT)689 {690 uint32_t msIter = 2;691 cIters = msTimeout/msIter;692 if (!cIters)693 {694 msIter = msTimeout;695 cIters = 1;696 }697 Timeout.QuadPart = -(int64_t) msIter /* ms */ * 10000;698 pTimeout = &Timeout;699 }700 else701 {702 pTimeout = NULL;703 cIters = 1;704 }705 706 Assert(cIters);707 do708 {709 NTSTATUS Status = KeWaitForSingleObject(&pMgr->SynchEvent, Executive, KernelMode,710 FALSE, /* BOOLEAN Alertable */711 pTimeout /* PLARGE_INTEGER Timeout */712 );713 if (Status == STATUS_TIMEOUT)714 {715 --cIters;716 }717 else718 {719 if (!NT_SUCCESS(Status))720 {721 WARN(("KeWaitForSingleObject failed with Status (0x%x)", Status));722 return Status;723 }724 725 /* succeeded */726 if (!vboxVideoCmHasUncompletedCmdsLocked(pMgr))727 {728 LONG tstL = KeSetEvent(&pMgr->SynchEvent, 0, FALSE);729 Assert(!tstL);730 return STATUS_SUCCESS;731 }732 733 LONG tstL = KeSetEvent(&pMgr->SynchEvent, 0, FALSE);734 Assert(!tstL);735 }736 737 if (!cIters)738 break;739 740 KeDelayExecutionThread(KernelMode, FALSE, pTimeout);741 --cIters;742 if (!cIters)743 break;744 } while (0);745 746 return STATUS_TIMEOUT;747 }748 -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCm.h
r38112 r48070 22 22 typedef struct VBOXVIDEOCM_MGR 23 23 { 24 K EVENT SynchEvent;24 KSPIN_LOCK SynchLock; 25 25 /* session list */ 26 26 LIST_ENTRY SessionList; … … 41 41 NTSTATUS vboxVideoCmInit(PVBOXVIDEOCM_MGR pMgr); 42 42 NTSTATUS vboxVideoCmTerm(PVBOXVIDEOCM_MGR pMgr); 43 NTSTATUS vboxVideoCmSignalEvents(PVBOXVIDEOCM_MGR pMgr); 43 44 44 45 NTSTATUS vboxVideoCmCmdSubmitCompleteEvent(PVBOXVIDEOCM_CTX pContext, PKEVENT pEvent); … … 58 59 NTSTATUS vboxVideoCmEscape(PVBOXVIDEOCM_CTX pContext, PVBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD pCmd, uint32_t cbCmd); 59 60 60 NTSTATUS vboxVideoCmWaitCompletedCmds(PVBOXVIDEOCM_MGR pMgr, uint32_t msTimeout);61 62 VOID vboxVideoCmLock(PVBOXVIDEOCM_CTX pContext);63 VOID vboxVideoCmUnlock(PVBOXVIDEOCM_CTX pContext);64 65 61 #endif /* #ifndef ___VBoxMPCm_h___ */ -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPMisc.cpp
r47566 r48070 573 573 } 574 574 575 #define VBOXWDDM_REG_DRVKEY_PREFIX L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\"576 577 575 NTSTATUS vboxWddmRegQueryDrvKeyName(PVBOXMP_DEVEXT pDevExt, ULONG cbBuf, PWCHAR pBuf, PULONG pcbResult) 578 576 { … … 607 605 } 608 606 609 #define VBOXWDDM_REG_DISPLAYSETTINGSKEY_PREFIX_VISTA L"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Control\\VIDEO\\"610 #define VBOXWDDM_REG_DISPLAYSETTINGSKEY_PREFIX_WIN7 L"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\UnitedVideo\\CONTROL\\VIDEO\\"611 612 #define VBOXWDDM_REG_DISPLAYSETTINGS_ATTACH_RELX L"Attach.RelativeX"613 #define VBOXWDDM_REG_DISPLAYSETTINGS_ATTACH_RELY L"Attach.RelativeY"614 #define VBOXWDDM_REG_DISPLAYSETTINGS_ATTACH_DESKTOP L"Attach.ToDesktop"615 616 607 NTSTATUS vboxWddmRegQueryDisplaySettingsKeyName(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, 617 608 ULONG cbBuf, PWCHAR pBuf, PULONG pcbResult) … … 660 651 return Status; 661 652 } 662 663 #define VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Video\\"664 #define VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY_SUBKEY L"\\Video"665 653 666 654 NTSTATUS vboxWddmRegQueryVideoGuidString(PVBOXMP_DEVEXT pDevExt, ULONG cbBuf, PWCHAR pBuf, PULONG pcbResult) … … 891 879 } 892 880 881 NTSTATUS vboxWddmRegDrvFlagsSet(PVBOXMP_DEVEXT pDevExt, DWORD fVal) 882 { 883 HANDLE hKey = NULL; 884 NTSTATUS Status = IoOpenDeviceRegistryKey(pDevExt->pPDO, PLUGPLAY_REGKEY_DRIVER, GENERIC_WRITE, &hKey); 885 if (!NT_SUCCESS(Status)) 886 { 887 WARN(("IoOpenDeviceRegistryKey failed, Status = 0x%x", Status)); 888 return Status; 889 } 890 891 Status = vboxWddmRegSetValueDword(hKey, VBOXWDDM_REG_DRV_FLAGS_NAME, fVal); 892 if (!NT_SUCCESS(Status)) 893 WARN(("vboxWddmRegSetValueDword failed, Status = 0x%x", Status)); 894 895 NTSTATUS tmpStatus = ZwClose(hKey); 896 Assert(tmpStatus == STATUS_SUCCESS); 897 898 return Status; 899 } 900 901 DWORD vboxWddmRegDrvFlagsGet(PVBOXMP_DEVEXT pDevExt, DWORD fDefault) 902 { 903 HANDLE hKey = NULL; 904 NTSTATUS Status = IoOpenDeviceRegistryKey(pDevExt->pPDO, PLUGPLAY_REGKEY_DRIVER, GENERIC_READ, &hKey); 905 if (!NT_SUCCESS(Status)) 906 { 907 WARN(("IoOpenDeviceRegistryKey failed, Status = 0x%x", Status)); 908 return fDefault; 909 } 910 911 DWORD dwVal = 0; 912 Status = vboxWddmRegQueryValueDword(hKey, VBOXWDDM_REG_DRV_FLAGS_NAME, &dwVal); 913 if (!NT_SUCCESS(Status)) 914 { 915 WARN(("vboxWddmRegQueryValueDword failed, Status = 0x%x", Status)); 916 dwVal = fDefault; 917 } 918 919 NTSTATUS tmpStatus = ZwClose(hKey); 920 Assert(tmpStatus == STATUS_SUCCESS); 921 922 return dwVal; 923 } 924 893 925 NTSTATUS vboxWddmRegQueryValueDword(IN HANDLE hKey, IN PWCHAR pName, OUT PDWORD pDword) 894 926 { … … 920 952 } 921 953 922 NTSTATUS vboxWddmRegSetValueDword(IN HANDLE hKey, IN PWCHAR pName, OUTDWORD val)954 NTSTATUS vboxWddmRegSetValueDword(IN HANDLE hKey, IN PWCHAR pName, IN DWORD val) 923 955 { 924 956 UNICODE_STRING RtlStr; -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPMisc.h
r47566 r48070 99 99 NTSTATUS vboxWddmRegOpenKey(OUT PHANDLE phKey, IN PWCHAR pName, IN ACCESS_MASK fAccess); 100 100 NTSTATUS vboxWddmRegQueryValueDword(IN HANDLE hKey, IN PWCHAR pName, OUT PDWORD pDword); 101 NTSTATUS vboxWddmRegSetValueDword(IN HANDLE hKey, IN PWCHAR pName, OUT DWORD val); 101 NTSTATUS vboxWddmRegSetValueDword(IN HANDLE hKey, IN PWCHAR pName, IN DWORD val); 102 103 NTSTATUS vboxWddmRegDrvFlagsSet(PVBOXMP_DEVEXT pDevExt, DWORD fVal); 104 DWORD vboxWddmRegDrvFlagsGet(PVBOXMP_DEVEXT pDevExt, DWORD fDefault); 102 105 103 106 UNICODE_STRING* vboxWddmVGuidGet(PVBOXMP_DEVEXT pDevExt); … … 184 187 #endif 185 188 189 NTSTATUS vboxWddmChildStatusConnect(PVBOXMP_DEVEXT pDevExt, uint32_t iChild, BOOLEAN fConnect); 190 186 191 #endif /* #ifndef ___VBoxMPMisc_h__ */ -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPTypes.h
r47059 r48070 35 35 #include <cr_vreg.h> 36 36 37 #ifdef DEBUG_misha 38 extern DWORD g_VBoxDbgBreakModes; 39 #endif 37 40 38 41 #if 0 … … 139 142 uint32_t HeightVisible; 140 143 uint32_t HeightTotal; 144 /* since there coul be multiple state changes on auto-resize, 145 * we pend notifying host to avoi flickering */ 146 volatile bool fStateSyncPening; 147 bool fConnected; 148 bool fConfigured; 141 149 } VBOXWDDM_TARGET, *PVBOXWDDM_TARGET; 142 150 -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVidPn.cpp
r44529 r48070 1263 1263 const DXGK_VIDPNTARGETMODESET_INTERFACE *pNewVidPnTargetModeSetInterface; 1264 1264 1265 if (VidPnSourceId != VidPnTargetId || pCbContext->apPathInfos[VidPnTargetId].enmState != VBOXVIDPNPATHITEM_STATE_PRESENT) 1266 { 1267 return STATUS_SUCCESS; 1268 } 1265 Assert(VidPnSourceId == VidPnTargetId); 1269 1266 1270 1267 D3DKMDT_HVIDPNSOURCEMODESET hCurVidPnSourceModeSet; … … 1306 1303 { 1307 1304 Assert(hNewVidPnTargetModeSet); 1308 if (VidPnSourceId == VidPnTargetId && pCbContext->apPathInfos[VidPnTargetId].enmState == VBOXVIDPNPATHITEM_STATE_PRESENT) 1309 { 1310 Assert(VidPnSourceId == VidPnTargetId); 1311 1305 Assert(VidPnSourceId == VidPnTargetId); 1306 // if (VidPnSourceId == VidPnTargetId && pCbContext->apPathInfos[VidPnTargetId].enmState == VBOXVIDPNPATHITEM_STATE_PRESENT) 1307 { 1312 1308 for (uint32_t i = 0; i < pInfo->cResolutions; ++i) 1313 1309 { … … 1398 1394 const DXGK_VIDPNSOURCEMODESET_INTERFACE *pNewVidPnSourceModeSetInterface; 1399 1395 1400 if (VidPnSourceId != VidPnTargetId || pCbContext->apPathInfos[VidPnSourceId].enmState != VBOXVIDPNPATHITEM_STATE_PRESENT) 1401 { 1402 return STATUS_SUCCESS; 1403 } 1396 Assert(VidPnSourceId == VidPnTargetId); 1404 1397 1405 1398 D3DKMDT_HVIDPNTARGETMODESET hCurVidPnTargetModeSet; … … 1441 1434 { 1442 1435 Assert(hNewVidPnSourceModeSet); 1443 if (VidPnSourceId == VidPnTargetId && pCbContext->apPathInfos[VidPnSourceId].enmState == VBOXVIDPNPATHITEM_STATE_PRESENT)1444 { 1445 Assert(VidPnSourceId == VidPnTargetId);1436 Assert(VidPnSourceId == VidPnTargetId); 1437 // if (VidPnSourceId == VidPnTargetId && pCbContext->apPathInfos[VidPnSourceId].enmState == VBOXVIDPNPATHITEM_STATE_PRESENT) 1438 { 1446 1439 for (uint32_t i = 0; i < pInfo->cModes; ++i) 1447 1440 { … … 1755 1748 else 1756 1749 { 1757 AssertFailed();1750 WARN(("cItems(%d) <= VidPnSourceId(%d)", pCbContext->cItems, VidPnSourceId)); 1758 1751 Status = STATUS_BUFFER_OVERFLOW; 1759 1752 break; … … 1766 1759 else 1767 1760 { 1768 AssertFailed();1761 WARN(("cItems(%d) <= VidPnTargetId(%d)", pCbContext->cItems, VidPnTargetId)); 1769 1762 Status = STATUS_BUFFER_OVERFLOW; 1770 1763 break; … … 1775 1768 1776 1769 /* VidPnSourceId == VidPnTargetId */ 1770 Assert(VidPnSourceId == VidPnTargetId); 1777 1771 if (pCbContext->cItems > VidPnSourceId) 1778 1772 { … … 1785 1779 else 1786 1780 { 1787 AssertFailed();1781 WARN(("cItems(%d) <= VidPnSource/TargetId(%d)", pCbContext->cItems, VidPnSourceId)); 1788 1782 Status = STATUS_BUFFER_OVERFLOW; 1789 1783 break; … … 1801 1795 /* we currently support only 0 -> 0, 1 -> 1, 2 -> 2 paths, AND 0 -> 0 must be present 1802 1796 * this routine disables all paths unsupported */ 1803 NTSTATUS vboxVidPnCheckTopology(D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface, 1804 BOOLEAN fBreakOnDisabled, UINT cItems, PVBOXVIDPNPATHITEM paItems, BOOLEAN *pfDisabledFound) 1805 { 1797 NTSTATUS vboxVidPnCheckTopology(D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface, BOOLEAN *pfSupported) 1798 { 1799 VBOXVIDPNPATHITEM aItems[VBOX_VIDEO_MAX_SCREENS]; 1800 const uint32_t cItems = RT_ELEMENTS(aItems); 1806 1801 UINT i; 1807 1802 for (i = 0; i < cItems; ++i) 1808 1803 { 1809 paItems[i].enmState = VBOXVIDPNPATHITEM_STATE_NOT_EXISTS;1804 aItems[i].enmState = VBOXVIDPNPATHITEM_STATE_NOT_EXISTS; 1810 1805 } 1811 1806 VBOXVIDPNGETPATHSINFO CbContext = {0}; 1812 1807 CbContext.Status = STATUS_SUCCESS; 1813 CbContext.fBreakOnDisabled = fBreakOnDisabled;1808 CbContext.fBreakOnDisabled = FALSE; 1814 1809 CbContext.fDisabledFound = FALSE; 1815 1810 CbContext.cItems = cItems; 1816 CbContext.paItems = paItems;1811 CbContext.paItems = aItems; 1817 1812 NTSTATUS Status = vboxVidPnEnumPaths(hVidPnTopology, pVidPnTopologyInterface, vboxVidPnCheckTopologyEnum, &CbContext); 1818 1813 if (!NT_SUCCESS(Status)) … … 1829 1824 } 1830 1825 1831 if (pfDisabledFound)1832 *pfDisabledFound = CbContext.fDisabledFound; 1833 1834 if (!fBreakOnDisabled)1835 {1836 /* now check if 0->0 path is present and enabled, and if not, disable everything */ 1837 if (cItems && paItems[0].enmState != VBOXVIDPNPATHITEM_STATE_PRESENT)1838 {1839 LOGREL(("path 0 not set to present\n")); 1840 for (i = 0; i < cItems; ++i) 1841 { 1842 if (paItems[i].enmState == VBOXVIDPNPATHITEM_STATE_PRESENT) 1843 paItems[i].enmState = VBOXVIDPNPATHITEM_STATE_DISABLED; 1844 } 1845 }1846 }1826 BOOLEAN fSupported = !CbContext.fDisabledFound; 1827 1828 /* now check if 0->0 path is present and enabled, and if not, disable everything */ 1829 // if (cItems && aItems[0].enmState != VBOXVIDPNPATHITEM_STATE_PRESENT) 1830 // { 1831 // LOG(("path 0 not set to present\n")); 1832 //// for (i = 0; i < cItems; ++i) 1833 //// { 1834 //// if (aItems[i].enmState == VBOXVIDPNPATHITEM_STATE_PRESENT) 1835 //// aItems[i].enmState = VBOXVIDPNPATHITEM_STATE_DISABLED; 1836 //// } 1837 // fSupported = FALSE; 1838 // } 1839 1840 if (pfSupported) 1841 *pfSupported = fSupported; 1847 1842 1848 1843 return Status; … … 2063 2058 else 2064 2059 { 2065 Assert(Status == STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET);2066 2060 if (Status != STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET) 2067 LOGREL(("pfnAcquireNextPathInfo Failed Status(0x%x), ignored since callback returned false", Status));2061 WARN(("pfnAcquireNextPathInfo Failed Status(0x%x), ignored since callback returned false", Status)); 2068 2062 Status = STATUS_SUCCESS; 2069 2063 } … … 2080 2074 else 2081 2075 { 2082 AssertBreakpoint(); 2083 LOGREL(("pfnAcquireNextPathInfo Failed Status(0x%x)", Status)); 2076 WARN(("pfnAcquireNextPathInfo Failed Status(0x%x)", Status)); 2084 2077 pNewVidPnPresentPathInfo = NULL; 2085 2078 break; … … 2090 2083 Status = STATUS_SUCCESS; 2091 2084 else 2092 LOGREL(("pfnAcquireFirstModeInfo failed Status(0x%x)", Status));2085 WARN(("pfnAcquireFirstModeInfo failed Status(0x%x)", Status)); 2093 2086 2094 2087 return Status; … … 2181 2174 return Status == STATUS_SUCCESS; 2182 2175 } 2176 2177 #ifdef DEBUG_misha 2178 DWORD g_VBoxDbgBreakModes = 0; 2179 #endif 2183 2180 2184 2181 NTSTATUS vboxVidPnCommitSourceModeForSrcId(PVBOXMP_DEVEXT pDevExt, const D3DKMDT_HVIDPN hDesiredVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId, PVBOXWDDM_ALLOCATION pAllocation) … … 2235 2232 } 2236 2233 else 2237 LOGREL(("vboxVidPnEnumTargetsForSource failed Status(0x%x)", Status));2234 WARN(("vboxVidPnEnumTargetsForSource failed Status(0x%x)", Status)); 2238 2235 } 2239 2236 else 2240 LOGREL(("pfnGetTopology failed Status(0x%x)", Status));2237 WARN(("pfnGetTopology failed Status(0x%x)", Status)); 2241 2238 } 2242 2239 else 2243 LOGREL(("vboxVidPnCommitSourceMode failed Status(0x%x)", Status));2240 WARN(("vboxVidPnCommitSourceMode failed Status(0x%x)", Status)); 2244 2241 /* release */ 2245 2242 pCurVidPnSourceModeSetInterface->pfnReleaseModeInfo(hCurVidPnSourceModeSet, pPinnedVidPnSourceModeInfo); … … 2247 2244 else if (Status == STATUS_GRAPHICS_MODE_NOT_PINNED) 2248 2245 { 2246 #ifdef DEBUG_misha 2247 Assert(!g_VBoxDbgBreakModes); 2248 ++g_VBoxDbgBreakModes; 2249 #endif 2249 2250 Status = vboxVidPnCommitSourceMode(pDevExt, srcId, NULL, pAllocation); 2250 2251 Assert(Status == STATUS_SUCCESS); 2251 2252 } 2252 2253 else 2253 LOGREL(("pfnAcquirePinnedModeInfo failed Status(0x%x)", Status));2254 WARN(("pfnAcquirePinnedModeInfo failed Status(0x%x)", Status)); 2254 2255 2255 2256 pVidPnInterface->pfnReleaseSourceModeSet(hDesiredVidPn, hCurVidPnSourceModeSet); … … 2257 2258 else 2258 2259 { 2259 LOGREL(("pfnAcquireSourceModeSet failed Status(0x%x)", Status));2260 WARN(("pfnAcquireSourceModeSet failed Status(0x%x)", Status)); 2260 2261 } 2261 2262 -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVidPn.h
r37490 r48070 58 58 CONST DXGKARG_ENUMVIDPNCOFUNCMODALITY* pEnumCofuncModalityArg; 59 59 PVBOXWDDM_VIDEOMODES_INFO pInfos; 60 UINT cPathInfos;61 PVBOXVIDPNPATHITEM apPathInfos;60 // UINT cPathInfos; 61 // PVBOXVIDPNPATHITEM apPathInfos; 62 62 } VBOXVIDPNCOFUNCMODALITY, *PVBOXVIDPNCOFUNCMODALITY; 63 63 … … 146 146 NTSTATUS vboxVidPnCofuncModalityForPath(PVBOXVIDPNCOFUNCMODALITY pCbContext, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId); 147 147 148 NTSTATUS vboxVidPnCheckTopology(D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface, 149 BOOLEAN fBreakOnDisabled, UINT cItems, PVBOXVIDPNPATHITEM paItems, BOOLEAN *pfDisabledFound); 148 NTSTATUS vboxVidPnCheckTopology(D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface, BOOLEAN *pfSupported); 150 149 151 150 NTSTATUS vboxVidPnPathAdd(D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface, -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp
r47603 r48070 31 31 #include <VBox/Hardware/VBoxVideoVBE.h> 32 32 33 #include <stdio.h> 34 33 35 DWORD g_VBoxLogUm = 0; 34 36 #ifdef VBOX_WDDM_WIN8 … … 187 189 } 188 190 191 BOOL vboxWddmGhDisplayCheckCompletePeningScreenInfo(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId) 192 { 193 if (!ASMAtomicCmpXchgBool(&pDevExt->aTargets[VidPnTargetId].fStateSyncPening, false, true)) 194 return FALSE; 195 return vboxWddmGhDisplayCheckSetInfoFromSource(pDevExt, &pDevExt->aSources[VidPnTargetId]); 196 } 197 189 198 NTSTATUS vboxWddmGhDisplayPostInfoView(PVBOXMP_DEVEXT pDevExt, const VBOXWDDM_ALLOC_DATA *pAllocData) 190 199 { … … 302 311 } 303 312 304 bool vboxWddmGhDisplayCheckSetInfoFromSource(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SOURCE pSource) 305 { 306 // Assert(VBOXVIDEOOFFSET_VOID != pSource->AllocData.Addr.offVram); 307 308 if (pSource->fGhSynced) 309 return false; 313 bool vboxWddmGhDisplaySetInfoFromSourceTarget(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SOURCE pSource, PVBOXWDDM_TARGET pTarget) 314 { 315 if (!pTarget->HeightVisible) 316 { 317 vboxWddmGhDisplayHideScreen(pDevExt, pSource->AllocData.SurfDesc.VidPnSourceId); 318 pSource->fGhSynced = 1; 319 return true; 320 } 310 321 311 322 char fGhSynced = 1; … … 346 357 WARN(("vboxWddmGhDisplaySetInfo failed, Status (0x%x)", Status)); 347 358 359 vboxVideoCmSignalEvents(&pDevExt->SeamlessCtxMgr); 360 348 361 return true; 362 } 363 364 bool vboxWddmGhDisplayCheckSetInfoFromSource(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SOURCE pSource) 365 { 366 Assert(VBOXVIDEOOFFSET_VOID != pSource->AllocData.Addr.offVram 367 || !pDevExt->aTargets[pSource->AllocData.SurfDesc.VidPnSourceId].HeightVisible); 368 369 if (pSource->fGhSynced) 370 return false; 371 372 PVBOXWDDM_TARGET pTarget = &pDevExt->aTargets[pSource->AllocData.SurfDesc.VidPnSourceId]; 373 if (ASMAtomicUoReadBool(&pTarget->fStateSyncPening)) 374 return false; 375 376 return vboxWddmGhDisplaySetInfoFromSourceTarget(pDevExt, pSource, pTarget); 349 377 } 350 378 … … 467 495 return VBOXWDDM_HGSMICMD_TYPE_CTL; 468 496 return VBOXWDDM_HGSMICMD_TYPE_UNDEFINED; 469 }470 471 static NTSTATUS vboxWddmChildStatusReportPerform(PVBOXMP_DEVEXT pDevExt, PVBOXVDMA_CHILD_STATUS pChildStatus, D3DDDI_VIDEO_PRESENT_TARGET_ID iChild)472 {473 DXGK_CHILD_STATUS DdiChildStatus;474 if (pChildStatus->fFlags & VBOXVDMA_CHILD_STATUS_F_DISCONNECTED)475 {476 /* report disconnected */477 memset(&DdiChildStatus, 0, sizeof (DdiChildStatus));478 DdiChildStatus.Type = StatusConnection;479 if (iChild != D3DDDI_ID_UNINITIALIZED)480 {481 Assert(iChild < UINT32_MAX/2);482 Assert(iChild < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays);483 DdiChildStatus.ChildUid = iChild;484 }485 else486 {487 Assert(pChildStatus->iChild < UINT32_MAX/2);488 Assert(pChildStatus->iChild < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays);489 DdiChildStatus.ChildUid = pChildStatus->iChild;490 }491 LOG(("Reporting DISCONNECT to child %d", DdiChildStatus.ChildUid));492 DdiChildStatus.HotPlug.Connected = FALSE;493 NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbIndicateChildStatus(pDevExt->u.primary.DxgkInterface.DeviceHandle, &DdiChildStatus);494 if (!NT_SUCCESS(Status))495 {496 WARN(("DxgkCbIndicateChildStatus failed with Status (0x%x)", Status));497 return Status;498 }499 }500 501 if (pChildStatus->fFlags & VBOXVDMA_CHILD_STATUS_F_CONNECTED)502 {503 /* report disconnected */504 memset(&DdiChildStatus, 0, sizeof (DdiChildStatus));505 DdiChildStatus.Type = StatusConnection;506 if (iChild != D3DDDI_ID_UNINITIALIZED)507 {508 Assert(iChild < UINT32_MAX/2);509 Assert(iChild < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays);510 DdiChildStatus.ChildUid = iChild;511 }512 else513 {514 Assert(pChildStatus->iChild < UINT32_MAX/2);515 Assert(pChildStatus->iChild < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays);516 DdiChildStatus.ChildUid = pChildStatus->iChild;517 }518 LOG(("Reporting CONNECT to child %d", DdiChildStatus.ChildUid));519 DdiChildStatus.HotPlug.Connected = TRUE;520 NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbIndicateChildStatus(pDevExt->u.primary.DxgkInterface.DeviceHandle, &DdiChildStatus);521 if (!NT_SUCCESS(Status))522 {523 WARN(("DxgkCbIndicateChildStatus failed with Status (0x%x)", Status));524 return Status;525 }526 }527 528 if (pChildStatus->fFlags & VBOXVDMA_CHILD_STATUS_F_ROTATED)529 {530 /* report disconnected */531 memset(&DdiChildStatus, 0, sizeof (DdiChildStatus));532 DdiChildStatus.Type = StatusRotation;533 if (iChild != D3DDDI_ID_UNINITIALIZED)534 {535 Assert(iChild < UINT32_MAX/2);536 Assert(iChild < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays);537 DdiChildStatus.ChildUid = iChild;538 }539 else540 {541 Assert(pChildStatus->iChild < UINT32_MAX/2);542 Assert(pChildStatus->iChild < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays);543 DdiChildStatus.ChildUid = pChildStatus->iChild;544 }545 LOG(("Reporting ROTATED to child %d", DdiChildStatus.ChildUid));546 DdiChildStatus.Rotation.Angle = pChildStatus->u8RotationAngle;547 NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbIndicateChildStatus(pDevExt->u.primary.DxgkInterface.DeviceHandle, &DdiChildStatus);548 if (!NT_SUCCESS(Status))549 {550 WARN(("DxgkCbIndicateChildStatus failed with Status (0x%x)", Status));551 return Status;552 }553 }554 555 return STATUS_SUCCESS;556 }557 558 static NTSTATUS vboxWddmChildStatusDoReportReconnected(PVBOXMP_DEVEXT pDevExt, VBOXVDMACMD_CHILD_STATUS_IRQ *pBody)559 {560 NTSTATUS Status = STATUS_SUCCESS;561 562 for (UINT i = 0; i < pBody->cInfos; ++i)563 {564 PVBOXVDMA_CHILD_STATUS pInfo = &pBody->aInfos[i];565 if (pBody->fFlags & VBOXVDMACMD_CHILD_STATUS_IRQ_F_APPLY_TO_ALL)566 {567 for (D3DDDI_VIDEO_PRESENT_TARGET_ID iChild = 0; iChild < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++iChild)568 {569 Status = vboxWddmChildStatusReportPerform(pDevExt, pInfo, iChild);570 if (!NT_SUCCESS(Status))571 {572 WARN(("vboxWddmChildStatusReportPerform failed with Status (0x%x)", Status));573 break;574 }575 }576 }577 else578 {579 Status = vboxWddmChildStatusReportPerform(pDevExt, pInfo, D3DDDI_ID_UNINITIALIZED);580 if (!NT_SUCCESS(Status))581 {582 WARN(("vboxWddmChildStatusReportPerform failed with Status (0x%x)", Status));583 break;584 }585 }586 }587 588 return Status;589 }590 591 typedef struct VBOXWDDMCHILDSTATUSCB592 {593 PVBOXVDMACBUF_DR pDr;594 PKEVENT pEvent;595 } VBOXWDDMCHILDSTATUSCB, *PVBOXWDDMCHILDSTATUSCB;596 597 static DECLCALLBACK(VOID) vboxWddmChildStatusReportCompletion(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pCmd, PVOID pvContext)598 {599 /* we should be called from our DPC routine */600 Assert(KeGetCurrentIrql() == DISPATCH_LEVEL);601 602 PVBOXWDDMCHILDSTATUSCB pCtx = (PVBOXWDDMCHILDSTATUSCB)pvContext;603 PVBOXVDMACBUF_DR pDr = pCtx->pDr;604 PVBOXVDMACMD pHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD);605 VBOXVDMACMD_CHILD_STATUS_IRQ *pBody = VBOXVDMACMD_BODY(pHdr, VBOXVDMACMD_CHILD_STATUS_IRQ);606 607 vboxWddmChildStatusDoReportReconnected(pDevExt, pBody);608 609 vboxVdmaCBufDrFree(&pDevExt->u.primary.Vdma, pDr);610 611 if (pCtx->pEvent)612 {613 KeSetEvent(pCtx->pEvent, 0, FALSE);614 }615 }616 617 static NTSTATUS vboxWddmChildStatusReportReconnected(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_TARGET_ID idTarget)618 {619 #ifdef VBOX_WDDM_MONITOR_REPLUG_IRQ620 NTSTATUS Status = STATUS_UNSUCCESSFUL;621 UINT cbCmd = VBOXVDMACMD_SIZE_FROMBODYSIZE(sizeof (VBOXVDMACMD_CHILD_STATUS_IRQ));622 623 PVBOXVDMACBUF_DR pDr = vboxVdmaCBufDrCreate(&pDevExt->u.primary.Vdma, cbCmd);624 if (pDr)625 {626 // vboxVdmaCBufDrCreate zero initializes the pDr627 /* the command data follows the descriptor */628 pDr->fFlags = VBOXVDMACBUF_FLAG_BUF_FOLLOWS_DR;629 pDr->cbBuf = cbCmd;630 pDr->rc = VERR_NOT_IMPLEMENTED;631 632 PVBOXVDMACMD pHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD);633 pHdr->enmType = VBOXVDMACMD_TYPE_CHILD_STATUS_IRQ;634 pHdr->u32CmdSpecific = 0;635 PVBOXVDMACMD_CHILD_STATUS_IRQ pBody = VBOXVDMACMD_BODY(pHdr, VBOXVDMACMD_CHILD_STATUS_IRQ);636 pBody->cInfos = 1;637 if (idTarget == D3DDDI_ID_ALL)638 {639 pBody->fFlags |= VBOXVDMACMD_CHILD_STATUS_IRQ_F_APPLY_TO_ALL;640 }641 pBody->aInfos[0].iChild = idTarget;642 pBody->aInfos[0].fFlags = VBOXVDMA_CHILD_STATUS_F_DISCONNECTED | VBOXVDMA_CHILD_STATUS_F_CONNECTED;643 /* we're going to KeWaitForSingleObject */644 Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);645 646 PVBOXVDMADDI_CMD pDdiCmd = VBOXVDMADDI_CMD_FROM_BUF_DR(pDr);647 VBOXWDDMCHILDSTATUSCB Ctx;648 KEVENT Event;649 KeInitializeEvent(&Event, NotificationEvent, FALSE);650 Ctx.pDr = pDr;651 Ctx.pEvent = &Event;652 vboxVdmaDdiCmdInit(pDdiCmd, 0, 0, vboxWddmChildStatusReportCompletion, &Ctx);653 /* mark command as submitted & invisible for the dx runtime since dx did not originate it */654 vboxVdmaDdiCmdSubmittedNotDx(pDdiCmd);655 int rc = vboxVdmaCBufDrSubmit(pDevExt, &pDevExt->u.primary.Vdma, pDr);656 Assert(rc == VINF_SUCCESS);657 if (RT_SUCCESS(rc))658 {659 Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);660 Assert(Status == STATUS_SUCCESS);661 return STATUS_SUCCESS;662 }663 664 Status = STATUS_UNSUCCESSFUL;665 666 vboxVdmaCBufDrFree(&pDevExt->u.primary.Vdma, pDr);667 }668 else669 {670 Assert(0);671 /* @todo: try flushing.. */672 LOGREL(("vboxVdmaCBufDrCreate returned NULL"));673 Status = STATUS_INSUFFICIENT_RESOURCES;674 }675 676 return Status;677 #else678 VBOXVDMACMD_CHILD_STATUS_IRQ Body = {0};679 Body.cInfos = 1;680 if (idTarget == D3DDDI_ID_ALL)681 {682 Body.fFlags |= VBOXVDMACMD_CHILD_STATUS_IRQ_F_APPLY_TO_ALL;683 }684 Body.aInfos[0].iChild = idTarget;685 Body.aInfos[0].fFlags = VBOXVDMA_CHILD_STATUS_F_DISCONNECTED | VBOXVDMA_CHILD_STATUS_F_CONNECTED;686 Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);687 return vboxWddmChildStatusDoReportReconnected(pDevExt, &Body);688 #endif689 }690 691 static NTSTATUS vboxWddmChildStatusCheckByMask(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_VIDEOMODES_INFO paInfos, uint8_t *pMask)692 {693 NTSTATUS Status = STATUS_SUCCESS;694 bool bChanged[VBOX_VIDEO_MAX_SCREENS] = {0};695 int i;696 697 LOG(("checking child status.."));698 699 for (i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)700 {701 if (pMask && !ASMBitTest(pMask, i))702 continue;703 704 LOG(("requested to change child status for display %d", i));705 706 /* @todo: check that we actually need the current source->target */707 PVBOXWDDM_VIDEOMODES_INFO pInfo = &paInfos[i];708 VIDEO_MODE_INFORMATION *pModeInfo = &pInfo->aModes[pInfo->iPreferredMode];709 BOOLEAN fMatch = FALSE;710 Status = vboxVidPnMatchMonitorModes(pDevExt, i, pInfo->aResolutions, pInfo->cResolutions, &fMatch);711 if (!NT_SUCCESS(Status))712 {713 WARN(("vboxVidPnMatchMonitorModes failed Status(0x%x)", Status));714 /* ignore the failures here, although we probably should not?? */715 break;716 }717 718 bChanged[i] = !fMatch;719 }720 721 if (!NT_SUCCESS(Status))722 {723 WARN(("updating monitor modes failed, Status(0x%x)", Status));724 return Status;725 }726 727 for (i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)728 {729 if (bChanged[i])730 {731 LOG(("modes changed for display %d", i));732 733 NTSTATUS tmpStatus = vboxWddmChildStatusReportReconnected(pDevExt, i);734 if (!NT_SUCCESS(tmpStatus))735 {736 WARN(("vboxWddmChildStatusReportReconnected failed Status(0x%x)", Status));737 /* ignore the failures here, although we probably should not?? */738 break;739 }740 }741 }742 743 /* wait for the reconnected monitor data to be picked up */744 CONST DXGK_MONITOR_INTERFACE *pMonitorInterface;745 Status = pDevExt->u.primary.DxgkInterface.DxgkCbQueryMonitorInterface(pDevExt->u.primary.DxgkInterface.DeviceHandle, DXGK_MONITOR_INTERFACE_VERSION_V1, &pMonitorInterface);746 if (!NT_SUCCESS(Status))747 {748 WARN(("DxgkCbQueryMonitorInterface failed, Status()0x%x", Status));749 return Status;750 }751 752 for (i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)753 {754 D3DKMDT_HMONITORSOURCEMODESET hMonitorSMS;755 CONST DXGK_MONITORSOURCEMODESET_INTERFACE *pMonitorSMSIf;756 if (!bChanged[i])757 continue;758 759 while (1)760 {761 Status = pMonitorInterface->pfnAcquireMonitorSourceModeSet(pDevExt->u.primary.DxgkInterface.DeviceHandle,762 i,763 &hMonitorSMS,764 &pMonitorSMSIf);765 if (NT_SUCCESS(Status))766 {767 NTSTATUS tmpStatus = pMonitorInterface->pfnReleaseMonitorSourceModeSet(pDevExt->u.primary.DxgkInterface.DeviceHandle, hMonitorSMS);768 if (!NT_SUCCESS(tmpStatus))769 {770 WARN(("pfnReleaseMonitorSourceModeSet failed tmpStatus(0x%x)", tmpStatus));771 }772 break;773 }774 775 if (Status != STATUS_GRAPHICS_MONITOR_NOT_CONNECTED)776 {777 WARN(("DxgkCbQueryMonitorInterface failed, Status()0x%x", Status));778 break;779 }780 781 Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);782 783 LARGE_INTEGER Interval;784 Interval.QuadPart = -(int64_t) 2 /* ms */ * 10000;785 NTSTATUS tmpStatus = KeDelayExecutionThread(KernelMode, FALSE, &Interval);786 if (!NT_SUCCESS(tmpStatus))787 {788 WARN(("KeDelayExecutionThread failed tmpStatus(0x%x)", tmpStatus));789 }790 }791 }792 793 return STATUS_SUCCESS;794 497 } 795 498 … … 1154 857 vboxVdmaDdiNodesInit(pDevExt); 1155 858 vboxVideoCmInit(&pDevExt->CmMgr); 859 vboxVideoCmInit(&pDevExt->SeamlessCtxMgr); 1156 860 InitializeListHead(&pDevExt->SwapchainList3D); 1157 861 pDevExt->cContexts3D = 0; 1158 862 pDevExt->cContexts2D = 0; 863 pDevExt->cContextsDispIfResize = 0; 1159 864 pDevExt->cUnlockedVBVADisabled = 0; 1160 865 VBOXWDDM_CTXLOCK_INIT(pDevExt); … … 1162 867 1163 868 VBoxMPCmnInitCustomVideoModes(pDevExt); 1164 VBoxWddmInvalidateAllVideoModesInfos(pDevExt);1165 869 1166 870 VBoxCommonFromDeviceExt(pDevExt)->fAnyX = VBoxVideoAnyWidthAllowed(); … … 1192 896 } 1193 897 898 DWORD dwVal = VBOXWDDM_CFG_DRV_DEFAULT; 899 HANDLE hKey = NULL; 900 WCHAR aNameBuf[100]; 901 902 Status = IoOpenDeviceRegistryKey(pDevExt->pPDO, PLUGPLAY_REGKEY_DRIVER, GENERIC_READ, &hKey); 903 if (!NT_SUCCESS(Status)) 904 { 905 WARN(("IoOpenDeviceRegistryKey failed, Status = 0x%x", Status)); 906 hKey = NULL; 907 } 908 909 910 if (hKey) 911 { 912 Status = vboxWddmRegQueryValueDword(hKey, VBOXWDDM_REG_DRV_FLAGS_NAME, &dwVal); 913 if (!NT_SUCCESS(Status)) 914 { 915 LOG(("vboxWddmRegQueryValueDword failed, Status = 0x%x", Status)); 916 dwVal = VBOXWDDM_CFG_DRV_DEFAULT; 917 } 918 } 919 920 pDevExt->dwDrvCfgFlags = dwVal; 921 922 for (UINT i = 0; i < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i) 923 { 924 PVBOXWDDM_TARGET pTarget = &pDevExt->aTargets[i]; 925 if (i == 0 || (pDevExt->dwDrvCfgFlags & VBOXWDDM_CFG_DRV_SECONDARY_TARGETS_CONNECTED) || !hKey) 926 { 927 pTarget->fConnected = true; 928 pTarget->fConfigured = true; 929 } 930 else if (hKey) 931 { 932 swprintf(aNameBuf, L"%s%d", VBOXWDDM_REG_DRV_DISPFLAGS_PREFIX, i); 933 Status = vboxWddmRegQueryValueDword(hKey, aNameBuf, &dwVal); 934 if (NT_SUCCESS(Status)) 935 { 936 pTarget->fConnected = !!(dwVal & VBOXWDDM_CFG_DRVTARGET_CONNECTED); 937 pTarget->fConfigured = true; 938 } 939 else 940 { 941 WARN(("vboxWddmRegQueryValueDword failed, Status = 0x%x", Status)); 942 pTarget->fConnected = false; 943 pTarget->fConfigured = false; 944 } 945 } 946 } 947 948 if (hKey) 949 { 950 NTSTATUS tmpStatus = ZwClose(hKey); 951 Assert(tmpStatus == STATUS_SUCCESS); 952 } 953 954 Status = STATUS_SUCCESS; 1194 955 #ifdef VBOX_WDDM_WIN8 1195 956 DXGK_DISPLAY_INFORMATION DisplayInfo; … … 1230 991 } 1231 992 #endif 993 994 VBoxWddmInitVideoModes(pDevExt); 1232 995 } 1233 996 else … … 1280 1043 1281 1044 vboxVideoCmTerm(&pDevExt->CmMgr); 1045 1046 vboxVideoCmTerm(&pDevExt->SeamlessCtxMgr); 1282 1047 1283 1048 /* do everything we did on DxgkDdiStartDevice in the reverse order */ … … 1691 1456 ChildRelations[i].ChildDeviceType = TypeVideoOutput; 1692 1457 ChildRelations[i].ChildCapabilities.Type.VideoOutput.InterfaceTechnology = D3DKMDT_VOT_HD15; /* VGA */ 1693 ChildRelations[i].ChildCapabilities.Type.VideoOutput.MonitorOrientationAwareness = D3DKMDT_MOA_ INTERRUPTIBLE; /* ?? D3DKMDT_MOA_NONE*/1458 ChildRelations[i].ChildCapabilities.Type.VideoOutput.MonitorOrientationAwareness = D3DKMDT_MOA_NONE; //D3DKMDT_MOA_INTERRUPTIBLE; /* ?? D3DKMDT_MOA_NONE*/ 1694 1459 ChildRelations[i].ChildCapabilities.Type.VideoOutput.SupportsSdtvModes = FALSE; 1695 1460 ChildRelations[i].ChildCapabilities.HpdAwareness = HpdAwarenessInterruptible; /* ?? HpdAwarenessAlwaysConnected; */ … … 1714 1479 LOGF(("ENTER, context(0x%x)", MiniportDeviceContext)); 1715 1480 1481 PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)MiniportDeviceContext; 1482 1716 1483 NTSTATUS Status = STATUS_SUCCESS; 1717 1484 switch (ChildStatus->Type) 1718 1485 { 1719 1486 case StatusConnection: 1720 ChildStatus->HotPlug.Connected = TRUE;1487 { 1721 1488 LOGF(("StatusConnection")); 1489 VBOXWDDM_TARGET *pTarget = &pDevExt->aTargets[ChildStatus->ChildUid]; 1490 ChildStatus->HotPlug.Connected = !!pTarget->fConnected; 1722 1491 break; 1492 } 1723 1493 case StatusRotation: 1494 LOGF(("StatusRotation")); 1724 1495 ChildStatus->Rotation.Angle = 0; 1725 LOGF(("StatusRotation"));1726 1496 break; 1727 1497 default: 1728 LOGREL(("ERROR: status type: %d", ChildStatus->Type)); 1729 AssertBreakpoint(); 1498 WARN(("ERROR: status type: %d", ChildStatus->Type)); 1730 1499 Status = STATUS_INVALID_PARAMETER; 1731 1500 break; … … 2993 2762 VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pS2P->Shadow2Primary.VidPnSourceId]; 2994 2763 PVBOXWDDM_ALLOCATION pSrcAlloc = pS2P->Shadow2Primary.ShadowAlloc.pAlloc; 2995 vboxWddmAddrSetVram(&pSrcAlloc->AllocData.Addr, pS2P->Shadow2Primary.ShadowAlloc.segmentIdAlloc, pS2P->Shadow2Primary.ShadowAlloc.offAlloc); 2764 BOOLEAN fShadowChanged = vboxWddmAddrSetVram(&pSrcAlloc->AllocData.Addr, pS2P->Shadow2Primary.ShadowAlloc.segmentIdAlloc, pS2P->Shadow2Primary.ShadowAlloc.offAlloc); 2765 if (fShadowChanged) 2766 pSource->fGhSynced = 0; 2996 2767 vboxWddmAssignShadow(pDevExt, pSource, pSrcAlloc, pS2P->Shadow2Primary.VidPnSourceId); 2997 2768 vboxWddmModeRenderFromShadowCheckOnSubmitCommand(pDevExt, NULL); … … 3019 2790 PVBOXWDDM_ALLOCATION pDstAlloc = pBlt->Blt.DstAlloc.pAlloc; 3020 2791 PVBOXWDDM_ALLOCATION pSrcAlloc = pBlt->Blt.SrcAlloc.pAlloc; 2792 BOOLEAN fSrcChanged; 3021 2793 3022 2794 vboxWddmAddrSetVram(&pDstAlloc->AllocData.Addr, pBlt->Blt.DstAlloc.segmentIdAlloc, pBlt->Blt.DstAlloc.offAlloc); 3023 vboxWddmAddrSetVram(&pSrcAlloc->AllocData.Addr, pBlt->Blt.SrcAlloc.segmentIdAlloc, pBlt->Blt.SrcAlloc.offAlloc);2795 fSrcChanged = vboxWddmAddrSetVram(&pSrcAlloc->AllocData.Addr, pBlt->Blt.SrcAlloc.segmentIdAlloc, pBlt->Blt.SrcAlloc.offAlloc); 3024 2796 3025 2797 if (VBOXWDDM_IS_REAL_FB_ALLOCATION(pDevExt, pDstAlloc)) … … 3029 2801 3030 2802 if (pSrcAlloc->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE) 2803 { 2804 if (fSrcChanged) 2805 pSource->fGhSynced = 0; 2806 3031 2807 vboxWddmAssignShadow(pDevExt, pSource, pSrcAlloc, pDstAlloc->AllocData.SurfDesc.VidPnSourceId); 2808 } 3032 2809 vboxWddmModeRenderFromShadowCheckOnSubmitCommand(pDevExt, NULL); 3033 2810 if(pContext->enmType != VBOXWDDM_CONTEXT_TYPE_CUSTOM_3D … … 3910 3687 case VBOXESC_SETVISIBLEREGION: 3911 3688 { 3689 PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pEscape->hContext; 3690 if (!pContext) 3691 { 3692 WARN(("VBOXESC_SETVISIBLEREGION no context supplied!")); 3693 Status = STATUS_INVALID_PARAMETER; 3694 break; 3695 } 3696 3697 if (pContext->enmType != VBOXWDDM_CONTEXT_TYPE_CUSTOM_DISPIF_SEAMLESS) 3698 { 3699 WARN(("VBOXESC_SETVISIBLEREGION invalid context supplied %d!", pContext->enmType)); 3700 Status = STATUS_INVALID_PARAMETER; 3701 break; 3702 } 3703 3912 3704 /* visible regions for seamless */ 3913 3705 LPRGNDATA lpRgnData = VBOXDISPIFESCAPE_DATA(pEscapeHdr, RGNDATA); … … 3948 3740 rc = VbglGRPerform (&req->header); 3949 3741 AssertRC(rc); 3950 if (!RT_SUCCESS(rc)) 3742 if (RT_SUCCESS(rc)) 3743 Status = STATUS_SUCCESS; 3744 else 3951 3745 { 3952 LOGREL(("VbglGRPerform failed rc (%d)", rc));3746 WARN(("VbglGRPerform failed rc (%d)", rc)); 3953 3747 Status = STATUS_UNSUCCESSFUL; 3954 3748 } … … 3956 3750 else 3957 3751 { 3958 LOGREL(("VbglGRAlloc failed rc (%d)", rc));3752 WARN(("VbglGRAlloc failed rc (%d)", rc)); 3959 3753 Status = STATUS_UNSUCCESSFUL; 3960 3754 } … … 3962 3756 else 3963 3757 { 3964 LOGREL(("VBOXESC_SETVISIBLEREGION: incorrect buffer size (%d), reported count (%d)", cbRects, lpRgnData->rdh.nCount)); 3965 AssertBreakpoint(); 3758 WARN(("VBOXESC_SETVISIBLEREGION: incorrect buffer size (%d), reported count (%d)", cbRects, lpRgnData->rdh.nCount)); 3966 3759 Status = STATUS_INVALID_PARAMETER; 3967 3760 } … … 4054 3847 case VBOXESC_REINITVIDEOMODES: 4055 3848 { 4056 if ( pEscape->Flags.HardwareAccess)4057 { 4058 WARN(("VBOXESC_REINITVIDEOMODES called withHardwareAccess flag set, failing"));3849 if (!pEscape->Flags.HardwareAccess) 3850 { 3851 WARN(("VBOXESC_REINITVIDEOMODESBYMASK called without HardwareAccess flag set, failing")); 4059 3852 Status = STATUS_INVALID_PARAMETER; 4060 3853 break; 4061 3854 } 4062 WARN(("VBOXESC_REINITVIDEOMODESBYMASK should be called instead")); 4063 PVBOXWDDM_VIDEOMODES_INFO pInfos = VBoxWddmUpdateAllVideoModesInfos(pDevExt); 4064 Status = vboxWddmChildStatusCheckByMask(pDevExt, pInfos, NULL); 4065 if (!NT_SUCCESS(Status)) 4066 { 4067 WARN(("vboxWddmChildStatusCheckByMask failed, Status 0x%x", Status)); 4068 } 4069 break; 4070 } 4071 case VBOXESC_REINITVIDEOMODESBYMASK: 4072 { 4073 BOOLEAN fCheckDisplayRecconect = (pEscapeHdr->u32CmdSpecific & VBOXWDDM_REINITVIDEOMODESBYMASK_F_RECONNECT_DISPLAYS_ON_CHANGE); 4074 if (fCheckDisplayRecconect && pEscape->Flags.HardwareAccess) 4075 { 4076 WARN(("VBOXESC_REINITVIDEOMODESBYMASK called with HardwareAccess flag set, failing")); 3855 3856 PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pEscape->hContext; 3857 if (!pContext) 3858 { 3859 WARN(("VBOXESC_REINITVIDEOMODES no context supplied!")); 4077 3860 Status = STATUS_INVALID_PARAMETER; 4078 3861 break; 4079 3862 } 3863 3864 if (pContext->enmType != VBOXWDDM_CONTEXT_TYPE_CUSTOM_DISPIF_RESIZE) 3865 { 3866 WARN(("VBOXESC_REINITVIDEOMODES invalid context supplied %d!", pContext->enmType)); 3867 Status = STATUS_INVALID_PARAMETER; 3868 break; 3869 } 3870 3871 WARN(("VBOXESC_REINITVIDEOMODESBYMASK should be called instead")); 3872 VBoxWddmUpdateVideoModesInfoByMask(pDevExt, NULL); 3873 Status = STATUS_SUCCESS; 3874 break; 3875 } 3876 case VBOXESC_REINITVIDEOMODESBYMASK: 3877 { 3878 if (!pEscape->Flags.HardwareAccess) 3879 { 3880 WARN(("VBOXESC_REINITVIDEOMODESBYMASK called without HardwareAccess flag set, failing")); 3881 Status = STATUS_INVALID_PARAMETER; 3882 break; 3883 } 3884 3885 PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pEscape->hContext; 3886 if (!pContext) 3887 { 3888 WARN(("VBOXESC_REINITVIDEOMODESBYMASK no context supplied!")); 3889 Status = STATUS_INVALID_PARAMETER; 3890 break; 3891 } 3892 3893 if (pContext->enmType != VBOXWDDM_CONTEXT_TYPE_CUSTOM_DISPIF_RESIZE) 3894 { 3895 WARN(("VBOXESC_REINITVIDEOMODESBYMASK invalid context supplied %d!", pContext->enmType)); 3896 Status = STATUS_INVALID_PARAMETER; 3897 break; 3898 } 3899 4080 3900 if (pEscape->PrivateDriverDataSize != sizeof (VBOXDISPIFESCAPE_REINITVIDEOMODESBYMASK)) 4081 3901 { … … 4086 3906 LOG(("=> VBOXESC_REINITVIDEOMODESBYMASK")); 4087 3907 PVBOXDISPIFESCAPE_REINITVIDEOMODESBYMASK pData = (PVBOXDISPIFESCAPE_REINITVIDEOMODESBYMASK)pEscapeHdr; 4088 PVBOXWDDM_VIDEOMODES_INFO pInfos = VBoxWddmUpdateVideoModesInfoByMask(pDevExt, pData->ScreenMask); 4089 if (fCheckDisplayRecconect) 4090 { 4091 Status = vboxWddmChildStatusCheckByMask(pDevExt, pInfos, pData->ScreenMask); 3908 VBoxWddmUpdateVideoModesInfoByMask(pDevExt, pData->ScreenMask); 3909 Status = STATUS_SUCCESS; 3910 LOG(("<= VBOXESC_REINITVIDEOMODESBYMASK")); 3911 break; 3912 } 3913 case VBOXESC_CONFIGURETARGETS: 3914 { 3915 LOG(("=> VBOXESC_CONFIGURETARGETS")); 3916 3917 if (!pEscape->Flags.HardwareAccess) 3918 { 3919 WARN(("VBOXESC_CONFIGURETARGETS called without HardwareAccess flag set, failing")); 3920 Status = STATUS_INVALID_PARAMETER; 3921 break; 3922 } 3923 3924 PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pEscape->hContext; 3925 if (!pContext) 3926 { 3927 WARN(("VBOXESC_CONFIGURETARGETS no context supplied!")); 3928 Status = STATUS_INVALID_PARAMETER; 3929 break; 3930 } 3931 3932 if (pContext->enmType != VBOXWDDM_CONTEXT_TYPE_CUSTOM_DISPIF_RESIZE) 3933 { 3934 WARN(("VBOXESC_CONFIGURETARGETS invalid context supplied %d!", pContext->enmType)); 3935 Status = STATUS_INVALID_PARAMETER; 3936 break; 3937 } 3938 3939 if (pEscape->PrivateDriverDataSize != sizeof (*pEscapeHdr)) 3940 { 3941 WARN(("VBOXESC_CONFIGURETARGETS invalid private driver size %d", pEscape->PrivateDriverDataSize)); 3942 Status = STATUS_INVALID_PARAMETER; 3943 break; 3944 } 3945 3946 if (pEscapeHdr->u32CmdSpecific) 3947 { 3948 WARN(("VBOXESC_CONFIGURETARGETS invalid command %d", pEscapeHdr->u32CmdSpecific)); 3949 Status = STATUS_INVALID_PARAMETER; 3950 break; 3951 } 3952 3953 HANDLE hKey = NULL; 3954 WCHAR aNameBuf[100]; 3955 uint32_t cAdjusted = 0; 3956 3957 for (int i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i) 3958 { 3959 VBOXWDDM_TARGET *pTarget = &pDevExt->aTargets[i]; 3960 if (pTarget->fConfigured) 3961 continue; 3962 3963 pTarget->fConfigured = true; 3964 3965 if (!pTarget->fConnected) 3966 { 3967 Status = vboxWddmChildStatusConnect(pDevExt, (uint32_t)i, TRUE); 3968 if (NT_SUCCESS(Status)) 3969 ++cAdjusted; 3970 else 3971 WARN(("VBOXESC_CONFIGURETARGETS vboxWddmChildStatusConnectSecondaries failed Status 0x%x\n", Status)); 3972 } 3973 3974 if (!hKey) 3975 { 3976 Status = IoOpenDeviceRegistryKey(pDevExt->pPDO, PLUGPLAY_REGKEY_DRIVER, GENERIC_WRITE, &hKey); 3977 if (!NT_SUCCESS(Status)) 3978 { 3979 WARN(("VBOXESC_CONFIGURETARGETS IoOpenDeviceRegistryKey failed, Status = 0x%x", Status)); 3980 hKey = NULL; 3981 continue; 3982 } 3983 } 3984 3985 Assert(hKey); 3986 3987 swprintf(aNameBuf, L"%s%d", VBOXWDDM_REG_DRV_DISPFLAGS_PREFIX, i); 3988 Status = vboxWddmRegSetValueDword(hKey, aNameBuf, VBOXWDDM_CFG_DRVTARGET_CONNECTED); 4092 3989 if (!NT_SUCCESS(Status)) 4093 { 4094 WARN(("vboxWddmChildStatusCheckByMask failed, Status 0x%x", Status)); 4095 } 4096 } 4097 LOG(("<= VBOXESC_REINITVIDEOMODESBYMASK")); 3990 WARN(("VBOXESC_CONFIGURETARGETS vboxWddmRegSetValueDword (%d) failed Status 0x%x\n", aNameBuf, Status)); 3991 3992 } 3993 3994 if (hKey) 3995 { 3996 NTSTATUS tmpStatus = ZwClose(hKey); 3997 Assert(tmpStatus == STATUS_SUCCESS); 3998 } 3999 4000 pEscapeHdr->u32CmdSpecific = cAdjusted; 4001 4002 Status = STATUS_SUCCESS; 4003 4004 LOG(("<= VBOXESC_CONFIGURETARGETS")); 4098 4005 break; 4099 4006 } … … 4221 4128 } 4222 4129 default: 4223 Assert(0); 4224 LOGREL(("unsupported escape code (0x%x)", pEscapeHdr->escapeCode)); 4130 WARN(("unsupported escape code (0x%x)", pEscapeHdr->escapeCode)); 4225 4131 break; 4226 4132 } … … 4228 4134 else 4229 4135 { 4230 LOGREL(("pEscape->PrivateDriverDataSize(%d) < (%d)", pEscape->PrivateDriverDataSize, sizeof (VBOXDISPIFESCAPE))); 4231 AssertBreakpoint(); 4136 WARN(("pEscape->PrivateDriverDataSize(%d) < (%d)", pEscape->PrivateDriverDataSize, sizeof (VBOXDISPIFESCAPE))); 4232 4137 Status = STATUS_BUFFER_TOO_SMALL; 4233 4138 } … … 4315 4220 4316 4221 NTSTATUS Status = STATUS_SUCCESS; 4317 BOOLEAN bSupported = TRUE;4318 4222 4319 4223 PVBOXMP_DEVEXT pContext = (PVBOXMP_DEVEXT)hAdapter; … … 4339 4243 } 4340 4244 4341 VBOXVIDPNPATHITEM aItems[VBOX_VIDEO_MAX_SCREENS]; 4342 BOOLEAN fDisabledFound = FALSE; 4343 Status = vboxVidPnCheckTopology(hVidPnTopology, pVidPnTopologyInterface, TRUE /* fBreakOnDisabled */, RT_ELEMENTS(aItems), aItems, &fDisabledFound); 4344 Assert(Status == STATUS_SUCCESS); 4245 BOOLEAN fSupported = FALSE; 4246 Status = vboxVidPnCheckTopology(hVidPnTopology, pVidPnTopologyInterface, &fSupported); 4345 4247 if (!NT_SUCCESS(Status)) 4346 4248 { … … 4349 4251 } 4350 4252 4351 if (fDisabledFound) 4352 { 4253 if (!fSupported) 4353 4254 LOG(("found unsupported path")); 4354 bSupported = FALSE; 4355 } 4356 4357 pIsSupportedVidPnArg->IsVidPnSupported = bSupported; 4255 4256 pIsSupportedVidPnArg->IsVidPnSupported = fSupported; 4358 4257 4359 4258 #ifdef VBOXWDDM_DEBUG_VIDPN … … 4380 4279 vboxVDbgBreakFv(); 4381 4280 4281 #ifdef DEBUG_misha 4282 Assert(0); 4283 #endif 4284 4382 4285 PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)hAdapter; 4383 4286 NTSTATUS Status; 4384 4287 PVBOXWDDM_RECOMMENDVIDPN pVidPnInfo = pRecommendFunctionalVidPnArg->PrivateDriverDataSize >= sizeof (VBOXWDDM_RECOMMENDVIDPN) ? 4385 4288 (PVBOXWDDM_RECOMMENDVIDPN)pRecommendFunctionalVidPnArg->pPrivateDriverData : NULL; 4386 PVBOXWDDM_VIDEOMODES_INFO pInfos = VBoxWddm UpdateAllVideoModesInfos(pDevExt);4289 PVBOXWDDM_VIDEOMODES_INFO pInfos = VBoxWddmGetAllVideoModesInfos(pDevExt); 4387 4290 int i; 4388 4291 … … 4529 4432 } 4530 4433 4531 VBOXVIDPNPATHITEM aItems[VBOX_VIDEO_MAX_SCREENS]; 4532 Status = vboxVidPnCheckTopology(hVidPnTopology, pVidPnTopologyInterface, FALSE /* fBreakOnDisabled */, RT_ELEMENTS(aItems), aItems, NULL /* *pfDisabledFound */);4533 Assert(Status == STATUS_SUCCESS);4434 #ifdef DEBUG_misha 4435 BOOLEAN fSupported = FALSE; 4436 Status = vboxVidPnCheckTopology(hVidPnTopology, pVidPnTopologyInterface, &fSupported); 4534 4437 if (!NT_SUCCESS(Status)) 4535 4438 { … … 4538 4441 } 4539 4442 4443 Assert(fSupported); 4444 #endif 4540 4445 VBOXVIDPNCOFUNCMODALITY CbContext = {0}; 4541 4446 CbContext.pDevExt = pDevExt; … … 4543 4448 CbContext.pEnumCofuncModalityArg = pEnumCofuncModalityArg; 4544 4449 CbContext.pInfos = VBoxWddmGetAllVideoModesInfos(pDevExt); 4545 CbContext.cPathInfos = RT_ELEMENTS(aItems);4546 CbContext.apPathInfos = aItems;4547 4450 4548 4451 Status = vboxVidPnEnumPaths(hVidPnTopology, pVidPnTopologyInterface, 4549 4452 vboxVidPnCofuncModalityPathEnum, &CbContext); 4550 Assert(Status == STATUS_SUCCESS);4551 4453 if (!NT_SUCCESS(Status)) 4552 4454 { … … 4705 4607 } 4706 4608 4707 4708 4609 NTSTATUS 4709 4610 APIENTRY … … 4716 4617 4717 4618 PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)hAdapter; 4718 uint32_t au32OldHeightVisible[VBOX_VIDEO_MAX_SCREENS];4719 4619 NTSTATUS Status; 4720 4620 4721 4621 vboxVDbgBreakFv(); 4722 4723 /* we first store the current visible height for each target (monitor)4724 * and then we will zero up it for targets either for the given source4725 * (in case pCommitVidPnArg->AffectedVidPnSourceId != D3DDDI_ID_ALL)4726 * or all targets otherwize.4727 * In the end we will match the old and new visible height for all targets to see if4728 * some of them become inactivated and hide them accordingly,4729 * or we will restore the old height values on failure */4730 for (int i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)4731 {4732 PVBOXWDDM_TARGET pTarget = &pDevExt->aTargets[i];4733 au32OldHeightVisible[i] = pTarget->HeightVisible;4734 }4735 4622 4736 4623 do { … … 4840 4727 pDevExt->u.primary.hCommittedVidPn = pCommitVidPnArg->hFunctionalVidPn; 4841 4728 4842 for (int i = 1; /* <- never try to hide a primary monitor */ 4843 i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i) 4729 for (int i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i) 4844 4730 { 4845 4731 PVBOXWDDM_TARGET pTarget = &pDevExt->aTargets[i]; 4846 if (!pTarget->HeightVisible && !!au32OldHeightVisible[i]) 4847 { 4848 /* the target was previously visible */ 4849 vboxWddmGhDisplayHideScreen(pDevExt, i); 4850 } 4851 } 4852 4853 //#ifdef VBOX_WDDM_WIN8 4854 // if (g_VBoxDisplayOnly) 4855 { 4856 for (int i = 0; /* <- never try to hide a primary monitor */ 4857 i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i) 4858 { 4859 PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[i]; 4860 if (pSource->bVisible) 4861 { 4732 PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[i]; 4733 uint32_t cAutoresizes = pDevExt->cContextsDispIfResize; 4734 if (!cAutoresizes) 4735 { 4736 if (pSource->bVisible || !pTarget->HeightVisible) 4862 4737 vboxWddmGhDisplayCheckSetInfoFromSource(pDevExt, pSource); 4863 } 4864 } 4865 } 4866 //#endif 4738 } 4739 else 4740 pTarget->fStateSyncPening = true; 4741 } 4742 4867 4743 LOGF(("LEAVE, SUCCESS status(0x%x), context(0x%x)", Status, hAdapter)); 4868 4744 … … 4871 4747 4872 4748 AssertRelease(!NT_SUCCESS(Status)); 4873 /* failure branch restore original visible height values, see comments above */4874 for (int i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)4875 {4876 PVBOXWDDM_TARGET pTarget = &pDevExt->aTargets[i];4877 pTarget->HeightVisible = au32OldHeightVisible[i];4878 }4879 4749 4880 4750 LOGF(("LEAVE, !!FAILURE!! status(0x%x), context(0x%x)", Status, hAdapter)); … … 5848 5718 break; 5849 5719 } 5720 case VBOXWDDM_CONTEXT_TYPE_CUSTOM_DISPIF_RESIZE: 5721 { 5722 pContext->enmType = pInfo->enmType; 5723 ASMAtomicIncU32(&pDevExt->cContextsDispIfResize); 5724 break; 5725 } 5726 case VBOXWDDM_CONTEXT_TYPE_CUSTOM_DISPIF_SEAMLESS: 5727 { 5728 pContext->enmType = pInfo->enmType; 5729 Status = vboxVideoCmCtxAdd(&pDevice->pAdapter->SeamlessCtxMgr, &pContext->CmContext, (HANDLE)pInfo->hUmEvent, pInfo->u64UmInfo); 5730 if (!NT_SUCCESS(Status)) 5731 { 5732 WARN(("vboxVideoCmCtxAdd failed, Status 0x%x", Status)); 5733 } 5734 break; 5735 } 5850 5736 default: 5851 5737 { 5852 Assert(0);5738 WARN(("unsupported context type %d", pInfo->enmType)); 5853 5739 Status = STATUS_INVALID_PARAMETER; 5854 5740 break; … … 5891 5777 PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)hContext; 5892 5778 PVBOXMP_DEVEXT pDevExt = pContext->pDevice->pAdapter; 5779 NTSTATUS Status = STATUS_SUCCESS; 5780 5893 5781 switch(pContext->enmType) 5894 5782 { … … 5905 5793 uint32_t cContexts = ASMAtomicDecU32(&pDevExt->cContexts2D); 5906 5794 Assert(cContexts < UINT32_MAX/2); 5795 break; 5796 } 5797 case VBOXWDDM_CONTEXT_TYPE_CUSTOM_DISPIF_RESIZE: 5798 { 5799 uint32_t cContexts = ASMAtomicDecU32(&pDevExt->cContextsDispIfResize); 5800 Assert(cContexts < UINT32_MAX/2); 5801 if (!cContexts) 5802 { 5803 for (int i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i) 5804 { 5805 vboxWddmGhDisplayCheckCompletePeningScreenInfo(pDevExt, i); 5806 } 5807 } 5808 break; 5809 } 5810 case VBOXWDDM_CONTEXT_TYPE_CUSTOM_DISPIF_SEAMLESS: 5811 { 5812 Status = vboxVideoCmCtxRemove(&pContext->pDevice->pAdapter->SeamlessCtxMgr, &pContext->CmContext); 5813 if (!NT_SUCCESS(Status)) 5814 WARN(("vboxVideoCmCtxRemove failed, Status 0x%x", Status)); 5815 5816 Assert(pContext->CmContext.pSession == NULL); 5907 5817 break; 5908 5818 } … … 5923 5833 vboxWddmSwapchainCtxTerm(pDevExt, pContext); 5924 5834 5925 NTSTATUS Status = vboxVideoAMgrCtxDestroy(&pContext->AllocContext); 5926 Assert(Status == STATUS_SUCCESS); 5927 if (Status == STATUS_SUCCESS) 5835 Status = vboxVideoAMgrCtxDestroy(&pContext->AllocContext); 5836 if (NT_SUCCESS(Status)) 5928 5837 { 5929 5838 Status = vboxVideoCmCtxRemove(&pContext->pDevice->pAdapter->CmMgr, &pContext->CmContext); 5930 Assert(Status == STATUS_SUCCESS); 5931 if (Status == STATUS_SUCCESS) 5932 { 5839 if (NT_SUCCESS(Status)) 5933 5840 vboxWddmMemFree(pContext); 5934 } 5935 } 5841 else 5842 WARN(("vboxVideoCmCtxRemove failed, Status 0x%x", Status)); 5843 } 5844 else 5845 WARN(("vboxVideoAMgrCtxDestroy failed, Status 0x%x", Status)); 5936 5846 5937 5847 LOGF(("LEAVE, hContext(0x%x)", hContext)); -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.h
r47063 r48070 37 37 //#define VBOXWDDM_DEBUG_VIDPN 38 38 39 #define VBOXWDDM_CFG_DRV_DEFAULT 0 40 #define VBOXWDDM_CFG_DRV_SECONDARY_TARGETS_CONNECTED 1 41 42 #define VBOXWDDM_CFG_DRVTARGET_CONNECTED 1 43 39 44 #define VBOXWDDM_CFG_LOG_UM_BACKDOOR 0x00000001 40 45 #define VBOXWDDM_CFG_LOG_UM_DBGPRINT 0x00000002 41 46 #define VBOXWDDM_CFG_STR_LOG_UM L"VBoxLogUm" 47 48 #define VBOXWDDM_REG_DRV_FLAGS_NAME L"VBoxFlags" 49 #define VBOXWDDM_REG_DRV_DISPFLAGS_PREFIX L"VBoxDispFlags" 50 51 #define VBOXWDDM_REG_DRVKEY_PREFIX L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\" 52 53 #define VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Video\\" 54 #define VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY_SUBKEY L"\\Video" 55 56 57 #define VBOXWDDM_REG_DISPLAYSETTINGSKEY_PREFIX_VISTA L"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Control\\VIDEO\\" 58 #define VBOXWDDM_REG_DISPLAYSETTINGSKEY_PREFIX_WIN7 L"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\UnitedVideo\\CONTROL\\VIDEO\\" 59 60 #define VBOXWDDM_REG_DISPLAYSETTINGS_ATTACH_RELX L"Attach.RelativeX" 61 #define VBOXWDDM_REG_DISPLAYSETTINGS_ATTACH_RELY L"Attach.RelativeY" 62 #define VBOXWDDM_REG_DISPLAYSETTINGS_ATTACH_DESKTOP L"Attach.ToDesktop" 63 42 64 extern DWORD g_VBoxLogUm; 43 65 … … 81 103 } 82 104 83 DECLINLINE(VOID) vboxWddmAddrSetVram(PVBOXWDDM_ADDR pAddr, UINT SegmentId, VBOXVIDEOOFFSET offVram) 84 { 105 DECLINLINE(BOOLEAN) vboxWddmAddrSetVram(PVBOXWDDM_ADDR pAddr, UINT SegmentId, VBOXVIDEOOFFSET offVram) 106 { 107 if (pAddr->SegmentId == SegmentId && pAddr->offVram == offVram) 108 return FALSE; 109 85 110 pAddr->SegmentId = SegmentId; 86 111 pAddr->offVram = offVram; 112 return TRUE; 87 113 } 88 114 … … 191 217 return pPrimary; 192 218 } 219 220 bool vboxWddmGhDisplayCheckSetInfoFromSource(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SOURCE pSource); 193 221 194 222 #define VBOXWDDMENTRY_2_SWAPCHAIN(_pE) ((PVBOXWDDM_SWAPCHAIN)((uint8_t*)(_pE) - RT_OFFSETOF(VBOXWDDM_SWAPCHAIN, DevExtListEntry))) -
trunk/src/VBox/Additions/WINNT/VBoxTray/Makefile.kmk
r42288 r48070 61 61 VBoxTray_DEFS += VBOX_WITH_WDDM 62 62 # VBoxTray_DEFS += LOG_ENABLED 63 VBoxTray_SOURCES += ../Graphics/Video/disp/wddm/VBoxDispKmt.cpp 63 64 endif 64 65 -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDispIf.cpp
r46625 r48070 27 27 #endif 28 28 29 #include "VBoxDisplay.h" 30 31 #ifndef NT_SUCCESS 32 # define NT_SUCCESS(_Status) ((_Status) >= 0) 33 #endif 34 35 typedef struct VBOXDISPIF_OP 36 { 37 PCVBOXDISPIF pIf; 38 VBOXDISPKMT_ADAPTER Adapter; 39 VBOXDISPKMT_DEVICE Device; 40 VBOXDISPKMT_CONTEXT Context; 41 } VBOXDISPIF_OP; 42 43 DWORD EnableAndResizeDispDev(DEVMODE *paDeviceModes, DISPLAY_DEVICE *paDisplayDevices, DWORD totalDispNum, UINT Id, DWORD aWidth, DWORD aHeight, 44 DWORD aBitsPerPixel, DWORD aPosX, DWORD aPosY, BOOL fEnabled, BOOL fExtDispSup); 45 46 static DWORD vboxDispIfWddmResizeDisplay(PCVBOXDISPIF const pIf, UINT Id, BOOL fEnable, DISPLAY_DEVICE * paDisplayDevices, DEVMODE *paDeviceMode, UINT devModes); 47 48 static DWORD vboxDispIfResizePerform(PCVBOXDISPIF const pIf, UINT iChangedMode, BOOL fEnable, BOOL fExtDispSup, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes); 49 50 static DWORD vboxDispIfWddmEnableDisplaysTryingTopology(PCVBOXDISPIF const pIf, UINT cIds, UINT *pIds, BOOL fEnable); 51 52 static DWORD vboxDispIfResizeStartedWDDMOp(VBOXDISPIF_OP *pOp); 53 29 54 /* APIs specific to win7 and above WDDM architecture. Not available for Vista WDDM. 30 55 * This is the reason they have not been put in the VBOXDISPIF struct in VBoxDispIf.h … … 42 67 static _VBOXDISPLAYWDDMAPICONTEXT gCtx = {0}; 43 68 69 typedef struct VBOXDISPIF_WDDM_DISPCFG 70 { 71 UINT32 cPathInfoArray; 72 DISPLAYCONFIG_PATH_INFO *pPathInfoArray; 73 UINT32 cModeInfoArray; 74 DISPLAYCONFIG_MODE_INFO *pModeInfoArray; 75 } VBOXDISPIF_WDDM_DISPCFG; 76 77 static DWORD vboxDispIfWddmDcCreate(VBOXDISPIF_WDDM_DISPCFG *pCfg, UINT32 fFlags) 78 { 79 UINT32 cPathInfoArray = 0; 80 UINT32 cModeInfoArray = 0; 81 DISPLAYCONFIG_PATH_INFO *pPathInfoArray; 82 DISPLAYCONFIG_MODE_INFO *pModeInfoArray; 83 DWORD winEr = gCtx.pfnGetDisplayConfigBufferSizes(fFlags, &cPathInfoArray, &cModeInfoArray); 84 if (winEr != ERROR_SUCCESS) 85 { 86 WARN(("VBoxTray: (WDDM) Failed GetDisplayConfigBufferSizes\n")); 87 return winEr; 88 } 89 90 pPathInfoArray = (DISPLAYCONFIG_PATH_INFO *)malloc(cPathInfoArray * sizeof(DISPLAYCONFIG_PATH_INFO)); 91 if (!pPathInfoArray) 92 { 93 WARN(("VBoxTray: (WDDM) malloc failed!\n")); 94 return ERROR_OUTOFMEMORY; 95 } 96 pModeInfoArray = (DISPLAYCONFIG_MODE_INFO *)malloc(cModeInfoArray * sizeof(DISPLAYCONFIG_MODE_INFO)); 97 if (!pModeInfoArray) 98 { 99 WARN(("VBoxTray: (WDDM) malloc failed!\n")); 100 free(pPathInfoArray); 101 return ERROR_OUTOFMEMORY; 102 } 103 104 winEr = gCtx.pfnQueryDisplayConfig(fFlags, &cPathInfoArray, pPathInfoArray, &cModeInfoArray, pModeInfoArray, NULL); 105 if (winEr != ERROR_SUCCESS) 106 { 107 WARN(("VBoxTray: (WDDM) Failed QueryDisplayConfig\n")); 108 free(pPathInfoArray); 109 free(pModeInfoArray); 110 return winEr; 111 } 112 113 pCfg->cPathInfoArray = cPathInfoArray; 114 pCfg->pPathInfoArray = pPathInfoArray; 115 pCfg->cModeInfoArray = cModeInfoArray; 116 pCfg->pModeInfoArray = pModeInfoArray; 117 return ERROR_SUCCESS; 118 } 119 120 static DWORD vboxDispIfWddmDcClone(VBOXDISPIF_WDDM_DISPCFG *pCfg, VBOXDISPIF_WDDM_DISPCFG *pCfgDst) 121 { 122 memset(pCfgDst, 0, sizeof (*pCfgDst)); 123 124 if (pCfg->cPathInfoArray) 125 { 126 pCfgDst->pPathInfoArray = (DISPLAYCONFIG_PATH_INFO *)malloc(pCfg->cPathInfoArray * sizeof (DISPLAYCONFIG_PATH_INFO)); 127 if (!pCfgDst->pPathInfoArray) 128 { 129 WARN(("VBoxTray: (WDDM) malloc failed!\n")); 130 return ERROR_OUTOFMEMORY; 131 } 132 133 memcpy(pCfgDst->pPathInfoArray, pCfg->pPathInfoArray, pCfg->cPathInfoArray * sizeof (DISPLAYCONFIG_PATH_INFO)); 134 135 pCfgDst->cPathInfoArray = pCfg->cPathInfoArray; 136 } 137 138 if (pCfg->cModeInfoArray) 139 { 140 pCfgDst->pModeInfoArray = (DISPLAYCONFIG_MODE_INFO *)malloc(pCfg->cModeInfoArray * sizeof (DISPLAYCONFIG_MODE_INFO)); 141 if (!pCfgDst->pModeInfoArray) 142 { 143 WARN(("VBoxTray: (WDDM) malloc failed!\n")); 144 if (pCfgDst->pPathInfoArray) 145 { 146 free(pCfgDst->pPathInfoArray); 147 pCfgDst->pPathInfoArray = NULL; 148 } 149 return ERROR_OUTOFMEMORY; 150 } 151 152 memcpy(pCfgDst->pModeInfoArray, pCfg->pModeInfoArray, pCfg->cModeInfoArray * sizeof (DISPLAYCONFIG_MODE_INFO)); 153 154 pCfgDst->cModeInfoArray = pCfg->cModeInfoArray; 155 } 156 157 return ERROR_SUCCESS; 158 } 159 160 161 static VOID vboxDispIfWddmDcTerm(VBOXDISPIF_WDDM_DISPCFG *pCfg) 162 { 163 if (pCfg->pPathInfoArray) 164 free(pCfg->pPathInfoArray); 165 if (pCfg->pModeInfoArray) 166 free(pCfg->pModeInfoArray); 167 /* sanity */ 168 memset(pCfg, 0, sizeof (*pCfg)); 169 } 170 171 static UINT32 g_cVBoxDispIfWddmDisplays = 0; 172 static DWORD vboxDispIfWddmDcQueryNumDisplays(UINT32 *pcDisplays) 173 { 174 if (!g_cVBoxDispIfWddmDisplays) 175 { 176 VBOXDISPIF_WDDM_DISPCFG DispCfg; 177 *pcDisplays = 0; 178 DWORD winEr = vboxDispIfWddmDcCreate(&DispCfg, QDC_ALL_PATHS); 179 if (winEr != ERROR_SUCCESS) 180 { 181 WARN(("VBoxTray:(WDDM) vboxDispIfWddmDcCreate Failed winEr %d\n", winEr)); 182 return winEr; 183 } 184 185 int cDisplays = -1; 186 187 for (UINT iter = 0; iter < DispCfg.cPathInfoArray; ++iter) 188 { 189 if (cDisplays < (int)(DispCfg.pPathInfoArray[iter].sourceInfo.id)) 190 cDisplays = (int)(DispCfg.pPathInfoArray[iter].sourceInfo.id); 191 } 192 193 cDisplays++; 194 195 g_cVBoxDispIfWddmDisplays = cDisplays; 196 Assert(g_cVBoxDispIfWddmDisplays); 197 198 vboxDispIfWddmDcTerm(&DispCfg); 199 } 200 201 *pcDisplays = g_cVBoxDispIfWddmDisplays; 202 return ERROR_SUCCESS; 203 } 204 205 static int vboxDispIfWddmDcSearchPath(VBOXDISPIF_WDDM_DISPCFG *pCfg, UINT srcId, UINT trgId) 206 { 207 for (UINT iter = 0; iter < pCfg->cPathInfoArray; ++iter) 208 { 209 if ((srcId == ~0UL || pCfg->pPathInfoArray[iter].sourceInfo.id == srcId) 210 && (trgId == ~0UL || pCfg->pPathInfoArray[iter].targetInfo.id == trgId)) 211 { 212 return (int)iter; 213 } 214 } 215 return -1; 216 } 217 218 static int vboxDispIfWddmDcSearchActivePath(VBOXDISPIF_WDDM_DISPCFG *pCfg, UINT srcId, UINT trgId) 219 { 220 int idx = vboxDispIfWddmDcSearchPath(pCfg, srcId, trgId); 221 if (idx < 0) 222 return idx; 223 224 if (!(pCfg->pPathInfoArray[idx].flags & DISPLAYCONFIG_PATH_ACTIVE)) 225 return -1; 226 227 return idx; 228 } 229 230 static VOID vboxDispIfWddmDcSettingsInvalidateModeIndex(VBOXDISPIF_WDDM_DISPCFG *pCfg, int idx) 231 { 232 pCfg->pPathInfoArray[idx].sourceInfo.modeInfoIdx = DISPLAYCONFIG_PATH_MODE_IDX_INVALID; 233 pCfg->pPathInfoArray[idx].targetInfo.modeInfoIdx = DISPLAYCONFIG_PATH_MODE_IDX_INVALID; 234 } 235 236 static VOID vboxDispIfWddmDcSettingsInvalidateModeIndeces(VBOXDISPIF_WDDM_DISPCFG *pCfg) 237 { 238 for (UINT iter = 0; iter < pCfg->cPathInfoArray; ++iter) 239 { 240 vboxDispIfWddmDcSettingsInvalidateModeIndex(pCfg, (int)iter); 241 } 242 243 if (pCfg->pModeInfoArray) 244 { 245 free(pCfg->pModeInfoArray); 246 pCfg->pModeInfoArray = NULL; 247 } 248 pCfg->cModeInfoArray = 0; 249 } 250 251 static DWORD vboxDispIfWddmDcSettingsModeAdd(VBOXDISPIF_WDDM_DISPCFG *pCfg, UINT *pIdx) 252 { 253 UINT32 cModeInfoArray = pCfg->cModeInfoArray + 1; 254 DISPLAYCONFIG_MODE_INFO *pModeInfoArray = (DISPLAYCONFIG_MODE_INFO *)malloc(cModeInfoArray * sizeof (DISPLAYCONFIG_MODE_INFO)); 255 if (!pModeInfoArray) 256 { 257 WARN(("VBoxTray: (WDDM) malloc failed!\n")); 258 return ERROR_OUTOFMEMORY; 259 } 260 261 memcpy (pModeInfoArray, pCfg->pModeInfoArray, pCfg->cModeInfoArray * sizeof(DISPLAYCONFIG_MODE_INFO)); 262 memset(&pModeInfoArray[cModeInfoArray-1], 0, sizeof (pModeInfoArray[0])); 263 free(pCfg->pModeInfoArray); 264 *pIdx = cModeInfoArray-1; 265 pCfg->pModeInfoArray = pModeInfoArray; 266 pCfg->cModeInfoArray = cModeInfoArray; 267 return ERROR_SUCCESS; 268 } 269 270 static DWORD vboxDispIfWddmDcSettingsUpdate(VBOXDISPIF_WDDM_DISPCFG *pCfg, int idx, DEVMODE *pDeviceMode, BOOL fInvalidateSrcMode, BOOL fEnable) 271 { 272 UINT Id = pCfg->pPathInfoArray[idx].sourceInfo.id; 273 274 if (fInvalidateSrcMode) 275 pCfg->pPathInfoArray[idx].sourceInfo.modeInfoIdx = DISPLAYCONFIG_PATH_MODE_IDX_INVALID; 276 else if (pDeviceMode) 277 { 278 UINT iSrcMode = pCfg->pPathInfoArray[idx].sourceInfo.modeInfoIdx; 279 if (iSrcMode == DISPLAYCONFIG_PATH_MODE_IDX_INVALID) 280 { 281 282 WARN(("VBoxTray: (WDDM) no source mode index specified")); 283 DWORD winEr = vboxDispIfWddmDcSettingsModeAdd(pCfg, &iSrcMode); 284 if (winEr != ERROR_SUCCESS) 285 { 286 WARN(("VBoxTray:(WDDM) vboxDispIfWddmDcSettingsModeAdd Failed winEr %d\n", winEr)); 287 return winEr; 288 } 289 pCfg->pPathInfoArray[idx].sourceInfo.modeInfoIdx = iSrcMode; 290 } 291 292 for (int i = 0; i < (int)pCfg->cPathInfoArray; ++i) 293 { 294 if (i == idx) 295 continue; 296 297 if (pCfg->pPathInfoArray[i].sourceInfo.modeInfoIdx == iSrcMode) 298 { 299 /* this is something we're not expecting/supporting */ 300 WARN(("VBoxTray: (WDDM) multiple paths have the same mode index")); 301 return ERROR_NOT_SUPPORTED; 302 } 303 } 304 305 if (pDeviceMode->dmFields & DM_PELSWIDTH) 306 pCfg->pModeInfoArray[iSrcMode].sourceMode.width = pDeviceMode->dmPelsWidth; 307 if (pDeviceMode->dmFields & DM_PELSHEIGHT) 308 pCfg->pModeInfoArray[iSrcMode].sourceMode.height = pDeviceMode->dmPelsHeight; 309 if (pDeviceMode->dmFields & DM_POSITION) 310 { 311 pCfg->pModeInfoArray[iSrcMode].sourceMode.position.x = pDeviceMode->dmPosition.x; 312 pCfg->pModeInfoArray[iSrcMode].sourceMode.position.y = pDeviceMode->dmPosition.y; 313 } 314 if (pDeviceMode->dmFields & DM_BITSPERPEL) 315 { 316 switch (pDeviceMode->dmBitsPerPel) 317 { 318 case 32: 319 pCfg->pModeInfoArray[iSrcMode].sourceMode.pixelFormat = DISPLAYCONFIG_PIXELFORMAT_32BPP; 320 break; 321 case 24: 322 pCfg->pModeInfoArray[iSrcMode].sourceMode.pixelFormat = DISPLAYCONFIG_PIXELFORMAT_24BPP; 323 break; 324 case 16: 325 pCfg->pModeInfoArray[iSrcMode].sourceMode.pixelFormat = DISPLAYCONFIG_PIXELFORMAT_16BPP; 326 break; 327 case 8: 328 pCfg->pModeInfoArray[iSrcMode].sourceMode.pixelFormat = DISPLAYCONFIG_PIXELFORMAT_8BPP; 329 break; 330 default: 331 LogRel(("VBoxTray: (WDDM) invalid bpp %d, using 32\n", pDeviceMode->dmBitsPerPel)); 332 pCfg->pModeInfoArray[iSrcMode].sourceMode.pixelFormat = DISPLAYCONFIG_PIXELFORMAT_32BPP; 333 break; 334 } 335 } 336 } 337 338 pCfg->pPathInfoArray[idx].targetInfo.modeInfoIdx = DISPLAYCONFIG_PATH_MODE_IDX_INVALID; 339 340 if (fEnable) 341 pCfg->pPathInfoArray[idx].flags |= DISPLAYCONFIG_PATH_ACTIVE; 342 else 343 pCfg->pPathInfoArray[idx].flags &= ~DISPLAYCONFIG_PATH_ACTIVE; 344 345 return ERROR_SUCCESS; 346 } 347 348 static DWORD vboxDispIfWddmDcSet(VBOXDISPIF_WDDM_DISPCFG *pCfg, UINT fFlags) 349 { 350 DWORD winEr = gCtx.pfnSetDisplayConfig(pCfg->cPathInfoArray, pCfg->pPathInfoArray, pCfg->cModeInfoArray, pCfg->pModeInfoArray, fFlags); 351 if (winEr != ERROR_SUCCESS) 352 Log(("VBoxTray:(WDDM) pfnSetDisplayConfig Failed for Flags 0x%x\n", fFlags)); 353 return winEr; 354 } 355 356 static BOOL vboxDispIfWddmDcSettingsAdjustSupportedPaths(VBOXDISPIF_WDDM_DISPCFG *pCfg) 357 { 358 BOOL fAdjusted = FALSE; 359 for (UINT iter = 0; iter < pCfg->cPathInfoArray; ++iter) 360 { 361 if (pCfg->pPathInfoArray[iter].sourceInfo.id == pCfg->pPathInfoArray[iter].targetInfo.id) 362 continue; 363 364 if (!(pCfg->pPathInfoArray[iter].flags & DISPLAYCONFIG_PATH_ACTIVE)) 365 continue; 366 367 pCfg->pPathInfoArray[iter].flags &= ~DISPLAYCONFIG_PATH_ACTIVE; 368 fAdjusted = TRUE; 369 } 370 371 return fAdjusted; 372 } 373 374 static void vboxDispIfWddmDcSettingsAttachDisbledToPrimary(VBOXDISPIF_WDDM_DISPCFG *pCfg) 375 { 376 for (UINT iter = 0; iter < pCfg->cPathInfoArray; ++iter) 377 { 378 if ((pCfg->pPathInfoArray[iter].flags & DISPLAYCONFIG_PATH_ACTIVE)) 379 continue; 380 381 pCfg->pPathInfoArray[iter].sourceInfo.id = 0; 382 pCfg->pPathInfoArray[iter].sourceInfo.modeInfoIdx = DISPLAYCONFIG_PATH_MODE_IDX_INVALID; 383 pCfg->pPathInfoArray[iter].targetInfo.modeInfoIdx = DISPLAYCONFIG_PATH_MODE_IDX_INVALID; 384 } 385 } 386 387 static DWORD vboxDispIfWddmDcSettingsIncludeAllTargets(VBOXDISPIF_WDDM_DISPCFG *pCfg) 388 { 389 UINT32 cDisplays = 0; 390 VBOXDISPIF_WDDM_DISPCFG AllCfg; 391 BOOL fAllCfgInited = FALSE; 392 393 DWORD winEr = vboxDispIfWddmDcQueryNumDisplays(&cDisplays); 394 if (winEr != ERROR_SUCCESS) 395 { 396 WARN(("VBoxTray:(WDDM) vboxDispIfWddmDcQueryNumDisplays Failed winEr %d\n", winEr)); 397 return winEr; 398 } 399 400 DISPLAYCONFIG_PATH_INFO *pPathInfoArray = (DISPLAYCONFIG_PATH_INFO *)malloc(cDisplays * sizeof(DISPLAYCONFIG_PATH_INFO)); 401 if (!pPathInfoArray) 402 { 403 WARN(("malloc failed\n")); 404 return ERROR_OUTOFMEMORY; 405 } 406 407 for (UINT i = 0; i < cDisplays; ++i) 408 { 409 int idx = vboxDispIfWddmDcSearchPath(pCfg, i, i); 410 if (idx < 0) 411 { 412 idx = vboxDispIfWddmDcSearchPath(pCfg, -1, i); 413 if (idx >= 0) 414 { 415 WARN(("VBoxTray:(WDDM) different source and target paare enabled, this is something we would not expect\n")); 416 } 417 } 418 419 if (idx >= 0) 420 pPathInfoArray[i] = pCfg->pPathInfoArray[idx]; 421 else 422 { 423 if (!fAllCfgInited) 424 { 425 winEr = vboxDispIfWddmDcCreate(&AllCfg, QDC_ALL_PATHS); 426 if (winEr != ERROR_SUCCESS) 427 { 428 WARN(("VBoxTray:(WDDM) vboxDispIfWddmDcCreate Failed winEr %d\n", winEr)); 429 free(pPathInfoArray); 430 return winEr; 431 } 432 fAllCfgInited = TRUE; 433 } 434 435 idx = vboxDispIfWddmDcSearchPath(&AllCfg, i, i); 436 if (idx < 0) 437 { 438 WARN(("VBoxTray:(WDDM) %d %d path not supported\n", i, i)); 439 idx = vboxDispIfWddmDcSearchPath(pCfg, -1, i); 440 if (idx < 0) 441 { 442 WARN(("VBoxTray:(WDDM) %d %d path not supported\n", -1, i)); 443 } 444 } 445 446 if (idx >= 0) 447 { 448 pPathInfoArray[i] = AllCfg.pPathInfoArray[idx]; 449 450 if (pPathInfoArray[i].flags & DISPLAYCONFIG_PATH_ACTIVE) 451 { 452 WARN(("VBoxTray:(WDDM) disabled path %d %d is marked active\n", 453 pPathInfoArray[i].sourceInfo.id, pPathInfoArray[i].targetInfo.id)); 454 pPathInfoArray[i].flags &= ~DISPLAYCONFIG_PATH_ACTIVE; 455 } 456 457 Assert(pPathInfoArray[i].sourceInfo.modeInfoIdx == DISPLAYCONFIG_PATH_MODE_IDX_INVALID); 458 Assert(pPathInfoArray[i].sourceInfo.statusFlags == 0); 459 460 Assert(pPathInfoArray[i].targetInfo.modeInfoIdx == DISPLAYCONFIG_PATH_MODE_IDX_INVALID); 461 Assert(pPathInfoArray[i].targetInfo.outputTechnology == DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HD15); 462 Assert(pPathInfoArray[i].targetInfo.rotation == DISPLAYCONFIG_ROTATION_IDENTITY); 463 Assert(pPathInfoArray[i].targetInfo.scaling == DISPLAYCONFIG_SCALING_PREFERRED); 464 Assert(pPathInfoArray[i].targetInfo.refreshRate.Numerator == 0); 465 Assert(pPathInfoArray[i].targetInfo.refreshRate.Denominator == 0); 466 Assert(pPathInfoArray[i].targetInfo.scanLineOrdering == DISPLAYCONFIG_SCANLINE_ORDERING_UNSPECIFIED); 467 Assert(pPathInfoArray[i].targetInfo.targetAvailable == TRUE); 468 Assert(pPathInfoArray[i].targetInfo.statusFlags == DISPLAYCONFIG_TARGET_FORCIBLE); 469 470 Assert(pPathInfoArray[i].flags == 0); 471 } 472 else 473 { 474 pPathInfoArray[i].sourceInfo.adapterId = pCfg->pPathInfoArray[0].sourceInfo.adapterId; 475 pPathInfoArray[i].sourceInfo.id = i; 476 pPathInfoArray[i].sourceInfo.modeInfoIdx = DISPLAYCONFIG_PATH_MODE_IDX_INVALID; 477 pPathInfoArray[i].sourceInfo.statusFlags = 0; 478 479 pPathInfoArray[i].targetInfo.adapterId = pPathInfoArray[i].sourceInfo.adapterId; 480 pPathInfoArray[i].targetInfo.id = i; 481 pPathInfoArray[i].targetInfo.modeInfoIdx = DISPLAYCONFIG_PATH_MODE_IDX_INVALID; 482 pPathInfoArray[i].targetInfo.outputTechnology = DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HD15; 483 pPathInfoArray[i].targetInfo.rotation = DISPLAYCONFIG_ROTATION_IDENTITY; 484 pPathInfoArray[i].targetInfo.scaling = DISPLAYCONFIG_SCALING_PREFERRED; 485 pPathInfoArray[i].targetInfo.refreshRate.Numerator = 0; 486 pPathInfoArray[i].targetInfo.refreshRate.Denominator = 0; 487 pPathInfoArray[i].targetInfo.scanLineOrdering = DISPLAYCONFIG_SCANLINE_ORDERING_UNSPECIFIED; 488 pPathInfoArray[i].targetInfo.targetAvailable = TRUE; 489 pPathInfoArray[i].targetInfo.statusFlags = DISPLAYCONFIG_TARGET_FORCIBLE; 490 491 pPathInfoArray[i].flags = 0; 492 } 493 } 494 } 495 496 free(pCfg->pPathInfoArray); 497 pCfg->pPathInfoArray = pPathInfoArray; 498 pCfg->cPathInfoArray = cDisplays; 499 if (fAllCfgInited) 500 vboxDispIfWddmDcTerm(&AllCfg); 501 502 return ERROR_SUCCESS; 503 } 504 505 static DWORD vboxDispIfOpBegin(PCVBOXDISPIF pIf, VBOXDISPIF_OP *pOp) 506 { 507 pOp->pIf = pIf; 508 509 HRESULT hr = vboxDispKmtOpenAdapter(&pIf->modeData.wddm.KmtCallbacks, &pOp->Adapter); 510 if (SUCCEEDED(hr)) 511 { 512 hr = vboxDispKmtCreateDevice(&pOp->Adapter, &pOp->Device); 513 if (SUCCEEDED(hr)) 514 { 515 hr = vboxDispKmtCreateContext(&pOp->Device, &pOp->Context, VBOXWDDM_CONTEXT_TYPE_CUSTOM_DISPIF_RESIZE, 516 0, 0, NULL, 0ULL); 517 if (SUCCEEDED(hr)) 518 return ERROR_SUCCESS; 519 else 520 WARN(("VBoxTray: vboxDispKmtCreateContext failed hr 0x%x", hr)); 521 522 vboxDispKmtDestroyDevice(&pOp->Device); 523 } 524 else 525 WARN(("VBoxTray: vboxDispKmtCreateDevice failed hr 0x%x", hr)); 526 527 vboxDispKmtCloseAdapter(&pOp->Adapter); 528 } 529 530 return hr; 531 } 532 533 static VOID vboxDispIfOpEnd(VBOXDISPIF_OP *pOp) 534 { 535 vboxDispKmtDestroyContext(&pOp->Context); 536 vboxDispKmtDestroyDevice(&pOp->Device); 537 vboxDispKmtCloseAdapter(&pOp->Adapter); 538 } 539 44 540 /* display driver interface abstraction for XPDM & WDDM 45 541 * with WDDM we can not use ExtEscape to communicate with our driver … … 60 556 { 61 557 #ifdef VBOX_WITH_WDDM 62 if (pIf->enmMode == VBOXDISPIF_MODE_WDDM)558 if (pIf->enmMode >= VBOXDISPIF_MODE_WDDM) 63 559 { 64 560 vboxDispIfWddmTerm(pIf); 561 562 vboxDispKmtCallbacksTerm(&pIf->modeData.wddm.KmtCallbacks); 65 563 } 66 564 #endif … … 127 625 128 626 /* this is vista and up */ 129 HMODULE hGdi32 = GetModuleHandle("gdi32"); 130 if (hGdi32 != NULL) 131 { 132 pIf->modeData.wddm.pfnD3DKMTOpenAdapterFromHdc = (PFND3DKMT_OPENADAPTERFROMHDC)GetProcAddress(hGdi32, "D3DKMTOpenAdapterFromHdc"); 133 Log((__FUNCTION__"pfnD3DKMTOpenAdapterFromHdc = %p\n", pIf->modeData.wddm.pfnD3DKMTOpenAdapterFromHdc)); 134 bSupported &= !!(pIf->modeData.wddm.pfnD3DKMTOpenAdapterFromHdc); 135 136 pIf->modeData.wddm.pfnD3DKMTOpenAdapterFromGdiDisplayName = (PFND3DKMT_OPENADAPTERFROMGDIDISPLAYNAME)GetProcAddress(hGdi32, "D3DKMTOpenAdapterFromGdiDisplayName"); 137 Log((__FUNCTION__": pfnD3DKMTOpenAdapterFromGdiDisplayName = %p\n", pIf->modeData.wddm.pfnD3DKMTOpenAdapterFromGdiDisplayName)); 138 bSupported &= !!(pIf->modeData.wddm.pfnD3DKMTOpenAdapterFromGdiDisplayName); 139 140 pIf->modeData.wddm.pfnD3DKMTCloseAdapter = (PFND3DKMT_CLOSEADAPTER)GetProcAddress(hGdi32, "D3DKMTCloseAdapter"); 141 Log((__FUNCTION__": pfnD3DKMTCloseAdapter = %p\n", pIf->modeData.wddm.pfnD3DKMTCloseAdapter)); 142 bSupported &= !!(pIf->modeData.wddm.pfnD3DKMTCloseAdapter); 143 144 pIf->modeData.wddm.pfnD3DKMTEscape = (PFND3DKMT_ESCAPE)GetProcAddress(hGdi32, "D3DKMTEscape"); 145 Log((__FUNCTION__": pfnD3DKMTEscape = %p\n", pIf->modeData.wddm.pfnD3DKMTEscape)); 146 bSupported &= !!(pIf->modeData.wddm.pfnD3DKMTCloseAdapter); 147 148 pIf->modeData.wddm.pfnD3DKMTInvalidateActiveVidPn = (PFND3DKMT_INVALIDATEACTIVEVIDPN)GetProcAddress(hGdi32, "D3DKMTInvalidateActiveVidPn"); 149 Log((__FUNCTION__": pfnD3DKMTInvalidateActiveVidPn = %p\n", pIf->modeData.wddm.pfnD3DKMTInvalidateActiveVidPn)); 150 bSupported &= !!(pIf->modeData.wddm.pfnD3DKMTInvalidateActiveVidPn); 151 152 pIf->modeData.wddm.pfnD3DKMTPollDisplayChildren = (PFND3DKMT_POLLDISPLAYCHILDREN)GetProcAddress(hGdi32, "D3DKMTPollDisplayChildren"); 153 Log((__FUNCTION__": pfnD3DKMTPollDisplayChildren = %p\n", pIf->modeData.wddm.pfnD3DKMTPollDisplayChildren)); 154 bSupported &= !!(pIf->modeData.wddm.pfnD3DKMTPollDisplayChildren); 155 156 if (!bSupported) 157 { 158 Log((__FUNCTION__": one of pfnD3DKMT function pointers failed to initialize\n")); 159 err = ERROR_NOT_SUPPORTED; 160 } 161 } 162 else 163 { 164 Log((__FUNCTION__": GetModuleHandle(gdi32) failed, err(%d)\n", GetLastError())); 165 err = ERROR_NOT_SUPPORTED; 166 } 167 627 HRESULT hr = vboxDispKmtCallbacksInit(&pIf->modeData.wddm.KmtCallbacks); 628 if (FAILED(hr)) 629 { 630 WARN(("VBoxTray: vboxDispKmtCallbacksInit failed hr 0x%x\n", hr)); 631 err = hr; 632 } 168 633 } 169 634 else 170 635 { 171 Log((__FUNCTION__": GetModuleHandle(user32) failed, err(%d)\n", GetLastError()));636 WARN((__FUNCTION__": GetModuleHandle(USER32) failed, err(%d)\n", GetLastError())); 172 637 err = ERROR_NOT_SUPPORTED; 173 638 } … … 175 640 else 176 641 { 177 Log((__FUNCTION__": can not switch to VBOXDISPIF_MODE_WDDM, because os is not Vista or upper\n"));642 WARN((__FUNCTION__": can not switch to VBOXDISPIF_MODE_WDDM, because os is not Vista or upper\n")); 178 643 err = ERROR_NOT_SUPPORTED; 179 644 } … … 185 650 186 651 return err; 652 } 653 654 static DWORD vboxDispIfSwitchToWDDM_W7(PVBOXDISPIF pIf) 655 { 656 return vboxDispIfSwitchToWDDM(pIf); 187 657 } 188 658 … … 209 679 { 210 680 winEr = GetLastError(); 211 Log(("CreateDC failed %d", winEr));681 WARN(("CreateDC failed %d", winEr)); 212 682 break; 213 683 } … … 218 688 { 219 689 winEr = GetLastError(); 220 Log(("EnumDisplayDevices failed %d", winEr));690 WARN(("EnumDisplayDevices failed %d", winEr)); 221 691 break; 222 692 } 223 693 } 224 694 225 Log(("vboxDispIfWDDMAdpHdcCreate failure branch %d", winEr));695 WARN(("vboxDispIfWDDMAdpHdcCreate failure branch %d", winEr)); 226 696 return winEr; 227 697 } 228 698 229 230 typedef DECLCALLBACK(BOOLEAN) FNVBOXDISPIFWDDM_ADAPTEROP(PCVBOXDISPIF pIf, D3DKMT_HANDLE hAdapter, DISPLAY_DEVICE *pDev, PVOID pContext); 231 typedef FNVBOXDISPIFWDDM_ADAPTEROP *PFNVBOXDISPIFWDDM_ADAPTEROP; 232 static DWORD vboxDispIfWDDMAdapterOp(PCVBOXDISPIF pIf, int iDisplay, PFNVBOXDISPIFWDDM_ADAPTEROP pfnOp, PVOID pContext) 233 { 234 D3DKMT_OPENADAPTERFROMHDC OpenAdapterData = {0}; 235 DISPLAY_DEVICE DDev; 236 DWORD err = vboxDispIfWDDMAdpHdcCreate(iDisplay, &OpenAdapterData.hDc, &DDev); 237 Assert(err == NO_ERROR); 238 if (err == NO_ERROR) 239 { 240 NTSTATUS Status = pIf->modeData.wddm.pfnD3DKMTOpenAdapterFromHdc(&OpenAdapterData); 241 Assert(!Status); 242 if (!Status) 243 { 244 BOOLEAN bCloseAdapter = pfnOp(pIf, OpenAdapterData.hAdapter, &DDev, pContext); 245 246 if (bCloseAdapter) 247 { 248 D3DKMT_CLOSEADAPTER ClosaAdapterData = {0}; 249 ClosaAdapterData.hAdapter = OpenAdapterData.hAdapter; 250 Status = pIf->modeData.wddm.pfnD3DKMTCloseAdapter(&ClosaAdapterData); 251 if (Status) 252 { 253 Log((__FUNCTION__": pfnD3DKMTCloseAdapter failed, Status (0x%x)\n", Status)); 254 } 255 } 256 } 257 else 258 { 259 Log((__FUNCTION__": pfnD3DKMTOpenAdapterFromGdiDisplayName failed, Status (0x%x)\n", Status)); 260 err = ERROR_GEN_FAILURE; 261 } 262 263 DeleteDC(OpenAdapterData.hDc); 264 } 265 else 266 Log((__FUNCTION__": vboxDispIfWDDMAdpHdcCreate failed, winEr (%d)\n", err)); 267 268 return err; 269 } 270 271 typedef struct 272 { 273 NTSTATUS Status; 274 PVBOXDISPIFESCAPE pEscape; 275 int cbData; 276 D3DDDI_ESCAPEFLAGS EscapeFlags; 277 } VBOXDISPIFWDDM_ESCAPEOP_CONTEXT, *PVBOXDISPIFWDDM_ESCAPEOP_CONTEXT; 278 279 DECLCALLBACK(BOOLEAN) vboxDispIfEscapeWDDMOp(PCVBOXDISPIF pIf, D3DKMT_HANDLE hAdapter, DISPLAY_DEVICE *pDev, PVOID pContext) 280 { 281 PVBOXDISPIFWDDM_ESCAPEOP_CONTEXT pCtx = (PVBOXDISPIFWDDM_ESCAPEOP_CONTEXT)pContext; 699 static DWORD vboxDispIfEscapeWDDM(PCVBOXDISPIF pIf, PVBOXDISPIFESCAPE pEscape, int cbData, BOOL fHwAccess) 700 { 701 DWORD winEr = ERROR_SUCCESS; 702 VBOXDISPKMT_ADAPTER Adapter; 703 HRESULT hr = vboxDispKmtOpenAdapter(&pIf->modeData.wddm.KmtCallbacks, &Adapter); 704 if (!SUCCEEDED(hr)) 705 { 706 WARN(("VBoxTray: vboxDispKmtOpenAdapter failed hr 0x%x\n", hr)); 707 return hr; 708 } 282 709 283 710 D3DKMT_ESCAPE EscapeData = {0}; 284 EscapeData.hAdapter = hAdapter;711 EscapeData.hAdapter = Adapter.hAdapter; 285 712 //EscapeData.hDevice = NULL; 286 713 EscapeData.Type = D3DKMT_ESCAPE_DRIVERPRIVATE; 287 EscapeData.Flags = pCtx->EscapeFlags; 288 EscapeData.pPrivateDriverData = pCtx->pEscape; 289 EscapeData.PrivateDriverDataSize = VBOXDISPIFESCAPE_SIZE(pCtx->cbData); 714 if (fHwAccess) 715 EscapeData.Flags.HardwareAccess = 1; 716 EscapeData.pPrivateDriverData = pEscape; 717 EscapeData.PrivateDriverDataSize = VBOXDISPIFESCAPE_SIZE(cbData); 290 718 //EscapeData.hContext = NULL; 291 719 292 pCtx->Status = pIf->modeData.wddm.pfnD3DKMTEscape(&EscapeData); 293 294 return TRUE; 295 } 296 297 static DWORD vboxDispIfEscapeWDDM(PCVBOXDISPIF pIf, PVBOXDISPIFESCAPE pEscape, int cbData, BOOL fHwAccess) 298 { 299 VBOXDISPIFWDDM_ESCAPEOP_CONTEXT Ctx = {0}; 300 Ctx.pEscape = pEscape; 301 Ctx.cbData = cbData; 302 if (fHwAccess) 303 Ctx.EscapeFlags.HardwareAccess = 1; 304 DWORD err = vboxDispIfWDDMAdapterOp(pIf, -1 /* iDisplay, -1 means primary */, vboxDispIfEscapeWDDMOp, &Ctx); 305 if (err == NO_ERROR) 306 { 307 if (!Ctx.Status) 308 err = NO_ERROR; 309 else 310 { 311 if (Ctx.Status == 0xC00000BBL) /* not supported */ 312 err = ERROR_NOT_SUPPORTED; 313 else 314 err = ERROR_GEN_FAILURE; 315 Log((__FUNCTION__": pfnD3DKMTEscape failed, Status (0x%x)\n", Ctx.Status)); 316 } 317 } 720 NTSTATUS Status = pIf->modeData.wddm.KmtCallbacks.pfnD3DKMTEscape(&EscapeData); 721 if (NT_SUCCESS(Status)) 722 winEr = ERROR_SUCCESS; 318 723 else 319 Log((__FUNCTION__": vboxDispIfWDDMAdapterOp failed, err (%d)\n", err)); 320 321 return err; 322 } 323 324 typedef struct 325 { 326 NTSTATUS Status; 327 VBOXWDDM_RECOMMENDVIDPN_SCREEN_INFO Info; 328 } VBOXDISPIFWDDM_RESIZEOP_CONTEXT, *PVBOXDISPIFWDDM_RESIZEOP_CONTEXT; 329 330 DECLCALLBACK(BOOLEAN) vboxDispIfResizeWDDMOp(PCVBOXDISPIF pIf, D3DKMT_HANDLE hAdapter, DISPLAY_DEVICE *pDev, PVOID pContext) 331 { 332 PVBOXDISPIFWDDM_RESIZEOP_CONTEXT pCtx = (PVBOXDISPIFWDDM_RESIZEOP_CONTEXT)pContext; 333 D3DKMT_INVALIDATEACTIVEVIDPN IAVidPnData = {0}; 334 uint32_t cbData = VBOXWDDM_RECOMMENDVIDPN_SIZE(1); 335 PVBOXWDDM_RECOMMENDVIDPN pData = (PVBOXWDDM_RECOMMENDVIDPN)malloc(cbData); 336 if (pData) 337 { 338 memset(pData, 0, cbData); 339 pData->cScreenInfos = 1; 340 memcpy(&pData->aScreenInfos[0], &pCtx->Info, sizeof (VBOXWDDM_RECOMMENDVIDPN_SCREEN_INFO)); 341 342 IAVidPnData.hAdapter = hAdapter; 343 IAVidPnData.pPrivateDriverData = pData; 344 IAVidPnData.PrivateDriverDataSize = cbData; 345 346 pCtx->Status = pIf->modeData.wddm.pfnD3DKMTInvalidateActiveVidPn(&IAVidPnData); 347 Assert(!pCtx->Status); 348 if (pCtx->Status) 349 Log((__FUNCTION__": pfnD3DKMTInvalidateActiveVidPn failed, Status (0x%x)\n", pCtx->Status)); 350 351 free(pData); 352 } 353 else 354 { 355 Log((__FUNCTION__": malloc failed\n")); 356 pCtx->Status = -1; 357 } 358 359 return TRUE; 360 } 361 362 static DWORD vboxDispIfResizeWDDM(PCVBOXDISPIF const pIf, ULONG Id, DWORD Width, DWORD Height, DWORD BitsPerPixel) 363 { 364 VBOXDISPIFWDDM_RESIZEOP_CONTEXT Ctx = {0}; 365 Ctx.Info.Id = Id; 366 Ctx.Info.Width = Width; 367 Ctx.Info.Height = Height; 368 Ctx.Info.BitsPerPixel = BitsPerPixel; 369 DWORD err = vboxDispIfWDDMAdapterOp(pIf, -1, /* (int)Id - always say -1 to use primary display since the display does not really matter here */ 370 vboxDispIfResizeWDDMOp, &Ctx); 371 if (err == NO_ERROR) 372 { 373 if (!Ctx.Status) 374 err = NO_ERROR; 375 else 376 { 377 if (Ctx.Status == 0xC00000BBL) /* not supported */ 378 err = ERROR_NOT_SUPPORTED; 379 else 380 err = ERROR_GEN_FAILURE; 381 Log((__FUNCTION__": vboxDispIfResizeWDDMOp failed, Status (0x%x)\n", Ctx.Status)); 382 } 383 } 384 else 385 Log((__FUNCTION__": vboxDispIfWDDMAdapterOp failed, err (%d)\n", err)); 386 387 return err; 724 { 725 WARN(("VBoxTray: pfnD3DKMTEscape failed Status 0x%x\n", Status)); 726 winEr = ERROR_GEN_FAILURE; 727 } 728 729 vboxDispKmtCloseAdapter(&Adapter); 730 731 return winEr; 388 732 } 389 733 #endif … … 398 742 #ifdef VBOX_WITH_WDDM 399 743 case VBOXDISPIF_MODE_WDDM: 744 case VBOXDISPIF_MODE_WDDM_W7: 400 745 return vboxDispIfEscapeWDDM(pIf, pEscape, cbData, TRUE /* BOOL fHwAccess */); 401 746 #endif … … 415 760 #ifdef VBOX_WITH_WDDM 416 761 case VBOXDISPIF_MODE_WDDM: 762 case VBOXDISPIF_MODE_WDDM_W7: 417 763 return vboxDispIfEscapeWDDM(pIf, pEscape, cbData, TRUE /* BOOL fHwAccess */); 418 764 #endif … … 422 768 } 423 769 } 424 425 static DWORD vboxDispIfResizeXPDM(PCVBOXDISPIF const pIf, ULONG Id, DWORD Width, DWORD Height, DWORD BitsPerPixel)426 {427 return ERROR_NOT_SUPPORTED;428 }429 430 DWORD VBoxDispIfResize(PCVBOXDISPIF const pIf, ULONG Id, DWORD Width, DWORD Height, DWORD BitsPerPixel)431 {432 switch (pIf->enmMode)433 {434 case VBOXDISPIF_MODE_XPDM_NT4:435 return ERROR_NOT_SUPPORTED;436 case VBOXDISPIF_MODE_XPDM:437 return vboxDispIfResizeXPDM(pIf, Id, Width, Height, BitsPerPixel);438 #ifdef VBOX_WITH_WDDM439 case VBOXDISPIF_MODE_WDDM:440 return vboxDispIfResizeWDDM(pIf, Id, Width, Height, BitsPerPixel);441 #endif442 default:443 Log((__FUNCTION__": unknown mode (%d)\n", pIf->enmMode));444 return ERROR_INVALID_PARAMETER;445 }446 }447 448 770 449 771 #ifdef VBOX_WITH_WDDM … … 460 782 UINT_PTR idTimer; 461 783 PCVBOXDISPIF pIf; 784 UINT iChangedMode; 785 BOOL fEnable; 786 BOOL fExtDispSup; 462 787 DISPLAY_DEVICE *paDisplayDevices; 463 788 DEVMODE *paDeviceModes; … … 506 831 } 507 832 508 static DWORD vboxDispIfWddmValidateFixResize(PCVBOXDISPIF const pIf, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes);833 //static DWORD vboxDispIfWddmValidateFixResize(PCVBOXDISPIF const pIf, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes); 509 834 510 835 static void vboxRrRetryReschedule() … … 512 837 } 513 838 514 static void VBoxRrRetrySchedule(PCVBOXDISPIF const pIf, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes)839 static void VBoxRrRetrySchedule(PCVBOXDISPIF const pIf, UINT iChangedMode, BOOL fEnable, BOOL fExtDispSup, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes) 515 840 { 516 841 PVBOXRR pMon = &g_VBoxRr; … … 519 844 520 845 pMon->pIf = pIf; 846 pMon->iChangedMode = iChangedMode; 847 pMon->fEnable = fEnable; 848 pMon->fExtDispSup = fExtDispSup; 849 521 850 if (cDevModes) 522 851 { … … 549 878 if (!pMon->idTimer) 550 879 { 551 Log(("VBoxTray: SetTimer failed!, err %d\n", GetLastError()));880 WARN(("VBoxTray: SetTimer failed!, err %d\n", GetLastError())); 552 881 vboxRrRetryStopLocked(); 553 882 } … … 562 891 if (pMon->pIf) 563 892 { 564 DWORD dwErr = vboxDispIf WddmValidateFixResize(pMon->pIf, pMon->paDisplayDevices, pMon->paDeviceModes, pMon->cDevModes);893 DWORD dwErr = vboxDispIfResizePerform(pMon->pIf, pMon->iChangedMode, pMon->fEnable, pMon->fExtDispSup, pMon->paDisplayDevices, pMon->paDeviceModes, pMon->cDevModes); 565 894 if (ERROR_RETRY != dwErr) 566 895 VBoxRrRetryStop(); … … 634 963 { 635 964 DWORD winErr = GetLastError(); 636 Log((__FUNCTION__": RegisterClass failed, winErr(%d)\n", winErr));965 WARN((__FUNCTION__": RegisterClass failed, winErr(%d)\n", winErr)); 637 966 hr = E_FAIL; 638 967 } … … 658 987 { 659 988 DWORD winErr = GetLastError(); 660 Log((__FUNCTION__": CreateWindowEx failed, winErr(%d)\n", winErr));989 WARN((__FUNCTION__": CreateWindowEx failed, winErr(%d)\n", winErr)); 661 990 hr = E_FAIL; 662 991 } … … 673 1002 674 1003 DWORD winErr = GetLastError(); 675 Log((__FUNCTION__": DestroyWindow failed, winErr(%d) for hWnd(0x%x)\n", winErr, hWnd));1004 WARN((__FUNCTION__": DestroyWindow failed, winErr(%d) for hWnd(0x%x)\n", winErr, hWnd)); 676 1005 677 1006 return HRESULT_FROM_WIN32(winErr); … … 731 1060 DWORD winEr = GetLastError(); 732 1061 hr = HRESULT_FROM_WIN32(winEr); 733 Assert(0);734 1062 /* just ensure we never return success in this case */ 735 1063 Assert(hr != S_OK); … … 737 1065 if (hr == S_OK || hr == S_FALSE) 738 1066 hr = E_FAIL; 739 Log(("VBoxTray: GetMessage returned -1, err %d\n", winEr));1067 WARN(("VBoxTray: GetMessage returned -1, err %d\n", winEr)); 740 1068 VBoxRrRetryStop(); 741 1069 break; … … 769 1097 { 770 1098 DWORD winErr = GetLastError(); 771 Log((__FUNCTION__": SetEvent failed, winErr = (%d)", winErr));1099 WARN((__FUNCTION__": SetEvent failed, winErr = (%d)", winErr)); 772 1100 HRESULT tmpHr = HRESULT_FROM_WIN32(winErr); 773 1101 Assert(tmpHr != S_OK); … … 822 1150 { 823 1151 DWORD winErr = GetLastError(); 824 Log((__FUNCTION__": CreateThread failed, winErr = (%d)", winErr));1152 WARN((__FUNCTION__": CreateThread failed, winErr = (%d)", winErr)); 825 1153 hr = HRESULT_FROM_WIN32(winErr); 826 1154 Assert(hr != S_OK); … … 831 1159 { 832 1160 DWORD winErr = GetLastError(); 833 Log((__FUNCTION__": CreateEvent failed, winErr = (%d)", winErr));1161 WARN((__FUNCTION__": CreateEvent failed, winErr = (%d)", winErr)); 834 1162 hr = HRESULT_FROM_WIN32(winErr); 835 1163 Assert(hr != S_OK); … … 877 1205 } 878 1206 879 880 typedef struct VBOXDISPIF_WDDM_INTERNAL881 {882 PCVBOXDISPIF pIf;883 } VBOXDISPIF_WDDM_INTERNAL, *PVBOXDISPIF_WDDM_INTERNAL;884 885 static VBOXDISPIF_WDDM_INTERNAL g_VBoxDispIfWddm;886 887 static BOOL vboxDispIfWddmValidateResize(DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes)888 {889 DISPLAY_DEVICE DisplayDevice;890 int i = 0;891 UINT cMatched = 0;892 DEVMODE CurDevMode, RegDevMode;893 for (int i = 0; ; ++i)894 {895 ZeroMemory(&DisplayDevice, sizeof(DISPLAY_DEVICE));896 DisplayDevice.cb = sizeof(DISPLAY_DEVICE);897 898 if (!EnumDisplayDevices (NULL, i, &DisplayDevice, 0))899 break;900 901 Log(("VBoxTray: vboxDispIfValidateResize: [%d(%d)] %s\n", i, cMatched, DisplayDevice.DeviceName));902 903 BOOL bFetchDevice = FALSE;904 905 if (DisplayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)906 {907 Log(("VBoxTray: vboxDispIfValidateResize: Found primary device. err %d\n", GetLastError ()));908 bFetchDevice = TRUE;909 }910 else if (!(DisplayDevice.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER))911 {912 913 Log(("VBoxTray: vboxDispIfValidateResize: Found secondary device. err %d\n", GetLastError ()));914 bFetchDevice = TRUE;915 }916 917 if (bFetchDevice)918 {919 if (cMatched >= cDevModes)920 {921 Log(("VBoxTray: vboxDispIfValidateResize: %d >= %d\n", cDevModes, cMatched));922 return FALSE;923 }924 925 /* First try to get the video mode stored in registry (ENUM_REGISTRY_SETTINGS).926 * A secondary display could be not active at the moment and would not have927 * a current video mode (ENUM_CURRENT_SETTINGS).928 */929 ZeroMemory(&RegDevMode, sizeof(RegDevMode));930 RegDevMode.dmSize = sizeof(DEVMODE);931 if (!EnumDisplaySettings((LPSTR)DisplayDevice.DeviceName,932 ENUM_REGISTRY_SETTINGS, &RegDevMode))933 {934 Log(("VBoxTray: vboxDispIfValidateResize: EnumDisplaySettings error %d\n", GetLastError ()));935 return FALSE;936 }937 938 /* with Win8 WDDM Display-only driver, it seems like sometimes we get an auto-resize setting being stored in registry, although current settings do not match */939 ZeroMemory(&CurDevMode, sizeof(CurDevMode));940 CurDevMode.dmSize = sizeof(CurDevMode);941 if (!EnumDisplaySettings((LPSTR)DisplayDevice.DeviceName,942 ENUM_CURRENT_SETTINGS, &CurDevMode))943 {944 /* ENUM_CURRENT_SETTINGS returns FALSE when the display is not active:945 * for example a disabled secondary display */946 Log(("VBoxTray: vboxDispIfValidateResize: EnumDisplaySettings(ENUM_CURRENT_SETTINGS) error %d\n", GetLastError ()));947 return FALSE;948 }949 950 /* No ENUM_REGISTRY_SETTINGS yet. Seen on Vista after installation.951 * Get the current video mode then.952 */953 if ( RegDevMode.dmPelsWidth != 0954 && RegDevMode.dmPelsHeight == 0)955 {956 if (CurDevMode.dmBitsPerPel != RegDevMode.dmBitsPerPel957 || CurDevMode.dmPelsWidth != RegDevMode.dmPelsWidth958 || CurDevMode.dmPelsHeight != RegDevMode.dmPelsHeight959 || CurDevMode.dmPosition.x != RegDevMode.dmPosition.x960 || CurDevMode.dmPosition.y != RegDevMode.dmPosition.y)961 {962 Log(("VBoxTray: vboxDispIfValidateResize: current settings do not match registry settings, trating as no-match"));963 return FALSE;964 }965 }966 967 UINT j = 0;968 for (; j < cDevModes; ++j)969 {970 if (!strncmp(DisplayDevice.DeviceName, paDisplayDevices[j].DeviceName, RT_ELEMENTS(CurDevMode.dmDeviceName)))971 {972 if (paDeviceModes[j].dmBitsPerPel != CurDevMode.dmBitsPerPel973 || (paDeviceModes[j].dmPelsWidth & 0xfff8) != (CurDevMode.dmPelsWidth & 0xfff8)974 || (paDeviceModes[j].dmPelsHeight & 0xfff8) != (CurDevMode.dmPelsHeight & 0xfff8)975 || (paDeviceModes[j].dmPosition.x & 0xfff8) != (CurDevMode.dmPosition.x & 0xfff8)976 || (paDeviceModes[j].dmPosition.y & 0xfff8) != (CurDevMode.dmPosition.y & 0xfff8)977 || (paDisplayDevices[j].StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) != (DisplayDevice.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP))978 {979 return FALSE;980 }981 break;982 }983 }984 985 if (j == cDevModes)986 return FALSE;987 988 ++cMatched;989 }990 }991 992 return cMatched == cDevModes;993 }994 995 static DWORD vboxDispIfWddmValidateFixResize(PCVBOXDISPIF const pIf, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes)996 {997 if (vboxDispIfWddmValidateResize(paDisplayDevices, paDeviceModes, cDevModes))998 return NO_ERROR;999 1000 LONG status = DISP_CHANGE_SUCCESSFUL;1001 1002 /* now try to resize in a "regular" way */1003 /* Assign the new rectangles to displays. */1004 for (UINT i = 0; i < cDevModes; i++)1005 {1006 /* On Vista one must specify DM_BITSPERPEL.1007 * Note that the current mode dmBitsPerPel is already in the DEVMODE structure.1008 */1009 paDeviceModes[i].dmFields = DM_POSITION | DM_PELSHEIGHT | DM_PELSWIDTH | DM_BITSPERPEL;1010 1011 Log(("VBoxTray: ResizeDisplayDevice: pfnChangeDisplaySettingsEx %x: %dx%dx%d at %d,%d\n",1012 pIf->modeData.wddm.pfnChangeDisplaySettingsEx,1013 paDeviceModes[i].dmPelsWidth,1014 paDeviceModes[i].dmPelsHeight,1015 paDeviceModes[i].dmBitsPerPel,1016 paDeviceModes[i].dmPosition.x,1017 paDeviceModes[i].dmPosition.y));1018 1019 /* the miniport might have been adjusted the display mode stuff,1020 * adjust the paDeviceModes[i] by picking the closest available one */1021 // DEVMODE AdjustedMode = paDeviceModes[i];1022 // vboxDispIfAdjustMode(&paDisplayDevices[i], &AdjustedMode);1023 1024 LONG tmpStatus = pIf->modeData.wddm.pfnChangeDisplaySettingsEx((LPSTR)paDisplayDevices[i].DeviceName,1025 &paDeviceModes[i], NULL, CDS_NORESET | CDS_UPDATEREGISTRY, NULL);1026 Log(("VBoxTray: ResizeDisplayDevice: ChangeDisplaySettingsEx position status %d, err %d\n", tmpStatus, GetLastError ()));1027 if (tmpStatus != DISP_CHANGE_SUCCESSFUL)1028 {1029 status = tmpStatus;1030 }1031 }1032 1033 /* A second call to ChangeDisplaySettings updates the monitor. */1034 LONG tmpStatus = pIf->modeData.wddm.pfnChangeDisplaySettingsEx(NULL, NULL, NULL, 0, NULL);1035 Log(("VBoxTray: ResizeDisplayDevice: ChangeDisplaySettings update status %d\n", status));1036 if (tmpStatus == DISP_CHANGE_SUCCESSFUL)1037 {1038 if (status == DISP_CHANGE_SUCCESSFUL)1039 {1040 Log(("VBoxTray: resize succeeded\n"));1041 return NO_ERROR;1042 }1043 }1044 else1045 {1046 if (status == DISP_CHANGE_SUCCESSFUL)1047 status = tmpStatus;1048 }1049 1050 if (status == DISP_CHANGE_FAILED)1051 {1052 Log(("VBoxTray: DISP_CHANGE_FAILED, retrying..\n"));1053 return ERROR_RETRY;1054 }1055 1056 Log(("VBoxTray: resize failed with status %d\n", status));1057 1058 return ERROR_GEN_FAILURE;1059 }1060 1061 1207 static DWORD vboxDispIfWddmInit(PCVBOXDISPIF pIf) 1062 1208 { 1063 memset(&g_VBoxDispIfWddm, 0, sizeof (g_VBoxDispIfWddm));1064 g_VBoxDispIfWddm.pIf = pIf;1065 1209 HRESULT hr = VBoxRrInit(); 1066 1210 if (SUCCEEDED(hr)) … … 1068 1212 return ERROR_SUCCESS; 1069 1213 } 1070 return ERROR_GEN_FAILURE; 1214 WARN(("VBoxTray: VBoxRrInit failed hr 0x%x\n", hr)); 1215 return hr; 1071 1216 } 1072 1217 … … 1074 1219 { 1075 1220 VBoxRrTerm(); 1076 memset(&g_VBoxDispIfWddm, 0, sizeof (g_VBoxDispIfWddm)); 1077 } 1078 1079 typedef struct VBOXDISPIF_REINITMODES_OP 1080 { 1081 VBOXDISPIFESCAPE_REINITVIDEOMODESBYMASK EscData; 1082 } VBOXDISPIF_REINITMODES_OP, *PVBOXDISPIF_REINITMODES_OP; 1083 1084 static DECLCALLBACK(BOOLEAN) vboxDispIfReninitModesWDDMOp(PCVBOXDISPIF pIf, D3DKMT_HANDLE hAdapter, DISPLAY_DEVICE *pDev, PVOID pContext) 1085 { 1086 PVBOXDISPIF_REINITMODES_OP pData = (PVBOXDISPIF_REINITMODES_OP)pContext; 1087 VBOXDISPIFWDDM_ESCAPEOP_CONTEXT Ctx = {0}; 1088 Ctx.pEscape = &pData->EscData.EscapeHdr; 1089 Ctx.cbData = sizeof (pData->EscData) - sizeof (pData->EscData.EscapeHdr); 1090 // Ctx.EscapeFlags.HardwareAccess = 0; 1091 DWORD err = vboxDispIfWDDMAdapterOp(pIf, -1 /* iDisplay, -1 means primary */, vboxDispIfEscapeWDDMOp, &Ctx); 1092 if (err == NO_ERROR) 1093 { 1094 if (!Ctx.Status) 1095 err = NO_ERROR; 1096 else 1097 { 1098 if (Ctx.Status == 0xC00000BBL) /* not supported */ 1099 err = ERROR_NOT_SUPPORTED; 1100 else 1101 err = ERROR_GEN_FAILURE; 1102 Log((__FUNCTION__": pfnD3DKMTEscape failed, Status (0x%x)\n", Ctx.Status)); 1103 } 1104 } 1221 } 1222 1223 static DWORD vboxDispIfQueryDisplayConnection(VBOXDISPIF_OP *pOp, UINT32 iDisplay, BOOL *pfConnected) 1224 { 1225 if (pOp->pIf->enmMode == VBOXDISPIF_MODE_WDDM) 1226 { 1227 /* @todo: do we need ti impl it? */ 1228 *pfConnected = TRUE; 1229 return ERROR_SUCCESS; 1230 } 1231 1232 *pfConnected = FALSE; 1233 1234 VBOXDISPIF_WDDM_DISPCFG DispCfg; 1235 DWORD winEr = vboxDispIfWddmDcCreate(&DispCfg, QDC_ALL_PATHS); 1236 if (winEr != ERROR_SUCCESS) 1237 { 1238 WARN(("VBoxTray: (WDDM) Failed vboxDispIfWddmDcCreate winEr %d\n", winEr)); 1239 return winEr; 1240 } 1241 1242 int idx = vboxDispIfWddmDcSearchPath(&DispCfg, iDisplay, iDisplay); 1243 *pfConnected = (idx >= 0); 1244 1245 vboxDispIfWddmDcTerm(&DispCfg); 1246 1247 return ERROR_SUCCESS; 1248 } 1249 1250 static DWORD vboxDispIfWaitDisplayDataInited(VBOXDISPIF_OP *pOp, const uint8_t *pu8DisplayMask) 1251 { 1252 DWORD winEr = ERROR_SUCCESS; 1253 do 1254 { 1255 Sleep(100); 1256 1257 D3DKMT_POLLDISPLAYCHILDREN PollData = {0}; 1258 PollData.hAdapter = pOp->Adapter.hAdapter; 1259 PollData.NonDestructiveOnly = 1; 1260 NTSTATUS Status = pOp->pIf->modeData.wddm.KmtCallbacks.pfnD3DKMTPollDisplayChildren(&PollData); 1261 if (Status != 0) 1262 { 1263 Log(("VBoxTray: (WDDM) pfnD3DKMTPollDisplayChildren failed, Status (0x%x)\n", Status)); 1264 continue; 1265 } 1266 1267 BOOL fFound = FALSE; 1268 #if 0 1269 for (UINT i = 0; i < VBOXWDDM_SCREENMASK_SIZE; ++i) 1270 { 1271 if (pu8DisplayMask && !ASMBitTest(pu8DisplayMask, i)) 1272 continue; 1273 1274 BOOL fConnected = FALSE; 1275 winEr = vboxDispIfQueryDisplayConnection(pOp, i, &fConnected); 1276 if (winEr != ERROR_SUCCESS) 1277 { 1278 WARN(("VBoxTray: (WDDM) Failed vboxDispIfQueryDisplayConnection winEr %d\n", winEr)); 1279 return winEr; 1280 } 1281 1282 if (!fConnected) 1283 { 1284 WARN(("VBoxTray: (WDDM) Display %d not connected, not expected\n", i)); 1285 fFound = TRUE; 1286 break; 1287 } 1288 } 1289 #endif 1290 if (!fFound) 1291 break; 1292 } while (1); 1293 1294 return winEr; 1295 } 1296 1297 static DWORD vboxDispIfReninitModesWDDM(VBOXDISPIF_OP *pOp, const uint8_t *pScreenIdMask) 1298 { 1299 DWORD winEr = ERROR_SUCCESS; 1300 VBOXDISPIFESCAPE_REINITVIDEOMODESBYMASK EscData = {0}; 1301 EscData.EscapeHdr.escapeCode = VBOXESC_REINITVIDEOMODESBYMASK; 1302 memcpy(EscData.ScreenMask, pScreenIdMask, sizeof (EscData.ScreenMask)); 1303 1304 D3DKMT_ESCAPE EscapeData = {0}; 1305 EscapeData.hAdapter = pOp->Adapter.hAdapter; 1306 EscapeData.hDevice = pOp->Device.hDevice; 1307 EscapeData.hContext = pOp->Context.hContext; 1308 EscapeData.Type = D3DKMT_ESCAPE_DRIVERPRIVATE; 1309 EscapeData.Flags.HardwareAccess = 1; 1310 EscapeData.pPrivateDriverData = &EscData; 1311 EscapeData.PrivateDriverDataSize = sizeof (EscData); 1312 1313 NTSTATUS Status = pOp->pIf->modeData.wddm.KmtCallbacks.pfnD3DKMTEscape(&EscapeData); 1314 if (NT_SUCCESS(Status)) 1315 winEr = ERROR_SUCCESS; 1105 1316 else 1106 Log((__FUNCTION__": vboxDispIfWDDMAdapterOp failed, err (%d)\n", err)); 1107 1108 D3DKMT_POLLDISPLAYCHILDREN PollData = {0}; 1109 PollData.hAdapter = hAdapter; 1110 PollData.NonDestructiveOnly = 1; 1111 NTSTATUS Status = pIf->modeData.wddm.pfnD3DKMTPollDisplayChildren(&PollData); 1112 if (Status != 0) 1113 { 1114 Log((__FUNCTION__": pfnD3DKMTPollDisplayChildren failed, Status (0x%x)\n", Status)); 1115 } 1116 return TRUE; 1117 } 1118 1119 static DWORD vboxDispIfReninitModesWDDM(PCVBOXDISPIF const pIf, uint8_t *pScreenIdMask, BOOL fReconnectDisplaysOnChange) 1120 { 1121 VBOXDISPIF_REINITMODES_OP OpData = {0}; 1122 OpData.EscData.EscapeHdr.escapeCode = VBOXESC_REINITVIDEOMODESBYMASK; 1123 if (fReconnectDisplaysOnChange) 1124 OpData.EscData.EscapeHdr.u32CmdSpecific = VBOXWDDM_REINITVIDEOMODESBYMASK_F_RECONNECT_DISPLAYS_ON_CHANGE; 1125 1126 memcpy(OpData.EscData.ScreenMask, pScreenIdMask, sizeof (OpData.EscData.ScreenMask)); 1127 1128 DWORD err = vboxDispIfWDDMAdapterOp(pIf, -1 /* iDisplay, -1 means primary */, vboxDispIfReninitModesWDDMOp, &OpData); 1129 return err; 1317 { 1318 WARN(("VBoxTray: pfnD3DKMTEscape VBOXESC_REINITVIDEOMODESBYMASK failed Status 0x%x\n", Status)); 1319 winEr = ERROR_GEN_FAILURE; 1320 } 1321 1322 winEr = vboxDispIfWaitDisplayDataInited(pOp, pScreenIdMask); 1323 if (winEr != NO_ERROR) 1324 WARN(("VBoxTray: (WDDM) Failed vboxDispIfWaitDisplayDataInited winEr %d\n", winEr)); 1325 1326 return winEr; 1130 1327 } 1131 1328 … … 1137 1334 } 1138 1335 1139 static DWORD vboxDispIfAdjustMode(DISPLAY_DEVICE *pDisplayDevice, DEVMODE *pDeviceMode) 1140 { 1141 DEVMODE CurMode; 1142 DEVMODE BestMatchMode; 1143 DWORD i = 0; 1144 int64_t diffWH = INT64_MAX; 1145 int diffBpp = INT32_MAX; 1146 for (; ; ++i) 1147 { 1148 CurMode.dmSize = sizeof (CurMode); 1149 CurMode.dmDriverExtra = 0; 1150 1151 if (!EnumDisplaySettings(pDisplayDevice->DeviceName, i, &CurMode)) 1152 break; 1153 1154 if (CurMode.dmPelsWidth == pDeviceMode->dmPelsWidth 1155 && CurMode.dmPelsHeight == pDeviceMode->dmPelsHeight 1156 && CurMode.dmBitsPerPel == pDeviceMode->dmBitsPerPel) 1157 { 1158 Log(("Exact match found")); 1159 *pDeviceMode = CurMode; 1160 return NO_ERROR; 1161 } 1162 1163 int diffCurrW = RT_ABS((int)(CurMode.dmPelsWidth - pDeviceMode->dmPelsWidth)); 1164 int diffCurrH = RT_ABS((int)(CurMode.dmPelsHeight - pDeviceMode->dmPelsHeight)); 1165 int diffCurrBpp = RT_ABS((int)(CurMode.dmBitsPerPel - pDeviceMode->dmBitsPerPel) 1166 - 1 /* <- to make higher bpp take precedence over lower ones */ 1167 ); 1168 1169 int64_t diffCurrHW = (int64_t)diffCurrW*diffCurrW + (int64_t)diffCurrH*diffCurrH; 1170 1171 if (i == 0 1172 || diffCurrHW < diffWH 1173 || (diffCurrHW == diffWH && diffCurrBpp < diffBpp)) 1174 { 1175 /* first run */ 1176 BestMatchMode = CurMode; 1177 diffWH = diffCurrHW; 1178 diffBpp = diffCurrBpp; 1179 continue; 1180 } 1181 } 1182 1183 if (i == 0) 1184 { 1185 Log(("No modes found!")); 1186 return NO_ERROR; 1187 } 1188 1189 *pDeviceMode = BestMatchMode; 1190 return NO_ERROR; 1191 } 1192 1193 static DWORD vboxDispIfAdjustModeValues(PCVBOXDISPIF const pIf, DISPLAY_DEVICE *pDisplayDevice, DEVMODE *pDeviceMode) 1194 { 1195 VBOXDISPIFESCAPE_ADJUSTVIDEOMODES Data = {0}; 1196 Data.EscapeHdr.escapeCode = VBOXESC_REINITVIDEOMODESBYMASK; 1197 Data.EscapeHdr.u32CmdSpecific = 1; 1198 Data.aScreenInfos[0].Mode.Id = 1199 Data.aScreenInfos[0].Mode.Width = pDeviceMode->dmPelsWidth; 1200 Data.aScreenInfos[0].Mode.Height = pDeviceMode->dmPelsHeight; 1201 Data.aScreenInfos[0].Mode.BitsPerPixel = pDeviceMode->dmBitsPerPel; 1202 if (pDeviceMode->dmPosition.x != 0 || pDeviceMode->dmPosition.y != 0) { 1203 Data.aScreenInfos[0].Mode.PosX = pDeviceMode->dmPosition.x; 1204 Data.aScreenInfos[0].Mode.PosY = pDeviceMode->dmPosition.y; 1205 } 1206 DWORD err = vboxDispIfEscapeWDDM(pIf, &Data.EscapeHdr, sizeof (Data) - sizeof (Data.EscapeHdr), TRUE); 1207 if (err != NO_ERROR) 1208 { 1209 Log((__FUNCTION__": VBoxDispIfEscape failed with err (%d)\n", err)); 1210 } 1211 return err; 1212 } 1213 1214 DWORD vboxDispIfResizeModesWDDM(PCVBOXDISPIF const pIf, UINT iChangedMode, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes) 1336 static DWORD vboxDispIfResizePerform(PCVBOXDISPIF const pIf, UINT iChangedMode, BOOL fEnable, BOOL fExtDispSup, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes) 1337 { 1338 DWORD winEr; 1339 if (pIf->enmMode > VBOXDISPIF_MODE_WDDM) 1340 { 1341 winEr = vboxDispIfWddmResizeDisplay(pIf, iChangedMode, fEnable, paDisplayDevices, paDeviceModes, cDevModes); 1342 if (winEr != NO_ERROR) 1343 WARN(("VBoxTray: (WDDM) Failed vboxDispIfWddmResizeDisplay winEr %d\n", winEr)); 1344 } 1345 else 1346 { 1347 winEr = EnableAndResizeDispDev(paDeviceModes, paDisplayDevices, cDevModes, iChangedMode, paDeviceModes[iChangedMode].dmPelsWidth, paDeviceModes[iChangedMode].dmPelsHeight, 1348 paDeviceModes[iChangedMode].dmBitsPerPel, paDeviceModes[iChangedMode].dmPosition.x, paDeviceModes[iChangedMode].dmPosition.y, fEnable, fExtDispSup); 1349 if (winEr != NO_ERROR) 1350 WARN(("VBoxTray: (WDDM) Failed EnableAndResizeDispDev winEr %d\n", winEr)); 1351 } 1352 return winEr; 1353 } 1354 1355 DWORD vboxDispIfResizeModesWDDM(PCVBOXDISPIF const pIf, UINT iChangedMode, BOOL fEnable, BOOL fExtDispSup, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes) 1215 1356 { 1216 1357 UINT cbVidPnInfo = VBOXWDDM_RECOMMENDVIDPN_SIZE(cDevModes); … … 1218 1359 pVidPnInfo->cScreenInfos = cDevModes; 1219 1360 D3DKMT_HANDLE hAdapter = NULL; 1220 NTSTATUS Status;1221 1361 DWORD winEr = NO_ERROR; 1222 1362 UINT i = 0; … … 1225 1365 VBoxRrRetryStop(); 1226 1366 1227 for (; i < cDevModes; i++) 1228 { 1229 PVBOXWDDM_RECOMMENDVIDPN_SCREEN_INFO pInfo = &pVidPnInfo->aScreenInfos[i]; 1230 D3DKMT_OPENADAPTERFROMHDC OpenAdapterData = {0}; 1231 OpenAdapterData.hDc = CreateDC(NULL, paDisplayDevices[i].DeviceName, NULL, NULL); 1232 if (!OpenAdapterData.hDc) 1233 { 1234 winEr = GetLastError(); 1235 Log(("VBoxTray: WARNING: Failed to get dc for display device %s, winEr %d\n", paDisplayDevices[i].DeviceName, winEr)); 1236 break; 1237 } 1238 1239 Status = pIf->modeData.wddm.pfnD3DKMTOpenAdapterFromHdc(&OpenAdapterData); 1240 Assert(!Status); 1241 if (Status) 1242 { 1243 winEr = ERROR_GEN_FAILURE; 1244 Log(("VBoxTray: WARNING: Failed to open adapter from dc, Status 0x%x\n", Status)); 1245 break; 1246 } 1247 1248 pInfo->Id = OpenAdapterData.VidPnSourceId; 1249 pInfo->Width = paDeviceModes[i].dmPelsWidth; 1250 pInfo->Height = paDeviceModes[i].dmPelsHeight; 1251 pInfo->BitsPerPixel = paDeviceModes[i].dmBitsPerPel; 1252 1253 if (i == iChangedMode && (paDeviceModes[i].dmPosition.x != 0 || paDeviceModes[i].dmPosition.y != 0) ) 1254 { 1255 /* change position values only if not equal to 0*/ 1256 LogRel(("VBoxTray: (WDDM) Change Position x=%d*y=%d Display Device ID=%d\n", paDeviceModes[i].dmPosition.x, paDeviceModes[i].dmPosition.y, i)); 1257 pInfo->PosX = paDeviceModes[i].dmPosition.x; 1258 pInfo->PosY = paDeviceModes[i].dmPosition.y; 1259 } 1260 1261 if (!hAdapter) 1262 { 1263 hAdapter = OpenAdapterData.hAdapter; 1264 } 1265 else 1266 { 1267 D3DKMT_CLOSEADAPTER ClosaAdapterData = {0}; 1268 ClosaAdapterData.hAdapter = OpenAdapterData.hAdapter; 1269 Status = pIf->modeData.wddm.pfnD3DKMTCloseAdapter(&ClosaAdapterData); 1270 if (Status) 1271 Log(("VBoxTray: WARNING: Failed to close adapter, Status 0x%x\n", Status)); 1272 } 1273 } 1274 1275 BOOL fAbleToInvalidateVidPn = FALSE; 1276 1277 if (0 && winEr == NO_ERROR) 1278 { 1279 Assert(hAdapter); 1280 1281 D3DKMT_INVALIDATEACTIVEVIDPN IAVidPnData = {0}; 1282 IAVidPnData.hAdapter = hAdapter; 1283 IAVidPnData.pPrivateDriverData = pVidPnInfo; 1284 IAVidPnData.PrivateDriverDataSize = cbVidPnInfo; 1285 1286 DWORD winEr = NO_ERROR; 1287 Status = pIf->modeData.wddm.pfnD3DKMTInvalidateActiveVidPn(&IAVidPnData); 1288 Assert(!Status); 1289 if (Status) 1290 { 1291 Log((__FUNCTION__": pfnD3DKMTInvalidateActiveVidPn failed, Status (0x%x)\n", Status)); 1292 winEr = ERROR_GEN_FAILURE; 1293 } 1294 else 1295 { 1296 fAbleToInvalidateVidPn = TRUE; 1297 } 1298 } 1299 1300 if (hAdapter) 1301 { 1302 D3DKMT_CLOSEADAPTER ClosaAdapterData = {0}; 1303 ClosaAdapterData.hAdapter = hAdapter; 1304 Status = pIf->modeData.wddm.pfnD3DKMTCloseAdapter(&ClosaAdapterData); 1305 if (Status) 1306 Log(("VBoxTray: WARNING: Failed to close adapter[2], Status 0x%x\n", Status)); 1307 } 1308 1309 // for (i = 0; i < cDevModes; i++) 1310 // { 1311 // vboxDispIfAdjustMode(&paDisplayDevices[i], &paDeviceModes[i]); 1312 // } 1313 1314 if (fAbleToInvalidateVidPn) 1315 { 1316 Log(("VBoxTray: Invalidating VidPn Worked!\n")); 1317 OSVERSIONINFO OSinfo; 1318 OSinfo.dwOSVersionInfoSize = sizeof (OSinfo); 1319 GetVersionEx (&OSinfo); 1320 /* for win 7 and above calling ChangeDisplaySettingsEx to resize a specific display, is having 1321 * a side affect for enabling all the monitors including the disabled ones. So using 1322 * WDDM win 7 APIs to resize the display for OSes Win7 and above. 1323 */ 1324 if (OSinfo.dwMajorVersion >= 6 && OSinfo.dwMinorVersion >= 1) 1325 winEr = vboxDispIfWddmResizeDisplay(pIf, iChangedMode, paDisplayDevices, paDeviceModes, cDevModes); 1326 else 1327 winEr = vboxDispIfWddmValidateFixResize(pIf, paDisplayDevices, paDeviceModes, cDevModes); 1328 1329 } 1330 else 1331 { 1332 Log(("VBoxTray: Falling back to monitor mode reinit\n")); 1333 /* fallback impl needed for display-only driver 1334 * since D3DKMTInvalidateActiveVidPn is not available for WDDM > 1.0: 1335 * make the driver invalidate VidPn, 1336 * which is done by emulating a monitor re-plug currently */ 1367 VBOXDISPIF_OP Op; 1368 1369 winEr = vboxDispIfOpBegin(pIf, &Op); 1370 if (winEr != NO_ERROR) 1371 { 1372 WARN(("VBoxTray: vboxDispIfOpBegin failed winEr 0x%x", winEr)); 1373 return winEr; 1374 } 1375 1376 1377 // if (fEnable) 1378 { 1379 1337 1380 uint8_t ScreenMask[VBOXWDDM_SCREENMASK_SIZE] = {0}; 1338 1381 ASMBitSet(ScreenMask, iChangedMode); 1339 vboxDispIfReninitModesWDDM(pIf, ScreenMask, TRUE); 1340 1341 OSVERSIONINFO OSinfo; 1342 OSinfo.dwOSVersionInfoSize = sizeof (OSinfo); 1343 GetVersionEx (&OSinfo); 1344 if (OSinfo.dwMajorVersion >= 6 && OSinfo.dwMinorVersion >= 1) 1345 winEr = vboxDispIfWddmResizeDisplay(pIf, iChangedMode, paDisplayDevices, paDeviceModes, cDevModes); 1346 else 1347 winEr = vboxDispIfWddmValidateFixResize(pIf, paDisplayDevices, paDeviceModes, cDevModes); 1348 Assert(winEr == NO_ERROR); 1349 } 1382 vboxDispIfReninitModesWDDM(&Op, ScreenMask); 1383 } 1384 1385 winEr = vboxDispIfResizePerform(pIf, iChangedMode, fEnable, fExtDispSup, paDisplayDevices, paDeviceModes, cDevModes); 1350 1386 1351 1387 if (winEr == ERROR_RETRY) 1352 1388 { 1353 VBoxRrRetrySchedule(pIf, paDisplayDevices, paDeviceModes, cDevModes);1389 VBoxRrRetrySchedule(pIf, iChangedMode, fEnable, fExtDispSup, paDisplayDevices, paDeviceModes, cDevModes); 1354 1390 /* just pretend everything is fine so far */ 1355 1391 winEr = NO_ERROR; 1356 1392 } 1357 1393 1394 vboxDispIfOpEnd(&Op); 1395 1358 1396 return winEr; 1359 1397 } 1360 1398 1361 DWORD vboxDispIfWddmEnableDisplay(PCVBOXDISPIF const pIf, UINT Id, bool fEnabled) 1362 { 1363 DISPLAYCONFIG_PATH_INFO *pPathInfoArray; 1364 DISPLAYCONFIG_MODE_INFO *pModeInfoArray; 1365 UINT numPathArrayElements = 0; 1366 UINT numModeInfoArrayElements = 0; 1367 ULONG dwStatus; 1368 1369 dwStatus = gCtx.pfnGetDisplayConfigBufferSizes(fEnabled ? QDC_ALL_PATHS : QDC_ONLY_ACTIVE_PATHS, &numPathArrayElements, &numModeInfoArrayElements); 1370 if (dwStatus != ERROR_SUCCESS) 1371 { 1372 LogFlow(("VBoxTray: (WDDM) Failed GetDisplayConfigBufferSizes \n")); 1373 return dwStatus; 1374 } 1375 pPathInfoArray = (DISPLAYCONFIG_PATH_INFO *)malloc(numPathArrayElements * sizeof(DISPLAYCONFIG_PATH_INFO)); 1376 if (!pPathInfoArray) 1377 return ERROR_OUTOFMEMORY; 1378 pModeInfoArray = (DISPLAYCONFIG_MODE_INFO *)malloc(numModeInfoArrayElements * sizeof(DISPLAYCONFIG_MODE_INFO)); 1379 if (!pModeInfoArray ) 1380 { 1381 if (pPathInfoArray) 1382 { 1383 free(pPathInfoArray); 1384 } 1385 return ERROR_OUTOFMEMORY; 1386 } 1387 dwStatus = gCtx.pfnQueryDisplayConfig(fEnabled ? QDC_ALL_PATHS : QDC_ONLY_ACTIVE_PATHS, &numPathArrayElements, pPathInfoArray,&numModeInfoArrayElements, pModeInfoArray, NULL); 1388 if (dwStatus != ERROR_SUCCESS) 1389 { 1390 LogFlow(("VBoxTray: (WDDM) Failed QueryDisplayConfig \n")); 1391 free(pPathInfoArray); 1392 free(pModeInfoArray); 1393 return dwStatus; 1394 } 1395 for (unsigned int i=0; i < numPathArrayElements; ++i) 1396 { 1397 LogRel(("Sourceid= %d and targetid = %d\n", pPathInfoArray[i].sourceInfo.id, pPathInfoArray[i].targetInfo.id)); 1398 if (pPathInfoArray[i].sourceInfo.id == Id) 1399 { 1400 if (fEnabled) 1401 { 1402 LogRel(("VBoxTray: (WDDM) Enable the Display Device i =%d \n", i)); 1403 pPathInfoArray[i].flags=DISPLAYCONFIG_PATH_ACTIVE; 1399 static DWORD vboxDispIfWddmEnableDisplays(PCVBOXDISPIF const pIf, UINT cIds, UINT *pIds, BOOL fEnabled, BOOL fSetTopology, DEVMODE *pDeviceMode) 1400 { 1401 VBOXDISPIF_WDDM_DISPCFG DispCfg; 1402 1403 DWORD winEr; 1404 int iPath; 1405 1406 winEr = vboxDispIfWddmDcCreate(&DispCfg, QDC_ONLY_ACTIVE_PATHS); 1407 if (winEr != ERROR_SUCCESS) 1408 { 1409 WARN(("VBoxTray: (WDDM) Failed vboxDispIfWddmDcCreate winEr %d\n", winEr)); 1410 return winEr; 1411 } 1412 1413 UINT cChangeIds = 0; 1414 UINT *pChangeIds = (UINT*)alloca(cIds * sizeof (*pChangeIds)); 1415 if (!pChangeIds) 1416 { 1417 WARN(("VBoxTray: (WDDM) Failed to alloc change ids\n")); 1418 winEr = ERROR_OUTOFMEMORY; 1419 goto done; 1420 } 1421 1422 for (UINT i = 0; i < cIds; ++i) 1423 { 1424 UINT Id = pIds[i]; 1425 bool fIsDup = false; 1426 for (UINT j = 0; j < cChangeIds; ++j) 1427 { 1428 if (pChangeIds[j] == Id) 1429 { 1430 fIsDup = true; 1404 1431 break; 1405 1432 } 1406 else 1407 { 1408 LogRel(("VBoxTray: (WDDM) Disable the Display Device Path ID=%d and Sourceid=%d\n", i, pPathInfoArray[i].sourceInfo.id)); 1409 pPathInfoArray[i].flags=0; 1410 break; 1411 } 1412 } 1413 } 1414 dwStatus = gCtx.pfnSetDisplayConfig(numPathArrayElements, pPathInfoArray, numModeInfoArrayElements, pModeInfoArray, (SDC_APPLY | SDC_SAVE_TO_DATABASE| SDC_ALLOW_CHANGES | SDC_USE_SUPPLIED_DISPLAY_CONFIG)); 1415 if (dwStatus != ERROR_SUCCESS) 1416 { 1417 free(pPathInfoArray); 1418 free(pModeInfoArray); 1419 LogRel(("VBoxTray:(WDDM) Failed to Enable/ disable the monitor.")); 1420 return dwStatus; 1421 } 1422 free(pPathInfoArray); 1423 free(pModeInfoArray); 1424 return ERROR_SUCCESS; 1425 } 1426 1427 DWORD vboxDispIfWddmResizeDisplay(PCVBOXDISPIF const pIf, UINT Id, DISPLAY_DEVICE * paDisplayDevices, DEVMODE *paDeviceMode, UINT devModes) 1428 { 1429 DISPLAYCONFIG_PATH_INFO *pPathInfoArray; 1430 DISPLAYCONFIG_MODE_INFO *pModeInfoArray; 1431 UINT numPathArrayElements = 0; 1432 UINT numModeInfoArrayElements = 0; 1433 ULONG dwStatus; 1434 bool fFoundDisplay = false; 1435 1436 dwStatus = gCtx.pfnGetDisplayConfigBufferSizes(QDC_ONLY_ACTIVE_PATHS, &numPathArrayElements, &numModeInfoArrayElements); 1437 if (dwStatus != ERROR_SUCCESS) 1438 { 1439 LogFlow(("VBoxTray: (WDDM) Failed GetDisplayConfigBufferSizes \n")); 1440 return dwStatus; 1441 } 1442 pPathInfoArray = (DISPLAYCONFIG_PATH_INFO *)malloc(numPathArrayElements * sizeof(DISPLAYCONFIG_PATH_INFO)); 1443 if (!pPathInfoArray) 1444 return ERROR_OUTOFMEMORY; 1445 pModeInfoArray = (DISPLAYCONFIG_MODE_INFO *)malloc(numModeInfoArrayElements * sizeof(DISPLAYCONFIG_MODE_INFO)); 1446 if (!pModeInfoArray ) 1447 { 1448 if (pPathInfoArray) 1449 { 1450 free(pPathInfoArray); 1451 } 1452 return ERROR_OUTOFMEMORY; 1453 } 1454 dwStatus = gCtx.pfnQueryDisplayConfig( QDC_ONLY_ACTIVE_PATHS, &numPathArrayElements, pPathInfoArray,&numModeInfoArrayElements, pModeInfoArray, NULL); 1455 if (dwStatus != ERROR_SUCCESS) 1456 { 1457 LogFlow(("VBoxTray: (WDDM) Failed QueryDisplayConfig \n")); 1458 free(pPathInfoArray); 1459 free(pModeInfoArray); 1460 return dwStatus; 1461 } 1462 LogFlow(("VBoxTray: NumPath =%d and NumMod=%d\n", numPathArrayElements, numModeInfoArrayElements)); 1463 for (UINT iter = 0; iter < numPathArrayElements; ++iter) 1464 { 1465 LogFlow(("Sourceid= %d and targetid = %d iter =%d and id = %d\n", pPathInfoArray[iter].sourceInfo.id, pPathInfoArray[iter].targetInfo.id, iter, Id)); 1466 if (pPathInfoArray[iter].sourceInfo.id == Id) 1467 { 1468 UINT iModIdx = pPathInfoArray[iter].sourceInfo.modeInfoIdx; 1469 LogFlow(("VBoxTray: Mode Index = %d\n", iModIdx)); 1470 pModeInfoArray[iModIdx].sourceMode.width = paDeviceMode[Id].dmPelsWidth; 1471 pModeInfoArray[iModIdx].sourceMode.height = paDeviceMode[Id].dmPelsHeight; 1472 if(paDeviceMode[Id].dmPosition.x != 0 || paDeviceMode[Id].dmPosition.y != 0) 1473 { 1474 pModeInfoArray[iModIdx].sourceMode.position.x = paDeviceMode[Id].dmPosition.x; 1475 pModeInfoArray[iModIdx].sourceMode.position.y = paDeviceMode[Id].dmPosition.y; 1476 } 1477 fFoundDisplay = true; 1478 break; 1479 } 1480 } 1481 if (fFoundDisplay) 1482 { 1483 /* Call SetDisplayConfig only if displaywith ID=Id has been found. */ 1484 LogFlow(("VBoxTray: Found Display with Id=%d\n", Id)); 1485 dwStatus = gCtx.pfnSetDisplayConfig(numPathArrayElements, pPathInfoArray, numModeInfoArrayElements, pModeInfoArray,(SDC_APPLY | SDC_SAVE_TO_DATABASE| SDC_ALLOW_CHANGES | SDC_USE_SUPPLIED_DISPLAY_CONFIG)); 1486 if (dwStatus != ERROR_SUCCESS) 1487 { 1488 LogRel(("VBoxTray:(WDDM) Failed to resize the monitor.\n")); 1489 free(pPathInfoArray); 1490 free(pModeInfoArray); 1491 1492 if (dwStatus == ERROR_GEN_FAILURE) 1493 { 1494 LogRel(("VBoxTray:(WDDM) going to retry\n")); 1495 return ERROR_RETRY; /* <- to make sure we retry */ 1496 } 1497 return dwStatus; 1498 } 1499 } 1500 free(pPathInfoArray); 1501 free(pModeInfoArray); 1502 return ERROR_SUCCESS; 1433 } 1434 1435 if (fIsDup) 1436 continue; 1437 1438 iPath = vboxDispIfWddmDcSearchPath(&DispCfg, Id, Id); 1439 1440 if (!((iPath >= 0) && (DispCfg.pPathInfoArray[iPath].flags & DISPLAYCONFIG_PATH_ACTIVE)) != !fEnabled) 1441 { 1442 pChangeIds[cChangeIds] = Id; 1443 ++cChangeIds; 1444 } 1445 } 1446 1447 if (cChangeIds == 0) 1448 { 1449 Log(("VBoxTray: (WDDM) vboxDispIfWddmEnableDisplay: settings are up to date\n")); 1450 winEr = ERROR_SUCCESS; 1451 goto done; 1452 } 1453 1454 /* we want to set primary for every disabled for non-topoly mode only */ 1455 winEr = vboxDispIfWddmDcSettingsIncludeAllTargets(&DispCfg); 1456 if (winEr != ERROR_SUCCESS) 1457 { 1458 WARN(("VBoxTray: (WDDM) Failed vboxDispIfWddmDcSettingsIncludeAllTargets winEr %d\n", winEr)); 1459 return winEr; 1460 } 1461 1462 if (fSetTopology) 1463 vboxDispIfWddmDcSettingsInvalidateModeIndeces(&DispCfg); 1464 1465 for (UINT i = 0; i < cChangeIds; ++i) 1466 { 1467 UINT Id = pChangeIds[i]; 1468 /* re-query paths */ 1469 iPath = vboxDispIfWddmDcSearchPath(&DispCfg, -1, Id); 1470 if (iPath < 0) 1471 { 1472 WARN(("VBoxTray: (WDDM) path index not found while it should")); 1473 winEr = ERROR_GEN_FAILURE; 1474 goto done; 1475 } 1476 1477 winEr = vboxDispIfWddmDcSettingsUpdate(&DispCfg, iPath, pDeviceMode, !fEnabled || fSetTopology, fEnabled); 1478 if (winEr != ERROR_SUCCESS) 1479 { 1480 WARN(("VBoxTray: (WDDM) Failed vboxDispIfWddmDcSettingsUpdate winEr %d\n", winEr)); 1481 goto done; 1482 } 1483 } 1484 1485 if (!fSetTopology) 1486 vboxDispIfWddmDcSettingsAttachDisbledToPrimary(&DispCfg); 1487 1488 #if 0 1489 /* ensure the zero-index (primary) screen is enabled */ 1490 iPath = vboxDispIfWddmDcSearchPath(&DispCfg, 0, 0); 1491 if (iPath < 0) 1492 { 1493 WARN(("VBoxTray: (WDDM) path index not found while it should")); 1494 winEr = ERROR_GEN_FAILURE; 1495 goto done; 1496 } 1497 1498 winEr = vboxDispIfWddmDcSettingsUpdate(&DispCfg, iPath, /* just re-use device node here*/ pDeviceMode, fSetTopology, TRUE); 1499 if (winEr != ERROR_SUCCESS) 1500 { 1501 WARN(("VBoxTray: (WDDM) Failed vboxDispIfWddmDcSettingsUpdate winEr %d\n", winEr)); 1502 goto done; 1503 } 1504 #endif 1505 1506 UINT fSetFlags = !fSetTopology ? (SDC_USE_SUPPLIED_DISPLAY_CONFIG) : (SDC_ALLOW_PATH_ORDER_CHANGES | SDC_TOPOLOGY_SUPPLIED); 1507 winEr = vboxDispIfWddmDcSet(&DispCfg, fSetFlags | SDC_VALIDATE); 1508 if (winEr != ERROR_SUCCESS) 1509 { 1510 if (!fSetTopology) 1511 { 1512 WARN(("VBoxTray: (WDDM) vboxDispIfWddmDcSet validation failed winEr, trying with changes %d\n", winEr)); 1513 fSetFlags |= SDC_ALLOW_CHANGES; 1514 } 1515 else 1516 { 1517 Log(("VBoxTray: (WDDM) vboxDispIfWddmDcSet topology validation failed winEr %d\n", winEr)); 1518 goto done; 1519 } 1520 } 1521 1522 if (!fSetTopology) 1523 fSetFlags |= SDC_SAVE_TO_DATABASE; 1524 1525 winEr = vboxDispIfWddmDcSet(&DispCfg, fSetFlags | SDC_APPLY); 1526 if (winEr != ERROR_SUCCESS) 1527 WARN(("VBoxTray: (WDDM) vboxDispIfWddmDcSet apply failed winEr %d\n", winEr)); 1528 1529 done: 1530 vboxDispIfWddmDcTerm(&DispCfg); 1531 1532 return winEr; 1533 } 1534 1535 static DWORD vboxDispIfWddmEnableDisplaysTryingTopology(PCVBOXDISPIF const pIf, UINT cIds, UINT *pIds, BOOL fEnable) 1536 { 1537 DWORD winEr = vboxDispIfWddmEnableDisplays(pIf, cIds, pIds, fEnable, FALSE, NULL); 1538 if (winEr != ERROR_SUCCESS) 1539 { 1540 if (fEnable) 1541 WARN(("VBoxTray: (WDDM) Failed vboxDispIfWddmEnableDisplay mode winEr %d\n", winEr)); 1542 else 1543 Log(("VBoxTray: (WDDM) Failed vboxDispIfWddmEnableDisplay mode winEr %d\n", winEr)); 1544 winEr = vboxDispIfWddmEnableDisplays(pIf, cIds, pIds, fEnable, TRUE, NULL); 1545 if (winEr != ERROR_SUCCESS) 1546 WARN(("VBoxTray: (WDDM) Failed vboxDispIfWddmEnableDisplay mode winEr %d\n", winEr)); 1547 } 1548 1549 return winEr; 1550 } 1551 1552 static DWORD vboxDispIfWddmResizeDisplay(PCVBOXDISPIF const pIf, UINT Id, BOOL fEnable, DISPLAY_DEVICE * paDisplayDevices, DEVMODE *paDeviceMode, UINT devModes) 1553 { 1554 VBOXDISPIF_WDDM_DISPCFG DispCfg; 1555 DWORD winEr; 1556 int iPath; 1557 1558 winEr = vboxDispIfWddmDcCreate(&DispCfg, QDC_ONLY_ACTIVE_PATHS); 1559 if (winEr != ERROR_SUCCESS) 1560 { 1561 WARN(("VBoxTray: (WDDM) Failed vboxDispIfWddmDcCreate\n")); 1562 return winEr; 1563 } 1564 1565 iPath = vboxDispIfWddmDcSearchActivePath(&DispCfg, Id, Id); 1566 1567 if (iPath < 0) 1568 { 1569 vboxDispIfWddmDcTerm(&DispCfg); 1570 1571 if (!fEnable) 1572 { 1573 /* nothing to be done here, just leave */ 1574 return ERROR_SUCCESS; 1575 } 1576 1577 winEr = vboxDispIfWddmEnableDisplaysTryingTopology(pIf, 1, &Id, fEnable); 1578 if (winEr != ERROR_SUCCESS) 1579 { 1580 WARN(("VBoxTray: (WDDM) Failed vboxDispIfWddmEnableDisplaysTryingTopology winEr %d\n", winEr)); 1581 return winEr; 1582 } 1583 1584 winEr = vboxDispIfWddmDcCreate(&DispCfg, QDC_ONLY_ACTIVE_PATHS); 1585 if (winEr != ERROR_SUCCESS) 1586 { 1587 WARN(("VBoxTray: (WDDM) Failed vboxDispIfWddmDcCreate winEr %d\n", winEr)); 1588 return winEr; 1589 } 1590 1591 iPath = vboxDispIfWddmDcSearchPath(&DispCfg, Id, Id); 1592 if (iPath < 0) 1593 { 1594 WARN(("VBoxTray: (WDDM) path (%d) is still disabled, going to retry winEr %d\n", winEr)); 1595 vboxDispIfWddmDcTerm(&DispCfg); 1596 return ERROR_RETRY; 1597 } 1598 } 1599 1600 Assert(iPath >= 0); 1601 1602 if (!fEnable) 1603 { 1604 /* need to disable it, and we are done */ 1605 vboxDispIfWddmDcTerm(&DispCfg); 1606 1607 winEr = vboxDispIfWddmEnableDisplaysTryingTopology(pIf, 1, &Id, fEnable); 1608 if (winEr != ERROR_SUCCESS) 1609 { 1610 WARN(("VBoxTray: (WDDM) Failed vboxDispIfWddmEnableDisplaysTryingTopology winEr %d\n", winEr)); 1611 return winEr; 1612 } 1613 1614 return winEr; 1615 } 1616 1617 Assert(fEnable); 1618 1619 winEr = vboxDispIfWddmDcSettingsUpdate(&DispCfg, iPath, &paDeviceMode[Id], FALSE, fEnable); 1620 if (winEr != ERROR_SUCCESS) 1621 { 1622 WARN(("VBoxTray: (WDDM) Failed vboxDispIfWddmDcSettingsUpdate\n")); 1623 vboxDispIfWddmDcTerm(&DispCfg); 1624 return winEr; 1625 } 1626 1627 UINT fSetFlags = SDC_USE_SUPPLIED_DISPLAY_CONFIG; 1628 winEr = vboxDispIfWddmDcSet(&DispCfg, fSetFlags | SDC_VALIDATE); 1629 if (winEr != ERROR_SUCCESS) 1630 { 1631 WARN(("VBoxTray:(WDDM) pfnSetDisplayConfig Failed to validate winEr %d.\n", winEr)); 1632 fSetFlags |= SDC_ALLOW_CHANGES; 1633 } 1634 1635 winEr = vboxDispIfWddmDcSet(&DispCfg, fSetFlags | SDC_SAVE_TO_DATABASE | SDC_APPLY); 1636 if (winEr != ERROR_SUCCESS) 1637 { 1638 WARN(("VBoxTray:(WDDM) pfnSetDisplayConfig Failed to validate winEr %d.\n", winEr)); 1639 } 1640 1641 vboxDispIfWddmDcTerm(&DispCfg); 1642 1643 return winEr; 1503 1644 } 1504 1645 1505 1646 #endif /* VBOX_WITH_WDDM */ 1506 1647 1507 DWORD VBoxDispIfResizeModes(PCVBOXDISPIF const pIf, UINT iChangedMode, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes)1648 DWORD VBoxDispIfResizeModes(PCVBOXDISPIF const pIf, UINT iChangedMode, BOOL fEnable, BOOL fExtDispSup, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes) 1508 1649 { 1509 1650 switch (pIf->enmMode) … … 1515 1656 #ifdef VBOX_WITH_WDDM 1516 1657 case VBOXDISPIF_MODE_WDDM: 1517 return vboxDispIfResizeModesWDDM(pIf, iChangedMode, paDisplayDevices, paDeviceModes, cDevModes); 1658 case VBOXDISPIF_MODE_WDDM_W7: 1659 return vboxDispIfResizeModesWDDM(pIf, iChangedMode, fEnable, fExtDispSup, paDisplayDevices, paDeviceModes, cDevModes); 1518 1660 #endif 1519 1661 default: 1520 Log((__FUNCTION__": unknown mode (%d)\n", pIf->enmMode));1662 WARN((__FUNCTION__": unknown mode (%d)\n", pIf->enmMode)); 1521 1663 return ERROR_INVALID_PARAMETER; 1522 1664 } … … 1533 1675 #ifdef VBOX_WITH_WDDM 1534 1676 case VBOXDISPIF_MODE_WDDM: 1677 case VBOXDISPIF_MODE_WDDM_W7: 1535 1678 return vboxDispIfCancelPendingResizeWDDM(pIf); 1536 1679 #endif 1537 1680 default: 1538 Log((__FUNCTION__": unknown mode (%d)\n", pIf->enmMode));1681 WARN((__FUNCTION__": unknown mode (%d)\n", pIf->enmMode)); 1539 1682 return ERROR_INVALID_PARAMETER; 1540 1683 } 1541 1684 } 1542 1685 1543 DWORD VBoxDispIfReninitModes(PCVBOXDISPIF const pIf, uint8_t *pScreenIdMask, BOOL fReconnectDisplaysOnChange) 1686 static DWORD vboxDispIfConfigureTargetsWDDM(VBOXDISPIF_OP *pOp, uint32_t *pcConnected) 1687 { 1688 VBOXDISPIFESCAPE EscapeHdr = {0}; 1689 EscapeHdr.escapeCode = VBOXESC_CONFIGURETARGETS; 1690 EscapeHdr.u32CmdSpecific = 0; 1691 1692 D3DKMT_ESCAPE EscapeData = {0}; 1693 EscapeData.hAdapter = pOp->Adapter.hAdapter; 1694 EscapeData.hDevice = pOp->Device.hDevice; 1695 EscapeData.hContext = pOp->Context.hContext; 1696 EscapeData.Type = D3DKMT_ESCAPE_DRIVERPRIVATE; 1697 EscapeData.Flags.HardwareAccess = 1; 1698 EscapeData.pPrivateDriverData = &EscapeHdr; 1699 EscapeData.PrivateDriverDataSize = sizeof (EscapeHdr); 1700 1701 NTSTATUS Status = pOp->pIf->modeData.wddm.KmtCallbacks.pfnD3DKMTEscape(&EscapeData); 1702 if (NT_SUCCESS(Status)) 1703 { 1704 if (pcConnected) 1705 *pcConnected = EscapeHdr.u32CmdSpecific; 1706 return NO_ERROR; 1707 } 1708 WARN(("VBoxTray: pfnD3DKMTEscape VBOXESC_CONFIGURETARGETS failed Status 0x%x\n", Status)); 1709 return Status; 1710 } 1711 1712 static DWORD vboxDispIfResizeStartedWDDMOp(VBOXDISPIF_OP *pOp) 1713 { 1714 DWORD NumDevices = VBoxGetDisplayConfigCount(); 1715 if (NumDevices == 0) 1716 { 1717 WARN(("VBoxTray: vboxDispIfResizeStartedWDDMOp: Zero devices found\n")); 1718 return ERROR_GEN_FAILURE; 1719 } 1720 1721 #ifdef DEBUG_misha 1722 { 1723 UINT cDcDisplays; 1724 DWORD winEr2 = vboxDispIfWddmDcQueryNumDisplays(&cDcDisplays); 1725 Assert(cDcDisplays == NumDevices); 1726 /* testing */ 1727 Assert(cDcDisplays == 2); 1728 } 1729 #endif 1730 DISPLAY_DEVICE *paDisplayDevices = (DISPLAY_DEVICE *)alloca (sizeof (DISPLAY_DEVICE) * NumDevices); 1731 DEVMODE *paDeviceModes = (DEVMODE *)alloca (sizeof (DEVMODE) * NumDevices); 1732 DWORD DevNum = 0; 1733 DWORD DevPrimaryNum = 0; 1734 1735 DWORD winEr = VBoxGetDisplayConfig(NumDevices, &DevPrimaryNum, &DevNum, paDisplayDevices, paDeviceModes); 1736 if (winEr != NO_ERROR) 1737 { 1738 WARN(("VBoxTray: vboxDispIfResizeStartedWDDMOp: VBoxGetDisplayConfig failed, %d\n", winEr)); 1739 return winEr; 1740 } 1741 1742 if (NumDevices != DevNum) 1743 WARN(("VBoxTray: vboxDispIfResizeStartedWDDMOp: NumDevices(%d) != DevNum(%d)\n", NumDevices, DevNum)); 1744 1745 1746 uint32_t cConnected = 0; 1747 winEr = vboxDispIfConfigureTargetsWDDM(pOp, &cConnected); 1748 if (winEr != NO_ERROR) 1749 { 1750 WARN(("VBoxTray: vboxDispIfConfigureTargetsWDDM failed winEr 0x%x\n", winEr)); 1751 return winEr; 1752 } 1753 1754 if (!cConnected) 1755 { 1756 Log(("VBoxTray: all targets already connected, nothing to do\n")); 1757 return NO_ERROR; 1758 } 1759 1760 winEr = vboxDispIfWaitDisplayDataInited(pOp, NULL); 1761 if (winEr != NO_ERROR) 1762 WARN(("VBoxTray: vboxDispIfResizeStartedWDDMOp: vboxDispIfWaitDisplayDataInited failed winEr 0x%x\n", winEr)); 1763 1764 DWORD NewNumDevices = VBoxGetDisplayConfigCount(); 1765 if (NewNumDevices == 0) 1766 { 1767 WARN(("VBoxTray: vboxDispIfResizeStartedWDDMOp: Zero devices found\n")); 1768 return ERROR_GEN_FAILURE; 1769 } 1770 1771 if (NewNumDevices != NumDevices) 1772 WARN(("VBoxTray: vboxDispIfResizeStartedWDDMOp: NumDevices(%d) != NewNumDevices(%d)\n", NumDevices, NewNumDevices)); 1773 1774 DISPLAY_DEVICE *paNewDisplayDevices = (DISPLAY_DEVICE *)alloca (sizeof (DISPLAY_DEVICE) * NewNumDevices); 1775 DEVMODE *paNewDeviceModes = (DEVMODE *)alloca (sizeof (DEVMODE) * NewNumDevices); 1776 DWORD NewDevNum = 0; 1777 DWORD NewDevPrimaryNum = 0; 1778 1779 winEr = VBoxGetDisplayConfig(NewNumDevices, &NewDevPrimaryNum, &NewDevNum, paNewDisplayDevices, paNewDeviceModes); 1780 if (winEr != NO_ERROR) 1781 { 1782 WARN(("VBoxTray: vboxDispIfResizeStartedWDDMOp: VBoxGetDisplayConfig failed for new devices, %d\n", winEr)); 1783 return winEr; 1784 } 1785 1786 if (NewNumDevices != NewDevNum) 1787 WARN(("VBoxTray: vboxDispIfResizeStartedWDDMOp: NewNumDevices(%d) != NewDevNum(%d)\n", NewNumDevices, NewDevNum)); 1788 1789 DWORD minDevNum = RT_MIN(DevNum, NewDevNum); 1790 UINT *pIds = (UINT*)alloca (sizeof (UINT) * minDevNum); 1791 UINT cIds = 0; 1792 for (DWORD i = 0; i < minDevNum; ++i) 1793 { 1794 if ((paNewDisplayDevices[i].StateFlags & DISPLAY_DEVICE_ACTIVE) 1795 && !(paDisplayDevices[i].StateFlags & DISPLAY_DEVICE_ACTIVE)) 1796 { 1797 pIds[cIds] = i; 1798 ++cIds; 1799 } 1800 } 1801 1802 if (!cIds) 1803 { 1804 /* this is something we would not regularly expect */ 1805 WARN(("VBoxTray: all targets already have proper config, nothing to do\n")); 1806 return NO_ERROR; 1807 } 1808 1809 if (pOp->pIf->enmMode > VBOXDISPIF_MODE_WDDM) 1810 { 1811 winEr = vboxDispIfWddmEnableDisplaysTryingTopology(pOp->pIf, cIds, pIds, FALSE); 1812 if (winEr != NO_ERROR) 1813 WARN(("VBoxTray: vboxDispIfWddmEnableDisplaysTryingTopology failed to record current settings, %d, ignoring\n", winEr)); 1814 } 1815 else 1816 { 1817 for (DWORD i = 0; i < cIds; ++i) 1818 { 1819 winEr = EnableAndResizeDispDev(paNewDeviceModes, paNewDisplayDevices, NewDevNum, i, 0, 0, 0, 0, 0, FALSE, TRUE); 1820 if (winEr != NO_ERROR) 1821 WARN(("VBoxTray: vboxDispIfResizeStartedWDDMOp: EnableAndResizeDispDev failed winEr 0x%x\n", winEr)); 1822 } 1823 } 1824 1825 return winEr; 1826 } 1827 1828 1829 static DWORD vboxDispIfResizeStartedWDDM(PCVBOXDISPIF const pIf) 1830 { 1831 VBOXDISPIF_OP Op; 1832 1833 DWORD winEr = vboxDispIfOpBegin(pIf, &Op); 1834 if (winEr != NO_ERROR) 1835 { 1836 WARN(("VBoxTray: vboxDispIfOpBegin failed winEr 0x%x\n", winEr)); 1837 return winEr; 1838 } 1839 1840 winEr = vboxDispIfResizeStartedWDDMOp(&Op); 1841 if (winEr != NO_ERROR) 1842 { 1843 WARN(("VBoxTray: vboxDispIfResizeStartedWDDMOp failed winEr 0x%x\n", winEr)); 1844 } 1845 1846 vboxDispIfOpEnd(&Op); 1847 1848 return winEr; 1849 } 1850 1851 DWORD VBoxDispIfResizeStarted(PCVBOXDISPIF const pIf) 1544 1852 { 1545 1853 switch (pIf->enmMode) 1546 1854 { 1547 1855 case VBOXDISPIF_MODE_XPDM_NT4: 1548 return ERROR_NOT_SUPPORTED;1856 return NO_ERROR; 1549 1857 case VBOXDISPIF_MODE_XPDM: 1550 return ERROR_NOT_SUPPORTED;1858 return NO_ERROR; 1551 1859 #ifdef VBOX_WITH_WDDM 1552 1860 case VBOXDISPIF_MODE_WDDM: 1553 return vboxDispIfReninitModesWDDM(pIf, pScreenIdMask, fReconnectDisplaysOnChange); 1861 case VBOXDISPIF_MODE_WDDM_W7: 1862 return vboxDispIfResizeStartedWDDM(pIf); 1554 1863 #endif 1555 1864 default: 1556 Log((__FUNCTION__": unknown mode (%d)\n", pIf->enmMode));1865 WARN((__FUNCTION__": unknown mode (%d)\n", pIf->enmMode)); 1557 1866 return ERROR_INVALID_PARAMETER; 1558 1867 } … … 1583 1892 if (!bSupported) 1584 1893 { 1585 Log((__FUNCTION__": pfnChangeDisplaySettingsEx function pointer failed to initialize\n"));1894 WARN((__FUNCTION__": pfnChangeDisplaySettingsEx function pointer failed to initialize\n")); 1586 1895 err = ERROR_NOT_SUPPORTED; 1587 1896 } … … 1589 1898 else 1590 1899 { 1591 Log((__FUNCTION__": failed to get user32 handle, err (%d)\n", GetLastError()));1900 WARN((__FUNCTION__": failed to get USER32 handle, err (%d)\n", GetLastError())); 1592 1901 err = ERROR_NOT_SUPPORTED; 1593 1902 } … … 1595 1904 else 1596 1905 { 1597 Log((__FUNCTION__": can not switch to VBOXDISPIF_MODE_XPDM, because os is not >= w2k\n"));1906 WARN((__FUNCTION__": can not switch to VBOXDISPIF_MODE_XPDM, because os is not >= w2k\n")); 1598 1907 err = ERROR_NOT_SUPPORTED; 1599 1908 } … … 1613 1922 1614 1923 #ifdef VBOX_WITH_WDDM 1615 if (pIf->enmMode == VBOXDISPIF_MODE_WDDM)1924 if (pIf->enmMode >= VBOXDISPIF_MODE_WDDM) 1616 1925 { 1617 1926 vboxDispIfWddmTerm(pIf); 1927 1928 vboxDispKmtCallbacksTerm(&pIf->modeData.wddm.KmtCallbacks); 1618 1929 } 1619 1930 #endif … … 1631 1942 } 1632 1943 else 1633 Log((__FUNCTION__": failed to switch to XPDM_NT4 mode, err (%d)\n", err));1944 WARN((__FUNCTION__": failed to switch to XPDM_NT4 mode, err (%d)\n", err)); 1634 1945 break; 1635 1946 case VBOXDISPIF_MODE_XPDM: … … 1642 1953 } 1643 1954 else 1644 Log((__FUNCTION__": failed to switch to XPDM mode, err (%d)\n", err));1955 WARN((__FUNCTION__": failed to switch to XPDM mode, err (%d)\n", err)); 1645 1956 break; 1646 1957 #ifdef VBOX_WITH_WDDM … … 1655 1966 } 1656 1967 else 1657 Log((__FUNCTION__": failed to switch to WDDM mode, err (%d)\n", err)); 1968 WARN((__FUNCTION__": failed to switch to WDDM mode, err (%d)\n", err)); 1969 break; 1970 } 1971 case VBOXDISPIF_MODE_WDDM_W7: 1972 { 1973 Log((__FUNCTION__": request to switch to VBOXDISPIF_MODE_WDDM_W7\n")); 1974 err = vboxDispIfSwitchToWDDM_W7(pIf); 1975 if (err == NO_ERROR) 1976 { 1977 Log((__FUNCTION__": successfully switched to WDDM mode\n")); 1978 pIf->enmMode = VBOXDISPIF_MODE_WDDM_W7; 1979 } 1980 else 1981 WARN((__FUNCTION__": failed to switch to WDDM mode, err (%d)\n", err)); 1658 1982 break; 1659 1983 } … … 1665 1989 return err; 1666 1990 } 1991 1992 static DWORD vboxDispIfSeamlesCreateWDDM(PCVBOXDISPIF const pIf, VBOXDISPIF_SEAMLESS *pSeamless, HANDLE hEvent) 1993 { 1994 HRESULT hr = vboxDispKmtOpenAdapter(&pIf->modeData.wddm.KmtCallbacks, &pSeamless->modeData.wddm.Adapter); 1995 if (SUCCEEDED(hr)) 1996 { 1997 hr = vboxDispKmtCreateDevice(&pSeamless->modeData.wddm.Adapter, &pSeamless->modeData.wddm.Device); 1998 if (SUCCEEDED(hr)) 1999 { 2000 hr = vboxDispKmtCreateContext(&pSeamless->modeData.wddm.Device, &pSeamless->modeData.wddm.Context, VBOXWDDM_CONTEXT_TYPE_CUSTOM_DISPIF_SEAMLESS, 2001 0, 0, hEvent, 0ULL); 2002 if (SUCCEEDED(hr)) 2003 return ERROR_SUCCESS; 2004 else 2005 WARN(("VBoxTray: vboxDispKmtCreateContext failed hr 0x%x", hr)); 2006 2007 vboxDispKmtDestroyDevice(&pSeamless->modeData.wddm.Device); 2008 } 2009 else 2010 WARN(("VBoxTray: vboxDispKmtCreateDevice failed hr 0x%x", hr)); 2011 2012 vboxDispKmtCloseAdapter(&pSeamless->modeData.wddm.Adapter); 2013 } 2014 2015 return hr; 2016 } 2017 2018 static DWORD vboxDispIfSeamlesTermWDDM(VBOXDISPIF_SEAMLESS *pSeamless) 2019 { 2020 vboxDispKmtDestroyContext(&pSeamless->modeData.wddm.Context); 2021 vboxDispKmtDestroyDevice(&pSeamless->modeData.wddm.Device); 2022 vboxDispKmtCloseAdapter(&pSeamless->modeData.wddm.Adapter); 2023 2024 return NO_ERROR; 2025 } 2026 2027 static DWORD vboxDispIfSeamlesSubmitWDDM(VBOXDISPIF_SEAMLESS *pSeamless, VBOXDISPIFESCAPE *pData, int cbData) 2028 { 2029 D3DKMT_ESCAPE EscapeData = {0}; 2030 EscapeData.hAdapter = pSeamless->modeData.wddm.Adapter.hAdapter; 2031 EscapeData.hDevice = pSeamless->modeData.wddm.Device.hDevice; 2032 EscapeData.hContext = pSeamless->modeData.wddm.Context.hContext; 2033 EscapeData.Type = D3DKMT_ESCAPE_DRIVERPRIVATE; 2034 EscapeData.Flags.HardwareAccess = 1; 2035 EscapeData.pPrivateDriverData = pData; 2036 EscapeData.PrivateDriverDataSize = VBOXDISPIFESCAPE_SIZE(cbData); 2037 2038 NTSTATUS Status = pSeamless->pIf->modeData.wddm.KmtCallbacks.pfnD3DKMTEscape(&EscapeData); 2039 if (NT_SUCCESS(Status)) 2040 return ERROR_SUCCESS; 2041 2042 WARN(("VBoxTray: pfnD3DKMTEscape Seamless failed Status 0x%x\n", Status)); 2043 return Status; 2044 } 2045 2046 DWORD VBoxDispIfSeamlesCreate(PCVBOXDISPIF const pIf, VBOXDISPIF_SEAMLESS *pSeamless, HANDLE hEvent) 2047 { 2048 memset(pSeamless, 0, sizeof (*pSeamless)); 2049 pSeamless->pIf = pIf; 2050 2051 switch (pIf->enmMode) 2052 { 2053 case VBOXDISPIF_MODE_XPDM_NT4: 2054 case VBOXDISPIF_MODE_XPDM: 2055 return NO_ERROR; 2056 #ifdef VBOX_WITH_WDDM 2057 case VBOXDISPIF_MODE_WDDM: 2058 case VBOXDISPIF_MODE_WDDM_W7: 2059 return vboxDispIfSeamlesCreateWDDM(pIf, pSeamless, hEvent); 2060 #endif 2061 default: 2062 WARN(("VBoxTray: VBoxDispIfSeamlesCreate: invalid mode %d\n", pIf->enmMode)); 2063 return ERROR_INVALID_PARAMETER; 2064 } 2065 } 2066 2067 DWORD VBoxDispIfSeamlesTerm(VBOXDISPIF_SEAMLESS *pSeamless) 2068 { 2069 PCVBOXDISPIF const pIf = pSeamless->pIf; 2070 DWORD winEr; 2071 switch (pIf->enmMode) 2072 { 2073 case VBOXDISPIF_MODE_XPDM_NT4: 2074 case VBOXDISPIF_MODE_XPDM: 2075 winEr = NO_ERROR; 2076 break; 2077 #ifdef VBOX_WITH_WDDM 2078 case VBOXDISPIF_MODE_WDDM: 2079 case VBOXDISPIF_MODE_WDDM_W7: 2080 winEr = vboxDispIfSeamlesTermWDDM(pSeamless); 2081 break; 2082 #endif 2083 default: 2084 WARN(("VBoxTray: VBoxDispIfSeamlesTerm: invalid mode %d\n", pIf->enmMode)); 2085 winEr = ERROR_INVALID_PARAMETER; 2086 break; 2087 } 2088 2089 if (winEr == NO_ERROR) 2090 memset(pSeamless, 0, sizeof (*pSeamless)); 2091 2092 return winEr; 2093 } 2094 2095 DWORD VBoxDispIfSeamlesSubmit(VBOXDISPIF_SEAMLESS *pSeamless, VBOXDISPIFESCAPE *pData, int cbData) 2096 { 2097 PCVBOXDISPIF const pIf = pSeamless->pIf; 2098 2099 if (pData->escapeCode != VBOXESC_SETVISIBLEREGION) 2100 { 2101 WARN(("VBoxTray: invalid escape code for Seamless submit %d\n", pData->escapeCode)); 2102 return ERROR_INVALID_PARAMETER; 2103 } 2104 2105 switch (pIf->enmMode) 2106 { 2107 case VBOXDISPIF_MODE_XPDM_NT4: 2108 case VBOXDISPIF_MODE_XPDM: 2109 return VBoxDispIfEscape(pIf, pData, cbData); 2110 #ifdef VBOX_WITH_WDDM 2111 case VBOXDISPIF_MODE_WDDM: 2112 case VBOXDISPIF_MODE_WDDM_W7: 2113 return vboxDispIfSeamlesSubmitWDDM(pSeamless, pData, cbData); 2114 #endif 2115 default: 2116 WARN(("VBoxTray: VBoxDispIfSeamlesSubmit: invalid mode %d\n", pIf->enmMode)); 2117 return ERROR_INVALID_PARAMETER; 2118 } 2119 } -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDispIf.h
r44729 r48070 19 19 # define D3DKMDT_SPECIAL_MULTIPLATFORM_TOOL 20 20 # include <d3dkmthk.h> 21 # include "../Graphics/Video/disp/wddm/VBoxDispKmt.h" 21 22 #endif 22 23 … … 30 31 #ifdef VBOX_WITH_WDDM 31 32 , VBOXDISPIF_MODE_WDDM 33 , VBOXDISPIF_MODE_WDDM_W7 32 34 #endif 33 35 } VBOXDISPIF_MODE; … … 59 61 BOOL (WINAPI * pfnEnumDisplayDevices)(IN LPCSTR lpDevice, IN DWORD iDevNum, OUT PDISPLAY_DEVICEA lpDisplayDevice, IN DWORD dwFlags); 60 62 61 /* open adapter */ 62 PFND3DKMT_OPENADAPTERFROMHDC pfnD3DKMTOpenAdapterFromHdc; 63 PFND3DKMT_OPENADAPTERFROMGDIDISPLAYNAME pfnD3DKMTOpenAdapterFromGdiDisplayName; 64 /* close adapter */ 65 PFND3DKMT_CLOSEADAPTER pfnD3DKMTCloseAdapter; 66 /* escape */ 67 PFND3DKMT_ESCAPE pfnD3DKMTEscape; 68 /* auto resize support */ 69 PFND3DKMT_INVALIDATEACTIVEVIDPN pfnD3DKMTInvalidateActiveVidPn; 70 PFND3DKMT_POLLDISPLAYCHILDREN pfnD3DKMTPollDisplayChildren; 63 VBOXDISPKMT_CALLBACKS KmtCallbacks; 71 64 } wddm; 72 65 #endif … … 84 77 DWORD VBoxDispIfEscape(PCVBOXDISPIF const pIf, PVBOXDISPIFESCAPE pEscape, int cbData); 85 78 DWORD VBoxDispIfEscapeInOut(PCVBOXDISPIF const pIf, PVBOXDISPIFESCAPE pEscape, int cbData); 86 DWORD VBoxDispIfResize(PCVBOXDISPIF const pIf, ULONG Id, DWORD Width, DWORD Height, DWORD BitsPerPixel); 87 DWORD VBoxDispIfResizeModes(PCVBOXDISPIF const pIf, UINT iChangedMode, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes); 79 DWORD VBoxDispIfResizeModes(PCVBOXDISPIF const pIf, UINT iChangedMode, BOOL fEnable, BOOL fExtDispSup, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes); 88 80 DWORD VBoxDispIfCancelPendingResize(PCVBOXDISPIF const pIf); 89 DWORD vboxDispIfWddmEnableDisplay(PCVBOXDISPIF const pIf, UINT Id, bool fEnabled); 90 DWORD vboxDispIfWddmResizeDisplay(PCVBOXDISPIF const pIf, UINT Id, DISPLAY_DEVICE * paDisplayDevices, DEVMODE *paDeviceMode, UINT devModes); 91 //DWORD VBoxDispIfReninitModes(PCVBOXDISPIF const pIf, uint8_t *pScreenIdMask, BOOL fReconnectDisplaysOnChange); 81 82 DWORD VBoxDispIfResizeStarted(PCVBOXDISPIF const pIf); 83 84 85 typedef struct VBOXDISPIF_SEAMLESS 86 { 87 PCVBOXDISPIF pIf; 88 89 union 90 { 91 #ifdef VBOX_WITH_WDDM 92 struct 93 { 94 VBOXDISPKMT_ADAPTER Adapter; 95 VBOXDISPKMT_DEVICE Device; 96 VBOXDISPKMT_CONTEXT Context; 97 } wddm; 98 #endif 99 } modeData; 100 } VBOXDISPIF_SEAMLESS; 101 102 DECLINLINE(bool) VBoxDispIfSeamlesIsValid(VBOXDISPIF_SEAMLESS *pSeamless) 103 { 104 return !!pSeamless->pIf; 105 } 106 107 DWORD VBoxDispIfSeamlesCreate(PCVBOXDISPIF const pIf, VBOXDISPIF_SEAMLESS *pSeamless, HANDLE hEvent); 108 DWORD VBoxDispIfSeamlesTerm(VBOXDISPIF_SEAMLESS *pSeamless); 109 DWORD VBoxDispIfSeamlesSubmit(VBOXDISPIF_SEAMLESS *pSeamless, VBOXDISPIFESCAPE *pData, int cbData); -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDisplay.cpp
r48030 r48070 90 90 Log(("VBoxTray: VBoxDisplayInit: WDDM driver is installed, switching display driver if to WDDM mode\n")); 91 91 /* this is hacky, but the most easiest way */ 92 DWORD err = VBoxDispIfSwitchMode(const_cast<PVBOXDISPIF>(&pEnv->dispIf), VBOXDISPIF_MODE_WDDM, NULL /* old mode, we don't care about it */); 92 VBOXDISPIF_MODE enmMode = (OSinfo.dwMajorVersion > 6 || OSinfo.dwMinorVersion > 0) ? VBOXDISPIF_MODE_WDDM_W7 : VBOXDISPIF_MODE_WDDM; 93 DWORD err = VBoxDispIfSwitchMode(const_cast<PVBOXDISPIF>(&pEnv->dispIf), enmMode, NULL /* old mode, we don't care about it */); 93 94 if (err == NO_ERROR) 94 95 Log(("VBoxTray: VBoxDisplayInit: DispIf switched to WDDM mode successfully\n")); … … 213 214 } 214 215 215 staticDWORD EnableAndResizeDispDev(DEVMODE *paDeviceModes, DISPLAY_DEVICE *paDisplayDevices, DWORD totalDispNum, UINT Id, DWORD aWidth, DWORD aHeight,216 DWORD aBitsPerPixel, DWORD aPosX, DWORD aPosY, BOOL fEnabled, BOOL fExtDispSup , VBOXDISPLAYCONTEXT *pCtx)216 DWORD EnableAndResizeDispDev(DEVMODE *paDeviceModes, DISPLAY_DEVICE *paDisplayDevices, DWORD totalDispNum, UINT Id, DWORD aWidth, DWORD aHeight, 217 DWORD aBitsPerPixel, DWORD aPosX, DWORD aPosY, BOOL fEnabled, BOOL fExtDispSup) 217 218 { 218 219 DISPLAY_DEVICE displayDeviceTmp; … … 307 308 } 308 309 return dwStatus; 309 } 310 311 /* Returns TRUE to try again. */ 312 static BOOL ResizeDisplayDevice(UINT Id, DWORD Width, DWORD Height, DWORD BitsPerPixel, 313 BOOL fEnabled, DWORD dwNewPosX, DWORD dwNewPosY, 314 VBOXDISPLAYCONTEXT *pCtx, BOOL fExtDispSup) 310 } 311 312 DWORD VBoxGetDisplayConfigCount() 315 313 { 316 BOOL fDispAlreadyEnabled = false; /* check whether the monitor with ID is already enabled. */317 BOOL fModeReset = (Width == 0 && Height == 0 && BitsPerPixel == 0 &&318 dwNewPosX == 0 && dwNewPosY == 0);319 BOOL fChangePosRequest = false; /* change in position requested */320 321 Log(("VBoxTray: ResizeDisplayDevice Width= %d, Height=%d , PosX=%d and PosY=%d \322 fEnabled = %d, fExtDisSup = %d\n",323 Width, Height, dwNewPosX, dwNewPosY, fEnabled, fExtDispSup));324 325 if (!gCtx.fAnyX)326 Width &= 0xFFF8;327 328 314 DISPLAY_DEVICE DisplayDevice; 329 DWORD dwStatus;330 315 331 316 ZeroMemory(&DisplayDevice, sizeof(DISPLAY_DEVICE)); 332 317 DisplayDevice.cb = sizeof(DISPLAY_DEVICE); 333 334 VBoxDispIfCancelPendingResize(&pCtx->pEnv->dispIf);335 318 336 319 /* Find out how many display devices the system has */ … … 358 341 } 359 342 360 Log(("VBoxTray: ResizeDisplayDevice: Found total %d devices. err %d\n", NumDevices, GetLastError ())); 361 362 if (NumDevices == 0 || Id >= NumDevices) 363 { 364 Log(("VBoxTray: ResizeDisplayDevice: Requested identifier %d is invalid. err %d\n", Id, GetLastError ())); 365 return FALSE; 366 } 367 368 DISPLAY_DEVICE *paDisplayDevices = (DISPLAY_DEVICE *)alloca (sizeof (DISPLAY_DEVICE) * NumDevices); 369 DEVMODE *paDeviceModes = (DEVMODE *)alloca (sizeof (DEVMODE) * NumDevices); 370 RECTL *paRects = (RECTL *)alloca (sizeof (RECTL) * NumDevices); 371 343 return NumDevices; 344 } 345 346 DWORD VBoxGetDisplayConfig(const DWORD NumDevices, DWORD *pDevPrimaryNum, DWORD *pNumDevices, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes) 347 { 372 348 /* Fetch information about current devices and modes. */ 373 349 DWORD DevNum = 0; 374 350 DWORD DevPrimaryNum = 0; 375 351 352 DISPLAY_DEVICE DisplayDevice; 353 376 354 ZeroMemory(&DisplayDevice, sizeof(DISPLAY_DEVICE)); 377 355 DisplayDevice.cb = sizeof(DISPLAY_DEVICE); 378 356 379 i = 0;357 DWORD i = 0; 380 358 while (EnumDisplayDevices (NULL, i, &DisplayDevice, 0)) 381 359 { … … 401 379 if (DevNum >= NumDevices) 402 380 { 403 Log(("VBoxTray: ResizeDisplayDevice: %d >= %d\n", NumDevices, DevNum));404 return FALSE;381 WARN(("VBoxTray: ResizeDisplayDevice: %d >= %d\n", NumDevices, DevNum)); 382 return ERROR_BUFFER_OVERFLOW; 405 383 } 406 384 … … 438 416 } 439 417 440 if (fExtDispSup) 441 { 442 LogRel(("VBoxTray: Extended Display Support.\n")); 443 Log(("VBoxTray: ResizeDisplayDevice1: %dx%dx%d at %d,%d . Id = %d and DevNum=%d, fEnabled=%d\n", 444 paDeviceModes[Id].dmPelsWidth, 445 paDeviceModes[Id].dmPelsHeight, 446 paDeviceModes[Id].dmBitsPerPel, 447 paDeviceModes[Id].dmPosition.x, 448 paDeviceModes[Id].dmPosition.y, 449 Id, DevNum, fEnabled)); 450 if ((DevNum == Id && fEnabled == 1)) 451 { 452 /* Calculation of new position for enabled 453 * secondary monitor . 454 */ 455 /* Used when a secondary monitor just needs to be enabled, without any 456 * change in its position 457 */ 458 if (dwNewPosX != 0) 459 { 460 LogRel(("VBoxTray: Setting Rectangle position x=%d*y=%d\n", dwNewPosX, dwNewPosY)); 461 paDeviceModes[DevNum].dmPosition.x = dwNewPosX; 462 paDeviceModes[DevNum].dmPosition.y = dwNewPosY; 463 fChangePosRequest = true; 464 } 465 paRects[DevNum].left = paDeviceModes[DevNum].dmPosition.x; 466 paRects[DevNum].top = paDeviceModes[DevNum].dmPosition.y; 467 paRects[DevNum].right = paDeviceModes[DevNum].dmPosition.x + paDeviceModes[DevNum].dmPelsWidth; 468 paRects[DevNum].bottom = paDeviceModes[DevNum].dmPosition.y + paDeviceModes[DevNum].dmPelsHeight; 469 } 470 else 471 { 472 paRects[DevNum].left = paDeviceModes[DevNum].dmPosition.x; 473 paRects[DevNum].top = paDeviceModes[DevNum].dmPosition.y; 474 paRects[DevNum].right = paDeviceModes[DevNum].dmPosition.x + paDeviceModes[DevNum].dmPelsWidth; 475 paRects[DevNum].bottom = paDeviceModes[DevNum].dmPosition.y + paDeviceModes[DevNum].dmPelsHeight; 476 } 477 } 478 else 479 { 480 LogRel(("VBoxTray: NO Ext Display Support \n")); 481 paRects[DevNum].left = paDeviceModes[DevNum].dmPosition.x; 482 paRects[DevNum].top = paDeviceModes[DevNum].dmPosition.y; 483 paRects[DevNum].right = paDeviceModes[DevNum].dmPosition.x + paDeviceModes[DevNum].dmPelsWidth; 484 paRects[DevNum].bottom = paDeviceModes[DevNum].dmPosition.y + paDeviceModes[DevNum].dmPelsHeight; 485 } 418 486 419 DevNum++; 487 420 } … … 491 424 i++; 492 425 } 426 427 *pNumDevices = DevNum; 428 429 return NO_ERROR; 430 } 431 432 /* Returns TRUE to try again. */ 433 static BOOL ResizeDisplayDevice(UINT Id, DWORD Width, DWORD Height, DWORD BitsPerPixel, 434 BOOL fEnabled, DWORD dwNewPosX, DWORD dwNewPosY, 435 VBOXDISPLAYCONTEXT *pCtx, BOOL fExtDispSup) 436 { 437 BOOL fDispAlreadyEnabled = false; /* check whether the monitor with ID is already enabled. */ 438 BOOL fModeReset = (Width == 0 && Height == 0 && BitsPerPixel == 0 && 439 dwNewPosX == 0 && dwNewPosY == 0); 440 DWORD dmFields = 0; 441 442 Log(("VBoxTray: ResizeDisplayDevice Width= %d, Height=%d , PosX=%d and PosY=%d \ 443 fEnabled = %d, fExtDisSup = %d\n", 444 Width, Height, dwNewPosX, dwNewPosY, fEnabled, fExtDispSup)); 445 446 if (!gCtx.fAnyX) 447 Width &= 0xFFF8; 448 449 VBoxDispIfCancelPendingResize(&pCtx->pEnv->dispIf); 450 451 DWORD NumDevices = VBoxGetDisplayConfigCount(); 452 453 if (NumDevices == 0 || Id >= NumDevices) 454 { 455 WARN(("VBoxTray: ResizeDisplayDevice: Requested identifier %d is invalid. err %d\n", Id, GetLastError ())); 456 return FALSE; 457 } 458 459 Log(("VBoxTray: ResizeDisplayDevice: Found total %d devices. err %d\n", NumDevices, GetLastError ())); 460 461 DISPLAY_DEVICE *paDisplayDevices = (DISPLAY_DEVICE *)alloca (sizeof (DISPLAY_DEVICE) * NumDevices); 462 DEVMODE *paDeviceModes = (DEVMODE *)alloca (sizeof (DEVMODE) * NumDevices); 463 RECTL *paRects = (RECTL *)alloca (sizeof (RECTL) * NumDevices); 464 DWORD DevNum = 0; 465 DWORD DevPrimaryNum = 0; 466 DWORD dwStatus = VBoxGetDisplayConfig(NumDevices, &DevPrimaryNum, &DevNum, paDisplayDevices, paDeviceModes); 467 if (dwStatus != NO_ERROR) 468 { 469 WARN(("VBoxTray: ResizeDisplayDevice: VBoxGetDisplayConfig failed, %d\n", dwStatus)); 470 return dwStatus; 471 } 472 473 if (NumDevices != DevNum) 474 WARN(("VBoxTray: ResizeDisplayDevice: NumDevices(%d) != DevNum(%d)\n", NumDevices, DevNum)); 475 476 DWORD i = 0; 477 478 for (i = 0; i < DevNum; ++i) 479 { 480 if (fExtDispSup) 481 { 482 LogRel(("VBoxTray: Extended Display Support.\n")); 483 Log(("VBoxTray: ResizeDisplayDevice1: %dx%dx%d at %d,%d . Id = %d and DevNum=%d, fEnabled=%d\n", 484 paDeviceModes[Id].dmPelsWidth, 485 paDeviceModes[Id].dmPelsHeight, 486 paDeviceModes[Id].dmBitsPerPel, 487 paDeviceModes[Id].dmPosition.x, 488 paDeviceModes[Id].dmPosition.y, 489 Id, DevNum, fEnabled)); 490 } 491 else 492 { 493 LogRel(("VBoxTray: NO Ext Display Support \n")); 494 } 495 496 paRects[i].left = paDeviceModes[i].dmPosition.x; 497 paRects[i].top = paDeviceModes[i].dmPosition.y; 498 paRects[i].right = paDeviceModes[i].dmPosition.x + paDeviceModes[i].dmPelsWidth; 499 paRects[i].bottom = paDeviceModes[i].dmPosition.y + paDeviceModes[i].dmPelsHeight; 500 } 501 493 502 /* Keep a record if the display with ID is already active or not. */ 494 503 if (paDisplayDevices[Id].StateFlags & DISPLAY_DEVICE_ACTIVE) … … 504 513 */ 505 514 if (Width == 0) 506 {507 515 Width = paRects[Id].right - paRects[Id].left; 508 } 516 else 517 dmFields |= DM_PELSWIDTH; 509 518 510 519 if (Height == 0) 511 {512 520 Height = paRects[Id].bottom - paRects[Id].top; 513 } 521 else 522 dmFields |= DM_PELSHEIGHT; 523 524 if (BitsPerPixel == 0) 525 BitsPerPixel = paDeviceModes[Id].dmBitsPerPel; 526 else 527 dmFields |= DM_BITSPERPEL; 528 529 if (!dwNewPosX && !dwNewPosY) 530 { 531 /* @fixme: zero position is a valid state, so another values should be used as a special case !!! */ 532 dwNewPosX = paRects[Id].left; 533 dwNewPosY = paRects[Id].top; 534 } 535 else 536 dmFields |= DM_POSITION; 514 537 515 538 /* Check whether a mode reset or a change is requested. … … 529 552 * all rect conditions are true. Thus in this case nothing has to be done. 530 553 */ 531 if ( !fModeReset && fEnabled && fDispAlreadyEnabled && !fChangePosRequest 554 if ( !fModeReset && (!fEnabled == !fDispAlreadyEnabled) 555 && paRects[Id].left == dwNewPosX 556 && paRects[Id].top == dwNewPosY 532 557 && paRects[Id].right - paRects[Id].left == Width 533 558 && paRects[Id].bottom - paRects[Id].top == Height … … 538 563 } 539 564 540 hlpResizeRect(paRects, NumDevices, DevPrimaryNum, Id, Width, Height); 565 hlpResizeRect(paRects, NumDevices, DevPrimaryNum, Id, 566 fEnabled ? Width : 0, fEnabled ? Height : 0, dwNewPosX, dwNewPosY); 541 567 #ifdef Log 542 568 for (i = 0; i < NumDevices; i++) … … 561 587 paDeviceModes[i].dmPelsHeight = paRects[i].bottom - paRects[i].top; 562 588 589 if (i == Id) 590 paDeviceModes[i].dmBitsPerPel = BitsPerPixel; 591 592 paDeviceModes[i].dmFields |= dmFields; 593 563 594 /* On Vista one must specify DM_BITSPERPEL. 564 595 * Note that the current mode dmBitsPerPel is already in the DEVMODE structure. 565 596 */ 566 paDeviceModes[i].dmFields = DM_PELSHEIGHT | DM_PELSWIDTH | DM_BITSPERPEL; 567 568 if (i == Id && BitsPerPixel != 0) 597 if (!(paDeviceModes[i].dmFields & DM_BITSPERPEL)) 569 598 { 570 LogRel(("VBoxTray: (WDDM)Changing resolution and position. \n")); 571 /* Change dmBitsPerPel if requested. */ 572 paDeviceModes[i].dmBitsPerPel = BitsPerPixel; 573 paDeviceModes[i].dmPelsWidth = Width; 574 paDeviceModes[i].dmPelsHeight = Height; 575 if (dwNewPosX != 0 || dwNewPosY != 0) 576 { 577 paDeviceModes[Id].dmPosition.x = dwNewPosX; 578 paDeviceModes[Id].dmPosition.y = dwNewPosY; 579 } 580 else 581 { 582 paDeviceModes[i].dmFields |= DM_POSITION; 583 paDeviceModes[Id].dmPosition.x = 0; 584 paDeviceModes[Id].dmPosition.y = 0; 585 } 599 WARN(("VBoxTray: (WDDM) no DM_BITSPERPEL\n")); 600 paDeviceModes[i].dmFields |= DM_BITSPERPEL; 601 paDeviceModes[i].dmBitsPerPel = 32; 586 602 } 587 603 … … 593 609 paDeviceModes[i].dmPosition.x, 594 610 paDeviceModes[i].dmPosition.y)); 595 596 } 597 /* Reques to enable /disable the secondary Display Device. Won't take the resize request now.*/ 598 if (!fDispAlreadyEnabled && fEnabled || fDispAlreadyEnabled && !fEnabled) 599 { 600 OSVERSIONINFO OSinfo; 601 OSinfo.dwOSVersionInfoSize = sizeof (OSinfo); 602 GetVersionEx (&OSinfo); 603 604 /* for win 7 and above */ 605 if (OSinfo.dwMajorVersion >= 6 && OSinfo.dwMinorVersion >= 1) 606 { 607 LogRel(("VBoxTray: (WDDM) Request to enable/disable %d display device\n", fEnabled)); 608 DWORD dwStatus = vboxDispIfWddmEnableDisplay(&pCtx->pEnv->dispIf, Id, RT_BOOL(fEnabled)); 609 if(dwStatus != ERROR_SUCCESS) 610 { 611 /* Not going to retry for enabling or disabling of the secondary display device.*/ 612 LogRel(("VBoxTray: (WDDM) Failed to enable the Display Device \n")); 613 } 614 } 615 else /* case: vista in wddm mode. SetDisplayConfig APIs etc is not avilable in this mode. */ 616 { 617 /* use traditional approach of ChangeDisplaySettingEx to enable/disable secondary monitor for Vista WDDM mode.*/ 618 dwStatus = EnableAndResizeDispDev(paDeviceModes, paDisplayDevices, DevNum, Id, Width, Height, BitsPerPixel, 619 dwNewPosX, dwNewPosY, fEnabled, fExtDispSup, pCtx); 620 if (dwStatus != DISP_CHANGE_SUCCESSFUL ) 621 { 622 /* Successfully set new video mode or our driver can not set 623 * the requested mode. Stop trying. 624 */ 625 LogRel(("VBoxTray: (WDDM) Failed to enable/disable the Display Device \n")); 626 } 627 } 628 return FALSE; /* for enable disable not retrying */ 629 } 630 else 631 { 632 /* Resize request. Secondary display device should be in an enabled state. */ 633 LogRel(("VBoxTray: (WDDM) Request to resize the display \n")); 634 DWORD err = VBoxDispIfResizeModes(&pCtx->pEnv->dispIf, Id, paDisplayDevices, paDeviceModes, NumDevices); 635 if (err == NO_ERROR || err != ERROR_RETRY) 636 { 637 if (err == NO_ERROR) 638 LogRel(("VBoxTray: VBoxDisplayThread: (WDDM) VBoxDispIfResizeModes succeeded\n")); 639 else 640 LogRel(("VBoxTray: VBoxDisplayThread: (WDDM) Failure VBoxDispIfResizeModes (%d)\n", err)); 641 return FALSE; 642 } 643 } 611 } 612 613 Log(("VBoxTray: (WDDM) Request to resize the displa\n")); 614 DWORD err = VBoxDispIfResizeModes(&pCtx->pEnv->dispIf, Id, fEnabled, fExtDispSup, paDisplayDevices, paDeviceModes, DevNum); 615 if (err == NO_ERROR || err != ERROR_RETRY) 616 { 617 if (err == NO_ERROR) 618 Log(("VBoxTray: VBoxDisplayThread: (WDDM) VBoxDispIfResizeModes succeeded\n")); 619 else 620 WARN(("VBoxTray: VBoxDisplayThread: (WDDM) Failure VBoxDispIfResizeModes (%d)\n", err)); 621 return FALSE; 622 } 623 644 624 Log(("VBoxTray: ResizeDisplayDevice: (WDDM) RETRY requested\n")); 645 625 return TRUE; … … 695 675 Id, Width, Height, dwNewPosX, dwNewPosY, fEnabled, fExtDispSup)); 696 676 dwStatus = EnableAndResizeDispDev(paDeviceModes, paDisplayDevices, DevNum, Id, Width, Height, BitsPerPixel, 697 dwNewPosX, dwNewPosY, fEnabled, fExtDispSup , pCtx);677 dwNewPosX, dwNewPosY, fEnabled, fExtDispSup); 698 678 if (dwStatus == DISP_CHANGE_SUCCESSFUL || dwStatus == DISP_CHANGE_BADMODE) 699 679 { … … 730 710 731 711 PostMessage(ghwndToolWindow, WM_VBOX_GRAPHICS_SUPPORTED, 0, 0); 712 713 VBoxDispIfResizeStarted(&pCtx->pEnv->dispIf); 732 714 733 715 do … … 979 961 if (waitEvent.u32EventFlagsOut & VMMDEV_EVENT_MOUSE_CAPABILITIES_CHANGED) 980 962 hlpReloadCursor(); 981 } else 963 } 964 else 982 965 { 983 966 Log(("VBoxTray: VBoxDisplayThread: error 0 from DeviceIoControl VBOXGUEST_IOCTL_WAITEVENT\n")); -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDisplay.h
r44528 r48070 23 23 void VBoxDisplayDestroy (const VBOXSERVICEENV *pEnv, void *pInstance); 24 24 25 DWORD VBoxGetDisplayConfigCount(); 26 DWORD VBoxGetDisplayConfig(const DWORD NumDevices, DWORD *pDevPrimaryNum, DWORD *pNumDevices, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes); 27 25 28 #ifndef VBOX_WITH_WDDM 26 29 static bool isVBoxDisplayDriverActive (void); -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxHelpers.cpp
r35907 r48070 112 112 113 113 void hlpResizeRect(RECTL *paRects, unsigned nRects, unsigned uPrimary, 114 unsigned uResized, int iNewWidth, int iNewHeight) 114 unsigned uResized, int iNewWidth, int iNewHeight, 115 int iNewPosX, int iNewPosY) 115 116 { 116 117 DDCLOG(("nRects %d, iPrimary %d, iResized %d, NewWidth %d, NewHeight %d\n", nRects, uPrimary, uResized, iNewWidth, iNewHeight)); … … 120 121 paNewRects[uResized].right += iNewWidth - (paNewRects[uResized].right - paNewRects[uResized].left); 121 122 paNewRects[uResized].bottom += iNewHeight - (paNewRects[uResized].bottom - paNewRects[uResized].top); 123 paNewRects[uResized].right += iNewPosX - paNewRects[uResized].left; 124 paNewRects[uResized].bottom += iNewPosY - paNewRects[uResized].top; 125 paNewRects[uResized].left = iNewPosX; 126 paNewRects[uResized].top = iNewPosY; 122 127 123 128 /* Verify all pairs of originally adjacent rectangles for all 4 directions. -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxHelpers.h
r44528 r48070 29 29 extern int hlpReportStatus(VBoxGuestFacilityStatus statusCurrent); 30 30 extern void hlpReloadCursor(void); 31 extern void hlpResizeRect(RECTL *paRects, unsigned nRects, unsigned uPrimary, unsigned uResized, int iNewWidth, int iNewHeight );31 extern void hlpResizeRect(RECTL *paRects, unsigned nRects, unsigned uPrimary, unsigned uResized, int iNewWidth, int iNewHeight, int iNewPosX, int iNewPosY); 32 32 extern int hlpShowBalloonTip(HINSTANCE hInst, HWND hWnd, UINT uID, const char *pszMsg, const char *pszTitle, UINT uTimeout, DWORD dwInfoFlags); 33 33 -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxSeamless.cpp
r46593 r48070 116 116 } 117 117 118 void VBoxSeamlessInstallHook()118 static void VBoxSeamlessInstallHook() 119 119 { 120 120 if (gCtx.pfnVBoxHookInstallWindowTracker) 121 121 { 122 122 /* Check current visible region state */ 123 VBoxSeamlessCheckWindows( );123 VBoxSeamlessCheckWindows(true); 124 124 125 125 HMODULE hMod = (HMODULE)RTLdrGetNativeHandle(gCtx.hModHook); … … 129 129 } 130 130 131 void VBoxSeamlessRemoveHook()131 static void VBoxSeamlessRemoveHook() 132 132 { 133 133 if (gCtx.pfnVBoxHookRemoveWindowTracker) … … 139 139 gCtx.lpEscapeData = NULL; 140 140 } 141 } 142 143 extern HANDLE ghSeamlessKmNotifyEvent; 144 145 static VBOXDISPIF_SEAMLESS gVBoxDispIfSeamless; 146 147 148 void VBoxSeamlessEnable() 149 { 150 Assert(ghSeamlessKmNotifyEvent); 151 152 VBoxDispIfSeamlesCreate(&gCtx.pEnv->dispIf, &gVBoxDispIfSeamless, ghSeamlessKmNotifyEvent); 153 154 VBoxSeamlessInstallHook(); 155 } 156 157 void VBoxSeamlessDisable() 158 { 159 VBoxSeamlessRemoveHook(); 160 161 VBoxDispIfSeamlesTerm(&gVBoxDispIfSeamless); 141 162 } 142 163 … … 245 266 } 246 267 247 void VBoxSeamlessCheckWindows() 248 { 268 void VBoxSeamlessCheckWindows(bool fForce) 269 { 270 if (!VBoxDispIfSeamlesIsValid(&gVBoxDispIfSeamless)) 271 return; 272 249 273 VBOX_ENUM_PARAM param; 250 274 … … 280 304 #endif 281 305 LPRGNDATA lpCtxRgnData = VBOXDISPIFESCAPE_DATA(gCtx.lpEscapeData, RGNDATA); 282 if ( !gCtx.lpEscapeData 306 if (fForce 307 || !gCtx.lpEscapeData 283 308 || (lpCtxRgnData->rdh.dwSize + lpCtxRgnData->rdh.nRgnSize != cbSize) 284 309 || memcmp(lpCtxRgnData, lpRgnData, cbSize)) 285 310 { 286 311 /* send to display driver */ 287 VBoxDispIf Escape(&gCtx.pEnv->dispIf, lpEscapeData, cbSize);312 VBoxDispIfSeamlesSubmit(&gVBoxDispIfSeamless, lpEscapeData, cbSize); 288 313 289 314 if (gCtx.lpEscapeData) -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxSeamless.h
r45760 r48070 24 24 25 25 26 void VBoxSeamless InstallHook();27 void VBoxSeamless RemoveHook();28 void VBoxSeamlessCheckWindows( );26 void VBoxSeamlessEnable(); 27 void VBoxSeamlessDisable(); 28 void VBoxSeamlessCheckWindows(bool fForce); 29 29 30 30 void VBoxSeamlessSetSupported(BOOL fSupported); -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxTray.cpp
r47195 r48070 46 46 #include <Wtsapi32.h> 47 47 48 #ifdef DEBUG_misha49 #define WARN(_m) do { \50 Assert(0); \51 Log(_m); \52 } while (0)53 #else54 #define WARN(_m) do { \55 Log(_m); \56 } while (0)57 #endif58 59 48 /* 60 49 * St (session [state] tracking) functionality API … … 136 125 HANDLE ghStopSem; 137 126 HANDLE ghSeamlessWtNotifyEvent = 0; 127 HANDLE ghSeamlessKmNotifyEvent = 0; 138 128 SERVICE_STATUS gVBoxServiceStatus; 139 129 SERVICE_STATUS_HANDLE gVBoxServiceStatusHandle; … … 629 619 Log(("VBoxTray: CreateEvent for Seamless failed, last error = %08X\n", dwErr)); 630 620 } 621 622 ghSeamlessKmNotifyEvent = CreateEvent(NULL, FALSE, FALSE, NULL); 623 if (ghSeamlessKmNotifyEvent == NULL) 624 { 625 dwErr = GetLastError(); 626 Log(("VBoxTray: CreateEvent for Seamless failed, last error = %08X\n", dwErr)); 627 } 631 628 } 632 629 } … … 640 637 CloseHandle(ghSeamlessWtNotifyEvent); 641 638 ghSeamlessWtNotifyEvent = NULL; 639 } 640 641 if (ghSeamlessKmNotifyEvent) 642 { 643 CloseHandle(ghSeamlessKmNotifyEvent); 644 ghSeamlessKmNotifyEvent = NULL; 642 645 } 643 646 } … … 725 728 */ 726 729 727 HANDLE hWaitEvent[ 3] = {0};730 HANDLE hWaitEvent[4] = {0}; 728 731 DWORD dwEventCount = 0; 729 732 … … 734 737 { 735 738 hWaitEvent[dwEventCount++] = ghSeamlessWtNotifyEvent; 739 } 740 741 if (0 != ghSeamlessKmNotifyEvent) 742 { 743 hWaitEvent[dwEventCount++] = ghSeamlessKmNotifyEvent; 736 744 } 737 745 … … 768 776 769 777 /* seamless window notification */ 770 VBoxSeamlessCheckWindows(); 778 VBoxSeamlessCheckWindows(false); 779 fHandled = TRUE; 780 } 781 else if (hWaitEvent[waitResult] == ghSeamlessKmNotifyEvent) 782 { 783 Log(("VBoxTray: Event 'Km Seamless' triggered\n")); 784 785 /* seamless window notification */ 786 VBoxSeamlessCheckWindows(true); 771 787 fHandled = TRUE; 772 788 } … … 988 1004 case WM_VBOX_SEAMLESS_UPDATE: 989 1005 if (VBoxCapsEntryIsEnabled(VBOXCAPS_ENTRY_IDX_SEAMLESS)) 990 VBoxSeamlessCheckWindows( );1006 VBoxSeamlessCheckWindows(true); 991 1007 return 0; 992 1008 … … 1297 1313 if (GetVersionEx(&info)) 1298 1314 { 1299 WARN(("VBoxTray: Windows version %ld.%ld\n", info.dwMajorVersion, info.dwMinorVersion));1315 LogRel(("VBoxTray: Windows version %ld.%ld\n", info.dwMajorVersion, info.dwMinorVersion)); 1300 1316 gMajorVersion = info.dwMajorVersion; 1301 1317 } … … 1507 1523 Assert(pCap->enmAcState == VBOXCAPS_ENTRY_ACSTATE_ACQUIRED); 1508 1524 Assert(pCap->enmFuncState == VBOXCAPS_ENTRY_FUNCSTATE_STARTED); 1509 VBoxSeamless InstallHook();1525 VBoxSeamlessEnable(); 1510 1526 } 1511 1527 else … … 1513 1529 Log(("VBoxTray: vboxCapsOnEnableSeamles: DISABLED\n")); 1514 1530 Assert(pCap->enmAcState != VBOXCAPS_ENTRY_ACSTATE_ACQUIRED || pCap->enmFuncState != VBOXCAPS_ENTRY_FUNCSTATE_STARTED); 1515 VBoxSeamless RemoveHook();1531 VBoxSeamlessDisable(); 1516 1532 } 1517 1533 } -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxTray.h
r47195 r48070 54 54 55 55 #include "VBoxDispIf.h" 56 57 #ifdef DEBUG_misha 58 #define WARN(_m) do { \ 59 Assert(0); \ 60 Log(_m); \ 61 } while (0) 62 #else 63 #define WARN(_m) do { \ 64 Log(_m); \ 65 } while (0) 66 #endif 56 67 57 68 /* -
trunk/src/VBox/Additions/WINNT/include/VBoxDisplay.h
r46966 r48070 38 38 # define VBOXESC_ADJUSTVIDEOMODES 0xABCD9011 39 39 # define VBOXESC_SETCTXHOSTID 0xABCD9012 40 # define VBOXESC_CONFIGURETARGETS 0xABCD9013 40 41 #endif /* #ifdef VBOX_WITH_WDDM */ 41 42 -
trunk/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp
r44876 r48070 1507 1507 } 1508 1508 1509 if ( pView->u32VBVAOffset == HGSMIOFFSET_VOID 1510 || pView->screen.u32LineSize == 0) /* Earlier broken saved states. */ 1509 if (pView->u32VBVAOffset == HGSMIOFFSET_VOID) 1511 1510 { 1512 1511 pView->pVBVA = NULL; … … 1845 1844 int64_t offEnd = (int64_t)pScreen->u32Height * pScreen->u32LineSize 1846 1845 + pScreen->u32Width + pScreen->u32StartOffset; 1847 LogRel FlowFunc(("VBVA_INFO_SCREEN: [%d] @%d,%d %dx%d, line 0x%x, BPP %d, flags 0x%x\n",1846 LogRel(("VBVA_INFO_SCREEN: [%d] @%d,%d %dx%d, line 0x%x, BPP %d, flags 0x%x\n", 1848 1847 pScreen->u32ViewIndex, pScreen->i32OriginX, pScreen->i32OriginY, 1849 1848 pScreen->u32Width, pScreen->u32Height, -
trunk/src/VBox/Devices/VMMDev/VMMDev.cpp
r47450 r48070 2993 2993 if (!fSameResolution) 2994 2994 { 2995 LogRel(("VMMDev::SetVideoModeHint: got a video mode hint (%dx%dx%d) at %d\n", cx, cy, cBits, idxDisplay)); 2995 LogRel(("VMMDev::SetVideoModeHint: got a video mode hint (%dx%dx%d)@(%dx%d),(%d;%d) at %d\n", 2996 cx, cy, cBits, xOrigin, yOrigin, fEnabled, fChangeOrigin, idxDisplay)); 2996 2997 2997 2998 /* we could validate the information here but hey, the guest can do that as well! */
Note:
See TracChangeset
for help on using the changeset viewer.