Commit 4f91eb3f authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

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

This also obsoletes the "from_surface" device field.
parent f1651e92
......@@ -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);
wined3d_mutex_lock();
*device = NULL;
/* Fail device creation if non-opengl surfaces are used. */
if (DefaultSurfaceType != WINED3D_SURFACE_TYPE_OPENGL)
{
ERR("The application wants to create a Direct3D device, but non-opengl surfaces are set in the registry.\n");
ERR("Please set the surface implementation to opengl or autodetection to allow 3D rendering.\n");
/* 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)
hr = d3d_device_create(ddraw, target, 7, &object);
if (SUCCEEDED(hr))
*device = &object->IDirect3DDevice7_iface;
else
{
ERR("Failed to allocate device memory.\n");
wined3d_mutex_unlock();
return DDERR_OUTOFMEMORY;
WARN("Failed to create device, hr %#x.\n", hr);
*device = NULL;
}
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();
return D3D_OK;
return hr;
}
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 *ddraw = impl_from_IDirect3D3(iface);
IDirect3DDevice7 *device7;
IDirect3DDeviceImpl *device_impl;
HRESULT hr;
TRACE("iface %p, riid %s, surface %p, device %p, outer_unknown %p.\n",
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,
surface_impl ? &surface_impl->IDirectDrawSurface7_iface : NULL, device ? &device7 : NULL);
wined3d_mutex_lock();
hr = d3d_device_create(ddraw, surface_impl, 3, &device_impl);
if (SUCCEEDED(hr))
{
device_impl = impl_from_IDirect3DDevice7(device7);
*device = &device_impl->IDirect3DDevice3_iface;
else
{
WARN("Failed to create device, hr %#x.\n", hr);
*device = NULL;
}
wined3d_mutex_unlock();
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 *ddraw = impl_from_IDirect3D2(iface);
IDirect3DDevice7 *device7;
IDirect3DDeviceImpl *device_impl;
HRESULT hr;
TRACE("iface %p, riid %s, surface %p, device %p.\n",
iface, debugstr_guid(riid), surface, device);
hr = d3d7_CreateDevice(&ddraw->IDirect3D7_iface, riid,
surface_impl ? &surface_impl->IDirectDrawSurface7_iface : NULL, device ? &device7 : NULL);
wined3d_mutex_lock();
hr = d3d_device_create(ddraw, surface_impl, 2, &device_impl);
if (SUCCEEDED(hr))
{
device_impl = impl_from_IDirect3DDevice7(device7);
*device = &device_impl->IDirect3DDevice2_iface;
else
{
WARN("Failed to create device, hr %#x.\n", hr);
*device = NULL;
}
wined3d_mutex_unlock();
return hr;
}
......
......@@ -278,7 +278,8 @@ struct IDirect3DDeviceImpl
IDirect3DDevice3 IDirect3DDevice3_iface;
IDirect3DDevice2 IDirect3DDevice2_iface;
IDirect3DDevice IDirect3DDevice_iface;
LONG ref;
LONG ref;
UINT version;
/* Other object connections */
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 */
BOOL legacyTextureBlending;
BOOL from_surface;
D3DMATRIX legacy_projection;
D3DMATRIX legacy_clipspace;
......@@ -315,8 +315,8 @@ struct IDirect3DDeviceImpl
D3DMATRIXHANDLE world, proj, view;
};
HRESULT d3d_device_init(IDirect3DDeviceImpl *device, struct ddraw *ddraw,
struct ddraw_surface *target) DECLSPEC_HIDDEN;
HRESULT d3d_device_create(struct ddraw *ddraw, struct ddraw_surface *target,
UINT version, IDirect3DDeviceImpl **device) DECLSPEC_HIDDEN;
/* The IID */
extern const GUID IID_D3DDEVICE_WineD3D DECLSPEC_HIDDEN;
......
......@@ -33,6 +33,7 @@
#include "ddraw_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
WINE_DECLARE_DEBUG_CHANNEL(winediag);
/* The device ID */
const GUID IID_D3DDEVICE_WineD3D = {
......@@ -180,7 +181,7 @@ IDirect3DDeviceImpl_7_QueryInterface(IDirect3DDevice7 *iface,
}
/* DirectDrawSurface */
else if (IsEqualGUID(&IID_IDirectDrawSurface, refiid) && This->from_surface)
else if (IsEqualGUID(&IID_IDirectDrawSurface, refiid) && This->version == 1)
{
*obj = &This->target->IDirectDrawSurface_iface;
TRACE("Returning IDirectDrawSurface interface %p.\n", *obj);
......@@ -7015,7 +7016,8 @@ enum wined3d_depth_buffer_type IDirect3DDeviceImpl_UpdateDepthStencil(IDirect3DD
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 =
{
......@@ -7035,6 +7037,7 @@ HRESULT d3d_device_init(IDirect3DDeviceImpl *device, struct ddraw *ddraw, struct
device->IDirect3DDevice2_iface.lpVtbl = &d3d_device2_vtbl;
device->IDirect3DDevice_iface.lpVtbl = &d3d_device1_vtbl;
device->ref = 1;
device->version = version;
device->ddraw = ddraw;
device->target = target;
list_init(&device->viewport_list);
......@@ -7092,3 +7095,46 @@ HRESULT d3d_device_init(IDirect3DDeviceImpl *device, struct ddraw *ddraw, struct
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;
}
......@@ -204,21 +204,19 @@ static HRESULT WINAPI ddraw_surface7_QueryInterface(IDirectDrawSurface7 *iface,
|| IsEqualGUID(riid, &IID_IDirect3DHALDevice)
|| IsEqualGUID(riid, &IID_IDirect3DRGBDevice))
{
IDirect3DDeviceImpl *device_impl;
IDirect3DDevice7 *device;
IDirect3DDeviceImpl *device;
HRESULT hr;
hr = IDirect3D7_CreateDevice(&This->ddraw->IDirect3D7_iface, riid,
&This->IDirectDrawSurface7_iface, &device);
wined3d_mutex_lock();
hr = d3d_device_create(This->ddraw, This, 1, &device);
wined3d_mutex_unlock();
if (FAILED(hr))
{
WARN("Failed to create device, hr %#x.\n", hr);
return hr;
}
device_impl = impl_from_IDirect3DDevice7(device);
device_impl->from_surface = TRUE;
*obj = &device_impl->IDirect3DDevice_iface;
*obj = &device->IDirect3DDevice_iface;
return S_OK;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment