VirtualBox

Ignore:
Timestamp:
Jul 22, 2014 7:36:45 PM (10 years ago)
Author:
vboxsync
Message:

wddm: autoresize enhancements

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/VBox

  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVidPn.cpp

    r51960 r52136  
    119119}
    120120
    121 NTSTATUS vboxVidPnCheckSourceModeInfo(const D3DKMDT_HVIDPN hDesiredVidPn,
    122         const D3DKMDT_VIDPN_SOURCE_MODE *pNewVidPnSourceModeInfo,
    123         BOOLEAN *pbSupported)
    124 {
    125     BOOLEAN bSupported = TRUE;
    126     /* we support both GRAPHICS and TEXT modes */
    127     switch (pNewVidPnSourceModeInfo->Type)
    128     {
    129         case D3DKMDT_RMT_GRAPHICS:
    130             /* any primary surface size actually
    131             pNewVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cx
    132             pNewVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cy
    133             */
    134             if (pNewVidPnSourceModeInfo->Format.Graphics.VisibleRegionSize.cx != pNewVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cx
    135                     || pNewVidPnSourceModeInfo->Format.Graphics.VisibleRegionSize.cy != pNewVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cy)
    136             {
    137                 LOG(("VisibleRegionSize(%d, %d) !=  PrimSurfSize(%d, %d)",
    138                         pNewVidPnSourceModeInfo->Format.Graphics.VisibleRegionSize.cx,
    139                         pNewVidPnSourceModeInfo->Format.Graphics.VisibleRegionSize.cy,
    140                         pNewVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cx,
    141                         pNewVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cy));
    142                 AssertBreakpoint();
    143                 bSupported = FALSE;
    144                 break;
    145             }
    146 
    147             /*
    148             pNewVidPnSourceModeInfo->Format.Graphics.Stride
    149             pNewVidPnSourceModeInfo->Format.Graphics.PixelFormat
    150             pNewVidPnSourceModeInfo->Format.Graphics.ColorBasis
    151             pNewVidPnSourceModeInfo->Format.Graphics.PixelValueAccessMode
    152             */
    153 
    154             break;
    155         case D3DKMDT_RMT_TEXT:
    156             break;
    157         default:
    158             AssertBreakpoint();
    159             LOG(("Warning: Unknown Src mode Type (%d)", pNewVidPnSourceModeInfo->Type));
    160             break;
    161     }
    162 
    163     *pbSupported = bSupported;
    164     return STATUS_SUCCESS;
    165 }
    166 
    167 NTSTATUS vboxVidPnCheckSourceModeSet(const D3DKMDT_HVIDPN hDesiredVidPn,
    168         D3DKMDT_HVIDPNSOURCEMODESET hNewVidPnSourceModeSet, const DXGK_VIDPNSOURCEMODESET_INTERFACE *pVidPnSourceModeSetInterface,
    169         BOOLEAN *pbSupported)
    170 {
    171     const D3DKMDT_VIDPN_SOURCE_MODE *pNewVidPnSourceModeInfo;
    172     NTSTATUS Status = pVidPnSourceModeSetInterface->pfnAcquireFirstModeInfo(hNewVidPnSourceModeSet, &pNewVidPnSourceModeInfo);
    173     BOOLEAN bSupported = TRUE;
    174     if (Status == STATUS_SUCCESS)
    175     {
    176         while (1)
    177         {
    178             Status = vboxVidPnCheckSourceModeInfo(hDesiredVidPn, pNewVidPnSourceModeInfo, &bSupported);
    179             if (Status == STATUS_SUCCESS && bSupported)
    180             {
    181                 const D3DKMDT_VIDPN_SOURCE_MODE *pNextVidPnSourceModeInfo;
    182                 Status = pVidPnSourceModeSetInterface->pfnAcquireNextModeInfo(hNewVidPnSourceModeSet, pNewVidPnSourceModeInfo, &pNextVidPnSourceModeInfo);
    183                 pVidPnSourceModeSetInterface->pfnReleaseModeInfo(hNewVidPnSourceModeSet, pNewVidPnSourceModeInfo);
    184                 if (Status == STATUS_SUCCESS)
    185                 {
    186                     pNewVidPnSourceModeInfo = pNextVidPnSourceModeInfo;
    187                 }
    188                 else if (Status == STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET)
    189                 {
    190                     Status = STATUS_SUCCESS;
    191                     break;
    192                 }
    193                 else
    194                 {
    195                     LOGREL(("pfnAcquireNextModeInfo Failed Status(0x%x)", Status));
    196                     break;
    197                 }
    198             }
    199             else
    200             {
    201                 pVidPnSourceModeSetInterface->pfnReleaseModeInfo(hNewVidPnSourceModeSet, pNewVidPnSourceModeInfo);
    202                 break;
    203             }
    204         }
    205     }
    206     else if (Status == STATUS_GRAPHICS_DATASET_IS_EMPTY)
    207         Status = STATUS_SUCCESS;
    208     else
    209         LOGREL(("pfnAcquireFirstModeInfo failed Status(0x%x)", Status));
    210 
    211     *pbSupported = bSupported;
    212     return Status;
    213 }
    214 
    215 NTSTATUS vboxVidPnPopulateVideoSignalInfo(D3DKMDT_VIDEO_SIGNAL_INFO *pVsi,
    216         D3DKMDT_2DREGION *pResolution,
     121static NTSTATUS vboxVidPnPopulateVideoSignalInfo(D3DKMDT_VIDEO_SIGNAL_INFO *pVsi,
     122        const RTRECTSIZE *pResolution,
    217123        ULONG VSync)
    218124{
     
    220126
    221127    pVsi->VideoStandard  = D3DKMDT_VSS_OTHER;
    222     pVsi->ActiveSize = *pResolution;
     128    pVsi->ActiveSize.cx = pResolution->cx;
     129    pVsi->ActiveSize.cy = pResolution->cy;
    223130    pVsi->VSyncFreq.Numerator = VSync * 1000;
    224131    pVsi->VSyncFreq.Denominator = 1000;
     
    261168}
    262169
    263 NTSTATUS vboxVidPnCheckTargetModeInfo(const D3DKMDT_HVIDPN hDesiredVidPn,
    264         const D3DKMDT_VIDPN_TARGET_MODE *pNewVidPnTargetModeInfo,
    265         BOOLEAN *pbSupported)
    266 {
    267     BOOLEAN bSupported = TRUE;
    268     D3DKMDT_VIDEO_SIGNAL_INFO CmpVsi;
    269     D3DKMDT_2DREGION CmpRes;
    270     CmpRes.cx = pNewVidPnTargetModeInfo->VideoSignalInfo.ActiveSize.cx;
    271     CmpRes.cy = pNewVidPnTargetModeInfo->VideoSignalInfo.ActiveSize.cy;
    272     NTSTATUS Status = vboxVidPnPopulateVideoSignalInfo(&CmpVsi,
    273                 &CmpRes,
    274                 pNewVidPnTargetModeInfo->VideoSignalInfo.VSyncFreq.Numerator/pNewVidPnTargetModeInfo->VideoSignalInfo.VSyncFreq.Denominator);
    275     Assert(Status == STATUS_SUCCESS);
    276     if (Status != STATUS_SUCCESS)
    277     {
    278         LOGREL(("vboxVidPnPopulateVideoSignalInfo error Status (0x%x)", Status));
    279         return Status;
    280     }
    281 
    282     if (!vboxVidPnMatchVideoSignal(&CmpVsi, &pNewVidPnTargetModeInfo->VideoSignalInfo))
    283     {
    284         WARN(("VideoSignalInfos do not match!!!"));
    285         AssertBreakpoint();
    286         bSupported = FALSE;
    287     }
    288 
    289     *pbSupported = bSupported;
    290     return STATUS_SUCCESS;
    291 }
    292 
    293 NTSTATUS vboxVidPnCheckTargetModeSet(const D3DKMDT_HVIDPN hDesiredVidPn,
    294         D3DKMDT_HVIDPNTARGETMODESET hNewVidPnTargetModeSet, const DXGK_VIDPNTARGETMODESET_INTERFACE *pVidPnTargetModeSetInterface,
    295         BOOLEAN *pbSupported)
    296 {
    297     const D3DKMDT_VIDPN_TARGET_MODE *pNewVidPnTargetModeInfo;
    298     NTSTATUS Status = pVidPnTargetModeSetInterface->pfnAcquireFirstModeInfo(hNewVidPnTargetModeSet, &pNewVidPnTargetModeInfo);
    299     BOOLEAN bSupported = TRUE;
    300     if (Status == STATUS_SUCCESS)
    301     {
    302         Assert(pNewVidPnTargetModeInfo);
    303         while (1)
    304         {
    305             Status = vboxVidPnCheckTargetModeInfo(hDesiredVidPn, pNewVidPnTargetModeInfo, &bSupported);
    306             if (Status == STATUS_SUCCESS && bSupported)
    307             {
    308                 const D3DKMDT_VIDPN_TARGET_MODE *pNextVidPnTargetModeInfo;
    309                 Status = pVidPnTargetModeSetInterface->pfnAcquireNextModeInfo(hNewVidPnTargetModeSet, pNewVidPnTargetModeInfo, &pNextVidPnTargetModeInfo);
    310                 pVidPnTargetModeSetInterface->pfnReleaseModeInfo(hNewVidPnTargetModeSet, pNewVidPnTargetModeInfo);
    311                 if (Status == STATUS_SUCCESS)
    312                 {
    313                     pNewVidPnTargetModeInfo = pNextVidPnTargetModeInfo;
    314                 }
    315                 else if (Status == STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET)
    316                 {
    317                     Status = STATUS_SUCCESS;
    318                     break;
    319                 }
    320                 else
    321                 {
    322                     LOGREL(("pfnAcquireNextModeInfo Failed Status(0x%x)", Status));
    323                     break;
    324                 }
    325             }
    326             else
    327             {
    328                 pVidPnTargetModeSetInterface->pfnReleaseModeInfo(hNewVidPnTargetModeSet, pNewVidPnTargetModeInfo);
    329                 break;
    330             }
    331         }
    332     }
    333     else if (Status == STATUS_GRAPHICS_DATASET_IS_EMPTY)
    334         Status = STATUS_SUCCESS;
     170static void vboxVidPnPopulateSourceModeInfo(D3DKMDT_VIDPN_SOURCE_MODE *pNewVidPnSourceModeInfo,
     171        const RTRECTSIZE *pSize)
     172{
     173    NTSTATUS Status = STATUS_SUCCESS;
     174    /* this is a graphics mode */
     175    pNewVidPnSourceModeInfo->Type = D3DKMDT_RMT_GRAPHICS;
     176    pNewVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cx = pSize->cx;
     177    pNewVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cy = pSize->cy;
     178    pNewVidPnSourceModeInfo->Format.Graphics.VisibleRegionSize = pNewVidPnSourceModeInfo->Format.Graphics.PrimSurfSize;
     179    pNewVidPnSourceModeInfo->Format.Graphics.Stride = pSize->cx * 4;
     180    pNewVidPnSourceModeInfo->Format.Graphics.PixelFormat = D3DDDIFMT_A8R8G8B8;
     181    Assert(pNewVidPnSourceModeInfo->Format.Graphics.PixelFormat != D3DDDIFMT_UNKNOWN);
     182    pNewVidPnSourceModeInfo->Format.Graphics.ColorBasis = D3DKMDT_CB_SRGB;
     183    if (pNewVidPnSourceModeInfo->Format.Graphics.PixelFormat == D3DDDIFMT_P8)
     184        pNewVidPnSourceModeInfo->Format.Graphics.PixelValueAccessMode = D3DKMDT_PVAM_SETTABLEPALETTE;
    335185    else
    336         LOGREL(("pfnAcquireFirstModeInfo failed Status(0x%x)", Status));
    337 
    338     *pbSupported = bSupported;
    339     return Status;
    340 }
    341 
    342 NTSTATUS vboxVidPnPopulateSourceModeInfoFromLegacy(D3DKMDT_VIDPN_SOURCE_MODE *pNewVidPnSourceModeInfo,
    343         VIDEO_MODE_INFORMATION *pMode)
    344 {
    345     NTSTATUS Status = STATUS_SUCCESS;
    346     if (pMode->AttributeFlags & VIDEO_MODE_GRAPHICS)
    347     {
    348         /* this is a graphics mode */
    349         pNewVidPnSourceModeInfo->Type = D3DKMDT_RMT_GRAPHICS;
    350         pNewVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cx = pMode->VisScreenWidth;
    351         pNewVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cy = pMode->VisScreenHeight;
    352         pNewVidPnSourceModeInfo->Format.Graphics.VisibleRegionSize = pNewVidPnSourceModeInfo->Format.Graphics.PrimSurfSize;
    353         pNewVidPnSourceModeInfo->Format.Graphics.Stride = pMode->ScreenStride;
    354         pNewVidPnSourceModeInfo->Format.Graphics.PixelFormat = vboxWddmCalcPixelFormat(pMode);
    355         Assert(pNewVidPnSourceModeInfo->Format.Graphics.PixelFormat != D3DDDIFMT_UNKNOWN);
    356         if (pNewVidPnSourceModeInfo->Format.Graphics.PixelFormat != D3DDDIFMT_UNKNOWN)
    357         {
    358             pNewVidPnSourceModeInfo->Format.Graphics.ColorBasis = D3DKMDT_CB_SRGB;
    359             if (pNewVidPnSourceModeInfo->Format.Graphics.PixelFormat == D3DDDIFMT_P8)
    360                 pNewVidPnSourceModeInfo->Format.Graphics.PixelValueAccessMode = D3DKMDT_PVAM_SETTABLEPALETTE;
    361             else
    362                 pNewVidPnSourceModeInfo->Format.Graphics.PixelValueAccessMode = D3DKMDT_PVAM_DIRECT;
    363         }
    364         else
    365         {
    366             LOGREL(("vboxWddmCalcPixelFormat failed"));
    367             Status = STATUS_INVALID_PARAMETER;
    368         }
    369     }
    370     else
    371     {
    372         /* @todo: XPDM driver does not seem to return text modes, should we? */
    373         LOGREL(("text mode not supported currently"));
    374         AssertBreakpoint();
    375         Status = STATUS_INVALID_PARAMETER;
    376     }
    377 
    378     return Status;
    379 }
    380 
    381 NTSTATUS vboxVidPnPopulateMonitorSourceModeInfoFromLegacy(PVBOXMP_DEVEXT pDevExt,
    382         D3DKMDT_MONITOR_SOURCE_MODE *pMonitorSourceMode,
    383         D3DKMDT_2DREGION *pResolution,
    384         D3DKMDT_MONITOR_CAPABILITIES_ORIGIN enmOrigin,
    385         BOOLEAN bPreferred)
    386 {
    387     NTSTATUS Status = vboxVidPnPopulateVideoSignalInfo(&pMonitorSourceMode->VideoSignalInfo, pResolution, 60 /* ULONG VSync */);
    388     Assert(Status == STATUS_SUCCESS);
    389     if (Status == STATUS_SUCCESS)
    390     {
    391         pMonitorSourceMode->ColorBasis = D3DKMDT_CB_SRGB;
    392         pMonitorSourceMode->ColorCoeffDynamicRanges.FirstChannel = 8;
    393         pMonitorSourceMode->ColorCoeffDynamicRanges.SecondChannel = 8;
    394         pMonitorSourceMode->ColorCoeffDynamicRanges.ThirdChannel = 8;
    395         pMonitorSourceMode->ColorCoeffDynamicRanges.FourthChannel = 0;
    396         pMonitorSourceMode->Origin = enmOrigin;
    397         pMonitorSourceMode->Preference = bPreferred ? D3DKMDT_MP_PREFERRED : D3DKMDT_MP_NOTPREFERRED;
    398     }
    399 
    400     return Status;
    401 }
    402 
    403 NTSTATUS vboxVidPnCreatePopulateMonitorSourceModeInfoFromLegacy(PVBOXMP_DEVEXT pDevExt,
    404         CONST D3DKMDT_HMONITORSOURCEMODESET hMonitorSMS,
    405         CONST DXGK_MONITORSOURCEMODESET_INTERFACE *pMonitorSMSIf,
    406         D3DKMDT_2DREGION *pResolution,
    407         D3DKMDT_MONITOR_CAPABILITIES_ORIGIN enmOrigin,
    408         BOOLEAN bPreferred)
    409 {
    410     D3DKMDT_MONITOR_SOURCE_MODE * pMonitorSMI;
    411     NTSTATUS Status = pMonitorSMSIf->pfnCreateNewModeInfo(hMonitorSMS, &pMonitorSMI);
    412     Assert(Status == STATUS_SUCCESS);
    413     if (Status == STATUS_SUCCESS)
    414     {
    415         do
    416         {
    417             Status = vboxVidPnPopulateMonitorSourceModeInfoFromLegacy(pDevExt,
    418                     pMonitorSMI,
    419                     pResolution,
    420                     enmOrigin,
    421                     bPreferred);
    422             Assert(Status == STATUS_SUCCESS);
    423             if (Status == STATUS_SUCCESS)
    424             {
    425                 Status = pMonitorSMSIf->pfnAddMode(hMonitorSMS, pMonitorSMI);
    426                 Assert(Status == STATUS_SUCCESS/* || Status == STATUS_GRAPHICS_MODE_ALREADY_IN_MODESET*/);
    427                 if (Status == STATUS_SUCCESS)
    428                     break;
    429                 LOGREL(("pfnAddMode failed, Status(0x%x)", Status));
    430             }
    431             else
    432                 LOGREL(("vboxVidPnPopulateMonitorSourceModeInfoFromLegacy failed, Status(0x%x)", Status));
    433 
    434             Assert (Status != STATUS_SUCCESS);
    435             /* we're here because of a failure */
    436             NTSTATUS tmpStatus = pMonitorSMSIf->pfnReleaseModeInfo(hMonitorSMS, pMonitorSMI);
    437             Assert(tmpStatus == STATUS_SUCCESS);
    438             if (tmpStatus != STATUS_SUCCESS)
    439                 LOGREL(("pfnReleaseModeInfo failed tmpStatus(0x%x)", tmpStatus));
    440 
    441             if (Status == STATUS_GRAPHICS_MODE_ALREADY_IN_MODESET)
    442                 Status = STATUS_SUCCESS;
    443         } while (0);
    444     }
    445     else
    446         LOGREL(("pfnCreateNewModeInfo failed, Status(0x%x)", Status));
    447 
    448     return Status;
    449 }
    450 
    451 NTSTATUS vboxVidPnPopulateTargetModeInfoFromLegacy(D3DKMDT_VIDPN_TARGET_MODE *pNewVidPnTargetModeInfo, D3DKMDT_2DREGION *pResolution, BOOLEAN fPreferred)
    452 {
    453     pNewVidPnTargetModeInfo->Preference = fPreferred ? D3DKMDT_MP_PREFERRED : D3DKMDT_MP_NOTPREFERRED;
     186        pNewVidPnSourceModeInfo->Format.Graphics.PixelValueAccessMode = D3DKMDT_PVAM_DIRECT;
     187}
     188
     189static void vboxVidPnPopulateMonitorModeInfo(D3DKMDT_MONITOR_SOURCE_MODE *pMonitorSourceMode,
     190        const RTRECTSIZE *pResolution)
     191{
     192    vboxVidPnPopulateVideoSignalInfo(&pMonitorSourceMode->VideoSignalInfo, pResolution, 60 /* ULONG VSync */);
     193    pMonitorSourceMode->ColorBasis = D3DKMDT_CB_SRGB;
     194    pMonitorSourceMode->ColorCoeffDynamicRanges.FirstChannel = 8;
     195    pMonitorSourceMode->ColorCoeffDynamicRanges.SecondChannel = 8;
     196    pMonitorSourceMode->ColorCoeffDynamicRanges.ThirdChannel = 8;
     197    pMonitorSourceMode->ColorCoeffDynamicRanges.FourthChannel = 0;
     198    pMonitorSourceMode->Origin = D3DKMDT_MCO_DRIVER;
     199    pMonitorSourceMode->Preference = D3DKMDT_MP_NOTPREFERRED;
     200}
     201
     202static NTSTATUS vboxVidPnPopulateTargetModeInfo(D3DKMDT_VIDPN_TARGET_MODE *pNewVidPnTargetModeInfo, const RTRECTSIZE *pResolution)
     203{
     204    pNewVidPnTargetModeInfo->Preference = D3DKMDT_MP_NOTPREFERRED;
    454205    return vboxVidPnPopulateVideoSignalInfo(&pNewVidPnTargetModeInfo->VideoSignalInfo, pResolution, 60 /* ULONG VSync */);
    455206}
     
    598349}
    599350
    600 typedef struct VBOXVIDPNCHECKADDMONITORMODES
    601 {
     351
     352static D3DKMDT_ENUMCOFUNCMODALITY_PIVOT_TYPE vboxVidPnCofuncModalityCurrentPathPivot(D3DKMDT_ENUMCOFUNCMODALITY_PIVOT_TYPE enmPivot,
     353                    const DXGK_ENUM_PIVOT *pPivot,
     354                    D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
     355{
     356    switch (enmPivot)
     357    {
     358        case D3DKMDT_EPT_VIDPNSOURCE:
     359            if (pPivot->VidPnSourceId == VidPnSourceId)
     360                return D3DKMDT_EPT_VIDPNSOURCE;
     361            if (pPivot->VidPnSourceId == D3DDDI_ID_ALL)
     362            {
     363#ifdef DEBUG_misha
     364                AssertFailed();
     365#endif
     366                return D3DKMDT_EPT_VIDPNSOURCE;
     367            }
     368            return D3DKMDT_EPT_NOPIVOT;
     369        case D3DKMDT_EPT_VIDPNTARGET:
     370            if (pPivot->VidPnTargetId == VidPnTargetId)
     371                return D3DKMDT_EPT_VIDPNTARGET;
     372            if (pPivot->VidPnTargetId == D3DDDI_ID_ALL)
     373            {
     374#ifdef DEBUG_misha
     375                AssertFailed();
     376#endif
     377                return D3DKMDT_EPT_VIDPNTARGET;
     378            }
     379            return D3DKMDT_EPT_NOPIVOT;
     380        case D3DKMDT_EPT_SCALING:
     381        case D3DKMDT_EPT_ROTATION:
     382        case D3DKMDT_EPT_NOPIVOT:
     383            return D3DKMDT_EPT_NOPIVOT;
     384        default:
     385            WARN(("unexpected pivot"));
     386            return D3DKMDT_EPT_NOPIVOT;
     387    }
     388}
     389
     390NTSTATUS vboxVidPnQueryPinnedTargetMode(D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface,
     391        D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId, RTRECTSIZE *pSize)
     392{
     393    D3DKMDT_HVIDPNTARGETMODESET hCurVidPnTargetModeSet;
     394    const DXGK_VIDPNTARGETMODESET_INTERFACE *pCurVidPnTargetModeSetInterface;
     395    pSize->cx = 0;
     396    pSize->cy = 0;
     397    NTSTATUS Status = pVidPnInterface->pfnAcquireTargetModeSet(hVidPn,
     398                        VidPnTargetId,
     399                        &hCurVidPnTargetModeSet,
     400                        &pCurVidPnTargetModeSetInterface);
     401    if (!NT_SUCCESS(Status))
     402    {
     403        WARN(("pfnAcquireTargetModeSet failed Status(0x%x)", Status));
     404        return Status;
     405    }
     406
     407    CONST D3DKMDT_VIDPN_TARGET_MODE* pPinnedVidPnTargetModeInfo;
     408    Status = pCurVidPnTargetModeSetInterface->pfnAcquirePinnedModeInfo(hCurVidPnTargetModeSet, &pPinnedVidPnTargetModeInfo);
     409    if (Status == STATUS_GRAPHICS_MODE_NOT_PINNED)
     410    {
     411        pPinnedVidPnTargetModeInfo = NULL;
     412        Status = STATUS_SUCCESS;
     413    }
     414    else if (!NT_SUCCESS(Status))
     415    {
     416        WARN(("pfnAcquirePinnedModeInfo failed Status(0x%x)", Status));
     417    }
     418    else
     419    {
     420        Assert(pPinnedVidPnTargetModeInfo);
     421        pSize->cx = pPinnedVidPnTargetModeInfo->VideoSignalInfo.ActiveSize.cx;
     422        pSize->cy = pPinnedVidPnTargetModeInfo->VideoSignalInfo.ActiveSize.cy;
     423        NTSTATUS tmpStatus = pCurVidPnTargetModeSetInterface->pfnReleaseModeInfo(hCurVidPnTargetModeSet, pPinnedVidPnTargetModeInfo);
     424        Assert(NT_SUCCESS(tmpStatus));
     425    }
     426
     427    NTSTATUS tmpStatus = pVidPnInterface->pfnReleaseTargetModeSet(hVidPn, hCurVidPnTargetModeSet);
     428    Assert(tmpStatus == STATUS_SUCCESS);
     429
     430    return Status;
     431}
     432
     433NTSTATUS vboxVidPnQueryPinnedSourceMode(D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface,
     434        D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, RTRECTSIZE *pSize)
     435{
     436    D3DKMDT_HVIDPNSOURCEMODESET hCurVidPnSourceModeSet;
     437    const DXGK_VIDPNSOURCEMODESET_INTERFACE *pCurVidPnSourceModeSetInterface;
     438    pSize->cx = 0;
     439    pSize->cy = 0;
     440    NTSTATUS Status = pVidPnInterface->pfnAcquireSourceModeSet(hVidPn,
     441                        VidPnSourceId,
     442                        &hCurVidPnSourceModeSet,
     443                        &pCurVidPnSourceModeSetInterface);
     444    if (!NT_SUCCESS(Status))
     445    {
     446        WARN(("pfnAcquireSourceModeSet failed Status(0x%x)", Status));
     447        return Status;
     448    }
     449
     450    CONST D3DKMDT_VIDPN_SOURCE_MODE* pPinnedVidPnSourceModeInfo;
     451    Status = pCurVidPnSourceModeSetInterface->pfnAcquirePinnedModeInfo(hCurVidPnSourceModeSet, &pPinnedVidPnSourceModeInfo);
     452    if (Status == STATUS_GRAPHICS_MODE_NOT_PINNED)
     453    {
     454        pPinnedVidPnSourceModeInfo = NULL;
     455        Status = STATUS_SUCCESS;
     456    }
     457    else if (!NT_SUCCESS(Status))
     458    {
     459        WARN(("pfnAcquirePinnedModeInfo failed Status(0x%x)", Status));
     460    }
     461    else
     462    {
     463        Assert(pPinnedVidPnSourceModeInfo);
     464        pSize->cx = pPinnedVidPnSourceModeInfo->Format.Graphics.VisibleRegionSize.cx;
     465        pSize->cy = pPinnedVidPnSourceModeInfo->Format.Graphics.VisibleRegionSize.cy;
     466        NTSTATUS tmpStatus = pCurVidPnSourceModeSetInterface->pfnReleaseModeInfo(hCurVidPnSourceModeSet, pPinnedVidPnSourceModeInfo);
     467        Assert(NT_SUCCESS(tmpStatus));
     468    }
     469
     470    NTSTATUS tmpStatus = pVidPnInterface->pfnReleaseSourceModeSet(hVidPn, hCurVidPnSourceModeSet);
     471    Assert(tmpStatus == STATUS_SUCCESS);
     472
     473    return Status;
     474}
     475
     476static NTSTATUS vboxVidPnSourceModeSetToArray(D3DKMDT_HVIDPNSOURCEMODESET hVidPnModeSet,
     477                    const DXGK_VIDPNSOURCEMODESET_INTERFACE *pVidPnModeSetInterface,
     478                    CR_SORTARRAY *pArray)
     479{
     480    VBOXVIDPN_SOURCEMODE_ITER Iter;
     481    const D3DKMDT_VIDPN_SOURCE_MODE *pVidPnModeInfo;
     482
     483    VBoxVidPnSourceModeIterInit(&Iter, hVidPnModeSet, pVidPnModeSetInterface);
     484
     485    while ((pVidPnModeInfo = VBoxVidPnSourceModeIterNext(&Iter)) != NULL)
     486    {
     487        RTRECTSIZE size;
     488        size.cx = pVidPnModeInfo->Format.Graphics.VisibleRegionSize.cx;
     489        size.cy = pVidPnModeInfo->Format.Graphics.VisibleRegionSize.cy;
     490        int rc = CrSaAdd(pArray, CR_RSIZE2U64(size));
     491        if (RT_FAILURE(rc))
     492        {
     493            WARN(("CrSaAdd failed %d", rc));
     494            VBoxVidPnSourceModeIterTerm(&Iter);
     495            return STATUS_UNSUCCESSFUL;
     496        }
     497    }
     498
     499    VBoxVidPnSourceModeIterTerm(&Iter);
     500
     501    return VBoxVidPnSourceModeIterStatus(&Iter);
     502}
     503
     504static NTSTATUS vboxVidPnSourceModeSetFromArray(D3DKMDT_HVIDPNSOURCEMODESET hVidPnModeSet,
     505        const DXGK_VIDPNSOURCEMODESET_INTERFACE *pVidPnModeSetInterface,
     506        const CR_SORTARRAY *pArray)
     507{
     508    for (uint32_t i = 0; i < CrSaGetSize(pArray); ++i)
     509    {
     510        RTRECTSIZE size = CR_U642RSIZE(CrSaGetVal(pArray, i));
     511
     512        D3DKMDT_VIDPN_SOURCE_MODE *pVidPnModeInfo;
     513        NTSTATUS Status = pVidPnModeSetInterface->pfnCreateNewModeInfo(hVidPnModeSet, &pVidPnModeInfo);
     514        if (!NT_SUCCESS(Status))
     515        {
     516            WARN(("pfnCreateNewModeInfo failed, Status 0x%x", Status));
     517            return Status;
     518        }
     519
     520        vboxVidPnPopulateSourceModeInfo(pVidPnModeInfo, &size);
     521
     522        Status = pVidPnModeSetInterface->pfnAddMode(hVidPnModeSet, pVidPnModeInfo);
     523        if (!NT_SUCCESS(Status))
     524        {
     525            WARN(("pfnAddMode failed, Status 0x%x", Status));
     526            NTSTATUS tmpStatus = pVidPnModeSetInterface->pfnReleaseModeInfo(hVidPnModeSet, pVidPnModeInfo);
     527            Assert(tmpStatus == STATUS_SUCCESS);
     528            return Status;
     529        }
     530    }
     531
     532    return STATUS_SUCCESS;
     533}
     534
     535static NTSTATUS vboxVidPnTargetModeSetToArray(D3DKMDT_HVIDPNTARGETMODESET hVidPnModeSet,
     536                    const DXGK_VIDPNTARGETMODESET_INTERFACE *pVidPnModeSetInterface,
     537                    CR_SORTARRAY *pArray)
     538{
     539    VBOXVIDPN_TARGETMODE_ITER Iter;
     540    const D3DKMDT_VIDPN_TARGET_MODE *pVidPnModeInfo;
     541
     542    VBoxVidPnTargetModeIterInit(&Iter, hVidPnModeSet, pVidPnModeSetInterface);
     543
     544    while ((pVidPnModeInfo = VBoxVidPnTargetModeIterNext(&Iter)) != NULL)
     545    {
     546        RTRECTSIZE size;
     547        size.cx = pVidPnModeInfo->VideoSignalInfo.ActiveSize.cx;
     548        size.cy = pVidPnModeInfo->VideoSignalInfo.ActiveSize.cy;
     549        int rc = CrSaAdd(pArray, CR_RSIZE2U64(size));
     550        if (RT_FAILURE(rc))
     551        {
     552            WARN(("CrSaAdd failed %d", rc));
     553            VBoxVidPnTargetModeIterTerm(&Iter);
     554            return STATUS_UNSUCCESSFUL;
     555        }
     556    }
     557
     558    VBoxVidPnTargetModeIterTerm(&Iter);
     559
     560    return VBoxVidPnTargetModeIterStatus(&Iter);
     561}
     562
     563static NTSTATUS vboxVidPnTargetModeSetFromArray(D3DKMDT_HVIDPNTARGETMODESET hVidPnModeSet,
     564        const DXGK_VIDPNTARGETMODESET_INTERFACE *pVidPnModeSetInterface,
     565        const CR_SORTARRAY *pArray)
     566{
     567    for (uint32_t i = 0; i < CrSaGetSize(pArray); ++i)
     568    {
     569        RTRECTSIZE size = CR_U642RSIZE(CrSaGetVal(pArray, i));
     570
     571        D3DKMDT_VIDPN_TARGET_MODE *pVidPnModeInfo;
     572        NTSTATUS Status = pVidPnModeSetInterface->pfnCreateNewModeInfo(hVidPnModeSet, &pVidPnModeInfo);
     573        if (!NT_SUCCESS(Status))
     574        {
     575            WARN(("pfnCreateNewModeInfo failed, Status 0x%x", Status));
     576            return Status;
     577        }
     578
     579        vboxVidPnPopulateTargetModeInfo(pVidPnModeInfo, &size);
     580
     581        Status = pVidPnModeSetInterface->pfnAddMode(hVidPnModeSet, pVidPnModeInfo);
     582        if (!NT_SUCCESS(Status))
     583        {
     584            WARN(("pfnAddMode failed, Status 0x%x", Status));
     585            NTSTATUS tmpStatus = pVidPnModeSetInterface->pfnReleaseModeInfo(hVidPnModeSet, pVidPnModeInfo);
     586            Assert(tmpStatus == STATUS_SUCCESS);
     587            return Status;
     588        }
     589    }
     590
     591    return STATUS_SUCCESS;
     592}
     593
     594static NTSTATUS vboxVidPnMonitorModeSetToArray(D3DKMDT_HMONITORSOURCEMODESET hVidPnModeSet,
     595                    const DXGK_MONITORSOURCEMODESET_INTERFACE *pVidPnModeSetInterface,
     596                    CR_SORTARRAY *pArray)
     597{
     598    VBOXVIDPN_MONITORMODE_ITER Iter;
     599    const D3DKMDT_MONITOR_SOURCE_MODE *pVidPnModeInfo;
     600
     601    VBoxVidPnMonitorModeIterInit(&Iter, hVidPnModeSet, pVidPnModeSetInterface);
     602
     603    while ((pVidPnModeInfo = VBoxVidPnMonitorModeIterNext(&Iter)) != NULL)
     604    {
     605        RTRECTSIZE size;
     606        size.cx = pVidPnModeInfo->VideoSignalInfo.ActiveSize.cx;
     607        size.cy = pVidPnModeInfo->VideoSignalInfo.ActiveSize.cy;
     608        int rc = CrSaAdd(pArray, CR_RSIZE2U64(size));
     609        if (RT_FAILURE(rc))
     610        {
     611            WARN(("CrSaAdd failed %d", rc));
     612            VBoxVidPnMonitorModeIterTerm(&Iter);
     613            return STATUS_UNSUCCESSFUL;
     614        }
     615    }
     616
     617    VBoxVidPnMonitorModeIterTerm(&Iter);
     618
     619    return VBoxVidPnMonitorModeIterStatus(&Iter);
     620}
     621
     622static NTSTATUS vboxVidPnMonitorModeSetFromArray(D3DKMDT_HMONITORSOURCEMODESET hVidPnModeSet,
     623        const DXGK_MONITORSOURCEMODESET_INTERFACE *pVidPnModeSetInterface,
     624        const CR_SORTARRAY *pArray)
     625{
     626    for (uint32_t i = 0; i < CrSaGetSize(pArray); ++i)
     627    {
     628        RTRECTSIZE size = CR_U642RSIZE(CrSaGetVal(pArray, i));
     629
     630        D3DKMDT_MONITOR_SOURCE_MODE *pVidPnModeInfo;
     631        NTSTATUS Status = pVidPnModeSetInterface->pfnCreateNewModeInfo(hVidPnModeSet, &pVidPnModeInfo);
     632        if (!NT_SUCCESS(Status))
     633        {
     634            WARN(("pfnCreateNewModeInfo failed, Status 0x%x", Status));
     635            return Status;
     636        }
     637
     638        vboxVidPnPopulateMonitorModeInfo(pVidPnModeInfo, &size);
     639
     640        Status = pVidPnModeSetInterface->pfnAddMode(hVidPnModeSet, pVidPnModeInfo);
     641        if (!NT_SUCCESS(Status))
     642        {
     643            WARN(("pfnAddMode failed, Status 0x%x", Status));
     644            NTSTATUS tmpStatus = pVidPnModeSetInterface->pfnReleaseModeInfo(hVidPnModeSet, pVidPnModeInfo);
     645            Assert(tmpStatus == STATUS_SUCCESS);
     646            return Status;
     647        }
     648    }
     649
     650    return STATUS_SUCCESS;
     651}
     652
     653
     654static NTSTATUS vboxVidPnCollectInfoForPathTarget(PVBOXMP_DEVEXT pDevExt,
     655        D3DKMDT_HVIDPN hVidPn,
     656        const DXGK_VIDPN_INTERFACE* pVidPnInterface,
     657        D3DKMDT_ENUMCOFUNCMODALITY_PIVOT_TYPE enmCurPivot,
     658        uint32_t *aAdjustedModeMap,
     659        CR_SORTARRAY *aModes,
     660        D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
     661{
     662    const CR_SORTARRAY* pSupportedModes = VBoxWddmVModesGet(pDevExt, VidPnTargetId);
    602663    NTSTATUS Status;
    603     D3DKMDT_2DREGION *pResolutions;
    604     uint32_t cResolutions;
    605 } VBOXVIDPNCHECKADDMONITORMODES, *PVBOXVIDPNCHECKADDMONITORMODES;
    606 
    607 static DECLCALLBACK(BOOLEAN) vboxVidPnCheckAddMonitorModesEnum(PVBOXMP_DEVEXT pDevExt, D3DKMDT_HMONITORSOURCEMODESET hMonitorSMS, CONST DXGK_MONITORSOURCEMODESET_INTERFACE *pMonitorSMSIf,
    608         CONST D3DKMDT_MONITOR_SOURCE_MODE *pMonitorSMI, PVOID pContext)
    609 {
    610     PVBOXVIDPNCHECKADDMONITORMODES pData = (PVBOXVIDPNCHECKADDMONITORMODES)pContext;
    611     NTSTATUS Status = STATUS_SUCCESS;
    612 
    613     for (uint32_t i = 0; i < pData->cResolutions; ++i)
    614     {
    615         D3DKMDT_VIDPN_TARGET_MODE dummyMode = {0};
    616         Status = vboxVidPnPopulateTargetModeInfoFromLegacy(&dummyMode, &pData->pResolutions[i], FALSE /* preference does not matter for now */);
    617         Assert(Status == STATUS_SUCCESS);
    618         if (Status == STATUS_SUCCESS)
    619         {
    620             if (vboxVidPnMatchVideoSignal(&dummyMode.VideoSignalInfo, &pMonitorSMI->VideoSignalInfo))
    621             {
    622                 /* mark it as unneeded */
    623                 pData->pResolutions[i].cx = 0;
    624                 break;
    625             }
     664    if (enmCurPivot == D3DKMDT_EPT_VIDPNTARGET)
     665    {
     666        D3DKMDT_HVIDPNTARGETMODESET hVidPnModeSet;
     667        const DXGK_VIDPNTARGETMODESET_INTERFACE *pVidPnModeSetInterface;
     668        Status = pVidPnInterface->pfnAcquireTargetModeSet(hVidPn,
     669                    VidPnTargetId,
     670                    &hVidPnModeSet,
     671                    &pVidPnModeSetInterface);
     672        if (!NT_SUCCESS(Status))
     673        {
     674            WARN(("pfnAcquireTargetModeSet failed %#x", Status));
     675            return Status;
     676        }
     677
     678        /* intersect modes from target */
     679        if (!ASMBitTest(aAdjustedModeMap, VidPnTargetId))
     680        {
     681            Status = vboxVidPnTargetModeSetToArray(hVidPnModeSet, pVidPnModeSetInterface, &aModes[VidPnTargetId]);
     682            ASMBitSet(aAdjustedModeMap, VidPnTargetId);
    626683        }
    627684        else
    628685        {
    629             LOGREL(("vboxVidPnPopulateTargetModeInfoFromLegacy failed Status(0x%x)", Status));
    630             break;
    631         }
    632     }
    633 
    634     pMonitorSMSIf->pfnReleaseModeInfo(hMonitorSMS, pMonitorSMI);
    635 
    636     pData->Status = Status;
    637 
    638     return Status == STATUS_SUCCESS;
    639 }
    640 
    641 typedef struct VBOXVIDPNCHECKMONMODESENUM
    642 {
    643     D3DKMDT_2DREGION Region;
    644     const D3DKMDT_MONITOR_SOURCE_MODE * pMonitorSMI;
    645 } VBOXVIDPNCHECKMONMODESENUM, *PVBOXVIDPNCHECKMONMODESENUM;
    646 
    647 static DECLCALLBACK(BOOLEAN) vboxFidPnCheckMonitorModesEnum(D3DKMDT_HMONITORSOURCEMODESET hMonitorSMS, CONST DXGK_MONITORSOURCEMODESET_INTERFACE *pMonitorSMSIf,
    648         CONST D3DKMDT_MONITOR_SOURCE_MODE *pMonitorSMI, PVOID pContext)
    649 {
    650     PVBOXVIDPNCHECKMONMODESENUM pInfo = (PVBOXVIDPNCHECKMONMODESENUM)pContext;
    651     if (pMonitorSMI->VideoSignalInfo.ActiveSize.cx == pInfo->Region.cx
    652             && pMonitorSMI->VideoSignalInfo.ActiveSize.cy == pInfo->Region.cy)
    653     {
    654         Assert(!pInfo->pMonitorSMI);
    655         if (pInfo->pMonitorSMI)
    656         {
    657             pMonitorSMSIf->pfnReleaseModeInfo(hMonitorSMS, pInfo->pMonitorSMI);
    658         }
    659         pInfo->pMonitorSMI = pMonitorSMI;
     686            CR_SORTARRAY Arr;
     687            CrSaInit(&Arr, 0);
     688            Status = vboxVidPnTargetModeSetToArray(hVidPnModeSet, pVidPnModeSetInterface, &aModes[VidPnTargetId]);
     689            CrSaIntersect(&aModes[VidPnTargetId], &Arr);
     690            CrSaCleanup(&Arr);
     691        }
     692
     693        NTSTATUS tmpStatus = pVidPnInterface->pfnReleaseTargetModeSet(hVidPn, hVidPnModeSet);
     694        Assert(tmpStatus == STATUS_SUCCESS);
     695
     696        if (!NT_SUCCESS(Status))
     697        {
     698            WARN(("vboxVidPnTargetModeSetToArray failed %#x", Status));
     699            return Status;
     700        }
     701
     702        return STATUS_SUCCESS;
     703    }
     704
     705    RTRECTSIZE pinnedSize = {0};
     706    Status = vboxVidPnQueryPinnedTargetMode(hVidPn, pVidPnInterface, VidPnTargetId, &pinnedSize);
     707    if (!NT_SUCCESS(Status))
     708    {
     709        WARN(("vboxVidPnQueryPinnedTargetMode failed %#x", Status));
     710        return Status;
     711    }
     712
     713    if (pinnedSize.cx)
     714    {
     715        Assert(CrSaContains(pSupportedModes, CR_RSIZE2U64(pinnedSize)));
     716
     717        if (!ASMBitTest(aAdjustedModeMap, VidPnTargetId))
     718        {
     719            Assert(CrSaGetSize(&aModes[VidPnTargetId]) == 0);
     720            int rc = CrSaAdd(&aModes[VidPnTargetId], CR_RSIZE2U64(pinnedSize));
     721            if (!RT_SUCCESS(rc))
     722            {
     723                WARN(("CrSaAdd failed %d", rc));
     724                return STATUS_UNSUCCESSFUL;
     725            }
     726            ASMBitSet(aAdjustedModeMap, VidPnTargetId);
     727        }
     728        else
     729        {
     730            CrSaClear(&aModes[VidPnTargetId]);
     731            int rc = CrSaAdd(&aModes[VidPnTargetId], CR_RSIZE2U64(pinnedSize));
     732            if (!RT_SUCCESS(rc))
     733            {
     734                WARN(("CrSaAdd failed %d", rc));
     735                return STATUS_UNSUCCESSFUL;
     736            }
     737        }
     738
     739        return STATUS_SUCCESS;
     740    }
     741
     742
     743    Status = vboxVidPnQueryPinnedSourceMode(hVidPn, pVidPnInterface, VidPnSourceId, &pinnedSize);
     744    if (!NT_SUCCESS(Status))
     745    {
     746        WARN(("vboxVidPnQueryPinnedSourceMode failed %#x", Status));
     747        return Status;
     748    }
     749
     750    if (pinnedSize.cx)
     751    {
     752        if (!ASMBitTest(aAdjustedModeMap, VidPnTargetId))
     753        {
     754            Assert(CrSaGetSize(&aModes[VidPnTargetId]) == 0);
     755            if (CrSaContains(pSupportedModes, CR_RSIZE2U64(pinnedSize)))
     756            {
     757                int rc = CrSaAdd(&aModes[VidPnTargetId], CR_RSIZE2U64(pinnedSize));
     758                if (!RT_SUCCESS(rc))
     759                {
     760                    WARN(("CrSaAdd failed %d", rc));
     761                    return STATUS_UNSUCCESSFUL;
     762                }
     763            }
     764            ASMBitSet(aAdjustedModeMap, VidPnTargetId);
     765        }
     766        else
     767        {
     768            CrSaClear(&aModes[VidPnTargetId]);
     769            if (CrSaContains(pSupportedModes, CR_RSIZE2U64(pinnedSize)))
     770            {
     771                int rc = CrSaAdd(&aModes[VidPnTargetId], CR_RSIZE2U64(pinnedSize));
     772                if (!RT_SUCCESS(rc))
     773                {
     774                    WARN(("CrSaAdd failed %d", rc));
     775                    return STATUS_UNSUCCESSFUL;
     776                }
     777            }
     778        }
     779
     780        return STATUS_SUCCESS;
     781    }
     782
     783    /* now we are here because no pinned info is specified, we need to populate it based on the supported info
     784     * and modes already configured,
     785     * this is pretty simple actually */
     786
     787    if (!ASMBitTest(aAdjustedModeMap, VidPnTargetId))
     788    {
     789        Assert(CrSaGetSize(&aModes[VidPnTargetId]) == 0);
     790        int rc = CrSaClone(pSupportedModes, &aModes[VidPnTargetId]);
     791        if (!RT_SUCCESS(rc))
     792        {
     793            WARN(("CrSaClone failed %d", rc));
     794            return STATUS_UNSUCCESSFUL;
     795        }
     796        ASMBitSet(aAdjustedModeMap, VidPnTargetId);
    660797    }
    661798    else
    662799    {
    663         pMonitorSMSIf->pfnReleaseModeInfo(hMonitorSMS, pMonitorSMI);
    664     }
    665     return TRUE;
    666 }
    667 
    668 typedef struct VBOXVIDPNMATCHMONMODESENUM
    669 {
    670     D3DKMDT_2DREGION *paResolutions;
    671     uint32_t cResolutions;
    672     BOOLEAN fMatched;
    673 } VBOXVIDPNMATCHMONMODESENUM, *PVBOXVIDPNMATCHMONMODESENUM;
    674 
    675 static DECLCALLBACK(BOOLEAN) vboxFidPnMatchMonitorModesEnum(D3DKMDT_HMONITORSOURCEMODESET hMonitorSMS, CONST DXGK_MONITORSOURCEMODESET_INTERFACE *pMonitorSMSIf,
    676         CONST D3DKMDT_MONITOR_SOURCE_MODE *pMonitorSMI, PVOID pContext)
    677 {
    678     PVBOXVIDPNMATCHMONMODESENUM pInfo = (PVBOXVIDPNMATCHMONMODESENUM)pContext;
    679 
    680     Assert(pInfo->fMatched);
    681 
    682     BOOLEAN fFound = FALSE;
    683 
    684     for (UINT i = 0; i < pInfo->cResolutions; ++i)
    685     {
    686         D3DKMDT_2DREGION *pResolution = &pInfo->paResolutions[i];
    687         if (pMonitorSMI->VideoSignalInfo.ActiveSize.cx == pResolution->cx
    688                 && pMonitorSMI->VideoSignalInfo.ActiveSize.cy == pResolution->cy)
    689         {
    690             fFound = TRUE;
    691             break;
    692         }
    693     }
    694 
    695     if (!fFound)
    696         pInfo->fMatched = FALSE;
    697 
    698     if (!pInfo->fMatched)
    699         LOG(("Found non-matching mode (%d X %d)",
    700                 pMonitorSMI->VideoSignalInfo.ActiveSize.cx, pMonitorSMI->VideoSignalInfo.ActiveSize.cy));
    701 
    702     pMonitorSMSIf->pfnReleaseModeInfo(hMonitorSMS, pMonitorSMI);
    703 
    704     return pInfo->fMatched;
    705 }
    706 
    707 /* matches the monitor mode set for the given target id with the resolution set, and sets the pfMatch to true if they match, otherwise sets it to false */
    708 NTSTATUS vboxVidPnMatchMonitorModes(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_TARGET_ID targetId,
    709         D3DKMDT_2DREGION *pResolutions, uint32_t cResolutions, BOOLEAN *pfMatch)
    710 {
    711     *pfMatch = FALSE;
    712     CONST DXGK_MONITOR_INTERFACE *pMonitorInterface;
    713     NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbQueryMonitorInterface(pDevExt->u.primary.DxgkInterface.DeviceHandle, DXGK_MONITOR_INTERFACE_VERSION_V1, &pMonitorInterface);
    714     if (!NT_SUCCESS(Status))
    715     {
    716         WARN(("DxgkCbQueryMonitorInterface failed, Status (0x%x)", Status));
     800        CrSaIntersect(&aModes[VidPnTargetId], pSupportedModes);
     801    }
     802
     803    /* we are done */
     804    return STATUS_SUCCESS;
     805}
     806
     807static NTSTATUS vboxVidPnApplyInfoForPathTarget(PVBOXMP_DEVEXT pDevExt,
     808        D3DKMDT_HVIDPN hVidPn,
     809        const DXGK_VIDPN_INTERFACE* pVidPnInterface,
     810        D3DKMDT_ENUMCOFUNCMODALITY_PIVOT_TYPE enmCurPivot,
     811        uint32_t *aAdjustedModeMap,
     812        const CR_SORTARRAY *aModes,
     813        D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
     814{
     815    Assert(ASMBitTest(aAdjustedModeMap, VidPnTargetId));
     816
     817    if (enmCurPivot == D3DKMDT_EPT_VIDPNTARGET)
     818        return STATUS_SUCCESS;
     819
     820    RTRECTSIZE pinnedSize = {0};
     821    NTSTATUS Status = vboxVidPnQueryPinnedTargetMode(hVidPn, pVidPnInterface, VidPnTargetId, &pinnedSize);
     822    if (!NT_SUCCESS(Status))
     823    {
     824        WARN(("vboxVidPnQueryPinnedTargetMode failed %#x", Status));
    717825        return Status;
    718826    }
    719827
    720     D3DKMDT_HMONITORSOURCEMODESET hMonitorSMS;
    721     CONST DXGK_MONITORSOURCEMODESET_INTERFACE *pMonitorSMSIf;
    722     Status = pMonitorInterface->pfnAcquireMonitorSourceModeSet(pDevExt->u.primary.DxgkInterface.DeviceHandle,
    723                                         targetId,
    724                                         &hMonitorSMS,
    725                                         &pMonitorSMSIf);
    726     if (!NT_SUCCESS(Status))
    727     {
    728         WARN(("pfnAcquireMonitorSourceModeSet failed, Status (0x%x)", Status));
    729         if (Status == STATUS_GRAPHICS_MONITOR_NOT_CONNECTED)
    730         {
    731             /* this is ok in case we replug the monitor to pick up the monitor modes properly,
    732              * so pretend success  */
    733             *pfMatch = TRUE;
    734             Status = STATUS_SUCCESS;
    735         }
     828    if (pinnedSize.cx)
     829        return STATUS_SUCCESS;
     830
     831    /* now just create the new source mode set and apply it */
     832    D3DKMDT_HVIDPNTARGETMODESET hVidPnModeSet;
     833    const DXGK_VIDPNTARGETMODESET_INTERFACE *pVidPnModeSetInterface;
     834    Status = pVidPnInterface->pfnCreateNewTargetModeSet(hVidPn,
     835                        VidPnTargetId,
     836                        &hVidPnModeSet,
     837                        &pVidPnModeSetInterface);
     838    if (!NT_SUCCESS(Status))
     839    {
     840        WARN(("pfnCreateNewTargetModeSet failed Status(0x%x)", Status));
    736841        return Status;
    737842    }
    738843
    739     /* we care only about monitor modes covering all needed resolutions,
    740      * we do NOT care if resolutions do not cover some monitor modes */
    741     SIZE_T cModes = 0;
    742     Status = pMonitorSMSIf->pfnGetNumModes(hMonitorSMS, &cModes);
    743     if (NT_SUCCESS(Status))
    744     {
    745         if (cModes < cResolutions)
    746         {
    747             *pfMatch = FALSE;
    748             LOG(("num modes(%d) and resolutions(%d) do not match, treat as not matched..", cModes, cResolutions));
     844    Status = vboxVidPnTargetModeSetFromArray(hVidPnModeSet,
     845            pVidPnModeSetInterface,
     846            &aModes[VidPnTargetId]);
     847    if (!NT_SUCCESS(Status))
     848    {
     849        WARN(("vboxVidPnTargetModeSetFromArray failed Status(0x%x)", Status));
     850        return Status;
     851    }
     852
     853    Status = pVidPnInterface->pfnAssignTargetModeSet(hVidPn, VidPnTargetId, hVidPnModeSet);
     854    if (!NT_SUCCESS(Status))
     855    {
     856        WARN(("\n\n!!!!!!!\n\n pfnAssignTargetModeSet failed, Status(0x%x)", Status));
     857        NTSTATUS tmpStatus = pVidPnInterface->pfnReleaseTargetModeSet(hVidPn, hVidPnModeSet);
     858        Assert(tmpStatus == STATUS_SUCCESS);
     859        return Status;
     860    }
     861
     862    return STATUS_SUCCESS;
     863}
     864
     865static NTSTATUS vboxVidPnApplyInfoForPathSource(PVBOXMP_DEVEXT pDevExt,
     866        D3DKMDT_HVIDPN hVidPn,
     867        const DXGK_VIDPN_INTERFACE* pVidPnInterface,
     868        D3DKMDT_ENUMCOFUNCMODALITY_PIVOT_TYPE enmCurPivot,
     869        uint32_t *aAdjustedModeMap,
     870        const CR_SORTARRAY *aModes,
     871        D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
     872{
     873    Assert(ASMBitTest(aAdjustedModeMap, VidPnTargetId));
     874
     875    if (enmCurPivot == D3DKMDT_EPT_VIDPNSOURCE)
     876        return STATUS_SUCCESS;
     877
     878    RTRECTSIZE pinnedSize = {0};
     879    NTSTATUS Status = vboxVidPnQueryPinnedSourceMode(hVidPn, pVidPnInterface, VidPnSourceId, &pinnedSize);
     880    if (!NT_SUCCESS(Status))
     881    {
     882        WARN(("vboxVidPnQueryPinnedSourceMode failed %#x", Status));
     883        return Status;
     884    }
     885
     886    if (pinnedSize.cx)
     887        return STATUS_SUCCESS;
     888
     889    /* now just create the new source mode set and apply it */
     890    D3DKMDT_HVIDPNSOURCEMODESET hVidPnModeSet;
     891    const DXGK_VIDPNSOURCEMODESET_INTERFACE *pVidPnModeSetInterface;
     892    Status = pVidPnInterface->pfnCreateNewSourceModeSet(hVidPn,
     893                        VidPnSourceId,
     894                        &hVidPnModeSet,
     895                        &pVidPnModeSetInterface);
     896    if (!NT_SUCCESS(Status))
     897    {
     898        WARN(("pfnCreateNewSourceModeSet failed Status(0x%x)", Status));
     899        return Status;
     900    }
     901
     902    Status = vboxVidPnSourceModeSetFromArray(hVidPnModeSet,
     903            pVidPnModeSetInterface,
     904            &aModes[VidPnTargetId]); /* <- target modes always! */
     905    if (!NT_SUCCESS(Status))
     906    {
     907        WARN(("vboxVidPnSourceModeSetFromArray failed Status(0x%x)", Status));
     908        return Status;
     909    }
     910
     911    Status = pVidPnInterface->pfnAssignSourceModeSet(hVidPn, VidPnSourceId, hVidPnModeSet);
     912    if (!NT_SUCCESS(Status))
     913    {
     914        WARN(("\n\n!!!!!!!\n\n pfnAssignSourceModeSet failed, Status(0x%x)", Status));
     915        NTSTATUS tmpStatus = pVidPnInterface->pfnReleaseSourceModeSet(hVidPn, hVidPnModeSet);
     916        Assert(tmpStatus == STATUS_SUCCESS);
     917        return Status;
     918    }
     919
     920    return STATUS_SUCCESS;
     921}
     922
     923static NTSTATUS vboxVidPnCollectInfoForPathSource(PVBOXMP_DEVEXT pDevExt,
     924        D3DKMDT_HVIDPN hVidPn,
     925        const DXGK_VIDPN_INTERFACE* pVidPnInterface,
     926        D3DKMDT_ENUMCOFUNCMODALITY_PIVOT_TYPE enmCurPivot,
     927        uint32_t *aAdjustedModeMap,
     928        CR_SORTARRAY *aModes,
     929        D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
     930{
     931    const CR_SORTARRAY* pSupportedModes = VBoxWddmVModesGet(pDevExt, VidPnTargetId); /* <- yes, modes are target-determined always */
     932    NTSTATUS Status;
     933
     934    if (enmCurPivot == D3DKMDT_EPT_VIDPNSOURCE)
     935    {
     936        D3DKMDT_HVIDPNSOURCEMODESET hVidPnModeSet;
     937        const DXGK_VIDPNSOURCEMODESET_INTERFACE *pVidPnModeSetInterface;
     938        Status = pVidPnInterface->pfnAcquireSourceModeSet(hVidPn,
     939                    VidPnSourceId,
     940                    &hVidPnModeSet,
     941                    &pVidPnModeSetInterface);
     942        if (!NT_SUCCESS(Status))
     943        {
     944            WARN(("pfnAcquireSourceModeSet failed %#x", Status));
     945            return Status;
     946        }
     947
     948        /* intersect modes from target */
     949        if (!ASMBitTest(aAdjustedModeMap, VidPnTargetId))
     950        {
     951            Status = vboxVidPnSourceModeSetToArray(hVidPnModeSet, pVidPnModeSetInterface, &aModes[VidPnTargetId]);
     952            ASMBitSet(aAdjustedModeMap, VidPnTargetId);
    749953        }
    750954        else
    751955        {
    752             VBOXVIDPNMATCHMONMODESENUM Info;
    753             Info.paResolutions = pResolutions;
    754             Info.cResolutions = cResolutions;
    755             Info.fMatched = TRUE;
    756 
    757             Status = vboxVidPnEnumMonitorSourceModes(hMonitorSMS, pMonitorSMSIf, vboxFidPnMatchMonitorModesEnum, &Info);
    758             if (NT_SUCCESS(Status))
    759             {
    760                 *pfMatch = Info.fMatched;
    761                 LOG(("modes %smatched", Info.fMatched ? "" : "NOT "));
    762             }
    763             else
    764                 WARN(("vboxVidPnEnumMonitorSourceModes failed, Status 0x%x", Status));
    765         }
     956            CR_SORTARRAY Arr;
     957            CrSaInit(&Arr, 0);
     958            Status = vboxVidPnSourceModeSetToArray(hVidPnModeSet, pVidPnModeSetInterface, &aModes[VidPnTargetId]);
     959            CrSaIntersect(&aModes[VidPnTargetId], &Arr);
     960            CrSaCleanup(&Arr);
     961        }
     962
     963        NTSTATUS tmpStatus = pVidPnInterface->pfnReleaseSourceModeSet(hVidPn, hVidPnModeSet);
     964        Assert(tmpStatus == STATUS_SUCCESS);
     965
     966        if (!NT_SUCCESS(Status))
     967        {
     968            WARN(("pfnReleaseSourceModeSet failed %#x", Status));
     969            return Status;
     970        }
     971
     972        /* intersect it with supported target modes, just in case */
     973        CrSaIntersect(&aModes[VidPnTargetId], pSupportedModes);
     974
     975        return STATUS_SUCCESS;
     976    }
     977
     978    RTRECTSIZE pinnedSize = {0};
     979    Status = vboxVidPnQueryPinnedSourceMode(hVidPn, pVidPnInterface, VidPnSourceId, &pinnedSize);
     980    if (!NT_SUCCESS(Status))
     981    {
     982        WARN(("vboxVidPnQueryPinnedSourceMode failed %#x", Status));
     983        return Status;
     984    }
     985
     986    if (pinnedSize.cx)
     987    {
     988        Assert(CrSaContains(pSupportedModes, CR_RSIZE2U64(pinnedSize)));
     989
     990        if (!ASMBitTest(aAdjustedModeMap, VidPnTargetId))
     991        {
     992            Assert(CrSaGetSize(&aModes[VidPnTargetId]) == 0);
     993
     994            if (CrSaContains(pSupportedModes, CR_RSIZE2U64(pinnedSize)))
     995            {
     996                int rc = CrSaAdd(&aModes[VidPnTargetId], CR_RSIZE2U64(pinnedSize));
     997                if (!RT_SUCCESS(rc))
     998                {
     999                    WARN(("CrSaAdd failed %d", rc));
     1000                    return STATUS_UNSUCCESSFUL;
     1001                }
     1002            }
     1003            ASMBitSet(aAdjustedModeMap, VidPnTargetId);
     1004        }
     1005        else
     1006        {
     1007            CrSaClear(&aModes[VidPnTargetId]);
     1008            if (CrSaContains(pSupportedModes, CR_RSIZE2U64(pinnedSize)))
     1009            {
     1010                int rc = CrSaAdd(&aModes[VidPnTargetId], CR_RSIZE2U64(pinnedSize));
     1011                if (!RT_SUCCESS(rc))
     1012                {
     1013                    WARN(("CrSaAdd failed %d", rc));
     1014                    return STATUS_UNSUCCESSFUL;
     1015                }
     1016            }
     1017        }
     1018
     1019        return STATUS_SUCCESS;
     1020    }
     1021
     1022
     1023    Status = vboxVidPnQueryPinnedTargetMode(hVidPn, pVidPnInterface, VidPnTargetId, &pinnedSize);
     1024    if (!NT_SUCCESS(Status))
     1025    {
     1026        WARN(("vboxVidPnQueryPinnedTargetMode failed %#x", Status));
     1027        return Status;
     1028    }
     1029
     1030    if (pinnedSize.cx)
     1031    {
     1032        Assert(CrSaContains(pSupportedModes, CR_RSIZE2U64(pinnedSize)));
     1033
     1034        if (!ASMBitTest(aAdjustedModeMap, VidPnTargetId))
     1035        {
     1036            Assert(CrSaGetSize(&aModes[VidPnTargetId]) == 0);
     1037            int rc = CrSaAdd(&aModes[VidPnTargetId], CR_RSIZE2U64(pinnedSize));
     1038            if (!RT_SUCCESS(rc))
     1039            {
     1040                WARN(("CrSaAdd failed %d", rc));
     1041                return STATUS_UNSUCCESSFUL;
     1042            }
     1043            ASMBitSet(aAdjustedModeMap, VidPnTargetId);
     1044        }
     1045        else
     1046        {
     1047            CrSaClear(&aModes[VidPnTargetId]);
     1048            int rc = CrSaAdd(&aModes[VidPnTargetId], CR_RSIZE2U64(pinnedSize));
     1049            if (!RT_SUCCESS(rc))
     1050            {
     1051                WARN(("CrSaAdd failed %d", rc));
     1052                return STATUS_UNSUCCESSFUL;
     1053            }
     1054        }
     1055
     1056        return STATUS_SUCCESS;
     1057    }
     1058
     1059    /* now we are here because no pinned info is specified, we need to populate it based on the supported info
     1060     * and modes already configured,
     1061     * this is pretty simple actually */
     1062
     1063    if (!ASMBitTest(aAdjustedModeMap, VidPnTargetId))
     1064    {
     1065        Assert(CrSaGetSize(&aModes[VidPnTargetId]) == 0);
     1066        int rc = CrSaClone(pSupportedModes, &aModes[VidPnTargetId]);
     1067        if (!RT_SUCCESS(rc))
     1068        {
     1069            WARN(("CrSaClone failed %d", rc));
     1070            return STATUS_UNSUCCESSFUL;
     1071        }
     1072        ASMBitSet(aAdjustedModeMap, VidPnTargetId);
    7661073    }
    7671074    else
    768         WARN(("pfnGetNumModes failed, Status 0x%x", Status));
    769 
    770     NTSTATUS tmpStatus = pMonitorInterface->pfnReleaseMonitorSourceModeSet(pDevExt->u.primary.DxgkInterface.DeviceHandle, hMonitorSMS);
    771     if (!NT_SUCCESS(tmpStatus))
    772         WARN(("pfnReleaseMonitorSourceModeSet failed tmpStatus(0x%x)", tmpStatus));
    773 
    774     return Status;
    775 }
    776 
    777 NTSTATUS vboxVidPnCheckAddMonitorModes(PVBOXMP_DEVEXT pDevExt,
    778         D3DDDI_VIDEO_PRESENT_TARGET_ID targetId, D3DKMDT_MONITOR_CAPABILITIES_ORIGIN enmOrigin,
    779         D3DKMDT_2DREGION *pResolutions, uint32_t cResolutions, int iPreferred)
     1075    {
     1076        CrSaIntersect(&aModes[VidPnTargetId], pSupportedModes);
     1077    }
     1078
     1079    /* we are done */
     1080    return STATUS_SUCCESS;
     1081}
     1082
     1083static NTSTATUS vboxVidPnCheckMonitorModes(PVBOXMP_DEVEXT pDevExt, uint32_t u32Target)
    7801084{
    7811085    NTSTATUS Status;
     
    7881092    }
    7891093
    790     D3DKMDT_HMONITORSOURCEMODESET hMonitorSMS;
    791     CONST DXGK_MONITORSOURCEMODESET_INTERFACE *pMonitorSMSIf;
     1094    D3DKMDT_HMONITORSOURCEMODESET hVidPnModeSet;
     1095    CONST DXGK_MONITORSOURCEMODESET_INTERFACE *pVidPnModeSetInterface;
     1096
     1097    const CR_SORTARRAY *pSupportedModes = VBoxWddmVModesGet(pDevExt, u32Target);
     1098    CR_SORTARRAY DiffModes;
     1099    int rc = CrSaInit(&DiffModes, CrSaGetSize(pSupportedModes));
     1100    if (!RT_SUCCESS(rc))
     1101    {
     1102        WARN(("CrSaInit failed"));
     1103        return STATUS_NO_MEMORY;
     1104    }
     1105
    7921106
    7931107    Status = pMonitorInterface->pfnAcquireMonitorSourceModeSet(pDevExt->u.primary.DxgkInterface.DeviceHandle,
    794                                         targetId,
    795                                         &hMonitorSMS,
    796                                         &pMonitorSMSIf);
     1108                                        u32Target,
     1109                                        &hVidPnModeSet,
     1110                                        &pVidPnModeSetInterface);
    7971111    if (!NT_SUCCESS(Status))
    7981112    {
    7991113        WARN(("DxgkCbQueryMonitorInterface failed, Status()0x%x", Status));
    800         if (Status == STATUS_GRAPHICS_MONITOR_NOT_CONNECTED)
    801         {
    802             /* this is ok in case we replug the monitor to pick up the monitor modes properly,
    803              * so pretend success  */
    804             Status = STATUS_SUCCESS;
    805         }
     1114//        if (Status == STATUS_GRAPHICS_MONITOR_NOT_CONNECTED)
     1115        CrSaCleanup(&DiffModes);
    8061116        return Status;
    8071117    }
    8081118
    809     for (uint32_t i = 0; i < cResolutions; ++i)
    810     {
    811         D3DKMDT_2DREGION *pRes = &pResolutions[i];
    812 
    813         Status = vboxVidPnCreatePopulateMonitorSourceModeInfoFromLegacy(pDevExt,
    814                 hMonitorSMS,
    815                 pMonitorSMSIf,
    816                 pRes,
    817                 enmOrigin,
    818                 iPreferred == i
    819                 );
    820         Assert(Status == STATUS_SUCCESS);
    821         if (Status != STATUS_SUCCESS)
    822         {
    823             LOGREL(("vboxVidPnCreatePopulateMonitorSourceModeInfoFromLegacy failed Status(0x%x)", Status));
    824             break;
    825         }
    826     }
    827 
    828     NTSTATUS tmpStatus = pMonitorInterface->pfnReleaseMonitorSourceModeSet(pDevExt->u.primary.DxgkInterface.DeviceHandle, hMonitorSMS);
     1119    VBOXVIDPN_MONITORMODE_ITER Iter;
     1120    const D3DKMDT_MONITOR_SOURCE_MODE *pVidPnModeInfo;
     1121
     1122    rc = CrSaClone(pSupportedModes, &DiffModes);
     1123    if (!RT_SUCCESS(rc))
     1124    {
     1125        WARN(("CrSaClone failed"));
     1126        Status = STATUS_NO_MEMORY;
     1127        goto done;
     1128    }
     1129
     1130    VBoxVidPnMonitorModeIterInit(&Iter, hVidPnModeSet, pVidPnModeSetInterface);
     1131
     1132    while ((pVidPnModeInfo = VBoxVidPnMonitorModeIterNext(&Iter)) != NULL)
     1133    {
     1134        RTRECTSIZE size;
     1135        size.cx = pVidPnModeInfo->VideoSignalInfo.ActiveSize.cx;
     1136        size.cy = pVidPnModeInfo->VideoSignalInfo.ActiveSize.cy;
     1137        CrSaRemove(&DiffModes, CR_RSIZE2U64(size));
     1138    }
     1139
     1140    VBoxVidPnMonitorModeIterTerm(&Iter);
     1141
     1142    Status = VBoxVidPnMonitorModeIterStatus(&Iter);
     1143    if (!NT_SUCCESS(Status))
     1144    {
     1145        WARN(("iter status failed %#x", Status));
     1146        goto done;
     1147    }
     1148
     1149    Status = vboxVidPnMonitorModeSetFromArray(hVidPnModeSet, pVidPnModeSetInterface, &DiffModes);
     1150    if (!NT_SUCCESS(Status))
     1151    {
     1152        WARN(("vboxVidPnMonitorModeSetFromArray failed %#x", Status));
     1153        goto done;
     1154    }
     1155
     1156done:
     1157    NTSTATUS tmpStatus = pMonitorInterface->pfnReleaseMonitorSourceModeSet(pDevExt->u.primary.DxgkInterface.DeviceHandle, hVidPnModeSet);
    8291158    if (!NT_SUCCESS(tmpStatus))
    830     {
    8311159        WARN(("pfnReleaseMonitorSourceModeSet failed tmpStatus(0x%x)", tmpStatus));
    832     }
     1160
     1161    CrSaCleanup(&DiffModes);
    8331162
    8341163    return Status;
    8351164}
    8361165
    837 NTSTATUS vboxVidPnPathAdd(D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface,
    838         const D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, const D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
     1166static NTSTATUS vboxVidPnPathAdd(D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface,
     1167        const D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, const D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId,
     1168        D3DKMDT_VIDPN_PRESENT_PATH_IMPORTANCE enmImportance)
    8391169{
    8401170    D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology;
     
    8571187    pNewVidPnPresentPathInfo->VidPnSourceId = VidPnSourceId;
    8581188    pNewVidPnPresentPathInfo->VidPnTargetId = VidPnTargetId;
    859     pNewVidPnPresentPathInfo->ImportanceOrdinal = D3DKMDT_VPPI_PRIMARY;
     1189    pNewVidPnPresentPathInfo->ImportanceOrdinal = enmImportance;
    8601190    pNewVidPnPresentPathInfo->ContentTransformation.Scaling = D3DKMDT_VPPS_IDENTITY;
    8611191    memset(&pNewVidPnPresentPathInfo->ContentTransformation.ScalingSupport,
     
    8951225    }
    8961226
     1227    LOG(("Recommended Path (%d->%d)", VidPnSourceId, VidPnTargetId));
     1228
    8971229    return Status;
    8981230}
    8991231
    900 static NTSTATUS vboxVidPnCreatePopulateSourceModeInfoFromLegacy(D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface,
    901         const D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId,
    902         VIDEO_MODE_INFORMATION *pModes, uint32_t cModes, int iModeToPin,
    903         D3DKMDT_VIDEO_PRESENT_SOURCE_MODE_ID *pModeIdToPin,
    904         BOOLEAN fDoPin
    905         )
    906 {
    907     D3DKMDT_HVIDPNSOURCEMODESET hNewVidPnSourceModeSet;
    908     const DXGK_VIDPNSOURCEMODESET_INTERFACE *pNewVidPnSourceModeSetInterface;
    909 
    910     if (pModeIdToPin)
    911         *pModeIdToPin = D3DDDI_ID_UNINITIALIZED;
    912 
    913     NTSTATUS Status = pVidPnInterface->pfnCreateNewSourceModeSet(hVidPn,
    914                         VidPnSourceId,
    915                         &hNewVidPnSourceModeSet,
    916                         &pNewVidPnSourceModeSetInterface);
    917     if (!NT_SUCCESS(Status))
    918     {
    919         AssertFailed();
     1232NTSTATUS VBoxVidPnRecommendMonitorModes(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_TARGET_ID VideoPresentTargetId,
     1233                        D3DKMDT_HMONITORSOURCEMODESET hVidPnModeSet, const DXGK_MONITORSOURCEMODESET_INTERFACE *pVidPnModeSetInterface)
     1234{
     1235    const CR_SORTARRAY *pSupportedModes = VBoxWddmVModesGet(pDevExt, VideoPresentTargetId);
     1236
     1237    NTSTATUS Status = vboxVidPnMonitorModeSetFromArray(hVidPnModeSet, pVidPnModeSetInterface, pSupportedModes);
     1238    if (!NT_SUCCESS(Status))
     1239    {
     1240        WARN(("vboxVidPnMonitorModeSetFromArray failed %d", Status));
    9201241        return Status;
    9211242    }
    9221243
    923     D3DKMDT_VIDEO_PRESENT_SOURCE_MODE_ID sourceModeId = D3DDDI_ID_UNINITIALIZED;
    924 
    925     for (uint32_t i = 0; i < cModes; ++i)
    926     {
    927         VIDEO_MODE_INFORMATION *pMode = &pModes[i];
    928         D3DKMDT_VIDPN_SOURCE_MODE *pNewVidPnSourceModeInfo;
    929         Status = pNewVidPnSourceModeSetInterface->pfnCreateNewModeInfo(hNewVidPnSourceModeSet, &pNewVidPnSourceModeInfo);
     1244    return STATUS_SUCCESS;
     1245}
     1246
     1247NTSTATUS VBoxVidPnUpdateModes(PVBOXMP_DEVEXT pDevExt, uint32_t u32TargetId, const RTRECTSIZE *pSize)
     1248{
     1249    if (u32TargetId >= (uint32_t)VBoxCommonFromDeviceExt(pDevExt)->cDisplays)
     1250    {
     1251        WARN(("invalid target id"));
     1252        return STATUS_INVALID_PARAMETER;
     1253    }
     1254
     1255    int rc = VBoxWddmVModesAdd(pDevExt, u32TargetId, pSize, TRUE);
     1256    if (RT_FAILURE(rc))
     1257    {
     1258        WARN(("VBoxWddmVModesAdd failed %d", rc));
     1259        return STATUS_UNSUCCESSFUL;
     1260    }
     1261
     1262    if (rc == VINF_ALREADY_INITIALIZED)
     1263    {
     1264        /* mode was already in list, just return */
     1265        Assert(CrSaContains(VBoxWddmVModesGet(pDevExt, u32TargetId), CR_RSIZE2U64(*pSize)));
     1266        return STATUS_SUCCESS;
     1267    }
     1268
     1269    /* modes have changed, need to replug */
     1270    NTSTATUS Status = VBoxWddmChildStatusReportReconnected(pDevExt, u32TargetId);
     1271    if (!NT_SUCCESS(Status))
     1272    {
     1273        WARN(("VBoxWddmChildStatusReportReconnected failed Status(%#x)", Status));
     1274        return Status;
     1275    }
     1276
     1277    return STATUS_SUCCESS;
     1278}
     1279
     1280NTSTATUS VBoxVidPnRecommendFunctional(PVBOXMP_DEVEXT pDevExt, D3DKMDT_HVIDPN hVidPn, const VBOXWDDM_RECOMMENDVIDPN *pData)
     1281{
     1282    const DXGK_VIDPN_INTERFACE* pVidPnInterface = NULL;
     1283    NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbQueryVidPnInterface(hVidPn, DXGK_VIDPN_INTERFACE_VERSION_V1, &pVidPnInterface);
     1284    if (!NT_SUCCESS(Status))
     1285    {
     1286        WARN(("DxgkCbQueryVidPnInterface failed Status(%#x)", Status));
     1287        return Status;
     1288    }
     1289
     1290    VBOXCMDVBVA_SCREENMAP_DECL(uint32_t, aVisitedSourceMap);
     1291
     1292    memset(aVisitedSourceMap, 0, sizeof (aVisitedSourceMap));
     1293
     1294    uint32_t Importance = (uint32_t)D3DKMDT_VPPI_PRIMARY;
     1295
     1296    for (uint32_t i = 0; i < (uint32_t)VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
     1297    {
     1298        int32_t iSource = pData->aTargets[i].iSource;
     1299        if (iSource < 0)
     1300            continue;
     1301
     1302        if (iSource >= VBoxCommonFromDeviceExt(pDevExt)->cDisplays)
     1303        {
     1304            WARN(("invalid iSource"));
     1305            return STATUS_INVALID_PARAMETER;
     1306        }
     1307
     1308        if (!pDevExt->fComplexTopologiesEnabled && iSource != i)
     1309        {
     1310            WARN(("complex topologies not supported!"));
     1311            return STATUS_INVALID_PARAMETER;
     1312        }
     1313
     1314        bool fNewSource = false;
     1315
     1316        if (!ASMBitTest(aVisitedSourceMap, iSource))
     1317        {
     1318            int rc = VBoxWddmVModesAdd(pDevExt, i, &pData->aSources[iSource].Size, TRUE);
     1319            if (RT_FAILURE(rc))
     1320            {
     1321                WARN(("VBoxWddmVModesAdd failed %d", rc));
     1322                return STATUS_UNSUCCESSFUL;
     1323            }
     1324
     1325            Assert(CrSaContains(VBoxWddmVModesGet(pDevExt, i), CR_RSIZE2U64(pData->aSources[iSource].Size)));
     1326
     1327            Status = vboxVidPnCheckMonitorModes(pDevExt, i);
     1328            if (!NT_SUCCESS(Status))
     1329            {
     1330                WARN(("vboxVidPnCheckMonitorModes failed %#x", Status));
     1331                return Status;
     1332            }
     1333
     1334            ASMBitSet(aVisitedSourceMap, iSource);
     1335            fNewSource = true;
     1336        }
     1337
     1338        Status = vboxVidPnPathAdd(hVidPn, pVidPnInterface,
     1339                (const D3DDDI_VIDEO_PRESENT_SOURCE_ID)iSource, (const D3DDDI_VIDEO_PRESENT_TARGET_ID)i,
     1340                (D3DKMDT_VIDPN_PRESENT_PATH_IMPORTANCE)Importance);
    9301341        if (!NT_SUCCESS(Status))
    9311342        {
    932             AssertFailed();
    933             break;
    934         }
    935 
    936         Status = vboxVidPnPopulateSourceModeInfoFromLegacy(pNewVidPnSourceModeInfo, pMode);
    937         if (NT_SUCCESS(Status))
    938         {
    939             if (i == iModeToPin)
    940             {
    941                 sourceModeId = pNewVidPnSourceModeInfo->Id;
    942             }
    943             Status = pNewVidPnSourceModeSetInterface->pfnAddMode(hNewVidPnSourceModeSet, pNewVidPnSourceModeInfo);
     1343            WARN(("vboxVidPnPathAdd failed Status()0x%x\n", Status));
     1344            return Status;
     1345        }
     1346
     1347        Importance++;
     1348
     1349        do {
     1350            D3DKMDT_HVIDPNTARGETMODESET hVidPnModeSet;
     1351            const DXGK_VIDPNTARGETMODESET_INTERFACE *pVidPnModeSetInterface;
     1352
     1353            Status = pVidPnInterface->pfnCreateNewTargetModeSet(hVidPn,
     1354                                i,
     1355                                &hVidPnModeSet,
     1356                                &pVidPnModeSetInterface);
    9441357            if (NT_SUCCESS(Status))
    9451358            {
    946                 /* success */
    947                 continue;
    948             }
    949             AssertFailed();
    950         }
    951         else
    952         {
    953             AssertFailed();
    954         }
    955 
    956         NTSTATUS tmpStatus = pNewVidPnSourceModeSetInterface->pfnReleaseModeInfo(hNewVidPnSourceModeSet, pNewVidPnSourceModeInfo);
    957         Assert(tmpStatus == STATUS_SUCCESS);
    958 
    959         /* we're here because of an error */
    960         Assert(!NT_SUCCESS(Status));
    961         break;
    962     }
    963 
    964     if (!NT_SUCCESS(Status))
    965     {
    966         AssertFailed();
    967         return Status;
    968     }
    969 
    970     if (sourceModeId != D3DDDI_ID_UNINITIALIZED)
    971     {
    972         if (pModeIdToPin)
    973         {
    974             *pModeIdToPin = sourceModeId;
    975         }
    976         Assert(iModeToPin >= 0);
    977         if (fDoPin)
    978         {
    979             Status = pNewVidPnSourceModeSetInterface->pfnPinMode(hNewVidPnSourceModeSet, sourceModeId);
    980             if (!NT_SUCCESS(Status))
    981             {
    982                 AssertFailed();
    983                 return Status;
    984             }
    985         }
    986     }
    987     else
    988     {
    989         Assert(iModeToPin < 0);
    990     }
    991 
    992     Status = pVidPnInterface->pfnAssignSourceModeSet(hVidPn, VidPnSourceId, hNewVidPnSourceModeSet);
    993     if (!NT_SUCCESS(Status))
    994     {
    995         AssertFailed();
    996         return Status;
    997     }
    998 
    999     return Status;
    1000 }
    1001 
    1002 static NTSTATUS vboxVidPnCreatePopulateTargetModeInfoFromLegacy(D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface,
    1003         const D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId,
    1004         D3DKMDT_2DREGION *pResolutions, uint32_t cResolutions,
    1005         VIDEO_MODE_INFORMATION *pModeToPin,
    1006         D3DKMDT_VIDEO_PRESENT_TARGET_MODE_ID *pModeIdToPin,
    1007         BOOLEAN fSetPreferred,
    1008         BOOLEAN fDoPin
    1009         )
    1010 {
    1011     D3DKMDT_HVIDPNTARGETMODESET hNewVidPnTargetModeSet;
    1012     const DXGK_VIDPNTARGETMODESET_INTERFACE *pNewVidPnTargetModeSetInterface;
    1013 
    1014     if (pModeIdToPin)
    1015         *pModeIdToPin = D3DDDI_ID_UNINITIALIZED;
    1016 
    1017     NTSTATUS Status = pVidPnInterface->pfnCreateNewTargetModeSet(hVidPn,
    1018                         VidPnTargetId,
    1019                         &hNewVidPnTargetModeSet,
    1020                         &pNewVidPnTargetModeSetInterface);
    1021     if (!NT_SUCCESS(Status))
    1022     {
    1023         AssertFailed();
    1024         return Status;
    1025     }
    1026 
    1027     D3DKMDT_VIDEO_PRESENT_TARGET_MODE_ID targetModeId = D3DDDI_ID_UNINITIALIZED;
    1028 
    1029     for (uint32_t i = 0; i < cResolutions; ++i)
    1030     {
    1031         D3DKMDT_2DREGION *pResolution = &pResolutions[i];
    1032         D3DKMDT_VIDPN_TARGET_MODE *pNewVidPnTargetModeInfo;
    1033         Status = pNewVidPnTargetModeSetInterface->pfnCreateNewModeInfo(hNewVidPnTargetModeSet, &pNewVidPnTargetModeInfo);
    1034         if (!NT_SUCCESS(Status))
    1035         {
    1036             AssertFailed();
    1037             break;
    1038         }
    1039 
    1040         BOOLEAN fIsPinMode = pModeToPin && pModeToPin->VisScreenWidth == pResolution->cx
    1041                 && pModeToPin->VisScreenHeight == pResolution->cy;
    1042 
    1043         Status = vboxVidPnPopulateTargetModeInfoFromLegacy(pNewVidPnTargetModeInfo, pResolution, fIsPinMode && fSetPreferred);
    1044         if (NT_SUCCESS(Status))
    1045         {
    1046             if (fIsPinMode)
    1047             {
    1048                 targetModeId = pNewVidPnTargetModeInfo->Id;
    1049             }
    1050             Status = pNewVidPnTargetModeSetInterface->pfnAddMode(hNewVidPnTargetModeSet, pNewVidPnTargetModeInfo);
    1051             if (NT_SUCCESS(Status))
    1052             {
    1053 
    1054                 /* success */
    1055                 continue;
    1056             }
    1057             AssertFailed();
    1058         }
    1059         else
    1060         {
    1061             AssertFailed();
    1062         }
    1063 
    1064         NTSTATUS tmpStatus = pNewVidPnTargetModeSetInterface->pfnReleaseModeInfo(hNewVidPnTargetModeSet, pNewVidPnTargetModeInfo);
    1065         Assert(tmpStatus == STATUS_SUCCESS);
    1066 
    1067         /* we're here because of an error */
    1068         Assert(!NT_SUCCESS(Status));
    1069         break;
    1070     }
    1071 
    1072     if (!NT_SUCCESS(Status))
    1073     {
    1074         AssertFailed();
    1075         return Status;
    1076     }
    1077 
    1078     if (targetModeId != D3DDDI_ID_UNINITIALIZED)
    1079     {
    1080         Assert(pModeToPin);
    1081 
    1082         if (pModeIdToPin)
    1083         {
    1084             *pModeIdToPin = targetModeId;
    1085         }
    1086 
    1087         if (fDoPin)
    1088         {
    1089             Status = pNewVidPnTargetModeSetInterface->pfnPinMode(hNewVidPnTargetModeSet, targetModeId);
    1090             if (!NT_SUCCESS(Status))
    1091             {
    1092                 AssertFailed();
    1093                 return Status;
    1094             }
    1095         }
    1096     }
    1097     else
    1098     {
    1099         Assert(!pModeToPin);
    1100     }
    1101 
    1102     Status = pVidPnInterface->pfnAssignTargetModeSet(hVidPn, VidPnTargetId, hNewVidPnTargetModeSet);
    1103     if (!NT_SUCCESS(Status))
    1104     {
    1105         AssertFailed();
    1106         return Status;
    1107     }
    1108 
    1109     return Status;
    1110 }
    1111 
    1112 NTSTATUS vboxVidPnCreatePopulateVidPnPathFromLegacy(PVBOXMP_DEVEXT pDevExt, D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface,
    1113         VIDEO_MODE_INFORMATION *pModes, uint32_t cModes, int iModeToPin,
    1114         D3DKMDT_2DREGION *pResolutions, uint32_t cResolutions,
    1115         const D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, const D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
    1116 {
    1117     NTSTATUS Status;
    1118 
    1119 #if 0
    1120     Status = vboxVidPnPathAdd(hVidPn, pVidPnInterface, VidPnSourceId, VidPnTargetId);
    1121     if (!NT_SUCCESS(Status))
    1122     {
    1123         AssertFailed();
    1124         return Status;
    1125     }
    1126 #endif
    1127 
    1128     VIDEO_MODE_INFORMATION *pModeToPin = iModeToPin >= 0 ? &pModes[iModeToPin] : NULL;
    1129     Status = vboxVidPnCreatePopulateTargetModeInfoFromLegacy(hVidPn, pVidPnInterface, VidPnTargetId, pResolutions, cResolutions, pModeToPin, NULL, TRUE, TRUE);
    1130     if (!NT_SUCCESS(Status))
    1131     {
    1132         AssertFailed();
    1133         return Status;
    1134     }
    1135 
    1136     Status = vboxVidPnCreatePopulateSourceModeInfoFromLegacy(hVidPn, pVidPnInterface, VidPnSourceId, pModes, cModes, iModeToPin, NULL, TRUE);
    1137     if (!NT_SUCCESS(Status))
    1138     {
    1139         AssertFailed();
    1140         return Status;
    1141     }
    1142 
    1143     return Status;
    1144 }
    1145 
    1146 typedef struct VBOXVIDPNPOPRESOLUTIONENUM
    1147 {
    1148     NTSTATUS Status;
    1149     D3DKMDT_2DREGION *pResolutions;
    1150     int cResolutions;
    1151     int cResultResolutions;
    1152 }VBOXVIDPNPOPRESOLUTIONENUM, *PVBOXVIDPNPOPRESOLUTIONENUM;
    1153 
    1154 static DECLCALLBACK(BOOLEAN) vboxVidPnPopulateResolutionsFromSourceModeSetEnum(D3DKMDT_HVIDPNSOURCEMODESET hNewVidPnSourceModeSet, const DXGK_VIDPNSOURCEMODESET_INTERFACE *pVidPnSourceModeSetInterface,
    1155         const D3DKMDT_VIDPN_SOURCE_MODE *pNewVidPnSourceModeInfo, PVOID pContext)
    1156 {
    1157     NTSTATUS Status = STATUS_SUCCESS;
    1158     PVBOXVIDPNPOPRESOLUTIONENUM pInfo = (PVBOXVIDPNPOPRESOLUTIONENUM)pContext;
    1159     Assert(pInfo->cResolutions >= pInfo->cResultResolutions);
    1160     Assert(pInfo->Status == STATUS_SUCCESS);
    1161     if (vboxWddmResolutionFind(pInfo->pResolutions, pInfo->cResultResolutions, &pNewVidPnSourceModeInfo->Format.Graphics.PrimSurfSize) < 0)
    1162     {
    1163         if (pInfo->cResultResolutions < pInfo->cResolutions)
    1164         {
    1165             pInfo->pResolutions[pInfo->cResultResolutions] = pNewVidPnSourceModeInfo->Format.Graphics.PrimSurfSize;
    1166             ++pInfo->cResultResolutions;
    1167         }
    1168         else
    1169         {
    1170             Status = STATUS_BUFFER_OVERFLOW;
    1171         }
    1172     }
    1173 
    1174     pInfo->Status = Status;
    1175 
    1176     return Status == STATUS_SUCCESS;
    1177 }
    1178 
    1179 static DECLCALLBACK(BOOLEAN) vboxVidPnPopulateResolutionsFromTargetModeSetEnum(D3DKMDT_HVIDPNTARGETMODESET hNewVidPnTargetModeSet, const DXGK_VIDPNTARGETMODESET_INTERFACE *pVidPnTargetModeSetInterface,
    1180         const D3DKMDT_VIDPN_TARGET_MODE *pNewVidPnTargetModeInfo, PVOID pContext)
    1181 {
    1182     NTSTATUS Status = STATUS_SUCCESS;
    1183     PVBOXVIDPNPOPRESOLUTIONENUM pInfo = (PVBOXVIDPNPOPRESOLUTIONENUM)pContext;
    1184     Assert(pInfo->cResolutions >= pInfo->cResultResolutions);
    1185     Assert(pInfo->Status == STATUS_SUCCESS);
    1186     if (vboxWddmResolutionFind(pInfo->pResolutions, pInfo->cResultResolutions, &pNewVidPnTargetModeInfo->VideoSignalInfo.ActiveSize) < 0)
    1187     {
    1188         if (pInfo->cResultResolutions < pInfo->cResolutions)
    1189         {
    1190             pInfo->pResolutions[pInfo->cResultResolutions] = pNewVidPnTargetModeInfo->VideoSignalInfo.ActiveSize;
    1191             ++pInfo->cResultResolutions;
    1192         }
    1193         else
    1194         {
    1195             Status = STATUS_BUFFER_OVERFLOW;
    1196         }
    1197     }
    1198 
    1199     pInfo->Status = Status;
    1200 
    1201     return Status == STATUS_SUCCESS;
    1202 }
    1203 
    1204 typedef struct VBOXVIDPNPOPMODEENUM
    1205 {
    1206     NTSTATUS Status;
    1207     VIDEO_MODE_INFORMATION *pModes;
    1208     int cModes;
    1209     int cResultModes;
    1210 }VBOXVIDPNPOPMODEENUM, *PVBOXVIDPNPOPMODEENUM;
    1211 
    1212 static DECLCALLBACK(BOOLEAN) vboxVidPnPopulateModesFromSourceModeSetEnum(D3DKMDT_HVIDPNSOURCEMODESET hNewVidPnSourceModeSet, const DXGK_VIDPNSOURCEMODESET_INTERFACE *pVidPnSourceModeSetInterface,
    1213         const D3DKMDT_VIDPN_SOURCE_MODE *pNewVidPnSourceModeInfo, PVOID pContext)
    1214 {
    1215     NTSTATUS Status = STATUS_SUCCESS;
    1216     PVBOXVIDPNPOPMODEENUM pInfo = (PVBOXVIDPNPOPMODEENUM)pContext;
    1217     VIDEO_MODE_INFORMATION Mode;
    1218     Assert(pInfo->cModes >= pInfo->cResultModes);
    1219     Assert(pInfo->Status == STATUS_SUCCESS);
    1220     if (VBoxWddmFillMode(&Mode, pNewVidPnSourceModeInfo->Format.Graphics.PixelFormat,
    1221             pNewVidPnSourceModeInfo->Format.Graphics.VisibleRegionSize.cx,
    1222             pNewVidPnSourceModeInfo->Format.Graphics.VisibleRegionSize.cy))
    1223     {
    1224         if (vboxWddmVideoModeFind(pInfo->pModes, pInfo->cModes, &Mode) < 0)
    1225         {
    1226             if (pInfo->cResultModes < pInfo->cModes)
    1227             {
    1228                 pInfo->pModes[pInfo->cResultModes] = Mode;
    1229                 ++pInfo->cResultModes;
     1359                D3DKMDT_VIDPN_TARGET_MODE *pVidPnModeInfo;
     1360                Status = pVidPnModeSetInterface->pfnCreateNewModeInfo(hVidPnModeSet, &pVidPnModeInfo);
     1361                if (NT_SUCCESS(Status))
     1362                {
     1363                    vboxVidPnPopulateTargetModeInfo(pVidPnModeInfo, &pData->aSources[iSource].Size);
     1364
     1365                    IN_CONST_D3DKMDT_VIDEO_PRESENT_TARGET_MODE_ID idMode = pVidPnModeInfo->Id;
     1366
     1367                    Status = pVidPnModeSetInterface->pfnAddMode(hVidPnModeSet, pVidPnModeInfo);
     1368                    if (NT_SUCCESS(Status))
     1369                    {
     1370                        pVidPnModeInfo = NULL;
     1371
     1372                        Status = pVidPnModeSetInterface->pfnPinMode(hVidPnModeSet, idMode);
     1373                        if (NT_SUCCESS(Status))
     1374                        {
     1375                            Status = pVidPnInterface->pfnAssignTargetModeSet(hVidPn, i, hVidPnModeSet);
     1376                            if (NT_SUCCESS(Status))
     1377                            {
     1378                                LOG(("Recommended Target[%d] (%dx%d)", i, pData->aSources[iSource].Size.cx, pData->aSources[iSource].Size.cy));
     1379                                break;
     1380                            }
     1381                            else
     1382                                WARN(("pfnAssignTargetModeSet failed %#x", Status));
     1383                        }
     1384                        else
     1385                            WARN(("pfnPinMode failed %#x", Status));
     1386
     1387                    }
     1388                    else
     1389                        WARN(("pfnAddMode failed %#x", Status));
     1390
     1391                    if (pVidPnModeInfo)
     1392                    {
     1393                        NTSTATUS tmpStatus = pVidPnModeSetInterface->pfnReleaseModeInfo(hVidPnModeSet, pVidPnModeInfo);
     1394                        Assert(tmpStatus == STATUS_SUCCESS);
     1395                    }
     1396                }
     1397                else
     1398                    WARN(("pfnCreateNewTargetModeSet failed %#x", Status));
     1399
     1400                NTSTATUS tmpStatus = pVidPnInterface->pfnReleaseTargetModeSet(hVidPn, hVidPnModeSet);
     1401                Assert(tmpStatus == STATUS_SUCCESS);
    12301402            }
    12311403            else
    1232             {
    1233                 Status = STATUS_BUFFER_OVERFLOW;
    1234             }
    1235         }
    1236     }
    1237     else
    1238     {
    1239         Assert(0);
    1240         Status = STATUS_INVALID_PARAMETER;
    1241     }
    1242 
    1243     pInfo->Status = Status;
    1244 
    1245     return Status == STATUS_SUCCESS;
    1246 }
    1247 
    1248 typedef struct VBOXVIDPNPOPMODETARGETENUM
    1249 {
    1250     VBOXVIDPNPOPMODEENUM Base;
    1251     VIDEO_MODE_INFORMATION *pSuperset;
    1252     int cSuperset;
    1253 }VBOXVIDPNPOPMODETARGETENUM, *PVBOXVIDPNPOPMODETARGETENUM;
    1254 
    1255 static DECLCALLBACK(BOOLEAN) vboxVidPnPopulateModesFromTargetModeSetEnum(D3DKMDT_HVIDPNTARGETMODESET hNewVidPnTargetModeSet, const DXGK_VIDPNTARGETMODESET_INTERFACE *pVidPnTargetModeSetInterface,
    1256         const D3DKMDT_VIDPN_TARGET_MODE *pNewVidPnTargetModeInfo, PVOID pContext)
    1257 {
    1258     NTSTATUS Status = STATUS_SUCCESS;
    1259     PVBOXVIDPNPOPMODETARGETENUM pInfo = (PVBOXVIDPNPOPMODETARGETENUM)pContext;
    1260     Assert(pInfo->Base.cModes >= pInfo->Base.cResultModes);
    1261     Assert(pInfo->Base.Status == STATUS_SUCCESS);
    1262     uint32_t cResult;
    1263     Status = VBoxWddmGetModesForResolution(pInfo->pSuperset, pInfo->cSuperset, -1, &pNewVidPnTargetModeInfo->VideoSignalInfo.ActiveSize,
    1264             pInfo->Base.pModes + pInfo->Base.cResultModes, pInfo->Base.cModes - pInfo->Base.cResultModes, &cResult, NULL);
    1265     Assert(Status == STATUS_SUCCESS);
    1266     if (Status == STATUS_SUCCESS)
    1267     {
    1268         pInfo->Base.cResultModes += cResult;
    1269     }
    1270 
    1271     pInfo->Base.Status = Status;
    1272 
    1273     return Status == STATUS_SUCCESS;
    1274 }
    1275 
    1276 static D3DKMDT_ENUMCOFUNCMODALITY_PIVOT_TYPE vboxVidPnCofuncModalityCurrentPathPivot(CONST DXGKARG_ENUMVIDPNCOFUNCMODALITY* pEnumCofuncModalityArg,
    1277                     D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
    1278 {
    1279     switch (pEnumCofuncModalityArg->EnumPivotType)
    1280     {
    1281         case D3DKMDT_EPT_VIDPNSOURCE:
    1282             if (pEnumCofuncModalityArg->EnumPivot.VidPnSourceId == VidPnSourceId)
    1283                 return D3DKMDT_EPT_VIDPNSOURCE;
    1284             if (pEnumCofuncModalityArg->EnumPivot.VidPnSourceId == D3DDDI_ID_ALL)
    1285             {
    1286 #ifdef DEBUG_misha
    1287                 AssertFailed();
    1288 #endif
    1289                 return D3DKMDT_EPT_VIDPNSOURCE;
    1290             }
    1291             return D3DKMDT_EPT_NOPIVOT;
    1292         case D3DKMDT_EPT_VIDPNTARGET:
    1293             if (pEnumCofuncModalityArg->EnumPivot.VidPnTargetId == VidPnTargetId)
    1294                 return D3DKMDT_EPT_VIDPNTARGET;
    1295             if (pEnumCofuncModalityArg->EnumPivot.VidPnTargetId == D3DDDI_ID_ALL)
    1296             {
    1297 #ifdef DEBUG_misha
    1298                 AssertFailed();
    1299 #endif
    1300                 return D3DKMDT_EPT_VIDPNTARGET;
    1301             }
    1302             return D3DKMDT_EPT_NOPIVOT;
    1303         case D3DKMDT_EPT_SCALING:
    1304         case D3DKMDT_EPT_ROTATION:
    1305         case D3DKMDT_EPT_NOPIVOT:
    1306             return D3DKMDT_EPT_NOPIVOT;
    1307         default:
    1308             AssertFailed();
    1309             return D3DKMDT_EPT_NOPIVOT;
    1310     }
    1311 }
    1312 
    1313 NTSTATUS vboxVidPnHasPinnedTargetMode(D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface,
    1314         D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId, BOOLEAN *pfHas)
    1315 {
    1316     D3DKMDT_HVIDPNTARGETMODESET hCurVidPnTargetModeSet;
    1317     const DXGK_VIDPNTARGETMODESET_INTERFACE *pCurVidPnTargetModeSetInterface;
    1318     *pfHas = FALSE;
    1319     NTSTATUS Status = pVidPnInterface->pfnAcquireTargetModeSet(hVidPn,
    1320                         VidPnTargetId,
    1321                         &hCurVidPnTargetModeSet,
    1322                         &pCurVidPnTargetModeSetInterface);
    1323     if (!NT_SUCCESS(Status))
    1324     {
    1325         AssertFailed();
    1326         return Status;
    1327     }
    1328 
    1329     CONST D3DKMDT_VIDPN_TARGET_MODE* pPinnedVidPnTargetModeInfo;
    1330     Status = pCurVidPnTargetModeSetInterface->pfnAcquirePinnedModeInfo(hCurVidPnTargetModeSet, &pPinnedVidPnTargetModeInfo);
    1331     if (Status == STATUS_GRAPHICS_MODE_NOT_PINNED)
    1332     {
    1333         pPinnedVidPnTargetModeInfo = NULL;
    1334         Status = STATUS_SUCCESS;
    1335     }
    1336     else if (!NT_SUCCESS(Status))
    1337     {
    1338         LOGREL(("pfnAcquirePinnedModeInfo failed Status(0x%x)", Status));
    1339         AssertFailed();
    1340     }
    1341     else
    1342     {
    1343         Assert(pPinnedVidPnTargetModeInfo);
    1344         NTSTATUS tmpStatus = pCurVidPnTargetModeSetInterface->pfnReleaseModeInfo(hCurVidPnTargetModeSet, pPinnedVidPnTargetModeInfo);
    1345         Assert(NT_SUCCESS(tmpStatus));
    1346         *pfHas = TRUE;
    1347     }
    1348 
    1349     NTSTATUS tmpStatus = pVidPnInterface->pfnReleaseTargetModeSet(hVidPn, hCurVidPnTargetModeSet);
    1350     Assert(tmpStatus == STATUS_SUCCESS);
    1351 
    1352     return Status;
    1353 }
    1354 
    1355 NTSTATUS vboxVidPnHasPinnedSourceMode(D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface,
    1356         D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, BOOLEAN *pfHas)
    1357 {
    1358     D3DKMDT_HVIDPNSOURCEMODESET hCurVidPnSourceModeSet;
    1359     const DXGK_VIDPNSOURCEMODESET_INTERFACE *pCurVidPnSourceModeSetInterface;
    1360     *pfHas = FALSE;
    1361     NTSTATUS Status = pVidPnInterface->pfnAcquireSourceModeSet(hVidPn,
    1362                         VidPnSourceId,
    1363                         &hCurVidPnSourceModeSet,
    1364                         &pCurVidPnSourceModeSetInterface);
    1365     if (!NT_SUCCESS(Status))
    1366     {
    1367         AssertFailed();
    1368         return Status;
    1369     }
    1370 
    1371     CONST D3DKMDT_VIDPN_SOURCE_MODE* pPinnedVidPnSourceModeInfo;
    1372     Status = pCurVidPnSourceModeSetInterface->pfnAcquirePinnedModeInfo(hCurVidPnSourceModeSet, &pPinnedVidPnSourceModeInfo);
    1373     if (Status == STATUS_GRAPHICS_MODE_NOT_PINNED)
    1374     {
    1375         pPinnedVidPnSourceModeInfo = NULL;
    1376         Status = STATUS_SUCCESS;
    1377     }
    1378     else if (!NT_SUCCESS(Status))
    1379     {
    1380         LOGREL(("pfnAcquirePinnedModeInfo failed Status(0x%x)", Status));
    1381         AssertFailed();
    1382     }
    1383     else
    1384     {
    1385         Assert(pPinnedVidPnSourceModeInfo);
    1386         NTSTATUS tmpStatus = pCurVidPnSourceModeSetInterface->pfnReleaseModeInfo(hCurVidPnSourceModeSet, pPinnedVidPnSourceModeInfo);
    1387         Assert(NT_SUCCESS(tmpStatus));
    1388         *pfHas = TRUE;
    1389     }
    1390 
    1391     NTSTATUS tmpStatus = pVidPnInterface->pfnReleaseSourceModeSet(hVidPn, hCurVidPnSourceModeSet);
    1392     Assert(tmpStatus == STATUS_SUCCESS);
    1393 
    1394     return Status;
    1395 }
    1396 
    1397 static NTSTATUS vboxVidPnCofuncModalityForPathTarget(PVBOXVIDPNCOFUNCMODALITY pCbContext,
    1398         D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
    1399 {
    1400     PVBOXMP_DEVEXT pDevExt = pCbContext->pDevExt;
    1401     D3DKMDT_HVIDPN hVidPn = pCbContext->pEnumCofuncModalityArg->hConstrainingVidPn;
    1402     const DXGK_VIDPN_INTERFACE* pVidPnInterface = pCbContext->pVidPnInterface;
    1403     PVBOXWDDM_VIDEOMODES_INFO pInfo = &pCbContext->pInfos[VidPnTargetId];
    1404 
    1405     D3DKMDT_HVIDPNTARGETMODESET hNewVidPnTargetModeSet = NULL;
    1406     const DXGK_VIDPNTARGETMODESET_INTERFACE *pNewVidPnTargetModeSetInterface;
    1407 
    1408     Assert(pDevExt->fComplexTopologiesEnabled || VidPnSourceId == VidPnTargetId);
    1409 
    1410     D3DKMDT_HVIDPNSOURCEMODESET hCurVidPnSourceModeSet;
    1411     const DXGK_VIDPNSOURCEMODESET_INTERFACE *pCurVidPnSourceModeSetInterface;
    1412     NTSTATUS Status = pVidPnInterface->pfnAcquireSourceModeSet(hVidPn,
    1413                 VidPnSourceId,
    1414                 &hCurVidPnSourceModeSet,
    1415                 &pCurVidPnSourceModeSetInterface);
    1416     if (!NT_SUCCESS(Status))
    1417     {
    1418         AssertFailed();
    1419         return Status;
    1420     }
    1421 
    1422     CONST D3DKMDT_VIDPN_SOURCE_MODE* pPinnedVidPnSourceModeInfo;
    1423     Status = pCurVidPnSourceModeSetInterface->pfnAcquirePinnedModeInfo(hCurVidPnSourceModeSet, &pPinnedVidPnSourceModeInfo);
    1424     if (Status == STATUS_GRAPHICS_MODE_NOT_PINNED)
    1425     {
    1426         pPinnedVidPnSourceModeInfo = NULL;
    1427         Status = STATUS_SUCCESS;
    1428     }
    1429     else if (!NT_SUCCESS(Status))
    1430     {
    1431         LOGREL(("pfnAcquirePinnedModeInfo failed Status(0x%x)", Status));
    1432         AssertFailed();
    1433     }
    1434     else
    1435     {
    1436         Assert(pPinnedVidPnSourceModeInfo);
    1437     }
    1438 
    1439     if (NT_SUCCESS(Status))
    1440     {
    1441         Status = pVidPnInterface->pfnCreateNewTargetModeSet(hVidPn,
    1442                             VidPnTargetId,
    1443                             &hNewVidPnTargetModeSet,
    1444                             &pNewVidPnTargetModeSetInterface);
    1445         if (NT_SUCCESS(Status))
    1446         {
    1447             Assert(hNewVidPnTargetModeSet);
    1448             Assert(pDevExt->fComplexTopologiesEnabled || VidPnSourceId == VidPnTargetId);
    1449 //            if (VidPnSourceId == VidPnTargetId && pCbContext->apPathInfos[VidPnTargetId].enmState == VBOXVIDPNPATHITEM_STATE_PRESENT)
    1450             {
    1451                 for (uint32_t i = 0; i < pInfo->cResolutions; ++i)
     1404                WARN(("pfnCreateNewTargetModeSet failed %#x", Status));
     1405
     1406            Assert(!NT_SUCCESS(Status));
     1407
     1408            return Status;
     1409        } while (0);
     1410
     1411        if (fNewSource)
     1412        {
     1413            do {
     1414                D3DKMDT_HVIDPNSOURCEMODESET hVidPnModeSet;
     1415                const DXGK_VIDPNSOURCEMODESET_INTERFACE *pVidPnModeSetInterface;
     1416
     1417                Status = pVidPnInterface->pfnCreateNewSourceModeSet(hVidPn,
     1418                                    iSource,
     1419                                    &hVidPnModeSet,
     1420                                    &pVidPnModeSetInterface);
     1421                if (NT_SUCCESS(Status))
    14521422                {
    1453                     D3DKMDT_2DREGION *pResolution = &pInfo->aResolutions[i];
    1454                     if (pPinnedVidPnSourceModeInfo)
     1423                    D3DKMDT_VIDPN_SOURCE_MODE *pVidPnModeInfo;
     1424                    Status = pVidPnModeSetInterface->pfnCreateNewModeInfo(hVidPnModeSet, &pVidPnModeInfo);
     1425                    if (NT_SUCCESS(Status))
    14551426                    {
    1456                         if (pPinnedVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cx != pResolution->cx
    1457                                 || pPinnedVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cy != pResolution->cy)
     1427                        vboxVidPnPopulateSourceModeInfo(pVidPnModeInfo, &pData->aSources[iSource].Size);
     1428
     1429                        IN_CONST_D3DKMDT_VIDEO_PRESENT_SOURCE_MODE_ID idMode = pVidPnModeInfo->Id;
     1430
     1431                        Status = pVidPnModeSetInterface->pfnAddMode(hVidPnModeSet, pVidPnModeInfo);
     1432                        if (NT_SUCCESS(Status))
    14581433                        {
    1459                             continue;
     1434                            pVidPnModeInfo = NULL;
     1435
     1436                            Status = pVidPnModeSetInterface->pfnPinMode(hVidPnModeSet, idMode);
     1437                            if (NT_SUCCESS(Status))
     1438                            {
     1439                                Status = pVidPnInterface->pfnAssignSourceModeSet(hVidPn, iSource, hVidPnModeSet);
     1440                                if (NT_SUCCESS(Status))
     1441                                {
     1442                                    LOG(("Recommended Source[%d] (%dx%d)", iSource, pData->aSources[iSource].Size.cx, pData->aSources[iSource].Size.cy));
     1443                                    break;
     1444                                }
     1445                                else
     1446                                    WARN(("pfnAssignSourceModeSet failed %#x", Status));
     1447                            }
     1448                            else
     1449                                WARN(("pfnPinMode failed %#x", Status));
     1450
     1451                        }
     1452                        else
     1453                            WARN(("pfnAddMode failed %#x", Status));
     1454
     1455                        if (pVidPnModeInfo)
     1456                        {
     1457                            NTSTATUS tmpStatus = pVidPnModeSetInterface->pfnReleaseModeInfo(hVidPnModeSet, pVidPnModeInfo);
     1458                            Assert(tmpStatus == STATUS_SUCCESS);
    14601459                        }
    14611460                    }
    1462 
    1463                     D3DKMDT_VIDPN_TARGET_MODE *pNewVidPnTargetModeInfo;
    1464                     Status = pNewVidPnTargetModeSetInterface->pfnCreateNewModeInfo(hNewVidPnTargetModeSet, &pNewVidPnTargetModeInfo);
    1465                     Assert(Status == STATUS_SUCCESS);
    1466                     if (NT_SUCCESS(Status))
    1467                     {
    1468                         Status = vboxVidPnPopulateTargetModeInfoFromLegacy(pNewVidPnTargetModeInfo, pResolution, i == pInfo->iPreferredResolution);
    1469                         if (NT_SUCCESS(Status))
    1470                         {
    1471                             Status = pNewVidPnTargetModeSetInterface->pfnAddMode(hNewVidPnTargetModeSet, pNewVidPnTargetModeInfo);
    1472                             if (NT_SUCCESS(Status))
    1473                             {
    1474                                 /* success */
    1475                                 continue;
    1476                             }
    1477                             else
    1478                                 WARN(("pfnAddMode failed, Status 0x%x", Status));
    1479                         }
    1480                         else
    1481                             WARN(("vboxVidPnPopulateTargetModeInfoFromLegacy failed, Status 0x%x", Status));
    1482 
    1483                         NTSTATUS tmpStatus = pNewVidPnTargetModeSetInterface->pfnReleaseModeInfo(hNewVidPnTargetModeSet, pNewVidPnTargetModeInfo);
    1484                         Assert(tmpStatus == STATUS_SUCCESS);
    1485                     }
    1486 
    1487                     /* we're here because of an error */
    1488                     Assert(!NT_SUCCESS(Status));
    1489                     /* ignore mode addition failure */
    1490                     Status = STATUS_SUCCESS;
    1491                     continue;
     1461                    else
     1462                        WARN(("pfnCreateNewSourceModeSet failed %#x", Status));
     1463
     1464                    NTSTATUS tmpStatus = pVidPnInterface->pfnReleaseSourceModeSet(hVidPn, hVidPnModeSet);
     1465                    Assert(tmpStatus == STATUS_SUCCESS);
    14921466                }
    1493             }
    1494         }
    1495         else
    1496         {
    1497             AssertFailed();
    1498         }
    1499     }
    1500     else
    1501     {
    1502         AssertFailed();
    1503     }
    1504 
    1505     if (pPinnedVidPnSourceModeInfo)
    1506     {
    1507         NTSTATUS tmpStatus = pCurVidPnSourceModeSetInterface->pfnReleaseModeInfo(hCurVidPnSourceModeSet, pPinnedVidPnSourceModeInfo);
    1508         Assert(tmpStatus == STATUS_SUCCESS);
    1509     }
    1510 
    1511     NTSTATUS tmpStatus = pVidPnInterface->pfnReleaseSourceModeSet(hVidPn, hCurVidPnSourceModeSet);
    1512     Assert(tmpStatus == STATUS_SUCCESS);
    1513 
    1514     if (NT_SUCCESS(Status))
    1515     {
    1516         Assert(hNewVidPnTargetModeSet);
    1517         Status = pVidPnInterface->pfnAssignTargetModeSet(hVidPn, VidPnTargetId, hNewVidPnTargetModeSet);
    1518         if (!NT_SUCCESS(Status))
    1519         {
    1520             WARN(("\n\n!!!!!!!\n\n pfnAssignTargetModeSet failed, Status(0x%x)", Status));
    1521             tmpStatus = pVidPnInterface->pfnReleaseTargetModeSet(hVidPn, hNewVidPnTargetModeSet);
    1522             Assert(tmpStatus == STATUS_SUCCESS);
    1523         }
    1524     }
    1525 
    1526     return Status;
    1527 }
    1528 
    1529 static NTSTATUS vboxVidPnCofuncModalityForPathSource(PVBOXVIDPNCOFUNCMODALITY pCbContext,
    1530         D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
    1531 {
    1532     PVBOXMP_DEVEXT pDevExt = pCbContext->pDevExt;
    1533     D3DKMDT_HVIDPN hVidPn = pCbContext->pEnumCofuncModalityArg->hConstrainingVidPn;
    1534     const DXGK_VIDPN_INTERFACE* pVidPnInterface = pCbContext->pVidPnInterface;
    1535     PVBOXWDDM_VIDEOMODES_INFO pInfo = &pCbContext->pInfos[VidPnTargetId];
    1536     D3DKMDT_HVIDPNSOURCEMODESET hNewVidPnSourceModeSet = NULL;
    1537     const DXGK_VIDPNSOURCEMODESET_INTERFACE *pNewVidPnSourceModeSetInterface;
    1538 
    1539     Assert(pDevExt->fComplexTopologiesEnabled || VidPnSourceId == VidPnTargetId);
    1540 
    1541     D3DKMDT_HVIDPNTARGETMODESET hCurVidPnTargetModeSet;
    1542     const DXGK_VIDPNTARGETMODESET_INTERFACE *pCurVidPnTargetModeSetInterface;
    1543     NTSTATUS Status = pVidPnInterface->pfnAcquireTargetModeSet(hVidPn,
    1544                         VidPnTargetId,
    1545                         &hCurVidPnTargetModeSet,
    1546                         &pCurVidPnTargetModeSetInterface);
    1547     if (!NT_SUCCESS(Status))
    1548     {
    1549         AssertFailed();
    1550         return Status;
    1551     }
    1552 
    1553     CONST D3DKMDT_VIDPN_TARGET_MODE* pPinnedVidPnTargetModeInfo;
    1554     Status = pCurVidPnTargetModeSetInterface->pfnAcquirePinnedModeInfo(hCurVidPnTargetModeSet, &pPinnedVidPnTargetModeInfo);
    1555     if (Status == STATUS_GRAPHICS_MODE_NOT_PINNED)
    1556     {
    1557         pPinnedVidPnTargetModeInfo = NULL;
    1558         Status = STATUS_SUCCESS;
    1559     }
    1560     else if (!NT_SUCCESS(Status))
    1561     {
    1562         LOGREL(("pfnAcquirePinnedModeInfo failed Status(0x%x)", Status));
    1563         AssertFailed();
    1564     }
    1565     else
    1566     {
    1567         Assert(pPinnedVidPnTargetModeInfo);
    1568     }
    1569 
    1570     if (NT_SUCCESS(Status))
    1571     {
    1572         NTSTATUS Status = pVidPnInterface->pfnCreateNewSourceModeSet(hVidPn,
    1573                             VidPnSourceId,
    1574                             &hNewVidPnSourceModeSet,
    1575                             &pNewVidPnSourceModeSetInterface);
    1576         if (NT_SUCCESS(Status))
    1577         {
    1578             Assert(hNewVidPnSourceModeSet);
    1579             Assert(pDevExt->fComplexTopologiesEnabled || VidPnSourceId == VidPnTargetId);
    1580 //            if (VidPnSourceId == VidPnTargetId && pCbContext->apPathInfos[VidPnSourceId].enmState == VBOXVIDPNPATHITEM_STATE_PRESENT)
    1581             {
    1582                 for (uint32_t i = 0; i < pInfo->cModes; ++i)
    1583                 {
    1584                     VIDEO_MODE_INFORMATION *pMode = &pInfo->aModes[i];
    1585                     if (pPinnedVidPnTargetModeInfo)
    1586                     {
    1587                         if (pPinnedVidPnTargetModeInfo->VideoSignalInfo.ActiveSize.cx != pMode->VisScreenWidth
    1588                                 || pPinnedVidPnTargetModeInfo->VideoSignalInfo.ActiveSize.cy != pMode->VisScreenHeight)
    1589                         {
    1590                             continue;
    1591                         }
    1592                     }
    1593 
    1594                     D3DKMDT_VIDPN_SOURCE_MODE *pNewVidPnSourceModeInfo;
    1595                     Status = pNewVidPnSourceModeSetInterface->pfnCreateNewModeInfo(hNewVidPnSourceModeSet, &pNewVidPnSourceModeInfo);
    1596                     if (NT_SUCCESS(Status))
    1597                     {
    1598                         Status = vboxVidPnPopulateSourceModeInfoFromLegacy(pNewVidPnSourceModeInfo, pMode);
    1599                         Assert(Status == STATUS_SUCCESS);
    1600                         if (NT_SUCCESS(Status))
    1601                         {
    1602                             Status = pNewVidPnSourceModeSetInterface->pfnAddMode(hNewVidPnSourceModeSet, pNewVidPnSourceModeInfo);
    1603                             if (NT_SUCCESS(Status))
    1604                             {
    1605                                 /* success */
    1606                                 continue;
    1607                             }
    1608                             else
    1609                                 WARN(("pfnAddMode failed, Status 0x%x", Status));
    1610                         }
    1611 
    1612                         NTSTATUS tmpStatus = pNewVidPnSourceModeSetInterface->pfnReleaseModeInfo(hNewVidPnSourceModeSet, pNewVidPnSourceModeInfo);
    1613                         Assert(tmpStatus == STATUS_SUCCESS);
    1614                     }
    1615                     else
    1616                         WARN(("pfnCreateNewModeInfo failed, Status 0x%x", Status));
    1617                     /* we're here because of an error */
    1618                     Assert(!NT_SUCCESS(Status));
    1619                     /* ignore mode addition failure */
    1620                     Status = STATUS_SUCCESS;
    1621                     continue;
    1622                 }
    1623             }
    1624         }
    1625         else
    1626         {
    1627             AssertFailed();
    1628         }
    1629     }
    1630     else
    1631     {
    1632         AssertFailed();
    1633     }
    1634 
    1635     if (pPinnedVidPnTargetModeInfo)
    1636     {
    1637         NTSTATUS tmpStatus = pCurVidPnTargetModeSetInterface->pfnReleaseModeInfo(hCurVidPnTargetModeSet, pPinnedVidPnTargetModeInfo);
    1638         Assert(tmpStatus == STATUS_SUCCESS);
    1639     }
    1640 
    1641     NTSTATUS tmpStatus = pVidPnInterface->pfnReleaseTargetModeSet(hVidPn, hCurVidPnTargetModeSet);
    1642     Assert(tmpStatus == STATUS_SUCCESS);
    1643 
    1644     if (NT_SUCCESS(Status))
    1645     {
    1646         Assert(hNewVidPnSourceModeSet);
    1647         Status = pVidPnInterface->pfnAssignSourceModeSet(hVidPn, VidPnSourceId, hNewVidPnSourceModeSet);
    1648         if (!NT_SUCCESS(Status))
    1649         {
    1650             WARN(("\n\n!!!!!!!\n\n pfnAssignSourceModeSet failed, Status(0x%x)", Status));
    1651             tmpStatus = pVidPnInterface->pfnReleaseSourceModeSet(hVidPn, hNewVidPnSourceModeSet);
    1652             Assert(tmpStatus == STATUS_SUCCESS);
    1653         }
    1654     }
    1655 
    1656     return Status;
    1657 }
    1658 
    1659 NTSTATUS vboxVidPnCofuncModalityForPath(PVBOXVIDPNCOFUNCMODALITY pCbContext,
    1660         D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
    1661 {
    1662     PVBOXMP_DEVEXT pDevExt = pCbContext->pDevExt;
    1663     D3DKMDT_HVIDPN hVidPn = pCbContext->pEnumCofuncModalityArg->hConstrainingVidPn;
    1664     const DXGK_VIDPN_INTERFACE* pVidPnInterface = pCbContext->pVidPnInterface;
    1665     NTSTATUS Status = STATUS_SUCCESS;
    1666     pCbContext->Status = STATUS_SUCCESS;
    1667     PVBOXWDDM_VIDEOMODES_INFO pInfo = &pCbContext->pInfos[VidPnTargetId];
    1668 
    1669     D3DKMDT_ENUMCOFUNCMODALITY_PIVOT_TYPE enmPivot = vboxVidPnCofuncModalityCurrentPathPivot(pCbContext->pEnumCofuncModalityArg, VidPnSourceId, VidPnTargetId);
    1670     BOOLEAN fHasPinnedMode = FALSE;
    1671     Status = vboxVidPnHasPinnedTargetMode(hVidPn, pVidPnInterface, VidPnTargetId, &fHasPinnedMode);
    1672     if (!NT_SUCCESS(Status))
    1673     {
    1674         AssertFailed();
    1675         return Status;
    1676     }
    1677 
    1678     BOOLEAN fNeedUpdate = enmPivot != D3DKMDT_EPT_VIDPNTARGET && !fHasPinnedMode;
    1679     if (fNeedUpdate)
    1680     {
    1681         Status = vboxVidPnCofuncModalityForPathTarget(pCbContext, VidPnSourceId, VidPnTargetId);
    1682     }
    1683 
    1684     if (NT_SUCCESS(Status))
    1685     {
    1686         fHasPinnedMode = FALSE;
    1687         Status = vboxVidPnHasPinnedSourceMode(hVidPn, pVidPnInterface, VidPnSourceId, &fHasPinnedMode);
    1688         if (!NT_SUCCESS(Status))
    1689         {
    1690             AssertFailed();
    1691             return Status;
    1692         }
    1693 
    1694         fNeedUpdate = enmPivot != D3DKMDT_EPT_VIDPNSOURCE && !fHasPinnedMode;
    1695         if (fNeedUpdate)
    1696         {
    1697             Status = vboxVidPnCofuncModalityForPathSource(pCbContext, VidPnSourceId, VidPnTargetId);
    1698         }
    1699     }
    1700 
    1701     return Status;
    1702 }
    1703 
    1704 DECLCALLBACK(BOOLEAN) vboxVidPnCofuncModalityPathEnum(D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface,
    1705         const D3DKMDT_VIDPN_PRESENT_PATH *pNewVidPnPresentPathInfo, PVOID pContext)
    1706 {
    1707     PVBOXVIDPNCOFUNCMODALITY pCbContext = (PVBOXVIDPNCOFUNCMODALITY)pContext;
    1708     D3DKMDT_VIDPN_PRESENT_PATH AdjustedPath = {0};
    1709     NTSTATUS Status = STATUS_SUCCESS;
    1710     bool bUpdatePath = false;
    1711     AdjustedPath.VidPnSourceId = pNewVidPnPresentPathInfo->VidPnSourceId;
    1712     AdjustedPath.VidPnTargetId = pNewVidPnPresentPathInfo->VidPnTargetId;
    1713     AdjustedPath.ContentTransformation = pNewVidPnPresentPathInfo->ContentTransformation;
    1714     AdjustedPath.CopyProtection = pNewVidPnPresentPathInfo->CopyProtection;
    1715 
    1716     if (pNewVidPnPresentPathInfo->ContentTransformation.Scaling == D3DKMDT_VPPS_UNPINNED)
    1717     {
    1718         AdjustedPath.ContentTransformation.ScalingSupport.Identity = TRUE;
    1719         bUpdatePath = true;
    1720     }
    1721 
    1722     if (pNewVidPnPresentPathInfo->ContentTransformation.Rotation == D3DKMDT_VPPR_UNPINNED)
    1723     {
    1724         AdjustedPath.ContentTransformation.RotationSupport.Identity = TRUE;
    1725         bUpdatePath = true;
    1726     }
    1727 
    1728     if (bUpdatePath)
    1729     {
    1730         Status = pVidPnTopologyInterface->pfnUpdatePathSupportInfo(hVidPnTopology, &AdjustedPath);
    1731         Assert(Status == STATUS_SUCCESS);
    1732     }
    1733 
    1734     Status = vboxVidPnCofuncModalityForPath(pCbContext, pNewVidPnPresentPathInfo->VidPnSourceId, pNewVidPnPresentPathInfo->VidPnTargetId);
    1735 
    1736     pVidPnTopologyInterface->pfnReleasePathInfo(hVidPnTopology, pNewVidPnPresentPathInfo);
    1737 
    1738     pCbContext->Status = Status;
    1739     Assert(Status == STATUS_SUCCESS);
    1740     return Status == STATUS_SUCCESS;
     1467                else
     1468                    WARN(("pfnCreateNewSourceModeSet failed %#x", Status));
     1469
     1470                Assert(!NT_SUCCESS(Status));
     1471
     1472                return Status;
     1473            } while (0);
     1474        }
     1475    }
     1476
     1477    Assert(NT_SUCCESS(Status));
     1478    return STATUS_SUCCESS;
    17411479}
    17421480
     
    18641602}
    18651603
    1866 typedef struct VBOXVIDPNGETPATHSINFO
    1867 {
    1868     PVBOXMP_DEVEXT pDevExt;
    1869     NTSTATUS Status;
    1870     BOOLEAN fBreakOnDisabled;
    1871     BOOLEAN fDisabledFound;
    1872 } VBOXVIDPNGETPATHSINFO, *PVBOXVIDPNGETPATHSINFO;
    1873 
    1874 static DECLCALLBACK(BOOLEAN) vboxVidPnCheckTopologyEnum(D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface,
    1875         const D3DKMDT_VIDPN_PRESENT_PATH *pNewVidPnPresentPathInfo, PVOID pContext)
    1876 {
    1877     PVBOXVIDPNGETPATHSINFO pCbContext = (PVBOXVIDPNGETPATHSINFO)pContext;
    1878     NTSTATUS Status = STATUS_SUCCESS;
    1879     CONST D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId = pNewVidPnPresentPathInfo->VidPnSourceId;
    1880     CONST D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId = pNewVidPnPresentPathInfo->VidPnTargetId;
    1881     BOOLEAN fDisabledFound = !vboxVidPnIsPathSupported(pCbContext->pDevExt, pNewVidPnPresentPathInfo);
    1882 
    1883     pCbContext->fDisabledFound |= fDisabledFound;
    1884     pCbContext->Status = Status;
    1885     if (!NT_SUCCESS(Status))
    1886         return FALSE; /* do not continue on failure */
    1887 
    1888     return !fDisabledFound || !pCbContext->fBreakOnDisabled;
    1889 }
    1890 
    1891 /* we currently support only 0 -> 0, 1 -> 1, 2 -> 2 paths, AND 0 -> 0 must be present
    1892  * this routine disables all paths unsupported */
    1893 NTSTATUS VBoxVidPnCheckTopology(PVBOXMP_DEVEXT pDevExt, D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface, BOOLEAN *pfSupported)
    1894 {
    1895     VBOXVIDPNGETPATHSINFO CbContext = {0};
    1896     CbContext.pDevExt = pDevExt;
    1897     CbContext.Status = STATUS_SUCCESS;
    1898     CbContext.fBreakOnDisabled = FALSE;
    1899     CbContext.fDisabledFound = FALSE;
    1900     NTSTATUS Status = vboxVidPnEnumPaths(hVidPnTopology, pVidPnTopologyInterface, vboxVidPnCheckTopologyEnum, &CbContext);
    1901     if (!NT_SUCCESS(Status))
    1902     {
    1903         WARN(("vboxVidPnEnumPaths failed Status()0x%x\n", Status));
     1604NTSTATUS VBoxVidPnIsSupported(PVBOXMP_DEVEXT pDevExt, D3DKMDT_HVIDPN hVidPn, BOOLEAN *pfSupported)
     1605{
     1606    *pfSupported = FALSE;
     1607
     1608    const DXGK_VIDPN_INTERFACE* pVidPnInterface = NULL;
     1609    NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbQueryVidPnInterface(hVidPn, DXGK_VIDPN_INTERFACE_VERSION_V1, &pVidPnInterface);
     1610    if (!NT_SUCCESS(Status))
     1611    {
     1612        WARN(("DxgkCbQueryVidPnInterface failed Status()0x%x\n", Status));
    19041613        return Status;
    19051614    }
    19061615
    1907     Status = CbContext.Status;
    1908     if (!NT_SUCCESS(Status))
    1909     {
    1910         WARN(("vboxVidPnCheckTopologyEnum returned failed Status()0x%x\n", Status));
     1616#ifdef VBOXWDDM_DEBUG_VIDPN
     1617    vboxVidPnDumpVidPn(">>>>IsSupported VidPN (IN) : >>>>\n", pDevExt, hVidPn, pVidPnInterface, "<<<<<<<<<<<<<<<<<<<<\n");
     1618#endif
     1619
     1620    D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology;
     1621    const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface;
     1622    Status = pVidPnInterface->pfnGetTopology(hVidPn, &hVidPnTopology, &pVidPnTopologyInterface);
     1623    if (!NT_SUCCESS(Status))
     1624    {
     1625        WARN(("pfnGetTopology failed Status()0x%x\n", Status));
    19111626        return Status;
    19121627    }
    19131628
    1914     BOOLEAN fSupported = !CbContext.fDisabledFound;
    1915 
    1916     /* now check if 0->0 path is present and enabled, and if not, disable everything */
    1917 //    if (cItems && aItems[0].enmState != VBOXVIDPNPATHITEM_STATE_PRESENT)
    1918 //    {
    1919 //        LOG(("path 0 not set to present\n"));
    1920 ////        for (i = 0; i < cItems; ++i)
    1921 ////        {
    1922 ////            if (aItems[i].enmState == VBOXVIDPNPATHITEM_STATE_PRESENT)
    1923 ////                aItems[i].enmState = VBOXVIDPNPATHITEM_STATE_DISABLED;
    1924 ////        }
    1925 //        fSupported = FALSE;
    1926 //    }
    1927 
    1928     if (pfSupported)
    1929         *pfSupported = fSupported;
     1629    VBOXVIDPN_PATH_ITER PathIter;
     1630    const D3DKMDT_VIDPN_PRESENT_PATH * pPath;
     1631    VBOXCMDVBVA_SCREENMAP_DECL(uint32_t, aVisitedTargetMap);
     1632    VBOXCMDVBVA_SCREENMAP_DECL(uint32_t, aModeMap);
     1633    CR_SORTARRAY aModes[VBOX_VIDEO_MAX_SCREENS];
     1634
     1635    memset(aVisitedTargetMap, 0, sizeof (aVisitedTargetMap));
     1636    memset(aModeMap, 0, sizeof (aModeMap));
     1637    memset(aModes, 0, sizeof (aModes));
     1638
     1639    CR_SORTARRAY TargetMode = {0};
     1640
     1641    BOOLEAN fSupported = TRUE;
     1642    /* collect info first */
     1643    VBoxVidPnPathIterInit(&PathIter, hVidPnTopology, pVidPnTopologyInterface);
     1644    while ((pPath = VBoxVidPnPathIterNext(&PathIter)) != NULL)
     1645    {
     1646        CrSaClear(&TargetMode);
     1647        D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId = pPath->VidPnSourceId;
     1648        D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId = pPath->VidPnTargetId;
     1649        /* actually vidpn topology should contain only one target info, right? */
     1650        Assert(!ASMBitTest(aVisitedTargetMap, VidPnTargetId));
     1651        ASMBitSet(aVisitedTargetMap, VidPnTargetId);
     1652
     1653        if (!vboxVidPnIsPathSupported(pDevExt, pPath))
     1654        {
     1655            fSupported = FALSE;
     1656            break;
     1657        }
     1658
     1659        RTRECTSIZE TargetSize;
     1660        RTRECTSIZE SourceSize;
     1661        Status = vboxVidPnQueryPinnedTargetMode(hVidPn, pVidPnInterface, VidPnTargetId, &TargetSize);
     1662        if (!NT_SUCCESS(Status))
     1663        {
     1664            WARN(("vboxVidPnQueryPinnedTargetMode failed %#x", Status));
     1665            break;
     1666        }
     1667
     1668        Status = vboxVidPnQueryPinnedSourceMode(hVidPn, pVidPnInterface, VidPnSourceId, &SourceSize);
     1669        if (!NT_SUCCESS(Status))
     1670        {
     1671            WARN(("vboxVidPnQueryPinnedSourceMode failed %#x", Status));
     1672            break;
     1673        }
     1674
     1675        if (memcmp(&TargetSize, &SourceSize, sizeof (TargetSize)) && TargetSize.cx)
     1676        {
     1677            if (!SourceSize.cx)
     1678                WARN(("not expected?"));
     1679
     1680            fSupported = FALSE;
     1681            break;
     1682        }
     1683
     1684        {
     1685            D3DKMDT_HVIDPNTARGETMODESET hVidPnModeSet;
     1686            const DXGK_VIDPNTARGETMODESET_INTERFACE *pVidPnModeSetInterface;
     1687            Status = pVidPnInterface->pfnAcquireTargetModeSet(hVidPn,
     1688                        VidPnTargetId,
     1689                        &hVidPnModeSet,
     1690                        &pVidPnModeSetInterface);
     1691            if (!NT_SUCCESS(Status))
     1692            {
     1693                WARN(("pfnAcquireTargetModeSet failed %#x", Status));
     1694                break;
     1695            }
     1696
     1697            Status = vboxVidPnTargetModeSetToArray(hVidPnModeSet, pVidPnModeSetInterface, &TargetMode);
     1698            if (!NT_SUCCESS(Status))
     1699            {
     1700                WARN(("vboxVidPnTargetModeSetToArray failed %#x", Status));
     1701                break;
     1702            }
     1703
     1704            NTSTATUS tmpStatus = pVidPnInterface->pfnReleaseTargetModeSet(hVidPn, hVidPnModeSet);
     1705            Assert(tmpStatus == STATUS_SUCCESS);
     1706        }
     1707
     1708        if (!ASMBitTest(aModeMap, VidPnSourceId))
     1709        {
     1710            D3DKMDT_HVIDPNSOURCEMODESET hVidPnModeSet;
     1711            const DXGK_VIDPNSOURCEMODESET_INTERFACE *pVidPnModeSetInterface;
     1712            Status = pVidPnInterface->pfnAcquireSourceModeSet(hVidPn,
     1713                        VidPnSourceId,
     1714                        &hVidPnModeSet,
     1715                        &pVidPnModeSetInterface);
     1716            if (!NT_SUCCESS(Status))
     1717            {
     1718                WARN(("pfnAcquireSourceModeSet failed %#x", Status));
     1719                break;
     1720            }
     1721
     1722            Status = vboxVidPnSourceModeSetToArray(hVidPnModeSet, pVidPnModeSetInterface, &aModes[VidPnSourceId]);
     1723            if (!NT_SUCCESS(Status))
     1724            {
     1725                WARN(("vboxVidPnSourceModeSetToArray failed %#x", Status));
     1726                break;
     1727            }
     1728
     1729            NTSTATUS tmpStatus = pVidPnInterface->pfnReleaseSourceModeSet(hVidPn, hVidPnModeSet);
     1730            Assert(tmpStatus == STATUS_SUCCESS);
     1731
     1732            ASMBitSet(aModeMap, VidPnSourceId);
     1733        }
     1734
     1735        if (CrSaCmp(&aModes[VidPnSourceId], &TargetMode))
     1736        {
     1737            WARN(("not expected 2?"));
     1738            fSupported = FALSE;
     1739            break;
     1740        }
     1741
     1742#if 0
     1743        const CR_SORTARRAY *pSupportedModes = VBoxWddmVModesGet(pDevExt, VidPnTargetId);
     1744        if (!CrSaCovers(pSupportedModes, &TargetMode))
     1745        {
     1746            WARN(("not expected 3?"));
     1747            fSupported = FALSE;
     1748            break;
     1749        }
     1750#endif
     1751    }
     1752
     1753    VBoxVidPnPathIterTerm(&PathIter);
     1754
     1755    if (!NT_SUCCESS(Status))
     1756        goto done;
     1757
     1758    Status = VBoxVidPnPathIterStatus(&PathIter);
     1759    if (!NT_SUCCESS(Status))
     1760    {
     1761        WARN(("PathIter failed Status()0x%x\n", Status));
     1762        goto done;
     1763    }
     1764
     1765    *pfSupported = fSupported;
     1766done:
     1767
     1768    CrSaCleanup(&TargetMode);
     1769
     1770    for (uint32_t i = 0; i < (uint32_t)VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
     1771    {
     1772        CrSaCleanup(&aModes[i]);
     1773    }
     1774
     1775
     1776    return Status;
     1777}
     1778
     1779NTSTATUS VBoxVidPnCofuncModality(PVBOXMP_DEVEXT pDevExt, D3DKMDT_HVIDPN hVidPn, D3DKMDT_ENUMCOFUNCMODALITY_PIVOT_TYPE enmPivot, const DXGK_ENUM_PIVOT *pPivot)
     1780{
     1781    const DXGK_VIDPN_INTERFACE* pVidPnInterface = NULL;
     1782    NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbQueryVidPnInterface(hVidPn, DXGK_VIDPN_INTERFACE_VERSION_V1, &pVidPnInterface);
     1783    if (!NT_SUCCESS(Status))
     1784    {
     1785        WARN(("DxgkCbQueryVidPnInterface failed Status()0x%x\n", Status));
     1786        return Status;
     1787    }
     1788
     1789#ifdef VBOXWDDM_DEBUG_VIDPN
     1790    vboxVidPnDumpCofuncModalityArg(">>>>MODALITY Args: ", pEnumCofuncModalityArg, "\n");
     1791    vboxVidPnDumpVidPn(">>>>MODALITY VidPN (IN) : >>>>\n", pDevExt, pEnumCofuncModalityArg->hConstrainingVidPn, pVidPnInterface, "<<<<<<<<<<<<<<<<<<<<\n");
     1792#endif
     1793
     1794    D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology;
     1795    const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface;
     1796    Status = pVidPnInterface->pfnGetTopology(hVidPn, &hVidPnTopology, &pVidPnTopologyInterface);
     1797    if (!NT_SUCCESS(Status))
     1798    {
     1799        WARN(("pfnGetTopology failed Status()0x%x\n", Status));
     1800        return Status;
     1801    }
     1802
     1803    VBOXVIDPN_PATH_ITER PathIter;
     1804    const D3DKMDT_VIDPN_PRESENT_PATH * pPath;
     1805    VBOXCMDVBVA_SCREENMAP_DECL(uint32_t, aVisitedTargetMap);
     1806    VBOXCMDVBVA_SCREENMAP_DECL(uint32_t, aAdjustedModeMap);
     1807    CR_SORTARRAY aModes[VBOX_VIDEO_MAX_SCREENS];
     1808
     1809    memset(aVisitedTargetMap, 0, sizeof (aVisitedTargetMap));
     1810    memset(aAdjustedModeMap, 0, sizeof (aAdjustedModeMap));
     1811    memset(aModes, 0, sizeof (aModes));
     1812
     1813    /* collect info first */
     1814    VBoxVidPnPathIterInit(&PathIter, hVidPnTopology, pVidPnTopologyInterface);
     1815    while ((pPath = VBoxVidPnPathIterNext(&PathIter)) != NULL)
     1816    {
     1817        D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId = pPath->VidPnSourceId;
     1818        D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId = pPath->VidPnTargetId;
     1819        /* actually vidpn topology should contain only one target info, right? */
     1820        Assert(!ASMBitTest(aVisitedTargetMap, VidPnTargetId));
     1821        ASMBitSet(aVisitedTargetMap, VidPnTargetId);
     1822
     1823        D3DKMDT_ENUMCOFUNCMODALITY_PIVOT_TYPE enmCurPivot = vboxVidPnCofuncModalityCurrentPathPivot(enmPivot, pPivot, VidPnSourceId, VidPnTargetId);
     1824
     1825        Status = vboxVidPnCollectInfoForPathTarget(pDevExt,
     1826                hVidPn,
     1827                pVidPnInterface,
     1828                enmCurPivot,
     1829                aAdjustedModeMap,
     1830                aModes,
     1831                VidPnSourceId, VidPnTargetId);
     1832        if (!NT_SUCCESS(Status))
     1833        {
     1834            WARN(("vboxVidPnCollectInfoForPathTarget failed Status(0x%x\n", Status));
     1835            break;
     1836        }
     1837
     1838        Assert(CrSaCovers(VBoxWddmVModesGet(pDevExt, VidPnTargetId), &aModes[VidPnTargetId]));
     1839
     1840        Status = vboxVidPnCollectInfoForPathSource(pDevExt,
     1841                hVidPn,
     1842                pVidPnInterface,
     1843                enmCurPivot,
     1844                aAdjustedModeMap,
     1845                aModes,
     1846                VidPnSourceId, VidPnTargetId);
     1847        if (!NT_SUCCESS(Status))
     1848        {
     1849            WARN(("vboxVidPnCollectInfoForPathSource failed Status(0x%x\n", Status));
     1850            break;
     1851        }
     1852
     1853        Assert(CrSaCovers(VBoxWddmVModesGet(pDevExt, VidPnTargetId), &aModes[VidPnTargetId]));
     1854    }
     1855
     1856    VBoxVidPnPathIterTerm(&PathIter);
     1857
     1858    if (!NT_SUCCESS(Status))
     1859        goto done;
     1860
     1861    Status = VBoxVidPnPathIterStatus(&PathIter);
     1862    if (!NT_SUCCESS(Status))
     1863    {
     1864        WARN(("PathIter failed Status()0x%x\n", Status));
     1865        goto done;
     1866    }
     1867
     1868    /* now we have collected all the necessary info,
     1869     * go ahead and apply it */
     1870    memset(aVisitedTargetMap, 0, sizeof (aVisitedTargetMap));
     1871    VBoxVidPnPathIterInit(&PathIter, hVidPnTopology, pVidPnTopologyInterface);
     1872    while ((pPath = VBoxVidPnPathIterNext(&PathIter)) != NULL)
     1873    {
     1874        D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId = pPath->VidPnSourceId;
     1875        D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId = pPath->VidPnTargetId;
     1876        /* actually vidpn topology should contain only one target info, right? */
     1877        Assert(!ASMBitTest(aVisitedTargetMap, VidPnTargetId));
     1878        ASMBitSet(aVisitedTargetMap, VidPnTargetId);
     1879
     1880        D3DKMDT_ENUMCOFUNCMODALITY_PIVOT_TYPE enmCurPivot = vboxVidPnCofuncModalityCurrentPathPivot(enmPivot, pPivot, VidPnSourceId, VidPnTargetId);
     1881
     1882        bool bUpdatePath = false;
     1883        D3DKMDT_VIDPN_PRESENT_PATH AdjustedPath = {0};
     1884        AdjustedPath.VidPnSourceId = pPath->VidPnSourceId;
     1885        AdjustedPath.VidPnTargetId = pPath->VidPnTargetId;
     1886        AdjustedPath.ContentTransformation = pPath->ContentTransformation;
     1887        AdjustedPath.CopyProtection = pPath->CopyProtection;
     1888
     1889        if (pPath->ContentTransformation.Scaling == D3DKMDT_VPPS_UNPINNED)
     1890        {
     1891            AdjustedPath.ContentTransformation.ScalingSupport.Identity = TRUE;
     1892            bUpdatePath = true;
     1893        }
     1894
     1895        if (pPath->ContentTransformation.Rotation == D3DKMDT_VPPR_UNPINNED)
     1896        {
     1897            AdjustedPath.ContentTransformation.RotationSupport.Identity = TRUE;
     1898            bUpdatePath = true;
     1899        }
     1900
     1901        if (bUpdatePath)
     1902        {
     1903            Status = pVidPnTopologyInterface->pfnUpdatePathSupportInfo(hVidPnTopology, &AdjustedPath);
     1904            if (!NT_SUCCESS(Status))
     1905            {
     1906                WARN(("pfnUpdatePathSupportInfo failed Status()0x%x\n", Status));
     1907                goto done;
     1908            }
     1909        }
     1910
     1911        Assert(CrSaCovers(VBoxWddmVModesGet(pDevExt, VidPnTargetId), &aModes[VidPnTargetId]));
     1912
     1913        Status = vboxVidPnApplyInfoForPathTarget(pDevExt,
     1914                hVidPn,
     1915                pVidPnInterface,
     1916                enmCurPivot,
     1917                aAdjustedModeMap,
     1918                aModes,
     1919                VidPnSourceId, VidPnTargetId);
     1920        if (!NT_SUCCESS(Status))
     1921        {
     1922            WARN(("vboxVidPnApplyInfoForPathTarget failed Status(0x%x\n", Status));
     1923            break;
     1924        }
     1925
     1926        Status = vboxVidPnApplyInfoForPathSource(pDevExt,
     1927                hVidPn,
     1928                pVidPnInterface,
     1929                enmCurPivot,
     1930                aAdjustedModeMap,
     1931                aModes,
     1932                VidPnSourceId, VidPnTargetId);
     1933        if (!NT_SUCCESS(Status))
     1934        {
     1935            WARN(("vboxVidPnApplyInfoForPathSource failed Status(0x%x\n", Status));
     1936            break;
     1937        }
     1938    }
     1939
     1940    VBoxVidPnPathIterTerm(&PathIter);
     1941
     1942    if (!NT_SUCCESS(Status))
     1943        goto done;
     1944
     1945    Status = VBoxVidPnPathIterStatus(&PathIter);
     1946    if (!NT_SUCCESS(Status))
     1947    {
     1948        WARN(("PathIter failed Status()0x%x\n", Status));
     1949        goto done;
     1950    }
     1951
     1952done:
     1953
     1954    for (uint32_t i = 0; i < (uint32_t)VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
     1955    {
     1956        CrSaCleanup(&aModes[i]);
     1957    }
    19301958
    19311959    return Status;
     
    23992427}
    24002428
    2401 typedef struct VBOXVIDPNCOMMIT
    2402 {
    2403     NTSTATUS Status;
    2404     PVBOXMP_DEVEXT pDevExt;
    2405     D3DKMDT_HVIDPN hVidPn;
    2406     const DXGK_VIDPN_INTERFACE* pVidPnInterface;
    2407     PVBOXWDDM_ALLOCATION pAllocation;
    2408     VBOXWDDM_SOURCE *paSources;
    2409     VBOXWDDM_TARGET *paTargets;
    2410 } VBOXVIDPNCOMMIT, *PVBOXVIDPNCOMMIT;
    2411 
    2412 DECLCALLBACK(BOOLEAN) vboxVidPnCommitPathEnum(D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface,
    2413         const D3DKMDT_VIDPN_PRESENT_PATH *pVidPnPresentPathInfo, PVOID pContext)
    2414 {
    2415     NTSTATUS Status = STATUS_SUCCESS;
    2416     PVBOXVIDPNCOMMIT pCommitInfo = (PVBOXVIDPNCOMMIT)pContext;
    2417     PVBOXMP_DEVEXT pDevExt = pCommitInfo->pDevExt;
    2418     const D3DKMDT_HVIDPN hDesiredVidPn = pCommitInfo->hVidPn;
    2419     const DXGK_VIDPN_INTERFACE* pVidPnInterface = pCommitInfo->pVidPnInterface;
    2420 
    2421     Status = VBoxVidPnCommitSourceModeForSrcId(pDevExt, hDesiredVidPn, pVidPnInterface, pCommitInfo->pAllocation,
    2422             pVidPnPresentPathInfo->VidPnSourceId, pCommitInfo->paSources, pCommitInfo->paTargets);
    2423     if (Status != STATUS_SUCCESS)
    2424         WARN(("VBoxVidPnCommitSourceModeForSrcId failed Status(0x%x)", Status));
    2425 
    2426     pCommitInfo->Status = Status;
    2427     pVidPnTopologyInterface->pfnReleasePathInfo(hVidPnTopology, pVidPnPresentPathInfo);
    2428     return Status == STATUS_SUCCESS;
    2429 }
    2430 
    24312429NTSTATUS VBoxVidPnCommitAll(PVBOXMP_DEVEXT pDevExt, const D3DKMDT_HVIDPN hDesiredVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface,
    24322430        PVBOXWDDM_ALLOCATION pAllocation,
     
    24612459    VBoxVidPnStCleanup(paSources, paTargets, VBoxCommonFromDeviceExt(pDevExt)->cDisplays);
    24622460
    2463     VBOXVIDPNCOMMIT CbContext;
    2464     memset(&CbContext, 0, sizeof (CbContext));
    2465     CbContext.pDevExt = pDevExt;
    2466     CbContext.hVidPn = hDesiredVidPn;
    2467     CbContext.pVidPnInterface = pVidPnInterface;
    2468     CbContext.pAllocation = pAllocation;
    2469     CbContext.paSources = paSources;
    2470     CbContext.paTargets = paTargets;
    2471     Status = vboxVidPnEnumPaths(hVidPnTopology, pVidPnTopologyInterface,
    2472                 vboxVidPnCommitPathEnum, &CbContext);
    2473     if (!NT_SUCCESS(Status))
    2474     {
    2475         WARN(("vboxVidPnEnumPaths failed Status 0x%x", Status));
     2461    VBOXVIDPN_PATH_ITER PathIter;
     2462    const D3DKMDT_VIDPN_PRESENT_PATH *pPath;
     2463    VBoxVidPnPathIterInit(&PathIter, hVidPnTopology, pVidPnTopologyInterface);
     2464    while ((pPath = VBoxVidPnPathIterNext(&PathIter)) != NULL)
     2465    {
     2466        Status = VBoxVidPnCommitSourceModeForSrcId(pDevExt, hDesiredVidPn, pVidPnInterface, pAllocation,
     2467                    pPath->VidPnSourceId, paSources, paTargets);
     2468        if (Status != STATUS_SUCCESS)
     2469        {
     2470            WARN(("VBoxVidPnCommitSourceModeForSrcId failed Status(0x%x)", Status));
     2471            break;
     2472        }
     2473    }
     2474
     2475    VBoxVidPnPathIterTerm(&PathIter);
     2476
     2477    if (!NT_SUCCESS(Status))
     2478    {
     2479        WARN((""));
    24762480        return Status;
    24772481    }
    24782482
    2479     Status = CbContext.Status;
    2480     if (!NT_SUCCESS(Status))
    2481     {
    2482         WARN(("vboxVidPnCommitPathEnum failed Status 0x%x", Status));
     2483    Status = VBoxVidPnPathIterStatus(&PathIter);
     2484    if (!NT_SUCCESS(Status))
     2485    {
     2486        WARN(("VBoxVidPnPathIterStatus failed Status 0x%x", Status));
    24832487        return Status;
    24842488    }
    24852489
    2486     return Status;
     2490    return STATUS_SUCCESS;
    24872491}
    24882492
Note: See TracChangeset for help on using the changeset viewer.

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