VirtualBox

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

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

Additions: tabs -> spaces.

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

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