VirtualBox

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

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

2d accel:

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