VirtualBox

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

Last change on this file since 63566 was 63566, checked in by vboxsync, 9 years ago

scm: cleaning up todos

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

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