VirtualBox

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

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

wddm: correctly report framebuffer offset to VGA device

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