[PATCH 3/7] dxgi: Create DXGI resource object, optionally supporting surface interfaces.

Nikolay Sivov wine at gitlab.winehq.org
Thu Jun 9 02:22:38 CDT 2022


From: Nikolay Sivov <nsivov at codeweavers.com>

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/d3d11/d3d11_private.h |   4 +-
 dlls/d3d11/tests/d3d11.c   |   7 -
 dlls/d3d11/texture.c       | 130 ++++++------
 dlls/dxgi/Makefile.in      |   2 +-
 dlls/dxgi/device.c         |  24 +--
 dlls/dxgi/dxgi_private.h   |  11 +-
 dlls/dxgi/resource.c       | 423 +++++++++++++++++++++++++++++++++++++
 dlls/dxgi/surface.c        | 296 --------------------------
 dlls/dxgi/tests/dxgi.c     |  32 ++-
 include/wine/winedxgi.idl  |   7 +-
 10 files changed, 525 insertions(+), 411 deletions(-)
 create mode 100644 dlls/dxgi/resource.c
 delete mode 100644 dlls/dxgi/surface.c

diff --git a/dlls/d3d11/d3d11_private.h b/dlls/d3d11/d3d11_private.h
index 29a01dd91ad..4e4efcae098 100644
--- a/dlls/d3d11/d3d11_private.h
+++ b/dlls/d3d11/d3d11_private.h
@@ -130,7 +130,7 @@ struct d3d_texture1d
     LONG refcount;
 
     struct wined3d_private_store private_store;
-    IUnknown *dxgi_surface;
+    IUnknown *dxgi_resource;
     struct wined3d_texture *wined3d_texture;
     D3D11_TEXTURE1D_DESC desc;
     ID3D11Device2 *device;
@@ -149,7 +149,7 @@ struct d3d_texture2d
     LONG refcount;
 
     struct wined3d_private_store private_store;
-    IUnknown *dxgi_surface;
+    IUnknown *dxgi_resource;
     struct wined3d_texture *wined3d_texture;
     D3D11_TEXTURE2D_DESC desc;
     ID3D11Device2 *device;
diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c
index 9c72de054c4..0c741283da5 100644
--- a/dlls/d3d11/tests/d3d11.c
+++ b/dlls/d3d11/tests/d3d11.c
@@ -2615,17 +2615,14 @@ static void test_texture1d_interfaces(void)
 
     hr = ID3D11Device_CreateTexture1D(device, &desc, NULL, &texture);
     ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
-    todo_wine
     test_dxgi_resource(texture);
     ID3D11Texture1D_Release(texture);
 
     desc.MipLevels = 0;
     hr = ID3D11Device_CreateTexture1D(device, &desc, NULL, &texture);
     ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
-    todo_wine
     test_dxgi_resource(texture);
     check_interface(texture, &IID_IDXGISurface, FALSE, FALSE);
-    todo_wine
     check_interface(texture, &IID_IDXGIResource, TRUE, FALSE);
     hr = check_interface(texture, &IID_ID3D10Texture1D, TRUE, TRUE); /* Not available on all Windows versions. */
     ID3D11Texture1D_Release(texture);
@@ -3015,9 +3012,7 @@ static void test_texture2d_interfaces(void)
     hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &texture);
     ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
     check_interface(texture, &IID_IDXGISurface, TRUE, FALSE);
-    todo_wine
     check_interface(texture, &IID_IDXGIResource, TRUE, FALSE);
-    todo_wine
     test_dxgi_resource(texture);
     ID3D11Texture2D_Release(texture);
 
@@ -3025,9 +3020,7 @@ static void test_texture2d_interfaces(void)
     hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &texture);
     ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
     check_interface(texture, &IID_IDXGISurface, FALSE, FALSE);
-    todo_wine
     check_interface(texture, &IID_IDXGIResource, TRUE, FALSE);
-    todo_wine
     test_dxgi_resource(texture);
     hr = check_interface(texture, &IID_ID3D10Texture2D, TRUE, TRUE); /* Not available on all Windows versions. */
     ID3D11Texture2D_Release(texture);
diff --git a/dlls/d3d11/texture.c b/dlls/d3d11/texture.c
index 09ba1136f97..b3f4d7132be 100644
--- a/dlls/d3d11/texture.c
+++ b/dlls/d3d11/texture.c
@@ -54,10 +54,10 @@ static HRESULT STDMETHODCALLTYPE d3d11_texture1d_QueryInterface(ID3D11Texture1D
         return S_OK;
     }
 
-    if (texture->dxgi_surface)
+    if (texture->dxgi_resource)
     {
-        TRACE("Forwarding to dxgi surface.\n");
-        return IUnknown_QueryInterface(texture->dxgi_surface, iid, out);
+        TRACE("Forwarding to dxgi resource.\n");
+        return IUnknown_QueryInterface(texture->dxgi_resource, iid, out);
     }
 
     WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
@@ -120,8 +120,8 @@ static HRESULT STDMETHODCALLTYPE d3d11_texture1d_GetPrivateData(ID3D11Texture1D
 
     TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
 
-    if (texture->dxgi_surface
-            && SUCCEEDED(IUnknown_QueryInterface(texture->dxgi_surface, &IID_IDXGISurface, (void **)&dxgi_surface)))
+    if (texture->dxgi_resource
+            && SUCCEEDED(IUnknown_QueryInterface(texture->dxgi_resource, &IID_IDXGISurface, (void **)&dxgi_surface)))
     {
         hr = IDXGISurface_GetPrivateData(dxgi_surface, guid, data_size, data);
         IDXGISurface_Release(dxgi_surface);
@@ -140,8 +140,8 @@ static HRESULT STDMETHODCALLTYPE d3d11_texture1d_SetPrivateData(ID3D11Texture1D
 
     TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
 
-    if (texture->dxgi_surface
-            && SUCCEEDED(IUnknown_QueryInterface(texture->dxgi_surface, &IID_IDXGISurface, (void **)&dxgi_surface)))
+    if (texture->dxgi_resource
+            && SUCCEEDED(IUnknown_QueryInterface(texture->dxgi_resource, &IID_IDXGISurface, (void **)&dxgi_surface)))
     {
         hr = IDXGISurface_SetPrivateData(dxgi_surface, guid, data_size, data);
         IDXGISurface_Release(dxgi_surface);
@@ -160,8 +160,8 @@ static HRESULT STDMETHODCALLTYPE d3d11_texture1d_SetPrivateDataInterface(ID3D11T
 
     TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
 
-    if (texture->dxgi_surface
-            && SUCCEEDED(IUnknown_QueryInterface(texture->dxgi_surface, &IID_IDXGISurface, (void **)&dxgi_surface)))
+    if (texture->dxgi_resource
+            && SUCCEEDED(IUnknown_QueryInterface(texture->dxgi_resource, &IID_IDXGISurface, (void **)&dxgi_surface)))
     {
         hr = IDXGISurface_SetPrivateDataInterface(dxgi_surface, guid, data);
         IDXGISurface_Release(dxgi_surface);
@@ -256,8 +256,8 @@ static void STDMETHODCALLTYPE d3d_texture1d_wined3d_object_released(void *parent
 {
     struct d3d_texture1d *texture = parent;
 
-    if (texture->dxgi_surface)
-        IUnknown_Release(texture->dxgi_surface);
+    if (texture->dxgi_resource)
+        IUnknown_Release(texture->dxgi_resource);
     wined3d_private_store_cleanup(&texture->private_store);
     heap_free(texture);
 }
@@ -425,7 +425,9 @@ HRESULT d3d_texture1d_create(struct d3d_device *device, const D3D11_TEXTURE1D_DE
 {
     struct wined3d_resource_desc wined3d_desc;
     struct d3d_texture1d *texture;
+    IWineDXGIDevice *wine_device;
     unsigned int levels;
+    BOOL needs_surface;
     DWORD flags = 0;
     HRESULT hr;
 
@@ -472,30 +474,26 @@ HRESULT d3d_texture1d_create(struct d3d_device *device, const D3D11_TEXTURE1D_DE
         return hr;
     }
 
-    if (desc->MipLevels == 1 && desc->ArraySize == 1)
+    if (FAILED(hr = ID3D10Device1_QueryInterface(&device->ID3D10Device1_iface, &IID_IWineDXGIDevice,
+            (void **)&wine_device)))
     {
-        IWineDXGIDevice *wine_device;
-
-        if (FAILED(hr = ID3D10Device1_QueryInterface(&device->ID3D10Device1_iface, &IID_IWineDXGIDevice,
-                (void **)&wine_device)))
-        {
-            ERR("Device should implement IWineDXGIDevice.\n");
-            wined3d_texture_decref(texture->wined3d_texture);
-            wined3d_mutex_unlock();
-            return E_FAIL;
-        }
-
-        hr = IWineDXGIDevice_create_surface(wine_device, texture->wined3d_texture, 0, NULL,
-                (IUnknown *)&texture->ID3D10Texture1D_iface, (void **)&texture->dxgi_surface);
-        IWineDXGIDevice_Release(wine_device);
-        if (FAILED(hr))
-        {
-            ERR("Failed to create DXGI surface, returning %#.lx\n", hr);
-            texture->dxgi_surface = NULL;
-            wined3d_texture_decref(texture->wined3d_texture);
-            wined3d_mutex_unlock();
-            return hr;
-        }
+        ERR("Device should implement IWineDXGIDevice.\n");
+        wined3d_texture_decref(texture->wined3d_texture);
+        wined3d_mutex_unlock();
+        return E_FAIL;
+    }
+
+    needs_surface = desc->MipLevels == 1 && desc->ArraySize == 1;
+    hr = IWineDXGIDevice_create_resource(wine_device, wined3d_texture_get_resource(texture->wined3d_texture),
+            0, NULL, (IUnknown *)&texture->ID3D10Texture1D_iface, needs_surface, (void **)&texture->dxgi_resource);
+    IWineDXGIDevice_Release(wine_device);
+    if (FAILED(hr))
+    {
+        ERR("Failed to create DXGI resource, returning %#.lx\n", hr);
+        texture->dxgi_resource = NULL;
+        wined3d_texture_decref(texture->wined3d_texture);
+        wined3d_mutex_unlock();
+        return hr;
     }
     wined3d_mutex_unlock();
 
@@ -533,10 +531,10 @@ static HRESULT STDMETHODCALLTYPE d3d11_texture2d_QueryInterface(ID3D11Texture2D
         return S_OK;
     }
 
-    if (texture->dxgi_surface)
+    if (texture->dxgi_resource)
     {
-        TRACE("Forwarding to dxgi surface.\n");
-        return IUnknown_QueryInterface(texture->dxgi_surface, riid, object);
+        TRACE("Forwarding to dxgi resource.\n");
+        return IUnknown_QueryInterface(texture->dxgi_resource, riid, object);
     }
 
     WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
@@ -599,8 +597,8 @@ static HRESULT STDMETHODCALLTYPE d3d11_texture2d_GetPrivateData(ID3D11Texture2D
 
     TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
 
-    if (texture->dxgi_surface
-            && SUCCEEDED(IUnknown_QueryInterface(texture->dxgi_surface, &IID_IDXGISurface, (void **)&dxgi_surface)))
+    if (texture->dxgi_resource
+            && SUCCEEDED(IUnknown_QueryInterface(texture->dxgi_resource, &IID_IDXGISurface, (void **)&dxgi_surface)))
     {
         hr = IDXGISurface_GetPrivateData(dxgi_surface, guid, data_size, data);
         IDXGISurface_Release(dxgi_surface);
@@ -619,8 +617,8 @@ static HRESULT STDMETHODCALLTYPE d3d11_texture2d_SetPrivateData(ID3D11Texture2D
 
     TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
 
-    if (texture->dxgi_surface
-            && SUCCEEDED(IUnknown_QueryInterface(texture->dxgi_surface, &IID_IDXGISurface, (void **)&dxgi_surface)))
+    if (texture->dxgi_resource
+            && SUCCEEDED(IUnknown_QueryInterface(texture->dxgi_resource, &IID_IDXGISurface, (void **)&dxgi_surface)))
     {
         hr = IDXGISurface_SetPrivateData(dxgi_surface, guid, data_size, data);
         IDXGISurface_Release(dxgi_surface);
@@ -639,8 +637,8 @@ static HRESULT STDMETHODCALLTYPE d3d11_texture2d_SetPrivateDataInterface(ID3D11T
 
     TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
 
-    if (texture->dxgi_surface
-            && SUCCEEDED(IUnknown_QueryInterface(texture->dxgi_surface, &IID_IDXGISurface, (void **)&dxgi_surface)))
+    if (texture->dxgi_resource
+            && SUCCEEDED(IUnknown_QueryInterface(texture->dxgi_resource, &IID_IDXGISurface, (void **)&dxgi_surface)))
     {
         hr = IDXGISurface_SetPrivateDataInterface(dxgi_surface, guid, data);
         IDXGISurface_Release(dxgi_surface);
@@ -750,7 +748,7 @@ static void STDMETHODCALLTYPE d3d_texture2d_wined3d_object_released(void *parent
 {
     struct d3d_texture2d *texture = parent;
 
-    if (texture->dxgi_surface) IUnknown_Release(texture->dxgi_surface);
+    if (texture->dxgi_resource) IUnknown_Release(texture->dxgi_resource);
     wined3d_private_store_cleanup(&texture->private_store);
     heap_free(texture);
 }
@@ -965,7 +963,9 @@ HRESULT d3d_texture2d_create(struct d3d_device *device, const D3D11_TEXTURE2D_DE
 {
     struct wined3d_resource_desc wined3d_desc;
     struct d3d_texture2d *texture;
+    IWineDXGIDevice *wine_device;
     unsigned int levels;
+    BOOL needs_surface;
     DWORD flags = 0;
     HRESULT hr;
 
@@ -1019,30 +1019,26 @@ HRESULT d3d_texture2d_create(struct d3d_device *device, const D3D11_TEXTURE2D_DE
     }
     texture->desc.MipLevels = levels;
 
-    if (desc->MipLevels == 1 && desc->ArraySize == 1)
+    if (FAILED(hr = ID3D10Device1_QueryInterface(&device->ID3D10Device1_iface, &IID_IWineDXGIDevice,
+            (void **)&wine_device)))
     {
-        IWineDXGIDevice *wine_device;
-
-        if (FAILED(hr = ID3D10Device1_QueryInterface(&device->ID3D10Device1_iface, &IID_IWineDXGIDevice,
-                (void **)&wine_device)))
-        {
-            ERR("Device should implement IWineDXGIDevice.\n");
-            wined3d_texture_decref(texture->wined3d_texture);
-            wined3d_mutex_unlock();
-            return E_FAIL;
-        }
-
-        hr = IWineDXGIDevice_create_surface(wine_device, texture->wined3d_texture, 0, NULL,
-                (IUnknown *)&texture->ID3D10Texture2D_iface, (void **)&texture->dxgi_surface);
-        IWineDXGIDevice_Release(wine_device);
-        if (FAILED(hr))
-        {
-            ERR("Failed to create DXGI surface, returning %#.lx\n", hr);
-            texture->dxgi_surface = NULL;
-            wined3d_texture_decref(texture->wined3d_texture);
-            wined3d_mutex_unlock();
-            return hr;
-        }
+        ERR("Device should implement IWineDXGIDevice.\n");
+        wined3d_texture_decref(texture->wined3d_texture);
+        wined3d_mutex_unlock();
+        return E_FAIL;
+    }
+
+    needs_surface = desc->MipLevels == 1 && desc->ArraySize == 1;
+    hr = IWineDXGIDevice_create_resource(wine_device, wined3d_texture_get_resource(texture->wined3d_texture),
+            0, NULL, (IUnknown *)&texture->ID3D10Texture2D_iface, needs_surface, (void **)&texture->dxgi_resource);
+    IWineDXGIDevice_Release(wine_device);
+    if (FAILED(hr))
+    {
+        ERR("Failed to create DXGI resource, returning %#.lx\n", hr);
+        texture->dxgi_resource = NULL;
+        wined3d_texture_decref(texture->wined3d_texture);
+        wined3d_mutex_unlock();
+        return hr;
     }
     wined3d_mutex_unlock();
 
diff --git a/dlls/dxgi/Makefile.in b/dlls/dxgi/Makefile.in
index db52f49a68a..dea2e4b58f7 100644
--- a/dlls/dxgi/Makefile.in
+++ b/dlls/dxgi/Makefile.in
@@ -9,7 +9,7 @@ C_SRCS = \
 	dxgi_main.c \
 	factory.c \
 	output.c \
-	surface.c \
+	resource.c \
 	swapchain.c \
 	utils.c
 
diff --git a/dlls/dxgi/device.c b/dlls/dxgi/device.c
index b9c5ff177c9..efa04e0f495 100644
--- a/dlls/dxgi/device.c
+++ b/dlls/dxgi/device.c
@@ -326,31 +326,31 @@ static void STDMETHODCALLTYPE dxgi_device_Trim(IWineDXGIDevice *iface)
 
 /* IWineDXGIDevice methods */
 
-static HRESULT STDMETHODCALLTYPE dxgi_device_create_surface(IWineDXGIDevice *iface,
-        struct wined3d_texture *wined3d_texture, DXGI_USAGE usage,
-        const DXGI_SHARED_RESOURCE *shared_resource, IUnknown *outer, void **surface)
+static HRESULT STDMETHODCALLTYPE dxgi_device_create_resource(IWineDXGIDevice *iface,
+        struct wined3d_resource *wined3d_resource, DXGI_USAGE usage,
+        const DXGI_SHARED_RESOURCE *shared_resource, IUnknown *outer, BOOL needs_surface, void **resource)
 {
-    struct dxgi_surface *object;
+    struct dxgi_resource *object;
     HRESULT hr;
 
-    TRACE("iface %p, wined3d_texture %p, usage %#x, shared_resource %p, outer %p, surface %p.\n",
-            iface, wined3d_texture, usage, shared_resource, outer, surface);
+    TRACE("iface %p, wined3d_resource %p, usage %#x, shared_resource %p, outer %p, surface %p.\n",
+            iface, wined3d_resource, usage, shared_resource, outer, resource);
 
     if (!(object = heap_alloc_zero(sizeof(*object))))
     {
-        ERR("Failed to allocate DXGI surface object memory.\n");
+        ERR("Failed to allocate DXGI resource object memory.\n");
         return E_OUTOFMEMORY;
     }
 
-    if (FAILED(hr = dxgi_surface_init(object, (IDXGIDevice *)iface, outer, wined3d_texture)))
+    if (FAILED(hr = dxgi_resource_init(object, (IDXGIDevice *)iface, outer, needs_surface, wined3d_resource)))
     {
-        WARN("Failed to initialize surface, hr %#lx.\n", hr);
+        WARN("Failed to initialize resource, hr %#lx.\n", hr);
         heap_free(object);
         return hr;
     }
 
-    TRACE("Created IDXGISurface %p.\n", object);
-    *surface = outer ? &object->IUnknown_iface : (IUnknown *)&object->IDXGISurface1_iface;
+    TRACE("Created resource %p.\n", object);
+    *resource = outer ? &object->IUnknown_iface : (IUnknown *)&object->IDXGIResource_iface;
 
     return S_OK;
 }
@@ -382,7 +382,7 @@ static const struct IWineDXGIDeviceVtbl dxgi_device_vtbl =
     /* IDXGIDevice3 methods */
     dxgi_device_Trim,
     /* IWineDXGIDevice methods */
-    dxgi_device_create_surface,
+    dxgi_device_create_resource,
 };
 
 static inline struct dxgi_device *impl_from_IWineDXGISwapChainFactory(IWineDXGISwapChainFactory *iface)
diff --git a/dlls/dxgi/dxgi_private.h b/dlls/dxgi/dxgi_private.h
index b3cd1164b90..dd17e39eca6 100644
--- a/dlls/dxgi/dxgi_private.h
+++ b/dlls/dxgi/dxgi_private.h
@@ -194,20 +194,21 @@ HRESULT d3d12_swapchain_create(IWineDXGIFactory *factory, ID3D12CommandQueue *qu
 
 BOOL dxgi_validate_swapchain_desc(const DXGI_SWAP_CHAIN_DESC1 *desc) DECLSPEC_HIDDEN;
 
-/* IDXGISurface */
-struct dxgi_surface
+/* IDXGISurface/IDXGIResource */
+struct dxgi_resource
 {
     IDXGISurface1 IDXGISurface1_iface;
+    IDXGIResource IDXGIResource_iface;
     IUnknown IUnknown_iface;
     IUnknown *outer_unknown;
     LONG refcount;
     struct wined3d_private_store private_store;
     IDXGIDevice *device;
-    struct wined3d_texture *wined3d_texture;
+    struct wined3d_resource *wined3d_resource;
     HDC dc;
 };
 
-HRESULT dxgi_surface_init(struct dxgi_surface *surface, IDXGIDevice *device,
-        IUnknown *outer, struct wined3d_texture *wined3d_texture) DECLSPEC_HIDDEN;
+HRESULT dxgi_resource_init(struct dxgi_resource *resource, IDXGIDevice *device,
+        IUnknown *outer, BOOL needs_surface, struct wined3d_resource *wined3d_resource) DECLSPEC_HIDDEN;
 
 #endif /* __WINE_DXGI_PRIVATE_H */
diff --git a/dlls/dxgi/resource.c b/dlls/dxgi/resource.c
new file mode 100644
index 00000000000..86ad4ec3f09
--- /dev/null
+++ b/dlls/dxgi/resource.c
@@ -0,0 +1,423 @@
+/*
+ * Copyright 2009 Henri Verbeet for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *
+ */
+
+#include "dxgi_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(dxgi);
+
+/* Inner IUnknown methods */
+
+static inline struct dxgi_resource *impl_from_IUnknown(IUnknown *iface)
+{
+    return CONTAINING_RECORD(iface, struct dxgi_resource, IUnknown_iface);
+}
+
+static HRESULT STDMETHODCALLTYPE dxgi_resource_inner_QueryInterface(IUnknown *iface, REFIID riid, void **out)
+{
+    struct dxgi_resource *resource = impl_from_IUnknown(iface);
+
+    TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
+
+    if ((IsEqualGUID(riid, &IID_IDXGISurface1)
+            || IsEqualGUID(riid, &IID_IDXGISurface)) && resource->IDXGISurface1_iface.lpVtbl != NULL)
+    {
+        IDXGISurface1_AddRef(&resource->IDXGISurface1_iface);
+        *out = &resource->IDXGISurface1_iface;
+        return S_OK;
+    }
+    else if (IsEqualGUID(riid, &IID_IDXGIResource)
+            || IsEqualGUID(riid, &IID_IDXGIDeviceSubObject)
+            || IsEqualGUID(riid, &IID_IDXGIObject)
+            || IsEqualGUID(riid, &IID_IUnknown))
+    {
+        IDXGIResource_AddRef(&resource->IDXGIResource_iface);
+        *out = &resource->IDXGIResource_iface;
+        return S_OK;
+    }
+
+    WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid));
+
+    *out = NULL;
+    return E_NOINTERFACE;
+}
+
+static ULONG STDMETHODCALLTYPE dxgi_resource_inner_AddRef(IUnknown *iface)
+{
+    struct dxgi_resource *resource = impl_from_IUnknown(iface);
+    ULONG refcount = InterlockedIncrement(&resource->refcount);
+
+    TRACE("%p increasing refcount to %lu.\n", resource, refcount);
+
+    return refcount;
+}
+
+static ULONG STDMETHODCALLTYPE dxgi_resource_inner_Release(IUnknown *iface)
+{
+    struct dxgi_resource *resource = impl_from_IUnknown(iface);
+    ULONG refcount = InterlockedDecrement(&resource->refcount);
+
+    TRACE("%p decreasing refcount to %lu.\n", resource, refcount);
+
+    if (!refcount)
+    {
+        wined3d_private_store_cleanup(&resource->private_store);
+        heap_free(resource);
+    }
+
+    return refcount;
+}
+
+static inline struct dxgi_resource *impl_from_IDXGISurface1(IDXGISurface1 *iface)
+{
+    return CONTAINING_RECORD(iface, struct dxgi_resource, IDXGISurface1_iface);
+}
+
+/* IUnknown methods */
+
+static HRESULT STDMETHODCALLTYPE dxgi_surface_QueryInterface(IDXGISurface1 *iface, REFIID riid,
+        void **object)
+{
+    struct dxgi_resource *resource = impl_from_IDXGISurface1(iface);
+    return IDXGIResource_QueryInterface(&resource->IDXGIResource_iface, riid, object);
+}
+
+static ULONG STDMETHODCALLTYPE dxgi_surface_AddRef(IDXGISurface1 *iface)
+{
+    struct dxgi_resource *resource = impl_from_IDXGISurface1(iface);
+    return IDXGIResource_AddRef(&resource->IDXGIResource_iface);
+}
+
+static ULONG STDMETHODCALLTYPE dxgi_surface_Release(IDXGISurface1 *iface)
+{
+    struct dxgi_resource *resource = impl_from_IDXGISurface1(iface);
+    return IDXGIResource_Release(&resource->IDXGIResource_iface);
+}
+
+/* IDXGIObject methods */
+
+static HRESULT STDMETHODCALLTYPE dxgi_surface_SetPrivateData(IDXGISurface1 *iface,
+        REFGUID guid, UINT data_size, const void *data)
+{
+    struct dxgi_resource *resource = impl_from_IDXGISurface1(iface);
+    return IDXGIResource_SetPrivateData(&resource->IDXGIResource_iface, guid, data_size, data);
+}
+
+static HRESULT STDMETHODCALLTYPE dxgi_surface_SetPrivateDataInterface(IDXGISurface1 *iface,
+        REFGUID guid, const IUnknown *object)
+{
+    struct dxgi_resource *resource = impl_from_IDXGISurface1(iface);
+    return IDXGIResource_SetPrivateDataInterface(&resource->IDXGIResource_iface, guid, object);
+}
+
+static HRESULT STDMETHODCALLTYPE dxgi_surface_GetPrivateData(IDXGISurface1 *iface,
+        REFGUID guid, UINT *data_size, void *data)
+{
+    struct dxgi_resource *resource = impl_from_IDXGISurface1(iface);
+    return IDXGIResource_GetPrivateData(&resource->IDXGIResource_iface, guid, data_size, data);
+}
+
+static HRESULT STDMETHODCALLTYPE dxgi_surface_GetParent(IDXGISurface1 *iface, REFIID riid, void **parent)
+{
+    struct dxgi_resource *resource = impl_from_IDXGISurface1(iface);
+    return IDXGIResource_GetParent(&resource->IDXGIResource_iface, riid, parent);
+}
+
+/* IDXGIDeviceSubObject methods */
+
+static HRESULT STDMETHODCALLTYPE dxgi_surface_GetDevice(IDXGISurface1 *iface, REFIID riid, void **device)
+{
+    struct dxgi_resource *resource = impl_from_IDXGISurface1(iface);
+    return IDXGIResource_GetDevice(&resource->IDXGIResource_iface, riid, device);
+}
+
+/* IDXGISurface methods */
+static HRESULT STDMETHODCALLTYPE dxgi_surface_GetDesc(IDXGISurface1 *iface, DXGI_SURFACE_DESC *desc)
+{
+    struct dxgi_resource *resource = impl_from_IDXGISurface1(iface);
+    struct wined3d_resource_desc wined3d_desc;
+
+    TRACE("iface %p, desc %p.\n", iface, desc);
+
+    wined3d_mutex_lock();
+    wined3d_resource_get_desc(resource->wined3d_resource, &wined3d_desc);
+    wined3d_mutex_unlock();
+    desc->Width = wined3d_desc.width;
+    desc->Height = wined3d_desc.height;
+    desc->Format = dxgi_format_from_wined3dformat(wined3d_desc.format);
+    dxgi_sample_desc_from_wined3d(&desc->SampleDesc, wined3d_desc.multisample_type, wined3d_desc.multisample_quality);
+
+    return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE dxgi_surface_Map(IDXGISurface1 *iface, DXGI_MAPPED_RECT *mapped_rect, UINT flags)
+{
+    struct dxgi_resource *resource = impl_from_IDXGISurface1(iface);
+    struct wined3d_map_desc wined3d_map_desc;
+    DWORD wined3d_map_flags = 0;
+    HRESULT hr;
+
+    TRACE("iface %p, mapped_rect %p, flags %#x.\n", iface, mapped_rect, flags);
+
+    if (flags & DXGI_MAP_READ)
+        wined3d_map_flags |= WINED3D_MAP_READ;
+    if (flags & DXGI_MAP_WRITE)
+        wined3d_map_flags |= WINED3D_MAP_WRITE;
+    if (flags & DXGI_MAP_DISCARD)
+        wined3d_map_flags |= WINED3D_MAP_DISCARD;
+
+    if (SUCCEEDED(hr = wined3d_resource_map(resource->wined3d_resource, 0, &wined3d_map_desc, NULL, wined3d_map_flags)))
+    {
+        mapped_rect->Pitch = wined3d_map_desc.row_pitch;
+        mapped_rect->pBits = wined3d_map_desc.data;
+    }
+
+    return hr;
+}
+
+static HRESULT STDMETHODCALLTYPE dxgi_surface_Unmap(IDXGISurface1 *iface)
+{
+    struct dxgi_resource *resource = impl_from_IDXGISurface1(iface);
+
+    TRACE("iface %p.\n", iface);
+    wined3d_resource_unmap(resource->wined3d_resource, 0);
+    return S_OK;
+}
+
+/* IDXGISurface1 methods */
+static HRESULT STDMETHODCALLTYPE dxgi_surface_GetDC(IDXGISurface1 *iface, BOOL discard, HDC *hdc)
+{
+    struct dxgi_resource *resource = impl_from_IDXGISurface1(iface);
+    HRESULT hr;
+
+    FIXME("iface %p, discard %d, hdc %p semi-stub!\n", iface, discard, hdc);
+
+    if (!hdc)
+        return E_INVALIDARG;
+
+    wined3d_mutex_lock();
+    hr = wined3d_texture_get_dc(wined3d_texture_from_resource(resource->wined3d_resource), 0, hdc);
+    wined3d_mutex_unlock();
+
+    if (SUCCEEDED(hr))
+       resource->dc = *hdc;
+
+    return hr;
+}
+
+static HRESULT STDMETHODCALLTYPE dxgi_surface_ReleaseDC(IDXGISurface1 *iface, RECT *dirty_rect)
+{
+    struct dxgi_resource *resource = impl_from_IDXGISurface1(iface);
+    HRESULT hr;
+
+    TRACE("iface %p, rect %s\n", iface, wine_dbgstr_rect(dirty_rect));
+
+    if (!IsRectEmpty(dirty_rect))
+        FIXME("dirty rectangle is ignored.\n");
+
+    wined3d_mutex_lock();
+    hr = wined3d_texture_release_dc(wined3d_texture_from_resource(resource->wined3d_resource), 0, resource->dc);
+    wined3d_mutex_unlock();
+
+    return hr;
+}
+
+static const struct IDXGISurface1Vtbl dxgi_surface_vtbl =
+{
+    /* IUnknown methods */
+    dxgi_surface_QueryInterface,
+    dxgi_surface_AddRef,
+    dxgi_surface_Release,
+    /* IDXGIObject methods */
+    dxgi_surface_SetPrivateData,
+    dxgi_surface_SetPrivateDataInterface,
+    dxgi_surface_GetPrivateData,
+    dxgi_surface_GetParent,
+    /* IDXGIDeviceSubObject methods */
+    dxgi_surface_GetDevice,
+    /* IDXGISurface methods */
+    dxgi_surface_GetDesc,
+    dxgi_surface_Map,
+    dxgi_surface_Unmap,
+    /* IDXGISurface1 methods */
+    dxgi_surface_GetDC,
+    dxgi_surface_ReleaseDC,
+};
+
+static inline struct dxgi_resource *impl_from_IDXGIResource(IDXGIResource *iface)
+{
+    return CONTAINING_RECORD(iface, struct dxgi_resource, IDXGIResource_iface);
+}
+
+/* IUnknown methods */
+
+static HRESULT STDMETHODCALLTYPE dxgi_resource_QueryInterface(IDXGIResource *iface, REFIID riid,
+        void **object)
+{
+    struct dxgi_resource *resource = impl_from_IDXGIResource(iface);
+    TRACE("Forwarding to outer IUnknown\n");
+    return IUnknown_QueryInterface(resource->outer_unknown, riid, object);
+}
+
+static ULONG STDMETHODCALLTYPE dxgi_resource_AddRef(IDXGIResource *iface)
+{
+    struct dxgi_resource *resource = impl_from_IDXGIResource(iface);
+    TRACE("Forwarding to outer IUnknown\n");
+    return IUnknown_AddRef(resource->outer_unknown);
+}
+
+static ULONG STDMETHODCALLTYPE dxgi_resource_Release(IDXGIResource *iface)
+{
+    struct dxgi_resource *resource = impl_from_IDXGIResource(iface);
+    TRACE("Forwarding to outer IUnknown\n");
+    return IUnknown_Release(resource->outer_unknown);
+}
+
+/* IDXGIObject methods */
+
+static HRESULT STDMETHODCALLTYPE dxgi_resource_SetPrivateData(IDXGIResource *iface,
+        REFGUID guid, UINT data_size, const void *data)
+{
+    struct dxgi_resource *resource = impl_from_IDXGIResource(iface);
+
+    TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
+
+    return dxgi_set_private_data(&resource->private_store, guid, data_size, data);
+}
+
+static HRESULT STDMETHODCALLTYPE dxgi_resource_SetPrivateDataInterface(IDXGIResource *iface,
+        REFGUID guid, const IUnknown *object)
+{
+    struct dxgi_resource *resource = impl_from_IDXGIResource(iface);
+
+    TRACE("iface %p, guid %s, object %p.\n", iface, debugstr_guid(guid), object);
+
+    return dxgi_set_private_data_interface(&resource->private_store, guid, object);
+}
+
+static HRESULT STDMETHODCALLTYPE dxgi_resource_GetPrivateData(IDXGIResource *iface,
+        REFGUID guid, UINT *data_size, void *data)
+{
+    struct dxgi_resource *resource = impl_from_IDXGIResource(iface);
+
+    TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
+
+    return dxgi_get_private_data(&resource->private_store, guid, data_size, data);
+}
+
+static HRESULT STDMETHODCALLTYPE dxgi_resource_GetParent(IDXGIResource *iface, REFIID riid, void **parent)
+{
+    struct dxgi_resource *resource = impl_from_IDXGIResource(iface);
+
+    TRACE("iface %p, riid %s, parent %p.\n", iface, debugstr_guid(riid), parent);
+
+    return IDXGIDevice_QueryInterface(resource->device, riid, parent);
+}
+
+/* IDXGIDeviceSubObject methods */
+
+static HRESULT STDMETHODCALLTYPE dxgi_resource_GetDevice(IDXGIResource *iface, REFIID riid, void **device)
+{
+    struct dxgi_resource *resource = impl_from_IDXGIResource(iface);
+
+    TRACE("iface %p, riid %s, device %p.\n", iface, debugstr_guid(riid), device);
+
+    return IDXGIDevice_QueryInterface(resource->device, riid, device);
+}
+
+/* IDXGIResource methods */
+static HRESULT STDMETHODCALLTYPE dxgi_resource_GetSharedHandle(IDXGIResource *iface, HANDLE *shared_handle)
+{
+    FIXME("iface %p, shared_handle %p stub!\n", iface, shared_handle);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE dxgi_resource_GetUsage(IDXGIResource *iface, DXGI_USAGE *usage)
+{
+    FIXME("iface %p, usage %p stub!\n", iface, usage);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE dxgi_resource_SetEvictionPriority(IDXGIResource *iface, UINT eviction_priority)
+{
+    FIXME("iface %p, eviction_priority %u stub!\n", iface, eviction_priority);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE dxgi_resource_GetEvictionPriority(IDXGIResource *iface, UINT *eviction_priority)
+{
+    FIXME("iface %p, eviction_priority %p stub!\n", iface, eviction_priority);
+
+    return E_NOTIMPL;
+}
+
+static const struct IDXGIResourceVtbl dxgi_resource_vtbl =
+{
+    /* IUnknown methods */
+    dxgi_resource_QueryInterface,
+    dxgi_resource_AddRef,
+    dxgi_resource_Release,
+    /* IDXGIObject methods */
+    dxgi_resource_SetPrivateData,
+    dxgi_resource_SetPrivateDataInterface,
+    dxgi_resource_GetPrivateData,
+    dxgi_resource_GetParent,
+    /* IDXGIDeviceSubObject methods */
+    dxgi_resource_GetDevice,
+    /* IDXGIResource methods */
+    dxgi_resource_GetSharedHandle,
+    dxgi_resource_GetUsage,
+    dxgi_resource_SetEvictionPriority,
+    dxgi_resource_GetEvictionPriority,
+};
+
+static const struct IUnknownVtbl dxgi_resource_inner_unknown_vtbl =
+{
+    /* IUnknown methods */
+    dxgi_resource_inner_QueryInterface,
+    dxgi_resource_inner_AddRef,
+    dxgi_resource_inner_Release,
+};
+
+HRESULT dxgi_resource_init(struct dxgi_resource *resource, IDXGIDevice *device,
+        IUnknown *outer, BOOL needs_surface, struct wined3d_resource *wined3d_resource)
+{
+    struct wined3d_resource_desc desc;
+
+    wined3d_resource_get_desc(wined3d_resource, &desc);
+    if ((desc.resource_type == WINED3D_RTYPE_TEXTURE_1D || desc.resource_type == WINED3D_RTYPE_TEXTURE_2D)
+            && needs_surface)
+    {
+        resource->IDXGISurface1_iface.lpVtbl = &dxgi_surface_vtbl;
+    }
+    else
+        resource->IDXGISurface1_iface.lpVtbl = NULL;
+    resource->IDXGIResource_iface.lpVtbl = &dxgi_resource_vtbl;
+    resource->IUnknown_iface.lpVtbl = &dxgi_resource_inner_unknown_vtbl;
+    resource->refcount = 1;
+    wined3d_private_store_init(&resource->private_store);
+    resource->outer_unknown = outer ? outer : &resource->IUnknown_iface;
+    resource->device = device;
+    resource->wined3d_resource = wined3d_resource;
+    resource->dc = NULL;
+
+    return S_OK;
+}
diff --git a/dlls/dxgi/surface.c b/dlls/dxgi/surface.c
deleted file mode 100644
index 628e335ee0d..00000000000
--- a/dlls/dxgi/surface.c
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * Copyright 2009 Henri Verbeet for CodeWeavers
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- */
-
-#include "dxgi_private.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(dxgi);
-
-/* Inner IUnknown methods */
-
-static inline struct dxgi_surface *impl_from_IUnknown(IUnknown *iface)
-{
-    return CONTAINING_RECORD(iface, struct dxgi_surface, IUnknown_iface);
-}
-
-static HRESULT STDMETHODCALLTYPE dxgi_surface_inner_QueryInterface(IUnknown *iface, REFIID riid, void **out)
-{
-    struct dxgi_surface *surface = impl_from_IUnknown(iface);
-
-    TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
-
-    if (IsEqualGUID(riid, &IID_IDXGISurface1)
-            || IsEqualGUID(riid, &IID_IDXGISurface)
-            || IsEqualGUID(riid, &IID_IDXGIDeviceSubObject)
-            || IsEqualGUID(riid, &IID_IDXGIObject)
-            || IsEqualGUID(riid, &IID_IUnknown))
-    {
-        IDXGISurface1_AddRef(&surface->IDXGISurface1_iface);
-        *out = &surface->IDXGISurface1_iface;
-        return S_OK;
-    }
-
-    WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid));
-
-    *out = NULL;
-    return E_NOINTERFACE;
-}
-
-static ULONG STDMETHODCALLTYPE dxgi_surface_inner_AddRef(IUnknown *iface)
-{
-    struct dxgi_surface *surface = impl_from_IUnknown(iface);
-    ULONG refcount = InterlockedIncrement(&surface->refcount);
-
-    TRACE("%p increasing refcount to %lu.\n", surface, refcount);
-
-    return refcount;
-}
-
-static ULONG STDMETHODCALLTYPE dxgi_surface_inner_Release(IUnknown *iface)
-{
-    struct dxgi_surface *surface = impl_from_IUnknown(iface);
-    ULONG refcount = InterlockedDecrement(&surface->refcount);
-
-    TRACE("%p decreasing refcount to %lu.\n", surface, refcount);
-
-    if (!refcount)
-    {
-        wined3d_private_store_cleanup(&surface->private_store);
-        heap_free(surface);
-    }
-
-    return refcount;
-}
-
-static inline struct dxgi_surface *impl_from_IDXGISurface1(IDXGISurface1 *iface)
-{
-    return CONTAINING_RECORD(iface, struct dxgi_surface, IDXGISurface1_iface);
-}
-
-/* IUnknown methods */
-
-static HRESULT STDMETHODCALLTYPE dxgi_surface_QueryInterface(IDXGISurface1 *iface, REFIID riid,
-        void **object)
-{
-    struct dxgi_surface *surface = impl_from_IDXGISurface1(iface);
-    TRACE("Forwarding to outer IUnknown\n");
-    return IUnknown_QueryInterface(surface->outer_unknown, riid, object);
-}
-
-static ULONG STDMETHODCALLTYPE dxgi_surface_AddRef(IDXGISurface1 *iface)
-{
-    struct dxgi_surface *surface = impl_from_IDXGISurface1(iface);
-    TRACE("Forwarding to outer IUnknown\n");
-    return IUnknown_AddRef(surface->outer_unknown);
-}
-
-static ULONG STDMETHODCALLTYPE dxgi_surface_Release(IDXGISurface1 *iface)
-{
-    struct dxgi_surface *surface = impl_from_IDXGISurface1(iface);
-    TRACE("Forwarding to outer IUnknown\n");
-    return IUnknown_Release(surface->outer_unknown);
-}
-
-/* IDXGIObject methods */
-
-static HRESULT STDMETHODCALLTYPE dxgi_surface_SetPrivateData(IDXGISurface1 *iface,
-        REFGUID guid, UINT data_size, const void *data)
-{
-    struct dxgi_surface *surface = impl_from_IDXGISurface1(iface);
-
-    TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
-
-    return dxgi_set_private_data(&surface->private_store, guid, data_size, data);
-}
-
-static HRESULT STDMETHODCALLTYPE dxgi_surface_SetPrivateDataInterface(IDXGISurface1 *iface,
-        REFGUID guid, const IUnknown *object)
-{
-    struct dxgi_surface *surface = impl_from_IDXGISurface1(iface);
-
-    TRACE("iface %p, guid %s, object %p.\n", iface, debugstr_guid(guid), object);
-
-    return dxgi_set_private_data_interface(&surface->private_store, guid, object);
-}
-
-static HRESULT STDMETHODCALLTYPE dxgi_surface_GetPrivateData(IDXGISurface1 *iface,
-        REFGUID guid, UINT *data_size, void *data)
-{
-    struct dxgi_surface *surface = impl_from_IDXGISurface1(iface);
-
-    TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
-
-    return dxgi_get_private_data(&surface->private_store, guid, data_size, data);
-}
-
-static HRESULT STDMETHODCALLTYPE dxgi_surface_GetParent(IDXGISurface1 *iface, REFIID riid, void **parent)
-{
-    struct dxgi_surface *surface = impl_from_IDXGISurface1(iface);
-
-    TRACE("iface %p, riid %s, parent %p.\n", iface, debugstr_guid(riid), parent);
-
-    return IDXGIDevice_QueryInterface(surface->device, riid, parent);
-}
-
-/* IDXGIDeviceSubObject methods */
-
-static HRESULT STDMETHODCALLTYPE dxgi_surface_GetDevice(IDXGISurface1 *iface, REFIID riid, void **device)
-{
-    struct dxgi_surface *surface = impl_from_IDXGISurface1(iface);
-
-    TRACE("iface %p, riid %s, device %p.\n", iface, debugstr_guid(riid), device);
-
-    return IDXGIDevice_QueryInterface(surface->device, riid, device);
-}
-
-/* IDXGISurface methods */
-static HRESULT STDMETHODCALLTYPE dxgi_surface_GetDesc(IDXGISurface1 *iface, DXGI_SURFACE_DESC *desc)
-{
-    struct dxgi_surface *surface = impl_from_IDXGISurface1(iface);
-    struct wined3d_resource_desc wined3d_desc;
-
-    TRACE("iface %p, desc %p.\n", iface, desc);
-
-    wined3d_mutex_lock();
-    wined3d_resource_get_desc(wined3d_texture_get_resource(surface->wined3d_texture), &wined3d_desc);
-    wined3d_mutex_unlock();
-    desc->Width = wined3d_desc.width;
-    desc->Height = wined3d_desc.height;
-    desc->Format = dxgi_format_from_wined3dformat(wined3d_desc.format);
-    dxgi_sample_desc_from_wined3d(&desc->SampleDesc, wined3d_desc.multisample_type, wined3d_desc.multisample_quality);
-
-    return S_OK;
-}
-
-static HRESULT STDMETHODCALLTYPE dxgi_surface_Map(IDXGISurface1 *iface, DXGI_MAPPED_RECT *mapped_rect, UINT flags)
-{
-    struct dxgi_surface *surface = impl_from_IDXGISurface1(iface);
-    struct wined3d_map_desc wined3d_map_desc;
-    DWORD wined3d_map_flags = 0;
-    HRESULT hr;
-
-    TRACE("iface %p, mapped_rect %p, flags %#x.\n", iface, mapped_rect, flags);
-
-    if (flags & DXGI_MAP_READ)
-        wined3d_map_flags |= WINED3D_MAP_READ;
-    if (flags & DXGI_MAP_WRITE)
-        wined3d_map_flags |= WINED3D_MAP_WRITE;
-    if (flags & DXGI_MAP_DISCARD)
-        wined3d_map_flags |= WINED3D_MAP_DISCARD;
-
-    if (SUCCEEDED(hr = wined3d_resource_map(wined3d_texture_get_resource(surface->wined3d_texture), 0,
-            &wined3d_map_desc, NULL, wined3d_map_flags)))
-    {
-        mapped_rect->Pitch = wined3d_map_desc.row_pitch;
-        mapped_rect->pBits = wined3d_map_desc.data;
-    }
-
-    return hr;
-}
-
-static HRESULT STDMETHODCALLTYPE dxgi_surface_Unmap(IDXGISurface1 *iface)
-{
-    struct dxgi_surface *surface = impl_from_IDXGISurface1(iface);
-
-    TRACE("iface %p.\n", iface);
-    wined3d_resource_unmap(wined3d_texture_get_resource(surface->wined3d_texture), 0);
-    return S_OK;
-}
-
-/* IDXGISurface1 methods */
-static HRESULT STDMETHODCALLTYPE dxgi_surface_GetDC(IDXGISurface1 *iface, BOOL discard, HDC *hdc)
-{
-    struct dxgi_surface *surface = impl_from_IDXGISurface1(iface);
-    HRESULT hr;
-
-    FIXME("iface %p, discard %d, hdc %p semi-stub!\n", iface, discard, hdc);
-
-    if (!hdc)
-        return E_INVALIDARG;
-
-    wined3d_mutex_lock();
-    hr = wined3d_texture_get_dc(surface->wined3d_texture, 0, hdc);
-    wined3d_mutex_unlock();
-
-    if (SUCCEEDED(hr))
-       surface->dc = *hdc;
-
-    return hr;
-}
-
-static HRESULT STDMETHODCALLTYPE dxgi_surface_ReleaseDC(IDXGISurface1 *iface, RECT *dirty_rect)
-{
-    struct dxgi_surface *surface = impl_from_IDXGISurface1(iface);
-    HRESULT hr;
-
-    TRACE("iface %p, rect %s\n", iface, wine_dbgstr_rect(dirty_rect));
-
-    if (!IsRectEmpty(dirty_rect))
-        FIXME("dirty rectangle is ignored.\n");
-
-    wined3d_mutex_lock();
-    hr = wined3d_texture_release_dc(surface->wined3d_texture, 0, surface->dc);
-    wined3d_mutex_unlock();
-
-    return hr;
-}
-
-static const struct IDXGISurface1Vtbl dxgi_surface_vtbl =
-{
-    /* IUnknown methods */
-    dxgi_surface_QueryInterface,
-    dxgi_surface_AddRef,
-    dxgi_surface_Release,
-    /* IDXGIObject methods */
-    dxgi_surface_SetPrivateData,
-    dxgi_surface_SetPrivateDataInterface,
-    dxgi_surface_GetPrivateData,
-    dxgi_surface_GetParent,
-    /* IDXGIDeviceSubObject methods */
-    dxgi_surface_GetDevice,
-    /* IDXGISurface methods */
-    dxgi_surface_GetDesc,
-    dxgi_surface_Map,
-    dxgi_surface_Unmap,
-    /* IDXGISurface1 methods */
-    dxgi_surface_GetDC,
-    dxgi_surface_ReleaseDC,
-};
-
-static const struct IUnknownVtbl dxgi_surface_inner_unknown_vtbl =
-{
-    /* IUnknown methods */
-    dxgi_surface_inner_QueryInterface,
-    dxgi_surface_inner_AddRef,
-    dxgi_surface_inner_Release,
-};
-
-HRESULT dxgi_surface_init(struct dxgi_surface *surface, IDXGIDevice *device,
-        IUnknown *outer, struct wined3d_texture *wined3d_texture)
-{
-    surface->IDXGISurface1_iface.lpVtbl = &dxgi_surface_vtbl;
-    surface->IUnknown_iface.lpVtbl = &dxgi_surface_inner_unknown_vtbl;
-    surface->refcount = 1;
-    wined3d_private_store_init(&surface->private_store);
-    surface->outer_unknown = outer ? outer : &surface->IUnknown_iface;
-    surface->device = device;
-    surface->wined3d_texture = wined3d_texture;
-    surface->dc = NULL;
-
-    return S_OK;
-}
diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c
index 5fd0ba89054..1874bcc0834 100644
--- a/dlls/dxgi/tests/dxgi.c
+++ b/dlls/dxgi/tests/dxgi.c
@@ -1265,7 +1265,6 @@ static void test_create_surface(void)
     hr = IDXGIDevice_CreateSurface(device, &desc, 1, DXGI_USAGE_RENDER_TARGET_OUTPUT, NULL, &surface);
     ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
 
-    todo_wine
     check_interface(surface, &IID_IDXGIResource, TRUE, FALSE);
     check_interface(surface, &IID_ID3D10Texture2D, TRUE, FALSE);
     /* Not available on all Windows versions. */
@@ -4492,19 +4491,13 @@ static void test_swapchain_parameters(void)
             continue;
 
         hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGIResource, (void **)&resource);
-        todo_wine ok(hr == S_OK, "Got unexpected hr %#lx, test %u.\n", hr, i);
-        if (FAILED(hr))
-        {
-            hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL);
-            ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
-
-            IDXGISwapChain_Release(swapchain);
-            continue;
-        }
+        ok(hr == S_OK, "Got unexpected hr %#lx, test %u.\n", hr, i);
 
         expected_usage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER;
         hr = IDXGIResource_GetUsage(resource, &usage);
+        todo_wine
         ok(hr == S_OK, "Got unexpected hr %#lx, test %u.\n", hr, i);
+        todo_wine
         ok((usage & expected_usage) == expected_usage, "Got usage %x, expected %x, test %u.\n",
                 usage, expected_usage, i);
 
@@ -4541,15 +4534,21 @@ static void test_swapchain_parameters(void)
                 broken_usage |= DXGI_USAGE_READ_ONLY;
 
             hr = IDXGIResource_GetUsage(resource, &usage);
+            todo_wine
             ok(hr == S_OK, "Got unexpected hr %#lx, test %u, buffer %u.\n", hr, i, j);
+            todo_wine
             ok(usage == expected_usage || broken(usage == broken_usage),
                     "Got usage %x, expected %x, test %u, buffer %u.\n",
                     usage, expected_usage, i, j);
 
             IDXGIResource_Release(resource);
         }
-        hr = IDXGISwapChain_GetBuffer(swapchain, j, &IID_IDXGIResource, (void **)&resource);
-        ok(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#lx, test %u.\n", hr, i);
+
+        if (strcmp(winetest_platform, "wine"))
+        {
+            hr = IDXGISwapChain_GetBuffer(swapchain, j, &IID_IDXGIResource, (void **)&resource);
+            ok(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#lx, test %u.\n", hr, i);
+        }
 
         hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL);
         ok(hr == S_OK, "Got unexpected hr %#lx, test %u.\n", hr, i);
@@ -4605,15 +4604,12 @@ static void test_swapchain_parameters(void)
         }
 
         hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGIResource, (void **)&resource);
-        todo_wine ok(hr == S_OK, "Got unexpected hr %#lx, test %u.\n", hr, i);
-        if (FAILED(hr))
-        {
-            IDXGISwapChain_Release(swapchain);
-            continue;
-        }
+        ok(hr == S_OK, "Got unexpected hr %#lx, test %u.\n", hr, i);
         expected_usage = usage | DXGI_USAGE_BACK_BUFFER | DXGI_USAGE_DISCARD_ON_PRESENT;
         hr = IDXGIResource_GetUsage(resource, &usage);
+        todo_wine
         ok(hr == S_OK, "Got unexpected hr %#lx, test %u.\n", hr, i);
+        todo_wine_if(i != 7)
         ok(usage == expected_usage, "Got usage %x, expected %x, test %u.\n", usage, expected_usage, i);
         IDXGIResource_Release(resource);
 
diff --git a/include/wine/winedxgi.idl b/include/wine/winedxgi.idl
index 83012047ea7..64e4218204b 100644
--- a/include/wine/winedxgi.idl
+++ b/include/wine/winedxgi.idl
@@ -44,12 +44,13 @@ interface IWineDXGISwapChainFactory : IUnknown
 ]
 interface IWineDXGIDevice : IDXGIDevice3
 {
-    HRESULT create_surface(
-        [in] struct wined3d_texture *wined3d_texture,
+    HRESULT create_resource(
+        [in] struct wined3d_resource *wined3d_resource,
         [in] DXGI_USAGE usage,
         [in] const DXGI_SHARED_RESOURCE *shared_resource,
         [in] IUnknown *outer,
-        [out] void **surface
+        [in] BOOL needs_surface,
+        [out] void **resource
     );
 }
 
-- 
GitLab


https://gitlab.winehq.org/wine/wine/-/merge_requests/212



More information about the wine-devel mailing list