From: Zebediah Figura zfigura@codeweavers.com
--- dlls/d3d9/tests/d3d9ex.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-)
diff --git a/dlls/d3d9/tests/d3d9ex.c b/dlls/d3d9/tests/d3d9ex.c index 41f930a2408..0915d50107f 100644 --- a/dlls/d3d9/tests/d3d9ex.c +++ b/dlls/d3d9/tests/d3d9ex.c @@ -3813,9 +3813,11 @@ static void test_swapchain_parameters(void) static void test_backbuffer_resize(void) { D3DPRESENT_PARAMETERS present_parameters = {0}; + IDirect3DSwapChain9 *swapchain, *old_swapchain; IDirect3DSurface9 *backbuffer, *old_backbuffer; + IDirect3DDevice9Ex *device, *device2; + IDirect3DBaseTexture9 *texture; D3DSURFACE_DESC surface_desc; - IDirect3DDevice9Ex *device; unsigned int color; ULONG refcount; HWND window; @@ -3861,6 +3863,16 @@ static void test_backbuffer_resize(void) color = get_pixel_color(device, 1, 1); ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
+ hr = IDirect3DDevice9_GetSwapChain(device, 0, &old_swapchain); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IDirect3DSurface9_GetContainer(backbuffer, &IID_IDirect3DSwapChain9, (void **)&swapchain); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(swapchain == old_swapchain, "Swapchains didn't match.\n"); + IDirect3DSwapChain9_Release(swapchain); + hr = IDirect3DSurface9_GetContainer(backbuffer, &IID_IDirect3DDevice9, (void **)&device2); + ok(hr == E_NOINTERFACE, "Got hr %#lx.\n", hr); + present_parameters.BackBufferWidth = 800; present_parameters.BackBufferHeight = 600; present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8; @@ -3877,6 +3889,27 @@ static void test_backbuffer_resize(void) ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#lx.\n", hr); todo_wine ok(surface_desc.Width == 640, "Got unexpected width %u.\n", surface_desc.Width); todo_wine ok(surface_desc.Height == 480, "Got unexpected height %u.\n", surface_desc.Height); + + hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(swapchain == old_swapchain, "Swapchains didn't match.\n"); + IDirect3DSwapChain9_Release(swapchain); + IDirect3DSwapChain9_Release(old_swapchain); + + hr = IDirect3DSurface9_GetContainer(old_backbuffer, &IID_IDirect3DSwapChain9, (void **)&swapchain); + todo_wine ok(hr == E_NOINTERFACE, "Got hr %#lx.\n", hr); + if (hr == S_OK) + IDirect3DSwapChain9_Release(swapchain); + hr = IDirect3DSurface9_GetContainer(old_backbuffer, &IID_IDirect3DBaseTexture9, (void **)&texture); + ok(hr == E_NOINTERFACE, "Got hr %#lx.\n", hr); + hr = IDirect3DSurface9_GetContainer(old_backbuffer, &IID_IDirect3DDevice9, (void **)&device2); + todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); + if (hr == S_OK) + { + ok(device2 == device, "Devices didn't match.\n"); + IDirect3DDevice9_Release(device2); + } + refcount = IDirect3DSurface9_Release(old_backbuffer); ok(!refcount, "Surface has %lu references left.\n", refcount);
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/d3d9/d3d9_private.h | 1 + dlls/d3d9/surface.c | 7 +++++++ 2 files changed, 8 insertions(+)
diff --git a/dlls/d3d9/d3d9_private.h b/dlls/d3d9/d3d9_private.h index 53c73853e46..cb86ce678fb 100644 --- a/dlls/d3d9/d3d9_private.h +++ b/dlls/d3d9/d3d9_private.h @@ -176,6 +176,7 @@ struct d3d9_surface IDirect3DDevice9Ex *parent_device; IUnknown *container; struct d3d9_texture *texture; + struct wined3d_swapchain *swapchain; };
struct wined3d_rendertarget_view *d3d9_surface_acquire_rendertarget_view(struct d3d9_surface *surface) DECLSPEC_HIDDEN; diff --git a/dlls/d3d9/surface.c b/dlls/d3d9/surface.c index df94aad3c59..f0cc36da3a1 100644 --- a/dlls/d3d9/surface.c +++ b/dlls/d3d9/surface.c @@ -70,6 +70,8 @@ static ULONG WINAPI d3d9_surface_AddRef(IDirect3DSurface9 *iface) if (surface->wined3d_rtv) wined3d_rendertarget_view_incref(surface->wined3d_rtv); wined3d_texture_incref(surface->wined3d_texture); + if (surface->swapchain) + wined3d_swapchain_incref(surface->swapchain); }
return refcount; @@ -103,6 +105,10 @@ static ULONG WINAPI d3d9_surface_Release(IDirect3DSurface9 *iface)
if (surface->wined3d_rtv) wined3d_rendertarget_view_decref(surface->wined3d_rtv); + if (surface->swapchain) + wined3d_swapchain_decref(surface->swapchain); + /* Releasing the texture may free the d3d9 object, so do not access it + * after releasing the texture. */ wined3d_texture_decref(surface->wined3d_texture);
/* Release the device last, as it may cause the device to be destroyed. */ @@ -363,6 +369,7 @@ struct d3d9_surface *d3d9_surface_create(struct wined3d_texture *wined3d_texture surface->container = container; surface->wined3d_texture = wined3d_texture; surface->sub_resource_idx = sub_resource_idx; + surface->swapchain = wined3d_texture_get_swapchain(wined3d_texture);
if (surface->container && SUCCEEDED(IUnknown_QueryInterface(surface->container, &IID_IDirect3DBaseTexture9, (void **)&texture)))
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/d3d8/d3d8_private.h | 1 + dlls/d3d8/surface.c | 7 +++++++ 2 files changed, 8 insertions(+)
diff --git a/dlls/d3d8/d3d8_private.h b/dlls/d3d8/d3d8_private.h index 69e16a50c3a..181a952a347 100644 --- a/dlls/d3d8/d3d8_private.h +++ b/dlls/d3d8/d3d8_private.h @@ -199,6 +199,7 @@ struct d3d8_surface IDirect3DDevice8 *parent_device; IUnknown *container; struct d3d8_texture *texture; + struct wined3d_swapchain *swapchain; };
struct wined3d_rendertarget_view *d3d8_surface_acquire_rendertarget_view(struct d3d8_surface *surface) DECLSPEC_HIDDEN; diff --git a/dlls/d3d8/surface.c b/dlls/d3d8/surface.c index b4545ca3657..37d225ede70 100644 --- a/dlls/d3d8/surface.c +++ b/dlls/d3d8/surface.c @@ -69,6 +69,8 @@ static ULONG WINAPI d3d8_surface_AddRef(IDirect3DSurface8 *iface) if (surface->wined3d_rtv) wined3d_rendertarget_view_incref(surface->wined3d_rtv); wined3d_texture_incref(surface->wined3d_texture); + if (surface->swapchain) + wined3d_swapchain_incref(surface->swapchain); }
return refcount; @@ -102,6 +104,10 @@ static ULONG WINAPI d3d8_surface_Release(IDirect3DSurface8 *iface)
if (surface->wined3d_rtv) wined3d_rendertarget_view_decref(surface->wined3d_rtv); + if (surface->swapchain) + wined3d_swapchain_decref(surface->swapchain); + /* Releasing the texture may free the d3d8 object, so do not access it + * after releasing the texture. */ wined3d_texture_decref(surface->wined3d_texture);
if (parent_device) @@ -325,6 +331,7 @@ struct d3d8_surface *d3d8_surface_create(struct wined3d_texture *wined3d_texture surface->container = container; surface->wined3d_texture = wined3d_texture; surface->sub_resource_idx = sub_resource_idx; + surface->swapchain = wined3d_texture_get_swapchain(wined3d_texture);
if (surface->container && SUCCEEDED(IUnknown_QueryInterface(surface->container, &IID_IDirect3DBaseTexture8, (void **)&texture)))
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/d3d11/d3d11_private.h | 1 + dlls/d3d11/texture.c | 9 +++++++++ 2 files changed, 10 insertions(+)
diff --git a/dlls/d3d11/d3d11_private.h b/dlls/d3d11/d3d11_private.h index 226d7b6b4e1..6177f24afe3 100644 --- a/dlls/d3d11/d3d11_private.h +++ b/dlls/d3d11/d3d11_private.h @@ -138,6 +138,7 @@ struct d3d_texture2d
IUnknown *dxgi_resource; struct wined3d_texture *wined3d_texture; + struct wined3d_swapchain *swapchain; D3D11_TEXTURE2D_DESC desc; ID3D11Device2 *device; }; diff --git a/dlls/d3d11/texture.c b/dlls/d3d11/texture.c index 5cd7df11f1f..1221fa035ba 100644 --- a/dlls/d3d11/texture.c +++ b/dlls/d3d11/texture.c @@ -558,6 +558,8 @@ static ULONG STDMETHODCALLTYPE d3d11_texture2d_AddRef(ID3D11Texture2D *iface) { ID3D11Device2_AddRef(texture->device); wined3d_texture_incref(texture->wined3d_texture); + if (texture->swapchain) + wined3d_swapchain_incref(texture->swapchain); }
return refcount; @@ -573,6 +575,10 @@ static ULONG STDMETHODCALLTYPE d3d11_texture2d_Release(ID3D11Texture2D *iface) if (!refcount) { ID3D11Device2 *device = texture->device; + if (texture->swapchain) + wined3d_swapchain_decref(texture->swapchain); + /* Releasing the texture may free the d3d11 object, so do not access it + * after releasing the texture. */ wined3d_texture_decref(texture->wined3d_texture); /* Release the device last, it may cause the wined3d device to be * destroyed. */ @@ -984,6 +990,9 @@ HRESULT d3d_texture2d_create(struct d3d_device *device, const D3D11_TEXTURE2D_DE texture, &d3d_texture2d_wined3d_parent_ops); wined3d_texture_incref(wined3d_texture); texture->wined3d_texture = wined3d_texture; + + if ((texture->swapchain = wined3d_texture_get_swapchain(wined3d_texture))) + wined3d_swapchain_incref(texture->swapchain); } else {
From: Zebediah Figura zfigura@codeweavers.com
Rely on the swapchain to reference its individual textures, and rely on the parent texture object to keep the swapchain alive if necessary.
This is necessary to allow detaching textures from a swapchain. --- dlls/wined3d/texture.c | 6 ------ 1 file changed, 6 deletions(-)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 4cd6d7035eb..1bf9adf869c 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -1513,9 +1513,6 @@ ULONG CDECL wined3d_texture_incref(struct wined3d_texture *texture)
TRACE("texture %p, swapchain %p.\n", texture, texture->swapchain);
- if (texture->swapchain) - return wined3d_swapchain_incref(texture->swapchain); - refcount = InterlockedIncrement(&texture->resource.ref); TRACE("%p increasing refcount to %u.\n", texture, refcount);
@@ -1606,9 +1603,6 @@ ULONG CDECL wined3d_texture_decref(struct wined3d_texture *texture)
TRACE("texture %p, swapchain %p.\n", texture, texture->swapchain);
- if (texture->swapchain) - return wined3d_swapchain_decref(texture->swapchain); - refcount = InterlockedDecrement(&texture->resource.ref); TRACE("%p decreasing refcount to %u.\n", texture, refcount);
This merge request was approved by Jan Sikorski.