From 175c63773dac411d3cfa80034ff7024a895740c1 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Wed, 29 Jan 2014 19:28:35 +0100 Subject: [PATCH] wined3d: Don't allow format conversion on Present() for d3d8. Note that this isn't currently enforced by wined3d_swapchain_create() or wined3d_device_reset() though. --- dlls/d3d9/directx.c | 5 ++- dlls/wined3d/directx.c | 96 ++++++++++++++++++------------------------ include/wine/wined3d.h | 1 + 3 files changed, 47 insertions(+), 55 deletions(-) diff --git a/dlls/d3d9/directx.c b/dlls/d3d9/directx.c index e73051d7943..79e9eb59e90 100644 --- a/dlls/d3d9/directx.c +++ b/dlls/d3d9/directx.c @@ -636,7 +636,10 @@ static const struct IDirect3D9ExVtbl d3d9_vtbl = BOOL d3d9_init(struct d3d9 *d3d9, BOOL extended) { - DWORD flags = extended ? 0 : WINED3D_VIDMEM_ACCOUNTING; + DWORD flags = WINED3D_PRESENT_CONVERSION; + + if (!extended) + flags |= WINED3D_VIDMEM_ACCOUNTING; d3d9->IDirect3D9Ex_iface.lpVtbl = &d3d9_vtbl; d3d9->refcount = 1; diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index 6617c3a8994..3ebf43a5fdb 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -4000,7 +4000,7 @@ HRESULT CDECL wined3d_check_device_type(const struct wined3d *wined3d, UINT adap enum wined3d_device_type device_type, enum wined3d_format_id display_format, enum wined3d_format_id backbuffer_format, BOOL windowed) { - HRESULT hr; + BOOL present_conversion = wined3d->flags & WINED3D_PRESENT_CONVERSION; TRACE("wined3d %p, adapter_idx %u, device_type %s, display_format %s, backbuffer_format %s, windowed %#x.\n", wined3d, adapter_idx, debug_d3ddevicetype(device_type), debug_d3dformat(display_format), @@ -4025,100 +4025,88 @@ HRESULT CDECL wined3d_check_device_type(const struct wined3d *wined3d, UINT adap return WINED3DERR_NOTAVAILABLE; } - if (windowed) + if (!windowed) { - /* WINED3DFMT_B10G10R10A2_UNORM is only allowed in fullscreen mode. */ - if (display_format == WINED3DFMT_B10G10R10A2_UNORM) - { - TRACE("Unsupported display/backbuffer format combination %s / %s for windowed mode.\n", - debug_d3dformat(display_format), debug_d3dformat(backbuffer_format)); - return WINED3DERR_NOTAVAILABLE; - } - - /* Windowed mode allows you to specify WINED3DFMT_UNKNOWN for the backbuffer format, - * it means 'reuse' the display format for the backbuffer. */ - if (backbuffer_format == WINED3DFMT_UNKNOWN) - backbuffer_format = display_format; - - /* In windowed mode, if color conversion from the backbuffer format to the - * display format is supported, then the format combination is supported. */ - hr = wined3d_check_device_format_conversion(wined3d, adapter_idx, device_type, backbuffer_format, display_format); - if (FAILED(hr)) - { - TRACE("Unsupported display/backbuffer format combination %s / %s; no color conversion.\n", - debug_d3dformat(display_format), debug_d3dformat(backbuffer_format)); - return WINED3DERR_NOTAVAILABLE; - } - } - else - { - UINT mode_count; - /* If the requested display format is not available, don't continue. */ - mode_count = wined3d_get_adapter_mode_count(wined3d, adapter_idx, - display_format, WINED3D_SCANLINE_ORDERING_UNKNOWN); - if (!mode_count) + if (!wined3d_get_adapter_mode_count(wined3d, adapter_idx, + display_format, WINED3D_SCANLINE_ORDERING_UNKNOWN)) { TRACE("No available modes for display format %s.\n", debug_d3dformat(display_format)); return WINED3DERR_NOTAVAILABLE; } + present_conversion = FALSE; + } + else if (display_format == WINED3DFMT_B10G10R10A2_UNORM) + { + /* WINED3DFMT_B10G10R10A2_UNORM is only allowed in fullscreen mode. */ + TRACE("Unsupported format combination %s / %s in windowed mode.\n", + debug_d3dformat(display_format), debug_d3dformat(backbuffer_format)); + return WINED3DERR_NOTAVAILABLE; + } + + if (present_conversion) + { + /* Use the display format as back buffer format if the latter is + * WINED3DFMT_UNKNOWN. */ if (backbuffer_format == WINED3DFMT_UNKNOWN) + backbuffer_format = display_format; + + if (FAILED(wined3d_check_device_format_conversion(wined3d, adapter_idx, + device_type, backbuffer_format, display_format))) { - TRACE("backbuffer_format WINED3FMT_UNKNOWN only available in windowed mode.\n"); + TRACE("Format conversion from %s to %s not supported.\n", + debug_d3dformat(backbuffer_format), debug_d3dformat(display_format)); return WINED3DERR_NOTAVAILABLE; } + } + else + { + /* When format conversion from the back buffer format to the display + * format is not allowed, only a limited number of combinations are + * valid. */ - /* In FULLSCREEN mode WINED3DFMT_B5G6R5_UNORM can only be mixed with - * backbuffer format WINED3DFMT_B5G6R5_UNORM. */ if (display_format == WINED3DFMT_B5G6R5_UNORM && backbuffer_format != WINED3DFMT_B5G6R5_UNORM) { - TRACE("Unsupported display/backbuffer format combination %s / %s.\n", + TRACE("Unsupported format combination %s / %s.\n", debug_d3dformat(display_format), debug_d3dformat(backbuffer_format)); return WINED3DERR_NOTAVAILABLE; } - /* In FULLSCREEN mode WINED3DFMT_B5G5R5X1_UNORM can only be mixed with - * backbuffer formats WINED3DFMT_B5G5R5X1_UNORM and - * WINED3DFMT_B5G5R5A1_UNORM. */ if (display_format == WINED3DFMT_B5G5R5X1_UNORM && !(backbuffer_format == WINED3DFMT_B5G5R5X1_UNORM || backbuffer_format == WINED3DFMT_B5G5R5A1_UNORM)) { - TRACE("Unsupported display/backbuffer format combination %s / %s.\n", + TRACE("Unsupported format combination %s / %s.\n", debug_d3dformat(display_format), debug_d3dformat(backbuffer_format)); return WINED3DERR_NOTAVAILABLE; } - /* In FULLSCREEN mode WINED3DFMT_B8G8R8X8_UNORM can only be mixed with - * backbuffer formats WINED3DFMT_B8G8R8X8_UNORM and - * WINED3DFMT_B8G8R8A8_UNORM. */ if (display_format == WINED3DFMT_B8G8R8X8_UNORM && !(backbuffer_format == WINED3DFMT_B8G8R8X8_UNORM || backbuffer_format == WINED3DFMT_B8G8R8A8_UNORM)) { - TRACE("Unsupported display/backbuffer format combination %s / %s.\n", + TRACE("Unsupported format combination %s / %s.\n", debug_d3dformat(display_format), debug_d3dformat(backbuffer_format)); return WINED3DERR_NOTAVAILABLE; } - /* WINED3DFMT_B10G10R10A2_UNORM can only be mixed with backbuffer format - * WINED3DFMT_B10G10R10A2_UNORM. */ if (display_format == WINED3DFMT_B10G10R10A2_UNORM && backbuffer_format != WINED3DFMT_B10G10R10A2_UNORM) { - TRACE("Unsupported display/backbuffer format combination %s / %s.\n", + TRACE("Unsupported format combination %s / %s.\n", debug_d3dformat(display_format), debug_d3dformat(backbuffer_format)); return WINED3DERR_NOTAVAILABLE; } } - /* Use CheckDeviceFormat to see if the backbuffer_format is usable with the given display_format */ - hr = wined3d_check_device_format(wined3d, adapter_idx, device_type, display_format, - WINED3DUSAGE_RENDERTARGET, WINED3D_RTYPE_SURFACE, backbuffer_format); - if (FAILED(hr)) - TRACE("Unsupported display/backbuffer format combination %s / %s.\n", - debug_d3dformat(display_format), debug_d3dformat(backbuffer_format)); + /* Validate that the back buffer format is usable for render targets. */ + if (FAILED(wined3d_check_device_format(wined3d, adapter_idx, device_type, display_format, + WINED3DUSAGE_RENDERTARGET, WINED3D_RTYPE_SURFACE, backbuffer_format))) + { + TRACE("Format %s not allowed for render targets.\n", debug_d3dformat(backbuffer_format)); + return WINED3DERR_NOTAVAILABLE; + } - return hr; + return WINED3D_OK; } HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapter_idx, diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 7ddd4664bff..de1884f7ca7 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -1217,6 +1217,7 @@ enum wined3d_display_rotation #define WINED3D_LEGACY_DEPTH_BIAS 0x00000001 #define WINED3D_NO3D 0x00000002 #define WINED3D_VIDMEM_ACCOUNTING 0x00000004 +#define WINED3D_PRESENT_CONVERSION 0x00000008 #define WINED3D_RESZ_CODE 0x7fa05000