From: Zebediah Figura zfigura@codeweavers.com
Move away from using the sub_resource_created callback to do this.
This is also a step away from using the create_swapchain_texture callback. --- dlls/d3d9/d3d9_private.h | 2 +- dlls/d3d9/device.c | 57 ++++++++++++++++++++++++++++------------ dlls/d3d9/surface.c | 6 ++--- dlls/d3d9/swapchain.c | 26 ++++++++++++++++++ 4 files changed, 70 insertions(+), 21 deletions(-)
diff --git a/dlls/d3d9/d3d9_private.h b/dlls/d3d9/d3d9_private.h index dd9fd2a0039..36cf8f68c83 100644 --- a/dlls/d3d9/d3d9_private.h +++ b/dlls/d3d9/d3d9_private.h @@ -180,7 +180,7 @@ struct d3d9_surface
struct wined3d_rendertarget_view *d3d9_surface_acquire_rendertarget_view(struct d3d9_surface *surface) DECLSPEC_HIDDEN; struct d3d9_surface *d3d9_surface_create(struct wined3d_texture *wined3d_texture, - unsigned int sub_resource_idx, const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN; + unsigned int sub_resource_idx) DECLSPEC_HIDDEN; struct d3d9_device *d3d9_surface_get_device(const struct d3d9_surface *surface) DECLSPEC_HIDDEN; void d3d9_surface_release_rendertarget_view(struct d3d9_surface *surface, struct wined3d_rendertarget_view *rtv) DECLSPEC_HIDDEN; diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c index 75861032c3a..ed88a4c2def 100644 --- a/dlls/d3d9/device.c +++ b/dlls/d3d9/device.c @@ -1019,7 +1019,7 @@ static HRESULT CDECL reset_enum_callback(struct wined3d_resource *resource) }
surface = wined3d_texture_get_sub_resource_parent(wined3d_texture_from_resource(resource), 0); - if (!surface->resource.refcount) + if (!surface || !surface->resource.refcount) return D3D_OK;
WARN("Surface %p in pool D3DPOOL_DEFAULT blocks the Reset call.\n", surface); @@ -1142,6 +1142,15 @@ static HRESULT d3d9_device_reset(struct d3d9_device *device, device->render_targets[0] = wined3d_rendertarget_view_get_sub_resource_parent(rtv); for (i = 1; i < ARRAY_SIZE(device->render_targets); ++i) device->render_targets[i] = NULL; + + if ((rtv = wined3d_device_context_get_depth_stencil_view(device->immediate_context))) + { + struct wined3d_resource *resource = wined3d_rendertarget_view_get_resource(rtv); + struct d3d9_surface *surface; + + if ((surface = d3d9_surface_create(wined3d_texture_from_resource(resource), 0))) + surface->parent_device = &device->IDirect3DDevice9Ex_iface; + } } else if (!extended) { @@ -1289,6 +1298,7 @@ static HRESULT WINAPI d3d9_device_CreateTexture(IDirect3DDevice9Ex *iface, struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); struct d3d9_texture *object; BOOL set_mem = FALSE; + unsigned int i; HRESULT hr;
TRACE("iface %p, width %u, height %u, levels %u, usage %#lx, format %#x, pool %#x, texture %p, shared_handle %p.\n", @@ -1340,6 +1350,16 @@ static HRESULT WINAPI d3d9_device_CreateTexture(IDirect3DDevice9Ex *iface, wined3d_mutex_unlock(); }
+ levels = wined3d_texture_get_level_count(object->wined3d_texture); + for (i = 0; i < levels; ++i) + { + if (!d3d9_surface_create(object->wined3d_texture, i)) + { + IDirect3DTexture9_Release(&object->IDirect3DBaseTexture9_iface); + return E_OUTOFMEMORY; + } + } + TRACE("Created texture %p.\n", object); *texture = (IDirect3DTexture9 *)&object->IDirect3DBaseTexture9_iface;
@@ -1399,6 +1419,7 @@ static HRESULT WINAPI d3d9_device_CreateCubeTexture(IDirect3DDevice9Ex *iface, { struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); struct d3d9_texture *object; + unsigned int i; HRESULT hr;
TRACE("iface %p, edge_length %u, levels %u, usage %#lx, format %#x, pool %#x, texture %p, shared_handle %p.\n", @@ -1432,6 +1453,16 @@ static HRESULT WINAPI d3d9_device_CreateCubeTexture(IDirect3DDevice9Ex *iface, return hr; }
+ levels = wined3d_texture_get_level_count(object->wined3d_texture); + for (i = 0; i < levels * 6; ++i) + { + if (!d3d9_surface_create(object->wined3d_texture, i)) + { + IDirect3DTexture9_Release(&object->IDirect3DBaseTexture9_iface); + return E_OUTOFMEMORY; + } + } + TRACE("Created cube texture %p.\n", object); *texture = (IDirect3DCubeTexture9 *)&object->IDirect3DBaseTexture9_iface;
@@ -1568,7 +1599,12 @@ static HRESULT d3d9_device_create_surface(struct d3d9_device *device, unsigned i return hr; }
- surface_impl = wined3d_texture_get_sub_resource_parent(texture, 0); + if (!(surface_impl = d3d9_surface_create(texture, 0))) + { + wined3d_texture_decref(texture); + wined3d_mutex_unlock(); + return E_OUTOFMEMORY; + } surface_impl->parent_device = &device->IDirect3DDevice9Ex_iface; *surface = &surface_impl->IDirect3DSurface9_iface; IDirect3DSurface9_AddRef(*surface); @@ -4498,16 +4534,7 @@ static HRESULT CDECL device_parent_texture_sub_resource_created(struct wined3d_d 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);
- if (type == WINED3D_RTYPE_TEXTURE_2D) - { - struct d3d9_surface *d3d_surface; - - if (!(d3d_surface = d3d9_surface_create(wined3d_texture, sub_resource_idx, parent_ops))) - return E_OUTOFMEMORY; - - *parent = d3d_surface; - } - else if (type == WINED3D_RTYPE_TEXTURE_3D) + if (type == WINED3D_RTYPE_TEXTURE_3D) { struct d3d9_volume *d3d_volume;
@@ -4518,7 +4545,7 @@ static HRESULT CDECL device_parent_texture_sub_resource_created(struct wined3d_d *parent = d3d_volume; TRACE("Created volume %p.\n", d3d_volume); } - else + else if (type != WINED3D_RTYPE_TEXTURE_2D) { ERR("Unhandled resource type %#x.\n", type); return E_FAIL; @@ -4532,7 +4559,6 @@ static HRESULT CDECL device_parent_create_swapchain_texture(struct wined3d_devic struct wined3d_texture **texture) { struct d3d9_device *device = device_from_device_parent(device_parent); - struct d3d9_surface *d3d_surface; HRESULT hr;
TRACE("device_parent %p, container_parent %p, desc %p, texture flags %#lx, texture %p.\n", @@ -4548,9 +4574,6 @@ static HRESULT CDECL device_parent_create_swapchain_texture(struct wined3d_devic return hr; }
- d3d_surface = wined3d_texture_get_sub_resource_parent(*texture, 0); - d3d_surface->parent_device = &device->IDirect3DDevice9Ex_iface; - return hr; }
diff --git a/dlls/d3d9/surface.c b/dlls/d3d9/surface.c index 146cb8ce35c..4503c360120 100644 --- a/dlls/d3d9/surface.c +++ b/dlls/d3d9/surface.c @@ -347,8 +347,7 @@ static const struct wined3d_parent_ops d3d9_surface_wined3d_parent_ops = surface_wined3d_object_destroyed, };
-struct d3d9_surface *d3d9_surface_create(struct wined3d_texture *wined3d_texture, - unsigned int sub_resource_idx, const struct wined3d_parent_ops **parent_ops) +struct d3d9_surface *d3d9_surface_create(struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx) { IDirect3DBaseTexture9 *texture; struct d3d9_surface *surface; @@ -371,7 +370,8 @@ struct d3d9_surface *d3d9_surface_create(struct wined3d_texture *wined3d_texture IDirect3DBaseTexture9_Release(texture); }
- *parent_ops = &d3d9_surface_wined3d_parent_ops; + wined3d_texture_set_sub_resource_parent(wined3d_texture, sub_resource_idx, + surface, &d3d9_surface_wined3d_parent_ops);
TRACE("Created surface %p.\n", surface); return surface; diff --git a/dlls/d3d9/swapchain.c b/dlls/d3d9/swapchain.c index 8c731812dd7..951fee75015 100644 --- a/dlls/d3d9/swapchain.c +++ b/dlls/d3d9/swapchain.c @@ -393,7 +393,10 @@ static HRESULT swapchain_init(struct d3d9_swapchain *swapchain, struct d3d9_devi HRESULT d3d9_swapchain_create(struct d3d9_device *device, struct wined3d_swapchain_desc *desc, unsigned int swap_interval, struct d3d9_swapchain **swapchain) { + struct wined3d_rendertarget_view *wined3d_dsv; struct d3d9_swapchain *object; + struct d3d9_surface *surface; + unsigned int i; HRESULT hr;
if (!(object = heap_alloc_zero(sizeof(*object)))) @@ -406,6 +409,29 @@ HRESULT d3d9_swapchain_create(struct d3d9_device *device, struct wined3d_swapcha return hr; }
+ for (i = 0; i < desc->backbuffer_count; ++i) + { + if (!(surface = d3d9_surface_create(wined3d_swapchain_get_back_buffer(object->wined3d_swapchain, i), 0))) + { + IDirect3DSwapChain9Ex_Release(&object->IDirect3DSwapChain9Ex_iface); + return E_OUTOFMEMORY; + } + surface->parent_device = &device->IDirect3DDevice9Ex_iface; + } + + if ((desc->flags & WINED3D_SWAPCHAIN_IMPLICIT) + && (wined3d_dsv = wined3d_device_context_get_depth_stencil_view(device->immediate_context))) + { + struct wined3d_resource *resource = wined3d_rendertarget_view_get_resource(wined3d_dsv); + + if (!(surface = d3d9_surface_create(wined3d_texture_from_resource(resource), 0))) + { + IDirect3DSwapChain9Ex_Release(&object->IDirect3DSwapChain9Ex_iface); + return E_OUTOFMEMORY; + } + surface->parent_device = &device->IDirect3DDevice9Ex_iface; + } + TRACE("Created swapchain %p.\n", object); *swapchain = object;