VirtualBox

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

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

video hw accel: properly handle synch vhwa command completion

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