ddraw: Version 1 devices are aggregated by the surface that created them.
This commit is contained in:
parent
e13de0adf8
commit
cf30899f1a
@ -4426,7 +4426,7 @@ static HRESULT WINAPI d3d7_CreateDevice(IDirect3D7 *iface, REFCLSID riid,
|
|||||||
TRACE("iface %p, riid %s, surface %p, device %p.\n", iface, debugstr_guid(riid), surface, device);
|
TRACE("iface %p, riid %s, surface %p, device %p.\n", iface, debugstr_guid(riid), surface, device);
|
||||||
|
|
||||||
wined3d_mutex_lock();
|
wined3d_mutex_lock();
|
||||||
hr = d3d_device_create(ddraw, target, 7, &object);
|
hr = d3d_device_create(ddraw, target, 7, &object, NULL);
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
*device = &object->IDirect3DDevice7_iface;
|
*device = &object->IDirect3DDevice7_iface;
|
||||||
else
|
else
|
||||||
@ -4454,7 +4454,7 @@ static HRESULT WINAPI d3d3_CreateDevice(IDirect3D3 *iface, REFCLSID riid,
|
|||||||
return CLASS_E_NOAGGREGATION;
|
return CLASS_E_NOAGGREGATION;
|
||||||
|
|
||||||
wined3d_mutex_lock();
|
wined3d_mutex_lock();
|
||||||
hr = d3d_device_create(ddraw, surface_impl, 3, &device_impl);
|
hr = d3d_device_create(ddraw, surface_impl, 3, &device_impl, NULL);
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
*device = &device_impl->IDirect3DDevice3_iface;
|
*device = &device_impl->IDirect3DDevice3_iface;
|
||||||
else
|
else
|
||||||
@ -4479,7 +4479,7 @@ static HRESULT WINAPI d3d2_CreateDevice(IDirect3D2 *iface, REFCLSID riid,
|
|||||||
iface, debugstr_guid(riid), surface, device);
|
iface, debugstr_guid(riid), surface, device);
|
||||||
|
|
||||||
wined3d_mutex_lock();
|
wined3d_mutex_lock();
|
||||||
hr = d3d_device_create(ddraw, surface_impl, 2, &device_impl);
|
hr = d3d_device_create(ddraw, surface_impl, 2, &device_impl, NULL);
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
*device = &device_impl->IDirect3DDevice2_iface;
|
*device = &device_impl->IDirect3DDevice2_iface;
|
||||||
else
|
else
|
||||||
|
@ -159,6 +159,7 @@ struct ddraw_surface
|
|||||||
struct ddraw *ddraw;
|
struct ddraw *ddraw;
|
||||||
struct wined3d_surface *wined3d_surface;
|
struct wined3d_surface *wined3d_surface;
|
||||||
struct wined3d_texture *wined3d_texture;
|
struct wined3d_texture *wined3d_texture;
|
||||||
|
IDirect3DDeviceImpl *device1;
|
||||||
|
|
||||||
/* This implementation handles attaching surfaces to other surfaces */
|
/* This implementation handles attaching surfaces to other surfaces */
|
||||||
struct ddraw_surface *next_attached;
|
struct ddraw_surface *next_attached;
|
||||||
@ -278,10 +279,11 @@ struct IDirect3DDeviceImpl
|
|||||||
IDirect3DDevice3 IDirect3DDevice3_iface;
|
IDirect3DDevice3 IDirect3DDevice3_iface;
|
||||||
IDirect3DDevice2 IDirect3DDevice2_iface;
|
IDirect3DDevice2 IDirect3DDevice2_iface;
|
||||||
IDirect3DDevice IDirect3DDevice_iface;
|
IDirect3DDevice IDirect3DDevice_iface;
|
||||||
|
IUnknown IUnknown_inner;
|
||||||
LONG ref;
|
LONG ref;
|
||||||
UINT version;
|
UINT version;
|
||||||
|
|
||||||
/* Other object connections */
|
IUnknown *outer_unknown;
|
||||||
struct wined3d_device *wined3d_device;
|
struct wined3d_device *wined3d_device;
|
||||||
struct ddraw *ddraw;
|
struct ddraw *ddraw;
|
||||||
struct wined3d_buffer *indexbuffer;
|
struct wined3d_buffer *indexbuffer;
|
||||||
@ -316,7 +318,7 @@ struct IDirect3DDeviceImpl
|
|||||||
};
|
};
|
||||||
|
|
||||||
HRESULT d3d_device_create(struct ddraw *ddraw, struct ddraw_surface *target,
|
HRESULT d3d_device_create(struct ddraw *ddraw, struct ddraw_surface *target,
|
||||||
UINT version, IDirect3DDeviceImpl **device) DECLSPEC_HIDDEN;
|
UINT version, IDirect3DDeviceImpl **device, IUnknown *outer_unknown) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
/* The IID */
|
/* The IID */
|
||||||
extern const GUID IID_D3DDEVICE_WineD3D DECLSPEC_HIDDEN;
|
extern const GUID IID_D3DDEVICE_WineD3D DECLSPEC_HIDDEN;
|
||||||
|
@ -75,178 +75,169 @@ static inline WORD d3d_fpu_setup(void)
|
|||||||
return oldcw;
|
return oldcw;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
static inline IDirect3DDeviceImpl *impl_from_IUnknown(IUnknown *iface)
|
||||||
* IUnknown Methods. Common for Version 1, 2, 3 and 7
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
* IDirect3DDevice7::QueryInterface
|
|
||||||
*
|
|
||||||
* Used to query other interfaces from a Direct3DDevice interface.
|
|
||||||
* It can return interface pointers to all Direct3DDevice versions as well
|
|
||||||
* as IDirectDraw and IDirect3D. For a link to QueryInterface
|
|
||||||
* rules see ddraw.c, IDirectDraw7::QueryInterface
|
|
||||||
*
|
|
||||||
* Exists in Version 1, 2, 3 and 7
|
|
||||||
*
|
|
||||||
* Params:
|
|
||||||
* refiid: Interface ID queried for
|
|
||||||
* obj: Used to return the interface pointer
|
|
||||||
*
|
|
||||||
* Returns:
|
|
||||||
* D3D_OK or E_NOINTERFACE
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
static HRESULT WINAPI
|
|
||||||
IDirect3DDeviceImpl_7_QueryInterface(IDirect3DDevice7 *iface,
|
|
||||||
REFIID refiid,
|
|
||||||
void **obj)
|
|
||||||
{
|
{
|
||||||
IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
|
return CONTAINING_RECORD(iface, IDirect3DDeviceImpl, IUnknown_inner);
|
||||||
|
}
|
||||||
|
|
||||||
TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(refiid), obj);
|
static HRESULT WINAPI d3d_device_inner_QueryInterface(IUnknown *iface, REFIID riid, void **out)
|
||||||
|
{
|
||||||
|
IDirect3DDeviceImpl *device = impl_from_IUnknown(iface);
|
||||||
|
|
||||||
/* According to COM docs, if the QueryInterface fails, obj should be set to NULL */
|
TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
|
||||||
*obj = NULL;
|
|
||||||
|
|
||||||
if(!refiid)
|
if (!riid)
|
||||||
|
{
|
||||||
|
*out = NULL;
|
||||||
return DDERR_INVALIDPARAMS;
|
return DDERR_INVALIDPARAMS;
|
||||||
|
|
||||||
if ( IsEqualGUID( &IID_IUnknown, refiid ) )
|
|
||||||
{
|
|
||||||
*obj = iface;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (This->version == 7)
|
if (IsEqualGUID(&IID_IUnknown, riid))
|
||||||
{
|
{
|
||||||
if (IsEqualGUID(&IID_IDirect3DDevice7, refiid))
|
IDirect3DDevice7_AddRef(&device->IDirect3DDevice7_iface);
|
||||||
*obj = iface;
|
*out = &device->IDirect3DDevice7_iface;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device->version == 7)
|
||||||
|
{
|
||||||
|
if (IsEqualGUID(&IID_IDirect3DDevice7, riid))
|
||||||
|
{
|
||||||
|
IDirect3DDevice7_AddRef(&device->IDirect3DDevice7_iface);
|
||||||
|
*out = &device->IDirect3DDevice7_iface;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (IsEqualGUID(&IID_IDirect3DDevice3, refiid) && This->version == 3)
|
|
||||||
*obj = &This->IDirect3DDevice3_iface;
|
|
||||||
else if (IsEqualGUID(&IID_IDirect3DDevice2, refiid) && This->version >= 2)
|
|
||||||
*obj = &This->IDirect3DDevice2_iface;
|
|
||||||
else if (IsEqualGUID(&IID_IDirect3DDevice, refiid))
|
|
||||||
*obj = &This->IDirect3DDevice_iface;
|
|
||||||
else if (IsEqualGUID(&IID_IDirectDrawSurface, refiid) && This->version == 1)
|
|
||||||
*obj = &This->target->IDirectDrawSurface_iface;
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(refiid));
|
if (IsEqualGUID(&IID_IDirect3DDevice3, riid) && device->version == 3)
|
||||||
return E_NOINTERFACE;
|
{
|
||||||
|
IDirect3DDevice3_AddRef(&device->IDirect3DDevice3_iface);
|
||||||
|
*out = &device->IDirect3DDevice3_iface;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsEqualGUID(&IID_IDirect3DDevice2, riid) && device->version >= 2)
|
||||||
|
{
|
||||||
|
IDirect3DDevice2_AddRef(&device->IDirect3DDevice2_iface);
|
||||||
|
*out = &device->IDirect3DDevice2_iface;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsEqualGUID(&IID_IDirect3DDevice, riid))
|
||||||
|
{
|
||||||
|
IDirect3DDevice_AddRef(&device->IDirect3DDevice_iface);
|
||||||
|
*out = &device->IDirect3DDevice_iface;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* AddRef the returned interface */
|
WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
|
||||||
IUnknown_AddRef( (IUnknown *) *obj);
|
|
||||||
return D3D_OK;
|
*out = NULL;
|
||||||
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI IDirect3DDeviceImpl_3_QueryInterface(IDirect3DDevice3 *iface, REFIID riid,
|
static HRESULT WINAPI IDirect3DDeviceImpl_7_QueryInterface(IDirect3DDevice7 *iface, REFIID riid, void **out)
|
||||||
void **obj)
|
|
||||||
{
|
{
|
||||||
IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
|
IDirect3DDeviceImpl *device = impl_from_IDirect3DDevice7(iface);
|
||||||
TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), obj);
|
|
||||||
|
|
||||||
return IDirect3DDevice7_QueryInterface(&This->IDirect3DDevice7_iface, riid, obj);
|
TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
|
||||||
|
|
||||||
|
return IUnknown_QueryInterface(device->outer_unknown, riid, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI IDirect3DDeviceImpl_2_QueryInterface(IDirect3DDevice2 *iface, REFIID riid,
|
static HRESULT WINAPI IDirect3DDeviceImpl_3_QueryInterface(IDirect3DDevice3 *iface, REFIID riid, void **out)
|
||||||
void **obj)
|
|
||||||
{
|
{
|
||||||
IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface);
|
IDirect3DDeviceImpl *device = impl_from_IDirect3DDevice3(iface);
|
||||||
TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), obj);
|
|
||||||
|
|
||||||
return IDirect3DDevice7_QueryInterface(&This->IDirect3DDevice7_iface, riid, obj);
|
TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
|
||||||
|
|
||||||
|
return IUnknown_QueryInterface(device->outer_unknown, riid, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI IDirect3DDeviceImpl_1_QueryInterface(IDirect3DDevice *iface, REFIID riid,
|
static HRESULT WINAPI IDirect3DDeviceImpl_2_QueryInterface(IDirect3DDevice2 *iface, REFIID riid, void **out)
|
||||||
void **obp)
|
|
||||||
{
|
{
|
||||||
IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface);
|
IDirect3DDeviceImpl *device = impl_from_IDirect3DDevice2(iface);
|
||||||
TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), obp);
|
|
||||||
|
|
||||||
return IDirect3DDevice7_QueryInterface(&This->IDirect3DDevice7_iface, riid, obp);
|
TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
|
||||||
|
|
||||||
|
return IUnknown_QueryInterface(device->outer_unknown, riid, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
static HRESULT WINAPI IDirect3DDeviceImpl_1_QueryInterface(IDirect3DDevice *iface, REFIID riid, void **out)
|
||||||
* IDirect3DDevice7::AddRef
|
|
||||||
*
|
|
||||||
* Increases the refcount....
|
|
||||||
* The most exciting Method, definitely
|
|
||||||
*
|
|
||||||
* Exists in Version 1, 2, 3 and 7
|
|
||||||
*
|
|
||||||
* Returns:
|
|
||||||
* The new refcount
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
static ULONG WINAPI
|
|
||||||
IDirect3DDeviceImpl_7_AddRef(IDirect3DDevice7 *iface)
|
|
||||||
{
|
{
|
||||||
IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
|
IDirect3DDeviceImpl *device = impl_from_IDirect3DDevice(iface);
|
||||||
ULONG ref = InterlockedIncrement(&This->ref);
|
|
||||||
|
|
||||||
TRACE("%p increasing refcount to %u.\n", This, ref);
|
TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
|
||||||
|
|
||||||
|
return IUnknown_QueryInterface(device->outer_unknown, riid, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI d3d_device_inner_AddRef(IUnknown *iface)
|
||||||
|
{
|
||||||
|
IDirect3DDeviceImpl *device = impl_from_IUnknown(iface);
|
||||||
|
ULONG ref = InterlockedIncrement(&device->ref);
|
||||||
|
|
||||||
|
TRACE("%p increasing refcount to %u.\n", device, ref);
|
||||||
|
|
||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ULONG WINAPI IDirect3DDeviceImpl_3_AddRef(IDirect3DDevice3 *iface)
|
static ULONG WINAPI IDirect3DDeviceImpl_7_AddRef(IDirect3DDevice7 *iface)
|
||||||
{
|
{
|
||||||
IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
|
IDirect3DDeviceImpl *device = impl_from_IDirect3DDevice7(iface);
|
||||||
|
|
||||||
TRACE("iface %p.\n", iface);
|
TRACE("iface %p.\n", iface);
|
||||||
|
|
||||||
return IDirect3DDevice7_AddRef(&This->IDirect3DDevice7_iface);
|
return IUnknown_AddRef(device->outer_unknown);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI IDirect3DDeviceImpl_3_AddRef(IDirect3DDevice3 *iface)
|
||||||
|
{
|
||||||
|
IDirect3DDeviceImpl *device = impl_from_IDirect3DDevice3(iface);
|
||||||
|
|
||||||
|
TRACE("iface %p.\n", iface);
|
||||||
|
|
||||||
|
return IUnknown_AddRef(device->outer_unknown);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ULONG WINAPI IDirect3DDeviceImpl_2_AddRef(IDirect3DDevice2 *iface)
|
static ULONG WINAPI IDirect3DDeviceImpl_2_AddRef(IDirect3DDevice2 *iface)
|
||||||
{
|
{
|
||||||
IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface);
|
IDirect3DDeviceImpl *device = impl_from_IDirect3DDevice2(iface);
|
||||||
|
|
||||||
TRACE("iface %p.\n", iface);
|
TRACE("iface %p.\n", iface);
|
||||||
|
|
||||||
return IDirect3DDevice7_AddRef(&This->IDirect3DDevice7_iface);
|
return IUnknown_AddRef(device->outer_unknown);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ULONG WINAPI IDirect3DDeviceImpl_1_AddRef(IDirect3DDevice *iface)
|
static ULONG WINAPI IDirect3DDeviceImpl_1_AddRef(IDirect3DDevice *iface)
|
||||||
{
|
{
|
||||||
IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface);
|
IDirect3DDeviceImpl *device = impl_from_IDirect3DDevice(iface);
|
||||||
|
|
||||||
TRACE("iface %p.\n", iface);
|
TRACE("iface %p.\n", iface);
|
||||||
|
|
||||||
return IDirect3DDevice7_AddRef(&This->IDirect3DDevice7_iface);
|
return IUnknown_AddRef(device->outer_unknown);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
static ULONG WINAPI d3d_device_inner_Release(IUnknown *iface)
|
||||||
* IDirect3DDevice7::Release
|
|
||||||
*
|
|
||||||
* Decreases the refcount of the interface
|
|
||||||
* When the refcount is reduced to 0, the object is destroyed.
|
|
||||||
*
|
|
||||||
* Exists in Version 1, 2, 3 and 7
|
|
||||||
*
|
|
||||||
* Returns:d
|
|
||||||
* The new refcount
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
static ULONG WINAPI
|
|
||||||
IDirect3DDeviceImpl_7_Release(IDirect3DDevice7 *iface)
|
|
||||||
{
|
{
|
||||||
IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
|
IDirect3DDeviceImpl *This = impl_from_IUnknown(iface);
|
||||||
ULONG ref = InterlockedDecrement(&This->ref);
|
ULONG ref = InterlockedDecrement(&This->ref);
|
||||||
|
|
||||||
TRACE("%p decreasing refcount to %u.\n", This, ref);
|
TRACE("%p decreasing refcount to %u.\n", This, ref);
|
||||||
|
|
||||||
/* This method doesn't destroy the WineD3DDevice, because it's still in use for
|
/* This method doesn't destroy the wined3d device, because it's still in
|
||||||
* 2D rendering. IDirectDrawSurface7::Release will destroy the WineD3DDevice
|
* use for 2D rendering. IDirectDrawSurface7::Release will destroy the
|
||||||
* when the render target is released
|
* wined3d device when the render target is released. */
|
||||||
*/
|
if (!ref)
|
||||||
if (ref == 0)
|
|
||||||
{
|
{
|
||||||
DWORD i;
|
DWORD i;
|
||||||
|
|
||||||
wined3d_mutex_lock();
|
wined3d_mutex_lock();
|
||||||
|
|
||||||
/* There is no need to unset any resources here, wined3d will take
|
/* There is no need to unset any resources here, wined3d will take
|
||||||
* care of that on Uninit3D(). */
|
* care of that on uninit_3d(). */
|
||||||
|
|
||||||
/* Free the index buffer. */
|
/* Free the index buffer. */
|
||||||
wined3d_buffer_decref(This->indexbuffer);
|
wined3d_buffer_decref(This->indexbuffer);
|
||||||
@ -256,7 +247,7 @@ IDirect3DDeviceImpl_7_Release(IDirect3DDevice7 *iface)
|
|||||||
wined3d_device_set_render_target(This->wined3d_device, 0,
|
wined3d_device_set_render_target(This->wined3d_device, 0,
|
||||||
This->ddraw->wined3d_frontbuffer, TRUE);
|
This->ddraw->wined3d_frontbuffer, TRUE);
|
||||||
|
|
||||||
/* Release the WineD3DDevice. This won't destroy it. */
|
/* Release the wined3d device. This won't destroy it. */
|
||||||
if (!wined3d_device_decref(This->wined3d_device))
|
if (!wined3d_device_decref(This->wined3d_device))
|
||||||
ERR("The wined3d device (%p) was destroyed unexpectedly.\n", This->wined3d_device);
|
ERR("The wined3d device (%p) was destroyed unexpectedly.\n", This->wined3d_device);
|
||||||
|
|
||||||
@ -291,7 +282,7 @@ IDirect3DDeviceImpl_7_Release(IDirect3DDevice7 *iface)
|
|||||||
{
|
{
|
||||||
/* No FIXME here because this might happen because of sloppy applications. */
|
/* No FIXME here because this might happen because of sloppy applications. */
|
||||||
WARN("Leftover stateblock handle %#x (%p), deleting.\n", i + 1, entry->object);
|
WARN("Leftover stateblock handle %#x (%p), deleting.\n", i + 1, entry->object);
|
||||||
IDirect3DDevice7_DeleteStateBlock(iface, i + 1);
|
IDirect3DDevice7_DeleteStateBlock(&This->IDirect3DDevice7_iface, i + 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,10 +303,9 @@ IDirect3DDeviceImpl_7_Release(IDirect3DDevice7 *iface)
|
|||||||
ddraw_handle_table_destroy(&This->handle_table);
|
ddraw_handle_table_destroy(&This->handle_table);
|
||||||
|
|
||||||
TRACE("Releasing target %p.\n", This->target);
|
TRACE("Releasing target %p.\n", This->target);
|
||||||
/* Release the render target and the WineD3D render target
|
/* Release the render target. */
|
||||||
* (See IDirect3D7::CreateDevice for more comments on this)
|
if (This->version != 1)
|
||||||
*/
|
IDirectDrawSurface7_Release(&This->target->IDirectDrawSurface7_iface);
|
||||||
IDirectDrawSurface7_Release(&This->target->IDirectDrawSurface7_iface);
|
|
||||||
TRACE("Target release done\n");
|
TRACE("Target release done\n");
|
||||||
|
|
||||||
This->ddraw->d3ddevice = NULL;
|
This->ddraw->d3ddevice = NULL;
|
||||||
@ -329,28 +319,40 @@ IDirect3DDeviceImpl_7_Release(IDirect3DDevice7 *iface)
|
|||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ULONG WINAPI IDirect3DDeviceImpl_3_Release(IDirect3DDevice3 *iface)
|
static ULONG WINAPI IDirect3DDeviceImpl_7_Release(IDirect3DDevice7 *iface)
|
||||||
{
|
{
|
||||||
IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
|
IDirect3DDeviceImpl *device = impl_from_IDirect3DDevice7(iface);
|
||||||
|
|
||||||
TRACE("iface %p.\n", iface);
|
TRACE("iface %p.\n", iface);
|
||||||
|
|
||||||
return IDirect3DDevice7_Release(&This->IDirect3DDevice7_iface);
|
return IUnknown_Release(device->outer_unknown);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI IDirect3DDeviceImpl_3_Release(IDirect3DDevice3 *iface)
|
||||||
|
{
|
||||||
|
IDirect3DDeviceImpl *device = impl_from_IDirect3DDevice3(iface);
|
||||||
|
|
||||||
|
TRACE("iface %p.\n", iface);
|
||||||
|
|
||||||
|
return IUnknown_Release(device->outer_unknown);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ULONG WINAPI IDirect3DDeviceImpl_2_Release(IDirect3DDevice2 *iface)
|
static ULONG WINAPI IDirect3DDeviceImpl_2_Release(IDirect3DDevice2 *iface)
|
||||||
{
|
{
|
||||||
IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface);
|
IDirect3DDeviceImpl *device = impl_from_IDirect3DDevice2(iface);
|
||||||
|
|
||||||
TRACE("iface %p.\n", iface);
|
TRACE("iface %p.\n", iface);
|
||||||
|
|
||||||
return IDirect3DDevice7_Release(&This->IDirect3DDevice7_iface);
|
return IUnknown_Release(device->outer_unknown);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ULONG WINAPI IDirect3DDeviceImpl_1_Release(IDirect3DDevice *iface)
|
static ULONG WINAPI IDirect3DDeviceImpl_1_Release(IDirect3DDevice *iface)
|
||||||
{
|
{
|
||||||
IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface);
|
IDirect3DDeviceImpl *device = impl_from_IDirect3DDevice(iface);
|
||||||
|
|
||||||
TRACE("iface %p.\n", iface);
|
TRACE("iface %p.\n", iface);
|
||||||
|
|
||||||
return IDirect3DDevice7_Release(&This->IDirect3DDevice7_iface);
|
return IUnknown_Release(device->outer_unknown);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
@ -6898,6 +6900,13 @@ static const struct IDirect3DDeviceVtbl d3d_device1_vtbl =
|
|||||||
IDirect3DDeviceImpl_1_GetDirect3D
|
IDirect3DDeviceImpl_1_GetDirect3D
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct IUnknownVtbl d3d_device_inner_vtbl =
|
||||||
|
{
|
||||||
|
d3d_device_inner_QueryInterface,
|
||||||
|
d3d_device_inner_AddRef,
|
||||||
|
d3d_device_inner_Release,
|
||||||
|
};
|
||||||
|
|
||||||
IDirect3DDeviceImpl *unsafe_impl_from_IDirect3DDevice7(IDirect3DDevice7 *iface)
|
IDirect3DDeviceImpl *unsafe_impl_from_IDirect3DDevice7(IDirect3DDevice7 *iface)
|
||||||
{
|
{
|
||||||
if (!iface) return NULL;
|
if (!iface) return NULL;
|
||||||
@ -6959,7 +6968,7 @@ enum wined3d_depth_buffer_type IDirect3DDeviceImpl_UpdateDepthStencil(IDirect3DD
|
|||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT d3d_device_init(IDirect3DDeviceImpl *device, struct ddraw *ddraw,
|
static HRESULT d3d_device_init(IDirect3DDeviceImpl *device, struct ddraw *ddraw,
|
||||||
struct ddraw_surface *target, UINT version)
|
struct ddraw_surface *target, UINT version, IUnknown *outer_unknown)
|
||||||
{
|
{
|
||||||
static const D3DMATRIX ident =
|
static const D3DMATRIX ident =
|
||||||
{
|
{
|
||||||
@ -6978,8 +6987,15 @@ static HRESULT d3d_device_init(IDirect3DDeviceImpl *device, struct ddraw *ddraw,
|
|||||||
device->IDirect3DDevice3_iface.lpVtbl = &d3d_device3_vtbl;
|
device->IDirect3DDevice3_iface.lpVtbl = &d3d_device3_vtbl;
|
||||||
device->IDirect3DDevice2_iface.lpVtbl = &d3d_device2_vtbl;
|
device->IDirect3DDevice2_iface.lpVtbl = &d3d_device2_vtbl;
|
||||||
device->IDirect3DDevice_iface.lpVtbl = &d3d_device1_vtbl;
|
device->IDirect3DDevice_iface.lpVtbl = &d3d_device1_vtbl;
|
||||||
|
device->IUnknown_inner.lpVtbl = &d3d_device_inner_vtbl;
|
||||||
device->ref = 1;
|
device->ref = 1;
|
||||||
device->version = version;
|
device->version = version;
|
||||||
|
|
||||||
|
if (outer_unknown)
|
||||||
|
device->outer_unknown = outer_unknown;
|
||||||
|
else
|
||||||
|
device->outer_unknown = &device->IUnknown_inner;
|
||||||
|
|
||||||
device->ddraw = ddraw;
|
device->ddraw = ddraw;
|
||||||
device->target = target;
|
device->target = target;
|
||||||
list_init(&device->viewport_list);
|
list_init(&device->viewport_list);
|
||||||
@ -7028,7 +7044,8 @@ static HRESULT d3d_device_init(IDirect3DDeviceImpl *device, struct ddraw *ddraw,
|
|||||||
*
|
*
|
||||||
* In most cases, those surfaces are the same anyway, but this will simply
|
* In most cases, those surfaces are the same anyway, but this will simply
|
||||||
* add another ref which is released when the device is destroyed. */
|
* add another ref which is released when the device is destroyed. */
|
||||||
IDirectDrawSurface7_AddRef(&target->IDirectDrawSurface7_iface);
|
if (version != 1)
|
||||||
|
IDirectDrawSurface7_AddRef(&target->IDirectDrawSurface7_iface);
|
||||||
|
|
||||||
ddraw->d3ddevice = device;
|
ddraw->d3ddevice = device;
|
||||||
|
|
||||||
@ -7039,12 +7056,13 @@ static HRESULT d3d_device_init(IDirect3DDeviceImpl *device, struct ddraw *ddraw,
|
|||||||
}
|
}
|
||||||
|
|
||||||
HRESULT d3d_device_create(struct ddraw *ddraw, struct ddraw_surface *target,
|
HRESULT d3d_device_create(struct ddraw *ddraw, struct ddraw_surface *target,
|
||||||
UINT version, IDirect3DDeviceImpl **device)
|
UINT version, IDirect3DDeviceImpl **device, IUnknown *outer_unknown)
|
||||||
{
|
{
|
||||||
IDirect3DDeviceImpl *object;
|
IDirect3DDeviceImpl *object;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
TRACE("ddraw %p, target %p, version %u, device %p.\n", ddraw, target, version, device);
|
TRACE("ddraw %p, target %p, version %u, device %p, outer_unknown %p.\n",
|
||||||
|
ddraw, target, version, device, outer_unknown);
|
||||||
|
|
||||||
if (DefaultSurfaceType != WINED3D_SURFACE_TYPE_OPENGL)
|
if (DefaultSurfaceType != WINED3D_SURFACE_TYPE_OPENGL)
|
||||||
{
|
{
|
||||||
@ -7067,7 +7085,7 @@ HRESULT d3d_device_create(struct ddraw *ddraw, struct ddraw_surface *target,
|
|||||||
return DDERR_OUTOFMEMORY;
|
return DDERR_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = d3d_device_init(object, ddraw, target, version);
|
hr = d3d_device_init(object, ddraw, target, version, outer_unknown);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
WARN("Failed to initialize device, hr %#x.\n", hr);
|
WARN("Failed to initialize device, hr %#x.\n", hr);
|
||||||
|
@ -204,19 +204,23 @@ static HRESULT WINAPI ddraw_surface7_QueryInterface(IDirectDrawSurface7 *iface,
|
|||||||
|| IsEqualGUID(riid, &IID_IDirect3DHALDevice)
|
|| IsEqualGUID(riid, &IID_IDirect3DHALDevice)
|
||||||
|| IsEqualGUID(riid, &IID_IDirect3DRGBDevice))
|
|| IsEqualGUID(riid, &IID_IDirect3DRGBDevice))
|
||||||
{
|
{
|
||||||
IDirect3DDeviceImpl *device;
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
wined3d_mutex_lock();
|
wined3d_mutex_lock();
|
||||||
hr = d3d_device_create(This->ddraw, This, 1, &device);
|
if (!This->device1)
|
||||||
wined3d_mutex_unlock();
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
{
|
||||||
WARN("Failed to create device, hr %#x.\n", hr);
|
HRESULT hr = d3d_device_create(This->ddraw, This, 1, &This->device1,
|
||||||
return hr;
|
(IUnknown *)&This->IDirectDrawSurface_iface);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
This->device1 = NULL;
|
||||||
|
wined3d_mutex_unlock();
|
||||||
|
WARN("Failed to create device, hr %#x.\n", hr);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
wined3d_mutex_unlock();
|
||||||
|
|
||||||
*obj = &device->IDirect3DDevice_iface;
|
IDirect3DDevice_AddRef(&This->device1->IDirect3DDevice_iface);
|
||||||
|
*obj = &This->device1->IDirect3DDevice_iface;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -502,6 +506,8 @@ static void ddraw_surface_cleanup(struct ddraw_surface *surface)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (surface->device1)
|
||||||
|
IUnknown_Release(&surface->device1->IUnknown_inner);
|
||||||
ifaceToRelease = surface->ifaceToRelease;
|
ifaceToRelease = surface->ifaceToRelease;
|
||||||
|
|
||||||
/* Destroy the root surface. */
|
/* Destroy the root surface. */
|
||||||
|
@ -3523,7 +3523,6 @@ static void FindDevice(void)
|
|||||||
hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
|
hr = IDirectDrawSurface_QueryInterface(Surface1, &IID_IDirect3DHALDevice, (void **)&d3dhal);
|
||||||
/* Currently Wine only supports the creation of one Direct3D device
|
/* Currently Wine only supports the creation of one Direct3D device
|
||||||
* for a given DirectDraw instance. */
|
* for a given DirectDraw instance. */
|
||||||
todo_wine
|
|
||||||
ok(SUCCEEDED(hr) || broken(hr == DDERR_INVALIDPIXELFORMAT) /* XP/Win2003 Wow64 on VMware */,
|
ok(SUCCEEDED(hr) || broken(hr == DDERR_INVALIDPIXELFORMAT) /* XP/Win2003 Wow64 on VMware */,
|
||||||
"Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
|
"Expected IDirectDrawSurface::QueryInterface to succeed, got 0x%08x\n", hr);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user