VirtualBox

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

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

HGSMI/VBVA: enable VRDP commands only if there are connected RDP clients.

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