Henri Verbeet : dxgi: Implement IDXGIDevice::CreateSurface().

Alexandre Julliard julliard at winehq.org
Mon Jan 19 08:58:34 CST 2009


Module: wine
Branch: master
Commit: c9f116a56f519fea0c171362d2e00dddfb908ce9
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=c9f116a56f519fea0c171362d2e00dddfb908ce9

Author: Henri Verbeet <hverbeet at codeweavers.com>
Date:   Mon Jan 19 10:39:06 2009 +0100

dxgi: Implement IDXGIDevice::CreateSurface().

---

 dlls/d3d10core/d3d10core_private.h |    1 +
 dlls/d3d10core/device.c            |   11 ++++
 dlls/d3d10core/tests/device.c      |    2 +-
 dlls/d3d10core/texture2d.c         |    9 ++++
 dlls/dxgi/device.c                 |   89 ++++++++++++++++++++++++++++++------
 dlls/dxgi/tests/device.c           |    2 +-
 include/wine/winedxgi.idl          |    7 +++
 7 files changed, 105 insertions(+), 16 deletions(-)

diff --git a/dlls/d3d10core/d3d10core_private.h b/dlls/d3d10core/d3d10core_private.h
index 1b28d5e..5453600 100644
--- a/dlls/d3d10core/d3d10core_private.h
+++ b/dlls/d3d10core/d3d10core_private.h
@@ -58,6 +58,7 @@ struct d3d10_texture2d
     const struct ID3D10Texture2DVtbl *vtbl;
     LONG refcount;
 
+    IUnknown *dxgi_surface;
     IWineD3DSurface *wined3d_surface;
 };
 
diff --git a/dlls/d3d10core/device.c b/dlls/d3d10core/device.c
index 034c9b9..2e4c5c1 100644
--- a/dlls/d3d10core/device.c
+++ b/dlls/d3d10core/device.c
@@ -602,6 +602,16 @@ static HRESULT STDMETHODCALLTYPE d3d10_device_CreateTexture2D(ID3D10Device *ifac
             return E_FAIL;
         }
 
+        hr = IWineDXGIDevice_create_surface(wine_device, NULL, 0, NULL,
+                (IUnknown *)object, (void **)&object->dxgi_surface);
+        if (FAILED(hr))
+        {
+            ERR("Failed to create DXGI surface, returning %#x\n", hr);
+            HeapFree(GetProcessHeap(), 0, object);
+            IWineDXGIDevice_Release(wine_device);
+            return hr;
+        }
+
         wined3d_device = IWineDXGIDevice_get_wined3d_device(wine_device);
         IWineDXGIDevice_Release(wine_device);
 
@@ -614,6 +624,7 @@ static HRESULT STDMETHODCALLTYPE d3d10_device_CreateTexture2D(ID3D10Device *ifac
         if (FAILED(hr))
         {
             ERR("CreateSurface failed, returning %#x\n", hr);
+            IDXGISurface_Release(object->dxgi_surface);
             HeapFree(GetProcessHeap(), 0, object);
             return hr;
         }
diff --git a/dlls/d3d10core/tests/device.c b/dlls/d3d10core/tests/device.c
index 5493d23..1a3f331 100644
--- a/dlls/d3d10core/tests/device.c
+++ b/dlls/d3d10core/tests/device.c
@@ -116,7 +116,7 @@ static void test_create_texture(ID3D10Device *device)
     ok(SUCCEEDED(hr), "Failed to create a 2d texture, hr %#x\n", hr);
 
     hr = ID3D10Texture2D_QueryInterface(texture, &IID_IDXGISurface, (void **)&surface);
-    todo_wine ok(SUCCEEDED(hr), "Texture should implement IDXGISurface\n");
+    ok(SUCCEEDED(hr), "Texture should implement IDXGISurface\n");
     if (SUCCEEDED(hr)) IDXGISurface_Release(surface);
     ID3D10Texture2D_Release(texture);
 
diff --git a/dlls/d3d10core/texture2d.c b/dlls/d3d10core/texture2d.c
index d0fb0f5..afb6167 100644
--- a/dlls/d3d10core/texture2d.c
+++ b/dlls/d3d10core/texture2d.c
@@ -28,6 +28,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d10core);
 
 static HRESULT STDMETHODCALLTYPE d3d10_texture2d_QueryInterface(ID3D10Texture2D *iface, REFIID riid, void **object)
 {
+    struct d3d10_texture2d *This = (struct d3d10_texture2d *)iface;
+
     TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object);
 
     if (IsEqualGUID(riid, &IID_ID3D10Texture2D)
@@ -40,6 +42,12 @@ static HRESULT STDMETHODCALLTYPE d3d10_texture2d_QueryInterface(ID3D10Texture2D
         return S_OK;
     }
 
+    if (This->dxgi_surface)
+    {
+        TRACE("Forwarding to dxgi surface\n");
+        return IDXGISurface_QueryInterface(This->dxgi_surface, riid, object);
+    }
+
     WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid));
 
     *object = NULL;
@@ -65,6 +73,7 @@ static ULONG STDMETHODCALLTYPE d3d10_texture2d_Release(ID3D10Texture2D *iface)
 
     if (!refcount)
     {
+        if (This->dxgi_surface) IDXGISurface_Release(This->dxgi_surface);
         if (This->wined3d_surface) IWineD3DSurface_Release(This->wined3d_surface);
         HeapFree(GetProcessHeap(), 0, This);
     }
diff --git a/dlls/dxgi/device.c b/dlls/dxgi/device.c
index 235e1f7..3c10f99 100644
--- a/dlls/dxgi/device.c
+++ b/dlls/dxgi/device.c
@@ -145,40 +145,65 @@ 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 dxgi_surface *object;
+    IWineD3DDeviceParent *device_parent;
     HRESULT hr;
     UINT i;
+    UINT j;
 
-    FIXME("iface %p, desc %p, surface_count %u, usage %#x, shared_resource %p, surface %p partial stub!\n",
+    TRACE("iface %p, desc %p, surface_count %u, usage %#x, shared_resource %p, surface %p\n",
             iface, desc, surface_count, usage, shared_resource, surface);
 
+    hr = IWineDXGIDevice_QueryInterface(iface, &IID_IWineD3DDeviceParent, (void **)&device_parent);
+    if (FAILED(hr))
+    {
+        ERR("Device should implement IWineD3DDeviceParent\n");
+        return E_FAIL;
+    }
+
+    FIXME("Implement DXGI<->wined3d format and usage conversion\n");
+
     memset(surface, 0, surface_count * sizeof(*surface));
     for (i = 0; i < surface_count; ++i)
     {
-        object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
-        if (!object)
+        IWineD3DSurface *wined3d_surface;
+        IUnknown *parent;
+
+        hr = IWineD3DDeviceParent_CreateSurface(device_parent, NULL, desc->Width, desc->Height, desc->Format,
+                usage, WINED3DPOOL_DEFAULT, 0, WINED3DCUBEMAP_FACE_POSITIVE_X, &wined3d_surface);
+        if (FAILED(hr))
         {
-            ERR("Failed to allocate DXGI surface object memory\n");
-            hr = E_OUTOFMEMORY;
+            ERR("CreateSurface failed, returning %#x\n", hr);
             goto fail;
         }
 
-        object->vtbl = &dxgi_surface_vtbl;
-        object->inner_unknown_vtbl = &dxgi_surface_inner_unknown_vtbl;
-        object->refcount = 1;
-        object->outer_unknown = (IUnknown *)&object->inner_unknown_vtbl;
-        surface[i] = (IDXGISurface *)object;
+        hr = IWineD3DSurface_GetParent(wined3d_surface, &parent);
+        IWineD3DSurface_Release(wined3d_surface);
+        if (FAILED(hr))
+        {
+            ERR("GetParent failed, returning %#x\n", hr);
+            goto fail;
+        }
+
+        hr = IUnknown_QueryInterface(parent, &IID_IDXGISurface, (void **)&surface[i]);
+        IUnknown_Release(parent);
+        if (FAILED(hr))
+        {
+            ERR("Surface should implement IDXGISurface\n");
+            goto fail;
+        }
 
-        TRACE("Created IDXGISurface %p (%u/%u)\n", object, i + 1, surface_count);
+        TRACE("Created IDXGISurface %p (%u/%u)\n", surface[i], i + 1, surface_count);
     }
+    IWineD3DDeviceParent_Release(device_parent);
 
     return S_OK;
 
 fail:
-    for (i = 0; i < surface_count; ++i)
+    for (j = 0; j < i; ++j)
     {
-        HeapFree(GetProcessHeap(), 0, surface[i]);
+        IDXGISurface_Release(surface[i]);
     }
+    IWineD3DDeviceParent_Release(device_parent);
     return hr;
 }
 
@@ -219,6 +244,41 @@ static IWineD3DDevice * STDMETHODCALLTYPE dxgi_device_get_wined3d_device(IWineDX
     return This->wined3d_device;
 }
 
+static HRESULT STDMETHODCALLTYPE dxgi_device_create_surface(IWineDXGIDevice *iface, const DXGI_SURFACE_DESC *desc,
+        DXGI_USAGE usage, const DXGI_SHARED_RESOURCE *shared_resource, IUnknown *outer, void **surface)
+{
+    struct dxgi_surface *object;
+
+    FIXME("iface %p, desc %p, usage %#x, shared_resource %p, outer %p, surface %p partial stub!\n",
+            iface, desc, usage, shared_resource, outer, surface);
+
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+    if (!object)
+    {
+        ERR("Failed to allocate DXGI surface object memory\n");
+        return E_OUTOFMEMORY;
+    }
+
+    object->vtbl = &dxgi_surface_vtbl;
+    object->inner_unknown_vtbl = &dxgi_surface_inner_unknown_vtbl;
+    object->refcount = 1;
+
+    if (outer)
+    {
+        object->outer_unknown = outer;
+        *surface = &object->inner_unknown_vtbl;
+    }
+    else
+    {
+        object->outer_unknown = (IUnknown *)&object->inner_unknown_vtbl;
+        *surface = object;
+    }
+
+    TRACE("Created IDXGISurface %p\n", object);
+
+    return S_OK;
+}
+
 const struct IWineDXGIDeviceVtbl dxgi_device_vtbl =
 {
     /* IUnknown methods */
@@ -238,4 +298,5 @@ const struct IWineDXGIDeviceVtbl dxgi_device_vtbl =
     dxgi_device_GetGPUThreadPriority,
     /* IWineDXGIAdapter methods */
     dxgi_device_get_wined3d_device,
+    dxgi_device_create_surface,
 };
diff --git a/dlls/dxgi/tests/device.c b/dlls/dxgi/tests/device.c
index 39d780a..12893b1 100644
--- a/dlls/dxgi/tests/device.c
+++ b/dlls/dxgi/tests/device.c
@@ -115,7 +115,7 @@ static void test_create_surface(IDXGIDevice *device)
     ok(SUCCEEDED(hr), "Failed to create a dxgi surface, hr %#x\n", hr);
 
     hr = IDXGISurface_QueryInterface(surface, &IID_ID3D10Texture2D, (void **)&texture);
-    todo_wine ok(SUCCEEDED(hr), "Surface should implement ID3D10Texture2D\n");
+    ok(SUCCEEDED(hr), "Surface should implement ID3D10Texture2D\n");
     if (SUCCEEDED(hr)) ID3D10Texture2D_Release(texture);
 
     IDXGISurface_Release(surface);
diff --git a/include/wine/winedxgi.idl b/include/wine/winedxgi.idl
index 860b695..3fc7883 100644
--- a/include/wine/winedxgi.idl
+++ b/include/wine/winedxgi.idl
@@ -46,4 +46,11 @@ interface IWineDXGIAdapter : IDXGIAdapter
 interface IWineDXGIDevice : IDXGIDevice
 {
     struct IWineD3DDevice *get_wined3d_device();
+    HRESULT create_surface(
+        [in] const DXGI_SURFACE_DESC *desc,
+        [in] DXGI_USAGE usage,
+        [in] const DXGI_SHARED_RESOURCE *shared_resource,
+        [in] IUnknown *outer,
+        [out] void **surface
+    );
 }




More information about the wine-cvs mailing list