VirtualBox

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

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

Duplicate case

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