dxgi: Implement IDXGIDevice::CreateSurface().
This commit is contained in:
parent
23094bfad8
commit
c9f116a56f
|
@ -58,6 +58,7 @@ struct d3d10_texture2d
|
||||||
const struct ID3D10Texture2DVtbl *vtbl;
|
const struct ID3D10Texture2DVtbl *vtbl;
|
||||||
LONG refcount;
|
LONG refcount;
|
||||||
|
|
||||||
|
IUnknown *dxgi_surface;
|
||||||
IWineD3DSurface *wined3d_surface;
|
IWineD3DSurface *wined3d_surface;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -602,6 +602,16 @@ static HRESULT STDMETHODCALLTYPE d3d10_device_CreateTexture2D(ID3D10Device *ifac
|
||||||
return E_FAIL;
|
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);
|
wined3d_device = IWineDXGIDevice_get_wined3d_device(wine_device);
|
||||||
IWineDXGIDevice_Release(wine_device);
|
IWineDXGIDevice_Release(wine_device);
|
||||||
|
|
||||||
|
@ -614,6 +624,7 @@ static HRESULT STDMETHODCALLTYPE d3d10_device_CreateTexture2D(ID3D10Device *ifac
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
ERR("CreateSurface failed, returning %#x\n", hr);
|
ERR("CreateSurface failed, returning %#x\n", hr);
|
||||||
|
IDXGISurface_Release(object->dxgi_surface);
|
||||||
HeapFree(GetProcessHeap(), 0, object);
|
HeapFree(GetProcessHeap(), 0, object);
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,7 +116,7 @@ static void test_create_texture(ID3D10Device *device)
|
||||||
ok(SUCCEEDED(hr), "Failed to create a 2d texture, hr %#x\n", hr);
|
ok(SUCCEEDED(hr), "Failed to create a 2d texture, hr %#x\n", hr);
|
||||||
|
|
||||||
hr = ID3D10Texture2D_QueryInterface(texture, &IID_IDXGISurface, (void **)&surface);
|
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);
|
if (SUCCEEDED(hr)) IDXGISurface_Release(surface);
|
||||||
ID3D10Texture2D_Release(texture);
|
ID3D10Texture2D_Release(texture);
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d10core);
|
||||||
|
|
||||||
static HRESULT STDMETHODCALLTYPE d3d10_texture2d_QueryInterface(ID3D10Texture2D *iface, REFIID riid, void **object)
|
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);
|
TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object);
|
||||||
|
|
||||||
if (IsEqualGUID(riid, &IID_ID3D10Texture2D)
|
if (IsEqualGUID(riid, &IID_ID3D10Texture2D)
|
||||||
|
@ -40,6 +42,12 @@ static HRESULT STDMETHODCALLTYPE d3d10_texture2d_QueryInterface(ID3D10Texture2D
|
||||||
return S_OK;
|
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));
|
WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid));
|
||||||
|
|
||||||
*object = NULL;
|
*object = NULL;
|
||||||
|
@ -65,6 +73,7 @@ static ULONG STDMETHODCALLTYPE d3d10_texture2d_Release(ID3D10Texture2D *iface)
|
||||||
|
|
||||||
if (!refcount)
|
if (!refcount)
|
||||||
{
|
{
|
||||||
|
if (This->dxgi_surface) IDXGISurface_Release(This->dxgi_surface);
|
||||||
if (This->wined3d_surface) IWineD3DSurface_Release(This->wined3d_surface);
|
if (This->wined3d_surface) IWineD3DSurface_Release(This->wined3d_surface);
|
||||||
HeapFree(GetProcessHeap(), 0, This);
|
HeapFree(GetProcessHeap(), 0, This);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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_SURFACE_DESC *desc, UINT surface_count, DXGI_USAGE usage,
|
||||||
const DXGI_SHARED_RESOURCE *shared_resource, IDXGISurface **surface)
|
const DXGI_SHARED_RESOURCE *shared_resource, IDXGISurface **surface)
|
||||||
{
|
{
|
||||||
struct dxgi_surface *object;
|
IWineD3DDeviceParent *device_parent;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
UINT i;
|
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);
|
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));
|
memset(surface, 0, surface_count * sizeof(*surface));
|
||||||
for (i = 0; i < surface_count; ++i)
|
for (i = 0; i < surface_count; ++i)
|
||||||
{
|
{
|
||||||
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
|
IWineD3DSurface *wined3d_surface;
|
||||||
if (!object)
|
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");
|
ERR("CreateSurface failed, returning %#x\n", hr);
|
||||||
hr = E_OUTOFMEMORY;
|
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
object->vtbl = &dxgi_surface_vtbl;
|
hr = IWineD3DSurface_GetParent(wined3d_surface, &parent);
|
||||||
object->inner_unknown_vtbl = &dxgi_surface_inner_unknown_vtbl;
|
IWineD3DSurface_Release(wined3d_surface);
|
||||||
object->refcount = 1;
|
if (FAILED(hr))
|
||||||
object->outer_unknown = (IUnknown *)&object->inner_unknown_vtbl;
|
{
|
||||||
surface[i] = (IDXGISurface *)object;
|
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;
|
return S_OK;
|
||||||
|
|
||||||
fail:
|
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;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,6 +244,41 @@ static IWineD3DDevice * STDMETHODCALLTYPE dxgi_device_get_wined3d_device(IWineDX
|
||||||
return This->wined3d_device;
|
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 =
|
const struct IWineDXGIDeviceVtbl dxgi_device_vtbl =
|
||||||
{
|
{
|
||||||
/* IUnknown methods */
|
/* IUnknown methods */
|
||||||
|
@ -238,4 +298,5 @@ const struct IWineDXGIDeviceVtbl dxgi_device_vtbl =
|
||||||
dxgi_device_GetGPUThreadPriority,
|
dxgi_device_GetGPUThreadPriority,
|
||||||
/* IWineDXGIAdapter methods */
|
/* IWineDXGIAdapter methods */
|
||||||
dxgi_device_get_wined3d_device,
|
dxgi_device_get_wined3d_device,
|
||||||
|
dxgi_device_create_surface,
|
||||||
};
|
};
|
||||||
|
|
|
@ -115,7 +115,7 @@ static void test_create_surface(IDXGIDevice *device)
|
||||||
ok(SUCCEEDED(hr), "Failed to create a dxgi surface, hr %#x\n", hr);
|
ok(SUCCEEDED(hr), "Failed to create a dxgi surface, hr %#x\n", hr);
|
||||||
|
|
||||||
hr = IDXGISurface_QueryInterface(surface, &IID_ID3D10Texture2D, (void **)&texture);
|
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);
|
if (SUCCEEDED(hr)) ID3D10Texture2D_Release(texture);
|
||||||
|
|
||||||
IDXGISurface_Release(surface);
|
IDXGISurface_Release(surface);
|
||||||
|
|
|
@ -46,4 +46,11 @@ interface IWineDXGIAdapter : IDXGIAdapter
|
||||||
interface IWineDXGIDevice : IDXGIDevice
|
interface IWineDXGIDevice : IDXGIDevice
|
||||||
{
|
{
|
||||||
struct IWineD3DDevice *get_wined3d_device();
|
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
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue