VirtualBox

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

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

Automated rebranding to Oracle copyright/license strings via filemuncher

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 71.3 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 && vboxHwBufferBeginUpdate (pDev))
1179 {
1180 vbvaReportDirtyRect (pDev, &pDesc->UpdatedMemRegion.Rect);
1181
1182 if ( pDev->pVBVA->hostFlags.u32HostEvents
1183 & VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET)
1184 {
1185 vrdpReset (pDev);
1186
1187 pDev->pVBVA->hostFlags.u32HostEvents &=
1188 ~VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET;
1189 }
1190
1191 if (pDev->pVBVA->hostFlags.u32HostEvents
1192 & VBVA_F_MODE_VRDP)
1193 {
1194 vrdpReportDirtyRect (pDev, &pDesc->UpdatedMemRegion.Rect);
1195 }
1196
1197 vboxHwBufferEndUpdate (pDev);
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#ifndef VBOX_WITH_HGSMI
1248 if (pDev->pInfo && vboxHwBufferBeginUpdate (pDev))
1249 {
1250 vbvaReportDirtyRect (pDev, &pDev->ddLock.rArea);
1251
1252 if ( pDev->pInfo->hostEvents.fu32Events
1253 & VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET)
1254 {
1255 vrdpReset (pDev);
1256
1257 pDev->pInfo->hostEvents.fu32Events &=
1258 ~VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET;
1259 }
1260
1261 if (pDev->vbva.pVbvaMemory->fu32ModeFlags
1262 & VBVA_F_MODE_VRDP)
1263 {
1264 vrdpReportDirtyRect (pDev, &pDev->ddLock.rArea);
1265 }
1266
1267 vboxHwBufferEndUpdate (pDev);
1268 }
1269#else
1270 if (pDev->bHGSMISupported && vboxHwBufferBeginUpdate (pDev))
1271 {
1272 vbvaReportDirtyRect (pDev, &pDev->ddLock.rArea);
1273
1274 if ( pDev->pVBVA->hostFlags.u32HostEvents
1275 & VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET)
1276 {
1277 vrdpReset (pDev);
1278
1279 pDev->pVBVA->hostFlags.u32HostEvents &=
1280 ~VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET;
1281 }
1282
1283 if (pDev->pVBVA->hostFlags.u32HostEvents
1284 & VBVA_F_MODE_VRDP)
1285 {
1286 vrdpReportDirtyRect (pDev, &pDev->ddLock.rArea);
1287 }
1288
1289 vboxHwBufferEndUpdate (pDev);
1290 }
1291#endif /* VBOX_WITH_HGSMI */
1292
1293 pDev->ddLock.bLocked = FALSE;
1294 }
1295
1296 lpUnlock->ddRVal = DD_OK;
1297 return DDHAL_DRIVER_NOTHANDLED;
1298}
1299
1300/**
1301 * DdDestroySurface
1302 *
1303 * The DdDestroySurface callback function destroys a DirectDraw surface.
1304 *
1305 * Parameters
1306 * lpDestroySurface
1307 * Points to a DD_DESTROYSURFACEDATA structure that contains the information needed to destroy a surface.
1308 *
1309 * Return Value
1310 *
1311 * DdDestroySurface returns one of the following callback codes:
1312 *
1313 * DDHAL_DRIVER_HANDLED
1314 * DDHAL_DRIVER_NOTHANDLED
1315 *
1316 */
1317DWORD APIENTRY DdDestroySurface(PDD_DESTROYSURFACEDATA lpDestroySurface)
1318{
1319#ifdef VBOX_WITH_VIDEOHWACCEL
1320 PPDEV pDev = (PPDEV)lpDestroySurface->lpDD->dhpdev;
1321 if(pDev->vhwaInfo.bVHWAEnabled)
1322 {
1323 DD_SURFACE_LOCAL* lpSurfaceLocal = lpDestroySurface->lpDDSurface;
1324 DD_SURFACE_GLOBAL* lpSurfaceGlobal = lpSurfaceLocal->lpGbl;
1325 VBOXVHWACMD* pCmd;
1326
1327 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
1328
1329 pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_DESTROY, sizeof(VBOXVHWACMD_SURF_DESTROY));
1330 // int rc = VERR_GENERAL_FAILURE;
1331 if(pCmd)
1332 {
1333 VBOXVHWACMD_SURF_DESTROY * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_DESTROY);
1334 PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC)lpSurfaceGlobal->dwReserved1;
1335
1336 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_DESTROY));
1337
1338 pBody->u.in.hSurf = pDesc->hHostHandle;
1339
1340 /* we're not interested in completion, just send the command */
1341 vboxVHWACommandSubmitAsynchAndComplete(pDev, pCmd);
1342
1343 vboxVHWASurfDescFree(pDesc);
1344
1345 lpSurfaceGlobal->dwReserved1 = (ULONG_PTR)NULL;
1346
1347 lpDestroySurface->ddRVal = DD_OK;
1348 }
1349 else
1350 {
1351 lpDestroySurface->ddRVal = DDERR_GENERIC;
1352 }
1353 }
1354 else
1355#endif
1356 lpDestroySurface->ddRVal = DD_OK;
1357
1358 /* we're not managing video memory currently, so return DDHAL_DRIVER_NOTHANDLED */
1359 return DDHAL_DRIVER_NOTHANDLED;
1360}
1361
1362
1363//-----------------------------------------------------------------------------
1364//
1365// DdSetExclusiveMode
1366//
1367// This function is called by DirectDraw when we switch from the GDI surface,
1368// to DirectDraw exclusive mode, e.g. to run a game in fullcreen mode.
1369// You only need to implement this function when you are using the
1370// 'HeapVidMemAllocAligned' function and allocate memory for Device Bitmaps
1371// and DirectDraw surfaces from the same heap.
1372//
1373// We use this call to disable GDI DeviceBitMaps when we are running in
1374// DirectDraw exclusive mode. Otherwise a DD app gets confused if both GDI and
1375// DirectDraw allocate memory from the same heap.
1376//
1377// See also DdFlipToGDISurface.
1378//
1379//-----------------------------------------------------------------------------
1380
1381
1382DWORD APIENTRY DdSetExclusiveMode(PDD_SETEXCLUSIVEMODEDATA lpSetExclusiveMode)
1383{
1384 PPDEV pDev = (PPDEV)lpSetExclusiveMode->lpDD->dhpdev;
1385 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
1386
1387 // remember setting of exclusive mode in pDev,
1388 // so GDI can stop to promote DeviceBitmaps into
1389 // video memory
1390
1391 pDev->bDdExclusiveMode = lpSetExclusiveMode->dwEnterExcl;
1392
1393 lpSetExclusiveMode->ddRVal = DD_OK;
1394
1395 return DDHAL_DRIVER_HANDLED;
1396}
1397
1398//-----------------------------------------------------------------------------
1399//
1400// DWORD DdFlipToGDISurface
1401//
1402// This function is called by DirectDraw when it flips to the surface on which
1403// GDI can write to.
1404//
1405//-----------------------------------------------------------------------------
1406
1407DWORD APIENTRY DdFlipToGDISurface(PDD_FLIPTOGDISURFACEDATA lpFlipToGDISurface)
1408{
1409 PPDEV pDev = (PPDEV)lpFlipToGDISurface->lpDD->dhpdev;
1410 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
1411
1412 pDev->dwNewDDSurfaceOffset = 0xffffffff;
1413
1414 lpFlipToGDISurface->ddRVal = DD_OK;
1415
1416 //
1417 // we return NOTHANDLED, then the ddraw runtime takes
1418 // care that we flip back to the primary...
1419 //
1420 return DDHAL_DRIVER_NOTHANDLED;
1421}
1422//-----------------------------------------------------------------------------
1423//
1424// DWORD DdFreeDriverMemory
1425//
1426// This function called by DirectDraw when it's running low on memory in
1427// our heap. You only need to implement this function if you use the
1428// DirectDraw 'HeapVidMemAllocAligned' function in your driver, and you
1429// can boot those allocations out of memory to make room for DirectDraw.
1430//
1431//-----------------------------------------------------------------------------
1432
1433DWORD APIENTRY DdFreeDriverMemory(PDD_FREEDRIVERMEMORYDATA lpFreeDriverMemory)
1434{
1435 PPDEV pDev = (PPDEV)lpFreeDriverMemory->lpDD->dhpdev;
1436 DISPDBG((0, "%s: %p\n", __FUNCTION__, pDev));
1437
1438 lpFreeDriverMemory->ddRVal = DDERR_OUTOFMEMORY;
1439 return DDHAL_DRIVER_HANDLED;
1440}
1441
1442#ifdef VBOX_WITH_VIDEOHWACCEL
1443#ifndef DBG_DDSTUBS
1444DWORD APIENTRY DdSetColorKey(PDD_SETCOLORKEYDATA lpSetColorKey)
1445{
1446 PPDEV pDev = (PPDEV)lpSetColorKey->lpDD->dhpdev;
1447 DD_SURFACE_LOCAL* lpSurfaceLocal = lpSetColorKey->lpDDSurface;
1448 DD_SURFACE_GLOBAL* lpSurfaceGlobal = lpSurfaceLocal->lpGbl;
1449 VBOXVHWACMD* pCmd;
1450
1451 DISPDBG((0, "%s\n", __FUNCTION__));
1452
1453 pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_COLORKEY_SET, sizeof(VBOXVHWACMD_SURF_COLORKEY_SET));
1454 // int rc = VERR_GENERAL_FAILURE;
1455 if(pCmd)
1456 {
1457 VBOXVHWACMD_SURF_COLORKEY_SET * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_COLORKEY_SET);
1458 PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC)lpSurfaceGlobal->dwReserved1;
1459 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_COLORKEY_SET));
1460
1461 pBody->u.in.offSurface = vboxVHWAVramOffsetFromPDEV(pDev, lpSurfaceGlobal->fpVidMem);
1462 pBody->u.in.hSurf = pDesc->hHostHandle;
1463 pBody->u.in.flags = vboxVHWAFromDDCKEYs(lpSetColorKey->dwFlags);
1464 vboxVHWAFromDDCOLORKEY(&pBody->u.in.CKey, &lpSetColorKey->ckNew);
1465
1466 vboxVHWACommandSubmitAsynchAndComplete(pDev, pCmd);
1467 lpSetColorKey->ddRVal = DD_OK;
1468 }
1469 return DDHAL_DRIVER_HANDLED;
1470}
1471
1472DWORD APIENTRY DdAddAttachedSurface(PDD_ADDATTACHEDSURFACEDATA lpAddAttachedSurface)
1473{
1474 DISPDBG((0, "%s\n", __FUNCTION__));
1475 lpAddAttachedSurface->ddRVal = DD_OK;
1476 return DDHAL_DRIVER_HANDLED;
1477}
1478
1479DWORD APIENTRY DdBlt(PDD_BLTDATA lpBlt)
1480{
1481 PPDEV pDev = (PPDEV)lpBlt->lpDD->dhpdev;
1482 DISPDBG((0, "%s\n", __FUNCTION__));
1483#if DX9_DDI
1484 if(VBOXDD_CHECKFLAG(lpBlt->dwFlags, DDBLT_EXTENDED_PRESENTATION_STRETCHFACTOR))
1485 {
1486 lpBlt->ddRVal = DD_OK;
1487 }
1488 else
1489#endif
1490 {
1491 DD_SURFACE_LOCAL* lpDestSurfaceLocal = lpBlt->lpDDDestSurface;
1492 DD_SURFACE_GLOBAL* lpDestSurfaceGlobal = lpDestSurfaceLocal->lpGbl;
1493 DD_SURFACE_LOCAL* lpSrcSurfaceLocal = lpBlt->lpDDSrcSurface;
1494 DD_SURFACE_GLOBAL* lpSrcSurfaceGlobal = lpSrcSurfaceLocal->lpGbl;
1495 VBOXVHWACMD* pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_BLT, sizeof(VBOXVHWACMD_SURF_BLT));
1496 // int rc = VERR_GENERAL_FAILURE;
1497 if(pCmd)
1498 {
1499 VBOXVHWACMD_SURF_BLT * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_BLT);
1500 PVBOXVHWASURFDESC pSrcDesc = (PVBOXVHWASURFDESC)lpSrcSurfaceGlobal->dwReserved1;
1501 PVBOXVHWASURFDESC pDestDesc = (PVBOXVHWASURFDESC)lpDestSurfaceGlobal->dwReserved1;
1502 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_BLT));
1503
1504 pBody->u.in.offSrcSurface = vboxVHWAVramOffsetFromPDEV(pDev, lpSrcSurfaceGlobal->fpVidMem);
1505 pBody->u.in.offDstSurface = vboxVHWAVramOffsetFromPDEV(pDev, lpDestSurfaceGlobal->fpVidMem);
1506
1507 pBody->u.in.hDstSurf = pDestDesc->hHostHandle;
1508 vboxVHWAFromRECTL(&pBody->u.in.dstRect, &lpBlt->rDest);
1509 pBody->u.in.hSrcSurf = pSrcDesc->hHostHandle;
1510 vboxVHWAFromRECTL(&pBody->u.in.srcRect, &lpBlt->rSrc);
1511 pBody->DstGuestSurfInfo = (uint64_t)pDestDesc;
1512 pBody->SrcGuestSurfInfo = (uint64_t)pSrcDesc;
1513
1514 pBody->u.in.flags = vboxVHWAFromDDBLTs(lpBlt->dwFlags);
1515 vboxVHWAFromDDBLTFX(&pBody->u.in.desc, &lpBlt->bltFX);
1516
1517 ASMAtomicIncU32(&pSrcDesc->cPendingBltsSrc);
1518 ASMAtomicIncU32(&pDestDesc->cPendingBltsDst);
1519
1520 vboxVHWARegionAdd(&pDestDesc->NonupdatedMemRegion, &lpBlt->rDest);
1521 vboxVHWARegionTrySubstitute(&pDestDesc->UpdatedMemRegion, &lpBlt->rDest);
1522
1523 if(pSrcDesc->UpdatedMemRegion.bValid)
1524 {
1525 pBody->u.in.xUpdatedSrcMemValid = 1;
1526 vboxVHWAFromRECTL(&pBody->u.in.xUpdatedSrcMemRect, &pSrcDesc->UpdatedMemRegion.Rect);
1527 vboxVHWARegionClear(&pSrcDesc->UpdatedMemRegion);
1528 }
1529
1530 vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWASurfBltCompletion, NULL);
1531
1532 lpBlt->ddRVal = DD_OK;
1533 }
1534 else
1535 {
1536 lpBlt->ddRVal = DDERR_GENERIC;
1537 }
1538 }
1539
1540 return DDHAL_DRIVER_HANDLED;
1541}
1542
1543//DWORD APIENTRY DdDestroySurface(PDD_DESTROYSURFACEDATA lpDestroySurface)
1544//{
1545// DISPDBG((0, "%s\n", __FUNCTION__));
1546// lpDestroySurface->ddRVal = DD_OK;
1547// return DDHAL_DRIVER_HANDLED;
1548//}
1549
1550DWORD APIENTRY DdFlip(PDD_FLIPDATA lpFlip)
1551{
1552 PPDEV pDev = (PPDEV)lpFlip->lpDD->dhpdev;
1553 DD_SURFACE_LOCAL* lpTargSurfaceLocal = lpFlip->lpSurfTarg;
1554 DD_SURFACE_GLOBAL* lpTargSurfaceGlobal = lpTargSurfaceLocal->lpGbl;
1555 DD_SURFACE_LOCAL* lpCurrSurfaceLocal = lpFlip->lpSurfCurr;
1556 DD_SURFACE_GLOBAL* lpCurrSurfaceGlobal = lpCurrSurfaceLocal->lpGbl;
1557 PVBOXVHWASURFDESC pCurrDesc = (PVBOXVHWASURFDESC)lpCurrSurfaceGlobal->dwReserved1;
1558 PVBOXVHWASURFDESC pTargDesc = (PVBOXVHWASURFDESC)lpTargSurfaceGlobal->dwReserved1;
1559 VBOXVHWACMD* pCmd;
1560
1561 DISPDBG((0, "%s\n", __FUNCTION__));
1562
1563 if(
1564// ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc)
1565// || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst)
1566// ||
1567 ASMAtomicUoReadU32(&pCurrDesc->cPendingFlipsTarg)
1568 || ASMAtomicUoReadU32(&pCurrDesc->cPendingFlipsCurr)
1569 || ASMAtomicUoReadU32(&pTargDesc->cPendingFlipsTarg)
1570 || ASMAtomicUoReadU32(&pTargDesc->cPendingFlipsCurr))
1571 {
1572 /* ensure we have host cmds processed to update pending blits and flips */
1573 vboxVHWACommandCheckHostCmds(pDev);
1574 if(
1575 // ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc)
1576 // || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst)
1577 // ||
1578 ASMAtomicUoReadU32(&pCurrDesc->cPendingFlipsTarg)
1579 || ASMAtomicUoReadU32(&pCurrDesc->cPendingFlipsCurr)
1580 || ASMAtomicUoReadU32(&pTargDesc->cPendingFlipsTarg)
1581 || ASMAtomicUoReadU32(&pTargDesc->cPendingFlipsCurr))
1582 {
1583 lpFlip->ddRVal = DDERR_WASSTILLDRAWING;
1584 return DDHAL_DRIVER_HANDLED;
1585 }
1586 }
1587
1588
1589 pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_FLIP, sizeof(VBOXVHWACMD_SURF_FLIP));
1590 // int rc = VERR_GENERAL_FAILURE;
1591 if(pCmd)
1592 {
1593 VBOXVHWACMD_SURF_FLIP * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_FLIP);
1594
1595 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_FLIP));
1596
1597 pBody->u.in.offCurrSurface = vboxVHWAVramOffsetFromPDEV(pDev, lpCurrSurfaceGlobal->fpVidMem);
1598 pBody->u.in.offTargSurface = vboxVHWAVramOffsetFromPDEV(pDev, lpTargSurfaceGlobal->fpVidMem);
1599
1600 pBody->u.in.hTargSurf = pTargDesc->hHostHandle;
1601 pBody->u.in.hCurrSurf = pCurrDesc->hHostHandle;
1602 pBody->TargGuestSurfInfo = (uint64_t)pTargDesc;
1603 pBody->CurrGuestSurfInfo = (uint64_t)pCurrDesc;
1604
1605 pTargDesc->bVisible = pCurrDesc->bVisible;
1606 pCurrDesc->bVisible = false;
1607
1608// pBody->u.in.flags = vboxVHWAFromDDFLIPs(lpFlip->dwFlags);
1609
1610 ASMAtomicIncU32(&pCurrDesc->cPendingFlipsCurr);
1611 ASMAtomicIncU32(&pTargDesc->cPendingFlipsTarg);
1612#ifdef DEBUG
1613 ASMAtomicIncU32(&pCurrDesc->cFlipsCurr);
1614 ASMAtomicIncU32(&pTargDesc->cFlipsTarg);
1615#endif
1616
1617 if(pTargDesc->UpdatedMemRegion.bValid)
1618 {
1619 pBody->u.in.xUpdatedTargMemValid = 1;
1620 vboxVHWAFromRECTL(&pBody->u.in.xUpdatedTargMemRect, &pTargDesc->UpdatedMemRegion.Rect);
1621 vboxVHWARegionClear(&pTargDesc->UpdatedMemRegion);
1622 }
1623
1624 vboxVHWACommandSubmitAsynch(pDev, pCmd, vboxVHWASurfFlipCompletion, NULL);
1625
1626 lpFlip->ddRVal = DD_OK;
1627 }
1628 else
1629 {
1630 lpFlip->ddRVal = DDERR_GENERIC;
1631 }
1632 return DDHAL_DRIVER_HANDLED;
1633}
1634
1635DWORD APIENTRY DdGetBltStatus(PDD_GETBLTSTATUSDATA lpGetBltStatus)
1636{
1637 PPDEV pDev = (PPDEV)lpGetBltStatus->lpDD->dhpdev;
1638
1639 DISPDBG((0, "%s\n", __FUNCTION__));
1640
1641 if(lpGetBltStatus->dwFlags == DDGBS_CANBLT)
1642 {
1643 lpGetBltStatus->ddRVal = DD_OK;
1644 }
1645 else /* DDGBS_ISBLTDONE */
1646 {
1647 DD_SURFACE_LOCAL* lpSurfaceLocal = lpGetBltStatus->lpDDSurface;
1648 DD_SURFACE_GLOBAL* lpSurfaceGlobal = lpSurfaceLocal->lpGbl;
1649 PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC)lpSurfaceGlobal->dwReserved1;
1650
1651 if(
1652 ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc)
1653 || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst)
1654 // || ASMAtomicUoReadU32(&pDesc->cPendingFlipsTarg)
1655 // || ASMAtomicUoReadU32(&pDesc->cPendingFlipsCurr)
1656 )
1657 {
1658 /* ensure we have host cmds processed to update pending blits and flips */
1659 vboxVHWACommandCheckHostCmds(pDev);
1660
1661 if(
1662 ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc)
1663 || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst)
1664 // || ASMAtomicUoReadU32(&pDesc->cPendingFlipsTarg)
1665 // || ASMAtomicUoReadU32(&pDesc->cPendingFlipsCurr)
1666 )
1667 {
1668 lpGetBltStatus->ddRVal = DDERR_WASSTILLDRAWING;
1669 }
1670 else
1671 {
1672 lpGetBltStatus->ddRVal = DD_OK;
1673 }
1674 }
1675 else
1676 {
1677 lpGetBltStatus->ddRVal = DD_OK;
1678 }
1679 }
1680
1681 return DDHAL_DRIVER_HANDLED;
1682}
1683
1684DWORD APIENTRY DdGetFlipStatus(PDD_GETFLIPSTATUSDATA lpGetFlipStatus)
1685{
1686 PPDEV pDev = (PPDEV)lpGetFlipStatus->lpDD->dhpdev;
1687 DD_SURFACE_LOCAL* lpSurfaceLocal = lpGetFlipStatus->lpDDSurface;
1688 DD_SURFACE_GLOBAL* lpSurfaceGlobal = lpSurfaceLocal->lpGbl;
1689 PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC)lpSurfaceGlobal->dwReserved1;
1690
1691 DISPDBG((0, "%s\n", __FUNCTION__));
1692
1693 if(
1694// ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc)
1695// || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst)
1696// ||
1697 ASMAtomicUoReadU32(&pDesc->cPendingFlipsTarg)
1698 || ASMAtomicUoReadU32(&pDesc->cPendingFlipsCurr)
1699 )
1700 {
1701 /* ensure we have host cmds processed to update pending blits and flips */
1702 vboxVHWACommandCheckHostCmds(pDev);
1703
1704 if(
1705 // ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc)
1706 // || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst)
1707 // ||
1708 ASMAtomicUoReadU32(&pDesc->cPendingFlipsTarg)
1709 || ASMAtomicUoReadU32(&pDesc->cPendingFlipsCurr)
1710 )
1711 {
1712 lpGetFlipStatus->ddRVal = DDERR_WASSTILLDRAWING;
1713 }
1714 else
1715 {
1716 lpGetFlipStatus->ddRVal = DD_OK;
1717 }
1718 }
1719 else
1720 {
1721 lpGetFlipStatus->ddRVal = DD_OK;
1722 }
1723
1724// if(lpGetFlipStatus->dwFlags == DDGFS_CANFLIP)
1725// {
1726// lpGetFlipStatus->ddRVal = DD_OK;
1727// }
1728// else
1729// {
1730// lpGetFlipStatus->ddRVal = DD_OK;
1731// }
1732
1733 return DDHAL_DRIVER_HANDLED;
1734}
1735
1736DWORD APIENTRY DdSetOverlayPosition(PDD_SETOVERLAYPOSITIONDATA lpSetOverlayPosition)
1737{
1738 PPDEV pDev = (PPDEV)lpSetOverlayPosition->lpDD->dhpdev;
1739 DD_SURFACE_LOCAL* lpDestSurfaceLocal = lpSetOverlayPosition->lpDDDestSurface;
1740 DD_SURFACE_GLOBAL* lpDestSurfaceGlobal = lpDestSurfaceLocal->lpGbl;
1741 DD_SURFACE_LOCAL* lpSrcSurfaceLocal = lpSetOverlayPosition->lpDDSrcSurface;
1742 DD_SURFACE_GLOBAL* lpSrcSurfaceGlobal = lpSrcSurfaceLocal->lpGbl;
1743 VBOXVHWACMD* pCmd;
1744 PVBOXVHWASURFDESC pSrcDesc = (PVBOXVHWASURFDESC)lpSrcSurfaceGlobal->dwReserved1;
1745 PVBOXVHWASURFDESC pDestDesc = (PVBOXVHWASURFDESC)lpDestSurfaceGlobal->dwReserved1;
1746
1747 DISPDBG((0, "%s\n", __FUNCTION__));
1748
1749 if(!pSrcDesc->bVisible)
1750 {
1751#ifdef DEBUG_misha
1752 AssertBreakpoint();
1753#endif
1754 lpSetOverlayPosition->ddRVal = DDERR_GENERIC;
1755 return DDHAL_DRIVER_HANDLED;
1756 }
1757
1758 pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_OVERLAY_SETPOSITION, sizeof(VBOXVHWACMD_SURF_OVERLAY_SETPOSITION));
1759 // int rc = VERR_GENERAL_FAILURE;
1760 if(pCmd)
1761 {
1762 VBOXVHWACMD_SURF_OVERLAY_SETPOSITION * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_OVERLAY_SETPOSITION);
1763
1764 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_OVERLAY_SETPOSITION));
1765
1766 pBody->u.in.offSrcSurface = vboxVHWAVramOffsetFromPDEV(pDev, lpSrcSurfaceGlobal->fpVidMem);
1767 pBody->u.in.offDstSurface = vboxVHWAVramOffsetFromPDEV(pDev, lpDestSurfaceGlobal->fpVidMem);
1768
1769 pBody->u.in.hDstSurf = pDestDesc->hHostHandle;
1770 pBody->u.in.hSrcSurf = pSrcDesc->hHostHandle;
1771
1772 pBody->u.in.xPos = lpSetOverlayPosition->lXPos;
1773 pBody->u.in.yPos = lpSetOverlayPosition->lYPos;
1774
1775 vboxVHWACommandSubmitAsynchAndComplete(pDev, pCmd);
1776 lpSetOverlayPosition->ddRVal = DD_OK;
1777 }
1778
1779 return DDHAL_DRIVER_HANDLED;
1780}
1781
1782DWORD APIENTRY DdUpdateOverlay(PDD_UPDATEOVERLAYDATA lpUpdateOverlay)
1783{
1784 PPDEV pDev = (PPDEV)lpUpdateOverlay->lpDD->dhpdev;
1785 DD_SURFACE_LOCAL* lpDestSurfaceLocal = lpUpdateOverlay->lpDDDestSurface;
1786 DD_SURFACE_LOCAL* lpSrcSurfaceLocal = lpUpdateOverlay->lpDDSrcSurface;
1787 DD_SURFACE_GLOBAL* lpSrcSurfaceGlobal = lpSrcSurfaceLocal->lpGbl;
1788 VBOXVHWACMD* pCmd;
1789 PVBOXVHWASURFDESC pSrcDesc = (PVBOXVHWASURFDESC)lpSrcSurfaceGlobal->dwReserved1;
1790
1791 DISPDBG((0, "%s\n", __FUNCTION__));
1792
1793// if(!pSrcDesc->bVisible)
1794// {
1795// lpUpdateOverlay->ddRVal = DDERR_GENERIC;
1796// return DDHAL_DRIVER_HANDLED;
1797// }
1798
1799 pCmd = vboxVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_OVERLAY_UPDATE, sizeof(VBOXVHWACMD_SURF_OVERLAY_UPDATE));
1800 // int rc = VERR_GENERAL_FAILURE;
1801 if(pCmd)
1802 {
1803 VBOXVHWACMD_SURF_OVERLAY_UPDATE * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_OVERLAY_UPDATE);
1804
1805 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_OVERLAY_UPDATE));
1806
1807 pBody->u.in.offSrcSurface = vboxVHWAVramOffsetFromPDEV(pDev, lpSrcSurfaceGlobal->fpVidMem);
1808
1809 pBody->u.in.hSrcSurf = pSrcDesc->hHostHandle;
1810
1811 vboxVHWAFromRECTL(&pBody->u.in.dstRect, &lpUpdateOverlay->rDest);
1812 vboxVHWAFromRECTL(&pBody->u.in.srcRect, &lpUpdateOverlay->rSrc);
1813
1814 pBody->u.in.flags = vboxVHWAFromDDOVERs(lpUpdateOverlay->dwFlags);
1815 vboxVHWAFromDDOVERLAYFX(&pBody->u.in.desc, &lpUpdateOverlay->overlayFX);
1816
1817 if(lpUpdateOverlay->dwFlags & DDOVER_HIDE)
1818 {
1819 pSrcDesc->bVisible = false;
1820 }
1821 else if(lpUpdateOverlay->dwFlags & DDOVER_SHOW)
1822 {
1823 pSrcDesc->bVisible = true;
1824 if(pSrcDesc->UpdatedMemRegion.bValid)
1825 {
1826 pBody->u.in.xUpdatedSrcMemValid = 1;
1827 vboxVHWAFromRECTL(&pBody->u.in.xUpdatedSrcMemRect, &pSrcDesc->UpdatedMemRegion.Rect);
1828 vboxVHWARegionClear(&pSrcDesc->UpdatedMemRegion);
1829 }
1830 }
1831
1832 if(lpDestSurfaceLocal)
1833 {
1834 DD_SURFACE_GLOBAL* lpDestSurfaceGlobal = lpDestSurfaceLocal->lpGbl;
1835 PVBOXVHWASURFDESC pDestDesc = (PVBOXVHWASURFDESC)lpDestSurfaceGlobal->dwReserved1;
1836 pBody->u.in.hDstSurf = pDestDesc->hHostHandle;
1837 pBody->u.in.offDstSurface = vboxVHWAVramOffsetFromPDEV(pDev, lpDestSurfaceGlobal->fpVidMem);
1838 }
1839
1840 vboxVHWACommandSubmitAsynchAndComplete(pDev, pCmd);
1841 lpUpdateOverlay->ddRVal = DD_OK;
1842 }
1843
1844 return DDHAL_DRIVER_HANDLED;
1845}
1846#else
1847DWORD APIENTRY DdSetColorKey(PDD_SETCOLORKEYDATA lpSetColorKey)
1848{
1849 DISPDBG((0, "%s\n", __FUNCTION__));
1850 lpSetColorKey->ddRVal = DD_OK;
1851 return DDHAL_DRIVER_HANDLED;
1852}
1853
1854DWORD APIENTRY DdAddAttachedSurface(PDD_ADDATTACHEDSURFACEDATA lpAddAttachedSurface)
1855{
1856 DISPDBG((0, "%s\n", __FUNCTION__));
1857 lpAddAttachedSurface->ddRVal = DD_OK;
1858 return DDHAL_DRIVER_HANDLED;
1859}
1860
1861DWORD APIENTRY DdBlt(PDD_BLTDATA lpBlt)
1862{
1863 DISPDBG((0, "%s\n", __FUNCTION__));
1864 lpBlt->ddRVal = DD_OK;
1865 return DDHAL_DRIVER_HANDLED;
1866}
1867
1868//DWORD APIENTRY DdDestroySurface(PDD_DESTROYSURFACEDATA lpDestroySurface)
1869//{
1870// DISPDBG((0, "%s\n", __FUNCTION__));
1871// lpDestroySurface->ddRVal = DD_OK;
1872// return DDHAL_DRIVER_HANDLED;
1873//}
1874
1875DWORD APIENTRY DdFlip(PDD_FLIPDATA lpFlip)
1876{
1877 DISPDBG((0, "%s\n", __FUNCTION__));
1878 lpFlip->ddRVal = DD_OK;
1879 return DDHAL_DRIVER_HANDLED;
1880}
1881
1882DWORD APIENTRY DdGetBltStatus(PDD_GETBLTSTATUSDATA lpGetBltStatus)
1883{
1884 DISPDBG((0, "%s\n", __FUNCTION__));
1885
1886 if(lpGetBltStatus->dwFlags == DDGBS_CANBLT)
1887 {
1888 lpGetBltStatus->ddRVal = DD_OK;
1889 }
1890 else
1891 {
1892 lpGetBltStatus->ddRVal = DD_OK;
1893 }
1894
1895 return DDHAL_DRIVER_HANDLED;
1896}
1897
1898DWORD APIENTRY DdGetFlipStatus(PDD_GETFLIPSTATUSDATA lpGetFlipStatus)
1899{
1900 DISPDBG((0, "%s\n", __FUNCTION__));
1901 if(lpGetFlipStatus->dwFlags == DDGFS_CANFLIP)
1902 {
1903 lpGetFlipStatus->ddRVal = DD_OK;
1904 }
1905 else
1906 {
1907 lpGetFlipStatus->ddRVal = DD_OK;
1908 }
1909
1910 return DDHAL_DRIVER_HANDLED;
1911}
1912
1913DWORD APIENTRY DdSetOverlayPosition(PDD_SETOVERLAYPOSITIONDATA lpSetOverlayPosition)
1914{
1915 DISPDBG((0, "%s\n", __FUNCTION__));
1916
1917 lpSetOverlayPosition->ddRVal = DD_OK;
1918 return DDHAL_DRIVER_HANDLED;
1919}
1920
1921DWORD APIENTRY DdUpdateOverlay(PDD_UPDATEOVERLAYDATA lpUpdateOverlay)
1922{
1923 DISPDBG((0, "%s\n", __FUNCTION__));
1924
1925 lpUpdateOverlay->ddRVal = DD_OK;
1926 return DDHAL_DRIVER_HANDLED;
1927}
1928
1929#endif
1930
1931//-----------------------------------------------------------------------------
1932// setupRops
1933//
1934// Build array for supported ROPS
1935//-----------------------------------------------------------------------------
1936static void
1937setupRops(
1938 LPBYTE proplist,
1939 LPDWORD proptable,
1940 int cnt )
1941{
1942 int i;
1943 DWORD idx;
1944 DWORD bit;
1945 DWORD rop;
1946
1947 for(i=0; i<cnt; i++)
1948 {
1949 rop = proplist[i];
1950 idx = rop / 32;
1951 bit = 1L << ((DWORD)(rop % 32));
1952 proptable[idx] |= bit;
1953 }
1954
1955} // setupRops
1956
1957//-----------------------------------------------------------------------------
1958//
1959// Function: __GetDDHALInfo
1960//
1961// Returns: void
1962//
1963// Description:
1964//
1965// Takes a pointer to a partially or fully filled in pThisDisplay and a pointer
1966// to an empty DDHALINFO and fills in the DDHALINFO. This eases porting to NT
1967// and means that caps changes are done in only one place. The pThisDisplay
1968// may not be fully constructed here, so you should only:
1969// a) Query the registry
1970// b) DISPDBG
1971// If you need to add anything to pThisDisplay for NT, you should fill it in
1972// during the DrvGetDirectDraw call.
1973//
1974// The problem here is when the code is run on NT. If there was any other way...
1975//
1976// The following caps have been found to cause NT to bail....
1977// DDCAPS_GDI, DDFXCAPS_BLTMIRRORUPDOWN, DDFXCAPS_BLTMIRRORLEFTRIGHT
1978//
1979//
1980//-----------------------------------------------------------------------------
1981
1982//
1983// use bits to indicate which ROPs you support.
1984//
1985// DWORD 0, bit 0 == ROP 0
1986// DWORD 8, bit 31 == ROP 255
1987//
1988
1989//static DWORD ropsAGP[DD_ROP_SPACE] = { 0 };
1990static BYTE ropListNT[] =
1991{
1992 SRCCOPY >> 16
1993// WHITENESS >> 16,
1994// BLACKNESS >> 16
1995};
1996
1997static DWORD rops[DD_ROP_SPACE] = { 0 };
1998
1999static bool
2000getDDHALInfo(
2001 PPDEV pDev,
2002 DD_HALINFO* pHALInfo)
2003{
2004 int i;
2005 if(!VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLT) && !VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_OVERLAY))
2006 return false;
2007
2008 pHALInfo->ddCaps.dwCaps |= vboxVHWAToDDCAPS(pDev->vhwaInfo.caps);
2009
2010 if(VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLT))
2011 {
2012 // Setup the ROPS we do.
2013 //TODO: hardcoded for now
2014 setupRops( ropListNT,
2015 rops,
2016 sizeof(ropListNT)/sizeof(ropListNT[0]));
2017
2018 //
2019 // ROPS supported
2020 //
2021 for( i=0;i<DD_ROP_SPACE;i++ )
2022 {
2023 pHALInfo->ddCaps.dwRops[i] = rops[i];
2024 }
2025 }
2026
2027 pHALInfo->ddCaps.ddsCaps.dwCaps |= vboxVHWAToDDSCAPS(pDev->vhwaInfo.surfaceCaps);
2028
2029 pHALInfo->ddCaps.dwCaps2 = vboxVHWAToDDCAPS2(pDev->vhwaInfo.caps2);
2030
2031 if(VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLT)
2032 && VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLTSTRETCH))
2033 {
2034 // Special effects caps
2035 //TODO: filter them out
2036 pHALInfo->ddCaps.dwFXCaps |= DDFXCAPS_BLTSTRETCHY |
2037 DDFXCAPS_BLTSTRETCHX |
2038 DDFXCAPS_BLTSTRETCHYN |
2039 DDFXCAPS_BLTSTRETCHXN |
2040 DDFXCAPS_BLTSHRINKY |
2041 DDFXCAPS_BLTSHRINKX |
2042 DDFXCAPS_BLTSHRINKYN |
2043 DDFXCAPS_BLTSHRINKXN |
2044 DDFXCAPS_BLTARITHSTRETCHY
2045 ;
2046
2047 // DDFXCAPS_BLTARITHSTRETCHY
2048 // DDFXCAPS_BLTARITHSTRETCHYN
2049 // DDFXCAPS_BLTMIRRORLEFTRIGHT
2050 // DDFXCAPS_BLTMIRRORUPDOWN
2051 // DDFXCAPS_BLTROTATION90
2052 }
2053
2054 if(VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_OVERLAY)
2055 && VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_OVERLAYSTRETCH))
2056 {
2057 // Special effects caps
2058 //TODO: filter them out
2059 pHALInfo->ddCaps.dwFXCaps |= DDFXCAPS_OVERLAYSTRETCHY |
2060 DDFXCAPS_OVERLAYSTRETCHX |
2061 DDFXCAPS_OVERLAYSTRETCHYN |
2062 DDFXCAPS_OVERLAYSTRETCHXN |
2063 DDFXCAPS_OVERLAYSHRINKY |
2064 DDFXCAPS_OVERLAYSHRINKX |
2065 DDFXCAPS_OVERLAYSHRINKYN |
2066 DDFXCAPS_OVERLAYSHRINKXN |
2067 DDFXCAPS_OVERLAYARITHSTRETCHY;
2068
2069 // DDFXCAPS_OVERLAYARITHSTRETCHY
2070 // DDFXCAPS_OVERLAYARITHSTRETCHYN
2071 // DDFXCAPS_OVERLAYMIRRORLEFTRIGHT
2072 // DDFXCAPS_OVERLAYMIRRORUPDOWN
2073
2074 }
2075
2076 pHALInfo->ddCaps.dwCKeyCaps = vboxVHWAToDDCKEYCAPS(pDev->vhwaInfo.colorKeyCaps);
2077
2078 pHALInfo->ddCaps.dwSVBFXCaps = 0;
2079
2080
2081 if(VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_OVERLAY)) /* no overlay support for now */
2082 {
2083 // Overlay is free to use.
2084 pHALInfo->ddCaps.dwMaxVisibleOverlays = pDev->vhwaInfo.numOverlays;
2085 pHALInfo->ddCaps.dwCurrVisibleOverlays = 0;
2086
2087 // Indicates that Perm3 has no stretch ratio limitation
2088 pHALInfo->ddCaps.dwMinOverlayStretch = 1;
2089 pHALInfo->ddCaps.dwMaxOverlayStretch = 32000;
2090 }
2091
2092 // Won't do Video-Sys mem Blits.
2093 pHALInfo->ddCaps.dwVSBCaps = 0;
2094 pHALInfo->ddCaps.dwVSBCKeyCaps = 0;
2095 pHALInfo->ddCaps.dwVSBFXCaps = 0;
2096 for( i=0;i<DD_ROP_SPACE;i++ )
2097 {
2098 pHALInfo->ddCaps.dwVSBRops[i] = 0;
2099 }
2100
2101 // Won't do Sys-Sys mem Blits
2102 pHALInfo->ddCaps.dwSSBCaps = 0;
2103 pHALInfo->ddCaps.dwSSBCKeyCaps = 0;
2104 pHALInfo->ddCaps.dwSSBFXCaps = 0;
2105 for( i=0;i<DD_ROP_SPACE;i++ )
2106 {
2107 pHALInfo->ddCaps.dwSSBRops[i] = 0;
2108 }
2109
2110 return true;
2111} // getDDHALInfo
2112
2113static DECLCALLBACK(void) vboxVHWASurfBltCompletion(PPDEV ppdev, VBOXVHWACMD * pCmd, void * pContext)
2114{
2115 VBOXVHWACMD_SURF_BLT * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_BLT);
2116 PVBOXVHWASURFDESC pSrcDesc = (PVBOXVHWASURFDESC)pBody->SrcGuestSurfInfo;
2117 PVBOXVHWASURFDESC pDestDesc = (PVBOXVHWASURFDESC)pBody->DstGuestSurfInfo;
2118
2119 ASMAtomicDecU32(&pSrcDesc->cPendingBltsSrc);
2120 ASMAtomicDecU32(&pDestDesc->cPendingBltsDst);
2121
2122 vbvaVHWACommandRelease(ppdev, pCmd);
2123}
2124
2125static DECLCALLBACK(void) vboxVHWASurfFlipCompletion(PPDEV ppdev, VBOXVHWACMD * pCmd, void * pContext)
2126{
2127 VBOXVHWACMD_SURF_FLIP * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_FLIP);
2128 PVBOXVHWASURFDESC pCurrDesc = (PVBOXVHWASURFDESC)pBody->CurrGuestSurfInfo;
2129 PVBOXVHWASURFDESC pTargDesc = (PVBOXVHWASURFDESC)pBody->TargGuestSurfInfo;
2130
2131 ASMAtomicDecU32(&pCurrDesc->cPendingFlipsCurr);
2132 ASMAtomicDecU32(&pTargDesc->cPendingFlipsTarg);
2133
2134 vbvaVHWACommandRelease(ppdev, pCmd);
2135}
2136
2137#endif
2138
2139
2140
2141#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