mirror of
https://github.com/reactos/wine.git
synced 2024-11-28 14:10:32 +00:00
d3d: Fix adapter mode enumeration and filtering.
This commit is contained in:
parent
e4a6562937
commit
ed21935479
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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");
|
||||
|
Loading…
Reference in New Issue
Block a user