From: Ken Thomases Subject: [PATCH 3/3] d3d9/tests: Improve testing of display formats and IDirect3D9_CheckDeviceType(). Message-Id: <978AFEF1-B6CC-428A-BB8C-F33F74CC8ECC@codeweavers.com> Date: Wed, 22 Jan 2014 16:42:38 -0600 Consolidates duplicated code by using a simpler table-driven mechanism. Instead of manually listing out certain combinations of display formats vs. backbuffer formats, it just lists the formats and some metadata about them. The algorithm tests every format against every format, using the metadata to predict success or failure. This also tests that CheckDeviceType() fails for display formats for which there are no adapter modes, rather than skipping those. Tests windowed mode. --- dlls/d3d9/tests/device.c | 162 ++++++++++++++++++---------------------------- 1 files changed, 64 insertions(+), 98 deletions(-) diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c index 799f1c3..b94d52a 100644 --- a/dlls/d3d9/tests/device.c +++ b/dlls/d3d9/tests/device.c @@ -2271,54 +2271,25 @@ cleanup: if(d3d9) IDirect3D9_Release(d3d9); } -struct formats { - D3DFORMAT DisplayFormat; - D3DFORMAT BackBufferFormat; - BOOL shouldPass; +struct format { + D3DFORMAT format; + D3DFORMAT alpha_format; + const char* name; + BOOL display; + BOOL windowed; }; -static const struct formats r5g6b5_format_list[] = +static const struct format formats[] = { - { D3DFMT_R5G6B5, D3DFMT_R5G6B5, TRUE }, - { D3DFMT_R5G6B5, D3DFMT_X1R5G5B5, FALSE }, - { D3DFMT_R5G6B5, D3DFMT_A1R5G5B5, FALSE }, - { D3DFMT_R5G6B5, D3DFMT_X8R8G8B8, FALSE }, - { D3DFMT_R5G6B5, D3DFMT_A8R8G8B8, FALSE }, - { 0, 0, 0} -}; - -static const struct formats x1r5g5b5_format_list[] = -{ - { D3DFMT_X1R5G5B5, D3DFMT_R5G6B5, FALSE }, - { D3DFMT_X1R5G5B5, D3DFMT_X1R5G5B5, TRUE }, - { D3DFMT_X1R5G5B5, D3DFMT_A1R5G5B5, TRUE }, - { D3DFMT_X1R5G5B5, D3DFMT_X8R8G8B8, FALSE }, - { D3DFMT_X1R5G5B5, D3DFMT_A8R8G8B8, FALSE }, - - /* A1R5G5B5 should not be usable as a display format, it is backbuffer-only */ - { D3DFMT_A1R5G5B5, D3DFMT_R5G6B5, FALSE }, - { D3DFMT_A1R5G5B5, D3DFMT_X1R5G5B5, FALSE }, - { D3DFMT_A1R5G5B5, D3DFMT_A1R5G5B5, FALSE }, - { D3DFMT_A1R5G5B5, D3DFMT_X8R8G8B8, FALSE }, - { D3DFMT_A1R5G5B5, D3DFMT_A8R8G8B8, FALSE }, - { 0, 0, 0} -}; - -static const struct formats x8r8g8b8_format_list[] = -{ - { D3DFMT_X8R8G8B8, D3DFMT_R5G6B5, FALSE }, - { D3DFMT_X8R8G8B8, D3DFMT_X1R5G5B5, FALSE }, - { D3DFMT_X8R8G8B8, D3DFMT_A1R5G5B5, FALSE }, - { D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, TRUE }, - { D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, TRUE }, - - /* A1R8G8B8 should not be usable as a display format, it is backbuffer-only */ - { D3DFMT_A8R8G8B8, D3DFMT_R5G6B5, FALSE }, - { D3DFMT_A8R8G8B8, D3DFMT_X1R5G5B5, FALSE }, - { D3DFMT_A8R8G8B8, D3DFMT_A1R5G5B5, FALSE }, - { D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8, FALSE }, - { D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE }, - { 0, 0, 0} +#define FORMAT(f, a, d, w) { f, a, #f, d, w } + FORMAT(D3DFMT_R5G6B5, 0, TRUE, TRUE), + FORMAT(D3DFMT_X1R5G5B5, D3DFMT_A1R5G5B5, TRUE, TRUE), + FORMAT(D3DFMT_A1R5G5B5, D3DFMT_A1R5G5B5, FALSE, FALSE), + FORMAT(D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, TRUE, TRUE), + FORMAT(D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE, FALSE), + FORMAT(D3DFMT_A2R10G10B10, 0, TRUE, FALSE), + FORMAT(D3DFMT_UNKNOWN, 0, FALSE, FALSE), +#undef FORMAT }; static void test_display_formats(void) @@ -2326,71 +2297,66 @@ static void test_display_formats(void) /* Direct3D9 offers 4 display formats R5G6B5, X1R5G5B5, X8R8G8B8 and A2R10G10B10. * Next to these there are 6 different backbuffer formats. Only a fixed number of * combinations are possible in FULLSCREEN mode. In windowed mode more combinations are - * allowed due to depth conversion and this is likely driver dependent. - * This test checks which combinations are possible in fullscreen mode and this should not be driver dependent. - * TODO: handle A2R10G10B10 but what hardware supports it? Parhelia? It is very rare. */ + * allowed due to depth conversion and this is likely driver dependent. */ UINT Adapter = D3DADAPTER_DEFAULT; D3DDEVTYPE DeviceType = D3DDEVTYPE_HAL; - int i, nmodes; - HRESULT hr; + int display; IDirect3D9 *d3d9 = pDirect3DCreate9( D3D_SDK_VERSION ); ok(d3d9 != NULL, "Failed to create IDirect3D9 object\n"); if(!d3d9) return; - nmodes = IDirect3D9_GetAdapterModeCount(d3d9, D3DADAPTER_DEFAULT, D3DFMT_R5G6B5); - if(!nmodes) { - skip("Display format R5G6B5 not supported, skipping\n"); - } else { - trace("Testing display format R5G6B5\n"); - for(i=0; r5g6b5_format_list[i].DisplayFormat != 0; i++) - { - hr = IDirect3D9_CheckDeviceType(d3d9, Adapter, DeviceType, r5g6b5_format_list[i].DisplayFormat, r5g6b5_format_list[i].BackBufferFormat, FALSE); - - if(r5g6b5_format_list[i].shouldPass) - ok(hr == D3D_OK || - broken(hr == D3DERR_NOTAVAILABLE) /* Windows VGA driver */, - "format %d %d didn't pass with hr=%#08x\n", r5g6b5_format_list[i].DisplayFormat, r5g6b5_format_list[i].BackBufferFormat, hr); - else - ok(hr != D3D_OK, "format %d %d didn't pass while it was expected to\n", r5g6b5_format_list[i].DisplayFormat, r5g6b5_format_list[i].BackBufferFormat); - } - } - - nmodes = IDirect3D9_GetAdapterModeCount(d3d9, D3DADAPTER_DEFAULT, D3DFMT_X1R5G5B5); - if(!nmodes) { - skip("Display format X1R5G5B5 not supported, skipping\n"); - } else { - trace("Testing display format X1R5G5B5\n"); - for(i=0; x1r5g5b5_format_list[i].DisplayFormat != 0; i++) - { - hr = IDirect3D9_CheckDeviceType(d3d9, Adapter, DeviceType, x1r5g5b5_format_list[i].DisplayFormat, x1r5g5b5_format_list[i].BackBufferFormat, FALSE); + for (display = 0; display < sizeof(formats) / sizeof(formats[0]); display++) + { + int nmodes, windowed; - if(x1r5g5b5_format_list[i].shouldPass) - ok(hr == D3D_OK || - broken(hr == D3DERR_NOTAVAILABLE) /* Spice QXL driver */, - "format %d %d didn't pass with hr=%#08x\n", x1r5g5b5_format_list[i].DisplayFormat, x1r5g5b5_format_list[i].BackBufferFormat, hr); - else - ok(hr != D3D_OK, "format %d %d didn't pass while it was expected to\n", x1r5g5b5_format_list[i].DisplayFormat, x1r5g5b5_format_list[i].BackBufferFormat); - } - } + nmodes = IDirect3D9_GetAdapterModeCount(d3d9, D3DADAPTER_DEFAULT, formats[display].format); + if (!nmodes) + trace("Display format %s not supported\n", formats[display].name); - nmodes = IDirect3D9_GetAdapterModeCount(d3d9, D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8); - if(!nmodes) { - skip("Display format X8R8G8B8 not supported, skipping\n"); - } else { - trace("Testing display format X8R8G8B8\n"); - for(i=0; x8r8g8b8_format_list[i].DisplayFormat != 0; i++) + for (windowed = 0; windowed <= 1; windowed++) { - hr = IDirect3D9_CheckDeviceType(d3d9, Adapter, DeviceType, x8r8g8b8_format_list[i].DisplayFormat, x8r8g8b8_format_list[i].BackBufferFormat, FALSE); - trace("CheckDeviceType(%d %d) = %08x shouldPass = %d\n", x8r8g8b8_format_list[i].DisplayFormat, x8r8g8b8_format_list[i].BackBufferFormat, hr, x8r8g8b8_format_list[i].shouldPass); + int backbuffer; + for (backbuffer = 0; backbuffer < sizeof(formats) / sizeof(formats[0]); backbuffer++) + { + BOOL shouldPass; + HRESULT hr; - if(x8r8g8b8_format_list[i].shouldPass) - ok(hr == D3D_OK || - broken(hr == D3DERR_NOTAVAILABLE) /* Windows VGA driver */, - "format %d %d didn't pass with hr=%#08x\n", x8r8g8b8_format_list[i].DisplayFormat, x8r8g8b8_format_list[i].BackBufferFormat, hr); - else - ok(hr != D3D_OK, "format %d %d didn't pass while it was expected to\n", x8r8g8b8_format_list[i].DisplayFormat, x8r8g8b8_format_list[i].BackBufferFormat); + if (!formats[display].display || !nmodes) + shouldPass = FALSE; + else if (windowed) + { + if (!formats[display].windowed) + shouldPass = FALSE; + else if (formats[backbuffer].format == D3DFMT_UNKNOWN) + shouldPass = TRUE; + else + { + hr = IDirect3D9_CheckDeviceFormat(d3d9, Adapter, DeviceType, formats[display].format, D3DUSAGE_RENDERTARGET, + D3DRTYPE_SURFACE, formats[backbuffer].format); + if (hr == D3D_OK) + hr = IDirect3D9_CheckDeviceFormatConversion(d3d9, Adapter, DeviceType, formats[backbuffer].format, formats[display].format); + shouldPass = (hr == D3D_OK); + } + } + else + shouldPass = (formats[display].format == formats[backbuffer].format || + (formats[display].alpha_format && formats[display].alpha_format == formats[backbuffer].alpha_format)); + + trace("Testing display format %s, backbuffer format %s, windowed %d, shouldPass %d\n", + formats[display].name, formats[backbuffer].name, windowed, shouldPass); + hr = IDirect3D9_CheckDeviceType(d3d9, Adapter, DeviceType, formats[display].format, formats[backbuffer].format, windowed); + + if (shouldPass) + ok(hr == D3D_OK || + broken(hr == D3DERR_NOTAVAILABLE) /* Windows VGA driver, Spice QXL driver */, + "format %s(%d) %s(%d) %s didn't pass with hr=%#08x\n", formats[display].name, formats[display].format, + formats[backbuffer].name, formats[backbuffer].format, windowed ? "windowed" : "full-screen", hr); + else + ok(hr != D3D_OK, "format %s(%d) %s(%d) %s passed while it wasn't expected to\n", formats[display].name, + formats[display].format, formats[backbuffer].name, formats[backbuffer].format, windowed ? "windowed" : "full-screen"); + } } }