VirtualBox

Ignore:
Timestamp:
Aug 26, 2013 6:13:22 PM (12 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
88439
Message:

wddm,vboxtray: forward-port autoresize, multimon, and seamless fixes from 4.2 r87071, r87353, r87356, r87528, r87568, r87581, r87584, r87608, r87673, r87678, r87708, r87629, r87529; additional fixes

Location:
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/common
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPCommon.h

    r44529 r48070  
    4242
    4343#ifdef VBOX_WDDM_MINIPORT
    44 void VBoxWddmInvalidateAllVideoModesInfos(PVBOXMP_DEVEXT pExt);
    45 void VBoxWddmInvalidateVideoModesInfo(PVBOXMP_DEVEXT pExt, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId);
    4644PVBOXWDDM_VIDEOMODES_INFO VBoxWddmUpdateVideoModesInfoByMask(PVBOXMP_DEVEXT pExt, uint8_t *pScreenIdMask);
    47 PVBOXWDDM_VIDEOMODES_INFO VBoxWddmUpdateAllVideoModesInfos(PVBOXMP_DEVEXT pExt);
     45void VBoxWddmInitVideoModes(PVBOXMP_DEVEXT pExt);
    4846NTSTATUS VBoxWddmGetModesForResolution(VIDEO_MODE_INFORMATION *pAllModes, uint32_t cAllModes, int iSearchPreferredMode,
    4947                                       const D3DKMDT_2DREGION *pResolution, VIDEO_MODE_INFORMATION * pModes,
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPDevExt.h

    r47070 r48070  
    100100
    101101   VBOXVIDEOCM_MGR CmMgr;
     102   VBOXVIDEOCM_MGR SeamlessCtxMgr;
    102103   /* hgsmi allocation manager */
    103104   VBOXVIDEOCM_ALLOC_MGR AllocMgr;
     
    110111   volatile uint32_t cContexts3D;
    111112   volatile uint32_t cContexts2D;
     113   volatile uint32_t cContextsDispIfResize;
    112114   volatile uint32_t cRenderFromShadowDisabledContexts;
    113115   volatile uint32_t cUnlockedVBVADisabled;
     116
     117   DWORD dwDrvCfgFlags;
    114118   /* this is examined and swicthed by DxgkDdiSubmitCommand only! */
    115119   volatile BOOLEAN fRenderToShadowDisabled;
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPVidModes.cpp

    r46876 r48070  
    900900#ifdef VBOX_WDDM_MINIPORT
    901901static VBOXWDDM_VIDEOMODES_INFO g_aVBoxVideoModeInfos[VBOX_VIDEO_MAX_SCREENS] = {0};
     902static VBOXWDDM_VIDEOMODES_INFO g_VBoxVideoModeTmp;
    902903
    903904bool VBoxWddmFillMode(PVBOXMP_DEVEXT pExt, uint32_t iDisplay, VIDEO_MODE_INFORMATION *pInfo, D3DDDIFORMAT enmFormat, ULONG w, ULONG h)
     
    954955
    955956    *piPreferredResolution = -1;
     957    *pcResolutions = 0;
    956958
    957959    for (uint32_t i=0; i<tableSize; ++i)
     
    10031005    Assert(pModes->aResolutions[pModes->iPreferredResolution].cx == pModes->aModes[pModes->iPreferredMode].VisScreenWidth
    10041006            && pModes->aResolutions[pModes->iPreferredResolution].cy == pModes->aModes[pModes->iPreferredMode].VisScreenHeight);
     1007    Assert(pModes->cModes >= pModes->cResolutions);
    10051008}
    10061009
     
    12251228}
    12261229
    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;
     1230static void VBoxWddmInitVideoMode(PVBOXMP_DEVEXT pExt, int i)
     1231{
     1232    VBoxWddmBuildVideoModesInfo(pExt, (D3DDDI_VIDEO_PRESENT_TARGET_ID)i, &g_aVBoxVideoModeInfos[i], NULL, 0);
     1233}
     1234
     1235void VBoxWddmInitVideoModes(PVBOXMP_DEVEXT pExt)
     1236{
     1237    for (int i = 0; i < VBoxCommonFromDeviceExt(pExt)->cDisplays; ++i)
     1238    {
     1239        VBoxWddmInitVideoMode(pExt, i);
     1240    }
     1241}
     1242
     1243static 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
     1313static 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
     1347typedef struct VBOXWDDMCHILDSTATUSCB
     1348{
     1349    PVBOXVDMACBUF_DR pDr;
     1350    PKEVENT pEvent;
     1351} VBOXWDDMCHILDSTATUSCB, *PVBOXWDDMCHILDSTATUSCB;
     1352
     1353static 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
     1374static 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
     1447NTSTATUS 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
     1467void 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)))
    12381476        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);
    12521488}
    12531489
     
    12561492    for (int i = 0; i < VBoxCommonFromDeviceExt(pExt)->cDisplays; ++i)
    12571493    {
    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
    12731500    return g_aVBoxVideoModeInfos;
    12741501}
     
    13641591}
    13651592
    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 
    14021593PVBOXWDDM_VIDEOMODES_INFO VBoxWddmGetAllVideoModesInfos(PVBOXMP_DEVEXT pExt)
    14031594{
    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 
    14101595    return g_aVBoxVideoModeInfos;
    14111596}
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette