ddraw: Some caps fixes.

Cards at DirectX7 times did not support non power of 2 textures, and
some games check the capatiblity flags incorrectly. Rollcage expects the
D3DPTEXTURECAPS_POW2 (limitation) flag set and fails with the reference
rasterizer which support NP2 textures and doesn't have the cap set.
This commit is contained in:
Stefan Dösinger 2007-05-09 11:49:27 +02:00 committed by Alexandre Julliard
parent fe3869388a
commit d9fef10b71
2 changed files with 174 additions and 6 deletions

View File

@ -312,16 +312,24 @@ IDirect3DImpl_3_EnumDevices(IDirect3D3 *iface,
*
* 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 appart 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(This->d3dversion != 1)
{
static CHAR reference_description[] = "Reference Direct3D ID";
static CHAR reference_description[] = "RGB Direct3D emulation";
TRACE("(%p) Enumerating WineD3D D3DDevice interface\n", This);
d1 = dref;
d2 = dref;
hr = Callback( (LPIID) &IID_IDirect3DRefDevice, reference_description, device_name, &d1, &d2, Context);
/* The rgb device has the pow2 flag set in the hel caps, but not in the hal caps */
d1.dpcLineCaps.dwTextureCaps &= ~(D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_NONPOW2CONDITIONAL | D3DPTEXTURECAPS_PERSPECTIVE);
d1.dpcTriCaps.dwTextureCaps &= ~(D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_NONPOW2CONDITIONAL | D3DPTEXTURECAPS_PERSPECTIVE);
hr = Callback( (LPIID) &IID_IDirect3DRGBDevice, reference_description, device_name, &d1, &d2, Context);
if(hr != D3DENUMRET_OK)
{
TRACE("Application cancelled the enumeration\n");
@ -329,10 +337,13 @@ IDirect3DImpl_3_EnumDevices(IDirect3D3 *iface,
}
}
TRACE("(%p) Enumerating WineD3D D3DDevice interface\n", This);
TRACE("(%p) Enumerating HAL Direct3D device\n", This);
d1 = dref;
d2 = dref;
hr = Callback( (LPIID) &IID_D3DDEVICE_WineD3D, wined3d_description, device_name, &d1, &d2, Context);
/* The hal device does not have the pow2 flag set in hel, but in hal */
d2.dpcLineCaps.dwTextureCaps &= ~(D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_NONPOW2CONDITIONAL | D3DPTEXTURECAPS_PERSPECTIVE);
d2.dpcTriCaps.dwTextureCaps &= ~(D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_NONPOW2CONDITIONAL | D3DPTEXTURECAPS_PERSPECTIVE);
hr = Callback( (LPIID) &IID_IDirect3DHALDevice, wined3d_description, device_name, &d1, &d2, Context);
if(hr != D3DENUMRET_OK)
{
TRACE("Application cancelled the enumeration\n");
@ -1304,6 +1315,12 @@ IDirect3DImpl_GetCaps(IWineD3D *WineD3D,
hr = IWineD3D_GetDeviceCaps(WineD3D, 0, WINED3DDEVTYPE_HAL, &WCaps);
if(hr != D3D_OK) return hr;
if(!(Desc7->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
*/
Desc7->dpcLineCaps.dwTextureCaps |= D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_NONPOW2CONDITIONAL;
}
/* Fill the missing members, and do some fixup */
Desc7->dpcLineCaps.dwSize = sizeof(Desc7->dpcLineCaps);
Desc7->dpcLineCaps.dwTextureBlendCaps = D3DPTBLENDCAPS_ADD | D3DPTBLENDCAPS_MODULATEMASK |

View File

@ -90,8 +90,18 @@ static BOOL CreateDirect3D(void)
&lpD3DDevice);
ok(rc==D3D_OK || rc==DDERR_NOPALETTEATTACHED || rc==E_OUTOFMEMORY, "CreateDevice returned: %x\n", rc);
if (!lpD3DDevice) {
trace("IDirect3D7::CreateDevice() failed with an error %x\n", rc);
return FALSE;
trace("IDirect3D7::CreateDevice() for a TnL Hal device failed with an error %x, trying HAL\n", rc);
rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DHALDevice, lpDDS,
&lpD3DDevice);
if (!lpD3DDevice) {
trace("IDirect3D7::CreateDevice() for a HAL device failed with an error %x, trying RGB\n", rc);
rc = IDirect3D7_CreateDevice(lpD3D, &IID_IDirect3DRGBDevice, lpDDS,
&lpD3DDevice);
if (!lpD3DDevice) {
trace("IDirect3D7::CreateDevice() for a RGB device failed with an error %x, giving up\n", rc);
return FALSE;
}
}
}
return TRUE;
@ -605,6 +615,146 @@ static void LimitTest(void)
IDirectDrawSurface7_Release(pTexture);
}
static HRESULT WINAPI enumDevicesCallback(GUID *Guid,LPSTR DeviceDescription,LPSTR DeviceName, D3DDEVICEDESC *hal, D3DDEVICEDESC *hel, VOID *ctx)
{
UINT ver = *((UINT *) ctx);
if(IsEqualGUID(&IID_IDirect3DRGBDevice, Guid))
{
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);
}
else if(IsEqualGUID(&IID_IDirect3DHALDevice, Guid))
{
/* pow2 is hardware dependent */
ok(hal->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
"HAL Device %d hal line caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
ok(hal->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE,
"HAL Device %d hal tri caps does not have D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
ok((hel->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
"HAL Device %d hel line caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
ok((hel->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) == 0,
"HAL Device %d hel tri caps has D3DPTEXTURECAPS_PERSPECTIVE set\n", ver);
}
else if(IsEqualGUID(&IID_IDirect3DRefDevice, Guid))
{
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);
}
else if(IsEqualGUID(&IID_IDirect3DRampDevice, Guid))
{
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);
}
else if(IsEqualGUID(&IID_IDirect3DMMXDevice, Guid))
{
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);
}
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");
}
return DDENUMRET_OK;
}
static void CapsTest(void)
{
IDirect3D3 *d3d3;
IDirect3D3 *d3d2;
IDirectDraw *dd1;
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);
ver = 3;
IDirect3D3_EnumDevices(d3d3, enumDevicesCallback, &ver);
IDirect3D3_Release(d3d3);
IDirectDraw_Release(dd1);
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);
ver = 2;
IDirect3D2_EnumDevices(d3d2, enumDevicesCallback, &ver);
IDirect3D2_Release(d3d2);
IDirectDraw_Release(dd1);
}
START_TEST(d3d)
{
init_function_pointers();
@ -622,5 +772,6 @@ START_TEST(d3d)
StateTest();
SceneTest();
LimitTest();
CapsTest();
ReleaseDirect3D();
}