VirtualBox

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

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

wddm: graphics dev update only necessary portion of framebuffer

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 111.0 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 = (uint32_t)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 = (uint32_t)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
553 vboxVDbgBreakFv();
554
555 NTSTATUS Status = STATUS_SUCCESS;
556
557 PDEVICE_EXTENSION pContext = (PDEVICE_EXTENSION)vboxWddmMemAllocZero(sizeof (DEVICE_EXTENSION));
558 if (pContext)
559 {
560 pContext->pPDO = PhysicalDeviceObject;
561 *MiniportDeviceContext = pContext;
562 }
563 else
564 {
565 Status = STATUS_INSUFFICIENT_RESOURCES;
566 drprintf(("VBoxVideoWddm: ERROR, failed to create context\n"));
567 }
568
569 dfprintf(("<== "__FUNCTION__ ", status(0x%x), pContext(0x%x)\n", Status, pContext));
570
571 return Status;
572}
573
574NTSTATUS DxgkDdiStartDevice(
575 IN CONST PVOID MiniportDeviceContext,
576 IN PDXGK_START_INFO DxgkStartInfo,
577 IN PDXGKRNL_INTERFACE DxgkInterface,
578 OUT PULONG NumberOfVideoPresentSources,
579 OUT PULONG NumberOfChildren
580 )
581{
582 /* The DxgkDdiStartDevice function should be made pageable. */
583 PAGED_CODE();
584
585 NTSTATUS Status;
586
587 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", MiniportDeviceContext));
588
589 vboxVDbgBreakFv();
590
591 if ( ARGUMENT_PRESENT(MiniportDeviceContext) &&
592 ARGUMENT_PRESENT(DxgkInterface) &&
593 ARGUMENT_PRESENT(DxgkStartInfo) &&
594 ARGUMENT_PRESENT(NumberOfVideoPresentSources),
595 ARGUMENT_PRESENT(NumberOfChildren)
596 )
597 {
598 PDEVICE_EXTENSION pContext = (PDEVICE_EXTENSION)MiniportDeviceContext;
599
600 /* Save DeviceHandle and function pointers supplied by the DXGKRNL_INTERFACE structure passed to DxgkInterface. */
601 memcpy(&pContext->u.primary.DxgkInterface, DxgkInterface, sizeof (DXGKRNL_INTERFACE));
602
603 /* 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)
604 * of the DXGK_DEVICE_INFO structure in the context block represented by MiniportDeviceContext. */
605 DXGK_DEVICE_INFO DeviceInfo;
606 Status = pContext->u.primary.DxgkInterface.DxgkCbGetDeviceInformation (pContext->u.primary.DxgkInterface.DeviceHandle, &DeviceInfo);
607 if (Status == STATUS_SUCCESS)
608 {
609 ULONG AdapterMemorySize;
610 Status = vboxWddmPickResources(pContext, &DeviceInfo, &AdapterMemorySize);
611 if (Status == STATUS_SUCCESS)
612 {
613 /* Initialize VBoxGuest library, which is used for requests which go through VMMDev. */
614 VbglInit ();
615
616 /* Guest supports only HGSMI, the old VBVA via VMMDev is not supported. Old
617 * code will be ifdef'ed and later removed.
618 * The host will however support both old and new interface to keep compatibility
619 * with old guest additions.
620 */
621 VBoxSetupDisplaysHGSMI(pContext, AdapterMemorySize);
622 if ((pContext)->u.primary.bHGSMI)
623 {
624 drprintf(("VBoxVideoWddm: using HGSMI\n"));
625 *NumberOfVideoPresentSources = pContext->cSources;
626 *NumberOfChildren = pContext->cSources;
627 dprintf(("VBoxVideoWddm: sources(%d), children(%d)\n", *NumberOfVideoPresentSources, *NumberOfChildren));
628 }
629 else
630 {
631 drprintf(("VBoxVideoWddm: HGSMI failed to initialize, returning err\n"));
632 /* @todo: report a better status */
633 Status = STATUS_UNSUCCESSFUL;
634 }
635 }
636 else
637 {
638 drprintf(("VBoxVideoWddm:: vboxWddmPickResources failed Status(0x%x), returning err\n", Status));
639 Status = STATUS_UNSUCCESSFUL;
640 }
641 }
642 else
643 {
644 drprintf(("VBoxVideoWddm: DxgkCbGetDeviceInformation failed Status(0x%x), returning err\n", Status));
645 }
646 }
647 else
648 {
649 drprintf(("VBoxVideoWddm: invalid parameter, returning err\n"));
650 Status = STATUS_INVALID_PARAMETER;
651 }
652
653 dfprintf(("<== "__FUNCTION__ ", status(0x%x)\n", Status));
654
655 return Status;
656}
657
658NTSTATUS DxgkDdiStopDevice(
659 IN CONST PVOID MiniportDeviceContext
660 )
661{
662 /* The DxgkDdiStopDevice function should be made pageable. */
663 PAGED_CODE();
664
665 dfprintf(("==> "__FUNCTION__ ", context(0x%p)\n", MiniportDeviceContext));
666
667 AssertBreakpoint();
668 /* @todo: fixme: implement */
669
670 dfprintf(("<== "__FUNCTION__ ", context(0x%p)\n", MiniportDeviceContext));
671
672 return STATUS_SUCCESS;
673}
674
675NTSTATUS DxgkDdiRemoveDevice(
676 IN CONST PVOID MiniportDeviceContext
677 )
678{
679 /* DxgkDdiRemoveDevice should be made pageable. */
680 PAGED_CODE();
681
682 dfprintf(("==> "__FUNCTION__ ", context(0x%p)\n", MiniportDeviceContext));
683
684 vboxVDbgBreakF();
685
686 vboxWddmMemFree(MiniportDeviceContext);
687
688 dfprintf(("<== "__FUNCTION__ ", context(0x%p)\n", MiniportDeviceContext));
689
690 return STATUS_SUCCESS;
691}
692
693NTSTATUS DxgkDdiDispatchIoRequest(
694 IN CONST PVOID MiniportDeviceContext,
695 IN ULONG VidPnSourceId,
696 IN PVIDEO_REQUEST_PACKET VideoRequestPacket
697 )
698{
699 dfprintf(("==> "__FUNCTION__ ", context(0x%p), ctl(0x%x)\n", MiniportDeviceContext, VideoRequestPacket->IoControlCode));
700
701 AssertBreakpoint();
702#if 0
703 PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)MiniportDeviceContext;
704
705 switch (VideoRequestPacket->IoControlCode)
706 {
707 case IOCTL_VIDEO_QUERY_COLOR_CAPABILITIES:
708 {
709 if (VideoRequestPacket->OutputBufferLength < sizeof(VIDEO_COLOR_CAPABILITIES))
710 {
711 AssertBreakpoint();
712 VideoRequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
713 return TRUE;
714 }
715 VIDEO_COLOR_CAPABILITIES *pCaps = (VIDEO_COLOR_CAPABILITIES*)VideoRequestPacket->OutputBuffer;
716
717 pCaps->Length = sizeof (VIDEO_COLOR_CAPABILITIES);
718 pCaps->AttributeFlags = VIDEO_DEVICE_COLOR;
719 pCaps->RedPhosphoreDecay = 0;
720 pCaps->GreenPhosphoreDecay = 0;
721 pCaps->BluePhosphoreDecay = 0;
722 pCaps->WhiteChromaticity_x = 3127;
723 pCaps->WhiteChromaticity_y = 3290;
724 pCaps->WhiteChromaticity_Y = 0;
725 pCaps->RedChromaticity_x = 6700;
726 pCaps->RedChromaticity_y = 3300;
727 pCaps->GreenChromaticity_x = 2100;
728 pCaps->GreenChromaticity_y = 7100;
729 pCaps->BlueChromaticity_x = 1400;
730 pCaps->BlueChromaticity_y = 800;
731 pCaps->WhiteGamma = 0;
732 pCaps->RedGamma = 20000;
733 pCaps->GreenGamma = 20000;
734 pCaps->BlueGamma = 20000;
735
736 VideoRequestPacket->StatusBlock->Status = NO_ERROR;
737 VideoRequestPacket->StatusBlock->Information = sizeof (VIDEO_COLOR_CAPABILITIES);
738 break;
739 }
740#if 0
741 case IOCTL_VIDEO_HANDLE_VIDEOPARAMETERS:
742 {
743 if (VideoRequestPacket->OutputBufferLength < sizeof(VIDEOPARAMETERS)
744 || VideoRequestPacket->InputBufferLength < sizeof(VIDEOPARAMETERS))
745 {
746 AssertBreakpoint();
747 VideoRequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
748 return TRUE;
749 }
750
751 Result = VBoxVideoResetDevice((PDEVICE_EXTENSION)HwDeviceExtension,
752 RequestPacket->StatusBlock);
753 break;
754 }
755#endif
756 default:
757 AssertBreakpoint();
758 VideoRequestPacket->StatusBlock->Status = ERROR_INVALID_FUNCTION;
759 VideoRequestPacket->StatusBlock->Information = 0;
760 }
761#endif
762 dfprintf(("<== "__FUNCTION__ ", context(0x%p), ctl(0x%x)\n", MiniportDeviceContext, VideoRequestPacket->IoControlCode));
763
764 return STATUS_SUCCESS;
765}
766
767BOOLEAN DxgkDdiInterruptRoutine(
768 IN CONST PVOID MiniportDeviceContext,
769 IN ULONG MessageNumber
770 )
771{
772 dfprintf(("==> "__FUNCTION__ ", context(0x%p), msg(0x%x)\n", MiniportDeviceContext, MessageNumber));
773
774 vboxVDbgBreakFv();
775
776 PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)MiniportDeviceContext;
777 BOOLEAN bOur = FALSE;
778 BOOLEAN bNeedDpc = FALSE;
779 if (pDevExt->u.primary.pHostFlags) /* If HGSMI is enabled at all. */
780 {
781 VBOXSHGSMILIST CtlList;
782 VBOXSHGSMILIST DmaCmdList;
783 vboxSHGSMIListInit(&CtlList);
784 vboxSHGSMIListInit(&DmaCmdList);
785
786 uint32_t flags = pDevExt->u.primary.pHostFlags->u32HostFlags;
787 bOur = (flags & HGSMIHOSTFLAGS_IRQ);
788 do
789 {
790 if (flags & HGSMIHOSTFLAGS_GCOMMAND_COMPLETED)
791 {
792 /* read the command offset */
793 HGSMIOFFSET offCmd = VBoxHGSMIGuestRead(pDevExt);
794 Assert(offCmd != HGSMIOFFSET_VOID);
795 if (offCmd != HGSMIOFFSET_VOID)
796 {
797 VBOXWDDM_HGSMICMD_TYPE enmType = vboxWddmHgsmiGetCmdTypeFromOffset(pDevExt, offCmd);
798 PVBOXSHGSMILIST pList;
799 HGSMIHEAP * pHeap = NULL;
800 switch (enmType)
801 {
802 case VBOXWDDM_HGSMICMD_TYPE_DMACMD:
803 pList = &DmaCmdList;
804 pHeap = &pDevExt->u.primary.Vdma.CmdHeap;
805 break;
806 case VBOXWDDM_HGSMICMD_TYPE_CTL:
807 pList = &CtlList;
808 pHeap = &pDevExt->u.primary.hgsmiAdapterHeap;
809 break;
810 default:
811 AssertBreakpoint();
812 }
813
814 if (pHeap)
815 {
816 int rc = VBoxSHGSMICommandProcessCompletion (pHeap, offCmd, TRUE /*bool bIrq*/ , pList);
817 AssertRC(rc);
818 }
819 }
820 }
821 else if (flags & HGSMIHOSTFLAGS_COMMANDS_PENDING)
822 {
823 AssertBreakpoint();
824 /* @todo: FIXME: implement !!! */
825 }
826 else
827 break;
828
829 flags = pDevExt->u.primary.pHostFlags->u32HostFlags;
830 } while (1);
831
832 if (!vboxSHGSMIListIsEmpty(&CtlList))
833 {
834 vboxSHGSMIListCat(&pDevExt->CtlList, &CtlList);
835 bNeedDpc = TRUE;
836 }
837
838 if (!vboxSHGSMIListIsEmpty(&DmaCmdList))
839 {
840 vboxSHGSMIListCat(&pDevExt->DmaCmdList, &DmaCmdList);
841 bNeedDpc = TRUE;
842 }
843
844 if (pDevExt->bSetNotifyDxDpc)
845 {
846 Assert(bNeedDpc == TRUE);
847 pDevExt->bNotifyDxDpc = TRUE;
848 pDevExt->bSetNotifyDxDpc = FALSE;
849 bNeedDpc = TRUE;
850 }
851
852 if (bOur)
853 {
854 HGSMIClearIrq (pDevExt);
855#ifdef DEBUG_misha
856 /* this is not entirely correct since host may concurrently complete some commands and raise a new IRQ while we are here,
857 * still this allows to check that the host flags are correctly cleared after the ISR */
858 Assert(pDevExt->u.primary.pHostFlags);
859 uint32_t flags = pDevExt->u.primary.pHostFlags->u32HostFlags;
860 Assert(flags == 0);
861#endif
862 BOOLEAN bDpcQueued = pDevExt->u.primary.DxgkInterface.DxgkCbQueueDpc(pDevExt->u.primary.DxgkInterface.DeviceHandle);
863 Assert(bDpcQueued);
864 }
865 }
866
867 dfprintf(("<== "__FUNCTION__ ", context(0x%p), bOur(0x%x)\n", MiniportDeviceContext, (ULONG)bOur));
868
869 return bOur;
870}
871
872
873typedef struct VBOXWDDM_DPCDATA
874{
875 VBOXSHGSMILIST CtlList;
876 VBOXSHGSMILIST DmaCmdList;
877 BOOL bNotifyDpc;
878} VBOXWDDM_DPCDATA, *PVBOXWDDM_DPCDATA;
879
880typedef struct VBOXWDDM_GETDPCDATA_CONTEXT
881{
882 PDEVICE_EXTENSION pDevExt;
883 VBOXWDDM_DPCDATA data;
884} VBOXWDDM_GETDPCDATA_CONTEXT, *PVBOXWDDM_GETDPCDATA_CONTEXT;
885
886BOOLEAN vboxWddmGetDPCDataCallback(PVOID Context)
887{
888 PVBOXWDDM_GETDPCDATA_CONTEXT pdc = (PVBOXWDDM_GETDPCDATA_CONTEXT)Context;
889
890 vboxSHGSMICmdListDetach2List(&pdc->pDevExt->CtlList, &pdc->data.CtlList);
891 vboxSHGSMICmdListDetach2List(&pdc->pDevExt->DmaCmdList, &pdc->data.DmaCmdList);
892 pdc->data.bNotifyDpc = pdc->pDevExt->bNotifyDxDpc;
893 pdc->pDevExt->bNotifyDxDpc = FALSE;
894 return TRUE;
895}
896
897VOID DxgkDdiDpcRoutine(
898 IN CONST PVOID MiniportDeviceContext
899 )
900{
901 dfprintf(("==> "__FUNCTION__ ", context(0x%p)\n", MiniportDeviceContext));
902
903 vboxVDbgBreakFv();
904
905 PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)MiniportDeviceContext;
906
907 VBOXWDDM_GETDPCDATA_CONTEXT context = {0};
908 BOOLEAN bRet;
909
910 context.pDevExt = pDevExt;
911
912 /* get DPC data at IRQL */
913 NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbSynchronizeExecution(
914 pDevExt->u.primary.DxgkInterface.DeviceHandle,
915 vboxWddmGetDPCDataCallback,
916 &context,
917 0, /* IN ULONG MessageNumber */
918 &bRet);
919 Assert(Status == STATUS_SUCCESS);
920
921 if (!vboxSHGSMIListIsEmpty(&context.data.CtlList))
922 {
923 int rc = VBoxSHGSMICommandPostprocessCompletion (&pDevExt->u.primary.hgsmiAdapterHeap, &context.data.CtlList);
924 AssertRC(rc);
925 }
926
927 if (!vboxSHGSMIListIsEmpty(&context.data.DmaCmdList))
928 {
929 int rc = VBoxSHGSMICommandPostprocessCompletion (&pDevExt->u.primary.Vdma.CmdHeap, &context.data.DmaCmdList);
930 AssertRC(rc);
931 }
932
933 if (context.data.bNotifyDpc)
934 pDevExt->u.primary.DxgkInterface.DxgkCbNotifyDpc(pDevExt->u.primary.DxgkInterface.DeviceHandle);
935
936 dfprintf(("<== "__FUNCTION__ ", context(0x%p)\n", MiniportDeviceContext));
937}
938
939NTSTATUS DxgkDdiQueryChildRelations(
940 IN CONST PVOID MiniportDeviceContext,
941 IN OUT PDXGK_CHILD_DESCRIPTOR ChildRelations,
942 IN ULONG ChildRelationsSize
943 )
944{
945 /* The DxgkDdiQueryChildRelations function should be made pageable. */
946 PAGED_CODE();
947
948 vboxVDbgBreakFv();
949
950 PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)MiniportDeviceContext;
951
952 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", MiniportDeviceContext));
953 Assert(ChildRelationsSize == (pDevExt->cSources + 1)*sizeof(DXGK_CHILD_DESCRIPTOR));
954 for (UINT i = 0; i < pDevExt->cSources; ++i)
955 {
956 ChildRelations[i].ChildDeviceType = TypeVideoOutput;
957 ChildRelations[i].ChildCapabilities.Type.VideoOutput.InterfaceTechnology = D3DKMDT_VOT_HD15; /* VGA */
958 ChildRelations[i].ChildCapabilities.Type.VideoOutput.MonitorOrientationAwareness = D3DKMDT_MOA_INTERRUPTIBLE; /* ?? D3DKMDT_MOA_NONE*/
959 ChildRelations[i].ChildCapabilities.Type.VideoOutput.SupportsSdtvModes = FALSE;
960 ChildRelations[i].ChildCapabilities.HpdAwareness = HpdAwarenessInterruptible; /* ?? HpdAwarenessAlwaysConnected; */
961 ChildRelations[i].AcpiUid = i; /* */
962 ChildRelations[i].ChildUid = i; /* should be == target id */
963 }
964 dfprintf(("<== "__FUNCTION__ ", context(0x%x)\n", MiniportDeviceContext));
965 return STATUS_SUCCESS;
966}
967
968NTSTATUS DxgkDdiQueryChildStatus(
969 IN CONST PVOID MiniportDeviceContext,
970 IN PDXGK_CHILD_STATUS ChildStatus,
971 IN BOOLEAN NonDestructiveOnly
972 )
973{
974 /* The DxgkDdiQueryChildStatus should be made pageable. */
975 PAGED_CODE();
976
977 vboxVDbgBreakFv();
978
979 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", MiniportDeviceContext));
980
981 NTSTATUS Status = STATUS_SUCCESS;
982 switch (ChildStatus->Type)
983 {
984 case StatusConnection:
985 ChildStatus->HotPlug.Connected = TRUE;
986 dfprintf(("VBoxVideoWddm: StatusConnection\n"));
987 break;
988 case StatusRotation:
989 ChildStatus->Rotation.Angle = 0;
990 dfprintf(("VBoxVideoWddm: StatusRotation\n"));
991 break;
992 default:
993 drprintf(("VBoxVideoWddm: ERROR: status type: %d\n", ChildStatus->Type));
994 AssertBreakpoint();
995 Status = STATUS_INVALID_PARAMETER;
996 break;
997 }
998
999 dfprintf(("<== "__FUNCTION__ ", context(0x%x)\n", MiniportDeviceContext));
1000
1001 return Status;
1002}
1003
1004NTSTATUS DxgkDdiQueryDeviceDescriptor(
1005 IN CONST PVOID MiniportDeviceContext,
1006 IN ULONG ChildUid,
1007 IN OUT PDXGK_DEVICE_DESCRIPTOR DeviceDescriptor
1008 )
1009{
1010 /* The DxgkDdiQueryDeviceDescriptor should be made pageable. */
1011 PAGED_CODE();
1012
1013 vboxVDbgBreakFv();
1014
1015 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", MiniportDeviceContext));
1016
1017 dfprintf(("<== "__FUNCTION__ ", context(0x%x)\n", MiniportDeviceContext));
1018
1019 /* we do not support EDID */
1020 return STATUS_MONITOR_NO_DESCRIPTOR;
1021}
1022
1023NTSTATUS DxgkDdiSetPowerState(
1024 IN CONST PVOID MiniportDeviceContext,
1025 IN ULONG DeviceUid,
1026 IN DEVICE_POWER_STATE DevicePowerState,
1027 IN POWER_ACTION ActionType
1028 )
1029{
1030 /* The DxgkDdiSetPowerState function should be made pageable. */
1031 PAGED_CODE();
1032
1033 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", MiniportDeviceContext));
1034
1035 /* @todo: */
1036 vboxVDbgBreakF();
1037
1038 dfprintf(("<== "__FUNCTION__ ", context(0x%x)\n", MiniportDeviceContext));
1039
1040 return STATUS_SUCCESS;
1041}
1042
1043NTSTATUS DxgkDdiNotifyAcpiEvent(
1044 IN CONST PVOID MiniportDeviceContext,
1045 IN DXGK_EVENT_TYPE EventType,
1046 IN ULONG Event,
1047 IN PVOID Argument,
1048 OUT PULONG AcpiFlags
1049 )
1050{
1051 dfprintf(("==> "__FUNCTION__ ", MiniportDeviceContext(0x%x)\n", MiniportDeviceContext));
1052
1053 vboxVDbgBreakF();
1054
1055 dfprintf(("<== "__FUNCTION__ ", MiniportDeviceContext(0x%x)\n", MiniportDeviceContext));
1056
1057 return STATUS_SUCCESS;
1058}
1059
1060VOID DxgkDdiResetDevice(
1061 IN CONST PVOID MiniportDeviceContext
1062 )
1063{
1064 /* DxgkDdiResetDevice can be called at any IRQL, so it must be in nonpageable memory. */
1065 vboxVDbgBreakF();
1066
1067 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", MiniportDeviceContext));
1068 dfprintf(("<== "__FUNCTION__ ", context(0x%x)\n", MiniportDeviceContext));
1069}
1070
1071VOID DxgkDdiUnload(
1072 VOID
1073 )
1074{
1075 /* DxgkDdiUnload should be made pageable. */
1076 PAGED_CODE();
1077 dfprintf(("==> "__FUNCTION__ "\n"));
1078
1079 AssertBreakpoint();
1080
1081 dfprintf(("<== "__FUNCTION__ "\n"));
1082}
1083
1084NTSTATUS DxgkDdiQueryInterface(
1085 IN CONST PVOID MiniportDeviceContext,
1086 IN PQUERY_INTERFACE QueryInterface
1087 )
1088{
1089 dfprintf(("==> "__FUNCTION__ ", MiniportDeviceContext(0x%x)\n", MiniportDeviceContext));
1090
1091 vboxVDbgBreakFv();
1092
1093 dfprintf(("<== "__FUNCTION__ ", MiniportDeviceContext(0x%x)\n", MiniportDeviceContext));
1094
1095 return STATUS_NOT_SUPPORTED;
1096}
1097
1098VOID DxgkDdiControlEtwLogging(
1099 IN BOOLEAN Enable,
1100 IN ULONG Flags,
1101 IN UCHAR Level
1102 )
1103{
1104 dfprintf(("==> "__FUNCTION__ "\n"));
1105
1106 vboxVDbgBreakF();
1107
1108 dfprintf(("<== "__FUNCTION__ "\n"));
1109}
1110
1111/**
1112 * DxgkDdiQueryAdapterInfo
1113 */
1114NTSTATUS APIENTRY DxgkDdiQueryAdapterInfo(
1115 CONST HANDLE hAdapter,
1116 CONST DXGKARG_QUERYADAPTERINFO* pQueryAdapterInfo)
1117{
1118 /* The DxgkDdiQueryAdapterInfo should be made pageable. */
1119 PAGED_CODE();
1120
1121 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", hAdapter));
1122 NTSTATUS Status = STATUS_SUCCESS;
1123 PDEVICE_EXTENSION pContext = (PDEVICE_EXTENSION)hAdapter;
1124
1125 vboxVDbgBreakFv();
1126
1127 switch (pQueryAdapterInfo->Type)
1128 {
1129 case DXGKQAITYPE_DRIVERCAPS:
1130 {
1131 DXGK_DRIVERCAPS *pCaps = (DXGK_DRIVERCAPS*)pQueryAdapterInfo->pOutputData;
1132
1133 pCaps->HighestAcceptableAddress.HighPart = 0x0;
1134 pCaps->HighestAcceptableAddress.LowPart = 0xffffffffUL;
1135 pCaps->MaxAllocationListSlotId = 16;
1136 pCaps->ApertureSegmentCommitLimit = 0;
1137 pCaps->MaxPointerWidth = 64;
1138 pCaps->MaxPointerHeight = 64;
1139 pCaps->PointerCaps.Value = 3; /* Monochrome , Color*/ /* MaskedColor == Value | 4, dosable for now */
1140 pCaps->InterruptMessageNumber = 0;
1141 pCaps->NumberOfSwizzlingRanges = 0;
1142 /* @todo: need to adjust this for proper 2D Accel support */
1143 pCaps->MaxOverlays = 0; /* ?? how much should we support? 32 */
1144 pCaps->GammaRampCaps.Value = 0;
1145 pCaps->PresentationCaps.Value = 0;
1146 pCaps->PresentationCaps.NoScreenToScreenBlt = 1;
1147 pCaps->PresentationCaps.NoOverlapScreenBlt = 1;
1148 pCaps->MaxQueuedFlipOnVSync = 0; /* do we need it? */
1149 pCaps->FlipCaps.Value = 0;
1150 /* ? pCaps->FlipCaps.FlipOnVSyncWithNoWait = 1; */
1151 pCaps->SchedulingCaps.Value = 0;
1152 /* we might need it for Aero.
1153 * Setting this flag means we support DeviceContext, i.e.
1154 * DxgkDdiCreateContext and DxgkDdiDestroyContext
1155 */
1156 pCaps->SchedulingCaps.MultiEngineAware = 1;
1157 pCaps->MemoryManagementCaps.Value = 0;
1158 /* @todo: this corelates with pCaps->SchedulingCaps.MultiEngineAware */
1159 pCaps->MemoryManagementCaps.PagingNode = 0;
1160 /* @todo: this corelates with pCaps->SchedulingCaps.MultiEngineAware */
1161 pCaps->GpuEngineTopology.NbAsymetricProcessingNodes = 1;
1162
1163 break;
1164 }
1165 case DXGKQAITYPE_QUERYSEGMENT:
1166 {
1167 /* no need for DXGK_QUERYSEGMENTIN as it contains AGP aperture info, which (AGP aperture) we do not support
1168 * DXGK_QUERYSEGMENTIN *pQsIn = (DXGK_QUERYSEGMENTIN*)pQueryAdapterInfo->pInputData; */
1169 DXGK_QUERYSEGMENTOUT *pQsOut = (DXGK_QUERYSEGMENTOUT*)pQueryAdapterInfo->pOutputData;
1170 if (!pQsOut->pSegmentDescriptor)
1171 {
1172 /* we are requested to provide the number of segments we support */
1173 pQsOut->NbSegment = 2;
1174 }
1175 else if (pQsOut->NbSegment != 2)
1176 {
1177 AssertBreakpoint();
1178 drprintf((__FUNCTION__ " NbSegment (%d) != 1\n", pQsOut->NbSegment));
1179 Status = STATUS_INVALID_PARAMETER;
1180 }
1181 else
1182 {
1183 DXGK_SEGMENTDESCRIPTOR* pDr = pQsOut->pSegmentDescriptor;
1184 /* we are requested to provide segment information */
1185 pDr->BaseAddress.QuadPart = 0; /* VBE_DISPI_LFB_PHYSICAL_ADDRESS; */
1186 pDr->CpuTranslatedAddress.QuadPart = VBE_DISPI_LFB_PHYSICAL_ADDRESS;
1187 /* make sure the size is page aligned */
1188 /* @todo: need to setup VBVA buffers and adjust the mem size here */
1189 pDr->Size = vboxWddmVramReportedSegmentSize(pContext);
1190 pDr->NbOfBanks = 0;
1191 pDr->pBankRangeTable = 0;
1192 pDr->CommitLimit = pDr->Size;
1193 pDr->Flags.Value = 0;
1194 pDr->Flags.CpuVisible = 1;
1195
1196 ++pDr;
1197 /* create cpu-invisible segment of the same size */
1198 pDr->BaseAddress.QuadPart = 0;
1199 pDr->CpuTranslatedAddress.QuadPart = 0;
1200 /* make sure the size is page aligned */
1201 /* @todo: need to setup VBVA buffers and adjust the mem size here */
1202 pDr->Size = vboxWddmVramReportedSegmentSize(pContext);
1203 pDr->NbOfBanks = 0;
1204 pDr->pBankRangeTable = 0;
1205 pDr->CommitLimit = pDr->Size;
1206 pDr->Flags.Value = 0;
1207
1208 pQsOut->PagingBufferSegmentId = 0;
1209 pQsOut->PagingBufferSize = 1024;
1210 pQsOut->PagingBufferPrivateDataSize = 0; /* @todo: do we need a private buffer ? */
1211 }
1212 break;
1213 }
1214 case DXGKQAITYPE_UMDRIVERPRIVATE:
1215 drprintf((__FUNCTION__ ": we do not support DXGKQAITYPE_UMDRIVERPRIVATE\n"));
1216 AssertBreakpoint();
1217 Status = STATUS_NOT_SUPPORTED;
1218 break;
1219 default:
1220 drprintf((__FUNCTION__ ": unsupported Type (%d)\n", pQueryAdapterInfo->Type));
1221 AssertBreakpoint();
1222 Status = STATUS_NOT_SUPPORTED;
1223 break;
1224 }
1225 dfprintf(("<== "__FUNCTION__ ", context(0x%x), Status(0x%x)\n", hAdapter, Status));
1226 return Status;
1227}
1228
1229/**
1230 * DxgkDdiCreateDevice
1231 */
1232NTSTATUS APIENTRY DxgkDdiCreateDevice(
1233 CONST HANDLE hAdapter,
1234 DXGKARG_CREATEDEVICE* pCreateDevice)
1235{
1236 /* DxgkDdiCreateDevice should be made pageable. */
1237 PAGED_CODE();
1238
1239 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", hAdapter));
1240 NTSTATUS Status = STATUS_SUCCESS;
1241 PDEVICE_EXTENSION pContext = (PDEVICE_EXTENSION)hAdapter;
1242
1243 vboxVDbgBreakFv();
1244
1245 PVBOXWDDM_DEVICE pDevice = (PVBOXWDDM_DEVICE)vboxWddmMemAllocZero(sizeof (VBOXWDDM_DEVICE));
1246 pCreateDevice->hDevice = pDevice;
1247 if (pCreateDevice->Flags.SystemDevice)
1248 pDevice->enmType = VBOXWDDM_DEVICE_TYPE_SYSTEM;
1249// else
1250// {
1251// AssertBreakpoint(); /* we do not support custom contexts for now */
1252// drprintf((__FUNCTION__ ": we do not support custom devices for now, hAdapter (0x%x)\n", hAdapter));
1253// }
1254
1255 pDevice->pAdapter = pContext;
1256 pDevice->hDevice = pCreateDevice->hDevice;
1257
1258 pCreateDevice->hDevice = pDevice;
1259 pCreateDevice->pInfo = NULL;
1260
1261 dfprintf(("<== "__FUNCTION__ ", context(0x%x), Status(0x%x)\n", hAdapter, Status));
1262
1263 return Status;
1264}
1265NTSTATUS vboxWddmDestroyAllocation(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_ALLOCATION pAllocation)
1266{
1267 PAGED_CODE();
1268
1269 switch (pAllocation->enmType)
1270 {
1271 case VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE:
1272 {
1273 PVBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE pAlloc = VBOXWDDM_ALLOCATION_BODY(pAllocation, VBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE);
1274 if (pAlloc->bAssigned)
1275 {
1276 /* @todo: do we need to notify host? */
1277 vboxWddmAssignPrimary(pDevExt, &pDevExt->aSources[pAlloc->VidPnSourceId], NULL, pAlloc->VidPnSourceId);
1278 }
1279 break;
1280 }
1281 default:
1282 break;
1283 }
1284 vboxWddmMemFree(pAllocation);
1285 return STATUS_SUCCESS;
1286}
1287
1288NTSTATUS vboxWddmCreateAllocation(PDEVICE_EXTENSION pDevExt, DXGK_ALLOCATIONINFO* pAllocationInfo)
1289{
1290 PAGED_CODE();
1291
1292 NTSTATUS Status = STATUS_SUCCESS;
1293
1294 Assert(pAllocationInfo->PrivateDriverDataSize >= VBOXWDDM_ALLOCINFO_HEADSIZE());
1295 if (pAllocationInfo->PrivateDriverDataSize >= VBOXWDDM_ALLOCINFO_HEADSIZE())
1296 {
1297 PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pAllocationInfo->pPrivateDriverData;
1298 switch (pAllocInfo->enmType)
1299 {
1300 case VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE:
1301 {
1302 Assert(pAllocationInfo->PrivateDriverDataSize >= VBOXWDDM_ALLOCINFO_SIZE(VBOXWDDM_ALLOCINFO_SHAREDPRIMARYSURFACE));
1303 if (pAllocationInfo->PrivateDriverDataSize >= VBOXWDDM_ALLOCINFO_SIZE(VBOXWDDM_ALLOCINFO_SHAREDPRIMARYSURFACE))
1304 {
1305 if (pAllocInfo->u.SurfInfo.bpp != 0)
1306 {
1307 PVBOXWDDM_ALLOCATION pAllocation = (PVBOXWDDM_ALLOCATION)vboxWddmMemAllocZero(VBOXWDDM_ALLOCATION_SIZE(VBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE));
1308 Assert(pAllocation);
1309 if (pAllocation)
1310 {
1311 pAllocation->enmType = VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE;
1312 pAllocation->offVram = VBOXVIDEOOFFSET_VOID;
1313 pAllocation->u.SurfInfo = pAllocInfo->u.SurfInfo;
1314 PVBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE pAlloc = VBOXWDDM_ALLOCATION_BODY(pAllocation, VBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE);
1315 PVBOXWDDM_ALLOCINFO_SHAREDPRIMARYSURFACE pAllocI = VBOXWDDM_ALLOCINFO_BODY(pAllocInfo, VBOXWDDM_ALLOCINFO_SHAREDPRIMARYSURFACE);
1316 pAlloc->RefreshRate = pAllocI->RefreshRate;
1317 pAlloc->VidPnSourceId = pAllocI->VidPnSourceId;
1318// pAlloc->offAddress = VBOXVIDEOOFFSET_VOID;
1319 pAlloc->bVisible = FALSE;
1320
1321 pAllocationInfo->pPrivateDriverData = NULL;
1322 pAllocationInfo->PrivateDriverDataSize = 0;
1323 pAllocationInfo->Alignment = 0;
1324 pAllocationInfo->Size = pAllocInfo->u.SurfInfo.pitch * pAllocInfo->u.SurfInfo.height;
1325 pAllocationInfo->PitchAlignedSize = 0;
1326 pAllocationInfo->HintedBank.Value = 0;
1327 pAllocationInfo->PreferredSegment.Value = 0;
1328 pAllocationInfo->SupportedReadSegmentSet = 1;
1329 pAllocationInfo->SupportedWriteSegmentSet = 1;
1330 pAllocationInfo->EvictionSegmentSet = 0;
1331 pAllocationInfo->MaximumRenamingListLength = 0;
1332 pAllocationInfo->hAllocation = pAllocation;
1333 pAllocationInfo->Flags.Value = 0;
1334 pAllocationInfo->Flags.CpuVisible = 1;
1335 pAllocationInfo->pAllocationUsageHint = NULL;
1336 pAllocationInfo->AllocationPriority = D3DDDI_ALLOCATIONPRIORITY_NORMAL;
1337 }
1338 else
1339 {
1340 drprintf((__FUNCTION__ ": ERROR: failed to create allocation description\n"));
1341 Status = STATUS_NO_MEMORY;
1342 }
1343 }
1344 else
1345 {
1346 drprintf((__FUNCTION__ ": Invalid format (%d)\n", pAllocInfo->u.SurfInfo.format));
1347 Status = STATUS_INVALID_PARAMETER;
1348 }
1349 }
1350 else
1351 {
1352 drprintf((__FUNCTION__ ": ERROR: PrivateDriverDataSize(%d) less than VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE cmd size(%d)\n", pAllocationInfo->PrivateDriverDataSize, VBOXWDDM_ALLOCINFO_SIZE(VBOXWDDM_ALLOCINFO_SHAREDPRIMARYSURFACE)));
1353 Status = STATUS_INVALID_PARAMETER;
1354 }
1355 break;
1356 }
1357 case VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE:
1358 case VBOXWDDM_ALLOC_TYPE_STD_STAGINGSURFACE:
1359 {
1360 Assert(pAllocationInfo->PrivateDriverDataSize >= VBOXWDDM_ALLOCINFO_HEADSIZE());
1361 if (pAllocationInfo->PrivateDriverDataSize >= VBOXWDDM_ALLOCINFO_HEADSIZE())
1362 {
1363 PVBOXWDDM_ALLOCATION pAllocation = (PVBOXWDDM_ALLOCATION)vboxWddmMemAllocZero(VBOXWDDM_ALLOCATION_HEADSIZE());
1364 Assert(pAllocation);
1365 if (pAllocation)
1366 {
1367 pAllocation->enmType = pAllocInfo->enmType;
1368 pAllocation->offVram = VBOXVIDEOOFFSET_VOID;
1369 pAllocation->u.SurfInfo = pAllocInfo->u.SurfInfo;
1370
1371 pAllocationInfo->pPrivateDriverData = NULL;
1372 pAllocationInfo->PrivateDriverDataSize = 0;
1373 pAllocationInfo->Alignment = 0;
1374 pAllocationInfo->Size = pAllocInfo->u.SurfInfo.pitch * pAllocInfo->u.SurfInfo.height;
1375 pAllocationInfo->PitchAlignedSize = 0;
1376 pAllocationInfo->HintedBank.Value = 0;
1377 pAllocationInfo->PreferredSegment.Value = 0;
1378 pAllocationInfo->SupportedReadSegmentSet = 1;
1379 pAllocationInfo->SupportedWriteSegmentSet = 1;
1380 pAllocationInfo->EvictionSegmentSet = 0;
1381 pAllocationInfo->MaximumRenamingListLength = 0;
1382 pAllocationInfo->hAllocation = pAllocation;
1383 pAllocationInfo->Flags.Value = 0;
1384 pAllocationInfo->Flags.CpuVisible = 1;
1385 pAllocationInfo->pAllocationUsageHint = NULL;
1386 pAllocationInfo->AllocationPriority = D3DDDI_ALLOCATIONPRIORITY_NORMAL;
1387 }
1388 else
1389 {
1390 drprintf((__FUNCTION__ ": ERROR: failed to create allocation description\n"));
1391 Status = STATUS_NO_MEMORY;
1392 }
1393 }
1394 else
1395 {
1396 drprintf((__FUNCTION__ ": ERROR: PrivateDriverDataSize(%d) less than cmd size(%d)\n", pAllocationInfo->PrivateDriverDataSize, VBOXWDDM_ALLOCINFO_HEADSIZE()));
1397 Status = STATUS_INVALID_PARAMETER;
1398 }
1399 break;
1400 }
1401 default:
1402 drprintf((__FUNCTION__ ": ERROR: invalid alloc info type(%d)\n", pAllocInfo->enmType));
1403 Status = STATUS_INVALID_PARAMETER;
1404 break;
1405 }
1406 }
1407 else
1408 {
1409 drprintf((__FUNCTION__ ": ERROR: PrivateDriverDataSize(%d) less than header size(%d)\n", pAllocationInfo->PrivateDriverDataSize, VBOXWDDM_ALLOCINFO_HEADSIZE()));
1410 Status = STATUS_INVALID_PARAMETER;
1411 }
1412
1413 return Status;
1414}
1415
1416NTSTATUS APIENTRY DxgkDdiCreateAllocation(
1417 CONST HANDLE hAdapter,
1418 DXGKARG_CREATEALLOCATION* pCreateAllocation)
1419{
1420 /* DxgkDdiCreateAllocation should be made pageable. */
1421 PAGED_CODE();
1422
1423 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", hAdapter));
1424
1425 vboxVDbgBreakFv();
1426
1427 NTSTATUS Status = STATUS_SUCCESS;
1428
1429 for (UINT i = 0; i < pCreateAllocation->NumAllocations; ++i)
1430 {
1431 Status = vboxWddmCreateAllocation((PDEVICE_EXTENSION)hAdapter, &pCreateAllocation->pAllocationInfo[i]);
1432 Assert(Status == STATUS_SUCCESS);
1433 if (Status != STATUS_SUCCESS)
1434 {
1435 drprintf((__FUNCTION__ ": ERROR: vboxWddmCreateAllocation error (0x%x)\n", Status));
1436 /* note: i-th allocation is expected to be cleared in a fail handling code above */
1437 for (UINT j = 0; j < i; ++j)
1438 {
1439 vboxWddmDestroyAllocation((PDEVICE_EXTENSION)hAdapter, (PVBOXWDDM_ALLOCATION)pCreateAllocation->pAllocationInfo[j].hAllocation);
1440 }
1441 }
1442 }
1443
1444 dfprintf(("<== "__FUNCTION__ ", status(0x%x), context(0x%x)\n", Status, hAdapter));
1445
1446 return Status;
1447}
1448
1449NTSTATUS
1450APIENTRY
1451DxgkDdiDestroyAllocation(
1452 CONST HANDLE hAdapter,
1453 CONST DXGKARG_DESTROYALLOCATION* pDestroyAllocation)
1454{
1455 /* DxgkDdiDestroyAllocation should be made pageable. */
1456 PAGED_CODE();
1457
1458 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", hAdapter));
1459
1460 vboxVDbgBreakFv();
1461
1462 NTSTATUS Status = STATUS_SUCCESS;
1463
1464 for (UINT i = 0; i < pDestroyAllocation->NumAllocations; ++i)
1465 {
1466 vboxWddmDestroyAllocation((PDEVICE_EXTENSION)hAdapter, (PVBOXWDDM_ALLOCATION)pDestroyAllocation->pAllocationList[i]);
1467 }
1468
1469 dfprintf(("<== "__FUNCTION__ ", status(0x%x), context(0x%x)\n", Status, hAdapter));
1470
1471 return Status;
1472}
1473
1474/**
1475 * DxgkDdiDescribeAllocation
1476 */
1477NTSTATUS
1478APIENTRY
1479DxgkDdiDescribeAllocation(
1480 CONST HANDLE hAdapter,
1481 DXGKARG_DESCRIBEALLOCATION* pDescribeAllocation)
1482{
1483 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1484
1485 vboxVDbgBreakFv();
1486
1487 PVBOXWDDM_ALLOCATION pAllocation = (PVBOXWDDM_ALLOCATION)pDescribeAllocation->hAllocation;
1488 pDescribeAllocation->Width = pAllocation->u.SurfInfo.width;
1489 pDescribeAllocation->Height = pAllocation->u.SurfInfo.height;
1490 pDescribeAllocation->Format = pAllocation->u.SurfInfo.format;
1491 memset (&pDescribeAllocation->MultisampleMethod, 0, sizeof (pDescribeAllocation->MultisampleMethod));
1492 pDescribeAllocation->RefreshRate.Numerator = 60000;
1493 pDescribeAllocation->RefreshRate.Denominator = 1000;
1494 pDescribeAllocation->PrivateDriverFormatAttribute = 0;
1495
1496 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1497
1498 return STATUS_SUCCESS;
1499}
1500
1501/**
1502 * DxgkDdiGetStandardAllocationDriverData
1503 */
1504NTSTATUS
1505APIENTRY
1506DxgkDdiGetStandardAllocationDriverData(
1507 CONST HANDLE hAdapter,
1508 DXGKARG_GETSTANDARDALLOCATIONDRIVERDATA* pGetStandardAllocationDriverData)
1509{
1510 /* DxgkDdiGetStandardAllocationDriverData should be made pageable. */
1511 PAGED_CODE();
1512
1513 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", hAdapter));
1514
1515 vboxVDbgBreakFv();
1516
1517 NTSTATUS Status = STATUS_SUCCESS;
1518 PVBOXWDDM_ALLOCINFO pAllocInfo = NULL;
1519
1520 switch (pGetStandardAllocationDriverData->StandardAllocationType)
1521 {
1522 case D3DKMDT_STANDARDALLOCATION_SHAREDPRIMARYSURFACE:
1523 {
1524 dfprintf((__FUNCTION__ ": D3DKMDT_STANDARDALLOCATION_SHAREDPRIMARYSURFACE\n"));
1525 if(pGetStandardAllocationDriverData->pAllocationPrivateDriverData)
1526 {
1527 pAllocInfo = (PVBOXWDDM_ALLOCINFO)pGetStandardAllocationDriverData->pAllocationPrivateDriverData;
1528 pAllocInfo->enmType = VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE;
1529 pAllocInfo->u.SurfInfo.width = pGetStandardAllocationDriverData->pCreateSharedPrimarySurfaceData->Width;
1530 pAllocInfo->u.SurfInfo.height = pGetStandardAllocationDriverData->pCreateSharedPrimarySurfaceData->Height;
1531 pAllocInfo->u.SurfInfo.format = pGetStandardAllocationDriverData->pCreateSharedPrimarySurfaceData->Format;
1532 pAllocInfo->u.SurfInfo.bpp = vboxWddmCalcBitsPerPixel(pAllocInfo->u.SurfInfo.format);
1533 pAllocInfo->u.SurfInfo.pitch = vboxWddmCalcPitch(pGetStandardAllocationDriverData->pCreateSharedPrimarySurfaceData->Width, pAllocInfo->u.SurfInfo.bpp);
1534 PVBOXWDDM_ALLOCINFO_SHAREDPRIMARYSURFACE pInfo = VBOXWDDM_ALLOCINFO_BODY(pAllocInfo, VBOXWDDM_ALLOCINFO_SHAREDPRIMARYSURFACE);
1535 pInfo->RefreshRate = pGetStandardAllocationDriverData->pCreateSharedPrimarySurfaceData->RefreshRate;
1536 pInfo->VidPnSourceId = pGetStandardAllocationDriverData->pCreateSharedPrimarySurfaceData->VidPnSourceId;
1537 }
1538 pGetStandardAllocationDriverData->AllocationPrivateDriverDataSize = VBOXWDDM_ALLOCINFO_SIZE(VBOXWDDM_ALLOCINFO_SHAREDPRIMARYSURFACE);
1539
1540 pGetStandardAllocationDriverData->ResourcePrivateDriverDataSize = 0;
1541 break;
1542 }
1543 case D3DKMDT_STANDARDALLOCATION_SHADOWSURFACE:
1544 {
1545 dfprintf((__FUNCTION__ ": D3DKMDT_STANDARDALLOCATION_SHADOWSURFACE\n"));
1546 UINT bpp = vboxWddmCalcBitsPerPixel(pGetStandardAllocationDriverData->pCreateShadowSurfaceData->Format);
1547 Assert(bpp);
1548 if (bpp != 0)
1549 {
1550 UINT Pitch = vboxWddmCalcPitch(pGetStandardAllocationDriverData->pCreateShadowSurfaceData->Width, bpp);
1551 pGetStandardAllocationDriverData->pCreateShadowSurfaceData->Pitch = Pitch;
1552
1553 /* @todo: need [d/q]word align?? */
1554
1555 if (pGetStandardAllocationDriverData->pAllocationPrivateDriverData)
1556 {
1557 pAllocInfo = (PVBOXWDDM_ALLOCINFO)pGetStandardAllocationDriverData->pAllocationPrivateDriverData;
1558 pAllocInfo->enmType = VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE;
1559 pAllocInfo->u.SurfInfo.width = pGetStandardAllocationDriverData->pCreateShadowSurfaceData->Width;
1560 pAllocInfo->u.SurfInfo.height = pGetStandardAllocationDriverData->pCreateShadowSurfaceData->Height;
1561 pAllocInfo->u.SurfInfo.format = pGetStandardAllocationDriverData->pCreateShadowSurfaceData->Format;
1562 pAllocInfo->u.SurfInfo.bpp = vboxWddmCalcBitsPerPixel(pAllocInfo->u.SurfInfo.format);
1563 pAllocInfo->u.SurfInfo.pitch = vboxWddmCalcPitch(pGetStandardAllocationDriverData->pCreateShadowSurfaceData->Width, pAllocInfo->u.SurfInfo.bpp);
1564
1565 pGetStandardAllocationDriverData->pCreateShadowSurfaceData->Pitch = pAllocInfo->u.SurfInfo.pitch;
1566 }
1567 pGetStandardAllocationDriverData->AllocationPrivateDriverDataSize = VBOXWDDM_ALLOCINFO_HEADSIZE();
1568
1569 pGetStandardAllocationDriverData->ResourcePrivateDriverDataSize = 0;
1570 }
1571 else
1572 {
1573 drprintf((__FUNCTION__ ": Invalid format (%d)\n", pGetStandardAllocationDriverData->pCreateShadowSurfaceData->Format));
1574 Status = STATUS_INVALID_PARAMETER;
1575 }
1576 break;
1577 }
1578 case D3DKMDT_STANDARDALLOCATION_STAGINGSURFACE:
1579 {
1580 dfprintf((__FUNCTION__ ": D3DKMDT_STANDARDALLOCATION_STAGINGSURFACE\n"));
1581 if(pGetStandardAllocationDriverData->pAllocationPrivateDriverData)
1582 {
1583 pAllocInfo = (PVBOXWDDM_ALLOCINFO)pGetStandardAllocationDriverData->pAllocationPrivateDriverData;
1584 pAllocInfo->enmType = VBOXWDDM_ALLOC_TYPE_STD_STAGINGSURFACE;
1585 pAllocInfo->u.SurfInfo.width = pGetStandardAllocationDriverData->pCreateStagingSurfaceData->Width;
1586 pAllocInfo->u.SurfInfo.height = pGetStandardAllocationDriverData->pCreateStagingSurfaceData->Height;
1587 pAllocInfo->u.SurfInfo.format = D3DDDIFMT_X8R8G8B8; /* staging has always always D3DDDIFMT_X8R8G8B8 */
1588 pAllocInfo->u.SurfInfo.bpp = vboxWddmCalcBitsPerPixel(pAllocInfo->u.SurfInfo.format);
1589 pAllocInfo->u.SurfInfo.pitch = vboxWddmCalcPitch(pGetStandardAllocationDriverData->pCreateStagingSurfaceData->Width, pAllocInfo->u.SurfInfo.bpp);
1590
1591 pGetStandardAllocationDriverData->pCreateStagingSurfaceData->Pitch = pAllocInfo->u.SurfInfo.pitch;
1592 }
1593 pGetStandardAllocationDriverData->AllocationPrivateDriverDataSize = VBOXWDDM_ALLOCINFO_HEADSIZE();
1594
1595 pGetStandardAllocationDriverData->ResourcePrivateDriverDataSize = 0;
1596 break;
1597 }
1598//#if (DXGKDDI_INTERFACE_VERSION >= DXGKDDI_INTERFACE_VERSION_WIN7)
1599// case D3DKMDT_STANDARDALLOCATION_GDISURFACE:
1600//# error port to Win7 DDI
1601// break;
1602//#endif
1603 default:
1604 drprintf((__FUNCTION__ ": Invalid allocation type (%d)\n", pGetStandardAllocationDriverData->StandardAllocationType));
1605 Status = STATUS_INVALID_PARAMETER;
1606 break;
1607 }
1608
1609 dfprintf(("<== "__FUNCTION__ ", status(0x%x), context(0x%x)\n", Status, hAdapter));
1610
1611 return Status;
1612}
1613
1614NTSTATUS
1615APIENTRY
1616DxgkDdiAcquireSwizzlingRange(
1617 CONST HANDLE hAdapter,
1618 DXGKARG_ACQUIRESWIZZLINGRANGE* pAcquireSwizzlingRange)
1619{
1620 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1621
1622 AssertBreakpoint();
1623
1624 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1625
1626 return STATUS_SUCCESS;
1627}
1628
1629NTSTATUS
1630APIENTRY
1631DxgkDdiReleaseSwizzlingRange(
1632 CONST HANDLE hAdapter,
1633 CONST DXGKARG_RELEASESWIZZLINGRANGE* pReleaseSwizzlingRange)
1634{
1635 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1636
1637 AssertBreakpoint();
1638
1639 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1640
1641 return STATUS_SUCCESS;
1642}
1643
1644NTSTATUS
1645APIENTRY
1646DxgkDdiPatch(
1647 CONST HANDLE hAdapter,
1648 CONST DXGKARG_PATCH* pPatch)
1649{
1650 /* DxgkDdiPatch should be made pageable. */
1651 PAGED_CODE();
1652
1653 NTSTATUS Status = STATUS_SUCCESS;
1654
1655 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", hAdapter));
1656
1657 vboxVDbgBreakFv();
1658
1659 /* Value == 2 is Present
1660 * Value == 4 is RedirectedPresent
1661 * we do not expect any other flags to be set here */
1662// Assert(pPatch->Flags.Value == 2 || pPatch->Flags.Value == 4);
1663
1664 uint8_t *pBuf = ((uint8_t *)pPatch->pDmaBuffer) + pPatch->DmaBufferSubmissionStartOffset;
1665 for (UINT i = pPatch->PatchLocationListSubmissionStart; i < pPatch->PatchLocationListSubmissionLength; ++i)
1666 {
1667 const D3DDDI_PATCHLOCATIONLIST* pPatchList = &pPatch->pPatchLocationList[i];
1668 Assert(pPatchList->AllocationIndex < pPatch->AllocationListSize);
1669 const DXGK_ALLOCATIONLIST *pAllocationList = &pPatch->pAllocationList[pPatchList->AllocationIndex];
1670 if (pAllocationList->SegmentId)
1671 {
1672 Assert(pPatchList->PatchOffset < (pPatch->DmaBufferSubmissionEndOffset - pPatch->DmaBufferSubmissionStartOffset));
1673 *((VBOXVIDEOOFFSET*)(pBuf+pPatchList->PatchOffset)) = (VBOXVIDEOOFFSET)pAllocationList->PhysicalAddress.QuadPart;
1674 }
1675 else
1676 {
1677 /* sanity */
1678 if (pPatch->Flags.Value == 2 || pPatch->Flags.Value == 4)
1679 Assert(i == 0);
1680 }
1681 }
1682
1683 dfprintf(("<== "__FUNCTION__ ", context(0x%x)\n", hAdapter));
1684
1685 return Status;
1686}
1687
1688NTSTATUS
1689APIENTRY
1690DxgkDdiSubmitCommand(
1691 CONST HANDLE hAdapter,
1692 CONST DXGKARG_SUBMITCOMMAND* pSubmitCommand)
1693{
1694 /* DxgkDdiSubmitCommand runs at dispatch, should not be pageable. */
1695 NTSTATUS Status = STATUS_SUCCESS;
1696
1697 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", hAdapter));
1698
1699 vboxVDbgBreakFv();
1700
1701 PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)hAdapter;
1702
1703 Assert(!pSubmitCommand->DmaBufferSegmentId);
1704
1705 /* the DMA command buffer is located in system RAM, the host will need to pick it from there */
1706 //BufInfo.fFlags = 0; /* see VBOXVDMACBUF_FLAG_xx */
1707 Assert(pSubmitCommand->DmaBufferPrivateDataSubmissionEndOffset - pSubmitCommand->DmaBufferPrivateDataSubmissionStartOffset >= sizeof (VBOXWDDM_DMA_PRIVATE_DATA));
1708 if (pSubmitCommand->DmaBufferPrivateDataSubmissionEndOffset - pSubmitCommand->DmaBufferPrivateDataSubmissionStartOffset < sizeof (VBOXWDDM_DMA_PRIVATE_DATA))
1709 {
1710 drprintf((__FUNCTION__": DmaBufferPrivateDataSubmissionEndOffset (%d) - DmaBufferPrivateDataSubmissionStartOffset (%d) < sizeof (VBOXWDDM_DMA_PRIVATE_DATA) (%d)\n",
1711 pSubmitCommand->DmaBufferPrivateDataSubmissionEndOffset,
1712 pSubmitCommand->DmaBufferPrivateDataSubmissionStartOffset,
1713 sizeof (VBOXWDDM_DMA_PRIVATE_DATA)));
1714 return STATUS_INVALID_PARAMETER;
1715 }
1716
1717 PVBOXWDDM_DMA_PRIVATE_DATA pPrivateData = (PVBOXWDDM_DMA_PRIVATE_DATA)((uint8_t*)pSubmitCommand->pDmaBufferPrivateData + pSubmitCommand->DmaBufferPrivateDataSubmissionStartOffset);
1718 Assert(pPrivateData);
1719 PVBOXVDMACBUF_DR pDr = vboxVdmaCBufDrCreate (&pDevExt->u.primary.Vdma, 0);
1720 if (!pDr)
1721 {
1722 /* @todo: try flushing.. */
1723 drprintf((__FUNCTION__": vboxVdmaCBufDrCreate returned NULL\n"));
1724 return STATUS_INSUFFICIENT_RESOURCES;
1725 }
1726 // vboxVdmaCBufDrCreate zero initializes the pDr
1727 //pDr->fFlags = 0;
1728 pDr->cbBuf = pSubmitCommand->DmaBufferSubmissionEndOffset - pSubmitCommand->DmaBufferSubmissionStartOffset;
1729 pDr->u32FenceId = pSubmitCommand->SubmissionFenceId;
1730 pDr->rc = VERR_NOT_IMPLEMENTED;
1731 if (pPrivateData)
1732 pDr->u64GuestContext = (uint64_t)pPrivateData->pContext;
1733// else // vboxVdmaCBufDrCreate zero initializes the pDr
1734// pDr->u64GuestContext = NULL;
1735 pDr->Location.phBuf = pSubmitCommand->DmaBufferPhysicalAddress.QuadPart + pSubmitCommand->DmaBufferSubmissionStartOffset;
1736
1737 vboxVdmaCBufDrSubmit (pDevExt, &pDevExt->u.primary.Vdma, pDr);
1738
1739 dfprintf(("<== "__FUNCTION__ ", context(0x%x)\n", hAdapter));
1740
1741 return Status;
1742}
1743
1744NTSTATUS
1745APIENTRY
1746DxgkDdiPreemptCommand(
1747 CONST HANDLE hAdapter,
1748 CONST DXGKARG_PREEMPTCOMMAND* pPreemptCommand)
1749{
1750 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1751
1752 AssertBreakpoint();
1753 /* @todo: fixme: implement */
1754
1755 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1756
1757 return STATUS_SUCCESS;
1758}
1759
1760/*
1761 * DxgkDdiBuildPagingBuffer
1762 */
1763NTSTATUS
1764APIENTRY
1765DxgkDdiBuildPagingBuffer(
1766 CONST HANDLE hAdapter,
1767 DXGKARG_BUILDPAGINGBUFFER* pBuildPagingBuffer)
1768{
1769 /* DxgkDdiBuildPagingBuffer should be made pageable. */
1770 PAGED_CODE();
1771
1772 vboxVDbgBreakFv();
1773
1774 NTSTATUS Status = STATUS_SUCCESS;
1775
1776 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", hAdapter));
1777
1778 /* @todo: */
1779 switch (pBuildPagingBuffer->Operation)
1780 {
1781 case DXGK_OPERATION_TRANSFER:
1782 {
1783// pBuildPagingBuffer->pDmaBuffer = (uint8_t*)pBuildPagingBuffer->pDmaBuffer + VBOXVDMACMD_SIZE(VBOXVDMACMD_DMA_BPB_TRANSFER);
1784 break;
1785 }
1786 case DXGK_OPERATION_FILL:
1787 {
1788// pBuildPagingBuffer->pDmaBuffer = (uint8_t*)pBuildPagingBuffer->pDmaBuffer + VBOXVDMACMD_SIZE(VBOXVDMACMD_DMA_BPB_FILL);
1789 break;
1790 }
1791 case DXGK_OPERATION_DISCARD_CONTENT:
1792 {
1793 AssertBreakpoint();
1794 break;
1795 }
1796 default:
1797 {
1798 drprintf((__FUNCTION__": unsupported op (%d)\n", pBuildPagingBuffer->Operation));
1799 AssertBreakpoint();
1800 break;
1801 }
1802 }
1803
1804 dfprintf(("<== "__FUNCTION__ ", context(0x%x)\n", hAdapter));
1805
1806 return Status;
1807
1808}
1809
1810NTSTATUS
1811APIENTRY
1812DxgkDdiSetPalette(
1813 CONST HANDLE hAdapter,
1814 CONST DXGKARG_SETPALETTE* pSetPalette
1815 )
1816{
1817 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1818
1819 AssertBreakpoint();
1820 /* @todo: fixme: implement */
1821
1822 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1823
1824 return STATUS_SUCCESS;
1825}
1826
1827NTSTATUS
1828APIENTRY
1829DxgkDdiSetPointerPosition(
1830 CONST HANDLE hAdapter,
1831 CONST DXGKARG_SETPOINTERPOSITION* pSetPointerPosition)
1832{
1833 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1834
1835 AssertBreakpoint();
1836 /* @todo: fixme: implement */
1837
1838 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1839
1840 return STATUS_SUCCESS;
1841}
1842
1843NTSTATUS
1844APIENTRY
1845DxgkDdiSetPointerShape(
1846 CONST HANDLE hAdapter,
1847 CONST DXGKARG_SETPOINTERSHAPE* pSetPointerShape)
1848{
1849 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1850
1851 AssertBreakpoint();
1852 /* @todo: fixme: implement */
1853
1854 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1855
1856 return STATUS_SUCCESS;
1857}
1858
1859NTSTATUS
1860APIENTRY CALLBACK
1861DxgkDdiResetFromTimeout(
1862 CONST HANDLE hAdapter)
1863{
1864 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1865
1866 AssertBreakpoint();
1867 /* @todo: fixme: implement */
1868
1869 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1870
1871 return STATUS_SUCCESS;
1872}
1873
1874NTSTATUS
1875APIENTRY
1876DxgkDdiEscape(
1877 CONST HANDLE hAdapter,
1878 CONST DXGKARG_ESCAPE* pEscape)
1879{
1880 PAGED_CODE();
1881
1882 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1883
1884 AssertBreakpoint();
1885
1886 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1887
1888 return STATUS_INVALID_PARAMETER;
1889}
1890
1891NTSTATUS
1892APIENTRY
1893DxgkDdiCollectDbgInfo(
1894 CONST HANDLE hAdapter,
1895 CONST DXGKARG_COLLECTDBGINFO* pCollectDbgInfo
1896 )
1897{
1898 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1899
1900 AssertBreakpoint();
1901
1902 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1903
1904 return STATUS_SUCCESS;
1905}
1906
1907NTSTATUS
1908APIENTRY
1909DxgkDdiQueryCurrentFence(
1910 CONST HANDLE hAdapter,
1911 DXGKARG_QUERYCURRENTFENCE* pCurrentFence)
1912{
1913 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1914
1915 AssertBreakpoint();
1916 /* @todo: fixme: implement */
1917
1918 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
1919
1920 return STATUS_SUCCESS;
1921}
1922
1923NTSTATUS
1924APIENTRY
1925DxgkDdiIsSupportedVidPn(
1926 CONST HANDLE hAdapter,
1927 OUT DXGKARG_ISSUPPORTEDVIDPN* pIsSupportedVidPnArg
1928 )
1929{
1930 /* The DxgkDdiIsSupportedVidPn should be made pageable. */
1931 PAGED_CODE();
1932
1933// dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", hAdapter));
1934
1935 vboxVDbgBreakFv();
1936
1937 PDEVICE_EXTENSION pContext = (PDEVICE_EXTENSION)hAdapter;
1938 BOOLEAN bSupported = TRUE;
1939 const DXGK_VIDPN_INTERFACE* pVidPnInterface = NULL;
1940 NTSTATUS Status = pContext->u.primary.DxgkInterface.DxgkCbQueryVidPnInterface(pIsSupportedVidPnArg->hDesiredVidPn, DXGK_VIDPN_INTERFACE_VERSION_V1, &pVidPnInterface);
1941 if (Status == STATUS_SUCCESS)
1942 {
1943 D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology;
1944 const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface;
1945 Status = pVidPnInterface->pfnGetTopology(pIsSupportedVidPnArg->hDesiredVidPn, &hVidPnTopology, &pVidPnTopologyInterface);
1946 if (Status == STATUS_SUCCESS)
1947 {
1948 Status = vboxVidPnCheckTopology(pIsSupportedVidPnArg->hDesiredVidPn, hVidPnTopology, pVidPnTopologyInterface, &bSupported);
1949 if (Status == STATUS_SUCCESS && bSupported)
1950 {
1951 for (UINT id = 0; id < pContext->cSources; ++id)
1952 {
1953 D3DKMDT_HVIDPNSOURCEMODESET hNewVidPnSourceModeSet;
1954 const DXGK_VIDPNSOURCEMODESET_INTERFACE *pVidPnSourceModeSetInterface;
1955 Status = pVidPnInterface->pfnAcquireSourceModeSet(pIsSupportedVidPnArg->hDesiredVidPn,
1956 id,
1957 &hNewVidPnSourceModeSet,
1958 &pVidPnSourceModeSetInterface);
1959 if (Status == STATUS_SUCCESS)
1960 {
1961 Status = vboxVidPnCheckSourceModeSet(pIsSupportedVidPnArg->hDesiredVidPn, hNewVidPnSourceModeSet, pVidPnSourceModeSetInterface, &bSupported);
1962
1963 pVidPnInterface->pfnReleaseSourceModeSet(pIsSupportedVidPnArg->hDesiredVidPn, hNewVidPnSourceModeSet);
1964
1965 if (Status != STATUS_SUCCESS || !bSupported)
1966 break;
1967 }
1968 else if (Status == STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE)
1969 {
1970 drprintf(("VBoxVideoWddm: Warning: pfnAcquireSourceModeSet returned STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE, continuing\n"));
1971 Status = STATUS_SUCCESS;
1972 }
1973 else
1974 {
1975 drprintf(("VBoxVideoWddm: pfnAcquireSourceModeSet failed Status(0x%x)\n"));
1976 break;
1977 }
1978 }
1979
1980 if (Status == STATUS_SUCCESS && bSupported)
1981 {
1982 for (UINT id = 0; id < pContext->cSources; ++id)
1983 {
1984 D3DKMDT_HVIDPNTARGETMODESET hNewVidPnTargetModeSet;
1985 CONST DXGK_VIDPNTARGETMODESET_INTERFACE *pVidPnTargetModeSetInterface;
1986 Status = pVidPnInterface->pfnAcquireTargetModeSet(pIsSupportedVidPnArg->hDesiredVidPn,
1987 id, /*__in CONST D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId */
1988 &hNewVidPnTargetModeSet,
1989 &pVidPnTargetModeSetInterface);
1990 if (Status == STATUS_SUCCESS)
1991 {
1992 Status = vboxVidPnCheckTargetModeSet(pIsSupportedVidPnArg->hDesiredVidPn, hNewVidPnTargetModeSet, pVidPnTargetModeSetInterface, &bSupported);
1993
1994 pVidPnInterface->pfnReleaseTargetModeSet(pIsSupportedVidPnArg->hDesiredVidPn, hNewVidPnTargetModeSet);
1995
1996 if (Status != STATUS_SUCCESS || !bSupported)
1997 break;
1998 }
1999 else if (Status == STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE)
2000 {
2001 drprintf(("VBoxVideoWddm: Warning: pfnAcquireSourceModeSet returned STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE, continuing\n"));
2002 Status = STATUS_SUCCESS;
2003 }
2004 else
2005 {
2006 drprintf(("VBoxVideoWddm: pfnAcquireSourceModeSet failed Status(0x%x)\n"));
2007 break;
2008 }
2009 }
2010 }
2011 }
2012 }
2013 else
2014 {
2015 drprintf(("VBoxVideoWddm: pfnGetTopology failed Status(0x%x)\n"));
2016 }
2017 }
2018 else
2019 {
2020 drprintf(("VBoxVideoWddm: DxgkCbQueryVidPnInterface failed Status(0x%x)\n"));
2021 }
2022 pIsSupportedVidPnArg->IsVidPnSupported = bSupported;
2023
2024// dfprintf(("<== "__FUNCTION__ ", status(0x%x), context(0x%x)\n", Status, hAdapter));
2025
2026 return Status;
2027}
2028
2029NTSTATUS
2030APIENTRY
2031DxgkDdiRecommendFunctionalVidPn(
2032 CONST HANDLE hAdapter,
2033 CONST DXGKARG_RECOMMENDFUNCTIONALVIDPN* CONST pRecommendFunctionalVidPnArg
2034 )
2035{
2036 /* The DxgkDdiRecommendFunctionalVidPn should be made pageable. */
2037 PAGED_CODE();
2038
2039 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", hAdapter));
2040
2041 vboxVDbgBreakF();
2042
2043 PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)hAdapter;
2044 NTSTATUS Status;
2045 uint32_t cModes;
2046 uint32_t iPreferredMode;
2047 VIDEO_MODE_INFORMATION *pModes;
2048 uint32_t cResolutions;
2049 D3DKMDT_2DREGION *pResolutions;
2050 VBoxWddmGetModesTable(pDevExt, /* PDEVICE_EXTENSION DeviceExtension */
2051 false, /* bool bRebuildTable*/
2052 &pModes, /* VIDEO_MODE_INFORMATION ** ppModes*/
2053 &cModes, /* uint32_t * pcModes */
2054 &iPreferredMode, /* uint32_t * pPreferrableMode*/
2055 &pResolutions, /* D3DKMDT_2DREGION **ppResolutions */
2056 &cResolutions /* uint32_t * pcResolutions */);
2057
2058
2059 const DXGK_VIDPN_INTERFACE* pVidPnInterface = NULL;
2060 Status = pDevExt->u.primary.DxgkInterface.DxgkCbQueryVidPnInterface(pRecommendFunctionalVidPnArg->hRecommendedFunctionalVidPn, DXGK_VIDPN_INTERFACE_VERSION_V1, &pVidPnInterface);
2061 Assert(Status == STATUS_SUCCESS);
2062 if (Status == STATUS_SUCCESS)
2063 {
2064 D3DKMDT_2DREGION PrefRegion;
2065 PrefRegion.cx = pModes[iPreferredMode].VisScreenHeight;
2066 PrefRegion.cy = pModes[iPreferredMode].VisScreenWidth;
2067 Status = vboxVidPnCreatePopulateVidPnFromLegacy(pDevExt, pRecommendFunctionalVidPnArg->hRecommendedFunctionalVidPn, pVidPnInterface,
2068#if 0
2069 pModes, cModes, iPreferredMode,
2070 pResolutions, cResolutions
2071#else
2072 &pModes[iPreferredMode], 1, 0,
2073 &PrefRegion, 1
2074#endif
2075 );
2076 Assert(Status == STATUS_SUCCESS);
2077 if (Status != STATUS_SUCCESS)
2078 drprintf((__FUNCTION__": vboxVidPnCreatePopulateVidPnFromLegacy failed Status(0x%x)\n", Status));
2079 }
2080 else
2081 drprintf((__FUNCTION__": DxgkCbQueryVidPnInterface failed Status(0x%x)\n", Status));
2082
2083 dfprintf(("<== "__FUNCTION__ ", status(0x%x), context(0x%x)\n", Status, hAdapter));
2084
2085 return Status;
2086}
2087
2088NTSTATUS
2089APIENTRY
2090DxgkDdiEnumVidPnCofuncModality(
2091 CONST HANDLE hAdapter,
2092 CONST DXGKARG_ENUMVIDPNCOFUNCMODALITY* CONST pEnumCofuncModalityArg
2093 )
2094{
2095 /* The DxgkDdiEnumVidPnCofuncModality function should be made pageable. */
2096 PAGED_CODE();
2097
2098// dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", hAdapter));
2099
2100 vboxVDbgBreakFv();
2101
2102 PDEVICE_EXTENSION pContext = (PDEVICE_EXTENSION)hAdapter;
2103 const DXGK_VIDPN_INTERFACE* pVidPnInterface = NULL;
2104 NTSTATUS Status = pContext->u.primary.DxgkInterface.DxgkCbQueryVidPnInterface(pEnumCofuncModalityArg->hConstrainingVidPn, DXGK_VIDPN_INTERFACE_VERSION_V1, &pVidPnInterface);
2105 if (Status == STATUS_SUCCESS)
2106 {
2107 D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology;
2108 const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface;
2109 NTSTATUS Status = pVidPnInterface->pfnGetTopology(pEnumCofuncModalityArg->hConstrainingVidPn, &hVidPnTopology, &pVidPnTopologyInterface);
2110 Assert(Status == STATUS_SUCCESS);
2111 if (Status == STATUS_SUCCESS)
2112 {
2113 VBOXVIDPNCOFUNCMODALITY CbContext = {0};
2114 CbContext.pEnumCofuncModalityArg = pEnumCofuncModalityArg;
2115 VBoxWddmGetModesTable(pContext, /* PDEVICE_EXTENSION DeviceExtension */
2116 false, /* bool bRebuildTable*/
2117 &CbContext.pModes, /* VIDEO_MODE_INFORMATION ** ppModes*/
2118 &CbContext.cModes, /* uint32_t * pcModes */
2119 &CbContext.iPreferredMode, /* uint32_t * pPreferrableMode*/
2120 &CbContext.pResolutions, /* D3DKMDT_2DREGION **ppResolutions */
2121 &CbContext.cResolutions /* uint32_t * pcResolutions */);
2122 Assert(CbContext.cModes);
2123 Assert(CbContext.cModes > CbContext.iPreferredMode);
2124 Status = vboxVidPnEnumPaths(pContext, pEnumCofuncModalityArg->hConstrainingVidPn, pVidPnInterface,
2125 hVidPnTopology, pVidPnTopologyInterface,
2126 vboxVidPnCofuncModalityPathEnum, &CbContext);
2127 Assert(Status == STATUS_SUCCESS);
2128 if (Status == STATUS_SUCCESS)
2129 {
2130 Status = CbContext.Status;
2131 Assert(Status == STATUS_SUCCESS);
2132 if (Status != STATUS_SUCCESS)
2133 drprintf((__FUNCTION__ ": vboxVidPnAdjustSourcesTargetsCallback failed Status(0x%x)\n", Status));
2134 }
2135 else
2136 drprintf((__FUNCTION__ ": vboxVidPnEnumPaths failed Status(0x%x)\n", Status));
2137 }
2138 else
2139 drprintf((__FUNCTION__ ": pfnGetTopology failed Status(0x%x)\n", Status));
2140 }
2141 else
2142 drprintf((__FUNCTION__ ": DxgkCbQueryVidPnInterface failed Status(0x%x)\n", Status));
2143
2144// dfprintf(("<== "__FUNCTION__ ", status(0x%x), context(0x%x)\n", Status, hAdapter));
2145
2146 return Status;
2147}
2148
2149NTSTATUS
2150APIENTRY
2151DxgkDdiSetVidPnSourceAddress(
2152 CONST HANDLE hAdapter,
2153 CONST DXGKARG_SETVIDPNSOURCEADDRESS* pSetVidPnSourceAddress
2154 )
2155{
2156 /* The DxgkDdiSetVidPnSourceAddress function should be made pageable. */
2157 PAGED_CODE();
2158
2159 vboxVDbgBreakFv();
2160
2161 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", hAdapter));
2162
2163 NTSTATUS Status = STATUS_SUCCESS;
2164 PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)hAdapter;
2165 Assert(pDevExt->cSources > pSetVidPnSourceAddress->VidPnSourceId);
2166 if (pDevExt->cSources > pSetVidPnSourceAddress->VidPnSourceId)
2167 {
2168 PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[pSetVidPnSourceAddress->VidPnSourceId];
2169 PVBOXWDDM_ALLOCATION pAllocation;
2170 Assert(pSetVidPnSourceAddress->hAllocation);
2171 Assert(pSetVidPnSourceAddress->hAllocation || pSource->pAllocation);
2172 Assert (pSetVidPnSourceAddress->Flags.Value < 2); /* i.e. 0 or 1 (ModeChange) */
2173 if (pSetVidPnSourceAddress->hAllocation)
2174 {
2175 pAllocation = (PVBOXWDDM_ALLOCATION)pSetVidPnSourceAddress->hAllocation;
2176 vboxWddmAssignPrimary(pDevExt, pSource, pAllocation, pSetVidPnSourceAddress->VidPnSourceId);
2177 }
2178 else
2179 pAllocation = pSource->pAllocation;
2180
2181 Assert(pAllocation);
2182 if (pAllocation)
2183 {
2184 Assert(pAllocation->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE);
2185 PVBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE pPrimary = VBOXWDDM_ALLOCATION_BODY(pAllocation, VBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE);
2186 pAllocation->offVram = (VBOXVIDEOOFFSET)pSetVidPnSourceAddress->PrimaryAddress.QuadPart;
2187 pAllocation->SegmentId = pSetVidPnSourceAddress->PrimarySegment;
2188 Assert (pAllocation->SegmentId);
2189 Assert (!pPrimary->bVisible);
2190 if (pPrimary->bVisible)
2191 {
2192 /* should not generally happen, but still inform host*/
2193 Status = vboxWddmGhDisplaySetInfo(pDevExt, pSource);
2194 Assert(Status == STATUS_SUCCESS);
2195 if (Status != STATUS_SUCCESS)
2196 drprintf((__FUNCTION__": vboxWddmGhDisplaySetInfo failed, Status (0x%x)\n", Status));
2197 }
2198 }
2199 else
2200 {
2201 drprintf((__FUNCTION__": no allocation data available!!\n"));
2202 Status = STATUS_INVALID_PARAMETER;
2203 }
2204 }
2205 else
2206 {
2207 drprintf((__FUNCTION__": invalid VidPnSourceId (%d), should be smaller than (%d)\n", pSetVidPnSourceAddress->VidPnSourceId, pDevExt->cSources));
2208 Status = STATUS_INVALID_PARAMETER;
2209 }
2210
2211 dfprintf(("<== "__FUNCTION__ ", status(0x%x), context(0x%x)\n", Status, hAdapter));
2212
2213 return Status;
2214}
2215
2216NTSTATUS
2217APIENTRY
2218DxgkDdiSetVidPnSourceVisibility(
2219 CONST HANDLE hAdapter,
2220 CONST DXGKARG_SETVIDPNSOURCEVISIBILITY* pSetVidPnSourceVisibility
2221 )
2222{
2223 /* DxgkDdiSetVidPnSourceVisibility should be made pageable. */
2224 PAGED_CODE();
2225
2226 vboxVDbgBreakFv();
2227
2228 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", hAdapter));
2229
2230 NTSTATUS Status = STATUS_SUCCESS;
2231 PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)hAdapter;
2232 Assert(pDevExt->cSources > pSetVidPnSourceVisibility->VidPnSourceId);
2233 if (pDevExt->cSources > pSetVidPnSourceVisibility->VidPnSourceId)
2234 {
2235 PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[pSetVidPnSourceVisibility->VidPnSourceId];
2236 PVBOXWDDM_ALLOCATION pAllocation = pSource->pAllocation;
2237 PVBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE pPrimary = VBOXWDDM_ALLOCATION_BODY(pAllocation, VBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE);
2238
2239 Assert(pPrimary->bVisible != pSetVidPnSourceVisibility->Visible);
2240 if (pPrimary->bVisible != pSetVidPnSourceVisibility->Visible)
2241 {
2242 pPrimary->bVisible = pSetVidPnSourceVisibility->Visible;
2243 if (pPrimary->bVisible)
2244 {
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 else
2251 {
2252 vboxVdmaFlush (pDevExt, &pDevExt->u.primary.Vdma);
2253 }
2254 }
2255 }
2256 else
2257 {
2258 drprintf((__FUNCTION__": invalid VidPnSourceId (%d), should be smaller than (%d)\n", pSetVidPnSourceVisibility->VidPnSourceId, pDevExt->cSources));
2259 Status = STATUS_INVALID_PARAMETER;
2260 }
2261
2262 dfprintf(("<== "__FUNCTION__ ", status(0x%x), context(0x%x)\n", Status, hAdapter));
2263
2264 return Status;
2265}
2266
2267NTSTATUS
2268APIENTRY
2269DxgkDdiCommitVidPn(
2270 CONST HANDLE hAdapter,
2271 CONST DXGKARG_COMMITVIDPN* CONST pCommitVidPnArg
2272 )
2273{
2274 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", hAdapter));
2275
2276 PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)hAdapter;
2277
2278 vboxVDbgBreakFv();
2279
2280 const DXGK_VIDPN_INTERFACE* pVidPnInterface = NULL;
2281 NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbQueryVidPnInterface(pCommitVidPnArg->hFunctionalVidPn, DXGK_VIDPN_INTERFACE_VERSION_V1, &pVidPnInterface);
2282 if (Status == STATUS_SUCCESS)
2283 {
2284 if (pCommitVidPnArg->AffectedVidPnSourceId != D3DDDI_ID_ALL)
2285 {
2286 Status = vboxVidPnCommitSourceModeForSrcId(
2287 pDevExt,
2288 pCommitVidPnArg->hFunctionalVidPn, pVidPnInterface,
2289 pCommitVidPnArg->AffectedVidPnSourceId, (PVBOXWDDM_ALLOCATION)pCommitVidPnArg->hPrimaryAllocation);
2290 Assert(Status == STATUS_SUCCESS);
2291 if (Status != STATUS_SUCCESS)
2292 drprintf((__FUNCTION__ ": vboxVidPnCommitSourceModeForSrcId failed Status(0x%x)\n", Status));
2293 }
2294 else
2295 {
2296 /* clear all current primaries */
2297 for (UINT i = 0; i < pDevExt->cSources; ++i)
2298 {
2299 vboxWddmAssignPrimary(pDevExt, &pDevExt->aSources[i], NULL, i);
2300 }
2301
2302 D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology;
2303 const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface;
2304 NTSTATUS Status = pVidPnInterface->pfnGetTopology(pCommitVidPnArg->hFunctionalVidPn, &hVidPnTopology, &pVidPnTopologyInterface);
2305 Assert(Status == STATUS_SUCCESS);
2306 if (Status == STATUS_SUCCESS)
2307 {
2308 VBOXVIDPNCOMMIT CbContext = {0};
2309 CbContext.pCommitVidPnArg = pCommitVidPnArg;
2310 Status = vboxVidPnEnumPaths(pDevExt, pCommitVidPnArg->hFunctionalVidPn, pVidPnInterface,
2311 hVidPnTopology, pVidPnTopologyInterface,
2312 vboxVidPnCommitPathEnum, &CbContext);
2313 Assert(Status == STATUS_SUCCESS);
2314 if (Status == STATUS_SUCCESS)
2315 {
2316 Status = CbContext.Status;
2317 Assert(Status == STATUS_SUCCESS);
2318 if (Status != STATUS_SUCCESS)
2319 drprintf((__FUNCTION__ ": vboxVidPnCommitPathEnum failed Status(0x%x)\n", Status));
2320 }
2321 else
2322 drprintf((__FUNCTION__ ": vboxVidPnEnumPaths failed Status(0x%x)\n", Status));
2323 }
2324 else
2325 drprintf((__FUNCTION__ ": pfnGetTopology failed Status(0x%x)\n", Status));
2326 }
2327 }
2328 else
2329 drprintf((__FUNCTION__ ": DxgkCbQueryVidPnInterface failed Status(0x%x)\n", Status));
2330
2331 dfprintf(("<== "__FUNCTION__ ", status(0x%x), context(0x%x)\n", Status, hAdapter));
2332
2333 return Status;
2334}
2335
2336NTSTATUS
2337APIENTRY
2338DxgkDdiUpdateActiveVidPnPresentPath(
2339 CONST HANDLE hAdapter,
2340 CONST DXGKARG_UPDATEACTIVEVIDPNPRESENTPATH* CONST pUpdateActiveVidPnPresentPathArg
2341 )
2342{
2343 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2344
2345 AssertBreakpoint();
2346
2347 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2348
2349 return STATUS_SUCCESS;
2350}
2351
2352NTSTATUS
2353APIENTRY
2354DxgkDdiRecommendMonitorModes(
2355 CONST HANDLE hAdapter,
2356 CONST DXGKARG_RECOMMENDMONITORMODES* CONST pRecommendMonitorModesArg
2357 )
2358{
2359 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2360
2361 vboxVDbgBreakFv();
2362
2363 PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)hAdapter;
2364 NTSTATUS Status;
2365 uint32_t cModes;
2366 uint32_t iPreferredMode;
2367 VIDEO_MODE_INFORMATION *pModes;
2368 uint32_t cResolutions;
2369 D3DKMDT_2DREGION *pResolutions;
2370 VBoxWddmGetModesTable(pDevExt, /* PDEVICE_EXTENSION DeviceExtension */
2371 false, /* bool bRebuildTable*/
2372 &pModes, /* VIDEO_MODE_INFORMATION ** ppModes*/
2373 &cModes, /* uint32_t * pcModes */
2374 &iPreferredMode, /* uint32_t * pPreferrableMode*/
2375 &pResolutions, /* D3DKMDT_2DREGION **ppResolutions */
2376 &cResolutions /* uint32_t * pcResolutions */);
2377
2378 for (uint32_t i = 0; i < cResolutions; i++)
2379 {
2380 D3DKMDT_MONITOR_SOURCE_MODE * pNewMonitorSourceModeInfo;
2381 Status = pRecommendMonitorModesArg->pMonitorSourceModeSetInterface->pfnCreateNewModeInfo(
2382 pRecommendMonitorModesArg->hMonitorSourceModeSet, &pNewMonitorSourceModeInfo);
2383 Assert(Status == STATUS_SUCCESS);
2384 if (Status == STATUS_SUCCESS)
2385 {
2386 Status = vboxVidPnPopulateMonitorSourceModeInfoFromLegacy(pDevExt,
2387 pNewMonitorSourceModeInfo,
2388 &pResolutions[i],
2389 D3DKMDT_MCO_DRIVER,
2390 true);
2391 Assert(Status == STATUS_SUCCESS);
2392 if (Status == STATUS_SUCCESS)
2393 {
2394 Status = pRecommendMonitorModesArg->pMonitorSourceModeSetInterface->pfnAddMode(
2395 pRecommendMonitorModesArg->hMonitorSourceModeSet, pNewMonitorSourceModeInfo);
2396 Assert(Status == STATUS_SUCCESS);
2397 if (Status == STATUS_SUCCESS)
2398 continue;
2399 }
2400
2401 /* error has occured, release & break */
2402 pRecommendMonitorModesArg->pMonitorSourceModeSetInterface->pfnReleaseModeInfo(
2403 pRecommendMonitorModesArg->hMonitorSourceModeSet, pNewMonitorSourceModeInfo);
2404 break;
2405 }
2406 }
2407
2408 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2409
2410 return Status;
2411}
2412
2413NTSTATUS
2414APIENTRY
2415DxgkDdiRecommendVidPnTopology(
2416 CONST HANDLE hAdapter,
2417 CONST DXGKARG_RECOMMENDVIDPNTOPOLOGY* CONST pRecommendVidPnTopologyArg
2418 )
2419{
2420 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2421
2422 vboxVDbgBreakFv();
2423
2424 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2425
2426 return STATUS_GRAPHICS_NO_RECOMMENDED_VIDPN_TOPOLOGY;
2427}
2428
2429NTSTATUS
2430APIENTRY
2431DxgkDdiGetScanLine(
2432 CONST HANDLE hAdapter,
2433 DXGKARG_GETSCANLINE* pGetScanLine)
2434{
2435 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2436
2437 AssertBreakpoint();
2438
2439 pGetScanLine->InVerticalBlank = FALSE;
2440 pGetScanLine->ScanLine = 0;
2441
2442 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2443
2444 return STATUS_SUCCESS;
2445}
2446
2447NTSTATUS
2448APIENTRY
2449DxgkDdiStopCapture(
2450 CONST HANDLE hAdapter,
2451 CONST DXGKARG_STOPCAPTURE* pStopCapture)
2452{
2453 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2454
2455 AssertBreakpoint();
2456
2457 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2458
2459 return STATUS_SUCCESS;
2460}
2461
2462NTSTATUS
2463APIENTRY
2464DxgkDdiControlInterrupt(
2465 CONST HANDLE hAdapter,
2466 CONST DXGK_INTERRUPT_TYPE InterruptType,
2467 BOOLEAN Enable
2468 )
2469{
2470 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2471
2472 AssertBreakpoint();
2473
2474 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2475
2476 /* @todo: STATUS_NOT_IMPLEMENTED ?? */
2477 return STATUS_SUCCESS;
2478}
2479
2480NTSTATUS
2481APIENTRY
2482DxgkDdiCreateOverlay(
2483 CONST HANDLE hAdapter,
2484 DXGKARG_CREATEOVERLAY *pCreateOverlay)
2485{
2486 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2487
2488 AssertBreakpoint();
2489
2490 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2491
2492 return STATUS_NOT_IMPLEMENTED;
2493}
2494
2495NTSTATUS
2496APIENTRY
2497DxgkDdiDestroyDevice(
2498 CONST HANDLE hDevice)
2499{
2500 /* DxgkDdiDestroyDevice should be made pageable. */
2501 PAGED_CODE();
2502
2503 dfprintf(("==> "__FUNCTION__ ", hDevice(0x%x)\n", hDevice));
2504
2505 vboxVDbgBreakFv();
2506
2507 vboxWddmMemFree(hDevice);
2508
2509 dfprintf(("<== "__FUNCTION__ ", \n"));
2510
2511 return STATUS_SUCCESS;
2512}
2513
2514/*
2515 * DxgkDdiOpenAllocation
2516 */
2517NTSTATUS
2518APIENTRY
2519DxgkDdiOpenAllocation(
2520 CONST HANDLE hDevice,
2521 CONST DXGKARG_OPENALLOCATION *pOpenAllocation)
2522{
2523 /* DxgkDdiOpenAllocation should be made pageable. */
2524 PAGED_CODE();
2525
2526 dfprintf(("==> "__FUNCTION__ ", hDevice(0x%x)\n", hDevice));
2527
2528 vboxVDbgBreakFv();
2529
2530 NTSTATUS Status = STATUS_SUCCESS;
2531
2532 for (UINT i = 0; i < pOpenAllocation->NumAllocations; ++i)
2533 {
2534 DXGK_OPENALLOCATIONINFO* pInfo = &pOpenAllocation->pOpenAllocation[i];
2535 PVBOXWDDM_OPENALLOCATION pOa = (PVBOXWDDM_OPENALLOCATION)vboxWddmMemAllocZero(sizeof (VBOXWDDM_OPENALLOCATION));
2536 pOa->hAllocation = pInfo->hAllocation;
2537 pInfo->hDeviceSpecificAllocation = pOa;
2538 }
2539
2540 dfprintf(("<== "__FUNCTION__ ", hDevice(0x%x)\n", hDevice));
2541
2542 return Status;
2543}
2544
2545NTSTATUS
2546APIENTRY
2547DxgkDdiCloseAllocation(
2548 CONST HANDLE hDevice,
2549 CONST DXGKARG_CLOSEALLOCATION* pCloseAllocation)
2550{
2551 /* DxgkDdiCloseAllocation should be made pageable. */
2552 PAGED_CODE();
2553
2554 dfprintf(("==> "__FUNCTION__ ", hDevice(0x%x)\n", hDevice));
2555
2556 vboxVDbgBreakFv();
2557
2558 for (UINT i = 0; i < pCloseAllocation->NumAllocations; ++i)
2559 {
2560 vboxWddmMemFree(pCloseAllocation->pOpenHandleList[i]);
2561 }
2562
2563 dfprintf(("<== "__FUNCTION__ ", hDevice(0x%x)\n", hDevice));
2564
2565 return STATUS_SUCCESS;
2566}
2567
2568NTSTATUS
2569APIENTRY
2570DxgkDdiRender(
2571 CONST HANDLE hContext,
2572 DXGKARG_RENDER *pRender)
2573{
2574 drprintf(("==> "__FUNCTION__ ", !!NOT_IMPLEMENTED!! hContext(0x%x)\n", hContext));
2575
2576 AssertBreakpoint();
2577
2578 drprintf(("<== "__FUNCTION__ ", !!NOT_IMPLEMENTED!! hContext(0x%x)\n", hContext));
2579
2580 return STATUS_NOT_IMPLEMENTED;
2581}
2582
2583#define VBOXVDMACMD_DMA_PRESENT_BLT_MINSIZE() (VBOXVDMACMD_SIZE(VBOXVDMACMD_DMA_PRESENT_BLT))
2584#define VBOXVDMACMD_DMA_PRESENT_BLT_SIZE(_c) (VBOXVDMACMD_BODY_FIELD_OFFSET(UINT, VBOXVDMACMD_DMA_PRESENT_BLT, aDstSubRects[_c]))
2585
2586DECLINLINE(PVBOXWDDM_ALLOCATION) vboxWddmGetAllocationFromOpenData(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_OPENALLOCATION pOa)
2587{
2588 DXGKARGCB_GETHANDLEDATA GhData;
2589 GhData.hObject = pOa->hAllocation;
2590 GhData.Type = DXGK_HANDLE_ALLOCATION;
2591 GhData.Flags.Value = 0;
2592 return (PVBOXWDDM_ALLOCATION)pDevExt->u.primary.DxgkInterface.DxgkCbGetHandleData(&GhData);
2593}
2594
2595DECLINLINE(PVBOXWDDM_ALLOCATION) vboxWddmGetAllocationFromAllocList(PDEVICE_EXTENSION pDevExt, DXGK_ALLOCATIONLIST *pAllocList)
2596{
2597 return vboxWddmGetAllocationFromOpenData(pDevExt, (PVBOXWDDM_OPENALLOCATION)pAllocList->hDeviceSpecificAllocation);
2598}
2599
2600DECLINLINE(VBOXVIDEOOFFSET) vboxWddmOffsetFromPhAddress(PHYSICAL_ADDRESS phAddr)
2601{
2602 return (VBOXVIDEOOFFSET)(phAddr.QuadPart ? phAddr.QuadPart - VBE_DISPI_LFB_PHYSICAL_ADDRESS : VBOXVIDEOOFFSET_VOID);
2603}
2604
2605DECLINLINE(VOID) vboxWddmRectlFromRect(const RECT *pRect, PVBOXVDMA_RECTL pRectl)
2606{
2607 pRectl->left = (int16_t)pRect->left;
2608 pRectl->width = (uint16_t)(pRect->right - pRect->left);
2609 pRectl->top = (int16_t)pRect->top;
2610 pRectl->height = (uint16_t)(pRect->bottom - pRect->top);
2611}
2612
2613DECLINLINE(VBOXVDMA_PIXEL_FORMAT) vboxWddmFromPixFormat(D3DDDIFORMAT format)
2614{
2615 return (VBOXVDMA_PIXEL_FORMAT)format;
2616}
2617
2618DECLINLINE(VOID) vboxWddmSurfDescFromAllocation(PVBOXWDDM_ALLOCATION pAllocation, PVBOXVDMA_SURF_DESC pDesc)
2619{
2620 pDesc->width = pAllocation->u.SurfInfo.width;
2621 pDesc->height = pAllocation->u.SurfInfo.height;
2622 pDesc->format = vboxWddmFromPixFormat(pAllocation->u.SurfInfo.format);
2623 pDesc->bpp = pAllocation->u.SurfInfo.bpp;
2624 pDesc->pitch = pAllocation->u.SurfInfo.pitch;
2625 pDesc->fFlags = 0;
2626}
2627
2628DECLINLINE(BOOLEAN) vboxWddmPixFormatConversionSupported(D3DDDIFORMAT From, D3DDDIFORMAT To)
2629{
2630 Assert(From != D3DDDIFMT_UNKNOWN);
2631 Assert(To != D3DDDIFMT_UNKNOWN);
2632 Assert(From == To);
2633 return From == To;
2634}
2635
2636DECLINLINE(PVBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE) vboxWddmCheckForVisiblePrimary(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_ALLOCATION pAllocation)
2637{
2638 if (pAllocation->enmType != VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE)
2639 return NULL;
2640
2641 PVBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE pPrimary = VBOXWDDM_ALLOCATION_BODY(pAllocation, VBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE);
2642 if (!pPrimary->bVisible)
2643 return NULL;
2644
2645 D3DDDI_VIDEO_PRESENT_SOURCE_ID id = pPrimary->VidPnSourceId;
2646 if (id >= pDevExt->cSources)
2647 return NULL;
2648
2649 PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[id];
2650 if (pSource->pAllocation != pAllocation)
2651 return NULL;
2652
2653 return pPrimary;
2654}
2655
2656/**
2657 * DxgkDdiPresent
2658 */
2659NTSTATUS
2660APIENTRY
2661DxgkDdiPresent(
2662 CONST HANDLE hContext,
2663 DXGKARG_PRESENT *pPresent)
2664{
2665 PAGED_CODE();
2666
2667 dfprintf(("==> "__FUNCTION__ ", hContext(0x%x)\n", hContext));
2668
2669 vboxVDbgBreakFv();
2670
2671 NTSTATUS Status = STATUS_SUCCESS;
2672 PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)hContext;
2673 PVBOXWDDM_DEVICE pDevice = pContext->pDevice;
2674 PDEVICE_EXTENSION pDevExt = pDevice->pAdapter;
2675
2676 Assert(pPresent->DmaBufferPrivateDataSize >= sizeof (VBOXWDDM_DMA_PRIVATE_DATA));
2677 if (pPresent->DmaBufferPrivateDataSize < sizeof (VBOXWDDM_DMA_PRIVATE_DATA))
2678 {
2679 drprintf((__FUNCTION__": Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXWDDM_DMA_PRIVATE_DATA (%d)\n", pPresent->DmaBufferPrivateDataSize , sizeof (VBOXWDDM_DMA_PRIVATE_DATA)));
2680 /* @todo: can this actually happen? what status tu return? */
2681 return STATUS_INVALID_PARAMETER;
2682 }
2683
2684 PVBOXWDDM_DMA_PRIVATE_DATA pPrivateData = (PVBOXWDDM_DMA_PRIVATE_DATA)pPresent->pDmaBufferPrivateData;
2685 pPrivateData->pContext = (PVBOXWDDM_CONTEXT)hContext;
2686
2687 if (pPresent->Flags.Blt)
2688 {
2689 Assert(pPresent->Flags.Value == 1); /* only Blt is set, we do not support anything else for now */
2690 UINT cbCmd = pPresent->DmaSize;
2691
2692 Assert(pPresent->SubRectCnt);
2693 UINT cmdSize = VBOXVDMACMD_DMA_PRESENT_BLT_SIZE(pPresent->SubRectCnt - pPresent->MultipassOffset);
2694 PVBOXVDMACMD pCmd = (PVBOXVDMACMD)pPresent->pDmaBuffer;
2695 pPresent->pDmaBuffer = ((uint8_t*)pPresent->pDmaBuffer) + cmdSize;
2696 Assert(cbCmd >= VBOXVDMACMD_DMA_PRESENT_BLT_MINSIZE());
2697 if (cbCmd >= VBOXVDMACMD_DMA_PRESENT_BLT_MINSIZE())
2698 {
2699 DXGK_ALLOCATIONLIST *pSrc = &pPresent->pAllocationList[DXGK_PRESENT_SOURCE_INDEX];
2700 DXGK_ALLOCATIONLIST *pDst = &pPresent->pAllocationList[DXGK_PRESENT_DESTINATION_INDEX];
2701 PVBOXWDDM_ALLOCATION pSrcAlloc = vboxWddmGetAllocationFromAllocList(pDevExt, pSrc);
2702 Assert(pSrcAlloc);
2703 if (pSrcAlloc)
2704 {
2705 PVBOXWDDM_ALLOCATION pDstAlloc = vboxWddmGetAllocationFromAllocList(pDevExt, pDst);
2706 Assert(pDstAlloc);
2707 if (pDstAlloc)
2708 {
2709 if (vboxWddmPixFormatConversionSupported(pSrcAlloc->u.SurfInfo.format, pDstAlloc->u.SurfInfo.format))
2710 {
2711 memset(pPresent->pPatchLocationListOut, 0, 2*sizeof (D3DDDI_PATCHLOCATIONLIST));
2712// pPresent->pPatchLocationListOut->PatchOffset = 0;
2713// ++pPresent->pPatchLocationListOut;
2714 pPresent->pPatchLocationListOut->PatchOffset = VBOXVDMACMD_BODY_FIELD_OFFSET(UINT, VBOXVDMACMD_DMA_PRESENT_BLT, offSrc);
2715 pPresent->pPatchLocationListOut->AllocationIndex = DXGK_PRESENT_SOURCE_INDEX;
2716 ++pPresent->pPatchLocationListOut;
2717 pPresent->pPatchLocationListOut->PatchOffset = VBOXVDMACMD_BODY_FIELD_OFFSET(UINT, VBOXVDMACMD_DMA_PRESENT_BLT, offDst);
2718 pPresent->pPatchLocationListOut->AllocationIndex = DXGK_PRESENT_DESTINATION_INDEX;
2719 ++pPresent->pPatchLocationListOut;
2720
2721 pCmd->enmType = VBOXVDMACMD_TYPE_DMA_PRESENT_BLT;
2722 pCmd->u32CmdSpecific = 0;
2723 PVBOXVDMACMD_DMA_PRESENT_BLT pTransfer = VBOXVDMACMD_BODY(pCmd, VBOXVDMACMD_DMA_PRESENT_BLT);
2724 pTransfer->offSrc = (VBOXVIDEOOFFSET)pSrc->PhysicalAddress.QuadPart;
2725 pTransfer->offDst = (VBOXVIDEOOFFSET)pDst->PhysicalAddress.QuadPart;
2726 vboxWddmSurfDescFromAllocation(pSrcAlloc, &pTransfer->srcDesc);
2727 vboxWddmSurfDescFromAllocation(pDstAlloc, &pTransfer->dstDesc);
2728 vboxWddmRectlFromRect(&pPresent->SrcRect, &pTransfer->srcRectl);
2729 vboxWddmRectlFromRect(&pPresent->DstRect, &pTransfer->dstRectl);
2730 UINT i = 0;
2731 cbCmd -= VBOXVDMACMD_BODY_FIELD_OFFSET(UINT, VBOXVDMACMD_DMA_PRESENT_BLT, aDstSubRects);
2732 Assert(cbCmd >= sizeof (VBOXVDMA_RECTL));
2733 Assert(cbCmd < pPresent->DmaSize);
2734 for (; i < pPresent->SubRectCnt; ++i)
2735 {
2736 if (cbCmd < sizeof (VBOXVDMA_RECTL))
2737 {
2738 Assert(i);
2739 pPresent->MultipassOffset += i;
2740 Status = STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER;
2741 break;
2742 }
2743 vboxWddmRectlFromRect(&pPresent->pDstSubRects[i + pPresent->MultipassOffset], &pTransfer->aDstSubRects[i]);
2744 cbCmd -= sizeof (VBOXVDMA_RECTL);
2745 }
2746 Assert(i);
2747 pTransfer->cDstSubRects = i;
2748 pPresent->pDmaBufferPrivateData = (uint8_t*)pPresent->pDmaBufferPrivateData + sizeof(VBOXWDDM_DMA_PRIVATE_DATA);
2749 }
2750 else
2751 {
2752 AssertBreakpoint();
2753 drprintf((__FUNCTION__": unsupported format conversion from(%d) to (%d)\n",pSrcAlloc->u.SurfInfo.format, pDstAlloc->u.SurfInfo.format));
2754 Status = STATUS_GRAPHICS_CANNOTCOLORCONVERT;
2755 }
2756 }
2757 else
2758 {
2759 /* this should not happen actually */
2760 drprintf((__FUNCTION__": failed to get Dst Allocation info for hDeviceSpecificAllocation(0x%x)\n",pDst->hDeviceSpecificAllocation));
2761 Status = STATUS_INVALID_HANDLE;
2762 }
2763 }
2764 else
2765 {
2766 /* this should not happen actually */
2767 drprintf((__FUNCTION__": failed to get Src Allocation info for hDeviceSpecificAllocation(0x%x)\n",pSrc->hDeviceSpecificAllocation));
2768 Status = STATUS_INVALID_HANDLE;
2769 }
2770 }
2771 else
2772 {
2773 /* this should not happen actually */
2774 drprintf((__FUNCTION__": cbCmd too small!! (%d)\n", cbCmd));
2775 Status = STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER;
2776 }
2777
2778 }
2779 else
2780 {
2781 drprintf((__FUNCTION__": cmd NOT IMPLEMENTED!! Flags(0x%x)\n", pPresent->Flags.Value));
2782 AssertBreakpoint();
2783 }
2784
2785 dfprintf(("<== "__FUNCTION__ ", hContext(0x%x), Status(0x%x)\n", hContext, Status));
2786
2787 return Status;
2788}
2789
2790NTSTATUS
2791APIENTRY
2792DxgkDdiUpdateOverlay(
2793 CONST HANDLE hOverlay,
2794 CONST DXGKARG_UPDATEOVERLAY *pUpdateOverlay)
2795{
2796 dfprintf(("==> "__FUNCTION__ ", hOverlay(0x%x)\n", hOverlay));
2797 AssertBreakpoint();
2798 dfprintf(("<== "__FUNCTION__ ", hOverlay(0x%x)\n", hOverlay));
2799 return STATUS_NOT_IMPLEMENTED;
2800}
2801
2802NTSTATUS
2803APIENTRY
2804DxgkDdiFlipOverlay(
2805 CONST HANDLE hOverlay,
2806 CONST DXGKARG_FLIPOVERLAY *pFlipOverlay)
2807{
2808 dfprintf(("==> "__FUNCTION__ ", hOverlay(0x%x)\n", hOverlay));
2809 AssertBreakpoint();
2810 dfprintf(("<== "__FUNCTION__ ", hOverlay(0x%x)\n", hOverlay));
2811 return STATUS_NOT_IMPLEMENTED;
2812}
2813
2814NTSTATUS
2815APIENTRY
2816DxgkDdiDestroyOverlay(
2817 CONST HANDLE hOverlay)
2818{
2819 dfprintf(("==> "__FUNCTION__ ", hOverlay(0x%x)\n", hOverlay));
2820 AssertBreakpoint();
2821 dfprintf(("<== "__FUNCTION__ ", hOverlay(0x%x)\n", hOverlay));
2822 return STATUS_NOT_IMPLEMENTED;
2823}
2824
2825/**
2826 * DxgkDdiCreateContext
2827 */
2828NTSTATUS
2829APIENTRY
2830DxgkDdiCreateContext(
2831 CONST HANDLE hDevice,
2832 DXGKARG_CREATECONTEXT *pCreateContext)
2833{
2834 /* DxgkDdiCreateContext should be made pageable */
2835 PAGED_CODE();
2836
2837 dfprintf(("==> "__FUNCTION__ ", hDevice(0x%x)\n", hDevice));
2838
2839 vboxVDbgBreakFv();
2840
2841 NTSTATUS Status = STATUS_SUCCESS;
2842 PVBOXWDDM_DEVICE pDevice = (PVBOXWDDM_DEVICE)hDevice;
2843 PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)vboxWddmMemAllocZero(sizeof (VBOXWDDM_CONTEXT));
2844
2845 pContext->pDevice = pDevice;
2846 pContext->hContext = pCreateContext->hContext;
2847 pContext->EngineAffinity = pCreateContext->EngineAffinity;
2848 pContext->NodeOrdinal = pCreateContext->NodeOrdinal;
2849 if (pCreateContext->Flags.SystemContext)
2850 pContext->enmType = VBOXWDDM_CONTEXT_TYPE_SYSTEM;
2851// else
2852// {
2853// AssertBreakpoint(); /* we do not support custom contexts for now */
2854// drprintf((__FUNCTION__ ", we do not support custom contexts for now, hDevice (0x%x)\n", hDevice));
2855// }
2856
2857 pCreateContext->hContext = pContext;
2858 pCreateContext->ContextInfo.DmaBufferSize = VBOXWDDM_C_DMA_BUFFER_SIZE;
2859 pCreateContext->ContextInfo.DmaBufferSegmentSet = 0;
2860 pCreateContext->ContextInfo.DmaBufferPrivateDataSize = sizeof (VBOXWDDM_DMA_PRIVATE_DATA);
2861 pCreateContext->ContextInfo.AllocationListSize = VBOXWDDM_C_ALLOC_LIST_SIZE;
2862 pCreateContext->ContextInfo.PatchLocationListSize = VBOXWDDM_C_PATH_LOCATION_LIST_SIZE;
2863//#if (DXGKDDI_INTERFACE_VERSION >= DXGKDDI_INTERFACE_VERSION_WIN7)
2864//# error port to Win7 DDI
2865// //pCreateContext->ContextInfo.DmaBufferAllocationGroup = ???;
2866//#endif // DXGKDDI_INTERFACE_VERSION
2867
2868 dfprintf(("<== "__FUNCTION__ ", hDevice(0x%x)\n", hDevice));
2869
2870 return Status;
2871}
2872
2873NTSTATUS
2874APIENTRY
2875DxgkDdiDestroyContext(
2876 CONST HANDLE hContext)
2877{
2878 dfprintf(("==> "__FUNCTION__ ", hContext(0x%x)\n", hContext));
2879 vboxVDbgBreakFv();
2880 vboxWddmMemFree(hContext);
2881 dfprintf(("<== "__FUNCTION__ ", hContext(0x%x)\n", hContext));
2882 return STATUS_SUCCESS;
2883}
2884
2885NTSTATUS
2886APIENTRY
2887DxgkDdiLinkDevice(
2888 __in CONST PDEVICE_OBJECT PhysicalDeviceObject,
2889 __in CONST PVOID MiniportDeviceContext,
2890 __inout PLINKED_DEVICE LinkedDevice
2891 )
2892{
2893 drprintf(("==> "__FUNCTION__ ", MiniportDeviceContext(0x%x)\n", MiniportDeviceContext));
2894 vboxVDbgBreakFv();
2895 AssertBreakpoint();
2896 drprintf(("<== "__FUNCTION__ ", MiniportDeviceContext(0x%x)\n", MiniportDeviceContext));
2897 return STATUS_NOT_IMPLEMENTED;
2898}
2899
2900NTSTATUS
2901APIENTRY
2902DxgkDdiSetDisplayPrivateDriverFormat(
2903 CONST HANDLE hAdapter,
2904 /*CONST*/ DXGKARG_SETDISPLAYPRIVATEDRIVERFORMAT* pSetDisplayPrivateDriverFormat
2905 )
2906{
2907 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2908 vboxVDbgBreakFv();
2909 AssertBreakpoint();
2910 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2911 return STATUS_SUCCESS;
2912}
2913
2914NTSTATUS APIENTRY CALLBACK DxgkDdiRestartFromTimeout(IN_CONST_HANDLE hAdapter)
2915{
2916 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2917 vboxVDbgBreakFv();
2918 AssertBreakpoint();
2919 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2920 return STATUS_SUCCESS;
2921}
2922
2923NTSTATUS
2924DriverEntry(
2925 IN PDRIVER_OBJECT DriverObject,
2926 IN PUNICODE_STRING RegistryPath
2927 )
2928{
2929 PAGED_CODE();
2930
2931 AssertBreakpoint();
2932
2933 drprintf(("VBoxVideoWddm::DriverEntry. Built %s %s\n", __DATE__, __TIME__));
2934
2935 DRIVER_INITIALIZATION_DATA DriverInitializationData = {'\0'};
2936
2937 if (! ARGUMENT_PRESENT(DriverObject) ||
2938 ! ARGUMENT_PRESENT(RegistryPath))
2939 {
2940 return STATUS_INVALID_PARAMETER;
2941 }
2942
2943 // Fill in the DriverInitializationData structure and call DxgkInitialize()
2944 DriverInitializationData.Version = DXGKDDI_INTERFACE_VERSION;
2945
2946 DriverInitializationData.DxgkDdiAddDevice = DxgkDdiAddDevice;
2947 DriverInitializationData.DxgkDdiStartDevice = DxgkDdiStartDevice;
2948 DriverInitializationData.DxgkDdiStopDevice = DxgkDdiStopDevice;
2949 DriverInitializationData.DxgkDdiRemoveDevice = DxgkDdiRemoveDevice;
2950 DriverInitializationData.DxgkDdiDispatchIoRequest = DxgkDdiDispatchIoRequest;
2951 DriverInitializationData.DxgkDdiInterruptRoutine = DxgkDdiInterruptRoutine;
2952 DriverInitializationData.DxgkDdiDpcRoutine = DxgkDdiDpcRoutine;
2953 DriverInitializationData.DxgkDdiQueryChildRelations = DxgkDdiQueryChildRelations;
2954 DriverInitializationData.DxgkDdiQueryChildStatus = DxgkDdiQueryChildStatus;
2955 DriverInitializationData.DxgkDdiQueryDeviceDescriptor = DxgkDdiQueryDeviceDescriptor;
2956 DriverInitializationData.DxgkDdiSetPowerState = DxgkDdiSetPowerState;
2957 DriverInitializationData.DxgkDdiNotifyAcpiEvent = DxgkDdiNotifyAcpiEvent;
2958 DriverInitializationData.DxgkDdiResetDevice = DxgkDdiResetDevice;
2959 DriverInitializationData.DxgkDdiUnload = DxgkDdiUnload;
2960 DriverInitializationData.DxgkDdiQueryInterface = DxgkDdiQueryInterface;
2961 DriverInitializationData.DxgkDdiControlEtwLogging = DxgkDdiControlEtwLogging;
2962
2963 DriverInitializationData.DxgkDdiQueryAdapterInfo = DxgkDdiQueryAdapterInfo;
2964 DriverInitializationData.DxgkDdiCreateDevice = DxgkDdiCreateDevice;
2965 DriverInitializationData.DxgkDdiCreateAllocation = DxgkDdiCreateAllocation;
2966 DriverInitializationData.DxgkDdiDestroyAllocation = DxgkDdiDestroyAllocation;
2967 DriverInitializationData.DxgkDdiDescribeAllocation = DxgkDdiDescribeAllocation;
2968 DriverInitializationData.DxgkDdiGetStandardAllocationDriverData = DxgkDdiGetStandardAllocationDriverData;
2969 DriverInitializationData.DxgkDdiAcquireSwizzlingRange = DxgkDdiAcquireSwizzlingRange;
2970 DriverInitializationData.DxgkDdiReleaseSwizzlingRange = DxgkDdiReleaseSwizzlingRange;
2971 DriverInitializationData.DxgkDdiPatch = DxgkDdiPatch;
2972 DriverInitializationData.DxgkDdiSubmitCommand = DxgkDdiSubmitCommand;
2973 DriverInitializationData.DxgkDdiPreemptCommand = DxgkDdiPreemptCommand;
2974 DriverInitializationData.DxgkDdiBuildPagingBuffer = DxgkDdiBuildPagingBuffer;
2975 DriverInitializationData.DxgkDdiSetPalette = DxgkDdiSetPalette;
2976 DriverInitializationData.DxgkDdiSetPointerPosition = DxgkDdiSetPointerPosition;
2977 DriverInitializationData.DxgkDdiSetPointerShape = DxgkDdiSetPointerShape;
2978 DriverInitializationData.DxgkDdiResetFromTimeout = DxgkDdiResetFromTimeout;
2979 DriverInitializationData.DxgkDdiRestartFromTimeout = DxgkDdiRestartFromTimeout;
2980 DriverInitializationData.DxgkDdiEscape = DxgkDdiEscape;
2981 DriverInitializationData.DxgkDdiCollectDbgInfo = DxgkDdiCollectDbgInfo;
2982 DriverInitializationData.DxgkDdiQueryCurrentFence = DxgkDdiQueryCurrentFence;
2983 DriverInitializationData.DxgkDdiIsSupportedVidPn = DxgkDdiIsSupportedVidPn;
2984 DriverInitializationData.DxgkDdiRecommendFunctionalVidPn = DxgkDdiRecommendFunctionalVidPn;
2985 DriverInitializationData.DxgkDdiEnumVidPnCofuncModality = DxgkDdiEnumVidPnCofuncModality;
2986 DriverInitializationData.DxgkDdiSetVidPnSourceAddress = DxgkDdiSetVidPnSourceAddress;
2987 DriverInitializationData.DxgkDdiSetVidPnSourceVisibility = DxgkDdiSetVidPnSourceVisibility;
2988 DriverInitializationData.DxgkDdiCommitVidPn = DxgkDdiCommitVidPn;
2989 DriverInitializationData.DxgkDdiUpdateActiveVidPnPresentPath = DxgkDdiUpdateActiveVidPnPresentPath;
2990 DriverInitializationData.DxgkDdiRecommendMonitorModes = DxgkDdiRecommendMonitorModes;
2991 DriverInitializationData.DxgkDdiRecommendVidPnTopology = DxgkDdiRecommendVidPnTopology;
2992 DriverInitializationData.DxgkDdiGetScanLine = DxgkDdiGetScanLine;
2993 DriverInitializationData.DxgkDdiStopCapture = DxgkDdiStopCapture;
2994 DriverInitializationData.DxgkDdiControlInterrupt = DxgkDdiControlInterrupt;
2995 DriverInitializationData.DxgkDdiCreateOverlay = DxgkDdiCreateOverlay;
2996
2997 DriverInitializationData.DxgkDdiDestroyDevice = DxgkDdiDestroyDevice;
2998 DriverInitializationData.DxgkDdiOpenAllocation = DxgkDdiOpenAllocation;
2999 DriverInitializationData.DxgkDdiCloseAllocation = DxgkDdiCloseAllocation;
3000 DriverInitializationData.DxgkDdiRender = DxgkDdiRender;
3001 DriverInitializationData.DxgkDdiPresent = DxgkDdiPresent;
3002
3003 DriverInitializationData.DxgkDdiUpdateOverlay = DxgkDdiUpdateOverlay;
3004 DriverInitializationData.DxgkDdiFlipOverlay = DxgkDdiFlipOverlay;
3005 DriverInitializationData.DxgkDdiDestroyOverlay = DxgkDdiDestroyOverlay;
3006
3007 DriverInitializationData.DxgkDdiCreateContext = DxgkDdiCreateContext;
3008 DriverInitializationData.DxgkDdiDestroyContext = DxgkDdiDestroyContext;
3009
3010 DriverInitializationData.DxgkDdiLinkDevice = NULL; //DxgkDdiLinkDevice;
3011 DriverInitializationData.DxgkDdiSetDisplayPrivateDriverFormat = DxgkDdiSetDisplayPrivateDriverFormat;
3012//#if (DXGKDDI_INTERFACE_VERSION >= DXGKDDI_INTERFACE_VERSION_WIN7)
3013//# error port to Win7 DDI
3014// DriverInitializationData.DxgkDdiRenderKm = DxgkDdiRenderKm;
3015// DriverInitializationData.DxgkDdiRestartFromTimeout = DxgkDdiRestartFromTimeout;
3016// DriverInitializationData.DxgkDdiSetVidPnSourceVisibility = DxgkDdiSetVidPnSourceVisibility;
3017// DriverInitializationData.DxgkDdiUpdateActiveVidPnPresentPath = DxgkDdiUpdateActiveVidPnPresentPath;
3018// DriverInitializationData.DxgkDdiQueryVidPnHWCapability = DxgkDdiQueryVidPnHWCapability;
3019//#endif
3020
3021 return DxgkInitialize(DriverObject,
3022 RegistryPath,
3023 &DriverInitializationData);
3024}
Note: See TracBrowser for help on using the repository browser.

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