VirtualBox

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

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

2d accel: guest driver fix for overlay surfaces not marked as visible

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

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