VirtualBox

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

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

wddm: more impl for autoresize support

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