VirtualBox

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

Last change on this file since 20653 was 20653, checked in by vboxsync, 16 years ago

video hw accel: fixes for basic ddraw op hanlding

  • Property svn:eol-style set to native
File size: 63.1 KB
Line 
1#ifdef VBOX_WITH_DDRAW
2
3/******************************Module*Header**********************************\
4*
5 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
6 *
7 * This file is part of VirtualBox Open Source Edition (OSE), as
8 * available from http://www.virtualbox.org. This file is free software;
9 * you can redistribute it and/or modify it under the terms of the GNU
10 * General Public License (GPL) as published by the Free Software
11 * Foundation, in version 2 as it comes in the "COPYING" file of the
12 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
13 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
14 *
15 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
16 * Clara, CA 95054 USA or visit http://www.sun.com if you need
17 * additional information or have any questions.
18*/
19/*
20* Based in part on Microsoft DDK sample code
21*
22* **************************
23* * DirectDraw SAMPLE CODE *
24* **************************
25*
26* Module Name: ddenable.c
27*
28* Content:
29*
30* Copyright (c) 1994-1998 3Dlabs Inc. Ltd. All rights reserved.
31* Copyright (c) 1995-1999 Microsoft Corporation. All rights reserved.
32\*****************************************************************************/
33
34#include "driver.h"
35#include "dd.h"
36#undef CO_E_NOTINITIALIZED
37#include <winerror.h>
38
39#if 0
40static DWORD APIENTRY DdCreateSurface(PDD_CREATESURFACEDATA lpCreateSurface);
41#endif
42
43#ifdef VBOX_WITH_VIDEOHWACCEL
44#include <iprt/asm.h>
45
46#define VBOXVHWA_CAP(_pdev, _cap) ((_pdev)->vhwaInfo.caps & (_cap))
47static bool getDDHALInfo(PPDEV pDev, DD_HALINFO* pHALInfo);
48static DECLCALLBACK(void) vboxVHWAFreeCmdCompletion(PPDEV ppdev, VBOXVHWACMD * pCmd, void * pContext);
49static DECLCALLBACK(void) vboxVHWASurfBltCompletion(PPDEV ppdev, VBOXVHWACMD * pCmd, void * pContext);
50
51#endif
52
53/**
54 * DrvGetDirectDrawInfo
55 *
56 * The DrvGetDirectDrawInfo function returns the capabilities of the graphics hardware.
57 *
58 * Parameters:
59 *
60 * dhpdev
61 * Handle to the PDEV returned by the driver’s DrvEnablePDEV routine.
62 * pHalInfo
63 * Points to a DD_HALINFO structure in which the driver should return the hardware capabilities that it supports.
64 * pdwNumHeaps
65 * Points to the location in which the driver should return the number of VIDEOMEMORY structures pointed to by pvmList.
66 * pvmList
67 * 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.
68 * pdwNumFourCCCodes
69 * Points to the location in which the driver should return the number of DWORDs pointed to by pdwFourCC.
70 * pdwFourCC
71 * 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.
72 *
73 * Return Value:
74 *
75 * DrvGetDirectDrawInfo returns TRUE if it succeeds; otherwise, it returns FALSE.
76 *
77 */
78BOOL APIENTRY DrvGetDirectDrawInfo(
79 DHPDEV dhpdev,
80 DD_HALINFO *pHalInfo,
81 DWORD *pdwNumHeaps,
82 VIDEOMEMORY *pvmList,
83 DWORD *pdwNumFourCCCodes,
84 DWORD *pdwFourCC
85 )
86{
87 PPDEV pDev = (PPDEV)dhpdev;
88 BOOL bDefineDDrawHeap = FALSE;
89 DWORD cHeaps = 0;
90 VIDEOMEMORY *pVm = NULL;
91
92 DISPDBG((0, "%s: %p, %p, %p, %p, %p. %p\n", __FUNCTION__, dhpdev, pHalInfo, pdwNumHeaps, pvmList, pdwNumFourCCCodes, pdwFourCC));
93
94 *pdwNumFourCCCodes = 0;
95 *pdwNumHeaps = 0;
96
97 /* Setup the HAL driver caps. */
98 pHalInfo->dwSize = sizeof(DD_HALINFO);
99#ifndef VBOX_WITH_VIDEOHWACCEL
100 pHalInfo->dwFlags = 0;
101#endif
102
103 if (!(pvmList && pdwFourCC))
104 {
105#ifdef VBOX_WITH_VIDEOHWACCEL
106 vboxVHWAInit();
107
108 memset(pHalInfo, 0, sizeof(DD_HALINFO));
109 pHalInfo->dwSize = sizeof(DD_HALINFO);
110
111 vboxVHWAInitHostInfo1(pDev);
112#else
113 memset(&pHalInfo->ddCaps, 0, sizeof(DDNTCORECAPS));
114#endif
115
116 pHalInfo->ddCaps.dwSize = sizeof(DDNTCORECAPS);
117 pHalInfo->ddCaps.dwVidMemTotal = pDev->layout.cbDDRAWHeap;
118 pHalInfo->ddCaps.dwVidMemFree = pHalInfo->ddCaps.dwVidMemTotal;
119
120 pHalInfo->ddCaps.dwCaps = 0;
121 pHalInfo->ddCaps.dwCaps2 = 0;
122
123 /* Declare we can handle textures wider than the primary */
124 pHalInfo->ddCaps.dwCaps2 |= DDCAPS2_WIDESURFACES;
125
126 pHalInfo->ddCaps.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
127
128 /* Create primary surface attributes */
129 pHalInfo->vmiData.pvPrimary = pDev->pjScreen;
130 pHalInfo->vmiData.fpPrimary = 0;
131 pHalInfo->vmiData.dwDisplayWidth = pDev->cxScreen;
132 pHalInfo->vmiData.dwDisplayHeight = pDev->cyScreen;
133 pHalInfo->vmiData.lDisplayPitch = pDev->lDeltaScreen;
134
135 pHalInfo->vmiData.ddpfDisplay.dwSize = sizeof(DDPIXELFORMAT);
136 pHalInfo->vmiData.ddpfDisplay.dwFlags = DDPF_RGB;
137 pHalInfo->vmiData.ddpfDisplay.dwRGBBitCount = pDev->ulBitCount;
138 DISPDBG((0, "pvPrimary %x\n", pHalInfo->vmiData.pvPrimary));
139 DISPDBG((0, "fpPrimary %x\n", pHalInfo->vmiData.fpPrimary));
140 DISPDBG((0, "dwDisplayWidth %d\n", pHalInfo->vmiData.dwDisplayWidth));
141 DISPDBG((0, "dwDisplayHeight %d\n", pHalInfo->vmiData.dwDisplayHeight));
142 DISPDBG((0, "lDisplayPitch %d\n", pHalInfo->vmiData.lDisplayPitch));
143 DISPDBG((0, "dwRGBBitCount %d\n", pHalInfo->vmiData.ddpfDisplay.dwRGBBitCount));
144
145 if (pDev->ulBitmapType == BMF_8BPP)
146 {
147 pHalInfo->vmiData.ddpfDisplay.dwFlags |= DDPF_PALETTEINDEXED8;
148 DISPDBG((0, "DDPF_PALETTEINDEXED8\n"));
149 }
150
151 pHalInfo->vmiData.ddpfDisplay.dwRBitMask = pDev->flRed;
152 pHalInfo->vmiData.ddpfDisplay.dwGBitMask = pDev->flGreen;
153 pHalInfo->vmiData.ddpfDisplay.dwBBitMask = pDev->flBlue;
154
155 pHalInfo->vmiData.dwOffscreenAlign = 4;
156 pHalInfo->vmiData.dwZBufferAlign = 4;
157 pHalInfo->vmiData.dwTextureAlign = 4;
158
159
160#ifdef VBOX_WITH_VIDEOHWACCEL
161 if(pDev->vhwaInfo.bVHWAEnabled)
162 {
163 pHalInfo->vmiData.dwOverlayAlign = 4;
164
165 pDev->vhwaInfo.bVHWAEnabled = getDDHALInfo(pDev, pHalInfo);
166 }
167#endif
168 }
169
170 cHeaps = 0;
171
172 /* Do we have sufficient videomemory to create an off-screen heap for DDraw? */
173 if (pDev->layout.cbDDRAWHeap > 0)
174 {
175 bDefineDDrawHeap = TRUE;
176 cHeaps++;
177 }
178
179 pDev->cHeaps = cHeaps;
180 *pdwNumHeaps = cHeaps;
181
182 // If pvmList is not NULL then we can go ahead and fill out the VIDEOMEMORY
183 // structures which define our requested heaps.
184
185 if(pvmList) {
186
187 pVm=pvmList;
188
189 //
190 // Snag a pointer to the video-memory list so that we can use it to
191 // call back to DirectDraw to allocate video memory:
192 //
193 pDev->pvmList = pVm;
194
195 //
196 // Define the heap for DirectDraw
197 //
198 if ( bDefineDDrawHeap )
199 {
200 pVm->dwFlags = VIDMEM_ISLINEAR ;
201 pVm->fpStart = pDev->layout.offDDRAWHeap;
202 pVm->fpEnd = pDev->layout.offDDRAWHeap + pDev->layout.cbDDRAWHeap - 1; /* inclusive */
203#ifndef VBOX_WITH_VIDEOHWACCEL
204 pVm->ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
205#endif
206 DISPDBG((0, "fpStart %x fpEnd %x\n", pVm->fpStart, pVm->fpEnd));
207
208 pVm++;
209 }
210 }
211
212#ifdef VBOX_WITH_VIDEOHWACCEL
213 if(pDev->vhwaInfo.bVHWAEnabled)
214 {
215// // TODO: filter out hw-unsupported fourccs
216//#define FOURCC_YUV422 (MAKEFOURCC('Y','U','Y','2'))
217//#define FOURCC_YUV411 (MAKEFOURCC('Y','4','1','1'))
218//
219// static DWORD fourCC[] = { FOURCC_YUV422, FOURCC_YUV411 }; // The FourCC's we support
220
221 *pdwNumFourCCCodes = pDev->vhwaInfo.numFourCC;
222
223 if (pdwFourCC && pDev->vhwaInfo.numFourCC)
224 {
225 int rc = vboxVHWAInitHostInfo2(pDev, pdwFourCC);
226 if(RT_FAILURE(rc))
227 {
228 *pdwNumFourCCCodes = 0;
229 pDev->vhwaInfo.numFourCC = 0;
230 }
231 }
232 }
233#endif
234
235#ifdef VBOX_WITH_VIDEOHWACCEL
236 if(pDev->vhwaInfo.bVHWAEnabled)
237 {
238 /* we need it to set DDHAL_PRIVATECAP_NOTIFYPRIMARYCREATION to make ddraw call us for primary surface creation */
239 /* DX5 and up */
240 pHalInfo->GetDriverInfo = DdGetDriverInfo;
241 pHalInfo->dwFlags |= DDHALINFO_GETDRIVERINFOSET;
242 }
243#endif
244
245#if 0
246 /* No 3D capabilities */
247 if (pHalInfo->lpD3DGlobalDriverData)
248 {
249 LPD3DHAL_GLOBALDRIVERDATA lpD3DGlobalDriverData = (LPD3DHAL_GLOBALDRIVERDATA)pHalInfo->lpD3DGlobalDriverData;
250 lpD3DGlobalDriverData->dwSize = sizeof(D3DHAL_GLOBALDRIVERDATA);
251 }
252#endif
253 return TRUE;
254}
255
256/**
257 * DrvEnableDirectDraw
258 *
259 * The DrvEnableDirectDraw function enables hardware for DirectDraw use.
260 *
261 * Parameters
262 *
263 * dhpdev
264 * Handle to the PDEV returned by the driver’s DrvEnablePDEV routine.
265 * pCallBacks
266 * Points to the DD_CALLBACKS structure to be initialized by the driver.
267 * pSurfaceCallBacks
268 * Points to the DD_SURFACECALLBACKS structure to be initialized by the driver.
269 * pPaletteCallBacks
270 * Points to the DD_PALETTECALLBACKS structure to be initialized by the driver.
271 *
272 * Return Value
273 *
274 * DrvEnableDirectDraw returns TRUE if it succeeds; otherwise, it returns FALSE.
275 *
276 */
277BOOL APIENTRY DrvEnableDirectDraw(
278 DHPDEV dhpdev,
279 DD_CALLBACKS *pCallBacks,
280 DD_SURFACECALLBACKS *pSurfaceCallBacks,
281 DD_PALETTECALLBACKS *pPaletteCallBacks
282 )
283{
284#ifdef VBOX_WITH_VIDEOHWACCEL
285 PPDEV pDev = (PPDEV)dhpdev;
286
287#endif
288
289 DISPDBG((0, "%s: %p, %p, %p, %p\n", __FUNCTION__, dhpdev, pCallBacks, pSurfaceCallBacks, pPaletteCallBacks));
290
291 /* Fill in the HAL Callback pointers */
292 pCallBacks->dwSize = sizeof(DD_CALLBACKS);
293 pCallBacks->dwFlags = 0;
294
295 pCallBacks->dwFlags = DDHAL_CB32_CREATESURFACE | DDHAL_CB32_CANCREATESURFACE | DDHAL_CB32_MAPMEMORY;
296 pCallBacks->CreateSurface = DdCreateSurface;
297 pCallBacks->CanCreateSurface = DdCanCreateSurface;
298 pCallBacks->MapMemory = DdMapMemory;
299 // pCallBacks->WaitForVerticalBlank = DdWaitForVerticalBlank;
300 // pCallBacks->GetScanLine = DdGetScanLine;
301 // DDHAL_CB32_WAITFORVERTICALBLANK | DDHAL_CB32_GETSCANLINE
302 /* Note: pCallBacks->SetMode & pCallBacks->DestroyDriver are unused in Windows 2000 and up */
303
304 /* Fill in the Surface Callback pointers */
305 pSurfaceCallBacks->dwSize = sizeof(DD_SURFACECALLBACKS);
306 pSurfaceCallBacks->dwFlags = DDHAL_SURFCB32_LOCK | DDHAL_SURFCB32_UNLOCK;
307 pSurfaceCallBacks->Lock = DdLock;
308 pSurfaceCallBacks->Unlock = DdUnlock;
309
310 /*
311 pSurfaceCallBacks->dwFlags = DDHAL_SURFCB32_DESTROYSURFACE | DDHAL_SURFCB32_LOCK; // DDHAL_SURFCB32_UNLOCK;
312 pSurfaceCallBacks->DestroySurface = DdDestroySurface;
313 pSurfaceCallBacks->Flip = DdFlip;
314 pSurfaceCallBacks->GetBltStatus = DdGetBltStatus;
315 pSurfaceCallBacks->GetFlipStatus = DdGetFlipStatus;
316 pSurfaceCallBacks->Blt = DdBlt;
317 DDHAL_SURFCB32_FLIP | DDHAL_SURFCB32_BLT | DDHAL_SURFCB32_GETBLTSTATUS | DDHAL_SURFCB32_GETFLIPSTATUS;
318 */
319
320// pSurfaceCallBacks.SetColorKey = DdSetColorKey;
321// pSurfaceCallBacks.dwFlags |= DDHAL_SURFCB32_SETCOLORKEY;
322
323 /* Fill in the Palette Callback pointers */
324 pPaletteCallBacks->dwSize = sizeof(DD_PALETTECALLBACKS);
325 pPaletteCallBacks->dwFlags = 0;
326
327#ifdef VBOX_WITH_VIDEOHWACCEL
328 if(pDev->vhwaInfo.bVHWAEnabled)
329 {
330 //TODO: filter out those we do not need in case not supported by hw
331 pSurfaceCallBacks->DestroySurface = DdDestroySurface;
332// pSurfaceCallBacks->Lock = DdLock;
333// pSurfaceCallBacks->Unlock = DdUnlock;
334 pSurfaceCallBacks->GetBltStatus = DdGetBltStatus;
335 pSurfaceCallBacks->GetFlipStatus = DdGetFlipStatus;
336 pSurfaceCallBacks->SetColorKey = DdSetColorKey;
337 pSurfaceCallBacks->Flip = DdFlip;
338 pSurfaceCallBacks->Blt = DdBlt;
339
340 pSurfaceCallBacks->dwFlags |= DDHAL_SURFCB32_DESTROYSURFACE |
341 DDHAL_SURFCB32_FLIP
342// | DDHAL_SURFCB32_LOCK
343 | DDHAL_SURFCB32_BLT |
344 DDHAL_SURFCB32_GETBLTSTATUS |
345 DDHAL_SURFCB32_GETFLIPSTATUS |
346 DDHAL_SURFCB32_SETCOLORKEY
347// | DDHAL_SURFCB32_UNLOCK
348 ;
349
350 if(pDev->vhwaInfo.caps & VBOXVHWA_CAPS_OVERLAY)
351 {
352 pSurfaceCallBacks->UpdateOverlay = DdUpdateOverlay; // Now supporting overlays.
353 pSurfaceCallBacks->SetOverlayPosition = DdSetOverlayPosition;
354 pSurfaceCallBacks->dwFlags |=
355 DDHAL_SURFCB32_UPDATEOVERLAY | // Now supporting
356 DDHAL_SURFCB32_SETOVERLAYPOSITION ; // overlays.
357 }
358 }
359#endif
360 return TRUE;
361}
362
363/**
364 * DrvDisableDirectDraw
365 *
366 * The DrvDisableDirectDraw function disables hardware for DirectDraw use.
367 *
368 * Parameters
369 *
370 * dhpdev
371 * Handle to the PDEV returned by the driver’s DrvEnablePDEV routine.
372 *
373 */
374VOID APIENTRY DrvDisableDirectDraw( DHPDEV dhpdev)
375{
376 DISPDBG((0, "%s: %p\n", __FUNCTION__, dhpdev));
377}
378
379/**
380 * DdGetDriverInfo
381 *
382 * The DdGetDriverInfo function queries the driver for additional DirectDraw and Direct3D functionality that the driver supports.
383 *
384 * Parameters
385 * lpGetDriverInfo
386 * Points to a DD_GETDRIVERINFODATA structure that contains the information required to perform the query.
387 *
388 * Return Value
389 *
390 * DdGetDriverInfo must return DDHAL_DRIVER_HANDLED.
391 *
392 */
393DWORD CALLBACK DdGetDriverInfo(DD_GETDRIVERINFODATA *lpData)
394{
395 PPDEV pDev = (PPDEV)lpData->dhpdev;
396 DWORD dwSize;
397
398 DISPDBG((0, "%s: %p\n", __FUNCTION__, lpData->dhpdev));
399
400 /* Default to 'not supported' */
401 lpData->ddRVal = DDERR_CURRENTLYNOTAVAIL;
402
403 /* Fill in supported stuff */
404 if (IsEqualIID(&lpData->guidInfo, &GUID_D3DCallbacks3))
405 {
406 DISPDBG((0, " -> GUID_D3DCallbacks3\n"));
407 }
408 else
409 if (IsEqualIID(&lpData->guidInfo, &GUID_D3DExtendedCaps))
410 {
411 DISPDBG((0, " -> GUID_D3DExtendedCaps\n"));
412 }
413 else
414 if (IsEqualIID(&lpData->guidInfo, &GUID_ZPixelFormats))
415 {
416 DISPDBG((0, " -> GUID_ZPixelFormats\n"));
417 }
418 else
419 if (IsEqualIID(&(lpData->guidInfo), &GUID_D3DParseUnknownCommandCallback))
420 {
421 DISPDBG((0, " -> GUID_D3DParseUnknownCommandCallback\n"));
422 }
423 else
424 if (IsEqualIID(&(lpData->guidInfo), &GUID_Miscellaneous2Callbacks))
425 {
426 DISPDBG((0, " -> GUID_Miscellaneous2Callbacks\n"));
427 }
428 else
429 if (IsEqualIID(&(lpData->guidInfo), &GUID_UpdateNonLocalHeap))
430 {
431 DISPDBG((0, " -> GUID_UpdateNonLocalHeap\n"));
432 }
433 else
434 if (IsEqualIID(&(lpData->guidInfo), &GUID_GetHeapAlignment))
435 {
436 DISPDBG((0, " -> GUID_GetHeapAlignment\n"));
437 }
438 else
439 if (IsEqualIID(&(lpData->guidInfo), &GUID_NTPrivateDriverCaps))
440 {
441 DD_NTPRIVATEDRIVERCAPS DDPrivateDriverCaps;
442
443 DISPDBG((0, " -> GUID_NTPrivateDriverCaps\n"));
444
445 memset(&DDPrivateDriverCaps, 0, sizeof(DDPrivateDriverCaps));
446 DDPrivateDriverCaps.dwSize=sizeof(DDPrivateDriverCaps);
447#ifndef VBOX_WITH_VIDEOHWACCEL
448 DDPrivateDriverCaps.dwPrivateCaps = 0; /* DDHAL_PRIVATECAP_NOTIFYPRIMARYCREATION -> call CreateSurface for the primary surface */
449#else
450 DDPrivateDriverCaps.dwPrivateCaps = DDHAL_PRIVATECAP_NOTIFYPRIMARYCREATION; /* -> call CreateSurface for the primary surface */
451#endif
452
453 lpData->dwActualSize =sizeof(DDPrivateDriverCaps);
454
455 dwSize = min(sizeof(DDPrivateDriverCaps),lpData->dwExpectedSize);
456 memcpy(lpData->lpvData, &DDPrivateDriverCaps, dwSize);
457 lpData->ddRVal = DD_OK;
458 }
459 else
460 if (IsEqualIID(&(lpData->guidInfo), &GUID_DDMoreSurfaceCaps))
461 {
462#ifndef VBOX_WITH_VIDEOHWACCEL
463 DD_MORESURFACECAPS DDMoreSurfaceCaps;
464 DDSCAPSEX ddsCapsEx, ddsCapsExAlt;
465
466 DISPDBG((0, " -> GUID_DDMoreSurfaceCaps\n"));
467
468 // fill in everything until expectedsize...
469 memset(&DDMoreSurfaceCaps, 0, sizeof(DDMoreSurfaceCaps));
470
471 // Caps for heaps 2..n
472 memset(&ddsCapsEx, 0, sizeof(ddsCapsEx));
473 memset(&ddsCapsExAlt, 0, sizeof(ddsCapsEx));
474
475 DDMoreSurfaceCaps.dwSize=lpData->dwExpectedSize;
476
477 lpData->dwActualSize = lpData->dwExpectedSize;
478
479 dwSize = min(sizeof(DDMoreSurfaceCaps),lpData->dwExpectedSize);
480 memcpy(lpData->lpvData, &DDMoreSurfaceCaps, dwSize);
481
482 // now fill in other heaps...
483 while (dwSize < lpData->dwExpectedSize)
484 {
485 memcpy( (PBYTE)lpData->lpvData+dwSize,
486 &ddsCapsEx,
487 sizeof(DDSCAPSEX));
488 dwSize += sizeof(DDSCAPSEX);
489 memcpy( (PBYTE)lpData->lpvData+dwSize,
490 &ddsCapsExAlt,
491 sizeof(DDSCAPSEX));
492 dwSize += sizeof(DDSCAPSEX);
493 }
494
495 lpData->ddRVal = DD_OK;
496#else
497 DISPDBG((0, " -> GUID_DDMoreSurfaceCaps\n"));
498#endif
499 }
500 else
501 if (IsEqualIID(&(lpData->guidInfo), &GUID_DDStereoMode))
502 {
503 DISPDBG((0, " -> GUID_DDStereoMode\n"));
504 }
505 else
506 if (IsEqualIID(&(lpData->guidInfo), &GUID_NonLocalVidMemCaps))
507 {
508 DISPDBG((0, " -> GUID_NonLocalVidMemCaps\n"));
509 }
510 else
511 if (IsEqualIID(&lpData->guidInfo, &GUID_NTCallbacks))
512 {
513#ifndef VBOX_WITH_VIDEOHWACCEL
514 DD_NTCALLBACKS NtCallbacks;
515
516 DISPDBG((0, " -> GUID_NTCallbacks\n"));
517 memset(&NtCallbacks, 0, sizeof(NtCallbacks));
518
519 dwSize = min(lpData->dwExpectedSize, sizeof(DD_NTCALLBACKS));
520
521 NtCallbacks.dwSize = dwSize;
522 NtCallbacks.dwFlags = DDHAL_NTCB32_FREEDRIVERMEMORY
523 | DDHAL_NTCB32_SETEXCLUSIVEMODE
524 | DDHAL_NTCB32_FLIPTOGDISURFACE
525 ;
526 NtCallbacks.FreeDriverMemory = DdFreeDriverMemory;
527 NtCallbacks.SetExclusiveMode = DdSetExclusiveMode;
528 NtCallbacks.FlipToGDISurface = DdFlipToGDISurface;
529
530 memcpy(lpData->lpvData, &NtCallbacks, dwSize);
531
532 lpData->ddRVal = DD_OK;
533#else
534 DISPDBG((0, " -> GUID_NTCallbacks\n"));
535#endif
536 }
537 else
538 if (IsEqualIID(&lpData->guidInfo, &GUID_KernelCaps))
539 {
540 DISPDBG((0, " -> GUID_KernelCaps\n"));
541 }
542 else
543 if (IsEqualIID(&lpData->guidInfo, &GUID_KernelCallbacks))
544 {
545 DISPDBG((0, " -> GUID_KernelCallbacks\n"));
546 }
547 else
548 if (IsEqualIID(&lpData->guidInfo, &GUID_MotionCompCallbacks))
549 {
550 DISPDBG((0, " -> GUID_MotionCompCallbacks\n"));
551 }
552 else
553 if (IsEqualIID(&lpData->guidInfo, &GUID_VideoPortCallbacks))
554 {
555 DISPDBG((0, " -> GUID_VideoPortCallbacks\n"));
556 }
557 else
558 if (IsEqualIID(&lpData->guidInfo, &GUID_ColorControlCallbacks))
559 {
560 DISPDBG((0, " -> GUID_ColorControlCallbacks\n"));
561 }
562 else
563 if (IsEqualIID(&lpData->guidInfo, &GUID_VideoPortCaps))
564 {
565 DISPDBG((0, " -> GUID_VideoPortCaps\n"));
566 }
567 else
568 if (IsEqualIID(&lpData->guidInfo, &GUID_D3DCallbacks2))
569 {
570 DISPDBG((0, " -> GUID_D3DCallbacks2\n"));
571 }
572 else
573 if (IsEqualIID(&lpData->guidInfo, &GUID_D3DCallbacks3))
574 {
575 DISPDBG((0, " -> GUID_D3DCallbacks3\n"));
576 }
577
578 /* Always return this */
579 return DDHAL_DRIVER_HANDLED;
580}
581
582/**
583 * DdCreateSurface
584 *
585 * The DdCreateSurface callback function creates a DirectDraw surface.
586 *
587 * lpCreateSurface
588 * Points to a DD_CREATESURFACEDATA structure that contains the information required to create a surface.
589 *
590 * Return Value
591 *
592 * DdCreateSurface returns one of the following callback codes:
593 * DDHAL_DRIVER_HANDLED
594 * DDHAL_DRIVER_NOTHANDLED
595 *
596 */
597DWORD APIENTRY DdCreateSurface(PDD_CREATESURFACEDATA lpCreateSurface)
598{
599 PPDEV pDev = (PPDEV)lpCreateSurface->lpDD->dhpdev;
600 DD_SURFACE_LOCAL* lpSurfaceLocal;
601 DD_SURFACE_GLOBAL* lpSurfaceGlobal;
602 LPDDSURFACEDESC lpSurfaceDesc;
603 LONG lPitch, lBpp;
604
605 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
606
607 lpSurfaceLocal = lpCreateSurface->lplpSList[0];
608 lpSurfaceGlobal = lpSurfaceLocal->lpGbl;
609 lpSurfaceDesc = lpCreateSurface->lpDDSurfaceDesc;
610
611#ifdef VBOX_WITH_VIDEOHWACCEL
612 if(pDev->vhwaInfo.bVHWAEnabled && lpSurfaceLocal->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
613 {
614 lBpp = pDev->ulBitCount;
615 lPitch = pDev->lDeltaScreen;
616 }
617 else
618#endif
619 {
620 lpSurfaceGlobal->dwReserved1 = 0;
621
622 if (lpSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED4)
623 {
624 lBpp = 4;
625 lPitch = lpSurfaceGlobal->wWidth/2;
626 lPitch = (lPitch + 31) & ~31;
627 }
628 else
629 if (lpSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8)
630 {
631 lBpp = 8;
632 lPitch = lpSurfaceGlobal->wWidth;
633 lPitch = (lPitch + 31) & ~31;
634 }
635 else
636 {
637 lBpp = lpSurfaceDesc->ddpfPixelFormat.dwRGBBitCount;
638 lPitch = lpSurfaceGlobal->wWidth*(lBpp/8);
639 }
640 DISPDBG((0, "New surface (%d,%d)\n", lpSurfaceGlobal->wWidth, lpSurfaceGlobal->wHeight));
641 DISPDBG((0, "BPP %d lPitch=%d\n", lBpp, lPitch));
642
643 lpSurfaceGlobal->dwBlockSizeX = lPitch;
644 lpSurfaceGlobal->dwBlockSizeY = lpSurfaceGlobal->wHeight;
645 lpSurfaceGlobal->lPitch = lPitch;
646
647 lpSurfaceDesc->lPitch = lpSurfaceGlobal->lPitch;
648 lpSurfaceDesc->dwFlags |= DDSD_PITCH;
649 }
650
651 //
652 // Modify surface descriptions as appropriate and let Direct
653 // Draw perform the allocation if the surface was not the primary
654 //
655 if (lpSurfaceLocal->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
656 {
657 DISPDBG((0, "-> primary surface\n"));
658 lpSurfaceGlobal->fpVidMem = 0;
659 }
660 else
661 {
662 DISPDBG((0, "-> secondary surface\n"));
663 lpSurfaceGlobal->fpVidMem = DDHAL_PLEASEALLOC_BLOCKSIZE;
664 }
665
666#ifdef VBOX_WITH_VIDEOHWACCEL
667 if(pDev->vhwaInfo.bVHWAEnabled)
668 {
669 VBOXVHWACMD* pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_CREATE, sizeof(VBOXVHWACMD_SURF_CREATE));
670 if(pCmd)
671 {
672 VBOXVHWACMD_SURF_CREATE * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_CREATE);
673 PVBOXVHWASURFDESC pDesc;
674 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_CREATE));
675
676 pBody->u.in.SurfInfo.surfCaps = vboxVHWAFromDDSCAPS(lpSurfaceLocal->ddsCaps.dwCaps);
677
678 pBody->u.in.SurfInfo.height = lpSurfaceGlobal->wHeight;
679 pBody->u.in.SurfInfo.width = lpSurfaceGlobal->wWidth;
680
681 vboxVHWAFromDDPIXELFORMAT(&pBody->u.in.SurfInfo.PixelFormat, &lpSurfaceGlobal->ddpfSurface);
682
683 if (lpSurfaceLocal->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
684 {
685 pBody->u.in.offSurface = 0;
686 }
687 else
688 {
689 pBody->u.in.offSurface = VBOXVHWA_OFFSET64_VOID;
690 }
691
692
693 pDesc = vboxVHWASurfDescAlloc();
694 if(pDesc)
695 {
696 pDesc->cBitsPerPixel = lBpp;
697 vboxVHWACommandSubmit(pDev, pCmd);
698 if(pCmd->rc == VINF_SUCCESS)
699 {
700 pDesc->hHostHandle = pBody->u.out.hSurf;
701 lpSurfaceGlobal->dwReserved1 = (ULONG_PTR)pDesc;
702 lpCreateSurface->ddRVal = DD_OK;
703 }
704 else
705 {
706 vboxVHWASurfDescFree(pDesc);
707 lpCreateSurface->ddRVal = DDERR_GENERIC;
708 }
709 }
710 vboxVHWACommandFree(pDev, pCmd);
711 }
712 }
713#endif
714 return DDHAL_DRIVER_NOTHANDLED;
715}
716
717/**
718 * DdCanCreateSurface
719 *
720 * The DdCanCreateSurface callback function indicates whether the driver can create a surface of the specified surface description.
721 *
722 *
723 * Parameters
724 * lpCanCreateSurface
725 * Points to the DD_CANCREATESURFACEDATA structure containing the information required for the driver to determine whether a surface can be created.
726 *
727 * Return Value
728 *
729 * DdCanCreateSurface returns one of the following callback codes:
730 *
731 * DDHAL_DRIVER_HANDLED
732 * DDHAL_DRIVER_NOTHANDLED
733 *
734 */
735DWORD APIENTRY DdCanCreateSurface(PDD_CANCREATESURFACEDATA lpCanCreateSurface)
736{
737 PPDEV pDev = (PPDEV)lpCanCreateSurface->lpDD->dhpdev;
738
739 PDD_SURFACEDESC lpDDS = lpCanCreateSurface->lpDDSurfaceDesc;
740
741 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
742
743 if (lpDDS->ddsCaps.dwCaps & DDSCAPS_ZBUFFER)
744 {
745 DISPDBG((0, "No Z-Bufer support\n"));
746 lpCanCreateSurface->ddRVal = DDERR_INVALIDPIXELFORMAT;
747 return DDHAL_DRIVER_HANDLED;
748 }
749 if (lpDDS->ddsCaps.dwCaps & DDSCAPS_TEXTURE)
750 {
751 DISPDBG((0, "No texture support\n"));
752 lpCanCreateSurface->ddRVal = DDERR_INVALIDPIXELFORMAT;
753 return DDHAL_DRIVER_HANDLED;
754 }
755
756#ifdef VBOX_WITH_VIDEOHWACCEL
757 if(pDev->vhwaInfo.bVHWAEnabled)
758 {
759 VBOXVHWACMD* pCmd;
760 uint32_t unsupportedSCaps = vboxVHWAUnsupportedDDSCAPS(lpDDS->ddsCaps.dwCaps);
761 if(unsupportedSCaps)
762 {
763 VHWADBG(("vboxVHWASurfCanCreate: unsupported ddscaps: 0x%x", unsupportedSCaps));
764 lpCanCreateSurface->ddRVal = DDERR_INVALIDCAPS;
765 return DDHAL_DRIVER_HANDLED;
766 }
767
768 unsupportedSCaps = vboxVHWAUnsupportedDDPFS(lpDDS->ddpfPixelFormat.dwFlags);
769 if(unsupportedSCaps)
770 {
771 VHWADBG(("vboxVHWASurfCanCreate: unsupported pixel format: 0x%x", unsupportedSCaps));
772 lpCanCreateSurface->ddRVal = DDERR_INVALIDPIXELFORMAT;
773 return DDHAL_DRIVER_HANDLED;
774 }
775
776 pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_CANCREATE, sizeof(VBOXVHWACMD_SURF_CANCREATE));
777 if(pCmd)
778 {
779 VBOXVHWACMD_SURF_CANCREATE * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_CANCREATE);
780 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_CANCREATE));
781
782 pBody->u.in.SurfInfo.surfCaps = vboxVHWAFromDDSCAPS(lpDDS->ddsCaps.dwCaps);
783
784 pBody->u.in.SurfInfo.height = lpDDS->dwHeight;
785 pBody->u.in.SurfInfo.width = lpDDS->dwWidth;
786 vboxVHWAFromDDPIXELFORMAT(&pBody->u.in.SurfInfo.PixelFormat, &lpDDS->ddpfPixelFormat);
787
788 vboxVHWACommandSubmit(pDev, pCmd);
789 Assert(pCmd->rc == VINF_SUCCESS);
790 if(pCmd->rc == VINF_SUCCESS)
791 {
792 if(pBody->u.out.ErrInfo)
793 {
794 lpCanCreateSurface->ddRVal = DDERR_GENERIC;
795 }
796 else
797 {
798 lpCanCreateSurface->ddRVal = DD_OK;
799 }
800 }
801 else
802 {
803 lpCanCreateSurface->ddRVal = DDERR_GENERIC;
804 }
805 vboxVHWACommandFree(pDev, pCmd);
806 }
807 else
808 {
809 lpCanCreateSurface->ddRVal = DDERR_GENERIC;
810 }
811 return DDHAL_DRIVER_HANDLED;
812 }
813#endif
814 if (lpCanCreateSurface->bIsDifferentPixelFormat && (lpDDS->ddpfPixelFormat.dwFlags & DDPF_FOURCC))
815 {
816 DISPDBG((0, "FOURCC not supported\n"));
817 lpCanCreateSurface->ddRVal = DDERR_INVALIDPIXELFORMAT;
818 return DDHAL_DRIVER_HANDLED;
819 }
820
821 lpCanCreateSurface->ddRVal = DD_OK;
822 return DDHAL_DRIVER_HANDLED;
823}
824
825// ***************************WIN NT ONLY**********************************
826//
827// DdMapMemory
828//
829// Maps application-modifiable portions of the frame buffer into the
830// user-mode address space of the specified process, or unmaps memory.
831//
832// DdMapMemory is called to perform memory mapping before the first call to
833// DdLock. The handle returned by the driver in fpProcess will be passed to
834// every DdLock call made on the driver.
835//
836// DdMapMemory is also called to unmap memory after the last DdUnLock call is
837// made.
838//
839// To prevent driver crashes, the driver must not map any portion of the frame
840// buffer that must not be modified by an application.
841//
842// Parameters
843// lpMapMemory
844// Points to a DD_MAPMEMORYDATA structure that contains details for
845// the memory mapping or unmapping operation.
846//
847// .lpDD
848// Points to a DD_DIRECTDRAW_GLOBAL structure that represents
849// the driver.
850// .bMap
851// Specifies the memory operation that the driver should perform.
852// A value of TRUE indicates that the driver should map memory;
853// FALSE means that the driver should unmap memory.
854// .hProcess
855// Specifies a handle to the process whose address space is
856// affected.
857// .fpProcess
858// Specifies the location in which the driver should return the
859// base address of the process's memory mapped space when bMap
860// is TRUE. When bMap is FALSE, fpProcess contains the base
861// address of the memory to be unmapped by the driver.
862// .ddRVal
863// Specifies the location in which the driver writes the return
864// value of the DdMapMemory callback. A return code of DD_OK
865// indicates success.
866//
867//-----------------------------------------------------------------------------
868
869DWORD CALLBACK DdMapMemory(PDD_MAPMEMORYDATA lpMapMemory)
870{
871 PPDEV pDev = (PPDEV)lpMapMemory->lpDD->dhpdev;
872
873 VIDEO_SHARE_MEMORY ShareMemory;
874 VIDEO_SHARE_MEMORY_INFORMATION ShareMemoryInformation;
875 DWORD ReturnedDataLength;
876
877 DISPDBG((0, "%s: %p bMap %d\n", __FUNCTION__, pDev, lpMapMemory->bMap));
878
879 if (lpMapMemory->bMap)
880 {
881 ShareMemory.ProcessHandle = lpMapMemory->hProcess;
882
883 // 'RequestedVirtualAddress' isn't actually used for the SHARE IOCTL:
884
885 ShareMemory.RequestedVirtualAddress = 0;
886
887 // We map in starting at the top of the frame buffer:
888
889 ShareMemory.ViewOffset = 0;
890
891 // We map down to the end of the frame buffer, including the offscreen heap.
892 ShareMemory.ViewSize = pDev->layout.offVBVABuffer;
893
894 DISPDBG((0, "ViewSize = %x\n", ShareMemory.ViewSize));
895
896 if (EngDeviceIoControl(pDev->hDriver,
897 IOCTL_VIDEO_SHARE_VIDEO_MEMORY,
898 &ShareMemory,
899 sizeof(VIDEO_SHARE_MEMORY),
900 &ShareMemoryInformation,
901 sizeof(VIDEO_SHARE_MEMORY_INFORMATION),
902 &ReturnedDataLength))
903 {
904 DISPDBG((0, "Failed IOCTL_VIDEO_SHARE_MEMORY\n"));
905
906 lpMapMemory->ddRVal = DDERR_GENERIC;
907
908 DISPDBG((0, "DdMapMemory: Exit GEN, DDHAL_DRIVER_HANDLED\n"));
909
910 return(DDHAL_DRIVER_HANDLED);
911 }
912
913 lpMapMemory->fpProcess =
914 (FLATPTR) ShareMemoryInformation.VirtualAddress;
915 }
916 else
917 {
918 ShareMemory.ProcessHandle = lpMapMemory->hProcess;
919 ShareMemory.ViewOffset = 0;
920 ShareMemory.ViewSize = 0;
921 ShareMemory.RequestedVirtualAddress = (VOID*) lpMapMemory->fpProcess;
922
923 if (EngDeviceIoControl(pDev->hDriver,
924 IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY,
925 &ShareMemory,
926 sizeof(VIDEO_SHARE_MEMORY),
927 NULL,
928 0,
929 &ReturnedDataLength))
930 {
931 DISPDBG((0, "Failed IOCTL_VIDEO_UNSHARE_MEMORY\n"));
932 }
933 }
934
935 lpMapMemory->ddRVal = DD_OK;
936
937 return(DDHAL_DRIVER_HANDLED);
938}
939
940/**
941 * DdLock
942 *
943 * 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.
944 *
945 * Parameters
946 * lpLock
947 * Points to a DD_LOCKDATA structure that contains the information required to perform the lockdown.
948 *
949 * Return Value
950 *
951 * DdLock returns one of the following callback codes:
952 *
953 * DDHAL_DRIVER_HANDLED
954 * DDHAL_DRIVER_NOTHANDLED
955 *
956 */
957DWORD APIENTRY DdLock(PDD_LOCKDATA lpLock)
958{
959 PPDEV pDev = (PPDEV)lpLock->lpDD->dhpdev;
960 DD_SURFACE_LOCAL* lpSurfaceLocal = lpLock->lpDDSurface;
961
962 DISPDBG((0, "%s: %p bHasRect = %d fpProcess = %p\n", __FUNCTION__, pDev, lpLock->bHasRect, lpLock->fpProcess));
963
964#ifdef VBOX_WITH_VIDEOHWACCEL
965 if(pDev->vhwaInfo.bVHWAEnabled)
966 {
967 DD_SURFACE_GLOBAL* lpSurfaceGlobal = lpSurfaceLocal->lpGbl;
968 PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC)lpSurfaceGlobal->dwReserved1;
969 VBOXVHWACMD* pCmd;
970 /* ensure we have host cmds processed to update pending blits and flips */
971 vboxVHWACommandCheckHostCmds(pDev);
972
973 // if(VBOXDD_CHECKFLAG(lpLock, DDLOCK_DONOTWAIT))
974 {
975 if(ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc)
976 || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst)
977 || ASMAtomicUoReadU32(&pDesc->cPendingFlips))
978 {
979 lpLock->ddRVal = DDERR_WASSTILLDRAWING;
980 return DDHAL_DRIVER_HANDLED;
981 }
982 }
983
984 if(VBOXDD_CHECKFLAG(lpLock->dwFlags, DDLOCK_SURFACEMEMORYPTR))
985 {
986 lpLock->lpSurfData = (LPVOID)(lpSurfaceGlobal->fpVidMem + lpSurfaceGlobal->lPitch * lpLock->rArea.top
987 + lpLock->rArea.left * pDesc->cBitsPerPixel/8);
988 }
989
990 pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_LOCK, sizeof(VBOXVHWACMD_SURF_LOCK));
991 if(pCmd)
992 {
993 VBOXVHWACMD_SURF_LOCK * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_LOCK);
994 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_LOCK));
995
996 pBody->u.in.offSurface = (uint64_t)lpSurfaceGlobal->fpVidMem;
997
998 if (lpLock->bHasRect)
999 {
1000 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));
1001 vboxVHWAFromRECTL(&pBody->u.in.rect, &lpLock->rArea);
1002 pBody->u.in.rectValid = 1;
1003 }
1004 else
1005 {
1006 pBody->u.in.rectValid = 0;
1007 }
1008
1009 pBody->u.in.hSurf = pDesc->hHostHandle;
1010
1011 if(VBOXDD_CHECKFLAG(lpLock->dwFlags, DDLOCK_DISCARDCONTENTS))
1012 {
1013 pBody->u.in.flags |= VBOXVHWA_LOCK_DISCARDCONTENTS;
1014 /* we're not interested in completion, just send the command */
1015 vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWAFreeCmdCompletion, NULL);
1016 }
1017 else
1018 {
1019 /* wait for the surface to be locked and memory buffer updated */
1020 vboxVHWACommandSubmit(pDev, pCmd);
1021 vboxVHWACommandFree(pDev, pCmd);
1022 }
1023
1024 lpLock->ddRVal = DD_OK;
1025 }
1026 else
1027 {
1028 lpLock->ddRVal = DDERR_GENERIC;
1029 }
1030 return DDHAL_DRIVER_HANDLED;
1031 }
1032#endif
1033 if (lpSurfaceLocal->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
1034 {
1035 /* The updated rectangle must be reported only for the primary surface. */
1036 pDev->ddLock.bLocked = TRUE;
1037
1038 if (lpLock->bHasRect)
1039 {
1040 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));
1041 pDev->ddLock.rArea = lpLock->rArea;
1042 }
1043 else
1044 {
1045 pDev->ddLock.rArea.left = 0;
1046 pDev->ddLock.rArea.top = 0;
1047 pDev->ddLock.rArea.right = pDev->cxScreen;
1048 pDev->ddLock.rArea.bottom = pDev->cyScreen;
1049 }
1050 }
1051 else
1052 {
1053 DISPDBG((0, "%s: secondary surface.\n", __FUNCTION__));
1054 }
1055
1056 // Because we correctly set 'fpVidMem' to be the offset into our frame
1057 // buffer when we created the surface, DirectDraw will automatically take
1058 // care of adding in the user-mode frame buffer address if we return
1059 // DDHAL_DRIVER_NOTHANDLED:
1060 lpLock->ddRVal = DD_OK;
1061 return DDHAL_DRIVER_NOTHANDLED;
1062}
1063
1064/**
1065 * DdUnlock
1066 *
1067 * The DdUnLock callback function releases the lock held on the specified surface.
1068 *
1069 * Parameters
1070 * lpUnlock
1071 * Points to a DD_UNLOCKDATA structure that contains the information required to perform the lock release. *
1072 *
1073 * Return Value
1074 *
1075 * DdLock returns one of the following callback codes:
1076 *
1077 * DDHAL_DRIVER_HANDLED
1078 * DDHAL_DRIVER_NOTHANDLED
1079 *
1080 */
1081DWORD APIENTRY DdUnlock(PDD_UNLOCKDATA lpUnlock)
1082{
1083 PPDEV pDev = (PPDEV)lpUnlock->lpDD->dhpdev;
1084 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
1085#ifdef VBOX_WITH_VIDEOHWACCEL
1086 if (pDev->vhwaInfo.bVHWAEnabled)
1087 {
1088 DD_SURFACE_LOCAL* lpSurfaceLocal = lpUnlock->lpDDSurface;
1089 DD_SURFACE_GLOBAL* lpSurfaceGlobal = lpSurfaceLocal->lpGbl;
1090 PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC)lpSurfaceGlobal->dwReserved1;
1091 VBOXVHWACMD* pCmd;
1092
1093 //TODO: hadle vrdp properly
1094 if ( pDev->pVBVA->u32HostEvents
1095 & VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET)
1096 {
1097 vrdpReset (pDev);
1098
1099 pDev->pVBVA->u32HostEvents &=
1100 ~VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET;
1101 }
1102
1103 /* ensure we have host cmds processed to update pending blits and flips */
1104 vboxVHWACommandCheckHostCmds(pDev);
1105
1106 pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_UNLOCK, sizeof(VBOXVHWACMD_SURF_UNLOCK));
1107 // int rc = VERR_GENERAL_FAILURE;
1108 if(pCmd)
1109 {
1110 VBOXVHWACMD_SURF_UNLOCK * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_UNLOCK);
1111 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_UNLOCK));
1112
1113 pBody->u.in.hSurf = pDesc->hHostHandle;
1114
1115 vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWAFreeCmdCompletion, NULL);
1116
1117 lpUnlock->ddRVal = DD_OK;
1118 }
1119 else
1120 {
1121 lpUnlock->ddRVal = DDERR_GENERIC;
1122 }
1123
1124 return DDHAL_DRIVER_HANDLED;
1125 }
1126#endif
1127 if (pDev->ddLock.bLocked)
1128 {
1129 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));
1130
1131#ifndef VBOX_WITH_HGSMI
1132 if (pDev->pInfo && vboxHwBufferBeginUpdate (pDev))
1133 {
1134 vbvaReportDirtyRect (pDev, &pDev->ddLock.rArea);
1135
1136 if ( pDev->pInfo->hostEvents.fu32Events
1137 & VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET)
1138 {
1139 vrdpReset (pDev);
1140
1141 pDev->pInfo->hostEvents.fu32Events &=
1142 ~VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET;
1143 }
1144
1145 if (pDev->vbva.pVbvaMemory->fu32ModeFlags
1146 & VBVA_F_MODE_VRDP)
1147 {
1148 vrdpReportDirtyRect (pDev, &pDev->ddLock.rArea);
1149 }
1150
1151 vboxHwBufferEndUpdate (pDev);
1152 }
1153#else
1154 if (pDev->bHGSMISupported && vboxHwBufferBeginUpdate (pDev))
1155 {
1156 vbvaReportDirtyRect (pDev, &pDev->ddLock.rArea);
1157
1158 if ( pDev->pVBVA->u32HostEvents
1159 & VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET)
1160 {
1161 vrdpReset (pDev);
1162
1163 pDev->pVBVA->u32HostEvents &=
1164 ~VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET;
1165 }
1166
1167 if (pDev->pVBVA->u32HostEvents
1168 & VBVA_F_MODE_VRDP)
1169 {
1170 vrdpReportDirtyRect (pDev, &pDev->ddLock.rArea);
1171 }
1172
1173 vboxHwBufferEndUpdate (pDev);
1174 }
1175#endif /* VBOX_WITH_HGSMI */
1176
1177 pDev->ddLock.bLocked = FALSE;
1178 }
1179
1180 lpUnlock->ddRVal = DD_OK;
1181 return DDHAL_DRIVER_NOTHANDLED;
1182}
1183
1184/**
1185 * DdDestroySurface
1186 *
1187 * The DdDestroySurface callback function destroys a DirectDraw surface.
1188 *
1189 * Parameters
1190 * lpDestroySurface
1191 * Points to a DD_DESTROYSURFACEDATA structure that contains the information needed to destroy a surface.
1192 *
1193 * Return Value
1194 *
1195 * DdDestroySurface returns one of the following callback codes:
1196 *
1197 * DDHAL_DRIVER_HANDLED
1198 * DDHAL_DRIVER_NOTHANDLED
1199 *
1200 */
1201DWORD APIENTRY DdDestroySurface(PDD_DESTROYSURFACEDATA lpDestroySurface)
1202{
1203#ifdef VBOX_WITH_VIDEOHWACCEL
1204 PPDEV pDev = (PPDEV)lpDestroySurface->lpDD->dhpdev;
1205 if(pDev->vhwaInfo.bVHWAEnabled)
1206 {
1207 DD_SURFACE_LOCAL* lpSurfaceLocal = lpDestroySurface->lpDDSurface;
1208 DD_SURFACE_GLOBAL* lpSurfaceGlobal = lpSurfaceLocal->lpGbl;
1209 VBOXVHWACMD* pCmd;
1210
1211 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
1212
1213 pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_DESTROY, sizeof(VBOXVHWACMD_SURF_DESTROY));
1214 // int rc = VERR_GENERAL_FAILURE;
1215 if(pCmd)
1216 {
1217 VBOXVHWACMD_SURF_DESTROY * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_DESTROY);
1218 PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC)lpSurfaceGlobal->dwReserved1;
1219
1220 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_DESTROY));
1221
1222 pBody->u.in.hSurf = pDesc->hHostHandle;
1223
1224 /* we're not interested in completion, just send the command */
1225 vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWAFreeCmdCompletion, NULL);
1226
1227 vboxVHWASurfDescFree(pDesc);
1228
1229 lpDestroySurface->ddRVal = DD_OK;
1230 }
1231 else
1232 {
1233 lpDestroySurface->ddRVal = DDERR_GENERIC;
1234 }
1235 }
1236 else
1237#endif
1238 lpDestroySurface->ddRVal = DD_OK;
1239 return DDHAL_DRIVER_HANDLED;
1240}
1241
1242
1243//-----------------------------------------------------------------------------
1244//
1245// DdSetExclusiveMode
1246//
1247// This function is called by DirectDraw when we switch from the GDI surface,
1248// to DirectDraw exclusive mode, e.g. to run a game in fullcreen mode.
1249// You only need to implement this function when you are using the
1250// 'HeapVidMemAllocAligned' function and allocate memory for Device Bitmaps
1251// and DirectDraw surfaces from the same heap.
1252//
1253// We use this call to disable GDI DeviceBitMaps when we are running in
1254// DirectDraw exclusive mode. Otherwise a DD app gets confused if both GDI and
1255// DirectDraw allocate memory from the same heap.
1256//
1257// See also DdFlipToGDISurface.
1258//
1259//-----------------------------------------------------------------------------
1260
1261
1262DWORD APIENTRY DdSetExclusiveMode(PDD_SETEXCLUSIVEMODEDATA lpSetExclusiveMode)
1263{
1264 PPDEV pDev = (PPDEV)lpSetExclusiveMode->lpDD->dhpdev;
1265 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
1266
1267 // remember setting of exclusive mode in pDev,
1268 // so GDI can stop to promote DeviceBitmaps into
1269 // video memory
1270
1271 pDev->bDdExclusiveMode = lpSetExclusiveMode->dwEnterExcl;
1272
1273 lpSetExclusiveMode->ddRVal = DD_OK;
1274
1275 return DDHAL_DRIVER_HANDLED;
1276}
1277
1278//-----------------------------------------------------------------------------
1279//
1280// DWORD DdFlipToGDISurface
1281//
1282// This function is called by DirectDraw when it flips to the surface on which
1283// GDI can write to.
1284//
1285//-----------------------------------------------------------------------------
1286
1287DWORD APIENTRY DdFlipToGDISurface(PDD_FLIPTOGDISURFACEDATA lpFlipToGDISurface)
1288{
1289 PPDEV pDev = (PPDEV)lpFlipToGDISurface->lpDD->dhpdev;
1290 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
1291
1292 pDev->dwNewDDSurfaceOffset = 0xffffffff;
1293
1294 lpFlipToGDISurface->ddRVal = DD_OK;
1295
1296 //
1297 // we return NOTHANDLED, then the ddraw runtime takes
1298 // care that we flip back to the primary...
1299 //
1300 return DDHAL_DRIVER_NOTHANDLED;
1301}
1302//-----------------------------------------------------------------------------
1303//
1304// DWORD DdFreeDriverMemory
1305//
1306// This function called by DirectDraw when it's running low on memory in
1307// our heap. You only need to implement this function if you use the
1308// DirectDraw 'HeapVidMemAllocAligned' function in your driver, and you
1309// can boot those allocations out of memory to make room for DirectDraw.
1310//
1311//-----------------------------------------------------------------------------
1312
1313DWORD APIENTRY DdFreeDriverMemory(PDD_FREEDRIVERMEMORYDATA lpFreeDriverMemory)
1314{
1315 PPDEV pDev = (PPDEV)lpFreeDriverMemory->lpDD->dhpdev;
1316 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
1317
1318 lpFreeDriverMemory->ddRVal = DDERR_OUTOFMEMORY;
1319 return DDHAL_DRIVER_HANDLED;
1320}
1321
1322#ifdef VBOX_WITH_VIDEOHWACCEL
1323DWORD APIENTRY DdSetColorKey(PDD_SETCOLORKEYDATA lpSetColorKey)
1324{
1325 DISPDBG((0, "%s\n", __FUNCTION__));
1326 lpSetColorKey->ddRVal = DD_OK;
1327 return DDHAL_DRIVER_HANDLED;
1328}
1329
1330DWORD APIENTRY DdAddAttachedSurface(PDD_ADDATTACHEDSURFACEDATA lpAddAttachedSurface)
1331{
1332 DISPDBG((0, "%s\n", __FUNCTION__));
1333 lpAddAttachedSurface->ddRVal = DD_OK;
1334 return DDHAL_DRIVER_HANDLED;
1335}
1336
1337DWORD APIENTRY DdBlt(PDD_BLTDATA lpBlt)
1338{
1339#ifdef VBOX_WITH_VIDEOHWACCEL
1340 PPDEV pDev = (PPDEV)lpBlt->lpDD->dhpdev;
1341 DISPDBG((0, "%s\n", __FUNCTION__));
1342#if DX9_DDI
1343 if(VBOXDD_CHECKFLAG(lpBlt->dwFlags, DDBLT_EXTENDED_PRESENTATION_STRETCHFACTOR))
1344 {
1345 lpBlt->ddRVal = DD_OK;
1346 }
1347 else
1348#endif
1349 {
1350 DD_SURFACE_LOCAL* lpDestSurfaceLocal = lpBlt->lpDDDestSurface;
1351 DD_SURFACE_GLOBAL* lpDestSurfaceGlobal = lpDestSurfaceLocal->lpGbl;
1352 DD_SURFACE_LOCAL* lpSrcSurfaceLocal = lpBlt->lpDDSrcSurface;
1353 DD_SURFACE_GLOBAL* lpSrcSurfaceGlobal = lpSrcSurfaceLocal->lpGbl;
1354 VBOXVHWACMD* pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_BLT, sizeof(VBOXVHWACMD_SURF_BLT));
1355 // int rc = VERR_GENERAL_FAILURE;
1356 if(pCmd)
1357 {
1358 VBOXVHWACMD_SURF_BLT * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_BLT);
1359 PVBOXVHWASURFDESC pSrcDesc = (PVBOXVHWASURFDESC)lpSrcSurfaceGlobal->dwReserved1;
1360 PVBOXVHWASURFDESC pDestDesc = (PVBOXVHWASURFDESC)lpDestSurfaceGlobal->dwReserved1;
1361 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_BLT));
1362
1363 pBody->u.in.offSrcSurface = (uint64_t)lpSrcSurfaceGlobal->fpVidMem;
1364 pBody->u.in.offDstSurface = (uint64_t)lpDestSurfaceGlobal->fpVidMem;
1365
1366 pBody->u.in.hDstSurf = pDestDesc->hHostHandle;
1367 vboxVHWAFromRECTL(&pBody->u.in.dstRect, &lpBlt->rDest);
1368 pBody->u.in.hSrcSurf = pSrcDesc->hHostHandle;
1369 vboxVHWAFromRECTL(&pBody->u.in.srcRect, &lpBlt->rSrc);
1370 pBody->DstGuestSurfInfo = (uint64_t)pDestDesc;
1371 pBody->SrcGuestSurfInfo = (uint64_t)pSrcDesc;
1372
1373 ASMAtomicIncU32(&pSrcDesc->cPendingBltsSrc);
1374 ASMAtomicIncU32(&pDestDesc->cPendingBltsDst);
1375
1376// if(VBOXDD_CHECKFLAG(lpBlt->dwFlags, DDBLT_ASYNC))
1377// {
1378 vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWASurfBltCompletion, NULL);
1379// }
1380// else
1381// {
1382// vboxVHWACommandSubmit(pDev, pCmd);
1383// }
1384 lpBlt->ddRVal = DD_OK;
1385 }
1386 else
1387 {
1388 lpBlt->ddRVal = DDERR_GENERIC;
1389 }
1390 }
1391
1392 return DDHAL_DRIVER_HANDLED;
1393#else
1394 lpBlt->ddRVal = DDERR_GENERIC;
1395 return DDHAL_DRIVER_NOTHANDLED;
1396#endif
1397}
1398
1399//DWORD APIENTRY DdDestroySurface(PDD_DESTROYSURFACEDATA lpDestroySurface)
1400//{
1401// DISPDBG((0, "%s\n", __FUNCTION__));
1402// lpDestroySurface->ddRVal = DD_OK;
1403// return DDHAL_DRIVER_HANDLED;
1404//}
1405
1406DWORD APIENTRY DdFlip(PDD_FLIPDATA lpFlip)
1407{
1408 DISPDBG((0, "%s\n", __FUNCTION__));
1409 lpFlip->ddRVal = DD_OK;
1410 return DDHAL_DRIVER_HANDLED;
1411}
1412
1413DWORD APIENTRY DdGetBltStatus(PDD_GETBLTSTATUSDATA lpGetBltStatus)
1414{
1415 DISPDBG((0, "%s\n", __FUNCTION__));
1416
1417 if(lpGetBltStatus->dwFlags == DDGBS_CANBLT)
1418 {
1419 lpGetBltStatus->ddRVal = DD_OK;
1420 }
1421 else
1422 {
1423 lpGetBltStatus->ddRVal = DD_OK;
1424 }
1425
1426 return DDHAL_DRIVER_HANDLED;
1427}
1428
1429DWORD APIENTRY DdGetFlipStatus(PDD_GETFLIPSTATUSDATA lpGetFlipStatus)
1430{
1431 DISPDBG((0, "%s\n", __FUNCTION__));
1432 if(lpGetFlipStatus->dwFlags == DDGFS_CANFLIP)
1433 {
1434 lpGetFlipStatus->ddRVal = DD_OK;
1435 }
1436 else
1437 {
1438 lpGetFlipStatus->ddRVal = DD_OK;
1439 }
1440
1441 return DDHAL_DRIVER_HANDLED;
1442}
1443
1444DWORD APIENTRY DdSetOverlayPosition(PDD_SETOVERLAYPOSITIONDATA lpSetOverlayPosition)
1445{
1446 DISPDBG((0, "%s\n", __FUNCTION__));
1447
1448 lpSetOverlayPosition->ddRVal = DD_OK;
1449 return DDHAL_DRIVER_HANDLED;
1450}
1451
1452DWORD APIENTRY DdUpdateOverlay(PDD_UPDATEOVERLAYDATA lpUpdateOverlay)
1453{
1454 DISPDBG((0, "%s\n", __FUNCTION__));
1455
1456 lpUpdateOverlay->ddRVal = DD_OK;
1457 return DDHAL_DRIVER_HANDLED;
1458}
1459
1460//-----------------------------------------------------------------------------
1461// setupRops
1462//
1463// Build array for supported ROPS
1464//-----------------------------------------------------------------------------
1465static void
1466setupRops(
1467 LPBYTE proplist,
1468 LPDWORD proptable,
1469 int cnt )
1470{
1471 int i;
1472 DWORD idx;
1473 DWORD bit;
1474 DWORD rop;
1475
1476 for(i=0; i<cnt; i++)
1477 {
1478 rop = proplist[i];
1479 idx = rop / 32;
1480 bit = 1L << ((DWORD)(rop % 32));
1481 proptable[idx] |= bit;
1482 }
1483
1484} // setupRops
1485
1486//-----------------------------------------------------------------------------
1487//
1488// Function: __GetDDHALInfo
1489//
1490// Returns: void
1491//
1492// Description:
1493//
1494// Takes a pointer to a partially or fully filled in pThisDisplay and a pointer
1495// to an empty DDHALINFO and fills in the DDHALINFO. This eases porting to NT
1496// and means that caps changes are done in only one place. The pThisDisplay
1497// may not be fully constructed here, so you should only:
1498// a) Query the registry
1499// b) DISPDBG
1500// If you need to add anything to pThisDisplay for NT, you should fill it in
1501// during the DrvGetDirectDraw call.
1502//
1503// The problem here is when the code is run on NT. If there was any other way...
1504//
1505// The following caps have been found to cause NT to bail....
1506// DDCAPS_GDI, DDFXCAPS_BLTMIRRORUPDOWN, DDFXCAPS_BLTMIRRORLEFTRIGHT
1507//
1508//
1509//-----------------------------------------------------------------------------
1510
1511//
1512// use bits to indicate which ROPs you support.
1513//
1514// DWORD 0, bit 0 == ROP 0
1515// DWORD 8, bit 31 == ROP 255
1516//
1517
1518//static DWORD ropsAGP[DD_ROP_SPACE] = { 0 };
1519static BYTE ropListNT[] =
1520{
1521 SRCCOPY >> 16
1522// WHITENESS >> 16,
1523// BLACKNESS >> 16
1524};
1525
1526static DWORD rops[DD_ROP_SPACE] = { 0 };
1527
1528static bool
1529getDDHALInfo(
1530 PPDEV pDev,
1531 DD_HALINFO* pHALInfo)
1532{
1533 int i;
1534 if(!VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLT) && !VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_OVERLAY))
1535 return false;
1536
1537 if(VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLT))
1538 {
1539 // Setup the ROPS we do.
1540 //TODO: hardcoded for now
1541 setupRops( ropListNT,
1542 rops,
1543 sizeof(ropListNT)/sizeof(ropListNT[0]));
1544
1545 // The most basic DirectDraw functionality
1546 pHALInfo->ddCaps.dwCaps |= DDCAPS_BLT
1547 | DDCAPS_BLTQUEUE;
1548 if(VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLTCOLORFILL))
1549 {
1550 pHALInfo->ddCaps.dwCaps |= DDCAPS_BLTCOLORFILL;
1551 }
1552 }
1553
1554// | DDCAPS_READSCANLINE
1555
1556
1557 pHALInfo->ddCaps.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN
1558 | DDSCAPS_PRIMARYSURFACE;
1559 if(pDev->vhwaInfo.surfaceCaps & VBOXVHWA_SCAPS_FLIP)
1560 {
1561 pHALInfo->ddCaps.ddsCaps.dwCaps |= DDSCAPS_FLIP;
1562 }
1563//disabled
1564// pHALInfo->ddCaps.dwCaps |= DDCAPS_3D |
1565// DDCAPS_BLTDEPTHFILL;
1566//
1567// pHALInfo->ddCaps.ddsCaps.dwCaps |= DDSCAPS_3DDEVICE |
1568// DDSCAPS_ZBUFFER |
1569// DDSCAPS_ALPHA;
1570 pHALInfo->ddCaps.dwCaps2 = 0;
1571
1572//#if DX7_TEXMANAGEMENT
1573 // We need to set this bit up in order to be able to do
1574 // out own texture management
1575// pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_CANMANAGETEXTURE;
1576//#if DX8_DDI
1577// pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_CANMANAGERESOURCE;
1578//#endif
1579//#endif
1580
1581//#if DX8_DDI
1582 // We need to flag we can run in windowed mode, otherwise we
1583 // might get restricted by apps to run in fullscreen only
1584 pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_CANRENDERWINDOWED;
1585//#endif
1586
1587//#if DX8_DDI
1588 // We need to flag we support dynamic textures. That is , apps can
1589 // lock with high frequency video memory textures without paying a
1590 // penalty for it. Since on this sample driver we only support
1591 // linear memory formats for textures we don't need to do anything
1592 // else for this support. Otherwise we would have to keep two surfaces
1593 // for textures created with the DDSCAPS2_HINTDYNAMIC hint in order
1594 // to efficiently do the linear<->swizzled transformation or keep the
1595 // texture permanantly in an unswizzled state.
1596// pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_DYNAMICTEXTURES;
1597 #if DX9_DDI
1598 // Notice that dynamic textures MUST be supported in order to instantiate a DX9 device
1599 #endif // DX9_DDI
1600//#endif
1601
1602// pHALInfo->ddCaps.dwFXCaps = 0;
1603
1604 // P3RX can do:
1605 // 1. Stretching/Shrinking
1606 // 2. YUV->RGB conversion
1607 // 3. Mirroring in X and Y
1608 // 4. ColorKeying from a source color and a source color space
1609 if(VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLT)
1610 && VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLTSTRETCH))
1611 {
1612 pHALInfo->ddCaps.dwCaps |= DDCAPS_BLTSTRETCH;
1613
1614 // Special effects caps
1615 //TODO: filter them out
1616 pHALInfo->ddCaps.dwFXCaps |= DDFXCAPS_BLTSTRETCHY |
1617 DDFXCAPS_BLTSTRETCHX |
1618 DDFXCAPS_BLTSTRETCHYN |
1619 DDFXCAPS_BLTSTRETCHXN |
1620 DDFXCAPS_BLTSHRINKY |
1621 DDFXCAPS_BLTSHRINKX |
1622 DDFXCAPS_BLTSHRINKYN |
1623 DDFXCAPS_BLTSHRINKXN;
1624
1625
1626 //mirroring with blitting
1627 pHALInfo->ddCaps.dwFXCaps |= DDFXCAPS_BLTMIRRORUPDOWN
1628 | DDFXCAPS_BLTMIRRORLEFTRIGHT;
1629
1630 }
1631
1632 if(VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLT)
1633 && VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLTFOURCC))
1634 {
1635 pHALInfo->ddCaps.dwCaps |= DDCAPS_BLTFOURCC;
1636
1637 // Enable copy blts between Four CC formats for DShow acceleration
1638 pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_COPYFOURCC;
1639 }
1640
1641 if(VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLT)
1642 && VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_COLORKEY))
1643 {
1644 pHALInfo->ddCaps.dwCaps |= DDCAPS_COLORKEY;
1645// | DDCAPS_CANBLTSYSMEM
1646
1647 // ColorKey caps
1648 //TODO: filter them out
1649 pHALInfo->ddCaps.dwCKeyCaps |= DDCKEYCAPS_SRCBLT |
1650 DDCKEYCAPS_SRCBLTCLRSPACE |
1651 DDCKEYCAPS_DESTBLT |
1652 DDCKEYCAPS_DESTBLTCLRSPACE;
1653
1654 pHALInfo->ddCaps.dwCKeyCaps |= DDCKEYCAPS_SRCBLTCLRSPACEYUV
1655 | DDCKEYCAPS_DESTBLTCLRSPACEYUV;
1656
1657#if 0
1658 DDCKEYCAPS_DESTBLT Supports transparent blitting with a color key that identifies the replaceable bits of the destination surface for RGB colors.
1659 DDCKEYCAPS_DESTBLTCLRSPACE Supports transparent blitting with a color space that identifies the replaceable bits of the destination surface for RGB colors.
1660 DDCKEYCAPS_DESTBLTCLRSPACEYUV Supports transparent blitting with a color space that identifies the replaceable bits of the destination surface for YUV colors.
1661 DDCKEYCAPS_DESTBLTYUV Supports transparent blitting with a color key that identifies the replaceable bits of the destination surface for YUV colors.
1662
1663 DDCKEYCAPS_SRCBLT Supports transparent blitting using the color key for the source with this surface for RGB colors.
1664 DDCKEYCAPS_SRCBLTCLRSPACE Supports transparent blitting using a color space for the source with this surface for RGB colors.
1665 DDCKEYCAPS_SRCBLTCLRSPACEYUV Supports transparent blitting using a color space for the source with this surface for YUV colors.
1666 DDCKEYCAPS_SRCBLTYUV Supports transparent blitting using the color key for the source with this surface for YUV colors.
1667#endif
1668
1669 }
1670
1671 if(VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_OVERLAY)
1672 && VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_COLORKEY))
1673 {
1674#if 0
1675 DDCKEYCAPS_DESTOVERLAY Supports overlaying with color keying of the replaceable bits of the destination surface being overlaid for RGB colors.
1676 DDCKEYCAPS_DESTOVERLAYCLRSPACE Supports a color space as the color key for the destination of RGB colors.
1677 DDCKEYCAPS_DESTOVERLAYCLRSPACEYUV Supports a color space as the color key for the destination of YUV colors.
1678 DDCKEYCAPS_DESTOVERLAYONEACTIVE Supports only one active destination color key value for visible overlay surfaces.
1679 DDCKEYCAPS_DESTOVERLAYYUV Supports overlaying using color keying of the replaceable bits of the destination surface being overlaid for YUV colors.
1680 DDCKEYCAPS_NOCOSTOVERLAY Indicates that there are no bandwidth tradeoffs for using the color key with an overlay.
1681
1682 DDCKEYCAPS_SRCOVERLAY Supports overlaying using the color key for the source with this overlay surface for RGB colors.
1683 DDCKEYCAPS_SRCOVERLAYCLRSPACE Supports overlaying using a color space as the source color key for the overlay surface for RGB colors.
1684 DDCKEYCAPS_SRCOVERLAYCLRSPACEYUV Supports overlaying using a color space as the source color key for the overlay surface for YUV colors.
1685 DDCKEYCAPS_SRCOVERLAYONEACTIVE Supports only one active source color key value for visible overlay surfaces.
1686 DDCKEYCAPS_SRCOVERLAYYUV Supports overlaying using the color key for the source with this overlay surface for YUV colors.
1687#endif
1688 }
1689// pHALInfo->ddCaps.dwSVBCaps = DDCAPS_BLT;
1690
1691// // We can do a texture from sysmem to video mem.
1692// pHALInfo->ddCaps.dwSVBCKeyCaps |= DDCKEYCAPS_DESTBLT |
1693// DDCKEYCAPS_DESTBLTCLRSPACE;
1694 pHALInfo->ddCaps.dwSVBFXCaps = 0;
1695
1696// // Fill in the sysmem->vidmem rops (only can copy);
1697// for( i=0;i<DD_ROP_SPACE;i++ )
1698// {
1699// pHALInfo->ddCaps.dwSVBRops[i] = rops[i];
1700// }
1701
1702
1703
1704//disabled
1705// pHALInfo->ddCaps.ddsCaps.dwCaps |= DDSCAPS_TEXTURE;
1706
1707//#if DX7_STEREO
1708// // Report the stereo capability back to runtime
1709// pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_STEREO;
1710// pHALInfo->ddCaps.dwSVCaps = DDSVCAPS_STEREOSEQUENTIAL;
1711//#endif
1712
1713 // Z Buffer is only 16 Bits
1714// pHALInfo->ddCaps.dwZBufferBitDepths = DDBD_16;
1715// pHALInfo->ddCaps.ddsCaps.dwCaps |= DDSCAPS_MIPMAP;
1716
1717 pHALInfo->ddCaps.ddsCaps.dwCaps |= DDSCAPS_LOCALVIDMEM;
1718
1719 {
1720//#ifdef SUPPORT_VIDEOPORT
1721// // We support 1 video port. Must set CurrVideoPorts to 0
1722// // We can't do interleaved bobbing yet - maybe in the future.
1723// pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_VIDEOPORT |
1724// DDCAPS2_CANBOBNONINTERLEAVED;
1725//
1726// pHALInfo->ddCaps.dwMaxVideoPorts = 1;
1727// pHALInfo->ddCaps.dwCurrVideoPorts = 0;
1728//
1729//
1730//#endif // SUPPORT_VIDEOPORT
1731
1732 if(VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_OVERLAY)) /* no overlay support for now */
1733 {
1734 // Overlay is free to use.
1735 pHALInfo->ddCaps.dwMaxVisibleOverlays = pDev->vhwaInfo.numOverlays;
1736 pHALInfo->ddCaps.dwCurrVisibleOverlays = 0;
1737
1738 pHALInfo->ddCaps.dwCaps |= DDCAPS_OVERLAY |
1739 DDCAPS_OVERLAYFOURCC |
1740 DDCAPS_OVERLAYSTRETCH |
1741 DDCAPS_COLORKEYHWASSIST |
1742 DDCAPS_OVERLAYCANTCLIP;
1743
1744 pHALInfo->ddCaps.dwCKeyCaps |= DDCKEYCAPS_SRCOVERLAY |
1745 DDCKEYCAPS_SRCOVERLAYONEACTIVE |
1746 DDCKEYCAPS_SRCOVERLAYYUV |
1747 DDCKEYCAPS_DESTOVERLAY |
1748 DDCKEYCAPS_DESTOVERLAYONEACTIVE |
1749 DDCKEYCAPS_DESTOVERLAYYUV;
1750
1751 pHALInfo->ddCaps.ddsCaps.dwCaps |= DDSCAPS_OVERLAY;
1752
1753 pHALInfo->ddCaps.dwFXCaps |= DDFXCAPS_OVERLAYSHRINKX |
1754 DDFXCAPS_OVERLAYSHRINKXN |
1755 DDFXCAPS_OVERLAYSHRINKY |
1756 DDFXCAPS_OVERLAYSHRINKYN |
1757 DDFXCAPS_OVERLAYSTRETCHX |
1758 DDFXCAPS_OVERLAYSTRETCHXN |
1759 DDFXCAPS_OVERLAYSTRETCHY |
1760 DDFXCAPS_OVERLAYSTRETCHYN;
1761
1762 // Indicates that Perm3 has no stretch ratio limitation
1763 pHALInfo->ddCaps.dwMinOverlayStretch = 1;
1764 pHALInfo->ddCaps.dwMaxOverlayStretch = 32000;
1765 }
1766 }
1767
1768//#ifdef W95_DDRAW
1769//#ifdef USE_DD_CONTROL_COLOR
1770// // Enable colour control asc brightness, contrast, gamma.
1771// pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_COLORCONTROLPRIMARY;
1772//#endif
1773//#endif
1774
1775 // Also permit surfaces wider than the display buffer.
1776 pHALInfo->ddCaps.dwCaps2 |= DDCAPS2_WIDESURFACES;
1777
1778
1779 // Won't do Video-Sys mem Blits.
1780 pHALInfo->ddCaps.dwVSBCaps = 0;
1781 pHALInfo->ddCaps.dwVSBCKeyCaps = 0;
1782 pHALInfo->ddCaps.dwVSBFXCaps = 0;
1783 for( i=0;i<DD_ROP_SPACE;i++ )
1784 {
1785 pHALInfo->ddCaps.dwVSBRops[i] = 0;
1786 }
1787
1788 // Won't do Sys-Sys mem Blits
1789 pHALInfo->ddCaps.dwSSBCaps = 0;
1790 pHALInfo->ddCaps.dwSSBCKeyCaps = 0;
1791 pHALInfo->ddCaps.dwSSBFXCaps = 0;
1792 for( i=0;i<DD_ROP_SPACE;i++ )
1793 {
1794 pHALInfo->ddCaps.dwSSBRops[i] = 0;
1795 }
1796
1797 //
1798 // bit depths supported for alpha and Z
1799 //
1800// pHALInfo->ddCaps.dwAlphaBltConstBitDepths = DDBD_2 |
1801// DDBD_4 |
1802// DDBD_8;
1803//
1804// pHALInfo->ddCaps.dwAlphaBltPixelBitDepths = DDBD_1 |
1805// DDBD_8;
1806// pHALInfo->ddCaps.dwAlphaBltSurfaceBitDepths = DDBD_1 |
1807// DDBD_2 |
1808// DDBD_4 |
1809// DDBD_8;
1810
1811//disabled
1812// // No alpha blending for overlays, so I'm not sure what these should be.
1813// // Because we support 32bpp overlays, it's just that you can't use the
1814// // alpha bits for blending. Pass.
1815// pHALInfo->ddCaps.dwAlphaBltConstBitDepths = DDBD_2 |
1816// DDBD_4 |
1817// DDBD_8;
1818//
1819// pHALInfo->ddCaps.dwAlphaBltPixelBitDepths = DDBD_1 |
1820// DDBD_8;
1821//
1822// pHALInfo->ddCaps.dwAlphaBltSurfaceBitDepths = DDBD_1 |
1823// DDBD_2 |
1824// DDBD_4 |
1825// DDBD_8;
1826
1827 //
1828 // ROPS supported
1829 //
1830 for( i=0;i<DD_ROP_SPACE;i++ )
1831 {
1832 pHALInfo->ddCaps.dwRops[i] = rops[i];
1833 }
1834
1835//Reenable: // For DX5 and beyond we support this new informational callback.
1836// pHALInfo->GetDriverInfo = DdGetDriverInfo;
1837// pHALInfo->dwFlags |= DDHALINFO_GETDRIVERINFOSET;
1838//
1839//#if DX8_DDI
1840// // Flag our support for a new class of GUIDs that may come through
1841// // GetDriverInfo for DX8 drivers. (This support will be compulsory)
1842// pHALInfo->dwFlags |= DDHALINFO_GETDRIVERINFO2;
1843//#endif DX8_DDI
1844
1845 return true;
1846} // getDDHALInfo
1847
1848static DECLCALLBACK(void) vboxVHWAFreeCmdCompletion(PPDEV ppdev, VBOXVHWACMD * pCmd, void * pContext)
1849{
1850 vboxVHWACommandFree(ppdev, pCmd);
1851}
1852
1853static DECLCALLBACK(void) vboxVHWASurfBltCompletion(PPDEV ppdev, VBOXVHWACMD * pCmd, void * pContext)
1854{
1855 VBOXVHWACMD_SURF_BLT * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_BLT);
1856 PVBOXVHWASURFDESC pSrcDesc = (PVBOXVHWASURFDESC)pBody->SrcGuestSurfInfo;
1857 PVBOXVHWASURFDESC pDestDesc = (PVBOXVHWASURFDESC)pBody->DstGuestSurfInfo;
1858
1859 ASMAtomicDecU32(&pSrcDesc->cPendingBltsSrc);
1860 ASMAtomicDecU32(&pDestDesc->cPendingBltsDst);
1861
1862 vboxVHWACommandFree(ppdev, pCmd);
1863}
1864
1865#endif
1866
1867
1868
1869#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