[PATCH v2 0/5] MR2676: dxgi, d3d9: Create swapchain textures from wined3d_swapchain_get_back_buffer() instead of using a callback.
-- v2: d3d9: Pass the container to d3d9_surface_create(). d3d9: Create sub-resource surfaces manually. d3d9: Move surface allocation to d3d9_surface_create(). dxgi: Create d3d11 swapchain textures directly from d3d11_swapchain_init(). dxgi: Introduce IWineDXGIDeviceParent::register_swapchain_texture() and use it in IDXGIDevice::CreateSurface(). https://gitlab.winehq.org/wine/wine/-/merge_requests/2676
From: Zebediah Figura <zfigura(a)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..01f5599c7d0 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_register_swapchain_texture(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_register_swapchain_texture, }; 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..f6411f3e975 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_register_swapchain_texture( + 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..fff00dead73 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 register_swapchain_texture(struct wined3d_texture *texture, + unsigned int texture_flags, IDXGISurface **ret_surface); } struct wine_dxgi_adapter_info -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/2676
From: Zebediah Figura <zfigura(a)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 01f5599c7d0..4cf066ef945 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; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/2676
From: Zebediah Figura <zfigura(a)codeweavers.com> Renamed from d3d9_surface_init() accordingly. --- 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) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/2676
From: Zebediah Figura <zfigura(a)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; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/2676
From: Zebediah Figura <zfigura(a)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; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/2676
Hi, It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated. The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=132221 Your paranoid android. === debian11 (build log) === /home/winetest/tools/testbot/var/wine-win32/../wine/dlls/dxgi/swapchain.c:873: undefined reference to `IWineDXGIDeviceParent_swapchain_texture_created' collect2: error: ld returned 1 exit status Task: The win32 Wine build failed === debian11b (build log) === /home/winetest/tools/testbot/var/wine-wow64/../wine/dlls/dxgi/swapchain.c:873: undefined reference to `IWineDXGIDeviceParent_swapchain_texture_created' collect2: error: ld returned 1 exit status Task: The wow64 Wine build failed
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.
Agreed on both counts; I've pushed these changes. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/2676#note_31258
participants (3)
-
Marvin -
Zebediah Figura -
Zebediah Figura (@zfigura)