VirtualBox

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

Last change on this file since 40309 was 38565, checked in by vboxsync, 13 years ago

wddm/3d: reuse window for wine swapchains representing one and the same 3d swapchain, bugfixes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 111.4 KB
Line 
1/* $Id: VBoxMPVidPn.cpp 38565 2011-08-30 09:28:15Z vboxsync $ */
2
3/** @file
4 * VBox WDDM Miniport driver
5 */
6
7/*
8 * Copyright (C) 2011 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
121NTSTATUS vboxVidPnCheckSourceModeInfo(const D3DKMDT_HVIDPN hDesiredVidPn,
122 const D3DKMDT_VIDPN_SOURCE_MODE *pNewVidPnSourceModeInfo,
123 BOOLEAN *pbSupported)
124{
125 BOOLEAN bSupported = TRUE;
126 /* we support both GRAPHICS and TEXT modes */
127 switch (pNewVidPnSourceModeInfo->Type)
128 {
129 case D3DKMDT_RMT_GRAPHICS:
130 /* any primary surface size actually
131 pNewVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cx
132 pNewVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cy
133 */
134 if (pNewVidPnSourceModeInfo->Format.Graphics.VisibleRegionSize.cx != pNewVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cx
135 || pNewVidPnSourceModeInfo->Format.Graphics.VisibleRegionSize.cy != pNewVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cy)
136 {
137 LOG(("VisibleRegionSize(%d, %d) != PrimSurfSize(%d, %d)",
138 pNewVidPnSourceModeInfo->Format.Graphics.VisibleRegionSize.cx,
139 pNewVidPnSourceModeInfo->Format.Graphics.VisibleRegionSize.cy,
140 pNewVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cx,
141 pNewVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cy));
142 AssertBreakpoint();
143 bSupported = FALSE;
144 break;
145 }
146
147 /*
148 pNewVidPnSourceModeInfo->Format.Graphics.Stride
149 pNewVidPnSourceModeInfo->Format.Graphics.PixelFormat
150 pNewVidPnSourceModeInfo->Format.Graphics.ColorBasis
151 pNewVidPnSourceModeInfo->Format.Graphics.PixelValueAccessMode
152 */
153
154 break;
155 case D3DKMDT_RMT_TEXT:
156 break;
157 default:
158 AssertBreakpoint();
159 LOG(("Warning: Unknown Src mode Type (%d)", pNewVidPnSourceModeInfo->Type));
160 break;
161 }
162
163 *pbSupported = bSupported;
164 return STATUS_SUCCESS;
165}
166
167NTSTATUS vboxVidPnCheckSourceModeSet(const D3DKMDT_HVIDPN hDesiredVidPn,
168 D3DKMDT_HVIDPNSOURCEMODESET hNewVidPnSourceModeSet, const DXGK_VIDPNSOURCEMODESET_INTERFACE *pVidPnSourceModeSetInterface,
169 BOOLEAN *pbSupported)
170{
171 const D3DKMDT_VIDPN_SOURCE_MODE *pNewVidPnSourceModeInfo;
172 NTSTATUS Status = pVidPnSourceModeSetInterface->pfnAcquireFirstModeInfo(hNewVidPnSourceModeSet, &pNewVidPnSourceModeInfo);
173 BOOLEAN bSupported = TRUE;
174 if (Status == STATUS_SUCCESS)
175 {
176 while (1)
177 {
178 Status = vboxVidPnCheckSourceModeInfo(hDesiredVidPn, pNewVidPnSourceModeInfo, &bSupported);
179 if (Status == STATUS_SUCCESS && bSupported)
180 {
181 const D3DKMDT_VIDPN_SOURCE_MODE *pNextVidPnSourceModeInfo;
182 Status = pVidPnSourceModeSetInterface->pfnAcquireNextModeInfo(hNewVidPnSourceModeSet, pNewVidPnSourceModeInfo, &pNextVidPnSourceModeInfo);
183 pVidPnSourceModeSetInterface->pfnReleaseModeInfo(hNewVidPnSourceModeSet, pNewVidPnSourceModeInfo);
184 if (Status == STATUS_SUCCESS)
185 {
186 pNewVidPnSourceModeInfo = pNextVidPnSourceModeInfo;
187 }
188 else if (Status == STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET)
189 {
190 Status = STATUS_SUCCESS;
191 break;
192 }
193 else
194 {
195 LOGREL(("pfnAcquireNextModeInfo Failed Status(0x%x)", Status));
196 break;
197 }
198 }
199 else
200 {
201 pVidPnSourceModeSetInterface->pfnReleaseModeInfo(hNewVidPnSourceModeSet, pNewVidPnSourceModeInfo);
202 break;
203 }
204 }
205 }
206 else if (Status == STATUS_GRAPHICS_DATASET_IS_EMPTY)
207 Status = STATUS_SUCCESS;
208 else
209 LOGREL(("VBoxVideoWddm: pfnAcquireFirstModeInfo failed Status(0x%x)", Status));
210
211 *pbSupported = bSupported;
212 return Status;
213}
214
215NTSTATUS vboxVidPnPopulateVideoSignalInfo(D3DKMDT_VIDEO_SIGNAL_INFO *pVsi,
216 D3DKMDT_2DREGION *pResolution,
217 ULONG VSync)
218{
219 NTSTATUS Status = STATUS_SUCCESS;
220
221 pVsi->VideoStandard = D3DKMDT_VSS_VESA_DMT;
222 pVsi->ActiveSize = *pResolution;
223 pVsi->VSyncFreq.Numerator = VSync * 1000;
224 pVsi->VSyncFreq.Denominator = 1000;
225 pVsi->TotalSize.cx = pVsi->ActiveSize.cx + VBOXVDPN_C_DISPLAY_HBLANK_SIZE;
226 pVsi->TotalSize.cy = pVsi->ActiveSize.cy + VBOXVDPN_C_DISPLAY_VBLANK_SIZE;
227 pVsi->PixelRate = pVsi->TotalSize.cx * pVsi->TotalSize.cy * VSync;
228 pVsi->HSyncFreq.Numerator = (UINT)((pVsi->PixelRate / pVsi->TotalSize.cy) * 1000);
229 pVsi->HSyncFreq.Denominator = 1000;
230 pVsi->ScanLineOrdering = D3DDDI_VSSLO_PROGRESSIVE;
231
232 return Status;
233}
234
235BOOLEAN vboxVidPnMatchVideoSignal(const D3DKMDT_VIDEO_SIGNAL_INFO *pVsi1, const D3DKMDT_VIDEO_SIGNAL_INFO *pVsi2)
236{
237 if (pVsi1->VideoStandard != pVsi2->VideoStandard)
238 return FALSE;
239 if (pVsi1->TotalSize.cx != pVsi2->TotalSize.cx)
240 return FALSE;
241 if (pVsi1->TotalSize.cy != pVsi2->TotalSize.cy)
242 return FALSE;
243 if (pVsi1->ActiveSize.cx != pVsi2->ActiveSize.cx)
244 return FALSE;
245 if (pVsi1->ActiveSize.cy != pVsi2->ActiveSize.cy)
246 return FALSE;
247 if (pVsi1->VSyncFreq.Numerator != pVsi2->VSyncFreq.Numerator)
248 return FALSE;
249 if (pVsi1->VSyncFreq.Denominator != pVsi2->VSyncFreq.Denominator)
250 return FALSE;
251 if (pVsi1->HSyncFreq.Numerator != pVsi2->HSyncFreq.Numerator)
252 return FALSE;
253 if (pVsi1->HSyncFreq.Denominator != pVsi2->HSyncFreq.Denominator)
254 return FALSE;
255 if (pVsi1->PixelRate != pVsi2->PixelRate)
256 return FALSE;
257 if (pVsi1->ScanLineOrdering != pVsi2->ScanLineOrdering)
258 return FALSE;
259
260 return TRUE;
261}
262
263NTSTATUS vboxVidPnCheckTargetModeInfo(const D3DKMDT_HVIDPN hDesiredVidPn,
264 const D3DKMDT_VIDPN_TARGET_MODE *pNewVidPnTargetModeInfo,
265 BOOLEAN *pbSupported)
266{
267 BOOLEAN bSupported = TRUE;
268 D3DKMDT_VIDEO_SIGNAL_INFO CmpVsi;
269 D3DKMDT_2DREGION CmpRes;
270 CmpRes.cx = pNewVidPnTargetModeInfo->VideoSignalInfo.ActiveSize.cx;
271 CmpRes.cy = pNewVidPnTargetModeInfo->VideoSignalInfo.ActiveSize.cy;
272 NTSTATUS Status = vboxVidPnPopulateVideoSignalInfo(&CmpVsi,
273 &CmpRes,
274 pNewVidPnTargetModeInfo->VideoSignalInfo.VSyncFreq.Numerator/pNewVidPnTargetModeInfo->VideoSignalInfo.VSyncFreq.Denominator);
275 Assert(Status == STATUS_SUCCESS);
276 if (Status != STATUS_SUCCESS)
277 {
278 LOGREL(("vboxVidPnPopulateVideoSignalInfo error Status (0x%x)", Status));
279 return Status;
280 }
281
282 if (!vboxVidPnMatchVideoSignal(&CmpVsi, &pNewVidPnTargetModeInfo->VideoSignalInfo))
283 {
284 WARN(("VideoSignalInfos do not match!!!"));
285 AssertBreakpoint();
286 bSupported = FALSE;
287 }
288
289 *pbSupported = bSupported;
290 return STATUS_SUCCESS;
291}
292
293NTSTATUS vboxVidPnCheckTargetModeSet(const D3DKMDT_HVIDPN hDesiredVidPn,
294 D3DKMDT_HVIDPNTARGETMODESET hNewVidPnTargetModeSet, const DXGK_VIDPNTARGETMODESET_INTERFACE *pVidPnTargetModeSetInterface,
295 BOOLEAN *pbSupported)
296{
297 const D3DKMDT_VIDPN_TARGET_MODE *pNewVidPnTargetModeInfo;
298 NTSTATUS Status = pVidPnTargetModeSetInterface->pfnAcquireFirstModeInfo(hNewVidPnTargetModeSet, &pNewVidPnTargetModeInfo);
299 BOOLEAN bSupported = TRUE;
300 if (Status == STATUS_SUCCESS)
301 {
302 Assert(pNewVidPnTargetModeInfo);
303 while (1)
304 {
305 Status = vboxVidPnCheckTargetModeInfo(hDesiredVidPn, pNewVidPnTargetModeInfo, &bSupported);
306 if (Status == STATUS_SUCCESS && bSupported)
307 {
308 const D3DKMDT_VIDPN_TARGET_MODE *pNextVidPnTargetModeInfo;
309 Status = pVidPnTargetModeSetInterface->pfnAcquireNextModeInfo(hNewVidPnTargetModeSet, pNewVidPnTargetModeInfo, &pNextVidPnTargetModeInfo);
310 pVidPnTargetModeSetInterface->pfnReleaseModeInfo(hNewVidPnTargetModeSet, pNewVidPnTargetModeInfo);
311 if (Status == STATUS_SUCCESS)
312 {
313 pNewVidPnTargetModeInfo = pNextVidPnTargetModeInfo;
314 }
315 else if (Status == STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET)
316 {
317 Status = STATUS_SUCCESS;
318 break;
319 }
320 else
321 {
322 LOGREL(("pfnAcquireNextModeInfo Failed Status(0x%x)", Status));
323 break;
324 }
325 }
326 else
327 {
328 pVidPnTargetModeSetInterface->pfnReleaseModeInfo(hNewVidPnTargetModeSet, pNewVidPnTargetModeInfo);
329 break;
330 }
331 }
332 }
333 else if (Status == STATUS_GRAPHICS_DATASET_IS_EMPTY)
334 Status = STATUS_SUCCESS;
335 else
336 LOGREL(("pfnAcquireFirstModeInfo failed Status(0x%x)", Status));
337
338 *pbSupported = bSupported;
339 return Status;
340}
341
342NTSTATUS vboxVidPnPopulateSourceModeInfoFromLegacy(D3DKMDT_VIDPN_SOURCE_MODE *pNewVidPnSourceModeInfo,
343 VIDEO_MODE_INFORMATION *pMode)
344{
345 NTSTATUS Status = STATUS_SUCCESS;
346 if (pMode->AttributeFlags & VIDEO_MODE_GRAPHICS)
347 {
348 /* this is a graphics mode */
349 pNewVidPnSourceModeInfo->Type = D3DKMDT_RMT_GRAPHICS;
350 pNewVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cx = pMode->VisScreenWidth;
351 pNewVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cy = pMode->VisScreenHeight;
352 pNewVidPnSourceModeInfo->Format.Graphics.VisibleRegionSize = pNewVidPnSourceModeInfo->Format.Graphics.PrimSurfSize;
353 pNewVidPnSourceModeInfo->Format.Graphics.Stride = pMode->ScreenStride;
354 pNewVidPnSourceModeInfo->Format.Graphics.PixelFormat = vboxWddmCalcPixelFormat(pMode);
355 Assert(pNewVidPnSourceModeInfo->Format.Graphics.PixelFormat != D3DDDIFMT_UNKNOWN);
356 if (pNewVidPnSourceModeInfo->Format.Graphics.PixelFormat != D3DDDIFMT_UNKNOWN)
357 {
358 pNewVidPnSourceModeInfo->Format.Graphics.ColorBasis = D3DKMDT_CB_SRGB;
359 if (pNewVidPnSourceModeInfo->Format.Graphics.PixelFormat == D3DDDIFMT_P8)
360 pNewVidPnSourceModeInfo->Format.Graphics.PixelValueAccessMode = D3DKMDT_PVAM_SETTABLEPALETTE;
361 else
362 pNewVidPnSourceModeInfo->Format.Graphics.PixelValueAccessMode = D3DKMDT_PVAM_DIRECT;
363 }
364 else
365 {
366 LOGREL(("vboxWddmCalcPixelFormat failed"));
367 Status = STATUS_INVALID_PARAMETER;
368 }
369 }
370 else
371 {
372 /* @todo: XPDM driver does not seem to return text modes, should we? */
373 LOGREL(("text mode not supported currently"));
374 AssertBreakpoint();
375 Status = STATUS_INVALID_PARAMETER;
376 }
377
378 return Status;
379}
380
381NTSTATUS vboxVidPnPopulateMonitorSourceModeInfoFromLegacy(PVBOXMP_DEVEXT pDevExt,
382 D3DKMDT_MONITOR_SOURCE_MODE *pMonitorSourceMode,
383 D3DKMDT_2DREGION *pResolution,
384 D3DKMDT_MONITOR_CAPABILITIES_ORIGIN enmOrigin,
385 BOOLEAN bPreferred)
386{
387 NTSTATUS Status = vboxVidPnPopulateVideoSignalInfo(&pMonitorSourceMode->VideoSignalInfo, pResolution, 60 /* ULONG VSync */);
388 Assert(Status == STATUS_SUCCESS);
389 if (Status == STATUS_SUCCESS)
390 {
391 pMonitorSourceMode->ColorBasis = D3DKMDT_CB_SRGB;
392 pMonitorSourceMode->ColorCoeffDynamicRanges.FirstChannel = 8;
393 pMonitorSourceMode->ColorCoeffDynamicRanges.SecondChannel = 8;
394 pMonitorSourceMode->ColorCoeffDynamicRanges.ThirdChannel = 8;
395 pMonitorSourceMode->ColorCoeffDynamicRanges.FourthChannel = 0;
396 pMonitorSourceMode->Origin = enmOrigin;
397 pMonitorSourceMode->Preference = bPreferred ? D3DKMDT_MP_PREFERRED : D3DKMDT_MP_NOTPREFERRED;
398 }
399
400 return Status;
401}
402
403NTSTATUS vboxVidPnCreatePopulateMonitorSourceModeInfoFromLegacy(PVBOXMP_DEVEXT pDevExt,
404 CONST D3DKMDT_HMONITORSOURCEMODESET hMonitorSMS,
405 CONST DXGK_MONITORSOURCEMODESET_INTERFACE *pMonitorSMSIf,
406 D3DKMDT_2DREGION *pResolution,
407 D3DKMDT_MONITOR_CAPABILITIES_ORIGIN enmOrigin,
408 BOOLEAN bPreferred)
409{
410 D3DKMDT_MONITOR_SOURCE_MODE * pMonitorSMI;
411 NTSTATUS Status = pMonitorSMSIf->pfnCreateNewModeInfo(hMonitorSMS, &pMonitorSMI);
412 Assert(Status == STATUS_SUCCESS);
413 if (Status == STATUS_SUCCESS)
414 {
415 do
416 {
417 Status = vboxVidPnPopulateMonitorSourceModeInfoFromLegacy(pDevExt,
418 pMonitorSMI,
419 pResolution,
420 enmOrigin,
421 bPreferred);
422 Assert(Status == STATUS_SUCCESS);
423 if (Status == STATUS_SUCCESS)
424 {
425 Status = pMonitorSMSIf->pfnAddMode(hMonitorSMS, pMonitorSMI);
426 Assert(Status == STATUS_SUCCESS/* || Status == STATUS_GRAPHICS_MODE_ALREADY_IN_MODESET*/);
427 if (Status == STATUS_SUCCESS)
428 break;
429 LOGREL(("pfnAddMode failed, Status(0x%x)", Status));
430 }
431 else
432 LOGREL(("vboxVidPnPopulateMonitorSourceModeInfoFromLegacy failed, Status(0x%x)", Status));
433
434 Assert (Status != STATUS_SUCCESS);
435 /* we're here because of a failure */
436 NTSTATUS tmpStatus = pMonitorSMSIf->pfnReleaseModeInfo(hMonitorSMS, pMonitorSMI);
437 Assert(tmpStatus == STATUS_SUCCESS);
438 if (tmpStatus != STATUS_SUCCESS)
439 LOGREL(("pfnReleaseModeInfo failed tmpStatus(0x%x)", tmpStatus));
440
441 if (Status == STATUS_GRAPHICS_MODE_ALREADY_IN_MODESET)
442 Status = STATUS_SUCCESS;
443 } while (0);
444 }
445 else
446 LOGREL(("pfnCreateNewModeInfo failed, Status(0x%x)", Status));
447
448 return Status;
449}
450
451NTSTATUS vboxVidPnPopulateTargetModeInfoFromLegacy(D3DKMDT_VIDPN_TARGET_MODE *pNewVidPnTargetModeInfo, D3DKMDT_2DREGION *pResolution, BOOLEAN fPreferred)
452{
453 pNewVidPnTargetModeInfo->Preference = fPreferred ? D3DKMDT_MP_PREFERRED : D3DKMDT_MP_NOTPREFERRED;
454 return vboxVidPnPopulateVideoSignalInfo(&pNewVidPnTargetModeInfo->VideoSignalInfo, pResolution, 60 /* ULONG VSync */);
455}
456
457typedef struct VBOXVIDPNCHECKADDMONITORMODES
458{
459 NTSTATUS Status;
460 D3DKMDT_2DREGION *pResolutions;
461 uint32_t cResolutions;
462} VBOXVIDPNCHECKADDMONITORMODES, *PVBOXVIDPNCHECKADDMONITORMODES;
463
464static DECLCALLBACK(BOOLEAN) vboxVidPnCheckAddMonitorModesEnum(PVBOXMP_DEVEXT pDevExt, D3DKMDT_HMONITORSOURCEMODESET hMonitorSMS, CONST DXGK_MONITORSOURCEMODESET_INTERFACE *pMonitorSMSIf,
465 CONST D3DKMDT_MONITOR_SOURCE_MODE *pMonitorSMI, PVOID pContext)
466{
467 PVBOXVIDPNCHECKADDMONITORMODES pData = (PVBOXVIDPNCHECKADDMONITORMODES)pContext;
468 NTSTATUS Status = STATUS_SUCCESS;
469
470 for (uint32_t i = 0; i < pData->cResolutions; ++i)
471 {
472 D3DKMDT_VIDPN_TARGET_MODE dummyMode = {0};
473 Status = vboxVidPnPopulateTargetModeInfoFromLegacy(&dummyMode, &pData->pResolutions[i], FALSE /* preference does not matter for now */);
474 Assert(Status == STATUS_SUCCESS);
475 if (Status == STATUS_SUCCESS)
476 {
477 if (vboxVidPnMatchVideoSignal(&dummyMode.VideoSignalInfo, &pMonitorSMI->VideoSignalInfo))
478 {
479 /* mark it as unneeded */
480 pData->pResolutions[i].cx = 0;
481 break;
482 }
483 }
484 else
485 {
486 LOGREL(("vboxVidPnPopulateTargetModeInfoFromLegacy failed Status(0x%x)", Status));
487 break;
488 }
489 }
490
491 pMonitorSMSIf->pfnReleaseModeInfo(hMonitorSMS, pMonitorSMI);
492
493 pData->Status = Status;
494
495 return Status == STATUS_SUCCESS;
496}
497
498typedef struct VBOXVIDPNCHECKMONMODESENUM
499{
500 D3DKMDT_2DREGION Region;
501 const D3DKMDT_MONITOR_SOURCE_MODE * pMonitorSMI;
502} VBOXVIDPNCHECKMONMODESENUM, *PVBOXVIDPNCHECKMONMODESENUM;
503
504static DECLCALLBACK(BOOLEAN) vboxFidPnCheckMonitorModesEnum(D3DKMDT_HMONITORSOURCEMODESET hMonitorSMS, CONST DXGK_MONITORSOURCEMODESET_INTERFACE *pMonitorSMSIf,
505 CONST D3DKMDT_MONITOR_SOURCE_MODE *pMonitorSMI, PVOID pContext)
506{
507 PVBOXVIDPNCHECKMONMODESENUM pInfo = (PVBOXVIDPNCHECKMONMODESENUM)pContext;
508 if (pMonitorSMI->VideoSignalInfo.ActiveSize.cx == pInfo->Region.cx
509 && pMonitorSMI->VideoSignalInfo.ActiveSize.cy == pInfo->Region.cy)
510 {
511 Assert(!pInfo->pMonitorSMI);
512 if (pInfo->pMonitorSMI)
513 {
514 pMonitorSMSIf->pfnReleaseModeInfo(hMonitorSMS, pInfo->pMonitorSMI);
515 }
516 pInfo->pMonitorSMI = pMonitorSMI;
517 }
518 else
519 {
520 pMonitorSMSIf->pfnReleaseModeInfo(hMonitorSMS, pMonitorSMI);
521 }
522 return TRUE;
523}
524
525typedef struct VBOXVIDPNMATCHMONMODESENUM
526{
527 D3DKMDT_2DREGION *paResolutions;
528 uint32_t cResolutions;
529 BOOLEAN fMatch;
530} VBOXVIDPNMATCHMONMODESENUM, *PVBOXVIDPNMATCHMONMODESENUM;
531
532static DECLCALLBACK(BOOLEAN) vboxFidPnMatchMonitorModesEnum(D3DKMDT_HMONITORSOURCEMODESET hMonitorSMS, CONST DXGK_MONITORSOURCEMODESET_INTERFACE *pMonitorSMSIf,
533 CONST D3DKMDT_MONITOR_SOURCE_MODE *pMonitorSMI, PVOID pContext)
534{
535 PVBOXVIDPNMATCHMONMODESENUM pInfo = (PVBOXVIDPNMATCHMONMODESENUM)pContext;
536
537 Assert(pInfo->fMatch);
538
539 for (UINT i = 0; i < pInfo->cResolutions; ++i)
540 {
541 D3DKMDT_2DREGION *pResolution = &pInfo->paResolutions[i];
542 if (pMonitorSMI->VideoSignalInfo.ActiveSize.cx != pResolution->cx
543 || pMonitorSMI->VideoSignalInfo.ActiveSize.cy != pResolution->cy)
544 {
545 pInfo->fMatch = FALSE;
546 break;
547 }
548 }
549
550 pMonitorSMSIf->pfnReleaseModeInfo(hMonitorSMS, pMonitorSMI);
551
552 return pInfo->fMatch;
553}
554
555/* matches the monitor mode set for the given target id with the resolution set, and sets the pfMatch to true if they match, otherwise sets it to false */
556NTSTATUS vboxVidPnMatchMonitorModes(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_TARGET_ID targetId,
557 D3DKMDT_2DREGION *pResolutions, uint32_t cResolutions, BOOLEAN *pfMatch)
558{
559 *pfMatch = FALSE;
560 CONST DXGK_MONITOR_INTERFACE *pMonitorInterface;
561 NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbQueryMonitorInterface(pDevExt->u.primary.DxgkInterface.DeviceHandle, DXGK_MONITOR_INTERFACE_VERSION_V1, &pMonitorInterface);
562 if (!NT_SUCCESS(Status))
563 {
564 WARN(("DxgkCbQueryMonitorInterface failed, Status (0x%x)", Status));
565 return Status;
566 }
567
568 D3DKMDT_HMONITORSOURCEMODESET hMonitorSMS;
569 CONST DXGK_MONITORSOURCEMODESET_INTERFACE *pMonitorSMSIf;
570 Status = pMonitorInterface->pfnAcquireMonitorSourceModeSet(pDevExt->u.primary.DxgkInterface.DeviceHandle,
571 targetId,
572 &hMonitorSMS,
573 &pMonitorSMSIf);
574 if (!NT_SUCCESS(Status))
575 {
576 WARN(("pfnAcquireMonitorSourceModeSet failed, Status (0x%x)", Status));
577 if (Status == STATUS_GRAPHICS_MONITOR_NOT_CONNECTED)
578 {
579 /* this is ok in case we replug the monitor to pick up the monitor modes properly,
580 * so pretend success */
581 *pfMatch = TRUE;
582 Status = STATUS_SUCCESS;
583 }
584 return Status;
585 }
586
587 VBOXVIDPNMATCHMONMODESENUM Info;
588 Info.paResolutions = pResolutions;
589 Info.cResolutions = cResolutions;
590 Info.fMatch = TRUE;
591
592 Status = vboxVidPnEnumMonitorSourceModes(hMonitorSMS, pMonitorSMSIf, vboxFidPnMatchMonitorModesEnum, &Info);
593 if (NT_SUCCESS(Status))
594 {
595 *pfMatch = Info.fMatch;
596 }
597
598 NTSTATUS tmpStatus = pMonitorInterface->pfnReleaseMonitorSourceModeSet(pDevExt->u.primary.DxgkInterface.DeviceHandle, hMonitorSMS);
599 if (!NT_SUCCESS(tmpStatus))
600 WARN(("pfnReleaseMonitorSourceModeSet failed tmpStatus(0x%x)", tmpStatus));
601
602 return Status;
603}
604
605NTSTATUS vboxVidPnCheckAddMonitorModes(PVBOXMP_DEVEXT pDevExt,
606 D3DDDI_VIDEO_PRESENT_TARGET_ID targetId, D3DKMDT_MONITOR_CAPABILITIES_ORIGIN enmOrigin,
607 D3DKMDT_2DREGION *pResolutions, uint32_t cResolutions, int iPreferred)
608{
609 NTSTATUS Status;
610 CONST DXGK_MONITOR_INTERFACE *pMonitorInterface;
611 Status = pDevExt->u.primary.DxgkInterface.DxgkCbQueryMonitorInterface(pDevExt->u.primary.DxgkInterface.DeviceHandle, DXGK_MONITOR_INTERFACE_VERSION_V1, &pMonitorInterface);
612 if (!NT_SUCCESS(Status))
613 {
614 WARN(("DxgkCbQueryMonitorInterface failed, Status()0x%x", Status));
615 return Status;
616 }
617
618 D3DKMDT_HMONITORSOURCEMODESET hMonitorSMS;
619 CONST DXGK_MONITORSOURCEMODESET_INTERFACE *pMonitorSMSIf;
620
621 Status = pMonitorInterface->pfnAcquireMonitorSourceModeSet(pDevExt->u.primary.DxgkInterface.DeviceHandle,
622 targetId,
623 &hMonitorSMS,
624 &pMonitorSMSIf);
625 if (!NT_SUCCESS(Status))
626 {
627 WARN(("DxgkCbQueryMonitorInterface failed, Status()0x%x", Status));
628 if (Status == STATUS_GRAPHICS_MONITOR_NOT_CONNECTED)
629 {
630 /* this is ok in case we replug the monitor to pick up the monitor modes properly,
631 * so pretend success */
632 Status = STATUS_SUCCESS;
633 }
634 return Status;
635 }
636
637 for (uint32_t i = 0; i < cResolutions; ++i)
638 {
639 D3DKMDT_2DREGION *pRes = &pResolutions[i];
640
641 Status = vboxVidPnCreatePopulateMonitorSourceModeInfoFromLegacy(pDevExt,
642 hMonitorSMS,
643 pMonitorSMSIf,
644 pRes,
645 enmOrigin,
646 iPreferred == i
647 );
648 Assert(Status == STATUS_SUCCESS);
649 if (Status != STATUS_SUCCESS)
650 {
651 LOGREL(("vboxVidPnCreatePopulateMonitorSourceModeInfoFromLegacy failed Status(0x%x)", Status));
652 break;
653 }
654 }
655
656 NTSTATUS tmpStatus = pMonitorInterface->pfnReleaseMonitorSourceModeSet(pDevExt->u.primary.DxgkInterface.DeviceHandle, hMonitorSMS);
657 if (!NT_SUCCESS(tmpStatus))
658 {
659 WARN(("pfnReleaseMonitorSourceModeSet failed tmpStatus(0x%x)", tmpStatus));
660 }
661
662 return Status;
663}
664
665NTSTATUS vboxVidPnPathAdd(D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface,
666 const D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, const D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
667{
668 D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology;
669 const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface;
670 NTSTATUS Status = pVidPnInterface->pfnGetTopology(hVidPn, &hVidPnTopology, &pVidPnTopologyInterface);
671 if (!NT_SUCCESS(Status))
672 {
673 AssertFailed();
674 return Status;
675 }
676
677 D3DKMDT_VIDPN_PRESENT_PATH *pNewVidPnPresentPathInfo;
678 Status = pVidPnTopologyInterface->pfnCreateNewPathInfo(hVidPnTopology, &pNewVidPnPresentPathInfo);
679 if (!NT_SUCCESS(Status))
680 {
681 AssertFailed();
682 return Status;
683 }
684
685 pNewVidPnPresentPathInfo->VidPnSourceId = VidPnSourceId;
686 pNewVidPnPresentPathInfo->VidPnTargetId = VidPnTargetId;
687 pNewVidPnPresentPathInfo->ImportanceOrdinal = D3DKMDT_VPPI_PRIMARY;
688 pNewVidPnPresentPathInfo->ContentTransformation.Scaling = D3DKMDT_VPPS_IDENTITY;
689 memset(&pNewVidPnPresentPathInfo->ContentTransformation.ScalingSupport,
690 0, sizeof (pNewVidPnPresentPathInfo->ContentTransformation.ScalingSupport));
691 pNewVidPnPresentPathInfo->ContentTransformation.ScalingSupport.Identity = 1;
692 pNewVidPnPresentPathInfo->ContentTransformation.ScalingSupport.Centered = 0;
693 pNewVidPnPresentPathInfo->ContentTransformation.ScalingSupport.Stretched = 0;
694 pNewVidPnPresentPathInfo->ContentTransformation.Rotation = D3DKMDT_VPPR_IDENTITY;
695 pNewVidPnPresentPathInfo->ContentTransformation.RotationSupport.Identity = 1;
696 pNewVidPnPresentPathInfo->ContentTransformation.RotationSupport.Rotate180 = 0;
697 pNewVidPnPresentPathInfo->ContentTransformation.RotationSupport.Rotate270 = 0;
698 pNewVidPnPresentPathInfo->ContentTransformation.RotationSupport.Rotate90 = 0;
699 pNewVidPnPresentPathInfo->VisibleFromActiveTLOffset.cx = 0;
700 pNewVidPnPresentPathInfo->VisibleFromActiveTLOffset.cy = 0;
701 pNewVidPnPresentPathInfo->VisibleFromActiveBROffset.cx = 0;
702 pNewVidPnPresentPathInfo->VisibleFromActiveBROffset.cy = 0;
703 pNewVidPnPresentPathInfo->VidPnTargetColorBasis = D3DKMDT_CB_SRGB; /* @todo: how does it matters? */
704 pNewVidPnPresentPathInfo->VidPnTargetColorCoeffDynamicRanges.FirstChannel = 8;
705 pNewVidPnPresentPathInfo->VidPnTargetColorCoeffDynamicRanges.SecondChannel = 8;
706 pNewVidPnPresentPathInfo->VidPnTargetColorCoeffDynamicRanges.ThirdChannel = 8;
707 pNewVidPnPresentPathInfo->VidPnTargetColorCoeffDynamicRanges.FourthChannel = 0;
708 pNewVidPnPresentPathInfo->Content = D3DKMDT_VPPC_GRAPHICS;
709 pNewVidPnPresentPathInfo->CopyProtection.CopyProtectionType = D3DKMDT_VPPMT_UNINITIALIZED;
710// pNewVidPnPresentPathInfo->CopyProtection.CopyProtectionType = D3DKMDT_VPPMT_NOPROTECTION;
711 pNewVidPnPresentPathInfo->CopyProtection.APSTriggerBits = 0;
712 memset(&pNewVidPnPresentPathInfo->CopyProtection.CopyProtectionSupport, 0, sizeof (pNewVidPnPresentPathInfo->CopyProtection.CopyProtectionSupport));
713// pNewVidPnPresentPathInfo->CopyProtection.CopyProtectionSupport.NoProtection = 1;
714 memset (&pNewVidPnPresentPathInfo->GammaRamp, 0, sizeof (pNewVidPnPresentPathInfo->GammaRamp));
715// pNewVidPnPresentPathInfo->GammaRamp.Type = D3DDDI_GAMMARAMP_DEFAULT;
716// pNewVidPnPresentPathInfo->GammaRamp.DataSize = 0;
717 Status = pVidPnTopologyInterface->pfnAddPath(hVidPnTopology, pNewVidPnPresentPathInfo);
718 if (!NT_SUCCESS(Status))
719 {
720 AssertFailed();
721 NTSTATUS tmpStatus = pVidPnTopologyInterface->pfnReleasePathInfo(hVidPnTopology, pNewVidPnPresentPathInfo);
722 Assert(NT_SUCCESS(tmpStatus));
723 }
724
725 return Status;
726}
727
728static NTSTATUS vboxVidPnCreatePopulateSourceModeInfoFromLegacy(D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface,
729 const D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId,
730 VIDEO_MODE_INFORMATION *pModes, uint32_t cModes, int iModeToPin,
731 D3DKMDT_VIDEO_PRESENT_SOURCE_MODE_ID *pModeIdToPin,
732 BOOLEAN fDoPin
733 )
734{
735 D3DKMDT_HVIDPNSOURCEMODESET hNewVidPnSourceModeSet;
736 const DXGK_VIDPNSOURCEMODESET_INTERFACE *pNewVidPnSourceModeSetInterface;
737
738 if (pModeIdToPin)
739 *pModeIdToPin = D3DDDI_ID_UNINITIALIZED;
740
741 NTSTATUS Status = pVidPnInterface->pfnCreateNewSourceModeSet(hVidPn,
742 VidPnSourceId,
743 &hNewVidPnSourceModeSet,
744 &pNewVidPnSourceModeSetInterface);
745 if (!NT_SUCCESS(Status))
746 {
747 AssertFailed();
748 return Status;
749 }
750
751 D3DKMDT_VIDEO_PRESENT_SOURCE_MODE_ID sourceModeId = D3DDDI_ID_UNINITIALIZED;
752
753 for (uint32_t i = 0; i < cModes; ++i)
754 {
755 VIDEO_MODE_INFORMATION *pMode = &pModes[i];
756 D3DKMDT_VIDPN_SOURCE_MODE *pNewVidPnSourceModeInfo;
757 Status = pNewVidPnSourceModeSetInterface->pfnCreateNewModeInfo(hNewVidPnSourceModeSet, &pNewVidPnSourceModeInfo);
758 if (!NT_SUCCESS(Status))
759 {
760 AssertFailed();
761 break;
762 }
763
764 Status = vboxVidPnPopulateSourceModeInfoFromLegacy(pNewVidPnSourceModeInfo, pMode);
765 if (NT_SUCCESS(Status))
766 {
767 if (i == iModeToPin)
768 {
769 sourceModeId = pNewVidPnSourceModeInfo->Id;
770 }
771 Status = pNewVidPnSourceModeSetInterface->pfnAddMode(hNewVidPnSourceModeSet, pNewVidPnSourceModeInfo);
772 if (NT_SUCCESS(Status))
773 {
774 /* success */
775 continue;
776 }
777 AssertFailed();
778 }
779 else
780 {
781 AssertFailed();
782 }
783
784 NTSTATUS tmpStatus = pNewVidPnSourceModeSetInterface->pfnReleaseModeInfo(hNewVidPnSourceModeSet, pNewVidPnSourceModeInfo);
785 Assert(tmpStatus == STATUS_SUCCESS);
786
787 /* we're here because of an error */
788 Assert(!NT_SUCCESS(Status));
789 break;
790 }
791
792 if (!NT_SUCCESS(Status))
793 {
794 AssertFailed();
795 return Status;
796 }
797
798 if (sourceModeId != D3DDDI_ID_UNINITIALIZED)
799 {
800 if (pModeIdToPin)
801 {
802 *pModeIdToPin = sourceModeId;
803 }
804 Assert(iModeToPin >= 0);
805 if (fDoPin)
806 {
807 Status = pNewVidPnSourceModeSetInterface->pfnPinMode(hNewVidPnSourceModeSet, sourceModeId);
808 if (!NT_SUCCESS(Status))
809 {
810 AssertFailed();
811 return Status;
812 }
813 }
814 }
815 else
816 {
817 Assert(iModeToPin < 0);
818 }
819
820 Status = pVidPnInterface->pfnAssignSourceModeSet(hVidPn, VidPnSourceId, hNewVidPnSourceModeSet);
821 if (!NT_SUCCESS(Status))
822 {
823 AssertFailed();
824 return Status;
825 }
826
827 return Status;
828}
829
830static NTSTATUS vboxVidPnCreatePopulateTargetModeInfoFromLegacy(D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface,
831 const D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId,
832 D3DKMDT_2DREGION *pResolutions, uint32_t cResolutions,
833 VIDEO_MODE_INFORMATION *pModeToPin,
834 D3DKMDT_VIDEO_PRESENT_TARGET_MODE_ID *pModeIdToPin,
835 BOOLEAN fSetPreferred,
836 BOOLEAN fDoPin
837 )
838{
839 D3DKMDT_HVIDPNTARGETMODESET hNewVidPnTargetModeSet;
840 const DXGK_VIDPNTARGETMODESET_INTERFACE *pNewVidPnTargetModeSetInterface;
841
842 if (pModeIdToPin)
843 *pModeIdToPin = D3DDDI_ID_UNINITIALIZED;
844
845 NTSTATUS Status = pVidPnInterface->pfnCreateNewTargetModeSet(hVidPn,
846 VidPnTargetId,
847 &hNewVidPnTargetModeSet,
848 &pNewVidPnTargetModeSetInterface);
849 if (!NT_SUCCESS(Status))
850 {
851 AssertFailed();
852 return Status;
853 }
854
855 D3DKMDT_VIDEO_PRESENT_TARGET_MODE_ID targetModeId = D3DDDI_ID_UNINITIALIZED;
856
857 for (uint32_t i = 0; i < cResolutions; ++i)
858 {
859 D3DKMDT_2DREGION *pResolution = &pResolutions[i];
860 D3DKMDT_VIDPN_TARGET_MODE *pNewVidPnTargetModeInfo;
861 Status = pNewVidPnTargetModeSetInterface->pfnCreateNewModeInfo(hNewVidPnTargetModeSet, &pNewVidPnTargetModeInfo);
862 if (!NT_SUCCESS(Status))
863 {
864 AssertFailed();
865 break;
866 }
867
868 BOOLEAN fIsPinMode = pModeToPin && pModeToPin->VisScreenWidth == pResolution->cx
869 && pModeToPin->VisScreenHeight == pResolution->cy;
870
871 Status = vboxVidPnPopulateTargetModeInfoFromLegacy(pNewVidPnTargetModeInfo, pResolution, fIsPinMode && fSetPreferred);
872 if (NT_SUCCESS(Status))
873 {
874 if (fIsPinMode)
875 {
876 targetModeId = pNewVidPnTargetModeInfo->Id;
877 }
878 Status = pNewVidPnTargetModeSetInterface->pfnAddMode(hNewVidPnTargetModeSet, pNewVidPnTargetModeInfo);
879 if (NT_SUCCESS(Status))
880 {
881
882 /* success */
883 continue;
884 }
885 AssertFailed();
886 }
887 else
888 {
889 AssertFailed();
890 }
891
892 NTSTATUS tmpStatus = pNewVidPnTargetModeSetInterface->pfnReleaseModeInfo(hNewVidPnTargetModeSet, pNewVidPnTargetModeInfo);
893 Assert(tmpStatus == STATUS_SUCCESS);
894
895 /* we're here because of an error */
896 Assert(!NT_SUCCESS(Status));
897 break;
898 }
899
900 if (!NT_SUCCESS(Status))
901 {
902 AssertFailed();
903 return Status;
904 }
905
906 if (targetModeId != D3DDDI_ID_UNINITIALIZED)
907 {
908 Assert(pModeToPin);
909
910 if (pModeIdToPin)
911 {
912 *pModeIdToPin = targetModeId;
913 }
914
915 if (fDoPin)
916 {
917 Status = pNewVidPnTargetModeSetInterface->pfnPinMode(hNewVidPnTargetModeSet, targetModeId);
918 if (!NT_SUCCESS(Status))
919 {
920 AssertFailed();
921 return Status;
922 }
923 }
924 }
925 else
926 {
927 Assert(!pModeToPin);
928 }
929
930 Status = pVidPnInterface->pfnAssignTargetModeSet(hVidPn, VidPnTargetId, hNewVidPnTargetModeSet);
931 if (!NT_SUCCESS(Status))
932 {
933 AssertFailed();
934 return Status;
935 }
936
937 return Status;
938}
939
940NTSTATUS vboxVidPnCreatePopulateVidPnPathFromLegacy(PVBOXMP_DEVEXT pDevExt, D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface,
941 VIDEO_MODE_INFORMATION *pModes, uint32_t cModes, int iModeToPin,
942 D3DKMDT_2DREGION *pResolutions, uint32_t cResolutions,
943 const D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, const D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
944{
945 NTSTATUS Status;
946
947#if 0
948 Status = vboxVidPnPathAdd(hVidPn, pVidPnInterface, VidPnSourceId, VidPnTargetId);
949 if (!NT_SUCCESS(Status))
950 {
951 AssertFailed();
952 return Status;
953 }
954#endif
955
956 VIDEO_MODE_INFORMATION *pModeToPin = iModeToPin >= 0 ? &pModes[iModeToPin] : NULL;
957 Status = vboxVidPnCreatePopulateTargetModeInfoFromLegacy(hVidPn, pVidPnInterface, VidPnTargetId, pResolutions, cResolutions, pModeToPin, NULL, TRUE, TRUE);
958 if (!NT_SUCCESS(Status))
959 {
960 AssertFailed();
961 return Status;
962 }
963
964 Status = vboxVidPnCreatePopulateSourceModeInfoFromLegacy(hVidPn, pVidPnInterface, VidPnSourceId, pModes, cModes, iModeToPin, NULL, TRUE);
965 if (!NT_SUCCESS(Status))
966 {
967 AssertFailed();
968 return Status;
969 }
970
971 return Status;
972}
973
974typedef struct VBOXVIDPNPOPRESOLUTIONENUM
975{
976 NTSTATUS Status;
977 D3DKMDT_2DREGION *pResolutions;
978 int cResolutions;
979 int cResultResolutions;
980}VBOXVIDPNPOPRESOLUTIONENUM, *PVBOXVIDPNPOPRESOLUTIONENUM;
981
982static DECLCALLBACK(BOOLEAN) vboxVidPnPopulateResolutionsFromSourceModeSetEnum(D3DKMDT_HVIDPNSOURCEMODESET hNewVidPnSourceModeSet, const DXGK_VIDPNSOURCEMODESET_INTERFACE *pVidPnSourceModeSetInterface,
983 const D3DKMDT_VIDPN_SOURCE_MODE *pNewVidPnSourceModeInfo, PVOID pContext)
984{
985 NTSTATUS Status = STATUS_SUCCESS;
986 PVBOXVIDPNPOPRESOLUTIONENUM pInfo = (PVBOXVIDPNPOPRESOLUTIONENUM)pContext;
987 Assert(pInfo->cResolutions >= pInfo->cResultResolutions);
988 Assert(pInfo->Status == STATUS_SUCCESS);
989 if (vboxWddmResolutionFind(pInfo->pResolutions, pInfo->cResultResolutions, &pNewVidPnSourceModeInfo->Format.Graphics.PrimSurfSize) < 0)
990 {
991 if (pInfo->cResultResolutions < pInfo->cResolutions)
992 {
993 pInfo->pResolutions[pInfo->cResultResolutions] = pNewVidPnSourceModeInfo->Format.Graphics.PrimSurfSize;
994 ++pInfo->cResultResolutions;
995 }
996 else
997 {
998 Status = STATUS_BUFFER_OVERFLOW;
999 }
1000 }
1001
1002 pInfo->Status = Status;
1003
1004 return Status == STATUS_SUCCESS;
1005}
1006
1007static DECLCALLBACK(BOOLEAN) vboxVidPnPopulateResolutionsFromTargetModeSetEnum(D3DKMDT_HVIDPNTARGETMODESET hNewVidPnTargetModeSet, const DXGK_VIDPNTARGETMODESET_INTERFACE *pVidPnTargetModeSetInterface,
1008 const D3DKMDT_VIDPN_TARGET_MODE *pNewVidPnTargetModeInfo, PVOID pContext)
1009{
1010 NTSTATUS Status = STATUS_SUCCESS;
1011 PVBOXVIDPNPOPRESOLUTIONENUM pInfo = (PVBOXVIDPNPOPRESOLUTIONENUM)pContext;
1012 Assert(pInfo->cResolutions >= pInfo->cResultResolutions);
1013 Assert(pInfo->Status == STATUS_SUCCESS);
1014 if (vboxWddmResolutionFind(pInfo->pResolutions, pInfo->cResultResolutions, &pNewVidPnTargetModeInfo->VideoSignalInfo.ActiveSize) < 0)
1015 {
1016 if (pInfo->cResultResolutions < pInfo->cResolutions)
1017 {
1018 pInfo->pResolutions[pInfo->cResultResolutions] = pNewVidPnTargetModeInfo->VideoSignalInfo.ActiveSize;
1019 ++pInfo->cResultResolutions;
1020 }
1021 else
1022 {
1023 Status = STATUS_BUFFER_OVERFLOW;
1024 }
1025 }
1026
1027 pInfo->Status = Status;
1028
1029 return Status == STATUS_SUCCESS;
1030}
1031
1032typedef struct VBOXVIDPNPOPMODEENUM
1033{
1034 NTSTATUS Status;
1035 VIDEO_MODE_INFORMATION *pModes;
1036 int cModes;
1037 int cResultModes;
1038}VBOXVIDPNPOPMODEENUM, *PVBOXVIDPNPOPMODEENUM;
1039
1040static DECLCALLBACK(BOOLEAN) vboxVidPnPopulateModesFromSourceModeSetEnum(D3DKMDT_HVIDPNSOURCEMODESET hNewVidPnSourceModeSet, const DXGK_VIDPNSOURCEMODESET_INTERFACE *pVidPnSourceModeSetInterface,
1041 const D3DKMDT_VIDPN_SOURCE_MODE *pNewVidPnSourceModeInfo, PVOID pContext)
1042{
1043 NTSTATUS Status = STATUS_SUCCESS;
1044 PVBOXVIDPNPOPMODEENUM pInfo = (PVBOXVIDPNPOPMODEENUM)pContext;
1045 VIDEO_MODE_INFORMATION Mode;
1046 Assert(pInfo->cModes >= pInfo->cResultModes);
1047 Assert(pInfo->Status == STATUS_SUCCESS);
1048 if (VBoxWddmFillMode(&Mode, pNewVidPnSourceModeInfo->Format.Graphics.PixelFormat,
1049 pNewVidPnSourceModeInfo->Format.Graphics.VisibleRegionSize.cx,
1050 pNewVidPnSourceModeInfo->Format.Graphics.VisibleRegionSize.cy))
1051 {
1052 if (vboxWddmVideoModeFind(pInfo->pModes, pInfo->cModes, &Mode) < 0)
1053 {
1054 if (pInfo->cResultModes < pInfo->cModes)
1055 {
1056 pInfo->pModes[pInfo->cResultModes] = Mode;
1057 ++pInfo->cResultModes;
1058 }
1059 else
1060 {
1061 Status = STATUS_BUFFER_OVERFLOW;
1062 }
1063 }
1064 }
1065 else
1066 {
1067 Assert(0);
1068 Status = STATUS_INVALID_PARAMETER;
1069 }
1070
1071 pInfo->Status = Status;
1072
1073 return Status == STATUS_SUCCESS;
1074}
1075
1076typedef struct VBOXVIDPNPOPMODETARGETENUM
1077{
1078 VBOXVIDPNPOPMODEENUM Base;
1079 VIDEO_MODE_INFORMATION *pSuperset;
1080 int cSuperset;
1081}VBOXVIDPNPOPMODETARGETENUM, *PVBOXVIDPNPOPMODETARGETENUM;
1082
1083static DECLCALLBACK(BOOLEAN) vboxVidPnPopulateModesFromTargetModeSetEnum(D3DKMDT_HVIDPNTARGETMODESET hNewVidPnTargetModeSet, const DXGK_VIDPNTARGETMODESET_INTERFACE *pVidPnTargetModeSetInterface,
1084 const D3DKMDT_VIDPN_TARGET_MODE *pNewVidPnTargetModeInfo, PVOID pContext)
1085{
1086 NTSTATUS Status = STATUS_SUCCESS;
1087 PVBOXVIDPNPOPMODETARGETENUM pInfo = (PVBOXVIDPNPOPMODETARGETENUM)pContext;
1088 Assert(pInfo->Base.cModes >= pInfo->Base.cResultModes);
1089 Assert(pInfo->Base.Status == STATUS_SUCCESS);
1090 uint32_t cResult;
1091 Status = VBoxWddmGetModesForResolution(pInfo->pSuperset, pInfo->cSuperset, -1, &pNewVidPnTargetModeInfo->VideoSignalInfo.ActiveSize,
1092 pInfo->Base.pModes + pInfo->Base.cResultModes, pInfo->Base.cModes - pInfo->Base.cResultModes, &cResult, NULL);
1093 Assert(Status == STATUS_SUCCESS);
1094 if (Status == STATUS_SUCCESS)
1095 {
1096 pInfo->Base.cResultModes += cResult;
1097 }
1098
1099 pInfo->Base.Status = Status;
1100
1101 return Status == STATUS_SUCCESS;
1102}
1103
1104static D3DKMDT_ENUMCOFUNCMODALITY_PIVOT_TYPE vboxVidPnCofuncModalityCurrentPathPivot(CONST DXGKARG_ENUMVIDPNCOFUNCMODALITY* pEnumCofuncModalityArg,
1105 D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
1106{
1107 switch (pEnumCofuncModalityArg->EnumPivotType)
1108 {
1109 case D3DKMDT_EPT_VIDPNSOURCE:
1110 if (pEnumCofuncModalityArg->EnumPivot.VidPnSourceId == VidPnSourceId)
1111 return D3DKMDT_EPT_VIDPNSOURCE;
1112 if (pEnumCofuncModalityArg->EnumPivot.VidPnSourceId == D3DDDI_ID_ALL)
1113 {
1114#ifdef DEBUG_misha
1115 AssertFailed();
1116#endif
1117 return D3DKMDT_EPT_VIDPNSOURCE;
1118 }
1119 return D3DKMDT_EPT_NOPIVOT;
1120 case D3DKMDT_EPT_VIDPNTARGET:
1121 if (pEnumCofuncModalityArg->EnumPivot.VidPnTargetId == VidPnTargetId)
1122 return D3DKMDT_EPT_VIDPNTARGET;
1123 if (pEnumCofuncModalityArg->EnumPivot.VidPnTargetId == D3DDDI_ID_ALL)
1124 {
1125#ifdef DEBUG_misha
1126 AssertFailed();
1127#endif
1128 return D3DKMDT_EPT_VIDPNTARGET;
1129 }
1130 return D3DKMDT_EPT_NOPIVOT;
1131 case D3DKMDT_EPT_SCALING:
1132 case D3DKMDT_EPT_ROTATION:
1133 case D3DKMDT_EPT_NOPIVOT:
1134 return D3DKMDT_EPT_NOPIVOT;
1135 default:
1136 AssertFailed();
1137 return D3DKMDT_EPT_NOPIVOT;
1138 }
1139}
1140
1141NTSTATUS vboxVidPnHasPinnedTargetMode(D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface,
1142 D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId, BOOLEAN *pfHas)
1143{
1144 D3DKMDT_HVIDPNTARGETMODESET hCurVidPnTargetModeSet;
1145 const DXGK_VIDPNTARGETMODESET_INTERFACE *pCurVidPnTargetModeSetInterface;
1146 *pfHas = FALSE;
1147 NTSTATUS Status = pVidPnInterface->pfnAcquireTargetModeSet(hVidPn,
1148 VidPnTargetId,
1149 &hCurVidPnTargetModeSet,
1150 &pCurVidPnTargetModeSetInterface);
1151 if (!NT_SUCCESS(Status))
1152 {
1153 AssertFailed();
1154 return Status;
1155 }
1156
1157 CONST D3DKMDT_VIDPN_TARGET_MODE* pPinnedVidPnTargetModeInfo;
1158 Status = pCurVidPnTargetModeSetInterface->pfnAcquirePinnedModeInfo(hCurVidPnTargetModeSet, &pPinnedVidPnTargetModeInfo);
1159 if (Status == STATUS_GRAPHICS_MODE_NOT_PINNED)
1160 {
1161 pPinnedVidPnTargetModeInfo = NULL;
1162 Status = STATUS_SUCCESS;
1163 }
1164 else if (!NT_SUCCESS(Status))
1165 {
1166 LOGREL(("pfnAcquirePinnedModeInfo failed Status(0x%x)", Status));
1167 AssertFailed();
1168 }
1169 else
1170 {
1171 Assert(pPinnedVidPnTargetModeInfo);
1172 NTSTATUS tmpStatus = pCurVidPnTargetModeSetInterface->pfnReleaseModeInfo(hCurVidPnTargetModeSet, pPinnedVidPnTargetModeInfo);
1173 Assert(NT_SUCCESS(tmpStatus));
1174 *pfHas = TRUE;
1175 }
1176
1177 NTSTATUS tmpStatus = pVidPnInterface->pfnReleaseTargetModeSet(hVidPn, hCurVidPnTargetModeSet);
1178 Assert(tmpStatus == STATUS_SUCCESS);
1179
1180 return Status;
1181}
1182
1183NTSTATUS vboxVidPnHasPinnedSourceMode(D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface,
1184 D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, BOOLEAN *pfHas)
1185{
1186 D3DKMDT_HVIDPNSOURCEMODESET hCurVidPnSourceModeSet;
1187 const DXGK_VIDPNSOURCEMODESET_INTERFACE *pCurVidPnSourceModeSetInterface;
1188 *pfHas = FALSE;
1189 NTSTATUS Status = pVidPnInterface->pfnAcquireSourceModeSet(hVidPn,
1190 VidPnSourceId,
1191 &hCurVidPnSourceModeSet,
1192 &pCurVidPnSourceModeSetInterface);
1193 if (!NT_SUCCESS(Status))
1194 {
1195 AssertFailed();
1196 return Status;
1197 }
1198
1199 CONST D3DKMDT_VIDPN_SOURCE_MODE* pPinnedVidPnSourceModeInfo;
1200 Status = pCurVidPnSourceModeSetInterface->pfnAcquirePinnedModeInfo(hCurVidPnSourceModeSet, &pPinnedVidPnSourceModeInfo);
1201 if (Status == STATUS_GRAPHICS_MODE_NOT_PINNED)
1202 {
1203 pPinnedVidPnSourceModeInfo = NULL;
1204 Status = STATUS_SUCCESS;
1205 }
1206 else if (!NT_SUCCESS(Status))
1207 {
1208 LOGREL(("pfnAcquirePinnedModeInfo failed Status(0x%x)", Status));
1209 AssertFailed();
1210 }
1211 else
1212 {
1213 Assert(pPinnedVidPnSourceModeInfo);
1214 NTSTATUS tmpStatus = pCurVidPnSourceModeSetInterface->pfnReleaseModeInfo(hCurVidPnSourceModeSet, pPinnedVidPnSourceModeInfo);
1215 Assert(NT_SUCCESS(tmpStatus));
1216 *pfHas = TRUE;
1217 }
1218
1219 NTSTATUS tmpStatus = pVidPnInterface->pfnReleaseSourceModeSet(hVidPn, hCurVidPnSourceModeSet);
1220 Assert(tmpStatus == STATUS_SUCCESS);
1221
1222 return Status;
1223}
1224
1225static NTSTATUS vboxVidPnCofuncModalityForPathTarget(PVBOXVIDPNCOFUNCMODALITY pCbContext,
1226 D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
1227{
1228 PVBOXMP_DEVEXT pDevExt = pCbContext->pDevExt;
1229 D3DKMDT_HVIDPN hVidPn = pCbContext->pEnumCofuncModalityArg->hConstrainingVidPn;
1230 const DXGK_VIDPN_INTERFACE* pVidPnInterface = pCbContext->pVidPnInterface;
1231 PVBOXWDDM_VIDEOMODES_INFO pInfo = &pCbContext->pInfos[VidPnTargetId];
1232
1233 D3DKMDT_HVIDPNTARGETMODESET hNewVidPnTargetModeSet = NULL;
1234 const DXGK_VIDPNTARGETMODESET_INTERFACE *pNewVidPnTargetModeSetInterface;
1235
1236 if (VidPnSourceId != VidPnTargetId || pCbContext->apPathInfos[VidPnTargetId].enmState != VBOXVIDPNPATHITEM_STATE_PRESENT)
1237 {
1238 return STATUS_SUCCESS;
1239 }
1240
1241 D3DKMDT_HVIDPNSOURCEMODESET hCurVidPnSourceModeSet;
1242 const DXGK_VIDPNSOURCEMODESET_INTERFACE *pCurVidPnSourceModeSetInterface;
1243 NTSTATUS Status = pVidPnInterface->pfnAcquireSourceModeSet(hVidPn,
1244 VidPnSourceId,
1245 &hCurVidPnSourceModeSet,
1246 &pCurVidPnSourceModeSetInterface);
1247 if (!NT_SUCCESS(Status))
1248 {
1249 AssertFailed();
1250 return Status;
1251 }
1252
1253 CONST D3DKMDT_VIDPN_SOURCE_MODE* pPinnedVidPnSourceModeInfo;
1254 Status = pCurVidPnSourceModeSetInterface->pfnAcquirePinnedModeInfo(hCurVidPnSourceModeSet, &pPinnedVidPnSourceModeInfo);
1255 if (Status == STATUS_GRAPHICS_MODE_NOT_PINNED)
1256 {
1257 pPinnedVidPnSourceModeInfo = NULL;
1258 Status = STATUS_SUCCESS;
1259 }
1260 else if (!NT_SUCCESS(Status))
1261 {
1262 LOGREL(("pfnAcquirePinnedModeInfo failed Status(0x%x)", Status));
1263 AssertFailed();
1264 }
1265 else
1266 {
1267 Assert(pPinnedVidPnSourceModeInfo);
1268 }
1269
1270 if (NT_SUCCESS(Status))
1271 {
1272 Status = pVidPnInterface->pfnCreateNewTargetModeSet(hVidPn,
1273 VidPnTargetId,
1274 &hNewVidPnTargetModeSet,
1275 &pNewVidPnTargetModeSetInterface);
1276 if (NT_SUCCESS(Status))
1277 {
1278 Assert(hNewVidPnTargetModeSet);
1279 if (VidPnSourceId == VidPnTargetId && pCbContext->apPathInfos[VidPnTargetId].enmState == VBOXVIDPNPATHITEM_STATE_PRESENT)
1280 {
1281 Assert(VidPnSourceId == VidPnTargetId);
1282
1283 for (uint32_t i = 0; i < pInfo->cResolutions; ++i)
1284 {
1285 D3DKMDT_2DREGION *pResolution = &pInfo->aResolutions[i];
1286 if (pPinnedVidPnSourceModeInfo)
1287 {
1288 if (pPinnedVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cx != pResolution->cx
1289 || pPinnedVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cy != pResolution->cy)
1290 {
1291 continue;
1292 }
1293 }
1294
1295 D3DKMDT_VIDPN_TARGET_MODE *pNewVidPnTargetModeInfo;
1296 Status = pNewVidPnTargetModeSetInterface->pfnCreateNewModeInfo(hNewVidPnTargetModeSet, &pNewVidPnTargetModeInfo);
1297 Assert(Status == STATUS_SUCCESS);
1298 if (NT_SUCCESS(Status))
1299 {
1300 Status = vboxVidPnPopulateTargetModeInfoFromLegacy(pNewVidPnTargetModeInfo, pResolution, i == pInfo->iPreferredResolution);
1301 Assert(Status == STATUS_SUCCESS);
1302 if (NT_SUCCESS(Status))
1303 {
1304 Status = pNewVidPnTargetModeSetInterface->pfnAddMode(hNewVidPnTargetModeSet, pNewVidPnTargetModeInfo);
1305 Assert(Status == STATUS_SUCCESS);
1306 if (NT_SUCCESS(Status))
1307 {
1308 /* success */
1309 continue;
1310 }
1311 }
1312
1313 NTSTATUS tmpStatus = pNewVidPnTargetModeSetInterface->pfnReleaseModeInfo(hNewVidPnTargetModeSet, pNewVidPnTargetModeInfo);
1314 Assert(tmpStatus == STATUS_SUCCESS);
1315 }
1316 /* we're here because of an error */
1317 Assert(!NT_SUCCESS(Status));
1318 break;
1319 }
1320 }
1321 }
1322 else
1323 {
1324 AssertFailed();
1325 }
1326 }
1327 else
1328 {
1329 AssertFailed();
1330 }
1331
1332 if (pPinnedVidPnSourceModeInfo)
1333 {
1334 NTSTATUS tmpStatus = pCurVidPnSourceModeSetInterface->pfnReleaseModeInfo(hCurVidPnSourceModeSet, pPinnedVidPnSourceModeInfo);
1335 Assert(tmpStatus == STATUS_SUCCESS);
1336 }
1337
1338 NTSTATUS tmpStatus = pVidPnInterface->pfnReleaseSourceModeSet(hVidPn, hCurVidPnSourceModeSet);
1339 Assert(tmpStatus == STATUS_SUCCESS);
1340
1341 if (NT_SUCCESS(Status))
1342 {
1343 Assert(hNewVidPnTargetModeSet);
1344 Status = pVidPnInterface->pfnAssignTargetModeSet(hVidPn, VidPnTargetId, hNewVidPnTargetModeSet);
1345 if (!NT_SUCCESS(Status))
1346 {
1347 WARN(("\n\n!!!!!!!\n\n pfnAssignTargetModeSet failed, Status(0x%x)", Status));
1348 tmpStatus = pVidPnInterface->pfnReleaseTargetModeSet(hVidPn, hNewVidPnTargetModeSet);
1349 Assert(tmpStatus == STATUS_SUCCESS);
1350 }
1351 }
1352
1353 return Status;
1354}
1355
1356static NTSTATUS vboxVidPnCofuncModalityForPathSource(PVBOXVIDPNCOFUNCMODALITY pCbContext,
1357 D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
1358{
1359 PVBOXMP_DEVEXT pDevExt = pCbContext->pDevExt;
1360 D3DKMDT_HVIDPN hVidPn = pCbContext->pEnumCofuncModalityArg->hConstrainingVidPn;
1361 const DXGK_VIDPN_INTERFACE* pVidPnInterface = pCbContext->pVidPnInterface;
1362 PVBOXWDDM_VIDEOMODES_INFO pInfo = &pCbContext->pInfos[VidPnTargetId];
1363 D3DKMDT_HVIDPNSOURCEMODESET hNewVidPnSourceModeSet = NULL;
1364 const DXGK_VIDPNSOURCEMODESET_INTERFACE *pNewVidPnSourceModeSetInterface;
1365
1366 if (VidPnSourceId != VidPnTargetId || pCbContext->apPathInfos[VidPnSourceId].enmState != VBOXVIDPNPATHITEM_STATE_PRESENT)
1367 {
1368 return STATUS_SUCCESS;
1369 }
1370
1371 D3DKMDT_HVIDPNTARGETMODESET hCurVidPnTargetModeSet;
1372 const DXGK_VIDPNTARGETMODESET_INTERFACE *pCurVidPnTargetModeSetInterface;
1373 NTSTATUS Status = pVidPnInterface->pfnAcquireTargetModeSet(hVidPn,
1374 VidPnTargetId,
1375 &hCurVidPnTargetModeSet,
1376 &pCurVidPnTargetModeSetInterface);
1377 if (!NT_SUCCESS(Status))
1378 {
1379 AssertFailed();
1380 return Status;
1381 }
1382
1383 CONST D3DKMDT_VIDPN_TARGET_MODE* pPinnedVidPnTargetModeInfo;
1384 Status = pCurVidPnTargetModeSetInterface->pfnAcquirePinnedModeInfo(hCurVidPnTargetModeSet, &pPinnedVidPnTargetModeInfo);
1385 if (Status == STATUS_GRAPHICS_MODE_NOT_PINNED)
1386 {
1387 pPinnedVidPnTargetModeInfo = NULL;
1388 Status = STATUS_SUCCESS;
1389 }
1390 else if (!NT_SUCCESS(Status))
1391 {
1392 LOGREL(("pfnAcquirePinnedModeInfo failed Status(0x%x)", Status));
1393 AssertFailed();
1394 }
1395 else
1396 {
1397 Assert(pPinnedVidPnTargetModeInfo);
1398 }
1399
1400 if (NT_SUCCESS(Status))
1401 {
1402 NTSTATUS Status = pVidPnInterface->pfnCreateNewSourceModeSet(hVidPn,
1403 VidPnSourceId,
1404 &hNewVidPnSourceModeSet,
1405 &pNewVidPnSourceModeSetInterface);
1406 if (NT_SUCCESS(Status))
1407 {
1408 Assert(hNewVidPnSourceModeSet);
1409 if (VidPnSourceId == VidPnTargetId && pCbContext->apPathInfos[VidPnSourceId].enmState == VBOXVIDPNPATHITEM_STATE_PRESENT)
1410 {
1411 Assert(VidPnSourceId == VidPnTargetId);
1412 for (uint32_t i = 0; i < pInfo->cModes; ++i)
1413 {
1414 VIDEO_MODE_INFORMATION *pMode = &pInfo->aModes[i];
1415 if (pPinnedVidPnTargetModeInfo)
1416 {
1417 if (pPinnedVidPnTargetModeInfo->VideoSignalInfo.ActiveSize.cx != pMode->VisScreenWidth
1418 || pPinnedVidPnTargetModeInfo->VideoSignalInfo.ActiveSize.cy != pMode->VisScreenHeight)
1419 {
1420 continue;
1421 }
1422 }
1423
1424 D3DKMDT_VIDPN_SOURCE_MODE *pNewVidPnSourceModeInfo;
1425 Status = pNewVidPnSourceModeSetInterface->pfnCreateNewModeInfo(hNewVidPnSourceModeSet, &pNewVidPnSourceModeInfo);
1426 Assert(Status == STATUS_SUCCESS);
1427 if (NT_SUCCESS(Status))
1428 {
1429 Status = vboxVidPnPopulateSourceModeInfoFromLegacy(pNewVidPnSourceModeInfo, pMode);
1430 Assert(Status == STATUS_SUCCESS);
1431 if (NT_SUCCESS(Status))
1432 {
1433 Status = pNewVidPnSourceModeSetInterface->pfnAddMode(hNewVidPnSourceModeSet, pNewVidPnSourceModeInfo);
1434 Assert(Status == STATUS_SUCCESS);
1435 if (NT_SUCCESS(Status))
1436 {
1437 /* success */
1438 continue;
1439 }
1440 }
1441
1442 NTSTATUS tmpStatus = pNewVidPnSourceModeSetInterface->pfnReleaseModeInfo(hNewVidPnSourceModeSet, pNewVidPnSourceModeInfo);
1443 Assert(tmpStatus == STATUS_SUCCESS);
1444 }
1445 /* we're here because of an error */
1446 Assert(!NT_SUCCESS(Status));
1447 break;
1448 }
1449 }
1450 }
1451 else
1452 {
1453 AssertFailed();
1454 }
1455 }
1456 else
1457 {
1458 AssertFailed();
1459 }
1460
1461 if (pPinnedVidPnTargetModeInfo)
1462 {
1463 NTSTATUS tmpStatus = pCurVidPnTargetModeSetInterface->pfnReleaseModeInfo(hCurVidPnTargetModeSet, pPinnedVidPnTargetModeInfo);
1464 Assert(tmpStatus == STATUS_SUCCESS);
1465 }
1466
1467 NTSTATUS tmpStatus = pVidPnInterface->pfnReleaseTargetModeSet(hVidPn, hCurVidPnTargetModeSet);
1468 Assert(tmpStatus == STATUS_SUCCESS);
1469
1470 if (NT_SUCCESS(Status))
1471 {
1472 Assert(hNewVidPnSourceModeSet);
1473 Status = pVidPnInterface->pfnAssignSourceModeSet(hVidPn, VidPnSourceId, hNewVidPnSourceModeSet);
1474 if (!NT_SUCCESS(Status))
1475 {
1476 WARN(("\n\n!!!!!!!\n\n pfnAssignSourceModeSet failed, Status(0x%x)", Status));
1477 tmpStatus = pVidPnInterface->pfnReleaseSourceModeSet(hVidPn, hNewVidPnSourceModeSet);
1478 Assert(tmpStatus == STATUS_SUCCESS);
1479 }
1480 }
1481
1482 return Status;
1483}
1484
1485NTSTATUS vboxVidPnCofuncModalityForPath(PVBOXVIDPNCOFUNCMODALITY pCbContext,
1486 D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
1487{
1488 PVBOXMP_DEVEXT pDevExt = pCbContext->pDevExt;
1489 D3DKMDT_HVIDPN hVidPn = pCbContext->pEnumCofuncModalityArg->hConstrainingVidPn;
1490 const DXGK_VIDPN_INTERFACE* pVidPnInterface = pCbContext->pVidPnInterface;
1491 NTSTATUS Status = STATUS_SUCCESS;
1492 pCbContext->Status = STATUS_SUCCESS;
1493 PVBOXWDDM_VIDEOMODES_INFO pInfo = &pCbContext->pInfos[VidPnTargetId];
1494
1495 D3DKMDT_ENUMCOFUNCMODALITY_PIVOT_TYPE enmPivot = vboxVidPnCofuncModalityCurrentPathPivot(pCbContext->pEnumCofuncModalityArg, VidPnSourceId, VidPnTargetId);
1496 BOOLEAN fHasPinnedMode = FALSE;
1497 Status = vboxVidPnHasPinnedTargetMode(hVidPn, pVidPnInterface, VidPnTargetId, &fHasPinnedMode);
1498 if (!NT_SUCCESS(Status))
1499 {
1500 AssertFailed();
1501 return Status;
1502 }
1503
1504 BOOLEAN fNeedUpdate = enmPivot != D3DKMDT_EPT_VIDPNTARGET && !fHasPinnedMode;
1505 if (fNeedUpdate)
1506 {
1507 Status = vboxVidPnCofuncModalityForPathTarget(pCbContext, VidPnSourceId, VidPnTargetId);
1508 }
1509
1510 if (NT_SUCCESS(Status))
1511 {
1512 fHasPinnedMode = FALSE;
1513 Status = vboxVidPnHasPinnedSourceMode(hVidPn, pVidPnInterface, VidPnSourceId, &fHasPinnedMode);
1514 if (!NT_SUCCESS(Status))
1515 {
1516 AssertFailed();
1517 return Status;
1518 }
1519
1520 fNeedUpdate = enmPivot != D3DKMDT_EPT_VIDPNSOURCE && !fHasPinnedMode;
1521 if (fNeedUpdate)
1522 {
1523 Status = vboxVidPnCofuncModalityForPathSource(pCbContext, VidPnSourceId, VidPnTargetId);
1524 }
1525 }
1526
1527 return Status;
1528}
1529
1530DECLCALLBACK(BOOLEAN) vboxVidPnCofuncModalityPathEnum(D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface,
1531 const D3DKMDT_VIDPN_PRESENT_PATH *pNewVidPnPresentPathInfo, PVOID pContext)
1532{
1533 PVBOXVIDPNCOFUNCMODALITY pCbContext = (PVBOXVIDPNCOFUNCMODALITY)pContext;
1534 D3DKMDT_VIDPN_PRESENT_PATH AdjustedPath = {0};
1535 NTSTATUS Status = STATUS_SUCCESS;
1536 bool bUpdatePath = false;
1537 AdjustedPath.VidPnSourceId = pNewVidPnPresentPathInfo->VidPnSourceId;
1538 AdjustedPath.VidPnTargetId = pNewVidPnPresentPathInfo->VidPnTargetId;
1539 AdjustedPath.ContentTransformation = pNewVidPnPresentPathInfo->ContentTransformation;
1540 AdjustedPath.CopyProtection = pNewVidPnPresentPathInfo->CopyProtection;
1541
1542 if (pNewVidPnPresentPathInfo->ContentTransformation.Scaling == D3DKMDT_VPPS_UNPINNED)
1543 {
1544 AdjustedPath.ContentTransformation.ScalingSupport.Identity = TRUE;
1545 bUpdatePath = true;
1546 }
1547
1548 if (pNewVidPnPresentPathInfo->ContentTransformation.Rotation == D3DKMDT_VPPR_UNPINNED)
1549 {
1550 AdjustedPath.ContentTransformation.RotationSupport.Identity = TRUE;
1551 bUpdatePath = true;
1552 }
1553
1554 if (bUpdatePath)
1555 {
1556 Status = pVidPnTopologyInterface->pfnUpdatePathSupportInfo(hVidPnTopology, &AdjustedPath);
1557 Assert(Status == STATUS_SUCCESS);
1558 }
1559
1560 Status = vboxVidPnCofuncModalityForPath(pCbContext, pNewVidPnPresentPathInfo->VidPnSourceId, pNewVidPnPresentPathInfo->VidPnTargetId);
1561
1562 pVidPnTopologyInterface->pfnReleasePathInfo(hVidPnTopology, pNewVidPnPresentPathInfo);
1563
1564 pCbContext->Status = Status;
1565 Assert(Status == STATUS_SUCCESS);
1566 return Status == STATUS_SUCCESS;
1567}
1568
1569static BOOLEAN vboxVidPnIsPathSupported(const D3DKMDT_VIDPN_PRESENT_PATH *pNewVidPnPresentPathInfo)
1570{
1571 if (pNewVidPnPresentPathInfo->VidPnSourceId != pNewVidPnPresentPathInfo->VidPnTargetId)
1572 {
1573 WARN(("unsupported source(%d)->target(%d) pair", pNewVidPnPresentPathInfo->VidPnSourceId, pNewVidPnPresentPathInfo->VidPnTargetId));
1574 return FALSE;
1575 }
1576
1577 /*
1578 ImportanceOrdinal does not matter for now
1579 pNewVidPnPresentPathInfo->ImportanceOrdinal
1580 */
1581
1582 if (pNewVidPnPresentPathInfo->ContentTransformation.Scaling != D3DKMDT_VPPS_UNPINNED
1583 && pNewVidPnPresentPathInfo->ContentTransformation.Scaling != D3DKMDT_VPPS_IDENTITY
1584 && pNewVidPnPresentPathInfo->ContentTransformation.Scaling != D3DKMDT_VPPS_NOTSPECIFIED)
1585 {
1586 WARN(("unsupported Scaling (%d)", pNewVidPnPresentPathInfo->ContentTransformation.Scaling));
1587 return FALSE;
1588 }
1589
1590 if ( !pNewVidPnPresentPathInfo->ContentTransformation.ScalingSupport.Identity
1591 || pNewVidPnPresentPathInfo->ContentTransformation.ScalingSupport.Centered
1592 || pNewVidPnPresentPathInfo->ContentTransformation.ScalingSupport.Stretched)
1593 {
1594 WARN(("unsupported Scaling support"));
1595 return FALSE;
1596 }
1597
1598 if (pNewVidPnPresentPathInfo->ContentTransformation.Rotation != D3DKMDT_VPPR_UNPINNED
1599 && pNewVidPnPresentPathInfo->ContentTransformation.Rotation != D3DKMDT_VPPR_IDENTITY
1600 && pNewVidPnPresentPathInfo->ContentTransformation.Rotation != D3DKMDT_VPPR_NOTSPECIFIED)
1601 {
1602 WARN(("unsupported rotation (%d)", pNewVidPnPresentPathInfo->ContentTransformation.Rotation));
1603 return FALSE;
1604 }
1605
1606 if ( !pNewVidPnPresentPathInfo->ContentTransformation.RotationSupport.Identity
1607 || pNewVidPnPresentPathInfo->ContentTransformation.RotationSupport.Rotate90
1608 || pNewVidPnPresentPathInfo->ContentTransformation.RotationSupport.Rotate180
1609 || pNewVidPnPresentPathInfo->ContentTransformation.RotationSupport.Rotate270)
1610 {
1611 WARN(("unsupported RotationSupport"));
1612 return FALSE;
1613 }
1614
1615 if (pNewVidPnPresentPathInfo->VisibleFromActiveTLOffset.cx
1616 || pNewVidPnPresentPathInfo->VisibleFromActiveTLOffset.cy)
1617 {
1618 WARN(("Non-zero TLOffset: cx(%d), cy(%d)",
1619 pNewVidPnPresentPathInfo->VisibleFromActiveTLOffset.cx,
1620 pNewVidPnPresentPathInfo->VisibleFromActiveTLOffset.cy));
1621 return FALSE;
1622 }
1623
1624 if (pNewVidPnPresentPathInfo->VisibleFromActiveBROffset.cx
1625 || pNewVidPnPresentPathInfo->VisibleFromActiveBROffset.cy)
1626 {
1627 WARN(("Non-zero TLOffset: cx(%d), cy(%d)",
1628 pNewVidPnPresentPathInfo->VisibleFromActiveBROffset.cx,
1629 pNewVidPnPresentPathInfo->VisibleFromActiveBROffset.cy));
1630 return FALSE;
1631 }
1632
1633 if (pNewVidPnPresentPathInfo->VidPnTargetColorBasis != D3DKMDT_CB_SRGB
1634 && pNewVidPnPresentPathInfo->VidPnTargetColorBasis != D3DKMDT_CB_UNINITIALIZED)
1635 {
1636 WARN(("unsupported VidPnTargetColorBasis (%d)", pNewVidPnPresentPathInfo->VidPnTargetColorBasis));
1637 return FALSE;
1638 }
1639
1640 /* channels?
1641 pNewVidPnPresentPathInfo->VidPnTargetColorCoeffDynamicRanges.FirstChannel;
1642 pNewVidPnPresentPathInfo->VidPnTargetColorCoeffDynamicRanges.SecondChannel;
1643 pNewVidPnPresentPathInfo->VidPnTargetColorCoeffDynamicRanges.ThirdChannel;
1644 we definitely not support fourth channel
1645 */
1646 if (pNewVidPnPresentPathInfo->VidPnTargetColorCoeffDynamicRanges.FourthChannel)
1647 {
1648 WARN(("Non-zero FourthChannel (%d)", pNewVidPnPresentPathInfo->VidPnTargetColorCoeffDynamicRanges.FourthChannel));
1649 return FALSE;
1650 }
1651
1652 /* Content (D3DKMDT_VPPC_GRAPHICS, _NOTSPECIFIED, _VIDEO), does not matter for now
1653 pNewVidPnPresentPathInfo->Content
1654 */
1655 /* not support copy protection for now */
1656 if (pNewVidPnPresentPathInfo->CopyProtection.CopyProtectionType != D3DKMDT_VPPMT_NOPROTECTION
1657 && pNewVidPnPresentPathInfo->CopyProtection.CopyProtectionType != D3DKMDT_VPPMT_UNINITIALIZED)
1658 {
1659 WARN(("Copy protection not supported CopyProtectionType(%d)", pNewVidPnPresentPathInfo->CopyProtection.CopyProtectionType));
1660 return FALSE;
1661 }
1662
1663 if (pNewVidPnPresentPathInfo->CopyProtection.APSTriggerBits)
1664 {
1665 WARN(("Copy protection not supported APSTriggerBits(%d)", pNewVidPnPresentPathInfo->CopyProtection.APSTriggerBits));
1666 return FALSE;
1667 }
1668
1669 D3DKMDT_VIDPN_PRESENT_PATH_COPYPROTECTION_SUPPORT tstCPSupport = {0};
1670 tstCPSupport.NoProtection = 1;
1671 if (memcmp(&tstCPSupport, &pNewVidPnPresentPathInfo->CopyProtection.CopyProtectionSupport, sizeof(tstCPSupport)))
1672 {
1673 WARN(("Copy protection support (0x%x)", *((UINT*)&pNewVidPnPresentPathInfo->CopyProtection.CopyProtectionSupport)));
1674 return FALSE;
1675 }
1676
1677 if (pNewVidPnPresentPathInfo->GammaRamp.Type != D3DDDI_GAMMARAMP_DEFAULT
1678 && pNewVidPnPresentPathInfo->GammaRamp.Type != D3DDDI_GAMMARAMP_UNINITIALIZED)
1679 {
1680 WARN(("Unsupported GammaRamp.Type (%d)", pNewVidPnPresentPathInfo->GammaRamp.Type));
1681 return FALSE;
1682 }
1683
1684 if (pNewVidPnPresentPathInfo->GammaRamp.DataSize != 0)
1685 {
1686 WARN(("Warning: non-zero GammaRamp.DataSize (%d), treating as supported", pNewVidPnPresentPathInfo->GammaRamp.DataSize));
1687 }
1688
1689 return TRUE;
1690}
1691
1692typedef struct VBOXVIDPNGETPATHSINFO
1693{
1694 NTSTATUS Status;
1695 BOOLEAN fBreakOnDisabled;
1696 BOOLEAN fDisabledFound;
1697 UINT cItems;
1698 PVBOXVIDPNPATHITEM paItems;
1699} VBOXVIDPNGETPATHSINFO, *PVBOXVIDPNGETPATHSINFO;
1700
1701static DECLCALLBACK(BOOLEAN) vboxVidPnCheckTopologyEnum(D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface,
1702 const D3DKMDT_VIDPN_PRESENT_PATH *pNewVidPnPresentPathInfo, PVOID pContext)
1703{
1704 PVBOXVIDPNGETPATHSINFO pCbContext = (PVBOXVIDPNGETPATHSINFO)pContext;
1705 NTSTATUS Status = STATUS_SUCCESS;
1706 CONST D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId = pNewVidPnPresentPathInfo->VidPnSourceId;
1707 CONST D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId = pNewVidPnPresentPathInfo->VidPnTargetId;
1708 BOOLEAN fDisabledFound = !vboxVidPnIsPathSupported(pNewVidPnPresentPathInfo);
1709 do
1710 {
1711 if (fDisabledFound)
1712 {
1713 if (pCbContext->cItems > VidPnSourceId)
1714 {
1715 pCbContext->paItems[VidPnSourceId].enmState = VBOXVIDPNPATHITEM_STATE_DISABLED;
1716 }
1717 else
1718 {
1719 AssertFailed();
1720 Status = STATUS_BUFFER_OVERFLOW;
1721 break;
1722 }
1723
1724 if (pCbContext->cItems > VidPnTargetId)
1725 {
1726 pCbContext->paItems[VidPnTargetId].enmState = VBOXVIDPNPATHITEM_STATE_DISABLED;
1727 }
1728 else
1729 {
1730 AssertFailed();
1731 Status = STATUS_BUFFER_OVERFLOW;
1732 break;
1733 }
1734
1735 break;
1736 }
1737
1738 /* VidPnSourceId == VidPnTargetId */
1739 if (pCbContext->cItems > VidPnSourceId)
1740 {
1741 if (pCbContext->paItems[VidPnSourceId].enmState != VBOXVIDPNPATHITEM_STATE_DISABLED)
1742 {
1743 Assert(pCbContext->paItems[VidPnSourceId].enmState == VBOXVIDPNPATHITEM_STATE_NOT_EXISTS);
1744 pCbContext->paItems[VidPnSourceId].enmState = VBOXVIDPNPATHITEM_STATE_PRESENT;
1745 }
1746 }
1747 else
1748 {
1749 AssertFailed();
1750 Status = STATUS_BUFFER_OVERFLOW;
1751 break;
1752 }
1753 } while (0);
1754
1755 pCbContext->fDisabledFound |= fDisabledFound;
1756 pCbContext->Status = Status;
1757 if (!NT_SUCCESS(Status))
1758 return FALSE; /* do not continue on failure */
1759
1760 return !fDisabledFound || !pCbContext->fBreakOnDisabled;
1761}
1762
1763/* we currently support only 0 -> 0, 1 -> 1, 2 -> 2 paths, AND 0 -> 0 must be present
1764 * this routine disables all paths unsupported */
1765NTSTATUS vboxVidPnCheckTopology(D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface,
1766 BOOLEAN fBreakOnDisabled, UINT cItems, PVBOXVIDPNPATHITEM paItems, BOOLEAN *pfDisabledFound)
1767{
1768 UINT i;
1769 for (i = 0; i < cItems; ++i)
1770 {
1771 paItems[i].enmState = VBOXVIDPNPATHITEM_STATE_NOT_EXISTS;
1772 }
1773 VBOXVIDPNGETPATHSINFO CbContext = {0};
1774 CbContext.Status = STATUS_SUCCESS;
1775 CbContext.fBreakOnDisabled = fBreakOnDisabled;
1776 CbContext.fDisabledFound = FALSE;
1777 CbContext.cItems = cItems;
1778 CbContext.paItems = paItems;
1779 NTSTATUS Status = vboxVidPnEnumPaths(hVidPnTopology, pVidPnTopologyInterface, vboxVidPnCheckTopologyEnum, &CbContext);
1780 if (!NT_SUCCESS(Status))
1781 {
1782 WARN(("vboxVidPnEnumPaths failed Status()0x%x\n", Status));
1783 return Status;
1784 }
1785
1786 Status = CbContext.Status;
1787 if (!NT_SUCCESS(Status))
1788 {
1789 WARN(("vboxVidPnCheckTopologyEnum returned failed Status()0x%x\n", Status));
1790 return Status;
1791 }
1792
1793 if (pfDisabledFound)
1794 *pfDisabledFound = CbContext.fDisabledFound;
1795
1796 if (!fBreakOnDisabled)
1797 {
1798 /* now check if 0->0 path is present and enabled, and if not, disable everything */
1799 if (cItems && paItems[0].enmState != VBOXVIDPNPATHITEM_STATE_PRESENT)
1800 {
1801 LOGREL(("path 0 not set to present\n"));
1802 for (i = 0; i < cItems; ++i)
1803 {
1804 if (paItems[i].enmState == VBOXVIDPNPATHITEM_STATE_PRESENT)
1805 paItems[i].enmState = VBOXVIDPNPATHITEM_STATE_DISABLED;
1806 }
1807 }
1808 }
1809
1810 return Status;
1811}
1812
1813NTSTATUS vboxVidPnEnumMonitorSourceModes(D3DKMDT_HMONITORSOURCEMODESET hMonitorSMS, CONST DXGK_MONITORSOURCEMODESET_INTERFACE *pMonitorSMSIf,
1814 PFNVBOXVIDPNENUMMONITORSOURCEMODES pfnCallback, PVOID pContext)
1815{
1816 CONST D3DKMDT_MONITOR_SOURCE_MODE *pMonitorSMI;
1817 NTSTATUS Status = pMonitorSMSIf->pfnAcquireFirstModeInfo(hMonitorSMS, &pMonitorSMI);
1818 Assert(Status == STATUS_SUCCESS || Status == STATUS_GRAPHICS_DATASET_IS_EMPTY);
1819 if (Status == STATUS_SUCCESS)
1820 {
1821 Assert(pMonitorSMI);
1822 while (1)
1823 {
1824 CONST D3DKMDT_MONITOR_SOURCE_MODE *pNextMonitorSMI;
1825 Status = pMonitorSMSIf->pfnAcquireNextModeInfo(hMonitorSMS, pMonitorSMI, &pNextMonitorSMI);
1826 if (!pfnCallback(hMonitorSMS, pMonitorSMSIf, pMonitorSMI, pContext))
1827 {
1828 Assert(Status == STATUS_SUCCESS || Status == STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET);
1829 if (Status == STATUS_SUCCESS)
1830 pMonitorSMSIf->pfnReleaseModeInfo(hMonitorSMS, pNextMonitorSMI);
1831 else if (Status == STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET)
1832 {
1833 Status = STATUS_SUCCESS;
1834 break;
1835 }
1836 else
1837 {
1838 LOGREL(("pfnAcquireNextModeInfo Failed Status(0x%x), ignored since callback returned false", Status));
1839 Status = STATUS_SUCCESS;
1840 }
1841 break;
1842 }
1843 else if (Status == STATUS_SUCCESS)
1844 pMonitorSMI = pNextMonitorSMI;
1845 else if (Status == STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET)
1846 {
1847 Status = STATUS_SUCCESS;
1848 break;
1849 }
1850 else
1851 {
1852 AssertBreakpoint();
1853 LOGREL(("pfnAcquireNextModeInfo Failed Status(0x%x)", Status));
1854 pNextMonitorSMI = NULL;
1855 break;
1856 }
1857 }
1858 }
1859 else if (Status == STATUS_GRAPHICS_DATASET_IS_EMPTY)
1860 Status = STATUS_SUCCESS;
1861 else
1862 LOGREL(("pfnAcquireFirstModeInfo failed Status(0x%x)", Status));
1863
1864 return Status;
1865}
1866
1867NTSTATUS vboxVidPnEnumSourceModes(D3DKMDT_HVIDPNSOURCEMODESET hNewVidPnSourceModeSet, const DXGK_VIDPNSOURCEMODESET_INTERFACE *pVidPnSourceModeSetInterface,
1868 PFNVBOXVIDPNENUMSOURCEMODES pfnCallback, PVOID pContext)
1869{
1870 const D3DKMDT_VIDPN_SOURCE_MODE *pNewVidPnSourceModeInfo;
1871 NTSTATUS Status = pVidPnSourceModeSetInterface->pfnAcquireFirstModeInfo(hNewVidPnSourceModeSet, &pNewVidPnSourceModeInfo);
1872 if (Status == STATUS_SUCCESS)
1873 {
1874 Assert(pNewVidPnSourceModeInfo);
1875 while (1)
1876 {
1877 const D3DKMDT_VIDPN_SOURCE_MODE *pNextVidPnSourceModeInfo;
1878 Status = pVidPnSourceModeSetInterface->pfnAcquireNextModeInfo(hNewVidPnSourceModeSet, pNewVidPnSourceModeInfo, &pNextVidPnSourceModeInfo);
1879 if (!pfnCallback(hNewVidPnSourceModeSet, pVidPnSourceModeSetInterface,
1880 pNewVidPnSourceModeInfo, pContext))
1881 {
1882 Assert(Status == STATUS_SUCCESS);
1883 if (Status == STATUS_SUCCESS)
1884 pVidPnSourceModeSetInterface->pfnReleaseModeInfo(hNewVidPnSourceModeSet, pNextVidPnSourceModeInfo);
1885 else if (Status == STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET)
1886 {
1887 Status = STATUS_SUCCESS;
1888 break;
1889 }
1890 else
1891 {
1892 LOGREL(("pfnAcquireNextModeInfo Failed Status(0x%x), ignored since callback returned false", Status));
1893 Status = STATUS_SUCCESS;
1894 }
1895
1896 break;
1897 }
1898 else if (Status == STATUS_SUCCESS)
1899 pNewVidPnSourceModeInfo = pNextVidPnSourceModeInfo;
1900 else if (Status == STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET)
1901 {
1902 Status = STATUS_SUCCESS;
1903 break;
1904 }
1905 else
1906 {
1907 AssertBreakpoint();
1908 LOGREL(("pfnAcquireNextModeInfo Failed Status(0x%x)", Status));
1909 pNewVidPnSourceModeInfo = NULL;
1910 break;
1911 }
1912 }
1913 }
1914 else if (Status == STATUS_GRAPHICS_DATASET_IS_EMPTY)
1915 Status = STATUS_SUCCESS;
1916 else
1917 LOGREL(("pfnAcquireFirstModeInfo failed Status(0x%x)", Status));
1918
1919 return Status;
1920}
1921
1922NTSTATUS vboxVidPnEnumTargetModes(D3DKMDT_HVIDPNTARGETMODESET hNewVidPnTargetModeSet, const DXGK_VIDPNTARGETMODESET_INTERFACE *pVidPnTargetModeSetInterface,
1923 PFNVBOXVIDPNENUMTARGETMODES pfnCallback, PVOID pContext)
1924{
1925 const D3DKMDT_VIDPN_TARGET_MODE *pNewVidPnTargetModeInfo;
1926 NTSTATUS Status = pVidPnTargetModeSetInterface->pfnAcquireFirstModeInfo(hNewVidPnTargetModeSet, &pNewVidPnTargetModeInfo);
1927 if (Status == STATUS_SUCCESS)
1928 {
1929 Assert(pNewVidPnTargetModeInfo);
1930 while (1)
1931 {
1932 const D3DKMDT_VIDPN_TARGET_MODE *pNextVidPnTargetModeInfo;
1933 Status = pVidPnTargetModeSetInterface->pfnAcquireNextModeInfo(hNewVidPnTargetModeSet, pNewVidPnTargetModeInfo, &pNextVidPnTargetModeInfo);
1934 if (!pfnCallback(hNewVidPnTargetModeSet, pVidPnTargetModeSetInterface,
1935 pNewVidPnTargetModeInfo, pContext))
1936 {
1937 Assert(Status == STATUS_SUCCESS);
1938 if (Status == STATUS_SUCCESS)
1939 pVidPnTargetModeSetInterface->pfnReleaseModeInfo(hNewVidPnTargetModeSet, pNextVidPnTargetModeInfo);
1940 else if (Status == STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET)
1941 {
1942 Status = STATUS_SUCCESS;
1943 break;
1944 }
1945 else
1946 {
1947 LOGREL(("pfnAcquireNextModeInfo Failed Status(0x%x), ignored since callback returned false", Status));
1948 Status = STATUS_SUCCESS;
1949 }
1950
1951 break;
1952 }
1953 else if (Status == STATUS_SUCCESS)
1954 pNewVidPnTargetModeInfo = pNextVidPnTargetModeInfo;
1955 else if (Status == STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET)
1956 {
1957 Status = STATUS_SUCCESS;
1958 break;
1959 }
1960 else
1961 {
1962 AssertBreakpoint();
1963 LOGREL(("pfnAcquireNextModeInfo Failed Status(0x%x)", Status));
1964 pNewVidPnTargetModeInfo = NULL;
1965 break;
1966 }
1967 }
1968 }
1969 else if (Status == STATUS_GRAPHICS_DATASET_IS_EMPTY)
1970 Status = STATUS_SUCCESS;
1971 else
1972 LOGREL(("pfnAcquireFirstModeInfo failed Status(0x%x)", Status));
1973
1974 return Status;
1975}
1976
1977NTSTATUS vboxVidPnEnumTargetsForSource(PVBOXMP_DEVEXT pDevExt, D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface,
1978 CONST D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId,
1979 PFNVBOXVIDPNENUMTARGETSFORSOURCE pfnCallback, PVOID pContext)
1980{
1981 SIZE_T cTgtPaths;
1982 NTSTATUS Status = pVidPnTopologyInterface->pfnGetNumPathsFromSource(hVidPnTopology, VidPnSourceId, &cTgtPaths);
1983 Assert(Status == STATUS_SUCCESS || Status == STATUS_GRAPHICS_SOURCE_NOT_IN_TOPOLOGY);
1984 if (Status == STATUS_SUCCESS)
1985 {
1986 for (SIZE_T i = 0; i < cTgtPaths; ++i)
1987 {
1988 D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId;
1989 Status = pVidPnTopologyInterface->pfnEnumPathTargetsFromSource(hVidPnTopology, VidPnSourceId, i, &VidPnTargetId);
1990 Assert(Status == STATUS_SUCCESS);
1991 if (Status == STATUS_SUCCESS)
1992 {
1993 if (!pfnCallback(pDevExt, hVidPnTopology, pVidPnTopologyInterface, VidPnSourceId, VidPnTargetId, cTgtPaths, pContext))
1994 break;
1995 }
1996 else
1997 {
1998 LOGREL(("pfnEnumPathTargetsFromSource failed Status(0x%x)", Status));
1999 break;
2000 }
2001 }
2002 }
2003 else if (Status != STATUS_GRAPHICS_SOURCE_NOT_IN_TOPOLOGY)
2004 LOGREL(("pfnGetNumPathsFromSource failed Status(0x%x)", Status));
2005
2006 return Status;
2007}
2008
2009NTSTATUS vboxVidPnEnumPaths(D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface,
2010 PFNVBOXVIDPNENUMPATHS pfnCallback, PVOID pContext)
2011{
2012 const D3DKMDT_VIDPN_PRESENT_PATH *pNewVidPnPresentPathInfo = NULL;
2013 NTSTATUS Status = pVidPnTopologyInterface->pfnAcquireFirstPathInfo(hVidPnTopology, &pNewVidPnPresentPathInfo);
2014 if (Status == STATUS_SUCCESS)
2015 {
2016 while (1)
2017 {
2018 const D3DKMDT_VIDPN_PRESENT_PATH *pNextVidPnPresentPathInfo;
2019 Status = pVidPnTopologyInterface->pfnAcquireNextPathInfo(hVidPnTopology, pNewVidPnPresentPathInfo, &pNextVidPnPresentPathInfo);
2020
2021 if (!pfnCallback(hVidPnTopology, pVidPnTopologyInterface, pNewVidPnPresentPathInfo, pContext))
2022 {
2023 if (Status == STATUS_SUCCESS)
2024 pVidPnTopologyInterface->pfnReleasePathInfo(hVidPnTopology, pNextVidPnPresentPathInfo);
2025 else
2026 {
2027 Assert(Status == STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET);
2028 if (Status != STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET)
2029 LOGREL(("pfnAcquireNextPathInfo Failed Status(0x%x), ignored since callback returned false", Status));
2030 Status = STATUS_SUCCESS;
2031 }
2032
2033 break;
2034 }
2035 else if (Status == STATUS_SUCCESS)
2036 pNewVidPnPresentPathInfo = pNextVidPnPresentPathInfo;
2037 else if (Status == STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET)
2038 {
2039 Status = STATUS_SUCCESS;
2040 break;
2041 }
2042 else
2043 {
2044 AssertBreakpoint();
2045 LOGREL(("pfnAcquireNextPathInfo Failed Status(0x%x)", Status));
2046 pNewVidPnPresentPathInfo = NULL;
2047 break;
2048 }
2049 }
2050 }
2051 else if (Status == STATUS_GRAPHICS_DATASET_IS_EMPTY)
2052 Status = STATUS_SUCCESS;
2053 else
2054 LOGREL(("pfnAcquireFirstModeInfo failed Status(0x%x)", Status));
2055
2056 return Status;
2057}
2058
2059NTSTATUS vboxVidPnSetupSourceInfo(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId, PVBOXWDDM_SOURCE pSource, CONST D3DKMDT_VIDPN_SOURCE_MODE* pVidPnSourceModeInfo, PVBOXWDDM_ALLOCATION pAllocation)
2060{
2061 vboxWddmAssignPrimary(pDevExt, pSource, pAllocation, srcId);
2062 return STATUS_SUCCESS;
2063}
2064
2065NTSTATUS vboxVidPnCommitSourceMode(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId, CONST D3DKMDT_VIDPN_SOURCE_MODE* pVidPnSourceModeInfo, PVBOXWDDM_ALLOCATION pAllocation)
2066{
2067 Assert(srcId < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays);
2068 if (srcId < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays)
2069 {
2070 PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[srcId];
2071 return vboxVidPnSetupSourceInfo(pDevExt, srcId, pSource, pVidPnSourceModeInfo, pAllocation);
2072 }
2073
2074 LOGREL(("invalid srcId (%d), cSources(%d)", srcId, VBoxCommonFromDeviceExt(pDevExt)->cDisplays));
2075 return STATUS_INVALID_PARAMETER;
2076}
2077
2078typedef struct VBOXVIDPNCOMMITTARGETMODE
2079{
2080 NTSTATUS Status;
2081 D3DKMDT_HVIDPN hVidPn;
2082 const DXGK_VIDPN_INTERFACE* pVidPnInterface;
2083} VBOXVIDPNCOMMITTARGETMODE;
2084
2085DECLCALLBACK(BOOLEAN) vboxVidPnCommitTargetModeEnum(PVBOXMP_DEVEXT pDevExt, D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface,
2086 CONST D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId, SIZE_T cTgtPaths, PVOID pContext)
2087{
2088 VBOXVIDPNCOMMITTARGETMODE *pInfo = (VBOXVIDPNCOMMITTARGETMODE*)pContext;
2089 Assert(cTgtPaths <= (SIZE_T)VBoxCommonFromDeviceExt(pDevExt)->cDisplays);
2090 D3DKMDT_HVIDPNTARGETMODESET hVidPnTargetModeSet;
2091 CONST DXGK_VIDPNTARGETMODESET_INTERFACE* pVidPnTargetModeSetInterface;
2092 NTSTATUS Status = pInfo->pVidPnInterface->pfnAcquireTargetModeSet(pInfo->hVidPn, VidPnTargetId, &hVidPnTargetModeSet, &pVidPnTargetModeSetInterface);
2093 Assert(Status == STATUS_SUCCESS);
2094 if (Status == STATUS_SUCCESS)
2095 {
2096 CONST D3DKMDT_VIDPN_TARGET_MODE* pPinnedVidPnTargetModeInfo;
2097 Status = pVidPnTargetModeSetInterface->pfnAcquirePinnedModeInfo(hVidPnTargetModeSet, &pPinnedVidPnTargetModeInfo);
2098 Assert(Status == STATUS_SUCCESS);
2099 if (Status == STATUS_SUCCESS)
2100 {
2101 VBOXWDDM_TARGET *pTarget = &pDevExt->aTargets[VidPnTargetId];
2102 if (pTarget->HeightVisible != pPinnedVidPnTargetModeInfo->VideoSignalInfo.ActiveSize.cy
2103 || pTarget->HeightTotal != pPinnedVidPnTargetModeInfo->VideoSignalInfo.TotalSize.cy)
2104 {
2105 pTarget->HeightVisible = pPinnedVidPnTargetModeInfo->VideoSignalInfo.ActiveSize.cy;
2106 pTarget->HeightTotal = pPinnedVidPnTargetModeInfo->VideoSignalInfo.TotalSize.cy;
2107 pTarget->ScanLineState = 0;
2108 }
2109 pVidPnTargetModeSetInterface->pfnReleaseModeInfo(hVidPnTargetModeSet, pPinnedVidPnTargetModeInfo);
2110 }
2111
2112 pInfo->pVidPnInterface->pfnReleaseTargetModeSet(pInfo->hVidPn, hVidPnTargetModeSet);
2113 }
2114 else
2115 LOGREL(("pfnAcquireTargetModeSet failed Status(0x%x)", Status));
2116
2117 pInfo->Status = Status;
2118 return Status == STATUS_SUCCESS;
2119}
2120
2121NTSTATUS vboxVidPnCommitSourceModeForSrcId(PVBOXMP_DEVEXT pDevExt, const D3DKMDT_HVIDPN hDesiredVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId, PVBOXWDDM_ALLOCATION pAllocation)
2122{
2123 D3DKMDT_HVIDPNSOURCEMODESET hCurVidPnSourceModeSet;
2124 const DXGK_VIDPNSOURCEMODESET_INTERFACE *pCurVidPnSourceModeSetInterface;
2125
2126 NTSTATUS Status = pVidPnInterface->pfnAcquireSourceModeSet(hDesiredVidPn,
2127 srcId,
2128 &hCurVidPnSourceModeSet,
2129 &pCurVidPnSourceModeSetInterface);
2130 Assert(Status == STATUS_SUCCESS);
2131 if (Status == STATUS_SUCCESS)
2132 {
2133 CONST D3DKMDT_VIDPN_SOURCE_MODE* pPinnedVidPnSourceModeInfo;
2134 Status = pCurVidPnSourceModeSetInterface->pfnAcquirePinnedModeInfo(hCurVidPnSourceModeSet, &pPinnedVidPnSourceModeInfo);
2135 Assert(Status == STATUS_SUCCESS || Status == STATUS_GRAPHICS_MODE_NOT_PINNED);
2136 if (Status == STATUS_SUCCESS)
2137 {
2138 Assert(pPinnedVidPnSourceModeInfo);
2139 Status = vboxVidPnCommitSourceMode(pDevExt, srcId, pPinnedVidPnSourceModeInfo, pAllocation);
2140 Assert(Status == STATUS_SUCCESS);
2141 if (Status == STATUS_SUCCESS)
2142 {
2143 D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology;
2144 CONST DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface;
2145 Status = pVidPnInterface->pfnGetTopology(hDesiredVidPn, &hVidPnTopology, &pVidPnTopologyInterface);
2146 Assert(Status == STATUS_SUCCESS);
2147 if (Status == STATUS_SUCCESS)
2148 {
2149 VBOXVIDPNCOMMITTARGETMODE TgtModeInfo = {0};
2150 TgtModeInfo.Status = STATUS_SUCCESS; /* <- to ensure we're succeeded if no targets are set */
2151 TgtModeInfo.hVidPn = hDesiredVidPn;
2152 TgtModeInfo.pVidPnInterface = pVidPnInterface;
2153 Status = vboxVidPnEnumTargetsForSource(pDevExt, hVidPnTopology, pVidPnTopologyInterface,
2154 srcId,
2155 vboxVidPnCommitTargetModeEnum, &TgtModeInfo);
2156 Assert(Status == STATUS_SUCCESS || Status == STATUS_GRAPHICS_SOURCE_NOT_IN_TOPOLOGY);
2157 if (Status == STATUS_SUCCESS)
2158 {
2159 Status = TgtModeInfo.Status;
2160 Assert(Status == STATUS_SUCCESS);
2161 }
2162 else if (Status == STATUS_GRAPHICS_SOURCE_NOT_IN_TOPOLOGY)
2163 {
2164 Status = STATUS_SUCCESS;
2165 }
2166 else
2167 LOGREL(("vboxVidPnEnumTargetsForSource failed Status(0x%x)", Status));
2168 }
2169 else
2170 LOGREL(("pfnGetTopology failed Status(0x%x)", Status));
2171 }
2172 else
2173 LOGREL(("vboxVidPnCommitSourceMode failed Status(0x%x)", Status));
2174 /* release */
2175 pCurVidPnSourceModeSetInterface->pfnReleaseModeInfo(hCurVidPnSourceModeSet, pPinnedVidPnSourceModeInfo);
2176 }
2177 else if (Status == STATUS_GRAPHICS_MODE_NOT_PINNED)
2178 {
2179 Status = vboxVidPnCommitSourceMode(pDevExt, srcId, NULL, pAllocation);
2180 Assert(Status == STATUS_SUCCESS);
2181 }
2182 else
2183 LOGREL(("pfnAcquirePinnedModeInfo failed Status(0x%x)", Status));
2184
2185 pVidPnInterface->pfnReleaseSourceModeSet(hDesiredVidPn, hCurVidPnSourceModeSet);
2186 }
2187 else
2188 {
2189 LOGREL(("pfnAcquireSourceModeSet failed Status(0x%x)", Status));
2190 }
2191
2192 return Status;
2193}
2194
2195DECLCALLBACK(BOOLEAN) vboxVidPnCommitPathEnum(D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface,
2196 const D3DKMDT_VIDPN_PRESENT_PATH *pVidPnPresentPathInfo, PVOID pContext)
2197{
2198 NTSTATUS Status = STATUS_SUCCESS;
2199 PVBOXVIDPNCOMMIT pCommitInfo = (PVBOXVIDPNCOMMIT)pContext;
2200 PVBOXMP_DEVEXT pDevExt = pCommitInfo->pDevExt;
2201 const D3DKMDT_HVIDPN hDesiredVidPn = pCommitInfo->pCommitVidPnArg->hFunctionalVidPn;
2202 const DXGK_VIDPN_INTERFACE* pVidPnInterface = pCommitInfo->pVidPnInterface;
2203
2204 if (pCommitInfo->pCommitVidPnArg->AffectedVidPnSourceId == D3DDDI_ID_ALL
2205 || pCommitInfo->pCommitVidPnArg->AffectedVidPnSourceId == pVidPnPresentPathInfo->VidPnSourceId)
2206 {
2207 Status = vboxVidPnCommitSourceModeForSrcId(pDevExt, hDesiredVidPn, pVidPnInterface, pVidPnPresentPathInfo->VidPnSourceId, (PVBOXWDDM_ALLOCATION)pCommitInfo->pCommitVidPnArg->hPrimaryAllocation);
2208 Assert(Status == STATUS_SUCCESS);
2209 if (Status != STATUS_SUCCESS)
2210 LOGREL(("vboxVidPnCommitSourceModeForSrcId failed Status(0x%x)", Status));
2211 }
2212
2213 pCommitInfo->Status = Status;
2214 pVidPnTopologyInterface->pfnReleasePathInfo(hVidPnTopology, pVidPnPresentPathInfo);
2215 return Status == STATUS_SUCCESS;
2216}
2217
2218#define VBOXVIDPNDUMP_STRCASE(_t) \
2219 case _t: return #_t;
2220#define VBOXVIDPNDUMP_STRCASE_UNKNOWN() \
2221 default: Assert(0); return "Unknown";
2222
2223#define VBOXVIDPNDUMP_STRFLAGS(_v, _t) \
2224 if ((_v)._t return #_t;
2225
2226const char* vboxVidPnDumpStrImportance(D3DKMDT_VIDPN_PRESENT_PATH_IMPORTANCE ImportanceOrdinal)
2227{
2228 switch (ImportanceOrdinal)
2229 {
2230 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPI_UNINITIALIZED);
2231 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPI_PRIMARY);
2232 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPI_SECONDARY);
2233 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPI_TERTIARY);
2234 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPI_QUATERNARY);
2235 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPI_QUINARY);
2236 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPI_SENARY);
2237 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPI_SEPTENARY);
2238 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPI_OCTONARY);
2239 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPI_NONARY);
2240 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPI_DENARY);
2241 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2242 }
2243}
2244
2245const char* vboxVidPnDumpStrScaling(D3DKMDT_VIDPN_PRESENT_PATH_SCALING Scaling)
2246{
2247 switch (Scaling)
2248 {
2249 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPS_UNINITIALIZED);
2250 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPS_IDENTITY);
2251 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPS_CENTERED);
2252 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPS_STRETCHED);
2253 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPS_UNPINNED);
2254 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPS_NOTSPECIFIED);
2255 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2256 }
2257}
2258
2259const char* vboxVidPnDumpStrRotation(D3DKMDT_VIDPN_PRESENT_PATH_ROTATION Rotation)
2260{
2261 switch (Rotation)
2262 {
2263 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPR_UNINITIALIZED);
2264 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPR_IDENTITY);
2265 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPR_ROTATE90);
2266 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPR_ROTATE180);
2267 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPR_ROTATE270);
2268 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPR_UNPINNED);
2269 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPR_NOTSPECIFIED);
2270 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2271 }
2272}
2273
2274const char* vboxVidPnDumpStrColorBasis(const D3DKMDT_COLOR_BASIS ColorBasis)
2275{
2276 switch (ColorBasis)
2277 {
2278 VBOXVIDPNDUMP_STRCASE(D3DKMDT_CB_UNINITIALIZED);
2279 VBOXVIDPNDUMP_STRCASE(D3DKMDT_CB_INTENSITY);
2280 VBOXVIDPNDUMP_STRCASE(D3DKMDT_CB_SRGB);
2281 VBOXVIDPNDUMP_STRCASE(D3DKMDT_CB_SCRGB);
2282 VBOXVIDPNDUMP_STRCASE(D3DKMDT_CB_YCBCR);
2283 VBOXVIDPNDUMP_STRCASE(D3DKMDT_CB_YPBPR);
2284 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2285 }
2286}
2287
2288const char* vboxVidPnDumpStrPvam(D3DKMDT_PIXEL_VALUE_ACCESS_MODE PixelValueAccessMode)
2289{
2290 switch (PixelValueAccessMode)
2291 {
2292 VBOXVIDPNDUMP_STRCASE(D3DKMDT_PVAM_UNINITIALIZED);
2293 VBOXVIDPNDUMP_STRCASE(D3DKMDT_PVAM_DIRECT);
2294 VBOXVIDPNDUMP_STRCASE(D3DKMDT_PVAM_PRESETPALETTE);
2295 VBOXVIDPNDUMP_STRCASE(D3DKMDT_PVAM_SETTABLEPALETTE);
2296 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2297 }
2298}
2299
2300
2301
2302const char* vboxVidPnDumpStrContent(D3DKMDT_VIDPN_PRESENT_PATH_CONTENT Content)
2303{
2304 switch (Content)
2305 {
2306 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPC_UNINITIALIZED);
2307 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPC_GRAPHICS);
2308 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPC_VIDEO);
2309 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPC_NOTSPECIFIED);
2310 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2311 }
2312}
2313
2314const char* vboxVidPnDumpStrCopyProtectionType(D3DKMDT_VIDPN_PRESENT_PATH_COPYPROTECTION_TYPE CopyProtectionType)
2315{
2316 switch (CopyProtectionType)
2317 {
2318 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPMT_UNINITIALIZED);
2319 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPMT_NOPROTECTION);
2320 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPMT_MACROVISION_APSTRIGGER);
2321 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPMT_MACROVISION_FULLSUPPORT);
2322 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2323 }
2324}
2325
2326const char* vboxVidPnDumpStrGammaRampType(D3DDDI_GAMMARAMP_TYPE Type)
2327{
2328 switch (Type)
2329 {
2330 VBOXVIDPNDUMP_STRCASE(D3DDDI_GAMMARAMP_UNINITIALIZED);
2331 VBOXVIDPNDUMP_STRCASE(D3DDDI_GAMMARAMP_DEFAULT);
2332 VBOXVIDPNDUMP_STRCASE(D3DDDI_GAMMARAMP_RGB256x3x16);
2333 VBOXVIDPNDUMP_STRCASE(D3DDDI_GAMMARAMP_DXGI_1);
2334 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2335 }
2336}
2337
2338const char* vboxVidPnDumpStrSourceModeType(D3DKMDT_VIDPN_SOURCE_MODE_TYPE Type)
2339{
2340 switch (Type)
2341 {
2342 VBOXVIDPNDUMP_STRCASE(D3DKMDT_RMT_UNINITIALIZED);
2343 VBOXVIDPNDUMP_STRCASE(D3DKMDT_RMT_GRAPHICS);
2344 VBOXVIDPNDUMP_STRCASE(D3DKMDT_RMT_TEXT);
2345 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2346 }
2347}
2348
2349const char* vboxVidPnDumpStrScanLineOrdering(D3DDDI_VIDEO_SIGNAL_SCANLINE_ORDERING ScanLineOrdering)
2350{
2351 switch (ScanLineOrdering)
2352 {
2353 VBOXVIDPNDUMP_STRCASE(D3DDDI_VSSLO_UNINITIALIZED);
2354 VBOXVIDPNDUMP_STRCASE(D3DDDI_VSSLO_PROGRESSIVE);
2355 VBOXVIDPNDUMP_STRCASE(D3DDDI_VSSLO_INTERLACED_UPPERFIELDFIRST);
2356 VBOXVIDPNDUMP_STRCASE(D3DDDI_VSSLO_INTERLACED_LOWERFIELDFIRST);
2357 VBOXVIDPNDUMP_STRCASE(D3DDDI_VSSLO_OTHER);
2358 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2359 }
2360}
2361
2362const char* vboxVidPnDumpStrCFMPivotType(D3DKMDT_ENUMCOFUNCMODALITY_PIVOT_TYPE EnumPivotType)
2363{
2364 switch (EnumPivotType)
2365 {
2366 VBOXVIDPNDUMP_STRCASE(D3DKMDT_EPT_UNINITIALIZED);
2367 VBOXVIDPNDUMP_STRCASE(D3DKMDT_EPT_VIDPNSOURCE);
2368 VBOXVIDPNDUMP_STRCASE(D3DKMDT_EPT_VIDPNTARGET);
2369 VBOXVIDPNDUMP_STRCASE(D3DKMDT_EPT_SCALING);
2370 VBOXVIDPNDUMP_STRCASE(D3DKMDT_EPT_ROTATION);
2371 VBOXVIDPNDUMP_STRCASE(D3DKMDT_EPT_NOPIVOT);
2372 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2373 }
2374}
2375
2376const char* vboxVidPnDumpStrModePreference(D3DKMDT_MODE_PREFERENCE Preference)
2377{
2378 switch (Preference)
2379 {
2380 VBOXVIDPNDUMP_STRCASE(D3DKMDT_MP_UNINITIALIZED);
2381 VBOXVIDPNDUMP_STRCASE(D3DKMDT_MP_PREFERRED);
2382 VBOXVIDPNDUMP_STRCASE(D3DKMDT_MP_NOTPREFERRED);
2383 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2384 }
2385}
2386
2387const char* vboxVidPnDumpStrSignalStandard(D3DKMDT_VIDEO_SIGNAL_STANDARD VideoStandard)
2388{
2389 switch (VideoStandard)
2390 {
2391 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_UNINITIALIZED);
2392 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_VESA_DMT);
2393 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_VESA_GTF);
2394 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_VESA_CVT);
2395 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_IBM);
2396 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_APPLE);
2397 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_NTSC_M);
2398 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_NTSC_J);
2399 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_NTSC_443);
2400 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_PAL_B);
2401 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_PAL_B1);
2402 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_PAL_G);
2403 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_PAL_H);
2404 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_PAL_I);
2405 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_PAL_D);
2406 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_PAL_N);
2407 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_PAL_NC);
2408 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_SECAM_B);
2409 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_SECAM_D);
2410 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_SECAM_G);
2411 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_SECAM_H);
2412 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_SECAM_K);
2413 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_SECAM_K1);
2414 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_SECAM_L);
2415 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_SECAM_L1);
2416 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_EIA_861);
2417 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_EIA_861A);
2418 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_EIA_861B);
2419 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_PAL_K);
2420 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_PAL_K1);
2421 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_PAL_L);
2422 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_PAL_M);
2423 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_OTHER);
2424 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2425 }
2426}
2427
2428const char* vboxVidPnDumpStrPixFormat(D3DDDIFORMAT PixelFormat)
2429{
2430 switch (PixelFormat)
2431 {
2432 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_UNKNOWN);
2433 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_R8G8B8);
2434 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A8R8G8B8);
2435 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_X8R8G8B8);
2436 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_R5G6B5);
2437 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_X1R5G5B5);
2438 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A1R5G5B5);
2439 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A4R4G4B4);
2440 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_R3G3B2);
2441 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A8);
2442 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A8R3G3B2);
2443 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_X4R4G4B4);
2444 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A2B10G10R10);
2445 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A8B8G8R8);
2446 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_X8B8G8R8);
2447 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_G16R16);
2448 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A2R10G10B10);
2449 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A16B16G16R16);
2450 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A8P8);
2451 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_R32F);
2452 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_G32R32F);
2453 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A32B32G32R32F);
2454 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_CxV8U8);
2455 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A1);
2456 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_BINARYBUFFER);
2457 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_VERTEXDATA);
2458 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_INDEX16);
2459 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_INDEX32);
2460 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_Q16W16V16U16);
2461 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_MULTI2_ARGB8);
2462 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_R16F);
2463 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_G16R16F);
2464 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A16B16G16R16F);
2465 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_D32F_LOCKABLE);
2466 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_D24FS8);
2467 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_D32_LOCKABLE);
2468 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_S8_LOCKABLE);
2469 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_S1D15);
2470 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_S8D24);
2471 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_X8D24);
2472 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_X4S4D24);
2473 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_L16);
2474 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_UYVY);
2475 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_R8G8_B8G8);
2476 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_YUY2);
2477 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_G8R8_G8B8);
2478 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_DXT1);
2479 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_DXT2);
2480 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_DXT3);
2481 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_DXT4);
2482 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_DXT5);
2483 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_D16_LOCKABLE);
2484 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_D32);
2485 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_D15S1);
2486 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_D24S8);
2487 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_D24X8);
2488 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_D24X4S4);
2489 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_D16);
2490 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_P8);
2491 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_L8);
2492 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A8L8);
2493 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A4L4);
2494 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_V8U8);
2495 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_L6V5U5);
2496 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_X8L8V8U8);
2497 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_Q8W8V8U8);
2498 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_V16U16);
2499 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_W11V11U10);
2500 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A2W10V10U10);
2501 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2502 }
2503}
2504
2505void vboxVidPnDumpCopyProtectoin(const char *pPrefix, const D3DKMDT_VIDPN_PRESENT_PATH_COPYPROTECTION *pCopyProtection, const char *pSuffix)
2506{
2507 LOGREL_EXACT(("%sType(%s), TODO%s", pPrefix,
2508 vboxVidPnDumpStrCopyProtectionType(pCopyProtection->CopyProtectionType), pSuffix));
2509}
2510
2511
2512void vboxVidPnDumpPathTransformation(const D3DKMDT_VIDPN_PRESENT_PATH_TRANSFORMATION *pContentTransformation)
2513{
2514 LOGREL_EXACT((" --Transformation: Scaling(%s), ScalingSupport(%d), Rotation(%s), RotationSupport(%d)--",
2515 vboxVidPnDumpStrScaling(pContentTransformation->Scaling), pContentTransformation->ScalingSupport,
2516 vboxVidPnDumpStrRotation(pContentTransformation->Rotation), pContentTransformation->RotationSupport));
2517}
2518
2519void vboxVidPnDumpRegion(const char *pPrefix, const D3DKMDT_2DREGION *pRegion, const char *pSuffix)
2520{
2521 LOGREL_EXACT(("%s%dX%d%s", pPrefix, pRegion->cx, pRegion->cy, pSuffix));
2522}
2523
2524void vboxVidPnDumpRational(const char *pPrefix, const D3DDDI_RATIONAL *pRational, const char *pSuffix)
2525{
2526 LOGREL_EXACT(("%s%d/%d=%d%s", pPrefix, pRational->Numerator, pRational->Denominator, pRational->Numerator/pRational->Denominator, pSuffix));
2527}
2528
2529void vboxVidPnDumpRanges(const char *pPrefix, const D3DKMDT_COLOR_COEFF_DYNAMIC_RANGES *pDynamicRanges, const char *pSuffix)
2530{
2531 LOGREL_EXACT(("%sFirstChannel(%d), SecondChannel(%d), ThirdChannel(%d), FourthChannel(%d)%s", pPrefix,
2532 pDynamicRanges->FirstChannel,
2533 pDynamicRanges->SecondChannel,
2534 pDynamicRanges->ThirdChannel,
2535 pDynamicRanges->FourthChannel,
2536 pSuffix));
2537}
2538
2539void vboxVidPnDumpGammaRamp(const char *pPrefix, const D3DKMDT_GAMMA_RAMP *pGammaRamp, const char *pSuffix)
2540{
2541 LOGREL_EXACT(("%sType(%s), DataSize(%d), TODO: dump the rest%s", pPrefix,
2542 vboxVidPnDumpStrGammaRampType(pGammaRamp->Type), pGammaRamp->DataSize,
2543 pSuffix));
2544}
2545
2546void vboxVidPnDumpSourceMode(const char *pPrefix, const D3DKMDT_VIDPN_SOURCE_MODE* pVidPnSourceModeInfo, const char *pSuffix)
2547{
2548 LOGREL_EXACT(("%sType(%s), ", pPrefix, vboxVidPnDumpStrSourceModeType(pVidPnSourceModeInfo->Type)));
2549 vboxVidPnDumpRegion("surf(", &pVidPnSourceModeInfo->Format.Graphics.PrimSurfSize, "), ");
2550 vboxVidPnDumpRegion("vis(", &pVidPnSourceModeInfo->Format.Graphics.VisibleRegionSize, "), ");
2551 LOGREL_EXACT(("stride(%d), ", pVidPnSourceModeInfo->Format.Graphics.Stride));
2552 LOGREL_EXACT(("format(%s), ", vboxVidPnDumpStrPixFormat(pVidPnSourceModeInfo->Format.Graphics.PixelFormat)));
2553 LOGREL_EXACT(("clrBasis(%s), ", vboxVidPnDumpStrColorBasis(pVidPnSourceModeInfo->Format.Graphics.ColorBasis)));
2554 LOGREL_EXACT(("pvam(%s)%s", vboxVidPnDumpStrPvam(pVidPnSourceModeInfo->Format.Graphics.PixelValueAccessMode), pSuffix));
2555}
2556
2557void vboxVidPnDumpSignalInfo(const char *pPrefix, const D3DKMDT_VIDEO_SIGNAL_INFO *pVideoSignalInfo, const char *pSuffix)
2558{
2559 LOGREL_EXACT(("%sVStd(%s), ", pPrefix, vboxVidPnDumpStrSignalStandard(pVideoSignalInfo->VideoStandard)));
2560 vboxVidPnDumpRegion("totSize(", &pVideoSignalInfo->TotalSize, "), ");
2561 vboxVidPnDumpRegion("activeSize(", &pVideoSignalInfo->ActiveSize, "), ");
2562 vboxVidPnDumpRational("VSynch(", &pVideoSignalInfo->VSyncFreq, "), ");
2563 LOGREL_EXACT(("PixelRate(%d), ScanLineOrdering(%s)%s", pVideoSignalInfo->PixelRate, vboxVidPnDumpStrScanLineOrdering(pVideoSignalInfo->ScanLineOrdering), pSuffix));
2564}
2565
2566void vboxVidPnDumpTargetMode(const char *pPrefix, const D3DKMDT_VIDPN_TARGET_MODE* CONST pVidPnTargetModeInfo, const char *pSuffix)
2567{
2568 LOGREL_EXACT(("%s", pPrefix));
2569 vboxVidPnDumpSignalInfo("VSI: ", &pVidPnTargetModeInfo->VideoSignalInfo, ", ");
2570 LOGREL_EXACT(("Preference(%s)%s", vboxVidPnDumpStrModePreference(pVidPnTargetModeInfo->Preference), pSuffix));
2571}
2572
2573void vboxVidPnDumpPinnedSourceMode(const D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId)
2574{
2575 D3DKMDT_HVIDPNSOURCEMODESET hCurVidPnSourceModeSet;
2576 const DXGK_VIDPNSOURCEMODESET_INTERFACE *pCurVidPnSourceModeSetInterface;
2577
2578 NTSTATUS Status = pVidPnInterface->pfnAcquireSourceModeSet(hVidPn,
2579 VidPnSourceId,
2580 &hCurVidPnSourceModeSet,
2581 &pCurVidPnSourceModeSetInterface);
2582 Assert(Status == STATUS_SUCCESS);
2583 if (Status == STATUS_SUCCESS)
2584 {
2585 CONST D3DKMDT_VIDPN_SOURCE_MODE* pPinnedVidPnSourceModeInfo;
2586
2587 Status = pCurVidPnSourceModeSetInterface->pfnAcquirePinnedModeInfo(hCurVidPnSourceModeSet, &pPinnedVidPnSourceModeInfo);
2588 Assert(Status == STATUS_SUCCESS || Status == STATUS_GRAPHICS_MODE_NOT_PINNED);
2589 if (Status == STATUS_SUCCESS)
2590 {
2591 vboxVidPnDumpSourceMode("Source Pinned: ", pPinnedVidPnSourceModeInfo, "\n");
2592 pCurVidPnSourceModeSetInterface->pfnReleaseModeInfo(hCurVidPnSourceModeSet, pPinnedVidPnSourceModeInfo);
2593 }
2594 else if (Status == STATUS_GRAPHICS_MODE_NOT_PINNED)
2595 {
2596 LOGREL_EXACT(("Source NOT Pinned\n"));
2597 }
2598 else
2599 {
2600 LOGREL_EXACT(("ERROR getting piined Source Mode(0x%x)\n", Status));
2601 }
2602 pVidPnInterface->pfnReleaseSourceModeSet(hVidPn, hCurVidPnSourceModeSet);
2603 }
2604 else
2605 {
2606 LOGREL_EXACT(("ERROR getting SourceModeSet(0x%x)\n", Status));
2607 }
2608}
2609
2610
2611DECLCALLBACK(BOOLEAN) vboxVidPnDumpSourceModeSetEnum(D3DKMDT_HVIDPNSOURCEMODESET hNewVidPnSourceModeSet, const DXGK_VIDPNSOURCEMODESET_INTERFACE *pVidPnSourceModeSetInterface,
2612 const D3DKMDT_VIDPN_SOURCE_MODE *pNewVidPnSourceModeInfo, PVOID pContext)
2613{
2614 vboxVidPnDumpSourceMode("SourceMode: ", pNewVidPnSourceModeInfo, "\n");
2615 return TRUE;
2616}
2617
2618void vboxVidPnDumpSourceModeSet(PVBOXMP_DEVEXT pDevExt, const D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId)
2619{
2620 LOGREL_EXACT((" >>>+++SourceMode Set for Source(%d)+++\n", VidPnSourceId));
2621 D3DKMDT_HVIDPNSOURCEMODESET hCurVidPnSourceModeSet;
2622 const DXGK_VIDPNSOURCEMODESET_INTERFACE *pCurVidPnSourceModeSetInterface;
2623
2624 NTSTATUS Status = pVidPnInterface->pfnAcquireSourceModeSet(hVidPn,
2625 VidPnSourceId,
2626 &hCurVidPnSourceModeSet,
2627 &pCurVidPnSourceModeSetInterface);
2628 Assert(Status == STATUS_SUCCESS);
2629 if (Status == STATUS_SUCCESS)
2630 {
2631
2632 Status = vboxVidPnEnumSourceModes(hCurVidPnSourceModeSet, pCurVidPnSourceModeSetInterface,
2633 vboxVidPnDumpSourceModeSetEnum, NULL);
2634 Assert(Status == STATUS_SUCCESS);
2635 if (Status != STATUS_SUCCESS)
2636 {
2637 LOGREL_EXACT(("ERROR enumerating Source Modes(0x%x)\n", Status));
2638 }
2639 pVidPnInterface->pfnReleaseSourceModeSet(hVidPn, hCurVidPnSourceModeSet);
2640 }
2641 else
2642 {
2643 LOGREL_EXACT(("ERROR getting SourceModeSet for Source(%d), Status(0x%x)\n", VidPnSourceId, Status));
2644 }
2645
2646 LOGREL_EXACT((" <<<+++End Of SourceMode Set for Source(%d)+++", VidPnSourceId));
2647}
2648
2649DECLCALLBACK(BOOLEAN) vboxVidPnDumpTargetModeSetEnum(D3DKMDT_HVIDPNTARGETMODESET hNewVidPnTargetModeSet, const DXGK_VIDPNTARGETMODESET_INTERFACE *pVidPnTargetModeSetInterface,
2650 const D3DKMDT_VIDPN_TARGET_MODE *pNewVidPnTargetModeInfo, PVOID pContext)
2651{
2652 vboxVidPnDumpTargetMode("TargetMode: ", pNewVidPnTargetModeInfo, "\n");
2653 return TRUE;
2654}
2655
2656void vboxVidPnDumpTargetModeSet(PVBOXMP_DEVEXT pDevExt, const D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
2657{
2658 LOGREL_EXACT((" >>>---TargetMode Set for Target(%d)---\n", VidPnTargetId));
2659 D3DKMDT_HVIDPNTARGETMODESET hCurVidPnTargetModeSet;
2660 const DXGK_VIDPNTARGETMODESET_INTERFACE *pCurVidPnTargetModeSetInterface;
2661
2662 NTSTATUS Status = pVidPnInterface->pfnAcquireTargetModeSet(hVidPn,
2663 VidPnTargetId,
2664 &hCurVidPnTargetModeSet,
2665 &pCurVidPnTargetModeSetInterface);
2666 Assert(Status == STATUS_SUCCESS);
2667 if (Status == STATUS_SUCCESS)
2668 {
2669
2670 Status = vboxVidPnEnumTargetModes(hCurVidPnTargetModeSet, pCurVidPnTargetModeSetInterface,
2671 vboxVidPnDumpTargetModeSetEnum, NULL);
2672 Assert(Status == STATUS_SUCCESS);
2673 if (Status != STATUS_SUCCESS)
2674 {
2675 LOGREL_EXACT(("ERROR enumerating Target Modes(0x%x)\n", Status));
2676 }
2677 pVidPnInterface->pfnReleaseTargetModeSet(hVidPn, hCurVidPnTargetModeSet);
2678 }
2679 else
2680 {
2681 LOGREL_EXACT(("ERROR getting TargetModeSet for Target(%d), Status(0x%x)\n", VidPnTargetId, Status));
2682 }
2683
2684 LOGREL_EXACT((" <<<---End Of TargetMode Set for Target(%d)---", VidPnTargetId));
2685}
2686
2687
2688void vboxVidPnDumpPinnedTargetMode(const D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
2689{
2690 D3DKMDT_HVIDPNTARGETMODESET hCurVidPnTargetModeSet;
2691 const DXGK_VIDPNTARGETMODESET_INTERFACE *pCurVidPnTargetModeSetInterface;
2692
2693 NTSTATUS Status = pVidPnInterface->pfnAcquireTargetModeSet(hVidPn,
2694 VidPnTargetId,
2695 &hCurVidPnTargetModeSet,
2696 &pCurVidPnTargetModeSetInterface);
2697 Assert(Status == STATUS_SUCCESS);
2698 if (Status == STATUS_SUCCESS)
2699 {
2700 CONST D3DKMDT_VIDPN_TARGET_MODE* pPinnedVidPnTargetModeInfo;
2701
2702 Status = pCurVidPnTargetModeSetInterface->pfnAcquirePinnedModeInfo(hCurVidPnTargetModeSet, &pPinnedVidPnTargetModeInfo);
2703 Assert(Status == STATUS_SUCCESS || Status == STATUS_GRAPHICS_MODE_NOT_PINNED);
2704 if (Status == STATUS_SUCCESS)
2705 {
2706 vboxVidPnDumpTargetMode("Target Pinned: ", pPinnedVidPnTargetModeInfo, "\n");
2707 pCurVidPnTargetModeSetInterface->pfnReleaseModeInfo(hCurVidPnTargetModeSet, pPinnedVidPnTargetModeInfo);
2708 }
2709 else if (Status == STATUS_GRAPHICS_MODE_NOT_PINNED)
2710 {
2711 LOGREL_EXACT(("Target NOT Pinned\n"));
2712 }
2713 else
2714 {
2715 LOGREL_EXACT(("ERROR getting piined Target Mode(0x%x)\n", Status));
2716 }
2717 pVidPnInterface->pfnReleaseTargetModeSet(hVidPn, hCurVidPnTargetModeSet);
2718 }
2719 else
2720 {
2721 LOGREL_EXACT(("ERROR getting TargetModeSet(0x%x)\n", Status));
2722 }
2723}
2724
2725void vboxVidPnDumpCofuncModalityArg(const char *pPrefix, CONST DXGKARG_ENUMVIDPNCOFUNCMODALITY* CONST pEnumCofuncModalityArg, const char *pSuffix)
2726{
2727 LOGREL_EXACT(("%sPivotType(%s), SourceId(0x%x), TargetId(0x%x),%s", pPrefix, vboxVidPnDumpStrCFMPivotType(pEnumCofuncModalityArg->EnumPivotType),
2728 pEnumCofuncModalityArg->EnumPivot.VidPnSourceId, pEnumCofuncModalityArg->EnumPivot.VidPnTargetId, pSuffix));
2729}
2730
2731void vboxVidPnDumpPath(const D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface, const D3DKMDT_VIDPN_PRESENT_PATH *pVidPnPresentPathInfo)
2732{
2733 LOGREL_EXACT((" >>**** Start Dump VidPn Path ****>>\n"));
2734 LOGREL_EXACT(("VidPnSourceId(%d), VidPnTargetId(%d)\n",
2735 pVidPnPresentPathInfo->VidPnSourceId, pVidPnPresentPathInfo->VidPnTargetId));
2736
2737 vboxVidPnDumpPinnedSourceMode(hVidPn, pVidPnInterface, pVidPnPresentPathInfo->VidPnSourceId);
2738 vboxVidPnDumpPinnedTargetMode(hVidPn, pVidPnInterface, pVidPnPresentPathInfo->VidPnTargetId);
2739
2740 vboxVidPnDumpPathTransformation(&pVidPnPresentPathInfo->ContentTransformation);
2741
2742 LOGREL_EXACT(("Importance(%s), TargetColorBasis(%s), Content(%s), ",
2743 vboxVidPnDumpStrImportance(pVidPnPresentPathInfo->ImportanceOrdinal),
2744 vboxVidPnDumpStrColorBasis(pVidPnPresentPathInfo->VidPnTargetColorBasis),
2745 vboxVidPnDumpStrContent(pVidPnPresentPathInfo->Content)));
2746 vboxVidPnDumpRegion("VFA_TL_O(", &pVidPnPresentPathInfo->VisibleFromActiveTLOffset, "), ");
2747 vboxVidPnDumpRegion("VFA_BR_O(", &pVidPnPresentPathInfo->VisibleFromActiveBROffset, "), ");
2748 vboxVidPnDumpRanges("CCDynamicRanges: ", &pVidPnPresentPathInfo->VidPnTargetColorCoeffDynamicRanges, "| ");
2749 vboxVidPnDumpCopyProtectoin("CProtection: ", &pVidPnPresentPathInfo->CopyProtection, "| ");
2750 vboxVidPnDumpGammaRamp("GammaRamp: ", &pVidPnPresentPathInfo->GammaRamp, "\n");
2751
2752 LOGREL_EXACT((" <<**** Stop Dump VidPn Path ****<<"));
2753}
2754
2755typedef struct VBOXVIDPNDUMPPATHENUM
2756{
2757 D3DKMDT_HVIDPN hVidPn;
2758 const DXGK_VIDPN_INTERFACE* pVidPnInterface;
2759} VBOXVIDPNDUMPPATHENUM, *PVBOXVIDPNDUMPPATHENUM;
2760
2761static DECLCALLBACK(BOOLEAN) vboxVidPnDumpPathEnum(D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface,
2762 const D3DKMDT_VIDPN_PRESENT_PATH *pVidPnPresentPathInfo, PVOID pContext)
2763{
2764 PVBOXVIDPNDUMPPATHENUM pData = (PVBOXVIDPNDUMPPATHENUM)pContext;
2765 vboxVidPnDumpPath(pData->hVidPn, pData->pVidPnInterface, pVidPnPresentPathInfo);
2766
2767 pVidPnTopologyInterface->pfnReleasePathInfo(hVidPnTopology, pVidPnPresentPathInfo);
2768 return TRUE;
2769}
2770
2771void vboxVidPnDumpVidPn(const char * pPrefix, PVBOXMP_DEVEXT pDevExt, D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface, const char * pSuffix)
2772{
2773 LOGREL_EXACT(("%s", pPrefix));
2774
2775 VBOXVIDPNDUMPPATHENUM CbData;
2776 CbData.hVidPn = hVidPn;
2777 CbData.pVidPnInterface = pVidPnInterface;
2778 D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology;
2779 const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface;
2780 NTSTATUS Status = pVidPnInterface->pfnGetTopology(hVidPn, &hVidPnTopology, &pVidPnTopologyInterface);
2781 Assert(Status == STATUS_SUCCESS);
2782 if (Status == STATUS_SUCCESS)
2783 {
2784 Status = vboxVidPnEnumPaths(hVidPnTopology, pVidPnTopologyInterface,
2785 vboxVidPnDumpPathEnum, &CbData);
2786 Assert(Status == STATUS_SUCCESS);
2787 }
2788
2789 for (int i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
2790 {
2791 vboxVidPnDumpSourceModeSet(pDevExt, hVidPn, pVidPnInterface, (D3DDDI_VIDEO_PRESENT_SOURCE_ID)i);
2792 vboxVidPnDumpTargetModeSet(pDevExt, hVidPn, pVidPnInterface, (D3DDDI_VIDEO_PRESENT_TARGET_ID)i);
2793 }
2794
2795 LOGREL_EXACT(("%s", pSuffix));
2796}
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