diff --git a/dlls/d3d10core/d3d10core_private.h b/dlls/d3d10core/d3d10core_private.h index 1b28d5e50f7..5453600bd05 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 034c9b9a5ab..2e4c5c15b38 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 5493d2370fc..1a3f331f9f3 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 d0fb0f529b7..afb6167d02a 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 235e1f7baaf..3c10f9918e6 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; + } - TRACE("Created IDXGISurface %p (%u/%u)\n", object, i + 1, surface_count); + 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", 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 39d780ab318..12893b153fa 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 860b695da92..3fc7883168f 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 + ); }