VirtualBox

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

Last change on this file since 66539 was 64878, checked in by vboxsync, 8 years ago

WDDM: pass the display enabled flag to the driver to be able to disable powered off screens. Clearly mark some disabled code.

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