d3d10: Add a dxgi device to the d3d10 device.

Henri Verbeet hverbeet at codeweavers.com
Wed Oct 22 10:41:16 CDT 2008


Although native dxgi obviously doesn't have a dxgi_wined3d_create_device
export, it does have a DXGID3D10CreateDevice export that's probably used
for the same purpose. Unfortunately that one is completely undocumented.
---
 dlls/d3d10/Makefile.in     |    2 +-
 dlls/d3d10/d3d10_main.c    |   27 ++++++++++++++++++++++
 dlls/d3d10/d3d10_private.h |    7 +++++
 dlls/d3d10/device.c        |    9 +++++++
 dlls/dxgi/device.c         |   54 +++++++++++++++++++++++++++++++++++++------
 dlls/dxgi/dxgi.spec        |    1 +
 dlls/dxgi/dxgi_main.c      |   46 +++++++++++++++++++++++++++++++++++++
 dlls/dxgi/dxgi_private.h   |    5 ++++
 8 files changed, 142 insertions(+), 9 deletions(-)

diff --git a/dlls/d3d10/Makefile.in b/dlls/d3d10/Makefile.in
index 7500aaa..1d36253 100644
--- a/dlls/d3d10/Makefile.in
+++ b/dlls/d3d10/Makefile.in
@@ -4,7 +4,7 @@ SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 MODULE    = d3d10.dll
 IMPORTLIB = d3d10
-IMPORTS   = dxguid uuid wined3d kernel32
+IMPORTS   = dxguid uuid dxgi wined3d kernel32
 
 C_SRCS = \
 	d3d10_main.c \
diff --git a/dlls/d3d10/d3d10_main.c b/dlls/d3d10/d3d10_main.c
index 6ed1756..738ef68 100644
--- a/dlls/d3d10/d3d10_main.c
+++ b/dlls/d3d10/d3d10_main.c
@@ -41,10 +41,29 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
     return TRUE;
 }
 
+static inline WINED3DDEVTYPE get_device_type(D3D10_DRIVER_TYPE driver_type)
+{
+    switch (driver_type)
+    {
+        case D3D10_DRIVER_TYPE_HARDWARE:
+            return WINED3DDEVTYPE_HAL;
+        case D3D10_DRIVER_TYPE_REFERENCE:
+            return WINED3DDEVTYPE_REF;
+        case D3D10_DRIVER_TYPE_NULL:
+            return WINED3DDEVTYPE_NULLREF;
+        case D3D10_DRIVER_TYPE_SOFTWARE:
+            return WINED3DDEVTYPE_SW;
+        default:
+            FIXME("Unrecognized driver type %#x\n", driver_type);
+            return WINED3DDEVTYPE_HAL;
+    }
+}
+
 HRESULT WINAPI D3D10CreateDevice(IDXGIAdapter *adapter, D3D10_DRIVER_TYPE driver_type,
         HMODULE swrast, UINT flags, UINT sdk_version, ID3D10Device **device)
 {
     struct d3d10_device *object;
+    HRESULT hr;
 
     FIXME("adapter %p, driver_type %s, swrast %p, flags %#x, sdk_version %d, device %p partial stub!\n",
             adapter, debug_d3d10_driver_type(driver_type), swrast, flags, sdk_version, device);
@@ -60,6 +79,14 @@ HRESULT WINAPI D3D10CreateDevice(IDXGIAdapter *adapter, D3D10_DRIVER_TYPE driver
     object->refcount = 1;
     *device = (ID3D10Device *)object;
 
+    if (FAILED(hr = dxgi_wined3d_create_device(adapter, get_device_type(driver_type), swrast, 0,
+            (IUnknown *)object, &IID_IUnknown, (void **)&object->dxgi_device)))
+    {
+        HeapFree(GetProcessHeap(), 0, object);
+        *device = NULL;
+        return hr;
+    }
+
     TRACE("Created ID3D10Device %p\n", object);
 
     return S_OK;
diff --git a/dlls/d3d10/d3d10_private.h b/dlls/d3d10/d3d10_private.h
index f76bda6..3a7faaa 100644
--- a/dlls/d3d10/d3d10_private.h
+++ b/dlls/d3d10/d3d10_private.h
@@ -23,10 +23,12 @@
 
 #define COBJMACROS
 #include "winbase.h"
+#include "wingdi.h"
 #include "winuser.h"
 #include "objbase.h"
 
 #include "d3d10.h"
+#include "wine/wined3d_interface.h"
 
 /* TRACE helper functions */
 const char *debug_d3d10_driver_type(D3D10_DRIVER_TYPE driver_type);
@@ -39,6 +41,11 @@ struct d3d10_device
 {
     const struct ID3D10DeviceVtbl *vtbl;
     LONG refcount;
+    IUnknown *dxgi_device;
 };
 
+/* DXGI */
+HRESULT WINAPI dxgi_wined3d_create_device(IDXGIAdapter *adapter, WINED3DDEVTYPE device_type,
+        HMODULE swrast, UINT flags, IUnknown *outer_unknown, REFIID riid, void **device);
+
 #endif /* __WINE_D3D10_PRIVATE_H */
diff --git a/dlls/d3d10/device.c b/dlls/d3d10/device.c
index eea9a75..e2603f6 100644
--- a/dlls/d3d10/device.c
+++ b/dlls/d3d10/device.c
@@ -28,6 +28,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d10);
 
 HRESULT STDMETHODCALLTYPE d3d10_device_QueryInterface(ID3D10Device* iface, REFIID riid, void **object)
 {
+    struct d3d10_device *This = (struct d3d10_device *)iface;
+
     TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object);
 
     if (IsEqualGUID(riid, &IID_IUnknown)
@@ -38,6 +40,12 @@ HRESULT STDMETHODCALLTYPE d3d10_device_QueryInterface(ID3D10Device* iface, REFII
         return S_OK;
     }
 
+    if (IsEqualGUID(riid, &IID_IDXGIObject)
+            || IsEqualGUID(riid, &IID_IDXGIDevice))
+    {
+        return IDXGIDevice_QueryInterface(This->dxgi_device, riid, object);
+    }
+
     WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid));
 
     *object = NULL;
@@ -63,6 +71,7 @@ ULONG STDMETHODCALLTYPE d3d10_device_Release(ID3D10Device* iface)
 
     if (!refcount)
     {
+        IUnknown_Release(This->dxgi_device);
         HeapFree(GetProcessHeap(), 0, This);
     }
 
diff --git a/dlls/dxgi/device.c b/dlls/dxgi/device.c
index 9c7f252..837c296 100644
--- a/dlls/dxgi/device.c
+++ b/dlls/dxgi/device.c
@@ -24,18 +24,25 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(dxgi);
 
-/* IUnknown methods */
+/* Inner IUnknown methods */
 
-HRESULT STDMETHODCALLTYPE dxgi_device_QueryInterface(IDXGIDevice* iface, REFIID riid, void **object)
+static inline struct dxgi_device *dxgi_device_from_inner_unknown(IUnknown *iface)
+{
+    return (struct dxgi_device *)((char*)iface - FIELD_OFFSET(struct dxgi_device, inner_unknown_vtbl));
+}
+
+HRESULT STDMETHODCALLTYPE dxgi_device_inner_QueryInterface(IUnknown* iface, REFIID riid, void **object)
 {
+    struct dxgi_device *This = dxgi_device_from_inner_unknown(iface);
+
     TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object);
 
     if (IsEqualGUID(riid, &IID_IUnknown)
             || IsEqualGUID(riid, &IID_IDXGIObject)
             || IsEqualGUID(riid, &IID_IDXGIDevice))
     {
-        IUnknown_AddRef(iface);
-        *object = iface;
+        IUnknown_AddRef((IUnknown *)This);
+        *object = This;
         return S_OK;
     }
 
@@ -45,9 +52,9 @@ HRESULT STDMETHODCALLTYPE dxgi_device_QueryInterface(IDXGIDevice* iface, REFIID
     return E_NOINTERFACE;
 }
 
-ULONG STDMETHODCALLTYPE dxgi_device_AddRef(IDXGIDevice* iface)
+ULONG STDMETHODCALLTYPE dxgi_device_inner_AddRef(IUnknown* iface)
 {
-    struct dxgi_device *This = (struct dxgi_device *)iface;
+    struct dxgi_device *This = dxgi_device_from_inner_unknown(iface);
     ULONG refcount = InterlockedIncrement(&This->refcount);
 
     TRACE("%p increasing refcount to %u\n", This, refcount);
@@ -55,9 +62,9 @@ ULONG STDMETHODCALLTYPE dxgi_device_AddRef(IDXGIDevice* iface)
     return refcount;
 }
 
-ULONG STDMETHODCALLTYPE dxgi_device_Release(IDXGIDevice* iface)
+ULONG STDMETHODCALLTYPE dxgi_device_inner_Release(IUnknown* iface)
 {
-    struct dxgi_device *This = (struct dxgi_device *)iface;
+    struct dxgi_device *This = dxgi_device_from_inner_unknown(iface);
     ULONG refcount = InterlockedDecrement(&This->refcount);
 
     TRACE("%p decreasing refcount to %u\n", This, refcount);
@@ -70,6 +77,29 @@ ULONG STDMETHODCALLTYPE dxgi_device_Release(IDXGIDevice* iface)
     return refcount;
 }
 
+/* IUnknown methods */
+
+HRESULT STDMETHODCALLTYPE dxgi_device_QueryInterface(IDXGIDevice* iface, REFIID riid, void **object)
+{
+    struct dxgi_device *This = (struct dxgi_device *)iface;
+    TRACE("Forwarding to outer IUnknown\n");
+    return IUnknown_QueryInterface(This->outer_unknown, riid, object);
+}
+
+ULONG STDMETHODCALLTYPE dxgi_device_AddRef(IDXGIDevice* iface)
+{
+    struct dxgi_device *This = (struct dxgi_device *)iface;
+    TRACE("Forwarding to outer IUnknown\n");
+    return IUnknown_AddRef(This->outer_unknown);
+}
+
+ULONG STDMETHODCALLTYPE dxgi_device_Release(IDXGIDevice* iface)
+{
+    struct dxgi_device *This = (struct dxgi_device *)iface;
+    TRACE("Forwarding to outer IUnknown\n");
+    return IUnknown_Release(This->outer_unknown);
+}
+
 /* IDXGIObject methods */
 
 HRESULT STDMETHODCALLTYPE dxgi_device_SetPrivateData(IDXGIDevice* iface, REFGUID guid, UINT data_size, const void *data)
@@ -160,3 +190,11 @@ const struct IDXGIDeviceVtbl dxgi_device_vtbl =
     dxgi_device_SetGPUThreadPriority,
     dxgi_device_GetGPUThreadPriority,
 };
+
+const struct IUnknownVtbl dxgi_device_inner_unkown_vtbl =
+{
+    /* IUnknown methods */
+    dxgi_device_inner_QueryInterface,
+    dxgi_device_inner_AddRef,
+    dxgi_device_inner_Release,
+};
diff --git a/dlls/dxgi/dxgi.spec b/dlls/dxgi/dxgi.spec
index 1c5069d..fab0c76 100644
--- a/dlls/dxgi/dxgi.spec
+++ b/dlls/dxgi/dxgi.spec
@@ -1 +1,2 @@
 @ stdcall CreateDXGIFactory(ptr ptr)
+@ stdcall dxgi_wined3d_create_device(ptr long ptr long ptr ptr ptr)
diff --git a/dlls/dxgi/dxgi_main.c b/dlls/dxgi/dxgi_main.c
index 44b4eee..24001b6 100644
--- a/dlls/dxgi/dxgi_main.c
+++ b/dlls/dxgi/dxgi_main.c
@@ -62,3 +62,49 @@ HRESULT WINAPI CreateDXGIFactory(REFIID riid, void **factory)
 
     return hr;
 }
+
+HRESULT WINAPI dxgi_wined3d_create_device(IDXGIAdapter *adapter, WINED3DDEVTYPE device_type,
+        HMODULE swrast, UINT flags, IUnknown *outer_unknown, REFIID riid, void **device)
+{
+    struct dxgi_device *object;
+    HRESULT hr;
+
+    FIXME("adapter %p, device_type %#x, swrast %p, flags %#x, outer_unknown %p, riid %s, device %p partial stub!\n",
+            adapter, device_type, swrast, flags, outer_unknown, debugstr_guid(riid), device);
+
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+    if (!object)
+    {
+        ERR("Failed to allocate DXGI device object memory\n");
+        return E_OUTOFMEMORY;
+    }
+
+    object->vtbl = &dxgi_device_vtbl;
+    object->inner_unknown_vtbl = &dxgi_device_inner_unkown_vtbl;
+    object->refcount = 1;
+
+    if (outer_unknown)
+    {
+        object->outer_unknown = outer_unknown;
+        if (!IsEqualGUID(riid, &IID_IUnknown))
+        {
+            hr = CLASS_E_NOAGGREGATION;
+            goto fail;
+        }
+        *device = &object->inner_unknown_vtbl;
+    }
+    else
+    {
+        object->outer_unknown = (IUnknown *)&object->inner_unknown_vtbl;
+        hr = IDXGIDevice_QueryInterface((IDXGIDevice *)object, riid, device);
+        if (FAILED(hr)) goto fail;
+        IDXGIDevice_Release((IDXGIDevice *)object);
+    }
+
+    return S_OK;
+
+fail:
+    HeapFree(GetProcessHeap(), 0, object);
+    *device = NULL;
+    return hr;
+}
diff --git a/dlls/dxgi/dxgi_private.h b/dlls/dxgi/dxgi_private.h
index 2d6fbc2..70149fe 100644
--- a/dlls/dxgi/dxgi_private.h
+++ b/dlls/dxgi/dxgi_private.h
@@ -23,10 +23,12 @@
 
 #define COBJMACROS
 #include "winbase.h"
+#include "wingdi.h"
 #include "winuser.h"
 #include "objbase.h"
 
 #include "dxgi.h"
+#include "wine/wined3d_interface.h"
 
 /* IDXGIFactory */
 extern const struct IDXGIFactoryVtbl dxgi_factory_vtbl;
@@ -38,9 +40,12 @@ struct dxgi_factory
 
 /* IDXGIDevice */
 extern const struct IDXGIDeviceVtbl dxgi_device_vtbl;
+extern const struct IUnknownVtbl dxgi_device_inner_unkown_vtbl;
 struct dxgi_device
 {
     const struct IDXGIDeviceVtbl *vtbl;
+    const struct IUnknownVtbl *inner_unknown_vtbl;
+    IUnknown *outer_unknown;
     LONG refcount;
 };
 
-- 
1.5.6.4



--------------000904060300000201050008--



More information about the wine-patches mailing list