VirtualBox

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

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

wddm: vboxtray: abstraction display driver API for passing escape codes (using ExtEscape for XPDM & PFND3DKMT stugg for WDDM); WDDM miniport driver: basics for handling autoresize & seamles

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 124.0 KB
Line 
1/*
2 * Copyright (C) 2010 Sun Microsystems, Inc.
3 *
4 * This file is part of VirtualBox Open Source Edition (OSE), as
5 * available from http://www.virtualbox.org. This file is free software;
6 * you can redistribute it and/or modify it under the terms of the GNU
7 * General Public License (GPL) as published by the Free Software
8 * Foundation, in version 2 as it comes in the "COPYING" file of the
9 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
10 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
11 *
12 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
13 * Clara, CA 95054 USA or visit http://www.sun.com if you need
14 * additional information or have any questions.
15 */
16
17#include "../VBoxVideo.h"
18#include "../Helper.h"
19
20#include <VBox/VBoxGuestLib.h>
21#include <VBox/VBoxVideo.h>
22#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 uint32_t iPreferredMode;
2420 VIDEO_MODE_INFORMATION *pModes;
2421 uint32_t cResolutions;
2422 D3DKMDT_2DREGION *pResolutions;
2423 VBoxWddmGetModesTable(pDevExt, /* PDEVICE_EXTENSION DeviceExtension */
2424 false, /* bool bRebuildTable*/
2425 &pModes, /* VIDEO_MODE_INFORMATION ** ppModes*/
2426 &cModes, /* uint32_t * pcModes */
2427 &iPreferredMode, /* uint32_t * pPreferrableMode*/
2428 &pResolutions, /* D3DKMDT_2DREGION **ppResolutions */
2429 &cResolutions /* uint32_t * pcResolutions */);
2430
2431
2432 const DXGK_VIDPN_INTERFACE* pVidPnInterface = NULL;
2433 Status = pDevExt->u.primary.DxgkInterface.DxgkCbQueryVidPnInterface(pRecommendFunctionalVidPnArg->hRecommendedFunctionalVidPn, DXGK_VIDPN_INTERFACE_VERSION_V1, &pVidPnInterface);
2434 Assert(Status == STATUS_SUCCESS);
2435 if (Status == STATUS_SUCCESS)
2436 {
2437 D3DKMDT_2DREGION PrefRegion;
2438 PrefRegion.cx = pModes[iPreferredMode].VisScreenHeight;
2439 PrefRegion.cy = pModes[iPreferredMode].VisScreenWidth;
2440 Status = vboxVidPnCreatePopulateVidPnFromLegacy(pDevExt, pRecommendFunctionalVidPnArg->hRecommendedFunctionalVidPn, pVidPnInterface,
2441#if 0
2442 pModes, cModes, iPreferredMode,
2443 pResolutions, cResolutions
2444#else
2445 &pModes[iPreferredMode], 1, 0,
2446 &PrefRegion, 1
2447#endif
2448 );
2449 Assert(Status == STATUS_SUCCESS);
2450 if (Status != STATUS_SUCCESS)
2451 drprintf((__FUNCTION__": vboxVidPnCreatePopulateVidPnFromLegacy failed Status(0x%x)\n", Status));
2452 }
2453 else
2454 drprintf((__FUNCTION__": DxgkCbQueryVidPnInterface failed Status(0x%x)\n", Status));
2455
2456 dfprintf(("<== "__FUNCTION__ ", status(0x%x), context(0x%x)\n", Status, hAdapter));
2457
2458 return Status;
2459}
2460
2461NTSTATUS
2462APIENTRY
2463DxgkDdiEnumVidPnCofuncModality(
2464 CONST HANDLE hAdapter,
2465 CONST DXGKARG_ENUMVIDPNCOFUNCMODALITY* CONST pEnumCofuncModalityArg
2466 )
2467{
2468 /* The DxgkDdiEnumVidPnCofuncModality function should be made pageable. */
2469 PAGED_CODE();
2470
2471// dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", hAdapter));
2472
2473 vboxVDbgBreakFv();
2474
2475 PDEVICE_EXTENSION pContext = (PDEVICE_EXTENSION)hAdapter;
2476 const DXGK_VIDPN_INTERFACE* pVidPnInterface = NULL;
2477 NTSTATUS Status = pContext->u.primary.DxgkInterface.DxgkCbQueryVidPnInterface(pEnumCofuncModalityArg->hConstrainingVidPn, DXGK_VIDPN_INTERFACE_VERSION_V1, &pVidPnInterface);
2478 if (Status == STATUS_SUCCESS)
2479 {
2480 D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology;
2481 const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface;
2482 NTSTATUS Status = pVidPnInterface->pfnGetTopology(pEnumCofuncModalityArg->hConstrainingVidPn, &hVidPnTopology, &pVidPnTopologyInterface);
2483 Assert(Status == STATUS_SUCCESS);
2484 if (Status == STATUS_SUCCESS)
2485 {
2486 VBOXVIDPNCOFUNCMODALITY CbContext = {0};
2487 CbContext.pEnumCofuncModalityArg = pEnumCofuncModalityArg;
2488 VBoxWddmGetModesTable(pContext, /* PDEVICE_EXTENSION DeviceExtension */
2489 false, /* bool bRebuildTable*/
2490 &CbContext.pModes, /* VIDEO_MODE_INFORMATION ** ppModes*/
2491 &CbContext.cModes, /* uint32_t * pcModes */
2492 &CbContext.iPreferredMode, /* uint32_t * pPreferrableMode*/
2493 &CbContext.pResolutions, /* D3DKMDT_2DREGION **ppResolutions */
2494 &CbContext.cResolutions /* uint32_t * pcResolutions */);
2495 Assert(CbContext.cModes);
2496 Assert(CbContext.cModes > CbContext.iPreferredMode);
2497 Status = vboxVidPnEnumPaths(pContext, pEnumCofuncModalityArg->hConstrainingVidPn, pVidPnInterface,
2498 hVidPnTopology, pVidPnTopologyInterface,
2499 vboxVidPnCofuncModalityPathEnum, &CbContext);
2500 Assert(Status == STATUS_SUCCESS);
2501 if (Status == STATUS_SUCCESS)
2502 {
2503 Status = CbContext.Status;
2504 Assert(Status == STATUS_SUCCESS);
2505 if (Status != STATUS_SUCCESS)
2506 drprintf((__FUNCTION__ ": vboxVidPnAdjustSourcesTargetsCallback failed Status(0x%x)\n", Status));
2507 }
2508 else
2509 drprintf((__FUNCTION__ ": vboxVidPnEnumPaths failed Status(0x%x)\n", Status));
2510 }
2511 else
2512 drprintf((__FUNCTION__ ": pfnGetTopology failed Status(0x%x)\n", Status));
2513 }
2514 else
2515 drprintf((__FUNCTION__ ": DxgkCbQueryVidPnInterface failed Status(0x%x)\n", Status));
2516
2517// dfprintf(("<== "__FUNCTION__ ", status(0x%x), context(0x%x)\n", Status, hAdapter));
2518
2519 return Status;
2520}
2521
2522NTSTATUS
2523APIENTRY
2524DxgkDdiSetVidPnSourceAddress(
2525 CONST HANDLE hAdapter,
2526 CONST DXGKARG_SETVIDPNSOURCEADDRESS* pSetVidPnSourceAddress
2527 )
2528{
2529 /* The DxgkDdiSetVidPnSourceAddress function should be made pageable. */
2530 PAGED_CODE();
2531
2532 vboxVDbgBreakFv();
2533
2534 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", hAdapter));
2535
2536 NTSTATUS Status = STATUS_SUCCESS;
2537 PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)hAdapter;
2538 Assert(pDevExt->cSources > pSetVidPnSourceAddress->VidPnSourceId);
2539 if (pDevExt->cSources > pSetVidPnSourceAddress->VidPnSourceId)
2540 {
2541 PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[pSetVidPnSourceAddress->VidPnSourceId];
2542 PVBOXWDDM_ALLOCATION pAllocation;
2543 Assert(pSetVidPnSourceAddress->hAllocation);
2544 Assert(pSetVidPnSourceAddress->hAllocation || pSource->pAllocation);
2545 Assert (pSetVidPnSourceAddress->Flags.Value < 2); /* i.e. 0 or 1 (ModeChange) */
2546 if (pSetVidPnSourceAddress->hAllocation)
2547 {
2548 pAllocation = (PVBOXWDDM_ALLOCATION)pSetVidPnSourceAddress->hAllocation;
2549 vboxWddmAssignPrimary(pDevExt, pSource, pAllocation, pSetVidPnSourceAddress->VidPnSourceId);
2550 }
2551 else
2552 pAllocation = pSource->pAllocation;
2553
2554 Assert(pAllocation);
2555 if (pAllocation)
2556 {
2557 Assert(pAllocation->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE);
2558 PVBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE pPrimary = VBOXWDDM_ALLOCATION_BODY(pAllocation, VBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE);
2559 pAllocation->offVram = (VBOXVIDEOOFFSET)pSetVidPnSourceAddress->PrimaryAddress.QuadPart;
2560 pAllocation->SegmentId = pSetVidPnSourceAddress->PrimarySegment;
2561 Assert (pAllocation->SegmentId);
2562 Assert (!pPrimary->bVisible);
2563 if (pPrimary->bVisible)
2564 {
2565 /* should not generally happen, but still inform host*/
2566 Status = vboxWddmGhDisplaySetInfo(pDevExt, pSource);
2567 Assert(Status == STATUS_SUCCESS);
2568 if (Status != STATUS_SUCCESS)
2569 drprintf((__FUNCTION__": vboxWddmGhDisplaySetInfo failed, Status (0x%x)\n", Status));
2570 }
2571 }
2572 else
2573 {
2574 drprintf((__FUNCTION__": no allocation data available!!\n"));
2575 Status = STATUS_INVALID_PARAMETER;
2576 }
2577 }
2578 else
2579 {
2580 drprintf((__FUNCTION__": invalid VidPnSourceId (%d), should be smaller than (%d)\n", pSetVidPnSourceAddress->VidPnSourceId, pDevExt->cSources));
2581 Status = STATUS_INVALID_PARAMETER;
2582 }
2583
2584 dfprintf(("<== "__FUNCTION__ ", status(0x%x), context(0x%x)\n", Status, hAdapter));
2585
2586 return Status;
2587}
2588
2589NTSTATUS
2590APIENTRY
2591DxgkDdiSetVidPnSourceVisibility(
2592 CONST HANDLE hAdapter,
2593 CONST DXGKARG_SETVIDPNSOURCEVISIBILITY* pSetVidPnSourceVisibility
2594 )
2595{
2596 /* DxgkDdiSetVidPnSourceVisibility should be made pageable. */
2597 PAGED_CODE();
2598
2599 vboxVDbgBreakFv();
2600
2601 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", hAdapter));
2602
2603 NTSTATUS Status = STATUS_SUCCESS;
2604 PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)hAdapter;
2605 Assert(pDevExt->cSources > pSetVidPnSourceVisibility->VidPnSourceId);
2606 if (pDevExt->cSources > pSetVidPnSourceVisibility->VidPnSourceId)
2607 {
2608 PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[pSetVidPnSourceVisibility->VidPnSourceId];
2609 PVBOXWDDM_ALLOCATION pAllocation = pSource->pAllocation;
2610 PVBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE pPrimary = VBOXWDDM_ALLOCATION_BODY(pAllocation, VBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE);
2611
2612 Assert(pPrimary->bVisible != pSetVidPnSourceVisibility->Visible);
2613 if (pPrimary->bVisible != pSetVidPnSourceVisibility->Visible)
2614 {
2615 pPrimary->bVisible = pSetVidPnSourceVisibility->Visible;
2616 if (pPrimary->bVisible)
2617 {
2618 Status = vboxWddmGhDisplaySetInfo(pDevExt, pSource);
2619 Assert(Status == STATUS_SUCCESS);
2620 if (Status != STATUS_SUCCESS)
2621 drprintf((__FUNCTION__": vboxWddmGhDisplaySetInfo failed, Status (0x%x)\n", Status));
2622 }
2623 else
2624 {
2625 vboxVdmaFlush (pDevExt, &pDevExt->u.primary.Vdma);
2626 }
2627 }
2628 }
2629 else
2630 {
2631 drprintf((__FUNCTION__": invalid VidPnSourceId (%d), should be smaller than (%d)\n", pSetVidPnSourceVisibility->VidPnSourceId, pDevExt->cSources));
2632 Status = STATUS_INVALID_PARAMETER;
2633 }
2634
2635 dfprintf(("<== "__FUNCTION__ ", status(0x%x), context(0x%x)\n", Status, hAdapter));
2636
2637 return Status;
2638}
2639
2640NTSTATUS
2641APIENTRY
2642DxgkDdiCommitVidPn(
2643 CONST HANDLE hAdapter,
2644 CONST DXGKARG_COMMITVIDPN* CONST pCommitVidPnArg
2645 )
2646{
2647 dfprintf(("==> "__FUNCTION__ ", context(0x%x)\n", hAdapter));
2648
2649 PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)hAdapter;
2650
2651 vboxVDbgBreakFv();
2652
2653 const DXGK_VIDPN_INTERFACE* pVidPnInterface = NULL;
2654 NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbQueryVidPnInterface(pCommitVidPnArg->hFunctionalVidPn, DXGK_VIDPN_INTERFACE_VERSION_V1, &pVidPnInterface);
2655 if (Status == STATUS_SUCCESS)
2656 {
2657 if (pCommitVidPnArg->AffectedVidPnSourceId != D3DDDI_ID_ALL)
2658 {
2659 Status = vboxVidPnCommitSourceModeForSrcId(
2660 pDevExt,
2661 pCommitVidPnArg->hFunctionalVidPn, pVidPnInterface,
2662 pCommitVidPnArg->AffectedVidPnSourceId, (PVBOXWDDM_ALLOCATION)pCommitVidPnArg->hPrimaryAllocation);
2663 Assert(Status == STATUS_SUCCESS);
2664 if (Status != STATUS_SUCCESS)
2665 drprintf((__FUNCTION__ ": vboxVidPnCommitSourceModeForSrcId failed Status(0x%x)\n", Status));
2666 }
2667 else
2668 {
2669 /* clear all current primaries */
2670 for (UINT i = 0; i < pDevExt->cSources; ++i)
2671 {
2672 vboxWddmAssignPrimary(pDevExt, &pDevExt->aSources[i], NULL, i);
2673 }
2674
2675 D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology;
2676 const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface;
2677 NTSTATUS Status = pVidPnInterface->pfnGetTopology(pCommitVidPnArg->hFunctionalVidPn, &hVidPnTopology, &pVidPnTopologyInterface);
2678 Assert(Status == STATUS_SUCCESS);
2679 if (Status == STATUS_SUCCESS)
2680 {
2681 VBOXVIDPNCOMMIT CbContext = {0};
2682 CbContext.pCommitVidPnArg = pCommitVidPnArg;
2683 Status = vboxVidPnEnumPaths(pDevExt, pCommitVidPnArg->hFunctionalVidPn, pVidPnInterface,
2684 hVidPnTopology, pVidPnTopologyInterface,
2685 vboxVidPnCommitPathEnum, &CbContext);
2686 Assert(Status == STATUS_SUCCESS);
2687 if (Status == STATUS_SUCCESS)
2688 {
2689 Status = CbContext.Status;
2690 Assert(Status == STATUS_SUCCESS);
2691 if (Status != STATUS_SUCCESS)
2692 drprintf((__FUNCTION__ ": vboxVidPnCommitPathEnum failed Status(0x%x)\n", Status));
2693 }
2694 else
2695 drprintf((__FUNCTION__ ": vboxVidPnEnumPaths failed Status(0x%x)\n", Status));
2696 }
2697 else
2698 drprintf((__FUNCTION__ ": pfnGetTopology failed Status(0x%x)\n", Status));
2699 }
2700 }
2701 else
2702 drprintf((__FUNCTION__ ": DxgkCbQueryVidPnInterface failed Status(0x%x)\n", Status));
2703
2704 dfprintf(("<== "__FUNCTION__ ", status(0x%x), context(0x%x)\n", Status, hAdapter));
2705
2706 return Status;
2707}
2708
2709NTSTATUS
2710APIENTRY
2711DxgkDdiUpdateActiveVidPnPresentPath(
2712 CONST HANDLE hAdapter,
2713 CONST DXGKARG_UPDATEACTIVEVIDPNPRESENTPATH* CONST pUpdateActiveVidPnPresentPathArg
2714 )
2715{
2716 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2717
2718 AssertBreakpoint();
2719
2720 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2721
2722 return STATUS_SUCCESS;
2723}
2724
2725NTSTATUS
2726APIENTRY
2727DxgkDdiRecommendMonitorModes(
2728 CONST HANDLE hAdapter,
2729 CONST DXGKARG_RECOMMENDMONITORMODES* CONST pRecommendMonitorModesArg
2730 )
2731{
2732 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2733
2734 vboxVDbgBreakFv();
2735
2736 PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)hAdapter;
2737 NTSTATUS Status;
2738 uint32_t cModes;
2739 uint32_t iPreferredMode;
2740 VIDEO_MODE_INFORMATION *pModes;
2741 uint32_t cResolutions;
2742 D3DKMDT_2DREGION *pResolutions;
2743 VBoxWddmGetModesTable(pDevExt, /* PDEVICE_EXTENSION DeviceExtension */
2744 false, /* bool bRebuildTable*/
2745 &pModes, /* VIDEO_MODE_INFORMATION ** ppModes*/
2746 &cModes, /* uint32_t * pcModes */
2747 &iPreferredMode, /* uint32_t * pPreferrableMode*/
2748 &pResolutions, /* D3DKMDT_2DREGION **ppResolutions */
2749 &cResolutions /* uint32_t * pcResolutions */);
2750
2751 for (uint32_t i = 0; i < cResolutions; i++)
2752 {
2753 D3DKMDT_MONITOR_SOURCE_MODE * pNewMonitorSourceModeInfo;
2754 Status = pRecommendMonitorModesArg->pMonitorSourceModeSetInterface->pfnCreateNewModeInfo(
2755 pRecommendMonitorModesArg->hMonitorSourceModeSet, &pNewMonitorSourceModeInfo);
2756 Assert(Status == STATUS_SUCCESS);
2757 if (Status == STATUS_SUCCESS)
2758 {
2759 Status = vboxVidPnPopulateMonitorSourceModeInfoFromLegacy(pDevExt,
2760 pNewMonitorSourceModeInfo,
2761 &pResolutions[i],
2762 D3DKMDT_MCO_DRIVER,
2763 true);
2764 Assert(Status == STATUS_SUCCESS);
2765 if (Status == STATUS_SUCCESS)
2766 {
2767 Status = pRecommendMonitorModesArg->pMonitorSourceModeSetInterface->pfnAddMode(
2768 pRecommendMonitorModesArg->hMonitorSourceModeSet, pNewMonitorSourceModeInfo);
2769 Assert(Status == STATUS_SUCCESS);
2770 if (Status == STATUS_SUCCESS)
2771 continue;
2772 }
2773
2774 /* error has occured, release & break */
2775 pRecommendMonitorModesArg->pMonitorSourceModeSetInterface->pfnReleaseModeInfo(
2776 pRecommendMonitorModesArg->hMonitorSourceModeSet, pNewMonitorSourceModeInfo);
2777 break;
2778 }
2779 }
2780
2781 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2782
2783 return Status;
2784}
2785
2786NTSTATUS
2787APIENTRY
2788DxgkDdiRecommendVidPnTopology(
2789 CONST HANDLE hAdapter,
2790 CONST DXGKARG_RECOMMENDVIDPNTOPOLOGY* CONST pRecommendVidPnTopologyArg
2791 )
2792{
2793 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2794
2795 vboxVDbgBreakFv();
2796
2797 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2798
2799 return STATUS_GRAPHICS_NO_RECOMMENDED_VIDPN_TOPOLOGY;
2800}
2801
2802NTSTATUS
2803APIENTRY
2804DxgkDdiGetScanLine(
2805 CONST HANDLE hAdapter,
2806 DXGKARG_GETSCANLINE* pGetScanLine)
2807{
2808 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2809
2810 AssertBreakpoint();
2811
2812 pGetScanLine->InVerticalBlank = FALSE;
2813 pGetScanLine->ScanLine = 0;
2814
2815 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2816
2817 return STATUS_SUCCESS;
2818}
2819
2820NTSTATUS
2821APIENTRY
2822DxgkDdiStopCapture(
2823 CONST HANDLE hAdapter,
2824 CONST DXGKARG_STOPCAPTURE* pStopCapture)
2825{
2826 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2827
2828 AssertBreakpoint();
2829
2830 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2831
2832 return STATUS_SUCCESS;
2833}
2834
2835NTSTATUS
2836APIENTRY
2837DxgkDdiControlInterrupt(
2838 CONST HANDLE hAdapter,
2839 CONST DXGK_INTERRUPT_TYPE InterruptType,
2840 BOOLEAN Enable
2841 )
2842{
2843 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2844
2845 AssertBreakpoint();
2846
2847 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2848
2849 /* @todo: STATUS_NOT_IMPLEMENTED ?? */
2850 return STATUS_SUCCESS;
2851}
2852
2853NTSTATUS
2854APIENTRY
2855DxgkDdiCreateOverlay(
2856 CONST HANDLE hAdapter,
2857 DXGKARG_CREATEOVERLAY *pCreateOverlay)
2858{
2859 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2860
2861 AssertBreakpoint();
2862
2863 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
2864
2865 return STATUS_NOT_IMPLEMENTED;
2866}
2867
2868NTSTATUS
2869APIENTRY
2870DxgkDdiDestroyDevice(
2871 CONST HANDLE hDevice)
2872{
2873 /* DxgkDdiDestroyDevice should be made pageable. */
2874 PAGED_CODE();
2875
2876 dfprintf(("==> "__FUNCTION__ ", hDevice(0x%x)\n", hDevice));
2877
2878 vboxVDbgBreakFv();
2879
2880 vboxWddmMemFree(hDevice);
2881
2882 dfprintf(("<== "__FUNCTION__ ", \n"));
2883
2884 return STATUS_SUCCESS;
2885}
2886
2887/*
2888 * DxgkDdiOpenAllocation
2889 */
2890NTSTATUS
2891APIENTRY
2892DxgkDdiOpenAllocation(
2893 CONST HANDLE hDevice,
2894 CONST DXGKARG_OPENALLOCATION *pOpenAllocation)
2895{
2896 /* DxgkDdiOpenAllocation should be made pageable. */
2897 PAGED_CODE();
2898
2899 dfprintf(("==> "__FUNCTION__ ", hDevice(0x%x)\n", hDevice));
2900
2901 vboxVDbgBreakFv();
2902
2903 NTSTATUS Status = STATUS_SUCCESS;
2904
2905 for (UINT i = 0; i < pOpenAllocation->NumAllocations; ++i)
2906 {
2907 DXGK_OPENALLOCATIONINFO* pInfo = &pOpenAllocation->pOpenAllocation[i];
2908 PVBOXWDDM_OPENALLOCATION pOa = (PVBOXWDDM_OPENALLOCATION)vboxWddmMemAllocZero(sizeof (VBOXWDDM_OPENALLOCATION));
2909 pOa->hAllocation = pInfo->hAllocation;
2910 pInfo->hDeviceSpecificAllocation = pOa;
2911 }
2912
2913 dfprintf(("<== "__FUNCTION__ ", hDevice(0x%x)\n", hDevice));
2914
2915 return Status;
2916}
2917
2918NTSTATUS
2919APIENTRY
2920DxgkDdiCloseAllocation(
2921 CONST HANDLE hDevice,
2922 CONST DXGKARG_CLOSEALLOCATION* pCloseAllocation)
2923{
2924 /* DxgkDdiCloseAllocation should be made pageable. */
2925 PAGED_CODE();
2926
2927 dfprintf(("==> "__FUNCTION__ ", hDevice(0x%x)\n", hDevice));
2928
2929 vboxVDbgBreakFv();
2930
2931 for (UINT i = 0; i < pCloseAllocation->NumAllocations; ++i)
2932 {
2933 vboxWddmMemFree(pCloseAllocation->pOpenHandleList[i]);
2934 }
2935
2936 dfprintf(("<== "__FUNCTION__ ", hDevice(0x%x)\n", hDevice));
2937
2938 return STATUS_SUCCESS;
2939}
2940
2941NTSTATUS
2942APIENTRY
2943DxgkDdiRender(
2944 CONST HANDLE hContext,
2945 DXGKARG_RENDER *pRender)
2946{
2947 drprintf(("==> "__FUNCTION__ ", !!NOT_IMPLEMENTED!! hContext(0x%x)\n", hContext));
2948
2949 AssertBreakpoint();
2950
2951 drprintf(("<== "__FUNCTION__ ", !!NOT_IMPLEMENTED!! hContext(0x%x)\n", hContext));
2952
2953 return STATUS_NOT_IMPLEMENTED;
2954}
2955
2956#define VBOXVDMACMD_DMA_PRESENT_BLT_MINSIZE() (VBOXVDMACMD_SIZE(VBOXVDMACMD_DMA_PRESENT_BLT))
2957#define VBOXVDMACMD_DMA_PRESENT_BLT_SIZE(_c) (VBOXVDMACMD_BODY_FIELD_OFFSET(UINT, VBOXVDMACMD_DMA_PRESENT_BLT, aDstSubRects[_c]))
2958
2959DECLINLINE(PVBOXWDDM_ALLOCATION) vboxWddmGetAllocationFromOpenData(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_OPENALLOCATION pOa)
2960{
2961 DXGKARGCB_GETHANDLEDATA GhData;
2962 GhData.hObject = pOa->hAllocation;
2963 GhData.Type = DXGK_HANDLE_ALLOCATION;
2964 GhData.Flags.Value = 0;
2965 return (PVBOXWDDM_ALLOCATION)pDevExt->u.primary.DxgkInterface.DxgkCbGetHandleData(&GhData);
2966}
2967
2968DECLINLINE(PVBOXWDDM_ALLOCATION) vboxWddmGetAllocationFromAllocList(PDEVICE_EXTENSION pDevExt, DXGK_ALLOCATIONLIST *pAllocList)
2969{
2970 return vboxWddmGetAllocationFromOpenData(pDevExt, (PVBOXWDDM_OPENALLOCATION)pAllocList->hDeviceSpecificAllocation);
2971}
2972
2973DECLINLINE(VBOXVIDEOOFFSET) vboxWddmOffsetFromPhAddress(PHYSICAL_ADDRESS phAddr)
2974{
2975 return (VBOXVIDEOOFFSET)(phAddr.QuadPart ? phAddr.QuadPart - VBE_DISPI_LFB_PHYSICAL_ADDRESS : VBOXVIDEOOFFSET_VOID);
2976}
2977
2978DECLINLINE(VOID) vboxWddmRectlFromRect(const RECT *pRect, PVBOXVDMA_RECTL pRectl)
2979{
2980 pRectl->left = (int16_t)pRect->left;
2981 pRectl->width = (uint16_t)(pRect->right - pRect->left);
2982 pRectl->top = (int16_t)pRect->top;
2983 pRectl->height = (uint16_t)(pRect->bottom - pRect->top);
2984}
2985
2986DECLINLINE(VBOXVDMA_PIXEL_FORMAT) vboxWddmFromPixFormat(D3DDDIFORMAT format)
2987{
2988 return (VBOXVDMA_PIXEL_FORMAT)format;
2989}
2990
2991DECLINLINE(VOID) vboxWddmSurfDescFromAllocation(PVBOXWDDM_ALLOCATION pAllocation, PVBOXVDMA_SURF_DESC pDesc)
2992{
2993 pDesc->width = pAllocation->u.SurfInfo.width;
2994 pDesc->height = pAllocation->u.SurfInfo.height;
2995 pDesc->format = vboxWddmFromPixFormat(pAllocation->u.SurfInfo.format);
2996 pDesc->bpp = pAllocation->u.SurfInfo.bpp;
2997 pDesc->pitch = pAllocation->u.SurfInfo.pitch;
2998 pDesc->fFlags = 0;
2999}
3000
3001DECLINLINE(BOOLEAN) vboxWddmPixFormatConversionSupported(D3DDDIFORMAT From, D3DDDIFORMAT To)
3002{
3003 Assert(From != D3DDDIFMT_UNKNOWN);
3004 Assert(To != D3DDDIFMT_UNKNOWN);
3005 Assert(From == To);
3006 return From == To;
3007}
3008
3009DECLINLINE(PVBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE) vboxWddmCheckForVisiblePrimary(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_ALLOCATION pAllocation)
3010{
3011 if (pAllocation->enmType != VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE)
3012 return NULL;
3013
3014 PVBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE pPrimary = VBOXWDDM_ALLOCATION_BODY(pAllocation, VBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE);
3015 if (!pPrimary->bVisible)
3016 return NULL;
3017
3018 D3DDDI_VIDEO_PRESENT_SOURCE_ID id = pPrimary->VidPnSourceId;
3019 if (id >= pDevExt->cSources)
3020 return NULL;
3021
3022 PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[id];
3023 if (pSource->pAllocation != pAllocation)
3024 return NULL;
3025
3026 return pPrimary;
3027}
3028
3029/**
3030 * DxgkDdiPresent
3031 */
3032NTSTATUS
3033APIENTRY
3034DxgkDdiPresent(
3035 CONST HANDLE hContext,
3036 DXGKARG_PRESENT *pPresent)
3037{
3038 PAGED_CODE();
3039
3040// dfprintf(("==> "__FUNCTION__ ", hContext(0x%x)\n", hContext));
3041
3042 vboxVDbgBreakFv();
3043
3044 NTSTATUS Status = STATUS_SUCCESS;
3045 PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)hContext;
3046 PVBOXWDDM_DEVICE pDevice = pContext->pDevice;
3047 PDEVICE_EXTENSION pDevExt = pDevice->pAdapter;
3048
3049 Assert(pPresent->DmaBufferPrivateDataSize >= sizeof (VBOXWDDM_DMA_PRIVATE_DATA));
3050 if (pPresent->DmaBufferPrivateDataSize < sizeof (VBOXWDDM_DMA_PRIVATE_DATA))
3051 {
3052 drprintf((__FUNCTION__": Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXWDDM_DMA_PRIVATE_DATA (%d)\n", pPresent->DmaBufferPrivateDataSize , sizeof (VBOXWDDM_DMA_PRIVATE_DATA)));
3053 /* @todo: can this actually happen? what status tu return? */
3054 return STATUS_INVALID_PARAMETER;
3055 }
3056
3057 PVBOXWDDM_DMA_PRIVATE_DATA pPrivateData = (PVBOXWDDM_DMA_PRIVATE_DATA)pPresent->pDmaBufferPrivateData;
3058 pPrivateData->pContext = (PVBOXWDDM_CONTEXT)hContext;
3059
3060 if (pPresent->Flags.Blt)
3061 {
3062 Assert(pPresent->Flags.Value == 1); /* only Blt is set, we do not support anything else for now */
3063 UINT cbCmd = pPresent->DmaSize;
3064
3065 Assert(pPresent->SubRectCnt);
3066 UINT cmdSize = VBOXVDMACMD_DMA_PRESENT_BLT_SIZE(pPresent->SubRectCnt - pPresent->MultipassOffset);
3067 PVBOXVDMACMD pCmd = (PVBOXVDMACMD)pPresent->pDmaBuffer;
3068 pPresent->pDmaBuffer = ((uint8_t*)pPresent->pDmaBuffer) + cmdSize;
3069 Assert(cbCmd >= VBOXVDMACMD_DMA_PRESENT_BLT_MINSIZE());
3070 if (cbCmd >= VBOXVDMACMD_DMA_PRESENT_BLT_MINSIZE())
3071 {
3072 DXGK_ALLOCATIONLIST *pSrc = &pPresent->pAllocationList[DXGK_PRESENT_SOURCE_INDEX];
3073 DXGK_ALLOCATIONLIST *pDst = &pPresent->pAllocationList[DXGK_PRESENT_DESTINATION_INDEX];
3074 PVBOXWDDM_ALLOCATION pSrcAlloc = vboxWddmGetAllocationFromAllocList(pDevExt, pSrc);
3075 Assert(pSrcAlloc);
3076 if (pSrcAlloc)
3077 {
3078 PVBOXWDDM_ALLOCATION pDstAlloc = vboxWddmGetAllocationFromAllocList(pDevExt, pDst);
3079 Assert(pDstAlloc);
3080 if (pDstAlloc)
3081 {
3082 if (vboxWddmPixFormatConversionSupported(pSrcAlloc->u.SurfInfo.format, pDstAlloc->u.SurfInfo.format))
3083 {
3084 memset(pPresent->pPatchLocationListOut, 0, 2*sizeof (D3DDDI_PATCHLOCATIONLIST));
3085// pPresent->pPatchLocationListOut->PatchOffset = 0;
3086// ++pPresent->pPatchLocationListOut;
3087 pPresent->pPatchLocationListOut->PatchOffset = VBOXVDMACMD_BODY_FIELD_OFFSET(UINT, VBOXVDMACMD_DMA_PRESENT_BLT, offSrc);
3088 pPresent->pPatchLocationListOut->AllocationIndex = DXGK_PRESENT_SOURCE_INDEX;
3089 ++pPresent->pPatchLocationListOut;
3090 pPresent->pPatchLocationListOut->PatchOffset = VBOXVDMACMD_BODY_FIELD_OFFSET(UINT, VBOXVDMACMD_DMA_PRESENT_BLT, offDst);
3091 pPresent->pPatchLocationListOut->AllocationIndex = DXGK_PRESENT_DESTINATION_INDEX;
3092 ++pPresent->pPatchLocationListOut;
3093
3094 pCmd->enmType = VBOXVDMACMD_TYPE_DMA_PRESENT_BLT;
3095 pCmd->u32CmdSpecific = 0;
3096 PVBOXVDMACMD_DMA_PRESENT_BLT pTransfer = VBOXVDMACMD_BODY(pCmd, VBOXVDMACMD_DMA_PRESENT_BLT);
3097 pTransfer->offSrc = (VBOXVIDEOOFFSET)pSrc->PhysicalAddress.QuadPart;
3098 pTransfer->offDst = (VBOXVIDEOOFFSET)pDst->PhysicalAddress.QuadPart;
3099 vboxWddmSurfDescFromAllocation(pSrcAlloc, &pTransfer->srcDesc);
3100 vboxWddmSurfDescFromAllocation(pDstAlloc, &pTransfer->dstDesc);
3101 vboxWddmRectlFromRect(&pPresent->SrcRect, &pTransfer->srcRectl);
3102 vboxWddmRectlFromRect(&pPresent->DstRect, &pTransfer->dstRectl);
3103 UINT i = 0;
3104 cbCmd -= VBOXVDMACMD_BODY_FIELD_OFFSET(UINT, VBOXVDMACMD_DMA_PRESENT_BLT, aDstSubRects);
3105 Assert(cbCmd >= sizeof (VBOXVDMA_RECTL));
3106 Assert(cbCmd < pPresent->DmaSize);
3107 for (; i < pPresent->SubRectCnt; ++i)
3108 {
3109 if (cbCmd < sizeof (VBOXVDMA_RECTL))
3110 {
3111 Assert(i);
3112 pPresent->MultipassOffset += i;
3113 Status = STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER;
3114 break;
3115 }
3116 vboxWddmRectlFromRect(&pPresent->pDstSubRects[i + pPresent->MultipassOffset], &pTransfer->aDstSubRects[i]);
3117 cbCmd -= sizeof (VBOXVDMA_RECTL);
3118 }
3119 Assert(i);
3120 pTransfer->cDstSubRects = i;
3121 pPresent->pDmaBufferPrivateData = (uint8_t*)pPresent->pDmaBufferPrivateData + sizeof(VBOXWDDM_DMA_PRIVATE_DATA);
3122 }
3123 else
3124 {
3125 AssertBreakpoint();
3126 drprintf((__FUNCTION__": unsupported format conversion from(%d) to (%d)\n",pSrcAlloc->u.SurfInfo.format, pDstAlloc->u.SurfInfo.format));
3127 Status = STATUS_GRAPHICS_CANNOTCOLORCONVERT;
3128 }
3129 }
3130 else
3131 {
3132 /* this should not happen actually */
3133 drprintf((__FUNCTION__": failed to get Dst Allocation info for hDeviceSpecificAllocation(0x%x)\n",pDst->hDeviceSpecificAllocation));
3134 Status = STATUS_INVALID_HANDLE;
3135 }
3136 }
3137 else
3138 {
3139 /* this should not happen actually */
3140 drprintf((__FUNCTION__": failed to get Src Allocation info for hDeviceSpecificAllocation(0x%x)\n",pSrc->hDeviceSpecificAllocation));
3141 Status = STATUS_INVALID_HANDLE;
3142 }
3143 }
3144 else
3145 {
3146 /* this should not happen actually */
3147 drprintf((__FUNCTION__": cbCmd too small!! (%d)\n", cbCmd));
3148 Status = STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER;
3149 }
3150
3151 }
3152 else
3153 {
3154 drprintf((__FUNCTION__": cmd NOT IMPLEMENTED!! Flags(0x%x)\n", pPresent->Flags.Value));
3155 AssertBreakpoint();
3156 }
3157
3158// dfprintf(("<== "__FUNCTION__ ", hContext(0x%x), Status(0x%x)\n", hContext, Status));
3159
3160 return Status;
3161}
3162
3163NTSTATUS
3164APIENTRY
3165DxgkDdiUpdateOverlay(
3166 CONST HANDLE hOverlay,
3167 CONST DXGKARG_UPDATEOVERLAY *pUpdateOverlay)
3168{
3169 dfprintf(("==> "__FUNCTION__ ", hOverlay(0x%x)\n", hOverlay));
3170 AssertBreakpoint();
3171 dfprintf(("<== "__FUNCTION__ ", hOverlay(0x%x)\n", hOverlay));
3172 return STATUS_NOT_IMPLEMENTED;
3173}
3174
3175NTSTATUS
3176APIENTRY
3177DxgkDdiFlipOverlay(
3178 CONST HANDLE hOverlay,
3179 CONST DXGKARG_FLIPOVERLAY *pFlipOverlay)
3180{
3181 dfprintf(("==> "__FUNCTION__ ", hOverlay(0x%x)\n", hOverlay));
3182 AssertBreakpoint();
3183 dfprintf(("<== "__FUNCTION__ ", hOverlay(0x%x)\n", hOverlay));
3184 return STATUS_NOT_IMPLEMENTED;
3185}
3186
3187NTSTATUS
3188APIENTRY
3189DxgkDdiDestroyOverlay(
3190 CONST HANDLE hOverlay)
3191{
3192 dfprintf(("==> "__FUNCTION__ ", hOverlay(0x%x)\n", hOverlay));
3193 AssertBreakpoint();
3194 dfprintf(("<== "__FUNCTION__ ", hOverlay(0x%x)\n", hOverlay));
3195 return STATUS_NOT_IMPLEMENTED;
3196}
3197
3198/**
3199 * DxgkDdiCreateContext
3200 */
3201NTSTATUS
3202APIENTRY
3203DxgkDdiCreateContext(
3204 CONST HANDLE hDevice,
3205 DXGKARG_CREATECONTEXT *pCreateContext)
3206{
3207 /* DxgkDdiCreateContext should be made pageable */
3208 PAGED_CODE();
3209
3210 dfprintf(("==> "__FUNCTION__ ", hDevice(0x%x)\n", hDevice));
3211
3212 vboxVDbgBreakFv();
3213
3214 NTSTATUS Status = STATUS_SUCCESS;
3215 PVBOXWDDM_DEVICE pDevice = (PVBOXWDDM_DEVICE)hDevice;
3216 PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)vboxWddmMemAllocZero(sizeof (VBOXWDDM_CONTEXT));
3217
3218 pContext->pDevice = pDevice;
3219 pContext->hContext = pCreateContext->hContext;
3220 pContext->EngineAffinity = pCreateContext->EngineAffinity;
3221 pContext->NodeOrdinal = pCreateContext->NodeOrdinal;
3222 if (pCreateContext->Flags.SystemContext)
3223 pContext->enmType = VBOXWDDM_CONTEXT_TYPE_SYSTEM;
3224// else
3225// {
3226// AssertBreakpoint(); /* we do not support custom contexts for now */
3227// drprintf((__FUNCTION__ ", we do not support custom contexts for now, hDevice (0x%x)\n", hDevice));
3228// }
3229
3230 pCreateContext->hContext = pContext;
3231 pCreateContext->ContextInfo.DmaBufferSize = VBOXWDDM_C_DMA_BUFFER_SIZE;
3232 pCreateContext->ContextInfo.DmaBufferSegmentSet = 0;
3233 pCreateContext->ContextInfo.DmaBufferPrivateDataSize = sizeof (VBOXWDDM_DMA_PRIVATE_DATA);
3234 pCreateContext->ContextInfo.AllocationListSize = VBOXWDDM_C_ALLOC_LIST_SIZE;
3235 pCreateContext->ContextInfo.PatchLocationListSize = VBOXWDDM_C_PATH_LOCATION_LIST_SIZE;
3236//#if (DXGKDDI_INTERFACE_VERSION >= DXGKDDI_INTERFACE_VERSION_WIN7)
3237//# error port to Win7 DDI
3238// //pCreateContext->ContextInfo.DmaBufferAllocationGroup = ???;
3239//#endif // DXGKDDI_INTERFACE_VERSION
3240
3241 dfprintf(("<== "__FUNCTION__ ", hDevice(0x%x)\n", hDevice));
3242
3243 return Status;
3244}
3245
3246NTSTATUS
3247APIENTRY
3248DxgkDdiDestroyContext(
3249 CONST HANDLE hContext)
3250{
3251 dfprintf(("==> "__FUNCTION__ ", hContext(0x%x)\n", hContext));
3252 vboxVDbgBreakFv();
3253 vboxWddmMemFree(hContext);
3254 dfprintf(("<== "__FUNCTION__ ", hContext(0x%x)\n", hContext));
3255 return STATUS_SUCCESS;
3256}
3257
3258NTSTATUS
3259APIENTRY
3260DxgkDdiLinkDevice(
3261 __in CONST PDEVICE_OBJECT PhysicalDeviceObject,
3262 __in CONST PVOID MiniportDeviceContext,
3263 __inout PLINKED_DEVICE LinkedDevice
3264 )
3265{
3266 drprintf(("==> "__FUNCTION__ ", MiniportDeviceContext(0x%x)\n", MiniportDeviceContext));
3267 vboxVDbgBreakFv();
3268 AssertBreakpoint();
3269 drprintf(("<== "__FUNCTION__ ", MiniportDeviceContext(0x%x)\n", MiniportDeviceContext));
3270 return STATUS_NOT_IMPLEMENTED;
3271}
3272
3273NTSTATUS
3274APIENTRY
3275DxgkDdiSetDisplayPrivateDriverFormat(
3276 CONST HANDLE hAdapter,
3277 /*CONST*/ DXGKARG_SETDISPLAYPRIVATEDRIVERFORMAT* pSetDisplayPrivateDriverFormat
3278 )
3279{
3280 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
3281 vboxVDbgBreakFv();
3282 AssertBreakpoint();
3283 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
3284 return STATUS_SUCCESS;
3285}
3286
3287NTSTATUS APIENTRY CALLBACK DxgkDdiRestartFromTimeout(IN_CONST_HANDLE hAdapter)
3288{
3289 dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
3290 vboxVDbgBreakFv();
3291 AssertBreakpoint();
3292 dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
3293 return STATUS_SUCCESS;
3294}
3295
3296NTSTATUS
3297DriverEntry(
3298 IN PDRIVER_OBJECT DriverObject,
3299 IN PUNICODE_STRING RegistryPath
3300 )
3301{
3302 PAGED_CODE();
3303
3304 AssertBreakpoint();
3305
3306 drprintf(("VBoxVideoWddm::DriverEntry. Built %s %s\n", __DATE__, __TIME__));
3307
3308 DRIVER_INITIALIZATION_DATA DriverInitializationData = {'\0'};
3309
3310 if (! ARGUMENT_PRESENT(DriverObject) ||
3311 ! ARGUMENT_PRESENT(RegistryPath))
3312 {
3313 return STATUS_INVALID_PARAMETER;
3314 }
3315
3316 // Fill in the DriverInitializationData structure and call DxgkInitialize()
3317 DriverInitializationData.Version = DXGKDDI_INTERFACE_VERSION;
3318
3319 DriverInitializationData.DxgkDdiAddDevice = DxgkDdiAddDevice;
3320 DriverInitializationData.DxgkDdiStartDevice = DxgkDdiStartDevice;
3321 DriverInitializationData.DxgkDdiStopDevice = DxgkDdiStopDevice;
3322 DriverInitializationData.DxgkDdiRemoveDevice = DxgkDdiRemoveDevice;
3323 DriverInitializationData.DxgkDdiDispatchIoRequest = DxgkDdiDispatchIoRequest;
3324 DriverInitializationData.DxgkDdiInterruptRoutine = DxgkDdiInterruptRoutine;
3325 DriverInitializationData.DxgkDdiDpcRoutine = DxgkDdiDpcRoutine;
3326 DriverInitializationData.DxgkDdiQueryChildRelations = DxgkDdiQueryChildRelations;
3327 DriverInitializationData.DxgkDdiQueryChildStatus = DxgkDdiQueryChildStatus;
3328 DriverInitializationData.DxgkDdiQueryDeviceDescriptor = DxgkDdiQueryDeviceDescriptor;
3329 DriverInitializationData.DxgkDdiSetPowerState = DxgkDdiSetPowerState;
3330 DriverInitializationData.DxgkDdiNotifyAcpiEvent = DxgkDdiNotifyAcpiEvent;
3331 DriverInitializationData.DxgkDdiResetDevice = DxgkDdiResetDevice;
3332 DriverInitializationData.DxgkDdiUnload = DxgkDdiUnload;
3333 DriverInitializationData.DxgkDdiQueryInterface = DxgkDdiQueryInterface;
3334 DriverInitializationData.DxgkDdiControlEtwLogging = DxgkDdiControlEtwLogging;
3335
3336 DriverInitializationData.DxgkDdiQueryAdapterInfo = DxgkDdiQueryAdapterInfo;
3337 DriverInitializationData.DxgkDdiCreateDevice = DxgkDdiCreateDevice;
3338 DriverInitializationData.DxgkDdiCreateAllocation = DxgkDdiCreateAllocation;
3339 DriverInitializationData.DxgkDdiDestroyAllocation = DxgkDdiDestroyAllocation;
3340 DriverInitializationData.DxgkDdiDescribeAllocation = DxgkDdiDescribeAllocation;
3341 DriverInitializationData.DxgkDdiGetStandardAllocationDriverData = DxgkDdiGetStandardAllocationDriverData;
3342 DriverInitializationData.DxgkDdiAcquireSwizzlingRange = DxgkDdiAcquireSwizzlingRange;
3343 DriverInitializationData.DxgkDdiReleaseSwizzlingRange = DxgkDdiReleaseSwizzlingRange;
3344 DriverInitializationData.DxgkDdiPatch = DxgkDdiPatch;
3345 DriverInitializationData.DxgkDdiSubmitCommand = DxgkDdiSubmitCommand;
3346 DriverInitializationData.DxgkDdiPreemptCommand = DxgkDdiPreemptCommand;
3347 DriverInitializationData.DxgkDdiBuildPagingBuffer = DxgkDdiBuildPagingBuffer;
3348 DriverInitializationData.DxgkDdiSetPalette = DxgkDdiSetPalette;
3349 DriverInitializationData.DxgkDdiSetPointerPosition = DxgkDdiSetPointerPosition;
3350 DriverInitializationData.DxgkDdiSetPointerShape = DxgkDdiSetPointerShape;
3351 DriverInitializationData.DxgkDdiResetFromTimeout = DxgkDdiResetFromTimeout;
3352 DriverInitializationData.DxgkDdiRestartFromTimeout = DxgkDdiRestartFromTimeout;
3353 DriverInitializationData.DxgkDdiEscape = DxgkDdiEscape;
3354 DriverInitializationData.DxgkDdiCollectDbgInfo = DxgkDdiCollectDbgInfo;
3355 DriverInitializationData.DxgkDdiQueryCurrentFence = DxgkDdiQueryCurrentFence;
3356 DriverInitializationData.DxgkDdiIsSupportedVidPn = DxgkDdiIsSupportedVidPn;
3357 DriverInitializationData.DxgkDdiRecommendFunctionalVidPn = DxgkDdiRecommendFunctionalVidPn;
3358 DriverInitializationData.DxgkDdiEnumVidPnCofuncModality = DxgkDdiEnumVidPnCofuncModality;
3359 DriverInitializationData.DxgkDdiSetVidPnSourceAddress = DxgkDdiSetVidPnSourceAddress;
3360 DriverInitializationData.DxgkDdiSetVidPnSourceVisibility = DxgkDdiSetVidPnSourceVisibility;
3361 DriverInitializationData.DxgkDdiCommitVidPn = DxgkDdiCommitVidPn;
3362 DriverInitializationData.DxgkDdiUpdateActiveVidPnPresentPath = DxgkDdiUpdateActiveVidPnPresentPath;
3363 DriverInitializationData.DxgkDdiRecommendMonitorModes = DxgkDdiRecommendMonitorModes;
3364 DriverInitializationData.DxgkDdiRecommendVidPnTopology = DxgkDdiRecommendVidPnTopology;
3365 DriverInitializationData.DxgkDdiGetScanLine = DxgkDdiGetScanLine;
3366 DriverInitializationData.DxgkDdiStopCapture = DxgkDdiStopCapture;
3367 DriverInitializationData.DxgkDdiControlInterrupt = DxgkDdiControlInterrupt;
3368 DriverInitializationData.DxgkDdiCreateOverlay = DxgkDdiCreateOverlay;
3369
3370 DriverInitializationData.DxgkDdiDestroyDevice = DxgkDdiDestroyDevice;
3371 DriverInitializationData.DxgkDdiOpenAllocation = DxgkDdiOpenAllocation;
3372 DriverInitializationData.DxgkDdiCloseAllocation = DxgkDdiCloseAllocation;
3373 DriverInitializationData.DxgkDdiRender = DxgkDdiRender;
3374 DriverInitializationData.DxgkDdiPresent = DxgkDdiPresent;
3375
3376 DriverInitializationData.DxgkDdiUpdateOverlay = DxgkDdiUpdateOverlay;
3377 DriverInitializationData.DxgkDdiFlipOverlay = DxgkDdiFlipOverlay;
3378 DriverInitializationData.DxgkDdiDestroyOverlay = DxgkDdiDestroyOverlay;
3379
3380 DriverInitializationData.DxgkDdiCreateContext = DxgkDdiCreateContext;
3381 DriverInitializationData.DxgkDdiDestroyContext = DxgkDdiDestroyContext;
3382
3383 DriverInitializationData.DxgkDdiLinkDevice = NULL; //DxgkDdiLinkDevice;
3384 DriverInitializationData.DxgkDdiSetDisplayPrivateDriverFormat = DxgkDdiSetDisplayPrivateDriverFormat;
3385//#if (DXGKDDI_INTERFACE_VERSION >= DXGKDDI_INTERFACE_VERSION_WIN7)
3386//# error port to Win7 DDI
3387// DriverInitializationData.DxgkDdiRenderKm = DxgkDdiRenderKm;
3388// DriverInitializationData.DxgkDdiRestartFromTimeout = DxgkDdiRestartFromTimeout;
3389// DriverInitializationData.DxgkDdiSetVidPnSourceVisibility = DxgkDdiSetVidPnSourceVisibility;
3390// DriverInitializationData.DxgkDdiUpdateActiveVidPnPresentPath = DxgkDdiUpdateActiveVidPnPresentPath;
3391// DriverInitializationData.DxgkDdiQueryVidPnHWCapability = DxgkDdiQueryVidPnHWCapability;
3392//#endif
3393
3394 return DxgkInitialize(DriverObject,
3395 RegistryPath,
3396 &DriverInitializationData);
3397}
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