1 /* DirectDrawSurface HAL driver
3 * Copyright 2001 TransGaming Technologies Inc.
11 #include "debugtools.h"
12 #include "ddraw_private.h"
13 #include "ddraw/user.h"
14 #include "ddraw/hal.h"
15 #include "dsurface/main.h"
16 #include "dsurface/dib.h"
17 #include "dsurface/user.h"
18 #include "dsurface/hal.h"
20 DEFAULT_DEBUG_CHANNEL(ddraw
);
22 static ICOM_VTABLE(IDirectDrawSurface7
) HAL_IDirectDrawSurface7_VTable
;
24 static HRESULT
HAL_DirectDrawSurface_create_surface(IDirectDrawSurfaceImpl
* This
,
27 HAL_PRIV_VAR(priv
, This
);
28 HAL_DDRAW_PRIV_VAR(ddpriv
, pDD
);
29 LPDDRAWI_DIRECTDRAW_GBL dd_gbl
= pDD
->local
.lpGbl
;
30 LPDDRAWI_DDRAWSURFACE_LCL local
= &This
->local
;
31 DDHAL_CREATESURFACEDATA data
;
35 data
.lpDDSurfaceDesc
= (LPDDSURFACEDESC
)&This
->surface_desc
;
36 data
.lplpSList
= &local
;
39 data
.CreateSurface
= dd_gbl
->lpDDCBtmp
->HALDD
.CreateSurface
;
40 hr
= data
.CreateSurface(&data
);
42 if (hr
== DDHAL_DRIVER_HANDLED
) {
43 if (This
->global
.fpVidMem
< 4) {
44 /* grab framebuffer data from current_mode */
45 priv
->hal
.fb_pitch
= dd_gbl
->vmiData
.lDisplayPitch
;
46 priv
->hal
.fb_vofs
= ddpriv
->hal
.next_vofs
;
47 priv
->hal
.fb_addr
= ((LPBYTE
)dd_gbl
->vmiData
.fpPrimary
) +
48 dd_gbl
->vmiData
.lDisplayPitch
* priv
->hal
.fb_vofs
;
49 TRACE("vofs=%ld, addr=%p\n", priv
->hal
.fb_vofs
, priv
->hal
.fb_addr
);
50 ddpriv
->hal
.next_vofs
+= This
->surface_desc
.dwHeight
;
52 This
->global
.fpVidMem
= (FLATPTR
)priv
->hal
.fb_addr
;
54 This
->surface_desc
.lpSurface
= (LPVOID
)This
->global
.fpVidMem
;
55 This
->surface_desc
.dwFlags
|= DDSD_LPSURFACE
;
56 if (This
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_EXECUTEBUFFER
) {
57 This
->surface_desc
.u1
.dwLinearSize
= This
->global
.u4
.dwLinearSize
;
58 This
->surface_desc
.dwFlags
|= DDSD_LINEARSIZE
;
60 This
->surface_desc
.u1
.lPitch
= This
->global
.u4
.lPitch
;
61 This
->surface_desc
.dwFlags
|= DDSD_PITCH
;
64 else priv
->hal
.need_late
= TRUE
;
69 static inline BOOL
HAL_IsUser(IDirectDrawSurfaceImpl
* This
)
71 HAL_PRIV_VAR(priv
, This
);
72 if (This
->surface_desc
.ddsCaps
.dwCaps
& (DDSCAPS_TEXTURE
| DDSCAPS_EXECUTEBUFFER
))
74 if (priv
->hal
.fb_addr
)
80 HAL_DirectDrawSurface_Construct(IDirectDrawSurfaceImpl
* This
,
82 const DDSURFACEDESC2
* pDDSD
)
84 HAL_PRIV_VAR(priv
, This
);
85 LPDDRAWI_DIRECTDRAW_GBL dd_gbl
= pDD
->local
.lpGbl
;
88 TRACE("(%p,%p,%p)\n",This
,pDD
,pDDSD
);
90 /* copy surface_desc, we may want to modify it before DIB construction */
91 This
->surface_desc
= *pDDSD
;
93 /* the driver may want to dereference these pointers */
94 This
->local
.lpSurfMore
= &This
->more
;
95 This
->local
.lpGbl
= &This
->global
;
96 This
->gmore
= &This
->global_more
;
98 if (This
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_TEXTURE
) {
99 hr
= HAL_DirectDrawSurface_create_surface(This
, pDD
);
100 if (FAILED(hr
)) return hr
;
102 hr
= DIB_DirectDrawSurface_Construct(This
, pDD
, &This
->surface_desc
);
103 if (FAILED(hr
)) return hr
;
105 else if (This
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_EXECUTEBUFFER
) {
106 FIXME("create execute buffer\n");
107 return DDERR_GENERIC
;
110 if (!(dd_gbl
->dwFlags
& DDRAWI_MODECHANGED
)) {
111 /* force a mode set (HALs like DGA may need it) */
112 hr
= HAL_DirectDraw_SetDisplayMode(ICOM_INTERFACE(pDD
, IDirectDraw7
),
113 pDD
->width
, pDD
->height
,
114 pDD
->pixelformat
.u1
.dwRGBBitCount
,
116 if (FAILED(hr
)) return hr
;
119 if (dd_gbl
->vmiData
.fpPrimary
) {
120 hr
= HAL_DirectDrawSurface_create_surface(This
, pDD
);
121 if (FAILED(hr
)) return hr
;
123 if (priv
->hal
.need_late
) {
124 /* this doesn't make sense... driver error? */
125 ERR("driver failed to create framebuffer surface\n");
126 return DDERR_GENERIC
;
129 hr
= DIB_DirectDrawSurface_Construct(This
, pDD
, &This
->surface_desc
);
130 if (FAILED(hr
)) return hr
;
132 /* no framebuffer, construct User-based primary */
133 hr
= User_DirectDrawSurface_Construct(This
, pDD
, pDDSD
);
134 if (FAILED(hr
)) return hr
;
136 /* must notify HAL *after* creating User-based primary */
137 /* (or use CreateSurfaceEx, which we don't yet) */
138 hr
= HAL_DirectDrawSurface_create_surface(This
, pDD
);
139 if (FAILED(hr
)) return hr
;
141 priv
->hal
.need_late
= FALSE
;
145 ICOM_INIT_INTERFACE(This
, IDirectDrawSurface7
,
146 HAL_IDirectDrawSurface7_VTable
);
148 This
->final_release
= HAL_DirectDrawSurface_final_release
;
149 This
->late_allocate
= HAL_DirectDrawSurface_late_allocate
;
150 This
->duplicate_surface
= HAL_DirectDrawSurface_duplicate_surface
;
152 This
->flip_data
= HAL_DirectDrawSurface_flip_data
;
153 This
->flip_update
= HAL_DirectDrawSurface_flip_update
;
155 This
->set_palette
= HAL_DirectDrawSurface_set_palette
;
157 This
->get_display_window
= HAL_DirectDrawSurface_get_display_window
;
163 HAL_DirectDrawSurface_Create(IDirectDrawImpl
*pDD
,
164 const DDSURFACEDESC2
*pDDSD
,
165 LPDIRECTDRAWSURFACE7
*ppSurf
,
168 IDirectDrawSurfaceImpl
* This
;
170 assert(pUnkOuter
== NULL
);
172 This
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
173 sizeof(*This
) + sizeof(HAL_DirectDrawSurfaceImpl
));
174 if (This
== NULL
) return E_OUTOFMEMORY
;
176 This
->private = (HAL_DirectDrawSurfaceImpl
*)(This
+1);
178 hr
= HAL_DirectDrawSurface_Construct(This
, pDD
, pDDSD
);
180 HeapFree(GetProcessHeap(), 0, This
);
182 *ppSurf
= ICOM_INTERFACE(This
, IDirectDrawSurface7
);
187 void HAL_DirectDrawSurface_final_release(IDirectDrawSurfaceImpl
* This
)
189 LPDDRAWI_DIRECTDRAW_GBL dd_gbl
= This
->more
.lpDD_lcl
->lpGbl
;
190 DDHAL_DESTROYSURFACEDATA data
;
192 /* destroy HAL surface */
194 data
.lpDDSurface
= &This
->local
;
196 data
.DestroySurface
= dd_gbl
->lpDDCBtmp
->HALDDSurface
.DestroySurface
;
197 data
.DestroySurface(&data
);
199 if (HAL_IsUser(This
)) {
200 User_DirectDrawSurface_final_release(This
);
202 DIB_DirectDrawSurface_final_release(This
);
206 HRESULT
HAL_DirectDrawSurface_late_allocate(IDirectDrawSurfaceImpl
* This
)
208 HAL_PRIV_VAR(priv
, This
);
209 if (priv
->hal
.need_late
) {
210 priv
->hal
.need_late
= FALSE
;
211 return HAL_DirectDrawSurface_create_surface(This
, This
->ddraw_owner
);
216 void HAL_DirectDrawSurface_set_palette(IDirectDrawSurfaceImpl
* This
,
217 IDirectDrawPaletteImpl
* pal
)
219 LPDDRAWI_DIRECTDRAW_GBL dd_gbl
= This
->more
.lpDD_lcl
->lpGbl
;
220 DDHAL_SETPALETTEDATA data
;
222 DIB_DirectDrawSurface_set_palette(This
, pal
);
224 data
.lpDDSurface
= &This
->local
;
225 data
.lpDDPalette
= &pal
->global
;
227 data
.Attach
= TRUE
; /* what's this? */
228 data
.SetPalette
= dd_gbl
->lpDDCBtmp
->HALDDSurface
.SetPalette
;
230 data
.SetPalette(&data
);
233 HRESULT
HAL_DirectDrawSurface_duplicate_surface(IDirectDrawSurfaceImpl
* This
,
234 LPDIRECTDRAWSURFACE7
* ppDup
)
236 return HAL_DirectDrawSurface_Create(This
->ddraw_owner
,
237 &This
->surface_desc
, ppDup
, NULL
);
240 void HAL_DirectDrawSurface_lock_update(IDirectDrawSurfaceImpl
* This
,
243 if (HAL_IsUser(This
)) {
244 User_DirectDrawSurface_lock_update(This
, pRect
);
246 Main_DirectDrawSurface_lock_update(This
, pRect
);
250 void HAL_DirectDrawSurface_unlock_update(IDirectDrawSurfaceImpl
* This
,
253 if (HAL_IsUser(This
)) {
254 User_DirectDrawSurface_unlock_update(This
, pRect
);
256 Main_DirectDrawSurface_unlock_update(This
, pRect
);
260 BOOL
HAL_DirectDrawSurface_flip_data(IDirectDrawSurfaceImpl
* front
,
261 IDirectDrawSurfaceImpl
* back
,
264 HAL_PRIV_VAR(front_priv
, front
);
265 HAL_PRIV_VAR(back_priv
, back
);
266 LPDDRAWI_DIRECTDRAW_GBL dd_gbl
= front
->more
.lpDD_lcl
->lpGbl
;
272 tmp
= front_priv
->hal
.fb_vofs
;
273 front_priv
->hal
.fb_vofs
= back_priv
->hal
.fb_vofs
;
274 back_priv
->hal
.fb_vofs
= tmp
;
278 tmp
= front_priv
->hal
.fb_addr
;
279 front_priv
->hal
.fb_addr
= back_priv
->hal
.fb_addr
;
280 back_priv
->hal
.fb_addr
= tmp
;
283 if (HAL_IsUser(front
)) {
284 ret
= User_DirectDrawSurface_flip_data(front
, back
, dwFlags
);
286 ret
= DIB_DirectDrawSurface_flip_data(front
, back
, dwFlags
);
290 data
.lpSurfCurr
= &front
->local
;
291 data
.lpSurfTarg
= &back
->local
;
292 data
.lpSurfCurrLeft
= NULL
;
293 data
.lpSurfTargLeft
= NULL
;
294 data
.dwFlags
= dwFlags
;
296 data
.Flip
= dd_gbl
->lpDDCBtmp
->HALDDSurface
.Flip
;
298 if (data
.Flip(&data
) == DDHAL_DRIVER_HANDLED
) ret
= FALSE
;
303 void HAL_DirectDrawSurface_flip_update(IDirectDrawSurfaceImpl
* This
, DWORD dwFlags
)
305 if (HAL_IsUser(This
)) {
306 User_DirectDrawSurface_flip_update(This
, dwFlags
);
310 HWND
HAL_DirectDrawSurface_get_display_window(IDirectDrawSurfaceImpl
* This
)
315 static ICOM_VTABLE(IDirectDrawSurface7
) HAL_IDirectDrawSurface7_VTable
=
317 Main_DirectDrawSurface_QueryInterface
,
318 Main_DirectDrawSurface_AddRef
,
319 Main_DirectDrawSurface_Release
,
320 Main_DirectDrawSurface_AddAttachedSurface
,
321 Main_DirectDrawSurface_AddOverlayDirtyRect
,
322 DIB_DirectDrawSurface_Blt
,
323 Main_DirectDrawSurface_BltBatch
,
324 DIB_DirectDrawSurface_BltFast
,
325 Main_DirectDrawSurface_DeleteAttachedSurface
,
326 Main_DirectDrawSurface_EnumAttachedSurfaces
,
327 Main_DirectDrawSurface_EnumOverlayZOrders
,
328 Main_DirectDrawSurface_Flip
,
329 Main_DirectDrawSurface_GetAttachedSurface
,
330 Main_DirectDrawSurface_GetBltStatus
,
331 Main_DirectDrawSurface_GetCaps
,
332 Main_DirectDrawSurface_GetClipper
,
333 Main_DirectDrawSurface_GetColorKey
,
334 Main_DirectDrawSurface_GetDC
,
335 Main_DirectDrawSurface_GetFlipStatus
,
336 Main_DirectDrawSurface_GetOverlayPosition
,
337 Main_DirectDrawSurface_GetPalette
,
338 Main_DirectDrawSurface_GetPixelFormat
,
339 Main_DirectDrawSurface_GetSurfaceDesc
,
340 Main_DirectDrawSurface_Initialize
,
341 Main_DirectDrawSurface_IsLost
,
342 Main_DirectDrawSurface_Lock
,
343 Main_DirectDrawSurface_ReleaseDC
,
344 DIB_DirectDrawSurface_Restore
,
345 Main_DirectDrawSurface_SetClipper
,
346 Main_DirectDrawSurface_SetColorKey
,
347 Main_DirectDrawSurface_SetOverlayPosition
,
348 Main_DirectDrawSurface_SetPalette
,
349 Main_DirectDrawSurface_Unlock
,
350 Main_DirectDrawSurface_UpdateOverlay
,
351 Main_DirectDrawSurface_UpdateOverlayDisplay
,
352 Main_DirectDrawSurface_UpdateOverlayZOrder
,
353 Main_DirectDrawSurface_GetDDInterface
,
354 Main_DirectDrawSurface_PageLock
,
355 Main_DirectDrawSurface_PageUnlock
,
356 DIB_DirectDrawSurface_SetSurfaceDesc
,
357 Main_DirectDrawSurface_SetPrivateData
,
358 Main_DirectDrawSurface_GetPrivateData
,
359 Main_DirectDrawSurface_FreePrivateData
,
360 Main_DirectDrawSurface_GetUniquenessValue
,
361 Main_DirectDrawSurface_ChangeUniquenessValue
,
362 Main_DirectDrawSurface_SetPriority
,
363 Main_DirectDrawSurface_GetPriority
,
364 Main_DirectDrawSurface_SetLOD
,
365 Main_DirectDrawSurface_GetLOD