VirtualBox

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

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

video hw accel: DdLock optimization

  • Property svn:eol-style set to native
File size: 70.8 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 RECTL tmpRect, *pRect;
1058 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_LOCK));
1059
1060 pBody->u.in.offSurface = (uint64_t)lpSurfaceGlobal->fpVidMem;
1061
1062 if (lpLock->bHasRect)
1063 {
1064 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));
1065 vboxVHWAFromRECTL(&pBody->u.in.rect, &lpLock->rArea);
1066 pBody->u.in.rectValid = 1;
1067
1068 pRect = &lpLock->rArea;
1069
1070 }
1071 else
1072 {
1073 pBody->u.in.rectValid = 0;
1074
1075 tmpRect.left=0;
1076 tmpRect.top=0;
1077 tmpRect.right=lpSurfaceGlobal->wWidth-1;
1078 tmpRect.bottom=lpSurfaceGlobal->wHeight-1;
1079 pRect = &tmpRect;
1080 }
1081
1082 pBody->u.in.hSurf = pDesc->hHostHandle;
1083
1084 if(VBOXDD_CHECKFLAG(lpLock->dwFlags, DDLOCK_DISCARDCONTENTS))
1085 {
1086 pBody->u.in.flags |= VBOXVHWA_LOCK_DISCARDCONTENTS;
1087
1088 if(vboxVHWARegionIncluded(&pDesc->DirtyRegion, pRect))
1089 {
1090 vboxVHWARegionClear(&pDesc->DirtyRegion);
1091 }
1092// }
1093// else if(vboxVHWARegionInterse)
1094 /* we're not interested in completion, just send the command */
1095 vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWAFreeCmdCompletion, NULL);
1096 }
1097 else if(!vboxVHWARegionIntersects(&pDesc->DirtyRegion, pRect))
1098 {
1099 vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWAFreeCmdCompletion, NULL);
1100 }
1101 else
1102 {
1103 /* wait for the surface to be locked and memory buffer updated */
1104 vboxVHWACommandSubmit(pDev, pCmd);
1105 vboxVHWACommandFree(pDev, pCmd);
1106 vboxVHWARegionClear(&pDesc->DirtyRegion);
1107 }
1108
1109 lpLock->ddRVal = DD_OK;
1110 }
1111 else
1112 {
1113 lpLock->ddRVal = DDERR_GENERIC;
1114 }
1115 return DDHAL_DRIVER_NOTHANDLED;
1116 }
1117#endif
1118 if (lpSurfaceLocal->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
1119 {
1120 /* The updated rectangle must be reported only for the primary surface. */
1121 pDev->ddLock.bLocked = TRUE;
1122
1123 if (lpLock->bHasRect)
1124 {
1125 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));
1126 pDev->ddLock.rArea = lpLock->rArea;
1127 }
1128 else
1129 {
1130 pDev->ddLock.rArea.left = 0;
1131 pDev->ddLock.rArea.top = 0;
1132 pDev->ddLock.rArea.right = pDev->cxScreen;
1133 pDev->ddLock.rArea.bottom = pDev->cyScreen;
1134 }
1135 }
1136 else
1137 {
1138 DISPDBG((0, "%s: secondary surface.\n", __FUNCTION__));
1139 }
1140
1141 // Because we correctly set 'fpVidMem' to be the offset into our frame
1142 // buffer when we created the surface, DirectDraw will automatically take
1143 // care of adding in the user-mode frame buffer address if we return
1144 // DDHAL_DRIVER_NOTHANDLED:
1145 lpLock->ddRVal = DD_OK;
1146 return DDHAL_DRIVER_NOTHANDLED;
1147}
1148
1149/**
1150 * DdUnlock
1151 *
1152 * The DdUnLock callback function releases the lock held on the specified surface.
1153 *
1154 * Parameters
1155 * lpUnlock
1156 * Points to a DD_UNLOCKDATA structure that contains the information required to perform the lock release. *
1157 *
1158 * Return Value
1159 *
1160 * DdLock returns one of the following callback codes:
1161 *
1162 * DDHAL_DRIVER_HANDLED
1163 * DDHAL_DRIVER_NOTHANDLED
1164 *
1165 */
1166DWORD APIENTRY DdUnlock(PDD_UNLOCKDATA lpUnlock)
1167{
1168 PPDEV pDev = (PPDEV)lpUnlock->lpDD->dhpdev;
1169 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
1170#ifdef VBOX_WITH_VIDEOHWACCEL
1171 if (pDev->vhwaInfo.bVHWAEnabled)
1172 {
1173 DD_SURFACE_LOCAL* lpSurfaceLocal = lpUnlock->lpDDSurface;
1174 DD_SURFACE_GLOBAL* lpSurfaceGlobal = lpSurfaceLocal->lpGbl;
1175 PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC)lpSurfaceGlobal->dwReserved1;
1176 VBOXVHWACMD* pCmd;
1177
1178 //TODO: hadle vrdp properly
1179 if ( pDev->pVBVA->u32HostEvents
1180 & VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET)
1181 {
1182 vrdpReset (pDev);
1183
1184 pDev->pVBVA->u32HostEvents &=
1185 ~VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET;
1186 }
1187
1188 /* ensure we have host cmds processed to update pending blits and flips */
1189 vboxVHWACommandCheckHostCmds(pDev);
1190
1191 pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_UNLOCK, sizeof(VBOXVHWACMD_SURF_UNLOCK));
1192 // int rc = VERR_GENERAL_FAILURE;
1193 if(pCmd)
1194 {
1195 VBOXVHWACMD_SURF_UNLOCK * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_UNLOCK);
1196 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_UNLOCK));
1197
1198 pBody->u.in.hSurf = pDesc->hHostHandle;
1199
1200 vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWAFreeCmdCompletion, NULL);
1201
1202 lpUnlock->ddRVal = DD_OK;
1203 }
1204 else
1205 {
1206 lpUnlock->ddRVal = DDERR_GENERIC;
1207 }
1208
1209 return DDHAL_DRIVER_NOTHANDLED;
1210 }
1211#endif
1212 if (pDev->ddLock.bLocked)
1213 {
1214 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));
1215
1216#ifndef VBOX_WITH_HGSMI
1217 if (pDev->pInfo && vboxHwBufferBeginUpdate (pDev))
1218 {
1219 vbvaReportDirtyRect (pDev, &pDev->ddLock.rArea);
1220
1221 if ( pDev->pInfo->hostEvents.fu32Events
1222 & VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET)
1223 {
1224 vrdpReset (pDev);
1225
1226 pDev->pInfo->hostEvents.fu32Events &=
1227 ~VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET;
1228 }
1229
1230 if (pDev->vbva.pVbvaMemory->fu32ModeFlags
1231 & VBVA_F_MODE_VRDP)
1232 {
1233 vrdpReportDirtyRect (pDev, &pDev->ddLock.rArea);
1234 }
1235
1236 vboxHwBufferEndUpdate (pDev);
1237 }
1238#else
1239 if (pDev->bHGSMISupported && vboxHwBufferBeginUpdate (pDev))
1240 {
1241 vbvaReportDirtyRect (pDev, &pDev->ddLock.rArea);
1242
1243 if ( pDev->pVBVA->u32HostEvents
1244 & VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET)
1245 {
1246 vrdpReset (pDev);
1247
1248 pDev->pVBVA->u32HostEvents &=
1249 ~VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET;
1250 }
1251
1252 if (pDev->pVBVA->u32HostEvents
1253 & VBVA_F_MODE_VRDP)
1254 {
1255 vrdpReportDirtyRect (pDev, &pDev->ddLock.rArea);
1256 }
1257
1258 vboxHwBufferEndUpdate (pDev);
1259 }
1260#endif /* VBOX_WITH_HGSMI */
1261
1262 pDev->ddLock.bLocked = FALSE;
1263 }
1264
1265 lpUnlock->ddRVal = DD_OK;
1266 return DDHAL_DRIVER_NOTHANDLED;
1267}
1268
1269/**
1270 * DdDestroySurface
1271 *
1272 * The DdDestroySurface callback function destroys a DirectDraw surface.
1273 *
1274 * Parameters
1275 * lpDestroySurface
1276 * Points to a DD_DESTROYSURFACEDATA structure that contains the information needed to destroy a surface.
1277 *
1278 * Return Value
1279 *
1280 * DdDestroySurface returns one of the following callback codes:
1281 *
1282 * DDHAL_DRIVER_HANDLED
1283 * DDHAL_DRIVER_NOTHANDLED
1284 *
1285 */
1286DWORD APIENTRY DdDestroySurface(PDD_DESTROYSURFACEDATA lpDestroySurface)
1287{
1288#ifdef VBOX_WITH_VIDEOHWACCEL
1289 PPDEV pDev = (PPDEV)lpDestroySurface->lpDD->dhpdev;
1290 if(pDev->vhwaInfo.bVHWAEnabled)
1291 {
1292 DD_SURFACE_LOCAL* lpSurfaceLocal = lpDestroySurface->lpDDSurface;
1293 DD_SURFACE_GLOBAL* lpSurfaceGlobal = lpSurfaceLocal->lpGbl;
1294 VBOXVHWACMD* pCmd;
1295
1296 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
1297
1298 pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_DESTROY, sizeof(VBOXVHWACMD_SURF_DESTROY));
1299 // int rc = VERR_GENERAL_FAILURE;
1300 if(pCmd)
1301 {
1302 VBOXVHWACMD_SURF_DESTROY * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_DESTROY);
1303 PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC)lpSurfaceGlobal->dwReserved1;
1304
1305 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_DESTROY));
1306
1307 pBody->u.in.hSurf = pDesc->hHostHandle;
1308
1309 /* we're not interested in completion, just send the command */
1310 vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWAFreeCmdCompletion, NULL);
1311
1312 vboxVHWASurfDescFree(pDesc);
1313
1314 lpDestroySurface->ddRVal = DD_OK;
1315 }
1316 else
1317 {
1318 lpDestroySurface->ddRVal = DDERR_GENERIC;
1319 }
1320 }
1321 else
1322#endif
1323 lpDestroySurface->ddRVal = DD_OK;
1324 return DDHAL_DRIVER_HANDLED;
1325}
1326
1327
1328//-----------------------------------------------------------------------------
1329//
1330// DdSetExclusiveMode
1331//
1332// This function is called by DirectDraw when we switch from the GDI surface,
1333// to DirectDraw exclusive mode, e.g. to run a game in fullcreen mode.
1334// You only need to implement this function when you are using the
1335// 'HeapVidMemAllocAligned' function and allocate memory for Device Bitmaps
1336// and DirectDraw surfaces from the same heap.
1337//
1338// We use this call to disable GDI DeviceBitMaps when we are running in
1339// DirectDraw exclusive mode. Otherwise a DD app gets confused if both GDI and
1340// DirectDraw allocate memory from the same heap.
1341//
1342// See also DdFlipToGDISurface.
1343//
1344//-----------------------------------------------------------------------------
1345
1346
1347DWORD APIENTRY DdSetExclusiveMode(PDD_SETEXCLUSIVEMODEDATA lpSetExclusiveMode)
1348{
1349 PPDEV pDev = (PPDEV)lpSetExclusiveMode->lpDD->dhpdev;
1350 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
1351
1352 // remember setting of exclusive mode in pDev,
1353 // so GDI can stop to promote DeviceBitmaps into
1354 // video memory
1355
1356 pDev->bDdExclusiveMode = lpSetExclusiveMode->dwEnterExcl;
1357
1358 lpSetExclusiveMode->ddRVal = DD_OK;
1359
1360 return DDHAL_DRIVER_HANDLED;
1361}
1362
1363//-----------------------------------------------------------------------------
1364//
1365// DWORD DdFlipToGDISurface
1366//
1367// This function is called by DirectDraw when it flips to the surface on which
1368// GDI can write to.
1369//
1370//-----------------------------------------------------------------------------
1371
1372DWORD APIENTRY DdFlipToGDISurface(PDD_FLIPTOGDISURFACEDATA lpFlipToGDISurface)
1373{
1374 PPDEV pDev = (PPDEV)lpFlipToGDISurface->lpDD->dhpdev;
1375 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
1376
1377 pDev->dwNewDDSurfaceOffset = 0xffffffff;
1378
1379 lpFlipToGDISurface->ddRVal = DD_OK;
1380
1381 //
1382 // we return NOTHANDLED, then the ddraw runtime takes
1383 // care that we flip back to the primary...
1384 //
1385 return DDHAL_DRIVER_NOTHANDLED;
1386}
1387//-----------------------------------------------------------------------------
1388//
1389// DWORD DdFreeDriverMemory
1390//
1391// This function called by DirectDraw when it's running low on memory in
1392// our heap. You only need to implement this function if you use the
1393// DirectDraw 'HeapVidMemAllocAligned' function in your driver, and you
1394// can boot those allocations out of memory to make room for DirectDraw.
1395//
1396//-----------------------------------------------------------------------------
1397
1398DWORD APIENTRY DdFreeDriverMemory(PDD_FREEDRIVERMEMORYDATA lpFreeDriverMemory)
1399{
1400 PPDEV pDev = (PPDEV)lpFreeDriverMemory->lpDD->dhpdev;
1401 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
1402
1403 lpFreeDriverMemory->ddRVal = DDERR_OUTOFMEMORY;
1404 return DDHAL_DRIVER_HANDLED;
1405}
1406
1407#ifdef VBOX_WITH_VIDEOHWACCEL
1408DWORD APIENTRY DdSetColorKey(PDD_SETCOLORKEYDATA lpSetColorKey)
1409{
1410 PPDEV pDev = (PPDEV)lpSetColorKey->lpDD->dhpdev;
1411 DD_SURFACE_LOCAL* lpSurfaceLocal = lpSetColorKey->lpDDSurface;
1412 DD_SURFACE_GLOBAL* lpSurfaceGlobal = lpSurfaceLocal->lpGbl;
1413 VBOXVHWACMD* pCmd;
1414
1415 DISPDBG((0, "%s\n", __FUNCTION__));
1416
1417 pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_COLORKEY_SET, sizeof(VBOXVHWACMD_SURF_COLORKEY_SET));
1418 // int rc = VERR_GENERAL_FAILURE;
1419 if(pCmd)
1420 {
1421 VBOXVHWACMD_SURF_COLORKEY_SET * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_COLORKEY_SET);
1422 PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC)lpSurfaceGlobal->dwReserved1;
1423 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_COLORKEY_SET));
1424
1425 pBody->u.in.offSurface = (uint64_t)lpSurfaceGlobal->fpVidMem;
1426 pBody->u.in.hSurf = pDesc->hHostHandle;
1427 pBody->u.in.flags = vboxVHWAFromDDCKEYs(lpSetColorKey->dwFlags);
1428 vboxVHWAFromDDCOLORKEY(&pBody->u.in.CKey, &lpSetColorKey->ckNew);
1429
1430 vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWAFreeCmdCompletion, NULL);
1431 lpSetColorKey->ddRVal = DD_OK;
1432 }
1433 return DDHAL_DRIVER_HANDLED;
1434}
1435
1436DWORD APIENTRY DdAddAttachedSurface(PDD_ADDATTACHEDSURFACEDATA lpAddAttachedSurface)
1437{
1438 DISPDBG((0, "%s\n", __FUNCTION__));
1439 lpAddAttachedSurface->ddRVal = DD_OK;
1440 return DDHAL_DRIVER_HANDLED;
1441}
1442
1443DWORD APIENTRY DdBlt(PDD_BLTDATA lpBlt)
1444{
1445 PPDEV pDev = (PPDEV)lpBlt->lpDD->dhpdev;
1446 DISPDBG((0, "%s\n", __FUNCTION__));
1447#if DX9_DDI
1448 if(VBOXDD_CHECKFLAG(lpBlt->dwFlags, DDBLT_EXTENDED_PRESENTATION_STRETCHFACTOR))
1449 {
1450 lpBlt->ddRVal = DD_OK;
1451 }
1452 else
1453#endif
1454 {
1455 DD_SURFACE_LOCAL* lpDestSurfaceLocal = lpBlt->lpDDDestSurface;
1456 DD_SURFACE_GLOBAL* lpDestSurfaceGlobal = lpDestSurfaceLocal->lpGbl;
1457 DD_SURFACE_LOCAL* lpSrcSurfaceLocal = lpBlt->lpDDSrcSurface;
1458 DD_SURFACE_GLOBAL* lpSrcSurfaceGlobal = lpSrcSurfaceLocal->lpGbl;
1459 VBOXVHWACMD* pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_BLT, sizeof(VBOXVHWACMD_SURF_BLT));
1460 // int rc = VERR_GENERAL_FAILURE;
1461 if(pCmd)
1462 {
1463 VBOXVHWACMD_SURF_BLT * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_BLT);
1464 PVBOXVHWASURFDESC pSrcDesc = (PVBOXVHWASURFDESC)lpSrcSurfaceGlobal->dwReserved1;
1465 PVBOXVHWASURFDESC pDestDesc = (PVBOXVHWASURFDESC)lpDestSurfaceGlobal->dwReserved1;
1466 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_BLT));
1467
1468 pBody->u.in.offSrcSurface = (uint64_t)lpSrcSurfaceGlobal->fpVidMem;
1469 pBody->u.in.offDstSurface = (uint64_t)lpDestSurfaceGlobal->fpVidMem;
1470
1471 pBody->u.in.hDstSurf = pDestDesc->hHostHandle;
1472 vboxVHWAFromRECTL(&pBody->u.in.dstRect, &lpBlt->rDest);
1473 pBody->u.in.hSrcSurf = pSrcDesc->hHostHandle;
1474 vboxVHWAFromRECTL(&pBody->u.in.srcRect, &lpBlt->rSrc);
1475 pBody->DstGuestSurfInfo = (uint64_t)pDestDesc;
1476 pBody->SrcGuestSurfInfo = (uint64_t)pSrcDesc;
1477
1478 pBody->u.in.flags = vboxVHWAFromDDBLTs(lpBlt->dwFlags);
1479 vboxVHWAFromDDBLTFX(&pBody->u.in.desc, &lpBlt->bltFX);
1480
1481 ASMAtomicIncU32(&pSrcDesc->cPendingBltsSrc);
1482 ASMAtomicIncU32(&pDestDesc->cPendingBltsDst);
1483
1484 vboxVHWARegionAdd(&pDestDesc->DirtyRegion, &lpBlt->rDest);
1485 vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWASurfBltCompletion, NULL);
1486
1487 lpBlt->ddRVal = DD_OK;
1488 }
1489 else
1490 {
1491 lpBlt->ddRVal = DDERR_GENERIC;
1492 }
1493 }
1494
1495 return DDHAL_DRIVER_HANDLED;
1496}
1497
1498//DWORD APIENTRY DdDestroySurface(PDD_DESTROYSURFACEDATA lpDestroySurface)
1499//{
1500// DISPDBG((0, "%s\n", __FUNCTION__));
1501// lpDestroySurface->ddRVal = DD_OK;
1502// return DDHAL_DRIVER_HANDLED;
1503//}
1504
1505DWORD APIENTRY DdFlip(PDD_FLIPDATA lpFlip)
1506{
1507 PPDEV pDev = (PPDEV)lpFlip->lpDD->dhpdev;
1508 DD_SURFACE_LOCAL* lpTargSurfaceLocal = lpFlip->lpSurfTarg;
1509 DD_SURFACE_GLOBAL* lpTargSurfaceGlobal = lpTargSurfaceLocal->lpGbl;
1510 DD_SURFACE_LOCAL* lpCurrSurfaceLocal = lpFlip->lpSurfCurr;
1511 DD_SURFACE_GLOBAL* lpCurrSurfaceGlobal = lpCurrSurfaceLocal->lpGbl;
1512 PVBOXVHWASURFDESC pCurrDesc = (PVBOXVHWASURFDESC)lpCurrSurfaceGlobal->dwReserved1;
1513 PVBOXVHWASURFDESC pTargDesc = (PVBOXVHWASURFDESC)lpTargSurfaceGlobal->dwReserved1;
1514 VBOXVHWACMD* pCmd;
1515
1516 DISPDBG((0, "%s\n", __FUNCTION__));
1517
1518 /* ensure we have host cmds processed to update pending blits and flips */
1519 vboxVHWACommandCheckHostCmds(pDev);
1520
1521// if(VBOXDD_CHECKFLAG(lpLock, DDLOCK_DONOTWAIT))
1522 {
1523 if(
1524// ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc)
1525// || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst)
1526// ||
1527 ASMAtomicUoReadU32(&pCurrDesc->cPendingFlipsTarg)
1528 || ASMAtomicUoReadU32(&pCurrDesc->cPendingFlipsCurr)
1529 || ASMAtomicUoReadU32(&pTargDesc->cPendingFlipsTarg)
1530 || ASMAtomicUoReadU32(&pTargDesc->cPendingFlipsCurr))
1531 {
1532 lpFlip->ddRVal = DDERR_WASSTILLDRAWING;
1533 return DDHAL_DRIVER_HANDLED;
1534 }
1535 }
1536
1537 pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_FLIP, sizeof(VBOXVHWACMD_SURF_FLIP));
1538 // int rc = VERR_GENERAL_FAILURE;
1539 if(pCmd)
1540 {
1541 VBOXVHWACMD_SURF_FLIP * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_FLIP);
1542
1543 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_FLIP));
1544
1545 pBody->u.in.offCurrSurface = (uint64_t)lpCurrSurfaceGlobal->fpVidMem;
1546 pBody->u.in.offTargSurface = (uint64_t)lpTargSurfaceGlobal->fpVidMem;
1547
1548 pBody->u.in.hTargSurf = pTargDesc->hHostHandle;
1549 pBody->u.in.hCurrSurf = pCurrDesc->hHostHandle;
1550 pBody->TargGuestSurfInfo = (uint64_t)pTargDesc;
1551 pBody->CurrGuestSurfInfo = (uint64_t)pCurrDesc;
1552
1553// pBody->u.in.flags = vboxVHWAFromDDFLIPs(lpFlip->dwFlags);
1554
1555 ASMAtomicIncU32(&pCurrDesc->cPendingFlipsCurr);
1556 ASMAtomicIncU32(&pTargDesc->cPendingFlipsTarg);
1557
1558 vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWASurfFlipCompletion, NULL);
1559
1560 lpFlip->ddRVal = DD_OK;
1561 }
1562 else
1563 {
1564 lpFlip->ddRVal = DDERR_GENERIC;
1565 }
1566 return DDHAL_DRIVER_HANDLED;
1567}
1568
1569DWORD APIENTRY DdGetBltStatus(PDD_GETBLTSTATUSDATA lpGetBltStatus)
1570{
1571 PPDEV pDev = (PPDEV)lpGetBltStatus->lpDD->dhpdev;
1572
1573 DISPDBG((0, "%s\n", __FUNCTION__));
1574
1575 if(lpGetBltStatus->dwFlags == DDGBS_CANBLT)
1576 {
1577 lpGetBltStatus->ddRVal = DD_OK;
1578 }
1579 else /* DDGBS_ISBLTDONE */
1580 {
1581 DD_SURFACE_LOCAL* lpSurfaceLocal = lpGetBltStatus->lpDDSurface;
1582 DD_SURFACE_GLOBAL* lpSurfaceGlobal = lpSurfaceLocal->lpGbl;
1583 PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC)lpSurfaceGlobal->dwReserved1;
1584
1585 /* ensure we have host cmds processed to update pending blits and flips */
1586 vboxVHWACommandCheckHostCmds(pDev);
1587
1588 if(
1589 ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc)
1590 || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst)
1591 // || ASMAtomicUoReadU32(&pDesc->cPendingFlipsTarg)
1592 // || ASMAtomicUoReadU32(&pDesc->cPendingFlipsCurr)
1593 )
1594 {
1595 lpGetBltStatus->ddRVal = DDERR_WASSTILLDRAWING;
1596 }
1597 else
1598 {
1599 lpGetBltStatus->ddRVal = DD_OK;
1600 }
1601 }
1602
1603 return DDHAL_DRIVER_HANDLED;
1604}
1605
1606DWORD APIENTRY DdGetFlipStatus(PDD_GETFLIPSTATUSDATA lpGetFlipStatus)
1607{
1608 PPDEV pDev = (PPDEV)lpGetFlipStatus->lpDD->dhpdev;
1609 DD_SURFACE_LOCAL* lpSurfaceLocal = lpGetFlipStatus->lpDDSurface;
1610 DD_SURFACE_GLOBAL* lpSurfaceGlobal = lpSurfaceLocal->lpGbl;
1611 PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC)lpSurfaceGlobal->dwReserved1;
1612
1613 DISPDBG((0, "%s\n", __FUNCTION__));
1614
1615 /* ensure we have host cmds processed to update pending blits and flips */
1616 vboxVHWACommandCheckHostCmds(pDev);
1617
1618 if(
1619// ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc)
1620// || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst)
1621// ||
1622 ASMAtomicUoReadU32(&pDesc->cPendingFlipsTarg)
1623 || ASMAtomicUoReadU32(&pDesc->cPendingFlipsCurr)
1624 )
1625 {
1626 lpGetFlipStatus->ddRVal = DDERR_WASSTILLDRAWING;
1627 }
1628 else
1629 {
1630 lpGetFlipStatus->ddRVal = DD_OK;
1631 }
1632
1633// if(lpGetFlipStatus->dwFlags == DDGFS_CANFLIP)
1634// {
1635// lpGetFlipStatus->ddRVal = DD_OK;
1636// }
1637// else
1638// {
1639// lpGetFlipStatus->ddRVal = DD_OK;
1640// }
1641
1642 return DDHAL_DRIVER_HANDLED;
1643}
1644
1645DWORD APIENTRY DdSetOverlayPosition(PDD_SETOVERLAYPOSITIONDATA lpSetOverlayPosition)
1646{
1647 PPDEV pDev = (PPDEV)lpSetOverlayPosition->lpDD->dhpdev;
1648 DD_SURFACE_LOCAL* lpDestSurfaceLocal = lpSetOverlayPosition->lpDDDestSurface;
1649 DD_SURFACE_GLOBAL* lpDestSurfaceGlobal = lpDestSurfaceLocal->lpGbl;
1650 DD_SURFACE_LOCAL* lpSrcSurfaceLocal = lpSetOverlayPosition->lpDDSrcSurface;
1651 DD_SURFACE_GLOBAL* lpSrcSurfaceGlobal = lpSrcSurfaceLocal->lpGbl;
1652 VBOXVHWACMD* pCmd;
1653 PVBOXVHWASURFDESC pSrcDesc = (PVBOXVHWASURFDESC)lpSrcSurfaceGlobal->dwReserved1;
1654 PVBOXVHWASURFDESC pDestDesc = (PVBOXVHWASURFDESC)lpDestSurfaceGlobal->dwReserved1;
1655
1656 DISPDBG((0, "%s\n", __FUNCTION__));
1657
1658 if(pSrcDesc->bHidden)
1659 {
1660 lpSetOverlayPosition->ddRVal = DDERR_GENERIC;
1661 return DDHAL_DRIVER_HANDLED;
1662 }
1663
1664 pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_OVERLAY_SETPOSITION, sizeof(VBOXVHWACMD_SURF_OVERLAY_SETPOSITION));
1665 // int rc = VERR_GENERAL_FAILURE;
1666 if(pCmd)
1667 {
1668 VBOXVHWACMD_SURF_OVERLAY_SETPOSITION * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_OVERLAY_SETPOSITION);
1669
1670 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_OVERLAY_SETPOSITION));
1671
1672 pBody->u.in.offSrcSurface = (uint64_t)lpSrcSurfaceGlobal->fpVidMem;
1673 pBody->u.in.offDstSurface = (uint64_t)lpDestSurfaceGlobal->fpVidMem;
1674
1675 pBody->u.in.hDstSurf = pDestDesc->hHostHandle;
1676 pBody->u.in.hSrcSurf = pSrcDesc->hHostHandle;
1677
1678 pBody->u.in.xPos = lpSetOverlayPosition->lXPos;
1679 pBody->u.in.yPos = lpSetOverlayPosition->lYPos;
1680
1681 vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWAFreeCmdCompletion, NULL);
1682 lpSetOverlayPosition->ddRVal = DD_OK;
1683 }
1684
1685 return DDHAL_DRIVER_HANDLED;
1686}
1687
1688DWORD APIENTRY DdUpdateOverlay(PDD_UPDATEOVERLAYDATA lpUpdateOverlay)
1689{
1690 PPDEV pDev = (PPDEV)lpUpdateOverlay->lpDD->dhpdev;
1691 DD_SURFACE_LOCAL* lpDestSurfaceLocal = lpUpdateOverlay->lpDDDestSurface;
1692 DD_SURFACE_LOCAL* lpSrcSurfaceLocal = lpUpdateOverlay->lpDDSrcSurface;
1693 DD_SURFACE_GLOBAL* lpSrcSurfaceGlobal = lpSrcSurfaceLocal->lpGbl;
1694 VBOXVHWACMD* pCmd;
1695 PVBOXVHWASURFDESC pSrcDesc = (PVBOXVHWASURFDESC)lpSrcSurfaceGlobal->dwReserved1;
1696
1697 DISPDBG((0, "%s\n", __FUNCTION__));
1698
1699// if(pSrcDesc->bHidden)
1700// {
1701// lpUpdateOverlay->ddRVal = DDERR_GENERIC;
1702// return DDHAL_DRIVER_HANDLED;
1703// }
1704
1705 pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_OVERLAY_UPDATE, sizeof(VBOXVHWACMD_SURF_OVERLAY_UPDATE));
1706 // int rc = VERR_GENERAL_FAILURE;
1707 if(pCmd)
1708 {
1709 VBOXVHWACMD_SURF_OVERLAY_UPDATE * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_OVERLAY_UPDATE);
1710
1711 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_OVERLAY_UPDATE));
1712
1713 pBody->u.in.offSrcSurface = (uint64_t)lpSrcSurfaceGlobal->fpVidMem;
1714
1715 pBody->u.in.hSrcSurf = pSrcDesc->hHostHandle;
1716
1717 vboxVHWAFromRECTL(&pBody->u.in.dstRect, &lpUpdateOverlay->rDest);
1718 vboxVHWAFromRECTL(&pBody->u.in.srcRect, &lpUpdateOverlay->rSrc);
1719
1720 pBody->u.in.flags = vboxVHWAFromDDOVERs(lpUpdateOverlay->dwFlags);
1721 vboxVHWAFromDDOVERLAYFX(&pBody->u.in.desc, &lpUpdateOverlay->overlayFX);
1722
1723 if(lpUpdateOverlay->dwFlags & DDOVER_HIDE)
1724 {
1725 pSrcDesc->bHidden = true;
1726 }
1727 else if(lpUpdateOverlay->dwFlags & DDOVER_SHOW)
1728 {
1729 pSrcDesc->bHidden = false;
1730 }
1731
1732 if(lpDestSurfaceLocal)
1733 {
1734 DD_SURFACE_GLOBAL* lpDestSurfaceGlobal = lpDestSurfaceLocal->lpGbl;
1735 PVBOXVHWASURFDESC pDestDesc = (PVBOXVHWASURFDESC)lpDestSurfaceGlobal->dwReserved1;
1736 pBody->u.in.hDstSurf = pDestDesc->hHostHandle;
1737 pBody->u.in.offDstSurface = (uint64_t)lpDestSurfaceGlobal->fpVidMem;
1738 }
1739
1740 vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWAFreeCmdCompletion, NULL);
1741 lpUpdateOverlay->ddRVal = DD_OK;
1742 }
1743
1744 return DDHAL_DRIVER_HANDLED;
1745}
1746
1747//-----------------------------------------------------------------------------
1748// setupRops
1749//
1750// Build array for supported ROPS
1751//-----------------------------------------------------------------------------
1752static void
1753setupRops(
1754 LPBYTE proplist,
1755 LPDWORD proptable,
1756 int cnt )
1757{
1758 int i;
1759 DWORD idx;
1760 DWORD bit;
1761 DWORD rop;
1762
1763 for(i=0; i<cnt; i++)
1764 {
1765 rop = proplist[i];
1766 idx = rop / 32;
1767 bit = 1L << ((DWORD)(rop % 32));
1768 proptable[idx] |= bit;
1769 }
1770
1771} // setupRops
1772
1773//-----------------------------------------------------------------------------
1774//
1775// Function: __GetDDHALInfo
1776//
1777// Returns: void
1778//
1779// Description:
1780//
1781// Takes a pointer to a partially or fully filled in pThisDisplay and a pointer
1782// to an empty DDHALINFO and fills in the DDHALINFO. This eases porting to NT
1783// and means that caps changes are done in only one place. The pThisDisplay
1784// may not be fully constructed here, so you should only:
1785// a) Query the registry
1786// b) DISPDBG
1787// If you need to add anything to pThisDisplay for NT, you should fill it in
1788// during the DrvGetDirectDraw call.
1789//
1790// The problem here is when the code is run on NT. If there was any other way...
1791//
1792// The following caps have been found to cause NT to bail....
1793// DDCAPS_GDI, DDFXCAPS_BLTMIRRORUPDOWN, DDFXCAPS_BLTMIRRORLEFTRIGHT
1794//
1795//
1796//-----------------------------------------------------------------------------
1797
1798//
1799// use bits to indicate which ROPs you support.
1800//
1801// DWORD 0, bit 0 == ROP 0
1802// DWORD 8, bit 31 == ROP 255
1803//
1804
1805//static DWORD ropsAGP[DD_ROP_SPACE] = { 0 };
1806static BYTE ropListNT[] =
1807{
1808 SRCCOPY >> 16
1809// WHITENESS >> 16,
1810// BLACKNESS >> 16
1811};
1812
1813static DWORD rops[DD_ROP_SPACE] = { 0 };
1814
1815static bool
1816getDDHALInfo(
1817 PPDEV pDev,
1818 DD_HALINFO* pHALInfo)
1819{
1820 int i;
1821 if(!VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLT) && !VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_OVERLAY))
1822 return false;
1823
1824 pHALInfo->ddCaps.dwCaps |= vboxVHWAToDDCAPS(pDev->vhwaInfo.caps);
1825
1826 if(VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLT))
1827 {
1828 // Setup the ROPS we do.
1829 //TODO: hardcoded for now
1830 setupRops( ropListNT,
1831 rops,
1832 sizeof(ropListNT)/sizeof(ropListNT[0]));
1833 }
1834
1835// | DDCAPS_READSCANLINE
1836
1837
1838 pHALInfo->ddCaps.ddsCaps.dwCaps |= vboxVHWAToDDSCAPS(pDev->vhwaInfo.surfaceCaps);
1839
1840//disabled
1841// pHALInfo->ddCaps.dwCaps |= DDCAPS_3D |
1842// DDCAPS_BLTDEPTHFILL;
1843//
1844// pHALInfo->ddCaps.ddsCaps.dwCaps |= DDSCAPS_3DDEVICE |
1845// DDSCAPS_ZBUFFER |
1846// DDSCAPS_ALPHA;
1847 pHALInfo->ddCaps.dwCaps2 = vboxVHWAToDDCAPS2(pDev->vhwaInfo.caps2);
1848
1849
1850
1851//#if DX7_TEXMANAGEMENT
1852 // We need to set this bit up in order to be able to do
1853 // out own texture management
1854// pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_CANMANAGETEXTURE;
1855//#if DX8_DDI
1856// pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_CANMANAGERESOURCE;
1857//#endif
1858//#endif
1859
1860//#if DX8_DDI
1861 // We need to flag we can run in windowed mode, otherwise we
1862 // might get restricted by apps to run in fullscreen only
1863 pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_CANRENDERWINDOWED;
1864
1865 // Also permit surfaces wider than the display buffer.
1866 pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_WIDESURFACES;
1867//#endif
1868
1869//#if DX8_DDI
1870 // We need to flag we support dynamic textures. That is , apps can
1871 // lock with high frequency video memory textures without paying a
1872 // penalty for it. Since on this sample driver we only support
1873 // linear memory formats for textures we don't need to do anything
1874 // else for this support. Otherwise we would have to keep two surfaces
1875 // for textures created with the DDSCAPS2_HINTDYNAMIC hint in order
1876 // to efficiently do the linear<->swizzled transformation or keep the
1877 // texture permanantly in an unswizzled state.
1878// pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_DYNAMICTEXTURES;
1879 #if DX9_DDI
1880 // Notice that dynamic textures MUST be supported in order to instantiate a DX9 device
1881 #endif // DX9_DDI
1882//#endif
1883
1884// pHALInfo->ddCaps.dwFXCaps = 0;
1885
1886 // P3RX can do:
1887 // 1. Stretching/Shrinking
1888 // 2. YUV->RGB conversion
1889 // 3. Mirroring in X and Y
1890 // 4. ColorKeying from a source color and a source color space
1891 if(VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLT)
1892 && VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLTSTRETCH))
1893 {
1894 // Special effects caps
1895 //TODO: filter them out
1896 pHALInfo->ddCaps.dwFXCaps |= DDFXCAPS_BLTSTRETCHY |
1897 DDFXCAPS_BLTSTRETCHX |
1898 DDFXCAPS_BLTSTRETCHYN |
1899 DDFXCAPS_BLTSTRETCHXN |
1900 DDFXCAPS_BLTSHRINKY |
1901 DDFXCAPS_BLTSHRINKX |
1902 DDFXCAPS_BLTSHRINKYN |
1903 DDFXCAPS_BLTSHRINKXN;
1904
1905 // DDFXCAPS_BLTARITHSTRETCHY
1906 // DDFXCAPS_BLTARITHSTRETCHYN
1907 // DDFXCAPS_BLTMIRRORLEFTRIGHT
1908 // DDFXCAPS_BLTMIRRORUPDOWN
1909 // DDFXCAPS_BLTROTATION90
1910 }
1911
1912 if(VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_OVERLAY)
1913 && VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_OVERLAYSTRETCH))
1914 {
1915 // Special effects caps
1916 //TODO: filter them out
1917 pHALInfo->ddCaps.dwFXCaps |= DDFXCAPS_OVERLAYSTRETCHY |
1918 DDFXCAPS_OVERLAYSTRETCHX |
1919 DDFXCAPS_OVERLAYSTRETCHYN |
1920 DDFXCAPS_OVERLAYSTRETCHXN |
1921 DDFXCAPS_OVERLAYSHRINKY |
1922 DDFXCAPS_OVERLAYSHRINKX |
1923 DDFXCAPS_OVERLAYSHRINKYN |
1924 DDFXCAPS_OVERLAYSHRINKXN;
1925
1926 // DDFXCAPS_OVERLAYARITHSTRETCHY
1927 // DDFXCAPS_OVERLAYARITHSTRETCHYN
1928 // DDFXCAPS_OVERLAYMIRRORLEFTRIGHT
1929 // DDFXCAPS_OVERLAYMIRRORUPDOWN
1930
1931 }
1932
1933 if(VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLT)
1934 && VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLTFOURCC))
1935 {
1936 pHALInfo->ddCaps.dwCaps |= DDCAPS_BLTFOURCC;
1937
1938 // Enable copy blts between Four CC formats for DShow acceleration
1939 pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_COPYFOURCC;
1940 }
1941
1942 if((VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLT) || VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_OVERLAY))
1943 && VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_COLORKEY))
1944 {
1945 pHALInfo->ddCaps.dwCKeyCaps = vboxVHWAToDDCKEYCAPS(pDev->vhwaInfo.colorKeyCaps);
1946 }
1947
1948// pHALInfo->ddCaps.dwSVBCaps = DDCAPS_BLT;
1949
1950// // We can do a texture from sysmem to video mem.
1951// pHALInfo->ddCaps.dwSVBCKeyCaps |= DDCKEYCAPS_DESTBLT |
1952// DDCKEYCAPS_DESTBLTCLRSPACE;
1953 pHALInfo->ddCaps.dwSVBFXCaps = 0;
1954
1955// // Fill in the sysmem->vidmem rops (only can copy);
1956// for( i=0;i<DD_ROP_SPACE;i++ )
1957// {
1958// pHALInfo->ddCaps.dwSVBRops[i] = rops[i];
1959// }
1960
1961
1962
1963//disabled
1964// pHALInfo->ddCaps.ddsCaps.dwCaps |= DDSCAPS_TEXTURE;
1965
1966//#if DX7_STEREO
1967// // Report the stereo capability back to runtime
1968// pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_STEREO;
1969// pHALInfo->ddCaps.dwSVCaps = DDSVCAPS_STEREOSEQUENTIAL;
1970//#endif
1971
1972 // Z Buffer is only 16 Bits
1973// pHALInfo->ddCaps.dwZBufferBitDepths = DDBD_16;
1974// pHALInfo->ddCaps.ddsCaps.dwCaps |= DDSCAPS_MIPMAP;
1975
1976 {
1977//#ifdef SUPPORT_VIDEOPORT
1978// // We support 1 video port. Must set CurrVideoPorts to 0
1979// // We can't do interleaved bobbing yet - maybe in the future.
1980// pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_VIDEOPORT |
1981// DDCAPS2_CANBOBNONINTERLEAVED;
1982//
1983// pHALInfo->ddCaps.dwMaxVideoPorts = 1;
1984// pHALInfo->ddCaps.dwCurrVideoPorts = 0;
1985//
1986//
1987//#endif // SUPPORT_VIDEOPORT
1988
1989 if(VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_OVERLAY)) /* no overlay support for now */
1990 {
1991 // Overlay is free to use.
1992 pHALInfo->ddCaps.dwMaxVisibleOverlays = pDev->vhwaInfo.numOverlays;
1993 pHALInfo->ddCaps.dwCurrVisibleOverlays = 0;
1994
1995 // Indicates that Perm3 has no stretch ratio limitation
1996 pHALInfo->ddCaps.dwMinOverlayStretch = 1;
1997 pHALInfo->ddCaps.dwMaxOverlayStretch = 32000;
1998 }
1999 }
2000
2001//#ifdef W95_DDRAW
2002//#ifdef USE_DD_CONTROL_COLOR
2003// // Enable colour control asc brightness, contrast, gamma.
2004// pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_COLORCONTROLPRIMARY;
2005//#endif
2006//#endif
2007
2008
2009 // Won't do Video-Sys mem Blits.
2010 pHALInfo->ddCaps.dwVSBCaps = 0;
2011 pHALInfo->ddCaps.dwVSBCKeyCaps = 0;
2012 pHALInfo->ddCaps.dwVSBFXCaps = 0;
2013 for( i=0;i<DD_ROP_SPACE;i++ )
2014 {
2015 pHALInfo->ddCaps.dwVSBRops[i] = 0;
2016 }
2017
2018 // Won't do Sys-Sys mem Blits
2019 pHALInfo->ddCaps.dwSSBCaps = 0;
2020 pHALInfo->ddCaps.dwSSBCKeyCaps = 0;
2021 pHALInfo->ddCaps.dwSSBFXCaps = 0;
2022 for( i=0;i<DD_ROP_SPACE;i++ )
2023 {
2024 pHALInfo->ddCaps.dwSSBRops[i] = 0;
2025 }
2026
2027 //
2028 // bit depths supported for alpha and Z
2029 //
2030// pHALInfo->ddCaps.dwAlphaBltConstBitDepths = DDBD_2 |
2031// DDBD_4 |
2032// DDBD_8;
2033//
2034// pHALInfo->ddCaps.dwAlphaBltPixelBitDepths = DDBD_1 |
2035// DDBD_8;
2036// pHALInfo->ddCaps.dwAlphaBltSurfaceBitDepths = DDBD_1 |
2037// DDBD_2 |
2038// DDBD_4 |
2039// DDBD_8;
2040
2041//disabled
2042// // No alpha blending for overlays, so I'm not sure what these should be.
2043// // Because we support 32bpp overlays, it's just that you can't use the
2044// // alpha bits for blending. Pass.
2045// pHALInfo->ddCaps.dwAlphaBltConstBitDepths = DDBD_2 |
2046// DDBD_4 |
2047// DDBD_8;
2048//
2049// pHALInfo->ddCaps.dwAlphaBltPixelBitDepths = DDBD_1 |
2050// DDBD_8;
2051//
2052// pHALInfo->ddCaps.dwAlphaBltSurfaceBitDepths = DDBD_1 |
2053// DDBD_2 |
2054// DDBD_4 |
2055// DDBD_8;
2056
2057 //
2058 // ROPS supported
2059 //
2060 for( i=0;i<DD_ROP_SPACE;i++ )
2061 {
2062 pHALInfo->ddCaps.dwRops[i] = rops[i];
2063 }
2064
2065//Reenable: // For DX5 and beyond we support this new informational callback.
2066// pHALInfo->GetDriverInfo = DdGetDriverInfo;
2067// pHALInfo->dwFlags |= DDHALINFO_GETDRIVERINFOSET;
2068//
2069//#if DX8_DDI
2070// // Flag our support for a new class of GUIDs that may come through
2071// // GetDriverInfo for DX8 drivers. (This support will be compulsory)
2072// pHALInfo->dwFlags |= DDHALINFO_GETDRIVERINFO2;
2073//#endif DX8_DDI
2074
2075 return true;
2076} // getDDHALInfo
2077
2078static DECLCALLBACK(void) vboxVHWAFreeCmdCompletion(PPDEV ppdev, VBOXVHWACMD * pCmd, void * pContext)
2079{
2080 vboxVHWACommandFree(ppdev, pCmd);
2081}
2082
2083static DECLCALLBACK(void) vboxVHWASurfBltCompletion(PPDEV ppdev, VBOXVHWACMD * pCmd, void * pContext)
2084{
2085 VBOXVHWACMD_SURF_BLT * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_BLT);
2086 PVBOXVHWASURFDESC pSrcDesc = (PVBOXVHWASURFDESC)pBody->SrcGuestSurfInfo;
2087 PVBOXVHWASURFDESC pDestDesc = (PVBOXVHWASURFDESC)pBody->DstGuestSurfInfo;
2088
2089 ASMAtomicDecU32(&pSrcDesc->cPendingBltsSrc);
2090 ASMAtomicDecU32(&pDestDesc->cPendingBltsDst);
2091
2092 vboxVHWACommandFree(ppdev, pCmd);
2093}
2094
2095static DECLCALLBACK(void) vboxVHWASurfFlipCompletion(PPDEV ppdev, VBOXVHWACMD * pCmd, void * pContext)
2096{
2097 VBOXVHWACMD_SURF_FLIP * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_FLIP);
2098 PVBOXVHWASURFDESC pCurrDesc = (PVBOXVHWASURFDESC)pBody->CurrGuestSurfInfo;
2099 PVBOXVHWASURFDESC pTargDesc = (PVBOXVHWASURFDESC)pBody->TargGuestSurfInfo;
2100
2101 ASMAtomicDecU32(&pCurrDesc->cPendingFlipsCurr);
2102 ASMAtomicDecU32(&pTargDesc->cPendingFlipsTarg);
2103
2104 vboxVHWACommandFree(ppdev, pCmd);
2105}
2106
2107#endif
2108
2109
2110
2111#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