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