VirtualBox

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

Last change on this file since 35501 was 35351, checked in by vboxsync, 14 years ago

scm cleanups.

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