ddraw: Keep track of the ddraw version used to create a device.

This also obsoletes the "from_surface" device field.
This commit is contained in:
Henri Verbeet 2012-04-03 21:15:12 +02:00 committed by Alexandre Julliard
parent f1651e9208
commit 4f91eb3fe1
4 changed files with 80 additions and 64 deletions

View File

@ -4426,50 +4426,17 @@ 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();
*device = NULL; hr = d3d_device_create(ddraw, target, 7, &object);
if (SUCCEEDED(hr))
/* Fail device creation if non-opengl surfaces are used. */ *device = &object->IDirect3DDevice7_iface;
if (DefaultSurfaceType != WINED3D_SURFACE_TYPE_OPENGL) else
{ {
ERR("The application wants to create a Direct3D device, but non-opengl surfaces are set in the registry.\n"); WARN("Failed to create device, hr %#x.\n", hr);
ERR("Please set the surface implementation to opengl or autodetection to allow 3D rendering.\n"); *device = NULL;
/* We only hit this path if a default surface is set in the registry. Incorrect autodetection
* is caught in CreateSurface or QueryInterface. */
wined3d_mutex_unlock();
return DDERR_NO3D;
} }
if (ddraw->d3ddevice)
{
FIXME("Only one Direct3D device per DirectDraw object supported.\n");
wined3d_mutex_unlock();
return DDERR_INVALIDPARAMS;
}
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
if (!object)
{
ERR("Failed to allocate device memory.\n");
wined3d_mutex_unlock();
return DDERR_OUTOFMEMORY;
}
hr = d3d_device_init(object, ddraw, target);
if (FAILED(hr))
{
WARN("Failed to initialize device, hr %#x.\n", hr);
HeapFree(GetProcessHeap(), 0, object);
wined3d_mutex_unlock();
return hr;
}
TRACE("Created device %p.\n", object);
*device = &object->IDirect3DDevice7_iface;
wined3d_mutex_unlock(); wined3d_mutex_unlock();
return D3D_OK; return hr;
} }
static HRESULT WINAPI d3d3_CreateDevice(IDirect3D3 *iface, REFCLSID riid, static HRESULT WINAPI d3d3_CreateDevice(IDirect3D3 *iface, REFCLSID riid,
@ -4477,22 +4444,25 @@ static HRESULT WINAPI d3d3_CreateDevice(IDirect3D3 *iface, REFCLSID riid,
{ {
struct ddraw_surface *surface_impl = unsafe_impl_from_IDirectDrawSurface4(surface); struct ddraw_surface *surface_impl = unsafe_impl_from_IDirectDrawSurface4(surface);
struct ddraw *ddraw = impl_from_IDirect3D3(iface); struct ddraw *ddraw = impl_from_IDirect3D3(iface);
IDirect3DDevice7 *device7;
IDirect3DDeviceImpl *device_impl; IDirect3DDeviceImpl *device_impl;
HRESULT hr; HRESULT hr;
TRACE("iface %p, riid %s, surface %p, device %p, outer_unknown %p.\n", TRACE("iface %p, riid %s, surface %p, device %p, outer_unknown %p.\n",
iface, debugstr_guid(riid), surface, device, outer_unknown); iface, debugstr_guid(riid), surface, device, outer_unknown);
if (outer_unknown) return CLASS_E_NOAGGREGATION; if (outer_unknown)
return CLASS_E_NOAGGREGATION;
hr = d3d7_CreateDevice(&ddraw->IDirect3D7_iface, riid, wined3d_mutex_lock();
surface_impl ? &surface_impl->IDirectDrawSurface7_iface : NULL, device ? &device7 : NULL); hr = d3d_device_create(ddraw, surface_impl, 3, &device_impl);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{
device_impl = impl_from_IDirect3DDevice7(device7);
*device = &device_impl->IDirect3DDevice3_iface; *device = &device_impl->IDirect3DDevice3_iface;
else
{
WARN("Failed to create device, hr %#x.\n", hr);
*device = NULL;
} }
wined3d_mutex_unlock();
return hr; return hr;
} }
@ -4502,20 +4472,22 @@ static HRESULT WINAPI d3d2_CreateDevice(IDirect3D2 *iface, REFCLSID riid,
{ {
struct ddraw_surface *surface_impl = unsafe_impl_from_IDirectDrawSurface(surface); struct ddraw_surface *surface_impl = unsafe_impl_from_IDirectDrawSurface(surface);
struct ddraw *ddraw = impl_from_IDirect3D2(iface); struct ddraw *ddraw = impl_from_IDirect3D2(iface);
IDirect3DDevice7 *device7;
IDirect3DDeviceImpl *device_impl; IDirect3DDeviceImpl *device_impl;
HRESULT hr; HRESULT hr;
TRACE("iface %p, riid %s, surface %p, device %p.\n", TRACE("iface %p, riid %s, surface %p, device %p.\n",
iface, debugstr_guid(riid), surface, device); iface, debugstr_guid(riid), surface, device);
hr = d3d7_CreateDevice(&ddraw->IDirect3D7_iface, riid, wined3d_mutex_lock();
surface_impl ? &surface_impl->IDirectDrawSurface7_iface : NULL, device ? &device7 : NULL); hr = d3d_device_create(ddraw, surface_impl, 2, &device_impl);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{
device_impl = impl_from_IDirect3DDevice7(device7);
*device = &device_impl->IDirect3DDevice2_iface; *device = &device_impl->IDirect3DDevice2_iface;
else
{
WARN("Failed to create device, hr %#x.\n", hr);
*device = NULL;
} }
wined3d_mutex_unlock();
return hr; return hr;
} }

View File

@ -278,7 +278,8 @@ struct IDirect3DDeviceImpl
IDirect3DDevice3 IDirect3DDevice3_iface; IDirect3DDevice3 IDirect3DDevice3_iface;
IDirect3DDevice2 IDirect3DDevice2_iface; IDirect3DDevice2 IDirect3DDevice2_iface;
IDirect3DDevice IDirect3DDevice_iface; IDirect3DDevice IDirect3DDevice_iface;
LONG ref; LONG ref;
UINT version;
/* Other object connections */ /* Other object connections */
struct wined3d_device *wined3d_device; struct wined3d_device *wined3d_device;
@ -293,7 +294,6 @@ struct IDirect3DDeviceImpl
/* Required to keep track which of two available texture blending modes in d3ddevice3 is used */ /* Required to keep track which of two available texture blending modes in d3ddevice3 is used */
BOOL legacyTextureBlending; BOOL legacyTextureBlending;
BOOL from_surface;
D3DMATRIX legacy_projection; D3DMATRIX legacy_projection;
D3DMATRIX legacy_clipspace; D3DMATRIX legacy_clipspace;
@ -315,8 +315,8 @@ struct IDirect3DDeviceImpl
D3DMATRIXHANDLE world, proj, view; D3DMATRIXHANDLE world, proj, view;
}; };
HRESULT d3d_device_init(IDirect3DDeviceImpl *device, struct ddraw *ddraw, HRESULT d3d_device_create(struct ddraw *ddraw, struct ddraw_surface *target,
struct ddraw_surface *target) DECLSPEC_HIDDEN; UINT version, IDirect3DDeviceImpl **device) DECLSPEC_HIDDEN;
/* The IID */ /* The IID */
extern const GUID IID_D3DDEVICE_WineD3D DECLSPEC_HIDDEN; extern const GUID IID_D3DDEVICE_WineD3D DECLSPEC_HIDDEN;

View File

@ -33,6 +33,7 @@
#include "ddraw_private.h" #include "ddraw_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(ddraw); WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
WINE_DECLARE_DEBUG_CHANNEL(winediag);
/* The device ID */ /* The device ID */
const GUID IID_D3DDEVICE_WineD3D = { const GUID IID_D3DDEVICE_WineD3D = {
@ -180,7 +181,7 @@ IDirect3DDeviceImpl_7_QueryInterface(IDirect3DDevice7 *iface,
} }
/* DirectDrawSurface */ /* DirectDrawSurface */
else if (IsEqualGUID(&IID_IDirectDrawSurface, refiid) && This->from_surface) else if (IsEqualGUID(&IID_IDirectDrawSurface, refiid) && This->version == 1)
{ {
*obj = &This->target->IDirectDrawSurface_iface; *obj = &This->target->IDirectDrawSurface_iface;
TRACE("Returning IDirectDrawSurface interface %p.\n", *obj); TRACE("Returning IDirectDrawSurface interface %p.\n", *obj);
@ -7015,7 +7016,8 @@ enum wined3d_depth_buffer_type IDirect3DDeviceImpl_UpdateDepthStencil(IDirect3DD
return WINED3D_ZB_TRUE; return WINED3D_ZB_TRUE;
} }
HRESULT d3d_device_init(IDirect3DDeviceImpl *device, struct ddraw *ddraw, struct ddraw_surface *target) static HRESULT d3d_device_init(IDirect3DDeviceImpl *device, struct ddraw *ddraw,
struct ddraw_surface *target, UINT version)
{ {
static const D3DMATRIX ident = static const D3DMATRIX ident =
{ {
@ -7035,6 +7037,7 @@ HRESULT d3d_device_init(IDirect3DDeviceImpl *device, struct ddraw *ddraw, struct
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->ref = 1; device->ref = 1;
device->version = version;
device->ddraw = ddraw; device->ddraw = ddraw;
device->target = target; device->target = target;
list_init(&device->viewport_list); list_init(&device->viewport_list);
@ -7092,3 +7095,46 @@ HRESULT d3d_device_init(IDirect3DDeviceImpl *device, struct ddraw *ddraw, struct
return D3D_OK; return D3D_OK;
} }
HRESULT d3d_device_create(struct ddraw *ddraw, struct ddraw_surface *target,
UINT version, IDirect3DDeviceImpl **device)
{
IDirect3DDeviceImpl *object;
HRESULT hr;
TRACE("ddraw %p, target %p, version %u, device %p.\n", ddraw, target, version, device);
if (DefaultSurfaceType != WINED3D_SURFACE_TYPE_OPENGL)
{
ERR_(winediag)("The application wants to create a Direct3D device, "
"but the current DirectDrawRenderer does not support this.\n");
return DDERR_NO3D;
}
if (ddraw->d3ddevice)
{
FIXME("Only one Direct3D device per DirectDraw object supported.\n");
return DDERR_INVALIDPARAMS;
}
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
if (!object)
{
ERR("Failed to allocate device memory.\n");
return DDERR_OUTOFMEMORY;
}
hr = d3d_device_init(object, ddraw, target, version);
if (FAILED(hr))
{
WARN("Failed to initialize device, hr %#x.\n", hr);
HeapFree(GetProcessHeap(), 0, object);
return hr;
}
TRACE("Created device %p.\n", object);
*device = object;
return D3D_OK;
}

View File

@ -204,21 +204,19 @@ 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_impl; IDirect3DDeviceImpl *device;
IDirect3DDevice7 *device;
HRESULT hr; HRESULT hr;
hr = IDirect3D7_CreateDevice(&This->ddraw->IDirect3D7_iface, riid, wined3d_mutex_lock();
&This->IDirectDrawSurface7_iface, &device); hr = d3d_device_create(This->ddraw, This, 1, &device);
wined3d_mutex_unlock();
if (FAILED(hr)) if (FAILED(hr))
{ {
WARN("Failed to create device, hr %#x.\n", hr); WARN("Failed to create device, hr %#x.\n", hr);
return hr; return hr;
} }
device_impl = impl_from_IDirect3DDevice7(device); *obj = &device->IDirect3DDevice_iface;
device_impl->from_surface = TRUE;
*obj = &device_impl->IDirect3DDevice_iface;
return S_OK; return S_OK;
} }