VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVidPn.cpp@ 95009

Last change on this file since 95009 was 95009, checked in by vboxsync, 3 years ago

WDDM: report both RGB and BGR graphics modes. bugref:9845

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 126.1 KB
Line 
1/* $Id: VBoxMPVidPn.cpp 95009 2022-05-13 16:45:53Z vboxsync $ */
2/** @file
3 * VBox WDDM Miniport driver
4 */
5
6/*
7 * Copyright (C) 2011-2022 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#include "VBoxMPWddm.h"
19#include "VBoxMPVidPn.h"
20#include "common/VBoxMPCommon.h"
21
22
23static NTSTATUS vboxVidPnCheckMonitorModes(PVBOXMP_DEVEXT pDevExt, uint32_t u32Target, const CR_SORTARRAY *pSupportedTargetModes = NULL);
24
25static D3DDDIFORMAT vboxWddmCalcPixelFormat(const VIDEO_MODE_INFORMATION *pInfo)
26{
27 switch (pInfo->BitsPerPlane)
28 {
29 case 32:
30 if(!(pInfo->AttributeFlags & VIDEO_MODE_PALETTE_DRIVEN) && !(pInfo->AttributeFlags & VIDEO_MODE_MANAGED_PALETTE))
31 {
32 if (pInfo->RedMask == 0xFF0000 && pInfo->GreenMask == 0xFF00 && pInfo->BlueMask == 0xFF)
33 return D3DDDIFMT_A8R8G8B8;
34 WARN(("unsupported format: bpp(%d), rmask(%d), gmask(%d), bmask(%d)",
35 pInfo->BitsPerPlane, pInfo->RedMask, pInfo->GreenMask, pInfo->BlueMask));
36 AssertBreakpoint();
37 }
38 else
39 {
40 WARN(("unsupported AttributeFlags(0x%x)", pInfo->AttributeFlags));
41 AssertBreakpoint();
42 }
43 break;
44 case 24:
45 if(!(pInfo->AttributeFlags & VIDEO_MODE_PALETTE_DRIVEN) && !(pInfo->AttributeFlags & VIDEO_MODE_MANAGED_PALETTE))
46 {
47 if (pInfo->RedMask == 0xFF0000 && pInfo->GreenMask == 0xFF00 && pInfo->BlueMask == 0xFF)
48 return D3DDDIFMT_R8G8B8;
49 WARN(("unsupported format: bpp(%d), rmask(%d), gmask(%d), bmask(%d)",
50 pInfo->BitsPerPlane, pInfo->RedMask, pInfo->GreenMask, pInfo->BlueMask));
51 AssertBreakpoint();
52 }
53 else
54 {
55 WARN(("unsupported AttributeFlags(0x%x)", pInfo->AttributeFlags));
56 AssertBreakpoint();
57 }
58 break;
59 case 16:
60 if(!(pInfo->AttributeFlags & VIDEO_MODE_PALETTE_DRIVEN) && !(pInfo->AttributeFlags & VIDEO_MODE_MANAGED_PALETTE))
61 {
62 if (pInfo->RedMask == 0xF800 && pInfo->GreenMask == 0x7E0 && pInfo->BlueMask == 0x1F)
63 return D3DDDIFMT_R5G6B5;
64 WARN(("unsupported format: bpp(%d), rmask(%d), gmask(%d), bmask(%d)",
65 pInfo->BitsPerPlane, pInfo->RedMask, pInfo->GreenMask, pInfo->BlueMask));
66 AssertBreakpoint();
67 }
68 else
69 {
70 WARN(("unsupported AttributeFlags(0x%x)", pInfo->AttributeFlags));
71 AssertBreakpoint();
72 }
73 break;
74 case 8:
75 if((pInfo->AttributeFlags & VIDEO_MODE_PALETTE_DRIVEN) && (pInfo->AttributeFlags & VIDEO_MODE_MANAGED_PALETTE))
76 {
77 return D3DDDIFMT_P8;
78 }
79 else
80 {
81 WARN(("unsupported AttributeFlags(0x%x)", pInfo->AttributeFlags));
82 AssertBreakpoint();
83 }
84 break;
85 default:
86 WARN(("unsupported bpp(%d)", pInfo->BitsPerPlane));
87 AssertBreakpoint();
88 break;
89 }
90
91 return D3DDDIFMT_UNKNOWN;
92}
93
94static int vboxWddmResolutionFind(const D3DKMDT_2DREGION *pResolutions, int cResolutions, const D3DKMDT_2DREGION *pRes)
95{
96 for (int i = 0; i < cResolutions; ++i)
97 {
98 const D3DKMDT_2DREGION *pResolution = &pResolutions[i];
99 if (pResolution->cx == pRes->cx && pResolution->cy == pRes->cy)
100 return i;
101 }
102 return -1;
103}
104
105static bool vboxWddmVideoModesMatch(const VIDEO_MODE_INFORMATION *pMode1, const VIDEO_MODE_INFORMATION *pMode2)
106{
107 return pMode1->VisScreenHeight == pMode2->VisScreenHeight
108 && pMode1->VisScreenWidth == pMode2->VisScreenWidth
109 && pMode1->BitsPerPlane == pMode2->BitsPerPlane;
110}
111
112static int vboxWddmVideoModeFind(const VIDEO_MODE_INFORMATION *pModes, int cModes, const VIDEO_MODE_INFORMATION *pM)
113{
114 for (int i = 0; i < cModes; ++i)
115 {
116 const VIDEO_MODE_INFORMATION *pMode = &pModes[i];
117 if (vboxWddmVideoModesMatch(pMode, pM))
118 return i;
119 }
120 return -1;
121}
122
123static NTSTATUS vboxVidPnPopulateVideoSignalInfo(D3DKMDT_VIDEO_SIGNAL_INFO *pVsi,
124 const RTRECTSIZE *pResolution,
125 ULONG VSync)
126{
127 NTSTATUS Status = STATUS_SUCCESS;
128
129 pVsi->VideoStandard = D3DKMDT_VSS_OTHER;
130 pVsi->ActiveSize.cx = pResolution->cx;
131 pVsi->ActiveSize.cy = pResolution->cy;
132 pVsi->TotalSize = pVsi->ActiveSize;
133 if (VBOXWDDM_IS_DISPLAYONLY())
134 {
135 /* VSYNC is not implemented in display-only mode (#8228).
136 * In this case Windows checks that frequencies are not specified.
137 */
138 pVsi->VSyncFreq.Numerator = D3DKMDT_FREQUENCY_NOTSPECIFIED;
139 pVsi->VSyncFreq.Denominator = D3DKMDT_FREQUENCY_NOTSPECIFIED;
140 pVsi->PixelRate = D3DKMDT_FREQUENCY_NOTSPECIFIED;
141 pVsi->HSyncFreq.Numerator = D3DKMDT_FREQUENCY_NOTSPECIFIED;
142 pVsi->HSyncFreq.Denominator = D3DKMDT_FREQUENCY_NOTSPECIFIED;
143 }
144 else
145 {
146 pVsi->VSyncFreq.Numerator = VSync * 1000;
147 pVsi->VSyncFreq.Denominator = 1000;
148 pVsi->PixelRate = pVsi->TotalSize.cx * pVsi->TotalSize.cy * VSync;
149 pVsi->HSyncFreq.Numerator = (UINT)((VSync * pVsi->TotalSize.cy) * 1000);
150 pVsi->HSyncFreq.Denominator = 1000;
151 }
152 pVsi->ScanLineOrdering = D3DDDI_VSSLO_PROGRESSIVE;
153
154 return Status;
155}
156
157BOOLEAN vboxVidPnMatchVideoSignal(const D3DKMDT_VIDEO_SIGNAL_INFO *pVsi1, const D3DKMDT_VIDEO_SIGNAL_INFO *pVsi2)
158{
159 if (pVsi1->VideoStandard != pVsi2->VideoStandard)
160 return FALSE;
161 if (pVsi1->TotalSize.cx != pVsi2->TotalSize.cx)
162 return FALSE;
163 if (pVsi1->TotalSize.cy != pVsi2->TotalSize.cy)
164 return FALSE;
165 if (pVsi1->ActiveSize.cx != pVsi2->ActiveSize.cx)
166 return FALSE;
167 if (pVsi1->ActiveSize.cy != pVsi2->ActiveSize.cy)
168 return FALSE;
169 if (pVsi1->VSyncFreq.Numerator != pVsi2->VSyncFreq.Numerator)
170 return FALSE;
171 if (pVsi1->VSyncFreq.Denominator != pVsi2->VSyncFreq.Denominator)
172 return FALSE;
173 if (pVsi1->HSyncFreq.Numerator != pVsi2->HSyncFreq.Numerator)
174 return FALSE;
175 if (pVsi1->HSyncFreq.Denominator != pVsi2->HSyncFreq.Denominator)
176 return FALSE;
177 if (pVsi1->PixelRate != pVsi2->PixelRate)
178 return FALSE;
179 if (pVsi1->ScanLineOrdering != pVsi2->ScanLineOrdering)
180 return FALSE;
181
182 return TRUE;
183}
184
185static void vboxVidPnPopulateSourceModeInfo(D3DKMDT_VIDPN_SOURCE_MODE *pNewVidPnSourceModeInfo, const RTRECTSIZE *pSize, D3DDDIFORMAT PixelFormat = D3DDDIFMT_A8R8G8B8)
186{
187 /* this is a graphics mode */
188 pNewVidPnSourceModeInfo->Type = D3DKMDT_RMT_GRAPHICS;
189 pNewVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cx = pSize->cx;
190 pNewVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cy = pSize->cy;
191 pNewVidPnSourceModeInfo->Format.Graphics.VisibleRegionSize = pNewVidPnSourceModeInfo->Format.Graphics.PrimSurfSize;
192 pNewVidPnSourceModeInfo->Format.Graphics.Stride = pSize->cx * 4;
193 pNewVidPnSourceModeInfo->Format.Graphics.PixelFormat = PixelFormat;
194 Assert(pNewVidPnSourceModeInfo->Format.Graphics.PixelFormat != D3DDDIFMT_UNKNOWN);
195 pNewVidPnSourceModeInfo->Format.Graphics.ColorBasis = D3DKMDT_CB_SRGB;
196 if (pNewVidPnSourceModeInfo->Format.Graphics.PixelFormat == D3DDDIFMT_P8)
197 pNewVidPnSourceModeInfo->Format.Graphics.PixelValueAccessMode = D3DKMDT_PVAM_SETTABLEPALETTE;
198 else
199 pNewVidPnSourceModeInfo->Format.Graphics.PixelValueAccessMode = D3DKMDT_PVAM_DIRECT;
200}
201
202static void vboxVidPnPopulateMonitorModeInfo(D3DKMDT_MONITOR_SOURCE_MODE *pMonitorSourceMode, const RTRECTSIZE *pResolution)
203{
204 vboxVidPnPopulateVideoSignalInfo(&pMonitorSourceMode->VideoSignalInfo, pResolution, g_RefreshRate);
205 pMonitorSourceMode->ColorBasis = D3DKMDT_CB_SRGB;
206 pMonitorSourceMode->ColorCoeffDynamicRanges.FirstChannel = 8;
207 pMonitorSourceMode->ColorCoeffDynamicRanges.SecondChannel = 8;
208 pMonitorSourceMode->ColorCoeffDynamicRanges.ThirdChannel = 8;
209 pMonitorSourceMode->ColorCoeffDynamicRanges.FourthChannel = 0;
210 pMonitorSourceMode->Origin = D3DKMDT_MCO_DRIVER;
211 pMonitorSourceMode->Preference = D3DKMDT_MP_NOTPREFERRED;
212}
213
214static NTSTATUS vboxVidPnPopulateTargetModeInfo(D3DKMDT_VIDPN_TARGET_MODE *pNewVidPnTargetModeInfo, const RTRECTSIZE *pResolution)
215{
216 pNewVidPnTargetModeInfo->Preference = D3DKMDT_MP_NOTPREFERRED;
217 return vboxVidPnPopulateVideoSignalInfo(&pNewVidPnTargetModeInfo->VideoSignalInfo, pResolution, g_RefreshRate);
218}
219
220void VBoxVidPnStTargetCleanup(PVBOXWDDM_SOURCE paSources, uint32_t cScreens, PVBOXWDDM_TARGET pTarget)
221{
222 RT_NOREF(cScreens);
223 if (pTarget->VidPnSourceId == D3DDDI_ID_UNINITIALIZED)
224 return;
225
226 Assert(pTarget->VidPnSourceId < cScreens);
227
228 PVBOXWDDM_SOURCE pSource = &paSources[pTarget->VidPnSourceId];
229 if (!pSource)
230 return;
231 Assert(pSource->cTargets);
232 Assert(ASMBitTest(pSource->aTargetMap, pTarget->u32Id));
233 ASMBitClear(pSource->aTargetMap, pTarget->u32Id);
234 pSource->cTargets--;
235 pTarget->VidPnSourceId = D3DDDI_ID_UNINITIALIZED;
236
237 pTarget->u8SyncState &= ~VBOXWDDM_HGSYNC_F_SYNCED_TOPOLOGY;
238 pSource->u8SyncState &= ~VBOXWDDM_HGSYNC_F_SYNCED_TOPOLOGY;
239}
240
241void VBoxVidPnStSourceTargetAdd(PVBOXWDDM_SOURCE paSources, uint32_t cScreens, PVBOXWDDM_SOURCE pSource, PVBOXWDDM_TARGET pTarget)
242{
243 if (pTarget->VidPnSourceId == pSource->AllocData.SurfDesc.VidPnSourceId)
244 return;
245
246 VBoxVidPnStTargetCleanup(paSources, cScreens, pTarget);
247
248 ASMBitSet(pSource->aTargetMap, pTarget->u32Id);
249 pSource->cTargets++;
250 pTarget->VidPnSourceId = pSource->AllocData.SurfDesc.VidPnSourceId;
251
252 pTarget->fBlankedByPowerOff = RT_BOOL(pSource->bBlankedByPowerOff);
253 LOG(("src %d and tgt %d are now blank %d",
254 pSource->AllocData.SurfDesc.VidPnSourceId, pTarget->u32Id, pTarget->fBlankedByPowerOff));
255
256 pTarget->u8SyncState &= ~VBOXWDDM_HGSYNC_F_SYNCED_TOPOLOGY;
257 pSource->u8SyncState &= ~VBOXWDDM_HGSYNC_F_SYNCED_TOPOLOGY;
258}
259
260void VBoxVidPnStTIterInit(PVBOXWDDM_SOURCE pSource, PVBOXWDDM_TARGET paTargets, uint32_t cTargets, VBOXWDDM_TARGET_ITER *pIter)
261{
262 pIter->pSource = pSource;
263 pIter->paTargets = paTargets;
264 pIter->cTargets = cTargets;
265 pIter->i = 0;
266 pIter->c = 0;
267}
268
269PVBOXWDDM_TARGET VBoxVidPnStTIterNext(VBOXWDDM_TARGET_ITER *pIter)
270{
271 PVBOXWDDM_SOURCE pSource = pIter->pSource;
272 if (pSource->cTargets <= pIter->c)
273 return NULL;
274
275 int i = (!pIter->c) ? ASMBitFirstSet(pSource->aTargetMap, pIter->cTargets)
276 : ASMBitNextSet(pSource->aTargetMap, pIter->cTargets, pIter->i);
277 if (i < 0)
278 STOP_FATAL();
279
280 pIter->i = (uint32_t)i;
281 pIter->c++;
282 return &pIter->paTargets[i];
283}
284
285void VBoxVidPnStSourceCleanup(PVBOXWDDM_SOURCE paSources, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, PVBOXWDDM_TARGET paTargets, uint32_t cTargets)
286{
287 PVBOXWDDM_SOURCE pSource = &paSources[VidPnSourceId];
288 VBOXWDDM_TARGET_ITER Iter;
289 VBoxVidPnStTIterInit(pSource, paTargets, cTargets, &Iter);
290 for (PVBOXWDDM_TARGET pTarget = VBoxVidPnStTIterNext(&Iter);
291 pTarget;
292 pTarget = VBoxVidPnStTIterNext(&Iter))
293 {
294 Assert(pTarget->VidPnSourceId == pSource->AllocData.SurfDesc.VidPnSourceId);
295 VBoxVidPnStTargetCleanup(paSources, cTargets, pTarget);
296 /* iterator is not safe wrt target removal, reinit it */
297 VBoxVidPnStTIterInit(pSource, paTargets, cTargets, &Iter);
298 }
299}
300
301void VBoxVidPnStCleanup(PVBOXWDDM_SOURCE paSources, PVBOXWDDM_TARGET paTargets, uint32_t cScreens)
302{
303 for (UINT i = 0; i < cScreens; ++i)
304 {
305 PVBOXWDDM_TARGET pTarget = &paTargets[i];
306 VBoxVidPnStTargetCleanup(paSources, cScreens, pTarget);
307 }
308}
309
310void VBoxVidPnAllocDataInit(VBOXWDDM_ALLOC_DATA *pData, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId)
311{
312 memset(pData, 0, sizeof (*pData));
313 pData->SurfDesc.VidPnSourceId = VidPnSourceId;
314 pData->Addr.offVram = VBOXVIDEOOFFSET_VOID;
315}
316
317void VBoxVidPnSourceInit(PVBOXWDDM_SOURCE pSource, const D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, uint8_t u8SyncState)
318{
319 memset(pSource, 0, sizeof (*pSource));
320 VBoxVidPnAllocDataInit(&pSource->AllocData, VidPnSourceId);
321 pSource->u8SyncState = (u8SyncState & VBOXWDDM_HGSYNC_F_SYNCED_ALL);
322}
323
324void VBoxVidPnTargetInit(PVBOXWDDM_TARGET pTarget, const D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId, uint8_t u8SyncState)
325{
326 memset(pTarget, 0, sizeof (*pTarget));
327 pTarget->u32Id = VidPnTargetId;
328 pTarget->VidPnSourceId = D3DDDI_ID_UNINITIALIZED;
329 pTarget->u8SyncState = (u8SyncState & VBOXWDDM_HGSYNC_F_SYNCED_ALL);
330}
331
332void VBoxVidPnSourcesInit(PVBOXWDDM_SOURCE pSources, uint32_t cScreens, uint8_t u8SyncState)
333{
334 for (uint32_t i = 0; i < cScreens; ++i)
335 VBoxVidPnSourceInit(&pSources[i], i, u8SyncState);
336}
337
338void VBoxVidPnTargetsInit(PVBOXWDDM_TARGET pTargets, uint32_t cScreens, uint8_t u8SyncState)
339{
340 for (uint32_t i = 0; i < cScreens; ++i)
341 VBoxVidPnTargetInit(&pTargets[i], i, u8SyncState);
342}
343
344void VBoxVidPnSourceCopy(VBOXWDDM_SOURCE *pDst, const VBOXWDDM_SOURCE *pSrc)
345{
346 uint8_t u8SyncState = pDst->u8SyncState;
347 *pDst = *pSrc;
348 pDst->u8SyncState &= u8SyncState;
349}
350
351void VBoxVidPnTargetCopy(VBOXWDDM_TARGET *pDst, const VBOXWDDM_TARGET *pSrc)
352{
353 uint8_t u8SyncState = pDst->u8SyncState;
354 *pDst = *pSrc;
355 pDst->u8SyncState &= u8SyncState;
356}
357
358void VBoxVidPnSourcesCopy(VBOXWDDM_SOURCE *pDst, const VBOXWDDM_SOURCE *pSrc, uint32_t cScreens)
359{
360 for (uint32_t i = 0; i < cScreens; ++i)
361 VBoxVidPnSourceCopy(&pDst[i], &pSrc[i]);
362}
363
364void VBoxVidPnTargetsCopy(VBOXWDDM_TARGET *pDst, const VBOXWDDM_TARGET *pSrc, uint32_t cScreens)
365{
366 for (uint32_t i = 0; i < cScreens; ++i)
367 VBoxVidPnTargetCopy(&pDst[i], &pSrc[i]);
368}
369
370void VBoxDumpSourceTargetArrays(VBOXWDDM_SOURCE *paSources, VBOXWDDM_TARGET *paTargets, uint32_t cScreens)
371{
372 RT_NOREF(paSources, paTargets, cScreens);
373
374 for (uint32_t i = 0; i < cScreens; i++)
375 {
376 LOG_EXACT(("source [%d] Sync 0x%x, cTgt %d, TgtMap0 0x%x, TgtRep %d, blanked %d\n",
377 i, paSources[i].u8SyncState, paSources[i].cTargets, paSources[i].aTargetMap[0], paSources[i].fTargetsReported, paSources[i].bBlankedByPowerOff));
378
379 LOG_EXACT(("target [%d] Sync 0x%x, VidPnSourceId %d, blanked %d\n",
380 i, paTargets[i].u8SyncState, paTargets[i].VidPnSourceId, paTargets[i].fBlankedByPowerOff));
381 }
382}
383
384static D3DKMDT_ENUMCOFUNCMODALITY_PIVOT_TYPE vboxVidPnCofuncModalityCurrentPathPivot(D3DKMDT_ENUMCOFUNCMODALITY_PIVOT_TYPE enmPivot,
385 const DXGK_ENUM_PIVOT *pPivot,
386 D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
387{
388 switch (enmPivot)
389 {
390 case D3DKMDT_EPT_VIDPNSOURCE:
391 if (pPivot->VidPnSourceId == VidPnSourceId)
392 return D3DKMDT_EPT_VIDPNSOURCE;
393 if (pPivot->VidPnSourceId == D3DDDI_ID_ALL)
394 {
395#ifdef DEBUG_misha
396 AssertFailed();
397#endif
398 return D3DKMDT_EPT_VIDPNSOURCE;
399 }
400 return D3DKMDT_EPT_NOPIVOT;
401 case D3DKMDT_EPT_VIDPNTARGET:
402 if (pPivot->VidPnTargetId == VidPnTargetId)
403 return D3DKMDT_EPT_VIDPNTARGET;
404 if (pPivot->VidPnTargetId == D3DDDI_ID_ALL)
405 {
406#ifdef DEBUG_misha
407 AssertFailed();
408#endif
409 return D3DKMDT_EPT_VIDPNTARGET;
410 }
411 return D3DKMDT_EPT_NOPIVOT;
412 case D3DKMDT_EPT_SCALING:
413 case D3DKMDT_EPT_ROTATION:
414 case D3DKMDT_EPT_NOPIVOT:
415 return D3DKMDT_EPT_NOPIVOT;
416 default:
417 WARN(("unexpected pivot"));
418 return D3DKMDT_EPT_NOPIVOT;
419 }
420}
421
422NTSTATUS vboxVidPnQueryPinnedTargetMode(D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface,
423 D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId, RTRECTSIZE *pSize)
424{
425 D3DKMDT_HVIDPNTARGETMODESET hCurVidPnTargetModeSet;
426 const DXGK_VIDPNTARGETMODESET_INTERFACE *pCurVidPnTargetModeSetInterface;
427 pSize->cx = 0;
428 pSize->cy = 0;
429 NTSTATUS Status = pVidPnInterface->pfnAcquireTargetModeSet(hVidPn,
430 VidPnTargetId,
431 &hCurVidPnTargetModeSet,
432 &pCurVidPnTargetModeSetInterface);
433 if (!NT_SUCCESS(Status))
434 {
435 WARN(("pfnAcquireTargetModeSet failed Status(0x%x)", Status));
436 return Status;
437 }
438
439 CONST D3DKMDT_VIDPN_TARGET_MODE* pPinnedVidPnTargetModeInfo;
440 Status = pCurVidPnTargetModeSetInterface->pfnAcquirePinnedModeInfo(hCurVidPnTargetModeSet, &pPinnedVidPnTargetModeInfo);
441 if (Status == STATUS_GRAPHICS_MODE_NOT_PINNED)
442 {
443 pPinnedVidPnTargetModeInfo = NULL;
444 Status = STATUS_SUCCESS;
445 }
446 else if (!NT_SUCCESS(Status))
447 {
448 WARN(("pfnAcquirePinnedModeInfo failed Status(0x%x)", Status));
449 }
450 else
451 {
452 Assert(pPinnedVidPnTargetModeInfo);
453 pSize->cx = pPinnedVidPnTargetModeInfo->VideoSignalInfo.ActiveSize.cx;
454 pSize->cy = pPinnedVidPnTargetModeInfo->VideoSignalInfo.ActiveSize.cy;
455 NTSTATUS rcNt2 = pCurVidPnTargetModeSetInterface->pfnReleaseModeInfo(hCurVidPnTargetModeSet, pPinnedVidPnTargetModeInfo);
456 AssertNtStatus(rcNt2);
457 }
458
459 NTSTATUS rcNt2 = pVidPnInterface->pfnReleaseTargetModeSet(hVidPn, hCurVidPnTargetModeSet);
460 AssertNtStatusSuccess(rcNt2);
461
462 return Status;
463}
464
465NTSTATUS vboxVidPnQueryPinnedSourceMode(D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface,
466 D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, RTRECTSIZE *pSize)
467{
468 D3DKMDT_HVIDPNSOURCEMODESET hCurVidPnSourceModeSet;
469 const DXGK_VIDPNSOURCEMODESET_INTERFACE *pCurVidPnSourceModeSetInterface;
470 pSize->cx = 0;
471 pSize->cy = 0;
472 NTSTATUS Status = pVidPnInterface->pfnAcquireSourceModeSet(hVidPn,
473 VidPnSourceId,
474 &hCurVidPnSourceModeSet,
475 &pCurVidPnSourceModeSetInterface);
476 if (!NT_SUCCESS(Status))
477 {
478 WARN(("pfnAcquireSourceModeSet failed Status(0x%x)", Status));
479 return Status;
480 }
481
482 CONST D3DKMDT_VIDPN_SOURCE_MODE* pPinnedVidPnSourceModeInfo;
483 Status = pCurVidPnSourceModeSetInterface->pfnAcquirePinnedModeInfo(hCurVidPnSourceModeSet, &pPinnedVidPnSourceModeInfo);
484 if (Status == STATUS_GRAPHICS_MODE_NOT_PINNED)
485 {
486 pPinnedVidPnSourceModeInfo = NULL;
487 Status = STATUS_SUCCESS;
488 }
489 else if (!NT_SUCCESS(Status))
490 {
491 WARN(("pfnAcquirePinnedModeInfo failed Status(0x%x)", Status));
492 }
493 else
494 {
495 Assert(pPinnedVidPnSourceModeInfo);
496 pSize->cx = pPinnedVidPnSourceModeInfo->Format.Graphics.VisibleRegionSize.cx;
497 pSize->cy = pPinnedVidPnSourceModeInfo->Format.Graphics.VisibleRegionSize.cy;
498 NTSTATUS rcNt2 = pCurVidPnSourceModeSetInterface->pfnReleaseModeInfo(hCurVidPnSourceModeSet, pPinnedVidPnSourceModeInfo);
499 AssertNtStatus(rcNt2);
500 }
501
502 NTSTATUS rcNt2 = pVidPnInterface->pfnReleaseSourceModeSet(hVidPn, hCurVidPnSourceModeSet);
503 AssertNtStatusSuccess(rcNt2);
504
505 return Status;
506}
507
508static NTSTATUS vboxVidPnSourceModeSetToArray(D3DKMDT_HVIDPNSOURCEMODESET hVidPnModeSet,
509 const DXGK_VIDPNSOURCEMODESET_INTERFACE *pVidPnModeSetInterface,
510 CR_SORTARRAY *pArray)
511{
512 VBOXVIDPN_SOURCEMODE_ITER Iter;
513 const D3DKMDT_VIDPN_SOURCE_MODE *pVidPnModeInfo;
514
515 VBoxVidPnSourceModeIterInit(&Iter, hVidPnModeSet, pVidPnModeSetInterface);
516
517 while ((pVidPnModeInfo = VBoxVidPnSourceModeIterNext(&Iter)) != NULL)
518 {
519 RTRECTSIZE size;
520 size.cx = pVidPnModeInfo->Format.Graphics.VisibleRegionSize.cx;
521 size.cy = pVidPnModeInfo->Format.Graphics.VisibleRegionSize.cy;
522 int rc = CrSaAdd(pArray, CR_RSIZE2U64(size));
523 if (RT_FAILURE(rc))
524 {
525 WARN(("CrSaAdd failed %d", rc));
526 VBoxVidPnSourceModeIterTerm(&Iter);
527 return STATUS_UNSUCCESSFUL;
528 }
529 }
530
531 VBoxVidPnSourceModeIterTerm(&Iter);
532
533 return VBoxVidPnSourceModeIterStatus(&Iter);
534}
535
536static NTSTATUS vboxVidPnSourceModeSetFromArray(D3DKMDT_HVIDPNSOURCEMODESET hVidPnModeSet,
537 const DXGK_VIDPNSOURCEMODESET_INTERFACE *pVidPnModeSetInterface,
538 const CR_SORTARRAY *pArray)
539{
540 for (uint32_t i = 0; i < CrSaGetSize(pArray); ++i)
541 {
542 RTRECTSIZE size = CR_U642RSIZE(CrSaGetVal(pArray, i));
543
544 for (uint32_t m = 0; m < 2; ++m)
545 {
546 D3DKMDT_VIDPN_SOURCE_MODE *pVidPnModeInfo;
547 NTSTATUS Status = pVidPnModeSetInterface->pfnCreateNewModeInfo(hVidPnModeSet, &pVidPnModeInfo);
548 if (!NT_SUCCESS(Status))
549 {
550 WARN(("pfnCreateNewModeInfo failed, Status 0x%x", Status));
551 return Status;
552 }
553
554 vboxVidPnPopulateSourceModeInfo(pVidPnModeInfo, &size, m == 0 ? D3DDDIFMT_A8R8G8B8 : D3DDDIFMT_A8B8G8R8);
555
556 Status = pVidPnModeSetInterface->pfnAddMode(hVidPnModeSet, pVidPnModeInfo);
557 if (!NT_SUCCESS(Status))
558 {
559 WARN(("pfnAddMode (%d x %d) failed, Status 0x%x", size.cx, size.cy, Status));
560 VBoxVidPnDumpSourceMode("SourceMode: ", pVidPnModeInfo, "\n");
561 NTSTATUS rcNt2 = pVidPnModeSetInterface->pfnReleaseModeInfo(hVidPnModeSet, pVidPnModeInfo);
562 AssertNtStatusSuccess(rcNt2);
563 // Continue adding modes into modeset even if a mode was rejected
564 continue;
565 }
566 }
567 }
568
569 return STATUS_SUCCESS;
570}
571
572static NTSTATUS vboxVidPnTargetModeSetToArray(D3DKMDT_HVIDPNTARGETMODESET hVidPnModeSet,
573 const DXGK_VIDPNTARGETMODESET_INTERFACE *pVidPnModeSetInterface,
574 CR_SORTARRAY *pArray)
575{
576 VBOXVIDPN_TARGETMODE_ITER Iter;
577 const D3DKMDT_VIDPN_TARGET_MODE *pVidPnModeInfo;
578
579 VBoxVidPnTargetModeIterInit(&Iter, hVidPnModeSet, pVidPnModeSetInterface);
580
581 while ((pVidPnModeInfo = VBoxVidPnTargetModeIterNext(&Iter)) != NULL)
582 {
583 RTRECTSIZE size;
584 size.cx = pVidPnModeInfo->VideoSignalInfo.ActiveSize.cx;
585 size.cy = pVidPnModeInfo->VideoSignalInfo.ActiveSize.cy;
586 int rc = CrSaAdd(pArray, CR_RSIZE2U64(size));
587 if (RT_FAILURE(rc))
588 {
589 WARN(("CrSaAdd failed %d", rc));
590 VBoxVidPnTargetModeIterTerm(&Iter);
591 return STATUS_UNSUCCESSFUL;
592 }
593 }
594
595 VBoxVidPnTargetModeIterTerm(&Iter);
596
597 return VBoxVidPnTargetModeIterStatus(&Iter);
598}
599
600static NTSTATUS vboxVidPnTargetModeSetFromArray(D3DKMDT_HVIDPNTARGETMODESET hVidPnModeSet,
601 const DXGK_VIDPNTARGETMODESET_INTERFACE *pVidPnModeSetInterface,
602 const CR_SORTARRAY *pArray)
603{
604 for (uint32_t i = 0; i < CrSaGetSize(pArray); ++i)
605 {
606 RTRECTSIZE size = CR_U642RSIZE(CrSaGetVal(pArray, i));
607
608 D3DKMDT_VIDPN_TARGET_MODE *pVidPnModeInfo;
609 NTSTATUS Status = pVidPnModeSetInterface->pfnCreateNewModeInfo(hVidPnModeSet, &pVidPnModeInfo);
610 if (!NT_SUCCESS(Status))
611 {
612 WARN(("pfnCreateNewModeInfo failed, Status 0x%x", Status));
613 return Status;
614 }
615
616 vboxVidPnPopulateTargetModeInfo(pVidPnModeInfo, &size);
617
618 Status = pVidPnModeSetInterface->pfnAddMode(hVidPnModeSet, pVidPnModeInfo);
619 if (!NT_SUCCESS(Status))
620 {
621 WARN(("pfnAddMode (%d x %d) failed, Status 0x%x", size.cx, size.cy, Status));
622 VBoxVidPnDumpTargetMode("TargetMode: ", pVidPnModeInfo, "\n");
623 NTSTATUS rcNt2 = pVidPnModeSetInterface->pfnReleaseModeInfo(hVidPnModeSet, pVidPnModeInfo);
624 AssertNtStatusSuccess(rcNt2);
625 // Continue adding modes into modeset even if a mode was rejected
626 continue;
627 }
628 }
629
630 return STATUS_SUCCESS;
631}
632
633static NTSTATUS vboxVidPnMonitorModeSetToArray(D3DKMDT_HMONITORSOURCEMODESET hVidPnModeSet,
634 const DXGK_MONITORSOURCEMODESET_INTERFACE *pVidPnModeSetInterface,
635 CR_SORTARRAY *pArray)
636{
637 VBOXVIDPN_MONITORMODE_ITER Iter;
638 const D3DKMDT_MONITOR_SOURCE_MODE *pVidPnModeInfo;
639
640 VBoxVidPnMonitorModeIterInit(&Iter, hVidPnModeSet, pVidPnModeSetInterface);
641
642 while ((pVidPnModeInfo = VBoxVidPnMonitorModeIterNext(&Iter)) != NULL)
643 {
644 RTRECTSIZE size;
645 size.cx = pVidPnModeInfo->VideoSignalInfo.ActiveSize.cx;
646 size.cy = pVidPnModeInfo->VideoSignalInfo.ActiveSize.cy;
647 int rc = CrSaAdd(pArray, CR_RSIZE2U64(size));
648 if (RT_FAILURE(rc))
649 {
650 WARN(("CrSaAdd failed %d", rc));
651 VBoxVidPnMonitorModeIterTerm(&Iter);
652 return STATUS_UNSUCCESSFUL;
653 }
654 }
655
656 VBoxVidPnMonitorModeIterTerm(&Iter);
657
658 return VBoxVidPnMonitorModeIterStatus(&Iter);
659}
660
661static NTSTATUS vboxVidPnMonitorModeSetFromArray(D3DKMDT_HMONITORSOURCEMODESET hVidPnModeSet,
662 const DXGK_MONITORSOURCEMODESET_INTERFACE *pVidPnModeSetInterface,
663 const CR_SORTARRAY *pArray)
664{
665 for (uint32_t i = 0; i < CrSaGetSize(pArray); ++i)
666 {
667 RTRECTSIZE size = CR_U642RSIZE(CrSaGetVal(pArray, i));
668
669 D3DKMDT_MONITOR_SOURCE_MODE *pVidPnModeInfo;
670 NTSTATUS Status = pVidPnModeSetInterface->pfnCreateNewModeInfo(hVidPnModeSet, &pVidPnModeInfo);
671 if (!NT_SUCCESS(Status))
672 {
673 WARN(("pfnCreateNewModeInfo failed, Status 0x%x", Status));
674 return Status;
675 }
676
677 vboxVidPnPopulateMonitorModeInfo(pVidPnModeInfo, &size);
678
679 Status = pVidPnModeSetInterface->pfnAddMode(hVidPnModeSet, pVidPnModeInfo);
680 if (!NT_SUCCESS(Status))
681 {
682 WARN(("pfnAddMode (%d x %d) failed, Status 0x%x", size.cx, size.cy, Status));
683 NTSTATUS rcNt2 = pVidPnModeSetInterface->pfnReleaseModeInfo(hVidPnModeSet, pVidPnModeInfo);
684 AssertNtStatusSuccess(rcNt2);
685 // Continue adding modes into modeset even if a mode was rejected
686 continue;
687 }
688
689 LOGF(("mode (%d x %d) added to monitor modeset", size.cx, size.cy));
690 }
691
692 return STATUS_SUCCESS;
693}
694
695
696static NTSTATUS vboxVidPnCollectInfoForPathTarget(PVBOXMP_DEVEXT pDevExt,
697 D3DKMDT_HVIDPN hVidPn,
698 const DXGK_VIDPN_INTERFACE* pVidPnInterface,
699 D3DKMDT_ENUMCOFUNCMODALITY_PIVOT_TYPE enmCurPivot,
700 uint32_t *aAdjustedModeMap,
701 CR_SORTARRAY *aModes,
702 D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
703{
704 const CR_SORTARRAY* pSupportedModes = VBoxWddmVModesGet(pDevExt, VidPnTargetId);
705 NTSTATUS Status;
706 if (enmCurPivot == D3DKMDT_EPT_VIDPNTARGET)
707 {
708 D3DKMDT_HVIDPNTARGETMODESET hVidPnModeSet;
709 const DXGK_VIDPNTARGETMODESET_INTERFACE *pVidPnModeSetInterface;
710 Status = pVidPnInterface->pfnAcquireTargetModeSet(hVidPn,
711 VidPnTargetId,
712 &hVidPnModeSet,
713 &pVidPnModeSetInterface);
714 if (!NT_SUCCESS(Status))
715 {
716 WARN(("pfnAcquireTargetModeSet failed %#x", Status));
717 return Status;
718 }
719
720 /* intersect modes from target */
721 if (!ASMBitTest(aAdjustedModeMap, VidPnTargetId))
722 {
723 Status = vboxVidPnTargetModeSetToArray(hVidPnModeSet, pVidPnModeSetInterface, &aModes[VidPnTargetId]);
724 ASMBitSet(aAdjustedModeMap, VidPnTargetId);
725 }
726 else
727 {
728 CR_SORTARRAY Arr;
729 CrSaInit(&Arr, 0);
730 Status = vboxVidPnTargetModeSetToArray(hVidPnModeSet, pVidPnModeSetInterface, &aModes[VidPnTargetId]);
731 CrSaIntersect(&aModes[VidPnTargetId], &Arr);
732 CrSaCleanup(&Arr);
733 }
734
735 NTSTATUS rcNt2 = pVidPnInterface->pfnReleaseTargetModeSet(hVidPn, hVidPnModeSet);
736 AssertNtStatusSuccess(rcNt2);
737
738 if (!NT_SUCCESS(Status))
739 {
740 WARN(("vboxVidPnTargetModeSetToArray failed %#x", Status));
741 return Status;
742 }
743
744 return STATUS_SUCCESS;
745 }
746
747 RTRECTSIZE pinnedSize = {0};
748 Status = vboxVidPnQueryPinnedTargetMode(hVidPn, pVidPnInterface, VidPnTargetId, &pinnedSize);
749 if (!NT_SUCCESS(Status))
750 {
751 WARN(("vboxVidPnQueryPinnedTargetMode failed %#x", Status));
752 return Status;
753 }
754
755 if (pinnedSize.cx)
756 {
757 Assert(CrSaContains(pSupportedModes, CR_RSIZE2U64(pinnedSize)));
758
759 if (!ASMBitTest(aAdjustedModeMap, VidPnTargetId))
760 {
761 Assert(CrSaGetSize(&aModes[VidPnTargetId]) == 0);
762 int rc = CrSaAdd(&aModes[VidPnTargetId], CR_RSIZE2U64(pinnedSize));
763 if (!RT_SUCCESS(rc))
764 {
765 WARN(("CrSaAdd failed %d", rc));
766 return STATUS_UNSUCCESSFUL;
767 }
768 ASMBitSet(aAdjustedModeMap, VidPnTargetId);
769 }
770 else
771 {
772 CrSaClear(&aModes[VidPnTargetId]);
773 int rc = CrSaAdd(&aModes[VidPnTargetId], CR_RSIZE2U64(pinnedSize));
774 if (!RT_SUCCESS(rc))
775 {
776 WARN(("CrSaAdd failed %d", rc));
777 return STATUS_UNSUCCESSFUL;
778 }
779 }
780
781 return STATUS_SUCCESS;
782 }
783
784
785 Status = vboxVidPnQueryPinnedSourceMode(hVidPn, pVidPnInterface, VidPnSourceId, &pinnedSize);
786 if (!NT_SUCCESS(Status))
787 {
788 WARN(("vboxVidPnQueryPinnedSourceMode failed %#x", Status));
789 return Status;
790 }
791
792 if (pinnedSize.cx)
793 {
794 if (!ASMBitTest(aAdjustedModeMap, VidPnTargetId))
795 {
796 Assert(CrSaGetSize(&aModes[VidPnTargetId]) == 0);
797 if (CrSaContains(pSupportedModes, CR_RSIZE2U64(pinnedSize)))
798 {
799 int rc = CrSaAdd(&aModes[VidPnTargetId], CR_RSIZE2U64(pinnedSize));
800 if (!RT_SUCCESS(rc))
801 {
802 WARN(("CrSaAdd failed %d", rc));
803 return STATUS_UNSUCCESSFUL;
804 }
805 }
806 ASMBitSet(aAdjustedModeMap, VidPnTargetId);
807 }
808 else
809 {
810 CrSaClear(&aModes[VidPnTargetId]);
811 if (CrSaContains(pSupportedModes, CR_RSIZE2U64(pinnedSize)))
812 {
813 int rc = CrSaAdd(&aModes[VidPnTargetId], CR_RSIZE2U64(pinnedSize));
814 if (!RT_SUCCESS(rc))
815 {
816 WARN(("CrSaAdd failed %d", rc));
817 return STATUS_UNSUCCESSFUL;
818 }
819 }
820 }
821
822 return STATUS_SUCCESS;
823 }
824
825 /* now we are here because no pinned info is specified, we need to populate it based on the supported info
826 * and modes already configured,
827 * this is pretty simple actually */
828
829 if (!ASMBitTest(aAdjustedModeMap, VidPnTargetId))
830 {
831 Assert(CrSaGetSize(&aModes[VidPnTargetId]) == 0);
832 int rc = CrSaClone(pSupportedModes, &aModes[VidPnTargetId]);
833 if (!RT_SUCCESS(rc))
834 {
835 WARN(("CrSaClone failed %d", rc));
836 return STATUS_UNSUCCESSFUL;
837 }
838 ASMBitSet(aAdjustedModeMap, VidPnTargetId);
839 }
840 else
841 {
842 CrSaIntersect(&aModes[VidPnTargetId], pSupportedModes);
843 }
844
845 /* we are done */
846 return STATUS_SUCCESS;
847}
848
849static NTSTATUS vboxVidPnApplyInfoForPathTarget(PVBOXMP_DEVEXT pDevExt,
850 D3DKMDT_HVIDPN hVidPn,
851 const DXGK_VIDPN_INTERFACE* pVidPnInterface,
852 D3DKMDT_ENUMCOFUNCMODALITY_PIVOT_TYPE enmCurPivot,
853 uint32_t *aAdjustedModeMap,
854 const CR_SORTARRAY *aModes,
855 D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId,
856 D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
857{
858 RT_NOREF(aAdjustedModeMap, VidPnSourceId);
859 Assert(ASMBitTest(aAdjustedModeMap, VidPnTargetId));
860
861 if (enmCurPivot == D3DKMDT_EPT_VIDPNTARGET)
862 return STATUS_SUCCESS;
863
864 RTRECTSIZE pinnedSize = {0};
865 NTSTATUS Status = vboxVidPnQueryPinnedTargetMode(hVidPn, pVidPnInterface, VidPnTargetId, &pinnedSize);
866 if (!NT_SUCCESS(Status))
867 {
868 WARN(("vboxVidPnQueryPinnedTargetMode failed %#x", Status));
869 return Status;
870 }
871
872 if (pinnedSize.cx)
873 return STATUS_SUCCESS;
874
875 /* now just create the new source mode set and apply it */
876 D3DKMDT_HVIDPNTARGETMODESET hVidPnModeSet;
877 const DXGK_VIDPNTARGETMODESET_INTERFACE *pVidPnModeSetInterface;
878 Status = pVidPnInterface->pfnCreateNewTargetModeSet(hVidPn,
879 VidPnTargetId,
880 &hVidPnModeSet,
881 &pVidPnModeSetInterface);
882 if (!NT_SUCCESS(Status))
883 {
884 WARN(("pfnCreateNewTargetModeSet failed Status(0x%x)", Status));
885 return Status;
886 }
887
888 Status = vboxVidPnTargetModeSetFromArray(hVidPnModeSet,
889 pVidPnModeSetInterface,
890 &aModes[VidPnTargetId]);
891 if (!NT_SUCCESS(Status))
892 {
893 WARN(("vboxVidPnTargetModeSetFromArray failed Status(0x%x)", Status));
894 vboxVidPnDumpVidPn("\nVidPn: ---------\n", pDevExt, hVidPn, pVidPnInterface, "\n------\n");
895 VBoxVidPnDumpMonitorModeSet("MonModeSet: --------\n", pDevExt, VidPnTargetId, "\n------\n");
896 NTSTATUS rcNt2 = pVidPnInterface->pfnReleaseTargetModeSet(hVidPn, hVidPnModeSet);
897 AssertNtStatusSuccess(rcNt2);
898 return Status;
899 }
900
901 Status = pVidPnInterface->pfnAssignTargetModeSet(hVidPn, VidPnTargetId, hVidPnModeSet);
902 if (!NT_SUCCESS(Status))
903 {
904 WARN(("\n\n!!!!!!!\n\n pfnAssignTargetModeSet failed, Status(0x%x)", Status));
905 vboxVidPnDumpVidPn("\nVidPn: ---------\n", pDevExt, hVidPn, pVidPnInterface, "\n------\n");
906 VBoxVidPnDumpMonitorModeSet("MonModeSet: --------\n", pDevExt, VidPnTargetId, "\n------\n");
907 NTSTATUS rcNt2 = pVidPnInterface->pfnReleaseTargetModeSet(hVidPn, hVidPnModeSet);
908 AssertNtStatusSuccess(rcNt2);
909 return Status;
910 }
911
912 Status = vboxVidPnCheckMonitorModes(pDevExt, VidPnTargetId, &aModes[VidPnTargetId]);
913
914 if (!NT_SUCCESS(Status))
915 {
916 WARN(("vboxVidPnCheckMonitorModes failed, Status(0x%x)", Status));
917 return Status;
918 }
919
920 return STATUS_SUCCESS;
921}
922
923static NTSTATUS vboxVidPnApplyInfoForPathSource(PVBOXMP_DEVEXT pDevExt,
924 D3DKMDT_HVIDPN hVidPn,
925 const DXGK_VIDPN_INTERFACE* pVidPnInterface,
926 D3DKMDT_ENUMCOFUNCMODALITY_PIVOT_TYPE enmCurPivot,
927 uint32_t *aAdjustedModeMap,
928 const CR_SORTARRAY *aModes,
929 D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
930{
931 RT_NOREF(aAdjustedModeMap);
932 Assert(ASMBitTest(aAdjustedModeMap, VidPnTargetId));
933
934 if (enmCurPivot == D3DKMDT_EPT_VIDPNSOURCE)
935 return STATUS_SUCCESS;
936
937 RTRECTSIZE pinnedSize = {0};
938 NTSTATUS Status = vboxVidPnQueryPinnedSourceMode(hVidPn, pVidPnInterface, VidPnSourceId, &pinnedSize);
939 if (!NT_SUCCESS(Status))
940 {
941 WARN(("vboxVidPnQueryPinnedSourceMode failed %#x", Status));
942 return Status;
943 }
944
945 if (pinnedSize.cx)
946 return STATUS_SUCCESS;
947
948 /* now just create the new source mode set and apply it */
949 D3DKMDT_HVIDPNSOURCEMODESET hVidPnModeSet;
950 const DXGK_VIDPNSOURCEMODESET_INTERFACE *pVidPnModeSetInterface;
951 Status = pVidPnInterface->pfnCreateNewSourceModeSet(hVidPn,
952 VidPnSourceId,
953 &hVidPnModeSet,
954 &pVidPnModeSetInterface);
955 if (!NT_SUCCESS(Status))
956 {
957 WARN(("pfnCreateNewSourceModeSet failed Status(0x%x)", Status));
958 return Status;
959 }
960
961 Status = vboxVidPnSourceModeSetFromArray(hVidPnModeSet,
962 pVidPnModeSetInterface,
963 &aModes[VidPnTargetId]); /* <- target modes always! */
964 if (!NT_SUCCESS(Status))
965 {
966 WARN(("vboxVidPnSourceModeSetFromArray failed Status(0x%x)", Status));
967 vboxVidPnDumpVidPn("\nVidPn: ---------\n", pDevExt, hVidPn, pVidPnInterface, "\n------\n");
968 VBoxVidPnDumpMonitorModeSet("MonModeSet: --------\n", pDevExt, VidPnTargetId, "\n------\n");
969 NTSTATUS rcNt2 = pVidPnInterface->pfnReleaseSourceModeSet(hVidPn, hVidPnModeSet);
970 AssertNtStatusSuccess(rcNt2);
971 return Status;
972 }
973
974 Status = pVidPnInterface->pfnAssignSourceModeSet(hVidPn, VidPnSourceId, hVidPnModeSet);
975 if (!NT_SUCCESS(Status))
976 {
977 WARN(("\n\n!!!!!!!\n\n pfnAssignSourceModeSet failed, Status(0x%x)", Status));
978 vboxVidPnDumpVidPn("\nVidPn: ---------\n", pDevExt, hVidPn, pVidPnInterface, "\n------\n");
979 VBoxVidPnDumpMonitorModeSet("MonModeSet: --------\n", pDevExt, VidPnTargetId, "\n------\n");
980 NTSTATUS rcNt2 = pVidPnInterface->pfnReleaseSourceModeSet(hVidPn, hVidPnModeSet);
981 AssertNtStatusSuccess(rcNt2);
982 return Status;
983 }
984
985 return STATUS_SUCCESS;
986}
987
988static NTSTATUS vboxVidPnCollectInfoForPathSource(PVBOXMP_DEVEXT pDevExt,
989 D3DKMDT_HVIDPN hVidPn,
990 const DXGK_VIDPN_INTERFACE* pVidPnInterface,
991 D3DKMDT_ENUMCOFUNCMODALITY_PIVOT_TYPE enmCurPivot,
992 uint32_t *aAdjustedModeMap,
993 CR_SORTARRAY *aModes,
994 D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
995{
996 const CR_SORTARRAY* pSupportedModes = VBoxWddmVModesGet(pDevExt, VidPnTargetId); /* <- yes, modes are target-determined always */
997 NTSTATUS Status;
998
999 if (enmCurPivot == D3DKMDT_EPT_VIDPNSOURCE)
1000 {
1001 D3DKMDT_HVIDPNSOURCEMODESET hVidPnModeSet;
1002 const DXGK_VIDPNSOURCEMODESET_INTERFACE *pVidPnModeSetInterface;
1003 Status = pVidPnInterface->pfnAcquireSourceModeSet(hVidPn,
1004 VidPnSourceId,
1005 &hVidPnModeSet,
1006 &pVidPnModeSetInterface);
1007 if (!NT_SUCCESS(Status))
1008 {
1009 WARN(("pfnAcquireSourceModeSet failed %#x", Status));
1010 return Status;
1011 }
1012
1013 /* intersect modes from target */
1014 if (!ASMBitTest(aAdjustedModeMap, VidPnTargetId))
1015 {
1016 Status = vboxVidPnSourceModeSetToArray(hVidPnModeSet, pVidPnModeSetInterface, &aModes[VidPnTargetId]);
1017 ASMBitSet(aAdjustedModeMap, VidPnTargetId);
1018 }
1019 else
1020 {
1021 CR_SORTARRAY Arr;
1022 CrSaInit(&Arr, 0);
1023 Status = vboxVidPnSourceModeSetToArray(hVidPnModeSet, pVidPnModeSetInterface, &aModes[VidPnTargetId]);
1024 CrSaIntersect(&aModes[VidPnTargetId], &Arr);
1025 CrSaCleanup(&Arr);
1026 }
1027
1028 NTSTATUS rcNt2 = pVidPnInterface->pfnReleaseSourceModeSet(hVidPn, hVidPnModeSet);
1029 AssertNtStatusSuccess(rcNt2);
1030
1031 if (!NT_SUCCESS(Status))
1032 {
1033 WARN(("pfnReleaseSourceModeSet failed %#x", Status));
1034 return Status;
1035 }
1036
1037 /* intersect it with supported target modes, just in case */
1038 CrSaIntersect(&aModes[VidPnTargetId], pSupportedModes);
1039
1040 return STATUS_SUCCESS;
1041 }
1042
1043 RTRECTSIZE pinnedSize = {0};
1044 Status = vboxVidPnQueryPinnedSourceMode(hVidPn, pVidPnInterface, VidPnSourceId, &pinnedSize);
1045 if (!NT_SUCCESS(Status))
1046 {
1047 WARN(("vboxVidPnQueryPinnedSourceMode failed %#x", Status));
1048 return Status;
1049 }
1050
1051 if (pinnedSize.cx)
1052 {
1053 Assert(CrSaContains(pSupportedModes, CR_RSIZE2U64(pinnedSize)));
1054
1055 if (!ASMBitTest(aAdjustedModeMap, VidPnTargetId))
1056 {
1057 Assert(CrSaGetSize(&aModes[VidPnTargetId]) == 0);
1058
1059 if (CrSaContains(pSupportedModes, CR_RSIZE2U64(pinnedSize)))
1060 {
1061 int rc = CrSaAdd(&aModes[VidPnTargetId], CR_RSIZE2U64(pinnedSize));
1062 if (!RT_SUCCESS(rc))
1063 {
1064 WARN(("CrSaAdd failed %d", rc));
1065 return STATUS_UNSUCCESSFUL;
1066 }
1067 }
1068 ASMBitSet(aAdjustedModeMap, VidPnTargetId);
1069 }
1070 else
1071 {
1072 CrSaClear(&aModes[VidPnTargetId]);
1073 if (CrSaContains(pSupportedModes, CR_RSIZE2U64(pinnedSize)))
1074 {
1075 int rc = CrSaAdd(&aModes[VidPnTargetId], CR_RSIZE2U64(pinnedSize));
1076 if (!RT_SUCCESS(rc))
1077 {
1078 WARN(("CrSaAdd failed %d", rc));
1079 return STATUS_UNSUCCESSFUL;
1080 }
1081 }
1082 }
1083
1084 return STATUS_SUCCESS;
1085 }
1086
1087
1088 Status = vboxVidPnQueryPinnedTargetMode(hVidPn, pVidPnInterface, VidPnTargetId, &pinnedSize);
1089 if (!NT_SUCCESS(Status))
1090 {
1091 WARN(("vboxVidPnQueryPinnedTargetMode failed %#x", Status));
1092 return Status;
1093 }
1094
1095 if (pinnedSize.cx)
1096 {
1097 Assert(CrSaContains(pSupportedModes, CR_RSIZE2U64(pinnedSize)));
1098
1099 if (!ASMBitTest(aAdjustedModeMap, VidPnTargetId))
1100 {
1101 Assert(CrSaGetSize(&aModes[VidPnTargetId]) == 0);
1102 int rc = CrSaAdd(&aModes[VidPnTargetId], CR_RSIZE2U64(pinnedSize));
1103 if (!RT_SUCCESS(rc))
1104 {
1105 WARN(("CrSaAdd failed %d", rc));
1106 return STATUS_UNSUCCESSFUL;
1107 }
1108 ASMBitSet(aAdjustedModeMap, VidPnTargetId);
1109 }
1110 else
1111 {
1112 CrSaClear(&aModes[VidPnTargetId]);
1113 int rc = CrSaAdd(&aModes[VidPnTargetId], CR_RSIZE2U64(pinnedSize));
1114 if (!RT_SUCCESS(rc))
1115 {
1116 WARN(("CrSaAdd failed %d", rc));
1117 return STATUS_UNSUCCESSFUL;
1118 }
1119 }
1120
1121 return STATUS_SUCCESS;
1122 }
1123
1124 /* now we are here because no pinned info is specified, we need to populate it based on the supported info
1125 * and modes already configured,
1126 * this is pretty simple actually */
1127
1128 if (!ASMBitTest(aAdjustedModeMap, VidPnTargetId))
1129 {
1130 Assert(CrSaGetSize(&aModes[VidPnTargetId]) == 0);
1131 int rc = CrSaClone(pSupportedModes, &aModes[VidPnTargetId]);
1132 if (!RT_SUCCESS(rc))
1133 {
1134 WARN(("CrSaClone failed %d", rc));
1135 return STATUS_UNSUCCESSFUL;
1136 }
1137 ASMBitSet(aAdjustedModeMap, VidPnTargetId);
1138 }
1139 else
1140 {
1141 CrSaIntersect(&aModes[VidPnTargetId], pSupportedModes);
1142 }
1143
1144 /* we are done */
1145 return STATUS_SUCCESS;
1146}
1147
1148static NTSTATUS vboxVidPnCheckMonitorModes(PVBOXMP_DEVEXT pDevExt, uint32_t u32Target, const CR_SORTARRAY *pSupportedModes)
1149{
1150 NTSTATUS Status;
1151 CONST DXGK_MONITOR_INTERFACE *pMonitorInterface;
1152 Status = pDevExt->u.primary.DxgkInterface.DxgkCbQueryMonitorInterface(pDevExt->u.primary.DxgkInterface.DeviceHandle, DXGK_MONITOR_INTERFACE_VERSION_V1, &pMonitorInterface);
1153 if (!NT_SUCCESS(Status))
1154 {
1155 WARN(("DxgkCbQueryMonitorInterface failed, Status()0x%x", Status));
1156 return Status;
1157 }
1158
1159 D3DKMDT_HMONITORSOURCEMODESET hVidPnModeSet;
1160 CONST DXGK_MONITORSOURCEMODESET_INTERFACE *pVidPnModeSetInterface;
1161
1162 if (!pSupportedModes)
1163 {
1164 pSupportedModes = VBoxWddmVModesGet(pDevExt, u32Target);
1165 }
1166
1167 CR_SORTARRAY DiffModes;
1168 int rc = CrSaInit(&DiffModes, CrSaGetSize(pSupportedModes));
1169 if (!RT_SUCCESS(rc))
1170 {
1171 WARN(("CrSaInit failed"));
1172 return STATUS_NO_MEMORY;
1173 }
1174
1175
1176 Status = pMonitorInterface->pfnAcquireMonitorSourceModeSet(pDevExt->u.primary.DxgkInterface.DeviceHandle,
1177 u32Target,
1178 &hVidPnModeSet,
1179 &pVidPnModeSetInterface);
1180 if (!NT_SUCCESS(Status))
1181 {
1182 WARN(("DxgkCbQueryMonitorInterface failed, Status()0x%x", Status));
1183// if (Status == STATUS_GRAPHICS_MONITOR_NOT_CONNECTED)
1184 CrSaCleanup(&DiffModes);
1185 return Status;
1186 }
1187
1188 VBOXVIDPN_MONITORMODE_ITER Iter;
1189 const D3DKMDT_MONITOR_SOURCE_MODE *pVidPnModeInfo;
1190
1191 rc = CrSaClone(pSupportedModes, &DiffModes);
1192 if (!RT_SUCCESS(rc))
1193 {
1194 WARN(("CrSaClone failed"));
1195 Status = STATUS_NO_MEMORY;
1196 goto done;
1197 }
1198
1199 VBoxVidPnMonitorModeIterInit(&Iter, hVidPnModeSet, pVidPnModeSetInterface);
1200
1201 while ((pVidPnModeInfo = VBoxVidPnMonitorModeIterNext(&Iter)) != NULL)
1202 {
1203 RTRECTSIZE size;
1204 size.cx = pVidPnModeInfo->VideoSignalInfo.ActiveSize.cx;
1205 size.cy = pVidPnModeInfo->VideoSignalInfo.ActiveSize.cy;
1206 CrSaRemove(&DiffModes, CR_RSIZE2U64(size));
1207 LOGF(("mode (%d x %d) is already in monitor modeset\n", size.cx, size.cy));
1208 }
1209
1210 VBoxVidPnMonitorModeIterTerm(&Iter);
1211
1212 Status = VBoxVidPnMonitorModeIterStatus(&Iter);
1213 if (!NT_SUCCESS(Status))
1214 {
1215 WARN(("iter status failed %#x", Status));
1216 goto done;
1217 }
1218
1219 LOGF(("Adding %d additional modes to monitor modeset\n", CrSaGetSize(&DiffModes)));
1220
1221 Status = vboxVidPnMonitorModeSetFromArray(hVidPnModeSet, pVidPnModeSetInterface, &DiffModes);
1222 if (!NT_SUCCESS(Status))
1223 {
1224 WARN(("vboxVidPnMonitorModeSetFromArray failed %#x", Status));
1225 goto done;
1226 }
1227
1228done:
1229 NTSTATUS rcNt2 = pMonitorInterface->pfnReleaseMonitorSourceModeSet(pDevExt->u.primary.DxgkInterface.DeviceHandle, hVidPnModeSet);
1230 if (!NT_SUCCESS(rcNt2))
1231 WARN(("pfnReleaseMonitorSourceModeSet failed rcNt2(0x%x)", rcNt2));
1232
1233 CrSaCleanup(&DiffModes);
1234
1235 return Status;
1236}
1237
1238static NTSTATUS vboxVidPnPathAdd(D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface,
1239 const D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, const D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId,
1240 D3DKMDT_VIDPN_PRESENT_PATH_IMPORTANCE enmImportance)
1241{
1242 D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology;
1243 const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface;
1244 NTSTATUS Status = pVidPnInterface->pfnGetTopology(hVidPn, &hVidPnTopology, &pVidPnTopologyInterface);
1245 if (!NT_SUCCESS(Status))
1246 {
1247 AssertFailed();
1248 return Status;
1249 }
1250
1251 D3DKMDT_VIDPN_PRESENT_PATH *pNewVidPnPresentPathInfo;
1252 Status = pVidPnTopologyInterface->pfnCreateNewPathInfo(hVidPnTopology, &pNewVidPnPresentPathInfo);
1253 if (!NT_SUCCESS(Status))
1254 {
1255 AssertFailed();
1256 return Status;
1257 }
1258
1259 pNewVidPnPresentPathInfo->VidPnSourceId = VidPnSourceId;
1260 pNewVidPnPresentPathInfo->VidPnTargetId = VidPnTargetId;
1261 pNewVidPnPresentPathInfo->ImportanceOrdinal = enmImportance;
1262 pNewVidPnPresentPathInfo->ContentTransformation.Scaling = D3DKMDT_VPPS_IDENTITY;
1263 memset(&pNewVidPnPresentPathInfo->ContentTransformation.ScalingSupport,
1264 0, sizeof (pNewVidPnPresentPathInfo->ContentTransformation.ScalingSupport));
1265 pNewVidPnPresentPathInfo->ContentTransformation.ScalingSupport.Identity = 1;
1266 pNewVidPnPresentPathInfo->ContentTransformation.ScalingSupport.Centered = 0;
1267 pNewVidPnPresentPathInfo->ContentTransformation.ScalingSupport.Stretched = 0;
1268 pNewVidPnPresentPathInfo->ContentTransformation.Rotation = D3DKMDT_VPPR_IDENTITY;
1269 pNewVidPnPresentPathInfo->ContentTransformation.RotationSupport.Identity = 1;
1270 pNewVidPnPresentPathInfo->ContentTransformation.RotationSupport.Rotate180 = 0;
1271 pNewVidPnPresentPathInfo->ContentTransformation.RotationSupport.Rotate270 = 0;
1272 pNewVidPnPresentPathInfo->ContentTransformation.RotationSupport.Rotate90 = 0;
1273 pNewVidPnPresentPathInfo->VisibleFromActiveTLOffset.cx = 0;
1274 pNewVidPnPresentPathInfo->VisibleFromActiveTLOffset.cy = 0;
1275 pNewVidPnPresentPathInfo->VisibleFromActiveBROffset.cx = 0;
1276 pNewVidPnPresentPathInfo->VisibleFromActiveBROffset.cy = 0;
1277 pNewVidPnPresentPathInfo->VidPnTargetColorBasis = D3DKMDT_CB_SRGB; /** @todo how does it matters? */
1278 pNewVidPnPresentPathInfo->VidPnTargetColorCoeffDynamicRanges.FirstChannel = 8;
1279 pNewVidPnPresentPathInfo->VidPnTargetColorCoeffDynamicRanges.SecondChannel = 8;
1280 pNewVidPnPresentPathInfo->VidPnTargetColorCoeffDynamicRanges.ThirdChannel = 8;
1281 pNewVidPnPresentPathInfo->VidPnTargetColorCoeffDynamicRanges.FourthChannel = 0;
1282 pNewVidPnPresentPathInfo->Content = D3DKMDT_VPPC_GRAPHICS;
1283 pNewVidPnPresentPathInfo->CopyProtection.CopyProtectionType = D3DKMDT_VPPMT_UNINITIALIZED;
1284// pNewVidPnPresentPathInfo->CopyProtection.CopyProtectionType = D3DKMDT_VPPMT_NOPROTECTION;
1285 pNewVidPnPresentPathInfo->CopyProtection.APSTriggerBits = 0;
1286 memset(&pNewVidPnPresentPathInfo->CopyProtection.CopyProtectionSupport, 0, sizeof (pNewVidPnPresentPathInfo->CopyProtection.CopyProtectionSupport));
1287// pNewVidPnPresentPathInfo->CopyProtection.CopyProtectionSupport.NoProtection = 1;
1288 memset (&pNewVidPnPresentPathInfo->GammaRamp, 0, sizeof (pNewVidPnPresentPathInfo->GammaRamp));
1289// pNewVidPnPresentPathInfo->GammaRamp.Type = D3DDDI_GAMMARAMP_DEFAULT;
1290// pNewVidPnPresentPathInfo->GammaRamp.DataSize = 0;
1291 Status = pVidPnTopologyInterface->pfnAddPath(hVidPnTopology, pNewVidPnPresentPathInfo);
1292 if (!NT_SUCCESS(Status))
1293 {
1294 AssertFailed();
1295 NTSTATUS rcNt2 = pVidPnTopologyInterface->pfnReleasePathInfo(hVidPnTopology, pNewVidPnPresentPathInfo);
1296 AssertNtStatus(rcNt2);
1297 }
1298
1299 LOG(("Recommended Path (%d->%d)", VidPnSourceId, VidPnTargetId));
1300
1301 return Status;
1302}
1303
1304NTSTATUS VBoxVidPnRecommendMonitorModes(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_TARGET_ID VideoPresentTargetId,
1305 D3DKMDT_HMONITORSOURCEMODESET hVidPnModeSet, const DXGK_MONITORSOURCEMODESET_INTERFACE *pVidPnModeSetInterface)
1306{
1307 const CR_SORTARRAY *pSupportedModes = VBoxWddmVModesGet(pDevExt, VideoPresentTargetId);
1308
1309 NTSTATUS Status = vboxVidPnMonitorModeSetFromArray(hVidPnModeSet, pVidPnModeSetInterface, pSupportedModes);
1310 if (!NT_SUCCESS(Status))
1311 {
1312 WARN(("vboxVidPnMonitorModeSetFromArray failed %d", Status));
1313 return Status;
1314 }
1315
1316 return STATUS_SUCCESS;
1317}
1318
1319NTSTATUS VBoxVidPnUpdateModes(PVBOXMP_DEVEXT pDevExt, uint32_t u32TargetId, const RTRECTSIZE *pSize)
1320{
1321 LOGF(("ENTER u32TargetId(%d) mode(%d x %d)", u32TargetId, pSize->cx, pSize->cy));
1322
1323 if (u32TargetId >= (uint32_t)VBoxCommonFromDeviceExt(pDevExt)->cDisplays)
1324 {
1325 WARN(("invalid target id"));
1326 return STATUS_INVALID_PARAMETER;
1327 }
1328
1329 int rc = VBoxWddmVModesAdd(pDevExt, u32TargetId, pSize, TRUE);
1330 LOGF(("VBoxWddmVModesAdd returned (%d)", rc));
1331
1332 if (RT_FAILURE(rc))
1333 {
1334 WARN(("VBoxWddmVModesAdd failed %d", rc));
1335 return STATUS_UNSUCCESSFUL;
1336 }
1337
1338 if (rc == VINF_ALREADY_INITIALIZED)
1339 {
1340 /* mode was already in list, just return */
1341 Assert(CrSaContains(VBoxWddmVModesGet(pDevExt, u32TargetId), CR_RSIZE2U64(*pSize)));
1342 LOGF(("LEAVE mode was already in modeset, just return"));
1343 return STATUS_SUCCESS;
1344 }
1345
1346#ifdef VBOX_WDDM_REPLUG_ON_MODE_CHANGE
1347 /* The VBOXESC_UPDATEMODES is a hint for the driver to use new display mode as soon as VidPn
1348 * manager will ask for it.
1349 * Probably, some new interface is required to plug/unplug displays by calling
1350 * VBoxWddmChildStatusReportReconnected.
1351 * But it is a bad idea to mix sending a display mode hint and (un)plug displays in VBOXESC_UPDATEMODES.
1352 */
1353
1354 /* modes have changed, need to replug */
1355 NTSTATUS Status = VBoxWddmChildStatusReportReconnected(pDevExt, u32TargetId);
1356 LOG(("VBoxWddmChildStatusReportReconnected returned (%d)", Status));
1357 if (!NT_SUCCESS(Status))
1358 {
1359 WARN(("VBoxWddmChildStatusReportReconnected failed Status(%#x)", Status));
1360 return Status;
1361 }
1362#endif
1363
1364 LOGF(("LEAVE u32TargetId(%d)", u32TargetId));
1365 return STATUS_SUCCESS;
1366}
1367
1368NTSTATUS VBoxVidPnRecommendFunctional(PVBOXMP_DEVEXT pDevExt, D3DKMDT_HVIDPN hVidPn, const VBOXWDDM_RECOMMENDVIDPN *pData)
1369{
1370 const DXGK_VIDPN_INTERFACE* pVidPnInterface = NULL;
1371 NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbQueryVidPnInterface(hVidPn, DXGK_VIDPN_INTERFACE_VERSION_V1, &pVidPnInterface);
1372 if (!NT_SUCCESS(Status))
1373 {
1374 WARN(("DxgkCbQueryVidPnInterface failed Status(%#x)", Status));
1375 return Status;
1376 }
1377
1378 VBOXCMDVBVA_SCREENMAP_DECL(uint32_t, aVisitedSourceMap);
1379
1380 memset(aVisitedSourceMap, 0, sizeof (aVisitedSourceMap));
1381
1382 uint32_t Importance = (uint32_t)D3DKMDT_VPPI_PRIMARY;
1383
1384 for (uint32_t i = 0; i < (uint32_t)VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
1385 {
1386 int32_t iSource = pData->aTargets[i].iSource;
1387 if (iSource < 0)
1388 continue;
1389
1390 if (iSource >= VBoxCommonFromDeviceExt(pDevExt)->cDisplays)
1391 {
1392 WARN(("invalid iSource"));
1393 return STATUS_INVALID_PARAMETER;
1394 }
1395
1396 if (!pDevExt->fComplexTopologiesEnabled && iSource != (int32_t)i)
1397 {
1398 WARN(("complex topologies not supported!"));
1399 return STATUS_INVALID_PARAMETER;
1400 }
1401
1402 bool fNewSource = false;
1403
1404 if (!ASMBitTest(aVisitedSourceMap, iSource))
1405 {
1406 int rc = VBoxWddmVModesAdd(pDevExt, i, &pData->aSources[iSource].Size, TRUE);
1407 if (RT_FAILURE(rc))
1408 {
1409 WARN(("VBoxWddmVModesAdd failed %d", rc));
1410 return STATUS_UNSUCCESSFUL;
1411 }
1412
1413 Assert(CrSaContains(VBoxWddmVModesGet(pDevExt, i), CR_RSIZE2U64(pData->aSources[iSource].Size)));
1414
1415 Status = vboxVidPnCheckMonitorModes(pDevExt, i);
1416 if (!NT_SUCCESS(Status))
1417 {
1418 WARN(("vboxVidPnCheckMonitorModes failed %#x", Status));
1419 return Status;
1420 }
1421
1422 ASMBitSet(aVisitedSourceMap, iSource);
1423 fNewSource = true;
1424 }
1425
1426 Status = vboxVidPnPathAdd(hVidPn, pVidPnInterface,
1427 (const D3DDDI_VIDEO_PRESENT_SOURCE_ID)iSource, (const D3DDDI_VIDEO_PRESENT_TARGET_ID)i,
1428 (D3DKMDT_VIDPN_PRESENT_PATH_IMPORTANCE)Importance);
1429 if (!NT_SUCCESS(Status))
1430 {
1431 WARN(("vboxVidPnPathAdd failed Status()0x%x\n", Status));
1432 return Status;
1433 }
1434
1435 Importance++;
1436
1437 do {
1438 D3DKMDT_HVIDPNTARGETMODESET hVidPnModeSet;
1439 const DXGK_VIDPNTARGETMODESET_INTERFACE *pVidPnModeSetInterface;
1440
1441 Status = pVidPnInterface->pfnCreateNewTargetModeSet(hVidPn,
1442 i,
1443 &hVidPnModeSet,
1444 &pVidPnModeSetInterface);
1445 if (NT_SUCCESS(Status))
1446 {
1447 D3DKMDT_VIDPN_TARGET_MODE *pVidPnModeInfo;
1448 Status = pVidPnModeSetInterface->pfnCreateNewModeInfo(hVidPnModeSet, &pVidPnModeInfo);
1449 if (NT_SUCCESS(Status))
1450 {
1451 vboxVidPnPopulateTargetModeInfo(pVidPnModeInfo, &pData->aSources[iSource].Size);
1452
1453 IN_CONST_D3DKMDT_VIDEO_PRESENT_TARGET_MODE_ID idMode = pVidPnModeInfo->Id;
1454
1455 Status = pVidPnModeSetInterface->pfnAddMode(hVidPnModeSet, pVidPnModeInfo);
1456 if (NT_SUCCESS(Status))
1457 {
1458 pVidPnModeInfo = NULL;
1459
1460 Status = pVidPnModeSetInterface->pfnPinMode(hVidPnModeSet, idMode);
1461 if (NT_SUCCESS(Status))
1462 {
1463 Status = pVidPnInterface->pfnAssignTargetModeSet(hVidPn, i, hVidPnModeSet);
1464 if (NT_SUCCESS(Status))
1465 {
1466 LOG(("Recommended Target[%d] (%dx%d)", i, pData->aSources[iSource].Size.cx, pData->aSources[iSource].Size.cy));
1467 break;
1468 }
1469 else
1470 WARN(("pfnAssignTargetModeSet failed %#x", Status));
1471 }
1472 else
1473 WARN(("pfnPinMode failed %#x", Status));
1474
1475 }
1476 else
1477 WARN(("pfnAddMode failed %#x", Status));
1478
1479 if (pVidPnModeInfo)
1480 {
1481 NTSTATUS rcNt2 = pVidPnModeSetInterface->pfnReleaseModeInfo(hVidPnModeSet, pVidPnModeInfo);
1482 AssertNtStatusSuccess(rcNt2);
1483 }
1484 }
1485 else
1486 WARN(("pfnCreateNewTargetModeSet failed %#x", Status));
1487
1488 NTSTATUS rcNt2 = pVidPnInterface->pfnReleaseTargetModeSet(hVidPn, hVidPnModeSet);
1489 AssertNtStatusSuccess(rcNt2);
1490 }
1491 else
1492 WARN(("pfnCreateNewTargetModeSet failed %#x", Status));
1493
1494 Assert(!NT_SUCCESS(Status));
1495
1496 return Status;
1497 } while (0);
1498
1499 if (fNewSource)
1500 {
1501 do {
1502 D3DKMDT_HVIDPNSOURCEMODESET hVidPnModeSet;
1503 const DXGK_VIDPNSOURCEMODESET_INTERFACE *pVidPnModeSetInterface;
1504
1505 Status = pVidPnInterface->pfnCreateNewSourceModeSet(hVidPn,
1506 iSource,
1507 &hVidPnModeSet,
1508 &pVidPnModeSetInterface);
1509 if (NT_SUCCESS(Status))
1510 {
1511 D3DKMDT_VIDPN_SOURCE_MODE *pVidPnModeInfo;
1512 Status = pVidPnModeSetInterface->pfnCreateNewModeInfo(hVidPnModeSet, &pVidPnModeInfo);
1513 if (NT_SUCCESS(Status))
1514 {
1515 vboxVidPnPopulateSourceModeInfo(pVidPnModeInfo, &pData->aSources[iSource].Size);
1516
1517 IN_CONST_D3DKMDT_VIDEO_PRESENT_SOURCE_MODE_ID idMode = pVidPnModeInfo->Id;
1518
1519 Status = pVidPnModeSetInterface->pfnAddMode(hVidPnModeSet, pVidPnModeInfo);
1520 if (NT_SUCCESS(Status))
1521 {
1522 pVidPnModeInfo = NULL;
1523
1524 Status = pVidPnModeSetInterface->pfnPinMode(hVidPnModeSet, idMode);
1525 if (NT_SUCCESS(Status))
1526 {
1527 Status = pVidPnInterface->pfnAssignSourceModeSet(hVidPn, iSource, hVidPnModeSet);
1528 if (NT_SUCCESS(Status))
1529 {
1530 LOG(("Recommended Source[%d] (%dx%d)", iSource, pData->aSources[iSource].Size.cx, pData->aSources[iSource].Size.cy));
1531 break;
1532 }
1533 else
1534 WARN(("pfnAssignSourceModeSet failed %#x", Status));
1535 }
1536 else
1537 WARN(("pfnPinMode failed %#x", Status));
1538
1539 }
1540 else
1541 WARN(("pfnAddMode failed %#x", Status));
1542
1543 if (pVidPnModeInfo)
1544 {
1545 NTSTATUS rcNt2 = pVidPnModeSetInterface->pfnReleaseModeInfo(hVidPnModeSet, pVidPnModeInfo);
1546 AssertNtStatusSuccess(rcNt2);
1547 }
1548 }
1549 else
1550 WARN(("pfnCreateNewSourceModeSet failed %#x", Status));
1551
1552 NTSTATUS rcNt2 = pVidPnInterface->pfnReleaseSourceModeSet(hVidPn, hVidPnModeSet);
1553 AssertNtStatusSuccess(rcNt2);
1554 }
1555 else
1556 WARN(("pfnCreateNewSourceModeSet failed %#x", Status));
1557
1558 Assert(!NT_SUCCESS(Status));
1559
1560 return Status;
1561 } while (0);
1562 }
1563 }
1564
1565 Assert(NT_SUCCESS(Status));
1566 return STATUS_SUCCESS;
1567}
1568
1569static BOOLEAN vboxVidPnIsPathSupported(PVBOXMP_DEVEXT pDevExt, const D3DKMDT_VIDPN_PRESENT_PATH *pNewVidPnPresentPathInfo)
1570{
1571 if (!pDevExt->fComplexTopologiesEnabled && pNewVidPnPresentPathInfo->VidPnSourceId != pNewVidPnPresentPathInfo->VidPnTargetId)
1572 {
1573 LOG(("unsupported source(%d)->target(%d) pair", pNewVidPnPresentPathInfo->VidPnSourceId, pNewVidPnPresentPathInfo->VidPnTargetId));
1574 return FALSE;
1575 }
1576
1577 /*
1578 ImportanceOrdinal does not matter for now
1579 pNewVidPnPresentPathInfo->ImportanceOrdinal
1580 */
1581
1582 if (pNewVidPnPresentPathInfo->ContentTransformation.Scaling != D3DKMDT_VPPS_UNPINNED
1583 && pNewVidPnPresentPathInfo->ContentTransformation.Scaling != D3DKMDT_VPPS_IDENTITY
1584 && pNewVidPnPresentPathInfo->ContentTransformation.Scaling != D3DKMDT_VPPS_NOTSPECIFIED)
1585 {
1586 WARN(("unsupported Scaling (%d)", pNewVidPnPresentPathInfo->ContentTransformation.Scaling));
1587 return FALSE;
1588 }
1589
1590 if ( !pNewVidPnPresentPathInfo->ContentTransformation.ScalingSupport.Identity
1591 || pNewVidPnPresentPathInfo->ContentTransformation.ScalingSupport.Centered
1592 || pNewVidPnPresentPathInfo->ContentTransformation.ScalingSupport.Stretched)
1593 {
1594 WARN(("unsupported Scaling support"));
1595 return FALSE;
1596 }
1597
1598 if (pNewVidPnPresentPathInfo->ContentTransformation.Rotation != D3DKMDT_VPPR_UNPINNED
1599 && pNewVidPnPresentPathInfo->ContentTransformation.Rotation != D3DKMDT_VPPR_IDENTITY
1600 && pNewVidPnPresentPathInfo->ContentTransformation.Rotation != D3DKMDT_VPPR_NOTSPECIFIED)
1601 {
1602 WARN(("unsupported rotation (%d)", pNewVidPnPresentPathInfo->ContentTransformation.Rotation));
1603 return FALSE;
1604 }
1605
1606 if ( !pNewVidPnPresentPathInfo->ContentTransformation.RotationSupport.Identity
1607 || pNewVidPnPresentPathInfo->ContentTransformation.RotationSupport.Rotate90
1608 || pNewVidPnPresentPathInfo->ContentTransformation.RotationSupport.Rotate180
1609 || pNewVidPnPresentPathInfo->ContentTransformation.RotationSupport.Rotate270)
1610 {
1611 WARN(("unsupported RotationSupport"));
1612 return FALSE;
1613 }
1614
1615 if (pNewVidPnPresentPathInfo->VisibleFromActiveTLOffset.cx
1616 || pNewVidPnPresentPathInfo->VisibleFromActiveTLOffset.cy)
1617 {
1618 WARN(("Non-zero TLOffset: cx(%d), cy(%d)",
1619 pNewVidPnPresentPathInfo->VisibleFromActiveTLOffset.cx,
1620 pNewVidPnPresentPathInfo->VisibleFromActiveTLOffset.cy));
1621 return FALSE;
1622 }
1623
1624 if (pNewVidPnPresentPathInfo->VisibleFromActiveBROffset.cx
1625 || pNewVidPnPresentPathInfo->VisibleFromActiveBROffset.cy)
1626 {
1627 WARN(("Non-zero TLOffset: cx(%d), cy(%d)",
1628 pNewVidPnPresentPathInfo->VisibleFromActiveBROffset.cx,
1629 pNewVidPnPresentPathInfo->VisibleFromActiveBROffset.cy));
1630 return FALSE;
1631 }
1632
1633 if (pNewVidPnPresentPathInfo->VidPnTargetColorBasis != D3DKMDT_CB_SRGB
1634 && pNewVidPnPresentPathInfo->VidPnTargetColorBasis != D3DKMDT_CB_UNINITIALIZED)
1635 {
1636 WARN(("unsupported VidPnTargetColorBasis (%d)", pNewVidPnPresentPathInfo->VidPnTargetColorBasis));
1637 return FALSE;
1638 }
1639
1640 /* channels?
1641 pNewVidPnPresentPathInfo->VidPnTargetColorCoeffDynamicRanges.FirstChannel;
1642 pNewVidPnPresentPathInfo->VidPnTargetColorCoeffDynamicRanges.SecondChannel;
1643 pNewVidPnPresentPathInfo->VidPnTargetColorCoeffDynamicRanges.ThirdChannel;
1644 we definitely not support fourth channel
1645 */
1646 if (pNewVidPnPresentPathInfo->VidPnTargetColorCoeffDynamicRanges.FourthChannel)
1647 {
1648 WARN(("Non-zero FourthChannel (%d)", pNewVidPnPresentPathInfo->VidPnTargetColorCoeffDynamicRanges.FourthChannel));
1649 return FALSE;
1650 }
1651
1652 /* Content (D3DKMDT_VPPC_GRAPHICS, _NOTSPECIFIED, _VIDEO), does not matter for now
1653 pNewVidPnPresentPathInfo->Content
1654 */
1655 /* not support copy protection for now */
1656 if (pNewVidPnPresentPathInfo->CopyProtection.CopyProtectionType != D3DKMDT_VPPMT_NOPROTECTION
1657 && pNewVidPnPresentPathInfo->CopyProtection.CopyProtectionType != D3DKMDT_VPPMT_UNINITIALIZED)
1658 {
1659 WARN(("Copy protection not supported CopyProtectionType(%d)", pNewVidPnPresentPathInfo->CopyProtection.CopyProtectionType));
1660 return FALSE;
1661 }
1662
1663 if (pNewVidPnPresentPathInfo->CopyProtection.APSTriggerBits)
1664 {
1665 WARN(("Copy protection not supported APSTriggerBits(%d)", pNewVidPnPresentPathInfo->CopyProtection.APSTriggerBits));
1666 return FALSE;
1667 }
1668
1669 D3DKMDT_VIDPN_PRESENT_PATH_COPYPROTECTION_SUPPORT tstCPSupport = {0};
1670 tstCPSupport.NoProtection = 1;
1671 if (memcmp(&tstCPSupport, &pNewVidPnPresentPathInfo->CopyProtection.CopyProtectionSupport, sizeof(tstCPSupport)))
1672 {
1673 WARN(("Copy protection support (0x%x)", *((UINT*)&pNewVidPnPresentPathInfo->CopyProtection.CopyProtectionSupport)));
1674 return FALSE;
1675 }
1676
1677 if (pNewVidPnPresentPathInfo->GammaRamp.Type != D3DDDI_GAMMARAMP_DEFAULT
1678 && pNewVidPnPresentPathInfo->GammaRamp.Type != D3DDDI_GAMMARAMP_UNINITIALIZED)
1679 {
1680 WARN(("Unsupported GammaRamp.Type (%d)", pNewVidPnPresentPathInfo->GammaRamp.Type));
1681 return FALSE;
1682 }
1683
1684 if (pNewVidPnPresentPathInfo->GammaRamp.DataSize != 0)
1685 {
1686 WARN(("Warning: non-zero GammaRamp.DataSize (%d), treating as supported", pNewVidPnPresentPathInfo->GammaRamp.DataSize));
1687 }
1688
1689 return TRUE;
1690}
1691
1692NTSTATUS VBoxVidPnIsSupported(PVBOXMP_DEVEXT pDevExt, D3DKMDT_HVIDPN hVidPn, BOOLEAN *pfSupported)
1693{
1694 /* According Microsoft Docs we must return pfSupported = TRUE here if hVidPn is NULL, as
1695 * the display adapter can always be configured to display nothing. */
1696 if (hVidPn == NULL)
1697 {
1698 *pfSupported = TRUE;
1699 return STATUS_SUCCESS;
1700 }
1701
1702 *pfSupported = FALSE;
1703
1704 const DXGK_VIDPN_INTERFACE* pVidPnInterface = NULL;
1705 NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbQueryVidPnInterface(hVidPn, DXGK_VIDPN_INTERFACE_VERSION_V1, &pVidPnInterface);
1706 if (!NT_SUCCESS(Status))
1707 {
1708 WARN(("DxgkCbQueryVidPnInterface failed Status()0x%x\n", Status));
1709 return Status;
1710 }
1711
1712#ifdef VBOXWDDM_DEBUG_VIDPN
1713 vboxVidPnDumpVidPn(">>>>IsSupported VidPN (IN) : >>>>\n", pDevExt, hVidPn, pVidPnInterface, "<<<<<<<<<<<<<<<<<<<<\n");
1714#endif
1715
1716 D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology;
1717 const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface;
1718 Status = pVidPnInterface->pfnGetTopology(hVidPn, &hVidPnTopology, &pVidPnTopologyInterface);
1719 if (!NT_SUCCESS(Status))
1720 {
1721 WARN(("pfnGetTopology failed Status()0x%x\n", Status));
1722 return Status;
1723 }
1724
1725 VBOXVIDPN_PATH_ITER PathIter;
1726 const D3DKMDT_VIDPN_PRESENT_PATH * pPath;
1727 VBOXCMDVBVA_SCREENMAP_DECL(uint32_t, aVisitedTargetMap);
1728
1729 memset(aVisitedTargetMap, 0, sizeof (aVisitedTargetMap));
1730
1731 BOOLEAN fSupported = TRUE;
1732 /* collect info first */
1733 VBoxVidPnPathIterInit(&PathIter, hVidPnTopology, pVidPnTopologyInterface);
1734 while ((pPath = VBoxVidPnPathIterNext(&PathIter)) != NULL)
1735 {
1736 D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId = pPath->VidPnSourceId;
1737 D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId = pPath->VidPnTargetId;
1738 /* actually vidpn topology should contain only one target info, right? */
1739 Assert(!ASMBitTest(aVisitedTargetMap, VidPnTargetId));
1740 ASMBitSet(aVisitedTargetMap, VidPnTargetId);
1741
1742 if (!vboxVidPnIsPathSupported(pDevExt, pPath))
1743 {
1744 fSupported = FALSE;
1745 break;
1746 }
1747
1748 RTRECTSIZE TargetSize;
1749 RTRECTSIZE SourceSize;
1750 Status = vboxVidPnQueryPinnedTargetMode(hVidPn, pVidPnInterface, VidPnTargetId, &TargetSize);
1751 if (!NT_SUCCESS(Status))
1752 {
1753 WARN(("vboxVidPnQueryPinnedTargetMode failed %#x", Status));
1754 break;
1755 }
1756
1757 Status = vboxVidPnQueryPinnedSourceMode(hVidPn, pVidPnInterface, VidPnSourceId, &SourceSize);
1758 if (!NT_SUCCESS(Status))
1759 {
1760 WARN(("vboxVidPnQueryPinnedSourceMode failed %#x", Status));
1761 break;
1762 }
1763
1764 if (memcmp(&TargetSize, &SourceSize, sizeof (TargetSize)) && TargetSize.cx)
1765 {
1766 if (!SourceSize.cx)
1767 WARN(("not expected?"));
1768
1769 fSupported = FALSE;
1770 break;
1771 }
1772 }
1773
1774 VBoxVidPnPathIterTerm(&PathIter);
1775
1776 if (!NT_SUCCESS(Status))
1777 goto done;
1778
1779 Status = VBoxVidPnPathIterStatus(&PathIter);
1780 if (!NT_SUCCESS(Status))
1781 {
1782 WARN(("PathIter failed Status()0x%x\n", Status));
1783 goto done;
1784 }
1785
1786 *pfSupported = fSupported;
1787done:
1788
1789 return Status;
1790}
1791
1792NTSTATUS VBoxVidPnCofuncModality(PVBOXMP_DEVEXT pDevExt, D3DKMDT_HVIDPN hVidPn, D3DKMDT_ENUMCOFUNCMODALITY_PIVOT_TYPE enmPivot, const DXGK_ENUM_PIVOT *pPivot)
1793{
1794 const DXGK_VIDPN_INTERFACE* pVidPnInterface = NULL;
1795 NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbQueryVidPnInterface(hVidPn, DXGK_VIDPN_INTERFACE_VERSION_V1, &pVidPnInterface);
1796 if (!NT_SUCCESS(Status))
1797 {
1798 WARN(("DxgkCbQueryVidPnInterface failed Status()0x%x\n", Status));
1799 return Status;
1800 }
1801
1802#ifdef VBOXWDDM_DEBUG_VIDPN
1803 vboxVidPnDumpCofuncModalityArg(">>>>MODALITY Args: ", enmPivot, pPivot, "\n");
1804 vboxVidPnDumpVidPn(">>>>MODALITY VidPN (IN) : >>>>\n", pDevExt, hVidPn, pVidPnInterface, "<<<<<<<<<<<<<<<<<<<<\n");
1805#endif
1806
1807 D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology;
1808 const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface;
1809 Status = pVidPnInterface->pfnGetTopology(hVidPn, &hVidPnTopology, &pVidPnTopologyInterface);
1810 if (!NT_SUCCESS(Status))
1811 {
1812 WARN(("pfnGetTopology failed Status()0x%x\n", Status));
1813 return Status;
1814 }
1815
1816 VBOXVIDPN_PATH_ITER PathIter;
1817 const D3DKMDT_VIDPN_PRESENT_PATH * pPath;
1818 VBOXCMDVBVA_SCREENMAP_DECL(uint32_t, aVisitedTargetMap);
1819 VBOXCMDVBVA_SCREENMAP_DECL(uint32_t, aAdjustedModeMap);
1820 CR_SORTARRAY aModes[VBOX_VIDEO_MAX_SCREENS];
1821
1822 memset(aVisitedTargetMap, 0, sizeof (aVisitedTargetMap));
1823 memset(aAdjustedModeMap, 0, sizeof (aAdjustedModeMap));
1824 memset(aModes, 0, sizeof (aModes));
1825
1826 /* collect info first */
1827 VBoxVidPnPathIterInit(&PathIter, hVidPnTopology, pVidPnTopologyInterface);
1828 while ((pPath = VBoxVidPnPathIterNext(&PathIter)) != NULL)
1829 {
1830 D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId = pPath->VidPnSourceId;
1831 D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId = pPath->VidPnTargetId;
1832 /* actually vidpn topology should contain only one target info, right? */
1833 Assert(!ASMBitTest(aVisitedTargetMap, VidPnTargetId));
1834 ASMBitSet(aVisitedTargetMap, VidPnTargetId);
1835
1836 D3DKMDT_ENUMCOFUNCMODALITY_PIVOT_TYPE enmCurPivot = vboxVidPnCofuncModalityCurrentPathPivot(enmPivot, pPivot, VidPnSourceId, VidPnTargetId);
1837
1838 Status = vboxVidPnCollectInfoForPathTarget(pDevExt,
1839 hVidPn,
1840 pVidPnInterface,
1841 enmCurPivot,
1842 aAdjustedModeMap,
1843 aModes,
1844 VidPnSourceId, VidPnTargetId);
1845 if (!NT_SUCCESS(Status))
1846 {
1847 WARN(("vboxVidPnCollectInfoForPathTarget failed Status(0x%x\n", Status));
1848 VBoxVidPnDumpCofuncModalityInfo("Modality Info: ", enmPivot, pPivot, "\n");
1849 break;
1850 }
1851
1852 Assert(CrSaCovers(VBoxWddmVModesGet(pDevExt, VidPnTargetId), &aModes[VidPnTargetId]));
1853
1854 Status = vboxVidPnCollectInfoForPathSource(pDevExt,
1855 hVidPn,
1856 pVidPnInterface,
1857 enmCurPivot,
1858 aAdjustedModeMap,
1859 aModes,
1860 VidPnSourceId, VidPnTargetId);
1861 if (!NT_SUCCESS(Status))
1862 {
1863 WARN(("vboxVidPnCollectInfoForPathSource failed Status(0x%x\n", Status));
1864 VBoxVidPnDumpCofuncModalityInfo("Modality Info: ", enmPivot, pPivot, "\n");
1865 break;
1866 }
1867
1868 Assert(CrSaCovers(VBoxWddmVModesGet(pDevExt, VidPnTargetId), &aModes[VidPnTargetId]));
1869 }
1870
1871 VBoxVidPnPathIterTerm(&PathIter);
1872
1873 if (!NT_SUCCESS(Status))
1874 goto done;
1875
1876 Status = VBoxVidPnPathIterStatus(&PathIter);
1877 if (!NT_SUCCESS(Status))
1878 {
1879 WARN(("PathIter failed Status()0x%x\n", Status));
1880 VBoxVidPnDumpCofuncModalityInfo("Modality Info: ", enmPivot, pPivot, "\n");
1881 goto done;
1882 }
1883
1884 /* now we have collected all the necessary info,
1885 * go ahead and apply it */
1886 memset(aVisitedTargetMap, 0, sizeof (aVisitedTargetMap));
1887 VBoxVidPnPathIterInit(&PathIter, hVidPnTopology, pVidPnTopologyInterface);
1888 while ((pPath = VBoxVidPnPathIterNext(&PathIter)) != NULL)
1889 {
1890 D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId = pPath->VidPnSourceId;
1891 D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId = pPath->VidPnTargetId;
1892 /* actually vidpn topology should contain only one target info, right? */
1893 Assert(!ASMBitTest(aVisitedTargetMap, VidPnTargetId));
1894 ASMBitSet(aVisitedTargetMap, VidPnTargetId);
1895
1896 D3DKMDT_ENUMCOFUNCMODALITY_PIVOT_TYPE enmCurPivot = vboxVidPnCofuncModalityCurrentPathPivot(enmPivot, pPivot, VidPnSourceId, VidPnTargetId);
1897
1898 bool bUpdatePath = false;
1899 D3DKMDT_VIDPN_PRESENT_PATH AdjustedPath = {0};
1900 AdjustedPath.VidPnSourceId = pPath->VidPnSourceId;
1901 AdjustedPath.VidPnTargetId = pPath->VidPnTargetId;
1902 AdjustedPath.ContentTransformation = pPath->ContentTransformation;
1903 AdjustedPath.CopyProtection = pPath->CopyProtection;
1904
1905 if (pPath->ContentTransformation.Scaling == D3DKMDT_VPPS_UNPINNED)
1906 {
1907 AdjustedPath.ContentTransformation.ScalingSupport.Identity = TRUE;
1908 bUpdatePath = true;
1909 }
1910
1911 if (pPath->ContentTransformation.Rotation == D3DKMDT_VPPR_UNPINNED)
1912 {
1913 AdjustedPath.ContentTransformation.RotationSupport.Identity = TRUE;
1914 bUpdatePath = true;
1915 }
1916
1917 if (bUpdatePath)
1918 {
1919 Status = pVidPnTopologyInterface->pfnUpdatePathSupportInfo(hVidPnTopology, &AdjustedPath);
1920 if (!NT_SUCCESS(Status))
1921 {
1922 WARN(("pfnUpdatePathSupportInfo failed Status()0x%x\n", Status));
1923 VBoxVidPnDumpCofuncModalityInfo("Modality Info: ", enmPivot, pPivot, "\n");
1924 goto done;
1925 }
1926 }
1927
1928 Assert(CrSaCovers(VBoxWddmVModesGet(pDevExt, VidPnTargetId), &aModes[VidPnTargetId]));
1929
1930 Status = vboxVidPnApplyInfoForPathTarget(pDevExt,
1931 hVidPn,
1932 pVidPnInterface,
1933 enmCurPivot,
1934 aAdjustedModeMap,
1935 aModes,
1936 VidPnSourceId, VidPnTargetId);
1937 if (!NT_SUCCESS(Status))
1938 {
1939 WARN(("vboxVidPnApplyInfoForPathTarget failed Status(0x%x\n", Status));
1940 VBoxVidPnDumpCofuncModalityInfo("Modality Info: ", enmPivot, pPivot, "\n");
1941 break;
1942 }
1943
1944 Status = vboxVidPnApplyInfoForPathSource(pDevExt,
1945 hVidPn,
1946 pVidPnInterface,
1947 enmCurPivot,
1948 aAdjustedModeMap,
1949 aModes,
1950 VidPnSourceId, VidPnTargetId);
1951 if (!NT_SUCCESS(Status))
1952 {
1953 WARN(("vboxVidPnApplyInfoForPathSource failed Status(0x%x\n", Status));
1954 VBoxVidPnDumpCofuncModalityInfo("Modality Info: ", enmPivot, pPivot, "\n");
1955 break;
1956 }
1957 }
1958
1959 VBoxVidPnPathIterTerm(&PathIter);
1960
1961 if (!NT_SUCCESS(Status))
1962 goto done;
1963
1964 Status = VBoxVidPnPathIterStatus(&PathIter);
1965 if (!NT_SUCCESS(Status))
1966 {
1967 WARN(("PathIter failed Status()0x%x\n", Status));
1968 VBoxVidPnDumpCofuncModalityInfo("Modality Info: ", enmPivot, pPivot, "\n");
1969 goto done;
1970 }
1971
1972done:
1973
1974 for (uint32_t i = 0; i < (uint32_t)VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
1975 {
1976 CrSaCleanup(&aModes[i]);
1977 }
1978
1979 return Status;
1980}
1981
1982NTSTATUS vboxVidPnEnumMonitorSourceModes(D3DKMDT_HMONITORSOURCEMODESET hMonitorSMS, CONST DXGK_MONITORSOURCEMODESET_INTERFACE *pMonitorSMSIf,
1983 PFNVBOXVIDPNENUMMONITORSOURCEMODES pfnCallback, PVOID pContext)
1984{
1985 CONST D3DKMDT_MONITOR_SOURCE_MODE *pMonitorSMI;
1986 NTSTATUS Status = pMonitorSMSIf->pfnAcquireFirstModeInfo(hMonitorSMS, &pMonitorSMI);
1987 Assert(Status == STATUS_SUCCESS || Status == STATUS_GRAPHICS_DATASET_IS_EMPTY);
1988 if (Status == STATUS_SUCCESS)
1989 {
1990 Assert(pMonitorSMI);
1991 while (1)
1992 {
1993 CONST D3DKMDT_MONITOR_SOURCE_MODE *pNextMonitorSMI;
1994 Status = pMonitorSMSIf->pfnAcquireNextModeInfo(hMonitorSMS, pMonitorSMI, &pNextMonitorSMI);
1995 if (!pfnCallback(hMonitorSMS, pMonitorSMSIf, pMonitorSMI, pContext))
1996 {
1997 Assert(Status == STATUS_SUCCESS || Status == STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET);
1998 if (Status == STATUS_SUCCESS)
1999 pMonitorSMSIf->pfnReleaseModeInfo(hMonitorSMS, pNextMonitorSMI);
2000 else if (Status == STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET)
2001 {
2002 Status = STATUS_SUCCESS;
2003 break;
2004 }
2005 else
2006 {
2007 LOGREL(("pfnAcquireNextModeInfo Failed Status(0x%x), ignored since callback returned false", Status));
2008 Status = STATUS_SUCCESS;
2009 }
2010 break;
2011 }
2012 else if (Status == STATUS_SUCCESS)
2013 pMonitorSMI = pNextMonitorSMI;
2014 else if (Status == STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET)
2015 {
2016 Status = STATUS_SUCCESS;
2017 break;
2018 }
2019 else
2020 {
2021 AssertBreakpoint();
2022 LOGREL(("pfnAcquireNextModeInfo Failed Status(0x%x)", Status));
2023 pNextMonitorSMI = NULL;
2024 break;
2025 }
2026 }
2027 }
2028 else if (Status == STATUS_GRAPHICS_DATASET_IS_EMPTY)
2029 Status = STATUS_SUCCESS;
2030 else
2031 LOGREL(("pfnAcquireFirstModeInfo failed Status(0x%x)", Status));
2032
2033 return Status;
2034}
2035
2036NTSTATUS vboxVidPnEnumSourceModes(D3DKMDT_HVIDPNSOURCEMODESET hNewVidPnSourceModeSet, const DXGK_VIDPNSOURCEMODESET_INTERFACE *pVidPnSourceModeSetInterface,
2037 PFNVBOXVIDPNENUMSOURCEMODES pfnCallback, PVOID pContext)
2038{
2039 const D3DKMDT_VIDPN_SOURCE_MODE *pNewVidPnSourceModeInfo;
2040 NTSTATUS Status = pVidPnSourceModeSetInterface->pfnAcquireFirstModeInfo(hNewVidPnSourceModeSet, &pNewVidPnSourceModeInfo);
2041 if (Status == STATUS_SUCCESS)
2042 {
2043 Assert(pNewVidPnSourceModeInfo);
2044 while (1)
2045 {
2046 const D3DKMDT_VIDPN_SOURCE_MODE *pNextVidPnSourceModeInfo;
2047 Status = pVidPnSourceModeSetInterface->pfnAcquireNextModeInfo(hNewVidPnSourceModeSet, pNewVidPnSourceModeInfo, &pNextVidPnSourceModeInfo);
2048 if (!pfnCallback(hNewVidPnSourceModeSet, pVidPnSourceModeSetInterface,
2049 pNewVidPnSourceModeInfo, pContext))
2050 {
2051 AssertNtStatusSuccess(Status);
2052 if (Status == STATUS_SUCCESS)
2053 pVidPnSourceModeSetInterface->pfnReleaseModeInfo(hNewVidPnSourceModeSet, pNextVidPnSourceModeInfo);
2054 else if (Status == STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET)
2055 {
2056 Status = STATUS_SUCCESS;
2057 break;
2058 }
2059 else
2060 {
2061 LOGREL(("pfnAcquireNextModeInfo Failed Status(0x%x), ignored since callback returned false", Status));
2062 Status = STATUS_SUCCESS;
2063 }
2064
2065 break;
2066 }
2067 else if (Status == STATUS_SUCCESS)
2068 pNewVidPnSourceModeInfo = pNextVidPnSourceModeInfo;
2069 else if (Status == STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET)
2070 {
2071 Status = STATUS_SUCCESS;
2072 break;
2073 }
2074 else
2075 {
2076 AssertBreakpoint();
2077 LOGREL(("pfnAcquireNextModeInfo Failed Status(0x%x)", Status));
2078 pNewVidPnSourceModeInfo = NULL;
2079 break;
2080 }
2081 }
2082 }
2083 else if (Status == STATUS_GRAPHICS_DATASET_IS_EMPTY)
2084 Status = STATUS_SUCCESS;
2085 else
2086 LOGREL(("pfnAcquireFirstModeInfo failed Status(0x%x)", Status));
2087
2088 return Status;
2089}
2090
2091NTSTATUS vboxVidPnEnumTargetModes(D3DKMDT_HVIDPNTARGETMODESET hNewVidPnTargetModeSet, const DXGK_VIDPNTARGETMODESET_INTERFACE *pVidPnTargetModeSetInterface,
2092 PFNVBOXVIDPNENUMTARGETMODES pfnCallback, PVOID pContext)
2093{
2094 const D3DKMDT_VIDPN_TARGET_MODE *pNewVidPnTargetModeInfo;
2095 NTSTATUS Status = pVidPnTargetModeSetInterface->pfnAcquireFirstModeInfo(hNewVidPnTargetModeSet, &pNewVidPnTargetModeInfo);
2096 if (Status == STATUS_SUCCESS)
2097 {
2098 Assert(pNewVidPnTargetModeInfo);
2099 while (1)
2100 {
2101 const D3DKMDT_VIDPN_TARGET_MODE *pNextVidPnTargetModeInfo;
2102 Status = pVidPnTargetModeSetInterface->pfnAcquireNextModeInfo(hNewVidPnTargetModeSet, pNewVidPnTargetModeInfo, &pNextVidPnTargetModeInfo);
2103 if (!pfnCallback(hNewVidPnTargetModeSet, pVidPnTargetModeSetInterface,
2104 pNewVidPnTargetModeInfo, pContext))
2105 {
2106 AssertNtStatusSuccess(Status);
2107 if (Status == STATUS_SUCCESS)
2108 pVidPnTargetModeSetInterface->pfnReleaseModeInfo(hNewVidPnTargetModeSet, pNextVidPnTargetModeInfo);
2109 else if (Status == STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET)
2110 {
2111 Status = STATUS_SUCCESS;
2112 break;
2113 }
2114 else
2115 {
2116 LOGREL(("pfnAcquireNextModeInfo Failed Status(0x%x), ignored since callback returned false", Status));
2117 Status = STATUS_SUCCESS;
2118 }
2119
2120 break;
2121 }
2122 else if (Status == STATUS_SUCCESS)
2123 pNewVidPnTargetModeInfo = pNextVidPnTargetModeInfo;
2124 else if (Status == STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET)
2125 {
2126 Status = STATUS_SUCCESS;
2127 break;
2128 }
2129 else
2130 {
2131 AssertBreakpoint();
2132 LOGREL(("pfnAcquireNextModeInfo Failed Status(0x%x)", Status));
2133 pNewVidPnTargetModeInfo = NULL;
2134 break;
2135 }
2136 }
2137 }
2138 else if (Status == STATUS_GRAPHICS_DATASET_IS_EMPTY)
2139 Status = STATUS_SUCCESS;
2140 else
2141 LOGREL(("pfnAcquireFirstModeInfo failed Status(0x%x)", Status));
2142
2143 return Status;
2144}
2145
2146NTSTATUS vboxVidPnEnumTargetsForSource(PVBOXMP_DEVEXT pDevExt, D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface,
2147 CONST D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId,
2148 PFNVBOXVIDPNENUMTARGETSFORSOURCE pfnCallback, PVOID pContext)
2149{
2150 SIZE_T cTgtPaths;
2151 NTSTATUS Status = pVidPnTopologyInterface->pfnGetNumPathsFromSource(hVidPnTopology, VidPnSourceId, &cTgtPaths);
2152 Assert(Status == STATUS_SUCCESS || Status == STATUS_GRAPHICS_SOURCE_NOT_IN_TOPOLOGY);
2153 if (Status == STATUS_SUCCESS)
2154 {
2155 for (SIZE_T i = 0; i < cTgtPaths; ++i)
2156 {
2157 D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId;
2158 Status = pVidPnTopologyInterface->pfnEnumPathTargetsFromSource(hVidPnTopology, VidPnSourceId, i, &VidPnTargetId);
2159 AssertNtStatusSuccess(Status);
2160 if (Status == STATUS_SUCCESS)
2161 {
2162 if (!pfnCallback(pDevExt, hVidPnTopology, pVidPnTopologyInterface, VidPnSourceId, VidPnTargetId, cTgtPaths, pContext))
2163 break;
2164 }
2165 else
2166 {
2167 LOGREL(("pfnEnumPathTargetsFromSource failed Status(0x%x)", Status));
2168 break;
2169 }
2170 }
2171 }
2172 else if (Status != STATUS_GRAPHICS_SOURCE_NOT_IN_TOPOLOGY)
2173 LOGREL(("pfnGetNumPathsFromSource failed Status(0x%x)", Status));
2174
2175 return Status;
2176}
2177
2178NTSTATUS vboxVidPnEnumPaths(D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface,
2179 PFNVBOXVIDPNENUMPATHS pfnCallback, PVOID pContext)
2180{
2181 const D3DKMDT_VIDPN_PRESENT_PATH *pNewVidPnPresentPathInfo = NULL;
2182 NTSTATUS Status = pVidPnTopologyInterface->pfnAcquireFirstPathInfo(hVidPnTopology, &pNewVidPnPresentPathInfo);
2183 if (Status == STATUS_SUCCESS)
2184 {
2185 while (1)
2186 {
2187 const D3DKMDT_VIDPN_PRESENT_PATH *pNextVidPnPresentPathInfo;
2188 Status = pVidPnTopologyInterface->pfnAcquireNextPathInfo(hVidPnTopology, pNewVidPnPresentPathInfo, &pNextVidPnPresentPathInfo);
2189
2190 if (!pfnCallback(hVidPnTopology, pVidPnTopologyInterface, pNewVidPnPresentPathInfo, pContext))
2191 {
2192 if (Status == STATUS_SUCCESS)
2193 pVidPnTopologyInterface->pfnReleasePathInfo(hVidPnTopology, pNextVidPnPresentPathInfo);
2194 else
2195 {
2196 if (Status != STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET)
2197 WARN(("pfnAcquireNextPathInfo Failed Status(0x%x), ignored since callback returned false", Status));
2198 Status = STATUS_SUCCESS;
2199 }
2200
2201 break;
2202 }
2203 else if (Status == STATUS_SUCCESS)
2204 pNewVidPnPresentPathInfo = pNextVidPnPresentPathInfo;
2205 else if (Status == STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET)
2206 {
2207 Status = STATUS_SUCCESS;
2208 break;
2209 }
2210 else
2211 {
2212 WARN(("pfnAcquireNextPathInfo Failed Status(0x%x)", Status));
2213 pNewVidPnPresentPathInfo = NULL;
2214 break;
2215 }
2216 }
2217 }
2218 else if (Status == STATUS_GRAPHICS_DATASET_IS_EMPTY)
2219 Status = STATUS_SUCCESS;
2220 else
2221 WARN(("pfnAcquireFirstModeInfo failed Status(0x%x)", Status));
2222
2223 return Status;
2224}
2225
2226NTSTATUS vboxVidPnSetupSourceInfo(PVBOXMP_DEVEXT pDevExt, CONST D3DKMDT_VIDPN_SOURCE_MODE* pVidPnSourceModeInfo,
2227 PVBOXWDDM_ALLOCATION pAllocation, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId,
2228 VBOXWDDM_SOURCE *paSources)
2229{
2230 RT_NOREF(pDevExt);
2231 PVBOXWDDM_SOURCE pSource = &paSources[VidPnSourceId];
2232 /* pVidPnSourceModeInfo could be null if STATUS_GRAPHICS_MODE_NOT_PINNED,
2233 * see VBoxVidPnCommitSourceModeForSrcId */
2234 uint8_t fChanges = 0;
2235 if (pVidPnSourceModeInfo)
2236 {
2237 if (pSource->AllocData.SurfDesc.width != pVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cx)
2238 {
2239 fChanges |= VBOXWDDM_HGSYNC_F_SYNCED_DIMENSIONS;
2240 pSource->AllocData.SurfDesc.width = pVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cx;
2241 }
2242 if (pSource->AllocData.SurfDesc.height != pVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cy)
2243 {
2244 fChanges |= VBOXWDDM_HGSYNC_F_SYNCED_DIMENSIONS;
2245 pSource->AllocData.SurfDesc.height = pVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cy;
2246 }
2247 if (pSource->AllocData.SurfDesc.format != pVidPnSourceModeInfo->Format.Graphics.PixelFormat)
2248 {
2249 fChanges |= VBOXWDDM_HGSYNC_F_SYNCED_DIMENSIONS;
2250 pSource->AllocData.SurfDesc.format = pVidPnSourceModeInfo->Format.Graphics.PixelFormat;
2251 }
2252 if (pSource->AllocData.SurfDesc.bpp != vboxWddmCalcBitsPerPixel(pVidPnSourceModeInfo->Format.Graphics.PixelFormat))
2253 {
2254 fChanges |= VBOXWDDM_HGSYNC_F_SYNCED_DIMENSIONS;
2255 pSource->AllocData.SurfDesc.bpp = vboxWddmCalcBitsPerPixel(pVidPnSourceModeInfo->Format.Graphics.PixelFormat);
2256 }
2257 if(pSource->AllocData.SurfDesc.pitch != pVidPnSourceModeInfo->Format.Graphics.Stride)
2258 {
2259 fChanges |= VBOXWDDM_HGSYNC_F_SYNCED_DIMENSIONS;
2260 pSource->AllocData.SurfDesc.pitch = pVidPnSourceModeInfo->Format.Graphics.Stride;
2261 }
2262 pSource->AllocData.SurfDesc.depth = 1;
2263 if (pSource->AllocData.SurfDesc.slicePitch != pVidPnSourceModeInfo->Format.Graphics.Stride)
2264 {
2265 fChanges |= VBOXWDDM_HGSYNC_F_SYNCED_DIMENSIONS;
2266 pSource->AllocData.SurfDesc.slicePitch = pVidPnSourceModeInfo->Format.Graphics.Stride;
2267 }
2268 if (pSource->AllocData.SurfDesc.cbSize != pVidPnSourceModeInfo->Format.Graphics.Stride * pVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cy)
2269 {
2270 fChanges |= VBOXWDDM_HGSYNC_F_SYNCED_DIMENSIONS;
2271 pSource->AllocData.SurfDesc.cbSize = pVidPnSourceModeInfo->Format.Graphics.Stride * pVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cy;
2272 }
2273
2274 if (g_VBoxDisplayOnly)
2275 {
2276 vboxWddmDmSetupDefaultVramLocation(pDevExt, VidPnSourceId, paSources);
2277 }
2278 }
2279 else
2280 {
2281 VBoxVidPnAllocDataInit(&pSource->AllocData, VidPnSourceId);
2282 Assert(!pAllocation);
2283 fChanges |= VBOXWDDM_HGSYNC_F_SYNCED_ALL;
2284 }
2285
2286 Assert(!g_VBoxDisplayOnly || !pAllocation);
2287 if (!g_VBoxDisplayOnly)
2288 {
2289 vboxWddmAssignPrimary(pSource, pAllocation, VidPnSourceId);
2290 }
2291
2292 Assert(pSource->AllocData.SurfDesc.VidPnSourceId == VidPnSourceId);
2293 pSource->u8SyncState &= ~fChanges;
2294 return STATUS_SUCCESS;
2295}
2296
2297NTSTATUS vboxVidPnCommitSourceMode(PVBOXMP_DEVEXT pDevExt, CONST D3DKMDT_VIDPN_SOURCE_MODE* pVidPnSourceModeInfo, PVBOXWDDM_ALLOCATION pAllocation,
2298 D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, VBOXWDDM_SOURCE *paSources)
2299{
2300 if (VidPnSourceId < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays)
2301 return vboxVidPnSetupSourceInfo(pDevExt, pVidPnSourceModeInfo, pAllocation, VidPnSourceId, paSources);
2302
2303 WARN(("invalid srcId (%d), cSources(%d)", VidPnSourceId, VBoxCommonFromDeviceExt(pDevExt)->cDisplays));
2304 return STATUS_INVALID_PARAMETER;
2305}
2306
2307typedef struct VBOXVIDPNCOMMITTARGETMODE
2308{
2309 NTSTATUS Status;
2310 D3DKMDT_HVIDPN hVidPn;
2311 const DXGK_VIDPN_INTERFACE* pVidPnInterface;
2312 VBOXWDDM_SOURCE *paSources;
2313 VBOXWDDM_TARGET *paTargets;
2314} VBOXVIDPNCOMMITTARGETMODE;
2315
2316DECLCALLBACK(BOOLEAN) vboxVidPnCommitTargetModeEnum(PVBOXMP_DEVEXT pDevExt, D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology,
2317 const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface,
2318 CONST D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId,
2319 D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId, SIZE_T cTgtPaths,
2320 PVOID pContext)
2321{
2322 RT_NOREF(hVidPnTopology, pVidPnTopologyInterface, cTgtPaths);
2323 VBOXVIDPNCOMMITTARGETMODE *pInfo = (VBOXVIDPNCOMMITTARGETMODE*)pContext;
2324 Assert(cTgtPaths <= (SIZE_T)VBoxCommonFromDeviceExt(pDevExt)->cDisplays);
2325 D3DKMDT_HVIDPNTARGETMODESET hVidPnTargetModeSet;
2326 CONST DXGK_VIDPNTARGETMODESET_INTERFACE* pVidPnTargetModeSetInterface;
2327 NTSTATUS Status = pInfo->pVidPnInterface->pfnAcquireTargetModeSet(pInfo->hVidPn, VidPnTargetId, &hVidPnTargetModeSet, &pVidPnTargetModeSetInterface);
2328 AssertNtStatusSuccess(Status);
2329 if (Status == STATUS_SUCCESS)
2330 {
2331 CONST D3DKMDT_VIDPN_TARGET_MODE* pPinnedVidPnTargetModeInfo;
2332 Status = pVidPnTargetModeSetInterface->pfnAcquirePinnedModeInfo(hVidPnTargetModeSet, &pPinnedVidPnTargetModeInfo);
2333 AssertNtStatusSuccess(Status);
2334 if (Status == STATUS_SUCCESS)
2335 {
2336 VBOXWDDM_SOURCE *pSource = &pInfo->paSources[VidPnSourceId];
2337 VBOXWDDM_TARGET *pTarget = &pInfo->paTargets[VidPnTargetId];
2338 pTarget->Size.cx = pPinnedVidPnTargetModeInfo->VideoSignalInfo.ActiveSize.cx;
2339 pTarget->Size.cy = pPinnedVidPnTargetModeInfo->VideoSignalInfo.TotalSize.cy;
2340
2341 VBoxVidPnStSourceTargetAdd(pInfo->paSources, VBoxCommonFromDeviceExt(pDevExt)->cDisplays, pSource, pTarget);
2342
2343 pTarget->u8SyncState &= ~VBOXWDDM_HGSYNC_F_SYNCED_DIMENSIONS;
2344
2345 pVidPnTargetModeSetInterface->pfnReleaseModeInfo(hVidPnTargetModeSet, pPinnedVidPnTargetModeInfo);
2346 }
2347 else
2348 WARN(("pfnAcquirePinnedModeInfo failed Status(0x%x)", Status));
2349
2350 pInfo->pVidPnInterface->pfnReleaseTargetModeSet(pInfo->hVidPn, hVidPnTargetModeSet);
2351 }
2352 else
2353 WARN(("pfnAcquireTargetModeSet failed Status(0x%x)", Status));
2354
2355 pInfo->Status = Status;
2356 return Status == STATUS_SUCCESS;
2357}
2358
2359NTSTATUS VBoxVidPnCommitSourceModeForSrcId(PVBOXMP_DEVEXT pDevExt, const D3DKMDT_HVIDPN hDesiredVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface,
2360 PVBOXWDDM_ALLOCATION pAllocation,
2361 D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, VBOXWDDM_SOURCE *paSources, VBOXWDDM_TARGET *paTargets, BOOLEAN bPathPowerTransition)
2362{
2363 D3DKMDT_HVIDPNSOURCEMODESET hCurVidPnSourceModeSet;
2364 const DXGK_VIDPNSOURCEMODESET_INTERFACE *pCurVidPnSourceModeSetInterface;
2365
2366 PVBOXWDDM_SOURCE pSource = &paSources[VidPnSourceId];
2367 NTSTATUS Status;
2368
2369 if (bPathPowerTransition)
2370 {
2371 RTRECTSIZE PinnedModeSize;
2372 bool bHasPinnedMode;
2373
2374 Status = vboxVidPnQueryPinnedSourceMode(hDesiredVidPn, pVidPnInterface, VidPnSourceId, &PinnedModeSize);
2375 bHasPinnedMode = Status == STATUS_SUCCESS && PinnedModeSize.cx > 0 && PinnedModeSize.cy > 0;
2376 pSource->bBlankedByPowerOff = !bHasPinnedMode;
2377
2378 LOG(("Path power transition: srcId %d goes blank %d", VidPnSourceId, pSource->bBlankedByPowerOff));
2379 }
2380
2381 VBOXWDDM_TARGET_ITER Iter;
2382 VBoxVidPnStTIterInit(pSource, paTargets, (uint32_t)VBoxCommonFromDeviceExt(pDevExt)->cDisplays, &Iter);
2383 for (PVBOXWDDM_TARGET pTarget = VBoxVidPnStTIterNext(&Iter);
2384 pTarget;
2385 pTarget = VBoxVidPnStTIterNext(&Iter))
2386 {
2387 Assert(pTarget->VidPnSourceId == pSource->AllocData.SurfDesc.VidPnSourceId);
2388 pTarget->Size.cx = 0;
2389 pTarget->Size.cy = 0;
2390 pTarget->fBlankedByPowerOff = RT_BOOL(pSource->bBlankedByPowerOff);
2391 pTarget->u8SyncState &= ~VBOXWDDM_HGSYNC_F_SYNCED_ALL;
2392 }
2393
2394 VBoxVidPnStSourceCleanup(paSources, VidPnSourceId, paTargets, (uint32_t)VBoxCommonFromDeviceExt(pDevExt)->cDisplays);
2395
2396 Status = pVidPnInterface->pfnAcquireSourceModeSet(hDesiredVidPn,
2397 VidPnSourceId,
2398 &hCurVidPnSourceModeSet,
2399 &pCurVidPnSourceModeSetInterface);
2400 AssertNtStatusSuccess(Status);
2401 if (Status == STATUS_SUCCESS)
2402 {
2403 CONST D3DKMDT_VIDPN_SOURCE_MODE* pPinnedVidPnSourceModeInfo;
2404 Status = pCurVidPnSourceModeSetInterface->pfnAcquirePinnedModeInfo(hCurVidPnSourceModeSet, &pPinnedVidPnSourceModeInfo);
2405 Assert(Status == STATUS_SUCCESS || Status == STATUS_GRAPHICS_MODE_NOT_PINNED);
2406 if (Status == STATUS_SUCCESS)
2407 {
2408 Assert(pPinnedVidPnSourceModeInfo);
2409 Status = vboxVidPnCommitSourceMode(pDevExt, pPinnedVidPnSourceModeInfo, pAllocation, VidPnSourceId, paSources);
2410 AssertNtStatusSuccess(Status);
2411 if (Status == STATUS_SUCCESS)
2412 {
2413 D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology;
2414 CONST DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface;
2415 Status = pVidPnInterface->pfnGetTopology(hDesiredVidPn, &hVidPnTopology, &pVidPnTopologyInterface);
2416 AssertNtStatusSuccess(Status);
2417 if (Status == STATUS_SUCCESS)
2418 {
2419 VBOXVIDPNCOMMITTARGETMODE TgtModeInfo = {0};
2420 TgtModeInfo.Status = STATUS_SUCCESS; /* <- to ensure we're succeeded if no targets are set */
2421 TgtModeInfo.hVidPn = hDesiredVidPn;
2422 TgtModeInfo.pVidPnInterface = pVidPnInterface;
2423 TgtModeInfo.paSources = paSources;
2424 TgtModeInfo.paTargets = paTargets;
2425 Status = vboxVidPnEnumTargetsForSource(pDevExt, hVidPnTopology, pVidPnTopologyInterface,
2426 VidPnSourceId,
2427 vboxVidPnCommitTargetModeEnum, &TgtModeInfo);
2428 Assert(Status == STATUS_SUCCESS || Status == STATUS_GRAPHICS_SOURCE_NOT_IN_TOPOLOGY);
2429 if (Status == STATUS_SUCCESS)
2430 {
2431 Status = TgtModeInfo.Status;
2432 AssertNtStatusSuccess(Status);
2433 }
2434 else if (Status == STATUS_GRAPHICS_SOURCE_NOT_IN_TOPOLOGY)
2435 {
2436 Status = STATUS_SUCCESS;
2437 }
2438 else
2439 WARN(("vboxVidPnEnumTargetsForSource failed Status(0x%x)", Status));
2440 }
2441 else
2442 WARN(("pfnGetTopology failed Status(0x%x)", Status));
2443 }
2444 else
2445 WARN(("vboxVidPnCommitSourceMode failed Status(0x%x)", Status));
2446 /* release */
2447 pCurVidPnSourceModeSetInterface->pfnReleaseModeInfo(hCurVidPnSourceModeSet, pPinnedVidPnSourceModeInfo);
2448 }
2449 else if (Status == STATUS_GRAPHICS_MODE_NOT_PINNED)
2450 {
2451 Status = vboxVidPnCommitSourceMode(pDevExt, NULL, pAllocation, VidPnSourceId, paSources);
2452 AssertNtStatusSuccess(Status);
2453 }
2454 else
2455 WARN(("pfnAcquirePinnedModeInfo failed Status(0x%x)", Status));
2456
2457 pVidPnInterface->pfnReleaseSourceModeSet(hDesiredVidPn, hCurVidPnSourceModeSet);
2458 }
2459 else
2460 {
2461 WARN(("pfnAcquireSourceModeSet failed Status(0x%x)", Status));
2462 }
2463
2464 return Status;
2465}
2466
2467NTSTATUS VBoxVidPnCommitAll(PVBOXMP_DEVEXT pDevExt, const D3DKMDT_HVIDPN hDesiredVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface,
2468 PVBOXWDDM_ALLOCATION pAllocation,
2469 VBOXWDDM_SOURCE *paSources, VBOXWDDM_TARGET *paTargets)
2470{
2471 D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology;
2472 const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface;
2473 NTSTATUS Status = pVidPnInterface->pfnGetTopology(hDesiredVidPn, &hVidPnTopology, &pVidPnTopologyInterface);
2474 if (!NT_SUCCESS(Status))
2475 {
2476 WARN(("pfnGetTopology failed Status 0x%x", Status));
2477 return Status;
2478 }
2479
2480 for (int i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
2481 {
2482 PVBOXWDDM_TARGET pTarget = &paTargets[i];
2483 pTarget->Size.cx = 0;
2484 pTarget->Size.cy = 0;
2485 pTarget->u8SyncState &= ~VBOXWDDM_HGSYNC_F_SYNCED_ALL;
2486
2487 if (pTarget->VidPnSourceId == D3DDDI_ID_UNINITIALIZED)
2488 continue;
2489
2490 Assert(pTarget->VidPnSourceId < (D3DDDI_VIDEO_PRESENT_SOURCE_ID)VBoxCommonFromDeviceExt(pDevExt)->cDisplays);
2491
2492 VBOXWDDM_SOURCE *pSource = &paSources[pTarget->VidPnSourceId];
2493 VBoxVidPnAllocDataInit(&pSource->AllocData, pTarget->VidPnSourceId);
2494 pSource->u8SyncState &= ~VBOXWDDM_HGSYNC_F_SYNCED_ALL;
2495 }
2496
2497 VBoxVidPnStCleanup(paSources, paTargets, VBoxCommonFromDeviceExt(pDevExt)->cDisplays);
2498
2499 VBOXVIDPN_PATH_ITER PathIter;
2500 const D3DKMDT_VIDPN_PRESENT_PATH *pPath;
2501 VBoxVidPnPathIterInit(&PathIter, hVidPnTopology, pVidPnTopologyInterface);
2502 while ((pPath = VBoxVidPnPathIterNext(&PathIter)) != NULL)
2503 {
2504 Status = VBoxVidPnCommitSourceModeForSrcId(pDevExt, hDesiredVidPn, pVidPnInterface, pAllocation,
2505 pPath->VidPnSourceId, paSources, paTargets, FALSE);
2506 if (Status != STATUS_SUCCESS)
2507 {
2508 WARN(("VBoxVidPnCommitSourceModeForSrcId failed Status(0x%x)", Status));
2509 break;
2510 }
2511 }
2512
2513 VBoxVidPnPathIterTerm(&PathIter);
2514
2515 if (!NT_SUCCESS(Status))
2516 {
2517 WARN((""));
2518 return Status;
2519 }
2520
2521 Status = VBoxVidPnPathIterStatus(&PathIter);
2522 if (!NT_SUCCESS(Status))
2523 {
2524 WARN(("VBoxVidPnPathIterStatus failed Status 0x%x", Status));
2525 return Status;
2526 }
2527
2528 return STATUS_SUCCESS;
2529}
2530
2531#define VBOXVIDPNDUMP_STRCASE(_t) \
2532 case _t: return #_t;
2533#define VBOXVIDPNDUMP_STRCASE_UNKNOWN() \
2534 default: Assert(0); return "Unknown";
2535
2536#define VBOXVIDPNDUMP_STRFLAGS(_v, _t) \
2537 if ((_v)._t return #_t;
2538
2539const char* vboxVidPnDumpStrImportance(D3DKMDT_VIDPN_PRESENT_PATH_IMPORTANCE ImportanceOrdinal)
2540{
2541 switch (ImportanceOrdinal)
2542 {
2543 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPI_UNINITIALIZED);
2544 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPI_PRIMARY);
2545 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPI_SECONDARY);
2546 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPI_TERTIARY);
2547 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPI_QUATERNARY);
2548 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPI_QUINARY);
2549 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPI_SENARY);
2550 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPI_SEPTENARY);
2551 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPI_OCTONARY);
2552 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPI_NONARY);
2553 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPI_DENARY);
2554 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2555 }
2556}
2557
2558const char* vboxVidPnDumpStrScaling(D3DKMDT_VIDPN_PRESENT_PATH_SCALING Scaling)
2559{
2560 switch (Scaling)
2561 {
2562 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPS_UNINITIALIZED);
2563 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPS_IDENTITY);
2564 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPS_CENTERED);
2565 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPS_STRETCHED);
2566 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPS_UNPINNED);
2567 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPS_NOTSPECIFIED);
2568 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2569 }
2570}
2571
2572const char* vboxVidPnDumpStrRotation(D3DKMDT_VIDPN_PRESENT_PATH_ROTATION Rotation)
2573{
2574 switch (Rotation)
2575 {
2576 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPR_UNINITIALIZED);
2577 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPR_IDENTITY);
2578 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPR_ROTATE90);
2579 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPR_ROTATE180);
2580 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPR_ROTATE270);
2581 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPR_UNPINNED);
2582 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPR_NOTSPECIFIED);
2583 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2584 }
2585}
2586
2587const char* vboxVidPnDumpStrColorBasis(const D3DKMDT_COLOR_BASIS ColorBasis)
2588{
2589 switch (ColorBasis)
2590 {
2591 VBOXVIDPNDUMP_STRCASE(D3DKMDT_CB_UNINITIALIZED);
2592 VBOXVIDPNDUMP_STRCASE(D3DKMDT_CB_INTENSITY);
2593 VBOXVIDPNDUMP_STRCASE(D3DKMDT_CB_SRGB);
2594 VBOXVIDPNDUMP_STRCASE(D3DKMDT_CB_SCRGB);
2595 VBOXVIDPNDUMP_STRCASE(D3DKMDT_CB_YCBCR);
2596 VBOXVIDPNDUMP_STRCASE(D3DKMDT_CB_YPBPR);
2597 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2598 }
2599}
2600
2601const char * vboxVidPnDumpStrMonCapabilitiesOrigin(D3DKMDT_MONITOR_CAPABILITIES_ORIGIN enmOrigin)
2602{
2603 switch (enmOrigin)
2604 {
2605 VBOXVIDPNDUMP_STRCASE(D3DKMDT_MCO_UNINITIALIZED);
2606 VBOXVIDPNDUMP_STRCASE(D3DKMDT_MCO_DEFAULTMONITORPROFILE);
2607 VBOXVIDPNDUMP_STRCASE(D3DKMDT_MCO_MONITORDESCRIPTOR);
2608 VBOXVIDPNDUMP_STRCASE(D3DKMDT_MCO_MONITORDESCRIPTOR_REGISTRYOVERRIDE);
2609 VBOXVIDPNDUMP_STRCASE(D3DKMDT_MCO_SPECIFICCAP_REGISTRYOVERRIDE);
2610 VBOXVIDPNDUMP_STRCASE(D3DKMDT_MCO_DRIVER);
2611 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2612 }
2613}
2614
2615const char* vboxVidPnDumpStrPvam(D3DKMDT_PIXEL_VALUE_ACCESS_MODE PixelValueAccessMode)
2616{
2617 switch (PixelValueAccessMode)
2618 {
2619 VBOXVIDPNDUMP_STRCASE(D3DKMDT_PVAM_UNINITIALIZED);
2620 VBOXVIDPNDUMP_STRCASE(D3DKMDT_PVAM_DIRECT);
2621 VBOXVIDPNDUMP_STRCASE(D3DKMDT_PVAM_PRESETPALETTE);
2622 VBOXVIDPNDUMP_STRCASE(D3DKMDT_PVAM_SETTABLEPALETTE);
2623 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2624 }
2625}
2626
2627
2628
2629const char* vboxVidPnDumpStrContent(D3DKMDT_VIDPN_PRESENT_PATH_CONTENT Content)
2630{
2631 switch (Content)
2632 {
2633 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPC_UNINITIALIZED);
2634 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPC_GRAPHICS);
2635 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPC_VIDEO);
2636 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPC_NOTSPECIFIED);
2637 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2638 }
2639}
2640
2641const char* vboxVidPnDumpStrCopyProtectionType(D3DKMDT_VIDPN_PRESENT_PATH_COPYPROTECTION_TYPE CopyProtectionType)
2642{
2643 switch (CopyProtectionType)
2644 {
2645 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPMT_UNINITIALIZED);
2646 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPMT_NOPROTECTION);
2647 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPMT_MACROVISION_APSTRIGGER);
2648 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPMT_MACROVISION_FULLSUPPORT);
2649 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2650 }
2651}
2652
2653const char* vboxVidPnDumpStrGammaRampType(D3DDDI_GAMMARAMP_TYPE Type)
2654{
2655 switch (Type)
2656 {
2657 VBOXVIDPNDUMP_STRCASE(D3DDDI_GAMMARAMP_UNINITIALIZED);
2658 VBOXVIDPNDUMP_STRCASE(D3DDDI_GAMMARAMP_DEFAULT);
2659 VBOXVIDPNDUMP_STRCASE(D3DDDI_GAMMARAMP_RGB256x3x16);
2660 VBOXVIDPNDUMP_STRCASE(D3DDDI_GAMMARAMP_DXGI_1);
2661 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2662 }
2663}
2664
2665const char* vboxVidPnDumpStrSourceModeType(D3DKMDT_VIDPN_SOURCE_MODE_TYPE Type)
2666{
2667 switch (Type)
2668 {
2669 VBOXVIDPNDUMP_STRCASE(D3DKMDT_RMT_UNINITIALIZED);
2670 VBOXVIDPNDUMP_STRCASE(D3DKMDT_RMT_GRAPHICS);
2671 VBOXVIDPNDUMP_STRCASE(D3DKMDT_RMT_TEXT);
2672 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2673 }
2674}
2675
2676const char* vboxVidPnDumpStrScanLineOrdering(D3DDDI_VIDEO_SIGNAL_SCANLINE_ORDERING ScanLineOrdering)
2677{
2678 switch (ScanLineOrdering)
2679 {
2680 VBOXVIDPNDUMP_STRCASE(D3DDDI_VSSLO_UNINITIALIZED);
2681 VBOXVIDPNDUMP_STRCASE(D3DDDI_VSSLO_PROGRESSIVE);
2682 VBOXVIDPNDUMP_STRCASE(D3DDDI_VSSLO_INTERLACED_UPPERFIELDFIRST);
2683 VBOXVIDPNDUMP_STRCASE(D3DDDI_VSSLO_INTERLACED_LOWERFIELDFIRST);
2684 VBOXVIDPNDUMP_STRCASE(D3DDDI_VSSLO_OTHER);
2685 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2686 }
2687}
2688
2689const char* vboxVidPnDumpStrCFMPivotType(D3DKMDT_ENUMCOFUNCMODALITY_PIVOT_TYPE EnumPivotType)
2690{
2691 switch (EnumPivotType)
2692 {
2693 VBOXVIDPNDUMP_STRCASE(D3DKMDT_EPT_UNINITIALIZED);
2694 VBOXVIDPNDUMP_STRCASE(D3DKMDT_EPT_VIDPNSOURCE);
2695 VBOXVIDPNDUMP_STRCASE(D3DKMDT_EPT_VIDPNTARGET);
2696 VBOXVIDPNDUMP_STRCASE(D3DKMDT_EPT_SCALING);
2697 VBOXVIDPNDUMP_STRCASE(D3DKMDT_EPT_ROTATION);
2698 VBOXVIDPNDUMP_STRCASE(D3DKMDT_EPT_NOPIVOT);
2699 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2700 }
2701}
2702
2703const char* vboxVidPnDumpStrModePreference(D3DKMDT_MODE_PREFERENCE Preference)
2704{
2705 switch (Preference)
2706 {
2707 VBOXVIDPNDUMP_STRCASE(D3DKMDT_MP_UNINITIALIZED);
2708 VBOXVIDPNDUMP_STRCASE(D3DKMDT_MP_PREFERRED);
2709 VBOXVIDPNDUMP_STRCASE(D3DKMDT_MP_NOTPREFERRED);
2710 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2711 }
2712}
2713
2714const char* vboxVidPnDumpStrSignalStandard(D3DKMDT_VIDEO_SIGNAL_STANDARD VideoStandard)
2715{
2716 switch (VideoStandard)
2717 {
2718 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_UNINITIALIZED);
2719 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_VESA_DMT);
2720 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_VESA_GTF);
2721 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_VESA_CVT);
2722 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_IBM);
2723 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_APPLE);
2724 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_NTSC_M);
2725 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_NTSC_J);
2726 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_NTSC_443);
2727 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_PAL_B);
2728 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_PAL_B1);
2729 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_PAL_G);
2730 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_PAL_H);
2731 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_PAL_I);
2732 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_PAL_D);
2733 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_PAL_N);
2734 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_PAL_NC);
2735 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_SECAM_B);
2736 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_SECAM_D);
2737 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_SECAM_G);
2738 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_SECAM_H);
2739 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_SECAM_K);
2740 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_SECAM_K1);
2741 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_SECAM_L);
2742 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_SECAM_L1);
2743 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_EIA_861);
2744 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_EIA_861A);
2745 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_EIA_861B);
2746 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_PAL_K);
2747 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_PAL_K1);
2748 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_PAL_L);
2749 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_PAL_M);
2750 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_OTHER);
2751 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2752 }
2753}
2754
2755const char* vboxVidPnDumpStrPixFormat(D3DDDIFORMAT PixelFormat)
2756{
2757 switch (PixelFormat)
2758 {
2759 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_UNKNOWN);
2760 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_R8G8B8);
2761 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A8R8G8B8);
2762 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_X8R8G8B8);
2763 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_R5G6B5);
2764 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_X1R5G5B5);
2765 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A1R5G5B5);
2766 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A4R4G4B4);
2767 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_R3G3B2);
2768 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A8);
2769 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A8R3G3B2);
2770 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_X4R4G4B4);
2771 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A2B10G10R10);
2772 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A8B8G8R8);
2773 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_X8B8G8R8);
2774 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_G16R16);
2775 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A2R10G10B10);
2776 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A16B16G16R16);
2777 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A8P8);
2778 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_R32F);
2779 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_G32R32F);
2780 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A32B32G32R32F);
2781 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_CxV8U8);
2782 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A1);
2783 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_BINARYBUFFER);
2784 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_VERTEXDATA);
2785 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_INDEX16);
2786 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_INDEX32);
2787 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_Q16W16V16U16);
2788 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_MULTI2_ARGB8);
2789 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_R16F);
2790 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_G16R16F);
2791 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A16B16G16R16F);
2792 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_D32F_LOCKABLE);
2793 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_D24FS8);
2794 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_D32_LOCKABLE);
2795 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_S8_LOCKABLE);
2796 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_S1D15);
2797 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_S8D24);
2798 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_X8D24);
2799 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_X4S4D24);
2800 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_L16);
2801 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_UYVY);
2802 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_R8G8_B8G8);
2803 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_YUY2);
2804 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_G8R8_G8B8);
2805 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_DXT1);
2806 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_DXT2);
2807 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_DXT3);
2808 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_DXT4);
2809 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_DXT5);
2810 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_D16_LOCKABLE);
2811 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_D32);
2812 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_D15S1);
2813 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_D24S8);
2814 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_D24X8);
2815 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_D24X4S4);
2816 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_D16);
2817 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_P8);
2818 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_L8);
2819 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A8L8);
2820 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A4L4);
2821 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_V8U8);
2822 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_L6V5U5);
2823 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_X8L8V8U8);
2824 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_Q8W8V8U8);
2825 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_V16U16);
2826 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_W11V11U10);
2827 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A2W10V10U10);
2828 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2829 }
2830}
2831
2832void vboxVidPnDumpCopyProtectoin(const char *pPrefix, const D3DKMDT_VIDPN_PRESENT_PATH_COPYPROTECTION *pCopyProtection, const char *pSuffix)
2833{
2834 LOGREL_EXACT(("%sType(%s), TODO%s", pPrefix,
2835 vboxVidPnDumpStrCopyProtectionType(pCopyProtection->CopyProtectionType), pSuffix));
2836}
2837
2838
2839void vboxVidPnDumpPathTransformation(const D3DKMDT_VIDPN_PRESENT_PATH_TRANSFORMATION *pContentTransformation)
2840{
2841 LOGREL_EXACT((" --Transformation: Scaling(%s), ScalingSupport(%d), Rotation(%s), RotationSupport(%d)--",
2842 vboxVidPnDumpStrScaling(pContentTransformation->Scaling), pContentTransformation->ScalingSupport,
2843 vboxVidPnDumpStrRotation(pContentTransformation->Rotation), pContentTransformation->RotationSupport));
2844}
2845
2846void vboxVidPnDumpRegion(const char *pPrefix, const D3DKMDT_2DREGION *pRegion, const char *pSuffix)
2847{
2848 LOGREL_EXACT(("%s%dX%d%s", pPrefix, pRegion->cx, pRegion->cy, pSuffix));
2849}
2850
2851void vboxVidPnDumpRational(const char *pPrefix, const D3DDDI_RATIONAL *pRational, const char *pSuffix)
2852{
2853 LOGREL_EXACT(("%s%d/%d=%d%s", pPrefix, pRational->Numerator, pRational->Denominator, pRational->Numerator/pRational->Denominator, pSuffix));
2854}
2855
2856void vboxVidPnDumpRanges(const char *pPrefix, const D3DKMDT_COLOR_COEFF_DYNAMIC_RANGES *pDynamicRanges, const char *pSuffix)
2857{
2858 LOGREL_EXACT(("%sFirstChannel(%d), SecondChannel(%d), ThirdChannel(%d), FourthChannel(%d)%s", pPrefix,
2859 pDynamicRanges->FirstChannel,
2860 pDynamicRanges->SecondChannel,
2861 pDynamicRanges->ThirdChannel,
2862 pDynamicRanges->FourthChannel,
2863 pSuffix));
2864}
2865
2866void vboxVidPnDumpGammaRamp(const char *pPrefix, const D3DKMDT_GAMMA_RAMP *pGammaRamp, const char *pSuffix)
2867{
2868 LOGREL_EXACT(("%sType(%s), DataSize(%d), TODO: dump the rest%s", pPrefix,
2869 vboxVidPnDumpStrGammaRampType(pGammaRamp->Type), pGammaRamp->DataSize,
2870 pSuffix));
2871}
2872
2873void VBoxVidPnDumpSourceMode(const char *pPrefix, const D3DKMDT_VIDPN_SOURCE_MODE* pVidPnSourceModeInfo, const char *pSuffix)
2874{
2875 LOGREL_EXACT(("%sType(%s), ", pPrefix, vboxVidPnDumpStrSourceModeType(pVidPnSourceModeInfo->Type)));
2876 vboxVidPnDumpRegion("surf(", &pVidPnSourceModeInfo->Format.Graphics.PrimSurfSize, "), ");
2877 vboxVidPnDumpRegion("vis(", &pVidPnSourceModeInfo->Format.Graphics.VisibleRegionSize, "), ");
2878 LOGREL_EXACT(("stride(%d), ", pVidPnSourceModeInfo->Format.Graphics.Stride));
2879 LOGREL_EXACT(("format(%s), ", vboxVidPnDumpStrPixFormat(pVidPnSourceModeInfo->Format.Graphics.PixelFormat)));
2880 LOGREL_EXACT(("clrBasis(%s), ", vboxVidPnDumpStrColorBasis(pVidPnSourceModeInfo->Format.Graphics.ColorBasis)));
2881 LOGREL_EXACT(("pvam(%s)%s", vboxVidPnDumpStrPvam(pVidPnSourceModeInfo->Format.Graphics.PixelValueAccessMode), pSuffix));
2882}
2883
2884void vboxVidPnDumpSignalInfo(const char *pPrefix, const D3DKMDT_VIDEO_SIGNAL_INFO *pVideoSignalInfo, const char *pSuffix)
2885{
2886 LOGREL_EXACT(("%sVStd(%s), ", pPrefix, vboxVidPnDumpStrSignalStandard(pVideoSignalInfo->VideoStandard)));
2887 vboxVidPnDumpRegion("totSize(", &pVideoSignalInfo->TotalSize, "), ");
2888 vboxVidPnDumpRegion("activeSize(", &pVideoSignalInfo->ActiveSize, "), ");
2889 vboxVidPnDumpRational("VSynch(", &pVideoSignalInfo->VSyncFreq, "), ");
2890 LOGREL_EXACT(("PixelRate(%d), ScanLineOrdering(%s)%s", pVideoSignalInfo->PixelRate, vboxVidPnDumpStrScanLineOrdering(pVideoSignalInfo->ScanLineOrdering), pSuffix));
2891}
2892
2893void VBoxVidPnDumpTargetMode(const char *pPrefix, const D3DKMDT_VIDPN_TARGET_MODE* CONST pVidPnTargetModeInfo, const char *pSuffix)
2894{
2895 LOGREL_EXACT(("%s", pPrefix));
2896 LOGREL_EXACT(("ID: %d, ", pVidPnTargetModeInfo->Id));
2897 vboxVidPnDumpSignalInfo("VSI: ", &pVidPnTargetModeInfo->VideoSignalInfo, ", ");
2898 LOGREL_EXACT(("Preference(%s)%s", vboxVidPnDumpStrModePreference(pVidPnTargetModeInfo->Preference), pSuffix));
2899}
2900
2901void VBoxVidPnDumpMonitorMode(const char *pPrefix, const D3DKMDT_MONITOR_SOURCE_MODE *pVidPnModeInfo, const char *pSuffix)
2902{
2903 LOGREL_EXACT(("%s", pPrefix));
2904
2905 LOGREL_EXACT(("ID: %d, ", pVidPnModeInfo->Id));
2906
2907 vboxVidPnDumpSignalInfo("VSI: ", &pVidPnModeInfo->VideoSignalInfo, ", ");
2908
2909 LOGREL_EXACT(("ColorBasis: %s, ", vboxVidPnDumpStrColorBasis(pVidPnModeInfo->ColorBasis)));
2910
2911 vboxVidPnDumpRanges("Ranges: ", &pVidPnModeInfo->ColorCoeffDynamicRanges, ", ");
2912
2913 LOGREL_EXACT(("MonCapOr: %s, ", vboxVidPnDumpStrMonCapabilitiesOrigin(pVidPnModeInfo->Origin)));
2914
2915 LOGREL_EXACT(("Preference(%s)%s", vboxVidPnDumpStrModePreference(pVidPnModeInfo->Preference), pSuffix));
2916}
2917
2918NTSTATUS VBoxVidPnDumpMonitorModeSet(const char *pPrefix, PVBOXMP_DEVEXT pDevExt, uint32_t u32Target, const char *pSuffix)
2919{
2920 LOGREL_EXACT(("%s Tgt[%d]\n", pPrefix, u32Target));
2921
2922 NTSTATUS Status;
2923 CONST DXGK_MONITOR_INTERFACE *pMonitorInterface;
2924 Status = pDevExt->u.primary.DxgkInterface.DxgkCbQueryMonitorInterface(pDevExt->u.primary.DxgkInterface.DeviceHandle, DXGK_MONITOR_INTERFACE_VERSION_V1, &pMonitorInterface);
2925 if (!NT_SUCCESS(Status))
2926 {
2927 WARN(("DxgkCbQueryMonitorInterface failed, Status()0x%x", Status));
2928 return Status;
2929 }
2930
2931 D3DKMDT_HMONITORSOURCEMODESET hVidPnModeSet;
2932 CONST DXGK_MONITORSOURCEMODESET_INTERFACE *pVidPnModeSetInterface;
2933
2934 Status = pMonitorInterface->pfnAcquireMonitorSourceModeSet(pDevExt->u.primary.DxgkInterface.DeviceHandle,
2935 u32Target,
2936 &hVidPnModeSet,
2937 &pVidPnModeSetInterface);
2938 if (!NT_SUCCESS(Status))
2939 {
2940 WARN(("DxgkCbQueryMonitorInterface failed, Status()0x%x", Status));
2941 return Status;
2942 }
2943
2944 VBOXVIDPN_MONITORMODE_ITER Iter;
2945 const D3DKMDT_MONITOR_SOURCE_MODE *pVidPnModeInfo;
2946
2947 VBoxVidPnMonitorModeIterInit(&Iter, hVidPnModeSet, pVidPnModeSetInterface);
2948
2949 while ((pVidPnModeInfo = VBoxVidPnMonitorModeIterNext(&Iter)) != NULL)
2950 {
2951 VBoxVidPnDumpMonitorMode("MonitorMode: ",pVidPnModeInfo, "\n");
2952 }
2953
2954 VBoxVidPnMonitorModeIterTerm(&Iter);
2955
2956 Status = VBoxVidPnMonitorModeIterStatus(&Iter);
2957 if (!NT_SUCCESS(Status))
2958 {
2959 WARN(("iter status failed %#x", Status));
2960 }
2961
2962 NTSTATUS rcNt2 = pMonitorInterface->pfnReleaseMonitorSourceModeSet(pDevExt->u.primary.DxgkInterface.DeviceHandle, hVidPnModeSet);
2963 if (!NT_SUCCESS(rcNt2))
2964 WARN(("pfnReleaseMonitorSourceModeSet failed rcNt2(0x%x)", rcNt2));
2965
2966 LOGREL_EXACT(("%s", pSuffix));
2967
2968 return Status;
2969}
2970
2971void vboxVidPnDumpPinnedSourceMode(const D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId)
2972{
2973 D3DKMDT_HVIDPNSOURCEMODESET hCurVidPnSourceModeSet;
2974 const DXGK_VIDPNSOURCEMODESET_INTERFACE *pCurVidPnSourceModeSetInterface;
2975
2976 NTSTATUS Status = pVidPnInterface->pfnAcquireSourceModeSet(hVidPn,
2977 VidPnSourceId,
2978 &hCurVidPnSourceModeSet,
2979 &pCurVidPnSourceModeSetInterface);
2980 AssertNtStatusSuccess(Status);
2981 if (Status == STATUS_SUCCESS)
2982 {
2983 CONST D3DKMDT_VIDPN_SOURCE_MODE* pPinnedVidPnSourceModeInfo;
2984
2985 Status = pCurVidPnSourceModeSetInterface->pfnAcquirePinnedModeInfo(hCurVidPnSourceModeSet, &pPinnedVidPnSourceModeInfo);
2986 Assert(Status == STATUS_SUCCESS || Status == STATUS_GRAPHICS_MODE_NOT_PINNED);
2987 if (Status == STATUS_SUCCESS)
2988 {
2989 VBoxVidPnDumpSourceMode("Source Pinned: ", pPinnedVidPnSourceModeInfo, "\n");
2990 pCurVidPnSourceModeSetInterface->pfnReleaseModeInfo(hCurVidPnSourceModeSet, pPinnedVidPnSourceModeInfo);
2991 }
2992 else if (Status == STATUS_GRAPHICS_MODE_NOT_PINNED)
2993 {
2994 LOGREL_EXACT(("Source NOT Pinned\n"));
2995 }
2996 else
2997 {
2998 LOGREL_EXACT(("ERROR getting piined Source Mode(0x%x)\n", Status));
2999 }
3000 pVidPnInterface->pfnReleaseSourceModeSet(hVidPn, hCurVidPnSourceModeSet);
3001 }
3002 else
3003 {
3004 LOGREL_EXACT(("ERROR getting SourceModeSet(0x%x)\n", Status));
3005 }
3006}
3007
3008
3009DECLCALLBACK(BOOLEAN) vboxVidPnDumpSourceModeSetEnum(D3DKMDT_HVIDPNSOURCEMODESET hNewVidPnSourceModeSet,
3010 const DXGK_VIDPNSOURCEMODESET_INTERFACE *pVidPnSourceModeSetInterface,
3011 const D3DKMDT_VIDPN_SOURCE_MODE *pNewVidPnSourceModeInfo, PVOID pContext)
3012{
3013
3014 RT_NOREF(hNewVidPnSourceModeSet, pVidPnSourceModeSetInterface, pNewVidPnSourceModeInfo, pContext);
3015 VBoxVidPnDumpSourceMode("SourceMode: ", pNewVidPnSourceModeInfo, "\n");
3016 return TRUE;
3017}
3018
3019void vboxVidPnDumpSourceModeSet(PVBOXMP_DEVEXT pDevExt, const D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface,
3020 D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId)
3021{
3022 RT_NOREF(pDevExt);
3023 LOGREL_EXACT(("\n >>>+++SourceMode Set for Source(%d)+++\n", VidPnSourceId));
3024 D3DKMDT_HVIDPNSOURCEMODESET hCurVidPnSourceModeSet;
3025 const DXGK_VIDPNSOURCEMODESET_INTERFACE *pCurVidPnSourceModeSetInterface;
3026
3027 NTSTATUS Status = pVidPnInterface->pfnAcquireSourceModeSet(hVidPn,
3028 VidPnSourceId,
3029 &hCurVidPnSourceModeSet,
3030 &pCurVidPnSourceModeSetInterface);
3031 AssertNtStatusSuccess(Status);
3032 if (Status == STATUS_SUCCESS)
3033 {
3034
3035 Status = vboxVidPnEnumSourceModes(hCurVidPnSourceModeSet, pCurVidPnSourceModeSetInterface,
3036 vboxVidPnDumpSourceModeSetEnum, NULL);
3037 AssertNtStatusSuccess(Status);
3038 if (Status != STATUS_SUCCESS)
3039 {
3040 LOGREL_EXACT(("ERROR enumerating Source Modes(0x%x)\n", Status));
3041 }
3042 pVidPnInterface->pfnReleaseSourceModeSet(hVidPn, hCurVidPnSourceModeSet);
3043 }
3044 else
3045 {
3046 LOGREL_EXACT(("ERROR getting SourceModeSet for Source(%d), Status(0x%x)\n", VidPnSourceId, Status));
3047 }
3048
3049 LOGREL_EXACT((" <<<+++End Of SourceMode Set for Source(%d)+++", VidPnSourceId));
3050}
3051
3052DECLCALLBACK(BOOLEAN) vboxVidPnDumpTargetModeSetEnum(D3DKMDT_HVIDPNTARGETMODESET hNewVidPnTargetModeSet,
3053 const DXGK_VIDPNTARGETMODESET_INTERFACE *pVidPnTargetModeSetInterface,
3054 const D3DKMDT_VIDPN_TARGET_MODE *pNewVidPnTargetModeInfo, PVOID pContext)
3055{
3056 RT_NOREF(hNewVidPnTargetModeSet, pVidPnTargetModeSetInterface, pNewVidPnTargetModeInfo, pContext);
3057 VBoxVidPnDumpTargetMode("TargetMode: ", pNewVidPnTargetModeInfo, "\n");
3058 return TRUE;
3059}
3060
3061void vboxVidPnDumpTargetModeSet(PVBOXMP_DEVEXT pDevExt, const D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface,
3062 D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
3063{
3064 RT_NOREF(pDevExt);
3065 LOGREL_EXACT(("\n >>>---TargetMode Set for Target(%d)---\n", VidPnTargetId));
3066 D3DKMDT_HVIDPNTARGETMODESET hCurVidPnTargetModeSet;
3067 const DXGK_VIDPNTARGETMODESET_INTERFACE *pCurVidPnTargetModeSetInterface;
3068
3069 NTSTATUS Status = pVidPnInterface->pfnAcquireTargetModeSet(hVidPn,
3070 VidPnTargetId,
3071 &hCurVidPnTargetModeSet,
3072 &pCurVidPnTargetModeSetInterface);
3073 AssertNtStatusSuccess(Status);
3074 if (Status == STATUS_SUCCESS)
3075 {
3076
3077 Status = vboxVidPnEnumTargetModes(hCurVidPnTargetModeSet, pCurVidPnTargetModeSetInterface,
3078 vboxVidPnDumpTargetModeSetEnum, NULL);
3079 AssertNtStatusSuccess(Status);
3080 if (Status != STATUS_SUCCESS)
3081 {
3082 LOGREL_EXACT(("ERROR enumerating Target Modes(0x%x)\n", Status));
3083 }
3084 pVidPnInterface->pfnReleaseTargetModeSet(hVidPn, hCurVidPnTargetModeSet);
3085 }
3086 else
3087 {
3088 LOGREL_EXACT(("ERROR getting TargetModeSet for Target(%d), Status(0x%x)\n", VidPnTargetId, Status));
3089 }
3090
3091 LOGREL_EXACT((" <<<---End Of TargetMode Set for Target(%d)---", VidPnTargetId));
3092}
3093
3094
3095void vboxVidPnDumpPinnedTargetMode(const D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
3096{
3097 D3DKMDT_HVIDPNTARGETMODESET hCurVidPnTargetModeSet;
3098 const DXGK_VIDPNTARGETMODESET_INTERFACE *pCurVidPnTargetModeSetInterface;
3099
3100 NTSTATUS Status = pVidPnInterface->pfnAcquireTargetModeSet(hVidPn,
3101 VidPnTargetId,
3102 &hCurVidPnTargetModeSet,
3103 &pCurVidPnTargetModeSetInterface);
3104 AssertNtStatusSuccess(Status);
3105 if (Status == STATUS_SUCCESS)
3106 {
3107 CONST D3DKMDT_VIDPN_TARGET_MODE* pPinnedVidPnTargetModeInfo;
3108
3109 Status = pCurVidPnTargetModeSetInterface->pfnAcquirePinnedModeInfo(hCurVidPnTargetModeSet, &pPinnedVidPnTargetModeInfo);
3110 Assert(Status == STATUS_SUCCESS || Status == STATUS_GRAPHICS_MODE_NOT_PINNED);
3111 if (Status == STATUS_SUCCESS)
3112 {
3113 VBoxVidPnDumpTargetMode("Target Pinned: ", pPinnedVidPnTargetModeInfo, "\n");
3114 pCurVidPnTargetModeSetInterface->pfnReleaseModeInfo(hCurVidPnTargetModeSet, pPinnedVidPnTargetModeInfo);
3115 }
3116 else if (Status == STATUS_GRAPHICS_MODE_NOT_PINNED)
3117 {
3118 LOGREL_EXACT(("Target NOT Pinned\n"));
3119 }
3120 else
3121 {
3122 LOGREL_EXACT(("ERROR getting piined Target Mode(0x%x)\n", Status));
3123 }
3124 pVidPnInterface->pfnReleaseTargetModeSet(hVidPn, hCurVidPnTargetModeSet);
3125 }
3126 else
3127 {
3128 LOGREL_EXACT(("ERROR getting TargetModeSet(0x%x)\n", Status));
3129 }
3130}
3131
3132void VBoxVidPnDumpCofuncModalityInfo(const char *pPrefix, D3DKMDT_ENUMCOFUNCMODALITY_PIVOT_TYPE enmEnumPivotType, const DXGK_ENUM_PIVOT *pPivot, const char *pSuffix)
3133{
3134 LOGREL_EXACT(("%sPivotType(%s), SourceId(0x%x), TargetId(0x%x),%s", pPrefix, vboxVidPnDumpStrCFMPivotType(enmEnumPivotType),
3135 pPivot->VidPnSourceId, pPivot->VidPnTargetId, pSuffix));
3136}
3137
3138void vboxVidPnDumpCofuncModalityArg(const char *pPrefix, D3DKMDT_ENUMCOFUNCMODALITY_PIVOT_TYPE enmPivot, const DXGK_ENUM_PIVOT *pPivot, const char *pSuffix)
3139{
3140 LOGREL_EXACT(("%sPivotType(%s), SourceId(0x%x), TargetId(0x%x),%s", pPrefix, vboxVidPnDumpStrCFMPivotType(enmPivot),
3141 pPivot->VidPnSourceId, pPivot->VidPnTargetId, pSuffix));
3142}
3143
3144void vboxVidPnDumpPath(const D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface, const D3DKMDT_VIDPN_PRESENT_PATH *pVidPnPresentPathInfo)
3145{
3146 LOGREL_EXACT((" >>**** Start Dump VidPn Path ****>>\n"));
3147 LOGREL_EXACT(("VidPnSourceId(%d), VidPnTargetId(%d)\n",
3148 pVidPnPresentPathInfo->VidPnSourceId, pVidPnPresentPathInfo->VidPnTargetId));
3149
3150 vboxVidPnDumpPinnedSourceMode(hVidPn, pVidPnInterface, pVidPnPresentPathInfo->VidPnSourceId);
3151 vboxVidPnDumpPinnedTargetMode(hVidPn, pVidPnInterface, pVidPnPresentPathInfo->VidPnTargetId);
3152
3153 vboxVidPnDumpPathTransformation(&pVidPnPresentPathInfo->ContentTransformation);
3154
3155 LOGREL_EXACT(("Importance(%s), TargetColorBasis(%s), Content(%s), ",
3156 vboxVidPnDumpStrImportance(pVidPnPresentPathInfo->ImportanceOrdinal),
3157 vboxVidPnDumpStrColorBasis(pVidPnPresentPathInfo->VidPnTargetColorBasis),
3158 vboxVidPnDumpStrContent(pVidPnPresentPathInfo->Content)));
3159 vboxVidPnDumpRegion("VFA_TL_O(", &pVidPnPresentPathInfo->VisibleFromActiveTLOffset, "), ");
3160 vboxVidPnDumpRegion("VFA_BR_O(", &pVidPnPresentPathInfo->VisibleFromActiveBROffset, "), ");
3161 vboxVidPnDumpRanges("CCDynamicRanges: ", &pVidPnPresentPathInfo->VidPnTargetColorCoeffDynamicRanges, "| ");
3162 vboxVidPnDumpCopyProtectoin("CProtection: ", &pVidPnPresentPathInfo->CopyProtection, "| ");
3163 vboxVidPnDumpGammaRamp("GammaRamp: ", &pVidPnPresentPathInfo->GammaRamp, "\n");
3164
3165 LOGREL_EXACT((" <<**** Stop Dump VidPn Path ****<<"));
3166}
3167
3168typedef struct VBOXVIDPNDUMPPATHENUM
3169{
3170 D3DKMDT_HVIDPN hVidPn;
3171 const DXGK_VIDPN_INTERFACE* pVidPnInterface;
3172} VBOXVIDPNDUMPPATHENUM, *PVBOXVIDPNDUMPPATHENUM;
3173
3174static DECLCALLBACK(BOOLEAN) vboxVidPnDumpPathEnum(D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface,
3175 const D3DKMDT_VIDPN_PRESENT_PATH *pVidPnPresentPathInfo, PVOID pContext)
3176{
3177 PVBOXVIDPNDUMPPATHENUM pData = (PVBOXVIDPNDUMPPATHENUM)pContext;
3178 vboxVidPnDumpPath(pData->hVidPn, pData->pVidPnInterface, pVidPnPresentPathInfo);
3179
3180 pVidPnTopologyInterface->pfnReleasePathInfo(hVidPnTopology, pVidPnPresentPathInfo);
3181 return TRUE;
3182}
3183
3184void vboxVidPnDumpVidPn(const char * pPrefix, PVBOXMP_DEVEXT pDevExt, D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface, const char * pSuffix)
3185{
3186 LOGREL_EXACT(("%s", pPrefix));
3187
3188 VBOXVIDPNDUMPPATHENUM CbData;
3189 CbData.hVidPn = hVidPn;
3190 CbData.pVidPnInterface = pVidPnInterface;
3191 D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology;
3192 const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface;
3193 NTSTATUS Status = pVidPnInterface->pfnGetTopology(hVidPn, &hVidPnTopology, &pVidPnTopologyInterface);
3194 AssertNtStatusSuccess(Status);
3195 if (Status == STATUS_SUCCESS)
3196 {
3197 Status = vboxVidPnEnumPaths(hVidPnTopology, pVidPnTopologyInterface,
3198 vboxVidPnDumpPathEnum, &CbData);
3199 AssertNtStatusSuccess(Status);
3200 }
3201
3202 for (int i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
3203 {
3204 vboxVidPnDumpSourceModeSet(pDevExt, hVidPn, pVidPnInterface, (D3DDDI_VIDEO_PRESENT_SOURCE_ID)i);
3205 vboxVidPnDumpTargetModeSet(pDevExt, hVidPn, pVidPnInterface, (D3DDDI_VIDEO_PRESENT_TARGET_ID)i);
3206 }
3207
3208 LOGREL_EXACT(("%s", pSuffix));
3209}
Note: See TracBrowser for help on using the repository browser.

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