VirtualBox

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

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

wddm/2d: bugfixing + more impl

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