VirtualBox

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

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

wddm/2D: more impl (get caps + initialization working)

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

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