VirtualBox

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

Last change on this file since 34438 was 34438, checked in by vboxsync, 14 years ago

VBoxVideoGuest.h, VMMDev.h, Additions/WINNT/Graphics: refactoring of the display driver to make the VBVA infrastructure and modesetting functions OS-independent

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 70.8 KB
Line 
1#ifdef VBOX_WITH_DDRAW
2
3/******************************Module*Header**********************************\
4*
5 * Copyright (C) 2006-2007 Oracle Corporation
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/*
16* Based in part on Microsoft DDK sample code
17*
18* **************************
19* * DirectDraw SAMPLE CODE *
20* **************************
21*
22* Module Name: ddenable.c
23*
24* Content:
25*
26* Copyright (c) 1994-1998 3Dlabs Inc. Ltd. All rights reserved.
27* Copyright (c) 1995-1999 Microsoft Corporation. All rights reserved.
28\*****************************************************************************/
29
30#include "driver.h"
31#include "dd.h"
32#undef CO_E_NOTINITIALIZED
33#include <winerror.h>
34
35#if 0
36static DWORD APIENTRY DdCreateSurface(PDD_CREATESURFACEDATA lpCreateSurface);
37#endif
38
39#ifdef VBOX_WITH_VIDEOHWACCEL
40#include <iprt/asm.h>
41
42#define VBOXVHWA_CAP(_pdev, _cap) ((_pdev)->vhwaInfo.caps & (_cap))
43static bool getDDHALInfo(PPDEV pDev, DD_HALINFO* pHALInfo);
44static DECLCALLBACK(void) vboxVHWASurfBltCompletion(PPDEV ppdev, VBOXVHWACMD * pCmd, void * pContext);
45static DECLCALLBACK(void) vboxVHWASurfFlipCompletion(PPDEV ppdev, VBOXVHWACMD * pCmd, void * pContext);
46
47//#define DBG_DDSTUBS 1
48#endif
49
50/**
51 * DrvGetDirectDrawInfo
52 *
53 * The DrvGetDirectDrawInfo function returns the capabilities of the graphics hardware.
54 *
55 * Parameters:
56 *
57 * dhpdev
58 * Handle to the PDEV returned by the driver’s DrvEnablePDEV routine.
59 * pHalInfo
60 * Points to a DD_HALINFO structure in which the driver should return the hardware capabilities that it supports.
61 * pdwNumHeaps
62 * Points to the location in which the driver should return the number of VIDEOMEMORY structures pointed to by pvmList.
63 * pvmList
64 * 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.
65 * pdwNumFourCCCodes
66 * Points to the location in which the driver should return the number of DWORDs pointed to by pdwFourCC.
67 * pdwFourCC
68 * 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.
69 *
70 * Return Value:
71 *
72 * DrvGetDirectDrawInfo returns TRUE if it succeeds; otherwise, it returns FALSE.
73 *
74 */
75
76DD_HALINFO g_h2;
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 memset(pHalInfo, 0, sizeof(DD_HALINFO));
107 pHalInfo->dwSize = sizeof(DD_HALINFO);
108
109 vboxVHWAInitHostInfo1(pDev);
110#else
111 memset(&pHalInfo->ddCaps, 0, sizeof(DDNTCORECAPS));
112#endif
113
114 pHalInfo->ddCaps.dwSize = sizeof(DDNTCORECAPS);
115 pHalInfo->ddCaps.dwVidMemTotal = pDev->layout.cbDDRAWHeap;
116 pHalInfo->ddCaps.dwVidMemFree = pHalInfo->ddCaps.dwVidMemTotal;
117
118 pHalInfo->ddCaps.dwCaps = 0;
119 pHalInfo->ddCaps.dwCaps2 = 0;
120
121 /* Declare we can handle textures wider than the primary */
122 pHalInfo->ddCaps.dwCaps2 |= DDCAPS2_WIDESURFACES;
123
124 pHalInfo->ddCaps.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
125
126 /* Create primary surface attributes */
127 pHalInfo->vmiData.pvPrimary = pDev->pjScreen;
128 pHalInfo->vmiData.fpPrimary = 0;
129 pHalInfo->vmiData.dwDisplayWidth = pDev->cxScreen;
130 pHalInfo->vmiData.dwDisplayHeight = pDev->cyScreen;
131 pHalInfo->vmiData.lDisplayPitch = pDev->lDeltaScreen;
132
133 pHalInfo->vmiData.ddpfDisplay.dwSize = sizeof(DDPIXELFORMAT);
134 pHalInfo->vmiData.ddpfDisplay.dwFlags = DDPF_RGB;
135 pHalInfo->vmiData.ddpfDisplay.dwRGBBitCount = pDev->ulBitCount;
136 DISPDBG((0, "pvPrimary %x\n", pHalInfo->vmiData.pvPrimary));
137 DISPDBG((0, "fpPrimary %x\n", pHalInfo->vmiData.fpPrimary));
138 DISPDBG((0, "dwDisplayWidth %d\n", pHalInfo->vmiData.dwDisplayWidth));
139 DISPDBG((0, "dwDisplayHeight %d\n", pHalInfo->vmiData.dwDisplayHeight));
140 DISPDBG((0, "lDisplayPitch %d\n", pHalInfo->vmiData.lDisplayPitch));
141 DISPDBG((0, "dwRGBBitCount %d\n", pHalInfo->vmiData.ddpfDisplay.dwRGBBitCount));
142
143 if (pDev->ulBitmapType == BMF_8BPP)
144 {
145 pHalInfo->vmiData.ddpfDisplay.dwFlags |= DDPF_PALETTEINDEXED8;
146 DISPDBG((0, "DDPF_PALETTEINDEXED8\n"));
147 }
148
149 pHalInfo->vmiData.ddpfDisplay.dwRBitMask = pDev->flRed;
150 pHalInfo->vmiData.ddpfDisplay.dwGBitMask = pDev->flGreen;
151 pHalInfo->vmiData.ddpfDisplay.dwBBitMask = pDev->flBlue;
152
153 pHalInfo->vmiData.dwOffscreenAlign = 4;
154 pHalInfo->vmiData.dwZBufferAlign = 4;
155 pHalInfo->vmiData.dwTextureAlign = 4;
156
157
158#ifdef VBOX_WITH_VIDEOHWACCEL
159 if(pDev->vhwaInfo.bVHWAEnabled)
160 {
161 pHalInfo->vmiData.dwOverlayAlign = 4;
162
163 pDev->vhwaInfo.bVHWAEnabled = getDDHALInfo(pDev, pHalInfo);
164 }
165#endif
166 }
167
168 cHeaps = 0;
169
170 /* Do we have sufficient videomemory to create an off-screen heap for DDraw? */
171 if (pDev->layout.cbDDRAWHeap > 0)
172 {
173 bDefineDDrawHeap = TRUE;
174 cHeaps++;
175 }
176
177 pDev->cHeaps = cHeaps;
178 *pdwNumHeaps = cHeaps;
179
180 // If pvmList is not NULL then we can go ahead and fill out the VIDEOMEMORY
181 // structures which define our requested heaps.
182
183 if(pvmList) {
184
185 pVm=pvmList;
186
187 //
188 // Snag a pointer to the video-memory list so that we can use it to
189 // call back to DirectDraw to allocate video memory:
190 //
191 pDev->pvmList = pVm;
192
193 //
194 // Define the heap for DirectDraw
195 //
196 if ( bDefineDDrawHeap )
197 {
198 pVm->dwFlags = VIDMEM_ISLINEAR ;
199 pVm->fpStart = pDev->layout.offDDRAWHeap;
200 pVm->fpEnd = pDev->layout.offDDRAWHeap + pDev->layout.cbDDRAWHeap - 1; /* inclusive */
201#ifdef VBOX_WITH_VIDEOHWACCEL
202 if(pDev->vhwaInfo.bVHWAEnabled)
203 {
204 pVm->ddsCaps.dwCaps = 0;
205 pVm->ddsCapsAlt.dwCaps = 0;
206 }
207 else
208#endif
209 {
210 pVm->ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
211 }
212 DISPDBG((0, "fpStart %x fpEnd %x\n", pVm->fpStart, pVm->fpEnd));
213
214 pVm++;
215 }
216 }
217
218#ifdef VBOX_WITH_VIDEOHWACCEL
219 if(pDev->vhwaInfo.bVHWAEnabled)
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 //
618 // Modify surface descriptions as appropriate and let Direct
619 // Draw perform the allocation if the surface was not the primary
620 //
621 if (lpSurfaceLocal->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
622 {
623 DISPDBG((0, "-> primary surface\n"));
624 lpSurfaceGlobal->fpVidMem = 0;
625 }
626 else
627 {
628 DISPDBG((0, "-> secondary surface\n"));
629 lpSurfaceGlobal->fpVidMem = DDHAL_PLEASEALLOC_BLOCKSIZE;
630 }
631
632 pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_CREATE, sizeof(VBOXVHWACMD_SURF_CREATE));
633 if(pCmd)
634 {
635 VBOXVHWACMD_SURF_CREATE * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_CREATE);
636 PVBOXVHWASURFDESC pDesc;
637 int rc;
638
639 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_CREATE));
640
641 rc = vboxVHWAFromDDSURFACEDESC(&pBody->SurfInfo, lpSurfaceDesc);
642
643 pBody->SurfInfo.surfCaps = vboxVHWAFromDDSCAPS(lpSurfaceLocal->ddsCaps.dwCaps);
644 pBody->SurfInfo.flags |= DDSD_CAPS;
645
646 pBody->SurfInfo.height = lpSurfaceGlobal->wHeight;
647 pBody->SurfInfo.width = lpSurfaceGlobal->wWidth;
648 pBody->SurfInfo.flags |= DDSD_HEIGHT | DDSD_WIDTH;
649
650 vboxVHWAFromDDPIXELFORMAT(&pBody->SurfInfo.PixelFormat, pFormat);
651 pBody->SurfInfo.flags |= VBOXVHWA_SD_PIXELFORMAT;
652
653 if (lpSurfaceLocal->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
654 {
655 pBody->SurfInfo.offSurface = vboxVHWAVramOffsetFromPDEV(pDev, 0);
656 }
657 else
658 {
659 pBody->SurfInfo.offSurface = VBOXVHWA_OFFSET64_VOID;
660 }
661
662
663 pDesc = vboxVHWASurfDescAlloc();
664 if(pDesc)
665 {
666 vboxVHWACommandSubmit(pDev, pCmd);
667 Assert(pCmd->rc == VINF_SUCCESS);
668 if(pCmd->rc == VINF_SUCCESS)
669 {
670 uint32_t surfSizeX = pBody->SurfInfo.sizeX;
671 uint32_t surfSizeY = pBody->SurfInfo.sizeY;
672 pDesc->hHostHandle = pBody->SurfInfo.hSurf;
673 if(!!(lpSurfaceLocal->ddsCaps.dwCaps & DDSCAPS_OVERLAY)
674 && !!(lpSurfaceLocal->ddsCaps.dwCaps & DDSCAPS_VISIBLE))
675 {
676 pDesc->bVisible = true;
677 }
678 lpSurfaceGlobal->dwReserved1 = (ULONG_PTR)pDesc;
679 lPitch = pBody->SurfInfo.pitch;
680// lBpp = pBody->SurfInfo.bitsPerPixel;
681// pDesc->cBitsPerPixel = lBpp;
682#if 0
683 lpSurfaceGlobal->dwBlockSizeX = lPitch;
684 lpSurfaceGlobal->dwBlockSizeY = lpSurfaceGlobal->wHeight;
685 lpSurfaceGlobal->lPitch = lPitch;
686#else
687 lpSurfaceGlobal->dwBlockSizeX = surfSizeX;
688 lpSurfaceGlobal->dwBlockSizeY = surfSizeY;
689 lpSurfaceGlobal->lPitch = lPitch;
690#endif
691#if 1
692 lpSurfaceDesc->lPitch = lpSurfaceGlobal->lPitch;
693 lpSurfaceDesc->dwFlags |= DDSD_PITCH;
694#endif
695
696 lpCreateSurface->ddRVal = DD_OK;
697 }
698 else
699 {
700 vboxVHWASurfDescFree(pDesc);
701 lpCreateSurface->ddRVal = DDERR_GENERIC;
702 }
703 }
704 vbvaVHWACommandRelease(pDev, pCmd);
705 }
706 return DDHAL_DRIVER_NOTHANDLED;
707 }
708#endif
709 lpSurfaceGlobal->dwReserved1 = 0;
710
711 if (lpSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED4)
712 {
713 lBpp = 4;
714 lPitch = lpSurfaceGlobal->wWidth/2;
715 lPitch = (lPitch + 31) & ~31;
716 }
717 else
718 if (lpSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8)
719 {
720 lBpp = 8;
721 lPitch = lpSurfaceGlobal->wWidth;
722 lPitch = (lPitch + 31) & ~31;
723 }
724 else
725 {
726 lBpp = lpSurfaceDesc->ddpfPixelFormat.dwRGBBitCount;
727 lPitch = lpSurfaceGlobal->wWidth*(lBpp/8);
728 }
729 DISPDBG((0, "New surface (%d,%d)\n", lpSurfaceGlobal->wWidth, lpSurfaceGlobal->wHeight));
730 DISPDBG((0, "BPP %d lPitch=%d\n", lBpp, lPitch));
731
732 lpSurfaceGlobal->dwBlockSizeX = lPitch;
733 lpSurfaceGlobal->dwBlockSizeY = lpSurfaceGlobal->wHeight;
734 lpSurfaceGlobal->lPitch = lPitch;
735
736 lpSurfaceDesc->lPitch = lpSurfaceGlobal->lPitch;
737 lpSurfaceDesc->dwFlags |= DDSD_PITCH;
738
739 //
740 // Modify surface descriptions as appropriate and let Direct
741 // Draw perform the allocation if the surface was not the primary
742 //
743 if (lpSurfaceLocal->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
744 {
745 DISPDBG((0, "-> primary surface\n"));
746 lpSurfaceGlobal->fpVidMem = 0;
747 }
748 else
749 {
750 DISPDBG((0, "-> secondary surface\n"));
751 lpSurfaceGlobal->fpVidMem = DDHAL_PLEASEALLOC_BLOCKSIZE;
752 }
753
754 return DDHAL_DRIVER_NOTHANDLED;
755}
756
757/**
758 * DdCanCreateSurface
759 *
760 * The DdCanCreateSurface callback function indicates whether the driver can create a surface of the specified surface description.
761 *
762 *
763 * Parameters
764 * lpCanCreateSurface
765 * Points to the DD_CANCREATESURFACEDATA structure containing the information required for the driver to determine whether a surface can be created.
766 *
767 * Return Value
768 *
769 * DdCanCreateSurface returns one of the following callback codes:
770 *
771 * DDHAL_DRIVER_HANDLED
772 * DDHAL_DRIVER_NOTHANDLED
773 *
774 */
775DWORD APIENTRY DdCanCreateSurface(PDD_CANCREATESURFACEDATA lpCanCreateSurface)
776{
777 PPDEV pDev = (PPDEV)lpCanCreateSurface->lpDD->dhpdev;
778
779 PDD_SURFACEDESC lpDDS = lpCanCreateSurface->lpDDSurfaceDesc;
780
781 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
782
783#ifdef VBOX_WITH_VIDEOHWACCEL
784 if(pDev->vhwaInfo.bVHWAEnabled)
785 {
786 VBOXVHWACMD* pCmd;
787 uint32_t unsupportedSCaps = vboxVHWAUnsupportedDDSCAPS(lpDDS->ddsCaps.dwCaps);
788 Assert(!unsupportedSCaps);
789 if(unsupportedSCaps)
790 {
791 VHWADBG(("vboxVHWASurfCanCreate: unsupported ddscaps: 0x%x", unsupportedSCaps));
792 lpCanCreateSurface->ddRVal = DDERR_INVALIDCAPS;
793 return DDHAL_DRIVER_HANDLED;
794 }
795
796 unsupportedSCaps = vboxVHWAUnsupportedDDPFS(lpDDS->ddpfPixelFormat.dwFlags);
797 Assert(!unsupportedSCaps);
798 if(unsupportedSCaps)
799 {
800 VHWADBG(("vboxVHWASurfCanCreate: unsupported pixel format: 0x%x", unsupportedSCaps));
801 lpCanCreateSurface->ddRVal = DDERR_INVALIDPIXELFORMAT;
802 return DDHAL_DRIVER_HANDLED;
803 }
804
805 pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_CANCREATE, sizeof(VBOXVHWACMD_SURF_CANCREATE));
806 if(pCmd)
807 {
808 int rc;
809 VBOXVHWACMD_SURF_CANCREATE * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_CANCREATE);
810 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_CANCREATE));
811
812 rc = vboxVHWAFromDDSURFACEDESC(&pBody->SurfInfo, lpDDS);
813 pBody->u.in.bIsDifferentPixelFormat = lpCanCreateSurface->bIsDifferentPixelFormat;
814
815 vboxVHWACommandSubmit(pDev, pCmd);
816 Assert(pCmd->rc == VINF_SUCCESS);
817 if(pCmd->rc == VINF_SUCCESS)
818 {
819#ifdef DEBUGVHWASTRICT
820 Assert(!pBody->u.out.ErrInfo);
821#endif
822 if(pBody->u.out.ErrInfo)
823 {
824 lpCanCreateSurface->ddRVal = DDERR_GENERIC;
825 }
826 else
827 {
828 lpCanCreateSurface->ddRVal = DD_OK;
829 }
830 }
831 else
832 {
833 lpCanCreateSurface->ddRVal = DDERR_GENERIC;
834 }
835 vbvaVHWACommandRelease(pDev, pCmd);
836 }
837 else
838 {
839 lpCanCreateSurface->ddRVal = DDERR_GENERIC;
840 }
841 return DDHAL_DRIVER_HANDLED;
842 }
843#endif
844
845 if (lpDDS->ddsCaps.dwCaps & DDSCAPS_ZBUFFER)
846 {
847 DISPDBG((0, "No Z-Bufer support\n"));
848 lpCanCreateSurface->ddRVal = DDERR_INVALIDPIXELFORMAT;
849 return DDHAL_DRIVER_HANDLED;
850 }
851 if (lpDDS->ddsCaps.dwCaps & DDSCAPS_TEXTURE)
852 {
853 DISPDBG((0, "No texture support\n"));
854 lpCanCreateSurface->ddRVal = DDERR_INVALIDPIXELFORMAT;
855 return DDHAL_DRIVER_HANDLED;
856 }
857 if (lpCanCreateSurface->bIsDifferentPixelFormat && (lpDDS->ddpfPixelFormat.dwFlags & DDPF_FOURCC))
858 {
859 DISPDBG((0, "FOURCC not supported\n"));
860 lpCanCreateSurface->ddRVal = DDERR_INVALIDPIXELFORMAT;
861 return DDHAL_DRIVER_HANDLED;
862 }
863
864 lpCanCreateSurface->ddRVal = DD_OK;
865 return DDHAL_DRIVER_HANDLED;
866}
867
868// ***************************WIN NT ONLY**********************************
869//
870// DdMapMemory
871//
872// Maps application-modifiable portions of the frame buffer into the
873// user-mode address space of the specified process, or unmaps memory.
874//
875// DdMapMemory is called to perform memory mapping before the first call to
876// DdLock. The handle returned by the driver in fpProcess will be passed to
877// every DdLock call made on the driver.
878//
879// DdMapMemory is also called to unmap memory after the last DdUnLock call is
880// made.
881//
882// To prevent driver crashes, the driver must not map any portion of the frame
883// buffer that must not be modified by an application.
884//
885// Parameters
886// lpMapMemory
887// Points to a DD_MAPMEMORYDATA structure that contains details for
888// the memory mapping or unmapping operation.
889//
890// .lpDD
891// Points to a DD_DIRECTDRAW_GLOBAL structure that represents
892// the driver.
893// .bMap
894// Specifies the memory operation that the driver should perform.
895// A value of TRUE indicates that the driver should map memory;
896// FALSE means that the driver should unmap memory.
897// .hProcess
898// Specifies a handle to the process whose address space is
899// affected.
900// .fpProcess
901// Specifies the location in which the driver should return the
902// base address of the process's memory mapped space when bMap
903// is TRUE. When bMap is FALSE, fpProcess contains the base
904// address of the memory to be unmapped by the driver.
905// .ddRVal
906// Specifies the location in which the driver writes the return
907// value of the DdMapMemory callback. A return code of DD_OK
908// indicates success.
909//
910//-----------------------------------------------------------------------------
911
912DWORD CALLBACK DdMapMemory(PDD_MAPMEMORYDATA lpMapMemory)
913{
914 PPDEV pDev = (PPDEV)lpMapMemory->lpDD->dhpdev;
915
916 VIDEO_SHARE_MEMORY ShareMemory;
917 VIDEO_SHARE_MEMORY_INFORMATION ShareMemoryInformation;
918 DWORD ReturnedDataLength;
919
920 DISPDBG((0, "%s: %p bMap %d\n", __FUNCTION__, pDev, lpMapMemory->bMap));
921
922 if (lpMapMemory->bMap)
923 {
924 ShareMemory.ProcessHandle = lpMapMemory->hProcess;
925
926 // 'RequestedVirtualAddress' isn't actually used for the SHARE IOCTL:
927
928 ShareMemory.RequestedVirtualAddress = 0;
929
930 // We map in starting at the top of the frame buffer:
931
932 ShareMemory.ViewOffset = 0;
933
934 // We map down to the end of the frame buffer, including the offscreen heap.
935 ShareMemory.ViewSize = pDev->layout.offVBVABuffer;
936
937 DISPDBG((0, "ViewSize = %x\n", ShareMemory.ViewSize));
938
939 if (EngDeviceIoControl(pDev->hDriver,
940 IOCTL_VIDEO_SHARE_VIDEO_MEMORY,
941 &ShareMemory,
942 sizeof(VIDEO_SHARE_MEMORY),
943 &ShareMemoryInformation,
944 sizeof(VIDEO_SHARE_MEMORY_INFORMATION),
945 &ReturnedDataLength))
946 {
947 DISPDBG((0, "Failed IOCTL_VIDEO_SHARE_MEMORY\n"));
948
949 lpMapMemory->ddRVal = DDERR_GENERIC;
950
951 DISPDBG((0, "DdMapMemory: Exit GEN, DDHAL_DRIVER_HANDLED\n"));
952
953 AssertBreakpoint();
954
955 return(DDHAL_DRIVER_HANDLED);
956 }
957
958 lpMapMemory->fpProcess =
959 (FLATPTR) ShareMemoryInformation.VirtualAddress;
960 }
961 else
962 {
963 ShareMemory.ProcessHandle = lpMapMemory->hProcess;
964 ShareMemory.ViewOffset = 0;
965 ShareMemory.ViewSize = 0;
966 ShareMemory.RequestedVirtualAddress = (VOID*) lpMapMemory->fpProcess;
967
968 if (EngDeviceIoControl(pDev->hDriver,
969 IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY,
970 &ShareMemory,
971 sizeof(VIDEO_SHARE_MEMORY),
972 NULL,
973 0,
974 &ReturnedDataLength))
975 {
976 DISPDBG((0, "Failed IOCTL_VIDEO_UNSHARE_MEMORY\n"));
977 AssertBreakpoint();
978 }
979 }
980
981 lpMapMemory->ddRVal = DD_OK;
982
983 return(DDHAL_DRIVER_HANDLED);
984}
985
986/**
987 * DdLock
988 *
989 * 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.
990 *
991 * Parameters
992 * lpLock
993 * Points to a DD_LOCKDATA structure that contains the information required to perform the lockdown.
994 *
995 * Return Value
996 *
997 * DdLock returns one of the following callback codes:
998 *
999 * DDHAL_DRIVER_HANDLED
1000 * DDHAL_DRIVER_NOTHANDLED
1001 *
1002 */
1003DWORD APIENTRY DdLock(PDD_LOCKDATA lpLock)
1004{
1005 PPDEV pDev = (PPDEV)lpLock->lpDD->dhpdev;
1006 DD_SURFACE_LOCAL* lpSurfaceLocal = lpLock->lpDDSurface;
1007
1008 DISPDBG((0, "%s: %p bHasRect = %d fpProcess = %p\n", __FUNCTION__, pDev, lpLock->bHasRect, lpLock->fpProcess));
1009
1010#ifdef VBOX_WITH_VIDEOHWACCEL
1011 if(pDev->vhwaInfo.bVHWAEnabled)
1012 {
1013#ifndef DBG_DDSTUBS
1014 DD_SURFACE_GLOBAL* lpSurfaceGlobal = lpSurfaceLocal->lpGbl;
1015 PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC)lpSurfaceGlobal->dwReserved1;
1016 RECTL tmpRect, *pRect;
1017
1018 if(ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc)
1019 || ASMAtomicUoReadU32(&pDesc->cPendingFlipsCurr)
1020 || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst)
1021 || ASMAtomicUoReadU32(&pDesc->cPendingFlipsTarg))
1022 {
1023 /* ensure we have host cmds processed to update pending blits and flips */
1024 vboxVHWACommandCheckHostCmds(pDev);
1025 if(ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc)
1026 || ASMAtomicUoReadU32(&pDesc->cPendingFlipsCurr)
1027 || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst)
1028 || ASMAtomicUoReadU32(&pDesc->cPendingFlipsTarg))
1029 {
1030 lpLock->ddRVal = DDERR_WASSTILLDRAWING;
1031 return DDHAL_DRIVER_HANDLED;
1032 }
1033 }
1034
1035// if(VBOXDD_CHECKFLAG(lpLock->dwFlags, DDLOCK_SURFACEMEMORYPTR))
1036// {
1037// lpLock->lpSurfData = (LPVOID)(lpSurfaceGlobal->fpVidMem + lpSurfaceGlobal->lPitch * lpLock->rArea.top
1038// + lpLock->rArea.left * pDesc->cBitsPerPixel/8);
1039// }
1040
1041 if (lpLock->bHasRect)
1042 {
1043 pRect = &lpLock->rArea;
1044 }
1045 else
1046 {
1047 tmpRect.left=0;
1048 tmpRect.top=0;
1049 tmpRect.right=lpSurfaceGlobal->wWidth-1;
1050 tmpRect.bottom=lpSurfaceGlobal->wHeight-1;
1051 pRect = &tmpRect;
1052 }
1053
1054 if(VBOXDD_CHECKFLAG(lpLock->dwFlags, DDLOCK_DISCARDCONTENTS))
1055 {
1056// pBody->u.in.flags |= VBOXVHWA_LOCK_DISCARDCONTENTS;
1057
1058 vboxVHWARegionTrySubstitute(&pDesc->NonupdatedMemRegion, pRect);
1059// /* we're not interested in completion, just send the command */
1060// vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWAFreeCmdCompletion, NULL);
1061 vboxVHWARegionAdd(&pDesc->UpdatedMemRegion, pRect);
1062 lpLock->ddRVal = DD_OK;
1063 }
1064 else if(!vboxVHWARegionIntersects(&pDesc->NonupdatedMemRegion, pRect))
1065 {
1066// vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWAFreeCmdCompletion, NULL);
1067 vboxVHWARegionAdd(&pDesc->UpdatedMemRegion, pRect);
1068 lpLock->ddRVal = DD_OK;
1069 }
1070 else
1071 {
1072 VBOXVHWACMD* pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_LOCK, sizeof(VBOXVHWACMD_SURF_LOCK));
1073 if(pCmd)
1074 {
1075 VBOXVHWACMD_SURF_LOCK * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_LOCK);
1076 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_LOCK));
1077
1078 pBody->u.in.offSurface = vboxVHWAVramOffsetFromPDEV(pDev, lpSurfaceGlobal->fpVidMem);
1079
1080// if (lpLock->bHasRect)
1081// {
1082// 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));
1083// vboxVHWAFromRECTL(&pBody->u.in.rect, &lpLock->rArea);
1084// pBody->u.in.rectValid = 1;
1085//
1086// }
1087// else
1088// {
1089// pBody->u.in.rectValid = 0;
1090// }
1091 Assert(pDesc->NonupdatedMemRegion.bValid);
1092 vboxVHWAFromRECTL(&pBody->u.in.rect, &pDesc->NonupdatedMemRegion.Rect);
1093 pBody->u.in.rectValid = 1;
1094
1095 pBody->u.in.hSurf = pDesc->hHostHandle;
1096
1097 /* wait for the surface to be locked and memory buffer updated */
1098 vboxVHWACommandSubmit(pDev, pCmd);
1099 vbvaVHWACommandRelease(pDev, pCmd);
1100 vboxVHWARegionClear(&pDesc->NonupdatedMemRegion);
1101 lpLock->ddRVal = DD_OK;
1102 }
1103 else
1104 {
1105 lpLock->ddRVal = DDERR_GENERIC;
1106 }
1107 }
1108#else
1109 lpLock->ddRVal = DD_OK;
1110#endif
1111 return DDHAL_DRIVER_NOTHANDLED;
1112 }
1113#endif
1114 if (lpSurfaceLocal->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
1115 {
1116 /* The updated rectangle must be reported only for the primary surface. */
1117 pDev->ddLock.bLocked = TRUE;
1118
1119 if (lpLock->bHasRect)
1120 {
1121 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));
1122 pDev->ddLock.rArea = lpLock->rArea;
1123 }
1124 else
1125 {
1126 pDev->ddLock.rArea.left = 0;
1127 pDev->ddLock.rArea.top = 0;
1128 pDev->ddLock.rArea.right = pDev->cxScreen;
1129 pDev->ddLock.rArea.bottom = pDev->cyScreen;
1130 }
1131 }
1132 else
1133 {
1134 DISPDBG((0, "%s: secondary surface.\n", __FUNCTION__));
1135 }
1136
1137 // Because we correctly set 'fpVidMem' to be the offset into our frame
1138 // buffer when we created the surface, DirectDraw will automatically take
1139 // care of adding in the user-mode frame buffer address if we return
1140 // DDHAL_DRIVER_NOTHANDLED:
1141 lpLock->ddRVal = DD_OK;
1142 return DDHAL_DRIVER_NOTHANDLED;
1143}
1144
1145/**
1146 * DdUnlock
1147 *
1148 * The DdUnLock callback function releases the lock held on the specified surface.
1149 *
1150 * Parameters
1151 * lpUnlock
1152 * Points to a DD_UNLOCKDATA structure that contains the information required to perform the lock release. *
1153 *
1154 * Return Value
1155 *
1156 * DdLock returns one of the following callback codes:
1157 *
1158 * DDHAL_DRIVER_HANDLED
1159 * DDHAL_DRIVER_NOTHANDLED
1160 *
1161 */
1162DWORD APIENTRY DdUnlock(PDD_UNLOCKDATA lpUnlock)
1163{
1164 PPDEV pDev = (PPDEV)lpUnlock->lpDD->dhpdev;
1165 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
1166#ifdef VBOX_WITH_VIDEOHWACCEL
1167 if (pDev->vhwaInfo.bVHWAEnabled)
1168 {
1169#ifndef DBG_DDSTUBS
1170 DD_SURFACE_LOCAL* lpSurfaceLocal = lpUnlock->lpDDSurface;
1171 DD_SURFACE_GLOBAL* lpSurfaceGlobal = lpSurfaceLocal->lpGbl;
1172 PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC)lpSurfaceGlobal->dwReserved1;
1173
1174// /* ensure we have host cmds processed to update pending blits and flips */
1175// vboxVHWACommandCheckHostCmds(pDev);
1176 if(!!(lpSurfaceLocal->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
1177 && pDesc->UpdatedMemRegion.bValid
1178 && VBoxVBVABufferBeginUpdate(&pDev->vbvaCtx, &pDev->guestCtx))
1179 {
1180 vbvaReportDirtyRect (pDev, &pDesc->UpdatedMemRegion.Rect);
1181
1182 if ( pDev->vbvaCtx.pVBVA->hostFlags.u32HostEvents
1183 & VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET)
1184 {
1185 vrdpReset (pDev);
1186
1187 pDev->vbvaCtx.pVBVA->hostFlags.u32HostEvents &=
1188 ~VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET;
1189 }
1190
1191 if (pDev->vbvaCtx.pVBVA->hostFlags.u32HostEvents
1192 & VBVA_F_MODE_VRDP)
1193 {
1194 vrdpReportDirtyRect (pDev, &pDesc->UpdatedMemRegion.Rect);
1195 }
1196
1197 VBoxVBVABufferEndUpdate(&pDev->vbvaCtx);
1198
1199 lpUnlock->ddRVal = DD_OK;
1200 }
1201 else if(lpSurfaceLocal->ddsCaps.dwCaps & DDSCAPS_VISIBLE
1202// || !!(lpSurfaceLocal->ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER)
1203 || ( !!(lpSurfaceLocal->ddsCaps.dwCaps & DDSCAPS_OVERLAY)
1204 && pDesc->bVisible
1205 )
1206 )
1207 {
1208 VBOXVHWACMD* pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_UNLOCK, sizeof(VBOXVHWACMD_SURF_UNLOCK));
1209 // int rc = VERR_GENERAL_FAILURE;
1210 if(pCmd)
1211 {
1212 VBOXVHWACMD_SURF_UNLOCK * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_UNLOCK);
1213 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_UNLOCK));
1214
1215 pBody->u.in.hSurf = pDesc->hHostHandle;
1216 if(pDesc->UpdatedMemRegion.bValid)
1217 {
1218 pBody->u.in.xUpdatedMemValid = 1;
1219 vboxVHWAFromRECTL(&pBody->u.in.xUpdatedMemRect, &pDesc->UpdatedMemRegion.Rect);
1220 vboxVHWARegionClear(&pDesc->UpdatedMemRegion);
1221 }
1222
1223 vboxVHWACommandSubmitAsynchAndComplete(pDev, pCmd);
1224
1225 lpUnlock->ddRVal = DD_OK;
1226 }
1227 else
1228 {
1229 lpUnlock->ddRVal = DDERR_GENERIC;
1230 }
1231 }
1232 else
1233 {
1234 lpUnlock->ddRVal = DD_OK;
1235 }
1236#else
1237 lpUnlock->ddRVal = DD_OK;
1238#endif
1239
1240 return DDHAL_DRIVER_NOTHANDLED;
1241 }
1242#endif
1243 if (pDev->ddLock.bLocked)
1244 {
1245 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));
1246
1247 if ( pDev->bHGSMISupported
1248 && VBoxVBVABufferBeginUpdate(&pDev->vbvaCtx, &pDev->guestCtx))
1249 {
1250 vbvaReportDirtyRect (pDev, &pDev->ddLock.rArea);
1251
1252 if ( pDev->vbvaCtx.pVBVA->hostFlags.u32HostEvents
1253 & VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET)
1254 {
1255 vrdpReset (pDev);
1256
1257 pDev->vbvaCtx.pVBVA->hostFlags.u32HostEvents &=
1258 ~VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET;
1259 }
1260
1261 if (pDev->vbvaCtx.pVBVA->hostFlags.u32HostEvents
1262 & VBVA_F_MODE_VRDP)
1263 {
1264 vrdpReportDirtyRect (pDev, &pDev->ddLock.rArea);
1265 }
1266
1267 VBoxVBVABufferEndUpdate(&pDev->vbvaCtx);
1268 }
1269
1270 pDev->ddLock.bLocked = FALSE;
1271 }
1272
1273 lpUnlock->ddRVal = DD_OK;
1274 return DDHAL_DRIVER_NOTHANDLED;
1275}
1276
1277/**
1278 * DdDestroySurface
1279 *
1280 * The DdDestroySurface callback function destroys a DirectDraw surface.
1281 *
1282 * Parameters
1283 * lpDestroySurface
1284 * Points to a DD_DESTROYSURFACEDATA structure that contains the information needed to destroy a surface.
1285 *
1286 * Return Value
1287 *
1288 * DdDestroySurface returns one of the following callback codes:
1289 *
1290 * DDHAL_DRIVER_HANDLED
1291 * DDHAL_DRIVER_NOTHANDLED
1292 *
1293 */
1294DWORD APIENTRY DdDestroySurface(PDD_DESTROYSURFACEDATA lpDestroySurface)
1295{
1296#ifdef VBOX_WITH_VIDEOHWACCEL
1297 PPDEV pDev = (PPDEV)lpDestroySurface->lpDD->dhpdev;
1298 if(pDev->vhwaInfo.bVHWAEnabled)
1299 {
1300 DD_SURFACE_LOCAL* lpSurfaceLocal = lpDestroySurface->lpDDSurface;
1301 DD_SURFACE_GLOBAL* lpSurfaceGlobal = lpSurfaceLocal->lpGbl;
1302 VBOXVHWACMD* pCmd;
1303
1304 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
1305
1306 pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_DESTROY, sizeof(VBOXVHWACMD_SURF_DESTROY));
1307 // int rc = VERR_GENERAL_FAILURE;
1308 if(pCmd)
1309 {
1310 VBOXVHWACMD_SURF_DESTROY * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_DESTROY);
1311 PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC)lpSurfaceGlobal->dwReserved1;
1312
1313 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_DESTROY));
1314
1315 pBody->u.in.hSurf = pDesc->hHostHandle;
1316
1317 /* we're not interested in completion, just send the command */
1318 vboxVHWACommandSubmitAsynchAndComplete(pDev, pCmd);
1319
1320 vboxVHWASurfDescFree(pDesc);
1321
1322 lpSurfaceGlobal->dwReserved1 = (ULONG_PTR)NULL;
1323
1324 lpDestroySurface->ddRVal = DD_OK;
1325 }
1326 else
1327 {
1328 lpDestroySurface->ddRVal = DDERR_GENERIC;
1329 }
1330 }
1331 else
1332#endif
1333 lpDestroySurface->ddRVal = DD_OK;
1334
1335 /* we're not managing video memory currently, so return DDHAL_DRIVER_NOTHANDLED */
1336 return DDHAL_DRIVER_NOTHANDLED;
1337}
1338
1339
1340//-----------------------------------------------------------------------------
1341//
1342// DdSetExclusiveMode
1343//
1344// This function is called by DirectDraw when we switch from the GDI surface,
1345// to DirectDraw exclusive mode, e.g. to run a game in fullcreen mode.
1346// You only need to implement this function when you are using the
1347// 'HeapVidMemAllocAligned' function and allocate memory for Device Bitmaps
1348// and DirectDraw surfaces from the same heap.
1349//
1350// We use this call to disable GDI DeviceBitMaps when we are running in
1351// DirectDraw exclusive mode. Otherwise a DD app gets confused if both GDI and
1352// DirectDraw allocate memory from the same heap.
1353//
1354// See also DdFlipToGDISurface.
1355//
1356//-----------------------------------------------------------------------------
1357
1358
1359DWORD APIENTRY DdSetExclusiveMode(PDD_SETEXCLUSIVEMODEDATA lpSetExclusiveMode)
1360{
1361 PPDEV pDev = (PPDEV)lpSetExclusiveMode->lpDD->dhpdev;
1362 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
1363
1364 // remember setting of exclusive mode in pDev,
1365 // so GDI can stop to promote DeviceBitmaps into
1366 // video memory
1367
1368 pDev->bDdExclusiveMode = lpSetExclusiveMode->dwEnterExcl;
1369
1370 lpSetExclusiveMode->ddRVal = DD_OK;
1371
1372 return DDHAL_DRIVER_HANDLED;
1373}
1374
1375//-----------------------------------------------------------------------------
1376//
1377// DWORD DdFlipToGDISurface
1378//
1379// This function is called by DirectDraw when it flips to the surface on which
1380// GDI can write to.
1381//
1382//-----------------------------------------------------------------------------
1383
1384DWORD APIENTRY DdFlipToGDISurface(PDD_FLIPTOGDISURFACEDATA lpFlipToGDISurface)
1385{
1386 PPDEV pDev = (PPDEV)lpFlipToGDISurface->lpDD->dhpdev;
1387 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
1388
1389 pDev->dwNewDDSurfaceOffset = 0xffffffff;
1390
1391 lpFlipToGDISurface->ddRVal = DD_OK;
1392
1393 //
1394 // we return NOTHANDLED, then the ddraw runtime takes
1395 // care that we flip back to the primary...
1396 //
1397 return DDHAL_DRIVER_NOTHANDLED;
1398}
1399//-----------------------------------------------------------------------------
1400//
1401// DWORD DdFreeDriverMemory
1402//
1403// This function called by DirectDraw when it's running low on memory in
1404// our heap. You only need to implement this function if you use the
1405// DirectDraw 'HeapVidMemAllocAligned' function in your driver, and you
1406// can boot those allocations out of memory to make room for DirectDraw.
1407//
1408//-----------------------------------------------------------------------------
1409
1410DWORD APIENTRY DdFreeDriverMemory(PDD_FREEDRIVERMEMORYDATA lpFreeDriverMemory)
1411{
1412 PPDEV pDev = (PPDEV)lpFreeDriverMemory->lpDD->dhpdev;
1413 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
1414
1415 lpFreeDriverMemory->ddRVal = DDERR_OUTOFMEMORY;
1416 return DDHAL_DRIVER_HANDLED;
1417}
1418
1419#ifdef VBOX_WITH_VIDEOHWACCEL
1420#ifndef DBG_DDSTUBS
1421DWORD APIENTRY DdSetColorKey(PDD_SETCOLORKEYDATA lpSetColorKey)
1422{
1423 PPDEV pDev = (PPDEV)lpSetColorKey->lpDD->dhpdev;
1424 DD_SURFACE_LOCAL* lpSurfaceLocal = lpSetColorKey->lpDDSurface;
1425 DD_SURFACE_GLOBAL* lpSurfaceGlobal = lpSurfaceLocal->lpGbl;
1426 VBOXVHWACMD* pCmd;
1427
1428 DISPDBG((0, "%s\n", __FUNCTION__));
1429
1430 pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_COLORKEY_SET, sizeof(VBOXVHWACMD_SURF_COLORKEY_SET));
1431 // int rc = VERR_GENERAL_FAILURE;
1432 if(pCmd)
1433 {
1434 VBOXVHWACMD_SURF_COLORKEY_SET * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_COLORKEY_SET);
1435 PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC)lpSurfaceGlobal->dwReserved1;
1436 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_COLORKEY_SET));
1437
1438 pBody->u.in.offSurface = vboxVHWAVramOffsetFromPDEV(pDev, lpSurfaceGlobal->fpVidMem);
1439 pBody->u.in.hSurf = pDesc->hHostHandle;
1440 pBody->u.in.flags = vboxVHWAFromDDCKEYs(lpSetColorKey->dwFlags);
1441 vboxVHWAFromDDCOLORKEY(&pBody->u.in.CKey, &lpSetColorKey->ckNew);
1442
1443 vboxVHWACommandSubmitAsynchAndComplete(pDev, pCmd);
1444 lpSetColorKey->ddRVal = DD_OK;
1445 }
1446 return DDHAL_DRIVER_HANDLED;
1447}
1448
1449DWORD APIENTRY DdAddAttachedSurface(PDD_ADDATTACHEDSURFACEDATA lpAddAttachedSurface)
1450{
1451 DISPDBG((0, "%s\n", __FUNCTION__));
1452 lpAddAttachedSurface->ddRVal = DD_OK;
1453 return DDHAL_DRIVER_HANDLED;
1454}
1455
1456DWORD APIENTRY DdBlt(PDD_BLTDATA lpBlt)
1457{
1458 PPDEV pDev = (PPDEV)lpBlt->lpDD->dhpdev;
1459 DISPDBG((0, "%s\n", __FUNCTION__));
1460#if DX9_DDI
1461 if(VBOXDD_CHECKFLAG(lpBlt->dwFlags, DDBLT_EXTENDED_PRESENTATION_STRETCHFACTOR))
1462 {
1463 lpBlt->ddRVal = DD_OK;
1464 }
1465 else
1466#endif
1467 {
1468 DD_SURFACE_LOCAL* lpDestSurfaceLocal = lpBlt->lpDDDestSurface;
1469 DD_SURFACE_GLOBAL* lpDestSurfaceGlobal = lpDestSurfaceLocal->lpGbl;
1470 DD_SURFACE_LOCAL* lpSrcSurfaceLocal = lpBlt->lpDDSrcSurface;
1471 DD_SURFACE_GLOBAL* lpSrcSurfaceGlobal = lpSrcSurfaceLocal->lpGbl;
1472 VBOXVHWACMD* pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_BLT, sizeof(VBOXVHWACMD_SURF_BLT));
1473 // int rc = VERR_GENERAL_FAILURE;
1474 if(pCmd)
1475 {
1476 VBOXVHWACMD_SURF_BLT * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_BLT);
1477 PVBOXVHWASURFDESC pSrcDesc = (PVBOXVHWASURFDESC)lpSrcSurfaceGlobal->dwReserved1;
1478 PVBOXVHWASURFDESC pDestDesc = (PVBOXVHWASURFDESC)lpDestSurfaceGlobal->dwReserved1;
1479 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_BLT));
1480
1481 pBody->u.in.offSrcSurface = vboxVHWAVramOffsetFromPDEV(pDev, lpSrcSurfaceGlobal->fpVidMem);
1482 pBody->u.in.offDstSurface = vboxVHWAVramOffsetFromPDEV(pDev, lpDestSurfaceGlobal->fpVidMem);
1483
1484 pBody->u.in.hDstSurf = pDestDesc->hHostHandle;
1485 vboxVHWAFromRECTL(&pBody->u.in.dstRect, &lpBlt->rDest);
1486 pBody->u.in.hSrcSurf = pSrcDesc->hHostHandle;
1487 vboxVHWAFromRECTL(&pBody->u.in.srcRect, &lpBlt->rSrc);
1488 pBody->DstGuestSurfInfo = (uint64_t)pDestDesc;
1489 pBody->SrcGuestSurfInfo = (uint64_t)pSrcDesc;
1490
1491 pBody->u.in.flags = vboxVHWAFromDDBLTs(lpBlt->dwFlags);
1492 vboxVHWAFromDDBLTFX(&pBody->u.in.desc, &lpBlt->bltFX);
1493
1494 ASMAtomicIncU32(&pSrcDesc->cPendingBltsSrc);
1495 ASMAtomicIncU32(&pDestDesc->cPendingBltsDst);
1496
1497 vboxVHWARegionAdd(&pDestDesc->NonupdatedMemRegion, &lpBlt->rDest);
1498 vboxVHWARegionTrySubstitute(&pDestDesc->UpdatedMemRegion, &lpBlt->rDest);
1499
1500 if(pSrcDesc->UpdatedMemRegion.bValid)
1501 {
1502 pBody->u.in.xUpdatedSrcMemValid = 1;
1503 vboxVHWAFromRECTL(&pBody->u.in.xUpdatedSrcMemRect, &pSrcDesc->UpdatedMemRegion.Rect);
1504 vboxVHWARegionClear(&pSrcDesc->UpdatedMemRegion);
1505 }
1506
1507 vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWASurfBltCompletion, NULL);
1508
1509 lpBlt->ddRVal = DD_OK;
1510 }
1511 else
1512 {
1513 lpBlt->ddRVal = DDERR_GENERIC;
1514 }
1515 }
1516
1517 return DDHAL_DRIVER_HANDLED;
1518}
1519
1520//DWORD APIENTRY DdDestroySurface(PDD_DESTROYSURFACEDATA lpDestroySurface)
1521//{
1522// DISPDBG((0, "%s\n", __FUNCTION__));
1523// lpDestroySurface->ddRVal = DD_OK;
1524// return DDHAL_DRIVER_HANDLED;
1525//}
1526
1527DWORD APIENTRY DdFlip(PDD_FLIPDATA lpFlip)
1528{
1529 PPDEV pDev = (PPDEV)lpFlip->lpDD->dhpdev;
1530 DD_SURFACE_LOCAL* lpTargSurfaceLocal = lpFlip->lpSurfTarg;
1531 DD_SURFACE_GLOBAL* lpTargSurfaceGlobal = lpTargSurfaceLocal->lpGbl;
1532 DD_SURFACE_LOCAL* lpCurrSurfaceLocal = lpFlip->lpSurfCurr;
1533 DD_SURFACE_GLOBAL* lpCurrSurfaceGlobal = lpCurrSurfaceLocal->lpGbl;
1534 PVBOXVHWASURFDESC pCurrDesc = (PVBOXVHWASURFDESC)lpCurrSurfaceGlobal->dwReserved1;
1535 PVBOXVHWASURFDESC pTargDesc = (PVBOXVHWASURFDESC)lpTargSurfaceGlobal->dwReserved1;
1536 VBOXVHWACMD* pCmd;
1537
1538 DISPDBG((0, "%s\n", __FUNCTION__));
1539
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 /* ensure we have host cmds processed to update pending blits and flips */
1550 vboxVHWACommandCheckHostCmds(pDev);
1551 if(
1552 // ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc)
1553 // || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst)
1554 // ||
1555 ASMAtomicUoReadU32(&pCurrDesc->cPendingFlipsTarg)
1556 || ASMAtomicUoReadU32(&pCurrDesc->cPendingFlipsCurr)
1557 || ASMAtomicUoReadU32(&pTargDesc->cPendingFlipsTarg)
1558 || ASMAtomicUoReadU32(&pTargDesc->cPendingFlipsCurr))
1559 {
1560 lpFlip->ddRVal = DDERR_WASSTILLDRAWING;
1561 return DDHAL_DRIVER_HANDLED;
1562 }
1563 }
1564
1565
1566 pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_FLIP, sizeof(VBOXVHWACMD_SURF_FLIP));
1567 // int rc = VERR_GENERAL_FAILURE;
1568 if(pCmd)
1569 {
1570 VBOXVHWACMD_SURF_FLIP * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_FLIP);
1571
1572 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_FLIP));
1573
1574 pBody->u.in.offCurrSurface = vboxVHWAVramOffsetFromPDEV(pDev, lpCurrSurfaceGlobal->fpVidMem);
1575 pBody->u.in.offTargSurface = vboxVHWAVramOffsetFromPDEV(pDev, lpTargSurfaceGlobal->fpVidMem);
1576
1577 pBody->u.in.hTargSurf = pTargDesc->hHostHandle;
1578 pBody->u.in.hCurrSurf = pCurrDesc->hHostHandle;
1579 pBody->TargGuestSurfInfo = (uint64_t)pTargDesc;
1580 pBody->CurrGuestSurfInfo = (uint64_t)pCurrDesc;
1581
1582 pTargDesc->bVisible = pCurrDesc->bVisible;
1583 pCurrDesc->bVisible = false;
1584
1585// pBody->u.in.flags = vboxVHWAFromDDFLIPs(lpFlip->dwFlags);
1586
1587 ASMAtomicIncU32(&pCurrDesc->cPendingFlipsCurr);
1588 ASMAtomicIncU32(&pTargDesc->cPendingFlipsTarg);
1589#ifdef DEBUG
1590 ASMAtomicIncU32(&pCurrDesc->cFlipsCurr);
1591 ASMAtomicIncU32(&pTargDesc->cFlipsTarg);
1592#endif
1593
1594 if(pTargDesc->UpdatedMemRegion.bValid)
1595 {
1596 pBody->u.in.xUpdatedTargMemValid = 1;
1597 vboxVHWAFromRECTL(&pBody->u.in.xUpdatedTargMemRect, &pTargDesc->UpdatedMemRegion.Rect);
1598 vboxVHWARegionClear(&pTargDesc->UpdatedMemRegion);
1599 }
1600
1601 vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWASurfFlipCompletion, NULL);
1602
1603 lpFlip->ddRVal = DD_OK;
1604 }
1605 else
1606 {
1607 lpFlip->ddRVal = DDERR_GENERIC;
1608 }
1609 return DDHAL_DRIVER_HANDLED;
1610}
1611
1612DWORD APIENTRY DdGetBltStatus(PDD_GETBLTSTATUSDATA lpGetBltStatus)
1613{
1614 PPDEV pDev = (PPDEV)lpGetBltStatus->lpDD->dhpdev;
1615
1616 DISPDBG((0, "%s\n", __FUNCTION__));
1617
1618 if(lpGetBltStatus->dwFlags == DDGBS_CANBLT)
1619 {
1620 lpGetBltStatus->ddRVal = DD_OK;
1621 }
1622 else /* DDGBS_ISBLTDONE */
1623 {
1624 DD_SURFACE_LOCAL* lpSurfaceLocal = lpGetBltStatus->lpDDSurface;
1625 DD_SURFACE_GLOBAL* lpSurfaceGlobal = lpSurfaceLocal->lpGbl;
1626 PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC)lpSurfaceGlobal->dwReserved1;
1627
1628 if(
1629 ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc)
1630 || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst)
1631 // || ASMAtomicUoReadU32(&pDesc->cPendingFlipsTarg)
1632 // || ASMAtomicUoReadU32(&pDesc->cPendingFlipsCurr)
1633 )
1634 {
1635 /* ensure we have host cmds processed to update pending blits and flips */
1636 vboxVHWACommandCheckHostCmds(pDev);
1637
1638 if(
1639 ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc)
1640 || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst)
1641 // || ASMAtomicUoReadU32(&pDesc->cPendingFlipsTarg)
1642 // || ASMAtomicUoReadU32(&pDesc->cPendingFlipsCurr)
1643 )
1644 {
1645 lpGetBltStatus->ddRVal = DDERR_WASSTILLDRAWING;
1646 }
1647 else
1648 {
1649 lpGetBltStatus->ddRVal = DD_OK;
1650 }
1651 }
1652 else
1653 {
1654 lpGetBltStatus->ddRVal = DD_OK;
1655 }
1656 }
1657
1658 return DDHAL_DRIVER_HANDLED;
1659}
1660
1661DWORD APIENTRY DdGetFlipStatus(PDD_GETFLIPSTATUSDATA lpGetFlipStatus)
1662{
1663 PPDEV pDev = (PPDEV)lpGetFlipStatus->lpDD->dhpdev;
1664 DD_SURFACE_LOCAL* lpSurfaceLocal = lpGetFlipStatus->lpDDSurface;
1665 DD_SURFACE_GLOBAL* lpSurfaceGlobal = lpSurfaceLocal->lpGbl;
1666 PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC)lpSurfaceGlobal->dwReserved1;
1667
1668 DISPDBG((0, "%s\n", __FUNCTION__));
1669
1670 if(
1671// ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc)
1672// || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst)
1673// ||
1674 ASMAtomicUoReadU32(&pDesc->cPendingFlipsTarg)
1675 || ASMAtomicUoReadU32(&pDesc->cPendingFlipsCurr)
1676 )
1677 {
1678 /* ensure we have host cmds processed to update pending blits and flips */
1679 vboxVHWACommandCheckHostCmds(pDev);
1680
1681 if(
1682 // ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc)
1683 // || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst)
1684 // ||
1685 ASMAtomicUoReadU32(&pDesc->cPendingFlipsTarg)
1686 || ASMAtomicUoReadU32(&pDesc->cPendingFlipsCurr)
1687 )
1688 {
1689 lpGetFlipStatus->ddRVal = DDERR_WASSTILLDRAWING;
1690 }
1691 else
1692 {
1693 lpGetFlipStatus->ddRVal = DD_OK;
1694 }
1695 }
1696 else
1697 {
1698 lpGetFlipStatus->ddRVal = DD_OK;
1699 }
1700
1701// if(lpGetFlipStatus->dwFlags == DDGFS_CANFLIP)
1702// {
1703// lpGetFlipStatus->ddRVal = DD_OK;
1704// }
1705// else
1706// {
1707// lpGetFlipStatus->ddRVal = DD_OK;
1708// }
1709
1710 return DDHAL_DRIVER_HANDLED;
1711}
1712
1713DWORD APIENTRY DdSetOverlayPosition(PDD_SETOVERLAYPOSITIONDATA lpSetOverlayPosition)
1714{
1715 PPDEV pDev = (PPDEV)lpSetOverlayPosition->lpDD->dhpdev;
1716 DD_SURFACE_LOCAL* lpDestSurfaceLocal = lpSetOverlayPosition->lpDDDestSurface;
1717 DD_SURFACE_GLOBAL* lpDestSurfaceGlobal = lpDestSurfaceLocal->lpGbl;
1718 DD_SURFACE_LOCAL* lpSrcSurfaceLocal = lpSetOverlayPosition->lpDDSrcSurface;
1719 DD_SURFACE_GLOBAL* lpSrcSurfaceGlobal = lpSrcSurfaceLocal->lpGbl;
1720 VBOXVHWACMD* pCmd;
1721 PVBOXVHWASURFDESC pSrcDesc = (PVBOXVHWASURFDESC)lpSrcSurfaceGlobal->dwReserved1;
1722 PVBOXVHWASURFDESC pDestDesc = (PVBOXVHWASURFDESC)lpDestSurfaceGlobal->dwReserved1;
1723
1724 DISPDBG((0, "%s\n", __FUNCTION__));
1725
1726 if(!pSrcDesc->bVisible)
1727 {
1728#ifdef DEBUG_misha
1729 AssertBreakpoint();
1730#endif
1731 lpSetOverlayPosition->ddRVal = DDERR_GENERIC;
1732 return DDHAL_DRIVER_HANDLED;
1733 }
1734
1735 pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_OVERLAY_SETPOSITION, sizeof(VBOXVHWACMD_SURF_OVERLAY_SETPOSITION));
1736 // int rc = VERR_GENERAL_FAILURE;
1737 if(pCmd)
1738 {
1739 VBOXVHWACMD_SURF_OVERLAY_SETPOSITION * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_OVERLAY_SETPOSITION);
1740
1741 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_OVERLAY_SETPOSITION));
1742
1743 pBody->u.in.offSrcSurface = vboxVHWAVramOffsetFromPDEV(pDev, lpSrcSurfaceGlobal->fpVidMem);
1744 pBody->u.in.offDstSurface = vboxVHWAVramOffsetFromPDEV(pDev, lpDestSurfaceGlobal->fpVidMem);
1745
1746 pBody->u.in.hDstSurf = pDestDesc->hHostHandle;
1747 pBody->u.in.hSrcSurf = pSrcDesc->hHostHandle;
1748
1749 pBody->u.in.xPos = lpSetOverlayPosition->lXPos;
1750 pBody->u.in.yPos = lpSetOverlayPosition->lYPos;
1751
1752 vboxVHWACommandSubmitAsynchAndComplete(pDev, pCmd);
1753 lpSetOverlayPosition->ddRVal = DD_OK;
1754 }
1755
1756 return DDHAL_DRIVER_HANDLED;
1757}
1758
1759DWORD APIENTRY DdUpdateOverlay(PDD_UPDATEOVERLAYDATA lpUpdateOverlay)
1760{
1761 PPDEV pDev = (PPDEV)lpUpdateOverlay->lpDD->dhpdev;
1762 DD_SURFACE_LOCAL* lpDestSurfaceLocal = lpUpdateOverlay->lpDDDestSurface;
1763 DD_SURFACE_LOCAL* lpSrcSurfaceLocal = lpUpdateOverlay->lpDDSrcSurface;
1764 DD_SURFACE_GLOBAL* lpSrcSurfaceGlobal = lpSrcSurfaceLocal->lpGbl;
1765 VBOXVHWACMD* pCmd;
1766 PVBOXVHWASURFDESC pSrcDesc = (PVBOXVHWASURFDESC)lpSrcSurfaceGlobal->dwReserved1;
1767
1768 DISPDBG((0, "%s\n", __FUNCTION__));
1769
1770// if(!pSrcDesc->bVisible)
1771// {
1772// lpUpdateOverlay->ddRVal = DDERR_GENERIC;
1773// return DDHAL_DRIVER_HANDLED;
1774// }
1775
1776 pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_OVERLAY_UPDATE, sizeof(VBOXVHWACMD_SURF_OVERLAY_UPDATE));
1777 // int rc = VERR_GENERAL_FAILURE;
1778 if(pCmd)
1779 {
1780 VBOXVHWACMD_SURF_OVERLAY_UPDATE * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_OVERLAY_UPDATE);
1781
1782 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_OVERLAY_UPDATE));
1783
1784 pBody->u.in.offSrcSurface = vboxVHWAVramOffsetFromPDEV(pDev, lpSrcSurfaceGlobal->fpVidMem);
1785
1786 pBody->u.in.hSrcSurf = pSrcDesc->hHostHandle;
1787
1788 vboxVHWAFromRECTL(&pBody->u.in.dstRect, &lpUpdateOverlay->rDest);
1789 vboxVHWAFromRECTL(&pBody->u.in.srcRect, &lpUpdateOverlay->rSrc);
1790
1791 pBody->u.in.flags = vboxVHWAFromDDOVERs(lpUpdateOverlay->dwFlags);
1792 vboxVHWAFromDDOVERLAYFX(&pBody->u.in.desc, &lpUpdateOverlay->overlayFX);
1793
1794 if(lpUpdateOverlay->dwFlags & DDOVER_HIDE)
1795 {
1796 pSrcDesc->bVisible = false;
1797 }
1798 else if(lpUpdateOverlay->dwFlags & DDOVER_SHOW)
1799 {
1800 pSrcDesc->bVisible = true;
1801 if(pSrcDesc->UpdatedMemRegion.bValid)
1802 {
1803 pBody->u.in.xFlags = VBOXVHWACMD_SURF_OVERLAY_UPDATE_F_SRCMEMRECT;
1804 vboxVHWAFromRECTL(&pBody->u.in.xUpdatedSrcMemRect, &pSrcDesc->UpdatedMemRegion.Rect);
1805 vboxVHWARegionClear(&pSrcDesc->UpdatedMemRegion);
1806 }
1807 }
1808
1809 if(lpDestSurfaceLocal)
1810 {
1811 DD_SURFACE_GLOBAL* lpDestSurfaceGlobal = lpDestSurfaceLocal->lpGbl;
1812 PVBOXVHWASURFDESC pDestDesc = (PVBOXVHWASURFDESC)lpDestSurfaceGlobal->dwReserved1;
1813 pBody->u.in.hDstSurf = pDestDesc->hHostHandle;
1814 pBody->u.in.offDstSurface = vboxVHWAVramOffsetFromPDEV(pDev, lpDestSurfaceGlobal->fpVidMem);
1815 }
1816
1817 vboxVHWACommandSubmitAsynchAndComplete(pDev, pCmd);
1818 lpUpdateOverlay->ddRVal = DD_OK;
1819 }
1820
1821 return DDHAL_DRIVER_HANDLED;
1822}
1823#else
1824DWORD APIENTRY DdSetColorKey(PDD_SETCOLORKEYDATA lpSetColorKey)
1825{
1826 DISPDBG((0, "%s\n", __FUNCTION__));
1827 lpSetColorKey->ddRVal = DD_OK;
1828 return DDHAL_DRIVER_HANDLED;
1829}
1830
1831DWORD APIENTRY DdAddAttachedSurface(PDD_ADDATTACHEDSURFACEDATA lpAddAttachedSurface)
1832{
1833 DISPDBG((0, "%s\n", __FUNCTION__));
1834 lpAddAttachedSurface->ddRVal = DD_OK;
1835 return DDHAL_DRIVER_HANDLED;
1836}
1837
1838DWORD APIENTRY DdBlt(PDD_BLTDATA lpBlt)
1839{
1840 DISPDBG((0, "%s\n", __FUNCTION__));
1841 lpBlt->ddRVal = DD_OK;
1842 return DDHAL_DRIVER_HANDLED;
1843}
1844
1845//DWORD APIENTRY DdDestroySurface(PDD_DESTROYSURFACEDATA lpDestroySurface)
1846//{
1847// DISPDBG((0, "%s\n", __FUNCTION__));
1848// lpDestroySurface->ddRVal = DD_OK;
1849// return DDHAL_DRIVER_HANDLED;
1850//}
1851
1852DWORD APIENTRY DdFlip(PDD_FLIPDATA lpFlip)
1853{
1854 DISPDBG((0, "%s\n", __FUNCTION__));
1855 lpFlip->ddRVal = DD_OK;
1856 return DDHAL_DRIVER_HANDLED;
1857}
1858
1859DWORD APIENTRY DdGetBltStatus(PDD_GETBLTSTATUSDATA lpGetBltStatus)
1860{
1861 DISPDBG((0, "%s\n", __FUNCTION__));
1862
1863 if(lpGetBltStatus->dwFlags == DDGBS_CANBLT)
1864 {
1865 lpGetBltStatus->ddRVal = DD_OK;
1866 }
1867 else
1868 {
1869 lpGetBltStatus->ddRVal = DD_OK;
1870 }
1871
1872 return DDHAL_DRIVER_HANDLED;
1873}
1874
1875DWORD APIENTRY DdGetFlipStatus(PDD_GETFLIPSTATUSDATA lpGetFlipStatus)
1876{
1877 DISPDBG((0, "%s\n", __FUNCTION__));
1878 if(lpGetFlipStatus->dwFlags == DDGFS_CANFLIP)
1879 {
1880 lpGetFlipStatus->ddRVal = DD_OK;
1881 }
1882 else
1883 {
1884 lpGetFlipStatus->ddRVal = DD_OK;
1885 }
1886
1887 return DDHAL_DRIVER_HANDLED;
1888}
1889
1890DWORD APIENTRY DdSetOverlayPosition(PDD_SETOVERLAYPOSITIONDATA lpSetOverlayPosition)
1891{
1892 DISPDBG((0, "%s\n", __FUNCTION__));
1893
1894 lpSetOverlayPosition->ddRVal = DD_OK;
1895 return DDHAL_DRIVER_HANDLED;
1896}
1897
1898DWORD APIENTRY DdUpdateOverlay(PDD_UPDATEOVERLAYDATA lpUpdateOverlay)
1899{
1900 DISPDBG((0, "%s\n", __FUNCTION__));
1901
1902 lpUpdateOverlay->ddRVal = DD_OK;
1903 return DDHAL_DRIVER_HANDLED;
1904}
1905
1906#endif
1907
1908//-----------------------------------------------------------------------------
1909// setupRops
1910//
1911// Build array for supported ROPS
1912//-----------------------------------------------------------------------------
1913static void
1914setupRops(
1915 LPBYTE proplist,
1916 LPDWORD proptable,
1917 int cnt )
1918{
1919 int i;
1920 DWORD idx;
1921 DWORD bit;
1922 DWORD rop;
1923
1924 for(i=0; i<cnt; i++)
1925 {
1926 rop = proplist[i];
1927 idx = rop / 32;
1928 bit = 1L << ((DWORD)(rop % 32));
1929 proptable[idx] |= bit;
1930 }
1931
1932} // setupRops
1933
1934//-----------------------------------------------------------------------------
1935//
1936// Function: __GetDDHALInfo
1937//
1938// Returns: void
1939//
1940// Description:
1941//
1942// Takes a pointer to a partially or fully filled in pThisDisplay and a pointer
1943// to an empty DDHALINFO and fills in the DDHALINFO. This eases porting to NT
1944// and means that caps changes are done in only one place. The pThisDisplay
1945// may not be fully constructed here, so you should only:
1946// a) Query the registry
1947// b) DISPDBG
1948// If you need to add anything to pThisDisplay for NT, you should fill it in
1949// during the DrvGetDirectDraw call.
1950//
1951// The problem here is when the code is run on NT. If there was any other way...
1952//
1953// The following caps have been found to cause NT to bail....
1954// DDCAPS_GDI, DDFXCAPS_BLTMIRRORUPDOWN, DDFXCAPS_BLTMIRRORLEFTRIGHT
1955//
1956//
1957//-----------------------------------------------------------------------------
1958
1959//
1960// use bits to indicate which ROPs you support.
1961//
1962// DWORD 0, bit 0 == ROP 0
1963// DWORD 8, bit 31 == ROP 255
1964//
1965
1966//static DWORD ropsAGP[DD_ROP_SPACE] = { 0 };
1967static BYTE ropListNT[] =
1968{
1969 SRCCOPY >> 16
1970// WHITENESS >> 16,
1971// BLACKNESS >> 16
1972};
1973
1974static DWORD rops[DD_ROP_SPACE] = { 0 };
1975
1976static bool
1977getDDHALInfo(
1978 PPDEV pDev,
1979 DD_HALINFO* pHALInfo)
1980{
1981 int i;
1982 if(!VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLT) && !VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_OVERLAY))
1983 return false;
1984
1985 pHALInfo->ddCaps.dwCaps |= vboxVHWAToDDCAPS(pDev->vhwaInfo.caps);
1986
1987 if(VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLT))
1988 {
1989 // Setup the ROPS we do.
1990 //TODO: hardcoded for now
1991 setupRops( ropListNT,
1992 rops,
1993 sizeof(ropListNT)/sizeof(ropListNT[0]));
1994
1995 //
1996 // ROPS supported
1997 //
1998 for( i=0;i<DD_ROP_SPACE;i++ )
1999 {
2000 pHALInfo->ddCaps.dwRops[i] = rops[i];
2001 }
2002 }
2003
2004 pHALInfo->ddCaps.ddsCaps.dwCaps |= vboxVHWAToDDSCAPS(pDev->vhwaInfo.surfaceCaps);
2005
2006 pHALInfo->ddCaps.dwCaps2 = vboxVHWAToDDCAPS2(pDev->vhwaInfo.caps2);
2007
2008 if(VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLT)
2009 && VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLTSTRETCH))
2010 {
2011 // Special effects caps
2012 //TODO: filter them out
2013 pHALInfo->ddCaps.dwFXCaps |= DDFXCAPS_BLTSTRETCHY |
2014 DDFXCAPS_BLTSTRETCHX |
2015 DDFXCAPS_BLTSTRETCHYN |
2016 DDFXCAPS_BLTSTRETCHXN |
2017 DDFXCAPS_BLTSHRINKY |
2018 DDFXCAPS_BLTSHRINKX |
2019 DDFXCAPS_BLTSHRINKYN |
2020 DDFXCAPS_BLTSHRINKXN |
2021 DDFXCAPS_BLTARITHSTRETCHY
2022 ;
2023
2024 // DDFXCAPS_BLTARITHSTRETCHY
2025 // DDFXCAPS_BLTARITHSTRETCHYN
2026 // DDFXCAPS_BLTMIRRORLEFTRIGHT
2027 // DDFXCAPS_BLTMIRRORUPDOWN
2028 // DDFXCAPS_BLTROTATION90
2029 }
2030
2031 if(VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_OVERLAY)
2032 && VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_OVERLAYSTRETCH))
2033 {
2034 // Special effects caps
2035 //TODO: filter them out
2036 pHALInfo->ddCaps.dwFXCaps |= DDFXCAPS_OVERLAYSTRETCHY |
2037 DDFXCAPS_OVERLAYSTRETCHX |
2038 DDFXCAPS_OVERLAYSTRETCHYN |
2039 DDFXCAPS_OVERLAYSTRETCHXN |
2040 DDFXCAPS_OVERLAYSHRINKY |
2041 DDFXCAPS_OVERLAYSHRINKX |
2042 DDFXCAPS_OVERLAYSHRINKYN |
2043 DDFXCAPS_OVERLAYSHRINKXN |
2044 DDFXCAPS_OVERLAYARITHSTRETCHY;
2045
2046 // DDFXCAPS_OVERLAYARITHSTRETCHY
2047 // DDFXCAPS_OVERLAYARITHSTRETCHYN
2048 // DDFXCAPS_OVERLAYMIRRORLEFTRIGHT
2049 // DDFXCAPS_OVERLAYMIRRORUPDOWN
2050
2051 }
2052
2053 pHALInfo->ddCaps.dwCKeyCaps = vboxVHWAToDDCKEYCAPS(pDev->vhwaInfo.colorKeyCaps);
2054
2055 pHALInfo->ddCaps.dwSVBFXCaps = 0;
2056
2057
2058 if(VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_OVERLAY)) /* no overlay support for now */
2059 {
2060 // Overlay is free to use.
2061 pHALInfo->ddCaps.dwMaxVisibleOverlays = pDev->vhwaInfo.numOverlays;
2062 pHALInfo->ddCaps.dwCurrVisibleOverlays = 0;
2063
2064 // Indicates that Perm3 has no stretch ratio limitation
2065 pHALInfo->ddCaps.dwMinOverlayStretch = 1;
2066 pHALInfo->ddCaps.dwMaxOverlayStretch = 32000;
2067 }
2068
2069 // Won't do Video-Sys mem Blits.
2070 pHALInfo->ddCaps.dwVSBCaps = 0;
2071 pHALInfo->ddCaps.dwVSBCKeyCaps = 0;
2072 pHALInfo->ddCaps.dwVSBFXCaps = 0;
2073 for( i=0;i<DD_ROP_SPACE;i++ )
2074 {
2075 pHALInfo->ddCaps.dwVSBRops[i] = 0;
2076 }
2077
2078 // Won't do Sys-Sys mem Blits
2079 pHALInfo->ddCaps.dwSSBCaps = 0;
2080 pHALInfo->ddCaps.dwSSBCKeyCaps = 0;
2081 pHALInfo->ddCaps.dwSSBFXCaps = 0;
2082 for( i=0;i<DD_ROP_SPACE;i++ )
2083 {
2084 pHALInfo->ddCaps.dwSSBRops[i] = 0;
2085 }
2086
2087 return true;
2088} // getDDHALInfo
2089
2090static DECLCALLBACK(void) vboxVHWASurfBltCompletion(PPDEV ppdev, VBOXVHWACMD * pCmd, void * pContext)
2091{
2092 VBOXVHWACMD_SURF_BLT * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_BLT);
2093 PVBOXVHWASURFDESC pSrcDesc = (PVBOXVHWASURFDESC)pBody->SrcGuestSurfInfo;
2094 PVBOXVHWASURFDESC pDestDesc = (PVBOXVHWASURFDESC)pBody->DstGuestSurfInfo;
2095
2096 ASMAtomicDecU32(&pSrcDesc->cPendingBltsSrc);
2097 ASMAtomicDecU32(&pDestDesc->cPendingBltsDst);
2098
2099 vbvaVHWACommandRelease(ppdev, pCmd);
2100}
2101
2102static DECLCALLBACK(void) vboxVHWASurfFlipCompletion(PPDEV ppdev, VBOXVHWACMD * pCmd, void * pContext)
2103{
2104 VBOXVHWACMD_SURF_FLIP * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_FLIP);
2105 PVBOXVHWASURFDESC pCurrDesc = (PVBOXVHWASURFDESC)pBody->CurrGuestSurfInfo;
2106 PVBOXVHWASURFDESC pTargDesc = (PVBOXVHWASURFDESC)pBody->TargGuestSurfInfo;
2107
2108 ASMAtomicDecU32(&pCurrDesc->cPendingFlipsCurr);
2109 ASMAtomicDecU32(&pTargDesc->cPendingFlipsTarg);
2110
2111 vbvaVHWACommandRelease(ppdev, pCmd);
2112}
2113
2114#endif
2115
2116
2117
2118#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