VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Display/dd.c@ 21553

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

video hw accel: overlay & flip fixes

  • Property svn:eol-style set to native
File size: 70.2 KB
Line 
1#ifdef VBOX_WITH_DDRAW
2
3/******************************Module*Header**********************************\
4*
5 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
6 *
7 * This file is part of VirtualBox Open Source Edition (OSE), as
8 * available from http://www.virtualbox.org. This file is free software;
9 * you can redistribute it and/or modify it under the terms of the GNU
10 * General Public License (GPL) as published by the Free Software
11 * Foundation, in version 2 as it comes in the "COPYING" file of the
12 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
13 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
14 *
15 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
16 * Clara, CA 95054 USA or visit http://www.sun.com if you need
17 * additional information or have any questions.
18*/
19/*
20* Based in part on Microsoft DDK sample code
21*
22* **************************
23* * DirectDraw SAMPLE CODE *
24* **************************
25*
26* Module Name: ddenable.c
27*
28* Content:
29*
30* Copyright (c) 1994-1998 3Dlabs Inc. Ltd. All rights reserved.
31* Copyright (c) 1995-1999 Microsoft Corporation. All rights reserved.
32\*****************************************************************************/
33
34#include "driver.h"
35#include "dd.h"
36#undef CO_E_NOTINITIALIZED
37#include <winerror.h>
38
39#if 0
40static DWORD APIENTRY DdCreateSurface(PDD_CREATESURFACEDATA lpCreateSurface);
41#endif
42
43#ifdef VBOX_WITH_VIDEOHWACCEL
44#include <iprt/asm.h>
45
46#define VBOXVHWA_CAP(_pdev, _cap) ((_pdev)->vhwaInfo.caps & (_cap))
47static bool getDDHALInfo(PPDEV pDev, DD_HALINFO* pHALInfo);
48static DECLCALLBACK(void) vboxVHWAFreeCmdCompletion(PPDEV ppdev, VBOXVHWACMD * pCmd, void * pContext);
49static DECLCALLBACK(void) vboxVHWASurfBltCompletion(PPDEV ppdev, VBOXVHWACMD * pCmd, void * pContext);
50static DECLCALLBACK(void) vboxVHWASurfFlipCompletion(PPDEV ppdev, VBOXVHWACMD * pCmd, void * pContext);
51#endif
52
53/**
54 * DrvGetDirectDrawInfo
55 *
56 * The DrvGetDirectDrawInfo function returns the capabilities of the graphics hardware.
57 *
58 * Parameters:
59 *
60 * dhpdev
61 * Handle to the PDEV returned by the driver’s DrvEnablePDEV routine.
62 * pHalInfo
63 * Points to a DD_HALINFO structure in which the driver should return the hardware capabilities that it supports.
64 * pdwNumHeaps
65 * Points to the location in which the driver should return the number of VIDEOMEMORY structures pointed to by pvmList.
66 * pvmList
67 * Points to an array of VIDEOMEMORY structures in which the driver should return information about each display memory chunk that it controls. The driver should ignore this parameter when it is NULL.
68 * pdwNumFourCCCodes
69 * Points to the location in which the driver should return the number of DWORDs pointed to by pdwFourCC.
70 * pdwFourCC
71 * Points to an array of DWORDs in which the driver should return information about each FOURCC that it supports. The driver should ignore this parameter when it is NULL.
72 *
73 * Return Value:
74 *
75 * DrvGetDirectDrawInfo returns TRUE if it succeeds; otherwise, it returns FALSE.
76 *
77 */
78BOOL APIENTRY DrvGetDirectDrawInfo(
79 DHPDEV dhpdev,
80 DD_HALINFO *pHalInfo,
81 DWORD *pdwNumHeaps,
82 VIDEOMEMORY *pvmList,
83 DWORD *pdwNumFourCCCodes,
84 DWORD *pdwFourCC
85 )
86{
87 PPDEV pDev = (PPDEV)dhpdev;
88 BOOL bDefineDDrawHeap = FALSE;
89 DWORD cHeaps = 0;
90 VIDEOMEMORY *pVm = NULL;
91
92 DISPDBG((0, "%s: %p, %p, %p, %p, %p. %p\n", __FUNCTION__, dhpdev, pHalInfo, pdwNumHeaps, pvmList, pdwNumFourCCCodes, pdwFourCC));
93
94 *pdwNumFourCCCodes = 0;
95 *pdwNumHeaps = 0;
96
97 /* Setup the HAL driver caps. */
98 pHalInfo->dwSize = sizeof(DD_HALINFO);
99#ifndef VBOX_WITH_VIDEOHWACCEL
100 pHalInfo->dwFlags = 0;
101#endif
102
103 if (!(pvmList && pdwFourCC))
104 {
105#ifdef VBOX_WITH_VIDEOHWACCEL
106 vboxVHWAInit();
107
108 memset(pHalInfo, 0, sizeof(DD_HALINFO));
109 pHalInfo->dwSize = sizeof(DD_HALINFO);
110
111 vboxVHWAInitHostInfo1(pDev);
112#else
113 memset(&pHalInfo->ddCaps, 0, sizeof(DDNTCORECAPS));
114#endif
115
116 pHalInfo->ddCaps.dwSize = sizeof(DDNTCORECAPS);
117 pHalInfo->ddCaps.dwVidMemTotal = pDev->layout.cbDDRAWHeap;
118 pHalInfo->ddCaps.dwVidMemFree = pHalInfo->ddCaps.dwVidMemTotal;
119
120 pHalInfo->ddCaps.dwCaps = 0;
121 pHalInfo->ddCaps.dwCaps2 = 0;
122
123 /* Declare we can handle textures wider than the primary */
124 pHalInfo->ddCaps.dwCaps2 |= DDCAPS2_WIDESURFACES;
125
126 pHalInfo->ddCaps.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
127
128 /* Create primary surface attributes */
129 pHalInfo->vmiData.pvPrimary = pDev->pjScreen;
130 pHalInfo->vmiData.fpPrimary = 0;
131 pHalInfo->vmiData.dwDisplayWidth = pDev->cxScreen;
132 pHalInfo->vmiData.dwDisplayHeight = pDev->cyScreen;
133 pHalInfo->vmiData.lDisplayPitch = pDev->lDeltaScreen;
134
135 pHalInfo->vmiData.ddpfDisplay.dwSize = sizeof(DDPIXELFORMAT);
136 pHalInfo->vmiData.ddpfDisplay.dwFlags = DDPF_RGB;
137 pHalInfo->vmiData.ddpfDisplay.dwRGBBitCount = pDev->ulBitCount;
138 DISPDBG((0, "pvPrimary %x\n", pHalInfo->vmiData.pvPrimary));
139 DISPDBG((0, "fpPrimary %x\n", pHalInfo->vmiData.fpPrimary));
140 DISPDBG((0, "dwDisplayWidth %d\n", pHalInfo->vmiData.dwDisplayWidth));
141 DISPDBG((0, "dwDisplayHeight %d\n", pHalInfo->vmiData.dwDisplayHeight));
142 DISPDBG((0, "lDisplayPitch %d\n", pHalInfo->vmiData.lDisplayPitch));
143 DISPDBG((0, "dwRGBBitCount %d\n", pHalInfo->vmiData.ddpfDisplay.dwRGBBitCount));
144
145 if (pDev->ulBitmapType == BMF_8BPP)
146 {
147 pHalInfo->vmiData.ddpfDisplay.dwFlags |= DDPF_PALETTEINDEXED8;
148 DISPDBG((0, "DDPF_PALETTEINDEXED8\n"));
149 }
150
151 pHalInfo->vmiData.ddpfDisplay.dwRBitMask = pDev->flRed;
152 pHalInfo->vmiData.ddpfDisplay.dwGBitMask = pDev->flGreen;
153 pHalInfo->vmiData.ddpfDisplay.dwBBitMask = pDev->flBlue;
154
155 pHalInfo->vmiData.dwOffscreenAlign = 4;
156 pHalInfo->vmiData.dwZBufferAlign = 4;
157 pHalInfo->vmiData.dwTextureAlign = 4;
158
159
160#ifdef VBOX_WITH_VIDEOHWACCEL
161 if(pDev->vhwaInfo.bVHWAEnabled)
162 {
163 pHalInfo->vmiData.dwOverlayAlign = 4;
164
165 pDev->vhwaInfo.bVHWAEnabled = getDDHALInfo(pDev, pHalInfo);
166 }
167#endif
168 }
169
170 cHeaps = 0;
171
172 /* Do we have sufficient videomemory to create an off-screen heap for DDraw? */
173 if (pDev->layout.cbDDRAWHeap > 0)
174 {
175 bDefineDDrawHeap = TRUE;
176 cHeaps++;
177 }
178
179 pDev->cHeaps = cHeaps;
180 *pdwNumHeaps = cHeaps;
181
182 // If pvmList is not NULL then we can go ahead and fill out the VIDEOMEMORY
183 // structures which define our requested heaps.
184
185 if(pvmList) {
186
187 pVm=pvmList;
188
189 //
190 // Snag a pointer to the video-memory list so that we can use it to
191 // call back to DirectDraw to allocate video memory:
192 //
193 pDev->pvmList = pVm;
194
195 //
196 // Define the heap for DirectDraw
197 //
198 if ( bDefineDDrawHeap )
199 {
200 pVm->dwFlags = VIDMEM_ISLINEAR ;
201 pVm->fpStart = pDev->layout.offDDRAWHeap;
202 pVm->fpEnd = pDev->layout.offDDRAWHeap + pDev->layout.cbDDRAWHeap - 1; /* inclusive */
203#ifndef VBOX_WITH_VIDEOHWACCEL
204 pVm->ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
205#endif
206 DISPDBG((0, "fpStart %x fpEnd %x\n", pVm->fpStart, pVm->fpEnd));
207
208 pVm++;
209 }
210 }
211
212#ifdef VBOX_WITH_VIDEOHWACCEL
213 if(pDev->vhwaInfo.bVHWAEnabled)
214 {
215// // TODO: filter out hw-unsupported fourccs
216//#define FOURCC_YUV422 (MAKEFOURCC('Y','U','Y','2'))
217//#define FOURCC_YUV411 (MAKEFOURCC('Y','4','1','1'))
218//
219// static DWORD fourCC[] = { FOURCC_YUV422, FOURCC_YUV411 }; // The FourCC's we support
220
221 *pdwNumFourCCCodes = pDev->vhwaInfo.numFourCC;
222
223 if (pdwFourCC && pDev->vhwaInfo.numFourCC)
224 {
225 int rc = vboxVHWAInitHostInfo2(pDev, pdwFourCC);
226 if(RT_FAILURE(rc))
227 {
228 *pdwNumFourCCCodes = 0;
229 pDev->vhwaInfo.numFourCC = 0;
230 }
231 }
232 }
233#endif
234
235#ifdef VBOX_WITH_VIDEOHWACCEL
236 if(pDev->vhwaInfo.bVHWAEnabled)
237 {
238 /* we need it to set DDHAL_PRIVATECAP_NOTIFYPRIMARYCREATION to make ddraw call us for primary surface creation */
239 /* DX5 and up */
240 pHalInfo->GetDriverInfo = DdGetDriverInfo;
241 pHalInfo->dwFlags |= DDHALINFO_GETDRIVERINFOSET;
242 }
243#endif
244
245#if 0
246 /* No 3D capabilities */
247 if (pHalInfo->lpD3DGlobalDriverData)
248 {
249 LPD3DHAL_GLOBALDRIVERDATA lpD3DGlobalDriverData = (LPD3DHAL_GLOBALDRIVERDATA)pHalInfo->lpD3DGlobalDriverData;
250 lpD3DGlobalDriverData->dwSize = sizeof(D3DHAL_GLOBALDRIVERDATA);
251 }
252#endif
253 return TRUE;
254}
255
256/**
257 * DrvEnableDirectDraw
258 *
259 * The DrvEnableDirectDraw function enables hardware for DirectDraw use.
260 *
261 * Parameters
262 *
263 * dhpdev
264 * Handle to the PDEV returned by the driver’s DrvEnablePDEV routine.
265 * pCallBacks
266 * Points to the DD_CALLBACKS structure to be initialized by the driver.
267 * pSurfaceCallBacks
268 * Points to the DD_SURFACECALLBACKS structure to be initialized by the driver.
269 * pPaletteCallBacks
270 * Points to the DD_PALETTECALLBACKS structure to be initialized by the driver.
271 *
272 * Return Value
273 *
274 * DrvEnableDirectDraw returns TRUE if it succeeds; otherwise, it returns FALSE.
275 *
276 */
277BOOL APIENTRY DrvEnableDirectDraw(
278 DHPDEV dhpdev,
279 DD_CALLBACKS *pCallBacks,
280 DD_SURFACECALLBACKS *pSurfaceCallBacks,
281 DD_PALETTECALLBACKS *pPaletteCallBacks
282 )
283{
284#ifdef VBOX_WITH_VIDEOHWACCEL
285 PPDEV pDev = (PPDEV)dhpdev;
286
287#endif
288
289 DISPDBG((0, "%s: %p, %p, %p, %p\n", __FUNCTION__, dhpdev, pCallBacks, pSurfaceCallBacks, pPaletteCallBacks));
290
291 /* Fill in the HAL Callback pointers */
292 pCallBacks->dwSize = sizeof(DD_CALLBACKS);
293 pCallBacks->dwFlags = 0;
294
295 pCallBacks->dwFlags = DDHAL_CB32_CREATESURFACE | DDHAL_CB32_CANCREATESURFACE | DDHAL_CB32_MAPMEMORY;
296 pCallBacks->CreateSurface = DdCreateSurface;
297 pCallBacks->CanCreateSurface = DdCanCreateSurface;
298 pCallBacks->MapMemory = DdMapMemory;
299 // pCallBacks->WaitForVerticalBlank = DdWaitForVerticalBlank;
300 // pCallBacks->GetScanLine = DdGetScanLine;
301 // DDHAL_CB32_WAITFORVERTICALBLANK | DDHAL_CB32_GETSCANLINE
302 /* Note: pCallBacks->SetMode & pCallBacks->DestroyDriver are unused in Windows 2000 and up */
303
304 /* Fill in the Surface Callback pointers */
305 pSurfaceCallBacks->dwSize = sizeof(DD_SURFACECALLBACKS);
306 pSurfaceCallBacks->dwFlags = DDHAL_SURFCB32_LOCK | DDHAL_SURFCB32_UNLOCK;
307 pSurfaceCallBacks->Lock = DdLock;
308 pSurfaceCallBacks->Unlock = DdUnlock;
309
310 /*
311 pSurfaceCallBacks->dwFlags = DDHAL_SURFCB32_DESTROYSURFACE | DDHAL_SURFCB32_LOCK; // DDHAL_SURFCB32_UNLOCK;
312 pSurfaceCallBacks->DestroySurface = DdDestroySurface;
313 pSurfaceCallBacks->Flip = DdFlip;
314 pSurfaceCallBacks->GetBltStatus = DdGetBltStatus;
315 pSurfaceCallBacks->GetFlipStatus = DdGetFlipStatus;
316 pSurfaceCallBacks->Blt = DdBlt;
317 DDHAL_SURFCB32_FLIP | DDHAL_SURFCB32_BLT | DDHAL_SURFCB32_GETBLTSTATUS | DDHAL_SURFCB32_GETFLIPSTATUS;
318 */
319
320// pSurfaceCallBacks.SetColorKey = DdSetColorKey;
321// pSurfaceCallBacks.dwFlags |= DDHAL_SURFCB32_SETCOLORKEY;
322
323 /* Fill in the Palette Callback pointers */
324 pPaletteCallBacks->dwSize = sizeof(DD_PALETTECALLBACKS);
325 pPaletteCallBacks->dwFlags = 0;
326
327#ifdef VBOX_WITH_VIDEOHWACCEL
328 if(pDev->vhwaInfo.bVHWAEnabled)
329 {
330 //TODO: filter out those we do not need in case not supported by hw
331 pSurfaceCallBacks->DestroySurface = DdDestroySurface;
332// pSurfaceCallBacks->Lock = DdLock;
333// pSurfaceCallBacks->Unlock = DdUnlock;
334 pSurfaceCallBacks->GetBltStatus = DdGetBltStatus;
335 pSurfaceCallBacks->GetFlipStatus = DdGetFlipStatus;
336 pSurfaceCallBacks->SetColorKey = DdSetColorKey;
337 pSurfaceCallBacks->Flip = DdFlip;
338 pSurfaceCallBacks->Blt = DdBlt;
339
340 pSurfaceCallBacks->dwFlags |= DDHAL_SURFCB32_DESTROYSURFACE |
341 DDHAL_SURFCB32_FLIP
342// | DDHAL_SURFCB32_LOCK
343 | DDHAL_SURFCB32_BLT |
344 DDHAL_SURFCB32_GETBLTSTATUS |
345 DDHAL_SURFCB32_GETFLIPSTATUS |
346 DDHAL_SURFCB32_SETCOLORKEY
347// | DDHAL_SURFCB32_UNLOCK
348 ;
349
350 if(pDev->vhwaInfo.caps & VBOXVHWA_CAPS_OVERLAY)
351 {
352 pSurfaceCallBacks->UpdateOverlay = DdUpdateOverlay; // Now supporting overlays.
353 pSurfaceCallBacks->SetOverlayPosition = DdSetOverlayPosition;
354 pSurfaceCallBacks->dwFlags |=
355 DDHAL_SURFCB32_UPDATEOVERLAY | // Now supporting
356 DDHAL_SURFCB32_SETOVERLAYPOSITION ; // overlays.
357 }
358 }
359#endif
360 return TRUE;
361}
362
363/**
364 * DrvDisableDirectDraw
365 *
366 * The DrvDisableDirectDraw function disables hardware for DirectDraw use.
367 *
368 * Parameters
369 *
370 * dhpdev
371 * Handle to the PDEV returned by the driver’s DrvEnablePDEV routine.
372 *
373 */
374VOID APIENTRY DrvDisableDirectDraw( DHPDEV dhpdev)
375{
376 DISPDBG((0, "%s: %p\n", __FUNCTION__, dhpdev));
377}
378
379/**
380 * DdGetDriverInfo
381 *
382 * The DdGetDriverInfo function queries the driver for additional DirectDraw and Direct3D functionality that the driver supports.
383 *
384 * Parameters
385 * lpGetDriverInfo
386 * Points to a DD_GETDRIVERINFODATA structure that contains the information required to perform the query.
387 *
388 * Return Value
389 *
390 * DdGetDriverInfo must return DDHAL_DRIVER_HANDLED.
391 *
392 */
393DWORD CALLBACK DdGetDriverInfo(DD_GETDRIVERINFODATA *lpData)
394{
395 PPDEV pDev = (PPDEV)lpData->dhpdev;
396 DWORD dwSize;
397
398 DISPDBG((0, "%s: %p\n", __FUNCTION__, lpData->dhpdev));
399
400 /* Default to 'not supported' */
401 lpData->ddRVal = DDERR_CURRENTLYNOTAVAIL;
402
403 /* Fill in supported stuff */
404 if (IsEqualIID(&lpData->guidInfo, &GUID_D3DCallbacks3))
405 {
406 DISPDBG((0, " -> GUID_D3DCallbacks3\n"));
407 }
408 else
409 if (IsEqualIID(&lpData->guidInfo, &GUID_D3DExtendedCaps))
410 {
411 DISPDBG((0, " -> GUID_D3DExtendedCaps\n"));
412 }
413 else
414 if (IsEqualIID(&lpData->guidInfo, &GUID_ZPixelFormats))
415 {
416 DISPDBG((0, " -> GUID_ZPixelFormats\n"));
417 }
418 else
419 if (IsEqualIID(&(lpData->guidInfo), &GUID_D3DParseUnknownCommandCallback))
420 {
421 DISPDBG((0, " -> GUID_D3DParseUnknownCommandCallback\n"));
422 }
423 else
424 if (IsEqualIID(&(lpData->guidInfo), &GUID_Miscellaneous2Callbacks))
425 {
426 DISPDBG((0, " -> GUID_Miscellaneous2Callbacks\n"));
427 }
428 else
429 if (IsEqualIID(&(lpData->guidInfo), &GUID_UpdateNonLocalHeap))
430 {
431 DISPDBG((0, " -> GUID_UpdateNonLocalHeap\n"));
432 }
433 else
434 if (IsEqualIID(&(lpData->guidInfo), &GUID_GetHeapAlignment))
435 {
436 DISPDBG((0, " -> GUID_GetHeapAlignment\n"));
437 }
438 else
439 if (IsEqualIID(&(lpData->guidInfo), &GUID_NTPrivateDriverCaps))
440 {
441 DD_NTPRIVATEDRIVERCAPS DDPrivateDriverCaps;
442
443 DISPDBG((0, " -> GUID_NTPrivateDriverCaps\n"));
444
445 memset(&DDPrivateDriverCaps, 0, sizeof(DDPrivateDriverCaps));
446 DDPrivateDriverCaps.dwSize=sizeof(DDPrivateDriverCaps);
447#ifndef VBOX_WITH_VIDEOHWACCEL
448 DDPrivateDriverCaps.dwPrivateCaps = 0; /* DDHAL_PRIVATECAP_NOTIFYPRIMARYCREATION -> call CreateSurface for the primary surface */
449#else
450 DDPrivateDriverCaps.dwPrivateCaps = DDHAL_PRIVATECAP_NOTIFYPRIMARYCREATION; /* -> call CreateSurface for the primary surface */
451#endif
452
453 lpData->dwActualSize =sizeof(DDPrivateDriverCaps);
454
455 dwSize = min(sizeof(DDPrivateDriverCaps),lpData->dwExpectedSize);
456 memcpy(lpData->lpvData, &DDPrivateDriverCaps, dwSize);
457 lpData->ddRVal = DD_OK;
458 }
459 else
460 if (IsEqualIID(&(lpData->guidInfo), &GUID_DDMoreSurfaceCaps))
461 {
462#ifndef VBOX_WITH_VIDEOHWACCEL
463 DD_MORESURFACECAPS DDMoreSurfaceCaps;
464 DDSCAPSEX ddsCapsEx, ddsCapsExAlt;
465
466 DISPDBG((0, " -> GUID_DDMoreSurfaceCaps\n"));
467
468 // fill in everything until expectedsize...
469 memset(&DDMoreSurfaceCaps, 0, sizeof(DDMoreSurfaceCaps));
470
471 // Caps for heaps 2..n
472 memset(&ddsCapsEx, 0, sizeof(ddsCapsEx));
473 memset(&ddsCapsExAlt, 0, sizeof(ddsCapsEx));
474
475 DDMoreSurfaceCaps.dwSize=lpData->dwExpectedSize;
476
477 lpData->dwActualSize = lpData->dwExpectedSize;
478
479 dwSize = min(sizeof(DDMoreSurfaceCaps),lpData->dwExpectedSize);
480 memcpy(lpData->lpvData, &DDMoreSurfaceCaps, dwSize);
481
482 // now fill in other heaps...
483 while (dwSize < lpData->dwExpectedSize)
484 {
485 memcpy( (PBYTE)lpData->lpvData+dwSize,
486 &ddsCapsEx,
487 sizeof(DDSCAPSEX));
488 dwSize += sizeof(DDSCAPSEX);
489 memcpy( (PBYTE)lpData->lpvData+dwSize,
490 &ddsCapsExAlt,
491 sizeof(DDSCAPSEX));
492 dwSize += sizeof(DDSCAPSEX);
493 }
494
495 lpData->ddRVal = DD_OK;
496#else
497 DISPDBG((0, " -> GUID_DDMoreSurfaceCaps\n"));
498#endif
499 }
500 else
501 if (IsEqualIID(&(lpData->guidInfo), &GUID_DDStereoMode))
502 {
503 DISPDBG((0, " -> GUID_DDStereoMode\n"));
504 }
505 else
506 if (IsEqualIID(&(lpData->guidInfo), &GUID_NonLocalVidMemCaps))
507 {
508 DISPDBG((0, " -> GUID_NonLocalVidMemCaps\n"));
509 }
510 else
511 if (IsEqualIID(&lpData->guidInfo, &GUID_NTCallbacks))
512 {
513#ifndef VBOX_WITH_VIDEOHWACCEL
514 DD_NTCALLBACKS NtCallbacks;
515
516 DISPDBG((0, " -> GUID_NTCallbacks\n"));
517 memset(&NtCallbacks, 0, sizeof(NtCallbacks));
518
519 dwSize = min(lpData->dwExpectedSize, sizeof(DD_NTCALLBACKS));
520
521 NtCallbacks.dwSize = dwSize;
522 NtCallbacks.dwFlags = DDHAL_NTCB32_FREEDRIVERMEMORY
523 | DDHAL_NTCB32_SETEXCLUSIVEMODE
524 | DDHAL_NTCB32_FLIPTOGDISURFACE
525 ;
526 NtCallbacks.FreeDriverMemory = DdFreeDriverMemory;
527 NtCallbacks.SetExclusiveMode = DdSetExclusiveMode;
528 NtCallbacks.FlipToGDISurface = DdFlipToGDISurface;
529
530 memcpy(lpData->lpvData, &NtCallbacks, dwSize);
531
532 lpData->ddRVal = DD_OK;
533#else
534 DISPDBG((0, " -> GUID_NTCallbacks\n"));
535#endif
536 }
537 else
538 if (IsEqualIID(&lpData->guidInfo, &GUID_KernelCaps))
539 {
540 DISPDBG((0, " -> GUID_KernelCaps\n"));
541 }
542 else
543 if (IsEqualIID(&lpData->guidInfo, &GUID_KernelCallbacks))
544 {
545 DISPDBG((0, " -> GUID_KernelCallbacks\n"));
546 }
547 else
548 if (IsEqualIID(&lpData->guidInfo, &GUID_MotionCompCallbacks))
549 {
550 DISPDBG((0, " -> GUID_MotionCompCallbacks\n"));
551 }
552 else
553 if (IsEqualIID(&lpData->guidInfo, &GUID_VideoPortCallbacks))
554 {
555 DISPDBG((0, " -> GUID_VideoPortCallbacks\n"));
556 }
557 else
558 if (IsEqualIID(&lpData->guidInfo, &GUID_ColorControlCallbacks))
559 {
560 DISPDBG((0, " -> GUID_ColorControlCallbacks\n"));
561 }
562 else
563 if (IsEqualIID(&lpData->guidInfo, &GUID_VideoPortCaps))
564 {
565 DISPDBG((0, " -> GUID_VideoPortCaps\n"));
566 }
567 else
568 if (IsEqualIID(&lpData->guidInfo, &GUID_D3DCallbacks2))
569 {
570 DISPDBG((0, " -> GUID_D3DCallbacks2\n"));
571 }
572 else
573 if (IsEqualIID(&lpData->guidInfo, &GUID_D3DCallbacks3))
574 {
575 DISPDBG((0, " -> GUID_D3DCallbacks3\n"));
576 }
577
578 /* Always return this */
579 return DDHAL_DRIVER_HANDLED;
580}
581
582/**
583 * DdCreateSurface
584 *
585 * The DdCreateSurface callback function creates a DirectDraw surface.
586 *
587 * lpCreateSurface
588 * Points to a DD_CREATESURFACEDATA structure that contains the information required to create a surface.
589 *
590 * Return Value
591 *
592 * DdCreateSurface returns one of the following callback codes:
593 * DDHAL_DRIVER_HANDLED
594 * DDHAL_DRIVER_NOTHANDLED
595 *
596 */
597DWORD APIENTRY DdCreateSurface(PDD_CREATESURFACEDATA lpCreateSurface)
598{
599 PPDEV pDev = (PPDEV)lpCreateSurface->lpDD->dhpdev;
600 DD_SURFACE_LOCAL* lpSurfaceLocal;
601 DD_SURFACE_GLOBAL* lpSurfaceGlobal;
602 LPDDSURFACEDESC lpSurfaceDesc;
603 LONG lPitch, lBpp;
604
605 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
606
607 lpSurfaceLocal = lpCreateSurface->lplpSList[0];
608 lpSurfaceGlobal = lpSurfaceLocal->lpGbl;
609 lpSurfaceDesc = lpCreateSurface->lpDDSurfaceDesc;
610
611#ifdef VBOX_WITH_VIDEOHWACCEL
612 if(pDev->vhwaInfo.bVHWAEnabled)
613 {
614 VBOXVHWACMD* pCmd;
615 DDPIXELFORMAT * pFormat = &lpSurfaceGlobal->ddpfSurface;
616
617 if(lpSurfaceLocal->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
618 {
619 lBpp = pDev->ulBitCount;
620 lPitch = pDev->lDeltaScreen;
621 }
622 else
623 {
624 if (pFormat->dwFlags & DDPF_PALETTEINDEXED4)
625 {
626 lBpp = 4;
627 lPitch = lpSurfaceGlobal->wWidth/2;
628 lPitch = (lPitch + 31) & ~31;
629 }
630 else
631 if (pFormat->dwFlags & DDPF_PALETTEINDEXED8)
632 {
633 lBpp = 8;
634 lPitch = lpSurfaceGlobal->wWidth;
635 lPitch = (lPitch + 31) & ~31;
636 }
637 else
638 {
639 lBpp = pFormat->dwRGBBitCount;
640 lPitch = lpSurfaceGlobal->wWidth*(lBpp/8);
641 }
642 }
643
644 DISPDBG((0, "New surface (%d,%d)\n", lpSurfaceGlobal->wWidth, lpSurfaceGlobal->wHeight));
645 DISPDBG((0, "BPP %d lPitch=%d\n", lBpp, lPitch));
646#if 1
647 lpSurfaceGlobal->dwBlockSizeX = lPitch;
648 lpSurfaceGlobal->dwBlockSizeY = lpSurfaceGlobal->wHeight;
649 lpSurfaceGlobal->lPitch = lPitch;
650#else
651 lpSurfaceGlobal->dwBlockSizeX = lPitch * lpSurfaceGlobal->wHeight;
652 lpSurfaceGlobal->dwBlockSizeY = 1;
653 lpSurfaceGlobal->lPitch = lPitch;
654#endif
655
656#if 1
657 lpSurfaceDesc->lPitch = lpSurfaceGlobal->lPitch;
658 lpSurfaceDesc->dwFlags |= DDSD_PITCH;
659#endif
660
661 //
662 // Modify surface descriptions as appropriate and let Direct
663 // Draw perform the allocation if the surface was not the primary
664 //
665 if (lpSurfaceLocal->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
666 {
667 DISPDBG((0, "-> primary surface\n"));
668 lpSurfaceGlobal->fpVidMem = 0;
669 }
670 else
671 {
672 DISPDBG((0, "-> secondary surface\n"));
673 lpSurfaceGlobal->fpVidMem = DDHAL_PLEASEALLOC_BLOCKSIZE;
674 }
675
676 pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_CREATE, sizeof(VBOXVHWACMD_SURF_CREATE));
677 if(pCmd)
678 {
679 VBOXVHWACMD_SURF_CREATE * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_CREATE);
680 PVBOXVHWASURFDESC pDesc;
681 int rc;
682
683 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_CREATE));
684
685 rc = vboxVHWAFromDDSURFACEDESC(&pBody->u.in.SurfInfo, lpSurfaceDesc);
686
687 pBody->u.in.SurfInfo.surfCaps = vboxVHWAFromDDSCAPS(lpSurfaceLocal->ddsCaps.dwCaps);
688 pBody->u.in.SurfInfo.flags |= DDSD_CAPS;
689
690 pBody->u.in.SurfInfo.height = lpSurfaceGlobal->wHeight;
691 pBody->u.in.SurfInfo.width = lpSurfaceGlobal->wWidth;
692 pBody->u.in.SurfInfo.flags |= DDSD_HEIGHT | DDSD_WIDTH;
693
694 vboxVHWAFromDDPIXELFORMAT(&pBody->u.in.SurfInfo.PixelFormat, pFormat);
695 pBody->u.in.SurfInfo.flags |= VBOXVHWA_SD_PIXELFORMAT;
696
697 if (lpSurfaceLocal->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
698 {
699 pBody->u.in.offSurface = 0;
700 }
701 else
702 {
703 pBody->u.in.offSurface = VBOXVHWA_OFFSET64_VOID;
704 }
705
706
707 pDesc = vboxVHWASurfDescAlloc();
708 if(pDesc)
709 {
710 pDesc->cBitsPerPixel = lBpp;
711 vboxVHWACommandSubmit(pDev, pCmd);
712 Assert(pCmd->rc == VINF_SUCCESS);
713 if(pCmd->rc == VINF_SUCCESS)
714 {
715 pDesc->hHostHandle = pBody->u.out.hSurf;
716 lpSurfaceGlobal->dwReserved1 = (ULONG_PTR)pDesc;
717 lpCreateSurface->ddRVal = DD_OK;
718 }
719 else
720 {
721 vboxVHWASurfDescFree(pDesc);
722 lpCreateSurface->ddRVal = DDERR_GENERIC;
723 }
724 }
725 vboxVHWACommandFree(pDev, pCmd);
726 }
727 return DDHAL_DRIVER_NOTHANDLED;
728 }
729#endif
730 lpSurfaceGlobal->dwReserved1 = 0;
731
732 if (lpSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED4)
733 {
734 lBpp = 4;
735 lPitch = lpSurfaceGlobal->wWidth/2;
736 lPitch = (lPitch + 31) & ~31;
737 }
738 else
739 if (lpSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8)
740 {
741 lBpp = 8;
742 lPitch = lpSurfaceGlobal->wWidth;
743 lPitch = (lPitch + 31) & ~31;
744 }
745 else
746 {
747 lBpp = lpSurfaceDesc->ddpfPixelFormat.dwRGBBitCount;
748 lPitch = lpSurfaceGlobal->wWidth*(lBpp/8);
749 }
750 DISPDBG((0, "New surface (%d,%d)\n", lpSurfaceGlobal->wWidth, lpSurfaceGlobal->wHeight));
751 DISPDBG((0, "BPP %d lPitch=%d\n", lBpp, lPitch));
752
753 lpSurfaceGlobal->dwBlockSizeX = lPitch;
754 lpSurfaceGlobal->dwBlockSizeY = lpSurfaceGlobal->wHeight;
755 lpSurfaceGlobal->lPitch = lPitch;
756
757 lpSurfaceDesc->lPitch = lpSurfaceGlobal->lPitch;
758 lpSurfaceDesc->dwFlags |= DDSD_PITCH;
759
760 //
761 // Modify surface descriptions as appropriate and let Direct
762 // Draw perform the allocation if the surface was not the primary
763 //
764 if (lpSurfaceLocal->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
765 {
766 DISPDBG((0, "-> primary surface\n"));
767 lpSurfaceGlobal->fpVidMem = 0;
768 }
769 else
770 {
771 DISPDBG((0, "-> secondary surface\n"));
772 lpSurfaceGlobal->fpVidMem = DDHAL_PLEASEALLOC_BLOCKSIZE;
773 }
774
775 return DDHAL_DRIVER_NOTHANDLED;
776}
777
778/**
779 * DdCanCreateSurface
780 *
781 * The DdCanCreateSurface callback function indicates whether the driver can create a surface of the specified surface description.
782 *
783 *
784 * Parameters
785 * lpCanCreateSurface
786 * Points to the DD_CANCREATESURFACEDATA structure containing the information required for the driver to determine whether a surface can be created.
787 *
788 * Return Value
789 *
790 * DdCanCreateSurface returns one of the following callback codes:
791 *
792 * DDHAL_DRIVER_HANDLED
793 * DDHAL_DRIVER_NOTHANDLED
794 *
795 */
796DWORD APIENTRY DdCanCreateSurface(PDD_CANCREATESURFACEDATA lpCanCreateSurface)
797{
798 PPDEV pDev = (PPDEV)lpCanCreateSurface->lpDD->dhpdev;
799
800 PDD_SURFACEDESC lpDDS = lpCanCreateSurface->lpDDSurfaceDesc;
801
802 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
803
804#ifdef VBOX_WITH_VIDEOHWACCEL
805 if(pDev->vhwaInfo.bVHWAEnabled)
806 {
807 VBOXVHWACMD* pCmd;
808 uint32_t unsupportedSCaps = vboxVHWAUnsupportedDDSCAPS(lpDDS->ddsCaps.dwCaps);
809 Assert(!unsupportedSCaps);
810 if(unsupportedSCaps)
811 {
812 VHWADBG(("vboxVHWASurfCanCreate: unsupported ddscaps: 0x%x", unsupportedSCaps));
813 lpCanCreateSurface->ddRVal = DDERR_INVALIDCAPS;
814 return DDHAL_DRIVER_HANDLED;
815 }
816
817 unsupportedSCaps = vboxVHWAUnsupportedDDPFS(lpDDS->ddpfPixelFormat.dwFlags);
818 Assert(!unsupportedSCaps);
819 if(unsupportedSCaps)
820 {
821 VHWADBG(("vboxVHWASurfCanCreate: unsupported pixel format: 0x%x", unsupportedSCaps));
822 lpCanCreateSurface->ddRVal = DDERR_INVALIDPIXELFORMAT;
823 return DDHAL_DRIVER_HANDLED;
824 }
825
826 pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_CANCREATE, sizeof(VBOXVHWACMD_SURF_CANCREATE));
827 if(pCmd)
828 {
829 int rc;
830 VBOXVHWACMD_SURF_CANCREATE * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_CANCREATE);
831 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_CANCREATE));
832
833 rc = vboxVHWAFromDDSURFACEDESC(&pBody->u.in.SurfInfo, lpDDS);
834 pBody->u.in.bIsDifferentPixelFormat = lpCanCreateSurface->bIsDifferentPixelFormat;
835
836 vboxVHWACommandSubmit(pDev, pCmd);
837 Assert(pCmd->rc == VINF_SUCCESS);
838 if(pCmd->rc == VINF_SUCCESS)
839 {
840 Assert(!pBody->u.out.ErrInfo);
841 if(pBody->u.out.ErrInfo)
842 {
843 lpCanCreateSurface->ddRVal = DDERR_GENERIC;
844 }
845 else
846 {
847 lpCanCreateSurface->ddRVal = DD_OK;
848 }
849 }
850 else
851 {
852 lpCanCreateSurface->ddRVal = DDERR_GENERIC;
853 }
854 vboxVHWACommandFree(pDev, pCmd);
855 }
856 else
857 {
858 lpCanCreateSurface->ddRVal = DDERR_GENERIC;
859 }
860 return DDHAL_DRIVER_HANDLED;
861 }
862#endif
863
864 if (lpDDS->ddsCaps.dwCaps & DDSCAPS_ZBUFFER)
865 {
866 DISPDBG((0, "No Z-Bufer support\n"));
867 lpCanCreateSurface->ddRVal = DDERR_INVALIDPIXELFORMAT;
868 return DDHAL_DRIVER_HANDLED;
869 }
870 if (lpDDS->ddsCaps.dwCaps & DDSCAPS_TEXTURE)
871 {
872 DISPDBG((0, "No texture support\n"));
873 lpCanCreateSurface->ddRVal = DDERR_INVALIDPIXELFORMAT;
874 return DDHAL_DRIVER_HANDLED;
875 }
876 if (lpCanCreateSurface->bIsDifferentPixelFormat && (lpDDS->ddpfPixelFormat.dwFlags & DDPF_FOURCC))
877 {
878 DISPDBG((0, "FOURCC not supported\n"));
879 lpCanCreateSurface->ddRVal = DDERR_INVALIDPIXELFORMAT;
880 return DDHAL_DRIVER_HANDLED;
881 }
882
883 lpCanCreateSurface->ddRVal = DD_OK;
884 return DDHAL_DRIVER_HANDLED;
885}
886
887// ***************************WIN NT ONLY**********************************
888//
889// DdMapMemory
890//
891// Maps application-modifiable portions of the frame buffer into the
892// user-mode address space of the specified process, or unmaps memory.
893//
894// DdMapMemory is called to perform memory mapping before the first call to
895// DdLock. The handle returned by the driver in fpProcess will be passed to
896// every DdLock call made on the driver.
897//
898// DdMapMemory is also called to unmap memory after the last DdUnLock call is
899// made.
900//
901// To prevent driver crashes, the driver must not map any portion of the frame
902// buffer that must not be modified by an application.
903//
904// Parameters
905// lpMapMemory
906// Points to a DD_MAPMEMORYDATA structure that contains details for
907// the memory mapping or unmapping operation.
908//
909// .lpDD
910// Points to a DD_DIRECTDRAW_GLOBAL structure that represents
911// the driver.
912// .bMap
913// Specifies the memory operation that the driver should perform.
914// A value of TRUE indicates that the driver should map memory;
915// FALSE means that the driver should unmap memory.
916// .hProcess
917// Specifies a handle to the process whose address space is
918// affected.
919// .fpProcess
920// Specifies the location in which the driver should return the
921// base address of the process's memory mapped space when bMap
922// is TRUE. When bMap is FALSE, fpProcess contains the base
923// address of the memory to be unmapped by the driver.
924// .ddRVal
925// Specifies the location in which the driver writes the return
926// value of the DdMapMemory callback. A return code of DD_OK
927// indicates success.
928//
929//-----------------------------------------------------------------------------
930
931DWORD CALLBACK DdMapMemory(PDD_MAPMEMORYDATA lpMapMemory)
932{
933 PPDEV pDev = (PPDEV)lpMapMemory->lpDD->dhpdev;
934
935 VIDEO_SHARE_MEMORY ShareMemory;
936 VIDEO_SHARE_MEMORY_INFORMATION ShareMemoryInformation;
937 DWORD ReturnedDataLength;
938
939 DISPDBG((0, "%s: %p bMap %d\n", __FUNCTION__, pDev, lpMapMemory->bMap));
940
941 if (lpMapMemory->bMap)
942 {
943 ShareMemory.ProcessHandle = lpMapMemory->hProcess;
944
945 // 'RequestedVirtualAddress' isn't actually used for the SHARE IOCTL:
946
947 ShareMemory.RequestedVirtualAddress = 0;
948
949 // We map in starting at the top of the frame buffer:
950
951 ShareMemory.ViewOffset = 0;
952
953 // We map down to the end of the frame buffer, including the offscreen heap.
954 ShareMemory.ViewSize = pDev->layout.offVBVABuffer;
955
956 DISPDBG((0, "ViewSize = %x\n", ShareMemory.ViewSize));
957
958 if (EngDeviceIoControl(pDev->hDriver,
959 IOCTL_VIDEO_SHARE_VIDEO_MEMORY,
960 &ShareMemory,
961 sizeof(VIDEO_SHARE_MEMORY),
962 &ShareMemoryInformation,
963 sizeof(VIDEO_SHARE_MEMORY_INFORMATION),
964 &ReturnedDataLength))
965 {
966 DISPDBG((0, "Failed IOCTL_VIDEO_SHARE_MEMORY\n"));
967
968 lpMapMemory->ddRVal = DDERR_GENERIC;
969
970 DISPDBG((0, "DdMapMemory: Exit GEN, DDHAL_DRIVER_HANDLED\n"));
971
972 return(DDHAL_DRIVER_HANDLED);
973 }
974
975 lpMapMemory->fpProcess =
976 (FLATPTR) ShareMemoryInformation.VirtualAddress;
977 }
978 else
979 {
980 ShareMemory.ProcessHandle = lpMapMemory->hProcess;
981 ShareMemory.ViewOffset = 0;
982 ShareMemory.ViewSize = 0;
983 ShareMemory.RequestedVirtualAddress = (VOID*) lpMapMemory->fpProcess;
984
985 if (EngDeviceIoControl(pDev->hDriver,
986 IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY,
987 &ShareMemory,
988 sizeof(VIDEO_SHARE_MEMORY),
989 NULL,
990 0,
991 &ReturnedDataLength))
992 {
993 DISPDBG((0, "Failed IOCTL_VIDEO_UNSHARE_MEMORY\n"));
994 }
995 }
996
997 lpMapMemory->ddRVal = DD_OK;
998
999 return(DDHAL_DRIVER_HANDLED);
1000}
1001
1002/**
1003 * DdLock
1004 *
1005 * The DdLock callback function locks a specified area of surface memory and provides a valid pointer to a block of memory associated with a surface.
1006 *
1007 * Parameters
1008 * lpLock
1009 * Points to a DD_LOCKDATA structure that contains the information required to perform the lockdown.
1010 *
1011 * Return Value
1012 *
1013 * DdLock returns one of the following callback codes:
1014 *
1015 * DDHAL_DRIVER_HANDLED
1016 * DDHAL_DRIVER_NOTHANDLED
1017 *
1018 */
1019DWORD APIENTRY DdLock(PDD_LOCKDATA lpLock)
1020{
1021 PPDEV pDev = (PPDEV)lpLock->lpDD->dhpdev;
1022 DD_SURFACE_LOCAL* lpSurfaceLocal = lpLock->lpDDSurface;
1023
1024 DISPDBG((0, "%s: %p bHasRect = %d fpProcess = %p\n", __FUNCTION__, pDev, lpLock->bHasRect, lpLock->fpProcess));
1025
1026#ifdef VBOX_WITH_VIDEOHWACCEL
1027 if(pDev->vhwaInfo.bVHWAEnabled)
1028 {
1029 DD_SURFACE_GLOBAL* lpSurfaceGlobal = lpSurfaceLocal->lpGbl;
1030 PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC)lpSurfaceGlobal->dwReserved1;
1031 VBOXVHWACMD* pCmd;
1032 /* ensure we have host cmds processed to update pending blits and flips */
1033 vboxVHWACommandCheckHostCmds(pDev);
1034
1035 // if(VBOXDD_CHECKFLAG(lpLock, DDLOCK_DONOTWAIT))
1036 {
1037 if(ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc)
1038 || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst)
1039 || ASMAtomicUoReadU32(&pDesc->cPendingFlipsTarg)
1040 || ASMAtomicUoReadU32(&pDesc->cPendingFlipsCurr))
1041 {
1042 lpLock->ddRVal = DDERR_WASSTILLDRAWING;
1043 return DDHAL_DRIVER_HANDLED;
1044 }
1045 }
1046
1047// if(VBOXDD_CHECKFLAG(lpLock->dwFlags, DDLOCK_SURFACEMEMORYPTR))
1048// {
1049// lpLock->lpSurfData = (LPVOID)(lpSurfaceGlobal->fpVidMem + lpSurfaceGlobal->lPitch * lpLock->rArea.top
1050// + lpLock->rArea.left * pDesc->cBitsPerPixel/8);
1051// }
1052
1053 pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_LOCK, sizeof(VBOXVHWACMD_SURF_LOCK));
1054 if(pCmd)
1055 {
1056 VBOXVHWACMD_SURF_LOCK * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_LOCK);
1057 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_LOCK));
1058
1059 pBody->u.in.offSurface = (uint64_t)lpSurfaceGlobal->fpVidMem;
1060
1061 if (lpLock->bHasRect)
1062 {
1063 DISPDBG((0, "%d,%d %dx%d\n", lpLock->rArea.left, lpLock->rArea.top, lpLock->rArea.right - lpLock->rArea.left, lpLock->rArea.bottom - lpLock->rArea.top));
1064 vboxVHWAFromRECTL(&pBody->u.in.rect, &lpLock->rArea);
1065 pBody->u.in.rectValid = 1;
1066 }
1067 else
1068 {
1069 pBody->u.in.rectValid = 0;
1070 }
1071
1072 pBody->u.in.hSurf = pDesc->hHostHandle;
1073
1074 if(VBOXDD_CHECKFLAG(lpLock->dwFlags, DDLOCK_DISCARDCONTENTS))
1075 {
1076 pBody->u.in.flags |= VBOXVHWA_LOCK_DISCARDCONTENTS;
1077 /* we're not interested in completion, just send the command */
1078 vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWAFreeCmdCompletion, NULL);
1079 }
1080 else
1081 {
1082 /* wait for the surface to be locked and memory buffer updated */
1083 vboxVHWACommandSubmit(pDev, pCmd);
1084 vboxVHWACommandFree(pDev, pCmd);
1085 }
1086
1087 lpLock->ddRVal = DD_OK;
1088 }
1089 else
1090 {
1091 lpLock->ddRVal = DDERR_GENERIC;
1092 }
1093 return DDHAL_DRIVER_NOTHANDLED;
1094 }
1095#endif
1096 if (lpSurfaceLocal->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
1097 {
1098 /* The updated rectangle must be reported only for the primary surface. */
1099 pDev->ddLock.bLocked = TRUE;
1100
1101 if (lpLock->bHasRect)
1102 {
1103 DISPDBG((0, "%d,%d %dx%d\n", lpLock->rArea.left, lpLock->rArea.top, lpLock->rArea.right - lpLock->rArea.left, lpLock->rArea.bottom - lpLock->rArea.top));
1104 pDev->ddLock.rArea = lpLock->rArea;
1105 }
1106 else
1107 {
1108 pDev->ddLock.rArea.left = 0;
1109 pDev->ddLock.rArea.top = 0;
1110 pDev->ddLock.rArea.right = pDev->cxScreen;
1111 pDev->ddLock.rArea.bottom = pDev->cyScreen;
1112 }
1113 }
1114 else
1115 {
1116 DISPDBG((0, "%s: secondary surface.\n", __FUNCTION__));
1117 }
1118
1119 // Because we correctly set 'fpVidMem' to be the offset into our frame
1120 // buffer when we created the surface, DirectDraw will automatically take
1121 // care of adding in the user-mode frame buffer address if we return
1122 // DDHAL_DRIVER_NOTHANDLED:
1123 lpLock->ddRVal = DD_OK;
1124 return DDHAL_DRIVER_NOTHANDLED;
1125}
1126
1127/**
1128 * DdUnlock
1129 *
1130 * The DdUnLock callback function releases the lock held on the specified surface.
1131 *
1132 * Parameters
1133 * lpUnlock
1134 * Points to a DD_UNLOCKDATA structure that contains the information required to perform the lock release. *
1135 *
1136 * Return Value
1137 *
1138 * DdLock returns one of the following callback codes:
1139 *
1140 * DDHAL_DRIVER_HANDLED
1141 * DDHAL_DRIVER_NOTHANDLED
1142 *
1143 */
1144DWORD APIENTRY DdUnlock(PDD_UNLOCKDATA lpUnlock)
1145{
1146 PPDEV pDev = (PPDEV)lpUnlock->lpDD->dhpdev;
1147 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
1148#ifdef VBOX_WITH_VIDEOHWACCEL
1149 if (pDev->vhwaInfo.bVHWAEnabled)
1150 {
1151 DD_SURFACE_LOCAL* lpSurfaceLocal = lpUnlock->lpDDSurface;
1152 DD_SURFACE_GLOBAL* lpSurfaceGlobal = lpSurfaceLocal->lpGbl;
1153 PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC)lpSurfaceGlobal->dwReserved1;
1154 VBOXVHWACMD* pCmd;
1155
1156 //TODO: hadle vrdp properly
1157 if ( pDev->pVBVA->u32HostEvents
1158 & VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET)
1159 {
1160 vrdpReset (pDev);
1161
1162 pDev->pVBVA->u32HostEvents &=
1163 ~VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET;
1164 }
1165
1166 /* ensure we have host cmds processed to update pending blits and flips */
1167 vboxVHWACommandCheckHostCmds(pDev);
1168
1169 pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_UNLOCK, sizeof(VBOXVHWACMD_SURF_UNLOCK));
1170 // int rc = VERR_GENERAL_FAILURE;
1171 if(pCmd)
1172 {
1173 VBOXVHWACMD_SURF_UNLOCK * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_UNLOCK);
1174 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_UNLOCK));
1175
1176 pBody->u.in.hSurf = pDesc->hHostHandle;
1177
1178 vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWAFreeCmdCompletion, NULL);
1179
1180 lpUnlock->ddRVal = DD_OK;
1181 }
1182 else
1183 {
1184 lpUnlock->ddRVal = DDERR_GENERIC;
1185 }
1186
1187 return DDHAL_DRIVER_NOTHANDLED;
1188 }
1189#endif
1190 if (pDev->ddLock.bLocked)
1191 {
1192 DISPDBG((0, "%d,%d %dx%d\n", pDev->ddLock.rArea.left, pDev->ddLock.rArea.top, pDev->ddLock.rArea.right - pDev->ddLock.rArea.left, pDev->ddLock.rArea.bottom - pDev->ddLock.rArea.top));
1193
1194#ifndef VBOX_WITH_HGSMI
1195 if (pDev->pInfo && vboxHwBufferBeginUpdate (pDev))
1196 {
1197 vbvaReportDirtyRect (pDev, &pDev->ddLock.rArea);
1198
1199 if ( pDev->pInfo->hostEvents.fu32Events
1200 & VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET)
1201 {
1202 vrdpReset (pDev);
1203
1204 pDev->pInfo->hostEvents.fu32Events &=
1205 ~VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET;
1206 }
1207
1208 if (pDev->vbva.pVbvaMemory->fu32ModeFlags
1209 & VBVA_F_MODE_VRDP)
1210 {
1211 vrdpReportDirtyRect (pDev, &pDev->ddLock.rArea);
1212 }
1213
1214 vboxHwBufferEndUpdate (pDev);
1215 }
1216#else
1217 if (pDev->bHGSMISupported && vboxHwBufferBeginUpdate (pDev))
1218 {
1219 vbvaReportDirtyRect (pDev, &pDev->ddLock.rArea);
1220
1221 if ( pDev->pVBVA->u32HostEvents
1222 & VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET)
1223 {
1224 vrdpReset (pDev);
1225
1226 pDev->pVBVA->u32HostEvents &=
1227 ~VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET;
1228 }
1229
1230 if (pDev->pVBVA->u32HostEvents
1231 & VBVA_F_MODE_VRDP)
1232 {
1233 vrdpReportDirtyRect (pDev, &pDev->ddLock.rArea);
1234 }
1235
1236 vboxHwBufferEndUpdate (pDev);
1237 }
1238#endif /* VBOX_WITH_HGSMI */
1239
1240 pDev->ddLock.bLocked = FALSE;
1241 }
1242
1243 lpUnlock->ddRVal = DD_OK;
1244 return DDHAL_DRIVER_NOTHANDLED;
1245}
1246
1247/**
1248 * DdDestroySurface
1249 *
1250 * The DdDestroySurface callback function destroys a DirectDraw surface.
1251 *
1252 * Parameters
1253 * lpDestroySurface
1254 * Points to a DD_DESTROYSURFACEDATA structure that contains the information needed to destroy a surface.
1255 *
1256 * Return Value
1257 *
1258 * DdDestroySurface returns one of the following callback codes:
1259 *
1260 * DDHAL_DRIVER_HANDLED
1261 * DDHAL_DRIVER_NOTHANDLED
1262 *
1263 */
1264DWORD APIENTRY DdDestroySurface(PDD_DESTROYSURFACEDATA lpDestroySurface)
1265{
1266#ifdef VBOX_WITH_VIDEOHWACCEL
1267 PPDEV pDev = (PPDEV)lpDestroySurface->lpDD->dhpdev;
1268 if(pDev->vhwaInfo.bVHWAEnabled)
1269 {
1270 DD_SURFACE_LOCAL* lpSurfaceLocal = lpDestroySurface->lpDDSurface;
1271 DD_SURFACE_GLOBAL* lpSurfaceGlobal = lpSurfaceLocal->lpGbl;
1272 VBOXVHWACMD* pCmd;
1273
1274 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
1275
1276 pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_DESTROY, sizeof(VBOXVHWACMD_SURF_DESTROY));
1277 // int rc = VERR_GENERAL_FAILURE;
1278 if(pCmd)
1279 {
1280 VBOXVHWACMD_SURF_DESTROY * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_DESTROY);
1281 PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC)lpSurfaceGlobal->dwReserved1;
1282
1283 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_DESTROY));
1284
1285 pBody->u.in.hSurf = pDesc->hHostHandle;
1286
1287 /* we're not interested in completion, just send the command */
1288 vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWAFreeCmdCompletion, NULL);
1289
1290 vboxVHWASurfDescFree(pDesc);
1291
1292 lpDestroySurface->ddRVal = DD_OK;
1293 }
1294 else
1295 {
1296 lpDestroySurface->ddRVal = DDERR_GENERIC;
1297 }
1298 }
1299 else
1300#endif
1301 lpDestroySurface->ddRVal = DD_OK;
1302 return DDHAL_DRIVER_HANDLED;
1303}
1304
1305
1306//-----------------------------------------------------------------------------
1307//
1308// DdSetExclusiveMode
1309//
1310// This function is called by DirectDraw when we switch from the GDI surface,
1311// to DirectDraw exclusive mode, e.g. to run a game in fullcreen mode.
1312// You only need to implement this function when you are using the
1313// 'HeapVidMemAllocAligned' function and allocate memory for Device Bitmaps
1314// and DirectDraw surfaces from the same heap.
1315//
1316// We use this call to disable GDI DeviceBitMaps when we are running in
1317// DirectDraw exclusive mode. Otherwise a DD app gets confused if both GDI and
1318// DirectDraw allocate memory from the same heap.
1319//
1320// See also DdFlipToGDISurface.
1321//
1322//-----------------------------------------------------------------------------
1323
1324
1325DWORD APIENTRY DdSetExclusiveMode(PDD_SETEXCLUSIVEMODEDATA lpSetExclusiveMode)
1326{
1327 PPDEV pDev = (PPDEV)lpSetExclusiveMode->lpDD->dhpdev;
1328 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
1329
1330 // remember setting of exclusive mode in pDev,
1331 // so GDI can stop to promote DeviceBitmaps into
1332 // video memory
1333
1334 pDev->bDdExclusiveMode = lpSetExclusiveMode->dwEnterExcl;
1335
1336 lpSetExclusiveMode->ddRVal = DD_OK;
1337
1338 return DDHAL_DRIVER_HANDLED;
1339}
1340
1341//-----------------------------------------------------------------------------
1342//
1343// DWORD DdFlipToGDISurface
1344//
1345// This function is called by DirectDraw when it flips to the surface on which
1346// GDI can write to.
1347//
1348//-----------------------------------------------------------------------------
1349
1350DWORD APIENTRY DdFlipToGDISurface(PDD_FLIPTOGDISURFACEDATA lpFlipToGDISurface)
1351{
1352 PPDEV pDev = (PPDEV)lpFlipToGDISurface->lpDD->dhpdev;
1353 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
1354
1355 pDev->dwNewDDSurfaceOffset = 0xffffffff;
1356
1357 lpFlipToGDISurface->ddRVal = DD_OK;
1358
1359 //
1360 // we return NOTHANDLED, then the ddraw runtime takes
1361 // care that we flip back to the primary...
1362 //
1363 return DDHAL_DRIVER_NOTHANDLED;
1364}
1365//-----------------------------------------------------------------------------
1366//
1367// DWORD DdFreeDriverMemory
1368//
1369// This function called by DirectDraw when it's running low on memory in
1370// our heap. You only need to implement this function if you use the
1371// DirectDraw 'HeapVidMemAllocAligned' function in your driver, and you
1372// can boot those allocations out of memory to make room for DirectDraw.
1373//
1374//-----------------------------------------------------------------------------
1375
1376DWORD APIENTRY DdFreeDriverMemory(PDD_FREEDRIVERMEMORYDATA lpFreeDriverMemory)
1377{
1378 PPDEV pDev = (PPDEV)lpFreeDriverMemory->lpDD->dhpdev;
1379 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
1380
1381 lpFreeDriverMemory->ddRVal = DDERR_OUTOFMEMORY;
1382 return DDHAL_DRIVER_HANDLED;
1383}
1384
1385#ifdef VBOX_WITH_VIDEOHWACCEL
1386DWORD APIENTRY DdSetColorKey(PDD_SETCOLORKEYDATA lpSetColorKey)
1387{
1388 PPDEV pDev = (PPDEV)lpSetColorKey->lpDD->dhpdev;
1389 DD_SURFACE_LOCAL* lpSurfaceLocal = lpSetColorKey->lpDDSurface;
1390 DD_SURFACE_GLOBAL* lpSurfaceGlobal = lpSurfaceLocal->lpGbl;
1391 VBOXVHWACMD* pCmd;
1392
1393 DISPDBG((0, "%s\n", __FUNCTION__));
1394
1395 pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_COLORKEY_SET, sizeof(VBOXVHWACMD_SURF_COLORKEY_SET));
1396 // int rc = VERR_GENERAL_FAILURE;
1397 if(pCmd)
1398 {
1399 VBOXVHWACMD_SURF_COLORKEY_SET * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_COLORKEY_SET);
1400 PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC)lpSurfaceGlobal->dwReserved1;
1401 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_COLORKEY_SET));
1402
1403 pBody->u.in.offSurface = (uint64_t)lpSurfaceGlobal->fpVidMem;
1404 pBody->u.in.hSurf = pDesc->hHostHandle;
1405 pBody->u.in.flags = vboxVHWAFromDDCKEYs(lpSetColorKey->dwFlags);
1406 vboxVHWAFromDDCOLORKEY(&pBody->u.in.CKey, &lpSetColorKey->ckNew);
1407
1408 vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWAFreeCmdCompletion, NULL);
1409 lpSetColorKey->ddRVal = DD_OK;
1410 }
1411 return DDHAL_DRIVER_HANDLED;
1412}
1413
1414DWORD APIENTRY DdAddAttachedSurface(PDD_ADDATTACHEDSURFACEDATA lpAddAttachedSurface)
1415{
1416 DISPDBG((0, "%s\n", __FUNCTION__));
1417 lpAddAttachedSurface->ddRVal = DD_OK;
1418 return DDHAL_DRIVER_HANDLED;
1419}
1420
1421DWORD APIENTRY DdBlt(PDD_BLTDATA lpBlt)
1422{
1423 PPDEV pDev = (PPDEV)lpBlt->lpDD->dhpdev;
1424 DISPDBG((0, "%s\n", __FUNCTION__));
1425#if DX9_DDI
1426 if(VBOXDD_CHECKFLAG(lpBlt->dwFlags, DDBLT_EXTENDED_PRESENTATION_STRETCHFACTOR))
1427 {
1428 lpBlt->ddRVal = DD_OK;
1429 }
1430 else
1431#endif
1432 {
1433 DD_SURFACE_LOCAL* lpDestSurfaceLocal = lpBlt->lpDDDestSurface;
1434 DD_SURFACE_GLOBAL* lpDestSurfaceGlobal = lpDestSurfaceLocal->lpGbl;
1435 DD_SURFACE_LOCAL* lpSrcSurfaceLocal = lpBlt->lpDDSrcSurface;
1436 DD_SURFACE_GLOBAL* lpSrcSurfaceGlobal = lpSrcSurfaceLocal->lpGbl;
1437 VBOXVHWACMD* pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_BLT, sizeof(VBOXVHWACMD_SURF_BLT));
1438 // int rc = VERR_GENERAL_FAILURE;
1439 if(pCmd)
1440 {
1441 VBOXVHWACMD_SURF_BLT * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_BLT);
1442 PVBOXVHWASURFDESC pSrcDesc = (PVBOXVHWASURFDESC)lpSrcSurfaceGlobal->dwReserved1;
1443 PVBOXVHWASURFDESC pDestDesc = (PVBOXVHWASURFDESC)lpDestSurfaceGlobal->dwReserved1;
1444 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_BLT));
1445
1446 pBody->u.in.offSrcSurface = (uint64_t)lpSrcSurfaceGlobal->fpVidMem;
1447 pBody->u.in.offDstSurface = (uint64_t)lpDestSurfaceGlobal->fpVidMem;
1448
1449 pBody->u.in.hDstSurf = pDestDesc->hHostHandle;
1450 vboxVHWAFromRECTL(&pBody->u.in.dstRect, &lpBlt->rDest);
1451 pBody->u.in.hSrcSurf = pSrcDesc->hHostHandle;
1452 vboxVHWAFromRECTL(&pBody->u.in.srcRect, &lpBlt->rSrc);
1453 pBody->DstGuestSurfInfo = (uint64_t)pDestDesc;
1454 pBody->SrcGuestSurfInfo = (uint64_t)pSrcDesc;
1455
1456 pBody->u.in.flags = vboxVHWAFromDDBLTs(lpBlt->dwFlags);
1457 vboxVHWAFromDDBLTFX(&pBody->u.in.desc, &lpBlt->bltFX);
1458
1459 ASMAtomicIncU32(&pSrcDesc->cPendingBltsSrc);
1460 ASMAtomicIncU32(&pDestDesc->cPendingBltsDst);
1461
1462// if(VBOXDD_CHECKFLAG(lpBlt->dwFlags, DDBLT_ASYNC))
1463// {
1464 vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWASurfBltCompletion, NULL);
1465// }
1466// else
1467// {
1468// vboxVHWACommandSubmit(pDev, pCmd);
1469// }
1470 lpBlt->ddRVal = DD_OK;
1471 }
1472 else
1473 {
1474 lpBlt->ddRVal = DDERR_GENERIC;
1475 }
1476 }
1477
1478 return DDHAL_DRIVER_HANDLED;
1479}
1480
1481//DWORD APIENTRY DdDestroySurface(PDD_DESTROYSURFACEDATA lpDestroySurface)
1482//{
1483// DISPDBG((0, "%s\n", __FUNCTION__));
1484// lpDestroySurface->ddRVal = DD_OK;
1485// return DDHAL_DRIVER_HANDLED;
1486//}
1487
1488DWORD APIENTRY DdFlip(PDD_FLIPDATA lpFlip)
1489{
1490 PPDEV pDev = (PPDEV)lpFlip->lpDD->dhpdev;
1491 DD_SURFACE_LOCAL* lpTargSurfaceLocal = lpFlip->lpSurfTarg;
1492 DD_SURFACE_GLOBAL* lpTargSurfaceGlobal = lpTargSurfaceLocal->lpGbl;
1493 DD_SURFACE_LOCAL* lpCurrSurfaceLocal = lpFlip->lpSurfCurr;
1494 DD_SURFACE_GLOBAL* lpCurrSurfaceGlobal = lpCurrSurfaceLocal->lpGbl;
1495 PVBOXVHWASURFDESC pCurrDesc = (PVBOXVHWASURFDESC)lpCurrSurfaceGlobal->dwReserved1;
1496 PVBOXVHWASURFDESC pTargDesc = (PVBOXVHWASURFDESC)lpTargSurfaceGlobal->dwReserved1;
1497 VBOXVHWACMD* pCmd;
1498
1499 DISPDBG((0, "%s\n", __FUNCTION__));
1500
1501 /* ensure we have host cmds processed to update pending blits and flips */
1502 vboxVHWACommandCheckHostCmds(pDev);
1503
1504// if(VBOXDD_CHECKFLAG(lpLock, DDLOCK_DONOTWAIT))
1505 {
1506 if(
1507// ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc)
1508// || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst)
1509// ||
1510 ASMAtomicUoReadU32(&pCurrDesc->cPendingFlipsTarg)
1511 || ASMAtomicUoReadU32(&pCurrDesc->cPendingFlipsCurr)
1512 || ASMAtomicUoReadU32(&pTargDesc->cPendingFlipsTarg)
1513 || ASMAtomicUoReadU32(&pTargDesc->cPendingFlipsCurr))
1514 {
1515 lpFlip->ddRVal = DDERR_WASSTILLDRAWING;
1516 return DDHAL_DRIVER_HANDLED;
1517 }
1518 }
1519
1520 pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_FLIP, sizeof(VBOXVHWACMD_SURF_FLIP));
1521 // int rc = VERR_GENERAL_FAILURE;
1522 if(pCmd)
1523 {
1524 VBOXVHWACMD_SURF_FLIP * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_FLIP);
1525
1526 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_FLIP));
1527
1528 pBody->u.in.offCurrSurface = (uint64_t)lpCurrSurfaceGlobal->fpVidMem;
1529 pBody->u.in.offTargSurface = (uint64_t)lpTargSurfaceGlobal->fpVidMem;
1530
1531 pBody->u.in.hTargSurf = pTargDesc->hHostHandle;
1532 pBody->u.in.hCurrSurf = pCurrDesc->hHostHandle;
1533 pBody->TargGuestSurfInfo = (uint64_t)pTargDesc;
1534 pBody->CurrGuestSurfInfo = (uint64_t)pCurrDesc;
1535
1536// pBody->u.in.flags = vboxVHWAFromDDFLIPs(lpFlip->dwFlags);
1537
1538 ASMAtomicIncU32(&pCurrDesc->cPendingFlipsCurr);
1539 ASMAtomicIncU32(&pTargDesc->cPendingFlipsTarg);
1540
1541 vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWASurfFlipCompletion, NULL);
1542
1543 lpFlip->ddRVal = DD_OK;
1544 }
1545 else
1546 {
1547 lpFlip->ddRVal = DDERR_GENERIC;
1548 }
1549 return DDHAL_DRIVER_HANDLED;
1550}
1551
1552DWORD APIENTRY DdGetBltStatus(PDD_GETBLTSTATUSDATA lpGetBltStatus)
1553{
1554 PPDEV pDev = (PPDEV)lpGetBltStatus->lpDD->dhpdev;
1555
1556 DISPDBG((0, "%s\n", __FUNCTION__));
1557
1558 if(lpGetBltStatus->dwFlags == DDGBS_CANBLT)
1559 {
1560 lpGetBltStatus->ddRVal = DD_OK;
1561 }
1562 else /* DDGBS_ISBLTDONE */
1563 {
1564 DD_SURFACE_LOCAL* lpSurfaceLocal = lpGetBltStatus->lpDDSurface;
1565 DD_SURFACE_GLOBAL* lpSurfaceGlobal = lpSurfaceLocal->lpGbl;
1566 PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC)lpSurfaceGlobal->dwReserved1;
1567
1568 /* ensure we have host cmds processed to update pending blits and flips */
1569 vboxVHWACommandCheckHostCmds(pDev);
1570
1571 if(
1572 ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc)
1573 || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst)
1574 // || ASMAtomicUoReadU32(&pDesc->cPendingFlipsTarg)
1575 // || ASMAtomicUoReadU32(&pDesc->cPendingFlipsCurr)
1576 )
1577 {
1578 lpGetBltStatus->ddRVal = DDERR_WASSTILLDRAWING;
1579 }
1580 else
1581 {
1582 lpGetBltStatus->ddRVal = DD_OK;
1583 }
1584 }
1585
1586 return DDHAL_DRIVER_HANDLED;
1587}
1588
1589DWORD APIENTRY DdGetFlipStatus(PDD_GETFLIPSTATUSDATA lpGetFlipStatus)
1590{
1591 PPDEV pDev = (PPDEV)lpGetFlipStatus->lpDD->dhpdev;
1592 DD_SURFACE_LOCAL* lpSurfaceLocal = lpGetFlipStatus->lpDDSurface;
1593 DD_SURFACE_GLOBAL* lpSurfaceGlobal = lpSurfaceLocal->lpGbl;
1594 PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC)lpSurfaceGlobal->dwReserved1;
1595
1596 DISPDBG((0, "%s\n", __FUNCTION__));
1597
1598 /* ensure we have host cmds processed to update pending blits and flips */
1599 vboxVHWACommandCheckHostCmds(pDev);
1600
1601 if(
1602// ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc)
1603// || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst)
1604// ||
1605 ASMAtomicUoReadU32(&pDesc->cPendingFlipsTarg)
1606 || ASMAtomicUoReadU32(&pDesc->cPendingFlipsCurr)
1607 )
1608 {
1609 lpGetFlipStatus->ddRVal = DDERR_WASSTILLDRAWING;
1610 }
1611 else
1612 {
1613 lpGetFlipStatus->ddRVal = DD_OK;
1614 }
1615
1616// if(lpGetFlipStatus->dwFlags == DDGFS_CANFLIP)
1617// {
1618// lpGetFlipStatus->ddRVal = DD_OK;
1619// }
1620// else
1621// {
1622// lpGetFlipStatus->ddRVal = DD_OK;
1623// }
1624
1625 return DDHAL_DRIVER_HANDLED;
1626}
1627
1628DWORD APIENTRY DdSetOverlayPosition(PDD_SETOVERLAYPOSITIONDATA lpSetOverlayPosition)
1629{
1630 PPDEV pDev = (PPDEV)lpSetOverlayPosition->lpDD->dhpdev;
1631 DD_SURFACE_LOCAL* lpDestSurfaceLocal = lpSetOverlayPosition->lpDDDestSurface;
1632 DD_SURFACE_GLOBAL* lpDestSurfaceGlobal = lpDestSurfaceLocal->lpGbl;
1633 DD_SURFACE_LOCAL* lpSrcSurfaceLocal = lpSetOverlayPosition->lpDDSrcSurface;
1634 DD_SURFACE_GLOBAL* lpSrcSurfaceGlobal = lpSrcSurfaceLocal->lpGbl;
1635 VBOXVHWACMD* pCmd;
1636 PVBOXVHWASURFDESC pSrcDesc = (PVBOXVHWASURFDESC)lpSrcSurfaceGlobal->dwReserved1;
1637 PVBOXVHWASURFDESC pDestDesc = (PVBOXVHWASURFDESC)lpDestSurfaceGlobal->dwReserved1;
1638
1639 DISPDBG((0, "%s\n", __FUNCTION__));
1640
1641 if(pSrcDesc->bHidden)
1642 {
1643 lpSetOverlayPosition->ddRVal = DDERR_GENERIC;
1644 return DDHAL_DRIVER_HANDLED;
1645 }
1646
1647 pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_OVERLAY_SETPOSITION, sizeof(VBOXVHWACMD_SURF_OVERLAY_SETPOSITION));
1648 // int rc = VERR_GENERAL_FAILURE;
1649 if(pCmd)
1650 {
1651 VBOXVHWACMD_SURF_OVERLAY_SETPOSITION * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_OVERLAY_SETPOSITION);
1652
1653 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_OVERLAY_SETPOSITION));
1654
1655 pBody->u.in.offSrcSurface = (uint64_t)lpSrcSurfaceGlobal->fpVidMem;
1656 pBody->u.in.offDstSurface = (uint64_t)lpDestSurfaceGlobal->fpVidMem;
1657
1658 pBody->u.in.hDstSurf = pDestDesc->hHostHandle;
1659 pBody->u.in.hSrcSurf = pSrcDesc->hHostHandle;
1660
1661 pBody->u.in.xPos = lpSetOverlayPosition->lXPos;
1662 pBody->u.in.yPos = lpSetOverlayPosition->lYPos;
1663
1664 vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWAFreeCmdCompletion, NULL);
1665 lpSetOverlayPosition->ddRVal = DD_OK;
1666 }
1667
1668 return DDHAL_DRIVER_HANDLED;
1669}
1670
1671DWORD APIENTRY DdUpdateOverlay(PDD_UPDATEOVERLAYDATA lpUpdateOverlay)
1672{
1673 PPDEV pDev = (PPDEV)lpUpdateOverlay->lpDD->dhpdev;
1674 DD_SURFACE_LOCAL* lpDestSurfaceLocal = lpUpdateOverlay->lpDDDestSurface;
1675 DD_SURFACE_LOCAL* lpSrcSurfaceLocal = lpUpdateOverlay->lpDDSrcSurface;
1676 DD_SURFACE_GLOBAL* lpSrcSurfaceGlobal = lpSrcSurfaceLocal->lpGbl;
1677 VBOXVHWACMD* pCmd;
1678 PVBOXVHWASURFDESC pSrcDesc = (PVBOXVHWASURFDESC)lpSrcSurfaceGlobal->dwReserved1;
1679
1680 DISPDBG((0, "%s\n", __FUNCTION__));
1681
1682// if(pSrcDesc->bHidden)
1683// {
1684// lpUpdateOverlay->ddRVal = DDERR_GENERIC;
1685// return DDHAL_DRIVER_HANDLED;
1686// }
1687
1688 pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_OVERLAY_UPDATE, sizeof(VBOXVHWACMD_SURF_OVERLAY_UPDATE));
1689 // int rc = VERR_GENERAL_FAILURE;
1690 if(pCmd)
1691 {
1692 VBOXVHWACMD_SURF_OVERLAY_UPDATE * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_OVERLAY_UPDATE);
1693
1694 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_OVERLAY_UPDATE));
1695
1696 pBody->u.in.offSrcSurface = (uint64_t)lpSrcSurfaceGlobal->fpVidMem;
1697
1698 pBody->u.in.hSrcSurf = pSrcDesc->hHostHandle;
1699
1700 vboxVHWAFromRECTL(&pBody->u.in.dstRect, &lpUpdateOverlay->rDest);
1701 vboxVHWAFromRECTL(&pBody->u.in.srcRect, &lpUpdateOverlay->rSrc);
1702
1703 pBody->u.in.flags = vboxVHWAFromDDOVERs(lpUpdateOverlay->dwFlags);
1704 vboxVHWAFromDDOVERLAYFX(&pBody->u.in.desc, &lpUpdateOverlay->overlayFX);
1705
1706 if(lpUpdateOverlay->dwFlags & DDOVER_HIDE)
1707 {
1708 pSrcDesc->bHidden = true;
1709 }
1710 else if(lpUpdateOverlay->dwFlags & DDOVER_SHOW)
1711 {
1712 pSrcDesc->bHidden = false;
1713 }
1714
1715 if(lpDestSurfaceLocal)
1716 {
1717 DD_SURFACE_GLOBAL* lpDestSurfaceGlobal = lpDestSurfaceLocal->lpGbl;
1718 PVBOXVHWASURFDESC pDestDesc = (PVBOXVHWASURFDESC)lpDestSurfaceGlobal->dwReserved1;
1719 pBody->u.in.hDstSurf = pDestDesc->hHostHandle;
1720 pBody->u.in.offDstSurface = (uint64_t)lpDestSurfaceGlobal->fpVidMem;
1721 }
1722
1723 vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWAFreeCmdCompletion, NULL);
1724 lpUpdateOverlay->ddRVal = DD_OK;
1725 }
1726
1727 return DDHAL_DRIVER_HANDLED;
1728}
1729
1730//-----------------------------------------------------------------------------
1731// setupRops
1732//
1733// Build array for supported ROPS
1734//-----------------------------------------------------------------------------
1735static void
1736setupRops(
1737 LPBYTE proplist,
1738 LPDWORD proptable,
1739 int cnt )
1740{
1741 int i;
1742 DWORD idx;
1743 DWORD bit;
1744 DWORD rop;
1745
1746 for(i=0; i<cnt; i++)
1747 {
1748 rop = proplist[i];
1749 idx = rop / 32;
1750 bit = 1L << ((DWORD)(rop % 32));
1751 proptable[idx] |= bit;
1752 }
1753
1754} // setupRops
1755
1756//-----------------------------------------------------------------------------
1757//
1758// Function: __GetDDHALInfo
1759//
1760// Returns: void
1761//
1762// Description:
1763//
1764// Takes a pointer to a partially or fully filled in pThisDisplay and a pointer
1765// to an empty DDHALINFO and fills in the DDHALINFO. This eases porting to NT
1766// and means that caps changes are done in only one place. The pThisDisplay
1767// may not be fully constructed here, so you should only:
1768// a) Query the registry
1769// b) DISPDBG
1770// If you need to add anything to pThisDisplay for NT, you should fill it in
1771// during the DrvGetDirectDraw call.
1772//
1773// The problem here is when the code is run on NT. If there was any other way...
1774//
1775// The following caps have been found to cause NT to bail....
1776// DDCAPS_GDI, DDFXCAPS_BLTMIRRORUPDOWN, DDFXCAPS_BLTMIRRORLEFTRIGHT
1777//
1778//
1779//-----------------------------------------------------------------------------
1780
1781//
1782// use bits to indicate which ROPs you support.
1783//
1784// DWORD 0, bit 0 == ROP 0
1785// DWORD 8, bit 31 == ROP 255
1786//
1787
1788//static DWORD ropsAGP[DD_ROP_SPACE] = { 0 };
1789static BYTE ropListNT[] =
1790{
1791 SRCCOPY >> 16
1792// WHITENESS >> 16,
1793// BLACKNESS >> 16
1794};
1795
1796static DWORD rops[DD_ROP_SPACE] = { 0 };
1797
1798static bool
1799getDDHALInfo(
1800 PPDEV pDev,
1801 DD_HALINFO* pHALInfo)
1802{
1803 int i;
1804 if(!VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLT) && !VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_OVERLAY))
1805 return false;
1806
1807 pHALInfo->ddCaps.dwCaps |= vboxVHWAToDDCAPS(pDev->vhwaInfo.caps);
1808
1809 if(VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLT))
1810 {
1811 // Setup the ROPS we do.
1812 //TODO: hardcoded for now
1813 setupRops( ropListNT,
1814 rops,
1815 sizeof(ropListNT)/sizeof(ropListNT[0]));
1816 }
1817
1818// | DDCAPS_READSCANLINE
1819
1820
1821 pHALInfo->ddCaps.ddsCaps.dwCaps |= vboxVHWAToDDSCAPS(pDev->vhwaInfo.surfaceCaps);
1822
1823//disabled
1824// pHALInfo->ddCaps.dwCaps |= DDCAPS_3D |
1825// DDCAPS_BLTDEPTHFILL;
1826//
1827// pHALInfo->ddCaps.ddsCaps.dwCaps |= DDSCAPS_3DDEVICE |
1828// DDSCAPS_ZBUFFER |
1829// DDSCAPS_ALPHA;
1830 pHALInfo->ddCaps.dwCaps2 = vboxVHWAToDDCAPS2(pDev->vhwaInfo.caps2);
1831
1832
1833
1834//#if DX7_TEXMANAGEMENT
1835 // We need to set this bit up in order to be able to do
1836 // out own texture management
1837// pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_CANMANAGETEXTURE;
1838//#if DX8_DDI
1839// pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_CANMANAGERESOURCE;
1840//#endif
1841//#endif
1842
1843//#if DX8_DDI
1844 // We need to flag we can run in windowed mode, otherwise we
1845 // might get restricted by apps to run in fullscreen only
1846 pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_CANRENDERWINDOWED;
1847
1848 // Also permit surfaces wider than the display buffer.
1849 pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_WIDESURFACES;
1850//#endif
1851
1852//#if DX8_DDI
1853 // We need to flag we support dynamic textures. That is , apps can
1854 // lock with high frequency video memory textures without paying a
1855 // penalty for it. Since on this sample driver we only support
1856 // linear memory formats for textures we don't need to do anything
1857 // else for this support. Otherwise we would have to keep two surfaces
1858 // for textures created with the DDSCAPS2_HINTDYNAMIC hint in order
1859 // to efficiently do the linear<->swizzled transformation or keep the
1860 // texture permanantly in an unswizzled state.
1861// pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_DYNAMICTEXTURES;
1862 #if DX9_DDI
1863 // Notice that dynamic textures MUST be supported in order to instantiate a DX9 device
1864 #endif // DX9_DDI
1865//#endif
1866
1867// pHALInfo->ddCaps.dwFXCaps = 0;
1868
1869 // P3RX can do:
1870 // 1. Stretching/Shrinking
1871 // 2. YUV->RGB conversion
1872 // 3. Mirroring in X and Y
1873 // 4. ColorKeying from a source color and a source color space
1874 if(VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLT)
1875 && VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLTSTRETCH))
1876 {
1877 // Special effects caps
1878 //TODO: filter them out
1879 pHALInfo->ddCaps.dwFXCaps |= DDFXCAPS_BLTSTRETCHY |
1880 DDFXCAPS_BLTSTRETCHX |
1881 DDFXCAPS_BLTSTRETCHYN |
1882 DDFXCAPS_BLTSTRETCHXN |
1883 DDFXCAPS_BLTSHRINKY |
1884 DDFXCAPS_BLTSHRINKX |
1885 DDFXCAPS_BLTSHRINKYN |
1886 DDFXCAPS_BLTSHRINKXN;
1887
1888 // DDFXCAPS_BLTARITHSTRETCHY
1889 // DDFXCAPS_BLTARITHSTRETCHYN
1890 // DDFXCAPS_BLTMIRRORLEFTRIGHT
1891 // DDFXCAPS_BLTMIRRORUPDOWN
1892 // DDFXCAPS_BLTROTATION90
1893 }
1894
1895 if(VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_OVERLAY)
1896 && VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_OVERLAYSTRETCH))
1897 {
1898 // Special effects caps
1899 //TODO: filter them out
1900 pHALInfo->ddCaps.dwFXCaps |= DDFXCAPS_OVERLAYSTRETCHY |
1901 DDFXCAPS_OVERLAYSTRETCHX |
1902 DDFXCAPS_OVERLAYSTRETCHYN |
1903 DDFXCAPS_OVERLAYSTRETCHXN |
1904 DDFXCAPS_OVERLAYSHRINKY |
1905 DDFXCAPS_OVERLAYSHRINKX |
1906 DDFXCAPS_OVERLAYSHRINKYN |
1907 DDFXCAPS_OVERLAYSHRINKXN;
1908
1909 // DDFXCAPS_OVERLAYARITHSTRETCHY
1910 // DDFXCAPS_OVERLAYARITHSTRETCHYN
1911 // DDFXCAPS_OVERLAYMIRRORLEFTRIGHT
1912 // DDFXCAPS_OVERLAYMIRRORUPDOWN
1913
1914 }
1915
1916 if(VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLT)
1917 && VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLTFOURCC))
1918 {
1919 pHALInfo->ddCaps.dwCaps |= DDCAPS_BLTFOURCC;
1920
1921 // Enable copy blts between Four CC formats for DShow acceleration
1922 pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_COPYFOURCC;
1923 }
1924
1925 if((VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLT) || VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_OVERLAY))
1926 && VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_COLORKEY))
1927 {
1928 pHALInfo->ddCaps.dwCKeyCaps = vboxVHWAToDDCKEYCAPS(pDev->vhwaInfo.colorKeyCaps);
1929 }
1930
1931// pHALInfo->ddCaps.dwSVBCaps = DDCAPS_BLT;
1932
1933// // We can do a texture from sysmem to video mem.
1934// pHALInfo->ddCaps.dwSVBCKeyCaps |= DDCKEYCAPS_DESTBLT |
1935// DDCKEYCAPS_DESTBLTCLRSPACE;
1936 pHALInfo->ddCaps.dwSVBFXCaps = 0;
1937
1938// // Fill in the sysmem->vidmem rops (only can copy);
1939// for( i=0;i<DD_ROP_SPACE;i++ )
1940// {
1941// pHALInfo->ddCaps.dwSVBRops[i] = rops[i];
1942// }
1943
1944
1945
1946//disabled
1947// pHALInfo->ddCaps.ddsCaps.dwCaps |= DDSCAPS_TEXTURE;
1948
1949//#if DX7_STEREO
1950// // Report the stereo capability back to runtime
1951// pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_STEREO;
1952// pHALInfo->ddCaps.dwSVCaps = DDSVCAPS_STEREOSEQUENTIAL;
1953//#endif
1954
1955 // Z Buffer is only 16 Bits
1956// pHALInfo->ddCaps.dwZBufferBitDepths = DDBD_16;
1957// pHALInfo->ddCaps.ddsCaps.dwCaps |= DDSCAPS_MIPMAP;
1958
1959 {
1960//#ifdef SUPPORT_VIDEOPORT
1961// // We support 1 video port. Must set CurrVideoPorts to 0
1962// // We can't do interleaved bobbing yet - maybe in the future.
1963// pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_VIDEOPORT |
1964// DDCAPS2_CANBOBNONINTERLEAVED;
1965//
1966// pHALInfo->ddCaps.dwMaxVideoPorts = 1;
1967// pHALInfo->ddCaps.dwCurrVideoPorts = 0;
1968//
1969//
1970//#endif // SUPPORT_VIDEOPORT
1971
1972 if(VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_OVERLAY)) /* no overlay support for now */
1973 {
1974 // Overlay is free to use.
1975 pHALInfo->ddCaps.dwMaxVisibleOverlays = pDev->vhwaInfo.numOverlays;
1976 pHALInfo->ddCaps.dwCurrVisibleOverlays = 0;
1977
1978 // Indicates that Perm3 has no stretch ratio limitation
1979 pHALInfo->ddCaps.dwMinOverlayStretch = 1;
1980 pHALInfo->ddCaps.dwMaxOverlayStretch = 32000;
1981 }
1982 }
1983
1984//#ifdef W95_DDRAW
1985//#ifdef USE_DD_CONTROL_COLOR
1986// // Enable colour control asc brightness, contrast, gamma.
1987// pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_COLORCONTROLPRIMARY;
1988//#endif
1989//#endif
1990
1991
1992 // Won't do Video-Sys mem Blits.
1993 pHALInfo->ddCaps.dwVSBCaps = 0;
1994 pHALInfo->ddCaps.dwVSBCKeyCaps = 0;
1995 pHALInfo->ddCaps.dwVSBFXCaps = 0;
1996 for( i=0;i<DD_ROP_SPACE;i++ )
1997 {
1998 pHALInfo->ddCaps.dwVSBRops[i] = 0;
1999 }
2000
2001 // Won't do Sys-Sys mem Blits
2002 pHALInfo->ddCaps.dwSSBCaps = 0;
2003 pHALInfo->ddCaps.dwSSBCKeyCaps = 0;
2004 pHALInfo->ddCaps.dwSSBFXCaps = 0;
2005 for( i=0;i<DD_ROP_SPACE;i++ )
2006 {
2007 pHALInfo->ddCaps.dwSSBRops[i] = 0;
2008 }
2009
2010 //
2011 // bit depths supported for alpha and Z
2012 //
2013// pHALInfo->ddCaps.dwAlphaBltConstBitDepths = DDBD_2 |
2014// DDBD_4 |
2015// DDBD_8;
2016//
2017// pHALInfo->ddCaps.dwAlphaBltPixelBitDepths = DDBD_1 |
2018// DDBD_8;
2019// pHALInfo->ddCaps.dwAlphaBltSurfaceBitDepths = DDBD_1 |
2020// DDBD_2 |
2021// DDBD_4 |
2022// DDBD_8;
2023
2024//disabled
2025// // No alpha blending for overlays, so I'm not sure what these should be.
2026// // Because we support 32bpp overlays, it's just that you can't use the
2027// // alpha bits for blending. Pass.
2028// pHALInfo->ddCaps.dwAlphaBltConstBitDepths = DDBD_2 |
2029// DDBD_4 |
2030// DDBD_8;
2031//
2032// pHALInfo->ddCaps.dwAlphaBltPixelBitDepths = DDBD_1 |
2033// DDBD_8;
2034//
2035// pHALInfo->ddCaps.dwAlphaBltSurfaceBitDepths = DDBD_1 |
2036// DDBD_2 |
2037// DDBD_4 |
2038// DDBD_8;
2039
2040 //
2041 // ROPS supported
2042 //
2043 for( i=0;i<DD_ROP_SPACE;i++ )
2044 {
2045 pHALInfo->ddCaps.dwRops[i] = rops[i];
2046 }
2047
2048//Reenable: // For DX5 and beyond we support this new informational callback.
2049// pHALInfo->GetDriverInfo = DdGetDriverInfo;
2050// pHALInfo->dwFlags |= DDHALINFO_GETDRIVERINFOSET;
2051//
2052//#if DX8_DDI
2053// // Flag our support for a new class of GUIDs that may come through
2054// // GetDriverInfo for DX8 drivers. (This support will be compulsory)
2055// pHALInfo->dwFlags |= DDHALINFO_GETDRIVERINFO2;
2056//#endif DX8_DDI
2057
2058 return true;
2059} // getDDHALInfo
2060
2061static DECLCALLBACK(void) vboxVHWAFreeCmdCompletion(PPDEV ppdev, VBOXVHWACMD * pCmd, void * pContext)
2062{
2063 vboxVHWACommandFree(ppdev, pCmd);
2064}
2065
2066static DECLCALLBACK(void) vboxVHWASurfBltCompletion(PPDEV ppdev, VBOXVHWACMD * pCmd, void * pContext)
2067{
2068 VBOXVHWACMD_SURF_BLT * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_BLT);
2069 PVBOXVHWASURFDESC pSrcDesc = (PVBOXVHWASURFDESC)pBody->SrcGuestSurfInfo;
2070 PVBOXVHWASURFDESC pDestDesc = (PVBOXVHWASURFDESC)pBody->DstGuestSurfInfo;
2071
2072 ASMAtomicDecU32(&pSrcDesc->cPendingBltsSrc);
2073 ASMAtomicDecU32(&pDestDesc->cPendingBltsDst);
2074
2075 vboxVHWACommandFree(ppdev, pCmd);
2076}
2077
2078static DECLCALLBACK(void) vboxVHWASurfFlipCompletion(PPDEV ppdev, VBOXVHWACMD * pCmd, void * pContext)
2079{
2080 VBOXVHWACMD_SURF_FLIP * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_FLIP);
2081 PVBOXVHWASURFDESC pCurrDesc = (PVBOXVHWASURFDESC)pBody->CurrGuestSurfInfo;
2082 PVBOXVHWASURFDESC pTargDesc = (PVBOXVHWASURFDESC)pBody->TargGuestSurfInfo;
2083
2084 ASMAtomicDecU32(&pCurrDesc->cPendingFlipsCurr);
2085 ASMAtomicDecU32(&pTargDesc->cPendingFlipsTarg);
2086
2087 vboxVHWACommandFree(ppdev, pCmd);
2088}
2089
2090#endif
2091
2092
2093
2094#endif /* VBOX_WITH_DDRAW */
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