VirtualBox

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

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

Automated rebranding to Oracle copyright/license strings via filemuncher

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

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