VirtualBox

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

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

wddm: disable complex topologies for now

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