[PATCH 5/5] ddraw: Enumerate the correct Direct3D devices in the correct order
Andrew D'Addesio
andrew at fatbag.net
Sun Oct 4 12:52:08 CDT 2015
Fixes 19153
---
dlls/ddraw/ddraw.c | 219 ++++++++++++++-------------
dlls/ddraw/tests/d3d.c | 392 ++++++++++++++++++++++++++++---------------------
2 files changed, 345 insertions(+), 266 deletions(-)
diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index 7b5b593..91b676d 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -49,33 +49,74 @@ static const DDDEVICEIDENTIFIER2 deviceidentifier =
0
};
+#define D3D_VERSION(x) (1<<(x))
+
static struct enum_device_entry
{
- char interface_name[100];
+ unsigned int version_mask;
+ /* Some games (Motoracer 2 demo) have the bad idea to modify the device
+ * name/description strings. Let's put the strings in sufficiently sized
+ * arrays in static-lifetime writable memory. */
+ char device_desc[100];
char device_name[100];
const GUID *device_guid;
-} device_list7[] =
+} device_list[] =
{
- /* T&L HAL device */
+ /* Ramp Emulation (D3D 1&2 only) */
{
- "WINE Direct3D7 Hardware Transform and Lighting acceleration using WineD3D",
- "Wine D3D7 T&L HAL",
- &IID_IDirect3DTnLHalDevice,
+ D3D_VERSION(1)|D3D_VERSION(2),
+ "WineD3D Ramp Software Emulation",
+ "Ramp Emulation",
+ &IID_IDirect3DRampDevice,
+ },
+
+ /* RGB Emulation (D3D 1-7) */
+ {
+ D3D_VERSION(1)|D3D_VERSION(2)|D3D_VERSION(3)|D3D_VERSION(7),
+ "WineD3D RGB Software Emulation",
+ "RGB Emulation",
+ &IID_IDirect3DRGBDevice,
},
- /* HAL device */
+ /* Direct3D HAL (D3D 1-7) */
{
- "WINE Direct3D7 Hardware acceleration using WineD3D",
+ D3D_VERSION(1)|D3D_VERSION(2)|D3D_VERSION(3)|D3D_VERSION(7),
+ "WineD3D Hardware Acceleration",
"Direct3D HAL",
&IID_IDirect3DHALDevice,
},
- /* RGB device */
+ /* MMX Emulation (D3D2 only) */
{
- "WINE Direct3D7 RGB Software Emulation using WineD3D",
- "Wine D3D7 RGB",
- &IID_IDirect3DRGBDevice,
+ D3D_VERSION(2),
+ "WineD3D MMX Software Emulation",
+ "MMX Emulation",
+ &IID_IDirect3DMMXDevice,
},
+
+ /* Direct3D T&L HAL (D3D7 only) */
+ {
+ D3D_VERSION(7),
+ "WineD3D Hardware Transform and Lighting Acceleration",
+ "Direct3D T&L HAL",
+ &IID_IDirect3DTnLHalDevice,
+ },
+
+ /* In the future, we may wish to add the "Reference Rasterizer" and
+ * "Null device", which are only available in DX6-8 and must be explicitly
+ * enabled by the registry values:
+ * * EnumReference
+ * * EnumNullDevice,
+ * which are DWORD values which must be created under
+ * HKLM\Software\Microsoft\Direct3D\Drivers and set to any nonzero value.
+ * (Refer to enablerefrast.reg/disablerefrast.reg in the DX6/7 SDKs and
+ * KB249579 for more information.)
+ *
+ * DirectX 9.0 and higher appear to no longer recognize these settings,
+ * so apparently these devices were removed starting with DX9.
+ *
+ * Some games (AvP, Motoracer 2) break if these devices are enumerated.
+ */
};
static void STDMETHODCALLTYPE ddraw_null_wined3d_object_destroyed(void *parent) {}
@@ -1369,15 +1410,6 @@ HRESULT ddraw_get_d3dcaps(const struct ddraw *ddraw, D3DDEVICEDESC7 *caps)
D3DPTADDRESSCAPS_WRAP | D3DPTADDRESSCAPS_MIRROR | D3DPTADDRESSCAPS_CLAMP |
D3DPTADDRESSCAPS_BORDER | D3DPTADDRESSCAPS_INDEPENDENTUV);
- if (!(caps->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2))
- {
- /* DirectX7 always has the np2 flag set, no matter what the card
- * supports. Some old games (Rollcage) check the caps incorrectly.
- * If wined3d supports nonpow2 textures it also has np2 conditional
- * support. */
- caps->dpcLineCaps.dwTextureCaps |= D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_NONPOW2CONDITIONAL;
- }
-
/* Fill the missing members, and do some fixup */
caps->dpcLineCaps.dwSize = sizeof(caps->dpcLineCaps);
caps->dpcLineCaps.dwTextureBlendCaps = D3DPTBLENDCAPS_ADD
@@ -3551,8 +3583,7 @@ static HRESULT WINAPI ddraw1_DuplicateSurface(IDirectDraw *iface, IDirectDrawSur
/*****************************************************************************
* IDirect3D7::EnumDevices
*
- * The EnumDevices method for IDirect3D7. It enumerates all supported
- * D3D7 devices. Currently the T&L, HAL and RGB devices are enumerated.
+ * The EnumDevices method for IDirect3D7. It enumerates all D3D7 devices.
*
* Params:
* callback: Function to call for each enumerated device
@@ -3582,12 +3613,15 @@ static HRESULT WINAPI d3d7_EnumDevices(IDirect3D7 *iface, LPD3DENUMDEVICESCALLBA
return hr;
}
- for (i = 0; i < sizeof(device_list7)/sizeof(device_list7[0]); i++)
+ for (i = 0; i < sizeof(device_list)/sizeof(device_list[0]); i++)
{
HRESULT ret;
- device_desc7.deviceGUID = *device_list7[i].device_guid;
- ret = callback(device_list7[i].interface_name, device_list7[i].device_name, &device_desc7, context);
+ if (!(device_list[i].version_mask & D3D_VERSION(7)))
+ continue;
+
+ device_desc7.deviceGUID = *device_list[i].device_guid;
+ ret = callback(device_list[i].device_desc, device_list[i].device_name, &device_desc7, context);
if (ret != DDENUMRET_OK)
{
TRACE("Application cancelled the enumeration.\n");
@@ -3603,11 +3637,21 @@ static HRESULT WINAPI d3d7_EnumDevices(IDirect3D7 *iface, LPD3DENUMDEVICESCALLBA
return D3D_OK;
}
+static void clear_device_desc(D3DDEVICEDESC *device_desc)
+{
+ memset(device_desc, 0, sizeof(*device_desc));
+ device_desc->dwSize = sizeof(*device_desc);
+ device_desc->dtcTransformCaps.dwSize = sizeof(device_desc->dtcTransformCaps);
+ device_desc->dlcLightingCaps.dwSize = sizeof(device_desc->dlcLightingCaps);
+ device_desc->dpcLineCaps.dwSize = sizeof(device_desc->dpcLineCaps);
+ device_desc->dpcTriCaps.dwSize = sizeof(device_desc->dpcTriCaps);
+}
+
/*****************************************************************************
* IDirect3D3::EnumDevices
*
- * Enumerates all supported Direct3DDevice interfaces. This is the
- * implementation for Direct3D 1 to Direc3D 3, Version 7 has its own.
+ * Enumerates all Direct3DDevice interfaces. This is the implementation for
+ * Direct3D 1 to Direct3D 3; Version 7 has its own.
*
* Version 1, 2 and 3
*
@@ -3622,18 +3666,12 @@ static HRESULT WINAPI d3d7_EnumDevices(IDirect3D7 *iface, LPD3DENUMDEVICESCALLBA
*****************************************************************************/
static HRESULT WINAPI d3d3_EnumDevices(IDirect3D3 *iface, LPD3DENUMDEVICESCALLBACK callback, void *context)
{
- static CHAR wined3d_description[] = "Wine D3DDevice using WineD3D and OpenGL";
-
struct ddraw *ddraw = impl_from_IDirect3D3(iface);
- D3DDEVICEDESC device_desc1, hal_desc, hel_desc;
+ DWORD desc_size;
+ D3DDEVICEDESC device_desc1, empty_desc1, hal_desc, hel_desc;
D3DDEVICEDESC7 device_desc7;
HRESULT hr;
-
- /* Some games (Motoracer 2 demo) have the bad idea to modify the device
- * name string. Let's put the string in a sufficiently sized array in
- * writable memory. */
- char device_name[50];
- strcpy(device_name,"Direct3D HEL");
+ size_t i;
TRACE("iface %p, callback %p, context %p.\n", iface, callback, context);
@@ -3642,52 +3680,58 @@ static HRESULT WINAPI d3d3_EnumDevices(IDirect3D3 *iface, LPD3DENUMDEVICESCALLBA
wined3d_mutex_lock();
+ switch (ddraw->d3dversion)
+ {
+ case 1: desc_size = D3D1_DESC_SIZE; break;
+ case 2: desc_size = D3D2_DESC_SIZE; break;
+ default: desc_size = D3D3_DESC_SIZE; break;
+ }
+
if (FAILED(hr = ddraw_get_d3dcaps(ddraw, &device_desc7)))
{
wined3d_mutex_unlock();
return hr;
}
+
ddraw_d3dcaps1_from_7(&device_desc1, &device_desc7);
+ device_desc1.dwSize = desc_size;
- /* Do I have to enumerate the reference id? Note from old d3d7:
- * "It seems that enumerating the reference IID on Direct3D 1 games
- * (AvP / Motoracer2) breaks them". So do not enumerate this iid in V1
- *
- * There's a registry key HKLM\Software\Microsoft\Direct3D\Drivers,
- * EnumReference which enables / disables enumerating the reference
- * rasterizer. It's a DWORD, 0 means disabled, 2 means enabled. The
- * enablerefrast.reg and disablerefrast.reg files in the DirectX 7.0 sdk
- * demo directory suggest this.
- *
- * Some games(GTA 2) seem to use the second enumerated device, so I have
- * to enumerate at least 2 devices. So enumerate the reference device to
- * have 2 devices.
- *
- * Other games (Rollcage) tell emulation and hal device apart by certain
- * flags. Rollcage expects D3DPTEXTURECAPS_POW2 to be set (yeah, it is a
- * limitation flag), and it refuses all devices that have the perspective
- * flag set. This way it refuses the emulation device, and HAL devices
- * never have POW2 unset in d3d7 on windows. */
- if (ddraw->d3dversion != 1)
- {
- static CHAR reference_description[] = "RGB Direct3D emulation";
-
- TRACE("Enumerating WineD3D D3DDevice interface.\n");
- hal_desc = device_desc1;
- hel_desc = device_desc1;
- /* The rgb device has the pow2 flag set in the hel caps, but not in the hal caps. */
- hal_desc.dpcLineCaps.dwTextureCaps &= ~(D3DPTEXTURECAPS_POW2
- | D3DPTEXTURECAPS_NONPOW2CONDITIONAL | D3DPTEXTURECAPS_PERSPECTIVE);
- hal_desc.dpcTriCaps.dwTextureCaps &= ~(D3DPTEXTURECAPS_POW2
- | D3DPTEXTURECAPS_NONPOW2CONDITIONAL | D3DPTEXTURECAPS_PERSPECTIVE);
- /* RGB, RAMP and MMX devices have a HAL dcmColorModel of 0 */
- hal_desc.dcmColorModel = 0;
- /* RGB, RAMP and MMX devices cannot report HAL hardware flags */
- hal_desc.dwFlags = 0;
-
- hr = callback((GUID *)&IID_IDirect3DRGBDevice, reference_description,
- device_name, &hal_desc, &hel_desc, context);
- if (hr != D3DENUMRET_OK)
+ clear_device_desc(&empty_desc1);
+ empty_desc1.dwSize = desc_size;
+
+ for (i = 0; i < sizeof(device_list)/sizeof(device_list[0]); i++)
+ {
+ if (!(device_list[i].version_mask & D3D_VERSION(ddraw->d3dversion)))
+ continue;
+
+ if (IsEqualGUID(&IID_IDirect3DHALDevice, device_list[i].device_guid))
+ {
+ hal_desc = device_desc1;
+
+ /* The HAL device's hel_desc is almost empty -- but not completely */
+ hel_desc = empty_desc1;
+ hel_desc.dwFlags = D3DDD_COLORMODEL | D3DDD_DEVCAPS | D3DDD_TRANSFORMCAPS
+ | D3DDD_LIGHTINGCAPS | D3DDD_BCLIPPING;
+ hel_desc.dcmColorModel = 0;
+ hel_desc.dwDevCaps = D3DDEVCAPS_FLOATTLVERTEX;
+ hel_desc.dtcTransformCaps.dwCaps = hal_desc.dtcTransformCaps.dwCaps;
+ hel_desc.dlcLightingCaps = hal_desc.dlcLightingCaps;
+ hel_desc.bClipping = hal_desc.bClipping;
+ hel_desc.dwMaxVertexCount = hal_desc.dwMaxVertexCount;
+ }
+ else
+ {
+ hal_desc = empty_desc1;
+
+ hel_desc = device_desc1;
+ /* Ramp device supports grayscale only */
+ if (IsEqualGUID(&IID_IDirect3DRampDevice, device_list[i].device_guid))
+ hel_desc.dcmColorModel = D3DCOLOR_MONO;
+ }
+
+ hr = callback((GUID *)device_list[i].device_guid, device_list[i].device_desc,
+ device_list[i].device_name, &hal_desc, &hel_desc, context);
+ if (hr != DDENUMRET_OK)
{
TRACE("Application cancelled the enumeration.\n");
wined3d_mutex_unlock();
@@ -3695,29 +3739,6 @@ static HRESULT WINAPI d3d3_EnumDevices(IDirect3D3 *iface, LPD3DENUMDEVICESCALLBA
}
}
- strcpy(device_name,"Direct3D HAL");
-
- TRACE("Enumerating HAL Direct3D device.\n");
- hal_desc = device_desc1;
- hel_desc = device_desc1;
-
- /* The hal device does not have the pow2 flag set in hel, but in hal. */
- hel_desc.dpcLineCaps.dwTextureCaps &= ~(D3DPTEXTURECAPS_POW2
- | D3DPTEXTURECAPS_NONPOW2CONDITIONAL | D3DPTEXTURECAPS_PERSPECTIVE);
- hel_desc.dpcTriCaps.dwTextureCaps &= ~(D3DPTEXTURECAPS_POW2
- | D3DPTEXTURECAPS_NONPOW2CONDITIONAL | D3DPTEXTURECAPS_PERSPECTIVE);
- /* HAL devices have a HEL dcmColorModel of 0 */
- hel_desc.dcmColorModel = 0;
-
- hr = callback((GUID *)&IID_IDirect3DHALDevice, wined3d_description,
- device_name, &hal_desc, &hel_desc, context);
- if (hr != D3DENUMRET_OK)
- {
- TRACE("Application cancelled the enumeration.\n");
- wined3d_mutex_unlock();
- return D3D_OK;
- }
-
TRACE("End of enumeration.\n");
wined3d_mutex_unlock();
diff --git a/dlls/ddraw/tests/d3d.c b/dlls/ddraw/tests/d3d.c
index 392c13f..f4de5dd 100644
--- a/dlls/ddraw/tests/d3d.c
+++ b/dlls/ddraw/tests/d3d.c
@@ -70,13 +70,35 @@ enum {
D3D3_DESC_SIZE = sizeof(D3DDEVICEDESC) /* 252 */
};
+enum {
+ device_ramp,
+ device_rgb,
+ device_hal,
+ device_mmx,
+ device_ref,
+ device_null,
+ device_tnlhal,
+ device_count
+};
+
+static const struct {
+ const char *device_name;
+ const GUID *device_guid;
+} device_list[device_count] = {
+ {"Ramp Emulation", &IID_IDirect3DRampDevice},
+ {"RGB Emulation", &IID_IDirect3DRGBDevice},
+ {"Direct3D HAL", &IID_IDirect3DHALDevice},
+ {"MMX Emulation", &IID_IDirect3DMMXDevice},
+ {"Reference Rasterizer", &IID_IDirect3DRefDevice},
+ {"Null device", &IID_IDirect3DNullDevice},
+ {"Direct3D T&L HAL", &IID_IDirect3DTnLHalDevice},
+};
+
typedef struct {
- int total;
- int rgb;
- int hal;
- int tnlhal;
- int unk;
-} D3D7ETest;
+ int d3dver;
+ int prev_device;
+ BOOL enumerated[device_count];
+} D3DETest;
typedef struct {
HRESULT desired_ret;
@@ -542,147 +564,183 @@ static void LimitTest(void)
IDirectDrawSurface7_Release(pTexture);
}
-static HRESULT WINAPI enumDevicesCallback(GUID *Guid, char *DeviceDescription,
- char *DeviceName, D3DDEVICEDESC *hal, D3DDEVICEDESC *hel, void *ctx)
+static int identify_device(GUID *Guid)
{
- UINT ver = *((UINT *) ctx);
- if(IsEqualGUID(&IID_IDirect3DRGBDevice, Guid))
+ int i;
+ for (i = 0; i < device_count; i++)
{
- ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
- "RGB Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
- ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
- "RGB Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
- ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
- "RGB Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
- ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
- "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
-
- ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
- "RGB Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
- ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
- "RGB Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
- ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
- "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
- ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
- "RGB Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
+ if (IsEqualGUID(device_list[i].device_guid, Guid))
+ return i;
+ }
+ return -1;
+}
+
+static void require_device(D3DETest *ctx, int device)
+{
+ ok(ctx->enumerated[device], "No D3D%d %s device enumerated\n",
+ ctx->d3dver, device_list[device].device_name);
+}
- ok(hal->dcmColorModel == 0, "RGB Device %u hal caps has colormodel %u\n", ver, hal->dcmColorModel);
- ok(hel->dcmColorModel == D3DCOLOR_RGB, "RGB Device %u hel caps has colormodel %u\n", ver, hel->dcmColorModel);
+static void prohibit_device(D3DETest *ctx, int device)
+{
+ ok(!ctx->enumerated[device], "D3D%d %s device was enumerated\n",
+ ctx->d3dver, device_list[device].device_name);
+}
- ok(hal->dwFlags == 0, "RGB Device %u hal caps has hardware flags %x\n", ver, hal->dwFlags);
- ok(hel->dwFlags != 0, "RGB Device %u hel caps has hardware flags %x\n", ver, hel->dwFlags);
+static void check_enumerated_devices(D3DETest *ctx)
+{
+ int ver = ctx->d3dver;
+
+ require_device(ctx, device_rgb);
+
+ if (ver == 1)
+ {
+ require_device(ctx, device_ramp);
+ prohibit_device(ctx, device_mmx);
+ prohibit_device(ctx, device_tnlhal);
}
- else if(IsEqualGUID(&IID_IDirect3DHALDevice, Guid))
+ else if (ver == 2)
{
- trace("HAL Device %d\n", ver);
- ok(hal->dcmColorModel == D3DCOLOR_RGB, "HAL Device %u hal caps has colormodel %u\n", ver, hel->dcmColorModel);
- ok(hel->dcmColorModel == 0, "HAL Device %u hel caps has colormodel %u\n", ver, hel->dcmColorModel);
-
- ok(hal->dwFlags != 0, "HAL Device %u hal caps has hardware flags %x\n", ver, hal->dwFlags);
- ok(hel->dwFlags != 0, "HAL Device %u hel caps has hardware flags %x\n", ver, hel->dwFlags);
+ require_device(ctx, device_ramp);
+ require_device(ctx, device_mmx);
+ prohibit_device(ctx, device_tnlhal);
}
- else if(IsEqualGUID(&IID_IDirect3DRefDevice, Guid))
+ else if (ver == 3)
{
- ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
- "REF Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
- ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
- "REF Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
- ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
- "REF Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
- ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
- "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
-
- ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
- "REF Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
- ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
- "REF Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
- ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
- "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
- ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
- "REF Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
+ prohibit_device(ctx, device_ramp);
+ prohibit_device(ctx, device_mmx);
+ prohibit_device(ctx, device_tnlhal);
}
- else if(IsEqualGUID(&IID_IDirect3DRampDevice, Guid))
+ else if (ver == 7)
{
- ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
- "Ramp Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
- ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
- "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
- ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
- "Ramp Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
- ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
- "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
-
- ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
- "Ramp Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
- ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
- "Ramp Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
- ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
- "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
- ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
- "Ramp Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
-
- ok(hal->dcmColorModel == 0, "Ramp Device %u hal caps has colormodel %u\n", ver, hal->dcmColorModel);
- ok(hel->dcmColorModel == D3DCOLOR_MONO, "Ramp Device %u hel caps has colormodel %u\n",
- ver, hel->dcmColorModel);
+ prohibit_device(ctx, device_ramp);
+ prohibit_device(ctx, device_mmx);
- ok(hal->dwFlags == 0, "Ramp Device %u hal caps has hardware flags %x\n", ver, hal->dwFlags);
- ok(hel->dwFlags != 0, "Ramp Device %u hel caps has hardware flags %x\n", ver, hel->dwFlags);
+ /* A couple of games (Delta Force LW, C&C TFD) require the T&L HAL device
+ * to only be enumerated together with the non-T&L HAL device. */
+ ok(!ctx->enumerated[device_tnlhal] || ctx->enumerated[device_hal],
+ "D3D%d T&L HAL device enumerated without non-T&L HAL device\n", ver);
}
- else if(IsEqualGUID(&IID_IDirect3DMMXDevice, Guid))
+}
+
+static HRESULT WINAPI enumDevicesCallback(GUID *Guid, char *DeviceDescription,
+ char *DeviceName, D3DDEVICEDESC *hal, D3DDEVICEDESC *hel, void *Context)
+{
+ D3DETest *ctx = Context;
+ int ver = ctx->d3dver;
+ int device = identify_device(Guid);
+ DWORD expected_desc_size;
+
+ trace("D3D%d %s\n", ver, DeviceName);
+
+ switch (ver)
{
- ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
- "MMX Device %d hal line caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
- ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) == 0,
- "MMX Device %d hal tri caps has D3DPTEXTURECAPS_POW2 flag set\n", ver);
- ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
- "MMX Device %d hel line caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
- ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2,
- "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_POW2 flag set\n", ver);
-
- ok((hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
- "MMX Device %d hal line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
- ok((hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
- "MMX Device %d hal tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
- ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
- "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
- ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
- "MMX Device %d hel tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
+ case 1: expected_desc_size = D3D1_DESC_SIZE; break;
+ case 2: expected_desc_size = D3D2_DESC_SIZE; break;
+ default: expected_desc_size = D3D3_DESC_SIZE; break;
+ }
- ok(hal->dcmColorModel == 0, "MMX Device %u hal caps has colormodel %u\n", ver, hal->dcmColorModel);
- ok(hel->dcmColorModel == D3DCOLOR_RGB, "MMX Device %u hel caps has colormodel %u\n", ver, hel->dcmColorModel);
+ ok(hal->dwSize == expected_desc_size,
+ "D3D%d %s hal_desc has dwSize %u\n", ver, DeviceName, hal->dwSize);
+ ok(hel->dwSize == expected_desc_size,
+ "D3D%d %s hel_desc has dwSize %u\n", ver, DeviceName, hel->dwSize);
- ok(hal->dwFlags == 0, "MMX Device %u hal caps has hardware flags %x\n", ver, hal->dwFlags);
- ok(hel->dwFlags != 0, "MMX Device %u hel caps has hardware flags %x\n", ver, hel->dwFlags);
+ if (device >= 0)
+ {
+ /* Many games (DD Goin Quackers, Sims Online) search for the device
+ * by name, not by GUID. So ensure the device has the correct name. */
+ const char *expected_name = device_list[device].device_name;
+ ok(!strcmp(DeviceName, expected_name),
+ "D3D%d %s has name \"%s\"\n", ver, expected_name, DeviceName);
+
+ ok(device > ctx->prev_device, "D3D%d %s enumerated after %s\n", ver,
+ expected_name, device_list[ctx->prev_device].device_name);
+ ctx->prev_device = device;
+ ctx->enumerated[device] = 1;
}
else
{
- ok(FALSE, "Unexpected device enumerated: \"%s\" \"%s\"\n", DeviceDescription, DeviceName);
- if(hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal line has pow2 set\n");
- else trace("hal line does NOT have pow2 set\n");
- if(hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hal tri has pow2 set\n");
- else trace("hal tri does NOT have pow2 set\n");
- if(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel line has pow2 set\n");
- else trace("hel line does NOT have pow2 set\n");
- if(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) trace("hel tri has pow2 set\n");
- else trace("hel tri does NOT have pow2 set\n");
+ ok(0, "Unrecognized D3D%d device enumerated: desc=\"%s\", name=\"%s\"\n",
+ ver, DeviceDescription, DeviceName);
}
+
+ if (device == device_hal || device == device_tnlhal)
+ {
+ /* matching description */
+ ok(hal->dwFlags != 0,
+ "D3D%d %s hal_desc has hardware flags %x\n", ver, DeviceName, hal->dwFlags);
+ ok(hal->dcmColorModel == D3DCOLOR_RGB,
+ "D3D%d %s hal_desc has colormodel %u\n", ver, DeviceName, hal->dcmColorModel);
+ /* Rollcage requires this dwTextureCaps flag on the matching description */
+ ok(hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
+ "D3D%d %s hal_desc line caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver, DeviceName);
+ ok(hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
+ "D3D%d %s hal_desc tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver, DeviceName);
+
+ /* non-matching description (should be almost empty -- but not completely) */
+ ok(hel->dwFlags != 0,
+ "D3D%d %s hel_desc has hardware flags %x\n", ver, DeviceName, hel->dwFlags);
+ ok(hel->dcmColorModel == 0,
+ "D3D%d %s hel_desc has colormodel %u\n", ver, DeviceName, hel->dcmColorModel);
+ ok(hel->dpcLineCaps.dwTextureCaps == 0,
+ "D3D%d %s hel_desc has line caps %x\n", ver, DeviceName, hel->dpcLineCaps.dwTextureCaps);
+ ok(hel->dpcTriCaps.dwTextureCaps == 0,
+ "D3D%d %s hel_desc has tri caps %x\n", ver, DeviceName, hel->dpcTriCaps.dwTextureCaps);
+ }
+ else
+ {
+ /* matching description */
+ ok(hel->dwFlags != 0,
+ "D3D%d %s hel_desc has hardware flags %x\n", ver, DeviceName, hel->dwFlags);
+ ok(hel->dcmColorModel == (device == device_ramp ? D3DCOLOR_MONO : D3DCOLOR_RGB),
+ "D3D%d %s hel_desc has colormodel %u\n", ver, DeviceName, hel->dcmColorModel);
+ /* Rollcage requires this dwTextureCaps flag on the matching description */
+ ok(hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
+ "D3D%d %s hel_desc line caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver, DeviceName);
+ ok(hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
+ "D3D%d %s hel_desc tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver, DeviceName);
+
+ /* non-matching description (should be empty) */
+ ok(hal->dwFlags == 0,
+ "D3D%d %s hal_desc has hardware flags %x\n", ver, DeviceName, hal->dwFlags);
+ ok(hal->dcmColorModel == 0,
+ "D3D%d %s hal_desc has colormodel %u\n", ver, DeviceName, hal->dcmColorModel);
+ ok(hal->dpcLineCaps.dwTextureCaps == 0,
+ "D3D%d %s hal_desc has line caps %x\n", ver, DeviceName, hal->dpcLineCaps.dwTextureCaps);
+ ok(hal->dpcTriCaps.dwTextureCaps == 0,
+ "D3D%d %s hal_desc has tri caps %x\n", ver, DeviceName, hal->dpcTriCaps.dwTextureCaps);
+ }
+
return DDENUMRET_OK;
}
static HRESULT WINAPI enumDevicesCallbackTest7(char *DeviceDescription, char *DeviceName,
D3DDEVICEDESC7 *lpdd7, void *Context)
{
- D3D7ETest *d3d7et = Context;
- if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DRGBDevice))
- d3d7et->rgb++;
- else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DHALDevice))
- d3d7et->hal++;
- else if(IsEqualGUID(&lpdd7->deviceGUID, &IID_IDirect3DTnLHalDevice))
- d3d7et->tnlhal++;
- else
- d3d7et->unk++;
+ D3DETest *ctx = Context;
+ int ver = ctx->d3dver;
+ int device = identify_device(&lpdd7->deviceGUID);
- d3d7et->total++;
+ trace("D3D%d %s\n", ver, DeviceName);
+
+ if (device >= 0)
+ {
+ /* Many games (DD Goin Quackers, Sims Online) search for the device
+ * by name, not by GUID. So ensure the device has the correct name. */
+ const char *expected_name = device_list[device].device_name;
+ ok(!strcmp(DeviceName, expected_name),
+ "D3D%d %s has name \"%s\"\n", ver, expected_name, DeviceName);
+
+ ok(device > ctx->prev_device, "D3D%d %s enumerated after %s\n", ver,
+ expected_name, device_list[ctx->prev_device].device_name);
+ ctx->prev_device = device;
+ ctx->enumerated[device] = 1;
+ }
+ else
+ {
+ ok(0, "Unrecognized D3D%d device enumerated: desc=\"%s\", name=\"%s\"\n",
+ ver, DeviceDescription, DeviceName);
+ }
return DDENUMRET_OK;
}
@@ -717,29 +775,21 @@ static HRESULT WINAPI enumDevicesLifetimeTest7(char *DeviceDescription, char *De
return DDENUMRET_OK;
}
-/* Check the deviceGUID of devices enumerated by
- IDirect3D7_EnumDevices. */
static void D3D7EnumTest(void)
{
HRESULT hr;
- D3D7ETest d3d7et;
+ D3DETest d3det;
D3D7ECancelTest d3d7_cancel_test;
hr = IDirect3D7_EnumDevices(lpD3D, NULL, NULL);
- ok(hr == DDERR_INVALIDPARAMS, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
+ ok(hr == DDERR_INVALIDPARAMS, "IDirect3D7_EnumDevices returned 0x%08x for null input\n", hr);
- memset(&d3d7et, 0, sizeof(d3d7et));
- hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCallbackTest7, &d3d7et);
+ d3det.d3dver = 7;
+ d3det.prev_device = -1;
+ memset(&d3det.enumerated, 0, sizeof(d3det.enumerated));
+ hr = IDirect3D7_EnumDevices(lpD3D, enumDevicesCallbackTest7, &d3det);
ok(hr == D3D_OK, "IDirect3D7_EnumDevices returned 0x%08x\n", hr);
-
- /* A couple of games (Delta Force LW and TFD) rely on this behaviour */
- ok(d3d7et.tnlhal < d3d7et.total, "TnLHal device enumerated as only device.\n");
-
- /* We make two additional assumptions. */
- ok(d3d7et.rgb, "No RGB Device enumerated.\n");
-
- if(d3d7et.tnlhal)
- ok(d3d7et.hal, "TnLHal device enumerated, but no Hal device found.\n");
+ check_enumerated_devices(&d3det);
d3d7_cancel_test.desired_ret = DDENUMRET_CANCEL;
d3d7_cancel_test.total = 0;
@@ -835,41 +885,52 @@ static void D3D7EnumLifetimeTest(void)
}
}
-static void CapsTest(void)
+static void D3D1EnumTest(void)
{
- IDirect3D3 *d3d3;
- IDirect3D3 *d3d2;
- IDirectDraw *dd1;
+ D3DETest d3det;
HRESULT hr;
- UINT ver;
- hr = DirectDrawCreate(NULL, &dd1, NULL);
- ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
- hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D3, (void **) &d3d3);
- ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
+ hr = IDirect3D_EnumDevices(Direct3D1, NULL, NULL);
+ ok(hr == DDERR_INVALIDPARAMS, "IDirect3D_EnumDevices returned 0x%08x for null input\n", hr);
- hr = IDirect3D3_EnumDevices(d3d3, NULL, NULL);
- ok(hr == DDERR_INVALIDPARAMS, "IDirect3D3_EnumDevices returned 0x%08x\n", hr);
+ d3det.d3dver = 1;
+ d3det.prev_device = -1;
+ memset(&d3det.enumerated, 0, sizeof(d3det.enumerated));
+ hr = IDirect3D_EnumDevices(Direct3D1, enumDevicesCallback, &d3det);
+ ok(hr == DD_OK, "IDirect3D_EnumDevices returned %08x\n", hr);
+ check_enumerated_devices(&d3det);
+}
- ver = 3;
- IDirect3D3_EnumDevices(d3d3, enumDevicesCallback, &ver);
+static void D3D2EnumTest(struct d3d2_test_context *context)
+{
+ D3DETest d3det;
+ HRESULT hr;
- IDirect3D3_Release(d3d3);
- IDirectDraw_Release(dd1);
+ hr = IDirect3D2_EnumDevices(context->d3d, NULL, NULL);
+ ok(hr == DDERR_INVALIDPARAMS, "IDirect3D2_EnumDevices returned 0x%08x for null input\n", hr);
- hr = DirectDrawCreate(NULL, &dd1, NULL);
- ok(hr == DD_OK, "Cannot create a DirectDraw 1 interface, hr = %08x\n", hr);
- hr = IDirectDraw_QueryInterface(dd1, &IID_IDirect3D2, (void **) &d3d2);
- ok(hr == D3D_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
+ d3det.d3dver = 2;
+ d3det.prev_device = -1;
+ memset(&d3det.enumerated, 0, sizeof(d3det.enumerated));
+ hr = IDirect3D2_EnumDevices(context->d3d, enumDevicesCallback, &d3det);
+ ok(hr == DD_OK, "IDirect3D2_EnumDevices returned %08x\n", hr);
+ check_enumerated_devices(&d3det);
+}
- hr = IDirect3D2_EnumDevices(d3d2, NULL, NULL);
- ok(hr == DDERR_INVALIDPARAMS, "IDirect3D2_EnumDevices returned 0x%08x\n", hr);
+static void D3D3EnumTest(struct d3d3_test_context *context)
+{
+ D3DETest d3det;
+ HRESULT hr;
- ver = 2;
- IDirect3D2_EnumDevices(d3d2, enumDevicesCallback, &ver);
+ hr = IDirect3D3_EnumDevices(context->d3d, NULL, NULL);
+ ok(hr == DDERR_INVALIDPARAMS, "IDirect3D3_EnumDevices returned 0x%08x for null input\n", hr);
- IDirect3D2_Release(d3d2);
- IDirectDraw_Release(dd1);
+ d3det.d3dver = 3;
+ d3det.prev_device = -1;
+ memset(&d3det.enumerated, 0, sizeof(d3det.enumerated));
+ hr = IDirect3D3_EnumDevices(context->d3d, enumDevicesCallback, &d3det);
+ ok(hr == DD_OK, "IDirect3D3_EnumDevices returned %08x\n", hr);
+ check_enumerated_devices(&d3det);
}
struct v_in {
@@ -4103,21 +4164,18 @@ error:
return FALSE;
}
-static void d3d3_nop_test(const struct d3d3_test_context *context)
-{
-}
-
START_TEST(d3d)
{
struct d3d3_test_context d3d3_context;
void (* const d3d3_tests[])(const struct d3d3_test_context *) =
{
- d3d3_nop_test /* please remove once the first real d3d3 test is added */
+ D3D3EnumTest
};
struct d3d2_test_context d3d2_context;
void (* const d3d2_tests[])(const struct d3d2_test_context *) =
{
+ D3D2EnumTest,
test_get_caps2
};
@@ -4136,7 +4194,6 @@ START_TEST(d3d)
D3D7EnumLifetimeTest();
SetMaterialTest();
ComputeSphereVisibility();
- CapsTest();
VertexBufferDescTest();
D3D7_OldRenderStateTest();
DeviceLoadTest();
@@ -4177,6 +4234,7 @@ START_TEST(d3d)
Direct3D1Test();
TextureLoadTest();
ViewportTest();
+ D3D1EnumTest();
FindDevice();
BackBuffer3DCreateSurfaceTest();
BackBuffer3DAttachmentTest();
--
2.4.3
More information about the wine-patches
mailing list