Out of what will probably end up being 6 total parts.
-- v2: ddraw: Make ddraw_surface_init() static. ddraw: Move sub-resource surface creation to ddraw_texture_init().
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/ddraw/surface.c | 94 +++++++++++++++++++------------------------- 1 file changed, 41 insertions(+), 53 deletions(-)
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index 4d8812cf106..eaa036b21bf 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -1325,6 +1325,36 @@ static unsigned int ddraw_swap_interval_from_flags(DWORD flags) } }
+static void ddraw_texture_rename_to(struct ddraw_texture *dst_texture, struct wined3d_texture *wined3d_texture, + struct wined3d_texture *draw_texture, struct wined3d_rendertarget_view *rtv, void *texture_memory) +{ + struct ddraw_surface *dst_surface = dst_texture->root; + struct wined3d_rendertarget_view *current_rtv; + + /* We don't have to worry about potential texture bindings, since + * flippable surfaces can never be textures. */ + + current_rtv = wined3d_device_context_get_rendertarget_view(dst_surface->ddraw->immediate_context, 0); + if (current_rtv == dst_surface->wined3d_rtv) + wined3d_device_context_set_rendertarget_views(dst_surface->ddraw->immediate_context, 0, 1, &rtv, FALSE); + wined3d_rendertarget_view_set_parent(rtv, dst_surface); + dst_surface->wined3d_rtv = rtv; + + if (dst_surface->sub_resource_idx) + ERR("Invalid sub-resource index %u for surface %p.\n", dst_surface->sub_resource_idx, dst_surface); + + wined3d_texture_set_sub_resource_parent(wined3d_texture, 0, dst_surface); + if (draw_texture) + wined3d_texture_set_sub_resource_parent(draw_texture, 0, dst_surface); + wined3d_resource_set_parent(wined3d_texture_get_resource(wined3d_texture), dst_texture); + if (draw_texture) + wined3d_resource_set_parent(wined3d_texture_get_resource(draw_texture), dst_texture); + dst_surface->wined3d_texture = wined3d_texture; + dst_surface->draw_texture = draw_texture; + + dst_texture->texture_memory = texture_memory; +} + /* FRAPS hooks IDirectDrawSurface::Flip and expects the version 1 method to be called when the * game uses later interfaces. */ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface1_Flip(IDirectDrawSurface *iface, @@ -1333,9 +1363,9 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface1_Flip(IDirectDrawSurface * struct ddraw_surface *dst_impl = impl_from_IDirectDrawSurface(iface); struct ddraw_surface *src_impl = unsafe_impl_from_IDirectDrawSurface(src); struct ddraw_texture *dst_ddraw_texture, *src_ddraw_texture; - struct wined3d_rendertarget_view *tmp_rtv, *src_rtv, *rtv; - DDSCAPS caps = {DDSCAPS_FLIP}; struct wined3d_texture *texture, *draw_texture; + struct wined3d_rendertarget_view *tmp_rtv; + DDSCAPS caps = {DDSCAPS_FLIP}; IDirectDrawSurface *current; void *texture_memory; HRESULT hr; @@ -1359,10 +1389,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface1_Flip(IDirectDrawSurface * }
tmp_rtv = ddraw_surface_get_rendertarget_view(dst_impl); - if (dst_impl->sub_resource_idx) - ERR("Invalid sub-resource index %u on surface %p.\n", dst_impl->sub_resource_idx, dst_impl); texture = dst_impl->wined3d_texture; - rtv = wined3d_device_context_get_rendertarget_view(dst_impl->ddraw->immediate_context, 0); dst_ddraw_texture = wined3d_texture_get_parent(dst_impl->wined3d_texture); texture_memory = dst_ddraw_texture->texture_memory; draw_texture = dst_impl->draw_texture; @@ -1386,24 +1413,12 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface1_Flip(IDirectDrawSurface * } }
- src_rtv = ddraw_surface_get_rendertarget_view(src_impl); - if (rtv == dst_impl->wined3d_rtv) - wined3d_device_context_set_rendertarget_views(dst_impl->ddraw->immediate_context, 0, 1, &src_rtv, FALSE); - wined3d_rendertarget_view_set_parent(src_rtv, dst_impl); - dst_impl->wined3d_rtv = src_rtv; - wined3d_texture_set_sub_resource_parent(src_impl->wined3d_texture, 0, dst_impl); - if (src_impl->draw_texture) - wined3d_texture_set_sub_resource_parent(src_impl->draw_texture, 0, dst_impl); src_ddraw_texture = wined3d_texture_get_parent(src_impl->wined3d_texture); - dst_ddraw_texture->texture_memory = src_ddraw_texture->texture_memory; - wined3d_resource_set_parent(wined3d_texture_get_resource(src_impl->wined3d_texture), dst_ddraw_texture); - if (src_impl->draw_texture) - wined3d_resource_set_parent(wined3d_texture_get_resource(src_impl->draw_texture), dst_ddraw_texture); + + ddraw_texture_rename_to(dst_ddraw_texture, src_impl->wined3d_texture, src_impl->draw_texture, + ddraw_surface_get_rendertarget_view(src_impl), src_ddraw_texture->texture_memory); + dst_ddraw_texture = src_ddraw_texture; - if (src_impl->sub_resource_idx) - ERR("Invalid sub-resource index %u on surface %p.\n", src_impl->sub_resource_idx, src_impl); - dst_impl->wined3d_texture = src_impl->wined3d_texture; - dst_impl->draw_texture = src_impl->draw_texture; } else { @@ -1423,44 +1438,17 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface1_Flip(IDirectDrawSurface * }
src_impl = impl_from_IDirectDrawSurface(current); - src_rtv = ddraw_surface_get_rendertarget_view(src_impl); - if (rtv == dst_impl->wined3d_rtv) - wined3d_device_context_set_rendertarget_views(dst_impl->ddraw->immediate_context, - 0, 1, &src_rtv, FALSE); - wined3d_rendertarget_view_set_parent(src_rtv, dst_impl); - dst_impl->wined3d_rtv = src_rtv; - wined3d_texture_set_sub_resource_parent(src_impl->wined3d_texture, 0, dst_impl); - if (src_impl->draw_texture) - wined3d_texture_set_sub_resource_parent(src_impl->draw_texture, 0, dst_impl); src_ddraw_texture = wined3d_texture_get_parent(src_impl->wined3d_texture); - dst_ddraw_texture->texture_memory = src_ddraw_texture->texture_memory; - wined3d_resource_set_parent(wined3d_texture_get_resource(src_impl->wined3d_texture), dst_ddraw_texture); - if (src_impl->draw_texture) - wined3d_resource_set_parent(wined3d_texture_get_resource(src_impl->draw_texture), dst_ddraw_texture); + + ddraw_texture_rename_to(dst_ddraw_texture, src_impl->wined3d_texture, src_impl->draw_texture, + ddraw_surface_get_rendertarget_view(src_impl), src_ddraw_texture->texture_memory); + dst_ddraw_texture = src_ddraw_texture; - if (src_impl->sub_resource_idx) - ERR("Invalid sub-resource index %u on surface %p.\n", src_impl->sub_resource_idx, src_impl); - dst_impl->wined3d_texture = src_impl->wined3d_texture; - dst_impl->draw_texture = src_impl->draw_texture; dst_impl = src_impl; } }
- /* We don't have to worry about potential texture bindings, since - * flippable surfaces can never be textures. */ - if (rtv == src_impl->wined3d_rtv) - wined3d_device_context_set_rendertarget_views(dst_impl->ddraw->immediate_context, 0, 1, &tmp_rtv, FALSE); - wined3d_rendertarget_view_set_parent(tmp_rtv, src_impl); - src_impl->wined3d_rtv = tmp_rtv; - wined3d_texture_set_sub_resource_parent(texture, 0, src_impl); - if (draw_texture) - wined3d_texture_set_sub_resource_parent(draw_texture, 0, src_impl); - dst_ddraw_texture->texture_memory = texture_memory; - wined3d_resource_set_parent(wined3d_texture_get_resource(texture), dst_ddraw_texture); - if (draw_texture) - wined3d_resource_set_parent(wined3d_texture_get_resource(draw_texture), dst_ddraw_texture); - src_impl->wined3d_texture = texture; - src_impl->draw_texture = draw_texture; + ddraw_texture_rename_to(dst_ddraw_texture, texture, draw_texture, tmp_rtv, texture_memory);
if (flags & ~(DDFLIP_NOVSYNC | DDFLIP_INTERVAL2 | DDFLIP_INTERVAL3 | DDFLIP_INTERVAL4)) {
From: Zebediah Figura zfigura@codeweavers.com
So that we can allow setting the sub resource and parent ops not from the texture_sub_resource_created() callback, and also that we can "detach" a wined3d surface from ddraw after creating it, so that we can recreate the backing wined3d texture, viz. in SetSurfaceDesc(). --- dlls/ddraw/surface.c | 15 ++++++++++++--- dlls/wined3d/texture.c | 3 ++- dlls/wined3d/wined3d.spec | 2 +- include/wine/wined3d.h | 2 +- 4 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index eaa036b21bf..a881572e027 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -29,6 +29,8 @@ WINE_DECLARE_DEBUG_CHANNEL(fps); static struct ddraw_surface *unsafe_impl_from_IDirectDrawSurface2(IDirectDrawSurface2 *iface); static struct ddraw_surface *unsafe_impl_from_IDirectDrawSurface3(IDirectDrawSurface3 *iface);
+static const struct wined3d_parent_ops ddraw_surface_wined3d_parent_ops; + static inline struct ddraw_surface *impl_from_IDirectDrawGammaControl(IDirectDrawGammaControl *iface) { return CONTAINING_RECORD(iface, struct ddraw_surface, IDirectDrawGammaControl_iface); @@ -1343,9 +1345,16 @@ static void ddraw_texture_rename_to(struct ddraw_texture *dst_texture, struct wi if (dst_surface->sub_resource_idx) ERR("Invalid sub-resource index %u for surface %p.\n", dst_surface->sub_resource_idx, dst_surface);
- wined3d_texture_set_sub_resource_parent(wined3d_texture, 0, dst_surface); if (draw_texture) - wined3d_texture_set_sub_resource_parent(draw_texture, 0, dst_surface); + { + wined3d_texture_set_sub_resource_parent(draw_texture, 0, dst_surface, &ddraw_surface_wined3d_parent_ops); + wined3d_texture_set_sub_resource_parent(wined3d_texture, 0, dst_surface, &ddraw_null_wined3d_parent_ops); + } + else + { + wined3d_texture_set_sub_resource_parent(wined3d_texture, 0, dst_surface, &ddraw_surface_wined3d_parent_ops); + } + wined3d_resource_set_parent(wined3d_texture_get_resource(wined3d_texture), dst_texture); if (draw_texture) wined3d_resource_set_parent(wined3d_texture_get_resource(draw_texture), dst_texture); @@ -6132,7 +6141,7 @@ static HRESULT ddraw_texture_init(struct ddraw_texture *texture, struct ddraw *d assert(parent->wined3d_texture == draw_texture); parent->draw_texture = draw_texture; parent->wined3d_texture = wined3d_texture; - wined3d_texture_set_sub_resource_parent(wined3d_texture, i, parent); + wined3d_texture_set_sub_resource_parent(wined3d_texture, i, parent, &ddraw_null_wined3d_parent_ops); wined3d_texture_incref(wined3d_texture); } } diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 33b938ad460..c6e80f45766 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -4329,7 +4329,7 @@ void * CDECL wined3d_texture_get_sub_resource_parent(struct wined3d_texture *tex }
void CDECL wined3d_texture_set_sub_resource_parent(struct wined3d_texture *texture, - unsigned int sub_resource_idx, void *parent) + unsigned int sub_resource_idx, void *parent, const struct wined3d_parent_ops *parent_ops) { TRACE("texture %p, sub_resource_idx %u, parent %p.\n", texture, sub_resource_idx, parent);
@@ -4337,6 +4337,7 @@ void CDECL wined3d_texture_set_sub_resource_parent(struct wined3d_texture *textu return;
texture->sub_resources[sub_resource_idx].parent = parent; + texture->sub_resources[sub_resource_idx].parent_ops = parent_ops; }
HRESULT CDECL wined3d_texture_get_sub_resource_desc(const struct wined3d_texture *texture, diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 2980568d94e..0f7c7938c39 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -307,7 +307,7 @@ @ cdecl wined3d_texture_set_color_key(ptr long ptr) @ cdecl wined3d_texture_set_lod(ptr long) @ cdecl wined3d_texture_set_overlay_position(ptr long long long) -@ cdecl wined3d_texture_set_sub_resource_parent(ptr long ptr) +@ cdecl wined3d_texture_set_sub_resource_parent(ptr long ptr ptr) @ cdecl wined3d_texture_update_desc(ptr long long long long long long ptr long) @ cdecl wined3d_texture_update_overlay(ptr long ptr ptr long ptr long)
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 5d8a1156b21..4535892fb5f 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2866,7 +2866,7 @@ unsigned int __cdecl wined3d_texture_set_lod(struct wined3d_texture *texture, un HRESULT __cdecl wined3d_texture_set_overlay_position(struct wined3d_texture *texture, unsigned int sub_resource_idx, LONG x, LONG y); void __cdecl wined3d_texture_set_sub_resource_parent(struct wined3d_texture *texture, - unsigned int sub_resource_idx, void *parent); + unsigned int sub_resource_idx, void *parent, const struct wined3d_parent_ops *parent_ops); HRESULT __cdecl wined3d_texture_update_desc(struct wined3d_texture *texture, unsigned int sub_resource_idx, UINT width, UINT height, enum wined3d_format_id format_id, enum wined3d_multisample_type multisample_type, UINT multisample_quality,
From: Zebediah Figura zfigura@codeweavers.com
So that we can "detach" a wined3d surface from ddraw after creating it, in turn so that we can recreate the backing wined3d texture for a surface, namely for SetSurfaceDesc(). --- dlls/ddraw/surface.c | 14 ++++++++++---- dlls/wined3d/resource.c | 3 ++- dlls/wined3d/wined3d.spec | 2 +- include/wine/wined3d.h | 3 ++- 4 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index a881572e027..3caee53ee73 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -30,6 +30,7 @@ static struct ddraw_surface *unsafe_impl_from_IDirectDrawSurface2(IDirectDrawSur static struct ddraw_surface *unsafe_impl_from_IDirectDrawSurface3(IDirectDrawSurface3 *iface);
static const struct wined3d_parent_ops ddraw_surface_wined3d_parent_ops; +static const struct wined3d_parent_ops ddraw_texture_wined3d_parent_ops;
static inline struct ddraw_surface *impl_from_IDirectDrawGammaControl(IDirectDrawGammaControl *iface) { @@ -1349,15 +1350,18 @@ static void ddraw_texture_rename_to(struct ddraw_texture *dst_texture, struct wi { wined3d_texture_set_sub_resource_parent(draw_texture, 0, dst_surface, &ddraw_surface_wined3d_parent_ops); wined3d_texture_set_sub_resource_parent(wined3d_texture, 0, dst_surface, &ddraw_null_wined3d_parent_ops); + wined3d_resource_set_parent(wined3d_texture_get_resource(draw_texture), + dst_texture, &ddraw_texture_wined3d_parent_ops); + wined3d_resource_set_parent(wined3d_texture_get_resource(wined3d_texture), + dst_texture, &ddraw_null_wined3d_parent_ops); } else { wined3d_texture_set_sub_resource_parent(wined3d_texture, 0, dst_surface, &ddraw_surface_wined3d_parent_ops); + wined3d_resource_set_parent(wined3d_texture_get_resource(wined3d_texture), + dst_texture, &ddraw_texture_wined3d_parent_ops); }
- wined3d_resource_set_parent(wined3d_texture_get_resource(wined3d_texture), dst_texture); - if (draw_texture) - wined3d_resource_set_parent(wined3d_texture_get_resource(draw_texture), dst_texture); dst_surface->wined3d_texture = wined3d_texture; dst_surface->draw_texture = draw_texture;
@@ -6134,7 +6138,9 @@ static HRESULT ddraw_texture_init(struct ddraw_texture *texture, struct ddraw *d NULL, &ddraw_null_wined3d_parent_ops, &wined3d_texture))) goto fail;
- wined3d_resource_set_parent(wined3d_texture_get_resource(wined3d_texture), texture); + wined3d_resource_set_parent(wined3d_texture_get_resource(wined3d_texture), + texture, &ddraw_null_wined3d_parent_ops); + for (i = 0; i < layers * levels; ++i) { parent = wined3d_texture_get_sub_resource_parent(draw_texture, i); diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c index e2100627198..c1e16c71799 100644 --- a/dlls/wined3d/resource.c +++ b/dlls/wined3d/resource.c @@ -292,9 +292,10 @@ void * CDECL wined3d_resource_get_parent(const struct wined3d_resource *resource return resource->parent; }
-void CDECL wined3d_resource_set_parent(struct wined3d_resource *resource, void *parent) +void CDECL wined3d_resource_set_parent(struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops) { resource->parent = parent; + resource->parent_ops = parent_ops; }
void CDECL wined3d_resource_get_desc(const struct wined3d_resource *resource, struct wined3d_resource_desc *desc) diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 0f7c7938c39..300fc2978da 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -195,7 +195,7 @@ @ cdecl wined3d_resource_get_priority(ptr) @ cdecl wined3d_resource_map(ptr long ptr ptr long) @ cdecl wined3d_resource_preload(ptr) -@ cdecl wined3d_resource_set_parent(ptr ptr) +@ cdecl wined3d_resource_set_parent(ptr ptr ptr) @ cdecl wined3d_resource_set_priority(ptr long) @ cdecl wined3d_resource_unmap(ptr long)
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 4535892fb5f..ea4be6100f2 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2679,7 +2679,8 @@ unsigned int __cdecl wined3d_resource_get_priority(const struct wined3d_resource HRESULT __cdecl wined3d_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx, struct wined3d_map_desc *map_desc, const struct wined3d_box *box, uint32_t flags); void __cdecl wined3d_resource_preload(struct wined3d_resource *resource); -void __cdecl wined3d_resource_set_parent(struct wined3d_resource *resource, void *parent); +void __cdecl wined3d_resource_set_parent(struct wined3d_resource *resource, + void *parent, const struct wined3d_parent_ops *parent_ops); unsigned int __cdecl wined3d_resource_set_priority(struct wined3d_resource *resource, unsigned int priority); HRESULT __cdecl wined3d_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx);
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/ddraw/ddraw.c | 28 +------------- dlls/ddraw/ddraw_private.h | 3 +- dlls/ddraw/surface.c | 76 +++++++++++++++++++++++++------------- 3 files changed, 54 insertions(+), 53 deletions(-)
diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c index 7d9d25e62c7..d6570739a51 100644 --- a/dlls/ddraw/ddraw.c +++ b/dlls/ddraw/ddraw.c @@ -5033,35 +5033,11 @@ static HRESULT CDECL device_parent_texture_sub_resource_created(struct wined3d_d enum wined3d_resource_type type, struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, void **parent, const struct wined3d_parent_ops **parent_ops) { - struct ddraw *ddraw = ddraw_from_device_parent(device_parent); - struct ddraw_surface *ddraw_surface; - TRACE("device_parent %p, type %#x, wined3d_texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n", device_parent, type, wined3d_texture, sub_resource_idx, parent, parent_ops);
- /* We have a swapchain or wined3d internal texture. */ - if (type != WINED3D_RTYPE_TEXTURE_2D || !wined3d_texture_get_parent(wined3d_texture) - || wined3d_texture_get_parent(wined3d_texture) == ddraw) - { - *parent = NULL; - *parent_ops = &ddraw_null_wined3d_parent_ops; - - return DD_OK; - } - - if (!(ddraw_surface = heap_alloc_zero(sizeof(*ddraw_surface)))) - { - ERR("Failed to allocate surface memory.\n"); - return DDERR_OUTOFVIDEOMEMORY; - } - - ddraw_surface_init(ddraw_surface, ddraw, wined3d_texture, sub_resource_idx, parent_ops); - *parent = ddraw_surface; - - ddraw_update_lost_surfaces(ddraw); - list_add_head(&ddraw->surface_list, &ddraw_surface->surface_list_entry); - - TRACE("Created ddraw surface %p.\n", ddraw_surface); + *parent = NULL; + *parent_ops = &ddraw_null_wined3d_parent_ops;
return DD_OK; } diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index e3fac63a38f..42ec8868257 100644 --- a/dlls/ddraw/ddraw_private.h +++ b/dlls/ddraw/ddraw_private.h @@ -239,8 +239,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ struct ddraw_surface **surface, IUnknown *outer_unknown, unsigned int version) DECLSPEC_HIDDEN; struct wined3d_rendertarget_view *ddraw_surface_get_rendertarget_view(struct ddraw_surface *surface) DECLSPEC_HIDDEN; void ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, - struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, - const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN; + struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx) DECLSPEC_HIDDEN; HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, const RECT *rect, BOOL read, unsigned int swap_interval) DECLSPEC_HIDDEN;
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index 3caee53ee73..30aeb650d5b 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -6117,10 +6117,8 @@ static HRESULT ddraw_texture_init(struct ddraw_texture *texture, struct ddraw *d draw_texture_desc.access = WINED3D_RESOURCE_ACCESS_GPU; draw_texture_desc.usage = WINED3DUSAGE_PRIVATE;
- if (SUCCEEDED(hr = wined3d_texture_create(wined3d_device, &draw_texture_desc, layers, + if (FAILED(hr = wined3d_texture_create(wined3d_device, &draw_texture_desc, layers, levels, 0, NULL, texture, &ddraw_texture_wined3d_parent_ops, &draw_texture))) - wined3d_texture_decref(draw_texture); - else WARN("Failed to create draw texture, hr %#lx.\n", hr); }
@@ -6140,16 +6138,6 @@ static HRESULT ddraw_texture_init(struct ddraw_texture *texture, struct ddraw *d
wined3d_resource_set_parent(wined3d_texture_get_resource(wined3d_texture), texture, &ddraw_null_wined3d_parent_ops); - - for (i = 0; i < layers * levels; ++i) - { - parent = wined3d_texture_get_sub_resource_parent(draw_texture, i); - assert(parent->wined3d_texture == draw_texture); - parent->draw_texture = draw_texture; - parent->wined3d_texture = wined3d_texture; - wined3d_texture_set_sub_resource_parent(wined3d_texture, i, parent, &ddraw_null_wined3d_parent_ops); - wined3d_texture_incref(wined3d_texture); - } } else { @@ -6167,12 +6155,9 @@ static HRESULT ddraw_texture_init(struct ddraw_texture *texture, struct ddraw *d goto fail; }
- root = wined3d_texture_get_sub_resource_parent(wined3d_texture, 0); - texture->root = root; - for (i = 0; i < layers; ++i) { - struct ddraw_surface **attach = &root->complex_array[layers - 1 - i]; + struct ddraw_surface *prev_level = NULL;
for (j = 0; j < levels; ++j) { @@ -6182,7 +6167,27 @@ static HRESULT ddraw_texture_init(struct ddraw_texture *texture, struct ddraw *d struct ddraw_surface *mip; DDSURFACEDESC2 *mip_desc;
- mip = wined3d_texture_get_sub_resource_parent(wined3d_texture, sub_resource_idx); + if (!(mip = heap_alloc_zero(sizeof(*mip)))) + { + hr = DDERR_OUTOFVIDEOMEMORY; + goto fail; + } + + ddraw_surface_init(mip, ddraw, wined3d_texture, sub_resource_idx); + + if (draw_texture) + { + wined3d_texture_set_sub_resource_parent(draw_texture, sub_resource_idx, + mip, &ddraw_surface_wined3d_parent_ops); + wined3d_texture_set_sub_resource_parent(wined3d_texture, sub_resource_idx, + mip, &ddraw_null_wined3d_parent_ops); + wined3d_texture_incref(mip->draw_texture = draw_texture); + } + else + { + wined3d_texture_set_sub_resource_parent(wined3d_texture, sub_resource_idx, + mip, &ddraw_surface_wined3d_parent_ops); + }
mip->sysmem_fallback = sysmem_fallback; mip_desc = &mip->surface_desc; @@ -6254,14 +6259,32 @@ static HRESULT ddraw_texture_init(struct ddraw_texture *texture, struct ddraw *d
}
- if (mip == root) - continue; + ddraw_update_lost_surfaces(ddraw); + list_add_head(&ddraw->surface_list, &mip->surface_list_entry);
- *attach = mip; - attach = &mip->complex_array[0]; + TRACE("Created ddraw surface %p.\n", mip); + + if (!j) + { + if (!i) + texture->root = mip; + else + texture->root->complex_array[layers - 1 - i] = mip; + } + else if (j == 1 && !i) + { + texture->root->complex_array[layers - 1] = mip; + } + else + { + prev_level->complex_array[0] = mip; + } + prev_level = mip; } }
+ root = texture->root; + wined3d_device_incref(texture->wined3d_device = ddraw->wined3d_device);
if (desc->dwFlags & DDSD_CKDESTOVERLAY) @@ -6278,6 +6301,8 @@ static HRESULT ddraw_texture_init(struct ddraw_texture *texture, struct ddraw *d (struct wined3d_color_key *)&desc->ddckCKSrcBlt);
wined3d_texture_decref(wined3d_texture); + if (draw_texture) + wined3d_texture_decref(draw_texture);
if (reserve_memory && FAILED(hr = ddraw_surface_reserve_memory(wined3d_texture, 1))) { @@ -6289,6 +6314,9 @@ static HRESULT ddraw_texture_init(struct ddraw_texture *texture, struct ddraw *d return D3D_OK;
fail: + if (draw_texture) + wined3d_texture_decref(draw_texture); + parent = wined3d_texture_get_sub_resource_parent(draw_texture, 0); if (texture->version == 7) IDirectDrawSurface7_Release(&parent->IDirectDrawSurface7_iface); @@ -6809,8 +6837,7 @@ fail: }
void ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, - struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, - const struct wined3d_parent_ops **parent_ops) + struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx) { struct ddraw_texture *texture = wined3d_texture_get_parent(wined3d_texture); unsigned int version = texture->version; @@ -6847,7 +6874,6 @@ void ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw,
wined3d_texture_incref(surface->wined3d_texture = wined3d_texture); surface->sub_resource_idx = sub_resource_idx; - *parent_ops = &ddraw_surface_wined3d_parent_ops; surface->texture_location = DDRAW_SURFACE_LOCATION_DEFAULT;
wined3d_private_store_init(&surface->private_store);
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/ddraw/ddraw_private.h | 2 - dlls/ddraw/surface.c | 86 +++++++++++++++++++------------------- 2 files changed, 43 insertions(+), 45 deletions(-)
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index 42ec8868257..18ec1d84a5b 100644 --- a/dlls/ddraw/ddraw_private.h +++ b/dlls/ddraw/ddraw_private.h @@ -238,8 +238,6 @@ struct ddraw_texture HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_desc, struct ddraw_surface **surface, IUnknown *outer_unknown, unsigned int version) DECLSPEC_HIDDEN; struct wined3d_rendertarget_view *ddraw_surface_get_rendertarget_view(struct ddraw_surface *surface) DECLSPEC_HIDDEN; -void ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, - struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx) DECLSPEC_HIDDEN; HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, const RECT *rect, BOOL read, unsigned int swap_interval) DECLSPEC_HIDDEN;
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index 30aeb650d5b..b75775cf252 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -5912,6 +5912,49 @@ static const struct wined3d_parent_ops ddraw_surface_wined3d_parent_ops = ddraw_surface_wined3d_object_destroyed, };
+static void ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, + struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx) +{ + struct ddraw_texture *texture = wined3d_texture_get_parent(wined3d_texture); + unsigned int version = texture->version; + + surface->IDirectDrawSurface7_iface.lpVtbl = &ddraw_surface7_vtbl; + surface->IDirectDrawSurface4_iface.lpVtbl = &ddraw_surface4_vtbl; + surface->IDirectDrawSurface3_iface.lpVtbl = &ddraw_surface3_vtbl; + surface->IDirectDrawSurface2_iface.lpVtbl = &ddraw_surface2_vtbl; + surface->IDirectDrawSurface_iface.lpVtbl = &ddraw_surface1_vtbl; + surface->IDirectDrawGammaControl_iface.lpVtbl = &ddraw_gamma_control_vtbl; + surface->IDirect3DTexture2_iface.lpVtbl = &d3d_texture2_vtbl; + surface->IDirect3DTexture_iface.lpVtbl = &d3d_texture1_vtbl; + surface->iface_count = 1; + surface->version = version; + surface->ddraw = ddraw; + + if (version == 7) + { + surface->ref7 = 1; + surface->texture_outer = (IUnknown *)&surface->IDirectDrawSurface7_iface; + } + else if (version == 4) + { + surface->ref4 = 1; + surface->texture_outer = (IUnknown *)&surface->IDirectDrawSurface4_iface; + } + else + { + surface->ref1 = 1; + surface->texture_outer = (IUnknown *)&surface->IDirectDrawSurface_iface; + } + + surface->first_attached = surface; + + wined3d_texture_incref(surface->wined3d_texture = wined3d_texture); + surface->sub_resource_idx = sub_resource_idx; + surface->texture_location = DDRAW_SURFACE_LOCATION_DEFAULT; + + wined3d_private_store_init(&surface->private_store); +} + static void STDMETHODCALLTYPE ddraw_texture_wined3d_object_destroyed(void *parent) { struct ddraw_texture *texture = parent; @@ -6836,49 +6879,6 @@ fail: return hr; }
-void ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, - struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx) -{ - struct ddraw_texture *texture = wined3d_texture_get_parent(wined3d_texture); - unsigned int version = texture->version; - - surface->IDirectDrawSurface7_iface.lpVtbl = &ddraw_surface7_vtbl; - surface->IDirectDrawSurface4_iface.lpVtbl = &ddraw_surface4_vtbl; - surface->IDirectDrawSurface3_iface.lpVtbl = &ddraw_surface3_vtbl; - surface->IDirectDrawSurface2_iface.lpVtbl = &ddraw_surface2_vtbl; - surface->IDirectDrawSurface_iface.lpVtbl = &ddraw_surface1_vtbl; - surface->IDirectDrawGammaControl_iface.lpVtbl = &ddraw_gamma_control_vtbl; - surface->IDirect3DTexture2_iface.lpVtbl = &d3d_texture2_vtbl; - surface->IDirect3DTexture_iface.lpVtbl = &d3d_texture1_vtbl; - surface->iface_count = 1; - surface->version = version; - surface->ddraw = ddraw; - - if (version == 7) - { - surface->ref7 = 1; - surface->texture_outer = (IUnknown *)&surface->IDirectDrawSurface7_iface; - } - else if (version == 4) - { - surface->ref4 = 1; - surface->texture_outer = (IUnknown *)&surface->IDirectDrawSurface4_iface; - } - else - { - surface->ref1 = 1; - surface->texture_outer = (IUnknown *)&surface->IDirectDrawSurface_iface; - } - - surface->first_attached = surface; - - wined3d_texture_incref(surface->wined3d_texture = wined3d_texture); - surface->sub_resource_idx = sub_resource_idx; - surface->texture_location = DDRAW_SURFACE_LOCATION_DEFAULT; - - wined3d_private_store_init(&surface->private_store); -} - static void STDMETHODCALLTYPE view_wined3d_object_destroyed(void *parent) { struct ddraw_surface *surface = parent;
v2: Fix chaining of cubemap surfaces with multiple mip levels. As part of this, rewrite the chaining a bit to make it clearer.
This merge request was approved by Jan Sikorski.