VirtualBox

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

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

Video hw accel: fallback for PBO allocation failure

  • Property svn:eol-style set to native
File size: 85.4 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#ifndef VBOX_WITH_VIDEOHWACCEL
208 pVm->ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
209#endif
210 DISPDBG((0, "fpStart %x fpEnd %x\n", pVm->fpStart, pVm->fpEnd));
211
212 pVm++;
213 }
214 }
215
216#ifdef VBOX_WITH_VIDEOHWACCEL
217 if(pDev->vhwaInfo.bVHWAEnabled)
218 {
219// // TODO: filter out hw-unsupported fourccs
220//#define FOURCC_YUV422 (MAKEFOURCC('Y','U','Y','2'))
221//#define FOURCC_YUV411 (MAKEFOURCC('Y','4','1','1'))
222//
223// static DWORD fourCC[] = { FOURCC_YUV422, FOURCC_YUV411 }; // The FourCC's we support
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 = 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 lpSurfaceGlobal->dwReserved1 = (ULONG_PTR)pDesc;
678 lPitch = pBody->SurfInfo.pitch;
679// lBpp = pBody->SurfInfo.bitsPerPixel;
680// pDesc->cBitsPerPixel = lBpp;
681#if 0
682 lpSurfaceGlobal->dwBlockSizeX = lPitch;
683 lpSurfaceGlobal->dwBlockSizeY = lpSurfaceGlobal->wHeight;
684 lpSurfaceGlobal->lPitch = lPitch;
685#else
686 lpSurfaceGlobal->dwBlockSizeX = surfSizeX;
687 lpSurfaceGlobal->dwBlockSizeY = surfSizeY;
688 lpSurfaceGlobal->lPitch = lPitch;
689#endif
690#if 1
691 lpSurfaceDesc->lPitch = lpSurfaceGlobal->lPitch;
692 lpSurfaceDesc->dwFlags |= DDSD_PITCH;
693#endif
694
695 lpCreateSurface->ddRVal = DD_OK;
696 }
697 else
698 {
699 vboxVHWASurfDescFree(pDesc);
700 lpCreateSurface->ddRVal = DDERR_GENERIC;
701 }
702 }
703 vbvaVHWACommandRelease(pDev, pCmd);
704 }
705 return DDHAL_DRIVER_NOTHANDLED;
706 }
707#endif
708 lpSurfaceGlobal->dwReserved1 = 0;
709
710 if (lpSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED4)
711 {
712 lBpp = 4;
713 lPitch = lpSurfaceGlobal->wWidth/2;
714 lPitch = (lPitch + 31) & ~31;
715 }
716 else
717 if (lpSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8)
718 {
719 lBpp = 8;
720 lPitch = lpSurfaceGlobal->wWidth;
721 lPitch = (lPitch + 31) & ~31;
722 }
723 else
724 {
725 lBpp = lpSurfaceDesc->ddpfPixelFormat.dwRGBBitCount;
726 lPitch = lpSurfaceGlobal->wWidth*(lBpp/8);
727 }
728 DISPDBG((0, "New surface (%d,%d)\n", lpSurfaceGlobal->wWidth, lpSurfaceGlobal->wHeight));
729 DISPDBG((0, "BPP %d lPitch=%d\n", lBpp, lPitch));
730
731 lpSurfaceGlobal->dwBlockSizeX = lPitch;
732 lpSurfaceGlobal->dwBlockSizeY = lpSurfaceGlobal->wHeight;
733 lpSurfaceGlobal->lPitch = lPitch;
734
735 lpSurfaceDesc->lPitch = lpSurfaceGlobal->lPitch;
736 lpSurfaceDesc->dwFlags |= DDSD_PITCH;
737
738 //
739 // Modify surface descriptions as appropriate and let Direct
740 // Draw perform the allocation if the surface was not the primary
741 //
742 if (lpSurfaceLocal->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
743 {
744 DISPDBG((0, "-> primary surface\n"));
745 lpSurfaceGlobal->fpVidMem = 0;
746 }
747 else
748 {
749 DISPDBG((0, "-> secondary surface\n"));
750 lpSurfaceGlobal->fpVidMem = DDHAL_PLEASEALLOC_BLOCKSIZE;
751 }
752
753 return DDHAL_DRIVER_NOTHANDLED;
754}
755
756/**
757 * DdCanCreateSurface
758 *
759 * The DdCanCreateSurface callback function indicates whether the driver can create a surface of the specified surface description.
760 *
761 *
762 * Parameters
763 * lpCanCreateSurface
764 * Points to the DD_CANCREATESURFACEDATA structure containing the information required for the driver to determine whether a surface can be created.
765 *
766 * Return Value
767 *
768 * DdCanCreateSurface returns one of the following callback codes:
769 *
770 * DDHAL_DRIVER_HANDLED
771 * DDHAL_DRIVER_NOTHANDLED
772 *
773 */
774DWORD APIENTRY DdCanCreateSurface(PDD_CANCREATESURFACEDATA lpCanCreateSurface)
775{
776 PPDEV pDev = (PPDEV)lpCanCreateSurface->lpDD->dhpdev;
777
778 PDD_SURFACEDESC lpDDS = lpCanCreateSurface->lpDDSurfaceDesc;
779
780 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
781
782#ifdef VBOX_WITH_VIDEOHWACCEL
783 if(pDev->vhwaInfo.bVHWAEnabled)
784 {
785 VBOXVHWACMD* pCmd;
786 uint32_t unsupportedSCaps = vboxVHWAUnsupportedDDSCAPS(lpDDS->ddsCaps.dwCaps);
787 Assert(!unsupportedSCaps);
788 if(unsupportedSCaps)
789 {
790 VHWADBG(("vboxVHWASurfCanCreate: unsupported ddscaps: 0x%x", unsupportedSCaps));
791 lpCanCreateSurface->ddRVal = DDERR_INVALIDCAPS;
792 return DDHAL_DRIVER_HANDLED;
793 }
794
795 unsupportedSCaps = vboxVHWAUnsupportedDDPFS(lpDDS->ddpfPixelFormat.dwFlags);
796 Assert(!unsupportedSCaps);
797 if(unsupportedSCaps)
798 {
799 VHWADBG(("vboxVHWASurfCanCreate: unsupported pixel format: 0x%x", unsupportedSCaps));
800 lpCanCreateSurface->ddRVal = DDERR_INVALIDPIXELFORMAT;
801 return DDHAL_DRIVER_HANDLED;
802 }
803
804 pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_CANCREATE, sizeof(VBOXVHWACMD_SURF_CANCREATE));
805 if(pCmd)
806 {
807 int rc;
808 VBOXVHWACMD_SURF_CANCREATE * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_CANCREATE);
809 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_CANCREATE));
810
811 rc = vboxVHWAFromDDSURFACEDESC(&pBody->SurfInfo, lpDDS);
812 pBody->u.in.bIsDifferentPixelFormat = lpCanCreateSurface->bIsDifferentPixelFormat;
813
814 vboxVHWACommandSubmit(pDev, pCmd);
815 Assert(pCmd->rc == VINF_SUCCESS);
816 if(pCmd->rc == VINF_SUCCESS)
817 {
818#ifdef DEBUGVHWASTRICT
819 Assert(!pBody->u.out.ErrInfo);
820#endif
821 if(pBody->u.out.ErrInfo)
822 {
823 lpCanCreateSurface->ddRVal = DDERR_GENERIC;
824 }
825 else
826 {
827 lpCanCreateSurface->ddRVal = DD_OK;
828 }
829 }
830 else
831 {
832 lpCanCreateSurface->ddRVal = DDERR_GENERIC;
833 }
834 vbvaVHWACommandRelease(pDev, pCmd);
835 }
836 else
837 {
838 lpCanCreateSurface->ddRVal = DDERR_GENERIC;
839 }
840 return DDHAL_DRIVER_HANDLED;
841 }
842#endif
843
844 if (lpDDS->ddsCaps.dwCaps & DDSCAPS_ZBUFFER)
845 {
846 DISPDBG((0, "No Z-Bufer support\n"));
847 lpCanCreateSurface->ddRVal = DDERR_INVALIDPIXELFORMAT;
848 return DDHAL_DRIVER_HANDLED;
849 }
850 if (lpDDS->ddsCaps.dwCaps & DDSCAPS_TEXTURE)
851 {
852 DISPDBG((0, "No texture support\n"));
853 lpCanCreateSurface->ddRVal = DDERR_INVALIDPIXELFORMAT;
854 return DDHAL_DRIVER_HANDLED;
855 }
856 if (lpCanCreateSurface->bIsDifferentPixelFormat && (lpDDS->ddpfPixelFormat.dwFlags & DDPF_FOURCC))
857 {
858 DISPDBG((0, "FOURCC not supported\n"));
859 lpCanCreateSurface->ddRVal = DDERR_INVALIDPIXELFORMAT;
860 return DDHAL_DRIVER_HANDLED;
861 }
862
863 lpCanCreateSurface->ddRVal = DD_OK;
864 return DDHAL_DRIVER_HANDLED;
865}
866
867// ***************************WIN NT ONLY**********************************
868//
869// DdMapMemory
870//
871// Maps application-modifiable portions of the frame buffer into the
872// user-mode address space of the specified process, or unmaps memory.
873//
874// DdMapMemory is called to perform memory mapping before the first call to
875// DdLock. The handle returned by the driver in fpProcess will be passed to
876// every DdLock call made on the driver.
877//
878// DdMapMemory is also called to unmap memory after the last DdUnLock call is
879// made.
880//
881// To prevent driver crashes, the driver must not map any portion of the frame
882// buffer that must not be modified by an application.
883//
884// Parameters
885// lpMapMemory
886// Points to a DD_MAPMEMORYDATA structure that contains details for
887// the memory mapping or unmapping operation.
888//
889// .lpDD
890// Points to a DD_DIRECTDRAW_GLOBAL structure that represents
891// the driver.
892// .bMap
893// Specifies the memory operation that the driver should perform.
894// A value of TRUE indicates that the driver should map memory;
895// FALSE means that the driver should unmap memory.
896// .hProcess
897// Specifies a handle to the process whose address space is
898// affected.
899// .fpProcess
900// Specifies the location in which the driver should return the
901// base address of the process's memory mapped space when bMap
902// is TRUE. When bMap is FALSE, fpProcess contains the base
903// address of the memory to be unmapped by the driver.
904// .ddRVal
905// Specifies the location in which the driver writes the return
906// value of the DdMapMemory callback. A return code of DD_OK
907// indicates success.
908//
909//-----------------------------------------------------------------------------
910
911DWORD CALLBACK DdMapMemory(PDD_MAPMEMORYDATA lpMapMemory)
912{
913 PPDEV pDev = (PPDEV)lpMapMemory->lpDD->dhpdev;
914
915 VIDEO_SHARE_MEMORY ShareMemory;
916 VIDEO_SHARE_MEMORY_INFORMATION ShareMemoryInformation;
917 DWORD ReturnedDataLength;
918
919 DISPDBG((0, "%s: %p bMap %d\n", __FUNCTION__, pDev, lpMapMemory->bMap));
920
921 if (lpMapMemory->bMap)
922 {
923 ShareMemory.ProcessHandle = lpMapMemory->hProcess;
924
925 // 'RequestedVirtualAddress' isn't actually used for the SHARE IOCTL:
926
927 ShareMemory.RequestedVirtualAddress = 0;
928
929 // We map in starting at the top of the frame buffer:
930
931 ShareMemory.ViewOffset = 0;
932
933 // We map down to the end of the frame buffer, including the offscreen heap.
934 ShareMemory.ViewSize = pDev->layout.offVBVABuffer;
935
936 DISPDBG((0, "ViewSize = %x\n", ShareMemory.ViewSize));
937
938 if (EngDeviceIoControl(pDev->hDriver,
939 IOCTL_VIDEO_SHARE_VIDEO_MEMORY,
940 &ShareMemory,
941 sizeof(VIDEO_SHARE_MEMORY),
942 &ShareMemoryInformation,
943 sizeof(VIDEO_SHARE_MEMORY_INFORMATION),
944 &ReturnedDataLength))
945 {
946 DISPDBG((0, "Failed IOCTL_VIDEO_SHARE_MEMORY\n"));
947
948 lpMapMemory->ddRVal = DDERR_GENERIC;
949
950 DISPDBG((0, "DdMapMemory: Exit GEN, DDHAL_DRIVER_HANDLED\n"));
951
952 return(DDHAL_DRIVER_HANDLED);
953 }
954
955 lpMapMemory->fpProcess =
956 (FLATPTR) ShareMemoryInformation.VirtualAddress;
957 }
958 else
959 {
960 ShareMemory.ProcessHandle = lpMapMemory->hProcess;
961 ShareMemory.ViewOffset = 0;
962 ShareMemory.ViewSize = 0;
963 ShareMemory.RequestedVirtualAddress = (VOID*) lpMapMemory->fpProcess;
964
965 if (EngDeviceIoControl(pDev->hDriver,
966 IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY,
967 &ShareMemory,
968 sizeof(VIDEO_SHARE_MEMORY),
969 NULL,
970 0,
971 &ReturnedDataLength))
972 {
973 DISPDBG((0, "Failed IOCTL_VIDEO_UNSHARE_MEMORY\n"));
974 }
975 }
976
977 lpMapMemory->ddRVal = DD_OK;
978
979 return(DDHAL_DRIVER_HANDLED);
980}
981
982/**
983 * DdLock
984 *
985 * 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.
986 *
987 * Parameters
988 * lpLock
989 * Points to a DD_LOCKDATA structure that contains the information required to perform the lockdown.
990 *
991 * Return Value
992 *
993 * DdLock returns one of the following callback codes:
994 *
995 * DDHAL_DRIVER_HANDLED
996 * DDHAL_DRIVER_NOTHANDLED
997 *
998 */
999DWORD APIENTRY DdLock(PDD_LOCKDATA lpLock)
1000{
1001 PPDEV pDev = (PPDEV)lpLock->lpDD->dhpdev;
1002 DD_SURFACE_LOCAL* lpSurfaceLocal = lpLock->lpDDSurface;
1003
1004 DISPDBG((0, "%s: %p bHasRect = %d fpProcess = %p\n", __FUNCTION__, pDev, lpLock->bHasRect, lpLock->fpProcess));
1005
1006#ifdef VBOX_WITH_VIDEOHWACCEL
1007 if(pDev->vhwaInfo.bVHWAEnabled)
1008 {
1009#ifndef DBG_DDSTUBS
1010 DD_SURFACE_GLOBAL* lpSurfaceGlobal = lpSurfaceLocal->lpGbl;
1011 PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC)lpSurfaceGlobal->dwReserved1;
1012 RECTL tmpRect, *pRect;
1013
1014 if(ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc)
1015 || ASMAtomicUoReadU32(&pDesc->cPendingFlipsCurr)
1016 || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst)
1017 || ASMAtomicUoReadU32(&pDesc->cPendingFlipsTarg))
1018 {
1019 /* ensure we have host cmds processed to update pending blits and flips */
1020 vboxVHWACommandCheckHostCmds(pDev);
1021 if(ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc)
1022 || ASMAtomicUoReadU32(&pDesc->cPendingFlipsCurr)
1023 || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst)
1024 || ASMAtomicUoReadU32(&pDesc->cPendingFlipsTarg))
1025 {
1026 lpLock->ddRVal = DDERR_WASSTILLDRAWING;
1027 return DDHAL_DRIVER_HANDLED;
1028 }
1029 }
1030
1031// if(VBOXDD_CHECKFLAG(lpLock->dwFlags, DDLOCK_SURFACEMEMORYPTR))
1032// {
1033// lpLock->lpSurfData = (LPVOID)(lpSurfaceGlobal->fpVidMem + lpSurfaceGlobal->lPitch * lpLock->rArea.top
1034// + lpLock->rArea.left * pDesc->cBitsPerPixel/8);
1035// }
1036
1037 if (lpLock->bHasRect)
1038 {
1039 pRect = &lpLock->rArea;
1040 }
1041 else
1042 {
1043 tmpRect.left=0;
1044 tmpRect.top=0;
1045 tmpRect.right=lpSurfaceGlobal->wWidth-1;
1046 tmpRect.bottom=lpSurfaceGlobal->wHeight-1;
1047 pRect = &tmpRect;
1048 }
1049
1050 if(VBOXDD_CHECKFLAG(lpLock->dwFlags, DDLOCK_DISCARDCONTENTS))
1051 {
1052// pBody->u.in.flags |= VBOXVHWA_LOCK_DISCARDCONTENTS;
1053
1054 vboxVHWARegionTrySubstitute(&pDesc->NonupdatedMemRegion, pRect);
1055// /* we're not interested in completion, just send the command */
1056// vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWAFreeCmdCompletion, NULL);
1057 vboxVHWARegionAdd(&pDesc->UpdatedMemRegion, pRect);
1058 lpLock->ddRVal = DD_OK;
1059 }
1060 else if(!vboxVHWARegionIntersects(&pDesc->NonupdatedMemRegion, pRect))
1061 {
1062// vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWAFreeCmdCompletion, NULL);
1063 vboxVHWARegionAdd(&pDesc->UpdatedMemRegion, pRect);
1064 lpLock->ddRVal = DD_OK;
1065 }
1066 else
1067 {
1068 VBOXVHWACMD* pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_LOCK, sizeof(VBOXVHWACMD_SURF_LOCK));
1069 if(pCmd)
1070 {
1071 VBOXVHWACMD_SURF_LOCK * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_LOCK);
1072 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_LOCK));
1073
1074 pBody->u.in.offSurface = (uint64_t)lpSurfaceGlobal->fpVidMem;
1075
1076// if (lpLock->bHasRect)
1077// {
1078// 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));
1079// vboxVHWAFromRECTL(&pBody->u.in.rect, &lpLock->rArea);
1080// pBody->u.in.rectValid = 1;
1081//
1082// }
1083// else
1084// {
1085// pBody->u.in.rectValid = 0;
1086// }
1087 Assert(pDesc->NonupdatedMemRegion.bValid);
1088 vboxVHWAFromRECTL(&pBody->u.in.rect, &pDesc->NonupdatedMemRegion.Rect);
1089 pBody->u.in.rectValid = 1;
1090
1091 pBody->u.in.hSurf = pDesc->hHostHandle;
1092
1093 /* wait for the surface to be locked and memory buffer updated */
1094 vboxVHWACommandSubmit(pDev, pCmd);
1095 vbvaVHWACommandRelease(pDev, pCmd);
1096 vboxVHWARegionClear(&pDesc->NonupdatedMemRegion);
1097 lpLock->ddRVal = DD_OK;
1098 }
1099 else
1100 {
1101 lpLock->ddRVal = DDERR_GENERIC;
1102 }
1103 }
1104#else
1105 lpLock->ddRVal = DD_OK;
1106#endif
1107 return DDHAL_DRIVER_NOTHANDLED;
1108 }
1109#endif
1110 if (lpSurfaceLocal->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
1111 {
1112 /* The updated rectangle must be reported only for the primary surface. */
1113 pDev->ddLock.bLocked = TRUE;
1114
1115 if (lpLock->bHasRect)
1116 {
1117 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));
1118 pDev->ddLock.rArea = lpLock->rArea;
1119 }
1120 else
1121 {
1122 pDev->ddLock.rArea.left = 0;
1123 pDev->ddLock.rArea.top = 0;
1124 pDev->ddLock.rArea.right = pDev->cxScreen;
1125 pDev->ddLock.rArea.bottom = pDev->cyScreen;
1126 }
1127 }
1128 else
1129 {
1130 DISPDBG((0, "%s: secondary surface.\n", __FUNCTION__));
1131 }
1132
1133 // Because we correctly set 'fpVidMem' to be the offset into our frame
1134 // buffer when we created the surface, DirectDraw will automatically take
1135 // care of adding in the user-mode frame buffer address if we return
1136 // DDHAL_DRIVER_NOTHANDLED:
1137 lpLock->ddRVal = DD_OK;
1138 return DDHAL_DRIVER_NOTHANDLED;
1139}
1140
1141/**
1142 * DdUnlock
1143 *
1144 * The DdUnLock callback function releases the lock held on the specified surface.
1145 *
1146 * Parameters
1147 * lpUnlock
1148 * Points to a DD_UNLOCKDATA structure that contains the information required to perform the lock release. *
1149 *
1150 * Return Value
1151 *
1152 * DdLock returns one of the following callback codes:
1153 *
1154 * DDHAL_DRIVER_HANDLED
1155 * DDHAL_DRIVER_NOTHANDLED
1156 *
1157 */
1158DWORD APIENTRY DdUnlock(PDD_UNLOCKDATA lpUnlock)
1159{
1160 PPDEV pDev = (PPDEV)lpUnlock->lpDD->dhpdev;
1161 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
1162#ifdef VBOX_WITH_VIDEOHWACCEL
1163 if (pDev->vhwaInfo.bVHWAEnabled)
1164 {
1165#ifndef DBG_DDSTUBS
1166 DD_SURFACE_LOCAL* lpSurfaceLocal = lpUnlock->lpDDSurface;
1167 DD_SURFACE_GLOBAL* lpSurfaceGlobal = lpSurfaceLocal->lpGbl;
1168 PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC)lpSurfaceGlobal->dwReserved1;
1169
1170 //TODO: hadle vrdp properly
1171 if ( pDev->pVBVA->u32HostEvents
1172 & VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET)
1173 {
1174 vrdpReset (pDev);
1175
1176 pDev->pVBVA->u32HostEvents &=
1177 ~VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET;
1178 }
1179
1180// /* ensure we have host cmds processed to update pending blits and flips */
1181// vboxVHWACommandCheckHostCmds(pDev);
1182
1183 if(lpSurfaceLocal->ddsCaps.dwCaps & DDSCAPS_VISIBLE
1184 || (
1185 !(lpSurfaceLocal->ddsCaps.dwCaps & DDSCAPS_COMPLEX)
1186 && (
1187 lpSurfaceLocal->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE
1188 || (
1189 (lpSurfaceLocal->ddsCaps.dwCaps & DDSCAPS_OVERLAY)
1190 && !pDesc->bHidden
1191 )
1192 )
1193 )
1194 )
1195 {
1196 VBOXVHWACMD* pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_UNLOCK, sizeof(VBOXVHWACMD_SURF_UNLOCK));
1197 // int rc = VERR_GENERAL_FAILURE;
1198 if(pCmd)
1199 {
1200 VBOXVHWACMD_SURF_UNLOCK * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_UNLOCK);
1201 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_UNLOCK));
1202
1203 pBody->u.in.hSurf = pDesc->hHostHandle;
1204 if(pDesc->UpdatedMemRegion.bValid)
1205 {
1206 pBody->u.in.xUpdatedMemValid = 1;
1207 vboxVHWAFromRECTL(&pBody->u.in.xUpdatedMemRect, &pDesc->UpdatedMemRegion.Rect);
1208 vboxVHWARegionClear(&pDesc->UpdatedMemRegion);
1209 }
1210
1211 vboxVHWACommandSubmitAsynchAndComplete(pDev, pCmd);
1212
1213 lpUnlock->ddRVal = DD_OK;
1214 }
1215 else
1216 {
1217 lpUnlock->ddRVal = DDERR_GENERIC;
1218 }
1219 }
1220#else
1221 lpUnlock->ddRVal = DD_OK;
1222#endif
1223
1224 return DDHAL_DRIVER_NOTHANDLED;
1225 }
1226#endif
1227 if (pDev->ddLock.bLocked)
1228 {
1229 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));
1230
1231#ifndef VBOX_WITH_HGSMI
1232 if (pDev->pInfo && vboxHwBufferBeginUpdate (pDev))
1233 {
1234 vbvaReportDirtyRect (pDev, &pDev->ddLock.rArea);
1235
1236 if ( pDev->pInfo->hostEvents.fu32Events
1237 & VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET)
1238 {
1239 vrdpReset (pDev);
1240
1241 pDev->pInfo->hostEvents.fu32Events &=
1242 ~VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET;
1243 }
1244
1245 if (pDev->vbva.pVbvaMemory->fu32ModeFlags
1246 & VBVA_F_MODE_VRDP)
1247 {
1248 vrdpReportDirtyRect (pDev, &pDev->ddLock.rArea);
1249 }
1250
1251 vboxHwBufferEndUpdate (pDev);
1252 }
1253#else
1254 if (pDev->bHGSMISupported && vboxHwBufferBeginUpdate (pDev))
1255 {
1256 vbvaReportDirtyRect (pDev, &pDev->ddLock.rArea);
1257
1258 if ( pDev->pVBVA->u32HostEvents
1259 & VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET)
1260 {
1261 vrdpReset (pDev);
1262
1263 pDev->pVBVA->u32HostEvents &=
1264 ~VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET;
1265 }
1266
1267 if (pDev->pVBVA->u32HostEvents
1268 & VBVA_F_MODE_VRDP)
1269 {
1270 vrdpReportDirtyRect (pDev, &pDev->ddLock.rArea);
1271 }
1272
1273 vboxHwBufferEndUpdate (pDev);
1274 }
1275#endif /* VBOX_WITH_HGSMI */
1276
1277 pDev->ddLock.bLocked = FALSE;
1278 }
1279
1280 lpUnlock->ddRVal = DD_OK;
1281 return DDHAL_DRIVER_NOTHANDLED;
1282}
1283
1284/**
1285 * DdDestroySurface
1286 *
1287 * The DdDestroySurface callback function destroys a DirectDraw surface.
1288 *
1289 * Parameters
1290 * lpDestroySurface
1291 * Points to a DD_DESTROYSURFACEDATA structure that contains the information needed to destroy a surface.
1292 *
1293 * Return Value
1294 *
1295 * DdDestroySurface returns one of the following callback codes:
1296 *
1297 * DDHAL_DRIVER_HANDLED
1298 * DDHAL_DRIVER_NOTHANDLED
1299 *
1300 */
1301DWORD APIENTRY DdDestroySurface(PDD_DESTROYSURFACEDATA lpDestroySurface)
1302{
1303#ifdef VBOX_WITH_VIDEOHWACCEL
1304 PPDEV pDev = (PPDEV)lpDestroySurface->lpDD->dhpdev;
1305 if(pDev->vhwaInfo.bVHWAEnabled)
1306 {
1307 DD_SURFACE_LOCAL* lpSurfaceLocal = lpDestroySurface->lpDDSurface;
1308 DD_SURFACE_GLOBAL* lpSurfaceGlobal = lpSurfaceLocal->lpGbl;
1309 VBOXVHWACMD* pCmd;
1310
1311 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
1312
1313 pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_DESTROY, sizeof(VBOXVHWACMD_SURF_DESTROY));
1314 // int rc = VERR_GENERAL_FAILURE;
1315 if(pCmd)
1316 {
1317 VBOXVHWACMD_SURF_DESTROY * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_DESTROY);
1318 PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC)lpSurfaceGlobal->dwReserved1;
1319
1320 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_DESTROY));
1321
1322 pBody->u.in.hSurf = pDesc->hHostHandle;
1323
1324 /* we're not interested in completion, just send the command */
1325 vboxVHWACommandSubmitAsynchAndComplete(pDev, pCmd);
1326
1327 vboxVHWASurfDescFree(pDesc);
1328
1329 lpDestroySurface->ddRVal = DD_OK;
1330 }
1331 else
1332 {
1333 lpDestroySurface->ddRVal = DDERR_GENERIC;
1334 }
1335 }
1336 else
1337#endif
1338 lpDestroySurface->ddRVal = DD_OK;
1339 return DDHAL_DRIVER_HANDLED;
1340}
1341
1342
1343//-----------------------------------------------------------------------------
1344//
1345// DdSetExclusiveMode
1346//
1347// This function is called by DirectDraw when we switch from the GDI surface,
1348// to DirectDraw exclusive mode, e.g. to run a game in fullcreen mode.
1349// You only need to implement this function when you are using the
1350// 'HeapVidMemAllocAligned' function and allocate memory for Device Bitmaps
1351// and DirectDraw surfaces from the same heap.
1352//
1353// We use this call to disable GDI DeviceBitMaps when we are running in
1354// DirectDraw exclusive mode. Otherwise a DD app gets confused if both GDI and
1355// DirectDraw allocate memory from the same heap.
1356//
1357// See also DdFlipToGDISurface.
1358//
1359//-----------------------------------------------------------------------------
1360
1361
1362DWORD APIENTRY DdSetExclusiveMode(PDD_SETEXCLUSIVEMODEDATA lpSetExclusiveMode)
1363{
1364 PPDEV pDev = (PPDEV)lpSetExclusiveMode->lpDD->dhpdev;
1365 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
1366
1367 // remember setting of exclusive mode in pDev,
1368 // so GDI can stop to promote DeviceBitmaps into
1369 // video memory
1370
1371 pDev->bDdExclusiveMode = lpSetExclusiveMode->dwEnterExcl;
1372
1373 lpSetExclusiveMode->ddRVal = DD_OK;
1374
1375 return DDHAL_DRIVER_HANDLED;
1376}
1377
1378//-----------------------------------------------------------------------------
1379//
1380// DWORD DdFlipToGDISurface
1381//
1382// This function is called by DirectDraw when it flips to the surface on which
1383// GDI can write to.
1384//
1385//-----------------------------------------------------------------------------
1386
1387DWORD APIENTRY DdFlipToGDISurface(PDD_FLIPTOGDISURFACEDATA lpFlipToGDISurface)
1388{
1389 PPDEV pDev = (PPDEV)lpFlipToGDISurface->lpDD->dhpdev;
1390 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
1391
1392 pDev->dwNewDDSurfaceOffset = 0xffffffff;
1393
1394 lpFlipToGDISurface->ddRVal = DD_OK;
1395
1396 //
1397 // we return NOTHANDLED, then the ddraw runtime takes
1398 // care that we flip back to the primary...
1399 //
1400 return DDHAL_DRIVER_NOTHANDLED;
1401}
1402//-----------------------------------------------------------------------------
1403//
1404// DWORD DdFreeDriverMemory
1405//
1406// This function called by DirectDraw when it's running low on memory in
1407// our heap. You only need to implement this function if you use the
1408// DirectDraw 'HeapVidMemAllocAligned' function in your driver, and you
1409// can boot those allocations out of memory to make room for DirectDraw.
1410//
1411//-----------------------------------------------------------------------------
1412
1413DWORD APIENTRY DdFreeDriverMemory(PDD_FREEDRIVERMEMORYDATA lpFreeDriverMemory)
1414{
1415 PPDEV pDev = (PPDEV)lpFreeDriverMemory->lpDD->dhpdev;
1416 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
1417
1418 lpFreeDriverMemory->ddRVal = DDERR_OUTOFMEMORY;
1419 return DDHAL_DRIVER_HANDLED;
1420}
1421
1422#ifdef VBOX_WITH_VIDEOHWACCEL
1423#ifndef DBG_DDSTUBS
1424DWORD APIENTRY DdSetColorKey(PDD_SETCOLORKEYDATA lpSetColorKey)
1425{
1426 PPDEV pDev = (PPDEV)lpSetColorKey->lpDD->dhpdev;
1427 DD_SURFACE_LOCAL* lpSurfaceLocal = lpSetColorKey->lpDDSurface;
1428 DD_SURFACE_GLOBAL* lpSurfaceGlobal = lpSurfaceLocal->lpGbl;
1429 VBOXVHWACMD* pCmd;
1430
1431 DISPDBG((0, "%s\n", __FUNCTION__));
1432
1433 pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_COLORKEY_SET, sizeof(VBOXVHWACMD_SURF_COLORKEY_SET));
1434 // int rc = VERR_GENERAL_FAILURE;
1435 if(pCmd)
1436 {
1437 VBOXVHWACMD_SURF_COLORKEY_SET * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_COLORKEY_SET);
1438 PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC)lpSurfaceGlobal->dwReserved1;
1439 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_COLORKEY_SET));
1440
1441 pBody->u.in.offSurface = (uint64_t)lpSurfaceGlobal->fpVidMem;
1442 pBody->u.in.hSurf = pDesc->hHostHandle;
1443 pBody->u.in.flags = vboxVHWAFromDDCKEYs(lpSetColorKey->dwFlags);
1444 vboxVHWAFromDDCOLORKEY(&pBody->u.in.CKey, &lpSetColorKey->ckNew);
1445
1446 vboxVHWACommandSubmitAsynchAndComplete(pDev, pCmd);
1447 lpSetColorKey->ddRVal = DD_OK;
1448 }
1449 return DDHAL_DRIVER_HANDLED;
1450}
1451
1452DWORD APIENTRY DdAddAttachedSurface(PDD_ADDATTACHEDSURFACEDATA lpAddAttachedSurface)
1453{
1454 DISPDBG((0, "%s\n", __FUNCTION__));
1455 lpAddAttachedSurface->ddRVal = DD_OK;
1456 return DDHAL_DRIVER_HANDLED;
1457}
1458
1459DWORD APIENTRY DdBlt(PDD_BLTDATA lpBlt)
1460{
1461 PPDEV pDev = (PPDEV)lpBlt->lpDD->dhpdev;
1462 DISPDBG((0, "%s\n", __FUNCTION__));
1463#if DX9_DDI
1464 if(VBOXDD_CHECKFLAG(lpBlt->dwFlags, DDBLT_EXTENDED_PRESENTATION_STRETCHFACTOR))
1465 {
1466 lpBlt->ddRVal = DD_OK;
1467 }
1468 else
1469#endif
1470 {
1471 DD_SURFACE_LOCAL* lpDestSurfaceLocal = lpBlt->lpDDDestSurface;
1472 DD_SURFACE_GLOBAL* lpDestSurfaceGlobal = lpDestSurfaceLocal->lpGbl;
1473 DD_SURFACE_LOCAL* lpSrcSurfaceLocal = lpBlt->lpDDSrcSurface;
1474 DD_SURFACE_GLOBAL* lpSrcSurfaceGlobal = lpSrcSurfaceLocal->lpGbl;
1475 VBOXVHWACMD* pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_BLT, sizeof(VBOXVHWACMD_SURF_BLT));
1476 // int rc = VERR_GENERAL_FAILURE;
1477 if(pCmd)
1478 {
1479 VBOXVHWACMD_SURF_BLT * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_BLT);
1480 PVBOXVHWASURFDESC pSrcDesc = (PVBOXVHWASURFDESC)lpSrcSurfaceGlobal->dwReserved1;
1481 PVBOXVHWASURFDESC pDestDesc = (PVBOXVHWASURFDESC)lpDestSurfaceGlobal->dwReserved1;
1482 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_BLT));
1483
1484 pBody->u.in.offSrcSurface = (uint64_t)lpSrcSurfaceGlobal->fpVidMem;
1485 pBody->u.in.offDstSurface = (uint64_t)lpDestSurfaceGlobal->fpVidMem;
1486
1487 pBody->u.in.hDstSurf = pDestDesc->hHostHandle;
1488 vboxVHWAFromRECTL(&pBody->u.in.dstRect, &lpBlt->rDest);
1489 pBody->u.in.hSrcSurf = pSrcDesc->hHostHandle;
1490 vboxVHWAFromRECTL(&pBody->u.in.srcRect, &lpBlt->rSrc);
1491 pBody->DstGuestSurfInfo = (uint64_t)pDestDesc;
1492 pBody->SrcGuestSurfInfo = (uint64_t)pSrcDesc;
1493
1494 pBody->u.in.flags = vboxVHWAFromDDBLTs(lpBlt->dwFlags);
1495 vboxVHWAFromDDBLTFX(&pBody->u.in.desc, &lpBlt->bltFX);
1496
1497 ASMAtomicIncU32(&pSrcDesc->cPendingBltsSrc);
1498 ASMAtomicIncU32(&pDestDesc->cPendingBltsDst);
1499
1500 vboxVHWARegionAdd(&pDestDesc->NonupdatedMemRegion, &lpBlt->rDest);
1501 vboxVHWARegionTrySubstitute(&pDestDesc->UpdatedMemRegion, &lpBlt->rDest);
1502
1503 if(pSrcDesc->UpdatedMemRegion.bValid)
1504 {
1505 pBody->u.in.xUpdatedSrcMemValid = 1;
1506 vboxVHWAFromRECTL(&pBody->u.in.xUpdatedSrcMemRect, &pSrcDesc->UpdatedMemRegion.Rect);
1507 vboxVHWARegionClear(&pSrcDesc->UpdatedMemRegion);
1508 }
1509
1510 vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWASurfBltCompletion, NULL);
1511
1512 lpBlt->ddRVal = DD_OK;
1513 }
1514 else
1515 {
1516 lpBlt->ddRVal = DDERR_GENERIC;
1517 }
1518 }
1519
1520 return DDHAL_DRIVER_HANDLED;
1521}
1522
1523//DWORD APIENTRY DdDestroySurface(PDD_DESTROYSURFACEDATA lpDestroySurface)
1524//{
1525// DISPDBG((0, "%s\n", __FUNCTION__));
1526// lpDestroySurface->ddRVal = DD_OK;
1527// return DDHAL_DRIVER_HANDLED;
1528//}
1529
1530DWORD APIENTRY DdFlip(PDD_FLIPDATA lpFlip)
1531{
1532 PPDEV pDev = (PPDEV)lpFlip->lpDD->dhpdev;
1533 DD_SURFACE_LOCAL* lpTargSurfaceLocal = lpFlip->lpSurfTarg;
1534 DD_SURFACE_GLOBAL* lpTargSurfaceGlobal = lpTargSurfaceLocal->lpGbl;
1535 DD_SURFACE_LOCAL* lpCurrSurfaceLocal = lpFlip->lpSurfCurr;
1536 DD_SURFACE_GLOBAL* lpCurrSurfaceGlobal = lpCurrSurfaceLocal->lpGbl;
1537 PVBOXVHWASURFDESC pCurrDesc = (PVBOXVHWASURFDESC)lpCurrSurfaceGlobal->dwReserved1;
1538 PVBOXVHWASURFDESC pTargDesc = (PVBOXVHWASURFDESC)lpTargSurfaceGlobal->dwReserved1;
1539 VBOXVHWACMD* pCmd;
1540
1541 DISPDBG((0, "%s\n", __FUNCTION__));
1542
1543 if(
1544// ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc)
1545// || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst)
1546// ||
1547 ASMAtomicUoReadU32(&pCurrDesc->cPendingFlipsTarg)
1548 || ASMAtomicUoReadU32(&pCurrDesc->cPendingFlipsCurr)
1549 || ASMAtomicUoReadU32(&pTargDesc->cPendingFlipsTarg)
1550 || ASMAtomicUoReadU32(&pTargDesc->cPendingFlipsCurr))
1551 {
1552 /* ensure we have host cmds processed to update pending blits and flips */
1553 vboxVHWACommandCheckHostCmds(pDev);
1554 if(
1555 // ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc)
1556 // || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst)
1557 // ||
1558 ASMAtomicUoReadU32(&pCurrDesc->cPendingFlipsTarg)
1559 || ASMAtomicUoReadU32(&pCurrDesc->cPendingFlipsCurr)
1560 || ASMAtomicUoReadU32(&pTargDesc->cPendingFlipsTarg)
1561 || ASMAtomicUoReadU32(&pTargDesc->cPendingFlipsCurr))
1562 {
1563 lpFlip->ddRVal = DDERR_WASSTILLDRAWING;
1564 return DDHAL_DRIVER_HANDLED;
1565 }
1566 }
1567
1568
1569 pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_FLIP, sizeof(VBOXVHWACMD_SURF_FLIP));
1570 // int rc = VERR_GENERAL_FAILURE;
1571 if(pCmd)
1572 {
1573 VBOXVHWACMD_SURF_FLIP * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_FLIP);
1574
1575 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_FLIP));
1576
1577 pBody->u.in.offCurrSurface = (uint64_t)lpCurrSurfaceGlobal->fpVidMem;
1578 pBody->u.in.offTargSurface = (uint64_t)lpTargSurfaceGlobal->fpVidMem;
1579
1580 pBody->u.in.hTargSurf = pTargDesc->hHostHandle;
1581 pBody->u.in.hCurrSurf = pCurrDesc->hHostHandle;
1582 pBody->TargGuestSurfInfo = (uint64_t)pTargDesc;
1583 pBody->CurrGuestSurfInfo = (uint64_t)pCurrDesc;
1584
1585// pBody->u.in.flags = vboxVHWAFromDDFLIPs(lpFlip->dwFlags);
1586
1587 ASMAtomicIncU32(&pCurrDesc->cPendingFlipsCurr);
1588 ASMAtomicIncU32(&pTargDesc->cPendingFlipsTarg);
1589#ifdef DEBUG
1590 ASMAtomicIncU32(&pCurrDesc->cFlipsCurr);
1591 ASMAtomicIncU32(&pTargDesc->cFlipsTarg);
1592#endif
1593
1594 if(pTargDesc->UpdatedMemRegion.bValid)
1595 {
1596 pBody->u.in.xUpdatedTargMemValid = 1;
1597 vboxVHWAFromRECTL(&pBody->u.in.xUpdatedTargMemRect, &pTargDesc->UpdatedMemRegion.Rect);
1598 vboxVHWARegionClear(&pTargDesc->UpdatedMemRegion);
1599 }
1600
1601 vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWASurfFlipCompletion, NULL);
1602
1603 lpFlip->ddRVal = DD_OK;
1604 }
1605 else
1606 {
1607 lpFlip->ddRVal = DDERR_GENERIC;
1608 }
1609 return DDHAL_DRIVER_HANDLED;
1610}
1611
1612DWORD APIENTRY DdGetBltStatus(PDD_GETBLTSTATUSDATA lpGetBltStatus)
1613{
1614 PPDEV pDev = (PPDEV)lpGetBltStatus->lpDD->dhpdev;
1615
1616 DISPDBG((0, "%s\n", __FUNCTION__));
1617
1618 if(lpGetBltStatus->dwFlags == DDGBS_CANBLT)
1619 {
1620 lpGetBltStatus->ddRVal = DD_OK;
1621 }
1622 else /* DDGBS_ISBLTDONE */
1623 {
1624 DD_SURFACE_LOCAL* lpSurfaceLocal = lpGetBltStatus->lpDDSurface;
1625 DD_SURFACE_GLOBAL* lpSurfaceGlobal = lpSurfaceLocal->lpGbl;
1626 PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC)lpSurfaceGlobal->dwReserved1;
1627
1628 if(
1629 ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc)
1630 || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst)
1631 // || ASMAtomicUoReadU32(&pDesc->cPendingFlipsTarg)
1632 // || ASMAtomicUoReadU32(&pDesc->cPendingFlipsCurr)
1633 )
1634 {
1635 /* ensure we have host cmds processed to update pending blits and flips */
1636 vboxVHWACommandCheckHostCmds(pDev);
1637
1638 if(
1639 ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc)
1640 || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst)
1641 // || ASMAtomicUoReadU32(&pDesc->cPendingFlipsTarg)
1642 // || ASMAtomicUoReadU32(&pDesc->cPendingFlipsCurr)
1643 )
1644 {
1645 lpGetBltStatus->ddRVal = DDERR_WASSTILLDRAWING;
1646 }
1647 else
1648 {
1649 lpGetBltStatus->ddRVal = DD_OK;
1650 }
1651 }
1652 else
1653 {
1654 lpGetBltStatus->ddRVal = DD_OK;
1655 }
1656 }
1657
1658 return DDHAL_DRIVER_HANDLED;
1659}
1660
1661DWORD APIENTRY DdGetFlipStatus(PDD_GETFLIPSTATUSDATA lpGetFlipStatus)
1662{
1663 PPDEV pDev = (PPDEV)lpGetFlipStatus->lpDD->dhpdev;
1664 DD_SURFACE_LOCAL* lpSurfaceLocal = lpGetFlipStatus->lpDDSurface;
1665 DD_SURFACE_GLOBAL* lpSurfaceGlobal = lpSurfaceLocal->lpGbl;
1666 PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC)lpSurfaceGlobal->dwReserved1;
1667
1668 DISPDBG((0, "%s\n", __FUNCTION__));
1669
1670 if(
1671// ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc)
1672// || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst)
1673// ||
1674 ASMAtomicUoReadU32(&pDesc->cPendingFlipsTarg)
1675 || ASMAtomicUoReadU32(&pDesc->cPendingFlipsCurr)
1676 )
1677 {
1678 /* ensure we have host cmds processed to update pending blits and flips */
1679 vboxVHWACommandCheckHostCmds(pDev);
1680
1681 if(
1682 // ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc)
1683 // || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst)
1684 // ||
1685 ASMAtomicUoReadU32(&pDesc->cPendingFlipsTarg)
1686 || ASMAtomicUoReadU32(&pDesc->cPendingFlipsCurr)
1687 )
1688 {
1689 lpGetFlipStatus->ddRVal = DDERR_WASSTILLDRAWING;
1690 }
1691 else
1692 {
1693 lpGetFlipStatus->ddRVal = DD_OK;
1694 }
1695 }
1696 else
1697 {
1698 lpGetFlipStatus->ddRVal = DD_OK;
1699 }
1700
1701// if(lpGetFlipStatus->dwFlags == DDGFS_CANFLIP)
1702// {
1703// lpGetFlipStatus->ddRVal = DD_OK;
1704// }
1705// else
1706// {
1707// lpGetFlipStatus->ddRVal = DD_OK;
1708// }
1709
1710 return DDHAL_DRIVER_HANDLED;
1711}
1712
1713DWORD APIENTRY DdSetOverlayPosition(PDD_SETOVERLAYPOSITIONDATA lpSetOverlayPosition)
1714{
1715 PPDEV pDev = (PPDEV)lpSetOverlayPosition->lpDD->dhpdev;
1716 DD_SURFACE_LOCAL* lpDestSurfaceLocal = lpSetOverlayPosition->lpDDDestSurface;
1717 DD_SURFACE_GLOBAL* lpDestSurfaceGlobal = lpDestSurfaceLocal->lpGbl;
1718 DD_SURFACE_LOCAL* lpSrcSurfaceLocal = lpSetOverlayPosition->lpDDSrcSurface;
1719 DD_SURFACE_GLOBAL* lpSrcSurfaceGlobal = lpSrcSurfaceLocal->lpGbl;
1720 VBOXVHWACMD* pCmd;
1721 PVBOXVHWASURFDESC pSrcDesc = (PVBOXVHWASURFDESC)lpSrcSurfaceGlobal->dwReserved1;
1722 PVBOXVHWASURFDESC pDestDesc = (PVBOXVHWASURFDESC)lpDestSurfaceGlobal->dwReserved1;
1723
1724 DISPDBG((0, "%s\n", __FUNCTION__));
1725
1726 if(pSrcDesc->bHidden)
1727 {
1728 lpSetOverlayPosition->ddRVal = DDERR_GENERIC;
1729 return DDHAL_DRIVER_HANDLED;
1730 }
1731
1732 pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_OVERLAY_SETPOSITION, sizeof(VBOXVHWACMD_SURF_OVERLAY_SETPOSITION));
1733 // int rc = VERR_GENERAL_FAILURE;
1734 if(pCmd)
1735 {
1736 VBOXVHWACMD_SURF_OVERLAY_SETPOSITION * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_OVERLAY_SETPOSITION);
1737
1738 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_OVERLAY_SETPOSITION));
1739
1740 pBody->u.in.offSrcSurface = (uint64_t)lpSrcSurfaceGlobal->fpVidMem;
1741 pBody->u.in.offDstSurface = (uint64_t)lpDestSurfaceGlobal->fpVidMem;
1742
1743 pBody->u.in.hDstSurf = pDestDesc->hHostHandle;
1744 pBody->u.in.hSrcSurf = pSrcDesc->hHostHandle;
1745
1746 pBody->u.in.xPos = lpSetOverlayPosition->lXPos;
1747 pBody->u.in.yPos = lpSetOverlayPosition->lYPos;
1748
1749 vboxVHWACommandSubmitAsynchAndComplete(pDev, pCmd);
1750 lpSetOverlayPosition->ddRVal = DD_OK;
1751 }
1752
1753 return DDHAL_DRIVER_HANDLED;
1754}
1755
1756DWORD APIENTRY DdUpdateOverlay(PDD_UPDATEOVERLAYDATA lpUpdateOverlay)
1757{
1758 PPDEV pDev = (PPDEV)lpUpdateOverlay->lpDD->dhpdev;
1759 DD_SURFACE_LOCAL* lpDestSurfaceLocal = lpUpdateOverlay->lpDDDestSurface;
1760 DD_SURFACE_LOCAL* lpSrcSurfaceLocal = lpUpdateOverlay->lpDDSrcSurface;
1761 DD_SURFACE_GLOBAL* lpSrcSurfaceGlobal = lpSrcSurfaceLocal->lpGbl;
1762 VBOXVHWACMD* pCmd;
1763 PVBOXVHWASURFDESC pSrcDesc = (PVBOXVHWASURFDESC)lpSrcSurfaceGlobal->dwReserved1;
1764
1765 DISPDBG((0, "%s\n", __FUNCTION__));
1766
1767// if(pSrcDesc->bHidden)
1768// {
1769// lpUpdateOverlay->ddRVal = DDERR_GENERIC;
1770// return DDHAL_DRIVER_HANDLED;
1771// }
1772
1773 pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_OVERLAY_UPDATE, sizeof(VBOXVHWACMD_SURF_OVERLAY_UPDATE));
1774 // int rc = VERR_GENERAL_FAILURE;
1775 if(pCmd)
1776 {
1777 VBOXVHWACMD_SURF_OVERLAY_UPDATE * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_OVERLAY_UPDATE);
1778
1779 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_OVERLAY_UPDATE));
1780
1781 pBody->u.in.offSrcSurface = (uint64_t)lpSrcSurfaceGlobal->fpVidMem;
1782
1783 pBody->u.in.hSrcSurf = pSrcDesc->hHostHandle;
1784
1785 vboxVHWAFromRECTL(&pBody->u.in.dstRect, &lpUpdateOverlay->rDest);
1786 vboxVHWAFromRECTL(&pBody->u.in.srcRect, &lpUpdateOverlay->rSrc);
1787
1788 pBody->u.in.flags = vboxVHWAFromDDOVERs(lpUpdateOverlay->dwFlags);
1789 vboxVHWAFromDDOVERLAYFX(&pBody->u.in.desc, &lpUpdateOverlay->overlayFX);
1790
1791 if(lpUpdateOverlay->dwFlags & DDOVER_HIDE)
1792 {
1793 pSrcDesc->bHidden = true;
1794 }
1795 else if(lpUpdateOverlay->dwFlags & DDOVER_SHOW)
1796 {
1797 pSrcDesc->bHidden = false;
1798 if(pSrcDesc->UpdatedMemRegion.bValid)
1799 {
1800 pBody->u.in.xUpdatedSrcMemValid = 1;
1801 vboxVHWAFromRECTL(&pBody->u.in.xUpdatedSrcMemRect, &pSrcDesc->UpdatedMemRegion.Rect);
1802 vboxVHWARegionClear(&pSrcDesc->UpdatedMemRegion);
1803 }
1804 }
1805
1806 if(lpDestSurfaceLocal)
1807 {
1808 DD_SURFACE_GLOBAL* lpDestSurfaceGlobal = lpDestSurfaceLocal->lpGbl;
1809 PVBOXVHWASURFDESC pDestDesc = (PVBOXVHWASURFDESC)lpDestSurfaceGlobal->dwReserved1;
1810 pBody->u.in.hDstSurf = pDestDesc->hHostHandle;
1811 pBody->u.in.offDstSurface = (uint64_t)lpDestSurfaceGlobal->fpVidMem;
1812 }
1813
1814 vboxVHWACommandSubmitAsynchAndComplete(pDev, pCmd);
1815 lpUpdateOverlay->ddRVal = DD_OK;
1816 }
1817
1818 return DDHAL_DRIVER_HANDLED;
1819}
1820#else
1821DWORD APIENTRY DdSetColorKey(PDD_SETCOLORKEYDATA lpSetColorKey)
1822{
1823 DISPDBG((0, "%s\n", __FUNCTION__));
1824 lpSetColorKey->ddRVal = DD_OK;
1825 return DDHAL_DRIVER_HANDLED;
1826}
1827
1828DWORD APIENTRY DdAddAttachedSurface(PDD_ADDATTACHEDSURFACEDATA lpAddAttachedSurface)
1829{
1830 DISPDBG((0, "%s\n", __FUNCTION__));
1831 lpAddAttachedSurface->ddRVal = DD_OK;
1832 return DDHAL_DRIVER_HANDLED;
1833}
1834
1835DWORD APIENTRY DdBlt(PDD_BLTDATA lpBlt)
1836{
1837 DISPDBG((0, "%s\n", __FUNCTION__));
1838 lpBlt->ddRVal = DD_OK;
1839 return DDHAL_DRIVER_HANDLED;
1840}
1841
1842//DWORD APIENTRY DdDestroySurface(PDD_DESTROYSURFACEDATA lpDestroySurface)
1843//{
1844// DISPDBG((0, "%s\n", __FUNCTION__));
1845// lpDestroySurface->ddRVal = DD_OK;
1846// return DDHAL_DRIVER_HANDLED;
1847//}
1848
1849DWORD APIENTRY DdFlip(PDD_FLIPDATA lpFlip)
1850{
1851 DISPDBG((0, "%s\n", __FUNCTION__));
1852 lpFlip->ddRVal = DD_OK;
1853 return DDHAL_DRIVER_HANDLED;
1854}
1855
1856DWORD APIENTRY DdGetBltStatus(PDD_GETBLTSTATUSDATA lpGetBltStatus)
1857{
1858 DISPDBG((0, "%s\n", __FUNCTION__));
1859
1860 if(lpGetBltStatus->dwFlags == DDGBS_CANBLT)
1861 {
1862 lpGetBltStatus->ddRVal = DD_OK;
1863 }
1864 else
1865 {
1866 lpGetBltStatus->ddRVal = DD_OK;
1867 }
1868
1869 return DDHAL_DRIVER_HANDLED;
1870}
1871
1872DWORD APIENTRY DdGetFlipStatus(PDD_GETFLIPSTATUSDATA lpGetFlipStatus)
1873{
1874 DISPDBG((0, "%s\n", __FUNCTION__));
1875 if(lpGetFlipStatus->dwFlags == DDGFS_CANFLIP)
1876 {
1877 lpGetFlipStatus->ddRVal = DD_OK;
1878 }
1879 else
1880 {
1881 lpGetFlipStatus->ddRVal = DD_OK;
1882 }
1883
1884 return DDHAL_DRIVER_HANDLED;
1885}
1886
1887DWORD APIENTRY DdSetOverlayPosition(PDD_SETOVERLAYPOSITIONDATA lpSetOverlayPosition)
1888{
1889 DISPDBG((0, "%s\n", __FUNCTION__));
1890
1891 lpSetOverlayPosition->ddRVal = DD_OK;
1892 return DDHAL_DRIVER_HANDLED;
1893}
1894
1895DWORD APIENTRY DdUpdateOverlay(PDD_UPDATEOVERLAYDATA lpUpdateOverlay)
1896{
1897 DISPDBG((0, "%s\n", __FUNCTION__));
1898
1899 lpUpdateOverlay->ddRVal = DD_OK;
1900 return DDHAL_DRIVER_HANDLED;
1901}
1902
1903#endif
1904
1905//-----------------------------------------------------------------------------
1906// setupRops
1907//
1908// Build array for supported ROPS
1909//-----------------------------------------------------------------------------
1910static void
1911setupRops(
1912 LPBYTE proplist,
1913 LPDWORD proptable,
1914 int cnt )
1915{
1916 int i;
1917 DWORD idx;
1918 DWORD bit;
1919 DWORD rop;
1920
1921 for(i=0; i<cnt; i++)
1922 {
1923 rop = proplist[i];
1924 idx = rop / 32;
1925 bit = 1L << ((DWORD)(rop % 32));
1926 proptable[idx] |= bit;
1927 }
1928
1929} // setupRops
1930
1931//-----------------------------------------------------------------------------
1932//
1933// Function: __GetDDHALInfo
1934//
1935// Returns: void
1936//
1937// Description:
1938//
1939// Takes a pointer to a partially or fully filled in pThisDisplay and a pointer
1940// to an empty DDHALINFO and fills in the DDHALINFO. This eases porting to NT
1941// and means that caps changes are done in only one place. The pThisDisplay
1942// may not be fully constructed here, so you should only:
1943// a) Query the registry
1944// b) DISPDBG
1945// If you need to add anything to pThisDisplay for NT, you should fill it in
1946// during the DrvGetDirectDraw call.
1947//
1948// The problem here is when the code is run on NT. If there was any other way...
1949//
1950// The following caps have been found to cause NT to bail....
1951// DDCAPS_GDI, DDFXCAPS_BLTMIRRORUPDOWN, DDFXCAPS_BLTMIRRORLEFTRIGHT
1952//
1953//
1954//-----------------------------------------------------------------------------
1955
1956//
1957// use bits to indicate which ROPs you support.
1958//
1959// DWORD 0, bit 0 == ROP 0
1960// DWORD 8, bit 31 == ROP 255
1961//
1962
1963//static DWORD ropsAGP[DD_ROP_SPACE] = { 0 };
1964static BYTE ropListNT[] =
1965{
1966 SRCCOPY >> 16
1967// WHITENESS >> 16,
1968// BLACKNESS >> 16
1969};
1970
1971static DWORD rops[DD_ROP_SPACE] = { 0 };
1972
1973#if 1
1974static bool
1975getDDHALInfo(
1976 PPDEV pDev,
1977 DD_HALINFO* pHALInfo)
1978{
1979 int i;
1980 if(!VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLT) && !VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_OVERLAY))
1981 return false;
1982
1983 pHALInfo->ddCaps.dwCaps |= vboxVHWAToDDCAPS(pDev->vhwaInfo.caps);
1984
1985 if(VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLT))
1986 {
1987 // Setup the ROPS we do.
1988 //TODO: hardcoded for now
1989 setupRops( ropListNT,
1990 rops,
1991 sizeof(ropListNT)/sizeof(ropListNT[0]));
1992
1993 //
1994 // ROPS supported
1995 //
1996 for( i=0;i<DD_ROP_SPACE;i++ )
1997 {
1998 pHALInfo->ddCaps.dwRops[i] = rops[i];
1999 }
2000 }
2001
2002// | DDCAPS_READSCANLINE
2003
2004
2005 pHALInfo->ddCaps.ddsCaps.dwCaps |= vboxVHWAToDDSCAPS(pDev->vhwaInfo.surfaceCaps);
2006
2007//disabled
2008// pHALInfo->ddCaps.dwCaps |= DDCAPS_3D |
2009// DDCAPS_BLTDEPTHFILL;
2010//
2011// pHALInfo->ddCaps.ddsCaps.dwCaps |= DDSCAPS_3DDEVICE |
2012// DDSCAPS_ZBUFFER |
2013// DDSCAPS_ALPHA;
2014 pHALInfo->ddCaps.dwCaps2 = vboxVHWAToDDCAPS2(pDev->vhwaInfo.caps2);
2015
2016
2017
2018//#if DX7_TEXMANAGEMENT
2019 // We need to set this bit up in order to be able to do
2020 // out own texture management
2021// pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_CANMANAGETEXTURE;
2022//#if DX8_DDI
2023// pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_CANMANAGERESOURCE;
2024//#endif
2025//#endif
2026
2027//#if DX8_DDI
2028 // We need to flag we can run in windowed mode, otherwise we
2029 // might get restricted by apps to run in fullscreen only
2030// pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_CANRENDERWINDOWED;
2031
2032 // Also permit surfaces wider than the display buffer.
2033// pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_WIDESURFACES;
2034//#endif
2035
2036//#if DX8_DDI
2037 // We need to flag we support dynamic textures. That is , apps can
2038 // lock with high frequency video memory textures without paying a
2039 // penalty for it. Since on this sample driver we only support
2040 // linear memory formats for textures we don't need to do anything
2041 // else for this support. Otherwise we would have to keep two surfaces
2042 // for textures created with the DDSCAPS2_HINTDYNAMIC hint in order
2043 // to efficiently do the linear<->swizzled transformation or keep the
2044 // texture permanantly in an unswizzled state.
2045// pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_DYNAMICTEXTURES;
2046 #if DX9_DDI
2047 // Notice that dynamic textures MUST be supported in order to instantiate a DX9 device
2048 #endif // DX9_DDI
2049//#endif
2050
2051// pHALInfo->ddCaps.dwFXCaps = 0;
2052
2053 // P3RX can do:
2054 // 1. Stretching/Shrinking
2055 // 2. YUV->RGB conversion
2056 // 3. Mirroring in X and Y
2057 // 4. ColorKeying from a source color and a source color space
2058 if(VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLT)
2059 && VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLTSTRETCH))
2060 {
2061 // Special effects caps
2062 //TODO: filter them out
2063 pHALInfo->ddCaps.dwFXCaps |= DDFXCAPS_BLTSTRETCHY |
2064 DDFXCAPS_BLTSTRETCHX |
2065 DDFXCAPS_BLTSTRETCHYN |
2066 DDFXCAPS_BLTSTRETCHXN |
2067 DDFXCAPS_BLTSHRINKY |
2068 DDFXCAPS_BLTSHRINKX |
2069 DDFXCAPS_BLTSHRINKYN |
2070 DDFXCAPS_BLTSHRINKXN;
2071
2072 // DDFXCAPS_BLTARITHSTRETCHY
2073 // DDFXCAPS_BLTARITHSTRETCHYN
2074 // DDFXCAPS_BLTMIRRORLEFTRIGHT
2075 // DDFXCAPS_BLTMIRRORUPDOWN
2076 // DDFXCAPS_BLTROTATION90
2077 }
2078
2079 if(VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_OVERLAY)
2080 && VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_OVERLAYSTRETCH))
2081 {
2082 // Special effects caps
2083 //TODO: filter them out
2084 pHALInfo->ddCaps.dwFXCaps |= DDFXCAPS_OVERLAYSTRETCHY |
2085 DDFXCAPS_OVERLAYSTRETCHX |
2086 DDFXCAPS_OVERLAYSTRETCHYN |
2087 DDFXCAPS_OVERLAYSTRETCHXN |
2088 DDFXCAPS_OVERLAYSHRINKY |
2089 DDFXCAPS_OVERLAYSHRINKX |
2090 DDFXCAPS_OVERLAYSHRINKYN |
2091 DDFXCAPS_OVERLAYSHRINKXN;
2092
2093 // DDFXCAPS_OVERLAYARITHSTRETCHY
2094 // DDFXCAPS_OVERLAYARITHSTRETCHYN
2095 // DDFXCAPS_OVERLAYMIRRORLEFTRIGHT
2096 // DDFXCAPS_OVERLAYMIRRORUPDOWN
2097
2098 }
2099
2100// if(VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLT)
2101// && VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLTFOURCC))
2102// {
2103// pHALInfo->ddCaps.dwCaps |= DDCAPS_BLTFOURCC;
2104//
2105// // Enable copy blts between Four CC formats for DShow acceleration
2106// pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_COPYFOURCC;
2107// }
2108
2109// if((VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLT) || VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_OVERLAY))
2110// && VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_COLORKEY))
2111 {
2112 pHALInfo->ddCaps.dwCKeyCaps = vboxVHWAToDDCKEYCAPS(pDev->vhwaInfo.colorKeyCaps);
2113 }
2114
2115// pHALInfo->ddCaps.dwSVBCaps = DDCAPS_BLT;
2116
2117// // We can do a texture from sysmem to video mem.
2118// pHALInfo->ddCaps.dwSVBCKeyCaps |= DDCKEYCAPS_DESTBLT |
2119// DDCKEYCAPS_DESTBLTCLRSPACE;
2120 pHALInfo->ddCaps.dwSVBFXCaps = 0;
2121
2122// // Fill in the sysmem->vidmem rops (only can copy);
2123// for( i=0;i<DD_ROP_SPACE;i++ )
2124// {
2125// pHALInfo->ddCaps.dwSVBRops[i] = rops[i];
2126// }
2127
2128
2129
2130//disabled
2131// pHALInfo->ddCaps.ddsCaps.dwCaps |= DDSCAPS_TEXTURE;
2132
2133//#if DX7_STEREO
2134// // Report the stereo capability back to runtime
2135// pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_STEREO;
2136// pHALInfo->ddCaps.dwSVCaps = DDSVCAPS_STEREOSEQUENTIAL;
2137//#endif
2138
2139 // Z Buffer is only 16 Bits
2140// pHALInfo->ddCaps.dwZBufferBitDepths = DDBD_16;
2141// pHALInfo->ddCaps.ddsCaps.dwCaps |= DDSCAPS_MIPMAP;
2142
2143 {
2144//#ifdef SUPPORT_VIDEOPORT
2145// // We support 1 video port. Must set CurrVideoPorts to 0
2146// // We can't do interleaved bobbing yet - maybe in the future.
2147// pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_VIDEOPORT |
2148// DDCAPS2_CANBOBNONINTERLEAVED;
2149//
2150// pHALInfo->ddCaps.dwMaxVideoPorts = 1;
2151// pHALInfo->ddCaps.dwCurrVideoPorts = 0;
2152//
2153//
2154//#endif // SUPPORT_VIDEOPORT
2155
2156 if(VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_OVERLAY)) /* no overlay support for now */
2157 {
2158 // Overlay is free to use.
2159 pHALInfo->ddCaps.dwMaxVisibleOverlays = pDev->vhwaInfo.numOverlays;
2160 pHALInfo->ddCaps.dwCurrVisibleOverlays = 0;
2161
2162 // Indicates that Perm3 has no stretch ratio limitation
2163 pHALInfo->ddCaps.dwMinOverlayStretch = 1;
2164 pHALInfo->ddCaps.dwMaxOverlayStretch = 32000;
2165 }
2166 }
2167
2168//#ifdef W95_DDRAW
2169//#ifdef USE_DD_CONTROL_COLOR
2170// // Enable colour control asc brightness, contrast, gamma.
2171// pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_COLORCONTROLPRIMARY;
2172//#endif
2173//#endif
2174
2175
2176 // Won't do Video-Sys mem Blits.
2177 pHALInfo->ddCaps.dwVSBCaps = 0;
2178 pHALInfo->ddCaps.dwVSBCKeyCaps = 0;
2179 pHALInfo->ddCaps.dwVSBFXCaps = 0;
2180 for( i=0;i<DD_ROP_SPACE;i++ )
2181 {
2182 pHALInfo->ddCaps.dwVSBRops[i] = 0;
2183 }
2184
2185 // Won't do Sys-Sys mem Blits
2186 pHALInfo->ddCaps.dwSSBCaps = 0;
2187 pHALInfo->ddCaps.dwSSBCKeyCaps = 0;
2188 pHALInfo->ddCaps.dwSSBFXCaps = 0;
2189 for( i=0;i<DD_ROP_SPACE;i++ )
2190 {
2191 pHALInfo->ddCaps.dwSSBRops[i] = 0;
2192 }
2193
2194 //
2195 // bit depths supported for alpha and Z
2196 //
2197// pHALInfo->ddCaps.dwAlphaBltConstBitDepths = DDBD_2 |
2198// DDBD_4 |
2199// DDBD_8;
2200//
2201// pHALInfo->ddCaps.dwAlphaBltPixelBitDepths = DDBD_1 |
2202// DDBD_8;
2203// pHALInfo->ddCaps.dwAlphaBltSurfaceBitDepths = DDBD_1 |
2204// DDBD_2 |
2205// DDBD_4 |
2206// DDBD_8;
2207
2208//disabled
2209// // No alpha blending for overlays, so I'm not sure what these should be.
2210// // Because we support 32bpp overlays, it's just that you can't use the
2211// // alpha bits for blending. Pass.
2212// pHALInfo->ddCaps.dwAlphaBltConstBitDepths = DDBD_2 |
2213// DDBD_4 |
2214// DDBD_8;
2215//
2216// pHALInfo->ddCaps.dwAlphaBltPixelBitDepths = DDBD_1 |
2217// DDBD_8;
2218//
2219// pHALInfo->ddCaps.dwAlphaBltSurfaceBitDepths = DDBD_1 |
2220// DDBD_2 |
2221// DDBD_4 |
2222// DDBD_8;
2223
2224
2225//Reenable: // For DX5 and beyond we support this new informational callback.
2226// pHALInfo->GetDriverInfo = DdGetDriverInfo;
2227// pHALInfo->dwFlags |= DDHALINFO_GETDRIVERINFOSET;
2228//
2229//#if DX8_DDI
2230// // Flag our support for a new class of GUIDs that may come through
2231// // GetDriverInfo for DX8 drivers. (This support will be compulsory)
2232// pHALInfo->dwFlags |= DDHALINFO_GETDRIVERINFO2;
2233//#endif DX8_DDI
2234
2235 return true;
2236} // getDDHALInfo
2237#else
2238bool
2239getDDHALInfo2(
2240 PPDEV pDev,
2241 DD_HALINFO* pHALInfo)
2242{
2243 int i;
2244
2245#if 0
2246 /* TODO: only enable features supported by the host backend & host hw
2247 * for now this just combines all caps we might use */
2248
2249 // Setup the ROPS we do.
2250 setupRops( ropListNT,
2251 rops,
2252 sizeof(ropListNT)/sizeof(ropListNT[0]));
2253
2254 // The most basic DirectDraw functionality
2255 pHALInfo->ddCaps.dwCaps |= DDCAPS_BLT
2256 | DDCAPS_BLTQUEUE
2257 | DDCAPS_BLTCOLORFILL
2258// | DDCAPS_READSCANLINE
2259 ;
2260#endif
2261 pHALInfo->ddCaps.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN
2262 | DDSCAPS_PRIMARYSURFACE
2263 | DDSCAPS_FLIP;
2264#if 0
2265 pHALInfo->ddCaps.dwCaps |= DDCAPS_3D |
2266 DDCAPS_BLTDEPTHFILL;
2267
2268 pHALInfo->ddCaps.ddsCaps.dwCaps |= DDSCAPS_3DDEVICE |
2269 DDSCAPS_ZBUFFER |
2270 DDSCAPS_ALPHA;
2271#endif
2272 pHALInfo->ddCaps.dwCaps2 = 0;
2273
2274//#if DX7_TEXMANAGEMENT
2275 // We need to set this bit up in order to be able to do
2276 // out own texture management
2277// pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_CANMANAGETEXTURE;
2278//#if DX8_DDI
2279// pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_CANMANAGERESOURCE;
2280//#endif
2281//#endif
2282
2283//#if DX8_DDI
2284 // We need to flag we can run in windowed mode, otherwise we
2285 // might get restricted by apps to run in fullscreen only
2286 pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_CANRENDERWINDOWED;
2287//#endif
2288
2289//#if DX8_DDI
2290 // We need to flag we support dynamic textures. That is , apps can
2291 // lock with high frequency video memory textures without paying a
2292 // penalty for it. Since on this sample driver we only support
2293 // linear memory formats for textures we don't need to do anything
2294 // else for this support. Otherwise we would have to keep two surfaces
2295 // for textures created with the DDSCAPS2_HINTDYNAMIC hint in order
2296 // to efficiently do the linear<->swizzled transformation or keep the
2297 // texture permanantly in an unswizzled state.
2298// pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_DYNAMICTEXTURES;
2299 #if DX9_DDI
2300 // Notice that dynamic textures MUST be supported in order to instantiate a DX9 device
2301 #endif // DX9_DDI
2302//#endif
2303
2304// pHALInfo->ddCaps.dwFXCaps = 0;
2305
2306 // P3RX can do:
2307 // 1. Stretching/Shrinking
2308 // 2. YUV->RGB conversion
2309 // 3. Mirroring in X and Y
2310 // 4. ColorKeying from a source color and a source color space
2311 pHALInfo->ddCaps.dwCaps |=
2312#if 0
2313 DDCAPS_BLTSTRETCH
2314 | DDCAPS_BLTFOURCC
2315 |
2316#endif
2317 DDCAPS_COLORKEY
2318// | DDCAPS_CANBLTSYSMEM
2319 ;
2320#if 0
2321 // Special effects caps
2322 pHALInfo->ddCaps.dwFXCaps |= DDFXCAPS_BLTSTRETCHY |
2323 DDFXCAPS_BLTSTRETCHX |
2324 DDFXCAPS_BLTSTRETCHYN |
2325 DDFXCAPS_BLTSTRETCHXN |
2326 DDFXCAPS_BLTSHRINKY |
2327 DDFXCAPS_BLTSHRINKX |
2328 DDFXCAPS_BLTSHRINKYN |
2329 DDFXCAPS_BLTSHRINKXN;
2330
2331 // ColorKey caps
2332 pHALInfo->ddCaps.dwCKeyCaps |= DDCKEYCAPS_SRCBLT |
2333 DDCKEYCAPS_SRCBLTCLRSPACE |
2334 DDCKEYCAPS_DESTBLT |
2335 DDCKEYCAPS_DESTBLTCLRSPACE;
2336#endif
2337// pHALInfo->ddCaps.dwSVBCaps = DDCAPS_BLT;
2338
2339// // We can do a texture from sysmem to video mem.
2340// pHALInfo->ddCaps.dwSVBCKeyCaps |= DDCKEYCAPS_DESTBLT |
2341// DDCKEYCAPS_DESTBLTCLRSPACE;
2342 pHALInfo->ddCaps.dwSVBFXCaps = 0;
2343
2344// // Fill in the sysmem->vidmem rops (only can copy);
2345// for( i=0;i<DD_ROP_SPACE;i++ )
2346// {
2347// pHALInfo->ddCaps.dwSVBRops[i] = rops[i];
2348// }
2349#if 0
2350 //mirroring with blitting
2351 pHALInfo->ddCaps.dwFXCaps |= DDFXCAPS_BLTMIRRORUPDOWN |
2352 DDFXCAPS_BLTMIRRORLEFTRIGHT;
2353
2354 pHALInfo->ddCaps.dwCKeyCaps |= DDCKEYCAPS_SRCBLTCLRSPACEYUV;
2355
2356 pHALInfo->ddCaps.ddsCaps.dwCaps |= DDSCAPS_TEXTURE;
2357#endif
2358//#if DX7_STEREO
2359// // Report the stereo capability back to runtime
2360// pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_STEREO;
2361// pHALInfo->ddCaps.dwSVCaps = DDSVCAPS_STEREOSEQUENTIAL;
2362//#endif
2363
2364 // Z Buffer is only 16 Bits
2365// pHALInfo->ddCaps.dwZBufferBitDepths = DDBD_16;
2366// pHALInfo->ddCaps.ddsCaps.dwCaps |= DDSCAPS_MIPMAP;
2367
2368 pHALInfo->ddCaps.ddsCaps.dwCaps |= DDSCAPS_LOCALVIDMEM;
2369
2370 {
2371//#ifdef SUPPORT_VIDEOPORT
2372// // We support 1 video port. Must set CurrVideoPorts to 0
2373// // We can't do interleaved bobbing yet - maybe in the future.
2374// pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_VIDEOPORT |
2375// DDCAPS2_CANBOBNONINTERLEAVED;
2376//
2377// pHALInfo->ddCaps.dwMaxVideoPorts = 1;
2378// pHALInfo->ddCaps.dwCurrVideoPorts = 0;
2379//
2380//
2381//#endif // SUPPORT_VIDEOPORT
2382
2383
2384 {
2385 // Overlay is free to use.
2386 pHALInfo->ddCaps.dwMaxVisibleOverlays = 1;
2387 pHALInfo->ddCaps.dwCurrVisibleOverlays = 0;
2388
2389 pHALInfo->ddCaps.dwCaps |= DDCAPS_OVERLAY |
2390 DDCAPS_OVERLAYFOURCC |
2391 DDCAPS_OVERLAYSTRETCH |
2392 DDCAPS_COLORKEYHWASSIST |
2393 DDCAPS_OVERLAYCANTCLIP;
2394
2395 pHALInfo->ddCaps.dwCKeyCaps |= DDCKEYCAPS_SRCOVERLAY |
2396 DDCKEYCAPS_SRCOVERLAYONEACTIVE |
2397 DDCKEYCAPS_SRCOVERLAYYUV |
2398 DDCKEYCAPS_DESTOVERLAY |
2399 DDCKEYCAPS_DESTOVERLAYONEACTIVE |
2400 DDCKEYCAPS_DESTOVERLAYYUV;
2401
2402 pHALInfo->ddCaps.ddsCaps.dwCaps |= DDSCAPS_OVERLAY;
2403
2404 pHALInfo->ddCaps.dwFXCaps |= DDFXCAPS_OVERLAYSHRINKX |
2405 DDFXCAPS_OVERLAYSHRINKXN |
2406 DDFXCAPS_OVERLAYSHRINKY |
2407 DDFXCAPS_OVERLAYSHRINKYN |
2408 DDFXCAPS_OVERLAYSTRETCHX |
2409 DDFXCAPS_OVERLAYSTRETCHXN |
2410 DDFXCAPS_OVERLAYSTRETCHY |
2411 DDFXCAPS_OVERLAYSTRETCHYN;
2412
2413 // Indicates that Perm3 has no stretch ratio limitation
2414 pHALInfo->ddCaps.dwMinOverlayStretch = 1;
2415 pHALInfo->ddCaps.dwMaxOverlayStretch = 32000;
2416 }
2417 }
2418
2419//#ifdef W95_DDRAW
2420//#ifdef USE_DD_CONTROL_COLOR
2421// // Enable colour control asc brightness, contrast, gamma.
2422// pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_COLORCONTROLPRIMARY;
2423//#endif
2424//#endif
2425
2426 // Also permit surfaces wider than the display buffer.
2427 pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_WIDESURFACES;
2428#if 0
2429 // Enable copy blts betweemn Four CC formats for DShow acceleration
2430 pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_COPYFOURCC;
2431#endif
2432 // Won't do Video-Sys mem Blits.
2433 pHALInfo->ddCaps.dwVSBCaps = 0;
2434 pHALInfo->ddCaps.dwVSBCKeyCaps = 0;
2435 pHALInfo->ddCaps.dwVSBFXCaps = 0;
2436 for( i=0;i<DD_ROP_SPACE;i++ )
2437 {
2438 pHALInfo->ddCaps.dwVSBRops[i] = 0;
2439 }
2440
2441 // Won't do Sys-Sys mem Blits
2442 pHALInfo->ddCaps.dwSSBCaps = 0;
2443 pHALInfo->ddCaps.dwSSBCKeyCaps = 0;
2444 pHALInfo->ddCaps.dwSSBFXCaps = 0;
2445 for( i=0;i<DD_ROP_SPACE;i++ )
2446 {
2447 pHALInfo->ddCaps.dwSSBRops[i] = 0;
2448 }
2449
2450 //
2451 // bit depths supported for alpha and Z
2452 //
2453// pHALInfo->ddCaps.dwAlphaBltConstBitDepths = DDBD_2 |
2454// DDBD_4 |
2455// DDBD_8;
2456//
2457// pHALInfo->ddCaps.dwAlphaBltPixelBitDepths = DDBD_1 |
2458// DDBD_8;
2459// pHALInfo->ddCaps.dwAlphaBltSurfaceBitDepths = DDBD_1 |
2460// DDBD_2 |
2461// DDBD_4 |
2462// DDBD_8;
2463#if 0
2464 // No alpha blending for overlays, so I'm not sure what these should be.
2465 // Because we support 32bpp overlays, it's just that you can't use the
2466 // alpha bits for blending. Pass.
2467 pHALInfo->ddCaps.dwAlphaBltConstBitDepths = DDBD_2 |
2468 DDBD_4 |
2469 DDBD_8;
2470
2471 pHALInfo->ddCaps.dwAlphaBltPixelBitDepths = DDBD_1 |
2472 DDBD_8;
2473
2474 pHALInfo->ddCaps.dwAlphaBltSurfaceBitDepths = DDBD_1 |
2475 DDBD_2 |
2476 DDBD_4 |
2477 DDBD_8;
2478
2479 //
2480 // ROPS supported
2481 //
2482 for( i=0;i<DD_ROP_SPACE;i++ )
2483 {
2484 pHALInfo->ddCaps.dwRops[i] = rops[i];
2485 }
2486#endif
2487//Reenable: // For DX5 and beyond we support this new informational callback.
2488// pHALInfo->GetDriverInfo = DdGetDriverInfo;
2489// pHALInfo->dwFlags |= DDHALINFO_GETDRIVERINFOSET;
2490//
2491//#if DX8_DDI
2492// // Flag our support for a new class of GUIDs that may come through
2493// // GetDriverInfo for DX8 drivers. (This support will be compulsory)
2494// pHALInfo->dwFlags |= DDHALINFO_GETDRIVERINFO2;
2495//#endif DX8_DDI
2496
2497 return true;
2498} // getDDHALInfo
2499
2500#endif
2501
2502static DECLCALLBACK(void) vboxVHWASurfBltCompletion(PPDEV ppdev, VBOXVHWACMD * pCmd, void * pContext)
2503{
2504 VBOXVHWACMD_SURF_BLT * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_BLT);
2505 PVBOXVHWASURFDESC pSrcDesc = (PVBOXVHWASURFDESC)pBody->SrcGuestSurfInfo;
2506 PVBOXVHWASURFDESC pDestDesc = (PVBOXVHWASURFDESC)pBody->DstGuestSurfInfo;
2507
2508 ASMAtomicDecU32(&pSrcDesc->cPendingBltsSrc);
2509 ASMAtomicDecU32(&pDestDesc->cPendingBltsDst);
2510
2511 vbvaVHWACommandRelease(ppdev, pCmd);
2512}
2513
2514static DECLCALLBACK(void) vboxVHWASurfFlipCompletion(PPDEV ppdev, VBOXVHWACMD * pCmd, void * pContext)
2515{
2516 VBOXVHWACMD_SURF_FLIP * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_FLIP);
2517 PVBOXVHWASURFDESC pCurrDesc = (PVBOXVHWASURFDESC)pBody->CurrGuestSurfInfo;
2518 PVBOXVHWASURFDESC pTargDesc = (PVBOXVHWASURFDESC)pBody->TargGuestSurfInfo;
2519
2520 ASMAtomicDecU32(&pCurrDesc->cPendingFlipsCurr);
2521 ASMAtomicDecU32(&pTargDesc->cPendingFlipsTarg);
2522
2523 vbvaVHWACommandRelease(ppdev, pCmd);
2524}
2525
2526#endif
2527
2528
2529
2530#endif /* VBOX_WITH_DDRAW */
Note: See TracBrowser for help on using the repository browser.

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