VirtualBox

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

Last change on this file since 54957 was 52631, checked in by vboxsync, 10 years ago

wddm: more verbose err logging

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