VirtualBox

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

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

video hw accel: perf improvements: 1.YV12 stored as BGRA, 2.PBO used for overlays; bug-fixes

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