From: Józef Kucia Subject: [PATCH 5/8] dxgi: Implement dxgi_output_FindClosestMatchingMode1(). Message-Id: <20190306131957.21411-5-jkucia@codeweavers.com> Date: Wed, 6 Mar 2019 14:19:54 +0100 Signed-off-by: Józef Kucia --- dlls/dxgi/dxgi_private.h | 3 ++ dlls/dxgi/output.c | 85 ++++++++++++++++++++++++++++------------ dlls/dxgi/utils.c | 25 ++++++++++++ 3 files changed, 87 insertions(+), 26 deletions(-) diff --git a/dlls/dxgi/dxgi_private.h b/dlls/dxgi/dxgi_private.h index 320a347dde5e..1461e3c3af74 100644 --- a/dlls/dxgi/dxgi_private.h +++ b/dlls/dxgi/dxgi_private.h @@ -80,6 +80,7 @@ struct dxgi_device_layer /* TRACE helper functions */ const char *debug_dxgi_format(DXGI_FORMAT format) DECLSPEC_HIDDEN; const char *debug_dxgi_mode(const DXGI_MODE_DESC *desc) DECLSPEC_HIDDEN; +const char *debug_dxgi_mode1(const DXGI_MODE_DESC1 *desc) DECLSPEC_HIDDEN; void dump_feature_levels(const D3D_FEATURE_LEVEL *feature_levels, unsigned int level_count) DECLSPEC_HIDDEN; DXGI_FORMAT dxgi_format_from_wined3dformat(enum wined3d_format_id format) DECLSPEC_HIDDEN; @@ -91,6 +92,8 @@ void wined3d_sample_desc_from_dxgi(enum wined3d_multisample_type *wined3d_type, unsigned int *wined3d_quality, const DXGI_SAMPLE_DESC *dxgi_desc) DECLSPEC_HIDDEN; void wined3d_display_mode_from_dxgi(struct wined3d_display_mode *wined3d_mode, const DXGI_MODE_DESC *mode) DECLSPEC_HIDDEN; +void wined3d_display_mode_from_dxgi1(struct wined3d_display_mode *wined3d_mode, + const DXGI_MODE_DESC1 *mode) DECLSPEC_HIDDEN; DXGI_USAGE dxgi_usage_from_wined3d_bind_flags(unsigned int wined3d_bind_flags) DECLSPEC_HIDDEN; unsigned int wined3d_bind_flags_from_dxgi_usage(DXGI_USAGE usage) DECLSPEC_HIDDEN; unsigned int dxgi_swapchain_flags_from_wined3d(unsigned int wined3d_flags) DECLSPEC_HIDDEN; diff --git a/dlls/dxgi/output.c b/dlls/dxgi/output.c index bf0a4159376a..b1f20b92ebf5 100644 --- a/dlls/dxgi/output.c +++ b/dlls/dxgi/output.c @@ -34,6 +34,47 @@ static void dxgi_mode_from_wined3d(DXGI_MODE_DESC *mode, const struct wined3d_di mode->Scaling = DXGI_MODE_SCALING_UNSPECIFIED; /* FIXME */ } +static void dxgi_mode1_from_wined3d(DXGI_MODE_DESC1 *mode, const struct wined3d_display_mode *wined3d_mode) +{ + mode->Width = wined3d_mode->width; + mode->Height = wined3d_mode->height; + mode->RefreshRate.Numerator = wined3d_mode->refresh_rate; + mode->RefreshRate.Denominator = 1; + mode->Format = dxgi_format_from_wined3dformat(wined3d_mode->format_id); + mode->ScanlineOrdering = wined3d_mode->scanline_ordering; + mode->Scaling = DXGI_MODE_SCALING_UNSPECIFIED; /* FIXME */ + mode->Stereo = FALSE; /* FIXME */ +} + +static HRESULT dxgi_output_find_closest_matching_mode(struct dxgi_output *output, + struct wined3d_display_mode *mode, IUnknown *device) +{ + struct dxgi_adapter *adapter; + struct wined3d *wined3d; + HRESULT hr; + + if (!mode->width != !mode->height) + return DXGI_ERROR_INVALID_CALL; + + if (mode->format_id == WINED3DFMT_UNKNOWN && !device) + return DXGI_ERROR_INVALID_CALL; + + if (mode->format_id == WINED3DFMT_UNKNOWN) + { + FIXME("Matching formats to device not implemented.\n"); + return E_NOTIMPL; + } + + wined3d_mutex_lock(); + adapter = output->adapter; + wined3d = adapter->factory->wined3d; + + hr = wined3d_find_closest_matching_adapter_mode(wined3d, adapter->ordinal, mode); + wined3d_mutex_unlock(); + + return hr; +} + static inline struct dxgi_output *impl_from_IDXGIOutput4(IDXGIOutput4 *iface) { return CONTAINING_RECORD(iface, struct dxgi_output, IDXGIOutput4_iface); @@ -234,33 +275,13 @@ static HRESULT STDMETHODCALLTYPE dxgi_output_FindClosestMatchingMode(IDXGIOutput { struct dxgi_output *output = impl_from_IDXGIOutput4(iface); struct wined3d_display_mode wined3d_mode; - struct dxgi_adapter *adapter; - struct wined3d *wined3d; HRESULT hr; - TRACE("iface %p, mode %p, closest_match %p, device %p.\n", iface, mode, closest_match, device); - - if ((!mode->Width && mode->Height) || (mode->Width && !mode->Height)) - return DXGI_ERROR_INVALID_CALL; - - if (mode->Format == DXGI_FORMAT_UNKNOWN && !device) - return DXGI_ERROR_INVALID_CALL; - - TRACE("Mode: %s.\n", debug_dxgi_mode(mode)); - if (mode->Format == DXGI_FORMAT_UNKNOWN) - { - FIXME("Matching formats to device not implemented.\n"); - return E_NOTIMPL; - } - - adapter = output->adapter; - wined3d = adapter->factory->wined3d; + TRACE("iface %p, mode %s, closest_match %p, device %p.\n", + iface, debug_dxgi_mode(mode), closest_match, device); - wined3d_mutex_lock(); wined3d_display_mode_from_dxgi(&wined3d_mode, mode); - hr = wined3d_find_closest_matching_adapter_mode(wined3d, adapter->ordinal, &wined3d_mode); - wined3d_mutex_unlock(); - + hr = dxgi_output_find_closest_matching_mode(output, &wined3d_mode, device); if (SUCCEEDED(hr)) { dxgi_mode_from_wined3d(closest_match, &wined3d_mode); @@ -366,10 +387,22 @@ static HRESULT STDMETHODCALLTYPE dxgi_output_GetDisplayModeList1(IDXGIOutput4 *i static HRESULT STDMETHODCALLTYPE dxgi_output_FindClosestMatchingMode1(IDXGIOutput4 *iface, const DXGI_MODE_DESC1 *mode, DXGI_MODE_DESC1 *closest_match, IUnknown *device) { - FIXME("iface %p, mode %p, closest_match %p, device %p stub!\n", - iface, mode, closest_match, device); + struct dxgi_output *output = impl_from_IDXGIOutput4(iface); + struct wined3d_display_mode wined3d_mode; + HRESULT hr; - return E_NOTIMPL; + TRACE("iface %p, mode %s, closest_match %p, device %p.\n", + iface, debug_dxgi_mode1(mode), closest_match, device); + + wined3d_display_mode_from_dxgi1(&wined3d_mode, mode); + hr = dxgi_output_find_closest_matching_mode(output, &wined3d_mode, device); + if (SUCCEEDED(hr)) + { + dxgi_mode1_from_wined3d(closest_match, &wined3d_mode); + TRACE("Returning %s.\n", debug_dxgi_mode1(closest_match)); + } + + return hr; } static HRESULT STDMETHODCALLTYPE dxgi_output_GetDisplaySurfaceData1(IDXGIOutput4 *iface, diff --git a/dlls/dxgi/utils.c b/dlls/dxgi/utils.c index 3a67cfededff..23f5188b0111 100644 --- a/dlls/dxgi/utils.c +++ b/dlls/dxgi/utils.c @@ -380,12 +380,26 @@ enum wined3d_format_id wined3dformat_from_dxgi_format(DXGI_FORMAT format) const char *debug_dxgi_mode(const DXGI_MODE_DESC *desc) { + if (!desc) + return "(null)"; + return wine_dbg_sprintf("resolution %ux%u, refresh rate %u / %u, " "format %s, scanline ordering %#x, scaling %#x", desc->Width, desc->Height, desc->RefreshRate.Numerator, desc->RefreshRate.Denominator, debug_dxgi_format(desc->Format), desc->ScanlineOrdering, desc->Scaling); } +const char *debug_dxgi_mode1(const DXGI_MODE_DESC1 *desc) +{ + if (!desc) + return "(null)"; + + return wine_dbg_sprintf("resolution %ux%u, refresh rate %u / %u, " + "format %s, scanline ordering %#x, scaling %#x, stereo %#x", + desc->Width, desc->Height, desc->RefreshRate.Numerator, desc->RefreshRate.Denominator, + debug_dxgi_format(desc->Format), desc->ScanlineOrdering, desc->Scaling, desc->Stereo); +} + void dump_feature_levels(const D3D_FEATURE_LEVEL *feature_levels, unsigned int level_count) { unsigned int i; @@ -455,6 +469,17 @@ void wined3d_display_mode_from_dxgi(struct wined3d_display_mode *wined3d_mode, wined3d_mode->scanline_ordering = wined3d_scanline_ordering_from_dxgi(mode->ScanlineOrdering); } +void wined3d_display_mode_from_dxgi1(struct wined3d_display_mode *wined3d_mode, + const DXGI_MODE_DESC1 *mode) +{ + wined3d_mode->width = mode->Width; + wined3d_mode->height = mode->Height; + wined3d_mode->refresh_rate = dxgi_rational_to_uint(&mode->RefreshRate); + wined3d_mode->format_id = wined3dformat_from_dxgi_format(mode->Format); + wined3d_mode->scanline_ordering = wined3d_scanline_ordering_from_dxgi(mode->ScanlineOrdering); + FIXME("Ignoring stereo %#x.\n", mode->Stereo); +} + DXGI_USAGE dxgi_usage_from_wined3d_bind_flags(unsigned int wined3d_bind_flags) { DXGI_USAGE dxgi_usage = 0; -- 2.19.2