VirtualBox

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

Last change on this file since 51111 was 50628, checked in by vboxsync, 11 years ago

wddm: misc bugfixes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 115.7 KB
Line 
1/* $Id: VBoxMPVidPn.cpp 50628 2014-02-27 12:39:15Z vboxsync $ */
2
3/** @file
4 * VBox WDDM Miniport driver
5 */
6
7/*
8 * Copyright (C) 2011-2013 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19#include "VBoxMPWddm.h"
20#include "VBoxMPVidPn.h"
21#include "common/VBoxMPCommon.h"
22
23static D3DDDIFORMAT vboxWddmCalcPixelFormat(const VIDEO_MODE_INFORMATION *pInfo)
24{
25 switch (pInfo->BitsPerPlane)
26 {
27 case 32:
28 if(!(pInfo->AttributeFlags & VIDEO_MODE_PALETTE_DRIVEN) && !(pInfo->AttributeFlags & VIDEO_MODE_MANAGED_PALETTE))
29 {
30 if (pInfo->RedMask == 0xFF0000 && pInfo->GreenMask == 0xFF00 && pInfo->BlueMask == 0xFF)
31 return D3DDDIFMT_A8R8G8B8;
32 WARN(("unsupported format: bpp(%d), rmask(%d), gmask(%d), bmask(%d)",
33 pInfo->BitsPerPlane, pInfo->RedMask, pInfo->GreenMask, pInfo->BlueMask));
34 AssertBreakpoint();
35 }
36 else
37 {
38 WARN(("unsupported AttributeFlags(0x%x)", pInfo->AttributeFlags));
39 AssertBreakpoint();
40 }
41 break;
42 case 24:
43 if(!(pInfo->AttributeFlags & VIDEO_MODE_PALETTE_DRIVEN) && !(pInfo->AttributeFlags & VIDEO_MODE_MANAGED_PALETTE))
44 {
45 if (pInfo->RedMask == 0xFF0000 && pInfo->GreenMask == 0xFF00 && pInfo->BlueMask == 0xFF)
46 return D3DDDIFMT_R8G8B8;
47 WARN(("unsupported format: bpp(%d), rmask(%d), gmask(%d), bmask(%d)",
48 pInfo->BitsPerPlane, pInfo->RedMask, pInfo->GreenMask, pInfo->BlueMask));
49 AssertBreakpoint();
50 }
51 else
52 {
53 WARN(("unsupported AttributeFlags(0x%x)", pInfo->AttributeFlags));
54 AssertBreakpoint();
55 }
56 break;
57 case 16:
58 if(!(pInfo->AttributeFlags & VIDEO_MODE_PALETTE_DRIVEN) && !(pInfo->AttributeFlags & VIDEO_MODE_MANAGED_PALETTE))
59 {
60 if (pInfo->RedMask == 0xF800 && pInfo->GreenMask == 0x7E0 && pInfo->BlueMask == 0x1F)
61 return D3DDDIFMT_R5G6B5;
62 WARN(("unsupported format: bpp(%d), rmask(%d), gmask(%d), bmask(%d)",
63 pInfo->BitsPerPlane, pInfo->RedMask, pInfo->GreenMask, pInfo->BlueMask));
64 AssertBreakpoint();
65 }
66 else
67 {
68 WARN(("unsupported AttributeFlags(0x%x)", pInfo->AttributeFlags));
69 AssertBreakpoint();
70 }
71 break;
72 case 8:
73 if((pInfo->AttributeFlags & VIDEO_MODE_PALETTE_DRIVEN) && (pInfo->AttributeFlags & VIDEO_MODE_MANAGED_PALETTE))
74 {
75 return D3DDDIFMT_P8;
76 }
77 else
78 {
79 WARN(("unsupported AttributeFlags(0x%x)", pInfo->AttributeFlags));
80 AssertBreakpoint();
81 }
82 break;
83 default:
84 WARN(("unsupported bpp(%d)", pInfo->BitsPerPlane));
85 AssertBreakpoint();
86 break;
87 }
88
89 return D3DDDIFMT_UNKNOWN;
90}
91
92static int vboxWddmResolutionFind(const D3DKMDT_2DREGION *pResolutions, int cResolutions, const D3DKMDT_2DREGION *pRes)
93{
94 for (int i = 0; i < cResolutions; ++i)
95 {
96 const D3DKMDT_2DREGION *pResolution = &pResolutions[i];
97 if (pResolution->cx == pRes->cx && pResolution->cy == pRes->cy)
98 return i;
99 }
100 return -1;
101}
102
103static bool vboxWddmVideoModesMatch(const VIDEO_MODE_INFORMATION *pMode1, const VIDEO_MODE_INFORMATION *pMode2)
104{
105 return pMode1->VisScreenHeight == pMode2->VisScreenHeight
106 && pMode1->VisScreenWidth == pMode2->VisScreenWidth
107 && pMode1->BitsPerPlane == pMode2->BitsPerPlane;
108}
109
110static int vboxWddmVideoModeFind(const VIDEO_MODE_INFORMATION *pModes, int cModes, const VIDEO_MODE_INFORMATION *pM)
111{
112 for (int i = 0; i < cModes; ++i)
113 {
114 const VIDEO_MODE_INFORMATION *pMode = &pModes[i];
115 if (vboxWddmVideoModesMatch(pMode, pM))
116 return i;
117 }
118 return -1;
119}
120
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(("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_OTHER;
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 fMatched;
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->fMatched);
538
539 BOOLEAN fFound = FALSE;
540
541 for (UINT i = 0; i < pInfo->cResolutions; ++i)
542 {
543 D3DKMDT_2DREGION *pResolution = &pInfo->paResolutions[i];
544 if (pMonitorSMI->VideoSignalInfo.ActiveSize.cx == pResolution->cx
545 && pMonitorSMI->VideoSignalInfo.ActiveSize.cy == pResolution->cy)
546 {
547 fFound = TRUE;
548 break;
549 }
550 }
551
552 if (!fFound)
553 pInfo->fMatched = FALSE;
554
555 if (!pInfo->fMatched)
556 LOG(("Found non-matching mode (%d X %d)",
557 pMonitorSMI->VideoSignalInfo.ActiveSize.cx, pMonitorSMI->VideoSignalInfo.ActiveSize.cy));
558
559 pMonitorSMSIf->pfnReleaseModeInfo(hMonitorSMS, pMonitorSMI);
560
561 return pInfo->fMatched;
562}
563
564/* 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 */
565NTSTATUS vboxVidPnMatchMonitorModes(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_TARGET_ID targetId,
566 D3DKMDT_2DREGION *pResolutions, uint32_t cResolutions, BOOLEAN *pfMatch)
567{
568 *pfMatch = FALSE;
569 CONST DXGK_MONITOR_INTERFACE *pMonitorInterface;
570 NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbQueryMonitorInterface(pDevExt->u.primary.DxgkInterface.DeviceHandle, DXGK_MONITOR_INTERFACE_VERSION_V1, &pMonitorInterface);
571 if (!NT_SUCCESS(Status))
572 {
573 WARN(("DxgkCbQueryMonitorInterface failed, Status (0x%x)", Status));
574 return Status;
575 }
576
577 D3DKMDT_HMONITORSOURCEMODESET hMonitorSMS;
578 CONST DXGK_MONITORSOURCEMODESET_INTERFACE *pMonitorSMSIf;
579 Status = pMonitorInterface->pfnAcquireMonitorSourceModeSet(pDevExt->u.primary.DxgkInterface.DeviceHandle,
580 targetId,
581 &hMonitorSMS,
582 &pMonitorSMSIf);
583 if (!NT_SUCCESS(Status))
584 {
585 WARN(("pfnAcquireMonitorSourceModeSet failed, Status (0x%x)", Status));
586 if (Status == STATUS_GRAPHICS_MONITOR_NOT_CONNECTED)
587 {
588 /* this is ok in case we replug the monitor to pick up the monitor modes properly,
589 * so pretend success */
590 *pfMatch = TRUE;
591 Status = STATUS_SUCCESS;
592 }
593 return Status;
594 }
595
596 /* we care only about monitor modes covering all needed resolutions,
597 * we do NOT care if resolutions do not cover some monitor modes */
598 SIZE_T cModes = 0;
599 Status = pMonitorSMSIf->pfnGetNumModes(hMonitorSMS, &cModes);
600 if (NT_SUCCESS(Status))
601 {
602 if (cModes < cResolutions)
603 {
604 *pfMatch = FALSE;
605 LOG(("num modes(%d) and resolutions(%d) do not match, treat as not matched..", cModes, cResolutions));
606 }
607 else
608 {
609 VBOXVIDPNMATCHMONMODESENUM Info;
610 Info.paResolutions = pResolutions;
611 Info.cResolutions = cResolutions;
612 Info.fMatched = TRUE;
613
614 Status = vboxVidPnEnumMonitorSourceModes(hMonitorSMS, pMonitorSMSIf, vboxFidPnMatchMonitorModesEnum, &Info);
615 if (NT_SUCCESS(Status))
616 {
617 *pfMatch = Info.fMatched;
618 LOG(("modes %smatched", Info.fMatched ? "" : "NOT "));
619 }
620 else
621 WARN(("vboxVidPnEnumMonitorSourceModes failed, Status 0x%x", Status));
622 }
623 }
624 else
625 WARN(("pfnGetNumModes failed, Status 0x%x", Status));
626
627 NTSTATUS tmpStatus = pMonitorInterface->pfnReleaseMonitorSourceModeSet(pDevExt->u.primary.DxgkInterface.DeviceHandle, hMonitorSMS);
628 if (!NT_SUCCESS(tmpStatus))
629 WARN(("pfnReleaseMonitorSourceModeSet failed tmpStatus(0x%x)", tmpStatus));
630
631 return Status;
632}
633
634NTSTATUS vboxVidPnCheckAddMonitorModes(PVBOXMP_DEVEXT pDevExt,
635 D3DDDI_VIDEO_PRESENT_TARGET_ID targetId, D3DKMDT_MONITOR_CAPABILITIES_ORIGIN enmOrigin,
636 D3DKMDT_2DREGION *pResolutions, uint32_t cResolutions, int iPreferred)
637{
638 NTSTATUS Status;
639 CONST DXGK_MONITOR_INTERFACE *pMonitorInterface;
640 Status = pDevExt->u.primary.DxgkInterface.DxgkCbQueryMonitorInterface(pDevExt->u.primary.DxgkInterface.DeviceHandle, DXGK_MONITOR_INTERFACE_VERSION_V1, &pMonitorInterface);
641 if (!NT_SUCCESS(Status))
642 {
643 WARN(("DxgkCbQueryMonitorInterface failed, Status()0x%x", Status));
644 return Status;
645 }
646
647 D3DKMDT_HMONITORSOURCEMODESET hMonitorSMS;
648 CONST DXGK_MONITORSOURCEMODESET_INTERFACE *pMonitorSMSIf;
649
650 Status = pMonitorInterface->pfnAcquireMonitorSourceModeSet(pDevExt->u.primary.DxgkInterface.DeviceHandle,
651 targetId,
652 &hMonitorSMS,
653 &pMonitorSMSIf);
654 if (!NT_SUCCESS(Status))
655 {
656 WARN(("DxgkCbQueryMonitorInterface failed, Status()0x%x", Status));
657 if (Status == STATUS_GRAPHICS_MONITOR_NOT_CONNECTED)
658 {
659 /* this is ok in case we replug the monitor to pick up the monitor modes properly,
660 * so pretend success */
661 Status = STATUS_SUCCESS;
662 }
663 return Status;
664 }
665
666 for (uint32_t i = 0; i < cResolutions; ++i)
667 {
668 D3DKMDT_2DREGION *pRes = &pResolutions[i];
669
670 Status = vboxVidPnCreatePopulateMonitorSourceModeInfoFromLegacy(pDevExt,
671 hMonitorSMS,
672 pMonitorSMSIf,
673 pRes,
674 enmOrigin,
675 iPreferred == i
676 );
677 Assert(Status == STATUS_SUCCESS);
678 if (Status != STATUS_SUCCESS)
679 {
680 LOGREL(("vboxVidPnCreatePopulateMonitorSourceModeInfoFromLegacy failed Status(0x%x)", Status));
681 break;
682 }
683 }
684
685 NTSTATUS tmpStatus = pMonitorInterface->pfnReleaseMonitorSourceModeSet(pDevExt->u.primary.DxgkInterface.DeviceHandle, hMonitorSMS);
686 if (!NT_SUCCESS(tmpStatus))
687 {
688 WARN(("pfnReleaseMonitorSourceModeSet failed tmpStatus(0x%x)", tmpStatus));
689 }
690
691 return Status;
692}
693
694NTSTATUS vboxVidPnPathAdd(D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface,
695 const D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, const D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
696{
697 D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology;
698 const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface;
699 NTSTATUS Status = pVidPnInterface->pfnGetTopology(hVidPn, &hVidPnTopology, &pVidPnTopologyInterface);
700 if (!NT_SUCCESS(Status))
701 {
702 AssertFailed();
703 return Status;
704 }
705
706 D3DKMDT_VIDPN_PRESENT_PATH *pNewVidPnPresentPathInfo;
707 Status = pVidPnTopologyInterface->pfnCreateNewPathInfo(hVidPnTopology, &pNewVidPnPresentPathInfo);
708 if (!NT_SUCCESS(Status))
709 {
710 AssertFailed();
711 return Status;
712 }
713
714 pNewVidPnPresentPathInfo->VidPnSourceId = VidPnSourceId;
715 pNewVidPnPresentPathInfo->VidPnTargetId = VidPnTargetId;
716 pNewVidPnPresentPathInfo->ImportanceOrdinal = D3DKMDT_VPPI_PRIMARY;
717 pNewVidPnPresentPathInfo->ContentTransformation.Scaling = D3DKMDT_VPPS_IDENTITY;
718 memset(&pNewVidPnPresentPathInfo->ContentTransformation.ScalingSupport,
719 0, sizeof (pNewVidPnPresentPathInfo->ContentTransformation.ScalingSupport));
720 pNewVidPnPresentPathInfo->ContentTransformation.ScalingSupport.Identity = 1;
721 pNewVidPnPresentPathInfo->ContentTransformation.ScalingSupport.Centered = 0;
722 pNewVidPnPresentPathInfo->ContentTransformation.ScalingSupport.Stretched = 0;
723 pNewVidPnPresentPathInfo->ContentTransformation.Rotation = D3DKMDT_VPPR_IDENTITY;
724 pNewVidPnPresentPathInfo->ContentTransformation.RotationSupport.Identity = 1;
725 pNewVidPnPresentPathInfo->ContentTransformation.RotationSupport.Rotate180 = 0;
726 pNewVidPnPresentPathInfo->ContentTransformation.RotationSupport.Rotate270 = 0;
727 pNewVidPnPresentPathInfo->ContentTransformation.RotationSupport.Rotate90 = 0;
728 pNewVidPnPresentPathInfo->VisibleFromActiveTLOffset.cx = 0;
729 pNewVidPnPresentPathInfo->VisibleFromActiveTLOffset.cy = 0;
730 pNewVidPnPresentPathInfo->VisibleFromActiveBROffset.cx = 0;
731 pNewVidPnPresentPathInfo->VisibleFromActiveBROffset.cy = 0;
732 pNewVidPnPresentPathInfo->VidPnTargetColorBasis = D3DKMDT_CB_SRGB; /* @todo: how does it matters? */
733 pNewVidPnPresentPathInfo->VidPnTargetColorCoeffDynamicRanges.FirstChannel = 8;
734 pNewVidPnPresentPathInfo->VidPnTargetColorCoeffDynamicRanges.SecondChannel = 8;
735 pNewVidPnPresentPathInfo->VidPnTargetColorCoeffDynamicRanges.ThirdChannel = 8;
736 pNewVidPnPresentPathInfo->VidPnTargetColorCoeffDynamicRanges.FourthChannel = 0;
737 pNewVidPnPresentPathInfo->Content = D3DKMDT_VPPC_GRAPHICS;
738 pNewVidPnPresentPathInfo->CopyProtection.CopyProtectionType = D3DKMDT_VPPMT_UNINITIALIZED;
739// pNewVidPnPresentPathInfo->CopyProtection.CopyProtectionType = D3DKMDT_VPPMT_NOPROTECTION;
740 pNewVidPnPresentPathInfo->CopyProtection.APSTriggerBits = 0;
741 memset(&pNewVidPnPresentPathInfo->CopyProtection.CopyProtectionSupport, 0, sizeof (pNewVidPnPresentPathInfo->CopyProtection.CopyProtectionSupport));
742// pNewVidPnPresentPathInfo->CopyProtection.CopyProtectionSupport.NoProtection = 1;
743 memset (&pNewVidPnPresentPathInfo->GammaRamp, 0, sizeof (pNewVidPnPresentPathInfo->GammaRamp));
744// pNewVidPnPresentPathInfo->GammaRamp.Type = D3DDDI_GAMMARAMP_DEFAULT;
745// pNewVidPnPresentPathInfo->GammaRamp.DataSize = 0;
746 Status = pVidPnTopologyInterface->pfnAddPath(hVidPnTopology, pNewVidPnPresentPathInfo);
747 if (!NT_SUCCESS(Status))
748 {
749 AssertFailed();
750 NTSTATUS tmpStatus = pVidPnTopologyInterface->pfnReleasePathInfo(hVidPnTopology, pNewVidPnPresentPathInfo);
751 Assert(NT_SUCCESS(tmpStatus));
752 }
753
754 return Status;
755}
756
757static NTSTATUS vboxVidPnCreatePopulateSourceModeInfoFromLegacy(D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface,
758 const D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId,
759 VIDEO_MODE_INFORMATION *pModes, uint32_t cModes, int iModeToPin,
760 D3DKMDT_VIDEO_PRESENT_SOURCE_MODE_ID *pModeIdToPin,
761 BOOLEAN fDoPin
762 )
763{
764 D3DKMDT_HVIDPNSOURCEMODESET hNewVidPnSourceModeSet;
765 const DXGK_VIDPNSOURCEMODESET_INTERFACE *pNewVidPnSourceModeSetInterface;
766
767 if (pModeIdToPin)
768 *pModeIdToPin = D3DDDI_ID_UNINITIALIZED;
769
770 NTSTATUS Status = pVidPnInterface->pfnCreateNewSourceModeSet(hVidPn,
771 VidPnSourceId,
772 &hNewVidPnSourceModeSet,
773 &pNewVidPnSourceModeSetInterface);
774 if (!NT_SUCCESS(Status))
775 {
776 AssertFailed();
777 return Status;
778 }
779
780 D3DKMDT_VIDEO_PRESENT_SOURCE_MODE_ID sourceModeId = D3DDDI_ID_UNINITIALIZED;
781
782 for (uint32_t i = 0; i < cModes; ++i)
783 {
784 VIDEO_MODE_INFORMATION *pMode = &pModes[i];
785 D3DKMDT_VIDPN_SOURCE_MODE *pNewVidPnSourceModeInfo;
786 Status = pNewVidPnSourceModeSetInterface->pfnCreateNewModeInfo(hNewVidPnSourceModeSet, &pNewVidPnSourceModeInfo);
787 if (!NT_SUCCESS(Status))
788 {
789 AssertFailed();
790 break;
791 }
792
793 Status = vboxVidPnPopulateSourceModeInfoFromLegacy(pNewVidPnSourceModeInfo, pMode);
794 if (NT_SUCCESS(Status))
795 {
796 if (i == iModeToPin)
797 {
798 sourceModeId = pNewVidPnSourceModeInfo->Id;
799 }
800 Status = pNewVidPnSourceModeSetInterface->pfnAddMode(hNewVidPnSourceModeSet, pNewVidPnSourceModeInfo);
801 if (NT_SUCCESS(Status))
802 {
803 /* success */
804 continue;
805 }
806 AssertFailed();
807 }
808 else
809 {
810 AssertFailed();
811 }
812
813 NTSTATUS tmpStatus = pNewVidPnSourceModeSetInterface->pfnReleaseModeInfo(hNewVidPnSourceModeSet, pNewVidPnSourceModeInfo);
814 Assert(tmpStatus == STATUS_SUCCESS);
815
816 /* we're here because of an error */
817 Assert(!NT_SUCCESS(Status));
818 break;
819 }
820
821 if (!NT_SUCCESS(Status))
822 {
823 AssertFailed();
824 return Status;
825 }
826
827 if (sourceModeId != D3DDDI_ID_UNINITIALIZED)
828 {
829 if (pModeIdToPin)
830 {
831 *pModeIdToPin = sourceModeId;
832 }
833 Assert(iModeToPin >= 0);
834 if (fDoPin)
835 {
836 Status = pNewVidPnSourceModeSetInterface->pfnPinMode(hNewVidPnSourceModeSet, sourceModeId);
837 if (!NT_SUCCESS(Status))
838 {
839 AssertFailed();
840 return Status;
841 }
842 }
843 }
844 else
845 {
846 Assert(iModeToPin < 0);
847 }
848
849 Status = pVidPnInterface->pfnAssignSourceModeSet(hVidPn, VidPnSourceId, hNewVidPnSourceModeSet);
850 if (!NT_SUCCESS(Status))
851 {
852 AssertFailed();
853 return Status;
854 }
855
856 return Status;
857}
858
859static NTSTATUS vboxVidPnCreatePopulateTargetModeInfoFromLegacy(D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface,
860 const D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId,
861 D3DKMDT_2DREGION *pResolutions, uint32_t cResolutions,
862 VIDEO_MODE_INFORMATION *pModeToPin,
863 D3DKMDT_VIDEO_PRESENT_TARGET_MODE_ID *pModeIdToPin,
864 BOOLEAN fSetPreferred,
865 BOOLEAN fDoPin
866 )
867{
868 D3DKMDT_HVIDPNTARGETMODESET hNewVidPnTargetModeSet;
869 const DXGK_VIDPNTARGETMODESET_INTERFACE *pNewVidPnTargetModeSetInterface;
870
871 if (pModeIdToPin)
872 *pModeIdToPin = D3DDDI_ID_UNINITIALIZED;
873
874 NTSTATUS Status = pVidPnInterface->pfnCreateNewTargetModeSet(hVidPn,
875 VidPnTargetId,
876 &hNewVidPnTargetModeSet,
877 &pNewVidPnTargetModeSetInterface);
878 if (!NT_SUCCESS(Status))
879 {
880 AssertFailed();
881 return Status;
882 }
883
884 D3DKMDT_VIDEO_PRESENT_TARGET_MODE_ID targetModeId = D3DDDI_ID_UNINITIALIZED;
885
886 for (uint32_t i = 0; i < cResolutions; ++i)
887 {
888 D3DKMDT_2DREGION *pResolution = &pResolutions[i];
889 D3DKMDT_VIDPN_TARGET_MODE *pNewVidPnTargetModeInfo;
890 Status = pNewVidPnTargetModeSetInterface->pfnCreateNewModeInfo(hNewVidPnTargetModeSet, &pNewVidPnTargetModeInfo);
891 if (!NT_SUCCESS(Status))
892 {
893 AssertFailed();
894 break;
895 }
896
897 BOOLEAN fIsPinMode = pModeToPin && pModeToPin->VisScreenWidth == pResolution->cx
898 && pModeToPin->VisScreenHeight == pResolution->cy;
899
900 Status = vboxVidPnPopulateTargetModeInfoFromLegacy(pNewVidPnTargetModeInfo, pResolution, fIsPinMode && fSetPreferred);
901 if (NT_SUCCESS(Status))
902 {
903 if (fIsPinMode)
904 {
905 targetModeId = pNewVidPnTargetModeInfo->Id;
906 }
907 Status = pNewVidPnTargetModeSetInterface->pfnAddMode(hNewVidPnTargetModeSet, pNewVidPnTargetModeInfo);
908 if (NT_SUCCESS(Status))
909 {
910
911 /* success */
912 continue;
913 }
914 AssertFailed();
915 }
916 else
917 {
918 AssertFailed();
919 }
920
921 NTSTATUS tmpStatus = pNewVidPnTargetModeSetInterface->pfnReleaseModeInfo(hNewVidPnTargetModeSet, pNewVidPnTargetModeInfo);
922 Assert(tmpStatus == STATUS_SUCCESS);
923
924 /* we're here because of an error */
925 Assert(!NT_SUCCESS(Status));
926 break;
927 }
928
929 if (!NT_SUCCESS(Status))
930 {
931 AssertFailed();
932 return Status;
933 }
934
935 if (targetModeId != D3DDDI_ID_UNINITIALIZED)
936 {
937 Assert(pModeToPin);
938
939 if (pModeIdToPin)
940 {
941 *pModeIdToPin = targetModeId;
942 }
943
944 if (fDoPin)
945 {
946 Status = pNewVidPnTargetModeSetInterface->pfnPinMode(hNewVidPnTargetModeSet, targetModeId);
947 if (!NT_SUCCESS(Status))
948 {
949 AssertFailed();
950 return Status;
951 }
952 }
953 }
954 else
955 {
956 Assert(!pModeToPin);
957 }
958
959 Status = pVidPnInterface->pfnAssignTargetModeSet(hVidPn, VidPnTargetId, hNewVidPnTargetModeSet);
960 if (!NT_SUCCESS(Status))
961 {
962 AssertFailed();
963 return Status;
964 }
965
966 return Status;
967}
968
969NTSTATUS vboxVidPnCreatePopulateVidPnPathFromLegacy(PVBOXMP_DEVEXT pDevExt, D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface,
970 VIDEO_MODE_INFORMATION *pModes, uint32_t cModes, int iModeToPin,
971 D3DKMDT_2DREGION *pResolutions, uint32_t cResolutions,
972 const D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, const D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
973{
974 NTSTATUS Status;
975
976#if 0
977 Status = vboxVidPnPathAdd(hVidPn, pVidPnInterface, VidPnSourceId, VidPnTargetId);
978 if (!NT_SUCCESS(Status))
979 {
980 AssertFailed();
981 return Status;
982 }
983#endif
984
985 VIDEO_MODE_INFORMATION *pModeToPin = iModeToPin >= 0 ? &pModes[iModeToPin] : NULL;
986 Status = vboxVidPnCreatePopulateTargetModeInfoFromLegacy(hVidPn, pVidPnInterface, VidPnTargetId, pResolutions, cResolutions, pModeToPin, NULL, TRUE, TRUE);
987 if (!NT_SUCCESS(Status))
988 {
989 AssertFailed();
990 return Status;
991 }
992
993 Status = vboxVidPnCreatePopulateSourceModeInfoFromLegacy(hVidPn, pVidPnInterface, VidPnSourceId, pModes, cModes, iModeToPin, NULL, TRUE);
994 if (!NT_SUCCESS(Status))
995 {
996 AssertFailed();
997 return Status;
998 }
999
1000 return Status;
1001}
1002
1003typedef struct VBOXVIDPNPOPRESOLUTIONENUM
1004{
1005 NTSTATUS Status;
1006 D3DKMDT_2DREGION *pResolutions;
1007 int cResolutions;
1008 int cResultResolutions;
1009}VBOXVIDPNPOPRESOLUTIONENUM, *PVBOXVIDPNPOPRESOLUTIONENUM;
1010
1011static DECLCALLBACK(BOOLEAN) vboxVidPnPopulateResolutionsFromSourceModeSetEnum(D3DKMDT_HVIDPNSOURCEMODESET hNewVidPnSourceModeSet, const DXGK_VIDPNSOURCEMODESET_INTERFACE *pVidPnSourceModeSetInterface,
1012 const D3DKMDT_VIDPN_SOURCE_MODE *pNewVidPnSourceModeInfo, PVOID pContext)
1013{
1014 NTSTATUS Status = STATUS_SUCCESS;
1015 PVBOXVIDPNPOPRESOLUTIONENUM pInfo = (PVBOXVIDPNPOPRESOLUTIONENUM)pContext;
1016 Assert(pInfo->cResolutions >= pInfo->cResultResolutions);
1017 Assert(pInfo->Status == STATUS_SUCCESS);
1018 if (vboxWddmResolutionFind(pInfo->pResolutions, pInfo->cResultResolutions, &pNewVidPnSourceModeInfo->Format.Graphics.PrimSurfSize) < 0)
1019 {
1020 if (pInfo->cResultResolutions < pInfo->cResolutions)
1021 {
1022 pInfo->pResolutions[pInfo->cResultResolutions] = pNewVidPnSourceModeInfo->Format.Graphics.PrimSurfSize;
1023 ++pInfo->cResultResolutions;
1024 }
1025 else
1026 {
1027 Status = STATUS_BUFFER_OVERFLOW;
1028 }
1029 }
1030
1031 pInfo->Status = Status;
1032
1033 return Status == STATUS_SUCCESS;
1034}
1035
1036static DECLCALLBACK(BOOLEAN) vboxVidPnPopulateResolutionsFromTargetModeSetEnum(D3DKMDT_HVIDPNTARGETMODESET hNewVidPnTargetModeSet, const DXGK_VIDPNTARGETMODESET_INTERFACE *pVidPnTargetModeSetInterface,
1037 const D3DKMDT_VIDPN_TARGET_MODE *pNewVidPnTargetModeInfo, PVOID pContext)
1038{
1039 NTSTATUS Status = STATUS_SUCCESS;
1040 PVBOXVIDPNPOPRESOLUTIONENUM pInfo = (PVBOXVIDPNPOPRESOLUTIONENUM)pContext;
1041 Assert(pInfo->cResolutions >= pInfo->cResultResolutions);
1042 Assert(pInfo->Status == STATUS_SUCCESS);
1043 if (vboxWddmResolutionFind(pInfo->pResolutions, pInfo->cResultResolutions, &pNewVidPnTargetModeInfo->VideoSignalInfo.ActiveSize) < 0)
1044 {
1045 if (pInfo->cResultResolutions < pInfo->cResolutions)
1046 {
1047 pInfo->pResolutions[pInfo->cResultResolutions] = pNewVidPnTargetModeInfo->VideoSignalInfo.ActiveSize;
1048 ++pInfo->cResultResolutions;
1049 }
1050 else
1051 {
1052 Status = STATUS_BUFFER_OVERFLOW;
1053 }
1054 }
1055
1056 pInfo->Status = Status;
1057
1058 return Status == STATUS_SUCCESS;
1059}
1060
1061typedef struct VBOXVIDPNPOPMODEENUM
1062{
1063 NTSTATUS Status;
1064 VIDEO_MODE_INFORMATION *pModes;
1065 int cModes;
1066 int cResultModes;
1067}VBOXVIDPNPOPMODEENUM, *PVBOXVIDPNPOPMODEENUM;
1068
1069static DECLCALLBACK(BOOLEAN) vboxVidPnPopulateModesFromSourceModeSetEnum(D3DKMDT_HVIDPNSOURCEMODESET hNewVidPnSourceModeSet, const DXGK_VIDPNSOURCEMODESET_INTERFACE *pVidPnSourceModeSetInterface,
1070 const D3DKMDT_VIDPN_SOURCE_MODE *pNewVidPnSourceModeInfo, PVOID pContext)
1071{
1072 NTSTATUS Status = STATUS_SUCCESS;
1073 PVBOXVIDPNPOPMODEENUM pInfo = (PVBOXVIDPNPOPMODEENUM)pContext;
1074 VIDEO_MODE_INFORMATION Mode;
1075 Assert(pInfo->cModes >= pInfo->cResultModes);
1076 Assert(pInfo->Status == STATUS_SUCCESS);
1077 if (VBoxWddmFillMode(&Mode, pNewVidPnSourceModeInfo->Format.Graphics.PixelFormat,
1078 pNewVidPnSourceModeInfo->Format.Graphics.VisibleRegionSize.cx,
1079 pNewVidPnSourceModeInfo->Format.Graphics.VisibleRegionSize.cy))
1080 {
1081 if (vboxWddmVideoModeFind(pInfo->pModes, pInfo->cModes, &Mode) < 0)
1082 {
1083 if (pInfo->cResultModes < pInfo->cModes)
1084 {
1085 pInfo->pModes[pInfo->cResultModes] = Mode;
1086 ++pInfo->cResultModes;
1087 }
1088 else
1089 {
1090 Status = STATUS_BUFFER_OVERFLOW;
1091 }
1092 }
1093 }
1094 else
1095 {
1096 Assert(0);
1097 Status = STATUS_INVALID_PARAMETER;
1098 }
1099
1100 pInfo->Status = Status;
1101
1102 return Status == STATUS_SUCCESS;
1103}
1104
1105typedef struct VBOXVIDPNPOPMODETARGETENUM
1106{
1107 VBOXVIDPNPOPMODEENUM Base;
1108 VIDEO_MODE_INFORMATION *pSuperset;
1109 int cSuperset;
1110}VBOXVIDPNPOPMODETARGETENUM, *PVBOXVIDPNPOPMODETARGETENUM;
1111
1112static DECLCALLBACK(BOOLEAN) vboxVidPnPopulateModesFromTargetModeSetEnum(D3DKMDT_HVIDPNTARGETMODESET hNewVidPnTargetModeSet, const DXGK_VIDPNTARGETMODESET_INTERFACE *pVidPnTargetModeSetInterface,
1113 const D3DKMDT_VIDPN_TARGET_MODE *pNewVidPnTargetModeInfo, PVOID pContext)
1114{
1115 NTSTATUS Status = STATUS_SUCCESS;
1116 PVBOXVIDPNPOPMODETARGETENUM pInfo = (PVBOXVIDPNPOPMODETARGETENUM)pContext;
1117 Assert(pInfo->Base.cModes >= pInfo->Base.cResultModes);
1118 Assert(pInfo->Base.Status == STATUS_SUCCESS);
1119 uint32_t cResult;
1120 Status = VBoxWddmGetModesForResolution(pInfo->pSuperset, pInfo->cSuperset, -1, &pNewVidPnTargetModeInfo->VideoSignalInfo.ActiveSize,
1121 pInfo->Base.pModes + pInfo->Base.cResultModes, pInfo->Base.cModes - pInfo->Base.cResultModes, &cResult, NULL);
1122 Assert(Status == STATUS_SUCCESS);
1123 if (Status == STATUS_SUCCESS)
1124 {
1125 pInfo->Base.cResultModes += cResult;
1126 }
1127
1128 pInfo->Base.Status = Status;
1129
1130 return Status == STATUS_SUCCESS;
1131}
1132
1133static D3DKMDT_ENUMCOFUNCMODALITY_PIVOT_TYPE vboxVidPnCofuncModalityCurrentPathPivot(CONST DXGKARG_ENUMVIDPNCOFUNCMODALITY* pEnumCofuncModalityArg,
1134 D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
1135{
1136 switch (pEnumCofuncModalityArg->EnumPivotType)
1137 {
1138 case D3DKMDT_EPT_VIDPNSOURCE:
1139 if (pEnumCofuncModalityArg->EnumPivot.VidPnSourceId == VidPnSourceId)
1140 return D3DKMDT_EPT_VIDPNSOURCE;
1141 if (pEnumCofuncModalityArg->EnumPivot.VidPnSourceId == D3DDDI_ID_ALL)
1142 {
1143#ifdef DEBUG_misha
1144 AssertFailed();
1145#endif
1146 return D3DKMDT_EPT_VIDPNSOURCE;
1147 }
1148 return D3DKMDT_EPT_NOPIVOT;
1149 case D3DKMDT_EPT_VIDPNTARGET:
1150 if (pEnumCofuncModalityArg->EnumPivot.VidPnTargetId == VidPnTargetId)
1151 return D3DKMDT_EPT_VIDPNTARGET;
1152 if (pEnumCofuncModalityArg->EnumPivot.VidPnTargetId == D3DDDI_ID_ALL)
1153 {
1154#ifdef DEBUG_misha
1155 AssertFailed();
1156#endif
1157 return D3DKMDT_EPT_VIDPNTARGET;
1158 }
1159 return D3DKMDT_EPT_NOPIVOT;
1160 case D3DKMDT_EPT_SCALING:
1161 case D3DKMDT_EPT_ROTATION:
1162 case D3DKMDT_EPT_NOPIVOT:
1163 return D3DKMDT_EPT_NOPIVOT;
1164 default:
1165 AssertFailed();
1166 return D3DKMDT_EPT_NOPIVOT;
1167 }
1168}
1169
1170NTSTATUS vboxVidPnHasPinnedTargetMode(D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface,
1171 D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId, BOOLEAN *pfHas)
1172{
1173 D3DKMDT_HVIDPNTARGETMODESET hCurVidPnTargetModeSet;
1174 const DXGK_VIDPNTARGETMODESET_INTERFACE *pCurVidPnTargetModeSetInterface;
1175 *pfHas = FALSE;
1176 NTSTATUS Status = pVidPnInterface->pfnAcquireTargetModeSet(hVidPn,
1177 VidPnTargetId,
1178 &hCurVidPnTargetModeSet,
1179 &pCurVidPnTargetModeSetInterface);
1180 if (!NT_SUCCESS(Status))
1181 {
1182 AssertFailed();
1183 return Status;
1184 }
1185
1186 CONST D3DKMDT_VIDPN_TARGET_MODE* pPinnedVidPnTargetModeInfo;
1187 Status = pCurVidPnTargetModeSetInterface->pfnAcquirePinnedModeInfo(hCurVidPnTargetModeSet, &pPinnedVidPnTargetModeInfo);
1188 if (Status == STATUS_GRAPHICS_MODE_NOT_PINNED)
1189 {
1190 pPinnedVidPnTargetModeInfo = NULL;
1191 Status = STATUS_SUCCESS;
1192 }
1193 else if (!NT_SUCCESS(Status))
1194 {
1195 LOGREL(("pfnAcquirePinnedModeInfo failed Status(0x%x)", Status));
1196 AssertFailed();
1197 }
1198 else
1199 {
1200 Assert(pPinnedVidPnTargetModeInfo);
1201 NTSTATUS tmpStatus = pCurVidPnTargetModeSetInterface->pfnReleaseModeInfo(hCurVidPnTargetModeSet, pPinnedVidPnTargetModeInfo);
1202 Assert(NT_SUCCESS(tmpStatus));
1203 *pfHas = TRUE;
1204 }
1205
1206 NTSTATUS tmpStatus = pVidPnInterface->pfnReleaseTargetModeSet(hVidPn, hCurVidPnTargetModeSet);
1207 Assert(tmpStatus == STATUS_SUCCESS);
1208
1209 return Status;
1210}
1211
1212NTSTATUS vboxVidPnHasPinnedSourceMode(D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface,
1213 D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, BOOLEAN *pfHas)
1214{
1215 D3DKMDT_HVIDPNSOURCEMODESET hCurVidPnSourceModeSet;
1216 const DXGK_VIDPNSOURCEMODESET_INTERFACE *pCurVidPnSourceModeSetInterface;
1217 *pfHas = FALSE;
1218 NTSTATUS Status = pVidPnInterface->pfnAcquireSourceModeSet(hVidPn,
1219 VidPnSourceId,
1220 &hCurVidPnSourceModeSet,
1221 &pCurVidPnSourceModeSetInterface);
1222 if (!NT_SUCCESS(Status))
1223 {
1224 AssertFailed();
1225 return Status;
1226 }
1227
1228 CONST D3DKMDT_VIDPN_SOURCE_MODE* pPinnedVidPnSourceModeInfo;
1229 Status = pCurVidPnSourceModeSetInterface->pfnAcquirePinnedModeInfo(hCurVidPnSourceModeSet, &pPinnedVidPnSourceModeInfo);
1230 if (Status == STATUS_GRAPHICS_MODE_NOT_PINNED)
1231 {
1232 pPinnedVidPnSourceModeInfo = NULL;
1233 Status = STATUS_SUCCESS;
1234 }
1235 else if (!NT_SUCCESS(Status))
1236 {
1237 LOGREL(("pfnAcquirePinnedModeInfo failed Status(0x%x)", Status));
1238 AssertFailed();
1239 }
1240 else
1241 {
1242 Assert(pPinnedVidPnSourceModeInfo);
1243 NTSTATUS tmpStatus = pCurVidPnSourceModeSetInterface->pfnReleaseModeInfo(hCurVidPnSourceModeSet, pPinnedVidPnSourceModeInfo);
1244 Assert(NT_SUCCESS(tmpStatus));
1245 *pfHas = TRUE;
1246 }
1247
1248 NTSTATUS tmpStatus = pVidPnInterface->pfnReleaseSourceModeSet(hVidPn, hCurVidPnSourceModeSet);
1249 Assert(tmpStatus == STATUS_SUCCESS);
1250
1251 return Status;
1252}
1253
1254static NTSTATUS vboxVidPnCofuncModalityForPathTarget(PVBOXVIDPNCOFUNCMODALITY pCbContext,
1255 D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
1256{
1257 PVBOXMP_DEVEXT pDevExt = pCbContext->pDevExt;
1258 D3DKMDT_HVIDPN hVidPn = pCbContext->pEnumCofuncModalityArg->hConstrainingVidPn;
1259 const DXGK_VIDPN_INTERFACE* pVidPnInterface = pCbContext->pVidPnInterface;
1260 PVBOXWDDM_VIDEOMODES_INFO pInfo = &pCbContext->pInfos[VidPnTargetId];
1261
1262 D3DKMDT_HVIDPNTARGETMODESET hNewVidPnTargetModeSet = NULL;
1263 const DXGK_VIDPNTARGETMODESET_INTERFACE *pNewVidPnTargetModeSetInterface;
1264
1265 Assert(VidPnSourceId == VidPnTargetId);
1266
1267 D3DKMDT_HVIDPNSOURCEMODESET hCurVidPnSourceModeSet;
1268 const DXGK_VIDPNSOURCEMODESET_INTERFACE *pCurVidPnSourceModeSetInterface;
1269 NTSTATUS Status = pVidPnInterface->pfnAcquireSourceModeSet(hVidPn,
1270 VidPnSourceId,
1271 &hCurVidPnSourceModeSet,
1272 &pCurVidPnSourceModeSetInterface);
1273 if (!NT_SUCCESS(Status))
1274 {
1275 AssertFailed();
1276 return Status;
1277 }
1278
1279 CONST D3DKMDT_VIDPN_SOURCE_MODE* pPinnedVidPnSourceModeInfo;
1280 Status = pCurVidPnSourceModeSetInterface->pfnAcquirePinnedModeInfo(hCurVidPnSourceModeSet, &pPinnedVidPnSourceModeInfo);
1281 if (Status == STATUS_GRAPHICS_MODE_NOT_PINNED)
1282 {
1283 pPinnedVidPnSourceModeInfo = NULL;
1284 Status = STATUS_SUCCESS;
1285 }
1286 else if (!NT_SUCCESS(Status))
1287 {
1288 LOGREL(("pfnAcquirePinnedModeInfo failed Status(0x%x)", Status));
1289 AssertFailed();
1290 }
1291 else
1292 {
1293 Assert(pPinnedVidPnSourceModeInfo);
1294 }
1295
1296 if (NT_SUCCESS(Status))
1297 {
1298 Status = pVidPnInterface->pfnCreateNewTargetModeSet(hVidPn,
1299 VidPnTargetId,
1300 &hNewVidPnTargetModeSet,
1301 &pNewVidPnTargetModeSetInterface);
1302 if (NT_SUCCESS(Status))
1303 {
1304 Assert(hNewVidPnTargetModeSet);
1305 Assert(VidPnSourceId == VidPnTargetId);
1306// if (VidPnSourceId == VidPnTargetId && pCbContext->apPathInfos[VidPnTargetId].enmState == VBOXVIDPNPATHITEM_STATE_PRESENT)
1307 {
1308 for (uint32_t i = 0; i < pInfo->cResolutions; ++i)
1309 {
1310 D3DKMDT_2DREGION *pResolution = &pInfo->aResolutions[i];
1311 if (pPinnedVidPnSourceModeInfo)
1312 {
1313 if (pPinnedVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cx != pResolution->cx
1314 || pPinnedVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cy != pResolution->cy)
1315 {
1316 continue;
1317 }
1318 }
1319
1320 D3DKMDT_VIDPN_TARGET_MODE *pNewVidPnTargetModeInfo;
1321 Status = pNewVidPnTargetModeSetInterface->pfnCreateNewModeInfo(hNewVidPnTargetModeSet, &pNewVidPnTargetModeInfo);
1322 Assert(Status == STATUS_SUCCESS);
1323 if (NT_SUCCESS(Status))
1324 {
1325 Status = vboxVidPnPopulateTargetModeInfoFromLegacy(pNewVidPnTargetModeInfo, pResolution, i == pInfo->iPreferredResolution);
1326 if (NT_SUCCESS(Status))
1327 {
1328 Status = pNewVidPnTargetModeSetInterface->pfnAddMode(hNewVidPnTargetModeSet, pNewVidPnTargetModeInfo);
1329 if (NT_SUCCESS(Status))
1330 {
1331 /* success */
1332 continue;
1333 }
1334 else
1335 WARN(("pfnAddMode failed, Status 0x%x", Status));
1336 }
1337 else
1338 WARN(("vboxVidPnPopulateTargetModeInfoFromLegacy failed, Status 0x%x", Status));
1339
1340 NTSTATUS tmpStatus = pNewVidPnTargetModeSetInterface->pfnReleaseModeInfo(hNewVidPnTargetModeSet, pNewVidPnTargetModeInfo);
1341 Assert(tmpStatus == STATUS_SUCCESS);
1342 }
1343
1344 /* we're here because of an error */
1345 Assert(!NT_SUCCESS(Status));
1346 /* ignore mode addition failure */
1347 Status = STATUS_SUCCESS;
1348 continue;
1349 }
1350 }
1351 }
1352 else
1353 {
1354 AssertFailed();
1355 }
1356 }
1357 else
1358 {
1359 AssertFailed();
1360 }
1361
1362 if (pPinnedVidPnSourceModeInfo)
1363 {
1364 NTSTATUS tmpStatus = pCurVidPnSourceModeSetInterface->pfnReleaseModeInfo(hCurVidPnSourceModeSet, pPinnedVidPnSourceModeInfo);
1365 Assert(tmpStatus == STATUS_SUCCESS);
1366 }
1367
1368 NTSTATUS tmpStatus = pVidPnInterface->pfnReleaseSourceModeSet(hVidPn, hCurVidPnSourceModeSet);
1369 Assert(tmpStatus == STATUS_SUCCESS);
1370
1371 if (NT_SUCCESS(Status))
1372 {
1373 Assert(hNewVidPnTargetModeSet);
1374 Status = pVidPnInterface->pfnAssignTargetModeSet(hVidPn, VidPnTargetId, hNewVidPnTargetModeSet);
1375 if (!NT_SUCCESS(Status))
1376 {
1377 WARN(("\n\n!!!!!!!\n\n pfnAssignTargetModeSet failed, Status(0x%x)", Status));
1378 tmpStatus = pVidPnInterface->pfnReleaseTargetModeSet(hVidPn, hNewVidPnTargetModeSet);
1379 Assert(tmpStatus == STATUS_SUCCESS);
1380 }
1381 }
1382
1383 return Status;
1384}
1385
1386static NTSTATUS vboxVidPnCofuncModalityForPathSource(PVBOXVIDPNCOFUNCMODALITY pCbContext,
1387 D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
1388{
1389 PVBOXMP_DEVEXT pDevExt = pCbContext->pDevExt;
1390 D3DKMDT_HVIDPN hVidPn = pCbContext->pEnumCofuncModalityArg->hConstrainingVidPn;
1391 const DXGK_VIDPN_INTERFACE* pVidPnInterface = pCbContext->pVidPnInterface;
1392 PVBOXWDDM_VIDEOMODES_INFO pInfo = &pCbContext->pInfos[VidPnTargetId];
1393 D3DKMDT_HVIDPNSOURCEMODESET hNewVidPnSourceModeSet = NULL;
1394 const DXGK_VIDPNSOURCEMODESET_INTERFACE *pNewVidPnSourceModeSetInterface;
1395
1396 Assert(VidPnSourceId == VidPnTargetId);
1397
1398 D3DKMDT_HVIDPNTARGETMODESET hCurVidPnTargetModeSet;
1399 const DXGK_VIDPNTARGETMODESET_INTERFACE *pCurVidPnTargetModeSetInterface;
1400 NTSTATUS Status = pVidPnInterface->pfnAcquireTargetModeSet(hVidPn,
1401 VidPnTargetId,
1402 &hCurVidPnTargetModeSet,
1403 &pCurVidPnTargetModeSetInterface);
1404 if (!NT_SUCCESS(Status))
1405 {
1406 AssertFailed();
1407 return Status;
1408 }
1409
1410 CONST D3DKMDT_VIDPN_TARGET_MODE* pPinnedVidPnTargetModeInfo;
1411 Status = pCurVidPnTargetModeSetInterface->pfnAcquirePinnedModeInfo(hCurVidPnTargetModeSet, &pPinnedVidPnTargetModeInfo);
1412 if (Status == STATUS_GRAPHICS_MODE_NOT_PINNED)
1413 {
1414 pPinnedVidPnTargetModeInfo = NULL;
1415 Status = STATUS_SUCCESS;
1416 }
1417 else if (!NT_SUCCESS(Status))
1418 {
1419 LOGREL(("pfnAcquirePinnedModeInfo failed Status(0x%x)", Status));
1420 AssertFailed();
1421 }
1422 else
1423 {
1424 Assert(pPinnedVidPnTargetModeInfo);
1425 }
1426
1427 if (NT_SUCCESS(Status))
1428 {
1429 NTSTATUS Status = pVidPnInterface->pfnCreateNewSourceModeSet(hVidPn,
1430 VidPnSourceId,
1431 &hNewVidPnSourceModeSet,
1432 &pNewVidPnSourceModeSetInterface);
1433 if (NT_SUCCESS(Status))
1434 {
1435 Assert(hNewVidPnSourceModeSet);
1436 Assert(VidPnSourceId == VidPnTargetId);
1437// if (VidPnSourceId == VidPnTargetId && pCbContext->apPathInfos[VidPnSourceId].enmState == VBOXVIDPNPATHITEM_STATE_PRESENT)
1438 {
1439 for (uint32_t i = 0; i < pInfo->cModes; ++i)
1440 {
1441 VIDEO_MODE_INFORMATION *pMode = &pInfo->aModes[i];
1442 if (pPinnedVidPnTargetModeInfo)
1443 {
1444 if (pPinnedVidPnTargetModeInfo->VideoSignalInfo.ActiveSize.cx != pMode->VisScreenWidth
1445 || pPinnedVidPnTargetModeInfo->VideoSignalInfo.ActiveSize.cy != pMode->VisScreenHeight)
1446 {
1447 continue;
1448 }
1449 }
1450
1451 D3DKMDT_VIDPN_SOURCE_MODE *pNewVidPnSourceModeInfo;
1452 Status = pNewVidPnSourceModeSetInterface->pfnCreateNewModeInfo(hNewVidPnSourceModeSet, &pNewVidPnSourceModeInfo);
1453 if (NT_SUCCESS(Status))
1454 {
1455 Status = vboxVidPnPopulateSourceModeInfoFromLegacy(pNewVidPnSourceModeInfo, pMode);
1456 Assert(Status == STATUS_SUCCESS);
1457 if (NT_SUCCESS(Status))
1458 {
1459 Status = pNewVidPnSourceModeSetInterface->pfnAddMode(hNewVidPnSourceModeSet, pNewVidPnSourceModeInfo);
1460 if (NT_SUCCESS(Status))
1461 {
1462 /* success */
1463 continue;
1464 }
1465 else
1466 WARN(("pfnAddMode failed, Status 0x%x", Status));
1467 }
1468
1469 NTSTATUS tmpStatus = pNewVidPnSourceModeSetInterface->pfnReleaseModeInfo(hNewVidPnSourceModeSet, pNewVidPnSourceModeInfo);
1470 Assert(tmpStatus == STATUS_SUCCESS);
1471 }
1472 else
1473 WARN(("pfnCreateNewModeInfo failed, Status 0x%x", Status));
1474 /* we're here because of an error */
1475 Assert(!NT_SUCCESS(Status));
1476 /* ignore mode addition failure */
1477 Status = STATUS_SUCCESS;
1478 continue;
1479 }
1480 }
1481 }
1482 else
1483 {
1484 AssertFailed();
1485 }
1486 }
1487 else
1488 {
1489 AssertFailed();
1490 }
1491
1492 if (pPinnedVidPnTargetModeInfo)
1493 {
1494 NTSTATUS tmpStatus = pCurVidPnTargetModeSetInterface->pfnReleaseModeInfo(hCurVidPnTargetModeSet, pPinnedVidPnTargetModeInfo);
1495 Assert(tmpStatus == STATUS_SUCCESS);
1496 }
1497
1498 NTSTATUS tmpStatus = pVidPnInterface->pfnReleaseTargetModeSet(hVidPn, hCurVidPnTargetModeSet);
1499 Assert(tmpStatus == STATUS_SUCCESS);
1500
1501 if (NT_SUCCESS(Status))
1502 {
1503 Assert(hNewVidPnSourceModeSet);
1504 Status = pVidPnInterface->pfnAssignSourceModeSet(hVidPn, VidPnSourceId, hNewVidPnSourceModeSet);
1505 if (!NT_SUCCESS(Status))
1506 {
1507 WARN(("\n\n!!!!!!!\n\n pfnAssignSourceModeSet failed, Status(0x%x)", Status));
1508 tmpStatus = pVidPnInterface->pfnReleaseSourceModeSet(hVidPn, hNewVidPnSourceModeSet);
1509 Assert(tmpStatus == STATUS_SUCCESS);
1510 }
1511 }
1512
1513 return Status;
1514}
1515
1516NTSTATUS vboxVidPnCofuncModalityForPath(PVBOXVIDPNCOFUNCMODALITY pCbContext,
1517 D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
1518{
1519 PVBOXMP_DEVEXT pDevExt = pCbContext->pDevExt;
1520 D3DKMDT_HVIDPN hVidPn = pCbContext->pEnumCofuncModalityArg->hConstrainingVidPn;
1521 const DXGK_VIDPN_INTERFACE* pVidPnInterface = pCbContext->pVidPnInterface;
1522 NTSTATUS Status = STATUS_SUCCESS;
1523 pCbContext->Status = STATUS_SUCCESS;
1524 PVBOXWDDM_VIDEOMODES_INFO pInfo = &pCbContext->pInfos[VidPnTargetId];
1525
1526 D3DKMDT_ENUMCOFUNCMODALITY_PIVOT_TYPE enmPivot = vboxVidPnCofuncModalityCurrentPathPivot(pCbContext->pEnumCofuncModalityArg, VidPnSourceId, VidPnTargetId);
1527 BOOLEAN fHasPinnedMode = FALSE;
1528 Status = vboxVidPnHasPinnedTargetMode(hVidPn, pVidPnInterface, VidPnTargetId, &fHasPinnedMode);
1529 if (!NT_SUCCESS(Status))
1530 {
1531 AssertFailed();
1532 return Status;
1533 }
1534
1535 BOOLEAN fNeedUpdate = enmPivot != D3DKMDT_EPT_VIDPNTARGET && !fHasPinnedMode;
1536 if (fNeedUpdate)
1537 {
1538 Status = vboxVidPnCofuncModalityForPathTarget(pCbContext, VidPnSourceId, VidPnTargetId);
1539 }
1540
1541 if (NT_SUCCESS(Status))
1542 {
1543 fHasPinnedMode = FALSE;
1544 Status = vboxVidPnHasPinnedSourceMode(hVidPn, pVidPnInterface, VidPnSourceId, &fHasPinnedMode);
1545 if (!NT_SUCCESS(Status))
1546 {
1547 AssertFailed();
1548 return Status;
1549 }
1550
1551 fNeedUpdate = enmPivot != D3DKMDT_EPT_VIDPNSOURCE && !fHasPinnedMode;
1552 if (fNeedUpdate)
1553 {
1554 Status = vboxVidPnCofuncModalityForPathSource(pCbContext, VidPnSourceId, VidPnTargetId);
1555 }
1556 }
1557
1558 return Status;
1559}
1560
1561DECLCALLBACK(BOOLEAN) vboxVidPnCofuncModalityPathEnum(D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface,
1562 const D3DKMDT_VIDPN_PRESENT_PATH *pNewVidPnPresentPathInfo, PVOID pContext)
1563{
1564 PVBOXVIDPNCOFUNCMODALITY pCbContext = (PVBOXVIDPNCOFUNCMODALITY)pContext;
1565 D3DKMDT_VIDPN_PRESENT_PATH AdjustedPath = {0};
1566 NTSTATUS Status = STATUS_SUCCESS;
1567 bool bUpdatePath = false;
1568 AdjustedPath.VidPnSourceId = pNewVidPnPresentPathInfo->VidPnSourceId;
1569 AdjustedPath.VidPnTargetId = pNewVidPnPresentPathInfo->VidPnTargetId;
1570 AdjustedPath.ContentTransformation = pNewVidPnPresentPathInfo->ContentTransformation;
1571 AdjustedPath.CopyProtection = pNewVidPnPresentPathInfo->CopyProtection;
1572
1573 if (pNewVidPnPresentPathInfo->ContentTransformation.Scaling == D3DKMDT_VPPS_UNPINNED)
1574 {
1575 AdjustedPath.ContentTransformation.ScalingSupport.Identity = TRUE;
1576 bUpdatePath = true;
1577 }
1578
1579 if (pNewVidPnPresentPathInfo->ContentTransformation.Rotation == D3DKMDT_VPPR_UNPINNED)
1580 {
1581 AdjustedPath.ContentTransformation.RotationSupport.Identity = TRUE;
1582 bUpdatePath = true;
1583 }
1584
1585 if (bUpdatePath)
1586 {
1587 Status = pVidPnTopologyInterface->pfnUpdatePathSupportInfo(hVidPnTopology, &AdjustedPath);
1588 Assert(Status == STATUS_SUCCESS);
1589 }
1590
1591 Status = vboxVidPnCofuncModalityForPath(pCbContext, pNewVidPnPresentPathInfo->VidPnSourceId, pNewVidPnPresentPathInfo->VidPnTargetId);
1592
1593 pVidPnTopologyInterface->pfnReleasePathInfo(hVidPnTopology, pNewVidPnPresentPathInfo);
1594
1595 pCbContext->Status = Status;
1596 Assert(Status == STATUS_SUCCESS);
1597 return Status == STATUS_SUCCESS;
1598}
1599
1600static BOOLEAN vboxVidPnIsPathSupported(const D3DKMDT_VIDPN_PRESENT_PATH *pNewVidPnPresentPathInfo)
1601{
1602 if (pNewVidPnPresentPathInfo->VidPnSourceId != pNewVidPnPresentPathInfo->VidPnTargetId)
1603 {
1604 LOG(("unsupported source(%d)->target(%d) pair", pNewVidPnPresentPathInfo->VidPnSourceId, pNewVidPnPresentPathInfo->VidPnTargetId));
1605 return FALSE;
1606 }
1607
1608 /*
1609 ImportanceOrdinal does not matter for now
1610 pNewVidPnPresentPathInfo->ImportanceOrdinal
1611 */
1612
1613 if (pNewVidPnPresentPathInfo->ContentTransformation.Scaling != D3DKMDT_VPPS_UNPINNED
1614 && pNewVidPnPresentPathInfo->ContentTransformation.Scaling != D3DKMDT_VPPS_IDENTITY
1615 && pNewVidPnPresentPathInfo->ContentTransformation.Scaling != D3DKMDT_VPPS_NOTSPECIFIED)
1616 {
1617 WARN(("unsupported Scaling (%d)", pNewVidPnPresentPathInfo->ContentTransformation.Scaling));
1618 return FALSE;
1619 }
1620
1621 if ( !pNewVidPnPresentPathInfo->ContentTransformation.ScalingSupport.Identity
1622 || pNewVidPnPresentPathInfo->ContentTransformation.ScalingSupport.Centered
1623 || pNewVidPnPresentPathInfo->ContentTransformation.ScalingSupport.Stretched)
1624 {
1625 WARN(("unsupported Scaling support"));
1626 return FALSE;
1627 }
1628
1629 if (pNewVidPnPresentPathInfo->ContentTransformation.Rotation != D3DKMDT_VPPR_UNPINNED
1630 && pNewVidPnPresentPathInfo->ContentTransformation.Rotation != D3DKMDT_VPPR_IDENTITY
1631 && pNewVidPnPresentPathInfo->ContentTransformation.Rotation != D3DKMDT_VPPR_NOTSPECIFIED)
1632 {
1633 WARN(("unsupported rotation (%d)", pNewVidPnPresentPathInfo->ContentTransformation.Rotation));
1634 return FALSE;
1635 }
1636
1637 if ( !pNewVidPnPresentPathInfo->ContentTransformation.RotationSupport.Identity
1638 || pNewVidPnPresentPathInfo->ContentTransformation.RotationSupport.Rotate90
1639 || pNewVidPnPresentPathInfo->ContentTransformation.RotationSupport.Rotate180
1640 || pNewVidPnPresentPathInfo->ContentTransformation.RotationSupport.Rotate270)
1641 {
1642 WARN(("unsupported RotationSupport"));
1643 return FALSE;
1644 }
1645
1646 if (pNewVidPnPresentPathInfo->VisibleFromActiveTLOffset.cx
1647 || pNewVidPnPresentPathInfo->VisibleFromActiveTLOffset.cy)
1648 {
1649 WARN(("Non-zero TLOffset: cx(%d), cy(%d)",
1650 pNewVidPnPresentPathInfo->VisibleFromActiveTLOffset.cx,
1651 pNewVidPnPresentPathInfo->VisibleFromActiveTLOffset.cy));
1652 return FALSE;
1653 }
1654
1655 if (pNewVidPnPresentPathInfo->VisibleFromActiveBROffset.cx
1656 || pNewVidPnPresentPathInfo->VisibleFromActiveBROffset.cy)
1657 {
1658 WARN(("Non-zero TLOffset: cx(%d), cy(%d)",
1659 pNewVidPnPresentPathInfo->VisibleFromActiveBROffset.cx,
1660 pNewVidPnPresentPathInfo->VisibleFromActiveBROffset.cy));
1661 return FALSE;
1662 }
1663
1664 if (pNewVidPnPresentPathInfo->VidPnTargetColorBasis != D3DKMDT_CB_SRGB
1665 && pNewVidPnPresentPathInfo->VidPnTargetColorBasis != D3DKMDT_CB_UNINITIALIZED)
1666 {
1667 WARN(("unsupported VidPnTargetColorBasis (%d)", pNewVidPnPresentPathInfo->VidPnTargetColorBasis));
1668 return FALSE;
1669 }
1670
1671 /* channels?
1672 pNewVidPnPresentPathInfo->VidPnTargetColorCoeffDynamicRanges.FirstChannel;
1673 pNewVidPnPresentPathInfo->VidPnTargetColorCoeffDynamicRanges.SecondChannel;
1674 pNewVidPnPresentPathInfo->VidPnTargetColorCoeffDynamicRanges.ThirdChannel;
1675 we definitely not support fourth channel
1676 */
1677 if (pNewVidPnPresentPathInfo->VidPnTargetColorCoeffDynamicRanges.FourthChannel)
1678 {
1679 WARN(("Non-zero FourthChannel (%d)", pNewVidPnPresentPathInfo->VidPnTargetColorCoeffDynamicRanges.FourthChannel));
1680 return FALSE;
1681 }
1682
1683 /* Content (D3DKMDT_VPPC_GRAPHICS, _NOTSPECIFIED, _VIDEO), does not matter for now
1684 pNewVidPnPresentPathInfo->Content
1685 */
1686 /* not support copy protection for now */
1687 if (pNewVidPnPresentPathInfo->CopyProtection.CopyProtectionType != D3DKMDT_VPPMT_NOPROTECTION
1688 && pNewVidPnPresentPathInfo->CopyProtection.CopyProtectionType != D3DKMDT_VPPMT_UNINITIALIZED)
1689 {
1690 WARN(("Copy protection not supported CopyProtectionType(%d)", pNewVidPnPresentPathInfo->CopyProtection.CopyProtectionType));
1691 return FALSE;
1692 }
1693
1694 if (pNewVidPnPresentPathInfo->CopyProtection.APSTriggerBits)
1695 {
1696 WARN(("Copy protection not supported APSTriggerBits(%d)", pNewVidPnPresentPathInfo->CopyProtection.APSTriggerBits));
1697 return FALSE;
1698 }
1699
1700 D3DKMDT_VIDPN_PRESENT_PATH_COPYPROTECTION_SUPPORT tstCPSupport = {0};
1701 tstCPSupport.NoProtection = 1;
1702 if (memcmp(&tstCPSupport, &pNewVidPnPresentPathInfo->CopyProtection.CopyProtectionSupport, sizeof(tstCPSupport)))
1703 {
1704 WARN(("Copy protection support (0x%x)", *((UINT*)&pNewVidPnPresentPathInfo->CopyProtection.CopyProtectionSupport)));
1705 return FALSE;
1706 }
1707
1708 if (pNewVidPnPresentPathInfo->GammaRamp.Type != D3DDDI_GAMMARAMP_DEFAULT
1709 && pNewVidPnPresentPathInfo->GammaRamp.Type != D3DDDI_GAMMARAMP_UNINITIALIZED)
1710 {
1711 WARN(("Unsupported GammaRamp.Type (%d)", pNewVidPnPresentPathInfo->GammaRamp.Type));
1712 return FALSE;
1713 }
1714
1715 if (pNewVidPnPresentPathInfo->GammaRamp.DataSize != 0)
1716 {
1717 WARN(("Warning: non-zero GammaRamp.DataSize (%d), treating as supported", pNewVidPnPresentPathInfo->GammaRamp.DataSize));
1718 }
1719
1720 return TRUE;
1721}
1722
1723typedef struct VBOXVIDPNGETPATHSINFO
1724{
1725 NTSTATUS Status;
1726 BOOLEAN fBreakOnDisabled;
1727 BOOLEAN fDisabledFound;
1728 UINT cItems;
1729 PVBOXVIDPNPATHITEM paItems;
1730} VBOXVIDPNGETPATHSINFO, *PVBOXVIDPNGETPATHSINFO;
1731
1732static DECLCALLBACK(BOOLEAN) vboxVidPnCheckTopologyEnum(D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface,
1733 const D3DKMDT_VIDPN_PRESENT_PATH *pNewVidPnPresentPathInfo, PVOID pContext)
1734{
1735 PVBOXVIDPNGETPATHSINFO pCbContext = (PVBOXVIDPNGETPATHSINFO)pContext;
1736 NTSTATUS Status = STATUS_SUCCESS;
1737 CONST D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId = pNewVidPnPresentPathInfo->VidPnSourceId;
1738 CONST D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId = pNewVidPnPresentPathInfo->VidPnTargetId;
1739 BOOLEAN fDisabledFound = !vboxVidPnIsPathSupported(pNewVidPnPresentPathInfo);
1740 do
1741 {
1742 if (fDisabledFound)
1743 {
1744 if (pCbContext->cItems > VidPnSourceId)
1745 {
1746 pCbContext->paItems[VidPnSourceId].enmState = VBOXVIDPNPATHITEM_STATE_DISABLED;
1747 }
1748 else
1749 {
1750 WARN(("cItems(%d) <= VidPnSourceId(%d)", pCbContext->cItems, VidPnSourceId));
1751 Status = STATUS_BUFFER_OVERFLOW;
1752 break;
1753 }
1754
1755 if (pCbContext->cItems > VidPnTargetId)
1756 {
1757 pCbContext->paItems[VidPnTargetId].enmState = VBOXVIDPNPATHITEM_STATE_DISABLED;
1758 }
1759 else
1760 {
1761 WARN(("cItems(%d) <= VidPnTargetId(%d)", pCbContext->cItems, VidPnTargetId));
1762 Status = STATUS_BUFFER_OVERFLOW;
1763 break;
1764 }
1765
1766 break;
1767 }
1768
1769 /* VidPnSourceId == VidPnTargetId */
1770 Assert(VidPnSourceId == VidPnTargetId);
1771 if (pCbContext->cItems > VidPnSourceId)
1772 {
1773 if (pCbContext->paItems[VidPnSourceId].enmState != VBOXVIDPNPATHITEM_STATE_DISABLED)
1774 {
1775 Assert(pCbContext->paItems[VidPnSourceId].enmState == VBOXVIDPNPATHITEM_STATE_NOT_EXISTS);
1776 pCbContext->paItems[VidPnSourceId].enmState = VBOXVIDPNPATHITEM_STATE_PRESENT;
1777 }
1778 }
1779 else
1780 {
1781 WARN(("cItems(%d) <= VidPnSource/TargetId(%d)", pCbContext->cItems, VidPnSourceId));
1782 Status = STATUS_BUFFER_OVERFLOW;
1783 break;
1784 }
1785 } while (0);
1786
1787 pCbContext->fDisabledFound |= fDisabledFound;
1788 pCbContext->Status = Status;
1789 if (!NT_SUCCESS(Status))
1790 return FALSE; /* do not continue on failure */
1791
1792 return !fDisabledFound || !pCbContext->fBreakOnDisabled;
1793}
1794
1795/* we currently support only 0 -> 0, 1 -> 1, 2 -> 2 paths, AND 0 -> 0 must be present
1796 * this routine disables all paths unsupported */
1797NTSTATUS vboxVidPnCheckTopology(D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface, BOOLEAN *pfSupported)
1798{
1799 VBOXVIDPNPATHITEM aItems[VBOX_VIDEO_MAX_SCREENS];
1800 const uint32_t cItems = RT_ELEMENTS(aItems);
1801 UINT i;
1802 for (i = 0; i < cItems; ++i)
1803 {
1804 aItems[i].enmState = VBOXVIDPNPATHITEM_STATE_NOT_EXISTS;
1805 }
1806 VBOXVIDPNGETPATHSINFO CbContext = {0};
1807 CbContext.Status = STATUS_SUCCESS;
1808 CbContext.fBreakOnDisabled = FALSE;
1809 CbContext.fDisabledFound = FALSE;
1810 CbContext.cItems = cItems;
1811 CbContext.paItems = aItems;
1812 NTSTATUS Status = vboxVidPnEnumPaths(hVidPnTopology, pVidPnTopologyInterface, vboxVidPnCheckTopologyEnum, &CbContext);
1813 if (!NT_SUCCESS(Status))
1814 {
1815 WARN(("vboxVidPnEnumPaths failed Status()0x%x\n", Status));
1816 return Status;
1817 }
1818
1819 Status = CbContext.Status;
1820 if (!NT_SUCCESS(Status))
1821 {
1822 WARN(("vboxVidPnCheckTopologyEnum returned failed Status()0x%x\n", Status));
1823 return Status;
1824 }
1825
1826 BOOLEAN fSupported = !CbContext.fDisabledFound;
1827
1828 /* now check if 0->0 path is present and enabled, and if not, disable everything */
1829// if (cItems && aItems[0].enmState != VBOXVIDPNPATHITEM_STATE_PRESENT)
1830// {
1831// LOG(("path 0 not set to present\n"));
1832//// for (i = 0; i < cItems; ++i)
1833//// {
1834//// if (aItems[i].enmState == VBOXVIDPNPATHITEM_STATE_PRESENT)
1835//// aItems[i].enmState = VBOXVIDPNPATHITEM_STATE_DISABLED;
1836//// }
1837// fSupported = FALSE;
1838// }
1839
1840 if (pfSupported)
1841 *pfSupported = fSupported;
1842
1843 return Status;
1844}
1845
1846NTSTATUS vboxVidPnEnumMonitorSourceModes(D3DKMDT_HMONITORSOURCEMODESET hMonitorSMS, CONST DXGK_MONITORSOURCEMODESET_INTERFACE *pMonitorSMSIf,
1847 PFNVBOXVIDPNENUMMONITORSOURCEMODES pfnCallback, PVOID pContext)
1848{
1849 CONST D3DKMDT_MONITOR_SOURCE_MODE *pMonitorSMI;
1850 NTSTATUS Status = pMonitorSMSIf->pfnAcquireFirstModeInfo(hMonitorSMS, &pMonitorSMI);
1851 Assert(Status == STATUS_SUCCESS || Status == STATUS_GRAPHICS_DATASET_IS_EMPTY);
1852 if (Status == STATUS_SUCCESS)
1853 {
1854 Assert(pMonitorSMI);
1855 while (1)
1856 {
1857 CONST D3DKMDT_MONITOR_SOURCE_MODE *pNextMonitorSMI;
1858 Status = pMonitorSMSIf->pfnAcquireNextModeInfo(hMonitorSMS, pMonitorSMI, &pNextMonitorSMI);
1859 if (!pfnCallback(hMonitorSMS, pMonitorSMSIf, pMonitorSMI, pContext))
1860 {
1861 Assert(Status == STATUS_SUCCESS || Status == STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET);
1862 if (Status == STATUS_SUCCESS)
1863 pMonitorSMSIf->pfnReleaseModeInfo(hMonitorSMS, pNextMonitorSMI);
1864 else if (Status == STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET)
1865 {
1866 Status = STATUS_SUCCESS;
1867 break;
1868 }
1869 else
1870 {
1871 LOGREL(("pfnAcquireNextModeInfo Failed Status(0x%x), ignored since callback returned false", Status));
1872 Status = STATUS_SUCCESS;
1873 }
1874 break;
1875 }
1876 else if (Status == STATUS_SUCCESS)
1877 pMonitorSMI = pNextMonitorSMI;
1878 else if (Status == STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET)
1879 {
1880 Status = STATUS_SUCCESS;
1881 break;
1882 }
1883 else
1884 {
1885 AssertBreakpoint();
1886 LOGREL(("pfnAcquireNextModeInfo Failed Status(0x%x)", Status));
1887 pNextMonitorSMI = NULL;
1888 break;
1889 }
1890 }
1891 }
1892 else if (Status == STATUS_GRAPHICS_DATASET_IS_EMPTY)
1893 Status = STATUS_SUCCESS;
1894 else
1895 LOGREL(("pfnAcquireFirstModeInfo failed Status(0x%x)", Status));
1896
1897 return Status;
1898}
1899
1900NTSTATUS vboxVidPnEnumSourceModes(D3DKMDT_HVIDPNSOURCEMODESET hNewVidPnSourceModeSet, const DXGK_VIDPNSOURCEMODESET_INTERFACE *pVidPnSourceModeSetInterface,
1901 PFNVBOXVIDPNENUMSOURCEMODES pfnCallback, PVOID pContext)
1902{
1903 const D3DKMDT_VIDPN_SOURCE_MODE *pNewVidPnSourceModeInfo;
1904 NTSTATUS Status = pVidPnSourceModeSetInterface->pfnAcquireFirstModeInfo(hNewVidPnSourceModeSet, &pNewVidPnSourceModeInfo);
1905 if (Status == STATUS_SUCCESS)
1906 {
1907 Assert(pNewVidPnSourceModeInfo);
1908 while (1)
1909 {
1910 const D3DKMDT_VIDPN_SOURCE_MODE *pNextVidPnSourceModeInfo;
1911 Status = pVidPnSourceModeSetInterface->pfnAcquireNextModeInfo(hNewVidPnSourceModeSet, pNewVidPnSourceModeInfo, &pNextVidPnSourceModeInfo);
1912 if (!pfnCallback(hNewVidPnSourceModeSet, pVidPnSourceModeSetInterface,
1913 pNewVidPnSourceModeInfo, pContext))
1914 {
1915 Assert(Status == STATUS_SUCCESS);
1916 if (Status == STATUS_SUCCESS)
1917 pVidPnSourceModeSetInterface->pfnReleaseModeInfo(hNewVidPnSourceModeSet, pNextVidPnSourceModeInfo);
1918 else if (Status == STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET)
1919 {
1920 Status = STATUS_SUCCESS;
1921 break;
1922 }
1923 else
1924 {
1925 LOGREL(("pfnAcquireNextModeInfo Failed Status(0x%x), ignored since callback returned false", Status));
1926 Status = STATUS_SUCCESS;
1927 }
1928
1929 break;
1930 }
1931 else if (Status == STATUS_SUCCESS)
1932 pNewVidPnSourceModeInfo = pNextVidPnSourceModeInfo;
1933 else if (Status == STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET)
1934 {
1935 Status = STATUS_SUCCESS;
1936 break;
1937 }
1938 else
1939 {
1940 AssertBreakpoint();
1941 LOGREL(("pfnAcquireNextModeInfo Failed Status(0x%x)", Status));
1942 pNewVidPnSourceModeInfo = NULL;
1943 break;
1944 }
1945 }
1946 }
1947 else if (Status == STATUS_GRAPHICS_DATASET_IS_EMPTY)
1948 Status = STATUS_SUCCESS;
1949 else
1950 LOGREL(("pfnAcquireFirstModeInfo failed Status(0x%x)", Status));
1951
1952 return Status;
1953}
1954
1955NTSTATUS vboxVidPnEnumTargetModes(D3DKMDT_HVIDPNTARGETMODESET hNewVidPnTargetModeSet, const DXGK_VIDPNTARGETMODESET_INTERFACE *pVidPnTargetModeSetInterface,
1956 PFNVBOXVIDPNENUMTARGETMODES pfnCallback, PVOID pContext)
1957{
1958 const D3DKMDT_VIDPN_TARGET_MODE *pNewVidPnTargetModeInfo;
1959 NTSTATUS Status = pVidPnTargetModeSetInterface->pfnAcquireFirstModeInfo(hNewVidPnTargetModeSet, &pNewVidPnTargetModeInfo);
1960 if (Status == STATUS_SUCCESS)
1961 {
1962 Assert(pNewVidPnTargetModeInfo);
1963 while (1)
1964 {
1965 const D3DKMDT_VIDPN_TARGET_MODE *pNextVidPnTargetModeInfo;
1966 Status = pVidPnTargetModeSetInterface->pfnAcquireNextModeInfo(hNewVidPnTargetModeSet, pNewVidPnTargetModeInfo, &pNextVidPnTargetModeInfo);
1967 if (!pfnCallback(hNewVidPnTargetModeSet, pVidPnTargetModeSetInterface,
1968 pNewVidPnTargetModeInfo, pContext))
1969 {
1970 Assert(Status == STATUS_SUCCESS);
1971 if (Status == STATUS_SUCCESS)
1972 pVidPnTargetModeSetInterface->pfnReleaseModeInfo(hNewVidPnTargetModeSet, pNextVidPnTargetModeInfo);
1973 else if (Status == STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET)
1974 {
1975 Status = STATUS_SUCCESS;
1976 break;
1977 }
1978 else
1979 {
1980 LOGREL(("pfnAcquireNextModeInfo Failed Status(0x%x), ignored since callback returned false", Status));
1981 Status = STATUS_SUCCESS;
1982 }
1983
1984 break;
1985 }
1986 else if (Status == STATUS_SUCCESS)
1987 pNewVidPnTargetModeInfo = pNextVidPnTargetModeInfo;
1988 else if (Status == STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET)
1989 {
1990 Status = STATUS_SUCCESS;
1991 break;
1992 }
1993 else
1994 {
1995 AssertBreakpoint();
1996 LOGREL(("pfnAcquireNextModeInfo Failed Status(0x%x)", Status));
1997 pNewVidPnTargetModeInfo = NULL;
1998 break;
1999 }
2000 }
2001 }
2002 else if (Status == STATUS_GRAPHICS_DATASET_IS_EMPTY)
2003 Status = STATUS_SUCCESS;
2004 else
2005 LOGREL(("pfnAcquireFirstModeInfo failed Status(0x%x)", Status));
2006
2007 return Status;
2008}
2009
2010NTSTATUS vboxVidPnEnumTargetsForSource(PVBOXMP_DEVEXT pDevExt, D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface,
2011 CONST D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId,
2012 PFNVBOXVIDPNENUMTARGETSFORSOURCE pfnCallback, PVOID pContext)
2013{
2014 SIZE_T cTgtPaths;
2015 NTSTATUS Status = pVidPnTopologyInterface->pfnGetNumPathsFromSource(hVidPnTopology, VidPnSourceId, &cTgtPaths);
2016 Assert(Status == STATUS_SUCCESS || Status == STATUS_GRAPHICS_SOURCE_NOT_IN_TOPOLOGY);
2017 if (Status == STATUS_SUCCESS)
2018 {
2019 for (SIZE_T i = 0; i < cTgtPaths; ++i)
2020 {
2021 D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId;
2022 Status = pVidPnTopologyInterface->pfnEnumPathTargetsFromSource(hVidPnTopology, VidPnSourceId, i, &VidPnTargetId);
2023 Assert(Status == STATUS_SUCCESS);
2024 if (Status == STATUS_SUCCESS)
2025 {
2026 if (!pfnCallback(pDevExt, hVidPnTopology, pVidPnTopologyInterface, VidPnSourceId, VidPnTargetId, cTgtPaths, pContext))
2027 break;
2028 }
2029 else
2030 {
2031 LOGREL(("pfnEnumPathTargetsFromSource failed Status(0x%x)", Status));
2032 break;
2033 }
2034 }
2035 }
2036 else if (Status != STATUS_GRAPHICS_SOURCE_NOT_IN_TOPOLOGY)
2037 LOGREL(("pfnGetNumPathsFromSource failed Status(0x%x)", Status));
2038
2039 return Status;
2040}
2041
2042NTSTATUS vboxVidPnEnumPaths(D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface,
2043 PFNVBOXVIDPNENUMPATHS pfnCallback, PVOID pContext)
2044{
2045 const D3DKMDT_VIDPN_PRESENT_PATH *pNewVidPnPresentPathInfo = NULL;
2046 NTSTATUS Status = pVidPnTopologyInterface->pfnAcquireFirstPathInfo(hVidPnTopology, &pNewVidPnPresentPathInfo);
2047 if (Status == STATUS_SUCCESS)
2048 {
2049 while (1)
2050 {
2051 const D3DKMDT_VIDPN_PRESENT_PATH *pNextVidPnPresentPathInfo;
2052 Status = pVidPnTopologyInterface->pfnAcquireNextPathInfo(hVidPnTopology, pNewVidPnPresentPathInfo, &pNextVidPnPresentPathInfo);
2053
2054 if (!pfnCallback(hVidPnTopology, pVidPnTopologyInterface, pNewVidPnPresentPathInfo, pContext))
2055 {
2056 if (Status == STATUS_SUCCESS)
2057 pVidPnTopologyInterface->pfnReleasePathInfo(hVidPnTopology, pNextVidPnPresentPathInfo);
2058 else
2059 {
2060 if (Status != STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET)
2061 WARN(("pfnAcquireNextPathInfo Failed Status(0x%x), ignored since callback returned false", Status));
2062 Status = STATUS_SUCCESS;
2063 }
2064
2065 break;
2066 }
2067 else if (Status == STATUS_SUCCESS)
2068 pNewVidPnPresentPathInfo = pNextVidPnPresentPathInfo;
2069 else if (Status == STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET)
2070 {
2071 Status = STATUS_SUCCESS;
2072 break;
2073 }
2074 else
2075 {
2076 WARN(("pfnAcquireNextPathInfo Failed Status(0x%x)", Status));
2077 pNewVidPnPresentPathInfo = NULL;
2078 break;
2079 }
2080 }
2081 }
2082 else if (Status == STATUS_GRAPHICS_DATASET_IS_EMPTY)
2083 Status = STATUS_SUCCESS;
2084 else
2085 WARN(("pfnAcquireFirstModeInfo failed Status(0x%x)", Status));
2086
2087 return Status;
2088}
2089
2090NTSTATUS vboxVidPnSetupSourceInfo(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId, PVBOXWDDM_SOURCE pSource, CONST D3DKMDT_VIDPN_SOURCE_MODE* pVidPnSourceModeInfo, PVBOXWDDM_ALLOCATION pAllocation)
2091{
2092 /* pVidPnSourceModeInfo could be null if STATUS_GRAPHICS_MODE_NOT_PINNED,
2093 * see vboxVidPnCommitSourceModeForSrcId */
2094 uint8_t fChanges = 0;
2095 if (pVidPnSourceModeInfo)
2096 {
2097 if (pSource->AllocData.SurfDesc.width != pVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cx)
2098 {
2099 fChanges |= VBOXWDDM_HGSYNC_F_SYNCED_DIMENSIONS;
2100 pSource->AllocData.SurfDesc.width = pVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cx;
2101 }
2102 if (pSource->AllocData.SurfDesc.height != pVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cy)
2103 {
2104 fChanges |= VBOXWDDM_HGSYNC_F_SYNCED_DIMENSIONS;
2105 pSource->AllocData.SurfDesc.height = pVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cy;
2106 }
2107 if (pSource->AllocData.SurfDesc.format != pVidPnSourceModeInfo->Format.Graphics.PixelFormat)
2108 {
2109 fChanges |= VBOXWDDM_HGSYNC_F_SYNCED_DIMENSIONS;
2110 pSource->AllocData.SurfDesc.format = pVidPnSourceModeInfo->Format.Graphics.PixelFormat;
2111 }
2112 if (pSource->AllocData.SurfDesc.bpp != vboxWddmCalcBitsPerPixel(pVidPnSourceModeInfo->Format.Graphics.PixelFormat))
2113 {
2114 fChanges |= VBOXWDDM_HGSYNC_F_SYNCED_DIMENSIONS;
2115 pSource->AllocData.SurfDesc.bpp = vboxWddmCalcBitsPerPixel(pVidPnSourceModeInfo->Format.Graphics.PixelFormat);
2116 }
2117 if(pSource->AllocData.SurfDesc.pitch != pVidPnSourceModeInfo->Format.Graphics.Stride)
2118 {
2119 fChanges |= VBOXWDDM_HGSYNC_F_SYNCED_DIMENSIONS;
2120 pSource->AllocData.SurfDesc.pitch = pVidPnSourceModeInfo->Format.Graphics.Stride;
2121 }
2122 pSource->AllocData.SurfDesc.depth = 1;
2123 if (pSource->AllocData.SurfDesc.slicePitch != pVidPnSourceModeInfo->Format.Graphics.Stride)
2124 {
2125 fChanges |= VBOXWDDM_HGSYNC_F_SYNCED_DIMENSIONS;
2126 pSource->AllocData.SurfDesc.slicePitch = pVidPnSourceModeInfo->Format.Graphics.Stride;
2127 }
2128 if (pSource->AllocData.SurfDesc.cbSize != pVidPnSourceModeInfo->Format.Graphics.Stride * pVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cy)
2129 {
2130 fChanges |= VBOXWDDM_HGSYNC_F_SYNCED_DIMENSIONS;
2131 pSource->AllocData.SurfDesc.cbSize = pVidPnSourceModeInfo->Format.Graphics.Stride * pVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cy;
2132 }
2133#ifdef VBOX_WDDM_WIN8
2134 if (g_VBoxDisplayOnly)
2135 {
2136 vboxWddmDmAdjustDefaultVramLocations(pDevExt, srcId);
2137 }
2138#endif
2139 }
2140 else
2141 {
2142 Assert(!pAllocation);
2143 fChanges |= VBOXWDDM_HGSYNC_F_SYNCED_ALL;
2144 }
2145
2146 vboxWddmAssignPrimary(pDevExt, pSource, pAllocation, srcId);
2147
2148 Assert(pSource->AllocData.SurfDesc.VidPnSourceId == srcId);
2149 pSource->u8SyncState &= ~fChanges;
2150 return STATUS_SUCCESS;
2151}
2152
2153NTSTATUS vboxVidPnCommitSourceMode(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId, CONST D3DKMDT_VIDPN_SOURCE_MODE* pVidPnSourceModeInfo, PVBOXWDDM_ALLOCATION pAllocation)
2154{
2155 Assert(srcId < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays);
2156 if (srcId < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays)
2157 {
2158 PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[srcId];
2159 return vboxVidPnSetupSourceInfo(pDevExt, srcId, pSource, pVidPnSourceModeInfo, pAllocation);
2160 }
2161
2162 LOGREL(("invalid srcId (%d), cSources(%d)", srcId, VBoxCommonFromDeviceExt(pDevExt)->cDisplays));
2163 return STATUS_INVALID_PARAMETER;
2164}
2165
2166typedef struct VBOXVIDPNCOMMITTARGETMODE
2167{
2168 NTSTATUS Status;
2169 D3DKMDT_HVIDPN hVidPn;
2170 const DXGK_VIDPN_INTERFACE* pVidPnInterface;
2171} VBOXVIDPNCOMMITTARGETMODE;
2172
2173DECLCALLBACK(BOOLEAN) vboxVidPnCommitTargetModeEnum(PVBOXMP_DEVEXT pDevExt, D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface,
2174 CONST D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId, SIZE_T cTgtPaths, PVOID pContext)
2175{
2176 VBOXVIDPNCOMMITTARGETMODE *pInfo = (VBOXVIDPNCOMMITTARGETMODE*)pContext;
2177 Assert(cTgtPaths <= (SIZE_T)VBoxCommonFromDeviceExt(pDevExt)->cDisplays);
2178 D3DKMDT_HVIDPNTARGETMODESET hVidPnTargetModeSet;
2179 CONST DXGK_VIDPNTARGETMODESET_INTERFACE* pVidPnTargetModeSetInterface;
2180 NTSTATUS Status = pInfo->pVidPnInterface->pfnAcquireTargetModeSet(pInfo->hVidPn, VidPnTargetId, &hVidPnTargetModeSet, &pVidPnTargetModeSetInterface);
2181 Assert(Status == STATUS_SUCCESS);
2182 if (Status == STATUS_SUCCESS)
2183 {
2184 CONST D3DKMDT_VIDPN_TARGET_MODE* pPinnedVidPnTargetModeInfo;
2185 Status = pVidPnTargetModeSetInterface->pfnAcquirePinnedModeInfo(hVidPnTargetModeSet, &pPinnedVidPnTargetModeInfo);
2186 Assert(Status == STATUS_SUCCESS);
2187 if (Status == STATUS_SUCCESS)
2188 {
2189 VBOXWDDM_TARGET *pTarget = &pDevExt->aTargets[VidPnTargetId];
2190 if (pTarget->HeightVisible != pPinnedVidPnTargetModeInfo->VideoSignalInfo.ActiveSize.cy
2191 || pTarget->HeightTotal != pPinnedVidPnTargetModeInfo->VideoSignalInfo.TotalSize.cy)
2192 {
2193 pTarget->HeightVisible = pPinnedVidPnTargetModeInfo->VideoSignalInfo.ActiveSize.cy;
2194 pTarget->HeightTotal = pPinnedVidPnTargetModeInfo->VideoSignalInfo.TotalSize.cy;
2195 }
2196 pVidPnTargetModeSetInterface->pfnReleaseModeInfo(hVidPnTargetModeSet, pPinnedVidPnTargetModeInfo);
2197 }
2198
2199 pInfo->pVidPnInterface->pfnReleaseTargetModeSet(pInfo->hVidPn, hVidPnTargetModeSet);
2200 }
2201 else
2202 LOGREL(("pfnAcquireTargetModeSet failed Status(0x%x)", Status));
2203
2204 pInfo->Status = Status;
2205 return Status == STATUS_SUCCESS;
2206}
2207
2208#ifdef DEBUG_misha
2209DWORD g_VBoxDbgBreakModes = 0;
2210#endif
2211
2212NTSTATUS vboxVidPnCommitSourceModeForSrcId(PVBOXMP_DEVEXT pDevExt, const D3DKMDT_HVIDPN hDesiredVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId, PVBOXWDDM_ALLOCATION pAllocation)
2213{
2214 D3DKMDT_HVIDPNSOURCEMODESET hCurVidPnSourceModeSet;
2215 const DXGK_VIDPNSOURCEMODESET_INTERFACE *pCurVidPnSourceModeSetInterface;
2216
2217#ifdef DEBUG_misha
2218 if (pAllocation)
2219 {
2220 Assert(pAllocation->AllocData.SurfDesc.VidPnSourceId == srcId);
2221 }
2222#endif
2223
2224 NTSTATUS Status = pVidPnInterface->pfnAcquireSourceModeSet(hDesiredVidPn,
2225 srcId,
2226 &hCurVidPnSourceModeSet,
2227 &pCurVidPnSourceModeSetInterface);
2228 Assert(Status == STATUS_SUCCESS);
2229 if (Status == STATUS_SUCCESS)
2230 {
2231 CONST D3DKMDT_VIDPN_SOURCE_MODE* pPinnedVidPnSourceModeInfo;
2232 Status = pCurVidPnSourceModeSetInterface->pfnAcquirePinnedModeInfo(hCurVidPnSourceModeSet, &pPinnedVidPnSourceModeInfo);
2233 Assert(Status == STATUS_SUCCESS || Status == STATUS_GRAPHICS_MODE_NOT_PINNED);
2234 if (Status == STATUS_SUCCESS)
2235 {
2236 Assert(pPinnedVidPnSourceModeInfo);
2237 Status = vboxVidPnCommitSourceMode(pDevExt, srcId, pPinnedVidPnSourceModeInfo, pAllocation);
2238 Assert(Status == STATUS_SUCCESS);
2239 if (Status == STATUS_SUCCESS)
2240 {
2241 D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology;
2242 CONST DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface;
2243 Status = pVidPnInterface->pfnGetTopology(hDesiredVidPn, &hVidPnTopology, &pVidPnTopologyInterface);
2244 Assert(Status == STATUS_SUCCESS);
2245 if (Status == STATUS_SUCCESS)
2246 {
2247 VBOXVIDPNCOMMITTARGETMODE TgtModeInfo = {0};
2248 TgtModeInfo.Status = STATUS_SUCCESS; /* <- to ensure we're succeeded if no targets are set */
2249 TgtModeInfo.hVidPn = hDesiredVidPn;
2250 TgtModeInfo.pVidPnInterface = pVidPnInterface;
2251 Status = vboxVidPnEnumTargetsForSource(pDevExt, hVidPnTopology, pVidPnTopologyInterface,
2252 srcId,
2253 vboxVidPnCommitTargetModeEnum, &TgtModeInfo);
2254 Assert(Status == STATUS_SUCCESS || Status == STATUS_GRAPHICS_SOURCE_NOT_IN_TOPOLOGY);
2255 if (Status == STATUS_SUCCESS)
2256 {
2257 Status = TgtModeInfo.Status;
2258 Assert(Status == STATUS_SUCCESS);
2259 }
2260 else if (Status == STATUS_GRAPHICS_SOURCE_NOT_IN_TOPOLOGY)
2261 {
2262 Status = STATUS_SUCCESS;
2263 }
2264 else
2265 WARN(("vboxVidPnEnumTargetsForSource failed Status(0x%x)", Status));
2266 }
2267 else
2268 WARN(("pfnGetTopology failed Status(0x%x)", Status));
2269 }
2270 else
2271 WARN(("vboxVidPnCommitSourceMode failed Status(0x%x)", Status));
2272 /* release */
2273 pCurVidPnSourceModeSetInterface->pfnReleaseModeInfo(hCurVidPnSourceModeSet, pPinnedVidPnSourceModeInfo);
2274 }
2275 else if (Status == STATUS_GRAPHICS_MODE_NOT_PINNED)
2276 {
2277#ifdef DEBUG_misha
2278 Assert(!g_VBoxDbgBreakModes);
2279 ++g_VBoxDbgBreakModes;
2280#endif
2281 Status = vboxVidPnCommitSourceMode(pDevExt, srcId, NULL, pAllocation);
2282 Assert(Status == STATUS_SUCCESS);
2283 }
2284 else
2285 WARN(("pfnAcquirePinnedModeInfo failed Status(0x%x)", Status));
2286
2287 pVidPnInterface->pfnReleaseSourceModeSet(hDesiredVidPn, hCurVidPnSourceModeSet);
2288 }
2289 else
2290 {
2291 WARN(("pfnAcquireSourceModeSet failed Status(0x%x)", Status));
2292 }
2293
2294 return Status;
2295}
2296
2297DECLCALLBACK(BOOLEAN) vboxVidPnCommitPathEnum(D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface,
2298 const D3DKMDT_VIDPN_PRESENT_PATH *pVidPnPresentPathInfo, PVOID pContext)
2299{
2300 NTSTATUS Status = STATUS_SUCCESS;
2301 PVBOXVIDPNCOMMIT pCommitInfo = (PVBOXVIDPNCOMMIT)pContext;
2302 PVBOXMP_DEVEXT pDevExt = pCommitInfo->pDevExt;
2303 const D3DKMDT_HVIDPN hDesiredVidPn = pCommitInfo->pCommitVidPnArg->hFunctionalVidPn;
2304 const DXGK_VIDPN_INTERFACE* pVidPnInterface = pCommitInfo->pVidPnInterface;
2305
2306 if (pCommitInfo->pCommitVidPnArg->AffectedVidPnSourceId == D3DDDI_ID_ALL
2307 || pCommitInfo->pCommitVidPnArg->AffectedVidPnSourceId == pVidPnPresentPathInfo->VidPnSourceId)
2308 {
2309 Status = vboxVidPnCommitSourceModeForSrcId(pDevExt, hDesiredVidPn, pVidPnInterface, pVidPnPresentPathInfo->VidPnSourceId, (PVBOXWDDM_ALLOCATION)pCommitInfo->pCommitVidPnArg->hPrimaryAllocation);
2310 Assert(Status == STATUS_SUCCESS);
2311 if (Status != STATUS_SUCCESS)
2312 LOGREL(("vboxVidPnCommitSourceModeForSrcId failed Status(0x%x)", Status));
2313 }
2314
2315 pCommitInfo->Status = Status;
2316 pVidPnTopologyInterface->pfnReleasePathInfo(hVidPnTopology, pVidPnPresentPathInfo);
2317 return Status == STATUS_SUCCESS;
2318}
2319
2320#define VBOXVIDPNDUMP_STRCASE(_t) \
2321 case _t: return #_t;
2322#define VBOXVIDPNDUMP_STRCASE_UNKNOWN() \
2323 default: Assert(0); return "Unknown";
2324
2325#define VBOXVIDPNDUMP_STRFLAGS(_v, _t) \
2326 if ((_v)._t return #_t;
2327
2328const char* vboxVidPnDumpStrImportance(D3DKMDT_VIDPN_PRESENT_PATH_IMPORTANCE ImportanceOrdinal)
2329{
2330 switch (ImportanceOrdinal)
2331 {
2332 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPI_UNINITIALIZED);
2333 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPI_PRIMARY);
2334 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPI_SECONDARY);
2335 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPI_TERTIARY);
2336 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPI_QUATERNARY);
2337 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPI_QUINARY);
2338 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPI_SENARY);
2339 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPI_SEPTENARY);
2340 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPI_OCTONARY);
2341 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPI_NONARY);
2342 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPI_DENARY);
2343 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2344 }
2345}
2346
2347const char* vboxVidPnDumpStrScaling(D3DKMDT_VIDPN_PRESENT_PATH_SCALING Scaling)
2348{
2349 switch (Scaling)
2350 {
2351 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPS_UNINITIALIZED);
2352 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPS_IDENTITY);
2353 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPS_CENTERED);
2354 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPS_STRETCHED);
2355 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPS_UNPINNED);
2356 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPS_NOTSPECIFIED);
2357 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2358 }
2359}
2360
2361const char* vboxVidPnDumpStrRotation(D3DKMDT_VIDPN_PRESENT_PATH_ROTATION Rotation)
2362{
2363 switch (Rotation)
2364 {
2365 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPR_UNINITIALIZED);
2366 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPR_IDENTITY);
2367 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPR_ROTATE90);
2368 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPR_ROTATE180);
2369 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPR_ROTATE270);
2370 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPR_UNPINNED);
2371 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPR_NOTSPECIFIED);
2372 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2373 }
2374}
2375
2376const char* vboxVidPnDumpStrColorBasis(const D3DKMDT_COLOR_BASIS ColorBasis)
2377{
2378 switch (ColorBasis)
2379 {
2380 VBOXVIDPNDUMP_STRCASE(D3DKMDT_CB_UNINITIALIZED);
2381 VBOXVIDPNDUMP_STRCASE(D3DKMDT_CB_INTENSITY);
2382 VBOXVIDPNDUMP_STRCASE(D3DKMDT_CB_SRGB);
2383 VBOXVIDPNDUMP_STRCASE(D3DKMDT_CB_SCRGB);
2384 VBOXVIDPNDUMP_STRCASE(D3DKMDT_CB_YCBCR);
2385 VBOXVIDPNDUMP_STRCASE(D3DKMDT_CB_YPBPR);
2386 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2387 }
2388}
2389
2390const char* vboxVidPnDumpStrPvam(D3DKMDT_PIXEL_VALUE_ACCESS_MODE PixelValueAccessMode)
2391{
2392 switch (PixelValueAccessMode)
2393 {
2394 VBOXVIDPNDUMP_STRCASE(D3DKMDT_PVAM_UNINITIALIZED);
2395 VBOXVIDPNDUMP_STRCASE(D3DKMDT_PVAM_DIRECT);
2396 VBOXVIDPNDUMP_STRCASE(D3DKMDT_PVAM_PRESETPALETTE);
2397 VBOXVIDPNDUMP_STRCASE(D3DKMDT_PVAM_SETTABLEPALETTE);
2398 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2399 }
2400}
2401
2402
2403
2404const char* vboxVidPnDumpStrContent(D3DKMDT_VIDPN_PRESENT_PATH_CONTENT Content)
2405{
2406 switch (Content)
2407 {
2408 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPC_UNINITIALIZED);
2409 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPC_GRAPHICS);
2410 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPC_VIDEO);
2411 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPC_NOTSPECIFIED);
2412 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2413 }
2414}
2415
2416const char* vboxVidPnDumpStrCopyProtectionType(D3DKMDT_VIDPN_PRESENT_PATH_COPYPROTECTION_TYPE CopyProtectionType)
2417{
2418 switch (CopyProtectionType)
2419 {
2420 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPMT_UNINITIALIZED);
2421 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPMT_NOPROTECTION);
2422 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPMT_MACROVISION_APSTRIGGER);
2423 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VPPMT_MACROVISION_FULLSUPPORT);
2424 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2425 }
2426}
2427
2428const char* vboxVidPnDumpStrGammaRampType(D3DDDI_GAMMARAMP_TYPE Type)
2429{
2430 switch (Type)
2431 {
2432 VBOXVIDPNDUMP_STRCASE(D3DDDI_GAMMARAMP_UNINITIALIZED);
2433 VBOXVIDPNDUMP_STRCASE(D3DDDI_GAMMARAMP_DEFAULT);
2434 VBOXVIDPNDUMP_STRCASE(D3DDDI_GAMMARAMP_RGB256x3x16);
2435 VBOXVIDPNDUMP_STRCASE(D3DDDI_GAMMARAMP_DXGI_1);
2436 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2437 }
2438}
2439
2440const char* vboxVidPnDumpStrSourceModeType(D3DKMDT_VIDPN_SOURCE_MODE_TYPE Type)
2441{
2442 switch (Type)
2443 {
2444 VBOXVIDPNDUMP_STRCASE(D3DKMDT_RMT_UNINITIALIZED);
2445 VBOXVIDPNDUMP_STRCASE(D3DKMDT_RMT_GRAPHICS);
2446 VBOXVIDPNDUMP_STRCASE(D3DKMDT_RMT_TEXT);
2447 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2448 }
2449}
2450
2451const char* vboxVidPnDumpStrScanLineOrdering(D3DDDI_VIDEO_SIGNAL_SCANLINE_ORDERING ScanLineOrdering)
2452{
2453 switch (ScanLineOrdering)
2454 {
2455 VBOXVIDPNDUMP_STRCASE(D3DDDI_VSSLO_UNINITIALIZED);
2456 VBOXVIDPNDUMP_STRCASE(D3DDDI_VSSLO_PROGRESSIVE);
2457 VBOXVIDPNDUMP_STRCASE(D3DDDI_VSSLO_INTERLACED_UPPERFIELDFIRST);
2458 VBOXVIDPNDUMP_STRCASE(D3DDDI_VSSLO_INTERLACED_LOWERFIELDFIRST);
2459 VBOXVIDPNDUMP_STRCASE(D3DDDI_VSSLO_OTHER);
2460 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2461 }
2462}
2463
2464const char* vboxVidPnDumpStrCFMPivotType(D3DKMDT_ENUMCOFUNCMODALITY_PIVOT_TYPE EnumPivotType)
2465{
2466 switch (EnumPivotType)
2467 {
2468 VBOXVIDPNDUMP_STRCASE(D3DKMDT_EPT_UNINITIALIZED);
2469 VBOXVIDPNDUMP_STRCASE(D3DKMDT_EPT_VIDPNSOURCE);
2470 VBOXVIDPNDUMP_STRCASE(D3DKMDT_EPT_VIDPNTARGET);
2471 VBOXVIDPNDUMP_STRCASE(D3DKMDT_EPT_SCALING);
2472 VBOXVIDPNDUMP_STRCASE(D3DKMDT_EPT_ROTATION);
2473 VBOXVIDPNDUMP_STRCASE(D3DKMDT_EPT_NOPIVOT);
2474 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2475 }
2476}
2477
2478const char* vboxVidPnDumpStrModePreference(D3DKMDT_MODE_PREFERENCE Preference)
2479{
2480 switch (Preference)
2481 {
2482 VBOXVIDPNDUMP_STRCASE(D3DKMDT_MP_UNINITIALIZED);
2483 VBOXVIDPNDUMP_STRCASE(D3DKMDT_MP_PREFERRED);
2484 VBOXVIDPNDUMP_STRCASE(D3DKMDT_MP_NOTPREFERRED);
2485 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2486 }
2487}
2488
2489const char* vboxVidPnDumpStrSignalStandard(D3DKMDT_VIDEO_SIGNAL_STANDARD VideoStandard)
2490{
2491 switch (VideoStandard)
2492 {
2493 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_UNINITIALIZED);
2494 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_VESA_DMT);
2495 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_VESA_GTF);
2496 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_VESA_CVT);
2497 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_IBM);
2498 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_APPLE);
2499 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_NTSC_M);
2500 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_NTSC_J);
2501 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_NTSC_443);
2502 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_PAL_B);
2503 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_PAL_B1);
2504 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_PAL_G);
2505 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_PAL_H);
2506 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_PAL_I);
2507 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_PAL_D);
2508 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_PAL_N);
2509 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_PAL_NC);
2510 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_SECAM_B);
2511 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_SECAM_D);
2512 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_SECAM_G);
2513 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_SECAM_H);
2514 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_SECAM_K);
2515 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_SECAM_K1);
2516 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_SECAM_L);
2517 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_SECAM_L1);
2518 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_EIA_861);
2519 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_EIA_861A);
2520 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_EIA_861B);
2521 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_PAL_K);
2522 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_PAL_K1);
2523 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_PAL_L);
2524 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_PAL_M);
2525 VBOXVIDPNDUMP_STRCASE(D3DKMDT_VSS_OTHER);
2526 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2527 }
2528}
2529
2530const char* vboxVidPnDumpStrPixFormat(D3DDDIFORMAT PixelFormat)
2531{
2532 switch (PixelFormat)
2533 {
2534 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_UNKNOWN);
2535 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_R8G8B8);
2536 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A8R8G8B8);
2537 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_X8R8G8B8);
2538 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_R5G6B5);
2539 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_X1R5G5B5);
2540 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A1R5G5B5);
2541 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A4R4G4B4);
2542 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_R3G3B2);
2543 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A8);
2544 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A8R3G3B2);
2545 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_X4R4G4B4);
2546 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A2B10G10R10);
2547 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A8B8G8R8);
2548 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_X8B8G8R8);
2549 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_G16R16);
2550 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A2R10G10B10);
2551 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A16B16G16R16);
2552 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A8P8);
2553 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_R32F);
2554 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_G32R32F);
2555 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A32B32G32R32F);
2556 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_CxV8U8);
2557 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A1);
2558 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_BINARYBUFFER);
2559 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_VERTEXDATA);
2560 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_INDEX16);
2561 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_INDEX32);
2562 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_Q16W16V16U16);
2563 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_MULTI2_ARGB8);
2564 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_R16F);
2565 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_G16R16F);
2566 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A16B16G16R16F);
2567 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_D32F_LOCKABLE);
2568 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_D24FS8);
2569 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_D32_LOCKABLE);
2570 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_S8_LOCKABLE);
2571 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_S1D15);
2572 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_S8D24);
2573 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_X8D24);
2574 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_X4S4D24);
2575 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_L16);
2576 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_UYVY);
2577 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_R8G8_B8G8);
2578 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_YUY2);
2579 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_G8R8_G8B8);
2580 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_DXT1);
2581 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_DXT2);
2582 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_DXT3);
2583 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_DXT4);
2584 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_DXT5);
2585 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_D16_LOCKABLE);
2586 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_D32);
2587 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_D15S1);
2588 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_D24S8);
2589 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_D24X8);
2590 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_D24X4S4);
2591 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_D16);
2592 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_P8);
2593 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_L8);
2594 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A8L8);
2595 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A4L4);
2596 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_V8U8);
2597 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_L6V5U5);
2598 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_X8L8V8U8);
2599 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_Q8W8V8U8);
2600 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_V16U16);
2601 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_W11V11U10);
2602 VBOXVIDPNDUMP_STRCASE(D3DDDIFMT_A2W10V10U10);
2603 VBOXVIDPNDUMP_STRCASE_UNKNOWN();
2604 }
2605}
2606
2607void vboxVidPnDumpCopyProtectoin(const char *pPrefix, const D3DKMDT_VIDPN_PRESENT_PATH_COPYPROTECTION *pCopyProtection, const char *pSuffix)
2608{
2609 LOGREL_EXACT(("%sType(%s), TODO%s", pPrefix,
2610 vboxVidPnDumpStrCopyProtectionType(pCopyProtection->CopyProtectionType), pSuffix));
2611}
2612
2613
2614void vboxVidPnDumpPathTransformation(const D3DKMDT_VIDPN_PRESENT_PATH_TRANSFORMATION *pContentTransformation)
2615{
2616 LOGREL_EXACT((" --Transformation: Scaling(%s), ScalingSupport(%d), Rotation(%s), RotationSupport(%d)--",
2617 vboxVidPnDumpStrScaling(pContentTransformation->Scaling), pContentTransformation->ScalingSupport,
2618 vboxVidPnDumpStrRotation(pContentTransformation->Rotation), pContentTransformation->RotationSupport));
2619}
2620
2621void vboxVidPnDumpRegion(const char *pPrefix, const D3DKMDT_2DREGION *pRegion, const char *pSuffix)
2622{
2623 LOGREL_EXACT(("%s%dX%d%s", pPrefix, pRegion->cx, pRegion->cy, pSuffix));
2624}
2625
2626void vboxVidPnDumpRational(const char *pPrefix, const D3DDDI_RATIONAL *pRational, const char *pSuffix)
2627{
2628 LOGREL_EXACT(("%s%d/%d=%d%s", pPrefix, pRational->Numerator, pRational->Denominator, pRational->Numerator/pRational->Denominator, pSuffix));
2629}
2630
2631void vboxVidPnDumpRanges(const char *pPrefix, const D3DKMDT_COLOR_COEFF_DYNAMIC_RANGES *pDynamicRanges, const char *pSuffix)
2632{
2633 LOGREL_EXACT(("%sFirstChannel(%d), SecondChannel(%d), ThirdChannel(%d), FourthChannel(%d)%s", pPrefix,
2634 pDynamicRanges->FirstChannel,
2635 pDynamicRanges->SecondChannel,
2636 pDynamicRanges->ThirdChannel,
2637 pDynamicRanges->FourthChannel,
2638 pSuffix));
2639}
2640
2641void vboxVidPnDumpGammaRamp(const char *pPrefix, const D3DKMDT_GAMMA_RAMP *pGammaRamp, const char *pSuffix)
2642{
2643 LOGREL_EXACT(("%sType(%s), DataSize(%d), TODO: dump the rest%s", pPrefix,
2644 vboxVidPnDumpStrGammaRampType(pGammaRamp->Type), pGammaRamp->DataSize,
2645 pSuffix));
2646}
2647
2648void vboxVidPnDumpSourceMode(const char *pPrefix, const D3DKMDT_VIDPN_SOURCE_MODE* pVidPnSourceModeInfo, const char *pSuffix)
2649{
2650 LOGREL_EXACT(("%sType(%s), ", pPrefix, vboxVidPnDumpStrSourceModeType(pVidPnSourceModeInfo->Type)));
2651 vboxVidPnDumpRegion("surf(", &pVidPnSourceModeInfo->Format.Graphics.PrimSurfSize, "), ");
2652 vboxVidPnDumpRegion("vis(", &pVidPnSourceModeInfo->Format.Graphics.VisibleRegionSize, "), ");
2653 LOGREL_EXACT(("stride(%d), ", pVidPnSourceModeInfo->Format.Graphics.Stride));
2654 LOGREL_EXACT(("format(%s), ", vboxVidPnDumpStrPixFormat(pVidPnSourceModeInfo->Format.Graphics.PixelFormat)));
2655 LOGREL_EXACT(("clrBasis(%s), ", vboxVidPnDumpStrColorBasis(pVidPnSourceModeInfo->Format.Graphics.ColorBasis)));
2656 LOGREL_EXACT(("pvam(%s)%s", vboxVidPnDumpStrPvam(pVidPnSourceModeInfo->Format.Graphics.PixelValueAccessMode), pSuffix));
2657}
2658
2659void vboxVidPnDumpSignalInfo(const char *pPrefix, const D3DKMDT_VIDEO_SIGNAL_INFO *pVideoSignalInfo, const char *pSuffix)
2660{
2661 LOGREL_EXACT(("%sVStd(%s), ", pPrefix, vboxVidPnDumpStrSignalStandard(pVideoSignalInfo->VideoStandard)));
2662 vboxVidPnDumpRegion("totSize(", &pVideoSignalInfo->TotalSize, "), ");
2663 vboxVidPnDumpRegion("activeSize(", &pVideoSignalInfo->ActiveSize, "), ");
2664 vboxVidPnDumpRational("VSynch(", &pVideoSignalInfo->VSyncFreq, "), ");
2665 LOGREL_EXACT(("PixelRate(%d), ScanLineOrdering(%s)%s", pVideoSignalInfo->PixelRate, vboxVidPnDumpStrScanLineOrdering(pVideoSignalInfo->ScanLineOrdering), pSuffix));
2666}
2667
2668void vboxVidPnDumpTargetMode(const char *pPrefix, const D3DKMDT_VIDPN_TARGET_MODE* CONST pVidPnTargetModeInfo, const char *pSuffix)
2669{
2670 LOGREL_EXACT(("%s", pPrefix));
2671 vboxVidPnDumpSignalInfo("VSI: ", &pVidPnTargetModeInfo->VideoSignalInfo, ", ");
2672 LOGREL_EXACT(("Preference(%s)%s", vboxVidPnDumpStrModePreference(pVidPnTargetModeInfo->Preference), pSuffix));
2673}
2674
2675void vboxVidPnDumpPinnedSourceMode(const D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId)
2676{
2677 D3DKMDT_HVIDPNSOURCEMODESET hCurVidPnSourceModeSet;
2678 const DXGK_VIDPNSOURCEMODESET_INTERFACE *pCurVidPnSourceModeSetInterface;
2679
2680 NTSTATUS Status = pVidPnInterface->pfnAcquireSourceModeSet(hVidPn,
2681 VidPnSourceId,
2682 &hCurVidPnSourceModeSet,
2683 &pCurVidPnSourceModeSetInterface);
2684 Assert(Status == STATUS_SUCCESS);
2685 if (Status == STATUS_SUCCESS)
2686 {
2687 CONST D3DKMDT_VIDPN_SOURCE_MODE* pPinnedVidPnSourceModeInfo;
2688
2689 Status = pCurVidPnSourceModeSetInterface->pfnAcquirePinnedModeInfo(hCurVidPnSourceModeSet, &pPinnedVidPnSourceModeInfo);
2690 Assert(Status == STATUS_SUCCESS || Status == STATUS_GRAPHICS_MODE_NOT_PINNED);
2691 if (Status == STATUS_SUCCESS)
2692 {
2693 vboxVidPnDumpSourceMode("Source Pinned: ", pPinnedVidPnSourceModeInfo, "\n");
2694 pCurVidPnSourceModeSetInterface->pfnReleaseModeInfo(hCurVidPnSourceModeSet, pPinnedVidPnSourceModeInfo);
2695 }
2696 else if (Status == STATUS_GRAPHICS_MODE_NOT_PINNED)
2697 {
2698 LOGREL_EXACT(("Source NOT Pinned\n"));
2699 }
2700 else
2701 {
2702 LOGREL_EXACT(("ERROR getting piined Source Mode(0x%x)\n", Status));
2703 }
2704 pVidPnInterface->pfnReleaseSourceModeSet(hVidPn, hCurVidPnSourceModeSet);
2705 }
2706 else
2707 {
2708 LOGREL_EXACT(("ERROR getting SourceModeSet(0x%x)\n", Status));
2709 }
2710}
2711
2712
2713DECLCALLBACK(BOOLEAN) vboxVidPnDumpSourceModeSetEnum(D3DKMDT_HVIDPNSOURCEMODESET hNewVidPnSourceModeSet, const DXGK_VIDPNSOURCEMODESET_INTERFACE *pVidPnSourceModeSetInterface,
2714 const D3DKMDT_VIDPN_SOURCE_MODE *pNewVidPnSourceModeInfo, PVOID pContext)
2715{
2716 vboxVidPnDumpSourceMode("SourceMode: ", pNewVidPnSourceModeInfo, "\n");
2717 return TRUE;
2718}
2719
2720void vboxVidPnDumpSourceModeSet(PVBOXMP_DEVEXT pDevExt, const D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId)
2721{
2722 LOGREL_EXACT((" >>>+++SourceMode Set for Source(%d)+++\n", VidPnSourceId));
2723 D3DKMDT_HVIDPNSOURCEMODESET hCurVidPnSourceModeSet;
2724 const DXGK_VIDPNSOURCEMODESET_INTERFACE *pCurVidPnSourceModeSetInterface;
2725
2726 NTSTATUS Status = pVidPnInterface->pfnAcquireSourceModeSet(hVidPn,
2727 VidPnSourceId,
2728 &hCurVidPnSourceModeSet,
2729 &pCurVidPnSourceModeSetInterface);
2730 Assert(Status == STATUS_SUCCESS);
2731 if (Status == STATUS_SUCCESS)
2732 {
2733
2734 Status = vboxVidPnEnumSourceModes(hCurVidPnSourceModeSet, pCurVidPnSourceModeSetInterface,
2735 vboxVidPnDumpSourceModeSetEnum, NULL);
2736 Assert(Status == STATUS_SUCCESS);
2737 if (Status != STATUS_SUCCESS)
2738 {
2739 LOGREL_EXACT(("ERROR enumerating Source Modes(0x%x)\n", Status));
2740 }
2741 pVidPnInterface->pfnReleaseSourceModeSet(hVidPn, hCurVidPnSourceModeSet);
2742 }
2743 else
2744 {
2745 LOGREL_EXACT(("ERROR getting SourceModeSet for Source(%d), Status(0x%x)\n", VidPnSourceId, Status));
2746 }
2747
2748 LOGREL_EXACT((" <<<+++End Of SourceMode Set for Source(%d)+++", VidPnSourceId));
2749}
2750
2751DECLCALLBACK(BOOLEAN) vboxVidPnDumpTargetModeSetEnum(D3DKMDT_HVIDPNTARGETMODESET hNewVidPnTargetModeSet, const DXGK_VIDPNTARGETMODESET_INTERFACE *pVidPnTargetModeSetInterface,
2752 const D3DKMDT_VIDPN_TARGET_MODE *pNewVidPnTargetModeInfo, PVOID pContext)
2753{
2754 vboxVidPnDumpTargetMode("TargetMode: ", pNewVidPnTargetModeInfo, "\n");
2755 return TRUE;
2756}
2757
2758void vboxVidPnDumpTargetModeSet(PVBOXMP_DEVEXT pDevExt, const D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
2759{
2760 LOGREL_EXACT((" >>>---TargetMode Set for Target(%d)---\n", VidPnTargetId));
2761 D3DKMDT_HVIDPNTARGETMODESET hCurVidPnTargetModeSet;
2762 const DXGK_VIDPNTARGETMODESET_INTERFACE *pCurVidPnTargetModeSetInterface;
2763
2764 NTSTATUS Status = pVidPnInterface->pfnAcquireTargetModeSet(hVidPn,
2765 VidPnTargetId,
2766 &hCurVidPnTargetModeSet,
2767 &pCurVidPnTargetModeSetInterface);
2768 Assert(Status == STATUS_SUCCESS);
2769 if (Status == STATUS_SUCCESS)
2770 {
2771
2772 Status = vboxVidPnEnumTargetModes(hCurVidPnTargetModeSet, pCurVidPnTargetModeSetInterface,
2773 vboxVidPnDumpTargetModeSetEnum, NULL);
2774 Assert(Status == STATUS_SUCCESS);
2775 if (Status != STATUS_SUCCESS)
2776 {
2777 LOGREL_EXACT(("ERROR enumerating Target Modes(0x%x)\n", Status));
2778 }
2779 pVidPnInterface->pfnReleaseTargetModeSet(hVidPn, hCurVidPnTargetModeSet);
2780 }
2781 else
2782 {
2783 LOGREL_EXACT(("ERROR getting TargetModeSet for Target(%d), Status(0x%x)\n", VidPnTargetId, Status));
2784 }
2785
2786 LOGREL_EXACT((" <<<---End Of TargetMode Set for Target(%d)---", VidPnTargetId));
2787}
2788
2789
2790void vboxVidPnDumpPinnedTargetMode(const D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
2791{
2792 D3DKMDT_HVIDPNTARGETMODESET hCurVidPnTargetModeSet;
2793 const DXGK_VIDPNTARGETMODESET_INTERFACE *pCurVidPnTargetModeSetInterface;
2794
2795 NTSTATUS Status = pVidPnInterface->pfnAcquireTargetModeSet(hVidPn,
2796 VidPnTargetId,
2797 &hCurVidPnTargetModeSet,
2798 &pCurVidPnTargetModeSetInterface);
2799 Assert(Status == STATUS_SUCCESS);
2800 if (Status == STATUS_SUCCESS)
2801 {
2802 CONST D3DKMDT_VIDPN_TARGET_MODE* pPinnedVidPnTargetModeInfo;
2803
2804 Status = pCurVidPnTargetModeSetInterface->pfnAcquirePinnedModeInfo(hCurVidPnTargetModeSet, &pPinnedVidPnTargetModeInfo);
2805 Assert(Status == STATUS_SUCCESS || Status == STATUS_GRAPHICS_MODE_NOT_PINNED);
2806 if (Status == STATUS_SUCCESS)
2807 {
2808 vboxVidPnDumpTargetMode("Target Pinned: ", pPinnedVidPnTargetModeInfo, "\n");
2809 pCurVidPnTargetModeSetInterface->pfnReleaseModeInfo(hCurVidPnTargetModeSet, pPinnedVidPnTargetModeInfo);
2810 }
2811 else if (Status == STATUS_GRAPHICS_MODE_NOT_PINNED)
2812 {
2813 LOGREL_EXACT(("Target NOT Pinned\n"));
2814 }
2815 else
2816 {
2817 LOGREL_EXACT(("ERROR getting piined Target Mode(0x%x)\n", Status));
2818 }
2819 pVidPnInterface->pfnReleaseTargetModeSet(hVidPn, hCurVidPnTargetModeSet);
2820 }
2821 else
2822 {
2823 LOGREL_EXACT(("ERROR getting TargetModeSet(0x%x)\n", Status));
2824 }
2825}
2826
2827void vboxVidPnDumpCofuncModalityArg(const char *pPrefix, CONST DXGKARG_ENUMVIDPNCOFUNCMODALITY* CONST pEnumCofuncModalityArg, const char *pSuffix)
2828{
2829 LOGREL_EXACT(("%sPivotType(%s), SourceId(0x%x), TargetId(0x%x),%s", pPrefix, vboxVidPnDumpStrCFMPivotType(pEnumCofuncModalityArg->EnumPivotType),
2830 pEnumCofuncModalityArg->EnumPivot.VidPnSourceId, pEnumCofuncModalityArg->EnumPivot.VidPnTargetId, pSuffix));
2831}
2832
2833void vboxVidPnDumpPath(const D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface, const D3DKMDT_VIDPN_PRESENT_PATH *pVidPnPresentPathInfo)
2834{
2835 LOGREL_EXACT((" >>**** Start Dump VidPn Path ****>>\n"));
2836 LOGREL_EXACT(("VidPnSourceId(%d), VidPnTargetId(%d)\n",
2837 pVidPnPresentPathInfo->VidPnSourceId, pVidPnPresentPathInfo->VidPnTargetId));
2838
2839 vboxVidPnDumpPinnedSourceMode(hVidPn, pVidPnInterface, pVidPnPresentPathInfo->VidPnSourceId);
2840 vboxVidPnDumpPinnedTargetMode(hVidPn, pVidPnInterface, pVidPnPresentPathInfo->VidPnTargetId);
2841
2842 vboxVidPnDumpPathTransformation(&pVidPnPresentPathInfo->ContentTransformation);
2843
2844 LOGREL_EXACT(("Importance(%s), TargetColorBasis(%s), Content(%s), ",
2845 vboxVidPnDumpStrImportance(pVidPnPresentPathInfo->ImportanceOrdinal),
2846 vboxVidPnDumpStrColorBasis(pVidPnPresentPathInfo->VidPnTargetColorBasis),
2847 vboxVidPnDumpStrContent(pVidPnPresentPathInfo->Content)));
2848 vboxVidPnDumpRegion("VFA_TL_O(", &pVidPnPresentPathInfo->VisibleFromActiveTLOffset, "), ");
2849 vboxVidPnDumpRegion("VFA_BR_O(", &pVidPnPresentPathInfo->VisibleFromActiveBROffset, "), ");
2850 vboxVidPnDumpRanges("CCDynamicRanges: ", &pVidPnPresentPathInfo->VidPnTargetColorCoeffDynamicRanges, "| ");
2851 vboxVidPnDumpCopyProtectoin("CProtection: ", &pVidPnPresentPathInfo->CopyProtection, "| ");
2852 vboxVidPnDumpGammaRamp("GammaRamp: ", &pVidPnPresentPathInfo->GammaRamp, "\n");
2853
2854 LOGREL_EXACT((" <<**** Stop Dump VidPn Path ****<<"));
2855}
2856
2857typedef struct VBOXVIDPNDUMPPATHENUM
2858{
2859 D3DKMDT_HVIDPN hVidPn;
2860 const DXGK_VIDPN_INTERFACE* pVidPnInterface;
2861} VBOXVIDPNDUMPPATHENUM, *PVBOXVIDPNDUMPPATHENUM;
2862
2863static DECLCALLBACK(BOOLEAN) vboxVidPnDumpPathEnum(D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface,
2864 const D3DKMDT_VIDPN_PRESENT_PATH *pVidPnPresentPathInfo, PVOID pContext)
2865{
2866 PVBOXVIDPNDUMPPATHENUM pData = (PVBOXVIDPNDUMPPATHENUM)pContext;
2867 vboxVidPnDumpPath(pData->hVidPn, pData->pVidPnInterface, pVidPnPresentPathInfo);
2868
2869 pVidPnTopologyInterface->pfnReleasePathInfo(hVidPnTopology, pVidPnPresentPathInfo);
2870 return TRUE;
2871}
2872
2873void vboxVidPnDumpVidPn(const char * pPrefix, PVBOXMP_DEVEXT pDevExt, D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface, const char * pSuffix)
2874{
2875 LOGREL_EXACT(("%s", pPrefix));
2876
2877 VBOXVIDPNDUMPPATHENUM CbData;
2878 CbData.hVidPn = hVidPn;
2879 CbData.pVidPnInterface = pVidPnInterface;
2880 D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology;
2881 const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface;
2882 NTSTATUS Status = pVidPnInterface->pfnGetTopology(hVidPn, &hVidPnTopology, &pVidPnTopologyInterface);
2883 Assert(Status == STATUS_SUCCESS);
2884 if (Status == STATUS_SUCCESS)
2885 {
2886 Status = vboxVidPnEnumPaths(hVidPnTopology, pVidPnTopologyInterface,
2887 vboxVidPnDumpPathEnum, &CbData);
2888 Assert(Status == STATUS_SUCCESS);
2889 }
2890
2891 for (int i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
2892 {
2893 vboxVidPnDumpSourceModeSet(pDevExt, hVidPn, pVidPnInterface, (D3DDDI_VIDEO_PRESENT_SOURCE_ID)i);
2894 vboxVidPnDumpTargetModeSet(pDevExt, hVidPn, pVidPnInterface, (D3DDDI_VIDEO_PRESENT_TARGET_ID)i);
2895 }
2896
2897 LOGREL_EXACT(("%s", pSuffix));
2898}
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