VirtualBox

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

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

Additions: scm

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