From: Zebediah Figura zfigura@codeweavers.com
Instead of having d3d11 create the wined3d texture, create it in dxgi instead, and let d3d11 create a d3d_texture2d object to wrap it.
This is a step towards getting rid of the create_swapchain_texture() callback, which is mildly difficult to work with and conceptually complex. --- dlls/d3d11/d3d11_private.h | 3 +- dlls/d3d11/device.c | 45 +++++++++++++++++++++- dlls/d3d11/texture.c | 77 ++++++++++++++++++++++---------------- dlls/dxgi/device.c | 28 ++++++++------ include/wine/winedxgi.idl | 2 + 5 files changed, 107 insertions(+), 48 deletions(-)
diff --git a/dlls/d3d11/d3d11_private.h b/dlls/d3d11/d3d11_private.h index 7cb3ba13c0a..226d7b6b4e1 100644 --- a/dlls/d3d11/d3d11_private.h +++ b/dlls/d3d11/d3d11_private.h @@ -148,7 +148,8 @@ static inline struct d3d_texture2d *impl_from_ID3D11Texture2D(ID3D11Texture2D *i }
HRESULT d3d_texture2d_create(struct d3d_device *device, const D3D11_TEXTURE2D_DESC *desc, - const D3D11_SUBRESOURCE_DATA *data, struct d3d_texture2d **texture) DECLSPEC_HIDDEN; + struct wined3d_texture *wined3d_texture, + const D3D11_SUBRESOURCE_DATA *data, struct d3d_texture2d **out) DECLSPEC_HIDDEN; struct d3d_texture2d *unsafe_impl_from_ID3D11Texture2D(ID3D11Texture2D *iface) DECLSPEC_HIDDEN; struct d3d_texture2d *unsafe_impl_from_ID3D10Texture2D(ID3D10Texture2D *iface) DECLSPEC_HIDDEN;
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index 5cb84c59dee..cf6ab388aec 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -3335,7 +3335,7 @@ static HRESULT STDMETHODCALLTYPE d3d11_device_CreateTexture2D(ID3D11Device2 *ifa
TRACE("iface %p, desc %p, data %p, texture %p.\n", iface, desc, data, texture);
- if (FAILED(hr = d3d_texture2d_create(device, desc, data, &object))) + if (FAILED(hr = d3d_texture2d_create(device, desc, NULL, data, &object))) return hr;
*texture = &object->ID3D11Texture2D_iface; @@ -6021,7 +6021,7 @@ static HRESULT STDMETHODCALLTYPE d3d10_device_CreateTexture2D(ID3D10Device1 *ifa d3d11_desc.CPUAccessFlags = d3d11_cpu_access_flags_from_d3d10_cpu_access_flags(desc->CPUAccessFlags); d3d11_desc.MiscFlags = d3d11_resource_misc_flags_from_d3d10_resource_misc_flags(desc->MiscFlags);
- if (FAILED(hr = d3d_texture2d_create(device, &d3d11_desc, (const D3D11_SUBRESOURCE_DATA *)data, &object))) + if (FAILED(hr = d3d_texture2d_create(device, &d3d11_desc, NULL, (const D3D11_SUBRESOURCE_DATA *)data, &object))) return hr;
*texture = &object->ID3D10Texture2D_iface; @@ -6780,6 +6780,46 @@ static struct wined3d_device_parent * STDMETHODCALLTYPE dxgi_device_parent_get_w return &device->device_parent; }
+static HRESULT STDMETHODCALLTYPE dxgi_device_parent_swapchain_texture_created(IWineDXGIDeviceParent *iface, + struct wined3d_texture *wined3d_texture, unsigned int texture_flags, IDXGISurface **ret_surface) +{ + struct d3d_device *device = device_from_dxgi_device_parent(iface); + struct wined3d_resource_desc wined3d_desc; + struct d3d_texture2d *object; + D3D11_TEXTURE2D_DESC desc; + HRESULT hr; + + wined3d_resource_get_desc(wined3d_texture_get_resource(wined3d_texture), &wined3d_desc); + + desc.Width = wined3d_desc.width; + desc.Height = wined3d_desc.height; + desc.MipLevels = 1; + desc.ArraySize = 1; + desc.Format = dxgi_format_from_wined3dformat(wined3d_desc.format); + desc.SampleDesc.Count = wined3d_desc.multisample_type ? wined3d_desc.multisample_type : 1; + desc.SampleDesc.Quality = wined3d_desc.multisample_quality; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = d3d11_bind_flags_from_wined3d(wined3d_desc.bind_flags); + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + + if (texture_flags & WINED3D_TEXTURE_CREATE_GET_DC) + { + desc.MiscFlags |= D3D11_RESOURCE_MISC_GDI_COMPATIBLE; + texture_flags &= ~WINED3D_TEXTURE_CREATE_GET_DC; + } + + if (texture_flags) + FIXME("Unhandled flags %#x.\n", texture_flags); + + if (FAILED(hr = d3d_texture2d_create(device, &desc, wined3d_texture, NULL, &object))) + return hr; + + hr = IUnknown_QueryInterface(object->dxgi_resource, &IID_IDXGISurface, (void **)ret_surface); + ID3D11Texture2D_Release(&object->ID3D11Texture2D_iface); + return hr; +} + static const struct IWineDXGIDeviceParentVtbl d3d_dxgi_device_parent_vtbl = { /* IUnknown methods */ @@ -6788,6 +6828,7 @@ static const struct IWineDXGIDeviceParentVtbl d3d_dxgi_device_parent_vtbl = dxgi_device_parent_Release, /* IWineDXGIDeviceParent methods */ dxgi_device_parent_get_wined3d_device_parent, + dxgi_device_parent_swapchain_texture_created, };
static inline struct d3d_device *device_from_wined3d_device_parent(struct wined3d_device_parent *device_parent) diff --git a/dlls/d3d11/texture.c b/dlls/d3d11/texture.c index dcc05725f65..5cd7df11f1f 100644 --- a/dlls/d3d11/texture.c +++ b/dlls/d3d11/texture.c @@ -956,11 +956,9 @@ static BOOL validate_texture2d_desc(const D3D11_TEXTURE2D_DESC *desc, D3D_FEATUR }
HRESULT d3d_texture2d_create(struct d3d_device *device, const D3D11_TEXTURE2D_DESC *desc, - const D3D11_SUBRESOURCE_DATA *data, struct d3d_texture2d **out) + struct wined3d_texture *wined3d_texture, const D3D11_SUBRESOURCE_DATA *data, struct d3d_texture2d **out) { - struct wined3d_resource_desc wined3d_desc; struct d3d_texture2d *texture; - unsigned int levels; BOOL needs_surface; DWORD flags = 0; HRESULT hr; @@ -980,38 +978,51 @@ HRESULT d3d_texture2d_create(struct d3d_device *device, const D3D11_TEXTURE2D_DE wined3d_mutex_lock(); texture->desc = *desc;
- wined3d_desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; - wined3d_desc.format = wined3dformat_from_dxgi_format(desc->Format); - wined3d_desc.multisample_type = desc->SampleDesc.Count > 1 ? desc->SampleDesc.Count : WINED3D_MULTISAMPLE_NONE; - wined3d_desc.multisample_quality = desc->SampleDesc.Quality; - wined3d_desc.usage = wined3d_usage_from_d3d11(desc->Usage); - wined3d_desc.bind_flags = wined3d_bind_flags_from_d3d11(desc->BindFlags, desc->MiscFlags); - wined3d_desc.access = wined3d_access_from_d3d11(desc->Usage, - desc->Usage == D3D11_USAGE_DEFAULT ? 0 : desc->CPUAccessFlags); - wined3d_desc.width = desc->Width; - wined3d_desc.height = desc->Height; - wined3d_desc.depth = 1; - wined3d_desc.size = 0; - - levels = desc->MipLevels ? desc->MipLevels : wined3d_log2i(max(desc->Width, desc->Height)) + 1; - - if (desc->MiscFlags & D3D11_RESOURCE_MISC_GDI_COMPATIBLE) - flags |= WINED3D_TEXTURE_CREATE_GET_DC; - if (desc->MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS) - flags |= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS; - - if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &wined3d_desc, - desc->ArraySize, levels, flags, (struct wined3d_sub_resource_data *)data, - texture, &d3d_texture2d_wined3d_parent_ops, &texture->wined3d_texture))) + if (wined3d_texture) { - WARN("Failed to create wined3d texture, hr %#lx.\n", hr); - free(texture); - wined3d_mutex_unlock(); - if (hr == WINED3DERR_NOTAVAILABLE || hr == WINED3DERR_INVALIDCALL) - hr = E_INVALIDARG; - return hr; + wined3d_resource_set_parent(wined3d_texture_get_resource(wined3d_texture), + texture, &d3d_texture2d_wined3d_parent_ops); + wined3d_texture_incref(wined3d_texture); + texture->wined3d_texture = wined3d_texture; + } + else + { + struct wined3d_resource_desc wined3d_desc; + unsigned int levels; + + wined3d_desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; + wined3d_desc.format = wined3dformat_from_dxgi_format(desc->Format); + wined3d_desc.multisample_type = desc->SampleDesc.Count > 1 ? desc->SampleDesc.Count : WINED3D_MULTISAMPLE_NONE; + wined3d_desc.multisample_quality = desc->SampleDesc.Quality; + wined3d_desc.usage = wined3d_usage_from_d3d11(desc->Usage); + wined3d_desc.bind_flags = wined3d_bind_flags_from_d3d11(desc->BindFlags, desc->MiscFlags); + wined3d_desc.access = wined3d_access_from_d3d11(desc->Usage, + desc->Usage == D3D11_USAGE_DEFAULT ? 0 : desc->CPUAccessFlags); + wined3d_desc.width = desc->Width; + wined3d_desc.height = desc->Height; + wined3d_desc.depth = 1; + wined3d_desc.size = 0; + + levels = desc->MipLevels ? desc->MipLevels : wined3d_log2i(max(desc->Width, desc->Height)) + 1; + + if (desc->MiscFlags & D3D11_RESOURCE_MISC_GDI_COMPATIBLE) + flags |= WINED3D_TEXTURE_CREATE_GET_DC; + if (desc->MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS) + flags |= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS; + + if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &wined3d_desc, + desc->ArraySize, levels, flags, (struct wined3d_sub_resource_data *)data, + texture, &d3d_texture2d_wined3d_parent_ops, &texture->wined3d_texture))) + { + WARN("Failed to create wined3d texture, hr %#lx.\n", hr); + free(texture); + wined3d_mutex_unlock(); + if (hr == WINED3DERR_NOTAVAILABLE || hr == WINED3DERR_INVALIDCALL) + hr = E_INVALIDARG; + return hr; + } + texture->desc.MipLevels = levels; } - texture->desc.MipLevels = levels;
needs_surface = desc->MipLevels == 1 && desc->ArraySize == 1; hr = d3d_device_create_dxgi_resource((IUnknown *)&device->ID3D10Device1_iface, diff --git a/dlls/dxgi/device.c b/dlls/dxgi/device.c index efa04e0f495..3f3a18e4639 100644 --- a/dlls/dxgi/device.c +++ b/dlls/dxgi/device.c @@ -21,6 +21,13 @@
WINE_DEFAULT_DEBUG_CHANNEL(dxgi);
+static void STDMETHODCALLTYPE dxgi_null_wined3d_object_destroyed(void *parent) {} + +static const struct wined3d_parent_ops dxgi_null_wined3d_parent_ops = +{ + dxgi_null_wined3d_object_destroyed, +}; + static inline struct dxgi_device *impl_from_IWineDXGIDevice(IWineDXGIDevice *iface) { return CONTAINING_RECORD(iface, struct dxgi_device, IWineDXGIDevice_iface); @@ -168,7 +175,7 @@ static HRESULT STDMETHODCALLTYPE dxgi_device_CreateSurface(IWineDXGIDevice *ifac const DXGI_SURFACE_DESC *desc, UINT surface_count, DXGI_USAGE usage, const DXGI_SHARED_RESOURCE *shared_resource, IDXGISurface **surface) { - struct wined3d_device_parent *device_parent; + struct dxgi_device *device = impl_from_IWineDXGIDevice(iface); struct wined3d_resource_desc surface_desc; IWineDXGIDeviceParent *dxgi_device_parent; HRESULT hr; @@ -185,8 +192,6 @@ static HRESULT STDMETHODCALLTYPE dxgi_device_CreateSurface(IWineDXGIDevice *ifac return E_FAIL; }
- device_parent = IWineDXGIDeviceParent_get_wined3d_device_parent(dxgi_device_parent); - surface_desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; surface_desc.format = wined3dformat_from_dxgi_format(desc->Format); wined3d_sample_desc_from_dxgi(&surface_desc.multisample_type, @@ -204,23 +209,22 @@ static HRESULT STDMETHODCALLTYPE dxgi_device_CreateSurface(IWineDXGIDevice *ifac for (i = 0; i < surface_count; ++i) { struct wined3d_texture *wined3d_texture; - IUnknown *parent;
- if (FAILED(hr = device_parent->ops->create_swapchain_texture(device_parent, - NULL, &surface_desc, 0, &wined3d_texture))) + if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &surface_desc, + 1, 1, 0, NULL, NULL, &dxgi_null_wined3d_parent_ops, &wined3d_texture))) { - ERR("Failed to create surface, hr %#lx.\n", hr); + ERR("Failed to create wined3d texture, hr %#lx.\n", hr); goto fail; }
- parent = wined3d_texture_get_parent(wined3d_texture); - hr = IUnknown_QueryInterface(parent, &IID_IDXGISurface, (void **)&surface[i]); - wined3d_texture_decref(wined3d_texture); - if (FAILED(hr)) + if (FAILED(hr = IWineDXGIDeviceParent_swapchain_texture_created( + dxgi_device_parent, wined3d_texture, 0, &surface[i]))) { - ERR("Surface should implement IDXGISurface.\n"); + wined3d_texture_decref(wined3d_texture); + ERR("Failed to create parent swapchain texture, hr %#lx.\n", hr); goto fail; } + wined3d_texture_decref(wined3d_texture);
TRACE("Created IDXGISurface %p (%u/%u).\n", surface[i], i + 1, surface_count); } diff --git a/include/wine/winedxgi.idl b/include/wine/winedxgi.idl index 64e4218204b..86447df55e9 100644 --- a/include/wine/winedxgi.idl +++ b/include/wine/winedxgi.idl @@ -62,6 +62,8 @@ interface IWineDXGIDevice : IDXGIDevice3 interface IWineDXGIDeviceParent : IUnknown { struct wined3d_device_parent *get_wined3d_device_parent(); + HRESULT swapchain_texture_created(struct wined3d_texture *texture, + unsigned int texture_flags, IDXGISurface **ret_surface); }
struct wine_dxgi_adapter_info
From: Zebediah Figura zfigura@codeweavers.com
Using the IWineDXGIDeviceParent::swapchain_texture_created() callback. --- dlls/d3d11/device.c | 41 ++--------------------------------------- dlls/dxgi/swapchain.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 39 deletions(-)
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index cf6ab388aec..caaa9b009ab 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -6898,49 +6898,12 @@ static HRESULT CDECL device_parent_create_swapchain_texture(struct wined3d_devic struct wined3d_texture **wined3d_texture) { struct d3d_device *device = device_from_wined3d_device_parent(device_parent); - struct d3d_texture2d *texture; - ID3D11Texture2D *texture_iface; - D3D11_TEXTURE2D_DESC desc; - HRESULT hr;
TRACE("device_parent %p, container_parent %p, wined3d_desc %p, texture_flags %#lx, wined3d_texture %p.\n", device_parent, container_parent, wined3d_desc, texture_flags, wined3d_texture);
- desc.Width = wined3d_desc->width; - desc.Height = wined3d_desc->height; - desc.MipLevels = 1; - desc.ArraySize = 1; - desc.Format = dxgi_format_from_wined3dformat(wined3d_desc->format); - desc.SampleDesc.Count = wined3d_desc->multisample_type ? wined3d_desc->multisample_type : 1; - desc.SampleDesc.Quality = wined3d_desc->multisample_quality; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = d3d11_bind_flags_from_wined3d(wined3d_desc->bind_flags); - desc.CPUAccessFlags = 0; - desc.MiscFlags = 0; - - if (texture_flags & WINED3D_TEXTURE_CREATE_GET_DC) - { - desc.MiscFlags |= D3D11_RESOURCE_MISC_GDI_COMPATIBLE; - texture_flags &= ~WINED3D_TEXTURE_CREATE_GET_DC; - } - - if (texture_flags) - FIXME("Unhandled flags %#lx.\n", texture_flags); - - if (FAILED(hr = d3d11_device_CreateTexture2D(&device->ID3D11Device2_iface, - &desc, NULL, &texture_iface))) - { - WARN("Failed to create 2D texture, hr %#lx.\n", hr); - return hr; - } - - texture = impl_from_ID3D11Texture2D(texture_iface); - - *wined3d_texture = texture->wined3d_texture; - wined3d_texture_incref(*wined3d_texture); - ID3D11Texture2D_Release(&texture->ID3D11Texture2D_iface); - - return S_OK; + return wined3d_texture_create(device->wined3d_device, wined3d_desc, 1, 1, + texture_flags, NULL, NULL, &d3d_null_wined3d_parent_ops, wined3d_texture); }
static const struct wined3d_device_parent_ops d3d_wined3d_device_parent_ops = diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index 910286b8c5f..5f310aef949 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -848,6 +848,41 @@ static const struct wined3d_swapchain_state_parent_ops d3d11_swapchain_state_par d3d11_swapchain_windowed_state_changed, };
+static HRESULT d3d11_swapchain_create_d3d11_textures(struct d3d11_swapchain *swapchain, + struct dxgi_device *device, struct wined3d_swapchain_desc *desc) +{ + IWineDXGIDeviceParent *dxgi_device_parent; + unsigned int texture_flags = 0; + unsigned int i; + HRESULT hr; + + if (FAILED(hr = IWineDXGIDevice_QueryInterface(&device->IWineDXGIDevice_iface, + &IID_IWineDXGIDeviceParent, (void **)&dxgi_device_parent))) + { + ERR("Device should implement IWineDXGIDeviceParent.\n"); + return E_FAIL; + } + + if (desc->flags & WINED3D_SWAPCHAIN_GDI_COMPATIBLE) + texture_flags |= WINED3D_TEXTURE_CREATE_GET_DC; + + for (i = 0; i < desc->backbuffer_count; ++i) + { + IDXGISurface *surface; + + if (FAILED(hr = IWineDXGIDeviceParent_swapchain_texture_created(dxgi_device_parent, + wined3d_swapchain_get_back_buffer(swapchain->wined3d_swapchain, i), texture_flags, &surface))) + { + ERR("Failed to create parent swapchain texture, hr %#lx.\n", hr); + break; + } + IDXGISurface_Release(surface); + } + + IWineDXGIDeviceParent_Release(dxgi_device_parent); + return hr; +} + HRESULT d3d11_swapchain_init(struct d3d11_swapchain *swapchain, struct dxgi_device *device, struct wined3d_swapchain_desc *desc) { @@ -891,6 +926,14 @@ HRESULT d3d11_swapchain_init(struct d3d11_swapchain *swapchain, struct dxgi_devi swapchain, &d3d11_swapchain_wined3d_parent_ops, &swapchain->wined3d_swapchain))) { WARN("Failed to create wined3d swapchain, hr %#lx.\n", hr); + if (hr == WINED3DERR_INVALIDCALL) + hr = E_INVALIDARG; + goto cleanup; + } + + if (FAILED(hr = d3d11_swapchain_create_d3d11_textures(swapchain, device, desc))) + { + ERR("Failed to create d3d11 textures, hr %#lx.\n", hr); goto cleanup; }
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/d3d9/d3d9_private.h | 4 ++-- dlls/d3d9/device.c | 4 +--- dlls/d3d9/surface.c | 9 ++++++++- 3 files changed, 11 insertions(+), 6 deletions(-)
diff --git a/dlls/d3d9/d3d9_private.h b/dlls/d3d9/d3d9_private.h index 7dc32e6c12f..dd9fd2a0039 100644 --- a/dlls/d3d9/d3d9_private.h +++ b/dlls/d3d9/d3d9_private.h @@ -179,11 +179,11 @@ 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; 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; -void surface_init(struct d3d9_surface *surface, struct wined3d_texture *wined3d_texture, - unsigned int sub_resource_idx, const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN; struct d3d9_surface *unsafe_impl_from_IDirect3DSurface9(IDirect3DSurface9 *iface) DECLSPEC_HIDDEN;
struct d3d9_vertexbuffer diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c index c6083d351e3..75861032c3a 100644 --- a/dlls/d3d9/device.c +++ b/dlls/d3d9/device.c @@ -4502,12 +4502,10 @@ static HRESULT CDECL device_parent_texture_sub_resource_created(struct wined3d_d { struct d3d9_surface *d3d_surface;
- if (!(d3d_surface = heap_alloc_zero(sizeof(*d3d_surface)))) + if (!(d3d_surface = d3d9_surface_create(wined3d_texture, sub_resource_idx, parent_ops))) return E_OUTOFMEMORY;
- surface_init(d3d_surface, wined3d_texture, sub_resource_idx, parent_ops); *parent = d3d_surface; - TRACE("Created surface %p.\n", d3d_surface); } else if (type == WINED3D_RTYPE_TEXTURE_3D) { diff --git a/dlls/d3d9/surface.c b/dlls/d3d9/surface.c index 810e4e00fb4..146cb8ce35c 100644 --- a/dlls/d3d9/surface.c +++ b/dlls/d3d9/surface.c @@ -347,10 +347,14 @@ static const struct wined3d_parent_ops d3d9_surface_wined3d_parent_ops = surface_wined3d_object_destroyed, };
-void surface_init(struct d3d9_surface *surface, struct wined3d_texture *wined3d_texture, +struct d3d9_surface *d3d9_surface_create(struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, const struct wined3d_parent_ops **parent_ops) { IDirect3DBaseTexture9 *texture; + struct d3d9_surface *surface; + + if (!(surface = heap_alloc_zero(sizeof(*surface)))) + return NULL;
surface->IDirect3DSurface9_iface.lpVtbl = &d3d9_surface_vtbl; d3d9_resource_init(&surface->resource); @@ -368,6 +372,9 @@ void surface_init(struct d3d9_surface *surface, struct wined3d_texture *wined3d_ }
*parent_ops = &d3d9_surface_wined3d_parent_ops; + + TRACE("Created surface %p.\n", surface); + return surface; }
static void STDMETHODCALLTYPE view_wined3d_object_destroyed(void *parent)
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;
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/d3d9/d3d9_private.h | 2 +- dlls/d3d9/device.c | 14 ++++++-------- dlls/d3d9/surface.c | 5 +++-- dlls/d3d9/swapchain.c | 6 ++++-- 4 files changed, 14 insertions(+), 13 deletions(-)
diff --git a/dlls/d3d9/d3d9_private.h b/dlls/d3d9/d3d9_private.h index 36cf8f68c83..53c73853e46 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) DECLSPEC_HIDDEN; + unsigned int sub_resource_idx, IUnknown *container) 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 ed88a4c2def..b5a16177e37 100644 --- a/dlls/d3d9/device.c +++ b/dlls/d3d9/device.c @@ -1148,7 +1148,8 @@ static HRESULT d3d9_device_reset(struct d3d9_device *device, 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))) + if ((surface = d3d9_surface_create(wined3d_texture_from_resource(resource), 0, + (IUnknown *)&device->IDirect3DDevice9Ex_iface))) surface->parent_device = &device->IDirect3DDevice9Ex_iface; } } @@ -1353,7 +1354,7 @@ static HRESULT WINAPI d3d9_device_CreateTexture(IDirect3DDevice9Ex *iface, levels = wined3d_texture_get_level_count(object->wined3d_texture); for (i = 0; i < levels; ++i) { - if (!d3d9_surface_create(object->wined3d_texture, i)) + if (!d3d9_surface_create(object->wined3d_texture, i, (IUnknown *)&object->IDirect3DBaseTexture9_iface)) { IDirect3DTexture9_Release(&object->IDirect3DBaseTexture9_iface); return E_OUTOFMEMORY; @@ -1456,7 +1457,7 @@ static HRESULT WINAPI d3d9_device_CreateCubeTexture(IDirect3DDevice9Ex *iface, levels = wined3d_texture_get_level_count(object->wined3d_texture); for (i = 0; i < levels * 6; ++i) { - if (!d3d9_surface_create(object->wined3d_texture, i)) + if (!d3d9_surface_create(object->wined3d_texture, i, (IUnknown *)&object->IDirect3DBaseTexture9_iface)) { IDirect3DTexture9_Release(&object->IDirect3DBaseTexture9_iface); return E_OUTOFMEMORY; @@ -1599,7 +1600,7 @@ static HRESULT d3d9_device_create_surface(struct d3d9_device *device, unsigned i return hr; }
- if (!(surface_impl = d3d9_surface_create(texture, 0))) + if (!(surface_impl = d3d9_surface_create(texture, 0, NULL))) { wined3d_texture_decref(texture); wined3d_mutex_unlock(); @@ -4564,11 +4565,8 @@ static HRESULT CDECL device_parent_create_swapchain_texture(struct wined3d_devic TRACE("device_parent %p, container_parent %p, desc %p, texture flags %#lx, texture %p.\n", device_parent, container_parent, desc, texture_flags, texture);
- if (container_parent == device_parent) - container_parent = &device->IDirect3DDevice9Ex_iface; - if (FAILED(hr = wined3d_texture_create(device->wined3d_device, desc, 1, 1, - texture_flags, NULL, container_parent, &d3d9_null_wined3d_parent_ops, texture))) + texture_flags, NULL, NULL, &d3d9_null_wined3d_parent_ops, texture))) { WARN("Failed to create texture, hr %#lx.\n", hr); return hr; diff --git a/dlls/d3d9/surface.c b/dlls/d3d9/surface.c index 4503c360120..df94aad3c59 100644 --- a/dlls/d3d9/surface.c +++ b/dlls/d3d9/surface.c @@ -347,7 +347,8 @@ 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) +struct d3d9_surface *d3d9_surface_create(struct wined3d_texture *wined3d_texture, + unsigned int sub_resource_idx, IUnknown *container) { IDirect3DBaseTexture9 *texture; struct d3d9_surface *surface; @@ -359,7 +360,7 @@ struct d3d9_surface *d3d9_surface_create(struct wined3d_texture *wined3d_texture d3d9_resource_init(&surface->resource); surface->resource.refcount = 0; list_init(&surface->rtv_entry); - surface->container = wined3d_texture_get_parent(wined3d_texture); + surface->container = container; surface->wined3d_texture = wined3d_texture; surface->sub_resource_idx = sub_resource_idx;
diff --git a/dlls/d3d9/swapchain.c b/dlls/d3d9/swapchain.c index 951fee75015..0c8b12dce91 100644 --- a/dlls/d3d9/swapchain.c +++ b/dlls/d3d9/swapchain.c @@ -411,7 +411,8 @@ HRESULT d3d9_swapchain_create(struct d3d9_device *device, struct wined3d_swapcha
for (i = 0; i < desc->backbuffer_count; ++i) { - if (!(surface = d3d9_surface_create(wined3d_swapchain_get_back_buffer(object->wined3d_swapchain, i), 0))) + if (!(surface = d3d9_surface_create(wined3d_swapchain_get_back_buffer(object->wined3d_swapchain, i), 0, + (IUnknown *)&object->IDirect3DSwapChain9Ex_iface))) { IDirect3DSwapChain9Ex_Release(&object->IDirect3DSwapChain9Ex_iface); return E_OUTOFMEMORY; @@ -424,7 +425,8 @@ HRESULT d3d9_swapchain_create(struct d3d9_device *device, struct wined3d_swapcha { struct wined3d_resource *resource = wined3d_rendertarget_view_get_resource(wined3d_dsv);
- if (!(surface = d3d9_surface_create(wined3d_texture_from_resource(resource), 0))) + if (!(surface = d3d9_surface_create(wined3d_texture_from_resource(resource), 0, + (IUnknown *)&device->IDirect3DDevice9Ex_iface))) { IDirect3DSwapChain9Ex_Release(&object->IDirect3DSwapChain9Ex_iface); return E_OUTOFMEMORY;
Couple comments, but I'm not going to hold it for those reasons.. I'm not a fan of the 'swapchain_texture_created' naming choice, I think I'd name it more imperatively, maybe 'register_swapchain_texture'. Commit message 'd3d9: Move surface allocation to d3d9_surface_init().' should probably say 'd3d9_surface_create()' instead.
This merge request was approved by Jan Sikorski.