VirtualBox

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

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

video hw accel: DdLock fix

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette