VirtualBox

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

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

Video Hw Accel: debugging & better color support (still debugging & perf enhancements needed)

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