1 /* DirectDraw Surface Implementation
3 * Copyright (c) 1997-2000 Marcus Meissner
4 * Copyright (c) 1998-2000 Lionel Ulmer
5 * Copyright (c) 2000-2001 TransGaming Technologies Inc.
6 * Copyright (c) 2006 Stefan Dösinger
7 * Copyright (c) 2011 Ričardas Barkauskas for CodeWeavers
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include "ddraw_private.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(ddraw
);
28 static struct ddraw_surface
*unsafe_impl_from_IDirectDrawSurface2(IDirectDrawSurface2
*iface
);
29 static struct ddraw_surface
*unsafe_impl_from_IDirectDrawSurface3(IDirectDrawSurface3
*iface
);
31 static inline struct ddraw_surface
*impl_from_IDirectDrawGammaControl(IDirectDrawGammaControl
*iface
)
33 return CONTAINING_RECORD(iface
, struct ddraw_surface
, IDirectDrawGammaControl_iface
);
36 static BOOL
ddraw_surface_is_lost(const struct ddraw_surface
*surface
)
38 return ddraw_surface_can_be_lost(surface
)
39 && (surface
->ddraw
->device_state
!= DDRAW_DEVICE_STATE_OK
|| surface
->is_lost
);
42 static BOOL
ddraw_gdi_is_front(struct ddraw
*ddraw
)
44 struct ddraw_surface
*surface
;
46 if (!ddraw
->gdi_surface
|| !(surface
= wined3d_texture_get_sub_resource_parent(ddraw
->gdi_surface
, 0)))
49 return surface
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_FRONTBUFFER
;
52 /* This is slow, of course. Also, in case of locks, we can't prevent other
53 * applications from drawing to the screen while we've locked the frontbuffer.
54 * We'd like to do this in wined3d instead, but for that to work wined3d needs
55 * to support windowless rendering first. */
56 HRESULT
ddraw_surface_update_frontbuffer(struct ddraw_surface
*surface
,
57 const RECT
*rect
, BOOL read
, unsigned int swap_interval
)
59 struct ddraw
*ddraw
= surface
->ddraw
;
60 struct wined3d_texture
*dst_texture
;
61 HDC surface_dc
, screen_dc
;
67 if (ddraw
->flags
& DDRAW_SWAPPED
&& !read
)
69 ddraw
->flags
&= ~DDRAW_SWAPPED
;
75 SetRect(&r
, 0, 0, surface
->surface_desc
.dwWidth
, surface
->surface_desc
.dwHeight
);
81 w
= rect
->right
- rect
->left
;
82 h
= rect
->bottom
- rect
->top
;
87 /* The interaction between ddraw and GDI drawing is not all that well
88 * documented, and somewhat arcane. In ddraw exclusive mode, GDI draws
89 * seemingly go to the *original* frontbuffer/primary surface, while ddraw
90 * draws/flips go to the *current* frontbuffer surface. The bottom line is
91 * that if the current frontbuffer is not the GDI frontbuffer, and there's
92 * e.g. a popup window in front of the ddraw swapchain window, we can't
93 * use wined3d_swapchain_present() to get the ddraw contents to the screen
94 * while in exclusive mode, since it would get obscured by the popup
95 * window. On the other hand, if the current frontbuffer *is* the GDI
96 * frontbuffer, that's what's supposed to happen; the popup should obscure
97 * (oart of) the ddraw swapchain window.
99 * This affects the "Deer Hunter" demo, which uses a popup window and GDI
100 * draws to draw part of the user interface. See also the "fswindow"
101 * sample is the DirectX 7 SDK. */
102 if (ddraw
->swapchain_window
&& (!(ddraw
->cooperative_level
& DDSCL_EXCLUSIVE
)
103 || ddraw
->swapchain_window
== GetForegroundWindow() || ddraw_gdi_is_front(ddraw
)))
105 /* Nothing to do, we control the frontbuffer, or at least the parts we
111 dst_texture
= wined3d_swapchain_get_back_buffer(ddraw
->wined3d_swapchain
, 0);
113 dst_texture
= ddraw
->wined3d_frontbuffer
;
115 if (SUCCEEDED(hr
= wined3d_texture_blt(dst_texture
, 0, rect
, surface
->wined3d_texture
,
116 surface
->sub_resource_idx
, rect
, 0, NULL
, WINED3D_TEXF_POINT
)) && swap_interval
)
118 hr
= wined3d_swapchain_present(ddraw
->wined3d_swapchain
, rect
, rect
, NULL
, swap_interval
, 0);
119 ddraw
->flags
|= DDRAW_SWAPPED
;
124 if (FAILED(hr
= wined3d_texture_get_dc(surface
->wined3d_texture
, surface
->sub_resource_idx
, &surface_dc
)))
126 ERR("Failed to get surface DC, hr %#x.\n", hr
);
129 if (surface
->palette
)
130 wined3d_palette_apply_to_dc(surface
->palette
->wined3d_palette
, surface_dc
);
132 if (!(screen_dc
= GetDC(NULL
)))
134 wined3d_texture_release_dc(surface
->wined3d_texture
, surface
->sub_resource_idx
, surface_dc
);
135 ERR("Failed to get screen DC.\n");
140 ret
= BitBlt(surface_dc
, x
, y
, w
, h
,
141 screen_dc
, x
, y
, SRCCOPY
);
143 ret
= BitBlt(screen_dc
, x
, y
, w
, h
,
144 surface_dc
, x
, y
, SRCCOPY
);
146 ReleaseDC(NULL
, screen_dc
);
147 wined3d_texture_release_dc(surface
->wined3d_texture
, surface
->sub_resource_idx
, surface_dc
);
151 ERR("Failed to blit to/from screen.\n");
158 /*****************************************************************************
159 * IUnknown parts follow
160 *****************************************************************************/
162 /*****************************************************************************
163 * IDirectDrawSurface7::QueryInterface
165 * A normal QueryInterface implementation. For QueryInterface rules
166 * see ddraw.c, IDirectDraw7::QueryInterface. This method
167 * can Query IDirectDrawSurface interfaces in all version, IDirect3DTexture
168 * in all versions, the IDirectDrawGammaControl interface and it can
169 * create an IDirect3DDevice. (Uses IDirect3D7::CreateDevice)
172 * riid: The interface id queried for
173 * obj: Address to write the pointer to
177 * E_NOINTERFACE if the requested interface wasn't found
179 *****************************************************************************/
180 static HRESULT WINAPI
ddraw_surface7_QueryInterface(IDirectDrawSurface7
*iface
, REFIID riid
, void **obj
)
182 struct ddraw_surface
*This
= impl_from_IDirectDrawSurface7(iface
);
184 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), obj
);
186 /* According to COM docs, if the QueryInterface fails, obj should be set to NULL */
190 return DDERR_INVALIDPARAMS
;
192 if (IsEqualGUID(riid
, &IID_IDirectDrawSurface7
))
194 IDirectDrawSurface7_AddRef(iface
);
196 TRACE("(%p) returning IDirectDrawSurface7 interface at %p\n", This
, *obj
);
200 if (IsEqualGUID(riid
, &IID_IDirectDrawSurface4
))
202 IDirectDrawSurface4_AddRef(&This
->IDirectDrawSurface4_iface
);
203 *obj
= &This
->IDirectDrawSurface4_iface
;
204 TRACE("(%p) returning IDirectDrawSurface4 interface at %p\n", This
, *obj
);
208 if (IsEqualGUID(riid
, &IID_IDirectDrawSurface3
))
210 IDirectDrawSurface3_AddRef(&This
->IDirectDrawSurface3_iface
);
211 *obj
= &This
->IDirectDrawSurface3_iface
;
212 TRACE("(%p) returning IDirectDrawSurface3 interface at %p\n", This
, *obj
);
216 if (IsEqualGUID(riid
, &IID_IDirectDrawSurface2
))
218 IDirectDrawSurface2_AddRef(&This
->IDirectDrawSurface2_iface
);
219 *obj
= &This
->IDirectDrawSurface2_iface
;
220 TRACE("(%p) returning IDirectDrawSurface2 interface at %p\n", This
, *obj
);
224 if (IsEqualGUID(riid
, &IID_IDirectDrawSurface
)
225 || IsEqualGUID(riid
, &IID_IUnknown
))
227 IDirectDrawSurface_AddRef(&This
->IDirectDrawSurface_iface
);
228 *obj
= &This
->IDirectDrawSurface_iface
;
229 TRACE("(%p) returning IDirectDrawSurface interface at %p\n", This
, *obj
);
233 if (IsEqualGUID(riid
, &IID_IDirectDrawGammaControl
))
235 IDirectDrawGammaControl_AddRef(&This
->IDirectDrawGammaControl_iface
);
236 *obj
= &This
->IDirectDrawGammaControl_iface
;
237 TRACE("(%p) returning IDirectDrawGammaControl interface at %p\n", This
, *obj
);
241 if (IsEqualGUID(riid
, &IID_IDirectDrawColorControl
))
243 WARN("Color control not implemented.\n");
245 return E_NOINTERFACE
;
248 if (This
->version
!= 7)
250 if (IsEqualGUID(riid
, &IID_D3DDEVICE_WineD3D
)
251 || IsEqualGUID(riid
, &IID_IDirect3DHALDevice
)
252 || IsEqualGUID(riid
, &IID_IDirect3DRGBDevice
))
254 wined3d_mutex_lock();
259 if (FAILED(hr
= d3d_device_create(This
->ddraw
, This
, (IUnknown
*)&This
->IDirectDrawSurface_iface
,
260 1, &This
->device1
, (IUnknown
*)&This
->IDirectDrawSurface_iface
)))
262 This
->device1
= NULL
;
263 wined3d_mutex_unlock();
264 WARN("Failed to create device, hr %#x.\n", hr
);
268 wined3d_mutex_unlock();
270 IDirect3DDevice_AddRef(&This
->device1
->IDirect3DDevice_iface
);
271 *obj
= &This
->device1
->IDirect3DDevice_iface
;
275 if (IsEqualGUID(&IID_IDirect3DTexture2
, riid
))
277 IDirect3DTexture2_AddRef(&This
->IDirect3DTexture2_iface
);
278 *obj
= &This
->IDirect3DTexture2_iface
;
282 if (IsEqualGUID( &IID_IDirect3DTexture
, riid
))
284 IDirect3DTexture2_AddRef(&This
->IDirect3DTexture_iface
);
285 *obj
= &This
->IDirect3DTexture_iface
;
290 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
292 if (This
->version
!= 7)
295 return E_NOINTERFACE
;
298 static HRESULT WINAPI
ddraw_surface4_QueryInterface(IDirectDrawSurface4
*iface
, REFIID riid
, void **object
)
300 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
302 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
304 return ddraw_surface7_QueryInterface(&surface
->IDirectDrawSurface7_iface
, riid
, object
);
307 static HRESULT WINAPI
ddraw_surface3_QueryInterface(IDirectDrawSurface3
*iface
, REFIID riid
, void **object
)
309 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface3(iface
);
311 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
313 return ddraw_surface7_QueryInterface(&surface
->IDirectDrawSurface7_iface
, riid
, object
);
316 static HRESULT WINAPI
ddraw_surface2_QueryInterface(IDirectDrawSurface2
*iface
, REFIID riid
, void **object
)
318 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface2(iface
);
320 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
322 return ddraw_surface7_QueryInterface(&surface
->IDirectDrawSurface7_iface
, riid
, object
);
325 static HRESULT WINAPI
ddraw_surface1_QueryInterface(IDirectDrawSurface
*iface
, REFIID riid
, void **object
)
327 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface(iface
);
329 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
331 return ddraw_surface7_QueryInterface(&surface
->IDirectDrawSurface7_iface
, riid
, object
);
334 static HRESULT WINAPI
ddraw_gamma_control_QueryInterface(IDirectDrawGammaControl
*iface
,
335 REFIID riid
, void **object
)
337 struct ddraw_surface
*surface
= impl_from_IDirectDrawGammaControl(iface
);
339 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
341 return ddraw_surface7_QueryInterface(&surface
->IDirectDrawSurface7_iface
, riid
, object
);
344 static HRESULT WINAPI
d3d_texture2_QueryInterface(IDirect3DTexture2
*iface
, REFIID riid
, void **object
)
346 struct ddraw_surface
*surface
= impl_from_IDirect3DTexture2(iface
);
348 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
350 return ddraw_surface7_QueryInterface(&surface
->IDirectDrawSurface7_iface
, riid
, object
);
353 static HRESULT WINAPI
d3d_texture1_QueryInterface(IDirect3DTexture
*iface
, REFIID riid
, void **object
)
355 struct ddraw_surface
*surface
= impl_from_IDirect3DTexture(iface
);
357 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
359 return ddraw_surface7_QueryInterface(&surface
->IDirectDrawSurface7_iface
, riid
, object
);
362 static void ddraw_surface_add_iface(struct ddraw_surface
*surface
)
364 ULONG iface_count
= InterlockedIncrement(&surface
->iface_count
);
365 TRACE("%p increasing iface count to %u.\n", surface
, iface_count
);
367 if (iface_count
== 1)
369 if (surface
->ifaceToRelease
)
370 IUnknown_AddRef(surface
->ifaceToRelease
);
371 wined3d_mutex_lock();
372 if (surface
->wined3d_rtv
)
373 wined3d_rendertarget_view_incref(surface
->wined3d_rtv
);
374 wined3d_texture_incref(surface
->wined3d_texture
);
375 wined3d_mutex_unlock();
379 /*****************************************************************************
380 * IDirectDrawSurface7::AddRef
382 * A normal addref implementation
387 *****************************************************************************/
388 static ULONG WINAPI
ddraw_surface7_AddRef(IDirectDrawSurface7
*iface
)
390 struct ddraw_surface
*This
= impl_from_IDirectDrawSurface7(iface
);
391 ULONG refcount
= InterlockedIncrement(&This
->ref7
);
393 TRACE("iface %p increasing refcount to %u.\n", iface
, refcount
);
397 ddraw_surface_add_iface(This
);
403 static ULONG WINAPI
ddraw_surface4_AddRef(IDirectDrawSurface4
*iface
)
405 struct ddraw_surface
*This
= impl_from_IDirectDrawSurface4(iface
);
406 ULONG refcount
= InterlockedIncrement(&This
->ref4
);
408 TRACE("iface %p increasing refcount to %u.\n", iface
, refcount
);
412 ddraw_surface_add_iface(This
);
418 static ULONG WINAPI
ddraw_surface3_AddRef(IDirectDrawSurface3
*iface
)
420 struct ddraw_surface
*This
= impl_from_IDirectDrawSurface3(iface
);
421 ULONG refcount
= InterlockedIncrement(&This
->ref3
);
423 TRACE("iface %p increasing refcount to %u.\n", iface
, refcount
);
427 ddraw_surface_add_iface(This
);
433 static ULONG WINAPI
ddraw_surface2_AddRef(IDirectDrawSurface2
*iface
)
435 struct ddraw_surface
*This
= impl_from_IDirectDrawSurface2(iface
);
436 ULONG refcount
= InterlockedIncrement(&This
->ref2
);
438 TRACE("iface %p increasing refcount to %u.\n", iface
, refcount
);
442 ddraw_surface_add_iface(This
);
448 static ULONG WINAPI
ddraw_surface1_AddRef(IDirectDrawSurface
*iface
)
450 struct ddraw_surface
*This
= impl_from_IDirectDrawSurface(iface
);
451 ULONG refcount
= InterlockedIncrement(&This
->ref1
);
453 TRACE("iface %p increasing refcount to %u.\n", iface
, refcount
);
457 ddraw_surface_add_iface(This
);
463 static ULONG WINAPI
ddraw_gamma_control_AddRef(IDirectDrawGammaControl
*iface
)
465 struct ddraw_surface
*This
= impl_from_IDirectDrawGammaControl(iface
);
466 ULONG refcount
= InterlockedIncrement(&This
->gamma_count
);
468 TRACE("iface %p increasing refcount to %u.\n", iface
, refcount
);
472 ddraw_surface_add_iface(This
);
478 static ULONG WINAPI
d3d_texture2_AddRef(IDirect3DTexture2
*iface
)
480 struct ddraw_surface
*surface
= impl_from_IDirect3DTexture2(iface
);
482 TRACE("iface %p.\n", iface
);
484 return IUnknown_AddRef(surface
->texture_outer
);
487 static ULONG WINAPI
d3d_texture1_AddRef(IDirect3DTexture
*iface
)
489 struct ddraw_surface
*surface
= impl_from_IDirect3DTexture(iface
);
491 TRACE("iface %p.\n", iface
);
493 return IUnknown_AddRef(surface
->texture_outer
);
496 static HRESULT
ddraw_surface_set_palette(struct ddraw_surface
*surface
, IDirectDrawPalette
*palette
)
498 struct ddraw_palette
*palette_impl
= unsafe_impl_from_IDirectDrawPalette(palette
);
499 struct ddraw_palette
*prev
;
501 TRACE("iface %p, palette %p.\n", surface
, palette
);
503 if (palette_impl
&& palette_impl
->flags
& DDPCAPS_ALPHA
504 && !(surface
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_TEXTURE
))
506 WARN("Alpha palette set on non-texture surface, returning DDERR_INVALIDSURFACETYPE.\n");
507 return DDERR_INVALIDSURFACETYPE
;
510 if (!format_is_paletteindexed(&surface
->surface_desc
.u4
.ddpfPixelFormat
))
511 return DDERR_INVALIDPIXELFORMAT
;
513 wined3d_mutex_lock();
515 prev
= surface
->palette
;
516 if (surface
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)
519 prev
->flags
&= ~DDPCAPS_PRIMARYSURFACE
;
521 palette_impl
->flags
|= DDPCAPS_PRIMARYSURFACE
;
522 wined3d_swapchain_set_palette(surface
->ddraw
->wined3d_swapchain
,
523 palette_impl
? palette_impl
->wined3d_palette
: NULL
);
524 ddraw_surface_update_frontbuffer(surface
, NULL
, FALSE
, 0);
527 IDirectDrawPalette_AddRef(&palette_impl
->IDirectDrawPalette_iface
);
529 IDirectDrawPalette_Release(&prev
->IDirectDrawPalette_iface
);
530 surface
->palette
= palette_impl
;
532 wined3d_mutex_unlock();
537 static void ddraw_surface_cleanup(struct ddraw_surface
*surface
)
539 struct ddraw_surface
*surf
;
542 TRACE("surface %p.\n", surface
);
544 /* The refcount test shows that the palette is detached when the surface
546 ddraw_surface_set_palette(surface
, NULL
);
548 /* Loop through all complex attached surfaces and destroy them.
550 * Yet again, only the root can have more than one complexly attached
551 * surface, all the others have a total of one. */
552 for (i
= 0; i
< MAX_COMPLEX_ATTACHED
; ++i
)
554 if (!surface
->complex_array
[i
])
557 surf
= surface
->complex_array
[i
];
558 surface
->complex_array
[i
] = NULL
;
559 if (!surf
->is_complex_root
)
561 struct ddraw_texture
*texture
= wined3d_texture_get_parent(surf
->wined3d_texture
);
562 struct wined3d_device
*wined3d_device
= texture
->wined3d_device
;
563 struct ddraw_surface
*root
= texture
->root
;
565 ddraw_surface_cleanup(surf
);
568 wined3d_device_decref(wined3d_device
);
572 if (surface
->device1
)
573 IUnknown_Release(&surface
->device1
->IUnknown_inner
);
575 if (surface
->iface_count
> 1)
577 /* This can happen when a complex surface is destroyed, because the
578 * 2nd surface was addref()ed when the app called
579 * GetAttachedSurface(). */
580 WARN("Destroying surface %p with refcounts 7: %u 4: %u 3: %u 2: %u 1: %u.\n",
581 surface
, surface
->ref7
, surface
->ref4
, surface
->ref3
, surface
->ref2
, surface
->ref1
);
584 if (surface
->wined3d_rtv
)
585 wined3d_rendertarget_view_decref(surface
->wined3d_rtv
);
586 wined3d_texture_decref(surface
->wined3d_texture
);
589 static ULONG
ddraw_surface_release_iface(struct ddraw_surface
*This
)
593 /* Prevent the surface from being destroyed if it's still attached to
594 * another surface. It will be destroyed when the root is destroyed. */
595 if (This
->iface_count
== 1 && This
->attached_iface
)
596 IUnknown_AddRef(This
->attached_iface
);
597 iface_count
= InterlockedDecrement(&This
->iface_count
);
599 TRACE("%p decreasing iface count to %u.\n", This
, iface_count
);
601 if (iface_count
== 0)
603 struct ddraw_texture
*texture
= wined3d_texture_get_parent(This
->wined3d_texture
);
604 struct wined3d_device
*wined3d_device
= texture
->wined3d_device
;
605 IUnknown
*release_iface
= This
->ifaceToRelease
;
607 /* Complex attached surfaces are destroyed implicitly when the root is released */
608 wined3d_mutex_lock();
609 if(!This
->is_complex_root
)
611 WARN("(%p) Attempt to destroy a surface that is not a complex root\n", This
);
612 wined3d_mutex_unlock();
615 ddraw_surface_cleanup(This
);
616 wined3d_mutex_unlock();
619 IUnknown_Release(release_iface
);
620 /* Release the device only after anything that may reference it (the
621 * wined3d texture and rendertarget view in particular) is released. */
622 wined3d_device_decref(wined3d_device
);
628 /*****************************************************************************
629 * IDirectDrawSurface7::Release
631 * Reduces the surface's refcount by 1. If the refcount falls to 0, the
632 * surface is destroyed.
634 * Destroying the surface is a bit tricky. For the connection between
635 * WineD3DSurfaces and DirectDrawSurfaces see IDirectDraw7::CreateSurface
636 * It has a nice graph explaining the connection.
638 * What happens here is basically this:
639 * When a surface is destroyed, its WineD3DSurface is released,
640 * and the refcount of the DirectDraw interface is reduced by 1. If it has
641 * complex surfaces attached to it, then these surfaces are destroyed too,
642 * regardless of their refcount. If any surface being destroyed has another
643 * surface attached to it (with a "soft" attachment, not complex), then
644 * this surface is detached with DeleteAttachedSurface.
646 * When the surface is a texture, the WineD3DTexture is released.
647 * If the surface is the Direct3D render target, then the D3D
648 * capabilities of the WineD3DDevice are uninitialized, which causes the
649 * swapchain to be released.
651 * When a complex sublevel falls to ref zero, then this is ignored.
656 *****************************************************************************/
657 static ULONG WINAPI
ddraw_surface7_Release(IDirectDrawSurface7
*iface
)
659 struct ddraw_surface
*This
= impl_from_IDirectDrawSurface7(iface
);
660 ULONG refcount
= InterlockedDecrement(&This
->ref7
);
662 TRACE("iface %p decreasing refcount to %u.\n", iface
, refcount
);
666 ddraw_surface_release_iface(This
);
672 static ULONG WINAPI
ddraw_surface4_Release(IDirectDrawSurface4
*iface
)
674 struct ddraw_surface
*This
= impl_from_IDirectDrawSurface4(iface
);
675 ULONG refcount
= InterlockedDecrement(&This
->ref4
);
677 TRACE("iface %p decreasing refcount to %u.\n", iface
, refcount
);
681 ddraw_surface_release_iface(This
);
687 static ULONG WINAPI
ddraw_surface3_Release(IDirectDrawSurface3
*iface
)
689 struct ddraw_surface
*This
= impl_from_IDirectDrawSurface3(iface
);
690 ULONG refcount
= InterlockedDecrement(&This
->ref3
);
692 TRACE("iface %p decreasing refcount to %u.\n", iface
, refcount
);
696 ddraw_surface_release_iface(This
);
702 static ULONG WINAPI
ddraw_surface2_Release(IDirectDrawSurface2
*iface
)
704 struct ddraw_surface
*This
= impl_from_IDirectDrawSurface2(iface
);
705 ULONG refcount
= InterlockedDecrement(&This
->ref2
);
707 TRACE("iface %p decreasing refcount to %u.\n", iface
, refcount
);
711 ddraw_surface_release_iface(This
);
717 static ULONG WINAPI
ddraw_surface1_Release(IDirectDrawSurface
*iface
)
719 struct ddraw_surface
*This
= impl_from_IDirectDrawSurface(iface
);
720 ULONG refcount
= InterlockedDecrement(&This
->ref1
);
722 TRACE("iface %p decreasing refcount to %u.\n", iface
, refcount
);
726 ddraw_surface_release_iface(This
);
732 static ULONG WINAPI
ddraw_gamma_control_Release(IDirectDrawGammaControl
*iface
)
734 struct ddraw_surface
*This
= impl_from_IDirectDrawGammaControl(iface
);
735 ULONG refcount
= InterlockedDecrement(&This
->gamma_count
);
737 TRACE("iface %p decreasing refcount to %u.\n", iface
, refcount
);
741 ddraw_surface_release_iface(This
);
747 static ULONG WINAPI
d3d_texture2_Release(IDirect3DTexture2
*iface
)
749 struct ddraw_surface
*surface
= impl_from_IDirect3DTexture2(iface
);
751 TRACE("iface %p.\n", iface
);
753 return IUnknown_Release(surface
->texture_outer
);
756 static ULONG WINAPI
d3d_texture1_Release(IDirect3DTexture
*iface
)
758 struct ddraw_surface
*surface
= impl_from_IDirect3DTexture(iface
);
760 TRACE("iface %p.\n", iface
);
762 return IUnknown_Release(surface
->texture_outer
);
765 /*****************************************************************************
766 * IDirectDrawSurface7::GetAttachedSurface
768 * Returns an attached surface with the requested caps. Surface attachment
769 * and complex surfaces are not clearly described by the MSDN or sdk,
770 * so this method is tricky and likely to contain problems.
771 * This implementation searches the complex list first, then the
774 * The chains are searched from This down to the last surface in the chain,
775 * not from the first element in the chain. The first surface found is
776 * returned. The MSDN says that this method fails if more than one surface
777 * matches the caps, but it is not sure if that is right. The attachment
778 * structure may not even allow two matching surfaces.
780 * The found surface is AddRef-ed before it is returned.
783 * Caps: Pointer to a DDCAPS2 structure describing the caps asked for
784 * Surface: Address to store the found surface
788 * DDERR_INVALIDPARAMS if Caps or Surface is NULL
789 * DDERR_NOTFOUND if no surface was found
791 *****************************************************************************/
792 static HRESULT WINAPI
ddraw_surface7_GetAttachedSurface(IDirectDrawSurface7
*iface
,
793 DDSCAPS2
*caps
, IDirectDrawSurface7
**surface
)
795 struct ddraw_surface
*head_surface
= impl_from_IDirectDrawSurface7(iface
);
796 struct ddraw_surface
*surf
;
800 TRACE("iface %p, caps %p, attachment %p.\n", iface
, caps
, surface
);
802 if (ddraw_surface_is_lost(head_surface
))
804 WARN("Surface %p is lost.\n", head_surface
);
807 return DDERR_SURFACELOST
;
810 wined3d_mutex_lock();
812 if(head_surface
->version
< 7)
814 /* Earlier dx apps put garbage into these members, clear them */
815 our_caps
.dwCaps
= caps
->dwCaps
;
816 our_caps
.dwCaps2
= 0;
817 our_caps
.dwCaps3
= 0;
818 our_caps
.u1
.dwCaps4
= 0;
825 TRACE("head_surface %p, looking for caps %#x, %#x, %#x, %#x.\n", head_surface
, our_caps
.dwCaps
,
826 our_caps
.dwCaps2
, our_caps
.dwCaps3
, our_caps
.u1
.dwCaps4
); /* FIXME: Better debugging */
828 for(i
= 0; i
< MAX_COMPLEX_ATTACHED
; i
++)
830 surf
= head_surface
->complex_array
[i
];
833 TRACE("Surface %p, caps %#x, %#x, %#x, %#x.\n", surf
,
834 surf
->surface_desc
.ddsCaps
.dwCaps
,
835 surf
->surface_desc
.ddsCaps
.dwCaps2
,
836 surf
->surface_desc
.ddsCaps
.dwCaps3
,
837 surf
->surface_desc
.ddsCaps
.u1
.dwCaps4
);
839 if (((surf
->surface_desc
.ddsCaps
.dwCaps
& our_caps
.dwCaps
) == our_caps
.dwCaps
) &&
840 ((surf
->surface_desc
.ddsCaps
.dwCaps2
& our_caps
.dwCaps2
) == our_caps
.dwCaps2
)) {
842 /* MSDN: "This method fails if more than one surface is attached
843 * that matches the capabilities requested."
845 * Not sure how to test this.
848 TRACE("head_surface %p, returning surface %p.\n", head_surface
, surf
);
849 *surface
= &surf
->IDirectDrawSurface7_iface
;
850 ddraw_surface7_AddRef(*surface
);
851 wined3d_mutex_unlock();
857 /* Next, look at the attachment chain */
860 while( (surf
= surf
->next_attached
) )
862 TRACE("Surface %p, caps %#x, %#x, %#x, %#x.\n", surf
,
863 surf
->surface_desc
.ddsCaps
.dwCaps
,
864 surf
->surface_desc
.ddsCaps
.dwCaps2
,
865 surf
->surface_desc
.ddsCaps
.dwCaps3
,
866 surf
->surface_desc
.ddsCaps
.u1
.dwCaps4
);
868 if (((surf
->surface_desc
.ddsCaps
.dwCaps
& our_caps
.dwCaps
) == our_caps
.dwCaps
) &&
869 ((surf
->surface_desc
.ddsCaps
.dwCaps2
& our_caps
.dwCaps2
) == our_caps
.dwCaps2
)) {
871 TRACE("head_surface %p, returning surface %p.\n", head_surface
, surf
);
872 *surface
= &surf
->IDirectDrawSurface7_iface
;
873 ddraw_surface7_AddRef(*surface
);
874 wined3d_mutex_unlock();
879 TRACE("head_surface %p, didn't find a valid surface.\n", head_surface
);
881 wined3d_mutex_unlock();
884 return DDERR_NOTFOUND
;
887 static HRESULT WINAPI
ddraw_surface4_GetAttachedSurface(IDirectDrawSurface4
*iface
,
888 DDSCAPS2
*caps
, IDirectDrawSurface4
**attachment
)
890 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
891 struct ddraw_surface
*attachment_impl
;
892 IDirectDrawSurface7
*attachment7
;
895 TRACE("iface %p, caps %p, attachment %p.\n", iface
, caps
, attachment
);
897 hr
= ddraw_surface7_GetAttachedSurface(&surface
->IDirectDrawSurface7_iface
,
904 attachment_impl
= impl_from_IDirectDrawSurface7(attachment7
);
905 *attachment
= &attachment_impl
->IDirectDrawSurface4_iface
;
906 ddraw_surface4_AddRef(*attachment
);
907 ddraw_surface7_Release(attachment7
);
912 static HRESULT WINAPI
ddraw_surface3_GetAttachedSurface(IDirectDrawSurface3
*iface
,
913 DDSCAPS
*caps
, IDirectDrawSurface3
**attachment
)
915 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface3(iface
);
916 struct ddraw_surface
*attachment_impl
;
917 IDirectDrawSurface7
*attachment7
;
921 TRACE("iface %p, caps %p, attachment %p.\n", iface
, caps
, attachment
);
923 caps2
.dwCaps
= caps
->dwCaps
;
926 caps2
.u1
.dwCaps4
= 0;
928 hr
= ddraw_surface7_GetAttachedSurface(&surface
->IDirectDrawSurface7_iface
,
929 &caps2
, &attachment7
);
935 attachment_impl
= impl_from_IDirectDrawSurface7(attachment7
);
936 *attachment
= &attachment_impl
->IDirectDrawSurface3_iface
;
937 ddraw_surface3_AddRef(*attachment
);
938 ddraw_surface7_Release(attachment7
);
943 static HRESULT WINAPI
ddraw_surface2_GetAttachedSurface(IDirectDrawSurface2
*iface
,
944 DDSCAPS
*caps
, IDirectDrawSurface2
**attachment
)
946 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface2(iface
);
947 struct ddraw_surface
*attachment_impl
;
948 IDirectDrawSurface7
*attachment7
;
952 TRACE("iface %p, caps %p, attachment %p.\n", iface
, caps
, attachment
);
954 caps2
.dwCaps
= caps
->dwCaps
;
957 caps2
.u1
.dwCaps4
= 0;
959 hr
= ddraw_surface7_GetAttachedSurface(&surface
->IDirectDrawSurface7_iface
,
960 &caps2
, &attachment7
);
966 attachment_impl
= impl_from_IDirectDrawSurface7(attachment7
);
967 *attachment
= &attachment_impl
->IDirectDrawSurface2_iface
;
968 ddraw_surface2_AddRef(*attachment
);
969 ddraw_surface7_Release(attachment7
);
974 static HRESULT WINAPI
ddraw_surface1_GetAttachedSurface(IDirectDrawSurface
*iface
,
975 DDSCAPS
*caps
, IDirectDrawSurface
**attachment
)
977 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface(iface
);
978 struct ddraw_surface
*attachment_impl
;
979 IDirectDrawSurface7
*attachment7
;
983 TRACE("iface %p, caps %p, attachment %p.\n", iface
, caps
, attachment
);
985 caps2
.dwCaps
= caps
->dwCaps
;
988 caps2
.u1
.dwCaps4
= 0;
990 hr
= ddraw_surface7_GetAttachedSurface(&surface
->IDirectDrawSurface7_iface
,
991 &caps2
, &attachment7
);
997 attachment_impl
= impl_from_IDirectDrawSurface7(attachment7
);
998 *attachment
= &attachment_impl
->IDirectDrawSurface_iface
;
999 ddraw_surface1_AddRef(*attachment
);
1000 ddraw_surface7_Release(attachment7
);
1005 /*****************************************************************************
1006 * IDirectDrawSurface7::Lock
1008 * Locks the surface and returns a pointer to the surface's memory
1011 * Rect: Rectangle to lock. If NULL, the whole surface is locked
1012 * DDSD: Pointer to a DDSURFACEDESC2 which shall receive the surface's desc.
1013 * Flags: Locking flags, e.g Read only or write only
1014 * h: An event handle that's not used and must be NULL
1018 * DDERR_INVALIDPARAMS if DDSD is NULL
1020 *****************************************************************************/
1021 static HRESULT
surface_lock(struct ddraw_surface
*surface
,
1022 RECT
*rect
, DDSURFACEDESC2
*surface_desc
, unsigned int surface_desc_size
,
1023 DWORD flags
, HANDLE h
)
1025 struct wined3d_map_desc map_desc
;
1026 struct wined3d_box box
;
1029 TRACE("surface %p, rect %s, surface_desc %p, surface_desc_size %u, flags %#x, h %p.\n",
1030 surface
, wine_dbgstr_rect(rect
), surface_desc
, surface_desc_size
, flags
, h
);
1032 /* surface->surface_desc.dwWidth and dwHeight are changeable, thus lock */
1033 wined3d_mutex_lock();
1035 /* Should I check for the handle to be NULL?
1037 * The DDLOCK flags and the D3DLOCK flags are equal
1038 * for the supported values. The others are ignored by WineD3D
1041 /* Windows zeroes this if the rect is invalid */
1042 surface_desc
->lpSurface
= NULL
;
1046 if ((rect
->left
< 0) || (rect
->top
< 0)
1047 || (rect
->left
> rect
->right
) || (rect
->right
> surface
->surface_desc
.dwWidth
)
1048 || (rect
->top
> rect
->bottom
) || (rect
->bottom
> surface
->surface_desc
.dwHeight
))
1050 WARN("Trying to lock an invalid rectangle, returning DDERR_INVALIDPARAMS\n");
1051 wined3d_mutex_unlock();
1052 return DDERR_INVALIDPARAMS
;
1054 wined3d_box_set(&box
, rect
->left
, rect
->top
, rect
->right
, rect
->bottom
, 0, 1);
1057 if (surface
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)
1058 hr
= ddraw_surface_update_frontbuffer(surface
, rect
, TRUE
, 0);
1060 hr
= wined3d_resource_map(wined3d_texture_get_resource(surface
->wined3d_texture
),
1061 surface
->sub_resource_idx
, &map_desc
, rect
? &box
: NULL
,
1062 wined3dmapflags_from_ddrawmapflags(flags
));
1065 wined3d_mutex_unlock();
1068 /* D3D8 and D3D9 return the general D3DERR_INVALIDCALL error, but ddraw has a more
1069 * specific error. But since wined3d returns that error in this only occasion,
1070 * keep d3d8 and d3d9 free from the return value override. There are many different
1071 * places where d3d8/9 would have to catch the DDERR_SURFACEBUSY, it is much easier
1072 * to do it in one place in ddraw.
1074 case WINED3DERR_INVALIDCALL
: return DDERR_SURFACEBUSY
;
1079 if (surface
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)
1081 if (flags
& DDLOCK_READONLY
)
1082 SetRectEmpty(&surface
->ddraw
->primary_lock
);
1084 surface
->ddraw
->primary_lock
= *rect
;
1086 SetRect(&surface
->ddraw
->primary_lock
, 0, 0, surface
->surface_desc
.dwWidth
, surface
->surface_desc
.dwHeight
);
1089 /* Windows does not set DDSD_LPSURFACE on locked surfaces. */
1090 DD_STRUCT_COPY_BYSIZE_(surface_desc
, &surface
->surface_desc
, surface_desc_size
, surface
->surface_desc
.dwSize
);
1091 surface_desc
->lpSurface
= map_desc
.data
;
1093 TRACE("locked surface returning description :\n");
1094 if (TRACE_ON(ddraw
))
1095 DDRAW_dump_surface_desc(surface_desc
);
1097 wined3d_mutex_unlock();
1102 static BOOL
surface_validate_lock_desc(struct ddraw_surface
*surface
,
1103 const DDSURFACEDESC
*desc
, unsigned int *size
)
1108 if (desc
->dwSize
== sizeof(DDSURFACEDESC
) || desc
->dwSize
== sizeof(DDSURFACEDESC2
))
1110 *size
= desc
->dwSize
;
1114 if (surface
->version
== 7
1115 && surface
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_TEXTURE
1116 && !(surface
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
))
1118 if (desc
->dwSize
>= sizeof(DDSURFACEDESC2
))
1119 *size
= sizeof(DDSURFACEDESC2
);
1121 *size
= sizeof(DDSURFACEDESC
);
1125 WARN("Invalid structure size %u.\n", desc
->dwSize
);
1129 static HRESULT WINAPI
ddraw_surface7_Lock(IDirectDrawSurface7
*iface
,
1130 RECT
*rect
, DDSURFACEDESC2
*surface_desc
, DWORD flags
, HANDLE h
)
1132 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface7(iface
);
1133 unsigned int surface_desc_size
;
1135 TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n",
1136 iface
, wine_dbgstr_rect(rect
), surface_desc
, flags
, h
);
1138 if (!surface_validate_lock_desc(surface
, (DDSURFACEDESC
*)surface_desc
, &surface_desc_size
))
1139 return DDERR_INVALIDPARAMS
;
1141 if (ddraw_surface_is_lost(surface
))
1143 WARN("Surface is lost.\n");
1144 return DDERR_SURFACELOST
;
1147 return surface_lock(surface
, rect
, surface_desc
, surface_desc_size
, flags
, h
);
1150 static HRESULT WINAPI
ddraw_surface4_Lock(IDirectDrawSurface4
*iface
, RECT
*rect
,
1151 DDSURFACEDESC2
*surface_desc
, DWORD flags
, HANDLE h
)
1153 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
1154 unsigned int surface_desc_size
;
1156 TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n",
1157 iface
, wine_dbgstr_rect(rect
), surface_desc
, flags
, h
);
1159 if (!surface_validate_lock_desc(surface
, (DDSURFACEDESC
*)surface_desc
, &surface_desc_size
))
1160 return DDERR_INVALIDPARAMS
;
1162 if (ddraw_surface_is_lost(surface
))
1164 WARN("Surface is lost.\n");
1165 return DDERR_SURFACELOST
;
1168 return surface_lock(surface
, rect
, surface_desc
, surface_desc_size
, flags
, h
);
1171 static HRESULT
ddraw_surface_lock_ddsd(struct ddraw_surface
*surface
, RECT
*rect
,
1172 DDSURFACEDESC
*surface_desc
, DWORD flags
, HANDLE h
)
1174 unsigned int surface_desc_size
;
1175 DDSURFACEDESC2 surface_desc2
;
1178 if (!surface_validate_lock_desc(surface
, surface_desc
, &surface_desc_size
))
1179 return DDERR_INVALIDPARAMS
;
1181 if (ddraw_surface_is_lost(surface
))
1183 WARN("Surface is lost.\n");
1184 return DDERR_SURFACELOST
;
1187 surface_desc2
.dwSize
= surface_desc
->dwSize
;
1188 surface_desc2
.dwFlags
= 0;
1189 hr
= surface_lock(surface
, rect
, &surface_desc2
, surface_desc_size
, flags
, h
);
1190 DDSD2_to_DDSD(&surface_desc2
, surface_desc
);
1191 surface_desc
->dwSize
= surface_desc2
.dwSize
;
1195 static HRESULT WINAPI
ddraw_surface3_Lock(IDirectDrawSurface3
*iface
, RECT
*rect
,
1196 DDSURFACEDESC
*surface_desc
, DWORD flags
, HANDLE h
)
1198 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface3(iface
);
1200 TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n",
1201 iface
, wine_dbgstr_rect(rect
), surface_desc
, flags
, h
);
1203 return ddraw_surface_lock_ddsd(surface
, rect
, surface_desc
, flags
, h
);
1206 static HRESULT WINAPI
ddraw_surface2_Lock(IDirectDrawSurface2
*iface
, RECT
*rect
,
1207 DDSURFACEDESC
*surface_desc
, DWORD flags
, HANDLE h
)
1209 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface2(iface
);
1211 TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n",
1212 iface
, wine_dbgstr_rect(rect
), surface_desc
, flags
, h
);
1214 return ddraw_surface_lock_ddsd(surface
, rect
, surface_desc
, flags
, h
);
1217 static HRESULT WINAPI
ddraw_surface1_Lock(IDirectDrawSurface
*iface
, RECT
*rect
,
1218 DDSURFACEDESC
*surface_desc
, DWORD flags
, HANDLE h
)
1220 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface(iface
);
1222 TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n",
1223 iface
, wine_dbgstr_rect(rect
), surface_desc
, flags
, h
);
1225 return ddraw_surface_lock_ddsd(surface
, rect
, surface_desc
, flags
, h
);
1228 /* FRAPS hooks IDirectDrawSurface::Unlock and expects the version 1 method to be called when the
1229 * game uses later interfaces. */
1230 static HRESULT WINAPI DECLSPEC_HOTPATCH
ddraw_surface1_Unlock(IDirectDrawSurface
*iface
, void *data
)
1232 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface(iface
);
1235 TRACE("iface %p, data %p.\n", iface
, data
);
1237 wined3d_mutex_lock();
1238 hr
= wined3d_resource_unmap(wined3d_texture_get_resource(surface
->wined3d_texture
), surface
->sub_resource_idx
);
1239 if (SUCCEEDED(hr
) && surface
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)
1240 hr
= ddraw_surface_update_frontbuffer(surface
, &surface
->ddraw
->primary_lock
, FALSE
, 0);
1241 wined3d_mutex_unlock();
1246 static HRESULT WINAPI DECLSPEC_HOTPATCH
ddraw_surface7_Unlock(IDirectDrawSurface7
*iface
, RECT
*rect
)
1248 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface7(iface
);
1250 TRACE("iface %p, rect %s.\n", iface
, wine_dbgstr_rect(rect
));
1252 return ddraw_surface1_Unlock(&surface
->IDirectDrawSurface_iface
, NULL
);
1255 static HRESULT WINAPI DECLSPEC_HOTPATCH
ddraw_surface4_Unlock(IDirectDrawSurface4
*iface
, RECT
*rect
)
1257 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
1259 TRACE("iface %p, rect %s.\n", iface
, wine_dbgstr_rect(rect
));
1261 return ddraw_surface1_Unlock(&surface
->IDirectDrawSurface_iface
, NULL
);
1264 static HRESULT WINAPI DECLSPEC_HOTPATCH
ddraw_surface3_Unlock(IDirectDrawSurface3
*iface
, void *data
)
1266 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface3(iface
);
1268 TRACE("iface %p, data %p.\n", iface
, data
);
1270 return ddraw_surface1_Unlock(&surface
->IDirectDrawSurface_iface
, data
);
1273 static HRESULT WINAPI DECLSPEC_HOTPATCH
ddraw_surface2_Unlock(IDirectDrawSurface2
*iface
, void *data
)
1275 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface2(iface
);
1277 TRACE("iface %p, data %p.\n", iface
, data
);
1279 return ddraw_surface1_Unlock(&surface
->IDirectDrawSurface_iface
, data
);
1282 static unsigned int ddraw_swap_interval_from_flags(DWORD flags
)
1284 if (flags
& DDFLIP_NOVSYNC
)
1287 switch (flags
& (DDFLIP_INTERVAL2
| DDFLIP_INTERVAL3
| DDFLIP_INTERVAL4
))
1289 case DDFLIP_INTERVAL2
:
1291 case DDFLIP_INTERVAL3
:
1293 case DDFLIP_INTERVAL4
:
1300 /* FRAPS hooks IDirectDrawSurface::Flip and expects the version 1 method to be called when the
1301 * game uses later interfaces. */
1302 static HRESULT WINAPI DECLSPEC_HOTPATCH
ddraw_surface1_Flip(IDirectDrawSurface
*iface
,
1303 IDirectDrawSurface
*src
, DWORD flags
)
1305 struct ddraw_surface
*dst_impl
= impl_from_IDirectDrawSurface(iface
);
1306 struct ddraw_surface
*src_impl
= unsafe_impl_from_IDirectDrawSurface(src
);
1307 struct ddraw_texture
*dst_ddraw_texture
, *src_ddraw_texture
;
1308 struct wined3d_rendertarget_view
*tmp_rtv
, *src_rtv
, *rtv
;
1309 DDSCAPS caps
= {DDSCAPS_FLIP
};
1310 struct wined3d_texture
*texture
;
1311 IDirectDrawSurface
*current
;
1312 void *texture_memory
;
1315 TRACE("iface %p, src %p, flags %#x.\n", iface
, src
, flags
);
1317 if (src
== iface
|| !(dst_impl
->surface_desc
.ddsCaps
.dwCaps
& (DDSCAPS_FRONTBUFFER
| DDSCAPS_OVERLAY
)))
1318 return DDERR_NOTFLIPPABLE
;
1320 if (ddraw_surface_is_lost(dst_impl
))
1321 return DDERR_SURFACELOST
;
1323 wined3d_mutex_lock();
1325 if ((dst_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)
1326 && !(dst_impl
->ddraw
->cooperative_level
& DDSCL_EXCLUSIVE
))
1328 WARN("Not in exclusive mode.\n");
1329 wined3d_mutex_unlock();
1330 return DDERR_NOEXCLUSIVEMODE
;
1333 tmp_rtv
= ddraw_surface_get_rendertarget_view(dst_impl
);
1334 if (dst_impl
->sub_resource_idx
)
1335 ERR("Invalid sub-resource index %u on surface %p.\n", dst_impl
->sub_resource_idx
, dst_impl
);
1336 texture
= dst_impl
->wined3d_texture
;
1337 rtv
= wined3d_device_get_rendertarget_view(dst_impl
->ddraw
->wined3d_device
, 0);
1338 dst_ddraw_texture
= wined3d_texture_get_parent(dst_impl
->wined3d_texture
);
1339 texture_memory
= dst_ddraw_texture
->texture_memory
;
1343 for (current
= iface
; current
!= src
;)
1345 if (FAILED(hr
= ddraw_surface1_GetAttachedSurface(current
, &caps
, ¤t
)))
1347 WARN("Surface %p is not on the same flip chain as surface %p.\n", src
, iface
);
1348 wined3d_mutex_unlock();
1349 return DDERR_NOTFLIPPABLE
;
1351 ddraw_surface1_Release(current
);
1352 if (current
== iface
)
1354 WARN("Surface %p is not on the same flip chain as surface %p.\n", src
, iface
);
1355 wined3d_mutex_unlock();
1356 return DDERR_NOTFLIPPABLE
;
1360 src_rtv
= ddraw_surface_get_rendertarget_view(src_impl
);
1361 if (rtv
== dst_impl
->wined3d_rtv
)
1362 wined3d_device_set_rendertarget_view(dst_impl
->ddraw
->wined3d_device
, 0, src_rtv
, FALSE
);
1363 wined3d_rendertarget_view_set_parent(src_rtv
, dst_impl
);
1364 dst_impl
->wined3d_rtv
= src_rtv
;
1365 wined3d_texture_set_sub_resource_parent(src_impl
->wined3d_texture
, 0, dst_impl
);
1366 src_ddraw_texture
= wined3d_texture_get_parent(src_impl
->wined3d_texture
);
1367 dst_ddraw_texture
->texture_memory
= src_ddraw_texture
->texture_memory
;
1368 wined3d_resource_set_parent(wined3d_texture_get_resource(src_impl
->wined3d_texture
), dst_ddraw_texture
);
1369 dst_ddraw_texture
= src_ddraw_texture
;
1370 if (src_impl
->sub_resource_idx
)
1371 ERR("Invalid sub-resource index %u on surface %p.\n", src_impl
->sub_resource_idx
, src_impl
);
1372 dst_impl
->wined3d_texture
= src_impl
->wined3d_texture
;
1376 for (current
= iface
;;)
1378 if (FAILED(hr
= ddraw_surface1_GetAttachedSurface(current
, &caps
, ¤t
)))
1380 ERR("Can't find a flip target\n");
1381 wined3d_mutex_unlock();
1382 return DDERR_NOTFLIPPABLE
; /* Unchecked */
1384 ddraw_surface1_Release(current
);
1385 if (current
== iface
)
1387 dst_impl
= impl_from_IDirectDrawSurface(iface
);
1391 src_impl
= impl_from_IDirectDrawSurface(current
);
1392 src_rtv
= ddraw_surface_get_rendertarget_view(src_impl
);
1393 if (rtv
== dst_impl
->wined3d_rtv
)
1394 wined3d_device_set_rendertarget_view(dst_impl
->ddraw
->wined3d_device
, 0, src_rtv
, FALSE
);
1395 wined3d_rendertarget_view_set_parent(src_rtv
, dst_impl
);
1396 dst_impl
->wined3d_rtv
= src_rtv
;
1397 wined3d_texture_set_sub_resource_parent(src_impl
->wined3d_texture
, 0, dst_impl
);
1398 src_ddraw_texture
= wined3d_texture_get_parent(src_impl
->wined3d_texture
);
1399 dst_ddraw_texture
->texture_memory
= src_ddraw_texture
->texture_memory
;
1400 wined3d_resource_set_parent(wined3d_texture_get_resource(src_impl
->wined3d_texture
), dst_ddraw_texture
);
1401 dst_ddraw_texture
= src_ddraw_texture
;
1402 if (src_impl
->sub_resource_idx
)
1403 ERR("Invalid sub-resource index %u on surface %p.\n", src_impl
->sub_resource_idx
, src_impl
);
1404 dst_impl
->wined3d_texture
= src_impl
->wined3d_texture
;
1405 dst_impl
= src_impl
;
1409 /* We don't have to worry about potential texture bindings, since
1410 * flippable surfaces can never be textures. */
1411 if (rtv
== src_impl
->wined3d_rtv
)
1412 wined3d_device_set_rendertarget_view(dst_impl
->ddraw
->wined3d_device
, 0, tmp_rtv
, FALSE
);
1413 wined3d_rendertarget_view_set_parent(tmp_rtv
, src_impl
);
1414 src_impl
->wined3d_rtv
= tmp_rtv
;
1415 wined3d_texture_set_sub_resource_parent(texture
, 0, src_impl
);
1416 dst_ddraw_texture
->texture_memory
= texture_memory
;
1417 wined3d_resource_set_parent(wined3d_texture_get_resource(texture
), dst_ddraw_texture
);
1418 src_impl
->wined3d_texture
= texture
;
1420 if (flags
& ~(DDFLIP_NOVSYNC
| DDFLIP_INTERVAL2
| DDFLIP_INTERVAL3
| DDFLIP_INTERVAL4
))
1424 FIXME("Ignoring flags %#x.\n", flags
);
1426 WARN("Ignoring flags %#x.\n", flags
);
1429 if (dst_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)
1430 hr
= ddraw_surface_update_frontbuffer(dst_impl
, NULL
, FALSE
, ddraw_swap_interval_from_flags(flags
));
1434 wined3d_mutex_unlock();
1439 static HRESULT WINAPI DECLSPEC_HOTPATCH
ddraw_surface7_Flip(IDirectDrawSurface7
*iface
,
1440 IDirectDrawSurface7
*src
, DWORD flags
)
1442 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface7(iface
);
1443 struct ddraw_surface
*src_impl
= unsafe_impl_from_IDirectDrawSurface7(src
);
1445 TRACE("iface %p, src %p, flags %#x.\n", iface
, src
, flags
);
1447 return ddraw_surface1_Flip(&surface
->IDirectDrawSurface_iface
,
1448 src_impl
? &src_impl
->IDirectDrawSurface_iface
: NULL
, flags
);
1451 static HRESULT WINAPI DECLSPEC_HOTPATCH
ddraw_surface4_Flip(IDirectDrawSurface4
*iface
,
1452 IDirectDrawSurface4
*src
, DWORD flags
)
1454 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
1455 struct ddraw_surface
*src_impl
= unsafe_impl_from_IDirectDrawSurface4(src
);
1457 TRACE("iface %p, src %p, flags %#x.\n", iface
, src
, flags
);
1459 return ddraw_surface1_Flip(&surface
->IDirectDrawSurface_iface
,
1460 src_impl
? &src_impl
->IDirectDrawSurface_iface
: NULL
, flags
);
1463 static HRESULT WINAPI DECLSPEC_HOTPATCH
ddraw_surface3_Flip(IDirectDrawSurface3
*iface
,
1464 IDirectDrawSurface3
*src
, DWORD flags
)
1466 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface3(iface
);
1467 struct ddraw_surface
*src_impl
= unsafe_impl_from_IDirectDrawSurface3(src
);
1469 TRACE("iface %p, src %p, flags %#x.\n", iface
, src
, flags
);
1471 return ddraw_surface1_Flip(&surface
->IDirectDrawSurface_iface
,
1472 src_impl
? &src_impl
->IDirectDrawSurface_iface
: NULL
, flags
);
1475 static HRESULT WINAPI DECLSPEC_HOTPATCH
ddraw_surface2_Flip(IDirectDrawSurface2
*iface
,
1476 IDirectDrawSurface2
*src
, DWORD flags
)
1478 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface2(iface
);
1479 struct ddraw_surface
*src_impl
= unsafe_impl_from_IDirectDrawSurface2(src
);
1481 TRACE("iface %p, src %p, flags %#x.\n", iface
, src
, flags
);
1483 return ddraw_surface1_Flip(&surface
->IDirectDrawSurface_iface
,
1484 src_impl
? &src_impl
->IDirectDrawSurface_iface
: NULL
, flags
);
1487 static HRESULT
ddraw_surface_blt(struct ddraw_surface
*dst_surface
, const RECT
*dst_rect
,
1488 struct ddraw_surface
*src_surface
, const RECT
*src_rect
, DWORD flags
, DWORD fill_colour
,
1489 const struct wined3d_blt_fx
*fx
, enum wined3d_texture_filter_type filter
)
1491 struct wined3d_device
*wined3d_device
= dst_surface
->ddraw
->wined3d_device
;
1492 struct wined3d_color colour
;
1493 DWORD wined3d_flags
;
1495 if (flags
& DDBLT_COLORFILL
)
1497 wined3d_flags
= WINED3DCLEAR_TARGET
;
1498 if (!(flags
& DDBLT_ASYNC
))
1499 wined3d_flags
|= WINED3DCLEAR_SYNCHRONOUS
;
1501 if (!wined3d_colour_from_ddraw_colour(&dst_surface
->surface_desc
.u4
.ddpfPixelFormat
,
1502 dst_surface
->palette
, fill_colour
, &colour
))
1503 return DDERR_INVALIDPARAMS
;
1505 wined3d_device_apply_stateblock(wined3d_device
, dst_surface
->ddraw
->state
);
1506 return wined3d_device_clear_rendertarget_view(wined3d_device
,
1507 ddraw_surface_get_rendertarget_view(dst_surface
),
1508 dst_rect
, wined3d_flags
, &colour
, 0.0f
, 0);
1511 if (flags
& DDBLT_DEPTHFILL
)
1513 wined3d_flags
= WINED3DCLEAR_ZBUFFER
;
1514 if (!(flags
& DDBLT_ASYNC
))
1515 wined3d_flags
|= WINED3DCLEAR_SYNCHRONOUS
;
1517 if (!wined3d_colour_from_ddraw_colour(&dst_surface
->surface_desc
.u4
.ddpfPixelFormat
,
1518 dst_surface
->palette
, fill_colour
, &colour
))
1519 return DDERR_INVALIDPARAMS
;
1521 wined3d_device_apply_stateblock(wined3d_device
, dst_surface
->ddraw
->state
);
1522 return wined3d_device_clear_rendertarget_view(wined3d_device
,
1523 ddraw_surface_get_rendertarget_view(dst_surface
),
1524 dst_rect
, wined3d_flags
, NULL
, colour
.r
, 0);
1527 wined3d_flags
= flags
& ~DDBLT_ASYNC
;
1528 if (wined3d_flags
& ~WINED3D_BLT_MASK
)
1530 FIXME("Unhandled flags %#x.\n", flags
);
1534 if (!(flags
& DDBLT_ASYNC
))
1535 wined3d_flags
|= WINED3D_BLT_SYNCHRONOUS
;
1537 return wined3d_texture_blt(dst_surface
->wined3d_texture
, dst_surface
->sub_resource_idx
, dst_rect
,
1538 src_surface
->wined3d_texture
, src_surface
->sub_resource_idx
, src_rect
, wined3d_flags
, fx
, filter
);
1541 static HRESULT
ddraw_surface_blt_clipped(struct ddraw_surface
*dst_surface
, const RECT
*dst_rect_in
,
1542 struct ddraw_surface
*src_surface
, const RECT
*src_rect_in
, DWORD flags
, DWORD fill_colour
,
1543 const struct wined3d_blt_fx
*fx
, enum wined3d_texture_filter_type filter
)
1545 RECT src_rect
, dst_rect
;
1546 float scale_x
, scale_y
;
1547 const RECT
*clip_rect
;
1548 UINT clip_list_size
;
1554 SetRect(&dst_rect
, 0, 0, dst_surface
->surface_desc
.dwWidth
,
1555 dst_surface
->surface_desc
.dwHeight
);
1557 dst_rect
= *dst_rect_in
;
1559 if (IsRectEmpty(&dst_rect
))
1560 return DDERR_INVALIDRECT
;
1565 SetRect(&src_rect
, 0, 0, src_surface
->surface_desc
.dwWidth
,
1566 src_surface
->surface_desc
.dwHeight
);
1568 src_rect
= *src_rect_in
;
1570 if (IsRectEmpty(&src_rect
))
1571 return DDERR_INVALIDRECT
;
1575 SetRectEmpty(&src_rect
);
1578 if (!dst_surface
->clipper
)
1580 if (src_surface
&& src_surface
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)
1581 hr
= ddraw_surface_update_frontbuffer(src_surface
, &src_rect
, TRUE
, 0);
1583 hr
= ddraw_surface_blt(dst_surface
, &dst_rect
, src_surface
, &src_rect
, flags
, fill_colour
, fx
, filter
);
1584 if (SUCCEEDED(hr
) && (dst_surface
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
))
1585 hr
= ddraw_surface_update_frontbuffer(dst_surface
, &dst_rect
, FALSE
, 0);
1590 if (!ddraw_clipper_is_valid(dst_surface
->clipper
))
1592 FIXME("Attempting to blit with an invalid clipper.\n");
1593 return DDERR_INVALIDPARAMS
;
1596 scale_x
= (float)(src_rect
.right
- src_rect
.left
) / (float)(dst_rect
.right
- dst_rect
.left
);
1597 scale_y
= (float)(src_rect
.bottom
- src_rect
.top
) / (float)(dst_rect
.bottom
- dst_rect
.top
);
1599 if (FAILED(hr
= IDirectDrawClipper_GetClipList(&dst_surface
->clipper
->IDirectDrawClipper_iface
,
1600 &dst_rect
, NULL
, &clip_list_size
)))
1602 WARN("Failed to get clip list size, hr %#x.\n", hr
);
1606 if (!(clip_list
= heap_alloc(clip_list_size
)))
1608 WARN("Failed to allocate clip list.\n");
1609 return E_OUTOFMEMORY
;
1612 if (FAILED(hr
= IDirectDrawClipper_GetClipList(&dst_surface
->clipper
->IDirectDrawClipper_iface
,
1613 &dst_rect
, clip_list
, &clip_list_size
)))
1615 WARN("Failed to get clip list, hr %#x.\n", hr
);
1616 heap_free(clip_list
);
1620 clip_rect
= (RECT
*)clip_list
->Buffer
;
1621 for (i
= 0; i
< clip_list
->rdh
.nCount
; ++i
)
1623 RECT src_rect_clipped
= src_rect
;
1627 src_rect_clipped
.left
+= (LONG
)((clip_rect
[i
].left
- dst_rect
.left
) * scale_x
);
1628 src_rect_clipped
.top
+= (LONG
)((clip_rect
[i
].top
- dst_rect
.top
) * scale_y
);
1629 src_rect_clipped
.right
-= (LONG
)((dst_rect
.right
- clip_rect
[i
].right
) * scale_x
);
1630 src_rect_clipped
.bottom
-= (LONG
)((dst_rect
.bottom
- clip_rect
[i
].bottom
) * scale_y
);
1632 if (src_surface
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)
1634 if (FAILED(hr
= ddraw_surface_update_frontbuffer(src_surface
, &src_rect_clipped
, TRUE
, 0)))
1639 if (FAILED(hr
= ddraw_surface_blt(dst_surface
, &clip_rect
[i
],
1640 src_surface
, &src_rect_clipped
, flags
, fill_colour
, fx
, filter
)))
1643 if (dst_surface
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)
1645 if (FAILED(hr
= ddraw_surface_update_frontbuffer(dst_surface
, &clip_rect
[i
], FALSE
, 0)))
1650 heap_free(clip_list
);
1654 /* FRAPS hooks IDirectDrawSurface::Blt and expects the version 1 method to be called when the
1655 * game uses later interfaces. */
1656 static HRESULT WINAPI DECLSPEC_HOTPATCH
ddraw_surface1_Blt(IDirectDrawSurface
*iface
, RECT
*dst_rect
,
1657 IDirectDrawSurface
*src_surface
, RECT
*src_rect
, DWORD flags
, DDBLTFX
*fx
)
1659 struct ddraw_surface
*dst_impl
= impl_from_IDirectDrawSurface(iface
);
1660 struct ddraw_surface
*src_impl
= unsafe_impl_from_IDirectDrawSurface(src_surface
);
1661 struct wined3d_blt_fx wined3d_fx
;
1662 DWORD unsupported_flags
;
1663 DWORD fill_colour
= 0;
1667 TRACE("iface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p.\n",
1668 iface
, wine_dbgstr_rect(dst_rect
), src_surface
, wine_dbgstr_rect(src_rect
), flags
, fx
);
1670 unsupported_flags
= DDBLT_ALPHADEST
1671 | DDBLT_ALPHADESTCONSTOVERRIDE
1672 | DDBLT_ALPHADESTNEG
1673 | DDBLT_ALPHADESTSURFACEOVERRIDE
1674 | DDBLT_ALPHAEDGEBLEND
1676 | DDBLT_ALPHASRCCONSTOVERRIDE
1678 | DDBLT_ALPHASRCSURFACEOVERRIDE
1680 | DDBLT_ZBUFFERDESTCONSTOVERRIDE
1681 | DDBLT_ZBUFFERDESTOVERRIDE
1682 | DDBLT_ZBUFFERSRCCONSTOVERRIDE
1683 | DDBLT_ZBUFFERSRCOVERRIDE
;
1684 if (flags
& unsupported_flags
)
1686 WARN("Ignoring unsupported flags %#x.\n", flags
& unsupported_flags
);
1687 flags
&= ~unsupported_flags
;
1690 if ((flags
& DDBLT_KEYSRCOVERRIDE
) && (!fx
|| flags
& DDBLT_KEYSRC
))
1692 WARN("Invalid source color key parameters, returning DDERR_INVALIDPARAMS\n");
1693 return DDERR_INVALIDPARAMS
;
1696 if ((flags
& DDBLT_KEYDESTOVERRIDE
) && (!fx
|| flags
& DDBLT_KEYDEST
))
1698 WARN("Invalid destination color key parameters, returning DDERR_INVALIDPARAMS\n");
1699 return DDERR_INVALIDPARAMS
;
1702 if (flags
& DDBLT_DDROPS
)
1704 FIXME("DDBLT_DDROPS not implemented.\n");
1706 FIXME(" rop %#x, pattern %p.\n", fx
->dwDDROP
, fx
->u5
.lpDDSPattern
);
1707 return DDERR_NORASTEROPHW
;
1710 wined3d_mutex_lock();
1712 if (flags
& (DDBLT_COLORFILL
| DDBLT_DEPTHFILL
))
1714 if (flags
& DDBLT_ROP
)
1716 wined3d_mutex_unlock();
1717 WARN("DDBLT_ROP used with DDBLT_COLORFILL or DDBLT_DEPTHFILL, returning DDERR_INVALIDPARAMS.\n");
1718 return DDERR_INVALIDPARAMS
;
1722 wined3d_mutex_unlock();
1723 WARN("Depth or colorfill is not compatible with source surfaces, returning DDERR_INVALIDPARAMS\n");
1724 return DDERR_INVALIDPARAMS
;
1728 wined3d_mutex_unlock();
1729 WARN("Depth or colorfill used with NULL fx, returning DDERR_INVALIDPARAMS.\n");
1730 return DDERR_INVALIDPARAMS
;
1733 if ((flags
& (DDBLT_COLORFILL
| DDBLT_DEPTHFILL
)) == (DDBLT_COLORFILL
| DDBLT_DEPTHFILL
))
1734 flags
&= ~DDBLT_DEPTHFILL
;
1736 if ((dst_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_ZBUFFER
) && (flags
& DDBLT_COLORFILL
))
1738 wined3d_mutex_unlock();
1739 WARN("DDBLT_COLORFILL used on a depth buffer, returning DDERR_INVALIDPARAMS.\n");
1740 return DDERR_INVALIDPARAMS
;
1742 if (!(dst_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_ZBUFFER
) && (flags
& DDBLT_DEPTHFILL
))
1744 wined3d_mutex_unlock();
1745 WARN("DDBLT_DEPTHFILL used on a color buffer, returning DDERR_INVALIDPARAMS.\n");
1746 return DDERR_INVALIDPARAMS
;
1750 if (flags
& DDBLT_ROP
)
1754 wined3d_mutex_unlock();
1755 WARN("DDBLT_ROP used with NULL fx, returning DDERR_INVALIDPARAMS.\n");
1756 return DDERR_INVALIDPARAMS
;
1759 if (src_impl
&& src_rect
1760 && ((ULONG
)src_rect
->left
>= src_rect
->right
|| src_rect
->right
> src_impl
->surface_desc
.dwWidth
1761 || (ULONG
)src_rect
->top
>= src_rect
->bottom
|| src_rect
->bottom
> src_impl
->surface_desc
.dwHeight
))
1763 wined3d_mutex_unlock();
1764 WARN("Invalid source rectangle.\n");
1765 return DDERR_INVALIDRECT
;
1768 flags
&= ~DDBLT_ROP
;
1778 if (fx
->dwROP
== WHITENESS
)
1779 rop_fx
.u5
.dwFillColor
= 0xffffffff;
1781 rop_fx
.u5
.dwFillColor
= 0;
1783 if (dst_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_ZBUFFER
)
1784 flags
|= DDBLT_DEPTHFILL
;
1786 flags
|= DDBLT_COLORFILL
;
1792 wined3d_mutex_unlock();
1793 WARN("Unsupported ROP %#x used, returning DDERR_NORASTEROPHW.\n", fx
->dwROP
);
1794 return DDERR_NORASTEROPHW
;
1798 if (!(flags
& (DDBLT_COLORFILL
| DDBLT_DEPTHFILL
)) && !src_impl
)
1800 WARN("No source surface.\n");
1801 wined3d_mutex_unlock();
1802 return DDERR_INVALIDPARAMS
;
1805 if (flags
& DDBLT_KEYSRC
&& (!src_impl
|| !(src_impl
->surface_desc
.dwFlags
& DDSD_CKSRCBLT
)))
1807 WARN("DDBLT_KEYSRC blit without color key in surface, returning DDERR_INVALIDPARAMS\n");
1808 wined3d_mutex_unlock();
1809 return DDERR_INVALIDPARAMS
;
1811 if (flags
& DDBLT_KEYDEST
&& !(dst_impl
->surface_desc
.dwFlags
& DDSD_CKDESTBLT
))
1813 WARN("DDBLT_KEYDEST blit without color key in surface, returning DDERR_INVALIDPARAMS\n");
1814 wined3d_mutex_unlock();
1815 return DDERR_INVALIDPARAMS
;
1820 wined3d_fx
.fx
= fx
->dwDDFX
;
1821 fill_colour
= fx
->u5
.dwFillColor
;
1822 wined3d_fx
.dst_color_key
.color_space_low_value
= fx
->ddckDestColorkey
.dwColorSpaceLowValue
;
1823 wined3d_fx
.dst_color_key
.color_space_high_value
= fx
->ddckDestColorkey
.dwColorSpaceHighValue
;
1824 wined3d_fx
.src_color_key
.color_space_low_value
= fx
->ddckSrcColorkey
.dwColorSpaceLowValue
;
1825 wined3d_fx
.src_color_key
.color_space_high_value
= fx
->ddckSrcColorkey
.dwColorSpaceHighValue
;
1828 hr
= ddraw_surface_blt_clipped(dst_impl
, dst_rect
, src_impl
,
1829 src_rect
, flags
, fill_colour
, fx
? &wined3d_fx
: NULL
, WINED3D_TEXF_LINEAR
);
1831 wined3d_mutex_unlock();
1834 case WINED3DERR_NOTAVAILABLE
: return DDERR_UNSUPPORTED
;
1839 static HRESULT WINAPI DECLSPEC_HOTPATCH
ddraw_surface7_Blt(IDirectDrawSurface7
*iface
, RECT
*dst_rect
,
1840 IDirectDrawSurface7
*src_surface
, RECT
*src_rect
, DWORD flags
, DDBLTFX
*fx
)
1842 struct ddraw_surface
*dst
= impl_from_IDirectDrawSurface7(iface
);
1843 struct ddraw_surface
*src
= unsafe_impl_from_IDirectDrawSurface7(src_surface
);
1845 TRACE("iface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p.\n",
1846 iface
, wine_dbgstr_rect(dst_rect
), src_surface
, wine_dbgstr_rect(src_rect
), flags
, fx
);
1848 return ddraw_surface1_Blt(&dst
->IDirectDrawSurface_iface
, dst_rect
,
1849 src
? &src
->IDirectDrawSurface_iface
: NULL
, src_rect
, flags
, fx
);
1852 static HRESULT WINAPI DECLSPEC_HOTPATCH
ddraw_surface4_Blt(IDirectDrawSurface4
*iface
, RECT
*dst_rect
,
1853 IDirectDrawSurface4
*src_surface
, RECT
*src_rect
, DWORD flags
, DDBLTFX
*fx
)
1855 struct ddraw_surface
*dst
= impl_from_IDirectDrawSurface4(iface
);
1856 struct ddraw_surface
*src
= unsafe_impl_from_IDirectDrawSurface4(src_surface
);
1858 TRACE("iface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p.\n",
1859 iface
, wine_dbgstr_rect(dst_rect
), src_surface
, wine_dbgstr_rect(src_rect
), flags
, fx
);
1861 return ddraw_surface1_Blt(&dst
->IDirectDrawSurface_iface
, dst_rect
,
1862 src
? &src
->IDirectDrawSurface_iface
: NULL
, src_rect
, flags
, fx
);
1865 static HRESULT WINAPI DECLSPEC_HOTPATCH
ddraw_surface3_Blt(IDirectDrawSurface3
*iface
, RECT
*dst_rect
,
1866 IDirectDrawSurface3
*src_surface
, RECT
*src_rect
, DWORD flags
, DDBLTFX
*fx
)
1868 struct ddraw_surface
*dst
= impl_from_IDirectDrawSurface3(iface
);
1869 struct ddraw_surface
*src
= unsafe_impl_from_IDirectDrawSurface3(src_surface
);
1871 TRACE("iface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p.\n",
1872 iface
, wine_dbgstr_rect(dst_rect
), src_surface
, wine_dbgstr_rect(src_rect
), flags
, fx
);
1874 return ddraw_surface1_Blt(&dst
->IDirectDrawSurface_iface
, dst_rect
,
1875 src
? &src
->IDirectDrawSurface_iface
: NULL
, src_rect
, flags
, fx
);
1878 static HRESULT WINAPI DECLSPEC_HOTPATCH
ddraw_surface2_Blt(IDirectDrawSurface2
*iface
, RECT
*dst_rect
,
1879 IDirectDrawSurface2
*src_surface
, RECT
*src_rect
, DWORD flags
, DDBLTFX
*fx
)
1881 struct ddraw_surface
*dst
= impl_from_IDirectDrawSurface2(iface
);
1882 struct ddraw_surface
*src
= unsafe_impl_from_IDirectDrawSurface2(src_surface
);
1884 TRACE("iface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p.\n",
1885 iface
, wine_dbgstr_rect(dst_rect
), src_surface
, wine_dbgstr_rect(src_rect
), flags
, fx
);
1887 return ddraw_surface1_Blt(&dst
->IDirectDrawSurface_iface
, dst_rect
,
1888 src
? &src
->IDirectDrawSurface_iface
: NULL
, src_rect
, flags
, fx
);
1891 /*****************************************************************************
1892 * IDirectDrawSurface7::AddAttachedSurface
1894 * Attaches a surface to another surface. How the surface attachments work
1895 * is not totally understood yet, and this method is prone to problems.
1896 * The surface that is attached is AddRef-ed.
1898 * Tests with complex surfaces suggest that the surface attachments form a
1899 * tree, but no method to test this has been found yet.
1901 * The attachment list consists of a first surface (first_attached) and
1902 * for each surface a pointer to the next attached surface (next_attached).
1903 * For the first surface, and a surface that has no attachments
1904 * first_attached points to the surface itself. A surface that has
1905 * no successors in the chain has next_attached set to NULL.
1907 * Newly attached surfaces are attached right after the root surface.
1908 * If a surface is attached to a complex surface compound, it's attached to
1909 * the surface that the app requested, not the complex root. See
1910 * GetAttachedSurface for a description how surfaces are found.
1912 * This is how the current implementation works, and it was coded by looking
1913 * at the needs of the applications.
1915 * So far only Z-Buffer attachments are tested, and they are activated in
1916 * WineD3D. Mipmaps could be tricky to activate in WineD3D.
1917 * Back buffers should work in 2D mode, but they are not tested(They can be
1918 * attached in older iface versions). Rendering to the front buffer and
1919 * switching between that and double buffering is not yet implemented in
1920 * WineD3D, so for 3D it might have unexpected results.
1922 * ddraw_surface_attach_surface is the real thing,
1923 * ddraw_surface7_AddAttachedSurface is a wrapper around it that
1924 * performs additional checks. Version 7 of this interface is much more restrictive
1925 * than its predecessors.
1928 * Attach: Surface to attach to iface
1932 * DDERR_CANNOTATTACHSURFACE if the surface can't be attached for some reason
1934 *****************************************************************************/
1935 static HRESULT
ddraw_surface_attach_surface(struct ddraw_surface
*This
, struct ddraw_surface
*Surf
)
1937 TRACE("surface %p, attachment %p.\n", This
, Surf
);
1940 return DDERR_CANNOTATTACHSURFACE
; /* unchecked */
1942 wined3d_mutex_lock();
1944 /* Check if the surface is already attached somewhere */
1945 if (Surf
->next_attached
|| Surf
->first_attached
!= Surf
)
1947 /* TODO: Test for the structure of the manual attachment. Is it a
1948 * chain or a list? What happens if one surface is attached to 2
1949 * different surfaces? */
1950 WARN("Surface %p is already attached somewhere. next_attached %p, first_attached %p.\n",
1951 Surf
, Surf
->next_attached
, Surf
->first_attached
);
1953 wined3d_mutex_unlock();
1954 return DDERR_SURFACEALREADYATTACHED
;
1957 /* This inserts the new surface at the 2nd position in the chain, right after the root surface */
1958 Surf
->next_attached
= This
->next_attached
;
1959 Surf
->first_attached
= This
->first_attached
;
1960 This
->next_attached
= Surf
;
1962 /* Check if the WineD3D depth stencil needs updating */
1963 if (This
->ddraw
->d3ddevice
)
1964 d3d_device_update_depth_stencil(This
->ddraw
->d3ddevice
);
1966 wined3d_mutex_unlock();
1971 static HRESULT WINAPI
ddraw_surface7_AddAttachedSurface(IDirectDrawSurface7
*iface
, IDirectDrawSurface7
*attachment
)
1973 struct ddraw_surface
*This
= impl_from_IDirectDrawSurface7(iface
);
1974 struct ddraw_surface
*attachment_impl
= unsafe_impl_from_IDirectDrawSurface7(attachment
);
1977 TRACE("iface %p, attachment %p.\n", iface
, attachment
);
1979 /* Version 7 of this interface seems to refuse everything except z buffers, as per msdn */
1980 if(!(attachment_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_ZBUFFER
))
1983 WARN("Application tries to attach a non Z buffer surface. caps %08x\n",
1984 attachment_impl
->surface_desc
.ddsCaps
.dwCaps
);
1985 return DDERR_CANNOTATTACHSURFACE
;
1988 hr
= ddraw_surface_attach_surface(This
, attachment_impl
);
1993 attachment_impl
->attached_iface
= (IUnknown
*)attachment
;
1994 IUnknown_AddRef(attachment_impl
->attached_iface
);
1998 static HRESULT WINAPI
ddraw_surface4_AddAttachedSurface(IDirectDrawSurface4
*iface
, IDirectDrawSurface4
*attachment
)
2000 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
2001 struct ddraw_surface
*attachment_impl
= unsafe_impl_from_IDirectDrawSurface4(attachment
);
2004 TRACE("iface %p, attachment %p.\n", iface
, attachment
);
2006 /* Tests suggest that
2007 * -> offscreen plain surfaces can be attached to other offscreen plain surfaces
2008 * -> offscreen plain surfaces can be attached to primaries
2009 * -> primaries can be attached to offscreen plain surfaces
2010 * -> z buffers can be attached to primaries */
2011 if (surface
->surface_desc
.ddsCaps
.dwCaps
& (DDSCAPS_PRIMARYSURFACE
| DDSCAPS_OFFSCREENPLAIN
)
2012 && attachment_impl
->surface_desc
.ddsCaps
.dwCaps
& (DDSCAPS_PRIMARYSURFACE
| DDSCAPS_OFFSCREENPLAIN
))
2014 /* Sizes have to match */
2015 if (attachment_impl
->surface_desc
.dwWidth
!= surface
->surface_desc
.dwWidth
2016 || attachment_impl
->surface_desc
.dwHeight
!= surface
->surface_desc
.dwHeight
)
2018 WARN("Surface sizes do not match.\n");
2019 return DDERR_CANNOTATTACHSURFACE
;
2022 else if (!(surface
->surface_desc
.ddsCaps
.dwCaps
& (DDSCAPS_PRIMARYSURFACE
| DDSCAPS_3DDEVICE
))
2023 || !(attachment_impl
->surface_desc
.ddsCaps
.dwCaps
& (DDSCAPS_ZBUFFER
)))
2025 WARN("Invalid attachment combination.\n");
2026 return DDERR_CANNOTATTACHSURFACE
;
2029 if (FAILED(hr
= ddraw_surface_attach_surface(surface
, attachment_impl
)))
2032 attachment_impl
->attached_iface
= (IUnknown
*)attachment
;
2033 IUnknown_AddRef(attachment_impl
->attached_iface
);
2037 static HRESULT WINAPI
ddraw_surface3_AddAttachedSurface(IDirectDrawSurface3
*iface
, IDirectDrawSurface3
*attachment
)
2039 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface3(iface
);
2040 struct ddraw_surface
*attachment_impl
= unsafe_impl_from_IDirectDrawSurface3(attachment
);
2043 TRACE("iface %p, attachment %p.\n", iface
, attachment
);
2045 if (FAILED(hr
= ddraw_surface4_AddAttachedSurface(&surface
->IDirectDrawSurface4_iface
,
2046 attachment_impl
? &attachment_impl
->IDirectDrawSurface4_iface
: NULL
)))
2049 attachment_impl
->attached_iface
= (IUnknown
*)attachment
;
2050 IUnknown_AddRef(attachment_impl
->attached_iface
);
2051 ddraw_surface4_Release(&attachment_impl
->IDirectDrawSurface4_iface
);
2055 static HRESULT WINAPI
ddraw_surface2_AddAttachedSurface(IDirectDrawSurface2
*iface
, IDirectDrawSurface2
*attachment
)
2057 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface2(iface
);
2058 struct ddraw_surface
*attachment_impl
= unsafe_impl_from_IDirectDrawSurface2(attachment
);
2061 TRACE("iface %p, attachment %p.\n", iface
, attachment
);
2063 if (FAILED(hr
= ddraw_surface4_AddAttachedSurface(&surface
->IDirectDrawSurface4_iface
,
2064 attachment_impl
? &attachment_impl
->IDirectDrawSurface4_iface
: NULL
)))
2067 attachment_impl
->attached_iface
= (IUnknown
*)attachment
;
2068 IUnknown_AddRef(attachment_impl
->attached_iface
);
2069 ddraw_surface4_Release(&attachment_impl
->IDirectDrawSurface4_iface
);
2073 static HRESULT WINAPI
ddraw_surface1_AddAttachedSurface(IDirectDrawSurface
*iface
, IDirectDrawSurface
*attachment
)
2075 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface(iface
);
2076 struct ddraw_surface
*attachment_impl
= unsafe_impl_from_IDirectDrawSurface(attachment
);
2079 TRACE("iface %p, attachment %p.\n", iface
, attachment
);
2081 if (FAILED(hr
= ddraw_surface4_AddAttachedSurface(&surface
->IDirectDrawSurface4_iface
,
2082 attachment_impl
? &attachment_impl
->IDirectDrawSurface4_iface
: NULL
)))
2085 attachment_impl
->attached_iface
= (IUnknown
*)attachment
;
2086 IUnknown_AddRef(attachment_impl
->attached_iface
);
2087 ddraw_surface4_Release(&attachment_impl
->IDirectDrawSurface4_iface
);
2091 /*****************************************************************************
2092 * IDirectDrawSurface7::DeleteAttachedSurface
2094 * Removes a surface from the attachment chain. The surface's refcount
2095 * is decreased by one after it has been removed
2098 * Flags: Some flags, not used by this implementation
2099 * Attach: Surface to detach
2103 * DDERR_SURFACENOTATTACHED if the surface isn't attached to
2105 *****************************************************************************/
2106 static HRESULT
ddraw_surface_delete_attached_surface(struct ddraw_surface
*surface
,
2107 struct ddraw_surface
*attachment
, IUnknown
*detach_iface
)
2109 struct ddraw_surface
*prev
= surface
;
2111 TRACE("surface %p, attachment %p, detach_iface %p.\n", surface
, attachment
, detach_iface
);
2113 wined3d_mutex_lock();
2114 if (!attachment
|| (attachment
->first_attached
!= surface
) || (attachment
== surface
) )
2116 wined3d_mutex_unlock();
2117 return DDERR_CANNOTDETACHSURFACE
;
2120 if (attachment
->attached_iface
!= detach_iface
)
2122 WARN("attachment->attach_iface %p != detach_iface %p.\n", attachment
->attached_iface
, detach_iface
);
2123 wined3d_mutex_unlock();
2124 return DDERR_SURFACENOTATTACHED
;
2127 /* Remove MIPMAPSUBLEVEL if this seemed to be one */
2128 if (surface
->surface_desc
.ddsCaps
.dwCaps
& attachment
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_MIPMAP
)
2130 attachment
->surface_desc
.ddsCaps
.dwCaps2
&= ~DDSCAPS2_MIPMAPSUBLEVEL
;
2131 /* FIXME: we should probably also subtract from dwMipMapCount of this
2132 * and all parent surfaces */
2135 /* Find the predecessor of the detached surface */
2136 while (prev
->next_attached
!= attachment
)
2138 if (!(prev
= prev
->next_attached
))
2140 ERR("Failed to find predecessor of %p.\n", attachment
);
2141 wined3d_mutex_unlock();
2142 return DDERR_SURFACENOTATTACHED
;
2146 /* Unchain the surface */
2147 prev
->next_attached
= attachment
->next_attached
;
2148 attachment
->next_attached
= NULL
;
2149 attachment
->first_attached
= attachment
;
2151 /* Check if the wined3d depth stencil needs updating. Note that we don't
2152 * just call d3d_device_update_depth_stencil() here since it uses
2153 * QueryInterface(). Some applications, SCP - Containment Breach in
2154 * particular, modify the QueryInterface() pointer in the surface vtbl
2155 * but don't cleanup properly after the relevant dll is unloaded. */
2156 if (attachment
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_ZBUFFER
2157 && wined3d_device_get_depth_stencil_view(surface
->ddraw
->wined3d_device
) == attachment
->wined3d_rtv
)
2158 wined3d_device_set_depth_stencil_view(surface
->ddraw
->wined3d_device
, NULL
);
2159 wined3d_mutex_unlock();
2161 /* Set attached_iface to NULL before releasing it, the surface may go
2163 attachment
->attached_iface
= NULL
;
2164 IUnknown_Release(detach_iface
);
2169 static HRESULT WINAPI
ddraw_surface7_DeleteAttachedSurface(IDirectDrawSurface7
*iface
,
2170 DWORD flags
, IDirectDrawSurface7
*attachment
)
2172 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface7(iface
);
2173 struct ddraw_surface
*attachment_impl
= unsafe_impl_from_IDirectDrawSurface7(attachment
);
2175 TRACE("iface %p, flags %#x, attachment %p.\n", iface
, flags
, attachment
);
2177 return ddraw_surface_delete_attached_surface(surface
, attachment_impl
, (IUnknown
*)attachment
);
2180 static HRESULT WINAPI
ddraw_surface4_DeleteAttachedSurface(IDirectDrawSurface4
*iface
,
2181 DWORD flags
, IDirectDrawSurface4
*attachment
)
2183 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
2184 struct ddraw_surface
*attachment_impl
= unsafe_impl_from_IDirectDrawSurface4(attachment
);
2186 TRACE("iface %p, flags %#x, attachment %p.\n", iface
, flags
, attachment
);
2188 return ddraw_surface_delete_attached_surface(surface
, attachment_impl
, (IUnknown
*)attachment
);
2191 static HRESULT WINAPI
ddraw_surface3_DeleteAttachedSurface(IDirectDrawSurface3
*iface
,
2192 DWORD flags
, IDirectDrawSurface3
*attachment
)
2194 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface3(iface
);
2195 struct ddraw_surface
*attachment_impl
= unsafe_impl_from_IDirectDrawSurface3(attachment
);
2197 TRACE("iface %p, flags %#x, attachment %p.\n", iface
, flags
, attachment
);
2199 return ddraw_surface_delete_attached_surface(surface
, attachment_impl
, (IUnknown
*)attachment
);
2202 static HRESULT WINAPI
ddraw_surface2_DeleteAttachedSurface(IDirectDrawSurface2
*iface
,
2203 DWORD flags
, IDirectDrawSurface2
*attachment
)
2205 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface2(iface
);
2206 struct ddraw_surface
*attachment_impl
= unsafe_impl_from_IDirectDrawSurface2(attachment
);
2208 TRACE("iface %p, flags %#x, attachment %p.\n", iface
, flags
, attachment
);
2210 return ddraw_surface_delete_attached_surface(surface
, attachment_impl
, (IUnknown
*)attachment
);
2213 static HRESULT WINAPI
ddraw_surface1_DeleteAttachedSurface(IDirectDrawSurface
*iface
,
2214 DWORD flags
, IDirectDrawSurface
*attachment
)
2216 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface(iface
);
2217 struct ddraw_surface
*attachment_impl
= unsafe_impl_from_IDirectDrawSurface(attachment
);
2219 TRACE("iface %p, flags %#x, attachment %p.\n", iface
, flags
, attachment
);
2221 return ddraw_surface_delete_attached_surface(surface
, attachment_impl
, (IUnknown
*)attachment
);
2224 /*****************************************************************************
2225 * IDirectDrawSurface7::AddOverlayDirtyRect
2227 * "This method is not currently implemented"
2235 *****************************************************************************/
2236 static HRESULT WINAPI
ddraw_surface7_AddOverlayDirtyRect(IDirectDrawSurface7
*iface
, RECT
*Rect
)
2238 TRACE("iface %p, rect %s.\n", iface
, wine_dbgstr_rect(Rect
));
2240 return DDERR_UNSUPPORTED
; /* unchecked */
2243 static HRESULT WINAPI
ddraw_surface4_AddOverlayDirtyRect(IDirectDrawSurface4
*iface
, RECT
*rect
)
2245 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
2247 TRACE("iface %p, rect %s.\n", iface
, wine_dbgstr_rect(rect
));
2249 return ddraw_surface7_AddOverlayDirtyRect(&surface
->IDirectDrawSurface7_iface
, rect
);
2252 static HRESULT WINAPI
ddraw_surface3_AddOverlayDirtyRect(IDirectDrawSurface3
*iface
, RECT
*rect
)
2254 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface3(iface
);
2256 TRACE("iface %p, rect %s.\n", iface
, wine_dbgstr_rect(rect
));
2258 return ddraw_surface7_AddOverlayDirtyRect(&surface
->IDirectDrawSurface7_iface
, rect
);
2261 static HRESULT WINAPI
ddraw_surface2_AddOverlayDirtyRect(IDirectDrawSurface2
*iface
, RECT
*rect
)
2263 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface2(iface
);
2265 TRACE("iface %p, rect %s.\n", iface
, wine_dbgstr_rect(rect
));
2267 return ddraw_surface7_AddOverlayDirtyRect(&surface
->IDirectDrawSurface7_iface
, rect
);
2270 static HRESULT WINAPI
ddraw_surface1_AddOverlayDirtyRect(IDirectDrawSurface
*iface
, RECT
*rect
)
2272 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface(iface
);
2274 TRACE("iface %p, rect %s.\n", iface
, wine_dbgstr_rect(rect
));
2276 return ddraw_surface7_AddOverlayDirtyRect(&surface
->IDirectDrawSurface7_iface
, rect
);
2279 /*****************************************************************************
2280 * IDirectDrawSurface7::GetDC
2282 * Returns a GDI device context for the surface
2285 * hdc: Address of a HDC variable to store the dc to
2289 * DDERR_INVALIDPARAMS if hdc is NULL
2291 *****************************************************************************/
2292 static HRESULT WINAPI
ddraw_surface7_GetDC(IDirectDrawSurface7
*iface
, HDC
*dc
)
2294 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface7(iface
);
2297 TRACE("iface %p, dc %p.\n", iface
, dc
);
2300 return DDERR_INVALIDPARAMS
;
2302 wined3d_mutex_lock();
2304 hr
= DDERR_DCALREADYCREATED
;
2305 else if (surface
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)
2306 hr
= ddraw_surface_update_frontbuffer(surface
, NULL
, TRUE
, 0);
2308 hr
= wined3d_texture_get_dc(surface
->wined3d_texture
, surface
->sub_resource_idx
, dc
);
2314 if (format_is_paletteindexed(&surface
->surface_desc
.u4
.ddpfPixelFormat
))
2316 const struct ddraw_palette
*palette
;
2318 if (surface
->palette
)
2319 palette
= surface
->palette
;
2320 else if (surface
->ddraw
->primary
)
2321 palette
= surface
->ddraw
->primary
->palette
;
2326 wined3d_palette_apply_to_dc(palette
->wined3d_palette
, *dc
);
2330 wined3d_mutex_unlock();
2333 /* Some, but not all errors set *dc to NULL. E.g. DCALREADYCREATED
2334 * does not touch *dc. */
2335 case WINED3DERR_INVALIDCALL
:
2337 return DDERR_CANTCREATEDC
;
2344 static HRESULT WINAPI
ddraw_surface4_GetDC(IDirectDrawSurface4
*iface
, HDC
*dc
)
2346 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
2348 TRACE("iface %p, dc %p.\n", iface
, dc
);
2350 return ddraw_surface7_GetDC(&surface
->IDirectDrawSurface7_iface
, dc
);
2353 static HRESULT WINAPI
ddraw_surface3_GetDC(IDirectDrawSurface3
*iface
, HDC
*dc
)
2355 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface3(iface
);
2357 TRACE("iface %p, dc %p.\n", iface
, dc
);
2359 return ddraw_surface7_GetDC(&surface
->IDirectDrawSurface7_iface
, dc
);
2362 static HRESULT WINAPI
ddraw_surface2_GetDC(IDirectDrawSurface2
*iface
, HDC
*dc
)
2364 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface2(iface
);
2366 TRACE("iface %p, dc %p.\n", iface
, dc
);
2368 return ddraw_surface7_GetDC(&surface
->IDirectDrawSurface7_iface
, dc
);
2371 static HRESULT WINAPI
ddraw_surface1_GetDC(IDirectDrawSurface
*iface
, HDC
*dc
)
2373 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface(iface
);
2375 TRACE("iface %p, dc %p.\n", iface
, dc
);
2377 return ddraw_surface7_GetDC(&surface
->IDirectDrawSurface7_iface
, dc
);
2380 /*****************************************************************************
2381 * IDirectDrawSurface7::ReleaseDC
2383 * Releases the DC that was constructed with GetDC
2386 * hdc: HDC to release
2389 * DD_OK on success, error code otherwise.
2391 *****************************************************************************/
2392 static HRESULT WINAPI
ddraw_surface7_ReleaseDC(IDirectDrawSurface7
*iface
, HDC hdc
)
2394 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface7(iface
);
2397 TRACE("iface %p, dc %p.\n", iface
, hdc
);
2399 wined3d_mutex_lock();
2404 else if (SUCCEEDED(hr
= wined3d_texture_release_dc(surface
->wined3d_texture
, surface
->sub_resource_idx
, hdc
)))
2407 if (surface
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)
2408 hr
= ddraw_surface_update_frontbuffer(surface
, NULL
, FALSE
, 0);
2410 wined3d_mutex_unlock();
2416 static HRESULT WINAPI
ddraw_surface4_ReleaseDC(IDirectDrawSurface4
*iface
, HDC dc
)
2418 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
2420 TRACE("iface %p, dc %p.\n", iface
, dc
);
2422 return ddraw_surface7_ReleaseDC(&surface
->IDirectDrawSurface7_iface
, dc
);
2425 static HRESULT WINAPI
ddraw_surface3_ReleaseDC(IDirectDrawSurface3
*iface
, HDC dc
)
2427 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface3(iface
);
2429 TRACE("iface %p, dc %p.\n", iface
, dc
);
2431 return ddraw_surface7_ReleaseDC(&surface
->IDirectDrawSurface7_iface
, dc
);
2434 static HRESULT WINAPI
ddraw_surface2_ReleaseDC(IDirectDrawSurface2
*iface
, HDC dc
)
2436 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface2(iface
);
2438 TRACE("iface %p, dc %p.\n", iface
, dc
);
2440 return ddraw_surface7_ReleaseDC(&surface
->IDirectDrawSurface7_iface
, dc
);
2443 static HRESULT WINAPI
ddraw_surface1_ReleaseDC(IDirectDrawSurface
*iface
, HDC dc
)
2445 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface(iface
);
2447 TRACE("iface %p, dc %p.\n", iface
, dc
);
2449 return ddraw_surface7_ReleaseDC(&surface
->IDirectDrawSurface7_iface
, dc
);
2452 /*****************************************************************************
2453 * IDirectDrawSurface7::GetCaps
2455 * Returns the surface's caps
2458 * Caps: Address to write the caps to
2462 * DDERR_INVALIDPARAMS if Caps is NULL
2464 *****************************************************************************/
2465 static HRESULT WINAPI
ddraw_surface7_GetCaps(IDirectDrawSurface7
*iface
, DDSCAPS2
*Caps
)
2467 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface7(iface
);
2469 TRACE("iface %p, caps %p.\n", iface
, Caps
);
2472 return DDERR_INVALIDPARAMS
;
2474 *Caps
= surface
->surface_desc
.ddsCaps
;
2479 static HRESULT WINAPI
ddraw_surface4_GetCaps(IDirectDrawSurface4
*iface
, DDSCAPS2
*caps
)
2481 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
2483 TRACE("iface %p, caps %p.\n", iface
, caps
);
2485 return ddraw_surface7_GetCaps(&surface
->IDirectDrawSurface7_iface
, caps
);
2488 static HRESULT WINAPI
ddraw_surface3_GetCaps(IDirectDrawSurface3
*iface
, DDSCAPS
*caps
)
2490 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface3(iface
);
2494 TRACE("iface %p, caps %p.\n", iface
, caps
);
2496 hr
= ddraw_surface7_GetCaps(&surface
->IDirectDrawSurface7_iface
, &caps2
);
2497 if (FAILED(hr
)) return hr
;
2499 caps
->dwCaps
= caps2
.dwCaps
;
2503 static HRESULT WINAPI
ddraw_surface2_GetCaps(IDirectDrawSurface2
*iface
, DDSCAPS
*caps
)
2505 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface2(iface
);
2509 TRACE("iface %p, caps %p.\n", iface
, caps
);
2511 hr
= ddraw_surface7_GetCaps(&surface
->IDirectDrawSurface7_iface
, &caps2
);
2512 if (FAILED(hr
)) return hr
;
2514 caps
->dwCaps
= caps2
.dwCaps
;
2518 static HRESULT WINAPI
ddraw_surface1_GetCaps(IDirectDrawSurface
*iface
, DDSCAPS
*caps
)
2520 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface(iface
);
2524 TRACE("iface %p, caps %p.\n", iface
, caps
);
2526 hr
= ddraw_surface7_GetCaps(&surface
->IDirectDrawSurface7_iface
, &caps2
);
2527 if (FAILED(hr
)) return hr
;
2529 caps
->dwCaps
= caps2
.dwCaps
;
2533 static HRESULT WINAPI
ddraw_surface7_SetPriority(IDirectDrawSurface7
*iface
, DWORD priority
)
2535 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface7(iface
);
2536 DWORD managed
= DDSCAPS2_TEXTUREMANAGE
| DDSCAPS2_D3DTEXTUREMANAGE
;
2538 struct wined3d_resource
*resource
;
2540 TRACE("iface %p, priority %u.\n", iface
, priority
);
2542 wined3d_mutex_lock();
2543 /* No need to check for offscreen plain surfaces or mipmap sublevels. SetPriority
2544 * calls on such surfaces segfault on Windows. */
2545 if (!(surface
->surface_desc
.ddsCaps
.dwCaps2
& managed
))
2547 WARN("Called on non-managed texture returning DDERR_INVALIDPARAMS.\n");
2548 hr
= DDERR_INVALIDPARAMS
;
2552 resource
= wined3d_texture_get_resource(surface
->wined3d_texture
);
2553 wined3d_resource_set_priority(resource
, priority
);
2556 wined3d_mutex_unlock();
2561 static HRESULT WINAPI
ddraw_surface7_GetPriority(IDirectDrawSurface7
*iface
, DWORD
*priority
)
2563 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface7(iface
);
2564 const struct wined3d_resource
*resource
;
2565 DWORD managed
= DDSCAPS2_TEXTUREMANAGE
| DDSCAPS2_D3DTEXTUREMANAGE
;
2568 TRACE("iface %p, priority %p.\n", iface
, priority
);
2570 wined3d_mutex_lock();
2571 if (surface
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_OFFSCREENPLAIN
)
2573 WARN("Called on offscreenplain surface, returning DDERR_INVALIDOBJECT.\n");
2574 hr
= DDERR_INVALIDOBJECT
;
2576 else if (!(surface
->surface_desc
.ddsCaps
.dwCaps2
& managed
) || !surface
->is_complex_root
)
2578 WARN("Called on non-managed texture or non-root surface, returning DDERR_INVALIDPARAMS.\n");
2579 hr
= DDERR_INVALIDPARAMS
;
2583 resource
= wined3d_texture_get_resource(surface
->wined3d_texture
);
2584 *priority
= wined3d_resource_get_priority(resource
);
2587 wined3d_mutex_unlock();
2592 /*****************************************************************************
2593 * IDirectDrawSurface7::SetPrivateData
2595 * Stores some data in the surface that is intended for the application's
2599 * tag: GUID that identifies the data
2600 * Data: Pointer to the private data
2601 * Size: Size of the private data
2605 * D3D_OK on success, error code otherwise.
2607 *****************************************************************************/
2608 static HRESULT WINAPI
ddraw_surface7_SetPrivateData(IDirectDrawSurface7
*iface
,
2609 REFGUID tag
, void *data
, DWORD size
, DWORD flags
)
2611 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface7(iface
);
2614 TRACE("iface %p, tag %s, data %p, data_size %u, flags %#x.\n",
2615 iface
, debugstr_guid(tag
), data
, size
, flags
);
2619 WARN("data is NULL, returning DDERR_INVALIDPARAMS.\n");
2620 return DDERR_INVALIDPARAMS
;
2623 wined3d_mutex_lock();
2624 hr
= wined3d_private_store_set_private_data(&surface
->private_store
, tag
, data
, size
, flags
);
2625 wined3d_mutex_unlock();
2626 return hr_ddraw_from_wined3d(hr
);
2629 static HRESULT WINAPI
ddraw_surface4_SetPrivateData(IDirectDrawSurface4
*iface
,
2630 REFGUID tag
, void *data
, DWORD size
, DWORD flags
)
2632 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
2634 TRACE("iface %p, tag %s, data %p, data_size %u, flags %#x.\n",
2635 iface
, debugstr_guid(tag
), data
, size
, flags
);
2637 return ddraw_surface7_SetPrivateData(&surface
->IDirectDrawSurface7_iface
, tag
, data
, size
, flags
);
2640 /*****************************************************************************
2641 * IDirectDrawSurface7::GetPrivateData
2643 * Returns the private data set with IDirectDrawSurface7::SetPrivateData
2646 * tag: GUID of the data to return
2647 * Data: Address where to write the data to
2648 * Size: Size of the buffer at Data
2652 * DDERR_INVALIDPARAMS if Data is NULL
2654 *****************************************************************************/
2655 static HRESULT WINAPI
ddraw_surface7_GetPrivateData(IDirectDrawSurface7
*iface
, REFGUID tag
, void *data
, DWORD
*size
)
2657 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface7(iface
);
2658 const struct wined3d_private_data
*stored_data
;
2661 TRACE("iface %p, tag %s, data %p, data_size %p.\n",
2662 iface
, debugstr_guid(tag
), data
, size
);
2664 wined3d_mutex_lock();
2665 stored_data
= wined3d_private_store_get_private_data(&surface
->private_store
, tag
);
2668 hr
= DDERR_NOTFOUND
;
2673 hr
= DDERR_INVALIDPARAMS
;
2676 if (*size
< stored_data
->size
)
2678 *size
= stored_data
->size
;
2679 hr
= DDERR_MOREDATA
;
2684 hr
= DDERR_INVALIDPARAMS
;
2688 *size
= stored_data
->size
;
2689 memcpy(data
, stored_data
->content
.data
, stored_data
->size
);
2693 wined3d_mutex_unlock();
2697 static HRESULT WINAPI
ddraw_surface4_GetPrivateData(IDirectDrawSurface4
*iface
, REFGUID tag
, void *data
, DWORD
*size
)
2699 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
2701 TRACE("iface %p, tag %s, data %p, data_size %p.\n",
2702 iface
, debugstr_guid(tag
), data
, size
);
2704 return ddraw_surface7_GetPrivateData(&surface
->IDirectDrawSurface7_iface
, tag
, data
, size
);
2707 /*****************************************************************************
2708 * IDirectDrawSurface7::FreePrivateData
2710 * Frees private data stored in the surface
2713 * tag: Tag of the data to free
2716 * D3D_OK on success, error code otherwise.
2718 *****************************************************************************/
2719 static HRESULT WINAPI
ddraw_surface7_FreePrivateData(IDirectDrawSurface7
*iface
, REFGUID tag
)
2721 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface7(iface
);
2722 struct wined3d_private_data
*entry
;
2724 TRACE("iface %p, tag %s.\n", iface
, debugstr_guid(tag
));
2726 wined3d_mutex_lock();
2727 entry
= wined3d_private_store_get_private_data(&surface
->private_store
, tag
);
2730 wined3d_mutex_unlock();
2731 return DDERR_NOTFOUND
;
2734 wined3d_private_store_free_private_data(&surface
->private_store
, entry
);
2735 wined3d_mutex_unlock();
2740 static HRESULT WINAPI
ddraw_surface4_FreePrivateData(IDirectDrawSurface4
*iface
, REFGUID tag
)
2742 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
2744 TRACE("iface %p, tag %s.\n", iface
, debugstr_guid(tag
));
2746 return ddraw_surface7_FreePrivateData(&surface
->IDirectDrawSurface7_iface
, tag
);
2749 /*****************************************************************************
2750 * IDirectDrawSurface7::PageLock
2752 * Prevents a sysmem surface from being paged out
2755 * Flags: Not used, must be 0(unchecked)
2758 * DD_OK, because it's a stub
2760 *****************************************************************************/
2761 static HRESULT WINAPI
ddraw_surface7_PageLock(IDirectDrawSurface7
*iface
, DWORD Flags
)
2763 TRACE("iface %p, flags %#x.\n", iface
, Flags
);
2765 /* This is Windows memory management related - we don't need this */
2769 static HRESULT WINAPI
ddraw_surface4_PageLock(IDirectDrawSurface4
*iface
, DWORD flags
)
2771 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
2773 TRACE("iface %p, flags %#x.\n", iface
, flags
);
2775 return ddraw_surface7_PageLock(&surface
->IDirectDrawSurface7_iface
, flags
);
2778 static HRESULT WINAPI
ddraw_surface3_PageLock(IDirectDrawSurface3
*iface
, DWORD flags
)
2780 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface3(iface
);
2782 TRACE("iface %p, flags %#x.\n", iface
, flags
);
2784 return ddraw_surface7_PageLock(&surface
->IDirectDrawSurface7_iface
, flags
);
2787 static HRESULT WINAPI
ddraw_surface2_PageLock(IDirectDrawSurface2
*iface
, DWORD flags
)
2789 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface2(iface
);
2791 TRACE("iface %p, flags %#x.\n", iface
, flags
);
2793 return ddraw_surface7_PageLock(&surface
->IDirectDrawSurface7_iface
, flags
);
2796 /*****************************************************************************
2797 * IDirectDrawSurface7::PageUnlock
2799 * Allows a sysmem surface to be paged out
2802 * Flags: Not used, must be 0(unchecked)
2805 * DD_OK, because it's a stub
2807 *****************************************************************************/
2808 static HRESULT WINAPI
ddraw_surface7_PageUnlock(IDirectDrawSurface7
*iface
, DWORD Flags
)
2810 TRACE("iface %p, flags %#x.\n", iface
, Flags
);
2815 static HRESULT WINAPI
ddraw_surface4_PageUnlock(IDirectDrawSurface4
*iface
, DWORD flags
)
2817 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
2819 TRACE("iface %p, flags %#x.\n", iface
, flags
);
2821 return ddraw_surface7_PageUnlock(&surface
->IDirectDrawSurface7_iface
, flags
);
2824 static HRESULT WINAPI
ddraw_surface3_PageUnlock(IDirectDrawSurface3
*iface
, DWORD flags
)
2826 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface3(iface
);
2828 TRACE("iface %p, flags %#x.\n", iface
, flags
);
2830 return ddraw_surface7_PageUnlock(&surface
->IDirectDrawSurface7_iface
, flags
);
2833 static HRESULT WINAPI
ddraw_surface2_PageUnlock(IDirectDrawSurface2
*iface
, DWORD flags
)
2835 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface2(iface
);
2837 TRACE("iface %p, flags %#x.\n", iface
, flags
);
2839 return ddraw_surface7_PageUnlock(&surface
->IDirectDrawSurface7_iface
, flags
);
2842 /*****************************************************************************
2843 * IDirectDrawSurface7::BltBatch
2845 * An unimplemented function
2853 *****************************************************************************/
2854 static HRESULT WINAPI DECLSPEC_HOTPATCH
ddraw_surface7_BltBatch(IDirectDrawSurface7
*iface
, DDBLTBATCH
*Batch
, DWORD Count
, DWORD Flags
)
2856 TRACE("iface %p, batch %p, count %u, flags %#x.\n", iface
, Batch
, Count
, Flags
);
2858 /* MSDN: "not currently implemented" */
2859 return DDERR_UNSUPPORTED
;
2862 static HRESULT WINAPI DECLSPEC_HOTPATCH
ddraw_surface4_BltBatch(IDirectDrawSurface4
*iface
, DDBLTBATCH
*batch
, DWORD count
, DWORD flags
)
2864 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
2866 TRACE("iface %p, batch %p, count %u, flags %#x.\n", iface
, batch
, count
, flags
);
2868 return ddraw_surface7_BltBatch(&surface
->IDirectDrawSurface7_iface
, batch
, count
, flags
);
2871 static HRESULT WINAPI DECLSPEC_HOTPATCH
ddraw_surface3_BltBatch(IDirectDrawSurface3
*iface
, DDBLTBATCH
*batch
, DWORD count
, DWORD flags
)
2873 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface3(iface
);
2875 TRACE("iface %p, batch %p, count %u, flags %#x.\n", iface
, batch
, count
, flags
);
2877 return ddraw_surface7_BltBatch(&surface
->IDirectDrawSurface7_iface
, batch
, count
, flags
);
2880 static HRESULT WINAPI DECLSPEC_HOTPATCH
ddraw_surface2_BltBatch(IDirectDrawSurface2
*iface
, DDBLTBATCH
*batch
, DWORD count
, DWORD flags
)
2882 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface2(iface
);
2884 TRACE("iface %p, batch %p, count %u, flags %#x.\n", iface
, batch
, count
, flags
);
2886 return ddraw_surface7_BltBatch(&surface
->IDirectDrawSurface7_iface
, batch
, count
, flags
);
2889 static HRESULT WINAPI DECLSPEC_HOTPATCH
ddraw_surface1_BltBatch(IDirectDrawSurface
*iface
, DDBLTBATCH
*batch
, DWORD count
, DWORD flags
)
2891 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface(iface
);
2893 TRACE("iface %p, batch %p, count %u, flags %#x.\n", iface
, batch
, count
, flags
);
2895 return ddraw_surface7_BltBatch(&surface
->IDirectDrawSurface7_iface
, batch
, count
, flags
);
2898 /*****************************************************************************
2899 * IDirectDrawSurface7::EnumAttachedSurfaces
2901 * Enumerates all surfaces attached to this surface
2904 * context: Pointer to pass unmodified to the callback
2905 * cb: Callback function to call for each surface
2909 * DDERR_INVALIDPARAMS if cb is NULL
2911 *****************************************************************************/
2912 static HRESULT WINAPI
ddraw_surface7_EnumAttachedSurfaces(IDirectDrawSurface7
*iface
,
2913 void *context
, LPDDENUMSURFACESCALLBACK7 cb
)
2915 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface7(iface
);
2916 struct ddraw_surface
*surf
;
2917 DDSURFACEDESC2 desc
;
2920 /* Attached surfaces aren't handled in WineD3D */
2921 TRACE("iface %p, context %p, callback %p.\n", iface
, context
, cb
);
2924 return DDERR_INVALIDPARAMS
;
2926 wined3d_mutex_lock();
2928 for(i
= 0; i
< MAX_COMPLEX_ATTACHED
; i
++)
2930 surf
= surface
->complex_array
[i
];
2933 ddraw_surface7_AddRef(&surf
->IDirectDrawSurface7_iface
);
2934 desc
= surf
->surface_desc
;
2935 /* check: != DDENUMRET_OK or == DDENUMRET_CANCEL? */
2936 if (cb(&surf
->IDirectDrawSurface7_iface
, &desc
, context
) == DDENUMRET_CANCEL
)
2938 wined3d_mutex_unlock();
2943 for (surf
= surface
->next_attached
; surf
!= NULL
; surf
= surf
->next_attached
)
2945 ddraw_surface7_AddRef(&surf
->IDirectDrawSurface7_iface
);
2946 desc
= surf
->surface_desc
;
2947 /* check: != DDENUMRET_OK or == DDENUMRET_CANCEL? */
2948 if (cb(&surf
->IDirectDrawSurface7_iface
, &desc
, context
) == DDENUMRET_CANCEL
)
2950 wined3d_mutex_unlock();
2955 TRACE(" end of enumeration.\n");
2957 wined3d_mutex_unlock();
2962 struct callback_info2
2964 LPDDENUMSURFACESCALLBACK2 callback
;
2968 struct callback_info
2970 LPDDENUMSURFACESCALLBACK callback
;
2974 static HRESULT CALLBACK
EnumCallback2(IDirectDrawSurface7
*surface
, DDSURFACEDESC2
*surface_desc
, void *context
)
2976 struct ddraw_surface
*surface_impl
= impl_from_IDirectDrawSurface7(surface
);
2977 const struct callback_info2
*info
= context
;
2979 ddraw_surface4_AddRef(&surface_impl
->IDirectDrawSurface4_iface
);
2980 ddraw_surface7_Release(surface
);
2982 return info
->callback(&surface_impl
->IDirectDrawSurface4_iface
, surface_desc
, info
->context
);
2985 static HRESULT CALLBACK
EnumCallback(IDirectDrawSurface7
*surface
, DDSURFACEDESC2
*surface_desc
, void *context
)
2987 struct ddraw_surface
*surface_impl
= impl_from_IDirectDrawSurface7(surface
);
2988 const struct callback_info
*info
= context
;
2990 ddraw_surface1_AddRef(&surface_impl
->IDirectDrawSurface_iface
);
2991 ddraw_surface7_Release(surface
);
2993 /* FIXME: Check surface_test.dwSize */
2994 return info
->callback(&surface_impl
->IDirectDrawSurface_iface
,
2995 (DDSURFACEDESC
*)surface_desc
, info
->context
);
2998 static HRESULT WINAPI
ddraw_surface4_EnumAttachedSurfaces(IDirectDrawSurface4
*iface
,
2999 void *context
, LPDDENUMSURFACESCALLBACK2 callback
)
3001 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
3002 struct callback_info2 info
;
3004 TRACE("iface %p, context %p, callback %p.\n", iface
, context
, callback
);
3006 info
.callback
= callback
;
3007 info
.context
= context
;
3009 return ddraw_surface7_EnumAttachedSurfaces(&surface
->IDirectDrawSurface7_iface
,
3010 &info
, EnumCallback2
);
3013 static HRESULT WINAPI
ddraw_surface3_EnumAttachedSurfaces(IDirectDrawSurface3
*iface
,
3014 void *context
, LPDDENUMSURFACESCALLBACK callback
)
3016 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface3(iface
);
3017 struct callback_info info
;
3019 TRACE("iface %p, context %p, callback %p.\n", iface
, context
, callback
);
3021 info
.callback
= callback
;
3022 info
.context
= context
;
3024 return ddraw_surface7_EnumAttachedSurfaces(&surface
->IDirectDrawSurface7_iface
,
3025 &info
, EnumCallback
);
3028 static HRESULT WINAPI
ddraw_surface2_EnumAttachedSurfaces(IDirectDrawSurface2
*iface
,
3029 void *context
, LPDDENUMSURFACESCALLBACK callback
)
3031 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface2(iface
);
3032 struct callback_info info
;
3034 TRACE("iface %p, context %p, callback %p.\n", iface
, context
, callback
);
3036 info
.callback
= callback
;
3037 info
.context
= context
;
3039 return ddraw_surface7_EnumAttachedSurfaces(&surface
->IDirectDrawSurface7_iface
,
3040 &info
, EnumCallback
);
3043 static HRESULT WINAPI
ddraw_surface1_EnumAttachedSurfaces(IDirectDrawSurface
*iface
,
3044 void *context
, LPDDENUMSURFACESCALLBACK callback
)
3046 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface(iface
);
3047 struct callback_info info
;
3049 TRACE("iface %p, context %p, callback %p.\n", iface
, context
, callback
);
3051 info
.callback
= callback
;
3052 info
.context
= context
;
3054 return ddraw_surface7_EnumAttachedSurfaces(&surface
->IDirectDrawSurface7_iface
,
3055 &info
, EnumCallback
);
3058 /*****************************************************************************
3059 * IDirectDrawSurface7::EnumOverlayZOrders
3061 * "Enumerates the overlay surfaces on the specified destination"
3064 * Flags: DDENUMOVERLAYZ_BACKTOFRONT or DDENUMOVERLAYZ_FRONTTOBACK
3065 * context: context to pass back to the callback
3066 * cb: callback function to call for each enumerated surface
3069 * DD_OK, because it's a stub
3071 *****************************************************************************/
3072 static HRESULT WINAPI
ddraw_surface7_EnumOverlayZOrders(IDirectDrawSurface7
*iface
,
3073 DWORD Flags
, void *context
, LPDDENUMSURFACESCALLBACK7 cb
)
3075 FIXME("iface %p, flags %#x, context %p, callback %p stub!\n", iface
, Flags
, context
, cb
);
3080 static HRESULT WINAPI
ddraw_surface4_EnumOverlayZOrders(IDirectDrawSurface4
*iface
,
3081 DWORD flags
, void *context
, LPDDENUMSURFACESCALLBACK2 callback
)
3083 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
3084 struct callback_info2 info
;
3086 TRACE("iface %p, flags %#x, context %p, callback %p.\n", iface
, flags
, context
, callback
);
3088 info
.callback
= callback
;
3089 info
.context
= context
;
3091 return ddraw_surface7_EnumOverlayZOrders(&surface
->IDirectDrawSurface7_iface
,
3092 flags
, &info
, EnumCallback2
);
3095 static HRESULT WINAPI
ddraw_surface3_EnumOverlayZOrders(IDirectDrawSurface3
*iface
,
3096 DWORD flags
, void *context
, LPDDENUMSURFACESCALLBACK callback
)
3098 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface3(iface
);
3099 struct callback_info info
;
3101 TRACE("iface %p, flags %#x, context %p, callback %p.\n", iface
, flags
, context
, callback
);
3103 info
.callback
= callback
;
3104 info
.context
= context
;
3106 return ddraw_surface7_EnumOverlayZOrders(&surface
->IDirectDrawSurface7_iface
,
3107 flags
, &info
, EnumCallback
);
3110 static HRESULT WINAPI
ddraw_surface2_EnumOverlayZOrders(IDirectDrawSurface2
*iface
,
3111 DWORD flags
, void *context
, LPDDENUMSURFACESCALLBACK callback
)
3113 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface2(iface
);
3114 struct callback_info info
;
3116 TRACE("iface %p, flags %#x, context %p, callback %p.\n", iface
, flags
, context
, callback
);
3118 info
.callback
= callback
;
3119 info
.context
= context
;
3121 return ddraw_surface7_EnumOverlayZOrders(&surface
->IDirectDrawSurface7_iface
,
3122 flags
, &info
, EnumCallback
);
3125 static HRESULT WINAPI
ddraw_surface1_EnumOverlayZOrders(IDirectDrawSurface
*iface
,
3126 DWORD flags
, void *context
, LPDDENUMSURFACESCALLBACK callback
)
3128 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface(iface
);
3129 struct callback_info info
;
3131 TRACE("iface %p, flags %#x, context %p, callback %p.\n", iface
, flags
, context
, callback
);
3133 info
.callback
= callback
;
3134 info
.context
= context
;
3136 return ddraw_surface7_EnumOverlayZOrders(&surface
->IDirectDrawSurface7_iface
,
3137 flags
, &info
, EnumCallback
);
3140 /*****************************************************************************
3141 * IDirectDrawSurface7::GetBltStatus
3143 * Returns the blitting status
3146 * Flags: DDGBS_CANBLT or DDGBS_ISBLTDONE
3148 *****************************************************************************/
3149 static HRESULT WINAPI
ddraw_surface7_GetBltStatus(IDirectDrawSurface7
*iface
, DWORD Flags
)
3151 TRACE("iface %p, flags %#x.\n", iface
, Flags
);
3155 case WINEDDGBS_CANBLT
:
3156 case WINEDDGBS_ISBLTDONE
:
3160 return DDERR_INVALIDPARAMS
;
3164 static HRESULT WINAPI
ddraw_surface4_GetBltStatus(IDirectDrawSurface4
*iface
, DWORD flags
)
3166 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
3168 TRACE("iface %p, flags %#x.\n", iface
, flags
);
3170 return ddraw_surface7_GetBltStatus(&surface
->IDirectDrawSurface7_iface
, flags
);
3173 static HRESULT WINAPI
ddraw_surface3_GetBltStatus(IDirectDrawSurface3
*iface
, DWORD flags
)
3175 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface3(iface
);
3177 TRACE("iface %p, flags %#x.\n", iface
, flags
);
3179 return ddraw_surface7_GetBltStatus(&surface
->IDirectDrawSurface7_iface
, flags
);
3182 static HRESULT WINAPI
ddraw_surface2_GetBltStatus(IDirectDrawSurface2
*iface
, DWORD flags
)
3184 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface2(iface
);
3186 TRACE("iface %p, flags %#x.\n", iface
, flags
);
3188 return ddraw_surface7_GetBltStatus(&surface
->IDirectDrawSurface7_iface
, flags
);
3191 static HRESULT WINAPI
ddraw_surface1_GetBltStatus(IDirectDrawSurface
*iface
, DWORD flags
)
3193 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface(iface
);
3195 TRACE("iface %p, flags %#x.\n", iface
, flags
);
3197 return ddraw_surface7_GetBltStatus(&surface
->IDirectDrawSurface7_iface
, flags
);
3200 /*****************************************************************************
3201 * IDirectDrawSurface7::GetColorKey
3203 * Returns the color key assigned to the surface
3207 * CKey: Address to store the key to
3211 * DDERR_INVALIDPARAMS if CKey is NULL
3213 *****************************************************************************/
3214 static HRESULT WINAPI
ddraw_surface7_GetColorKey(IDirectDrawSurface7
*iface
, DWORD Flags
, DDCOLORKEY
*CKey
)
3216 struct ddraw_surface
*This
= impl_from_IDirectDrawSurface7(iface
);
3218 TRACE("iface %p, flags %#x, color_key %p.\n", iface
, Flags
, CKey
);
3221 return DDERR_INVALIDPARAMS
;
3223 wined3d_mutex_lock();
3227 case DDCKEY_DESTBLT
:
3228 if (!(This
->surface_desc
.dwFlags
& DDSD_CKDESTBLT
))
3230 wined3d_mutex_unlock();
3231 return DDERR_NOCOLORKEY
;
3233 *CKey
= This
->surface_desc
.ddckCKDestBlt
;
3236 case DDCKEY_DESTOVERLAY
:
3237 if (!(This
->surface_desc
.dwFlags
& DDSD_CKDESTOVERLAY
))
3239 wined3d_mutex_unlock();
3240 return DDERR_NOCOLORKEY
;
3242 *CKey
= This
->surface_desc
.u3
.ddckCKDestOverlay
;
3246 if (!(This
->surface_desc
.dwFlags
& DDSD_CKSRCBLT
))
3248 wined3d_mutex_unlock();
3249 return DDERR_NOCOLORKEY
;
3251 *CKey
= This
->surface_desc
.ddckCKSrcBlt
;
3254 case DDCKEY_SRCOVERLAY
:
3255 if (!(This
->surface_desc
.dwFlags
& DDSD_CKSRCOVERLAY
))
3257 wined3d_mutex_unlock();
3258 return DDERR_NOCOLORKEY
;
3260 *CKey
= This
->surface_desc
.ddckCKSrcOverlay
;
3264 wined3d_mutex_unlock();
3265 return DDERR_INVALIDPARAMS
;
3268 wined3d_mutex_unlock();
3273 static HRESULT WINAPI
ddraw_surface4_GetColorKey(IDirectDrawSurface4
*iface
, DWORD flags
, DDCOLORKEY
*color_key
)
3275 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
3277 TRACE("iface %p, flags %#x, color_key %p.\n", iface
, flags
, color_key
);
3279 return ddraw_surface7_GetColorKey(&surface
->IDirectDrawSurface7_iface
, flags
, color_key
);
3282 static HRESULT WINAPI
ddraw_surface3_GetColorKey(IDirectDrawSurface3
*iface
, DWORD flags
, DDCOLORKEY
*color_key
)
3284 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface3(iface
);
3286 TRACE("iface %p, flags %#x, color_key %p.\n", iface
, flags
, color_key
);
3288 return ddraw_surface7_GetColorKey(&surface
->IDirectDrawSurface7_iface
, flags
, color_key
);
3291 static HRESULT WINAPI
ddraw_surface2_GetColorKey(IDirectDrawSurface2
*iface
, DWORD flags
, DDCOLORKEY
*color_key
)
3293 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface2(iface
);
3295 TRACE("iface %p, flags %#x, color_key %p.\n", iface
, flags
, color_key
);
3297 return ddraw_surface7_GetColorKey(&surface
->IDirectDrawSurface7_iface
, flags
, color_key
);
3300 static HRESULT WINAPI
ddraw_surface1_GetColorKey(IDirectDrawSurface
*iface
, DWORD flags
, DDCOLORKEY
*color_key
)
3302 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface(iface
);
3304 TRACE("iface %p, flags %#x, color_key %p.\n", iface
, flags
, color_key
);
3306 return ddraw_surface7_GetColorKey(&surface
->IDirectDrawSurface7_iface
, flags
, color_key
);
3309 /*****************************************************************************
3310 * IDirectDrawSurface7::GetFlipStatus
3312 * Returns the flipping status of the surface
3315 * Flags: DDGFS_CANFLIP of DDGFS_ISFLIPDONE
3317 *****************************************************************************/
3318 static HRESULT WINAPI
ddraw_surface7_GetFlipStatus(IDirectDrawSurface7
*iface
, DWORD Flags
)
3320 TRACE("iface %p, flags %#x.\n", iface
, Flags
);
3322 /* XXX: DDERR_INVALIDSURFACETYPE */
3326 case WINEDDGFS_CANFLIP
:
3327 case WINEDDGFS_ISFLIPDONE
:
3331 return DDERR_INVALIDPARAMS
;
3335 static HRESULT WINAPI
ddraw_surface4_GetFlipStatus(IDirectDrawSurface4
*iface
, DWORD flags
)
3337 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
3339 TRACE("iface %p, flags %#x.\n", iface
, flags
);
3341 return ddraw_surface7_GetFlipStatus(&surface
->IDirectDrawSurface7_iface
, flags
);
3344 static HRESULT WINAPI
ddraw_surface3_GetFlipStatus(IDirectDrawSurface3
*iface
, DWORD flags
)
3346 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface3(iface
);
3348 TRACE("iface %p, flags %#x.\n", iface
, flags
);
3350 return ddraw_surface7_GetFlipStatus(&surface
->IDirectDrawSurface7_iface
, flags
);
3353 static HRESULT WINAPI
ddraw_surface2_GetFlipStatus(IDirectDrawSurface2
*iface
, DWORD flags
)
3355 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface2(iface
);
3357 TRACE("iface %p, flags %#x.\n", iface
, flags
);
3359 return ddraw_surface7_GetFlipStatus(&surface
->IDirectDrawSurface7_iface
, flags
);
3362 static HRESULT WINAPI
ddraw_surface1_GetFlipStatus(IDirectDrawSurface
*iface
, DWORD flags
)
3364 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface(iface
);
3366 TRACE("iface %p, flags %#x.\n", iface
, flags
);
3368 return ddraw_surface7_GetFlipStatus(&surface
->IDirectDrawSurface7_iface
, flags
);
3371 /*****************************************************************************
3372 * IDirectDrawSurface7::GetOverlayPosition
3374 * Returns the display coordinates of a visible and active overlay surface
3381 * DDERR_NOTAOVERLAYSURFACE, because it's a stub
3382 *****************************************************************************/
3383 static HRESULT WINAPI
ddraw_surface7_GetOverlayPosition(IDirectDrawSurface7
*iface
, LONG
*x
, LONG
*y
)
3385 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface7(iface
);
3388 TRACE("iface %p, x %p, y %p.\n", iface
, x
, y
);
3390 wined3d_mutex_lock();
3391 hr
= wined3d_texture_get_overlay_position(surface
->wined3d_texture
,
3392 surface
->sub_resource_idx
, x
, y
);
3393 wined3d_mutex_unlock();
3398 static HRESULT WINAPI
ddraw_surface4_GetOverlayPosition(IDirectDrawSurface4
*iface
, LONG
*x
, LONG
*y
)
3400 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
3402 TRACE("iface %p, x %p, y %p.\n", iface
, x
, y
);
3404 return ddraw_surface7_GetOverlayPosition(&surface
->IDirectDrawSurface7_iface
, x
, y
);
3407 static HRESULT WINAPI
ddraw_surface3_GetOverlayPosition(IDirectDrawSurface3
*iface
, LONG
*x
, LONG
*y
)
3409 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface3(iface
);
3411 TRACE("iface %p, x %p, y %p.\n", iface
, x
, y
);
3413 return ddraw_surface7_GetOverlayPosition(&surface
->IDirectDrawSurface7_iface
, x
, y
);
3416 static HRESULT WINAPI
ddraw_surface2_GetOverlayPosition(IDirectDrawSurface2
*iface
, LONG
*x
, LONG
*y
)
3418 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface2(iface
);
3420 TRACE("iface %p, x %p, y %p.\n", iface
, x
, y
);
3422 return ddraw_surface7_GetOverlayPosition(&surface
->IDirectDrawSurface7_iface
, x
, y
);
3425 static HRESULT WINAPI
ddraw_surface1_GetOverlayPosition(IDirectDrawSurface
*iface
, LONG
*x
, LONG
*y
)
3427 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface(iface
);
3429 TRACE("iface %p, x %p, y %p.\n", iface
, x
, y
);
3431 return ddraw_surface7_GetOverlayPosition(&surface
->IDirectDrawSurface7_iface
, x
, y
);
3434 /*****************************************************************************
3435 * IDirectDrawSurface7::GetPixelFormat
3437 * Returns the pixel format of the Surface
3440 * PixelFormat: Pointer to a DDPIXELFORMAT structure to which the pixel
3441 * format should be written
3445 * DDERR_INVALIDPARAMS if PixelFormat is NULL
3447 *****************************************************************************/
3448 static HRESULT WINAPI
ddraw_surface7_GetPixelFormat(IDirectDrawSurface7
*iface
, DDPIXELFORMAT
*PixelFormat
)
3450 /* What is DDERR_INVALIDSURFACETYPE for here? */
3451 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface7(iface
);
3453 TRACE("iface %p, pixel_format %p.\n", iface
, PixelFormat
);
3456 return DDERR_INVALIDPARAMS
;
3458 wined3d_mutex_lock();
3459 DD_STRUCT_COPY_BYSIZE(PixelFormat
, &surface
->surface_desc
.u4
.ddpfPixelFormat
);
3460 wined3d_mutex_unlock();
3465 static HRESULT WINAPI
ddraw_surface4_GetPixelFormat(IDirectDrawSurface4
*iface
, DDPIXELFORMAT
*pixel_format
)
3467 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
3469 TRACE("iface %p, pixel_format %p.\n", iface
, pixel_format
);
3471 return ddraw_surface7_GetPixelFormat(&surface
->IDirectDrawSurface7_iface
, pixel_format
);
3474 static HRESULT WINAPI
ddraw_surface3_GetPixelFormat(IDirectDrawSurface3
*iface
, DDPIXELFORMAT
*pixel_format
)
3476 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface3(iface
);
3478 TRACE("iface %p, pixel_format %p.\n", iface
, pixel_format
);
3480 return ddraw_surface7_GetPixelFormat(&surface
->IDirectDrawSurface7_iface
, pixel_format
);
3483 static HRESULT WINAPI
ddraw_surface2_GetPixelFormat(IDirectDrawSurface2
*iface
, DDPIXELFORMAT
*pixel_format
)
3485 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface2(iface
);
3487 TRACE("iface %p, pixel_format %p.\n", iface
, pixel_format
);
3489 return ddraw_surface7_GetPixelFormat(&surface
->IDirectDrawSurface7_iface
, pixel_format
);
3492 static HRESULT WINAPI
ddraw_surface1_GetPixelFormat(IDirectDrawSurface
*iface
, DDPIXELFORMAT
*pixel_format
)
3494 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface(iface
);
3496 TRACE("iface %p, pixel_format %p.\n", iface
, pixel_format
);
3498 return ddraw_surface7_GetPixelFormat(&surface
->IDirectDrawSurface7_iface
, pixel_format
);
3501 /*****************************************************************************
3502 * IDirectDrawSurface7::GetSurfaceDesc
3504 * Returns the description of this surface
3507 * DDSD: Address of a DDSURFACEDESC2 structure that is to be filled with the
3512 * DDERR_INVALIDPARAMS if DDSD is NULL
3514 *****************************************************************************/
3515 static HRESULT WINAPI
ddraw_surface7_GetSurfaceDesc(IDirectDrawSurface7
*iface
, DDSURFACEDESC2
*DDSD
)
3517 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface7(iface
);
3519 TRACE("iface %p, surface_desc %p.\n", iface
, DDSD
);
3522 return DDERR_INVALIDPARAMS
;
3524 if (DDSD
->dwSize
!= sizeof(DDSURFACEDESC2
))
3526 WARN("Incorrect struct size %d, returning DDERR_INVALIDPARAMS\n",DDSD
->dwSize
);
3527 return DDERR_INVALIDPARAMS
;
3530 wined3d_mutex_lock();
3531 DD_STRUCT_COPY_BYSIZE(DDSD
, &surface
->surface_desc
);
3532 TRACE("Returning surface desc:\n");
3533 if (TRACE_ON(ddraw
)) DDRAW_dump_surface_desc(DDSD
);
3534 wined3d_mutex_unlock();
3539 static HRESULT WINAPI
ddraw_surface4_GetSurfaceDesc(IDirectDrawSurface4
*iface
, DDSURFACEDESC2
*DDSD
)
3541 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
3543 TRACE("iface %p, surface_desc %p.\n", iface
, DDSD
);
3545 return ddraw_surface7_GetSurfaceDesc(&surface
->IDirectDrawSurface7_iface
, DDSD
);
3548 static HRESULT WINAPI
ddraw_surface3_GetSurfaceDesc(IDirectDrawSurface3
*iface
, DDSURFACEDESC
*surface_desc
)
3550 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface3(iface
);
3552 TRACE("iface %p, surface_desc %p.\n", iface
, surface_desc
);
3554 if (!surface_desc
) return DDERR_INVALIDPARAMS
;
3556 if (surface_desc
->dwSize
!= sizeof(DDSURFACEDESC
))
3558 WARN("Incorrect structure size %u, returning DDERR_INVALIDPARAMS.\n", surface_desc
->dwSize
);
3559 return DDERR_INVALIDPARAMS
;
3562 wined3d_mutex_lock();
3563 DDSD2_to_DDSD(&surface
->surface_desc
, surface_desc
);
3564 TRACE("Returning surface desc:\n");
3565 if (TRACE_ON(ddraw
))
3567 /* DDRAW_dump_surface_desc handles the smaller size */
3568 DDRAW_dump_surface_desc((DDSURFACEDESC2
*)surface_desc
);
3570 wined3d_mutex_unlock();
3575 static HRESULT WINAPI
ddraw_surface2_GetSurfaceDesc(IDirectDrawSurface2
*iface
, DDSURFACEDESC
*DDSD
)
3577 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface2(iface
);
3579 TRACE("iface %p, surface_desc %p.\n", iface
, DDSD
);
3581 return ddraw_surface3_GetSurfaceDesc(&surface
->IDirectDrawSurface3_iface
, DDSD
);
3584 static HRESULT WINAPI
ddraw_surface1_GetSurfaceDesc(IDirectDrawSurface
*iface
, DDSURFACEDESC
*DDSD
)
3586 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface(iface
);
3588 TRACE("iface %p, surface_desc %p.\n", iface
, DDSD
);
3590 return ddraw_surface3_GetSurfaceDesc(&surface
->IDirectDrawSurface3_iface
, DDSD
);
3593 /*****************************************************************************
3594 * IDirectDrawSurface7::Initialize
3596 * Initializes the surface. This is a no-op in Wine
3599 * DD: Pointer to an DirectDraw interface
3600 * DDSD: Surface description for initialization
3603 * DDERR_ALREADYINITIALIZED
3605 *****************************************************************************/
3606 static HRESULT WINAPI
ddraw_surface7_Initialize(IDirectDrawSurface7
*iface
,
3607 IDirectDraw
*ddraw
, DDSURFACEDESC2
*surface_desc
)
3609 TRACE("iface %p, ddraw %p, surface_desc %p.\n", iface
, ddraw
, surface_desc
);
3611 return DDERR_ALREADYINITIALIZED
;
3614 static HRESULT WINAPI
ddraw_surface4_Initialize(IDirectDrawSurface4
*iface
,
3615 IDirectDraw
*ddraw
, DDSURFACEDESC2
*surface_desc
)
3617 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
3619 TRACE("iface %p, ddraw %p, surface_desc %p.\n", iface
, ddraw
, surface_desc
);
3621 return ddraw_surface7_Initialize(&surface
->IDirectDrawSurface7_iface
,
3622 ddraw
, surface_desc
);
3625 static HRESULT WINAPI
ddraw_surface3_Initialize(IDirectDrawSurface3
*iface
,
3626 IDirectDraw
*ddraw
, DDSURFACEDESC
*surface_desc
)
3628 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface3(iface
);
3629 DDSURFACEDESC2 surface_desc2
;
3631 TRACE("iface %p, ddraw %p, surface_desc %p.\n", iface
, ddraw
, surface_desc
);
3633 if (surface_desc
) DDSD_to_DDSD2(surface_desc
, &surface_desc2
);
3634 return ddraw_surface7_Initialize(&surface
->IDirectDrawSurface7_iface
,
3635 ddraw
, surface_desc
? &surface_desc2
: NULL
);
3638 static HRESULT WINAPI
ddraw_surface2_Initialize(IDirectDrawSurface2
*iface
,
3639 IDirectDraw
*ddraw
, DDSURFACEDESC
*surface_desc
)
3641 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface2(iface
);
3642 DDSURFACEDESC2 surface_desc2
;
3644 TRACE("iface %p, ddraw %p, surface_desc %p.\n", iface
, ddraw
, surface_desc
);
3646 if (surface_desc
) DDSD_to_DDSD2(surface_desc
, &surface_desc2
);
3647 return ddraw_surface7_Initialize(&surface
->IDirectDrawSurface7_iface
,
3648 ddraw
, surface_desc
? &surface_desc2
: NULL
);
3651 static HRESULT WINAPI
ddraw_surface1_Initialize(IDirectDrawSurface
*iface
,
3652 IDirectDraw
*ddraw
, DDSURFACEDESC
*surface_desc
)
3654 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface(iface
);
3655 DDSURFACEDESC2 surface_desc2
;
3657 TRACE("iface %p, ddraw %p, surface_desc %p.\n", iface
, ddraw
, surface_desc
);
3659 if (surface_desc
) DDSD_to_DDSD2(surface_desc
, &surface_desc2
);
3660 return ddraw_surface7_Initialize(&surface
->IDirectDrawSurface7_iface
,
3661 ddraw
, surface_desc
? &surface_desc2
: NULL
);
3664 /*****************************************************************************
3665 * IDirect3DTexture1::Initialize
3667 * The sdk says it's not implemented
3675 *****************************************************************************/
3676 static HRESULT WINAPI
d3d_texture1_Initialize(IDirect3DTexture
*iface
,
3677 IDirect3DDevice
*device
, IDirectDrawSurface
*surface
)
3679 TRACE("iface %p, device %p, surface %p.\n", iface
, device
, surface
);
3681 return DDERR_UNSUPPORTED
; /* Unchecked */
3684 /*****************************************************************************
3685 * IDirectDrawSurface7::IsLost
3687 * Checks if the surface is lost
3690 * DD_OK, if the surface is usable
3691 * DDERR_ISLOST if the surface is lost
3693 *****************************************************************************/
3694 static HRESULT WINAPI
ddraw_surface7_IsLost(IDirectDrawSurface7
*iface
)
3696 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface7(iface
);
3698 TRACE("iface %p.\n", iface
);
3700 return ddraw_surface_is_lost(surface
) ? DDERR_SURFACELOST
: DD_OK
;
3703 static HRESULT WINAPI
ddraw_surface4_IsLost(IDirectDrawSurface4
*iface
)
3705 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
3707 TRACE("iface %p.\n", iface
);
3709 return ddraw_surface_is_lost(surface
) ? DDERR_SURFACELOST
: DD_OK
;
3712 static HRESULT WINAPI
ddraw_surface3_IsLost(IDirectDrawSurface3
*iface
)
3714 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface3(iface
);
3716 TRACE("iface %p.\n", iface
);
3718 return ddraw_surface_is_lost(surface
) ? DDERR_SURFACELOST
: DD_OK
;
3721 static HRESULT WINAPI
ddraw_surface2_IsLost(IDirectDrawSurface2
*iface
)
3723 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface2(iface
);
3725 TRACE("iface %p.\n", iface
);
3727 return ddraw_surface_is_lost(surface
) ? DDERR_SURFACELOST
: DD_OK
;
3730 static HRESULT WINAPI
ddraw_surface1_IsLost(IDirectDrawSurface
*iface
)
3732 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface(iface
);
3734 TRACE("iface %p.\n", iface
);
3736 return ddraw_surface_is_lost(surface
) ? DDERR_SURFACELOST
: DD_OK
;
3739 /*****************************************************************************
3740 * IDirectDrawSurface7::Restore
3742 * Restores a lost surface. This makes the surface usable again, but
3743 * doesn't reload its old contents
3746 * DD_OK on success, error code otherwise.
3748 *****************************************************************************/
3749 static HRESULT WINAPI
ddraw_surface7_Restore(IDirectDrawSurface7
*iface
)
3751 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface7(iface
);
3754 TRACE("iface %p.\n", iface
);
3756 if (surface
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)
3758 struct wined3d_swapchain
*swapchain
= surface
->ddraw
->wined3d_swapchain
;
3759 struct wined3d_sub_resource_desc wined3d_desc
;
3760 struct wined3d_display_mode mode
;
3763 if (FAILED(hr
= wined3d_swapchain_get_display_mode(swapchain
, &mode
, NULL
)))
3765 WARN("Failed to get display mode, hr %#x.\n", hr
);
3769 if (FAILED(hr
= wined3d_texture_get_sub_resource_desc(surface
->wined3d_texture
, 0, &wined3d_desc
)))
3771 WARN("Failed to get resource desc, hr %#x.\n", hr
);
3775 if (mode
.width
!= wined3d_desc
.width
|| mode
.height
!= wined3d_desc
.height
)
3777 WARN("Display mode dimensions %ux%u don't match surface dimensions %ux%u.\n",
3778 mode
.width
, mode
.height
, wined3d_desc
.width
, wined3d_desc
.height
);
3779 return DDERR_WRONGMODE
;
3782 if (mode
.format_id
!= wined3d_desc
.format
)
3784 WARN("Display mode format %#x doesn't match surface format %#x.\n",
3785 mode
.format_id
, wined3d_desc
.format
);
3786 return DDERR_WRONGMODE
;
3790 if (!ddraw_surface_can_be_lost(surface
))
3792 ddraw_update_lost_surfaces(surface
->ddraw
);
3793 if (surface
->ddraw
->device_state
== DDRAW_DEVICE_STATE_LOST
)
3794 return DDERR_WRONGMODE
;
3796 surface
->is_lost
= FALSE
;
3797 for(i
= 0; i
< MAX_COMPLEX_ATTACHED
; i
++)
3799 if (surface
->complex_array
[i
])
3800 surface
->complex_array
[i
]->is_lost
= FALSE
;
3806 static HRESULT WINAPI
ddraw_surface4_Restore(IDirectDrawSurface4
*iface
)
3808 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
3810 TRACE("iface %p.\n", iface
);
3812 return ddraw_surface7_Restore(&surface
->IDirectDrawSurface7_iface
);
3815 static HRESULT WINAPI
ddraw_surface3_Restore(IDirectDrawSurface3
*iface
)
3817 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface3(iface
);
3819 TRACE("iface %p.\n", iface
);
3821 return ddraw_surface7_Restore(&surface
->IDirectDrawSurface7_iface
);
3824 static HRESULT WINAPI
ddraw_surface2_Restore(IDirectDrawSurface2
*iface
)
3826 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface2(iface
);
3828 TRACE("iface %p.\n", iface
);
3830 return ddraw_surface7_Restore(&surface
->IDirectDrawSurface7_iface
);
3833 static HRESULT WINAPI
ddraw_surface1_Restore(IDirectDrawSurface
*iface
)
3835 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface(iface
);
3837 TRACE("iface %p.\n", iface
);
3839 return ddraw_surface7_Restore(&surface
->IDirectDrawSurface7_iface
);
3842 /*****************************************************************************
3843 * IDirectDrawSurface7::SetOverlayPosition
3845 * Changes the display coordinates of an overlay surface
3852 * DDERR_NOTAOVERLAYSURFACE, because we don't support overlays right now
3853 *****************************************************************************/
3854 static HRESULT WINAPI
ddraw_surface7_SetOverlayPosition(IDirectDrawSurface7
*iface
, LONG x
, LONG y
)
3856 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface7(iface
);
3859 TRACE("iface %p, x %d, y %d.\n", iface
, x
, y
);
3861 wined3d_mutex_lock();
3862 hr
= wined3d_texture_set_overlay_position(surface
->wined3d_texture
,
3863 surface
->sub_resource_idx
, x
, y
);
3864 wined3d_mutex_unlock();
3869 static HRESULT WINAPI
ddraw_surface4_SetOverlayPosition(IDirectDrawSurface4
*iface
, LONG x
, LONG y
)
3871 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
3873 TRACE("iface %p, x %d, y %d.\n", iface
, x
, y
);
3875 return ddraw_surface7_SetOverlayPosition(&surface
->IDirectDrawSurface7_iface
, x
, y
);
3878 static HRESULT WINAPI
ddraw_surface3_SetOverlayPosition(IDirectDrawSurface3
*iface
, LONG x
, LONG y
)
3880 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface3(iface
);
3882 TRACE("iface %p, x %d, y %d.\n", iface
, x
, y
);
3884 return ddraw_surface7_SetOverlayPosition(&surface
->IDirectDrawSurface7_iface
, x
, y
);
3887 static HRESULT WINAPI
ddraw_surface2_SetOverlayPosition(IDirectDrawSurface2
*iface
, LONG x
, LONG y
)
3889 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface2(iface
);
3891 TRACE("iface %p, x %d, y %d.\n", iface
, x
, y
);
3893 return ddraw_surface7_SetOverlayPosition(&surface
->IDirectDrawSurface7_iface
, x
, y
);
3896 static HRESULT WINAPI
ddraw_surface1_SetOverlayPosition(IDirectDrawSurface
*iface
, LONG x
, LONG y
)
3898 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface(iface
);
3900 TRACE("iface %p, x %d, y %d.\n", iface
, x
, y
);
3902 return ddraw_surface7_SetOverlayPosition(&surface
->IDirectDrawSurface7_iface
, x
, y
);
3905 /*****************************************************************************
3906 * IDirectDrawSurface7::UpdateOverlay
3908 * Modifies the attributes of an overlay surface.
3911 * SrcRect: The section of the source being used for the overlay
3912 * DstSurface: Address of the surface that is overlaid
3913 * DstRect: Place of the overlay
3914 * Flags: some DDOVER_* flags
3917 * DDERR_UNSUPPORTED, because we don't support overlays
3919 *****************************************************************************/
3920 static HRESULT WINAPI
ddraw_surface7_UpdateOverlay(IDirectDrawSurface7
*iface
, RECT
*src_rect
,
3921 IDirectDrawSurface7
*dst_surface
, RECT
*dst_rect
, DWORD flags
, DDOVERLAYFX
*fx
)
3923 struct ddraw_surface
*src_impl
= impl_from_IDirectDrawSurface7(iface
);
3924 struct ddraw_surface
*dst_impl
= unsafe_impl_from_IDirectDrawSurface7(dst_surface
);
3925 struct wined3d_texture
*dst_wined3d_texture
= NULL
;
3926 unsigned int dst_sub_resource_idx
= 0;
3929 TRACE("iface %p, src_rect %s, dst_surface %p, dst_rect %s, flags %#x, fx %p.\n",
3930 iface
, wine_dbgstr_rect(src_rect
), dst_surface
, wine_dbgstr_rect(dst_rect
), flags
, fx
);
3933 FIXME("Ignoring fx %p.\n", fx
);
3935 wined3d_mutex_lock();
3938 dst_wined3d_texture
= dst_impl
->wined3d_texture
;
3939 dst_sub_resource_idx
= dst_impl
->sub_resource_idx
;
3941 hr
= wined3d_texture_update_overlay(src_impl
->wined3d_texture
, src_impl
->sub_resource_idx
,
3942 src_rect
, dst_wined3d_texture
, dst_sub_resource_idx
, dst_rect
, flags
);
3943 wined3d_mutex_unlock();
3945 return hr_ddraw_from_wined3d(hr
);
3948 static HRESULT WINAPI
ddraw_surface4_UpdateOverlay(IDirectDrawSurface4
*iface
, RECT
*src_rect
,
3949 IDirectDrawSurface4
*dst_surface
, RECT
*dst_rect
, DWORD flags
, DDOVERLAYFX
*fx
)
3951 struct ddraw_surface
*src_impl
= impl_from_IDirectDrawSurface4(iface
);
3952 struct ddraw_surface
*dst_impl
= unsafe_impl_from_IDirectDrawSurface4(dst_surface
);
3954 TRACE("iface %p, src_rect %s, dst_surface %p, dst_rect %s, flags %#x, fx %p.\n",
3955 iface
, wine_dbgstr_rect(src_rect
), dst_surface
, wine_dbgstr_rect(dst_rect
), flags
, fx
);
3957 return ddraw_surface7_UpdateOverlay(&src_impl
->IDirectDrawSurface7_iface
, src_rect
,
3958 dst_impl
? &dst_impl
->IDirectDrawSurface7_iface
: NULL
, dst_rect
, flags
, fx
);
3961 static HRESULT WINAPI
ddraw_surface3_UpdateOverlay(IDirectDrawSurface3
*iface
, RECT
*src_rect
,
3962 IDirectDrawSurface3
*dst_surface
, RECT
*dst_rect
, DWORD flags
, DDOVERLAYFX
*fx
)
3964 struct ddraw_surface
*src_impl
= impl_from_IDirectDrawSurface3(iface
);
3965 struct ddraw_surface
*dst_impl
= unsafe_impl_from_IDirectDrawSurface3(dst_surface
);
3967 TRACE("iface %p, src_rect %s, dst_surface %p, dst_rect %s, flags %#x, fx %p.\n",
3968 iface
, wine_dbgstr_rect(src_rect
), dst_surface
, wine_dbgstr_rect(dst_rect
), flags
, fx
);
3970 return ddraw_surface7_UpdateOverlay(&src_impl
->IDirectDrawSurface7_iface
, src_rect
,
3971 dst_impl
? &dst_impl
->IDirectDrawSurface7_iface
: NULL
, dst_rect
, flags
, fx
);
3974 static HRESULT WINAPI
ddraw_surface2_UpdateOverlay(IDirectDrawSurface2
*iface
, RECT
*src_rect
,
3975 IDirectDrawSurface2
*dst_surface
, RECT
*dst_rect
, DWORD flags
, DDOVERLAYFX
*fx
)
3977 struct ddraw_surface
*src_impl
= impl_from_IDirectDrawSurface2(iface
);
3978 struct ddraw_surface
*dst_impl
= unsafe_impl_from_IDirectDrawSurface2(dst_surface
);
3980 TRACE("iface %p, src_rect %s, dst_surface %p, dst_rect %s, flags %#x, fx %p.\n",
3981 iface
, wine_dbgstr_rect(src_rect
), dst_surface
, wine_dbgstr_rect(dst_rect
), flags
, fx
);
3983 return ddraw_surface7_UpdateOverlay(&src_impl
->IDirectDrawSurface7_iface
, src_rect
,
3984 dst_impl
? &dst_impl
->IDirectDrawSurface7_iface
: NULL
, dst_rect
, flags
, fx
);
3987 static HRESULT WINAPI
ddraw_surface1_UpdateOverlay(IDirectDrawSurface
*iface
, RECT
*src_rect
,
3988 IDirectDrawSurface
*dst_surface
, RECT
*dst_rect
, DWORD flags
, DDOVERLAYFX
*fx
)
3990 struct ddraw_surface
*src_impl
= impl_from_IDirectDrawSurface(iface
);
3991 struct ddraw_surface
*dst_impl
= unsafe_impl_from_IDirectDrawSurface(dst_surface
);
3993 TRACE("iface %p, src_rect %s, dst_surface %p, dst_rect %s, flags %#x, fx %p.\n",
3994 iface
, wine_dbgstr_rect(src_rect
), dst_surface
, wine_dbgstr_rect(dst_rect
), flags
, fx
);
3996 return ddraw_surface7_UpdateOverlay(&src_impl
->IDirectDrawSurface7_iface
, src_rect
,
3997 dst_impl
? &dst_impl
->IDirectDrawSurface7_iface
: NULL
, dst_rect
, flags
, fx
);
4000 /*****************************************************************************
4001 * IDirectDrawSurface7::UpdateOverlayDisplay
4003 * The DX7 sdk says that it's not implemented
4008 * Returns: DDERR_UNSUPPORTED, because we don't support overlays
4010 *****************************************************************************/
4011 static HRESULT WINAPI
ddraw_surface7_UpdateOverlayDisplay(IDirectDrawSurface7
*iface
, DWORD Flags
)
4013 TRACE("iface %p, flags %#x.\n", iface
, Flags
);
4015 return DDERR_UNSUPPORTED
;
4018 static HRESULT WINAPI
ddraw_surface4_UpdateOverlayDisplay(IDirectDrawSurface4
*iface
, DWORD flags
)
4020 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
4022 TRACE("iface %p, flags %#x.\n", iface
, flags
);
4024 return ddraw_surface7_UpdateOverlayDisplay(&surface
->IDirectDrawSurface7_iface
, flags
);
4027 static HRESULT WINAPI
ddraw_surface3_UpdateOverlayDisplay(IDirectDrawSurface3
*iface
, DWORD flags
)
4029 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface3(iface
);
4031 TRACE("iface %p, flags %#x.\n", iface
, flags
);
4033 return ddraw_surface7_UpdateOverlayDisplay(&surface
->IDirectDrawSurface7_iface
, flags
);
4036 static HRESULT WINAPI
ddraw_surface2_UpdateOverlayDisplay(IDirectDrawSurface2
*iface
, DWORD flags
)
4038 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface2(iface
);
4040 TRACE("iface %p, flags %#x.\n", iface
, flags
);
4042 return ddraw_surface7_UpdateOverlayDisplay(&surface
->IDirectDrawSurface7_iface
, flags
);
4045 static HRESULT WINAPI
ddraw_surface1_UpdateOverlayDisplay(IDirectDrawSurface
*iface
, DWORD flags
)
4047 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface(iface
);
4049 TRACE("iface %p, flags %#x.\n", iface
, flags
);
4051 return ddraw_surface7_UpdateOverlayDisplay(&surface
->IDirectDrawSurface7_iface
, flags
);
4054 /*****************************************************************************
4055 * IDirectDrawSurface7::UpdateOverlayZOrder
4057 * Sets an overlay's Z order
4060 * Flags: DDOVERZ_* flags
4061 * DDSRef: Defines the relative position in the overlay chain
4064 * DDERR_NOTOVERLAYSURFACE, because we don't support overlays
4066 *****************************************************************************/
4067 static HRESULT WINAPI
ddraw_surface7_UpdateOverlayZOrder(IDirectDrawSurface7
*iface
,
4068 DWORD flags
, IDirectDrawSurface7
*reference
)
4070 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface7(iface
);
4072 FIXME("iface %p, flags %#x, reference %p stub!\n", iface
, flags
, reference
);
4074 wined3d_mutex_lock();
4075 if (!(surface
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_OVERLAY
))
4077 WARN("Not an overlay surface.\n");
4078 wined3d_mutex_unlock();
4079 return DDERR_NOTAOVERLAYSURFACE
;
4081 wined3d_mutex_unlock();
4086 static HRESULT WINAPI
ddraw_surface4_UpdateOverlayZOrder(IDirectDrawSurface4
*iface
,
4087 DWORD flags
, IDirectDrawSurface4
*reference
)
4089 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
4090 struct ddraw_surface
*reference_impl
= unsafe_impl_from_IDirectDrawSurface4(reference
);
4092 TRACE("iface %p, flags %#x, reference %p.\n", iface
, flags
, reference
);
4094 return ddraw_surface7_UpdateOverlayZOrder(&surface
->IDirectDrawSurface7_iface
, flags
,
4095 reference_impl
? &reference_impl
->IDirectDrawSurface7_iface
: NULL
);
4098 static HRESULT WINAPI
ddraw_surface3_UpdateOverlayZOrder(IDirectDrawSurface3
*iface
,
4099 DWORD flags
, IDirectDrawSurface3
*reference
)
4101 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface3(iface
);
4102 struct ddraw_surface
*reference_impl
= unsafe_impl_from_IDirectDrawSurface3(reference
);
4104 TRACE("iface %p, flags %#x, reference %p.\n", iface
, flags
, reference
);
4106 return ddraw_surface7_UpdateOverlayZOrder(&surface
->IDirectDrawSurface7_iface
, flags
,
4107 reference_impl
? &reference_impl
->IDirectDrawSurface7_iface
: NULL
);
4110 static HRESULT WINAPI
ddraw_surface2_UpdateOverlayZOrder(IDirectDrawSurface2
*iface
,
4111 DWORD flags
, IDirectDrawSurface2
*reference
)
4113 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface2(iface
);
4114 struct ddraw_surface
*reference_impl
= unsafe_impl_from_IDirectDrawSurface2(reference
);
4116 TRACE("iface %p, flags %#x, reference %p.\n", iface
, flags
, reference
);
4118 return ddraw_surface7_UpdateOverlayZOrder(&surface
->IDirectDrawSurface7_iface
, flags
,
4119 reference_impl
? &reference_impl
->IDirectDrawSurface7_iface
: NULL
);
4122 static HRESULT WINAPI
ddraw_surface1_UpdateOverlayZOrder(IDirectDrawSurface
*iface
,
4123 DWORD flags
, IDirectDrawSurface
*reference
)
4125 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface(iface
);
4126 struct ddraw_surface
*reference_impl
= unsafe_impl_from_IDirectDrawSurface(reference
);
4128 TRACE("iface %p, flags %#x, reference %p.\n", iface
, flags
, reference
);
4130 return ddraw_surface7_UpdateOverlayZOrder(&surface
->IDirectDrawSurface7_iface
, flags
,
4131 reference_impl
? &reference_impl
->IDirectDrawSurface7_iface
: NULL
);
4134 /*****************************************************************************
4135 * IDirectDrawSurface7::GetDDInterface
4137 * Returns the IDirectDraw7 interface pointer of the DirectDraw object this
4138 * surface belongs to
4141 * DD: Address to write the interface pointer to
4145 * DDERR_INVALIDPARAMS if DD is NULL
4147 *****************************************************************************/
4148 static HRESULT WINAPI
ddraw_surface7_GetDDInterface(IDirectDrawSurface7
*iface
, void **DD
)
4150 struct ddraw_surface
*This
= impl_from_IDirectDrawSurface7(iface
);
4152 TRACE("iface %p, ddraw %p.\n", iface
, DD
);
4155 return DDERR_INVALIDPARAMS
;
4157 switch(This
->version
)
4160 *DD
= &This
->ddraw
->IDirectDraw7_iface
;
4164 *DD
= &This
->ddraw
->IDirectDraw4_iface
;
4168 *DD
= &This
->ddraw
->IDirectDraw2_iface
;
4172 *DD
= &This
->ddraw
->IDirectDraw_iface
;
4176 IUnknown_AddRef((IUnknown
*)*DD
);
4181 static HRESULT WINAPI
ddraw_surface4_GetDDInterface(IDirectDrawSurface4
*iface
, void **ddraw
)
4183 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
4185 TRACE("iface %p, ddraw %p.\n", iface
, ddraw
);
4187 return ddraw_surface7_GetDDInterface(&surface
->IDirectDrawSurface7_iface
, ddraw
);
4190 static HRESULT WINAPI
ddraw_surface3_GetDDInterface(IDirectDrawSurface3
*iface
, void **ddraw
)
4192 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface3(iface
);
4194 TRACE("iface %p, ddraw %p.\n", iface
, ddraw
);
4196 return ddraw_surface7_GetDDInterface(&surface
->IDirectDrawSurface7_iface
, ddraw
);
4199 static HRESULT WINAPI
ddraw_surface2_GetDDInterface(IDirectDrawSurface2
*iface
, void **ddraw
)
4201 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface2(iface
);
4203 TRACE("iface %p, ddraw %p.\n", iface
, ddraw
);
4205 return ddraw_surface7_GetDDInterface(&surface
->IDirectDrawSurface7_iface
, ddraw
);
4208 static HRESULT WINAPI
ddraw_surface7_ChangeUniquenessValue(IDirectDrawSurface7
*iface
)
4210 TRACE("iface %p.\n", iface
);
4215 static HRESULT WINAPI
ddraw_surface4_ChangeUniquenessValue(IDirectDrawSurface4
*iface
)
4217 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
4219 TRACE("iface %p.\n", iface
);
4221 return ddraw_surface7_ChangeUniquenessValue(&surface
->IDirectDrawSurface7_iface
);
4224 static HRESULT WINAPI
ddraw_surface7_GetUniquenessValue(IDirectDrawSurface7
*iface
, DWORD
*pValue
)
4226 TRACE("iface %p, value %p.\n", iface
, pValue
);
4233 static HRESULT WINAPI
ddraw_surface4_GetUniquenessValue(IDirectDrawSurface4
*iface
, DWORD
*pValue
)
4235 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
4237 TRACE("iface %p, value %p.\n", iface
, pValue
);
4239 return ddraw_surface7_GetUniquenessValue(&surface
->IDirectDrawSurface7_iface
, pValue
);
4242 /*****************************************************************************
4243 * IDirectDrawSurface7::SetLOD
4245 * Sets the level of detail of a texture
4248 * MaxLOD: LOD to set
4252 * DDERR_INVALIDOBJECT if the surface is invalid for this method
4254 *****************************************************************************/
4255 static HRESULT WINAPI
ddraw_surface7_SetLOD(IDirectDrawSurface7
*iface
, DWORD MaxLOD
)
4257 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface7(iface
);
4260 TRACE("iface %p, lod %u.\n", iface
, MaxLOD
);
4262 wined3d_mutex_lock();
4263 if (!(surface
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_TEXTUREMANAGE
))
4265 wined3d_mutex_unlock();
4266 return DDERR_INVALIDOBJECT
;
4269 hr
= wined3d_texture_set_lod(surface
->wined3d_texture
, MaxLOD
);
4270 wined3d_mutex_unlock();
4275 /*****************************************************************************
4276 * IDirectDrawSurface7::GetLOD
4278 * Returns the level of detail of a Direct3D texture
4281 * MaxLOD: Address to write the LOD to
4285 * DDERR_INVALIDPARAMS if MaxLOD is NULL
4286 * DDERR_INVALIDOBJECT if the surface is invalid for this method
4288 *****************************************************************************/
4289 static HRESULT WINAPI
ddraw_surface7_GetLOD(IDirectDrawSurface7
*iface
, DWORD
*MaxLOD
)
4291 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface7(iface
);
4293 TRACE("iface %p, lod %p.\n", iface
, MaxLOD
);
4296 return DDERR_INVALIDPARAMS
;
4298 wined3d_mutex_lock();
4299 if (!(surface
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_TEXTUREMANAGE
))
4301 wined3d_mutex_unlock();
4302 return DDERR_INVALIDOBJECT
;
4305 *MaxLOD
= wined3d_texture_get_lod(surface
->wined3d_texture
);
4306 wined3d_mutex_unlock();
4311 /*****************************************************************************
4312 * IDirectDrawSurface7::BltFast
4314 * Performs a fast Blit.
4317 * dstx: The x coordinate to blit to on the destination
4318 * dsty: The y coordinate to blit to on the destination
4319 * Source: The source surface
4320 * rsrc: The source rectangle
4321 * trans: Type of transfer. Some DDBLTFAST_* flags
4324 * DD_OK on success, error code otherwise.
4326 *****************************************************************************/
4327 static HRESULT WINAPI DECLSPEC_HOTPATCH
ddraw_surface7_BltFast(IDirectDrawSurface7
*iface
,
4328 DWORD dst_x
, DWORD dst_y
, IDirectDrawSurface7
*src_surface
, RECT
*src_rect
, DWORD trans
)
4330 struct ddraw_surface
*dst_impl
= impl_from_IDirectDrawSurface7(iface
);
4331 struct ddraw_surface
*src_impl
= unsafe_impl_from_IDirectDrawSurface7(src_surface
);
4332 DWORD flags
= WINED3D_BLT_SYNCHRONOUS
;
4333 DWORD src_w
, src_h
, dst_w
, dst_h
;
4337 TRACE("iface %p, dst_x %u, dst_y %u, src_surface %p, src_rect %s, flags %#x.\n",
4338 iface
, dst_x
, dst_y
, src_surface
, wine_dbgstr_rect(src_rect
), trans
);
4340 dst_w
= dst_impl
->surface_desc
.dwWidth
;
4341 dst_h
= dst_impl
->surface_desc
.dwHeight
;
4345 SetRect(&s
, 0, 0, src_impl
->surface_desc
.dwWidth
, src_impl
->surface_desc
.dwHeight
);
4349 src_w
= src_rect
->right
- src_rect
->left
;
4350 src_h
= src_rect
->bottom
- src_rect
->top
;
4351 if (src_w
> dst_w
|| dst_x
> dst_w
- src_w
4352 || src_h
> dst_h
|| dst_y
> dst_h
- src_h
)
4354 WARN("Destination area out of bounds, returning DDERR_INVALIDRECT.\n");
4355 return DDERR_INVALIDRECT
;
4358 SetRect(&dst_rect
, dst_x
, dst_y
, dst_x
+ src_w
, dst_y
+ src_h
);
4359 if (trans
& DDBLTFAST_SRCCOLORKEY
)
4360 flags
|= WINED3D_BLT_SRC_CKEY
;
4361 if (trans
& DDBLTFAST_DESTCOLORKEY
)
4362 flags
|= WINED3D_BLT_DST_CKEY
;
4363 if (trans
& DDBLTFAST_WAIT
)
4364 flags
|= WINED3D_BLT_WAIT
;
4365 if (trans
& DDBLTFAST_DONOTWAIT
)
4366 flags
|= WINED3D_BLT_DO_NOT_WAIT
;
4368 wined3d_mutex_lock();
4369 if (dst_impl
->clipper
)
4371 wined3d_mutex_unlock();
4372 WARN("Destination surface has a clipper set, returning DDERR_BLTFASTCANTCLIP.\n");
4373 return DDERR_BLTFASTCANTCLIP
;
4376 if (src_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)
4377 hr
= ddraw_surface_update_frontbuffer(src_impl
, src_rect
, TRUE
, 0);
4379 hr
= wined3d_texture_blt(dst_impl
->wined3d_texture
, dst_impl
->sub_resource_idx
, &dst_rect
,
4380 src_impl
->wined3d_texture
, src_impl
->sub_resource_idx
, src_rect
, flags
, NULL
, WINED3D_TEXF_POINT
);
4381 if (SUCCEEDED(hr
) && (dst_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
))
4382 hr
= ddraw_surface_update_frontbuffer(dst_impl
, &dst_rect
, FALSE
, 0);
4383 wined3d_mutex_unlock();
4387 case WINED3DERR_NOTAVAILABLE
: return DDERR_UNSUPPORTED
;
4392 static HRESULT WINAPI DECLSPEC_HOTPATCH
ddraw_surface4_BltFast(IDirectDrawSurface4
*iface
, DWORD dst_x
, DWORD dst_y
,
4393 IDirectDrawSurface4
*src_surface
, RECT
*src_rect
, DWORD flags
)
4395 struct ddraw_surface
*dst_impl
= impl_from_IDirectDrawSurface4(iface
);
4396 struct ddraw_surface
*src_impl
= unsafe_impl_from_IDirectDrawSurface4(src_surface
);
4398 TRACE("iface %p, dst_x %u, dst_y %u, src_surface %p, src_rect %s, flags %#x.\n",
4399 iface
, dst_x
, dst_y
, src_surface
, wine_dbgstr_rect(src_rect
), flags
);
4401 return ddraw_surface7_BltFast(&dst_impl
->IDirectDrawSurface7_iface
, dst_x
, dst_y
,
4402 src_impl
? &src_impl
->IDirectDrawSurface7_iface
: NULL
, src_rect
, flags
);
4405 static HRESULT WINAPI DECLSPEC_HOTPATCH
ddraw_surface3_BltFast(IDirectDrawSurface3
*iface
, DWORD dst_x
, DWORD dst_y
,
4406 IDirectDrawSurface3
*src_surface
, RECT
*src_rect
, DWORD flags
)
4408 struct ddraw_surface
*dst_impl
= impl_from_IDirectDrawSurface3(iface
);
4409 struct ddraw_surface
*src_impl
= unsafe_impl_from_IDirectDrawSurface3(src_surface
);
4411 TRACE("iface %p, dst_x %u, dst_y %u, src_surface %p, src_rect %s, flags %#x.\n",
4412 iface
, dst_x
, dst_y
, src_surface
, wine_dbgstr_rect(src_rect
), flags
);
4414 return ddraw_surface7_BltFast(&dst_impl
->IDirectDrawSurface7_iface
, dst_x
, dst_y
,
4415 src_impl
? &src_impl
->IDirectDrawSurface7_iface
: NULL
, src_rect
, flags
);
4418 static HRESULT WINAPI DECLSPEC_HOTPATCH
ddraw_surface2_BltFast(IDirectDrawSurface2
*iface
, DWORD dst_x
, DWORD dst_y
,
4419 IDirectDrawSurface2
*src_surface
, RECT
*src_rect
, DWORD flags
)
4421 struct ddraw_surface
*dst_impl
= impl_from_IDirectDrawSurface2(iface
);
4422 struct ddraw_surface
*src_impl
= unsafe_impl_from_IDirectDrawSurface2(src_surface
);
4424 TRACE("iface %p, dst_x %u, dst_y %u, src_surface %p, src_rect %s, flags %#x.\n",
4425 iface
, dst_x
, dst_y
, src_surface
, wine_dbgstr_rect(src_rect
), flags
);
4427 return ddraw_surface7_BltFast(&dst_impl
->IDirectDrawSurface7_iface
, dst_x
, dst_y
,
4428 src_impl
? &src_impl
->IDirectDrawSurface7_iface
: NULL
, src_rect
, flags
);
4431 static HRESULT WINAPI DECLSPEC_HOTPATCH
ddraw_surface1_BltFast(IDirectDrawSurface
*iface
, DWORD dst_x
, DWORD dst_y
,
4432 IDirectDrawSurface
*src_surface
, RECT
*src_rect
, DWORD flags
)
4434 struct ddraw_surface
*dst_impl
= impl_from_IDirectDrawSurface(iface
);
4435 struct ddraw_surface
*src_impl
= unsafe_impl_from_IDirectDrawSurface(src_surface
);
4437 TRACE("iface %p, dst_x %u, dst_y %u, src_surface %p, src_rect %s, flags %#x.\n",
4438 iface
, dst_x
, dst_y
, src_surface
, wine_dbgstr_rect(src_rect
), flags
);
4440 return ddraw_surface7_BltFast(&dst_impl
->IDirectDrawSurface7_iface
, dst_x
, dst_y
,
4441 src_impl
? &src_impl
->IDirectDrawSurface7_iface
: NULL
, src_rect
, flags
);
4444 static HRESULT WINAPI
ddraw_surface7_GetClipper(IDirectDrawSurface7
*iface
, IDirectDrawClipper
**clipper
)
4446 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface7(iface
);
4448 TRACE("iface %p, clipper %p.\n", iface
, clipper
);
4451 return DDERR_INVALIDPARAMS
;
4453 wined3d_mutex_lock();
4454 if (!surface
->clipper
)
4456 wined3d_mutex_unlock();
4458 return DDERR_NOCLIPPERATTACHED
;
4461 *clipper
= &surface
->clipper
->IDirectDrawClipper_iface
;
4462 if (ddraw_clipper_is_valid(surface
->clipper
))
4463 IDirectDrawClipper_AddRef(*clipper
);
4464 wined3d_mutex_unlock();
4469 static HRESULT WINAPI
ddraw_surface4_GetClipper(IDirectDrawSurface4
*iface
, IDirectDrawClipper
**clipper
)
4471 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
4473 TRACE("iface %p, clipper %p.\n", iface
, clipper
);
4475 return ddraw_surface7_GetClipper(&surface
->IDirectDrawSurface7_iface
, clipper
);
4478 static HRESULT WINAPI
ddraw_surface3_GetClipper(IDirectDrawSurface3
*iface
, IDirectDrawClipper
**clipper
)
4480 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface3(iface
);
4482 TRACE("iface %p, clipper %p.\n", iface
, clipper
);
4484 return ddraw_surface7_GetClipper(&surface
->IDirectDrawSurface7_iface
, clipper
);
4487 static HRESULT WINAPI
ddraw_surface2_GetClipper(IDirectDrawSurface2
*iface
, IDirectDrawClipper
**clipper
)
4489 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface2(iface
);
4491 TRACE("iface %p, clipper %p.\n", iface
, clipper
);
4493 return ddraw_surface7_GetClipper(&surface
->IDirectDrawSurface7_iface
, clipper
);
4496 static HRESULT WINAPI
ddraw_surface1_GetClipper(IDirectDrawSurface
*iface
, IDirectDrawClipper
**clipper
)
4498 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface(iface
);
4500 TRACE("iface %p, clipper %p.\n", iface
, clipper
);
4502 return ddraw_surface7_GetClipper(&surface
->IDirectDrawSurface7_iface
, clipper
);
4505 /*****************************************************************************
4506 * IDirectDrawSurface7::SetClipper
4508 * Sets a clipper for the surface
4511 * Clipper: IDirectDrawClipper interface of the clipper to set
4516 *****************************************************************************/
4517 static HRESULT WINAPI
ddraw_surface7_SetClipper(IDirectDrawSurface7
*iface
,
4518 IDirectDrawClipper
*iclipper
)
4520 struct ddraw_surface
*This
= impl_from_IDirectDrawSurface7(iface
);
4521 struct ddraw_clipper
*clipper
= unsafe_impl_from_IDirectDrawClipper(iclipper
);
4522 struct ddraw_clipper
*old_clipper
= This
->clipper
;
4525 TRACE("iface %p, clipper %p.\n", iface
, iclipper
);
4527 wined3d_mutex_lock();
4528 if (clipper
== This
->clipper
)
4530 wined3d_mutex_unlock();
4534 This
->clipper
= clipper
;
4536 if (clipper
!= NULL
)
4537 IDirectDrawClipper_AddRef(iclipper
);
4538 if (old_clipper
&& ddraw_clipper_is_valid(old_clipper
))
4539 IDirectDrawClipper_Release(&old_clipper
->IDirectDrawClipper_iface
);
4541 if ((This
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
) && This
->ddraw
->wined3d_swapchain
)
4545 IDirectDrawClipper_GetHWnd(iclipper
, &clipWindow
);
4550 wined3d_swapchain_set_window(This
->ddraw
->wined3d_swapchain
, clipWindow
);
4551 ddraw_set_swapchain_window(This
->ddraw
, clipWindow
);
4555 wined3d_swapchain_set_window(This
->ddraw
->wined3d_swapchain
, This
->ddraw
->d3d_window
);
4556 ddraw_set_swapchain_window(This
->ddraw
, This
->ddraw
->dest_window
);
4560 wined3d_mutex_unlock();
4565 static HRESULT WINAPI
ddraw_surface4_SetClipper(IDirectDrawSurface4
*iface
, IDirectDrawClipper
*clipper
)
4567 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
4569 TRACE("iface %p, clipper %p.\n", iface
, clipper
);
4571 return ddraw_surface7_SetClipper(&surface
->IDirectDrawSurface7_iface
, clipper
);
4574 static HRESULT WINAPI
ddraw_surface3_SetClipper(IDirectDrawSurface3
*iface
, IDirectDrawClipper
*clipper
)
4576 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface3(iface
);
4578 TRACE("iface %p, clipper %p.\n", iface
, clipper
);
4580 return ddraw_surface7_SetClipper(&surface
->IDirectDrawSurface7_iface
, clipper
);
4583 static HRESULT WINAPI
ddraw_surface2_SetClipper(IDirectDrawSurface2
*iface
, IDirectDrawClipper
*clipper
)
4585 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface2(iface
);
4587 TRACE("iface %p, clipper %p.\n", iface
, clipper
);
4589 return ddraw_surface7_SetClipper(&surface
->IDirectDrawSurface7_iface
, clipper
);
4592 static HRESULT WINAPI
ddraw_surface1_SetClipper(IDirectDrawSurface
*iface
, IDirectDrawClipper
*clipper
)
4594 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface(iface
);
4596 TRACE("iface %p, clipper %p.\n", iface
, clipper
);
4598 return ddraw_surface7_SetClipper(&surface
->IDirectDrawSurface7_iface
, clipper
);
4601 /*****************************************************************************
4602 * IDirectDrawSurface7::SetSurfaceDesc
4604 * Sets the surface description. It can override the pixel format, the surface
4606 * It's not really tested.
4609 * DDSD: Pointer to the new surface description to set
4614 * DDERR_INVALIDPARAMS if DDSD is NULL
4616 *****************************************************************************/
4617 static HRESULT WINAPI
ddraw_surface7_SetSurfaceDesc(IDirectDrawSurface7
*iface
, DDSURFACEDESC2
*DDSD
, DWORD Flags
)
4619 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface7(iface
);
4621 const DWORD allowed_flags
= DDSD_LPSURFACE
| DDSD_PIXELFORMAT
| DDSD_WIDTH
4622 | DDSD_HEIGHT
| DDSD_PITCH
| DDSD_CAPS
;
4623 enum wined3d_format_id format_id
;
4624 UINT pitch
, width
, height
;
4626 TRACE("iface %p, surface_desc %p, flags %#x.\n", iface
, DDSD
, Flags
);
4630 WARN("DDSD is NULL, returning DDERR_INVALIDPARAMS\n");
4631 return DDERR_INVALIDPARAMS
;
4635 WARN("Flags is %x, returning DDERR_INVALIDPARAMS\n", Flags
);
4636 return DDERR_INVALIDPARAMS
;
4638 if (!(surface
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_SYSTEMMEMORY
)
4639 || surface
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
4640 || surface
->surface_desc
.ddsCaps
.dwCaps2
& (DDSCAPS2_TEXTUREMANAGE
| DDSCAPS2_D3DTEXTUREMANAGE
))
4642 WARN("Surface is not in system memory, returning DDERR_INVALIDSURFACETYPE.\n");
4643 return DDERR_INVALIDSURFACETYPE
;
4646 /* Tests show that only LPSURFACE and PIXELFORMAT can be set, and LPSURFACE is required
4647 * for PIXELFORMAT to work */
4648 if (DDSD
->dwFlags
& ~allowed_flags
)
4650 WARN("Invalid flags (0x%08x) set, returning DDERR_INVALIDPARAMS\n", DDSD
->dwFlags
);
4651 return DDERR_INVALIDPARAMS
;
4653 if (!(DDSD
->dwFlags
& DDSD_LPSURFACE
) || !DDSD
->lpSurface
)
4655 WARN("DDSD_LPSURFACE is not set or lpSurface is NULL, returning DDERR_INVALIDPARAMS\n");
4656 return DDERR_INVALIDPARAMS
;
4658 if ((DDSD
->dwFlags
& DDSD_CAPS
) && DDSD
->ddsCaps
.dwCaps
)
4660 WARN("DDSD_CAPS is set, returning DDERR_INVALIDCAPS.\n");
4661 return DDERR_INVALIDCAPS
;
4663 if (DDSD
->dwFlags
& DDSD_WIDTH
)
4665 if (!(DDSD
->dwFlags
& DDSD_PITCH
))
4667 WARN("DDSD_WIDTH is set, but DDSD_PITCH is not, returning DDERR_INVALIDPARAMS.\n");
4668 return DDERR_INVALIDPARAMS
;
4670 if (!DDSD
->dwWidth
|| DDSD
->u1
.lPitch
<= 0 || DDSD
->u1
.lPitch
& 0x3)
4672 WARN("Pitch is %d, width is %u, returning DDERR_INVALIDPARAMS.\n",
4673 DDSD
->u1
.lPitch
, DDSD
->dwWidth
);
4674 return DDERR_INVALIDPARAMS
;
4676 if (DDSD
->dwWidth
!= surface
->surface_desc
.dwWidth
)
4677 TRACE("Surface width changed from %u to %u.\n", surface
->surface_desc
.dwWidth
, DDSD
->dwWidth
);
4678 if (DDSD
->u1
.lPitch
!= surface
->surface_desc
.u1
.lPitch
)
4679 TRACE("Surface pitch changed from %u to %u.\n", surface
->surface_desc
.u1
.lPitch
, DDSD
->u1
.lPitch
);
4680 pitch
= DDSD
->u1
.lPitch
;
4681 width
= DDSD
->dwWidth
;
4683 else if (DDSD
->dwFlags
& DDSD_PITCH
)
4685 WARN("DDSD_PITCH is set, but DDSD_WIDTH is not, returning DDERR_INVALIDPARAMS.\n");
4686 return DDERR_INVALIDPARAMS
;
4690 pitch
= surface
->surface_desc
.u1
.lPitch
;
4691 width
= surface
->surface_desc
.dwWidth
;
4694 if (DDSD
->dwFlags
& DDSD_HEIGHT
)
4696 if (!DDSD
->dwHeight
)
4698 WARN("Height is 0, returning DDERR_INVALIDPARAMS.\n");
4699 return DDERR_INVALIDPARAMS
;
4701 if (DDSD
->dwHeight
!= surface
->surface_desc
.dwHeight
)
4702 TRACE("Surface height changed from %u to %u.\n", surface
->surface_desc
.dwHeight
, DDSD
->dwHeight
);
4703 height
= DDSD
->dwHeight
;
4707 height
= surface
->surface_desc
.dwHeight
;
4710 wined3d_mutex_lock();
4711 if (DDSD
->dwFlags
& DDSD_PIXELFORMAT
)
4713 enum wined3d_format_id current_format_id
;
4714 format_id
= wined3dformat_from_ddrawformat(&DDSD
->u4
.ddpfPixelFormat
);
4716 if (format_id
== WINED3DFMT_UNKNOWN
)
4718 ERR("Requested to set an unknown pixelformat\n");
4719 wined3d_mutex_unlock();
4720 return DDERR_INVALIDPARAMS
;
4722 current_format_id
= wined3dformat_from_ddrawformat(&surface
->surface_desc
.u4
.ddpfPixelFormat
);
4723 if (format_id
!= current_format_id
)
4724 TRACE("Surface format changed from %#x to %#x.\n", current_format_id
, format_id
);
4728 format_id
= wined3dformat_from_ddrawformat(&surface
->surface_desc
.u4
.ddpfPixelFormat
);
4731 if (FAILED(hr
= wined3d_texture_update_desc(surface
->wined3d_texture
, surface
->sub_resource_idx
,
4732 width
, height
, format_id
, WINED3D_MULTISAMPLE_NONE
, 0, DDSD
->lpSurface
, pitch
)))
4734 WARN("Failed to update surface desc, hr %#x.\n", hr
);
4735 wined3d_mutex_unlock();
4736 return hr_ddraw_from_wined3d(hr
);
4739 if (DDSD
->dwFlags
& DDSD_WIDTH
)
4740 surface
->surface_desc
.dwWidth
= width
;
4741 if (DDSD
->dwFlags
& DDSD_PITCH
)
4742 surface
->surface_desc
.u1
.lPitch
= DDSD
->u1
.lPitch
;
4743 if (DDSD
->dwFlags
& DDSD_HEIGHT
)
4744 surface
->surface_desc
.dwHeight
= height
;
4745 if (DDSD
->dwFlags
& DDSD_PIXELFORMAT
)
4746 surface
->surface_desc
.u4
.ddpfPixelFormat
= DDSD
->u4
.ddpfPixelFormat
;
4748 wined3d_mutex_unlock();
4753 static HRESULT WINAPI
ddraw_surface4_SetSurfaceDesc(IDirectDrawSurface4
*iface
,
4754 DDSURFACEDESC2
*surface_desc
, DWORD flags
)
4756 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
4758 TRACE("iface %p, surface_desc %p, flags %#x.\n", iface
, surface_desc
, flags
);
4760 return ddraw_surface7_SetSurfaceDesc(&surface
->IDirectDrawSurface7_iface
,
4761 surface_desc
, flags
);
4764 static HRESULT WINAPI
ddraw_surface3_SetSurfaceDesc(IDirectDrawSurface3
*iface
,
4765 DDSURFACEDESC
*surface_desc
, DWORD flags
)
4767 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface3(iface
);
4768 DDSURFACEDESC2 surface_desc2
;
4770 TRACE("iface %p, surface_desc %p, flags %#x.\n", iface
, surface_desc
, flags
);
4772 if (surface_desc
) DDSD_to_DDSD2(surface_desc
, &surface_desc2
);
4773 return ddraw_surface7_SetSurfaceDesc(&surface
->IDirectDrawSurface7_iface
,
4774 surface_desc
? &surface_desc2
: NULL
, flags
);
4777 static HRESULT WINAPI
ddraw_surface7_GetPalette(IDirectDrawSurface7
*iface
, IDirectDrawPalette
**palette
)
4779 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface7(iface
);
4780 struct ddraw_palette
*palette_impl
;
4783 TRACE("iface %p, palette %p.\n", iface
, palette
);
4786 return DDERR_INVALIDPARAMS
;
4787 if (ddraw_surface_is_lost(surface
))
4789 WARN("Surface lost, returning DDERR_SURFACELOST.\n");
4790 return DDERR_SURFACELOST
;
4793 wined3d_mutex_lock();
4794 if ((palette_impl
= surface
->palette
))
4796 *palette
= &palette_impl
->IDirectDrawPalette_iface
;
4797 IDirectDrawPalette_AddRef(*palette
);
4802 hr
= DDERR_NOPALETTEATTACHED
;
4804 wined3d_mutex_unlock();
4809 static HRESULT WINAPI
ddraw_surface4_GetPalette(IDirectDrawSurface4
*iface
, IDirectDrawPalette
**palette
)
4811 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
4813 TRACE("iface %p, palette %p.\n", iface
, palette
);
4815 return ddraw_surface7_GetPalette(&surface
->IDirectDrawSurface7_iface
, palette
);
4818 static HRESULT WINAPI
ddraw_surface3_GetPalette(IDirectDrawSurface3
*iface
, IDirectDrawPalette
**palette
)
4820 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface3(iface
);
4822 TRACE("iface %p, palette %p.\n", iface
, palette
);
4824 return ddraw_surface7_GetPalette(&surface
->IDirectDrawSurface7_iface
, palette
);
4827 static HRESULT WINAPI
ddraw_surface2_GetPalette(IDirectDrawSurface2
*iface
, IDirectDrawPalette
**palette
)
4829 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface2(iface
);
4831 TRACE("iface %p, palette %p.\n", iface
, palette
);
4833 return ddraw_surface7_GetPalette(&surface
->IDirectDrawSurface7_iface
, palette
);
4836 static HRESULT WINAPI
ddraw_surface1_GetPalette(IDirectDrawSurface
*iface
, IDirectDrawPalette
**palette
)
4838 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface(iface
);
4840 TRACE("iface %p, palette %p.\n", iface
, palette
);
4842 return ddraw_surface7_GetPalette(&surface
->IDirectDrawSurface7_iface
, palette
);
4845 static HRESULT
ddraw_surface_set_color_key(struct ddraw_surface
*surface
, DWORD flags
, DDCOLORKEY
*color_key
)
4847 DDCOLORKEY fixed_color_key
;
4848 HRESULT hr
= WINED3D_OK
;
4850 if (flags
& DDCKEY_COLORSPACE
)
4852 if (color_key
&& color_key
->dwColorSpaceLowValue
!= color_key
->dwColorSpaceHighValue
)
4854 WARN("Range color keys are not supported, returning DDERR_NOCOLORKEYHW.\n");
4855 return DDERR_NOCOLORKEYHW
;
4857 flags
&= ~DDCKEY_COLORSPACE
;
4860 wined3d_mutex_lock();
4864 fixed_color_key
.dwColorSpaceLowValue
= fixed_color_key
.dwColorSpaceHighValue
= color_key
->dwColorSpaceLowValue
;
4865 switch (flags
& ~DDCKEY_COLORSPACE
)
4867 case DDCKEY_DESTBLT
:
4868 surface
->surface_desc
.ddckCKDestBlt
= fixed_color_key
;
4869 surface
->surface_desc
.dwFlags
|= DDSD_CKDESTBLT
;
4872 case DDCKEY_DESTOVERLAY
:
4873 surface
->surface_desc
.u3
.ddckCKDestOverlay
= fixed_color_key
;
4874 surface
->surface_desc
.dwFlags
|= DDSD_CKDESTOVERLAY
;
4877 case DDCKEY_SRCOVERLAY
:
4878 surface
->surface_desc
.ddckCKSrcOverlay
= fixed_color_key
;
4879 surface
->surface_desc
.dwFlags
|= DDSD_CKSRCOVERLAY
;
4883 surface
->surface_desc
.ddckCKSrcBlt
= fixed_color_key
;
4884 surface
->surface_desc
.dwFlags
|= DDSD_CKSRCBLT
;
4888 wined3d_mutex_unlock();
4889 return DDERR_INVALIDPARAMS
;
4894 switch (flags
& ~DDCKEY_COLORSPACE
)
4896 case DDCKEY_DESTBLT
:
4897 surface
->surface_desc
.dwFlags
&= ~DDSD_CKDESTBLT
;
4900 case DDCKEY_DESTOVERLAY
:
4901 surface
->surface_desc
.dwFlags
&= ~DDSD_CKDESTOVERLAY
;
4904 case DDCKEY_SRCOVERLAY
:
4905 surface
->surface_desc
.dwFlags
&= ~DDSD_CKSRCOVERLAY
;
4909 surface
->surface_desc
.dwFlags
&= ~DDSD_CKSRCBLT
;
4913 wined3d_mutex_unlock();
4914 return DDERR_INVALIDPARAMS
;
4918 if (surface
->is_complex_root
)
4919 hr
= wined3d_texture_set_color_key(surface
->wined3d_texture
, flags
,
4920 color_key
? (struct wined3d_color_key
*)&fixed_color_key
: NULL
);
4922 wined3d_mutex_unlock();
4924 return hr_ddraw_from_wined3d(hr
);
4927 static HRESULT WINAPI
ddraw_surface7_SetColorKey(IDirectDrawSurface7
*iface
, DWORD flags
, DDCOLORKEY
*color_key
)
4929 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface7(iface
);
4931 TRACE("iface %p, flags %#x, color_key %p.\n", iface
, flags
, color_key
);
4933 if (surface
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_MIPMAPSUBLEVEL
)
4934 return DDERR_NOTONMIPMAPSUBLEVEL
;
4936 return ddraw_surface_set_color_key(surface
, flags
, color_key
);
4939 static HRESULT WINAPI
ddraw_surface4_SetColorKey(IDirectDrawSurface4
*iface
, DWORD flags
, DDCOLORKEY
*color_key
)
4941 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
4943 TRACE("iface %p, flags %#x, color_key %p.\n", iface
, flags
, color_key
);
4945 return ddraw_surface_set_color_key(surface
, flags
, color_key
);
4948 static HRESULT WINAPI
ddraw_surface3_SetColorKey(IDirectDrawSurface3
*iface
, DWORD flags
, DDCOLORKEY
*color_key
)
4950 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface3(iface
);
4952 TRACE("iface %p, flags %#x, color_key %p.\n", iface
, flags
, color_key
);
4954 return ddraw_surface_set_color_key(surface
, flags
, color_key
);
4957 static HRESULT WINAPI
ddraw_surface2_SetColorKey(IDirectDrawSurface2
*iface
, DWORD flags
, DDCOLORKEY
*color_key
)
4959 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface2(iface
);
4961 TRACE("iface %p, flags %#x, color_key %p.\n", iface
, flags
, color_key
);
4963 return ddraw_surface_set_color_key(surface
, flags
, color_key
);
4966 static HRESULT WINAPI
ddraw_surface1_SetColorKey(IDirectDrawSurface
*iface
, DWORD flags
, DDCOLORKEY
*color_key
)
4968 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface(iface
);
4970 TRACE("iface %p, flags %#x, color_key %p.\n", iface
, flags
, color_key
);
4972 return ddraw_surface_set_color_key(surface
, flags
, color_key
);
4975 static HRESULT WINAPI
ddraw_surface7_SetPalette(IDirectDrawSurface7
*iface
, IDirectDrawPalette
*palette
)
4977 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface7(iface
);
4979 TRACE("iface %p, palette %p.\n", iface
, palette
);
4981 if (surface
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_MIPMAPSUBLEVEL
)
4982 return DDERR_NOTONMIPMAPSUBLEVEL
;
4983 if (ddraw_surface_is_lost(surface
))
4985 WARN("Surface lost, returning DDERR_SURFACELOST.\n");
4986 return DDERR_SURFACELOST
;
4989 return ddraw_surface_set_palette(surface
, palette
);
4992 static HRESULT WINAPI
ddraw_surface4_SetPalette(IDirectDrawSurface4
*iface
, IDirectDrawPalette
*palette
)
4994 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface4(iface
);
4996 TRACE("iface %p, palette %p.\n", iface
, palette
);
4998 if (ddraw_surface_is_lost(surface
))
5000 WARN("Surface lost, returning DDERR_SURFACELOST.\n");
5001 return DDERR_SURFACELOST
;
5004 return ddraw_surface_set_palette(surface
, palette
);
5007 static HRESULT WINAPI
ddraw_surface3_SetPalette(IDirectDrawSurface3
*iface
, IDirectDrawPalette
*palette
)
5009 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface3(iface
);
5011 TRACE("iface %p, palette %p.\n", iface
, palette
);
5013 if (ddraw_surface_is_lost(surface
))
5015 WARN("Surface lost, returning DDERR_SURFACELOST.\n");
5016 return DDERR_SURFACELOST
;
5019 return ddraw_surface_set_palette(surface
, palette
);
5022 static HRESULT WINAPI
ddraw_surface2_SetPalette(IDirectDrawSurface2
*iface
, IDirectDrawPalette
*palette
)
5024 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface2(iface
);
5026 TRACE("iface %p, palette %p.\n", iface
, palette
);
5028 if (ddraw_surface_is_lost(surface
))
5030 WARN("Surface lost, returning DDERR_SURFACELOST.\n");
5031 return DDERR_SURFACELOST
;
5034 return ddraw_surface_set_palette(surface
, palette
);
5037 static HRESULT WINAPI
ddraw_surface1_SetPalette(IDirectDrawSurface
*iface
, IDirectDrawPalette
*palette
)
5039 struct ddraw_surface
*surface
= impl_from_IDirectDrawSurface(iface
);
5041 TRACE("iface %p, palette %p.\n", iface
, palette
);
5043 if (ddraw_surface_is_lost(surface
))
5045 WARN("Surface lost, returning DDERR_SURFACELOST.\n");
5046 return DDERR_SURFACELOST
;
5049 return ddraw_surface_set_palette(surface
, palette
);
5052 /**********************************************************
5053 * IDirectDrawGammaControl::GetGammaRamp
5055 * Returns the current gamma ramp for a surface
5059 * gamma_ramp: Address to write the ramp to
5063 * DDERR_INVALIDPARAMS if gamma_ramp is NULL
5065 **********************************************************/
5066 static HRESULT WINAPI
ddraw_gamma_control_GetGammaRamp(IDirectDrawGammaControl
*iface
,
5067 DWORD flags
, DDGAMMARAMP
*gamma_ramp
)
5069 struct ddraw_surface
*surface
= impl_from_IDirectDrawGammaControl(iface
);
5071 TRACE("iface %p, flags %#x, gamma_ramp %p.\n", iface
, flags
, gamma_ramp
);
5075 WARN("Invalid gamma_ramp passed.\n");
5076 return DDERR_INVALIDPARAMS
;
5079 wined3d_mutex_lock();
5080 if (surface
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)
5082 /* Note: DDGAMMARAMP is compatible with struct wined3d_gamma_ramp. */
5083 wined3d_device_get_gamma_ramp(surface
->ddraw
->wined3d_device
, 0, (struct wined3d_gamma_ramp
*)gamma_ramp
);
5087 ERR("Not implemented for non-primary surfaces.\n");
5089 wined3d_mutex_unlock();
5094 /**********************************************************
5095 * IDirectDrawGammaControl::SetGammaRamp
5097 * Sets the red, green and blue gamma ramps for
5100 * flags: Can be DDSGR_CALIBRATE to request calibration
5101 * gamma_ramp: Structure containing the new gamma ramp
5105 * DDERR_INVALIDPARAMS if gamma_ramp is NULL
5107 **********************************************************/
5108 static HRESULT WINAPI
ddraw_gamma_control_SetGammaRamp(IDirectDrawGammaControl
*iface
,
5109 DWORD flags
, DDGAMMARAMP
*gamma_ramp
)
5111 struct ddraw_surface
*surface
= impl_from_IDirectDrawGammaControl(iface
);
5113 TRACE("iface %p, flags %#x, gamma_ramp %p.\n", iface
, flags
, gamma_ramp
);
5117 WARN("Invalid gamma_ramp passed.\n");
5118 return DDERR_INVALIDPARAMS
;
5121 wined3d_mutex_lock();
5122 if (surface
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)
5124 /* Note: DDGAMMARAMP is compatible with struct wined3d_gamma_ramp. */
5125 wined3d_device_set_gamma_ramp(surface
->ddraw
->wined3d_device
,
5126 0, flags
, (struct wined3d_gamma_ramp
*)gamma_ramp
);
5130 ERR("Not implemented for non-primary surfaces.\n");
5132 wined3d_mutex_unlock();
5137 /*****************************************************************************
5138 * IDirect3DTexture2::PaletteChanged
5140 * Informs the texture about a palette change
5143 * start: Start index of the change
5144 * count: The number of changed entries
5147 * D3D_OK, because it's a stub
5149 *****************************************************************************/
5150 static HRESULT WINAPI
d3d_texture2_PaletteChanged(IDirect3DTexture2
*iface
, DWORD start
, DWORD count
)
5152 FIXME("iface %p, start %u, count %u stub!\n", iface
, start
, count
);
5157 static HRESULT WINAPI
d3d_texture1_PaletteChanged(IDirect3DTexture
*iface
, DWORD start
, DWORD count
)
5159 struct ddraw_surface
*surface
= impl_from_IDirect3DTexture(iface
);
5161 TRACE("iface %p, start %u, count %u.\n", iface
, start
, count
);
5163 return d3d_texture2_PaletteChanged(&surface
->IDirect3DTexture2_iface
, start
, count
);
5166 /*****************************************************************************
5167 * IDirect3DTexture::Unload
5169 * DX5 SDK: "The IDirect3DTexture2::Unload method is not implemented
5175 *****************************************************************************/
5176 static HRESULT WINAPI
d3d_texture1_Unload(IDirect3DTexture
*iface
)
5178 WARN("iface %p. Not implemented.\n", iface
);
5180 return DDERR_UNSUPPORTED
;
5183 /*****************************************************************************
5184 * IDirect3DTexture2::GetHandle
5186 * Returns handle for the texture.
5189 * device: Device this handle is assigned to
5190 * handle: Address to store the handle at.
5195 *****************************************************************************/
5196 static HRESULT WINAPI
d3d_texture2_GetHandle(IDirect3DTexture2
*iface
,
5197 IDirect3DDevice2
*device
, D3DTEXTUREHANDLE
*handle
)
5199 struct ddraw_surface
*surface
= impl_from_IDirect3DTexture2(iface
);
5200 struct d3d_device
*device_impl
= unsafe_impl_from_IDirect3DDevice2(device
);
5202 TRACE("iface %p, device %p, handle %p.\n", iface
, device
, handle
);
5204 wined3d_mutex_lock();
5206 if (!surface
->Handle
)
5208 DWORD h
= ddraw_allocate_handle(&device_impl
->handle_table
, surface
, DDRAW_HANDLE_SURFACE
);
5209 if (h
== DDRAW_INVALID_HANDLE
)
5211 ERR("Failed to allocate a texture handle.\n");
5212 wined3d_mutex_unlock();
5213 return DDERR_OUTOFMEMORY
;
5216 surface
->Handle
= h
+ 1;
5219 TRACE("Returning handle %08x.\n", surface
->Handle
);
5220 *handle
= surface
->Handle
;
5222 wined3d_mutex_unlock();
5227 static HRESULT WINAPI
d3d_texture1_GetHandle(IDirect3DTexture
*iface
,
5228 IDirect3DDevice
*device
, D3DTEXTUREHANDLE
*handle
)
5230 struct ddraw_surface
*surface
= impl_from_IDirect3DTexture(iface
);
5231 struct d3d_device
*device_impl
= unsafe_impl_from_IDirect3DDevice(device
);
5233 TRACE("iface %p, device %p, handle %p.\n", iface
, device
, handle
);
5235 return d3d_texture2_GetHandle(&surface
->IDirect3DTexture2_iface
,
5236 device_impl
? &device_impl
->IDirect3DDevice2_iface
: NULL
, handle
);
5239 /*****************************************************************************
5240 * get_sub_mimaplevel
5242 * Helper function that returns the next mipmap level
5244 * tex_ptr: Surface of which to return the next level
5246 *****************************************************************************/
5247 static struct ddraw_surface
*get_sub_mimaplevel(struct ddraw_surface
*surface
)
5249 /* Now go down the mipmap chain to the next surface */
5250 static DDSCAPS2 mipmap_caps
= { DDSCAPS_MIPMAP
| DDSCAPS_TEXTURE
, 0, 0, {0} };
5251 IDirectDrawSurface7
*next_level
;
5254 hr
= ddraw_surface7_GetAttachedSurface(&surface
->IDirectDrawSurface7_iface
, &mipmap_caps
, &next_level
);
5255 if (FAILED(hr
)) return NULL
;
5257 ddraw_surface7_Release(next_level
);
5259 return impl_from_IDirectDrawSurface7(next_level
);
5262 /*****************************************************************************
5263 * IDirect3DTexture2::Load
5265 * Loads a texture created with the DDSCAPS_ALLOCONLOAD
5267 * This function isn't relayed to WineD3D because the whole interface is
5268 * implemented in DDraw only. For speed improvements an implementation which
5269 * takes OpenGL more into account could be placed into WineD3D.
5272 * src_texture: Address of the texture to load
5276 * D3DERR_TEXTURE_LOAD_FAILED.
5278 *****************************************************************************/
5279 static HRESULT WINAPI
d3d_texture2_Load(IDirect3DTexture2
*iface
, IDirect3DTexture2
*src_texture
)
5281 struct ddraw_surface
*dst_surface
= impl_from_IDirect3DTexture2(iface
);
5282 struct ddraw_surface
*src_surface
= unsafe_impl_from_IDirect3DTexture2(src_texture
);
5283 struct wined3d_resource
*dst_resource
, *src_resource
;
5286 TRACE("iface %p, src_texture %p.\n", iface
, src_texture
);
5288 if (src_surface
== dst_surface
)
5290 TRACE("copying surface %p to surface %p, why?\n", src_surface
, dst_surface
);
5294 wined3d_mutex_lock();
5296 dst_resource
= wined3d_texture_get_resource(dst_surface
->wined3d_texture
);
5297 src_resource
= wined3d_texture_get_resource(src_surface
->wined3d_texture
);
5299 if (((src_surface
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_MIPMAP
)
5300 != (dst_surface
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_MIPMAP
))
5301 || (src_surface
->surface_desc
.u2
.dwMipMapCount
!= dst_surface
->surface_desc
.u2
.dwMipMapCount
))
5303 ERR("Trying to load surfaces with different mip-map counts.\n");
5308 struct ddraw_palette
*dst_pal
, *src_pal
;
5309 DDSURFACEDESC
*src_desc
, *dst_desc
;
5311 TRACE("Copying surface %p to surface %p.\n", src_surface
, dst_surface
);
5313 /* Suppress the ALLOCONLOAD flag */
5314 dst_surface
->surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_ALLOCONLOAD
;
5316 /* Get the palettes */
5317 dst_pal
= dst_surface
->palette
;
5318 src_pal
= src_surface
->palette
;
5322 PALETTEENTRY palent
[256];
5326 wined3d_mutex_unlock();
5327 return DDERR_NOPALETTEATTACHED
;
5329 IDirectDrawPalette_GetEntries(&src_pal
->IDirectDrawPalette_iface
, 0, 0, 256, palent
);
5330 IDirectDrawPalette_SetEntries(&dst_pal
->IDirectDrawPalette_iface
, 0, 0, 256, palent
);
5333 /* Copy one surface on the other */
5334 dst_desc
= (DDSURFACEDESC
*)&(dst_surface
->surface_desc
);
5335 src_desc
= (DDSURFACEDESC
*)&(src_surface
->surface_desc
);
5337 if ((src_desc
->dwWidth
!= dst_desc
->dwWidth
) || (src_desc
->dwHeight
!= dst_desc
->dwHeight
))
5339 /* Should also check for same pixel format, u1.lPitch, ... */
5340 ERR("Error in surface sizes.\n");
5341 wined3d_mutex_unlock();
5342 return D3DERR_TEXTURE_LOAD_FAILED
;
5346 struct wined3d_map_desc src_map_desc
, dst_map_desc
;
5348 /* Copy the src blit color key if the source has one, don't erase
5349 * the destination's ckey if the source has none */
5350 if (src_desc
->dwFlags
& DDSD_CKSRCBLT
)
5352 IDirectDrawSurface7_SetColorKey(&dst_surface
->IDirectDrawSurface7_iface
,
5353 DDCKEY_SRCBLT
, &src_desc
->ddckCKSrcBlt
);
5356 if (FAILED(hr
= wined3d_resource_map(src_resource
,
5357 src_surface
->sub_resource_idx
, &src_map_desc
, NULL
, WINED3D_MAP_READ
)))
5359 ERR("Failed to lock source surface, hr %#x.\n", hr
);
5360 wined3d_mutex_unlock();
5361 return D3DERR_TEXTURE_LOAD_FAILED
;
5364 if (FAILED(hr
= wined3d_resource_map(dst_resource
,
5365 dst_surface
->sub_resource_idx
, &dst_map_desc
, NULL
, WINED3D_MAP_WRITE
)))
5367 ERR("Failed to lock destination surface, hr %#x.\n", hr
);
5368 wined3d_resource_unmap(src_resource
, src_surface
->sub_resource_idx
);
5369 wined3d_mutex_unlock();
5370 return D3DERR_TEXTURE_LOAD_FAILED
;
5373 if (dst_surface
->surface_desc
.u4
.ddpfPixelFormat
.dwFlags
& DDPF_FOURCC
)
5374 memcpy(dst_map_desc
.data
, src_map_desc
.data
, src_surface
->surface_desc
.u1
.dwLinearSize
);
5376 memcpy(dst_map_desc
.data
, src_map_desc
.data
, src_map_desc
.row_pitch
* src_desc
->dwHeight
);
5378 wined3d_resource_unmap(dst_resource
, dst_surface
->sub_resource_idx
);
5379 wined3d_resource_unmap(src_resource
, src_surface
->sub_resource_idx
);
5382 if (src_surface
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_MIPMAP
)
5383 src_surface
= get_sub_mimaplevel(src_surface
);
5387 if (dst_surface
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_MIPMAP
)
5388 dst_surface
= get_sub_mimaplevel(dst_surface
);
5392 if (!src_surface
|| !dst_surface
)
5394 if (src_surface
!= dst_surface
)
5395 ERR("Loading surface with different mipmap structure.\n");
5400 wined3d_mutex_unlock();
5405 static HRESULT WINAPI
d3d_texture1_Load(IDirect3DTexture
*iface
, IDirect3DTexture
*src_texture
)
5407 struct ddraw_surface
*dst_surface
= impl_from_IDirect3DTexture(iface
);
5408 struct ddraw_surface
*src_surface
= unsafe_impl_from_IDirect3DTexture(src_texture
);
5410 TRACE("iface %p, src_texture %p.\n", iface
, src_texture
);
5412 return d3d_texture2_Load(&dst_surface
->IDirect3DTexture2_iface
,
5413 src_surface
? &src_surface
->IDirect3DTexture2_iface
: NULL
);
5416 /*****************************************************************************
5418 *****************************************************************************/
5420 /* Some windowed mode wrappers expect this vtbl to be writable. */
5421 static struct IDirectDrawSurface7Vtbl ddraw_surface7_vtbl
=
5424 ddraw_surface7_QueryInterface
,
5425 ddraw_surface7_AddRef
,
5426 ddraw_surface7_Release
,
5427 /* IDirectDrawSurface */
5428 ddraw_surface7_AddAttachedSurface
,
5429 ddraw_surface7_AddOverlayDirtyRect
,
5431 ddraw_surface7_BltBatch
,
5432 ddraw_surface7_BltFast
,
5433 ddraw_surface7_DeleteAttachedSurface
,
5434 ddraw_surface7_EnumAttachedSurfaces
,
5435 ddraw_surface7_EnumOverlayZOrders
,
5436 ddraw_surface7_Flip
,
5437 ddraw_surface7_GetAttachedSurface
,
5438 ddraw_surface7_GetBltStatus
,
5439 ddraw_surface7_GetCaps
,
5440 ddraw_surface7_GetClipper
,
5441 ddraw_surface7_GetColorKey
,
5442 ddraw_surface7_GetDC
,
5443 ddraw_surface7_GetFlipStatus
,
5444 ddraw_surface7_GetOverlayPosition
,
5445 ddraw_surface7_GetPalette
,
5446 ddraw_surface7_GetPixelFormat
,
5447 ddraw_surface7_GetSurfaceDesc
,
5448 ddraw_surface7_Initialize
,
5449 ddraw_surface7_IsLost
,
5450 ddraw_surface7_Lock
,
5451 ddraw_surface7_ReleaseDC
,
5452 ddraw_surface7_Restore
,
5453 ddraw_surface7_SetClipper
,
5454 ddraw_surface7_SetColorKey
,
5455 ddraw_surface7_SetOverlayPosition
,
5456 ddraw_surface7_SetPalette
,
5457 ddraw_surface7_Unlock
,
5458 ddraw_surface7_UpdateOverlay
,
5459 ddraw_surface7_UpdateOverlayDisplay
,
5460 ddraw_surface7_UpdateOverlayZOrder
,
5461 /* IDirectDrawSurface2 */
5462 ddraw_surface7_GetDDInterface
,
5463 ddraw_surface7_PageLock
,
5464 ddraw_surface7_PageUnlock
,
5465 /* IDirectDrawSurface3 */
5466 ddraw_surface7_SetSurfaceDesc
,
5467 /* IDirectDrawSurface4 */
5468 ddraw_surface7_SetPrivateData
,
5469 ddraw_surface7_GetPrivateData
,
5470 ddraw_surface7_FreePrivateData
,
5471 ddraw_surface7_GetUniquenessValue
,
5472 ddraw_surface7_ChangeUniquenessValue
,
5473 /* IDirectDrawSurface7 */
5474 ddraw_surface7_SetPriority
,
5475 ddraw_surface7_GetPriority
,
5476 ddraw_surface7_SetLOD
,
5477 ddraw_surface7_GetLOD
,
5480 /* Some windowed mode wrappers expect this vtbl to be writable. */
5481 static struct IDirectDrawSurface4Vtbl ddraw_surface4_vtbl
=
5484 ddraw_surface4_QueryInterface
,
5485 ddraw_surface4_AddRef
,
5486 ddraw_surface4_Release
,
5487 /* IDirectDrawSurface */
5488 ddraw_surface4_AddAttachedSurface
,
5489 ddraw_surface4_AddOverlayDirtyRect
,
5491 ddraw_surface4_BltBatch
,
5492 ddraw_surface4_BltFast
,
5493 ddraw_surface4_DeleteAttachedSurface
,
5494 ddraw_surface4_EnumAttachedSurfaces
,
5495 ddraw_surface4_EnumOverlayZOrders
,
5496 ddraw_surface4_Flip
,
5497 ddraw_surface4_GetAttachedSurface
,
5498 ddraw_surface4_GetBltStatus
,
5499 ddraw_surface4_GetCaps
,
5500 ddraw_surface4_GetClipper
,
5501 ddraw_surface4_GetColorKey
,
5502 ddraw_surface4_GetDC
,
5503 ddraw_surface4_GetFlipStatus
,
5504 ddraw_surface4_GetOverlayPosition
,
5505 ddraw_surface4_GetPalette
,
5506 ddraw_surface4_GetPixelFormat
,
5507 ddraw_surface4_GetSurfaceDesc
,
5508 ddraw_surface4_Initialize
,
5509 ddraw_surface4_IsLost
,
5510 ddraw_surface4_Lock
,
5511 ddraw_surface4_ReleaseDC
,
5512 ddraw_surface4_Restore
,
5513 ddraw_surface4_SetClipper
,
5514 ddraw_surface4_SetColorKey
,
5515 ddraw_surface4_SetOverlayPosition
,
5516 ddraw_surface4_SetPalette
,
5517 ddraw_surface4_Unlock
,
5518 ddraw_surface4_UpdateOverlay
,
5519 ddraw_surface4_UpdateOverlayDisplay
,
5520 ddraw_surface4_UpdateOverlayZOrder
,
5521 /* IDirectDrawSurface2 */
5522 ddraw_surface4_GetDDInterface
,
5523 ddraw_surface4_PageLock
,
5524 ddraw_surface4_PageUnlock
,
5525 /* IDirectDrawSurface3 */
5526 ddraw_surface4_SetSurfaceDesc
,
5527 /* IDirectDrawSurface4 */
5528 ddraw_surface4_SetPrivateData
,
5529 ddraw_surface4_GetPrivateData
,
5530 ddraw_surface4_FreePrivateData
,
5531 ddraw_surface4_GetUniquenessValue
,
5532 ddraw_surface4_ChangeUniquenessValue
,
5535 /* Some windowed mode wrappers expect this vtbl to be writable. */
5536 static struct IDirectDrawSurface3Vtbl ddraw_surface3_vtbl
=
5539 ddraw_surface3_QueryInterface
,
5540 ddraw_surface3_AddRef
,
5541 ddraw_surface3_Release
,
5542 /* IDirectDrawSurface */
5543 ddraw_surface3_AddAttachedSurface
,
5544 ddraw_surface3_AddOverlayDirtyRect
,
5546 ddraw_surface3_BltBatch
,
5547 ddraw_surface3_BltFast
,
5548 ddraw_surface3_DeleteAttachedSurface
,
5549 ddraw_surface3_EnumAttachedSurfaces
,
5550 ddraw_surface3_EnumOverlayZOrders
,
5551 ddraw_surface3_Flip
,
5552 ddraw_surface3_GetAttachedSurface
,
5553 ddraw_surface3_GetBltStatus
,
5554 ddraw_surface3_GetCaps
,
5555 ddraw_surface3_GetClipper
,
5556 ddraw_surface3_GetColorKey
,
5557 ddraw_surface3_GetDC
,
5558 ddraw_surface3_GetFlipStatus
,
5559 ddraw_surface3_GetOverlayPosition
,
5560 ddraw_surface3_GetPalette
,
5561 ddraw_surface3_GetPixelFormat
,
5562 ddraw_surface3_GetSurfaceDesc
,
5563 ddraw_surface3_Initialize
,
5564 ddraw_surface3_IsLost
,
5565 ddraw_surface3_Lock
,
5566 ddraw_surface3_ReleaseDC
,
5567 ddraw_surface3_Restore
,
5568 ddraw_surface3_SetClipper
,
5569 ddraw_surface3_SetColorKey
,
5570 ddraw_surface3_SetOverlayPosition
,
5571 ddraw_surface3_SetPalette
,
5572 ddraw_surface3_Unlock
,
5573 ddraw_surface3_UpdateOverlay
,
5574 ddraw_surface3_UpdateOverlayDisplay
,
5575 ddraw_surface3_UpdateOverlayZOrder
,
5576 /* IDirectDrawSurface2 */
5577 ddraw_surface3_GetDDInterface
,
5578 ddraw_surface3_PageLock
,
5579 ddraw_surface3_PageUnlock
,
5580 /* IDirectDrawSurface3 */
5581 ddraw_surface3_SetSurfaceDesc
,
5584 /* Some windowed mode wrappers expect this vtbl to be writable. */
5585 static struct IDirectDrawSurface2Vtbl ddraw_surface2_vtbl
=
5588 ddraw_surface2_QueryInterface
,
5589 ddraw_surface2_AddRef
,
5590 ddraw_surface2_Release
,
5591 /* IDirectDrawSurface */
5592 ddraw_surface2_AddAttachedSurface
,
5593 ddraw_surface2_AddOverlayDirtyRect
,
5595 ddraw_surface2_BltBatch
,
5596 ddraw_surface2_BltFast
,
5597 ddraw_surface2_DeleteAttachedSurface
,
5598 ddraw_surface2_EnumAttachedSurfaces
,
5599 ddraw_surface2_EnumOverlayZOrders
,
5600 ddraw_surface2_Flip
,
5601 ddraw_surface2_GetAttachedSurface
,
5602 ddraw_surface2_GetBltStatus
,
5603 ddraw_surface2_GetCaps
,
5604 ddraw_surface2_GetClipper
,
5605 ddraw_surface2_GetColorKey
,
5606 ddraw_surface2_GetDC
,
5607 ddraw_surface2_GetFlipStatus
,
5608 ddraw_surface2_GetOverlayPosition
,
5609 ddraw_surface2_GetPalette
,
5610 ddraw_surface2_GetPixelFormat
,
5611 ddraw_surface2_GetSurfaceDesc
,
5612 ddraw_surface2_Initialize
,
5613 ddraw_surface2_IsLost
,
5614 ddraw_surface2_Lock
,
5615 ddraw_surface2_ReleaseDC
,
5616 ddraw_surface2_Restore
,
5617 ddraw_surface2_SetClipper
,
5618 ddraw_surface2_SetColorKey
,
5619 ddraw_surface2_SetOverlayPosition
,
5620 ddraw_surface2_SetPalette
,
5621 ddraw_surface2_Unlock
,
5622 ddraw_surface2_UpdateOverlay
,
5623 ddraw_surface2_UpdateOverlayDisplay
,
5624 ddraw_surface2_UpdateOverlayZOrder
,
5625 /* IDirectDrawSurface2 */
5626 ddraw_surface2_GetDDInterface
,
5627 ddraw_surface2_PageLock
,
5628 ddraw_surface2_PageUnlock
,
5631 /* Bad Mojo Redux expects this vtbl to be writable. */
5632 static struct IDirectDrawSurfaceVtbl ddraw_surface1_vtbl
=
5635 ddraw_surface1_QueryInterface
,
5636 ddraw_surface1_AddRef
,
5637 ddraw_surface1_Release
,
5638 /* IDirectDrawSurface */
5639 ddraw_surface1_AddAttachedSurface
,
5640 ddraw_surface1_AddOverlayDirtyRect
,
5642 ddraw_surface1_BltBatch
,
5643 ddraw_surface1_BltFast
,
5644 ddraw_surface1_DeleteAttachedSurface
,
5645 ddraw_surface1_EnumAttachedSurfaces
,
5646 ddraw_surface1_EnumOverlayZOrders
,
5647 ddraw_surface1_Flip
,
5648 ddraw_surface1_GetAttachedSurface
,
5649 ddraw_surface1_GetBltStatus
,
5650 ddraw_surface1_GetCaps
,
5651 ddraw_surface1_GetClipper
,
5652 ddraw_surface1_GetColorKey
,
5653 ddraw_surface1_GetDC
,
5654 ddraw_surface1_GetFlipStatus
,
5655 ddraw_surface1_GetOverlayPosition
,
5656 ddraw_surface1_GetPalette
,
5657 ddraw_surface1_GetPixelFormat
,
5658 ddraw_surface1_GetSurfaceDesc
,
5659 ddraw_surface1_Initialize
,
5660 ddraw_surface1_IsLost
,
5661 ddraw_surface1_Lock
,
5662 ddraw_surface1_ReleaseDC
,
5663 ddraw_surface1_Restore
,
5664 ddraw_surface1_SetClipper
,
5665 ddraw_surface1_SetColorKey
,
5666 ddraw_surface1_SetOverlayPosition
,
5667 ddraw_surface1_SetPalette
,
5668 ddraw_surface1_Unlock
,
5669 ddraw_surface1_UpdateOverlay
,
5670 ddraw_surface1_UpdateOverlayDisplay
,
5671 ddraw_surface1_UpdateOverlayZOrder
,
5674 static const struct IDirectDrawGammaControlVtbl ddraw_gamma_control_vtbl
=
5676 ddraw_gamma_control_QueryInterface
,
5677 ddraw_gamma_control_AddRef
,
5678 ddraw_gamma_control_Release
,
5679 ddraw_gamma_control_GetGammaRamp
,
5680 ddraw_gamma_control_SetGammaRamp
,
5683 static const struct IDirect3DTexture2Vtbl d3d_texture2_vtbl
=
5685 d3d_texture2_QueryInterface
,
5686 d3d_texture2_AddRef
,
5687 d3d_texture2_Release
,
5688 d3d_texture2_GetHandle
,
5689 d3d_texture2_PaletteChanged
,
5693 static const struct IDirect3DTextureVtbl d3d_texture1_vtbl
=
5695 d3d_texture1_QueryInterface
,
5696 d3d_texture1_AddRef
,
5697 d3d_texture1_Release
,
5698 d3d_texture1_Initialize
,
5699 d3d_texture1_GetHandle
,
5700 d3d_texture1_PaletteChanged
,
5702 d3d_texture1_Unload
,
5705 /* Some games (e.g. Tomb Raider 3) pass the wrong version of the
5706 * IDirectDrawSurface interface to ddraw methods. */
5707 struct ddraw_surface
*unsafe_impl_from_IDirectDrawSurface7(IDirectDrawSurface7
*iface
)
5709 if (!iface
) return NULL
;
5710 if (iface
->lpVtbl
!= &ddraw_surface7_vtbl
)
5712 HRESULT hr
= IDirectDrawSurface7_QueryInterface(iface
, &IID_IDirectDrawSurface7
, (void **)&iface
);
5715 WARN("Object %p doesn't expose interface IDirectDrawSurface7.\n", iface
);
5718 IDirectDrawSurface7_Release(iface
);
5720 return CONTAINING_RECORD(iface
, struct ddraw_surface
, IDirectDrawSurface7_iface
);
5723 struct ddraw_surface
*unsafe_impl_from_IDirectDrawSurface4(IDirectDrawSurface4
*iface
)
5725 if (!iface
) return NULL
;
5726 if (iface
->lpVtbl
!= &ddraw_surface4_vtbl
)
5728 HRESULT hr
= IDirectDrawSurface4_QueryInterface(iface
, &IID_IDirectDrawSurface4
, (void **)&iface
);
5731 WARN("Object %p doesn't expose interface IDirectDrawSurface4.\n", iface
);
5734 IDirectDrawSurface4_Release(iface
);
5736 return CONTAINING_RECORD(iface
, struct ddraw_surface
, IDirectDrawSurface4_iface
);
5739 static struct ddraw_surface
*unsafe_impl_from_IDirectDrawSurface3(IDirectDrawSurface3
*iface
)
5741 if (!iface
) return NULL
;
5742 if (iface
->lpVtbl
!= &ddraw_surface3_vtbl
)
5744 HRESULT hr
= IDirectDrawSurface3_QueryInterface(iface
, &IID_IDirectDrawSurface3
, (void **)&iface
);
5747 WARN("Object %p doesn't expose interface IDirectDrawSurface3.\n", iface
);
5750 IDirectDrawSurface3_Release(iface
);
5752 return CONTAINING_RECORD(iface
, struct ddraw_surface
, IDirectDrawSurface3_iface
);
5755 static struct ddraw_surface
*unsafe_impl_from_IDirectDrawSurface2(IDirectDrawSurface2
*iface
)
5757 if (!iface
) return NULL
;
5758 if (iface
->lpVtbl
!= &ddraw_surface2_vtbl
)
5760 HRESULT hr
= IDirectDrawSurface2_QueryInterface(iface
, &IID_IDirectDrawSurface2
, (void **)&iface
);
5763 WARN("Object %p doesn't expose interface IDirectDrawSurface2.\n", iface
);
5766 IDirectDrawSurface2_Release(iface
);
5768 return CONTAINING_RECORD(iface
, struct ddraw_surface
, IDirectDrawSurface2_iface
);
5771 struct ddraw_surface
*unsafe_impl_from_IDirectDrawSurface(IDirectDrawSurface
*iface
)
5773 if (!iface
) return NULL
;
5774 if (iface
->lpVtbl
!= &ddraw_surface1_vtbl
)
5776 HRESULT hr
= IDirectDrawSurface_QueryInterface(iface
, &IID_IDirectDrawSurface
, (void **)&iface
);
5779 WARN("Object %p doesn't expose interface IDirectDrawSurface.\n", iface
);
5782 IDirectDrawSurface_Release(iface
);
5784 return CONTAINING_RECORD(iface
, struct ddraw_surface
, IDirectDrawSurface_iface
);
5787 struct ddraw_surface
*unsafe_impl_from_IDirect3DTexture2(IDirect3DTexture2
*iface
)
5789 if (!iface
) return NULL
;
5790 assert(iface
->lpVtbl
== &d3d_texture2_vtbl
);
5791 return CONTAINING_RECORD(iface
, struct ddraw_surface
, IDirect3DTexture2_iface
);
5794 struct ddraw_surface
*unsafe_impl_from_IDirect3DTexture(IDirect3DTexture
*iface
)
5796 if (!iface
) return NULL
;
5797 assert(iface
->lpVtbl
== &d3d_texture1_vtbl
);
5798 return CONTAINING_RECORD(iface
, struct ddraw_surface
, IDirect3DTexture_iface
);
5801 static void STDMETHODCALLTYPE
ddraw_surface_wined3d_object_destroyed(void *parent
)
5803 struct ddraw_surface
*surface
= parent
;
5805 TRACE("surface %p.\n", surface
);
5807 /* This shouldn't happen, ddraw_surface_release_iface() should prevent the
5808 * surface from being destroyed in this case. */
5809 if (surface
->first_attached
!= surface
)
5810 ERR("Surface is still attached to surface %p.\n", surface
->first_attached
);
5812 while (surface
->next_attached
)
5813 if (FAILED(ddraw_surface_delete_attached_surface(surface
,
5814 surface
->next_attached
, surface
->next_attached
->attached_iface
)))
5815 ERR("DeleteAttachedSurface failed.\n");
5817 /* Having a texture handle set implies that the device still exists. */
5818 if (surface
->Handle
)
5819 ddraw_free_handle(&surface
->ddraw
->d3ddevice
->handle_table
, surface
->Handle
- 1, DDRAW_HANDLE_SURFACE
);
5821 /* Reduce the ddraw surface count. */
5822 list_remove(&surface
->surface_list_entry
);
5824 if (surface
->clipper
&& ddraw_clipper_is_valid(surface
->clipper
))
5825 IDirectDrawClipper_Release(&surface
->clipper
->IDirectDrawClipper_iface
);
5827 if (surface
== surface
->ddraw
->primary
)
5829 surface
->ddraw
->primary
= NULL
;
5830 surface
->ddraw
->gdi_surface
= NULL
;
5833 wined3d_private_store_cleanup(&surface
->private_store
);
5838 static const struct wined3d_parent_ops ddraw_surface_wined3d_parent_ops
=
5840 ddraw_surface_wined3d_object_destroyed
,
5843 static void STDMETHODCALLTYPE
ddraw_texture_wined3d_object_destroyed(void *parent
)
5845 struct ddraw_texture
*texture
= parent
;
5847 TRACE("texture %p, texture_memory %p.\n", texture
, texture
->texture_memory
);
5849 heap_free(texture
->texture_memory
);
5853 static const struct wined3d_parent_ops ddraw_texture_wined3d_parent_ops
=
5855 ddraw_texture_wined3d_object_destroyed
,
5858 static HRESULT CDECL
ddraw_reset_enum_callback(struct wined3d_resource
*resource
)
5863 static HRESULT
ddraw_surface_reserve_memory(struct wined3d_texture
*wined3d_texture
)
5865 static const unsigned int extra_size
= 0x10000;
5867 struct ddraw_texture
*texture
= wined3d_texture_get_parent(wined3d_texture
);
5868 struct wined3d_resource_desc resource_desc
;
5869 struct wined3d_sub_resource_desc desc
;
5870 unsigned int pitch
, slice_pitch
;
5871 unsigned int sub_resource_idx
;
5872 HRESULT hr
= WINED3D_OK
;
5873 unsigned int offset
;
5875 wined3d_resource_get_desc(wined3d_texture_get_resource(wined3d_texture
), &resource_desc
);
5876 if (!(texture
->texture_memory
= heap_alloc_zero(resource_desc
.size
+ extra_size
)))
5878 ERR("Out of memory.\n");
5879 return E_OUTOFMEMORY
;
5881 TRACE("texture->texture_memory %p.\n", texture
->texture_memory
);
5884 sub_resource_idx
= 0;
5885 while (wined3d_texture_get_sub_resource_desc(wined3d_texture
, sub_resource_idx
, &desc
)
5888 wined3d_texture_get_pitch(wined3d_texture
, sub_resource_idx
, &pitch
, &slice_pitch
);
5890 if (FAILED(hr
= wined3d_texture_update_desc(wined3d_texture
, sub_resource_idx
,
5891 desc
.width
, desc
.height
, resource_desc
.format
,
5892 desc
.multisample_type
, desc
.multisample_quality
,
5893 (BYTE
*)texture
->texture_memory
+ offset
, pitch
)))
5895 heap_free(texture
->texture_memory
);
5896 texture
->texture_memory
= NULL
;
5900 offset
+= desc
.size
;
5905 HRESULT
ddraw_surface_create(struct ddraw
*ddraw
, const DDSURFACEDESC2
*surface_desc
,
5906 struct ddraw_surface
**surface
, IUnknown
*outer_unknown
, unsigned int version
)
5908 struct wined3d_sub_resource_desc wined3d_mip_desc
;
5909 struct ddraw_surface
*root
, *mip
, **attach
;
5910 struct wined3d_resource_desc wined3d_desc
;
5911 DDPIXELFORMAT wined3d_display_mode_format
;
5912 struct wined3d_texture
*wined3d_texture
;
5913 struct wined3d_display_mode mode
;
5914 DDSURFACEDESC2
*desc
, *mip_desc
;
5915 struct ddraw_texture
*texture
;
5916 BOOL sysmem_fallback
= FALSE
;
5917 unsigned int layers
= 1;
5918 unsigned int pitch
= 0;
5919 BOOL reserve_memory
;
5923 TRACE("ddraw %p, surface_desc %p, surface %p, outer_unknown %p, version %u.\n",
5924 ddraw
, surface_desc
, surface
, outer_unknown
, version
);
5925 if (TRACE_ON(ddraw
))
5927 TRACE("Requesting surface desc:\n");
5928 DDRAW_dump_surface_desc(surface_desc
);
5932 return CLASS_E_NOAGGREGATION
;
5937 if (!(texture
= heap_alloc(sizeof(*texture
))))
5938 return E_OUTOFMEMORY
;
5940 texture
->texture_memory
= NULL
;
5941 texture
->version
= version
;
5942 texture
->surface_desc
= *surface_desc
;
5943 desc
= &texture
->surface_desc
;
5945 /* Ensure DDSD_CAPS is always set. */
5946 desc
->dwFlags
|= DDSD_CAPS
;
5948 if (desc
->ddsCaps
.dwCaps
& DDSCAPS_FLIP
)
5950 if (!(desc
->dwFlags
& DDSD_BACKBUFFERCOUNT
) || !desc
->u5
.dwBackBufferCount
)
5952 WARN("Tried to create a flippable surface without any back buffers.\n");
5954 return DDERR_INVALIDCAPS
;
5957 if (!(desc
->ddsCaps
.dwCaps
& DDSCAPS_COMPLEX
))
5959 WARN("Tried to create a flippable surface without DDSCAPS_COMPLEX.\n");
5961 return DDERR_INVALIDCAPS
;
5964 if (desc
->ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
5966 WARN("Tried to create a flippable cubemap.\n");
5968 return DDERR_INVALIDPARAMS
;
5971 if (desc
->ddsCaps
.dwCaps
& DDSCAPS_TEXTURE
)
5973 FIXME("Flippable textures not implemented.\n");
5975 return DDERR_INVALIDCAPS
;
5980 if (desc
->dwFlags
& DDSD_BACKBUFFERCOUNT
)
5982 WARN("Tried to specify a back buffer count for a non-flippable surface.\n");
5983 hr
= desc
->ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
? DDERR_INVALIDPARAMS
: DDERR_INVALIDCAPS
;
5989 if (desc
->ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)
5991 if (desc
->ddsCaps
.dwCaps
& DDSCAPS_TEXTURE
)
5993 WARN("Tried to create a primary surface with DDSCAPS_TEXTURE.\n");
5995 return DDERR_INVALIDCAPS
;
5998 if ((desc
->ddsCaps
.dwCaps
& DDSCAPS_COMPLEX
) && !(desc
->ddsCaps
.dwCaps
& DDSCAPS_FLIP
))
6000 WARN("Tried to create a flippable primary surface without both DDSCAPS_FLIP and DDSCAPS_COMPLEX.\n");
6002 return DDERR_INVALIDCAPS
;
6005 if ((desc
->ddsCaps
.dwCaps
& DDSCAPS_FLIP
) && !(ddraw
->cooperative_level
& DDSCL_EXCLUSIVE
))
6007 WARN("Tried to create a flippable primary surface without DDSCL_EXCLUSIVE.\n");
6009 return DDERR_NOEXCLUSIVEMODE
;
6013 /* This is a special case in ddrawex, but not allowed in ddraw. */
6014 if ((desc
->ddsCaps
.dwCaps
& (DDSCAPS_VIDEOMEMORY
| DDSCAPS_SYSTEMMEMORY
))
6015 == (DDSCAPS_VIDEOMEMORY
| DDSCAPS_SYSTEMMEMORY
))
6017 WARN("Tried to create a surface in both system and video memory.\n");
6019 return DDERR_INVALIDCAPS
;
6022 if ((desc
->ddsCaps
.dwCaps
& (DDSCAPS_ALLOCONLOAD
| DDSCAPS_MIPMAP
))
6023 && !(desc
->ddsCaps
.dwCaps
& DDSCAPS_TEXTURE
))
6025 WARN("Caps %#x require DDSCAPS_TEXTURE.\n", desc
->ddsCaps
.dwCaps
);
6027 return DDERR_INVALIDCAPS
;
6030 if ((desc
->ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP_ALLFACES
)
6031 && !(desc
->ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
))
6033 WARN("Cube map faces requested without cube map flag.\n");
6035 return DDERR_INVALIDCAPS
;
6038 if ((desc
->ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
6039 && !(desc
->ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP_ALLFACES
))
6041 WARN("Cube map without faces requested.\n");
6043 return DDERR_INVALIDPARAMS
;
6046 if ((desc
->ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
6047 && (desc
->ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP_ALLFACES
) != DDSCAPS2_CUBEMAP_ALLFACES
)
6048 FIXME("Partial cube maps not implemented.\n");
6050 if (desc
->ddsCaps
.dwCaps2
& (DDSCAPS2_TEXTUREMANAGE
| DDSCAPS2_D3DTEXTUREMANAGE
))
6052 if (!(desc
->ddsCaps
.dwCaps
& DDSCAPS_TEXTURE
))
6054 WARN("DDSCAPS2_TEXTUREMANAGE used without DDSCAPS_TEXTURE, returning DDERR_INVALIDCAPS.\n");
6056 return DDERR_INVALIDCAPS
;
6058 if (desc
->ddsCaps
.dwCaps
& (DDSCAPS_VIDEOMEMORY
| DDSCAPS_SYSTEMMEMORY
))
6060 WARN("DDSCAPS2_TEXTUREMANAGE used with DDSCAPS_VIDEOMEMORY "
6061 "or DDSCAPS_SYSTEMMEMORY, returning DDERR_INVALIDCAPS.\n");
6063 return DDERR_INVALIDCAPS
;
6067 if (desc
->ddsCaps
.dwCaps
& DDSCAPS_WRITEONLY
6068 && !(desc
->ddsCaps
.dwCaps2
& (DDSCAPS2_TEXTUREMANAGE
| DDSCAPS2_D3DTEXTUREMANAGE
)))
6070 WARN("DDSCAPS_WRITEONLY used without DDSCAPS2_TEXTUREMANAGE, returning DDERR_INVALIDCAPS.\n");
6072 return DDERR_INVALIDCAPS
;
6075 if (FAILED(hr
= wined3d_output_get_display_mode(ddraw
->wined3d_output
, &mode
, NULL
)))
6077 ERR("Failed to get display mode, hr %#x.\n", hr
);
6079 return hr_ddraw_from_wined3d(hr
);
6082 wined3d_display_mode_format
.dwSize
= sizeof(wined3d_display_mode_format
);
6083 ddrawformat_from_wined3dformat(&wined3d_display_mode_format
, mode
.format_id
);
6085 /* No pixelformat given? Use the current screen format. */
6086 if (!(desc
->dwFlags
& DDSD_PIXELFORMAT
))
6088 desc
->dwFlags
|= DDSD_PIXELFORMAT
;
6089 desc
->u4
.ddpfPixelFormat
= wined3d_display_mode_format
;
6092 wined3d_desc
.resource_type
= WINED3D_RTYPE_TEXTURE_2D
;
6093 wined3d_desc
.format
= wined3dformat_from_ddrawformat(&desc
->u4
.ddpfPixelFormat
);
6094 if (wined3d_desc
.format
== WINED3DFMT_UNKNOWN
)
6096 WARN("Unsupported / unknown pixelformat.\n");
6098 return DDERR_INVALIDPIXELFORMAT
;
6101 /* No width or no height? Use the screen size. */
6102 if (!(desc
->dwFlags
& DDSD_WIDTH
) || !(desc
->dwFlags
& DDSD_HEIGHT
))
6104 if (!(desc
->ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
))
6106 WARN("No width / height specified.\n");
6108 return DDERR_INVALIDPARAMS
;
6111 desc
->dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
6112 desc
->dwWidth
= mode
.width
;
6113 desc
->dwHeight
= mode
.height
;
6116 if (!desc
->dwWidth
|| !desc
->dwHeight
)
6119 return DDERR_INVALIDPARAMS
;
6122 if (desc
->ddsCaps
.dwCaps
& DDSCAPS_FLIP
)
6123 desc
->ddsCaps
.dwCaps
|= DDSCAPS_FRONTBUFFER
;
6125 if (desc
->ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)
6127 /* The first surface is a front buffer, the back buffers are created
6129 desc
->ddsCaps
.dwCaps
|= DDSCAPS_VISIBLE
;
6130 if (ddraw
->cooperative_level
& DDSCL_EXCLUSIVE
)
6132 struct wined3d_swapchain_desc swapchain_desc
;
6134 wined3d_swapchain_get_desc(ddraw
->wined3d_swapchain
, &swapchain_desc
);
6135 swapchain_desc
.backbuffer_width
= mode
.width
;
6136 swapchain_desc
.backbuffer_height
= mode
.height
;
6137 swapchain_desc
.backbuffer_format
= mode
.format_id
;
6139 if (ddraw
->d3ddevice
)
6141 if (ddraw
->d3ddevice
->recording
)
6142 wined3d_stateblock_decref(ddraw
->d3ddevice
->recording
);
6143 ddraw
->d3ddevice
->recording
= NULL
;
6144 ddraw
->d3ddevice
->update_state
= ddraw
->d3ddevice
->state
;
6146 wined3d_stateblock_reset(ddraw
->state
);
6148 if (FAILED(hr
= wined3d_device_reset(ddraw
->wined3d_device
,
6149 &swapchain_desc
, NULL
, ddraw_reset_enum_callback
, TRUE
)))
6151 ERR("Failed to reset device.\n");
6153 return hr_ddraw_from_wined3d(hr
);
6156 wined3d_stateblock_set_render_state(ddraw
->state
, WINED3D_RS_ZENABLE
,
6157 !!swapchain_desc
.enable_auto_depth_stencil
);
6161 wined3d_desc
.multisample_type
= WINED3D_MULTISAMPLE_NONE
;
6162 wined3d_desc
.multisample_quality
= 0;
6163 wined3d_desc
.usage
= 0;
6164 wined3d_desc
.bind_flags
= 0;
6165 wined3d_desc
.access
= WINED3D_RESOURCE_ACCESS_GPU
| WINED3D_RESOURCE_ACCESS_MAP_R
| WINED3D_RESOURCE_ACCESS_MAP_W
;
6166 wined3d_desc
.width
= desc
->dwWidth
;
6167 wined3d_desc
.height
= desc
->dwHeight
;
6168 wined3d_desc
.depth
= 1;
6169 wined3d_desc
.size
= 0;
6171 if ((desc
->ddsCaps
.dwCaps
& DDSCAPS_3DDEVICE
) && (ddraw
->flags
& DDRAW_NO3D
))
6173 WARN("The application requests a 3D capable surface, but the ddraw object was created without 3D support.\n");
6174 /* Do not fail surface creation, only fail 3D device creation. */
6177 /* Mipmap count fixes */
6178 if (desc
->ddsCaps
.dwCaps
& DDSCAPS_MIPMAP
)
6180 if (desc
->ddsCaps
.dwCaps
& DDSCAPS_COMPLEX
)
6182 if (desc
->dwFlags
& DDSD_MIPMAPCOUNT
)
6184 /* Mipmap count is given, should not be 0. */
6185 if (!desc
->u2
.dwMipMapCount
)
6188 return DDERR_INVALIDPARAMS
;
6193 /* Undocumented feature: Create sublevels until either the
6194 * width or the height is 1. */
6196 desc
->u2
.dwMipMapCount
= wined3d_log2i(max(desc
->dwWidth
, desc
->dwHeight
)) + 1;
6198 desc
->u2
.dwMipMapCount
= wined3d_log2i(min(desc
->dwWidth
, desc
->dwHeight
)) + 1;
6203 desc
->u2
.dwMipMapCount
= 1;
6206 desc
->dwFlags
|= DDSD_MIPMAPCOUNT
;
6207 levels
= desc
->u2
.dwMipMapCount
;
6214 if (!(desc
->ddsCaps
.dwCaps
& (DDSCAPS_VIDEOMEMORY
| DDSCAPS_SYSTEMMEMORY
)))
6216 if (!(desc
->ddsCaps
.dwCaps2
& (DDSCAPS2_TEXTUREMANAGE
| DDSCAPS2_D3DTEXTUREMANAGE
)))
6218 unsigned int bind_flags
= 0;
6221 if (desc
->ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
6223 usage
|= WINED3DUSAGE_LEGACY_CUBEMAP
;
6224 bind_flags
|= WINED3D_BIND_SHADER_RESOURCE
;
6226 else if (desc
->ddsCaps
.dwCaps
& DDSCAPS_TEXTURE
)
6228 bind_flags
|= WINED3D_BIND_SHADER_RESOURCE
;
6231 if (desc
->ddsCaps
.dwCaps
& DDSCAPS_ZBUFFER
)
6232 bind_flags
|= WINED3D_BIND_DEPTH_STENCIL
;
6233 else if (desc
->ddsCaps
.dwCaps
& DDSCAPS_3DDEVICE
)
6234 bind_flags
|= WINED3D_BIND_RENDER_TARGET
;
6236 if (!(ddraw
->flags
& DDRAW_NO3D
) && SUCCEEDED(hr
= wined3d_check_device_format(ddraw
->wined3d
,
6237 ddraw
->wined3d_adapter
, WINED3D_DEVICE_TYPE_HAL
, mode
.format_id
,
6238 usage
, bind_flags
, WINED3D_RTYPE_TEXTURE_2D
, wined3d_desc
.format
)))
6240 desc
->ddsCaps
.dwCaps
|= DDSCAPS_VIDEOMEMORY
;
6244 desc
->ddsCaps
.dwCaps
|= DDSCAPS_SYSTEMMEMORY
;
6245 sysmem_fallback
= TRUE
;
6248 else if (!(desc
->ddsCaps
.dwCaps
& DDSCAPS_TEXTURE
))
6250 /* Tests show surfaces without memory flags get these flags added
6251 * right after creation. */
6252 desc
->ddsCaps
.dwCaps
|= DDSCAPS_LOCALVIDMEM
| DDSCAPS_VIDEOMEMORY
;
6256 if ((desc
->ddsCaps
.dwCaps
& (DDSCAPS_OVERLAY
| DDSCAPS_SYSTEMMEMORY
))
6257 == (DDSCAPS_OVERLAY
| DDSCAPS_SYSTEMMEMORY
))
6259 WARN("System memory overlays are not allowed.\n");
6261 return DDERR_NOOVERLAYHW
;
6264 if (desc
->ddsCaps
.dwCaps
& DDSCAPS_SYSTEMMEMORY
)
6266 wined3d_desc
.access
= WINED3D_RESOURCE_ACCESS_CPU
6267 | WINED3D_RESOURCE_ACCESS_MAP_R
| WINED3D_RESOURCE_ACCESS_MAP_W
;
6271 if (!(ddraw
->flags
& DDRAW_NO3D
))
6273 if (desc
->ddsCaps
.dwCaps
& DDSCAPS_TEXTURE
)
6274 wined3d_desc
.bind_flags
|= WINED3D_BIND_SHADER_RESOURCE
;
6275 if (desc
->ddsCaps
.dwCaps
& DDSCAPS_ZBUFFER
)
6276 wined3d_desc
.bind_flags
|= WINED3D_BIND_DEPTH_STENCIL
;
6277 else if (desc
->ddsCaps
.dwCaps
& DDSCAPS_3DDEVICE
)
6278 wined3d_desc
.bind_flags
|= WINED3D_BIND_RENDER_TARGET
;
6281 if (desc
->ddsCaps
.dwCaps2
& (DDSCAPS2_TEXTUREMANAGE
| DDSCAPS2_D3DTEXTUREMANAGE
))
6283 wined3d_desc
.bind_flags
&= ~WINED3D_BIND_RENDER_TARGET
;
6284 wined3d_desc
.access
= WINED3D_RESOURCE_ACCESS_GPU
| WINED3D_RESOURCE_ACCESS_CPU
6285 | WINED3D_RESOURCE_ACCESS_MAP_R
| WINED3D_RESOURCE_ACCESS_MAP_W
;
6286 /* Managed textures have the system memory flag set. */
6287 desc
->ddsCaps
.dwCaps
|= DDSCAPS_SYSTEMMEMORY
;
6289 else if (desc
->ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
)
6291 /* Videomemory adds localvidmem. This is mutually exclusive with
6292 * systemmemory and texturemanage. */
6293 desc
->ddsCaps
.dwCaps
|= DDSCAPS_LOCALVIDMEM
;
6294 /* Dynamic resources can't be written by the GPU. */
6295 if (!(wined3d_desc
.bind_flags
& (WINED3D_BIND_RENDER_TARGET
| WINED3D_BIND_DEPTH_STENCIL
)))
6296 wined3d_desc
.usage
|= WINED3DUSAGE_DYNAMIC
;
6300 if (desc
->dwFlags
& DDSD_LPSURFACE
)
6302 if (wined3d_desc
.access
& WINED3D_RESOURCE_ACCESS_GPU
)
6304 WARN("User memory surfaces should not be GPU accessible.\n");
6306 return DDERR_INVALIDCAPS
;
6311 WARN("User memory surfaces not supported before version 4.\n");
6313 return DDERR_INVALIDPARAMS
;
6316 if (!desc
->lpSurface
)
6318 WARN("NULL surface memory pointer specified.\n");
6320 return DDERR_INVALIDPARAMS
;
6323 if (format_is_compressed(&desc
->u4
.ddpfPixelFormat
))
6325 if (version
!= 4 && (desc
->dwFlags
& DDSD_PITCH
))
6327 WARN("Pitch specified on a compressed user memory surface.\n");
6329 return DDERR_INVALIDPARAMS
;
6332 if (!(desc
->dwFlags
& (DDSD_LINEARSIZE
| DDSD_PITCH
)))
6334 WARN("Compressed user memory surfaces should explicitly specify the linear size.\n");
6336 return DDERR_INVALIDPARAMS
;
6339 if ((desc
->dwFlags
& DDSD_LINEARSIZE
)
6340 && desc
->u1
.dwLinearSize
< wined3d_calculate_format_pitch(ddraw
->wined3d_adapter
,
6341 wined3d_desc
.format
, wined3d_desc
.width
) * ((desc
->dwHeight
+ 3) / 4))
6343 WARN("Invalid linear size %u specified.\n", desc
->u1
.dwLinearSize
);
6345 return DDERR_INVALIDPARAMS
;
6350 if (!(desc
->dwFlags
& DDSD_PITCH
))
6352 WARN("User memory surfaces should explicitly specify the pitch.\n");
6354 return DDERR_INVALIDPARAMS
;
6357 if (desc
->u1
.lPitch
< wined3d_calculate_format_pitch(ddraw
->wined3d_adapter
,
6358 wined3d_desc
.format
, wined3d_desc
.width
) || desc
->u1
.lPitch
& 3)
6360 WARN("Invalid pitch %u specified.\n", desc
->u1
.lPitch
);
6362 return DDERR_INVALIDPARAMS
;
6365 pitch
= desc
->u1
.lPitch
;
6369 if (((desc
->dwFlags
& DDSD_CKDESTOVERLAY
)
6370 && desc
->u3
.ddckCKDestOverlay
.dwColorSpaceLowValue
!= desc
->u3
.ddckCKDestOverlay
.dwColorSpaceHighValue
)
6371 || ((desc
->dwFlags
& DDSD_CKDESTBLT
)
6372 && desc
->ddckCKDestBlt
.dwColorSpaceLowValue
!= desc
->ddckCKDestBlt
.dwColorSpaceHighValue
)
6373 || ((desc
->dwFlags
& DDSD_CKSRCOVERLAY
)
6374 && desc
->ddckCKSrcOverlay
.dwColorSpaceLowValue
!= desc
->ddckCKSrcOverlay
.dwColorSpaceHighValue
)
6375 || ((desc
->dwFlags
& DDSD_CKSRCBLT
)
6376 && desc
->ddckCKSrcBlt
.dwColorSpaceLowValue
!= desc
->ddckCKSrcBlt
.dwColorSpaceHighValue
))
6378 WARN("Range color keys not supported, returning DDERR_NOCOLORKEYHW.\n");
6380 return DDERR_NOCOLORKEYHW
;
6383 if ((ddraw
->flags
& DDRAW_NO3D
) && (desc
->ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
))
6385 WARN("Video memory surfaces not supported without 3D support.\n");
6387 return DDERR_NODIRECTDRAWHW
;
6390 if (desc
->ddsCaps
.dwCaps
& (DDSCAPS_OVERLAY
))
6391 wined3d_desc
.usage
|= WINED3DUSAGE_OVERLAY
;
6393 if (desc
->ddsCaps
.dwCaps
& DDSCAPS_OWNDC
)
6394 wined3d_desc
.usage
|= WINED3DUSAGE_OWNDC
;
6396 if (desc
->ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
6398 wined3d_desc
.usage
|= WINED3DUSAGE_LEGACY_CUBEMAP
;
6402 /* Some applications assume surfaces will always be mapped at the same
6403 * address. Some of those also assume that this address is valid even when
6404 * the surface isn't mapped, and that updates done this way will be
6405 * visible on the screen. The game Nox is such an application,
6406 * Commandos: Behind Enemy Lines is another. Setting
6407 * WINED3D_TEXTURE_CREATE_GET_DC_LENIENT will ensure this. */
6408 if (FAILED(hr
= wined3d_texture_create(ddraw
->wined3d_device
, &wined3d_desc
, layers
, levels
,
6409 WINED3D_TEXTURE_CREATE_GET_DC_LENIENT
, NULL
, texture
,
6410 &ddraw_texture_wined3d_parent_ops
, &wined3d_texture
)))
6412 WARN("Failed to create wined3d texture, hr %#x.\n", hr
);
6414 return hr_ddraw_from_wined3d(hr
);
6417 root
= wined3d_texture_get_sub_resource_parent(wined3d_texture
, 0);
6418 wined3d_texture_decref(wined3d_texture
);
6419 root
->is_complex_root
= TRUE
;
6420 root
->sysmem_fallback
= sysmem_fallback
;
6421 texture
->root
= root
;
6422 wined3d_device_incref(texture
->wined3d_device
= ddraw
->wined3d_device
);
6424 if (desc
->dwFlags
& DDSD_CKDESTOVERLAY
)
6425 wined3d_texture_set_color_key(wined3d_texture
, DDCKEY_DESTOVERLAY
,
6426 (struct wined3d_color_key
*)&desc
->u3
.ddckCKDestOverlay
);
6427 if (desc
->dwFlags
& DDSD_CKDESTBLT
)
6428 wined3d_texture_set_color_key(wined3d_texture
, DDCKEY_DESTBLT
,
6429 (struct wined3d_color_key
*)&desc
->ddckCKDestBlt
);
6430 if (desc
->dwFlags
& DDSD_CKSRCOVERLAY
)
6431 wined3d_texture_set_color_key(wined3d_texture
, DDCKEY_SRCOVERLAY
,
6432 (struct wined3d_color_key
*)&desc
->ddckCKSrcOverlay
);
6433 if (desc
->dwFlags
& DDSD_CKSRCBLT
)
6434 wined3d_texture_set_color_key(wined3d_texture
, DDCKEY_SRCBLT
,
6435 (struct wined3d_color_key
*)&desc
->ddckCKSrcBlt
);
6437 for (i
= 0; i
< layers
; ++i
)
6439 attach
= &root
->complex_array
[layers
- 1 - i
];
6441 for (j
= 0; j
< levels
; ++j
)
6443 mip
= wined3d_texture_get_sub_resource_parent(wined3d_texture
, i
* levels
+ j
);
6444 mip
->sysmem_fallback
= sysmem_fallback
;
6445 mip_desc
= &mip
->surface_desc
;
6446 if (desc
->ddsCaps
.dwCaps
& DDSCAPS_MIPMAP
)
6447 mip_desc
->u2
.dwMipMapCount
= levels
- j
;
6451 wined3d_texture_get_sub_resource_desc(wined3d_texture
, i
* levels
+ j
, &wined3d_mip_desc
);
6452 mip_desc
->dwWidth
= wined3d_mip_desc
.width
;
6453 mip_desc
->dwHeight
= wined3d_mip_desc
.height
;
6455 mip_desc
->ddsCaps
.dwCaps2
|= DDSCAPS2_MIPMAPSUBLEVEL
;
6459 mip_desc
->ddsCaps
.dwCaps2
&= ~DDSCAPS2_MIPMAPSUBLEVEL
;
6462 if (mip_desc
->ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
6464 mip_desc
->ddsCaps
.dwCaps2
&= ~DDSCAPS2_CUBEMAP_ALLFACES
;
6468 case WINED3D_CUBEMAP_FACE_POSITIVE_X
:
6469 mip_desc
->ddsCaps
.dwCaps2
|= DDSCAPS2_CUBEMAP_POSITIVEX
;
6471 case WINED3D_CUBEMAP_FACE_NEGATIVE_X
:
6472 mip_desc
->ddsCaps
.dwCaps2
|= DDSCAPS2_CUBEMAP_NEGATIVEX
;
6474 case WINED3D_CUBEMAP_FACE_POSITIVE_Y
:
6475 mip_desc
->ddsCaps
.dwCaps2
|= DDSCAPS2_CUBEMAP_POSITIVEY
;
6477 case WINED3D_CUBEMAP_FACE_NEGATIVE_Y
:
6478 mip_desc
->ddsCaps
.dwCaps2
|= DDSCAPS2_CUBEMAP_NEGATIVEY
;
6480 case WINED3D_CUBEMAP_FACE_POSITIVE_Z
:
6481 mip_desc
->ddsCaps
.dwCaps2
|= DDSCAPS2_CUBEMAP_POSITIVEZ
;
6483 case WINED3D_CUBEMAP_FACE_NEGATIVE_Z
:
6484 mip_desc
->ddsCaps
.dwCaps2
|= DDSCAPS2_CUBEMAP_NEGATIVEZ
;
6494 attach
= &mip
->complex_array
[0];
6498 if ((desc
->dwFlags
& DDSD_LPSURFACE
) && FAILED(hr
= wined3d_texture_update_desc(wined3d_texture
, 0,
6499 wined3d_desc
.width
, wined3d_desc
.height
, wined3d_desc
.format
,
6500 WINED3D_MULTISAMPLE_NONE
, 0, desc
->lpSurface
, pitch
)))
6502 ERR("Failed to set surface memory, hr %#x.\n", hr
);
6506 reserve_memory
= !(desc
->dwFlags
& DDSD_LPSURFACE
)
6507 && desc
->ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
6508 && wined3d_display_mode_format
.u1
.dwRGBBitCount
<= 16;
6510 if (reserve_memory
&& FAILED(hr
= ddraw_surface_reserve_memory(wined3d_texture
)))
6512 ERR("Failed to reserve surface memory, hr %#x.\n", hr
);
6516 if (desc
->dwFlags
& DDSD_BACKBUFFERCOUNT
)
6518 unsigned int count
= desc
->u5
.dwBackBufferCount
;
6519 struct ddraw_surface
*last
= root
;
6521 attach
= &last
->complex_array
[0];
6522 for (i
= 0; i
< count
; ++i
)
6524 if (!(texture
= heap_alloc(sizeof(*texture
))))
6530 texture
->texture_memory
= NULL
;
6531 texture
->version
= version
;
6532 texture
->surface_desc
= root
->surface_desc
;
6533 desc
= &texture
->surface_desc
;
6535 /* Only one surface in the flipping chain is a back buffer, one is
6536 * a front buffer, the others are just flippable surfaces. */
6537 desc
->ddsCaps
.dwCaps
&= ~(DDSCAPS_VISIBLE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_FRONTBUFFER
6538 | DDSCAPS_BACKBUFFER
);
6540 desc
->ddsCaps
.dwCaps
|= DDSCAPS_BACKBUFFER
;
6541 desc
->u5
.dwBackBufferCount
= 0;
6543 if (FAILED(hr
= wined3d_texture_create(ddraw
->wined3d_device
, &wined3d_desc
, 1, 1,
6544 WINED3D_TEXTURE_CREATE_GET_DC_LENIENT
, NULL
, texture
,
6545 &ddraw_texture_wined3d_parent_ops
, &wined3d_texture
)))
6548 hr
= hr_ddraw_from_wined3d(hr
);
6552 last
= wined3d_texture_get_sub_resource_parent(wined3d_texture
, 0);
6553 last
->sysmem_fallback
= sysmem_fallback
;
6554 wined3d_texture_decref(wined3d_texture
);
6555 texture
->root
= last
;
6556 wined3d_device_incref(texture
->wined3d_device
= ddraw
->wined3d_device
);
6558 if (desc
->dwFlags
& DDSD_CKDESTOVERLAY
)
6559 wined3d_texture_set_color_key(wined3d_texture
, DDCKEY_DESTOVERLAY
,
6560 (struct wined3d_color_key
*)&desc
->u3
.ddckCKDestOverlay
);
6561 if (desc
->dwFlags
& DDSD_CKDESTBLT
)
6562 wined3d_texture_set_color_key(wined3d_texture
, DDCKEY_DESTBLT
,
6563 (struct wined3d_color_key
*)&desc
->ddckCKDestBlt
);
6564 if (desc
->dwFlags
& DDSD_CKSRCOVERLAY
)
6565 wined3d_texture_set_color_key(wined3d_texture
, DDCKEY_SRCOVERLAY
,
6566 (struct wined3d_color_key
*)&desc
->ddckCKSrcOverlay
);
6567 if (desc
->dwFlags
& DDSD_CKSRCBLT
)
6568 wined3d_texture_set_color_key(wined3d_texture
, DDCKEY_SRCBLT
,
6569 (struct wined3d_color_key
*)&desc
->ddckCKSrcBlt
);
6571 if (reserve_memory
&& FAILED(hr
= ddraw_surface_reserve_memory(wined3d_texture
)))
6573 hr
= hr_ddraw_from_wined3d(hr
);
6578 attach
= &last
->complex_array
[0];
6583 if (surface_desc
->ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)
6585 ddraw
->primary
= root
;
6586 ddraw
->gdi_surface
= root
->wined3d_texture
;
6594 IDirectDrawSurface7_Release(&root
->IDirectDrawSurface7_iface
);
6595 else if (version
== 4)
6596 IDirectDrawSurface4_Release(&root
->IDirectDrawSurface4_iface
);
6598 IDirectDrawSurface_Release(&root
->IDirectDrawSurface_iface
);
6603 void ddraw_surface_init(struct ddraw_surface
*surface
, struct ddraw
*ddraw
,
6604 struct wined3d_texture
*wined3d_texture
, unsigned int sub_resource_idx
,
6605 const struct wined3d_parent_ops
**parent_ops
)
6607 struct ddraw_texture
*texture
= wined3d_texture_get_parent(wined3d_texture
);
6608 unsigned int texture_level
, row_pitch
, slice_pitch
;
6609 DDSURFACEDESC2
*desc
= &surface
->surface_desc
;
6610 unsigned int version
= texture
->version
;
6612 surface
->IDirectDrawSurface7_iface
.lpVtbl
= &ddraw_surface7_vtbl
;
6613 surface
->IDirectDrawSurface4_iface
.lpVtbl
= &ddraw_surface4_vtbl
;
6614 surface
->IDirectDrawSurface3_iface
.lpVtbl
= &ddraw_surface3_vtbl
;
6615 surface
->IDirectDrawSurface2_iface
.lpVtbl
= &ddraw_surface2_vtbl
;
6616 surface
->IDirectDrawSurface_iface
.lpVtbl
= &ddraw_surface1_vtbl
;
6617 surface
->IDirectDrawGammaControl_iface
.lpVtbl
= &ddraw_gamma_control_vtbl
;
6618 surface
->IDirect3DTexture2_iface
.lpVtbl
= &d3d_texture2_vtbl
;
6619 surface
->IDirect3DTexture_iface
.lpVtbl
= &d3d_texture1_vtbl
;
6620 surface
->iface_count
= 1;
6621 surface
->version
= version
;
6622 surface
->ddraw
= ddraw
;
6627 surface
->texture_outer
= (IUnknown
*)&surface
->IDirectDrawSurface7_iface
;
6629 else if (version
== 4)
6632 surface
->texture_outer
= (IUnknown
*)&surface
->IDirectDrawSurface4_iface
;
6637 surface
->texture_outer
= (IUnknown
*)&surface
->IDirectDrawSurface_iface
;
6640 *desc
= texture
->surface_desc
;
6641 surface
->first_attached
= surface
;
6643 texture_level
= desc
->ddsCaps
.dwCaps
& DDSCAPS_MIPMAP
? sub_resource_idx
% desc
->u2
.dwMipMapCount
: 0;
6644 wined3d_texture_get_pitch(wined3d_texture
, texture_level
, &row_pitch
, &slice_pitch
);
6645 if (format_is_compressed(&desc
->u4
.ddpfPixelFormat
))
6647 if (desc
->dwFlags
& DDSD_LPSURFACE
)
6648 desc
->u1
.dwLinearSize
= ~0u;
6650 desc
->u1
.dwLinearSize
= slice_pitch
;
6651 desc
->dwFlags
|= DDSD_LINEARSIZE
;
6652 desc
->dwFlags
&= ~(DDSD_LPSURFACE
| DDSD_PITCH
);
6656 if (!(desc
->dwFlags
& DDSD_LPSURFACE
))
6657 desc
->u1
.lPitch
= row_pitch
;
6658 desc
->dwFlags
|= DDSD_PITCH
;
6659 desc
->dwFlags
&= ~(DDSD_LPSURFACE
| DDSD_LINEARSIZE
);
6661 desc
->lpSurface
= NULL
;
6663 wined3d_texture_incref(surface
->wined3d_texture
= wined3d_texture
);
6664 surface
->sub_resource_idx
= sub_resource_idx
;
6665 *parent_ops
= &ddraw_surface_wined3d_parent_ops
;
6667 wined3d_private_store_init(&surface
->private_store
);
6670 static void STDMETHODCALLTYPE
view_wined3d_object_destroyed(void *parent
)
6672 struct ddraw_surface
*surface
= parent
;
6674 /* If the surface reference count drops to zero, we release our reference
6675 * to the view, but don't clear the pointer yet, in case e.g. a
6676 * GetRenderTarget() call brings the surface back before the view is
6677 * actually destroyed. When the view is destroyed, we need to clear the
6678 * pointer, or a subsequent surface AddRef() would reference it again.
6680 * This is safe because as long as the view still has a reference to the
6681 * texture, the surface is also still alive, and we're called before the
6682 * view releases that reference. */
6683 surface
->wined3d_rtv
= NULL
;
6686 static const struct wined3d_parent_ops ddraw_view_wined3d_parent_ops
=
6688 view_wined3d_object_destroyed
,
6691 struct wined3d_rendertarget_view
*ddraw_surface_get_rendertarget_view(struct ddraw_surface
*surface
)
6695 if (surface
->wined3d_rtv
)
6696 return surface
->wined3d_rtv
;
6698 if (FAILED(hr
= wined3d_rendertarget_view_create_from_sub_resource(surface
->wined3d_texture
,
6699 surface
->sub_resource_idx
, surface
, &ddraw_view_wined3d_parent_ops
, &surface
->wined3d_rtv
)))
6701 ERR("Failed to create rendertarget view, hr %#x.\n", hr
);
6705 return surface
->wined3d_rtv
;