From: Zebediah Figura zfigura@codeweavers.com
--- dlls/d3d8/d3d8_private.h | 4 +-- dlls/d3d8/device.c | 60 ++++++++++++++++++++++++++++------------ dlls/d3d8/surface.c | 6 ++-- dlls/d3d8/swapchain.c | 26 +++++++++++++++++ 4 files changed, 74 insertions(+), 22 deletions(-)
diff --git a/dlls/d3d8/d3d8_private.h b/dlls/d3d8/d3d8_private.h index c1d43b2dfce..3f4e15229db 100644 --- a/dlls/d3d8/d3d8_private.h +++ b/dlls/d3d8/d3d8_private.h @@ -202,8 +202,8 @@ struct d3d8_surface };
struct wined3d_rendertarget_view *d3d8_surface_acquire_rendertarget_view(struct d3d8_surface *surface) DECLSPEC_HIDDEN; -struct d3d8_surface *d3d8_surface_create(struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, - const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN; +struct d3d8_surface *d3d8_surface_create(struct wined3d_texture *wined3d_texture, + unsigned int sub_resource_idx) DECLSPEC_HIDDEN; struct d3d8_device *d3d8_surface_get_device(const struct d3d8_surface *surface) DECLSPEC_HIDDEN; void d3d8_surface_release_rendertarget_view(struct d3d8_surface *surface, struct wined3d_rendertarget_view *rtv) DECLSPEC_HIDDEN; diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c index 5d96d1b625b..981bd76cee9 100644 --- a/dlls/d3d8/device.c +++ b/dlls/d3d8/device.c @@ -930,7 +930,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); @@ -973,6 +973,8 @@ static HRESULT WINAPI d3d8_device_Reset(IDirect3DDevice8 *iface, if (SUCCEEDED(hr = wined3d_device_reset(device->wined3d_device, &swapchain_desc, NULL, reset_enum_callback, TRUE))) { + struct wined3d_rendertarget_view *rtv; + present_parameters->BackBufferCount = swapchain_desc.backbuffer_count; implicit_swapchain = wined3d_swapchain_get_parent(device->implicit_swapchain); implicit_swapchain->swap_interval @@ -981,6 +983,16 @@ static HRESULT WINAPI d3d8_device_Reset(IDirect3DDevice8 *iface, wined3d_stateblock_set_render_state(device->state, WINED3D_RS_ZENABLE, !!swapchain_desc.enable_auto_depth_stencil); device_reset_viewport_state(device); + + if ((rtv = wined3d_device_context_get_depth_stencil_view(device->immediate_context))) + { + struct wined3d_resource *resource = wined3d_rendertarget_view_get_resource(rtv); + struct d3d8_surface *surface; + + if ((surface = d3d8_surface_create(wined3d_texture_from_resource(resource), 0))) + surface->parent_device = &device->IDirect3DDevice8_iface; + } + device->device_state = D3D8_DEVICE_STATE_OK; } else @@ -1085,6 +1097,7 @@ static HRESULT WINAPI d3d8_device_CreateTexture(IDirect3DDevice8 *iface, { struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); struct d3d8_texture *object; + unsigned int i; HRESULT hr;
TRACE("iface %p, width %u, height %u, levels %u, usage %#lx, format %#x, pool %#x, texture %p.\n", @@ -1105,6 +1118,16 @@ static HRESULT WINAPI d3d8_device_CreateTexture(IDirect3DDevice8 *iface, return hr; }
+ levels = wined3d_texture_get_level_count(object->wined3d_texture); + for (i = 0; i < levels; ++i) + { + if (!d3d8_surface_create(object->wined3d_texture, i)) + { + IDirect3DTexture8_Release(&object->IDirect3DBaseTexture8_iface); + return E_OUTOFMEMORY; + } + } + TRACE("Created texture %p.\n", object); *texture = (IDirect3DTexture8 *)&object->IDirect3DBaseTexture8_iface;
@@ -1148,6 +1171,7 @@ static HRESULT WINAPI d3d8_device_CreateCubeTexture(IDirect3DDevice8 *iface, UIN { struct d3d8_device *device = impl_from_IDirect3DDevice8(iface); struct d3d8_texture *object; + unsigned int i; HRESULT hr;
TRACE("iface %p, edge_length %u, levels %u, usage %#lx, format %#x, pool %#x, texture %p.\n", @@ -1168,6 +1192,16 @@ static HRESULT WINAPI d3d8_device_CreateCubeTexture(IDirect3DDevice8 *iface, UIN return hr; }
+ levels = wined3d_texture_get_level_count(object->wined3d_texture); + for (i = 0; i < levels * 6; ++i) + { + if (!d3d8_surface_create(object->wined3d_texture, i)) + { + IDirect3DTexture8_Release(&object->IDirect3DBaseTexture8_iface); + return E_OUTOFMEMORY; + } + } + TRACE("Created cube texture %p.\n", object); *texture = (IDirect3DCubeTexture8 *)&object->IDirect3DBaseTexture8_iface;
@@ -1263,7 +1297,12 @@ static HRESULT d3d8_device_create_surface(struct d3d8_device *device, enum wined return hr; }
- surface_impl = wined3d_texture_get_sub_resource_parent(texture, 0); + if (!(surface_impl = d3d8_surface_create(texture, 0))) + { + wined3d_texture_decref(texture); + wined3d_mutex_unlock(); + return E_OUTOFMEMORY; + } surface_impl->parent_device = &device->IDirect3DDevice8_iface; *surface = &surface_impl->IDirect3DSurface8_iface; IDirect3DSurface8_AddRef(*surface); @@ -3564,16 +3603,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 d3d8_surface *d3d_surface; - - if (!(d3d_surface = d3d8_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 d3d8_volume *d3d_volume;
@@ -3584,7 +3614,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; @@ -3598,7 +3628,6 @@ static HRESULT CDECL device_parent_create_swapchain_texture(struct wined3d_devic struct wined3d_texture **texture) { struct d3d8_device *device = device_from_device_parent(device_parent); - struct d3d8_surface *d3d_surface; HRESULT hr;
TRACE("device_parent %p, container_parent %p, desc %p, texture flags %#lx, texture %p.\n", @@ -3611,9 +3640,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->IDirect3DDevice8_iface; - return hr; }
diff --git a/dlls/d3d8/surface.c b/dlls/d3d8/surface.c index a0281bff230..795ff1f9ce5 100644 --- a/dlls/d3d8/surface.c +++ b/dlls/d3d8/surface.c @@ -309,8 +309,7 @@ static const struct wined3d_parent_ops d3d8_surface_wined3d_parent_ops = surface_wined3d_object_destroyed, };
-struct d3d8_surface *d3d8_surface_create(struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, - const struct wined3d_parent_ops **parent_ops) +struct d3d8_surface *d3d8_surface_create(struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx) { IDirect3DBaseTexture8 *texture; struct d3d8_surface *surface; @@ -333,7 +332,8 @@ struct d3d8_surface *d3d8_surface_create(struct wined3d_texture *wined3d_texture IDirect3DBaseTexture8_Release(texture); }
- *parent_ops = &d3d8_surface_wined3d_parent_ops; + wined3d_texture_set_sub_resource_parent(wined3d_texture, sub_resource_idx, + surface, &d3d8_surface_wined3d_parent_ops);
TRACE("Created surface %p.\n", surface); return surface; diff --git a/dlls/d3d8/swapchain.c b/dlls/d3d8/swapchain.c index 476846d7e89..37b55b8fc3a 100644 --- a/dlls/d3d8/swapchain.c +++ b/dlls/d3d8/swapchain.c @@ -193,7 +193,10 @@ static HRESULT swapchain_init(struct d3d8_swapchain *swapchain, struct d3d8_devi HRESULT d3d8_swapchain_create(struct d3d8_device *device, struct wined3d_swapchain_desc *desc, unsigned int swap_interval, struct d3d8_swapchain **swapchain) { + struct wined3d_rendertarget_view *wined3d_dsv; struct d3d8_swapchain *object; + struct d3d8_surface *surface; + unsigned int i; HRESULT hr;
if (!(object = heap_alloc_zero(sizeof(*object)))) @@ -206,6 +209,29 @@ HRESULT d3d8_swapchain_create(struct d3d8_device *device, struct wined3d_swapcha return hr; }
+ for (i = 0; i < desc->backbuffer_count; ++i) + { + if (!(surface = d3d8_surface_create(wined3d_swapchain_get_back_buffer(object->wined3d_swapchain, i), 0))) + { + IDirect3DSwapChain8_Release(&object->IDirect3DSwapChain8_iface); + return E_OUTOFMEMORY; + } + surface->parent_device = &device->IDirect3DDevice8_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 = d3d8_surface_create(wined3d_texture_from_resource(resource), 0))) + { + IDirect3DSwapChain8_Release(&object->IDirect3DSwapChain8_iface); + return E_OUTOFMEMORY; + } + surface->parent_device = &device->IDirect3DDevice8_iface; + } + TRACE("Created swapchain %p.\n", object); *swapchain = object;