VirtualBox

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

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

2d: working multi-monitor + some fixing for working with not-using-VRAM mode

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