d3d: Fix adapter mode enumeration and filtering.

This commit is contained in:
Chris Robinson 2006-12-20 04:44:08 -08:00 committed by Alexandre Julliard
parent e4a6562937
commit ed21935479
4 changed files with 180 additions and 73 deletions

View File

@ -1,5 +1,6 @@
/*
* Copyright (C) 2006 Vitaliy Margolen
* Copyright (C) 2006 Chris Robinson
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -686,6 +687,35 @@ cleanup:
if(pDevice) IDirect3D8_Release(pDevice);
}
/* Test adapter display modes */
static void test_display_modes(void)
{
UINT max_modes, i;
D3DDISPLAYMODE dmode;
HRESULT res;
IDirect3D8 *pD3d;
pD3d = pDirect3DCreate8( D3D_SDK_VERSION );
ok(pD3d != NULL, "Failed to create IDirect3D8 object\n");
if(!pD3d) return;
max_modes = IDirect3D8_GetAdapterModeCount(pD3d, D3DADAPTER_DEFAULT);
ok(max_modes > 0, "GetAdapterModeCount(D3DADAPTER_DEFAULT) returned 0!\n");
for(i=0; i<max_modes;i++) {
res = IDirect3D8_EnumAdapterModes(pD3d, D3DADAPTER_DEFAULT, i, &dmode);
ok(res==D3D_OK, "EnumAdapterModes returned %s for mode %u!\n", DXGetErrorString8(res), i);
if(res != D3D_OK)
continue;
ok(dmode.Format==D3DFMT_X8R8G8B8 || dmode.Format==D3DFMT_R5G6B5,
"Unexpected display mode returned for mode %u: %#x\n", i , dmode.Format);
}
IDirect3D8_Release(pD3d);
}
START_TEST(device)
{
HMODULE d3d8_handle = LoadLibraryA( "d3d8.dll" );
@ -693,6 +723,7 @@ START_TEST(device)
pDirect3DCreate8 = (void *)GetProcAddress( d3d8_handle, "Direct3DCreate8" );
if (pDirect3DCreate8)
{
test_display_modes();
test_swapchain();
test_refcount();
test_mipmap_levels();

View File

@ -103,6 +103,10 @@ static UINT WINAPI IDirect3D9Impl_GetAdapterModeCount(LPDIRECT3D9 iface, UINT Ad
static HRESULT WINAPI IDirect3D9Impl_EnumAdapterModes(LPDIRECT3D9 iface, UINT Adapter, D3DFORMAT Format, UINT Mode, D3DDISPLAYMODE* pMode) {
IDirect3D9Impl *This = (IDirect3D9Impl *)iface;
/* We can't pass this to WineD3D, otherwise it'll think it came from D3D8.
It's supposed to fail anyway, so no harm returning failure. */
if(Format == D3DFMT_UNKNOWN)
return D3DERR_INVALIDCALL;
return IWineD3D_EnumAdapterModes(This->WineD3D, Adapter, Format, Mode, (WINED3DDISPLAYMODE *) pMode);
}

View File

@ -1,6 +1,7 @@
/*
* Copyright (C) 2006 Vitaliy Margolen
* Copyright (C) 2006 Stefan Dösinger(For CodeWeavers)
* Copyright (C) 2006 Chris Robinson
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -838,6 +839,96 @@ cleanup:
if(pDevice) IDirect3D9_Release(pDevice);
}
/* Test adapter display modes */
static void test_display_modes(void)
{
D3DDISPLAYMODE dmode;
IDirect3D9 *pD3d;
pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
if(!pD3d) return;
#define TEST_FMT(x,r) do { \
HRESULT res = IDirect3D9_EnumAdapterModes(pD3d, 0, (x), 0, &dmode); \
ok(res==(r), "EnumAdapterModes("#x") did not return "#r" (got %s)!\n", DXGetErrorString9(res)); \
} while(0)
TEST_FMT(D3DFMT_X1R5G5B5, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_R8G8B8, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_A8R8G8B8, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_A1R5G5B5, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_A4R4G4B4, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_R3G3B2, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_A8, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_A8R3G3B2, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_X4R4G4B4, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_A2B10G10R10, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_A8B8G8R8, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_X8B8G8R8, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_G16R16, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_A2R10G10B10, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_A16B16G16R16, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_A8P8, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_P8, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_L8, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_A8L8, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_A4L4, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_V8U8, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_L6V5U5, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_X8L8V8U8, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_Q8W8V8U8, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_V16U16, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_W11V11U10, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_A2W10V10U10, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_UYVY, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_YUY2, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_DXT1, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_DXT2, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_DXT3, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_DXT4, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_DXT5, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_MULTI2_ARGB, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_G8R8_G8B8, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_R8G8_B8G8, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_D16_LOCKABLE, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_D32, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_D15S1, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_D24S8, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_D24X8, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_D24X4S4, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_D16, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_L16, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_D32F_LOCKABLE, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_D24FS8, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_VERTEXDATA, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_INDEX16, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_INDEX32, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_Q16W16V16U16, D3DERR_INVALIDCALL);
/* Flaoting point formats */
TEST_FMT(D3DFMT_R16F, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_G16R16F, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_A16B16G16R16F, D3DERR_INVALIDCALL);
/* IEEE formats */
TEST_FMT(D3DFMT_R32F, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_G32R32F, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_A32B32G32R32F, D3DERR_INVALIDCALL);
TEST_FMT(D3DFMT_CxV8U8, D3DERR_INVALIDCALL);
TEST_FMT(0, D3DERR_INVALIDCALL);
IDirect3D9_Release(pD3d);
}
START_TEST(device)
{
HMODULE d3d9_handle = LoadLibraryA( "d3d9.dll" );
@ -845,6 +936,7 @@ START_TEST(device)
pDirect3DCreate9 = (void *)GetProcAddress( d3d9_handle, "Direct3DCreate9" );
if (pDirect3DCreate9)
{
test_display_modes();
test_swapchain();
test_refcount();
test_mipmap_levels();

View File

@ -1080,31 +1080,23 @@ static UINT WINAPI IWineD3DImpl_GetAdapterModeCount(IWineD3D *iface, UINT Ad
#if !defined( DEBUG_SINGLE_MODE )
DEVMODEW DevModeW;
/* Work out the current screen bpp */
HDC hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
int bpp = GetDeviceCaps(hdc, BITSPIXEL);
DeleteDC(hdc);
while (EnumDisplaySettingsExW(NULL, j, &DevModeW, 0)) {
j++;
switch (Format)
{
case WINED3DFMT_UNKNOWN:
i++;
break;
case WINED3DFMT_X8R8G8B8:
case WINED3DFMT_A8R8G8B8:
if (min(DevModeW.dmBitsPerPel, bpp) == 32) i++;
if (min(DevModeW.dmBitsPerPel, bpp) == 24) i++;
break;
case WINED3DFMT_X1R5G5B5:
case WINED3DFMT_A1R5G5B5:
case WINED3DFMT_R5G6B5:
if (min(DevModeW.dmBitsPerPel, bpp) == 16) i++;
break;
default:
/* Skip other modes as they do not match the requested format */
break;
case WINED3DFMT_UNKNOWN:
if (DevModeW.dmBitsPerPel == 32 ||
DevModeW.dmBitsPerPel == 16) i++;
break;
case WINED3DFMT_X8R8G8B8:
if (DevModeW.dmBitsPerPel == 32) i++;
break;
case WINED3DFMT_R5G6B5:
if (DevModeW.dmBitsPerPel == 16) i++;
break;
default:
/* Skip other modes as they do not match the requested format */
break;
}
}
#else
@ -1132,79 +1124,67 @@ static HRESULT WINAPI IWineD3DImpl_EnumAdapterModes(IWineD3D *iface, UINT Adapte
}
if (Adapter == 0) { /* Display */
int bpp;
#if !defined( DEBUG_SINGLE_MODE )
DEVMODEW DevModeW;
int ModeIdx = 0;
int i = 0;
int j = 0;
/* Work out the current screen bpp */
HDC hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
bpp = GetDeviceCaps(hdc, BITSPIXEL);
DeleteDC(hdc);
/* If we are filtering to a specific format, then need to skip all unrelated
modes, but if mode is irrelevant, then we can use the index directly */
if (Format == WINED3DFMT_UNKNOWN)
{
ModeIdx = Mode;
} else {
int i = 0;
int j = 0;
DEVMODEW DevModeWtmp;
while (i<(Mode) && EnumDisplaySettingsExW(NULL, j, &DevModeWtmp, 0)) {
j++;
switch (Format)
{
/* If we are filtering to a specific format (D3D9), then need to skip
all unrelated modes, but if mode is irrelevant (D3D8), then we can
just count through the ones with valid bit depths */
while ((i<=Mode) && EnumDisplaySettingsExW(NULL, j++, &DevModeW, 0)) {
switch (Format)
{
case WINED3DFMT_UNKNOWN:
i++;
break;
if (DevModeW.dmBitsPerPel == 32 ||
DevModeW.dmBitsPerPel == 16) i++;
break;
case WINED3DFMT_X8R8G8B8:
case WINED3DFMT_A8R8G8B8:
if (min(DevModeWtmp.dmBitsPerPel, bpp) == 32) i++;
if (min(DevModeWtmp.dmBitsPerPel, bpp) == 24) i++;
break;
case WINED3DFMT_X1R5G5B5:
case WINED3DFMT_A1R5G5B5:
if (DevModeW.dmBitsPerPel == 32) i++;
break;
case WINED3DFMT_R5G6B5:
if (min(DevModeWtmp.dmBitsPerPel, bpp) == 16) i++;
break;
if (DevModeW.dmBitsPerPel == 16) i++;
break;
default:
/* Skip other modes as they do not match requested format */
break;
}
/* Modes that don't match what we support can get an early-out */
TRACE_(d3d_caps)("Searching for %s, returning D3DERR_INVALIDCALL\n", debug_d3dformat(Format));
return WINED3DERR_INVALIDCALL;
}
ModeIdx = j;
}
if (i == 0) {
TRACE_(d3d_caps)("No modes found for format (%x - %s)\n", Format, debug_d3dformat(Format));
return WINED3DERR_INVALIDCALL;
}
ModeIdx = j - 1;
/* Now get the display mode via the calculated index */
if (EnumDisplaySettingsExW(NULL, ModeIdx, &DevModeW, 0))
{
if (EnumDisplaySettingsExW(NULL, ModeIdx, &DevModeW, 0)) {
pMode->Width = DevModeW.dmPelsWidth;
pMode->Height = DevModeW.dmPelsHeight;
bpp = min(DevModeW.dmBitsPerPel, bpp);
pMode->RefreshRate = D3DADAPTER_DEFAULT;
if (DevModeW.dmFields & DM_DISPLAYFREQUENCY)
{
pMode->RefreshRate = DevModeW.dmDisplayFrequency;
}
if (Format == WINED3DFMT_UNKNOWN)
{
switch (bpp) {
case 8: pMode->Format = WINED3DFMT_R3G3B2; break;
case 16: pMode->Format = WINED3DFMT_R5G6B5; break;
case 24: /* Robots and EVE Online need 24 and 32 bit as A8R8G8B8 to start */
case 32: pMode->Format = WINED3DFMT_A8R8G8B8; break;
default: pMode->Format = WINED3DFMT_UNKNOWN;
switch (DevModeW.dmBitsPerPel)
{
case 16:
pMode->Format = WINED3DFMT_R5G6B5;
break;
case 32:
pMode->Format = WINED3DFMT_X8R8G8B8;
break;
default:
pMode->Format = WINED3DFMT_UNKNOWN;
ERR("Unhandled bit depth (%u) in mode list!\n", DevModeW.dmBitsPerPel);
}
} else {
pMode->Format = Format;
}
}
else
{
} else {
TRACE_(d3d_caps)("Requested mode out of range %d\n", Mode);
return WINED3DERR_INVALIDCALL;
}
@ -1215,11 +1195,11 @@ static HRESULT WINAPI IWineD3DImpl_EnumAdapterModes(IWineD3D *iface, UINT Adapte
pMode->Width = 800;
pMode->Height = 600;
pMode->RefreshRate = D3DADAPTER_DEFAULT;
pMode->Format = (Format == WINED3DFMT_UNKNOWN) ? WINED3DFMT_A8R8G8B8 : Format;
bpp = 32;
pMode->Format = (Format == WINED3DFMT_UNKNOWN) ? WINED3DFMT_X8R8G8B8 : Format;
#endif
TRACE_(d3d_caps)("W %d H %d rr %d fmt (%x - %s) bpp %u\n", pMode->Width, pMode->Height,
pMode->RefreshRate, pMode->Format, debug_d3dformat(pMode->Format), bpp);
pMode->RefreshRate, pMode->Format, debug_d3dformat(pMode->Format),
DevModeW.dmBitsPerPel);
} else {
FIXME_(d3d_caps)("Adapter not primary display\n");