VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoWddm.cpp@ 27201

Last change on this file since 27201 was 27201, checked in by vboxsync, 15 years ago

wddm: bugfix

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 117.2 KB
Line 
1/*
2 * Copyright (C) 2010 Sun Microsystems, Inc.
3 *
4 * This file is part of VirtualBox Open Source Edition (OSE), as
5 * available from http://www.virtualbox.org. This file is free software;
6 * you can redistribute it and/or modify it under the terms of the GNU
7 * General Public License (GPL) as published by the Free Software
8 * Foundation, in version 2 as it comes in the "COPYING" file of the
9 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
10 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
11 *
12 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
13 * Clara, CA 95054 USA or visit http://www.sun.com if you need
14 * additional information or have any questions.
15 */
16
17#include "../VBoxVideo.h"
18#include "../Helper.h"
19
20#include <VBox/VBoxGuestLib.h>
21#include <VBox/VBoxVideo.h>
22
23#define VBOXWDDM_MEMTAG 'MDBV'
24PVOID vboxWddmMemAlloc(IN SIZE_T cbSize)
25{
26 return ExAllocatePoolWithTag(NonPagedPool, cbSize, VBOXWDDM_MEMTAG);
27}
28
29PVOID vboxWddmMemAllocZero(IN SIZE_T cbSize)
30{
31 PVOID pvMem = vboxWddmMemAlloc(cbSize);
32 memset(pvMem, 0, cbSize);
33 return pvMem;
34}
35
36
37VOID vboxWddmMemFree(PVOID pvMem)
38{
39 ExFreePool(pvMem);
40}
41
42void vboxSHGSMICbCommandWrite(struct _HGSMIHEAP * pHeap, HGSMIOFFSET data)
43{
44 /* @todo: this should be taken from PDEVICE_EXTENSION */
45 //VBoxHGSMIGuestWrite(pDevExt, data);
46 VBoxVideoCmnPortWriteUlong((PULONG)VGA_PORT_HGSMI_GUEST, data);
47}
48
49//VBOXVIDEOOFFSET vboxWddmVRAMAddressToOffset(PDEVICE_EXTENSION pDevExt, PHYSICAL_ADDRESS phAddress)
50//{
51// Assert(phAddress.QuadPart >= VBE_DISPI_LFB_PHYSICAL_ADDRESS);
52// if (phAddress.QuadPart < VBE_DISPI_LFB_PHYSICAL_ADDRESS)
53// return VBOXVIDEOOFFSET_VOID;
54//
55// VBOXVIDEOOFFSET off = phAddress.QuadPart - VBE_DISPI_LFB_PHYSICAL_ADDRESS;
56// Assert(off < pDevExt->u.primary.cbVRAM);
57// if (off >= pDevExt->u.primary.cbVRAM)
58// return VBOXVIDEOOFFSET_VOID;
59//
60// return off;
61//}
62
63VBOXVIDEOOFFSET vboxWddmValidatePrimary(PVBOXWDDM_ALLOCATION pAllocation)
64{
65 Assert(pAllocation);
66 if (!pAllocation)
67 {
68 drprintf((__FUNCTION__": no allocation specified for Source\n"));
69 return VBOXVIDEOOFFSET_VOID;
70 }
71
72 Assert(pAllocation->SegmentId);
73 if (!pAllocation->SegmentId)
74 {
75 drprintf((__FUNCTION__": allocation is not paged in\n"));
76 return VBOXVIDEOOFFSET_VOID;
77 }
78
79 VBOXVIDEOOFFSET offVram = pAllocation->offVram;
80 Assert(offVram != VBOXVIDEOOFFSET_VOID);
81 if (offVram == VBOXVIDEOOFFSET_VOID)
82 drprintf((__FUNCTION__": VRAM pffset is not defined\n"));
83
84 return offVram;
85}
86
87NTSTATUS vboxWddmGhDisplayPostInfoScreen (PDEVICE_EXTENSION pDevExt, PVBOXWDDM_ALLOCATION pAllocation)
88{
89 VBOXVIDEOOFFSET offVram = pAllocation->offVram;
90 Assert(offVram != VBOXVIDEOOFFSET_VOID);
91 if (offVram == VBOXVIDEOOFFSET_VOID)
92 return STATUS_INVALID_PARAMETER;
93
94 PVBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE pPrimaryInfo = VBOXWDDM_ALLOCATION_BODY(pAllocation, VBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE);
95 /* Issue the screen info command. */
96 void *p = vboxHGSMIBufferAlloc (pDevExt,
97 sizeof (VBVAINFOSCREEN),
98 HGSMI_CH_VBVA,
99 VBVA_INFO_SCREEN);
100 Assert(p);
101 if (p)
102 {
103 VBVAINFOSCREEN *pScreen = (VBVAINFOSCREEN *)p;
104
105 pScreen->u32ViewIndex = pPrimaryInfo->VidPnSourceId;
106 pScreen->i32OriginX = 0;
107 pScreen->i32OriginY = 0;
108 pScreen->u32StartOffset = offVram;
109 pScreen->u32LineSize = pAllocation->u.SurfInfo.pitch;
110 pScreen->u32Width = pAllocation->u.SurfInfo.width;
111 pScreen->u32Height = pAllocation->u.SurfInfo.height;
112 pScreen->u16BitsPerPixel = (uint16_t)pAllocation->u.SurfInfo.bpp;
113 pScreen->u16Flags = VBVA_SCREEN_F_ACTIVE;
114
115 vboxHGSMIBufferSubmit (pDevExt, p);
116
117 vboxHGSMIBufferFree (pDevExt, p);
118 }
119
120 return STATUS_SUCCESS;
121}
122
123NTSTATUS vboxWddmGhDisplayPostInfoView (PDEVICE_EXTENSION pDevExt, PVBOXWDDM_ALLOCATION pAllocation)
124{
125 VBOXVIDEOOFFSET offVram = pAllocation->offVram;
126 Assert(offVram != VBOXVIDEOOFFSET_VOID);
127 if (offVram == VBOXVIDEOOFFSET_VOID)
128 return STATUS_INVALID_PARAMETER;
129
130 PVBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE pPrimaryInfo = VBOXWDDM_ALLOCATION_BODY(pAllocation, VBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE);
131 /* Issue the screen info command. */
132 void *p = vboxHGSMIBufferAlloc (pDevExt,
133 sizeof (VBVAINFOVIEW),
134 HGSMI_CH_VBVA,
135 VBVA_INFO_VIEW);
136 Assert(p);
137 if (p)
138 {
139 VBVAINFOVIEW *pView = (VBVAINFOVIEW *)p;
140
141 pView->u32ViewIndex = pPrimaryInfo->VidPnSourceId;
142 pView->u32ViewOffset = offVram;
143 pView->u32ViewSize = vboxWddmVramReportedSegmentSize(pDevExt)/pDevExt->cSources;
144
145 pView->u32MaxScreenSize = pView->u32ViewSize;
146
147 vboxHGSMIBufferSubmit (pDevExt, p);
148
149 vboxHGSMIBufferFree (pDevExt, p);
150 }
151
152 return STATUS_SUCCESS;
153}
154
155NTSTATUS vboxWddmGhDisplaySetMode (PDEVICE_EXTENSION pDevExt, PVBOXWDDM_ALLOCATION pAllocation)
156{
157 PVBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE pPrimaryInfo = VBOXWDDM_ALLOCATION_BODY(pAllocation, VBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE);
158 if (pPrimaryInfo->VidPnSourceId)
159 return STATUS_SUCCESS;
160
161 if (VBoxVideoSetCurrentModePerform(pDevExt, pAllocation->u.SurfInfo.width,
162 pAllocation->u.SurfInfo.height, pAllocation->u.SurfInfo.bpp))
163 return STATUS_SUCCESS;
164
165 AssertBreakpoint();
166 drprintf((__FUNCTION__": VBoxVideoSetCurrentModePerform failed\n"));
167 return STATUS_UNSUCCESSFUL;
168}
169
170
171NTSTATUS vboxWddmGhDisplaySetInfo(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_SOURCE pSource)
172{
173 PVBOXWDDM_ALLOCATION pAllocation = pSource->pAllocation;
174 VBOXVIDEOOFFSET offVram = vboxWddmValidatePrimary(pAllocation);
175 Assert(offVram != VBOXVIDEOOFFSET_VOID);
176 if (offVram == VBOXVIDEOOFFSET_VOID)
177 return STATUS_INVALID_PARAMETER;
178
179 /*
180 * Set the current mode into the hardware.
181 */
182 NTSTATUS Status = vboxWddmGhDisplaySetMode (pDevExt, pAllocation);
183 Assert(Status == STATUS_SUCCESS);
184 if (Status == STATUS_SUCCESS)
185 {
186 Status = vboxWddmGhDisplayPostInfoView (pDevExt, pAllocation);
187 Assert(Status == STATUS_SUCCESS);
188 if (Status == STATUS_SUCCESS)
189 {
190 Status = vboxWddmGhDisplayPostInfoScreen (pDevExt, pAllocation);
191 Assert(Status == STATUS_SUCCESS);
192 if (Status != STATUS_SUCCESS)
193 drprintf((__FUNCTION__": vboxWddmGhDisplayPostInfoScreen failed\n"));
194 }
195 else
196 drprintf((__FUNCTION__": vboxWddmGhDisplayPostInfoView failed\n"));
197 }
198 else
199 drprintf((__FUNCTION__": vboxWddmGhDisplaySetMode failed\n"));
200
201 return Status;
202}
203
204HGSMIHEAP* vboxWddmHgsmiGetHeapFromCmdOffset(PDEVICE_EXTENSION pDevExt, HGSMIOFFSET offCmd)
205{
206 if(HGSMIAreaContainsOffset(&pDevExt->u.primary.Vdma.CmdHeap.area, offCmd))
207 return &pDevExt->u.primary.Vdma.CmdHeap;
208 if (HGSMIAreaContainsOffset(&pDevExt->u.primary.hgsmiAdapterHeap.area, offCmd))
209 return &pDevExt->u.primary.hgsmiAdapterHeap;
210 return NULL;
211}
212
213typedef enum
214{
215 VBOXWDDM_HGSMICMD_TYPE_UNDEFINED = 0,
216 VBOXWDDM_HGSMICMD_TYPE_CTL = 1,
217 VBOXWDDM_HGSMICMD_TYPE_DMACMD = 2
218} VBOXWDDM_HGSMICMD_TYPE;
219
220VBOXWDDM_HGSMICMD_TYPE vboxWddmHgsmiGetCmdTypeFromOffset(PDEVICE_EXTENSION pDevExt, HGSMIOFFSET offCmd)
221{
222 if(HGSMIAreaContainsOffset(&pDevExt->u.primary.Vdma.CmdHeap.area, offCmd))
223 return VBOXWDDM_HGSMICMD_TYPE_DMACMD;
224 if (HGSMIAreaContainsOffset(&pDevExt->u.primary.hgsmiAdapterHeap.area, offCmd))
225 return VBOXWDDM_HGSMICMD_TYPE_CTL;
226 return VBOXWDDM_HGSMICMD_TYPE_UNDEFINED;
227}
228
229
230#define VBOXWDDM_REG_DRVKEY_PREFIX L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\"
231
232NTSTATUS vboxWddmRegQueryDrvKeyName(PDEVICE_EXTENSION pDevExt, ULONG cbBuf, PWCHAR pBuf, PULONG pcbResult)
233{
234 WCHAR fallBackBuf[2];
235 PWCHAR pSuffix;
236 bool bFallback = false;
237
238 if (cbBuf > sizeof(VBOXWDDM_REG_DRVKEY_PREFIX))
239 {
240 wcscpy(pBuf, VBOXWDDM_REG_DRVKEY_PREFIX);
241 pSuffix = pBuf + (sizeof (VBOXWDDM_REG_DRVKEY_PREFIX)-2);
242 cbBuf -= sizeof (VBOXWDDM_REG_DRVKEY_PREFIX)-2;
243 }
244 else
245 {
246 pSuffix = fallBackBuf;
247 cbBuf = sizeof (fallBackBuf);
248 bFallback = true;
249 }
250
251 NTSTATUS Status = IoGetDeviceProperty (pDevExt->pPDO,
252 DevicePropertyDriverKeyName,
253 cbBuf,
254 pSuffix,
255 &cbBuf);
256 if (Status == STATUS_SUCCESS && bFallback)
257 Status = STATUS_BUFFER_TOO_SMALL;
258 if (Status == STATUS_BUFFER_TOO_SMALL)
259 *pcbResult = cbBuf + sizeof (VBOXWDDM_REG_DRVKEY_PREFIX)-2;
260
261 return Status;
262}
263
264NTSTATUS vboxWddmRegOpenKey(OUT PHANDLE phKey, IN PWCHAR pName, IN ACCESS_MASK fAccess)
265{
266 OBJECT_ATTRIBUTES ObjAttr;
267 UNICODE_STRING RtlStr;
268 RtlStr.Buffer = pName;
269 RtlStr.Length = USHORT(wcslen(pName) * sizeof(WCHAR));
270 RtlStr.MaximumLength = RtlStr.Length + sizeof(WCHAR);
271
272 InitializeObjectAttributes(&ObjAttr, &RtlStr, OBJ_CASE_INSENSITIVE, NULL, NULL);
273
274 return ZwOpenKey(phKey, fAccess, &ObjAttr);
275}
276
277NTSTATUS vboxWddmRegQueryValueDword(IN HANDLE hKey, IN PWCHAR pName, OUT PDWORD pDword)
278{
279 UCHAR Buf[32]; /* should be enough */
280 ULONG cbBuf;
281 PKEY_VALUE_PARTIAL_INFORMATION pInfo = (PKEY_VALUE_PARTIAL_INFORMATION)Buf;
282 UNICODE_STRING RtlStr;
283 RtlStr.Buffer = pName;
284 RtlStr.Length = USHORT(wcslen(pName) * sizeof(WCHAR));
285 RtlStr.MaximumLength = RtlStr.Length + sizeof(WCHAR);
286 NTSTATUS Status = ZwQueryValueKey(hKey,
287 &RtlStr,
288 KeyValuePartialInformation,
289 pInfo,
290 sizeof(Buf),
291 &cbBuf);
292 if (Status == STATUS_SUCCESS)
293 {
294 if (pInfo->Type == REG_DWORD)
295 {
296 Assert(pInfo->DataLength == 4);
297 *pDword = *((PULONG)pInfo->Data);
298 return STATUS_SUCCESS;
299 }
300 }
301
302 return STATUS_INVALID_PARAMETER;
303}
304
305NTSTATUS vboxWddmRegSetValueDword(IN HANDLE hKey, IN PWCHAR pName, OUT DWORD val)
306{
307 UCHAR Buf[32]; /* should be enough */
308 PKEY_VALUE_PARTIAL_INFORMATION pInfo = (PKEY_VALUE_PARTIAL_INFORMATION)Buf;
309 UNICODE_STRING RtlStr;
310 RtlStr.Buffer = pName;
311 RtlStr.Length = USHORT(wcslen(pName) * sizeof(WCHAR));
312 RtlStr.MaximumLength = RtlStr.Length + sizeof(WCHAR);
313 return ZwSetValueKey(hKey, &RtlStr,
314 NULL, /* IN ULONG TitleIndex OPTIONAL, reserved */
315 REG_DWORD,
316 &val,
317 sizeof(val));
318}
319
320VP_STATUS VBoxVideoCmnRegQueryDword(IN VBOXCMNREG Reg, PWSTR pName, uint32_t *pVal)
321{
322 if(!Reg)
323 return ERROR_INVALID_PARAMETER;
324 NTSTATUS Status = vboxWddmRegQueryValueDword(Reg, pName, (PDWORD)pVal);
325 return Status == STATUS_SUCCESS ? NO_ERROR : ERROR_INVALID_PARAMETER;
326}
327
328VP_STATUS VBoxVideoCmnRegSetDword(IN VBOXCMNREG Reg, PWSTR pName, uint32_t Val)
329{
330 if(!Reg)
331 return ERROR_INVALID_PARAMETER;
332 NTSTATUS Status = vboxWddmRegSetValueDword(Reg, pName, Val);
333 return Status == STATUS_SUCCESS ? NO_ERROR : ERROR_INVALID_PARAMETER;
334}
335
336VP_STATUS VBoxVideoCmnRegInit(IN PDEVICE_EXTENSION pDeviceExtension, OUT VBOXCMNREG *pReg)
337{
338 WCHAR Buf[512];
339 ULONG cbBuf = sizeof(Buf);
340 NTSTATUS Status = vboxWddmRegQueryDrvKeyName(pDeviceExtension, cbBuf, Buf, &cbBuf);
341 Assert(Status == STATUS_SUCCESS);
342 if (Status == STATUS_SUCCESS)
343 {
344 Status = vboxWddmRegOpenKey(pReg, Buf, GENERIC_READ | GENERIC_WRITE);
345 Assert(Status == STATUS_SUCCESS);
346 if(Status == STATUS_SUCCESS)
347 return NO_ERROR;
348 }
349
350 /* fall-back to make the subsequent VBoxVideoCmnRegXxx calls treat the fail accordingly
351 * basically needed to make as less modifications to the current XPDM code as possible */
352 *pReg = NULL;
353
354 return ERROR_INVALID_PARAMETER;
355}
356
357UINT vboxWddmCalcBitsPerPixel(D3DDDIFORMAT format)
358{
359 switch (format)
360 {
361 case D3DDDIFMT_R8G8B8:
362 return 24;
363 case D3DDDIFMT_A8R8G8B8:
364 case D3DDDIFMT_X8R8G8B8:
365 return 32;
366 case D3DDDIFMT_R5G6B5:
367 case D3DDDIFMT_X1R5G5B5:
368 case D3DDDIFMT_A1R5G5B5:
369 case D3DDDIFMT_A4R4G4B4:
370 return 16;
371 case D3DDDIFMT_R3G3B2:
372 case D3DDDIFMT_A8:
373 return 8;
374 case D3DDDIFMT_A8R3G3B2:
375 case D3DDDIFMT_X4R4G4B4:
376 return 16;
377 case D3DDDIFMT_A2B10G10R10:
378 case D3DDDIFMT_A8B8G8R8:
379 case D3DDDIFMT_X8B8G8R8:
380 case D3DDDIFMT_G16R16:
381 case D3DDDIFMT_A2R10G10B10:
382 return 32;
383 case D3DDDIFMT_A16B16G16R16:
384 return 64;
385 default:
386 AssertBreakpoint();
387 return 0;
388 }
389}
390
391D3DDDIFORMAT vboxWddmCalcPixelFormat(VIDEO_MODE_INFORMATION *pInfo)
392{
393 switch (pInfo->BitsPerPlane)
394 {
395 case 32:
396 if(!(pInfo->AttributeFlags & VIDEO_MODE_PALETTE_DRIVEN) && !(pInfo->AttributeFlags & VIDEO_MODE_MANAGED_PALETTE))
397 {
398 if (pInfo->RedMask == 0xFF0000 && pInfo->GreenMask == 0xFF00 && pInfo->BlueMask == 0xFF)
399 return D3DDDIFMT_X8R8G8B8;
400 drprintf((__FUNCTION__": unsupported format: bpp(%d), rmask(%d), gmask(%d), bmask(%d)\n", pInfo->BitsPerPlane, pInfo->RedMask, pInfo->GreenMask, pInfo->BlueMask));
401 AssertBreakpoint();
402 }
403 else
404 {
405 drprintf((__FUNCTION__": unsupported AttributeFlags(0x%x)\n", pInfo->AttributeFlags));
406 AssertBreakpoint();
407 }
408 break;
409 case 24:
410 if(!(pInfo->AttributeFlags & VIDEO_MODE_PALETTE_DRIVEN) && !(pInfo->AttributeFlags & VIDEO_MODE_MANAGED_PALETTE))
411 {
412 if (pInfo->RedMask == 0xFF0000 && pInfo->GreenMask == 0xFF00 && pInfo->BlueMask == 0xFF)
413 return D3DDDIFMT_R8G8B8;
414 drprintf((__FUNCTION__": unsupported format: bpp(%d), rmask(%d), gmask(%d), bmask(%d)\n", pInfo->BitsPerPlane, pInfo->RedMask, pInfo->GreenMask, pInfo->BlueMask));
415 AssertBreakpoint();
416 }
417 else
418 {
419 drprintf((__FUNCTION__": unsupported AttributeFlags(0x%x)\n", pInfo->AttributeFlags));
420 AssertBreakpoint();
421 }
422 break;
423 case 16:
424 if(!(pInfo->AttributeFlags & VIDEO_MODE_PALETTE_DRIVEN) && !(pInfo->AttributeFlags & VIDEO_MODE_MANAGED_PALETTE))
425 {
426 if (pInfo->RedMask == 0xF800 && pInfo->GreenMask == 0x7E0 && pInfo->BlueMask == 0x1F)
427 return D3DDDIFMT_R5G6B5;
428 drprintf((__FUNCTION__": unsupported format: bpp(%d), rmask(%d), gmask(%d), bmask(%d)\n", pInfo->BitsPerPlane, pInfo->RedMask, pInfo->GreenMask, pInfo->BlueMask));
429 AssertBreakpoint();
430 }
431 else
432 {
433 drprintf((__FUNCTION__": unsupported AttributeFlags(0x%x)\n", pInfo->AttributeFlags));
434 AssertBreakpoint();
435 }
436 break;
437 case 8:
438 if((pInfo->AttributeFlags & VIDEO_MODE_PALETTE_DRIVEN) && (pInfo->AttributeFlags & VIDEO_MODE_MANAGED_PALETTE))
439 {
440 return D3DDDIFMT_P8;
441 }
442 else
443 {
444 drprintf((__FUNCTION__": unsupported AttributeFlags(0x%x)\n", pInfo->AttributeFlags));
445 AssertBreakpoint();
446 }
447 break;
448 default:
449 drprintf((__FUNCTION__": unsupported bpp(%d)\n", pInfo->BitsPerPlane));
450 AssertBreakpoint();
451 break;
452 }
453
454 return D3DDDIFMT_UNKNOWN;
455}
456
457UINT vboxWddmCalcPitch(UINT w, UINT bitsPerPixel)
458{
459 UINT Pitch = bitsPerPixel * w;
460 /* pitch is now in bits, translate in bytes */
461 if(Pitch & 7)
462 Pitch = (Pitch >> 3) + 1;
463 else
464 Pitch = (Pitch >> 3);
465
466 return Pitch;
467}
468
469NTSTATUS vboxWddmPickResources(PDEVICE_EXTENSION pContext, PDXGK_DEVICE_INFO pDeviceInfo, PULONG pAdapterMemorySize)
470{
471 NTSTATUS Status = STATUS_SUCCESS;
472 USHORT DispiId;
473 *pAdapterMemorySize = VBE_DISPI_TOTAL_VIDEO_MEMORY_BYTES;
474
475 VBoxVideoCmnPortWriteUshort((PUSHORT)VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ID);
476 VBoxVideoCmnPortWriteUshort((PUSHORT)VBE_DISPI_IOPORT_DATA, VBE_DISPI_ID2);
477 DispiId = VBoxVideoCmnPortReadUshort((PUSHORT)VBE_DISPI_IOPORT_DATA);
478 if (DispiId == VBE_DISPI_ID2)
479 {
480 dprintf(("VBoxVideoWddm: found the VBE card\n"));
481 /*
482 * Write some hardware information to registry, so that
483 * it's visible in Windows property dialog.
484 */
485
486 /*
487 * Query the adapter's memory size. It's a bit of a hack, we just read
488 * an ULONG from the data port without setting an index before.
489 */
490 *pAdapterMemorySize = VBoxVideoCmnPortReadUlong((PULONG)VBE_DISPI_IOPORT_DATA);
491 if (VBoxHGSMIIsSupported (pContext))
492 {
493 pContext->u.primary.IOPortHost = (RTIOPORT)VGA_PORT_HGSMI_HOST;
494 pContext->u.primary.IOPortGuest = (RTIOPORT)VGA_PORT_HGSMI_GUEST;
495
496 PCM_RESOURCE_LIST pRcList = pDeviceInfo->TranslatedResourceList;
497 /* @todo: verify resources */
498 for (ULONG i = 0; i < pRcList->Count; ++i)
499 {
500 PCM_FULL_RESOURCE_DESCRIPTOR pFRc = &pRcList->List[i];
501 for (ULONG j = 0; j < pFRc->PartialResourceList.Count; ++j)
502 {
503 PCM_PARTIAL_RESOURCE_DESCRIPTOR pPRc = &pFRc->PartialResourceList.PartialDescriptors[j];
504 switch (pPRc->Type)
505 {
506 case CmResourceTypePort:
507 break;
508 case CmResourceTypeInterrupt:
509 break;
510 case CmResourceTypeMemory:
511 break;
512 case CmResourceTypeDma:
513 break;
514 case CmResourceTypeDeviceSpecific:
515 break;
516 case CmResourceTypeBusNumber:
517 break;
518 default:
519 break;
520 }
521 }
522 }
523 }
524 else
525 {
526 drprintf(("VBoxVideoWddm: HGSMI unsupported, returning err\n"));
527 /* @todo: report a better status */
528 Status = STATUS_UNSUCCESSFUL;
529 }
530 }
531 else
532 {
533 drprintf(("VBoxVideoWddm:: VBE card not found, returning err\n"));
534 Status = STATUS_UNSUCCESSFUL;
535 }
536
537
538 return Status;
539}
540
541/* driver callbacks */
542
543NTSTATUS DxgkDdiAddDevice(
544 IN CONST PDEVICE_OBJECT PhysicalDeviceObject,
545 OUT PVOID *MiniportDeviceContext
546 )
547{
548 /* The DxgkDdiAddDevice function should be made pageable. */
549 PAGED_CODE();
550
551 dfprintf(("==> "__FUNCTION__ ", pdo(0x%x)\n", PhysicalDeviceObject));
552 NTSTATUS Status = STATUS_SUCCESS;
553
554 PDEVICE_EXTENSION pContext = (PDEVICE_EXTENSION)vboxWddmMemAllocZero(sizeof (DEVICE_EXTENSION));
555 if (pContext)
556 {
557 pContext->pPDO = PhysicalDeviceObject;
558 *MiniportDeviceContext = pContext;
559 }
560 else
561 {
562 Status = STATUS_INSUFFICIENT_RESOURCES;
563 drprintf(("VBoxVideoWddm: ERROR, failed to create context\n"));
564 }
565
566 dfprintf(("<== "__FUNCTION__ ", status(0x%x), pContext(0x%x)\n", Status, pContext));
567
568 return Status;
569}
570
571NTSTATUS DxgkDdiStartDevice(
572 IN CONST PVOID MiniportDeviceContext,
573 IN PDXGK_START_INFO DxgkStartInfo,
574 IN PDXGKRNL_INTERFACE DxgkInterface,
575 OUT PULONG NumberOfVideoPresentSources,
576 OUT PULONG NumberOfChildren
577 )
578{
579 /* The DxgkDdiStartDevice function should be made pageable. */
580 PAGED_CODE();
581
582 NTSTATUS Status;
583
584 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", MiniportDeviceContext));
585
586 if ( ARGUMENT_PRESENT(MiniportDeviceContext) &&
587 ARGUMENT_PRESENT(DxgkInterface) &&
588 ARGUMENT_PRESENT(DxgkStartInfo) &&
589 ARGUMENT_PRESENT(NumberOfVideoPresentSources),
590 ARGUMENT_PRESENT(NumberOfChildren)
591 )
592 {
593 PDEVICE_EXTENSION pContext = (PDEVICE_EXTENSION)MiniportDeviceContext;
594
595 /* Save DeviceHandle and function pointers supplied by the DXGKRNL_INTERFACE structure passed to DxgkInterface. */
596 memcpy(&pContext->u.primary.DxgkInterface, DxgkInterface, sizeof (DXGKRNL_INTERFACE));
597
598 /* Allocate a DXGK_DEVICE_INFO structure, and call DxgkCbGetDeviceInformation to fill in the members of that structure, which include the registry path, the PDO, and a list of translated resources for the display adapter represented by MiniportDeviceContext. Save selected members (ones that the display miniport driver will need later)
599 * of the DXGK_DEVICE_INFO structure in the context block represented by MiniportDeviceContext. */
600 DXGK_DEVICE_INFO DeviceInfo;
601 Status = pContext->u.primary.DxgkInterface.DxgkCbGetDeviceInformation (pContext->u.primary.DxgkInterface.DeviceHandle, &DeviceInfo);
602 if (Status == STATUS_SUCCESS)
603 {
604 ULONG AdapterMemorySize;
605 Status = vboxWddmPickResources(pContext, &DeviceInfo, &AdapterMemorySize);
606 if (Status == STATUS_SUCCESS)
607 {
608 /* Initialize VBoxGuest library, which is used for requests which go through VMMDev. */
609 VbglInit ();
610
611 /* Guest supports only HGSMI, the old VBVA via VMMDev is not supported. Old
612 * code will be ifdef'ed and later removed.
613 * The host will however support both old and new interface to keep compatibility
614 * with old guest additions.
615 */
616 VBoxSetupDisplaysHGSMI(pContext, AdapterMemorySize);
617 if ((pContext)->u.primary.bHGSMI)
618 {
619 drprintf(("VBoxVideoWddm: using HGSMI\n"));
620 *NumberOfVideoPresentSources = pContext->cSources;
621 *NumberOfChildren = pContext->cSources;
622 dprintf(("VBoxVideoWddm: sources(%d), children(%d)\n", *NumberOfVideoPresentSources, *NumberOfChildren));
623 }
624 else
625 {
626 drprintf(("VBoxVideoWddm: HGSMI failed to initialize, returning err\n"));
627 /* @todo: report a better status */
628 Status = STATUS_UNSUCCESSFUL;
629 }
630 }
631 else
632 {
633 drprintf(("VBoxVideoWddm:: vboxWddmPickResources failed Status(0x%x), returning err\n", Status));
634 Status = STATUS_UNSUCCESSFUL;
635 }
636 }
637 else
638 {
639 drprintf(("VBoxVideoWddm: DxgkCbGetDeviceInformation failed Status(0x%x), returning err\n", Status));
640 }
641 }
642 else
643 {
644 drprintf(("VBoxVideoWddm: invalid parameter, returning err\n"));
645 Status = STATUS_INVALID_PARAMETER;
646 }
647
648 dfprintf(("<== "__FUNCTION__ ", status(0x%x)\n", Status));
649
650 return Status;
651}
652
653NTSTATUS DxgkDdiStopDevice(
654 IN CONST PVOID MiniportDeviceContext
655 )
656{
657 /* The DxgkDdiStopDevice function should be made pageable. */
658 PAGED_CODE();
659
660 dfprintf(("==> "__FUNCTION__ ", context(0x%p)\n", MiniportDeviceContext));
661
662 AssertBreakpoint();
663 /* @todo: fixme: implement */
664
665 dfprintf(("<== "__FUNCTION__ ", context(0x%p)\n", MiniportDeviceContext));
666
667 return STATUS_SUCCESS;
668}
669
670NTSTATUS DxgkDdiRemoveDevice(
671 IN CONST PVOID MiniportDeviceContext
672 )
673{
674 /* DxgkDdiRemoveDevice should be made pageable. */
675 PAGED_CODE();
676
677 dfprintf(("==> "__FUNCTION__ ", context(0x%p)\n", MiniportDeviceContext));
678
679 vboxWddmMemFree(MiniportDeviceContext);
680
681 dfprintf(("<== "__FUNCTION__ ", context(0x%p)\n", MiniportDeviceContext));
682
683 return STATUS_SUCCESS;
684}
685
686NTSTATUS DxgkDdiDispatchIoRequest(
687 IN CONST PVOID MiniportDeviceContext,
688 IN ULONG VidPnSourceId,
689 IN PVIDEO_REQUEST_PACKET VideoRequestPacket
690 )
691{
692 dfprintf(("==> "__FUNCTION__ ", context(0x%p), ctl(0x%x)\n", MiniportDeviceContext, VideoRequestPacket->IoControlCode));
693
694 AssertBreakpoint();
695#if 0
696 PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)MiniportDeviceContext;
697
698 switch (VideoRequestPacket->IoControlCode)
699 {
700 case IOCTL_VIDEO_QUERY_COLOR_CAPABILITIES:
701 {
702 if (VideoRequestPacket->OutputBufferLength < sizeof(VIDEO_COLOR_CAPABILITIES))
703 {
704 AssertBreakpoint();
705 VideoRequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
706 return TRUE;
707 }
708 VIDEO_COLOR_CAPABILITIES *pCaps = (VIDEO_COLOR_CAPABILITIES*)VideoRequestPacket->OutputBuffer;
709
710 pCaps->Length = sizeof (VIDEO_COLOR_CAPABILITIES);
711 pCaps->AttributeFlags = VIDEO_DEVICE_COLOR;
712 pCaps->RedPhosphoreDecay = 0;
713 pCaps->GreenPhosphoreDecay = 0;
714 pCaps->BluePhosphoreDecay = 0;
715 pCaps->WhiteChromaticity_x = 3127;
716 pCaps->WhiteChromaticity_y = 3290;
717 pCaps->WhiteChromaticity_Y = 0;
718 pCaps->RedChromaticity_x = 6700;
719 pCaps->RedChromaticity_y = 3300;
720 pCaps->GreenChromaticity_x = 2100;
721 pCaps->GreenChromaticity_y = 7100;
722 pCaps->BlueChromaticity_x = 1400;
723 pCaps->BlueChromaticity_y = 800;
724 pCaps->WhiteGamma = 0;
725 pCaps->RedGamma = 20000;
726 pCaps->GreenGamma = 20000;
727 pCaps->BlueGamma = 20000;
728
729 VideoRequestPacket->StatusBlock->Status = NO_ERROR;
730 VideoRequestPacket->StatusBlock->Information = sizeof (VIDEO_COLOR_CAPABILITIES);
731 break;
732 }
733#if 0
734 case IOCTL_VIDEO_HANDLE_VIDEOPARAMETERS:
735 {
736 if (VideoRequestPacket->OutputBufferLength < sizeof(VIDEOPARAMETERS)
737 || VideoRequestPacket->InputBufferLength < sizeof(VIDEOPARAMETERS))
738 {
739 AssertBreakpoint();
740 VideoRequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
741 return TRUE;
742 }
743
744 Result = VBoxVideoResetDevice((PDEVICE_EXTENSION)HwDeviceExtension,
745 RequestPacket->StatusBlock);
746 break;
747 }
748#endif
749 default:
750 AssertBreakpoint();
751 VideoRequestPacket->StatusBlock->Status = ERROR_INVALID_FUNCTION;
752 VideoRequestPacket->StatusBlock->Information = 0;
753 }
754#endif
755 dfprintf(("<== "__FUNCTION__ ", context(0x%p), ctl(0x%x)\n", MiniportDeviceContext, VideoRequestPacket->IoControlCode));
756
757 return STATUS_SUCCESS;
758}
759
760BOOLEAN DxgkDdiInterruptRoutine(
761 IN CONST PVOID MiniportDeviceContext,
762 IN ULONG MessageNumber
763 )
764{
765 dfprintf(("==> "__FUNCTION__ ", context(0x%p), msg(0x%x)\n", MiniportDeviceContext, MessageNumber));
766
767 PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)MiniportDeviceContext;
768 BOOLEAN bOur = FALSE;
769 if (pDevExt->u.primary.pHostFlags) /* If HGSMI is enabled at all. */
770 {
771 VBOXSHGSMILIST CtlList;
772 VBOXSHGSMILIST DmaCmdList;
773 vboxSHGSMIListInit(&CtlList);
774 vboxSHGSMIListInit(&DmaCmdList);
775 do
776 {
777 uint32_t flags = pDevExt->u.primary.pHostFlags->u32HostFlags;
778 if (flags & HGSMIHOSTFLAGS_GCOMMAND_COMPLETED)
779 {
780 bOur = TRUE;
781 /* read the command offset */
782 HGSMIOFFSET offCmd = VBoxHGSMIGuestRead(pDevExt);
783 Assert(offCmd != HGSMIOFFSET_VOID);
784 if (offCmd != HGSMIOFFSET_VOID)
785 {
786 VBOXWDDM_HGSMICMD_TYPE enmType = vboxWddmHgsmiGetCmdTypeFromOffset(pDevExt, offCmd);
787 PVBOXSHGSMILIST pList;
788 HGSMIHEAP * pHeap = NULL;
789 switch (enmType)
790 {
791 case VBOXWDDM_HGSMICMD_TYPE_DMACMD:
792 pList = &DmaCmdList;
793 pHeap = &pDevExt->u.primary.Vdma.CmdHeap;
794 break;
795 case VBOXWDDM_HGSMICMD_TYPE_CTL:
796 pList = &CtlList;
797 pHeap = &pDevExt->u.primary.hgsmiAdapterHeap;
798 break;
799 default:
800 AssertBreakpoint();
801 }
802
803 if (pHeap)
804 {
805 int rc = VBoxSHGSMICommandProcessCompletion (pHeap, offCmd, TRUE /*bool bIrq*/ , pList);
806 AssertRC(rc);
807 }
808 }
809 }
810 else if (flags & HGSMIHOSTFLAGS_COMMANDS_PENDING)
811 {
812 bOur = TRUE;
813 AssertBreakpoint();
814 /* @todo: FIXME: implement !!! */
815 }
816 else if (flags & HGSMIHOSTFLAGS_IRQ)
817 {
818 bOur = TRUE;
819 AssertBreakpoint();
820 /* unknown command */
821 }
822 else
823 break;
824 } while (1);
825
826 if (!vboxSHGSMIListIsEmpty(&CtlList))
827 vboxSHGSMIListCat(&pDevExt->CtlList, &CtlList);
828
829 if (!vboxSHGSMIListIsEmpty(&DmaCmdList))
830 vboxSHGSMIListCat(&pDevExt->DmaCmdList, &DmaCmdList);
831
832 if (pDevExt->bSetNotifyDxDpc)
833 {
834 pDevExt->bNotifyDxDpc = TRUE;
835 pDevExt->bSetNotifyDxDpc = FALSE;
836 }
837
838 if (bOur)
839 HGSMIClearIrq (pDevExt);
840 }
841
842 dfprintf(("<== "__FUNCTION__ ", context(0x%p), bOur(0x%x)\n", MiniportDeviceContext, (ULONG)bOur));
843
844 return bOur;
845}
846
847
848typedef struct VBOXWDDM_DPCDATA
849{
850 VBOXSHGSMILIST CtlList;
851 VBOXSHGSMILIST DmaCmdList;
852 BOOL bNotifyDpc;
853} VBOXWDDM_DPCDATA, *PVBOXWDDM_DPCDATA;
854
855typedef struct VBOXWDDM_GETDPCDATA_CONTEXT
856{
857 PDEVICE_EXTENSION pDevExt;
858 VBOXWDDM_DPCDATA data;
859} VBOXWDDM_GETDPCDATA_CONTEXT, *PVBOXWDDM_GETDPCDATA_CONTEXT;
860
861BOOLEAN vboxWddmGetDPCDataCallback(PVOID Context)
862{
863 PVBOXWDDM_GETDPCDATA_CONTEXT pdc = (PVBOXWDDM_GETDPCDATA_CONTEXT)Context;
864
865 vboxSHGSMICmdListDetach2List(&pdc->pDevExt->CtlList, &pdc->data.CtlList);
866 vboxSHGSMICmdListDetach2List(&pdc->pDevExt->DmaCmdList, &pdc->data.DmaCmdList);
867 pdc->data.bNotifyDpc = pdc->pDevExt->bNotifyDxDpc;
868 pdc->pDevExt->bNotifyDxDpc = FALSE;
869 return TRUE;
870}
871
872VOID DxgkDdiDpcRoutine(
873 IN CONST PVOID MiniportDeviceContext
874 )
875{
876 dfprintf(("==> "__FUNCTION__ ", context(0x%p)\n", MiniportDeviceContext));
877
878 PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)MiniportDeviceContext;
879
880 VBOXWDDM_DPCDATA dpcData = {0};
881 BOOLEAN bRet;
882
883 /* get DPC data at IRQL */
884 NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbSynchronizeExecution(
885 pDevExt->u.primary.DxgkInterface.DeviceHandle,
886 vboxWddmGetDPCDataCallback,
887 &dpcData,
888 0,
889 &bRet);
890 Assert(Status == STATUS_SUCCESS);
891
892 if (!vboxSHGSMIListIsEmpty(&dpcData.CtlList))
893 {
894 int rc = VBoxSHGSMICommandPostprocessCompletion (&pDevExt->u.primary.hgsmiAdapterHeap, &dpcData.CtlList);
895 AssertRC(rc);
896 }
897
898 if (!vboxSHGSMIListIsEmpty(&dpcData.DmaCmdList))
899 {
900 int rc = VBoxSHGSMICommandPostprocessCompletion (&pDevExt->u.primary.Vdma.CmdHeap, &dpcData.DmaCmdList);
901 AssertRC(rc);
902 }
903
904 if (dpcData.bNotifyDpc)
905 pDevExt->u.primary.DxgkInterface.DxgkCbNotifyDpc(pDevExt->u.primary.DxgkInterface.DeviceHandle);
906
907 dfprintf(("<== "__FUNCTION__ ", context(0x%p)\n", MiniportDeviceContext));
908}
909
910NTSTATUS DxgkDdiQueryChildRelations(
911 IN CONST PVOID MiniportDeviceContext,
912 IN OUT PDXGK_CHILD_DESCRIPTOR ChildRelations,
913 IN ULONG ChildRelationsSize
914 )
915{
916 /* The DxgkDdiQueryChildRelations function should be made pageable. */
917 PAGED_CODE();
918
919 vboxVDbgBreakFv();
920
921 PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)MiniportDeviceContext;
922
923 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", MiniportDeviceContext));
924 Assert(ChildRelationsSize == (pDevExt->cSources + 1)*sizeof(DXGK_CHILD_DESCRIPTOR));
925 for (UINT i = 0; i < pDevExt->cSources; ++i)
926 {
927 ChildRelations[i].ChildDeviceType = TypeVideoOutput;
928 ChildRelations[i].ChildCapabilities.Type.VideoOutput.InterfaceTechnology = D3DKMDT_VOT_HD15; /* VGA */
929 ChildRelations[i].ChildCapabilities.Type.VideoOutput.MonitorOrientationAwareness = D3DKMDT_MOA_INTERRUPTIBLE; /* ?? D3DKMDT_MOA_NONE*/
930 ChildRelations[i].ChildCapabilities.Type.VideoOutput.SupportsSdtvModes = FALSE;
931 ChildRelations[i].ChildCapabilities.HpdAwareness = HpdAwarenessInterruptible; /* ?? HpdAwarenessAlwaysConnected; */
932 ChildRelations[i].AcpiUid = i; /* */
933 ChildRelations[i].ChildUid = i; /* should be == target id */
934 }
935 dfprintf(("<== "__FUNCTION__ ", context(0x%x)\n", MiniportDeviceContext));
936 return STATUS_SUCCESS;
937}
938
939NTSTATUS DxgkDdiQueryChildStatus(
940 IN CONST PVOID MiniportDeviceContext,
941 IN PDXGK_CHILD_STATUS ChildStatus,
942 IN BOOLEAN NonDestructiveOnly
943 )
944{
945 /* The DxgkDdiQueryChildStatus should be made pageable. */
946 PAGED_CODE();
947
948 vboxVDbgBreakFv();
949
950 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", MiniportDeviceContext));
951
952 NTSTATUS Status = STATUS_SUCCESS;
953 switch (ChildStatus->Type)
954 {
955 case StatusConnection:
956 ChildStatus->HotPlug.Connected = TRUE;
957 dfprintf(("VBoxVideoWddm: StatusConnection\n"));
958 break;
959 case StatusRotation:
960 ChildStatus->Rotation.Angle = 0;
961 dfprintf(("VBoxVideoWddm: StatusRotation\n"));
962 break;
963 default:
964 drprintf(("VBoxVideoWddm: ERROR: status type: %d\n", ChildStatus->Type));
965 AssertBreakpoint();
966 Status = STATUS_INVALID_PARAMETER;
967 break;
968 }
969
970 dfprintf(("<== "__FUNCTION__ ", context(0x%x)\n", MiniportDeviceContext));
971
972 return Status;
973}
974
975NTSTATUS DxgkDdiQueryDeviceDescriptor(
976 IN CONST PVOID MiniportDeviceContext,
977 IN ULONG ChildUid,
978 IN OUT PDXGK_DEVICE_DESCRIPTOR DeviceDescriptor
979 )
980{
981 /* The DxgkDdiQueryDeviceDescriptor should be made pageable. */
982 PAGED_CODE();
983
984 vboxVDbgBreakFv();
985
986 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", MiniportDeviceContext));
987
988 dfprintf(("<== "__FUNCTION__ ", context(0x%x)\n", MiniportDeviceContext));
989
990 /* we do not support EDID */
991 return STATUS_MONITOR_NO_DESCRIPTOR;
992}
993
994NTSTATUS DxgkDdiSetPowerState(
995 IN CONST PVOID MiniportDeviceContext,
996 IN ULONG DeviceUid,
997 IN DEVICE_POWER_STATE DevicePowerState,
998 IN POWER_ACTION ActionType
999 )
1000{
1001 /* The DxgkDdiSetPowerState function should be made pageable. */
1002 PAGED_CODE();
1003
1004 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", MiniportDeviceContext));
1005
1006 /* @todo: */
1007 vboxVDbgBreakF();
1008
1009 dfprintf(("<== "__FUNCTION__ ", context(0x%x)\n", MiniportDeviceContext));
1010
1011 return STATUS_SUCCESS;
1012}
1013
1014NTSTATUS DxgkDdiNotifyAcpiEvent(
1015 IN CONST PVOID MiniportDeviceContext,
1016 IN DXGK_EVENT_TYPE EventType,
1017 IN ULONG Event,
1018 IN PVOID Argument,
1019 OUT PULONG AcpiFlags
1020 )
1021{
1022 dfprintf(("==> "__FUNCTION__ ", MiniportDeviceContext(0x%x)\n", MiniportDeviceContext));
1023
1024 vboxVDbgBreakF();
1025
1026 dfprintf(("<== "__FUNCTION__ ", MiniportDeviceContext(0x%x)\n", MiniportDeviceContext));
1027
1028 return STATUS_SUCCESS;
1029}
1030
1031VOID DxgkDdiResetDevice(
1032 IN CONST PVOID MiniportDeviceContext
1033 )
1034{
1035 /* DxgkDdiResetDevice can be called at any IRQL, so it must be in nonpageable memory. */
1036 vboxVDbgBreakF();
1037
1038 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", MiniportDeviceContext));
1039 dfprintf(("<== "__FUNCTION__ ", context(0x%x)\n", MiniportDeviceContext));
1040}
1041
1042VOID DxgkDdiUnload(
1043 VOID
1044 )
1045{
1046 /* DxgkDdiUnload should be made pageable. */
1047 PAGED_CODE();
1048 dfprintf(("==> "__FUNCTION__ "\n"));
1049
1050 AssertBreakpoint();
1051
1052 dfprintf(("<== "__FUNCTION__ "\n"));
1053}
1054
1055NTSTATUS DxgkDdiQueryInterface(
1056 IN CONST PVOID MiniportDeviceContext,
1057 IN PQUERY_INTERFACE QueryInterface
1058 )
1059{
1060 dfprintf(("==> "__FUNCTION__ ", MiniportDeviceContext(0x%x)\n", MiniportDeviceContext));
1061
1062 vboxVDbgBreakF();
1063
1064 dfprintf(("<== "__FUNCTION__ ", MiniportDeviceContext(0x%x)\n", MiniportDeviceContext));
1065
1066 return STATUS_NOT_SUPPORTED;
1067}
1068
1069VOID DxgkDdiControlEtwLogging(
1070 IN BOOLEAN Enable,
1071 IN ULONG Flags,
1072 IN UCHAR Level
1073 )
1074{
1075 dfprintf(("==> "__FUNCTION__ "\n"));
1076
1077 vboxVDbgBreakF();
1078
1079 dfprintf(("<== "__FUNCTION__ "\n"));
1080}
1081
1082/**
1083 * DxgkDdiQueryAdapterInfo
1084 */
1085NTSTATUS APIENTRY DxgkDdiQueryAdapterInfo(
1086 CONST HANDLE hAdapter,
1087 CONST DXGKARG_QUERYADAPTERINFO* pQueryAdapterInfo)
1088{
1089 /* The DxgkDdiQueryAdapterInfo should be made pageable. */
1090 PAGED_CODE();
1091
1092 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", hAdapter));
1093 NTSTATUS Status = STATUS_SUCCESS;
1094 PDEVICE_EXTENSION pContext = (PDEVICE_EXTENSION)hAdapter;
1095
1096 vboxVDbgBreakF();
1097
1098 switch (pQueryAdapterInfo->Type)
1099 {
1100 case DXGKQAITYPE_DRIVERCAPS:
1101 {
1102 DXGK_DRIVERCAPS *pCaps = (DXGK_DRIVERCAPS*)pQueryAdapterInfo->pOutputData;
1103
1104 pCaps->HighestAcceptableAddress.HighPart = 0x0;
1105 pCaps->HighestAcceptableAddress.LowPart = 0xffffffffUL;
1106 pCaps->MaxAllocationListSlotId = 16;
1107 pCaps->ApertureSegmentCommitLimit = 0;
1108 pCaps->MaxPointerWidth = 64;
1109 pCaps->MaxPointerHeight = 64;
1110 pCaps->PointerCaps.Value = 3; /* Monochrome , Color*/ /* MaskedColor == Value | 4, dosable for now */
1111 pCaps->InterruptMessageNumber = 0;
1112 pCaps->NumberOfSwizzlingRanges = 0;
1113 /* @todo: need to adjust this for proper 2D Accel support */
1114 pCaps->MaxOverlays = 0; /* ?? how much should we support? 32 */
1115 pCaps->GammaRampCaps.Value = 0;
1116 pCaps->PresentationCaps.Value = 0;
1117 pCaps->PresentationCaps.NoScreenToScreenBlt = 1;
1118 pCaps->PresentationCaps.NoOverlapScreenBlt = 1;
1119 pCaps->MaxQueuedFlipOnVSync = 0; /* do we need it? */
1120 pCaps->FlipCaps.Value = 0;
1121 /* ? pCaps->FlipCaps.FlipOnVSyncWithNoWait = 1; */
1122 pCaps->SchedulingCaps.Value = 0;
1123 /* we might need it for Aero.
1124 * Setting this flag means we support DeviceContext, i.e.
1125 * DxgkDdiCreateContext and DxgkDdiDestroyContext
1126 */
1127 pCaps->SchedulingCaps.MultiEngineAware = 1;
1128 pCaps->MemoryManagementCaps.Value = 0;
1129 /* @todo: this corelates with pCaps->SchedulingCaps.MultiEngineAware */
1130 pCaps->MemoryManagementCaps.PagingNode = 0;
1131 /* @todo: this corelates with pCaps->SchedulingCaps.MultiEngineAware */
1132 pCaps->GpuEngineTopology.NbAsymetricProcessingNodes = 1;
1133
1134 break;
1135 }
1136 case DXGKQAITYPE_QUERYSEGMENT:
1137 {
1138 /* no need for DXGK_QUERYSEGMENTIN as it contains AGP aperture info, which (AGP aperture) we do not support
1139 * DXGK_QUERYSEGMENTIN *pQsIn = (DXGK_QUERYSEGMENTIN*)pQueryAdapterInfo->pInputData; */
1140 DXGK_QUERYSEGMENTOUT *pQsOut = (DXGK_QUERYSEGMENTOUT*)pQueryAdapterInfo->pOutputData;
1141 if (!pQsOut->pSegmentDescriptor)
1142 {
1143 /* we are requested to provide the number of segments we support */
1144 pQsOut->NbSegment = 1;
1145 }
1146 else if (pQsOut->NbSegment != 1)
1147 {
1148 AssertBreakpoint();
1149 drprintf((__FUNCTION__ " NbSegment (%d) != 1\n", pQsOut->NbSegment));
1150 Status = STATUS_INVALID_PARAMETER;
1151 }
1152 else
1153 {
1154 DXGK_SEGMENTDESCRIPTOR* pDr = pQsOut->pSegmentDescriptor;
1155 /* we are requested to provide segment information */
1156 pDr->BaseAddress.QuadPart = 0; /* VBE_DISPI_LFB_PHYSICAL_ADDRESS; */
1157 pDr->CpuTranslatedAddress.QuadPart = VBE_DISPI_LFB_PHYSICAL_ADDRESS;
1158 /* make sure the size is page aligned */
1159 /* @todo: need to setup VBVA buffers and adjust the mem size here */
1160 pDr->Size = vboxWddmVramReportedSegmentSize(pContext);
1161 pDr->NbOfBanks = 0;
1162 pDr->pBankRangeTable = 0;
1163 pDr->CommitLimit = pDr->Size;
1164 pDr->Flags.Value = 0;
1165 pDr->Flags.CpuVisible = 1;
1166
1167 ++pDr;
1168 /* create cpu-invisible segment of the same size */
1169 pDr->BaseAddress.QuadPart = 0;
1170 pDr->CpuTranslatedAddress.QuadPart = 0;
1171 /* make sure the size is page aligned */
1172 /* @todo: need to setup VBVA buffers and adjust the mem size here */
1173 pDr->Size = vboxWddmVramReportedSegmentSize(pContext);
1174 pDr->NbOfBanks = 0;
1175 pDr->pBankRangeTable = 0;
1176 pDr->CommitLimit = pDr->Size;
1177 pDr->Flags.Value = 0;
1178
1179 pQsOut->PagingBufferSegmentId = 0;
1180 pQsOut->PagingBufferSize = 1024;
1181 pQsOut->PagingBufferPrivateDataSize = 0; /* @todo: do we need a private buffer ? */
1182 }
1183 break;
1184 }
1185 case DXGKQAITYPE_UMDRIVERPRIVATE:
1186 drprintf((__FUNCTION__ ": we do not support DXGKQAITYPE_UMDRIVERPRIVATE\n"));
1187 AssertBreakpoint();
1188 Status = STATUS_NOT_SUPPORTED;
1189 break;
1190 default:
1191 drprintf((__FUNCTION__ ": unsupported Type (%d)\n", pQueryAdapterInfo->Type));
1192 AssertBreakpoint();
1193 Status = STATUS_NOT_SUPPORTED;
1194 break;
1195 }
1196 dfprintf(("<== "__FUNCTION__ ", context(0x%x), Status(0x%x)\n", hAdapter, Status));
1197 return Status;
1198}
1199
1200/**
1201 * DxgkDdiCreateDevice
1202 */
1203NTSTATUS APIENTRY DxgkDdiCreateDevice(
1204 CONST HANDLE hAdapter,
1205 DXGKARG_CREATEDEVICE* pCreateDevice)
1206{
1207 /* DxgkDdiCreateDevice should be made pageable. */
1208 PAGED_CODE();
1209
1210 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", hAdapter));
1211 NTSTATUS Status = STATUS_SUCCESS;
1212 PDEVICE_EXTENSION pContext = (PDEVICE_EXTENSION)hAdapter;
1213
1214 vboxVDbgBreakFv();
1215
1216 PVBOXWDDM_DEVICE pDevice = (PVBOXWDDM_DEVICE)vboxWddmMemAllocZero(sizeof (VBOXWDDM_DEVICE));
1217 pCreateDevice->hDevice = pDevice;
1218 if (pCreateDevice->Flags.SystemDevice)
1219 pDevice->enmType = VBOXWDDM_DEVICE_TYPE_SYSTEM;
1220 else
1221 {
1222 AssertBreakpoint(); /* we do not support custom contexts for now */
1223 drprintf((__FUNCTION__ ": we do not support custom devices for now, hAdapter (0x%x)\n", hAdapter));
1224 }
1225
1226 pDevice->pAdapter = pContext;
1227 pDevice->hDevice = pCreateDevice->hDevice;
1228
1229 pCreateDevice->hDevice = pDevice;
1230 pCreateDevice->pInfo = NULL;
1231
1232 dfprintf(("<== "__FUNCTION__ ", context(0x%x), Status(0x%x)\n", hAdapter, Status));
1233
1234 return Status;
1235}
1236NTSTATUS vboxWddmDestroyAllocation(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_ALLOCATION pAllocation)
1237{
1238 PAGED_CODE();
1239
1240 vboxWddmMemFree(pAllocation);
1241 return STATUS_SUCCESS;
1242}
1243
1244NTSTATUS vboxWddmCreateAllocation(PDEVICE_EXTENSION pDevExt, DXGK_ALLOCATIONINFO* pAllocationInfo)
1245{
1246 PAGED_CODE();
1247
1248 NTSTATUS Status = STATUS_SUCCESS;
1249
1250 Assert(pAllocationInfo->PrivateDriverDataSize >= VBOXWDDM_ALLOCINFO_HEADSIZE());
1251 if (pAllocationInfo->PrivateDriverDataSize >= VBOXWDDM_ALLOCINFO_HEADSIZE())
1252 {
1253 PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pAllocationInfo->pPrivateDriverData;
1254 switch (pAllocInfo->enmType)
1255 {
1256 case VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE:
1257 {
1258 Assert(pAllocationInfo->PrivateDriverDataSize >= VBOXWDDM_ALLOCINFO_SIZE(VBOXWDDM_ALLOCINFO_SHAREDPRIMARYSURFACE));
1259 if (pAllocationInfo->PrivateDriverDataSize >= VBOXWDDM_ALLOCINFO_SIZE(VBOXWDDM_ALLOCINFO_SHAREDPRIMARYSURFACE))
1260 {
1261 if (pAllocInfo->u.SurfInfo.bpp != 0)
1262 {
1263 PVBOXWDDM_ALLOCATION pAllocation = (PVBOXWDDM_ALLOCATION)vboxWddmMemAllocZero(VBOXWDDM_ALLOCATION_SIZE(VBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE));
1264 Assert(pAllocation);
1265 if (pAllocation)
1266 {
1267 pAllocation->enmType = VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE;
1268 pAllocation->u.SurfInfo = pAllocInfo->u.SurfInfo;
1269 PVBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE pAlloc = VBOXWDDM_ALLOCATION_BODY(pAllocation, VBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE);
1270 PVBOXWDDM_ALLOCINFO_SHAREDPRIMARYSURFACE pAllocI = VBOXWDDM_ALLOCINFO_BODY(pAllocInfo, VBOXWDDM_ALLOCINFO_SHAREDPRIMARYSURFACE);
1271 pAlloc->RefreshRate = pAllocI->RefreshRate;
1272 pAlloc->VidPnSourceId = pAllocI->VidPnSourceId;
1273// pAlloc->offAddress = VBOXVIDEOOFFSET_VOID;
1274 pAlloc->bVisible = FALSE;
1275
1276 pAllocationInfo->pPrivateDriverData = NULL;
1277 pAllocationInfo->PrivateDriverDataSize = 0;
1278 pAllocationInfo->Alignment = 0;
1279 pAllocationInfo->Size = pAllocInfo->u.SurfInfo.pitch * pAllocInfo->u.SurfInfo.height;
1280 pAllocationInfo->PitchAlignedSize = 0;
1281 pAllocationInfo->HintedBank.Value = 0;
1282 pAllocationInfo->PreferredSegment.Value = 0;
1283 pAllocationInfo->SupportedReadSegmentSet = 1;
1284 pAllocationInfo->SupportedWriteSegmentSet = 1;
1285 pAllocationInfo->EvictionSegmentSet = 0;
1286 pAllocationInfo->MaximumRenamingListLength = 0;
1287 pAllocationInfo->hAllocation = pAllocation;
1288 pAllocationInfo->Flags.Value = 0;
1289 pAllocationInfo->Flags.CpuVisible = 1;
1290 pAllocationInfo->pAllocationUsageHint = NULL;
1291 pAllocationInfo->AllocationPriority = D3DDDI_ALLOCATIONPRIORITY_NORMAL;
1292 }
1293 else
1294 {
1295 drprintf((__FUNCTION__ ": ERROR: failed to create allocation description\n"));
1296 Status = STATUS_NO_MEMORY;
1297 }
1298 }
1299 else
1300 {
1301 drprintf((__FUNCTION__ ": Invalid format (%d)\n", pAllocInfo->u.SurfInfo.format));
1302 Status = STATUS_INVALID_PARAMETER;
1303 }
1304 }
1305 else
1306 {
1307 drprintf((__FUNCTION__ ": ERROR: PrivateDriverDataSize(%d) less than VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE cmd size(%d)\n", pAllocationInfo->PrivateDriverDataSize, VBOXWDDM_ALLOCINFO_SIZE(VBOXWDDM_ALLOCINFO_SHAREDPRIMARYSURFACE)));
1308 Status = STATUS_INVALID_PARAMETER;
1309 }
1310 break;
1311 }
1312 case VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE:
1313 case VBOXWDDM_ALLOC_TYPE_STD_STAGINGSURFACE:
1314 {
1315 Assert(pAllocationInfo->PrivateDriverDataSize >= VBOXWDDM_ALLOCINFO_HEADSIZE());
1316 if (pAllocationInfo->PrivateDriverDataSize >= VBOXWDDM_ALLOCINFO_HEADSIZE())
1317 {
1318 PVBOXWDDM_ALLOCATION pAllocation = (PVBOXWDDM_ALLOCATION)vboxWddmMemAllocZero(VBOXWDDM_ALLOCATION_HEADSIZE());
1319 Assert(pAllocation);
1320 if (pAllocation)
1321 {
1322 pAllocation->enmType = pAllocInfo->enmType;
1323 pAllocation->u.SurfInfo = pAllocInfo->u.SurfInfo;
1324
1325 pAllocationInfo->pPrivateDriverData = NULL;
1326 pAllocationInfo->PrivateDriverDataSize = 0;
1327 pAllocationInfo->Alignment = 0;
1328 pAllocationInfo->Size = pAllocInfo->u.SurfInfo.pitch * pAllocInfo->u.SurfInfo.height;
1329 pAllocationInfo->PitchAlignedSize = 0;
1330 pAllocationInfo->HintedBank.Value = 0;
1331 pAllocationInfo->PreferredSegment.Value = 0;
1332 pAllocationInfo->SupportedReadSegmentSet = 1;
1333 pAllocationInfo->SupportedWriteSegmentSet = 1;
1334 pAllocationInfo->EvictionSegmentSet = 0;
1335 pAllocationInfo->MaximumRenamingListLength = 0;
1336 pAllocationInfo->hAllocation = pAllocation;
1337 pAllocationInfo->Flags.Value = 0;
1338 pAllocationInfo->Flags.CpuVisible = 1;
1339 pAllocationInfo->pAllocationUsageHint = NULL;
1340 pAllocationInfo->AllocationPriority = D3DDDI_ALLOCATIONPRIORITY_NORMAL;
1341 }
1342 else
1343 {
1344 drprintf((__FUNCTION__ ": ERROR: failed to create allocation description\n"));
1345 Status = STATUS_NO_MEMORY;
1346 }
1347 }
1348 else
1349 {
1350 drprintf((__FUNCTION__ ": ERROR: PrivateDriverDataSize(%d) less than cmd size(%d)\n", pAllocationInfo->PrivateDriverDataSize, VBOXWDDM_ALLOCINFO_HEADSIZE()));
1351 Status = STATUS_INVALID_PARAMETER;
1352 }
1353 break;
1354 }
1355 default:
1356 drprintf((__FUNCTION__ ": ERROR: invalid alloc info type(%d)\n", pAllocInfo->enmType));
1357 Status = STATUS_INVALID_PARAMETER;
1358 break;
1359 }
1360 }
1361 else
1362 {
1363 drprintf((__FUNCTION__ ": ERROR: PrivateDriverDataSize(%d) less than header size(%d)\n", pAllocationInfo->PrivateDriverDataSize, VBOXWDDM_ALLOCINFO_HEADSIZE()));
1364 Status = STATUS_INVALID_PARAMETER;
1365 }
1366
1367 return Status;
1368}
1369
1370NTSTATUS APIENTRY DxgkDdiCreateAllocation(
1371 CONST HANDLE hAdapter,
1372 DXGKARG_CREATEALLOCATION* pCreateAllocation)
1373{
1374 /* DxgkDdiCreateAllocation should be made pageable. */
1375 PAGED_CODE();
1376
1377 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", hAdapter));
1378
1379 AssertBreakpoint();
1380
1381 NTSTATUS Status = STATUS_SUCCESS;
1382
1383 for (UINT i = 0; i < pCreateAllocation->NumAllocations; ++i)
1384 {
1385 Status = vboxWddmCreateAllocation((PDEVICE_EXTENSION)hAdapter, &pCreateAllocation->pAllocationInfo[i]);
1386 Assert(Status == STATUS_SUCCESS);
1387 if (Status != STATUS_SUCCESS)
1388 {
1389 drprintf((__FUNCTION__ ": ERROR: vboxWddmCreateAllocation error (0x%x)\n", Status));
1390 /* note: i-th allocation is expected to be cleared in a fail handling code above */
1391 for (UINT j = 0; j < i; ++j)
1392 {
1393 vboxWddmDestroyAllocation((PDEVICE_EXTENSION)hAdapter, (PVBOXWDDM_ALLOCATION)pCreateAllocation->pAllocationInfo[j].hAllocation);
1394 }
1395 }
1396 }
1397
1398 dfprintf(("<== "__FUNCTION__ ", status(0x%x), context(0x%x)\n", Status, hAdapter));
1399
1400 return Status;
1401}
1402
1403NTSTATUS
1404APIENTRY
1405DxgkDdiDestroyAllocation(
1406 CONST HANDLE hAdapter,
1407 CONST DXGKARG_DESTROYALLOCATION* pDestroyAllocation)
1408{
1409 /* DxgkDdiDestroyAllocation should be made pageable. */
1410 PAGED_CODE();
1411
1412 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", hAdapter));
1413 NTSTATUS Status = STATUS_SUCCESS;
1414
1415 for (UINT i = 0; i < pDestroyAllocation->NumAllocations; ++i)
1416 {
1417 vboxWddmDestroyAllocation((PDEVICE_EXTENSION)hAdapter, (PVBOXWDDM_ALLOCATION)pDestroyAllocation->pAllocationList[i]);
1418 }
1419
1420 dfprintf(("<== "__FUNCTION__ ", status(0x%x), context(0x%x)\n", Status, hAdapter));
1421
1422 return Status;
1423}
1424
1425/**
1426 * DxgkDdiDescribeAllocation
1427 */
1428NTSTATUS
1429APIENTRY
1430DxgkDdiDescribeAllocation(
1431 CONST HANDLE hAdapter,
1432 DXGKARG_DESCRIBEALLOCATION* pDescribeAllocation)
1433{
1434 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1435
1436 AssertBreakpoint();
1437 PVBOXWDDM_ALLOCATION pAllocation = (PVBOXWDDM_ALLOCATION)pDescribeAllocation->hAllocation;
1438 pDescribeAllocation->Width = pAllocation->u.SurfInfo.width;
1439 pDescribeAllocation->Height = pAllocation->u.SurfInfo.height;
1440 pDescribeAllocation->Format = pAllocation->u.SurfInfo.format;
1441 memset (&pDescribeAllocation->MultisampleMethod, 0, sizeof (pDescribeAllocation->MultisampleMethod));
1442 pDescribeAllocation->RefreshRate.Numerator = 60000;
1443 pDescribeAllocation->RefreshRate.Denominator = 1000;
1444 pDescribeAllocation->PrivateDriverFormatAttribute = 0;
1445
1446 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1447
1448 return STATUS_SUCCESS;
1449}
1450
1451/**
1452 * DxgkDdiGetStandardAllocationDriverData
1453 */
1454NTSTATUS
1455APIENTRY
1456DxgkDdiGetStandardAllocationDriverData(
1457 CONST HANDLE hAdapter,
1458 DXGKARG_GETSTANDARDALLOCATIONDRIVERDATA* pGetStandardAllocationDriverData)
1459{
1460 /* DxgkDdiGetStandardAllocationDriverData should be made pageable. */
1461 PAGED_CODE();
1462
1463 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", hAdapter));
1464
1465 AssertBreakpoint();
1466
1467 NTSTATUS Status = STATUS_SUCCESS;
1468 PVBOXWDDM_ALLOCINFO pAllocInfo = NULL;
1469
1470 switch (pGetStandardAllocationDriverData->StandardAllocationType)
1471 {
1472 case D3DKMDT_STANDARDALLOCATION_SHAREDPRIMARYSURFACE:
1473 {
1474 dfprintf((__FUNCTION__ ": D3DKMDT_STANDARDALLOCATION_SHAREDPRIMARYSURFACE\n"));
1475 if(pGetStandardAllocationDriverData->pAllocationPrivateDriverData)
1476 {
1477 pAllocInfo = (PVBOXWDDM_ALLOCINFO)pGetStandardAllocationDriverData->pAllocationPrivateDriverData;
1478 pAllocInfo->enmType = VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE;
1479 pAllocInfo->u.SurfInfo.width = pGetStandardAllocationDriverData->pCreateSharedPrimarySurfaceData->Width;
1480 pAllocInfo->u.SurfInfo.height = pGetStandardAllocationDriverData->pCreateSharedPrimarySurfaceData->Height;
1481 pAllocInfo->u.SurfInfo.format = pGetStandardAllocationDriverData->pCreateSharedPrimarySurfaceData->Format;
1482 pAllocInfo->u.SurfInfo.bpp = vboxWddmCalcBitsPerPixel(pAllocInfo->u.SurfInfo.format);
1483 pAllocInfo->u.SurfInfo.pitch = vboxWddmCalcPitch(pGetStandardAllocationDriverData->pCreateSharedPrimarySurfaceData->Width, pAllocInfo->u.SurfInfo.bpp);
1484 PVBOXWDDM_ALLOCINFO_SHAREDPRIMARYSURFACE pInfo = VBOXWDDM_ALLOCINFO_BODY(pAllocInfo, VBOXWDDM_ALLOCINFO_SHAREDPRIMARYSURFACE);
1485 pInfo->RefreshRate = pGetStandardAllocationDriverData->pCreateSharedPrimarySurfaceData->RefreshRate;
1486 pInfo->VidPnSourceId = pGetStandardAllocationDriverData->pCreateSharedPrimarySurfaceData->VidPnSourceId;
1487 }
1488 pGetStandardAllocationDriverData->AllocationPrivateDriverDataSize = VBOXWDDM_ALLOCINFO_SIZE(VBOXWDDM_ALLOCINFO_SHAREDPRIMARYSURFACE);
1489
1490 pGetStandardAllocationDriverData->ResourcePrivateDriverDataSize = 0;
1491 break;
1492 }
1493 case D3DKMDT_STANDARDALLOCATION_SHADOWSURFACE:
1494 {
1495 dfprintf((__FUNCTION__ ": D3DKMDT_STANDARDALLOCATION_SHADOWSURFACE\n"));
1496 UINT bpp = vboxWddmCalcBitsPerPixel(pGetStandardAllocationDriverData->pCreateShadowSurfaceData->Format);
1497 Assert(bpp);
1498 if (bpp != 0)
1499 {
1500 UINT Pitch = vboxWddmCalcPitch(pGetStandardAllocationDriverData->pCreateShadowSurfaceData->Width, bpp);
1501 pGetStandardAllocationDriverData->pCreateShadowSurfaceData->Pitch = Pitch;
1502
1503 /* @todo: need [d/q]word align?? */
1504
1505 if (pGetStandardAllocationDriverData->pAllocationPrivateDriverData)
1506 {
1507 pAllocInfo = (PVBOXWDDM_ALLOCINFO)pGetStandardAllocationDriverData->pAllocationPrivateDriverData;
1508 pAllocInfo->enmType = VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE;
1509 pAllocInfo->u.SurfInfo.width = pGetStandardAllocationDriverData->pCreateShadowSurfaceData->Width;
1510 pAllocInfo->u.SurfInfo.height = pGetStandardAllocationDriverData->pCreateShadowSurfaceData->Height;
1511 pAllocInfo->u.SurfInfo.format = pGetStandardAllocationDriverData->pCreateShadowSurfaceData->Format;
1512 pAllocInfo->u.SurfInfo.bpp = vboxWddmCalcBitsPerPixel(pAllocInfo->u.SurfInfo.format);
1513 pAllocInfo->u.SurfInfo.pitch = vboxWddmCalcPitch(pGetStandardAllocationDriverData->pCreateShadowSurfaceData->Width, pAllocInfo->u.SurfInfo.bpp);
1514
1515 pGetStandardAllocationDriverData->pCreateShadowSurfaceData->Pitch = pAllocInfo->u.SurfInfo.pitch;
1516 }
1517 pGetStandardAllocationDriverData->AllocationPrivateDriverDataSize = VBOXWDDM_ALLOCINFO_HEADSIZE();
1518
1519 pGetStandardAllocationDriverData->ResourcePrivateDriverDataSize = 0;
1520 }
1521 else
1522 {
1523 drprintf((__FUNCTION__ ": Invalid format (%d)\n", pGetStandardAllocationDriverData->pCreateShadowSurfaceData->Format));
1524 Status = STATUS_INVALID_PARAMETER;
1525 }
1526 break;
1527 }
1528 case D3DKMDT_STANDARDALLOCATION_STAGINGSURFACE:
1529 {
1530 dfprintf((__FUNCTION__ ": D3DKMDT_STANDARDALLOCATION_STAGINGSURFACE\n"));
1531 if(pGetStandardAllocationDriverData->pAllocationPrivateDriverData)
1532 {
1533 pAllocInfo = (PVBOXWDDM_ALLOCINFO)pGetStandardAllocationDriverData->pAllocationPrivateDriverData;
1534 pAllocInfo->enmType = VBOXWDDM_ALLOC_TYPE_STD_STAGINGSURFACE;
1535 pAllocInfo->u.SurfInfo.width = pGetStandardAllocationDriverData->pCreateStagingSurfaceData->Width;
1536 pAllocInfo->u.SurfInfo.height = pGetStandardAllocationDriverData->pCreateStagingSurfaceData->Height;
1537 pAllocInfo->u.SurfInfo.format = D3DDDIFMT_X8R8G8B8; /* staging has always always D3DDDIFMT_X8R8G8B8 */
1538 pAllocInfo->u.SurfInfo.bpp = vboxWddmCalcBitsPerPixel(pAllocInfo->u.SurfInfo.format);
1539 pAllocInfo->u.SurfInfo.pitch = vboxWddmCalcPitch(pGetStandardAllocationDriverData->pCreateStagingSurfaceData->Width, pAllocInfo->u.SurfInfo.bpp);
1540
1541 pGetStandardAllocationDriverData->pCreateStagingSurfaceData->Pitch = pAllocInfo->u.SurfInfo.pitch;
1542 }
1543 pGetStandardAllocationDriverData->AllocationPrivateDriverDataSize = VBOXWDDM_ALLOCINFO_HEADSIZE();
1544
1545 pGetStandardAllocationDriverData->ResourcePrivateDriverDataSize = 0;
1546 break;
1547 }
1548//#if (DXGKDDI_INTERFACE_VERSION >= DXGKDDI_INTERFACE_VERSION_WIN7)
1549// case D3DKMDT_STANDARDALLOCATION_GDISURFACE:
1550//# error port to Win7 DDI
1551// break;
1552//#endif
1553 default:
1554 drprintf((__FUNCTION__ ": Invalid allocation type (%d)\n", pGetStandardAllocationDriverData->StandardAllocationType));
1555 Status = STATUS_INVALID_PARAMETER;
1556 break;
1557 }
1558
1559 dfprintf(("<== "__FUNCTION__ ", status(0x%x), context(0x%x)\n", Status, hAdapter));
1560
1561 return Status;
1562}
1563
1564NTSTATUS
1565APIENTRY
1566DxgkDdiAcquireSwizzlingRange(
1567 CONST HANDLE hAdapter,
1568 DXGKARG_ACQUIRESWIZZLINGRANGE* pAcquireSwizzlingRange)
1569{
1570 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1571
1572 AssertBreakpoint();
1573
1574 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1575
1576 return STATUS_SUCCESS;
1577}
1578
1579NTSTATUS
1580APIENTRY
1581DxgkDdiReleaseSwizzlingRange(
1582 CONST HANDLE hAdapter,
1583 CONST DXGKARG_RELEASESWIZZLINGRANGE* pReleaseSwizzlingRange)
1584{
1585 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1586
1587 AssertBreakpoint();
1588
1589 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1590
1591 return STATUS_SUCCESS;
1592}
1593
1594NTSTATUS
1595APIENTRY
1596DxgkDdiPatch(
1597 CONST HANDLE hAdapter,
1598 CONST DXGKARG_PATCH* pPatch)
1599{
1600 /* DxgkDdiPatch should be made pageable. */
1601 PAGED_CODE();
1602
1603 NTSTATUS Status = STATUS_SUCCESS;
1604
1605 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", hAdapter));
1606
1607 /* Value == 2 is Present
1608 * Value == 4 is RedirectedPresent
1609 * we do not expect any other flags to be set here */
1610 Assert(pPatch->Flags.Value == 2 || pPatch->Flags.Value == 4);
1611
1612 uint8_t *pBuf = ((uint8_t *)pPatch->pDmaBuffer) + pPatch->DmaBufferPrivateDataSubmissionStartOffset;
1613 for (UINT i = pPatch->PatchLocationListSubmissionStart; i < pPatch->PatchLocationListSubmissionLength; ++i)
1614 {
1615 const D3DDDI_PATCHLOCATIONLIST* pPatchList = &pPatch->pPatchLocationList[i];
1616 Assert(pPatchList->AllocationIndex < pPatch->AllocationListSize);
1617 const DXGK_ALLOCATIONLIST *pAllocationList = &pPatch->pAllocationList[pPatchList->AllocationIndex];
1618 if (pAllocationList->SegmentId)
1619 {
1620 Assert(pPatchList->PatchOffset < (pPatch->DmaBufferPrivateDataSubmissionEndOffset - pPatch->DmaBufferPrivateDataSubmissionStartOffset));
1621 *((VBOXVIDEOOFFSET*)(pBuf+pPatchList->PatchOffset)) = (VBOXVIDEOOFFSET)pAllocationList->PhysicalAddress.QuadPart;
1622 }
1623 else
1624 {
1625 /* sanity */
1626 if (pPatch->Flags.Value == 2 || pPatch->Flags.Value == 4)
1627 Assert(i == 0);
1628 }
1629 }
1630
1631 dfprintf(("<== "__FUNCTION__ ", context(0x%x)\n", hAdapter));
1632
1633 return Status;
1634}
1635
1636NTSTATUS
1637APIENTRY
1638DxgkDdiSubmitCommand(
1639 CONST HANDLE hAdapter,
1640 CONST DXGKARG_SUBMITCOMMAND* pSubmitCommand)
1641{
1642 /* DxgkDdiSubmitCommand runs at dispatch, should not be pageable. */
1643 NTSTATUS Status = STATUS_SUCCESS;
1644
1645 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", hAdapter));
1646
1647 PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)hAdapter;
1648 VBOXVDMACMDBUF_INFO BufInfo = {0};
1649
1650 Assert(pSubmitCommand->DmaBufferSegmentId);
1651
1652 /* the DMA command buffer is located in system RAM, the host will need to pick it from there */
1653 //BufInfo.fFlags = 0; /* see VBOXVDMACBUF_FLAG_xx */
1654 BufInfo.cbBuf = pSubmitCommand->DmaBufferPrivateDataSubmissionEndOffset - pSubmitCommand->DmaBufferPrivateDataSubmissionStartOffset;
1655 BufInfo.Location.phBuf = pSubmitCommand->DmaBufferPhysicalAddress.QuadPart + pSubmitCommand->DmaBufferPrivateDataSubmissionStartOffset;
1656 BufInfo.u32FenceId = pSubmitCommand->SubmissionFenceId;
1657
1658 int rc = vboxVdmaCBufSubmit (pDevExt, &pDevExt->u.primary.Vdma, &BufInfo);
1659 AssertRC(rc);
1660 if (!RT_SUCCESS(rc))
1661 {
1662 switch (rc)
1663 {
1664 case VERR_OUT_OF_RESOURCES:
1665 /* @todo: try flushing.. */
1666 Status = STATUS_INSUFFICIENT_RESOURCES;
1667 break;
1668 default:
1669 Status = STATUS_UNSUCCESSFUL;
1670 break;
1671 }
1672 }
1673
1674 dfprintf(("<== "__FUNCTION__ ", context(0x%x)\n", hAdapter));
1675
1676 return Status;
1677}
1678
1679NTSTATUS
1680APIENTRY
1681DxgkDdiPreemptCommand(
1682 CONST HANDLE hAdapter,
1683 CONST DXGKARG_PREEMPTCOMMAND* pPreemptCommand)
1684{
1685 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1686
1687 AssertBreakpoint();
1688 /* @todo: fixme: implement */
1689
1690 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1691
1692 return STATUS_SUCCESS;
1693}
1694
1695NTSTATUS
1696APIENTRY
1697DxgkDdiBuildPagingBuffer(
1698 CONST HANDLE hAdapter,
1699 DXGKARG_BUILDPAGINGBUFFER* pBuildPagingBuffer)
1700{
1701 /* DxgkDdiBuildPagingBuffer should be made pageable. */
1702 PAGED_CODE();
1703
1704 AssertBreakpoint();
1705
1706 NTSTATUS Status = STATUS_SUCCESS;
1707
1708 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", hAdapter));
1709
1710 /* @todo: */
1711 switch (pBuildPagingBuffer->Operation)
1712 {
1713 case DXGK_OPERATION_TRANSFER:
1714 {
1715 PVBOXWDDM_ALLOCATION pAllocation = (PVBOXWDDM_ALLOCATION)pBuildPagingBuffer->Transfer.hAllocation;
1716 break;
1717 }
1718 case DXGK_OPERATION_FILL:
1719 break;
1720 case DXGK_OPERATION_DISCARD_CONTENT:
1721 break;
1722 default:
1723 drprintf((__FUNCTION__": unsupported op (%d)\n", pBuildPagingBuffer->Operation));
1724 AssertBreakpoint();
1725 break;
1726 }
1727
1728 dfprintf(("<== "__FUNCTION__ ", context(0x%x)\n", hAdapter));
1729
1730 return Status;
1731
1732}
1733
1734NTSTATUS
1735APIENTRY
1736DxgkDdiSetPalette(
1737 CONST HANDLE hAdapter,
1738 CONST DXGKARG_SETPALETTE* pSetPalette
1739 )
1740{
1741 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1742
1743 AssertBreakpoint();
1744 /* @todo: fixme: implement */
1745
1746 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1747
1748 return STATUS_SUCCESS;
1749}
1750
1751NTSTATUS
1752APIENTRY
1753DxgkDdiSetPointerPosition(
1754 CONST HANDLE hAdapter,
1755 CONST DXGKARG_SETPOINTERPOSITION* pSetPointerPosition)
1756{
1757 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1758
1759 AssertBreakpoint();
1760 /* @todo: fixme: implement */
1761
1762 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1763
1764 return STATUS_SUCCESS;
1765}
1766
1767NTSTATUS
1768APIENTRY
1769DxgkDdiSetPointerShape(
1770 CONST HANDLE hAdapter,
1771 CONST DXGKARG_SETPOINTERSHAPE* pSetPointerShape)
1772{
1773 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1774
1775 AssertBreakpoint();
1776 /* @todo: fixme: implement */
1777
1778 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1779
1780 return STATUS_SUCCESS;
1781}
1782
1783NTSTATUS
1784APIENTRY CALLBACK
1785DxgkDdiResetFromTimeout(
1786 CONST HANDLE hAdapter)
1787{
1788 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1789
1790 AssertBreakpoint();
1791 /* @todo: fixme: implement */
1792
1793 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1794
1795 return STATUS_SUCCESS;
1796}
1797
1798NTSTATUS
1799APIENTRY
1800DxgkDdiEscape(
1801 CONST HANDLE hAdapter,
1802 CONST DXGKARG_ESCAPE* pEscape)
1803{
1804 PAGED_CODE();
1805
1806 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1807
1808 AssertBreakpoint();
1809
1810 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1811
1812 return STATUS_INVALID_PARAMETER;
1813}
1814
1815NTSTATUS
1816APIENTRY
1817DxgkDdiCollectDbgInfo(
1818 CONST HANDLE hAdapter,
1819 CONST DXGKARG_COLLECTDBGINFO* pCollectDbgInfo
1820 )
1821{
1822 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1823
1824 AssertBreakpoint();
1825
1826 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1827
1828 return STATUS_SUCCESS;
1829}
1830
1831NTSTATUS
1832APIENTRY
1833DxgkDdiQueryCurrentFence(
1834 CONST HANDLE hAdapter,
1835 DXGKARG_QUERYCURRENTFENCE* pCurrentFence)
1836{
1837 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1838
1839 AssertBreakpoint();
1840 /* @todo: fixme: implement */
1841
1842 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1843
1844 return STATUS_SUCCESS;
1845}
1846
1847NTSTATUS
1848APIENTRY
1849DxgkDdiIsSupportedVidPn(
1850 CONST HANDLE hAdapter,
1851 OUT DXGKARG_ISSUPPORTEDVIDPN* pIsSupportedVidPnArg
1852 )
1853{
1854 /* The DxgkDdiIsSupportedVidPn should be made pageable. */
1855 PAGED_CODE();
1856
1857 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", hAdapter));
1858
1859 AssertBreakpoint();
1860
1861 PDEVICE_EXTENSION pContext = (PDEVICE_EXTENSION)hAdapter;
1862 BOOLEAN bSupported = TRUE;
1863 const DXGK_VIDPN_INTERFACE* pVidPnInterface = NULL;
1864 NTSTATUS Status = pContext->u.primary.DxgkInterface.DxgkCbQueryVidPnInterface(pIsSupportedVidPnArg->hDesiredVidPn, DXGK_VIDPN_INTERFACE_VERSION_V1, &pVidPnInterface);
1865 if (Status == STATUS_SUCCESS)
1866 {
1867 D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology;
1868 const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface;
1869 Status = pVidPnInterface->pfnGetTopology(pIsSupportedVidPnArg->hDesiredVidPn, &hVidPnTopology, &pVidPnTopologyInterface);
1870 if (Status == STATUS_SUCCESS)
1871 {
1872 Status = vboxVidPnCheckTopology(pIsSupportedVidPnArg->hDesiredVidPn, hVidPnTopology, pVidPnTopologyInterface, &bSupported);
1873 if (Status == STATUS_SUCCESS && bSupported)
1874 {
1875 for (UINT id = 0; id < pContext->cSources; ++id)
1876 {
1877 D3DKMDT_HVIDPNSOURCEMODESET hNewVidPnSourceModeSet;
1878 const DXGK_VIDPNSOURCEMODESET_INTERFACE *pVidPnSourceModeSetInterface;
1879 Status = pVidPnInterface->pfnAcquireSourceModeSet(pIsSupportedVidPnArg->hDesiredVidPn,
1880 id,
1881 &hNewVidPnSourceModeSet,
1882 &pVidPnSourceModeSetInterface);
1883 if (Status == STATUS_SUCCESS)
1884 {
1885 Status = vboxVidPnCheckSourceModeSet(pIsSupportedVidPnArg->hDesiredVidPn, hNewVidPnSourceModeSet, pVidPnSourceModeSetInterface, &bSupported);
1886
1887 pVidPnInterface->pfnReleaseSourceModeSet(pIsSupportedVidPnArg->hDesiredVidPn, hNewVidPnSourceModeSet);
1888
1889 if (Status != STATUS_SUCCESS || !bSupported)
1890 break;
1891 }
1892 else if (Status == STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE)
1893 {
1894 drprintf(("VBoxVideoWddm: Warning: pfnAcquireSourceModeSet returned STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE, continuing\n"));
1895 Status = STATUS_SUCCESS;
1896 }
1897 else
1898 {
1899 drprintf(("VBoxVideoWddm: pfnAcquireSourceModeSet failed Status(0x%x)\n"));
1900 break;
1901 }
1902 }
1903
1904 if (Status == STATUS_SUCCESS && bSupported)
1905 {
1906 for (UINT id = 0; id < pContext->cSources; ++id)
1907 {
1908 D3DKMDT_HVIDPNTARGETMODESET hNewVidPnTargetModeSet;
1909 CONST DXGK_VIDPNTARGETMODESET_INTERFACE *pVidPnTargetModeSetInterface;
1910 Status = pVidPnInterface->pfnAcquireTargetModeSet(pIsSupportedVidPnArg->hDesiredVidPn,
1911 id, /*__in CONST D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId */
1912 &hNewVidPnTargetModeSet,
1913 &pVidPnTargetModeSetInterface);
1914 if (Status == STATUS_SUCCESS)
1915 {
1916 Status = vboxVidPnCheckTargetModeSet(pIsSupportedVidPnArg->hDesiredVidPn, hNewVidPnTargetModeSet, pVidPnTargetModeSetInterface, &bSupported);
1917
1918 pVidPnInterface->pfnReleaseTargetModeSet(pIsSupportedVidPnArg->hDesiredVidPn, hNewVidPnTargetModeSet);
1919
1920 if (Status != STATUS_SUCCESS || !bSupported)
1921 break;
1922 }
1923 else if (Status == STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE)
1924 {
1925 drprintf(("VBoxVideoWddm: Warning: pfnAcquireSourceModeSet returned STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE, continuing\n"));
1926 Status = STATUS_SUCCESS;
1927 }
1928 else
1929 {
1930 drprintf(("VBoxVideoWddm: pfnAcquireSourceModeSet failed Status(0x%x)\n"));
1931 break;
1932 }
1933 }
1934 }
1935 }
1936 }
1937 else
1938 {
1939 drprintf(("VBoxVideoWddm: pfnGetTopology failed Status(0x%x)\n"));
1940 }
1941 }
1942 else
1943 {
1944 drprintf(("VBoxVideoWddm: DxgkCbQueryVidPnInterface failed Status(0x%x)\n"));
1945 }
1946 pIsSupportedVidPnArg->IsVidPnSupported = bSupported;
1947
1948 dfprintf(("<== "__FUNCTION__ ", status(0x%x), context(0x%x)\n", Status, hAdapter));
1949
1950 return Status;
1951}
1952
1953NTSTATUS
1954APIENTRY
1955DxgkDdiRecommendFunctionalVidPn(
1956 CONST HANDLE hAdapter,
1957 CONST DXGKARG_RECOMMENDFUNCTIONALVIDPN* CONST pRecommendFunctionalVidPnArg
1958 )
1959{
1960 /* The DxgkDdiRecommendFunctionalVidPn should be made pageable. */
1961 PAGED_CODE();
1962
1963 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", hAdapter));
1964
1965 PDEVICE_EXTENSION pContext = (PDEVICE_EXTENSION)hAdapter;
1966 const DXGK_VIDPN_INTERFACE* pVidPnInterface = NULL;
1967 NTSTATUS Status = pContext->u.primary.DxgkInterface.DxgkCbQueryVidPnInterface(pRecommendFunctionalVidPnArg->hRecommendedFunctionalVidPn, DXGK_VIDPN_INTERFACE_VERSION_V1, &pVidPnInterface);
1968 if (Status == STATUS_SUCCESS)
1969 {
1970 D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology;
1971 const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface;
1972 Status = pVidPnInterface->pfnGetTopology(pRecommendFunctionalVidPnArg->hRecommendedFunctionalVidPn, &hVidPnTopology, &pVidPnTopologyInterface);
1973 if (Status == STATUS_SUCCESS)
1974 {
1975 D3DKMDT_VIDPN_PRESENT_PATH *pNewVidPnPresentPathInfo;
1976 Status = pVidPnTopologyInterface->pfnCreateNewPathInfo(hVidPnTopology, &pNewVidPnPresentPathInfo);
1977 if (Status == STATUS_SUCCESS)
1978 {
1979 pNewVidPnPresentPathInfo->VidPnSourceId = 0;
1980 pNewVidPnPresentPathInfo->VidPnTargetId = 0;
1981 pNewVidPnPresentPathInfo->ImportanceOrdinal = D3DKMDT_VPPI_PRIMARY;
1982 pNewVidPnPresentPathInfo->ContentTransformation.Scaling = D3DKMDT_VPPS_IDENTITY;
1983 memset(&pNewVidPnPresentPathInfo->ContentTransformation.ScalingSupport,
1984 0, sizeof (pNewVidPnPresentPathInfo->ContentTransformation.ScalingSupport));
1985 pNewVidPnPresentPathInfo->ContentTransformation.ScalingSupport.Identity = 1;
1986 pNewVidPnPresentPathInfo->ContentTransformation.ScalingSupport.Centered = 1;
1987 pNewVidPnPresentPathInfo->ContentTransformation.ScalingSupport.Stretched = 0;
1988 pNewVidPnPresentPathInfo->ContentTransformation.Rotation = D3DKMDT_VPPR_IDENTITY;
1989 pNewVidPnPresentPathInfo->ContentTransformation.RotationSupport.Identity = 1;
1990 pNewVidPnPresentPathInfo->ContentTransformation.RotationSupport.Rotate180 = 0;
1991 pNewVidPnPresentPathInfo->ContentTransformation.RotationSupport.Rotate270 = 0;
1992 pNewVidPnPresentPathInfo->ContentTransformation.RotationSupport.Rotate90 = 0;
1993 pNewVidPnPresentPathInfo->VisibleFromActiveTLOffset.cx = 0;
1994 pNewVidPnPresentPathInfo->VisibleFromActiveTLOffset.cy = 0;
1995 pNewVidPnPresentPathInfo->VisibleFromActiveBROffset.cx = 0;
1996 pNewVidPnPresentPathInfo->VisibleFromActiveBROffset.cy = 0;
1997 pNewVidPnPresentPathInfo->VidPnTargetColorBasis = D3DKMDT_CB_SRGB; /* @todo: how does it matters? */
1998 pNewVidPnPresentPathInfo->VidPnTargetColorCoeffDynamicRanges.FirstChannel = 8;
1999 pNewVidPnPresentPathInfo->VidPnTargetColorCoeffDynamicRanges.SecondChannel = 8;
2000 pNewVidPnPresentPathInfo->VidPnTargetColorCoeffDynamicRanges.ThirdChannel = 8;
2001 pNewVidPnPresentPathInfo->VidPnTargetColorCoeffDynamicRanges.FourthChannel = 0;
2002 pNewVidPnPresentPathInfo->Content = D3DKMDT_VPPC_GRAPHICS;
2003 pNewVidPnPresentPathInfo->CopyProtection.CopyProtectionType = D3DKMDT_VPPMT_NOPROTECTION;
2004 pNewVidPnPresentPathInfo->CopyProtection.APSTriggerBits = 0;
2005 memset(&pNewVidPnPresentPathInfo->CopyProtection.CopyProtectionSupport, 0, sizeof (pNewVidPnPresentPathInfo->CopyProtection.CopyProtectionSupport));
2006 pNewVidPnPresentPathInfo->CopyProtection.CopyProtectionSupport.NoProtection = 1;
2007 pNewVidPnPresentPathInfo->GammaRamp.Type = D3DDDI_GAMMARAMP_DEFAULT;
2008 pNewVidPnPresentPathInfo->GammaRamp.DataSize = 0;
2009 Status = pVidPnTopologyInterface->pfnAddPath(hVidPnTopology, pNewVidPnPresentPathInfo);
2010 if (Status == STATUS_SUCCESS)
2011 {
2012 D3DKMDT_HVIDPNSOURCEMODESET hNewVidPnSourceModeSet;
2013 const DXGK_VIDPNSOURCEMODESET_INTERFACE *pVidPnSourceModeSetInterface;
2014 Status = pVidPnInterface->pfnCreateNewSourceModeSet(pRecommendFunctionalVidPnArg->hRecommendedFunctionalVidPn,
2015 0, /*__in CONST D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId */
2016 &hNewVidPnSourceModeSet,
2017 &pVidPnSourceModeSetInterface);
2018 if (Status == STATUS_SUCCESS)
2019 {
2020 D3DKMDT_VIDPN_SOURCE_MODE *pNewVidPnSourceModeInfo;
2021 Status = pVidPnSourceModeSetInterface->pfnCreateNewModeInfo(hNewVidPnSourceModeSet, &pNewVidPnSourceModeInfo);
2022 if (Status == STATUS_SUCCESS)
2023 {
2024 D3DKMDT_VIDEO_PRESENT_SOURCE_MODE_ID modeId = pNewVidPnSourceModeInfo->Id;
2025 pNewVidPnSourceModeInfo->Type = D3DKMDT_RMT_GRAPHICS;
2026 /* @todo: should we obtain the default mode from the host? */
2027 pNewVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cx = 1024;
2028 pNewVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cy = 768;
2029 pNewVidPnSourceModeInfo->Format.Graphics.VisibleRegionSize = pNewVidPnSourceModeInfo->Format.Graphics.PrimSurfSize;
2030 pNewVidPnSourceModeInfo->Format.Graphics.Stride = pNewVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cx * 4;
2031 pNewVidPnSourceModeInfo->Format.Graphics.PixelFormat = D3DDDIFMT_X8R8G8B8;
2032 pNewVidPnSourceModeInfo->Format.Graphics.ColorBasis = D3DKMDT_CB_SRGB;
2033 pNewVidPnSourceModeInfo->Format.Graphics.PixelValueAccessMode = D3DKMDT_PVAM_DIRECT;
2034 Status = pVidPnSourceModeSetInterface->pfnAddMode(hNewVidPnSourceModeSet, pNewVidPnSourceModeInfo);
2035 if (Status == STATUS_SUCCESS)
2036 {
2037 Status = pVidPnSourceModeSetInterface->pfnPinMode(hNewVidPnSourceModeSet, modeId);
2038 if (Status == STATUS_SUCCESS)
2039 {
2040 D3DKMDT_HVIDPNTARGETMODESET hNewVidPnTargetModeSet;
2041 CONST DXGK_VIDPNTARGETMODESET_INTERFACE *pVidPnTargetModeSetInterface;
2042 Status = pVidPnInterface->pfnCreateNewTargetModeSet(pRecommendFunctionalVidPnArg->hRecommendedFunctionalVidPn,
2043 0, /* __in CONST D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId */
2044 &hNewVidPnTargetModeSet,
2045 &pVidPnTargetModeSetInterface);
2046 if (Status == STATUS_SUCCESS)
2047 {
2048 D3DKMDT_VIDPN_TARGET_MODE *pNewVidPnTargetModeInfo;
2049 Status = pVidPnTargetModeSetInterface->pfnCreateNewModeInfo(hNewVidPnTargetModeSet, &pNewVidPnTargetModeInfo);
2050 if (Status == STATUS_SUCCESS)
2051 {
2052 D3DKMDT_VIDEO_PRESENT_TARGET_MODE_ID targetId = pNewVidPnTargetModeInfo->Id;
2053 pNewVidPnTargetModeInfo->VideoSignalInfo.VideoStandard = D3DKMDT_VSS_OTHER;
2054 pNewVidPnTargetModeInfo->VideoSignalInfo.TotalSize.cx = 1024;
2055 pNewVidPnTargetModeInfo->VideoSignalInfo.TotalSize.cy = 768;
2056 pNewVidPnTargetModeInfo->VideoSignalInfo.ActiveSize = pNewVidPnTargetModeInfo->VideoSignalInfo.TotalSize;
2057 pNewVidPnTargetModeInfo->VideoSignalInfo.VSyncFreq.Numerator = 60;
2058 pNewVidPnTargetModeInfo->VideoSignalInfo.VSyncFreq.Denominator = 1;
2059 pNewVidPnTargetModeInfo->VideoSignalInfo.HSyncFreq.Numerator = 63 * 768; /* @todo: do we need that? */
2060 pNewVidPnTargetModeInfo->VideoSignalInfo.HSyncFreq.Denominator = 1;
2061 pNewVidPnTargetModeInfo->VideoSignalInfo.PixelRate = 165000; /* ?? */
2062 pNewVidPnTargetModeInfo->VideoSignalInfo.ScanLineOrdering = D3DDDI_VSSLO_PROGRESSIVE;
2063 pNewVidPnTargetModeInfo->Preference = D3DKMDT_MP_PREFERRED;
2064 Status = pVidPnTargetModeSetInterface->pfnAddMode(hNewVidPnTargetModeSet, pNewVidPnTargetModeInfo);
2065 if (Status == STATUS_SUCCESS)
2066 {
2067 Status = pVidPnTargetModeSetInterface->pfnPinMode(hNewVidPnTargetModeSet, targetId);
2068 if (Status == STATUS_SUCCESS)
2069 {
2070
2071 }
2072 else
2073 {
2074 drprintf(("VBoxVideoWddm: pfnPinMode (target) failed Status(0x%x)\n"));
2075 }
2076 }
2077 else
2078 {
2079 drprintf(("VBoxVideoWddm: pfnAddMode (target) failed Status(0x%x)\n"));
2080 pVidPnTargetModeSetInterface->pfnReleaseModeInfo(hNewVidPnTargetModeSet, pNewVidPnTargetModeInfo);
2081 pNewVidPnTargetModeInfo = NULL;
2082 }
2083 }
2084 else
2085 {
2086 drprintf(("VBoxVideoWddm: pfnCreateNewModeInfo (target) failed Status(0x%x)\n"));
2087 }
2088 }
2089 else
2090 {
2091 drprintf(("VBoxVideoWddm: pfnCreateNewTargetModeSet failed Status(0x%x)\n"));
2092 }
2093 }
2094 else
2095 {
2096 drprintf(("VBoxVideoWddm: pfnPinMode failed Status(0x%x)\n"));
2097 }
2098 }
2099 else
2100 {
2101 drprintf(("VBoxVideoWddm: pfnAddMode failed Status(0x%x)\n"));
2102 pVidPnSourceModeSetInterface->pfnReleaseModeInfo(hNewVidPnSourceModeSet, pNewVidPnSourceModeInfo);
2103 pNewVidPnSourceModeInfo = NULL;
2104 }
2105 }
2106 else
2107 {
2108 drprintf(("VBoxVideoWddm: pfnCreateNewModeInfo failed Status(0x%x)\n"));
2109 }
2110 }
2111 else
2112 {
2113 drprintf(("VBoxVideoWddm: pfnCreateNewSourceModeSet failed Status(0x%x)\n"));
2114 }
2115 }
2116 else
2117 {
2118 drprintf(("VBoxVideoWddm: pfnAddPath failed Status(0x%x)\n"));
2119 pVidPnTopologyInterface->pfnReleasePathInfo(hVidPnTopology, pNewVidPnPresentPathInfo);
2120 pNewVidPnPresentPathInfo = NULL;
2121 }
2122 }
2123 else
2124 {
2125 drprintf(("VBoxVideoWddm: pfnCreateNewPathInfo failed Status(0x%x)\n"));
2126 }
2127 }
2128 else
2129 {
2130 drprintf(("VBoxVideoWddm: pfnGetTopology failed Status(0x%x)\n"));
2131 }
2132 }
2133 else
2134 {
2135 drprintf(("VBoxVideoWddm: DxgkCbQueryVidPnInterface failed Status(0x%x)\n"));
2136 }
2137
2138 dfprintf(("<== "__FUNCTION__ ", status(0x%x), context(0x%x)\n", Status, hAdapter));
2139
2140 return Status;
2141}
2142
2143NTSTATUS
2144APIENTRY
2145DxgkDdiEnumVidPnCofuncModality(
2146 CONST HANDLE hAdapter,
2147 CONST DXGKARG_ENUMVIDPNCOFUNCMODALITY* CONST pEnumCofuncModalityArg
2148 )
2149{
2150 /* The DxgkDdiEnumVidPnCofuncModality function should be made pageable. */
2151 PAGED_CODE();
2152
2153 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", hAdapter));
2154
2155 PDEVICE_EXTENSION pContext = (PDEVICE_EXTENSION)hAdapter;
2156
2157 const DXGK_VIDPN_INTERFACE* pVidPnInterface = NULL;
2158 NTSTATUS Status = pContext->u.primary.DxgkInterface.DxgkCbQueryVidPnInterface(pEnumCofuncModalityArg->hConstrainingVidPn, DXGK_VIDPN_INTERFACE_VERSION_V1, &pVidPnInterface);
2159 if (Status == STATUS_SUCCESS)
2160 {
2161 D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology;
2162 const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface;
2163 NTSTATUS Status = pVidPnInterface->pfnGetTopology(pEnumCofuncModalityArg->hConstrainingVidPn, &hVidPnTopology, &pVidPnTopologyInterface);
2164 Assert(Status == STATUS_SUCCESS);
2165 if (Status == STATUS_SUCCESS)
2166 {
2167 VBOXVIDPNCOFUNCMODALITY CbContext = {0};
2168 CbContext.pEnumCofuncModalityArg = pEnumCofuncModalityArg;
2169 VBoxWddmGetModesTable(pContext, /* PDEVICE_EXTENSION DeviceExtension */
2170 true, /* bool bRebuildTable*/
2171 &CbContext.pModes, /* VIDEO_MODE_INFORMATION ** ppModes*/
2172 &CbContext.cModes, /* uint32_t * pcModes */
2173 &CbContext.iPreferredMode, /* uint32_t * pPreferrableMode*/
2174 &CbContext.pResolutions, /* D3DKMDT_2DREGION **ppResolutions */
2175 &CbContext.cResolutions /* uint32_t * pcResolutions */);
2176 Assert(CbContext.cModes);
2177 Assert(CbContext.cModes > CbContext.iPreferredMode);
2178 Status = vboxVidPnEnumPaths(pContext, pEnumCofuncModalityArg->hConstrainingVidPn, pVidPnInterface,
2179 hVidPnTopology, pVidPnTopologyInterface,
2180 vboxVidPnCofuncModalityPathEnum, &CbContext);
2181 Assert(Status == STATUS_SUCCESS);
2182 if (Status == STATUS_SUCCESS)
2183 {
2184 Status = CbContext.Status;
2185 Assert(Status == STATUS_SUCCESS);
2186 if (Status != STATUS_SUCCESS)
2187 drprintf((__FUNCTION__ ": vboxVidPnAdjustSourcesTargetsCallback failed Status(0x%x)\n", Status));
2188 }
2189 else
2190 drprintf((__FUNCTION__ ": vboxVidPnEnumPaths failed Status(0x%x)\n", Status));
2191 }
2192 else
2193 drprintf((__FUNCTION__ ": pfnGetTopology failed Status(0x%x)\n", Status));
2194 }
2195 else
2196 drprintf((__FUNCTION__ ": DxgkCbQueryVidPnInterface failed Status(0x%x)\n", Status));
2197
2198 dfprintf(("<== "__FUNCTION__ ", status(0x%x), context(0x%x)\n", Status, hAdapter));
2199
2200 return Status;
2201}
2202
2203NTSTATUS
2204APIENTRY
2205DxgkDdiSetVidPnSourceAddress(
2206 CONST HANDLE hAdapter,
2207 CONST DXGKARG_SETVIDPNSOURCEADDRESS* pSetVidPnSourceAddress
2208 )
2209{
2210 /* The DxgkDdiSetVidPnSourceAddress function should be made pageable. */
2211 PAGED_CODE();
2212
2213 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", hAdapter));
2214
2215 NTSTATUS Status = STATUS_SUCCESS;
2216 PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)hAdapter;
2217 Assert(pDevExt->cSources > pSetVidPnSourceAddress->VidPnSourceId);
2218 if (pDevExt->cSources > pSetVidPnSourceAddress->VidPnSourceId)
2219 {
2220 PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[pSetVidPnSourceAddress->VidPnSourceId];
2221 PVBOXWDDM_ALLOCATION pAllocation;
2222 Assert(pSetVidPnSourceAddress->hAllocation);
2223 Assert(pSetVidPnSourceAddress->hAllocation || pSource->pAllocation);
2224 Assert (pSetVidPnSourceAddress->Flags.Value < 2); /* i.e. 0 or 1 (ModeChange) */
2225 if (pSetVidPnSourceAddress->hAllocation)
2226 {
2227 pAllocation = (PVBOXWDDM_ALLOCATION)pSetVidPnSourceAddress->hAllocation;
2228 vboxWddmAssignPrimary(pDevExt, pSource, pAllocation, pSetVidPnSourceAddress->VidPnSourceId);
2229 }
2230 else
2231 pAllocation = pSource->pAllocation;
2232
2233 Assert(pAllocation);
2234 if (pAllocation)
2235 {
2236 Assert(pAllocation->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE);
2237 PVBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE pPrimary = VBOXWDDM_ALLOCATION_BODY(pAllocation, VBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE);
2238 pAllocation->offVram = (VBOXVIDEOOFFSET)pSetVidPnSourceAddress->PrimaryAddress.QuadPart;
2239 pAllocation->SegmentId = pSetVidPnSourceAddress->PrimarySegment;
2240 Assert (pAllocation->SegmentId);
2241 Assert (!pPrimary->bVisible);
2242 if (pPrimary->bVisible)
2243 {
2244 /* should not generally happen, but still inform host*/
2245 Status = vboxWddmGhDisplaySetInfo(pDevExt, pSource);
2246 Assert(Status == STATUS_SUCCESS);
2247 if (Status != STATUS_SUCCESS)
2248 drprintf((__FUNCTION__": vboxWddmGhDisplaySetInfo failed, Status (0x%x)\n", Status));
2249 }
2250 }
2251 else
2252 {
2253 drprintf((__FUNCTION__": no allocation data available!!\n"));
2254 Status = STATUS_INVALID_PARAMETER;
2255 }
2256 }
2257 else
2258 {
2259 drprintf((__FUNCTION__": invalid VidPnSourceId (%d), should be smaller than (%d)\n", pSetVidPnSourceAddress->VidPnSourceId, pDevExt->cSources));
2260 Status = STATUS_INVALID_PARAMETER;
2261 }
2262
2263 dfprintf(("<== "__FUNCTION__ ", status(0x%x), context(0x%x)\n", Status, hAdapter));
2264
2265 return Status;
2266}
2267
2268NTSTATUS
2269APIENTRY
2270DxgkDdiSetVidPnSourceVisibility(
2271 CONST HANDLE hAdapter,
2272 CONST DXGKARG_SETVIDPNSOURCEVISIBILITY* pSetVidPnSourceVisibility
2273 )
2274{
2275 /* DxgkDdiSetVidPnSourceVisibility should be made pageable. */
2276 PAGED_CODE();
2277
2278 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", hAdapter));
2279
2280 NTSTATUS Status = STATUS_SUCCESS;
2281 PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)hAdapter;
2282 Assert(pDevExt->cSources > pSetVidPnSourceVisibility->VidPnSourceId);
2283 if (pDevExt->cSources > pSetVidPnSourceVisibility->VidPnSourceId)
2284 {
2285 PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[pSetVidPnSourceVisibility->VidPnSourceId];
2286 PVBOXWDDM_ALLOCATION pAllocation = pSource->pAllocation;
2287 PVBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE pPrimary = VBOXWDDM_ALLOCATION_BODY(pAllocation, VBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE);
2288
2289 Assert(pPrimary->bVisible != pSetVidPnSourceVisibility->Visible);
2290 if (pPrimary->bVisible != pSetVidPnSourceVisibility->Visible)
2291 {
2292 pPrimary->bVisible = pSetVidPnSourceVisibility->Visible;
2293 if (pPrimary->bVisible)
2294 {
2295 Status = vboxWddmGhDisplaySetInfo(pDevExt, pSource);
2296 Assert(Status == STATUS_SUCCESS);
2297 if (Status != STATUS_SUCCESS)
2298 drprintf((__FUNCTION__": vboxWddmGhDisplaySetInfo failed, Status (0x%x)\n", Status));
2299 }
2300 else
2301 {
2302 vboxVdmaFlush (pDevExt, &pDevExt->u.primary.Vdma);
2303 }
2304 }
2305 }
2306 else
2307 {
2308 drprintf((__FUNCTION__": invalid VidPnSourceId (%d), should be smaller than (%d)\n", pSetVidPnSourceVisibility->VidPnSourceId, pDevExt->cSources));
2309 Status = STATUS_INVALID_PARAMETER;
2310 }
2311
2312 dfprintf(("<== "__FUNCTION__ ", status(0x%x), context(0x%x)\n", Status, hAdapter));
2313
2314 return Status;
2315}
2316
2317NTSTATUS
2318APIENTRY
2319DxgkDdiCommitVidPn(
2320 CONST HANDLE hAdapter,
2321 CONST DXGKARG_COMMITVIDPN* CONST pCommitVidPnArg
2322 )
2323{
2324 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", hAdapter));
2325
2326 PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)hAdapter;
2327
2328 const DXGK_VIDPN_INTERFACE* pVidPnInterface = NULL;
2329 NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbQueryVidPnInterface(pCommitVidPnArg->hFunctionalVidPn, DXGK_VIDPN_INTERFACE_VERSION_V1, &pVidPnInterface);
2330 if (Status == STATUS_SUCCESS)
2331 {
2332 if (pCommitVidPnArg->AffectedVidPnSourceId != D3DDDI_ID_ALL)
2333 {
2334 Status = vboxVidPnCommitSourceModeForSrcId(
2335 pDevExt,
2336 pCommitVidPnArg->hFunctionalVidPn, pVidPnInterface,
2337 pCommitVidPnArg->AffectedVidPnSourceId, (PVBOXWDDM_ALLOCATION)pCommitVidPnArg->hPrimaryAllocation);
2338 Assert(Status == STATUS_SUCCESS);
2339 if (Status != STATUS_SUCCESS)
2340 drprintf((__FUNCTION__ ": vboxVidPnCommitSourceModeForSrcId failed Status(0x%x)\n", Status));
2341 }
2342 else
2343 {
2344 /* clear all current primaries */
2345 for (UINT i = 0; i < pDevExt->cSources; ++i)
2346 {
2347 vboxWddmAssignPrimary(pDevExt, &pDevExt->aSources[i], NULL, i);
2348 }
2349
2350 D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology;
2351 const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface;
2352 NTSTATUS Status = pVidPnInterface->pfnGetTopology(pCommitVidPnArg->hFunctionalVidPn, &hVidPnTopology, &pVidPnTopologyInterface);
2353 Assert(Status == STATUS_SUCCESS);
2354 if (Status == STATUS_SUCCESS)
2355 {
2356 VBOXVIDPNCOMMIT CbContext = {0};
2357 CbContext.pCommitVidPnArg = pCommitVidPnArg;
2358 Status = vboxVidPnEnumPaths(pDevExt, pCommitVidPnArg->hFunctionalVidPn, pVidPnInterface,
2359 hVidPnTopology, pVidPnTopologyInterface,
2360 vboxVidPnCommitPathEnum, &CbContext);
2361 Assert(Status == STATUS_SUCCESS);
2362 if (Status == STATUS_SUCCESS)
2363 {
2364 Status = CbContext.Status;
2365 Assert(Status == STATUS_SUCCESS);
2366 if (Status != STATUS_SUCCESS)
2367 drprintf((__FUNCTION__ ": vboxVidPnCommitPathEnum failed Status(0x%x)\n", Status));
2368 }
2369 else
2370 drprintf((__FUNCTION__ ": vboxVidPnEnumPaths failed Status(0x%x)\n", Status));
2371 }
2372 else
2373 drprintf((__FUNCTION__ ": pfnGetTopology failed Status(0x%x)\n", Status));
2374 }
2375 }
2376 else
2377 drprintf((__FUNCTION__ ": DxgkCbQueryVidPnInterface failed Status(0x%x)\n", Status));
2378
2379 dfprintf(("<== "__FUNCTION__ ", status(0x%x), context(0x%x)\n", Status, hAdapter));
2380
2381 return Status;
2382}
2383
2384NTSTATUS
2385APIENTRY
2386DxgkDdiUpdateActiveVidPnPresentPath(
2387 CONST HANDLE hAdapter,
2388 CONST DXGKARG_UPDATEACTIVEVIDPNPRESENTPATH* CONST pUpdateActiveVidPnPresentPathArg
2389 )
2390{
2391 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2392
2393 AssertBreakpoint();
2394
2395 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2396
2397 return STATUS_SUCCESS;
2398}
2399
2400NTSTATUS
2401APIENTRY
2402DxgkDdiRecommendMonitorModes(
2403 CONST HANDLE hAdapter,
2404 CONST DXGKARG_RECOMMENDMONITORMODES* CONST pRecommendMonitorModesArg
2405 )
2406{
2407 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2408
2409 vboxVDbgBreakF();
2410
2411 PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)hAdapter;
2412 NTSTATUS Status;
2413 uint32_t cModes;
2414 uint32_t iPreferredMode;
2415 VIDEO_MODE_INFORMATION *pModes;
2416 uint32_t cResolutions;
2417 D3DKMDT_2DREGION *pResolutions;
2418 VBoxWddmGetModesTable(pDevExt, /* PDEVICE_EXTENSION DeviceExtension */
2419 true, /* bool bRebuildTable*/
2420 &pModes, /* VIDEO_MODE_INFORMATION ** ppModes*/
2421 &cModes, /* uint32_t * pcModes */
2422 &iPreferredMode, /* uint32_t * pPreferrableMode*/
2423 &pResolutions, /* D3DKMDT_2DREGION **ppResolutions */
2424 &cResolutions /* uint32_t * pcResolutions */);
2425
2426 for (uint32_t i = 0; i < cResolutions; i++)
2427 {
2428 D3DKMDT_MONITOR_SOURCE_MODE * pNewMonitorSourceModeInfo;
2429 Status = pRecommendMonitorModesArg->pMonitorSourceModeSetInterface->pfnCreateNewModeInfo(
2430 pRecommendMonitorModesArg->hMonitorSourceModeSet, &pNewMonitorSourceModeInfo);
2431 Assert(Status == STATUS_SUCCESS);
2432 if (Status == STATUS_SUCCESS)
2433 {
2434 Status = vboxVidPnPopulateMonitorSourceModeInfoFromLegacy(pDevExt,
2435 pNewMonitorSourceModeInfo,
2436 &pResolutions[i],
2437 D3DKMDT_MCO_DRIVER,
2438 true);
2439 Assert(Status == STATUS_SUCCESS);
2440 if (Status == STATUS_SUCCESS)
2441 {
2442 Status = pRecommendMonitorModesArg->pMonitorSourceModeSetInterface->pfnAddMode(
2443 pRecommendMonitorModesArg->hMonitorSourceModeSet, pNewMonitorSourceModeInfo);
2444 Assert(Status == STATUS_SUCCESS);
2445 if (Status == STATUS_SUCCESS)
2446 continue;
2447 }
2448
2449 /* error has occured, release & break */
2450 pRecommendMonitorModesArg->pMonitorSourceModeSetInterface->pfnReleaseModeInfo(
2451 pRecommendMonitorModesArg->hMonitorSourceModeSet, pNewMonitorSourceModeInfo);
2452 break;
2453 }
2454 }
2455
2456 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2457
2458 return Status;
2459}
2460
2461NTSTATUS
2462APIENTRY
2463DxgkDdiRecommendVidPnTopology(
2464 CONST HANDLE hAdapter,
2465 CONST DXGKARG_RECOMMENDVIDPNTOPOLOGY* CONST pRecommendVidPnTopologyArg
2466 )
2467{
2468 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2469
2470 vboxVDbgBreakF();
2471
2472 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2473
2474 return STATUS_GRAPHICS_NO_RECOMMENDED_VIDPN_TOPOLOGY;
2475}
2476
2477NTSTATUS
2478APIENTRY
2479DxgkDdiGetScanLine(
2480 CONST HANDLE hAdapter,
2481 DXGKARG_GETSCANLINE* pGetScanLine)
2482{
2483 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2484
2485 AssertBreakpoint();
2486
2487 pGetScanLine->InVerticalBlank = FALSE;
2488 pGetScanLine->ScanLine = 0;
2489
2490 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2491
2492 return STATUS_SUCCESS;
2493}
2494
2495NTSTATUS
2496APIENTRY
2497DxgkDdiStopCapture(
2498 CONST HANDLE hAdapter,
2499 CONST DXGKARG_STOPCAPTURE* pStopCapture)
2500{
2501 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2502
2503 AssertBreakpoint();
2504
2505 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2506
2507 return STATUS_SUCCESS;
2508}
2509
2510NTSTATUS
2511APIENTRY
2512DxgkDdiControlInterrupt(
2513 CONST HANDLE hAdapter,
2514 CONST DXGK_INTERRUPT_TYPE InterruptType,
2515 BOOLEAN Enable
2516 )
2517{
2518 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2519
2520 AssertBreakpoint();
2521
2522 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2523
2524 /* @todo: STATUS_NOT_IMPLEMENTED ?? */
2525 return STATUS_SUCCESS;
2526}
2527
2528NTSTATUS
2529APIENTRY
2530DxgkDdiCreateOverlay(
2531 CONST HANDLE hAdapter,
2532 DXGKARG_CREATEOVERLAY *pCreateOverlay)
2533{
2534 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2535
2536 AssertBreakpoint();
2537
2538 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2539
2540 return STATUS_NOT_IMPLEMENTED;
2541}
2542
2543NTSTATUS
2544APIENTRY
2545DxgkDdiDestroyDevice(
2546 CONST HANDLE hDevice)
2547{
2548 /* DxgkDdiDestroyDevice should be made pageable. */
2549 PAGED_CODE();
2550
2551 dfprintf(("==> "__FUNCTION__ ", hDevice(0x%x)\n", hDevice));
2552
2553 vboxWddmMemFree(hDevice);
2554
2555 dfprintf(("<== "__FUNCTION__ ", \n"));
2556
2557 return STATUS_SUCCESS;
2558}
2559
2560NTSTATUS
2561APIENTRY
2562DxgkDdiOpenAllocation(
2563 CONST HANDLE hDevice,
2564 CONST DXGKARG_OPENALLOCATION *pOpenAllocation)
2565{
2566 /* DxgkDdiOpenAllocation should be made pageable. */
2567 PAGED_CODE();
2568
2569 dfprintf(("==> "__FUNCTION__ ", hDevice(0x%x)\n", hDevice));
2570
2571 AssertBreakpoint();
2572
2573 NTSTATUS Status = STATUS_SUCCESS;
2574
2575 for (UINT i = 0; i < pOpenAllocation->NumAllocations; ++i)
2576 {
2577 DXGK_OPENALLOCATIONINFO* pInfo = &pOpenAllocation->pOpenAllocation[i];
2578 PVBOXWDDM_OPENALLOCATION pOa = (PVBOXWDDM_OPENALLOCATION)vboxWddmMemAllocZero(sizeof (VBOXWDDM_OPENALLOCATION));
2579 pOa->hAllocation = pInfo->hAllocation;
2580 pInfo->hDeviceSpecificAllocation = pOa;
2581 }
2582
2583 dfprintf(("<== "__FUNCTION__ ", hDevice(0x%x)\n", hDevice));
2584
2585 return Status;
2586}
2587
2588NTSTATUS
2589APIENTRY
2590DxgkDdiCloseAllocation(
2591 CONST HANDLE hDevice,
2592 CONST DXGKARG_CLOSEALLOCATION* pCloseAllocation)
2593{
2594 /* DxgkDdiCloseAllocation should be made pageable. */
2595 PAGED_CODE();
2596
2597 dfprintf(("==> "__FUNCTION__ ", hDevice(0x%x)\n", hDevice));
2598
2599 for (UINT i = 0; i < pCloseAllocation->NumAllocations; ++i)
2600 {
2601 vboxWddmMemFree(pCloseAllocation->pOpenHandleList[i]);
2602 }
2603
2604 dfprintf(("<== "__FUNCTION__ ", hDevice(0x%x)\n", hDevice));
2605
2606 return STATUS_SUCCESS;
2607}
2608
2609NTSTATUS
2610APIENTRY
2611DxgkDdiRender(
2612 CONST HANDLE hContext,
2613 DXGKARG_RENDER *pRender)
2614{
2615 drprintf(("==> "__FUNCTION__ ", !!NOT_IMPLEMENTED!! hContext(0x%x)\n", hContext));
2616
2617 AssertBreakpoint();
2618
2619 drprintf(("<== "__FUNCTION__ ", !!NOT_IMPLEMENTED!! hContext(0x%x)\n", hContext));
2620
2621 return STATUS_NOT_IMPLEMENTED;
2622}
2623
2624#define VBOXVDMACMD_DMA_PRESENT_BLT_MINSIZE() (VBOXVDMACMD_SIZE(VBOXVDMACMD_DMA_PRESENT_BLT))
2625#define VBOXVDMACMD_DMA_PRESENT_BLT_SIZE(_c) (VBOXVDMACMD_BODY_FIELD_OFFSET(UINT, VBOXVDMACMD_DMA_PRESENT_BLT, aDstSubRects[_c]))
2626
2627DECLINLINE(PVBOXWDDM_ALLOCATION) vboxWddmGetAllocationFromOpenData(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_OPENALLOCATION pOa)
2628{
2629 DXGKARGCB_GETHANDLEDATA GhData;
2630 GhData.hObject = pOa->hAllocation;
2631 GhData.Type = DXGK_HANDLE_ALLOCATION;
2632 GhData.Flags.Value = 0;
2633 return (PVBOXWDDM_ALLOCATION)pDevExt->u.primary.DxgkInterface.DxgkCbGetHandleData(&GhData);
2634}
2635
2636DECLINLINE(PVBOXWDDM_ALLOCATION) vboxWddmGetAllocationFromAllocList(PDEVICE_EXTENSION pDevExt, DXGK_ALLOCATIONLIST *pAllocList)
2637{
2638 return vboxWddmGetAllocationFromOpenData(pDevExt, (PVBOXWDDM_OPENALLOCATION)pAllocList->hDeviceSpecificAllocation);
2639}
2640
2641DECLINLINE(VBOXVIDEOOFFSET) vboxWddmOffsetFromPhAddress(PHYSICAL_ADDRESS phAddr)
2642{
2643 return (VBOXVIDEOOFFSET)(phAddr.QuadPart ? phAddr.QuadPart - VBE_DISPI_LFB_PHYSICAL_ADDRESS : VBOXVIDEOOFFSET_VOID);
2644}
2645
2646DECLINLINE(VOID) vboxWddmRectlFromRect(const RECT *pRect, PVBOXVDMA_RECTL pRectl)
2647{
2648 pRectl->left = (int16_t)pRect->left;
2649 pRectl->width = (uint16_t)(pRect->right - pRect->left);
2650 pRectl->top = (int16_t)pRect->top;
2651 pRectl->height = (uint16_t)(pRect->bottom - pRect->top);
2652}
2653
2654DECLINLINE(VBOXVDMA_PIXEL_FORMAT) vboxWddmFromPixFormat(D3DDDIFORMAT format)
2655{
2656 return (VBOXVDMA_PIXEL_FORMAT)format;
2657}
2658
2659DECLINLINE(VOID) vboxWddmSurfDescFromAllocation(PVBOXWDDM_ALLOCATION pAllocation, PVBOXVDMA_SURF_DESC pDesc)
2660{
2661 pDesc->width = pAllocation->u.SurfInfo.width;
2662 pDesc->height = pAllocation->u.SurfInfo.height;
2663 pDesc->format = vboxWddmFromPixFormat(pAllocation->u.SurfInfo.format);
2664 pDesc->bpp = pAllocation->u.SurfInfo.bpp;
2665 pDesc->pitch = pAllocation->u.SurfInfo.pitch;
2666 pDesc->fFlags = 0;
2667}
2668
2669DECLINLINE(BOOLEAN) vboxWddmPixFormatConversionSupported(D3DDDIFORMAT From, D3DDDIFORMAT To)
2670{
2671 Assert(From != D3DDDIFMT_UNKNOWN);
2672 Assert(To != D3DDDIFMT_UNKNOWN);
2673 Assert(From == To);
2674 return From == To;
2675}
2676
2677DECLINLINE(PVBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE) vboxWddmCheckForVisiblePrimary(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_ALLOCATION pAllocation)
2678{
2679 if (pAllocation->enmType != VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE)
2680 return NULL;
2681
2682 PVBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE pPrimary = VBOXWDDM_ALLOCATION_BODY(pAllocation, VBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE);
2683 if (!pPrimary->bVisible)
2684 return NULL;
2685
2686 D3DDDI_VIDEO_PRESENT_SOURCE_ID id = pPrimary->VidPnSourceId;
2687 if (id >= pDevExt->cSources)
2688 return NULL;
2689
2690 PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[id];
2691 if (pSource->pAllocation != pAllocation)
2692 return NULL;
2693
2694 return pPrimary;
2695}
2696
2697/**
2698 * DxgkDdiPresent
2699 */
2700NTSTATUS
2701APIENTRY
2702DxgkDdiPresent(
2703 CONST HANDLE hContext,
2704 DXGKARG_PRESENT *pPresent)
2705{
2706 PAGED_CODE();
2707
2708 dfprintf(("==> "__FUNCTION__ ", hContext(0x%x)\n", hContext));
2709
2710 NTSTATUS Status = STATUS_SUCCESS;
2711 PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)hContext;
2712 PVBOXWDDM_DEVICE pDevice = pContext->pDevice;
2713 PDEVICE_EXTENSION pDevExt = pDevice->pAdapter;
2714
2715 if (pPresent->Flags.Blt)
2716 {
2717 Assert(pPresent->Flags.Value == 1); /* only Blt is set, we do not support anything else for now */
2718 UINT cbCmd = pPresent->DmaSize;
2719
2720 UINT cmdSize = VBOXVDMACMD_DMA_PRESENT_BLT_SIZE(pPresent->SubRectCnt - pPresent->MultipassOffset);
2721 PVBOXVDMACMD pCmd = (PVBOXVDMACMD)pPresent->pDmaBuffer;
2722 pPresent->pDmaBuffer = ((uint8_t*)pPresent->pDmaBuffer) + cmdSize;
2723 Assert(cbCmd >= VBOXVDMACMD_DMA_PRESENT_BLT_MINSIZE());
2724 if (cbCmd >= VBOXVDMACMD_DMA_PRESENT_BLT_MINSIZE())
2725 {
2726 DXGK_ALLOCATIONLIST *pSrc = &pPresent->pAllocationList[DXGK_PRESENT_SOURCE_INDEX];
2727 DXGK_ALLOCATIONLIST *pDst = &pPresent->pAllocationList[DXGK_PRESENT_DESTINATION_INDEX];
2728 PVBOXWDDM_ALLOCATION pSrcAlloc = vboxWddmGetAllocationFromAllocList(pDevExt, pSrc);
2729 Assert(pSrcAlloc);
2730 if (pSrcAlloc)
2731 {
2732 PVBOXWDDM_ALLOCATION pDstAlloc = vboxWddmGetAllocationFromAllocList(pDevExt, pDst);
2733 Assert(pDstAlloc);
2734 if (pDstAlloc)
2735 {
2736 if (vboxWddmPixFormatConversionSupported(pSrcAlloc->u.SurfInfo.format, pDstAlloc->u.SurfInfo.format))
2737 {
2738 memset(pPresent->pPatchLocationListOut, 0, 2*sizeof (D3DDDI_PATCHLOCATIONLIST));
2739// pPresent->pPatchLocationListOut->PatchOffset = 0;
2740// ++pPresent->pPatchLocationListOut;
2741 pPresent->pPatchLocationListOut->PatchOffset = VBOXVDMACMD_BODY_FIELD_OFFSET(UINT, VBOXVDMACMD_DMA_PRESENT_BLT, offSrc);
2742 pPresent->pPatchLocationListOut->AllocationIndex = 0;
2743 ++pPresent->pPatchLocationListOut;
2744 pPresent->pPatchLocationListOut->PatchOffset = VBOXVDMACMD_BODY_FIELD_OFFSET(UINT, VBOXVDMACMD_DMA_PRESENT_BLT, offDst);
2745 pPresent->pPatchLocationListOut->AllocationIndex = 1;
2746 ++pPresent->pPatchLocationListOut;
2747
2748 pCmd->enmType = VBOXVDMACMD_TYPE_DMA_PRESENT_BLT;
2749 pCmd->u32CmdSpecific = 0;
2750 PVBOXVDMACMD_DMA_PRESENT_BLT pTransfer = VBOXVDMACMD_BODY(pCmd, VBOXVDMACMD_DMA_PRESENT_BLT);
2751 pTransfer->offSrc = (VBOXVIDEOOFFSET)pSrc->PhysicalAddress.QuadPart;
2752 pTransfer->offDst = (VBOXVIDEOOFFSET)pDst->PhysicalAddress.QuadPart;
2753 vboxWddmSurfDescFromAllocation(pSrcAlloc, &pTransfer->srcDesc);
2754 vboxWddmSurfDescFromAllocation(pDstAlloc, &pTransfer->dstDesc);
2755 vboxWddmRectlFromRect(&pPresent->SrcRect, &pTransfer->srcRectl);
2756 vboxWddmRectlFromRect(&pPresent->DstRect, &pTransfer->dstRectl);
2757 UINT i = 0;
2758 cbCmd -= VBOXVDMACMD_BODY_FIELD_OFFSET(UINT, VBOXVDMACMD_DMA_PRESENT_BLT, aDstSubRects);
2759 Assert(cbCmd >= sizeof (VBOXVDMA_RECTL));
2760 Assert(cbCmd < pPresent->DmaSize);
2761 for (; i < pPresent->SubRectCnt; ++i)
2762 {
2763 if (cbCmd < sizeof (VBOXVDMA_RECTL))
2764 {
2765 Assert(i);
2766 pPresent->MultipassOffset += i;
2767 Status = STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER;
2768 break;
2769 }
2770 vboxWddmRectlFromRect(&pPresent->pDstSubRects[i + pPresent->MultipassOffset], &pTransfer->aDstSubRects[i]);
2771 cbCmd -= sizeof (VBOXVDMA_RECTL);
2772 }
2773 Assert(i);
2774 pTransfer->cDstSubRects = i;
2775 }
2776 else
2777 {
2778 AssertBreakpoint();
2779 drprintf((__FUNCTION__": unsupported format conversion from(%d) to (%d)\n",pSrcAlloc->u.SurfInfo.format, pDstAlloc->u.SurfInfo.format));
2780 Status = STATUS_GRAPHICS_CANNOTCOLORCONVERT;
2781 }
2782 }
2783 else
2784 {
2785 /* this should not happen actually */
2786 drprintf((__FUNCTION__": failed to get Dst Allocation info for hDeviceSpecificAllocation(0x%x)\n",pDst->hDeviceSpecificAllocation));
2787 Status = STATUS_INVALID_HANDLE;
2788 }
2789 }
2790 else
2791 {
2792 /* this should not happen actually */
2793 drprintf((__FUNCTION__": failed to get Src Allocation info for hDeviceSpecificAllocation(0x%x)\n",pSrc->hDeviceSpecificAllocation));
2794 Status = STATUS_INVALID_HANDLE;
2795 }
2796 }
2797 else
2798 {
2799 /* this should not happen actually */
2800 drprintf((__FUNCTION__": cbCmd too small!! (%d)\n", cbCmd));
2801 Status = STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER;
2802 }
2803
2804 }
2805 else
2806 {
2807 drprintf((__FUNCTION__": cmd NOT IMPLEMENTED!! Flags(0x%x)\n", pPresent->Flags.Value));
2808 AssertBreakpoint();
2809 }
2810
2811 dfprintf(("<== "__FUNCTION__ ", hContext(0x%x), Status(0x%x)\n", hContext, Status));
2812
2813 return Status;
2814}
2815
2816NTSTATUS
2817APIENTRY
2818DxgkDdiUpdateOverlay(
2819 CONST HANDLE hOverlay,
2820 CONST DXGKARG_UPDATEOVERLAY *pUpdateOverlay)
2821{
2822 dfprintf(("==> "__FUNCTION__ ", hOverlay(0x%x)\n", hOverlay));
2823 AssertBreakpoint();
2824 dfprintf(("<== "__FUNCTION__ ", hOverlay(0x%x)\n", hOverlay));
2825 return STATUS_NOT_IMPLEMENTED;
2826}
2827
2828NTSTATUS
2829APIENTRY
2830DxgkDdiFlipOverlay(
2831 CONST HANDLE hOverlay,
2832 CONST DXGKARG_FLIPOVERLAY *pFlipOverlay)
2833{
2834 dfprintf(("==> "__FUNCTION__ ", hOverlay(0x%x)\n", hOverlay));
2835 AssertBreakpoint();
2836 dfprintf(("<== "__FUNCTION__ ", hOverlay(0x%x)\n", hOverlay));
2837 return STATUS_NOT_IMPLEMENTED;
2838}
2839
2840NTSTATUS
2841APIENTRY
2842DxgkDdiDestroyOverlay(
2843 CONST HANDLE hOverlay)
2844{
2845 dfprintf(("==> "__FUNCTION__ ", hOverlay(0x%x)\n", hOverlay));
2846 AssertBreakpoint();
2847 dfprintf(("<== "__FUNCTION__ ", hOverlay(0x%x)\n", hOverlay));
2848 return STATUS_NOT_IMPLEMENTED;
2849}
2850
2851/**
2852 * DxgkDdiCreateContext
2853 */
2854NTSTATUS
2855APIENTRY
2856DxgkDdiCreateContext(
2857 CONST HANDLE hDevice,
2858 DXGKARG_CREATECONTEXT *pCreateContext)
2859{
2860 /* DxgkDdiCreateContext should be made pageable */
2861 PAGED_CODE();
2862
2863 dfprintf(("==> "__FUNCTION__ ", hDevice(0x%x)\n", hDevice));
2864
2865 AssertBreakpoint();
2866
2867 NTSTATUS Status = STATUS_SUCCESS;
2868 PVBOXWDDM_DEVICE pDevice = (PVBOXWDDM_DEVICE)hDevice;
2869 PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)vboxWddmMemAllocZero(sizeof (VBOXWDDM_CONTEXT));
2870
2871 pContext->pDevice = pDevice;
2872 pContext->EngineAffinity = pCreateContext->EngineAffinity;
2873 pContext->NodeOrdinal = pCreateContext->NodeOrdinal;
2874 if (pCreateContext->Flags.SystemContext)
2875 pContext->enmType = VBOXWDDM_CONTEXT_TYPE_SYSTEM;
2876 else
2877 {
2878 AssertBreakpoint(); /* we do not support custom contexts for now */
2879 drprintf((__FUNCTION__ ", we do not support custom contexts for now, hDevice (0x%x)\n", hDevice));
2880 }
2881
2882 pCreateContext->hContext = pContext;
2883 pCreateContext->ContextInfo.DmaBufferSize = VBOXWDDM_C_DMA_BUFFER_SIZE;
2884 pCreateContext->ContextInfo.DmaBufferSegmentSet = 0;
2885 pCreateContext->ContextInfo.DmaBufferPrivateDataSize = sizeof (VBOXWDDM_DMA_PRIVATE_DATA);
2886 pCreateContext->ContextInfo.AllocationListSize = VBOXWDDM_C_ALLOC_LIST_SIZE;
2887 pCreateContext->ContextInfo.PatchLocationListSize = VBOXWDDM_C_PATH_LOCATION_LIST_SIZE;
2888//#if (DXGKDDI_INTERFACE_VERSION >= DXGKDDI_INTERFACE_VERSION_WIN7)
2889//# error port to Win7 DDI
2890// //pCreateContext->ContextInfo.DmaBufferAllocationGroup = ???;
2891//#endif // DXGKDDI_INTERFACE_VERSION
2892
2893 dfprintf(("<== "__FUNCTION__ ", hDevice(0x%x)\n", hDevice));
2894
2895 return Status;
2896}
2897
2898NTSTATUS
2899APIENTRY
2900DxgkDdiDestroyContext(
2901 CONST HANDLE hContext)
2902{
2903 dfprintf(("==> "__FUNCTION__ ", hContext(0x%x)\n", hContext));
2904 vboxWddmMemFree(hContext);
2905 dfprintf(("<== "__FUNCTION__ ", hContext(0x%x)\n", hContext));
2906 return STATUS_SUCCESS;
2907}
2908
2909NTSTATUS
2910APIENTRY
2911DxgkDdiLinkDevice(
2912 __in CONST PDEVICE_OBJECT PhysicalDeviceObject,
2913 __in CONST PVOID MiniportDeviceContext,
2914 __inout PLINKED_DEVICE LinkedDevice
2915 )
2916{
2917 drprintf(("==> "__FUNCTION__ ", MiniportDeviceContext(0x%x)\n", MiniportDeviceContext));
2918 AssertBreakpoint();
2919 drprintf(("<== "__FUNCTION__ ", MiniportDeviceContext(0x%x)\n", MiniportDeviceContext));
2920 return STATUS_NOT_IMPLEMENTED;
2921}
2922
2923NTSTATUS
2924APIENTRY
2925DxgkDdiSetDisplayPrivateDriverFormat(
2926 CONST HANDLE hAdapter,
2927 /*CONST*/ DXGKARG_SETDISPLAYPRIVATEDRIVERFORMAT* pSetDisplayPrivateDriverFormat
2928 )
2929{
2930 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2931 AssertBreakpoint();
2932 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2933 return STATUS_SUCCESS;
2934}
2935
2936NTSTATUS APIENTRY CALLBACK DxgkDdiRestartFromTimeout(IN_CONST_HANDLE hAdapter)
2937{
2938 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2939 AssertBreakpoint();
2940 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2941 return STATUS_SUCCESS;
2942}
2943
2944NTSTATUS
2945DriverEntry(
2946 IN PDRIVER_OBJECT DriverObject,
2947 IN PUNICODE_STRING RegistryPath
2948 )
2949{
2950 PAGED_CODE();
2951
2952 AssertBreakpoint();
2953
2954 drprintf(("VBoxVideoWddm::DriverEntry. Built %s %s\n", __DATE__, __TIME__));
2955
2956 DRIVER_INITIALIZATION_DATA DriverInitializationData = {'\0'};
2957
2958 if (! ARGUMENT_PRESENT(DriverObject) ||
2959 ! ARGUMENT_PRESENT(RegistryPath))
2960 {
2961 return STATUS_INVALID_PARAMETER;
2962 }
2963
2964 // Fill in the DriverInitializationData structure and call DxgkInitialize()
2965 DriverInitializationData.Version = DXGKDDI_INTERFACE_VERSION;
2966
2967 DriverInitializationData.DxgkDdiAddDevice = DxgkDdiAddDevice;
2968 DriverInitializationData.DxgkDdiStartDevice = DxgkDdiStartDevice;
2969 DriverInitializationData.DxgkDdiStopDevice = DxgkDdiStopDevice;
2970 DriverInitializationData.DxgkDdiRemoveDevice = DxgkDdiRemoveDevice;
2971 DriverInitializationData.DxgkDdiDispatchIoRequest = DxgkDdiDispatchIoRequest;
2972 DriverInitializationData.DxgkDdiInterruptRoutine = DxgkDdiInterruptRoutine;
2973 DriverInitializationData.DxgkDdiDpcRoutine = DxgkDdiDpcRoutine;
2974 DriverInitializationData.DxgkDdiQueryChildRelations = DxgkDdiQueryChildRelations;
2975 DriverInitializationData.DxgkDdiQueryChildStatus = DxgkDdiQueryChildStatus;
2976 DriverInitializationData.DxgkDdiQueryDeviceDescriptor = DxgkDdiQueryDeviceDescriptor;
2977 DriverInitializationData.DxgkDdiSetPowerState = DxgkDdiSetPowerState;
2978 DriverInitializationData.DxgkDdiNotifyAcpiEvent = DxgkDdiNotifyAcpiEvent;
2979 DriverInitializationData.DxgkDdiResetDevice = DxgkDdiResetDevice;
2980 DriverInitializationData.DxgkDdiUnload = DxgkDdiUnload;
2981 DriverInitializationData.DxgkDdiQueryInterface = DxgkDdiQueryInterface;
2982 DriverInitializationData.DxgkDdiControlEtwLogging = DxgkDdiControlEtwLogging;
2983
2984 DriverInitializationData.DxgkDdiQueryAdapterInfo = DxgkDdiQueryAdapterInfo;
2985 DriverInitializationData.DxgkDdiCreateDevice = DxgkDdiCreateDevice;
2986 DriverInitializationData.DxgkDdiCreateAllocation = DxgkDdiCreateAllocation;
2987 DriverInitializationData.DxgkDdiDestroyAllocation = DxgkDdiDestroyAllocation;
2988 DriverInitializationData.DxgkDdiDescribeAllocation = DxgkDdiDescribeAllocation;
2989 DriverInitializationData.DxgkDdiGetStandardAllocationDriverData = DxgkDdiGetStandardAllocationDriverData;
2990 DriverInitializationData.DxgkDdiAcquireSwizzlingRange = DxgkDdiAcquireSwizzlingRange;
2991 DriverInitializationData.DxgkDdiReleaseSwizzlingRange = DxgkDdiReleaseSwizzlingRange;
2992 DriverInitializationData.DxgkDdiPatch = DxgkDdiPatch;
2993 DriverInitializationData.DxgkDdiSubmitCommand = DxgkDdiSubmitCommand;
2994 DriverInitializationData.DxgkDdiPreemptCommand = DxgkDdiPreemptCommand;
2995 DriverInitializationData.DxgkDdiBuildPagingBuffer = DxgkDdiBuildPagingBuffer;
2996 DriverInitializationData.DxgkDdiSetPalette = DxgkDdiSetPalette;
2997 DriverInitializationData.DxgkDdiSetPointerPosition = DxgkDdiSetPointerPosition;
2998 DriverInitializationData.DxgkDdiSetPointerShape = DxgkDdiSetPointerShape;
2999 DriverInitializationData.DxgkDdiResetFromTimeout = DxgkDdiResetFromTimeout;
3000 DriverInitializationData.DxgkDdiRestartFromTimeout = DxgkDdiRestartFromTimeout;
3001 DriverInitializationData.DxgkDdiEscape = DxgkDdiEscape;
3002 DriverInitializationData.DxgkDdiCollectDbgInfo = DxgkDdiCollectDbgInfo;
3003 DriverInitializationData.DxgkDdiQueryCurrentFence = DxgkDdiQueryCurrentFence;
3004 DriverInitializationData.DxgkDdiIsSupportedVidPn = DxgkDdiIsSupportedVidPn;
3005 DriverInitializationData.DxgkDdiRecommendFunctionalVidPn = DxgkDdiRecommendFunctionalVidPn;
3006 DriverInitializationData.DxgkDdiEnumVidPnCofuncModality = DxgkDdiEnumVidPnCofuncModality;
3007 DriverInitializationData.DxgkDdiSetVidPnSourceAddress = DxgkDdiSetVidPnSourceAddress;
3008 DriverInitializationData.DxgkDdiSetVidPnSourceVisibility = DxgkDdiSetVidPnSourceVisibility;
3009 DriverInitializationData.DxgkDdiCommitVidPn = DxgkDdiCommitVidPn;
3010 DriverInitializationData.DxgkDdiUpdateActiveVidPnPresentPath = DxgkDdiUpdateActiveVidPnPresentPath;
3011 DriverInitializationData.DxgkDdiRecommendMonitorModes = DxgkDdiRecommendMonitorModes;
3012 DriverInitializationData.DxgkDdiRecommendVidPnTopology = DxgkDdiRecommendVidPnTopology;
3013 DriverInitializationData.DxgkDdiGetScanLine = DxgkDdiGetScanLine;
3014 DriverInitializationData.DxgkDdiStopCapture = DxgkDdiStopCapture;
3015 DriverInitializationData.DxgkDdiControlInterrupt = DxgkDdiControlInterrupt;
3016 DriverInitializationData.DxgkDdiCreateOverlay = DxgkDdiCreateOverlay;
3017
3018 DriverInitializationData.DxgkDdiDestroyDevice = DxgkDdiDestroyDevice;
3019 DriverInitializationData.DxgkDdiOpenAllocation = DxgkDdiOpenAllocation;
3020 DriverInitializationData.DxgkDdiCloseAllocation = DxgkDdiCloseAllocation;
3021 DriverInitializationData.DxgkDdiRender = DxgkDdiRender;
3022 DriverInitializationData.DxgkDdiPresent = DxgkDdiPresent;
3023
3024 DriverInitializationData.DxgkDdiUpdateOverlay = DxgkDdiUpdateOverlay;
3025 DriverInitializationData.DxgkDdiFlipOverlay = DxgkDdiFlipOverlay;
3026 DriverInitializationData.DxgkDdiDestroyOverlay = DxgkDdiDestroyOverlay;
3027
3028 DriverInitializationData.DxgkDdiCreateContext = DxgkDdiCreateContext;
3029 DriverInitializationData.DxgkDdiDestroyContext = DxgkDdiDestroyContext;
3030
3031 DriverInitializationData.DxgkDdiLinkDevice = NULL; //DxgkDdiLinkDevice;
3032 DriverInitializationData.DxgkDdiSetDisplayPrivateDriverFormat = DxgkDdiSetDisplayPrivateDriverFormat;
3033//#if (DXGKDDI_INTERFACE_VERSION >= DXGKDDI_INTERFACE_VERSION_WIN7)
3034//# error port to Win7 DDI
3035// DriverInitializationData.DxgkDdiRenderKm = DxgkDdiRenderKm;
3036// DriverInitializationData.DxgkDdiRestartFromTimeout = DxgkDdiRestartFromTimeout;
3037// DriverInitializationData.DxgkDdiSetVidPnSourceVisibility = DxgkDdiSetVidPnSourceVisibility;
3038// DriverInitializationData.DxgkDdiUpdateActiveVidPnPresentPath = DxgkDdiUpdateActiveVidPnPresentPath;
3039// DriverInitializationData.DxgkDdiQueryVidPnHWCapability = DxgkDdiQueryVidPnHWCapability;
3040//#endif
3041
3042 return DxgkInitialize(DriverObject,
3043 RegistryPath,
3044 &DriverInitializationData);
3045}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette