From 43f469ec6a0518028c12c757895e2c483eafd4ec Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Mon, 19 Jan 2009 10:39:05 +0100 Subject: [PATCH] d3d10core: Implement device_parent_CreateSurface(). --- .gitignore | 2 +- dlls/d3d10core/d3d10core_private.h | 3 + dlls/d3d10core/device.c | 64 +++++++++++++++++++++- dlls/d3d10core/texture2d.c | 6 ++ dlls/dxgi/Makefile.in | 2 - dlls/dxgi/device.c | 48 +++++++++++----- dlls/dxgi/dxgi_private.h | 6 +- include/Makefile.in | 3 +- .../wine/winedxgi.idl | 12 +++- tools/make_makefiles | 1 + 10 files changed, 123 insertions(+), 24 deletions(-) rename dlls/dxgi/dxgi_private_interface.idl => include/wine/winedxgi.idl (82%) diff --git a/.gitignore b/.gitignore index 4b61b4da2d1..65a04708684 100644 --- a/.gitignore +++ b/.gitignore @@ -34,7 +34,6 @@ dlls/ctl3dv2.dll16 dlls/ddeml.dll16 dlls/dispdib.dll16 dlls/display.drv16 -dlls/dxgi/dxgi_private_interface.h dlls/gdi.exe16 dlls/imm.dll16 dlls/jscript/jsglobal.tlb @@ -202,6 +201,7 @@ include/vmr9.h include/wine/itss.h include/wine/svcctl.h include/wine/wined3d.h +include/wine/winedxgi.h include/wtypes.h include/wuapi.h include/xmldom.h diff --git a/dlls/d3d10core/d3d10core_private.h b/dlls/d3d10core/d3d10core_private.h index fa645ccc2e3..1b28d5e50f7 100644 --- a/dlls/d3d10core/d3d10core_private.h +++ b/dlls/d3d10core/d3d10core_private.h @@ -32,6 +32,7 @@ #include "initguid.h" #endif #include "wine/wined3d.h" +#include "wine/winedxgi.h" /* TRACE helper functions */ const char *debug_d3d10_primitive_topology(D3D10_PRIMITIVE_TOPOLOGY topology); @@ -56,6 +57,8 @@ struct d3d10_texture2d { const struct ID3D10Texture2DVtbl *vtbl; LONG refcount; + + IWineD3DSurface *wined3d_surface; }; /* Layered device */ diff --git a/dlls/d3d10core/device.c b/dlls/d3d10core/device.c index 132b70a34ba..965bd49f940 100644 --- a/dlls/d3d10core/device.c +++ b/dlls/d3d10core/device.c @@ -575,6 +575,7 @@ static HRESULT STDMETHODCALLTYPE d3d10_device_CreateTexture2D(ID3D10Device *ifac const D3D10_TEXTURE2D_DESC *desc, const D3D10_SUBRESOURCE_DATA *data, ID3D10Texture2D **texture) { struct d3d10_texture2d *object; + HRESULT hr; FIXME("iface %p, desc %p, data %p, texture %p partial stub!\n", iface, desc, data, texture); @@ -587,6 +588,37 @@ static HRESULT STDMETHODCALLTYPE d3d10_device_CreateTexture2D(ID3D10Device *ifac object->vtbl = &d3d10_texture2d_vtbl; object->refcount = 1; + + if (desc->MipLevels == 1 && desc->ArraySize == 1) + { + IWineD3DDevice *wined3d_device; + IWineDXGIDevice *wine_device; + + hr = ID3D10Device_QueryInterface(iface, &IID_IWineDXGIDevice, (void **)&wine_device); + if (FAILED(hr)) + { + ERR("Device should implement IWineDXGIDevice\n"); + HeapFree(GetProcessHeap(), 0, object); + return E_FAIL; + } + + wined3d_device = IWineDXGIDevice_get_wined3d_device(wine_device); + IWineDXGIDevice_Release(wine_device); + + FIXME("Implement DXGI<->wined3d format and usage conversion\n"); + + hr = IWineD3DDevice_CreateSurface(wined3d_device, desc->Width, desc->Height, desc->Format, FALSE, + FALSE, 0, &object->wined3d_surface, WINED3DRTYPE_SURFACE, desc->Usage, WINED3DPOOL_DEFAULT, + desc->SampleDesc.Count, desc->SampleDesc.Quality, NULL, SURFACE_OPENGL, (IUnknown *)object); + IWineD3DDevice_Release(wined3d_device); + if (FAILED(hr)) + { + ERR("CreateSurface failed, returning %#x\n", hr); + HeapFree(GetProcessHeap(), 0, object); + return hr; + } + } + *texture = (ID3D10Texture2D *)object; TRACE("Created ID3D10Texture2D %p\n", object); @@ -937,11 +969,39 @@ static HRESULT STDMETHODCALLTYPE device_parent_CreateSurface(IWineD3DDeviceParen IUnknown *superior, UINT width, UINT height, WINED3DFORMAT format, DWORD usage, WINED3DPOOL pool, UINT level, WINED3DCUBEMAP_FACES face, IWineD3DSurface **surface) { + struct d3d10_device *This = device_from_device_parent(iface); + struct d3d10_texture2d *texture; + D3D10_TEXTURE2D_DESC desc; + HRESULT hr; + FIXME("iface %p, superior %p, width %u, height %u, format %#x, usage %#x,\n" - "\tpool %#x, level %u, face %u, surface %p stub!\n", + "\tpool %#x, level %u, face %u, surface %p partial stub!\n", iface, superior, width, height, format, usage, pool, level, face, surface); - return E_NOTIMPL; + FIXME("Implement DXGI<->wined3d format and usage conversion\n"); + + desc.Width = width; + desc.Height = height; + desc.MipLevels = 1; + desc.ArraySize = 1; + desc.Format = format; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = usage; + desc.BindFlags = 0; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + + hr = d3d10_device_CreateTexture2D((ID3D10Device *)This, &desc, NULL, (ID3D10Texture2D **)&texture); + if (FAILED(hr)) + { + ERR("CreateTexture2D failed, returning %#x\n", hr); + return hr; + } + + *surface = texture->wined3d_surface; + + return S_OK; } static HRESULT STDMETHODCALLTYPE device_parent_CreateRenderTarget(IWineD3DDeviceParent *iface, diff --git a/dlls/d3d10core/texture2d.c b/dlls/d3d10core/texture2d.c index 9b57c613419..d0fb0f529b7 100644 --- a/dlls/d3d10core/texture2d.c +++ b/dlls/d3d10core/texture2d.c @@ -63,6 +63,12 @@ static ULONG STDMETHODCALLTYPE d3d10_texture2d_Release(ID3D10Texture2D *iface) TRACE("%p decreasing refcount to %u\n", This, refcount); + if (!refcount) + { + if (This->wined3d_surface) IWineD3DSurface_Release(This->wined3d_surface); + HeapFree(GetProcessHeap(), 0, This); + } + return refcount; } diff --git a/dlls/dxgi/Makefile.in b/dlls/dxgi/Makefile.in index 9215e611a98..d340b6f4f26 100644 --- a/dlls/dxgi/Makefile.in +++ b/dlls/dxgi/Makefile.in @@ -17,8 +17,6 @@ C_SRCS = \ RC_SRCS = version.rc -IDL_H_SRCS = dxgi_private_interface.idl - @MAKE_DLL_RULES@ @DEPENDENCIES@ # everything below this line is overwritten by make depend diff --git a/dlls/dxgi/device.c b/dlls/dxgi/device.c index 69ba3e595bd..28bc9becac2 100644 --- a/dlls/dxgi/device.c +++ b/dlls/dxgi/device.c @@ -26,7 +26,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(dxgi); /* IUnknown methods */ -static HRESULT STDMETHODCALLTYPE dxgi_device_QueryInterface(IDXGIDevice *iface, REFIID riid, void **object) +static HRESULT STDMETHODCALLTYPE dxgi_device_QueryInterface(IWineDXGIDevice *iface, REFIID riid, void **object) { struct dxgi_device *This = (struct dxgi_device *)iface; @@ -34,7 +34,8 @@ static HRESULT STDMETHODCALLTYPE dxgi_device_QueryInterface(IDXGIDevice *iface, if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDXGIObject) - || IsEqualGUID(riid, &IID_IDXGIDevice)) + || IsEqualGUID(riid, &IID_IDXGIDevice) + || IsEqualGUID(riid, &IID_IWineDXGIDevice)) { IUnknown_AddRef(iface); *object = iface; @@ -53,7 +54,7 @@ static HRESULT STDMETHODCALLTYPE dxgi_device_QueryInterface(IDXGIDevice *iface, return E_NOINTERFACE; } -static ULONG STDMETHODCALLTYPE dxgi_device_AddRef(IDXGIDevice *iface) +static ULONG STDMETHODCALLTYPE dxgi_device_AddRef(IWineDXGIDevice *iface) { struct dxgi_device *This = (struct dxgi_device *)iface; ULONG refcount = InterlockedIncrement(&This->refcount); @@ -63,7 +64,7 @@ static ULONG STDMETHODCALLTYPE dxgi_device_AddRef(IDXGIDevice *iface) return refcount; } -static ULONG STDMETHODCALLTYPE dxgi_device_Release(IDXGIDevice *iface) +static ULONG STDMETHODCALLTYPE dxgi_device_Release(IWineDXGIDevice *iface) { struct dxgi_device *This = (struct dxgi_device *)iface; ULONG refcount = InterlockedDecrement(&This->refcount); @@ -85,28 +86,31 @@ static ULONG STDMETHODCALLTYPE dxgi_device_Release(IDXGIDevice *iface) /* IDXGIObject methods */ -static HRESULT STDMETHODCALLTYPE dxgi_device_SetPrivateData(IDXGIDevice *iface, REFGUID guid, UINT data_size, const void *data) +static HRESULT STDMETHODCALLTYPE dxgi_device_SetPrivateData(IWineDXGIDevice *iface, + REFGUID guid, UINT data_size, const void *data) { FIXME("iface %p, guid %s, data_size %u, data %p stub!\n", iface, debugstr_guid(guid), data_size, data); return E_NOTIMPL; } -static HRESULT STDMETHODCALLTYPE dxgi_device_SetPrivateDataInterface(IDXGIDevice *iface, REFGUID guid, const IUnknown *object) +static HRESULT STDMETHODCALLTYPE dxgi_device_SetPrivateDataInterface(IWineDXGIDevice *iface, + REFGUID guid, const IUnknown *object) { FIXME("iface %p, guid %s, object %p stub!\n", iface, debugstr_guid(guid), object); return E_NOTIMPL; } -static HRESULT STDMETHODCALLTYPE dxgi_device_GetPrivateData(IDXGIDevice *iface, REFGUID guid, UINT *data_size, void *data) +static HRESULT STDMETHODCALLTYPE dxgi_device_GetPrivateData(IWineDXGIDevice *iface, + REFGUID guid, UINT *data_size, void *data) { FIXME("iface %p, guid %s, data_size %p, data %p stub!\n", iface, debugstr_guid(guid), data_size, data); return E_NOTIMPL; } -static HRESULT STDMETHODCALLTYPE dxgi_device_GetParent(IDXGIDevice *iface, REFIID riid, void **parent) +static HRESULT STDMETHODCALLTYPE dxgi_device_GetParent(IWineDXGIDevice *iface, REFIID riid, void **parent) { FIXME("iface %p, riid %s, parent %p stub!\n", iface, debugstr_guid(riid), parent); @@ -115,7 +119,7 @@ static HRESULT STDMETHODCALLTYPE dxgi_device_GetParent(IDXGIDevice *iface, REFII /* IDXGIDevice methods */ -static HRESULT STDMETHODCALLTYPE dxgi_device_GetAdapter(IDXGIDevice *iface, IDXGIAdapter **adapter) +static HRESULT STDMETHODCALLTYPE dxgi_device_GetAdapter(IWineDXGIDevice *iface, IDXGIAdapter **adapter) { struct dxgi_device *This = (struct dxgi_device *)iface; WINED3DDEVICE_CREATION_PARAMETERS create_parameters; @@ -137,7 +141,7 @@ static HRESULT STDMETHODCALLTYPE dxgi_device_GetAdapter(IDXGIDevice *iface, IDXG return IWineDXGIFactory_EnumAdapters(This->factory, create_parameters.AdapterOrdinal, adapter); } -static HRESULT STDMETHODCALLTYPE dxgi_device_CreateSurface(IDXGIDevice *iface, +static HRESULT STDMETHODCALLTYPE dxgi_device_CreateSurface(IWineDXGIDevice *iface, const DXGI_SURFACE_DESC *desc, UINT surface_count, DXGI_USAGE usage, const DXGI_SHARED_RESOURCE *shared_resource, IDXGISurface **surface) { @@ -176,7 +180,7 @@ fail: return hr; } -static HRESULT STDMETHODCALLTYPE dxgi_device_QueryResourceResidency(IDXGIDevice *iface, +static HRESULT STDMETHODCALLTYPE dxgi_device_QueryResourceResidency(IWineDXGIDevice *iface, IUnknown *const *resources, DXGI_RESIDENCY *residency, UINT resource_count) { FIXME("iface %p, resources %p, residency %p, resource_count %u stub!\n", @@ -185,21 +189,35 @@ static HRESULT STDMETHODCALLTYPE dxgi_device_QueryResourceResidency(IDXGIDevice return E_NOTIMPL; } -static HRESULT STDMETHODCALLTYPE dxgi_device_SetGPUThreadPriority(IDXGIDevice *iface, INT priority) +static HRESULT STDMETHODCALLTYPE dxgi_device_SetGPUThreadPriority(IWineDXGIDevice *iface, INT priority) { FIXME("iface %p, priority %d stub!\n", iface, priority); return E_NOTIMPL; } -static HRESULT STDMETHODCALLTYPE dxgi_device_GetGPUThreadPriority(IDXGIDevice *iface, INT *priority) +static HRESULT STDMETHODCALLTYPE dxgi_device_GetGPUThreadPriority(IWineDXGIDevice *iface, INT *priority) { FIXME("iface %p, priority %p stub!\n", iface, priority); return E_NOTIMPL; } -const struct IDXGIDeviceVtbl dxgi_device_vtbl = +/* IWineDXGIDevice methods */ + +static IWineD3DDevice * STDMETHODCALLTYPE dxgi_device_get_wined3d_device(IWineDXGIDevice *iface) +{ + struct dxgi_device *This = (struct dxgi_device *)iface; + + TRACE("iface %p\n", iface); + + EnterCriticalSection(&dxgi_cs); + IWineD3DDevice_AddRef(This->wined3d_device); + LeaveCriticalSection(&dxgi_cs); + return This->wined3d_device; +} + +const struct IWineDXGIDeviceVtbl dxgi_device_vtbl = { /* IUnknown methods */ dxgi_device_QueryInterface, @@ -216,4 +234,6 @@ const struct IDXGIDeviceVtbl dxgi_device_vtbl = dxgi_device_QueryResourceResidency, dxgi_device_SetGPUThreadPriority, dxgi_device_GetGPUThreadPriority, + /* IWineDXGIAdapter methods */ + dxgi_device_get_wined3d_device, }; diff --git a/dlls/dxgi/dxgi_private.h b/dlls/dxgi/dxgi_private.h index c7ed875b367..d19b9b1934c 100644 --- a/dlls/dxgi/dxgi_private.h +++ b/dlls/dxgi/dxgi_private.h @@ -32,7 +32,7 @@ #include "initguid.h" #endif #include "wine/wined3d.h" -#include "dxgi_private_interface.h" +#include "wine/winedxgi.h" extern CRITICAL_SECTION dxgi_cs; @@ -51,10 +51,10 @@ struct dxgi_factory }; /* IDXGIDevice */ -extern const struct IDXGIDeviceVtbl dxgi_device_vtbl; +extern const struct IWineDXGIDeviceVtbl dxgi_device_vtbl; struct dxgi_device { - const struct IDXGIDeviceVtbl *vtbl; + const struct IWineDXGIDeviceVtbl *vtbl; IUnknown *child_layer; LONG refcount; IWineD3DDevice *wined3d_device; diff --git a/include/Makefile.in b/include/Makefile.in index 7aca0e496eb..98bd715b228 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -5,7 +5,8 @@ VPATH = @srcdir@ MODULE = none PRIVATE_IDL_H_SRCS = \ - wine/wined3d.idl + wine/wined3d.idl \ + wine/winedxgi.idl PUBLIC_IDL_H_SRCS = \ activaut.idl \ diff --git a/dlls/dxgi/dxgi_private_interface.idl b/include/wine/winedxgi.idl similarity index 82% rename from dlls/dxgi/dxgi_private_interface.idl rename to include/wine/winedxgi.idl index 2bb8b43024b..860b695da92 100644 --- a/dlls/dxgi/dxgi_private_interface.idl +++ b/include/wine/winedxgi.idl @@ -1,5 +1,5 @@ /* - * Copyright 2008 Henri Verbeet for CodeWeavers + * Copyright 2008-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 @@ -37,3 +37,13 @@ interface IWineDXGIAdapter : IDXGIAdapter { UINT get_ordinal(); } + +[ + object, + local, + uuid(3e1ff30b-c951-48c3-b010-0fb49f3dca71) +] +interface IWineDXGIDevice : IDXGIDevice +{ + struct IWineD3DDevice *get_wined3d_device(); +} diff --git a/tools/make_makefiles b/tools/make_makefiles index 86dcd4cb63d..d134d8ece03 100755 --- a/tools/make_makefiles +++ b/tools/make_makefiles @@ -116,6 +116,7 @@ my %private_idl_headers = ( "dyngraph.idl" => 1, "vmrender.idl" => 1, "wine/wined3d.idl" => 1, + "wine/winedxgi.idl" => 1, ); my (@makefiles, %makefiles); -- 2.11.4.GIT