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