dxgi: Implement dxgi_output_GetDisplayModeList1().

Signed-off-by: Józef Kucia <jkucia@codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Józef Kucia 2019-03-07 11:21:23 +01:00 committed by Alexandre Julliard
parent 5307a251e5
commit b817be926d
1 changed files with 90 additions and 59 deletions

View File

@ -75,6 +75,85 @@ static HRESULT dxgi_output_find_closest_matching_mode(struct dxgi_output *output
return hr; return hr;
} }
enum dxgi_mode_struct_version
{
DXGI_MODE_STRUCT_VERSION_0,
DXGI_MODE_STRUCT_VERSION_1,
};
static HRESULT dxgi_output_get_display_mode_list(struct dxgi_output *output,
DXGI_FORMAT format, unsigned int *mode_count, void *modes,
enum dxgi_mode_struct_version struct_version)
{
enum wined3d_format_id wined3d_format;
struct wined3d_display_mode mode;
unsigned int i, max_count;
struct wined3d *wined3d;
HRESULT hr;
if (!mode_count)
return DXGI_ERROR_INVALID_CALL;
if (format == DXGI_FORMAT_UNKNOWN)
{
*mode_count = 0;
return S_OK;
}
wined3d_format = wined3dformat_from_dxgi_format(format);
wined3d_mutex_lock();
wined3d = output->adapter->factory->wined3d;
max_count = wined3d_get_adapter_mode_count(wined3d, output->adapter->ordinal,
wined3d_format, WINED3D_SCANLINE_ORDERING_UNKNOWN);
if (!modes)
{
wined3d_mutex_unlock();
*mode_count = max_count;
return S_OK;
}
if (max_count > *mode_count)
{
wined3d_mutex_unlock();
return DXGI_ERROR_MORE_DATA;
}
*mode_count = max_count;
for (i = 0; i < *mode_count; ++i)
{
if (FAILED(hr = wined3d_enum_adapter_modes(wined3d, output->adapter->ordinal,
wined3d_format, WINED3D_SCANLINE_ORDERING_UNKNOWN, i, &mode)))
{
WARN("Failed to enum adapter mode %u, hr %#x.\n", i, hr);
wined3d_mutex_unlock();
return hr;
}
switch (struct_version)
{
case DXGI_MODE_STRUCT_VERSION_0:
{
DXGI_MODE_DESC *desc = modes;
dxgi_mode_from_wined3d(&desc[i], &mode);
break;
}
case DXGI_MODE_STRUCT_VERSION_1:
{
DXGI_MODE_DESC1 *desc = modes;
dxgi_mode1_from_wined3d(&desc[i], &mode);
break;
}
}
}
wined3d_mutex_unlock();
return S_OK;
}
static inline struct dxgi_output *impl_from_IDXGIOutput4(IDXGIOutput4 *iface) static inline struct dxgi_output *impl_from_IDXGIOutput4(IDXGIOutput4 *iface)
{ {
return CONTAINING_RECORD(iface, struct dxgi_output, IDXGIOutput4_iface); return CONTAINING_RECORD(iface, struct dxgi_output, IDXGIOutput4_iface);
@ -208,66 +287,15 @@ static HRESULT STDMETHODCALLTYPE dxgi_output_GetDesc(IDXGIOutput4 *iface, DXGI_O
} }
static HRESULT STDMETHODCALLTYPE dxgi_output_GetDisplayModeList(IDXGIOutput4 *iface, static HRESULT STDMETHODCALLTYPE dxgi_output_GetDisplayModeList(IDXGIOutput4 *iface,
DXGI_FORMAT format, UINT flags, UINT *mode_count, DXGI_MODE_DESC *desc) DXGI_FORMAT format, UINT flags, UINT *mode_count, DXGI_MODE_DESC *modes)
{ {
struct dxgi_output *output = impl_from_IDXGIOutput4(iface); struct dxgi_output *output = impl_from_IDXGIOutput4(iface);
enum wined3d_format_id wined3d_format;
unsigned int i, max_count;
struct wined3d *wined3d;
FIXME("iface %p, format %s, flags %#x, mode_count %p, desc %p partial stub!\n", FIXME("iface %p, format %s, flags %#x, mode_count %p, modes %p partial stub!\n",
iface, debug_dxgi_format(format), flags, mode_count, desc); iface, debug_dxgi_format(format), flags, mode_count, modes);
if (!mode_count) return dxgi_output_get_display_mode_list(output,
return DXGI_ERROR_INVALID_CALL; format, mode_count, modes, DXGI_MODE_STRUCT_VERSION_0);
if (format == DXGI_FORMAT_UNKNOWN)
{
*mode_count = 0;
return S_OK;
}
wined3d = output->adapter->factory->wined3d;
wined3d_format = wined3dformat_from_dxgi_format(format);
wined3d_mutex_lock();
max_count = wined3d_get_adapter_mode_count(wined3d, output->adapter->ordinal,
wined3d_format, WINED3D_SCANLINE_ORDERING_UNKNOWN);
if (!desc)
{
wined3d_mutex_unlock();
*mode_count = max_count;
return S_OK;
}
if (max_count > *mode_count)
{
wined3d_mutex_unlock();
return DXGI_ERROR_MORE_DATA;
}
*mode_count = max_count;
for (i = 0; i < *mode_count; ++i)
{
struct wined3d_display_mode mode;
HRESULT hr;
hr = wined3d_enum_adapter_modes(wined3d, output->adapter->ordinal, wined3d_format,
WINED3D_SCANLINE_ORDERING_UNKNOWN, i, &mode);
if (FAILED(hr))
{
WARN("EnumAdapterModes failed, hr %#x.\n", hr);
wined3d_mutex_unlock();
return hr;
}
dxgi_mode_from_wined3d(&desc[i], &mode);
}
wined3d_mutex_unlock();
return S_OK;
} }
static HRESULT STDMETHODCALLTYPE dxgi_output_FindClosestMatchingMode(IDXGIOutput4 *iface, static HRESULT STDMETHODCALLTYPE dxgi_output_FindClosestMatchingMode(IDXGIOutput4 *iface,
@ -378,10 +406,13 @@ static HRESULT STDMETHODCALLTYPE dxgi_output_GetFrameStatistics(IDXGIOutput4 *if
static HRESULT STDMETHODCALLTYPE dxgi_output_GetDisplayModeList1(IDXGIOutput4 *iface, static HRESULT STDMETHODCALLTYPE dxgi_output_GetDisplayModeList1(IDXGIOutput4 *iface,
DXGI_FORMAT format, UINT flags, UINT *mode_count, DXGI_MODE_DESC1 *modes) DXGI_FORMAT format, UINT flags, UINT *mode_count, DXGI_MODE_DESC1 *modes)
{ {
FIXME("iface %p, format %#x, flags %#x, mode_count %p, modes %p stub!\n", struct dxgi_output *output = impl_from_IDXGIOutput4(iface);
iface, format, flags, mode_count, modes);
return E_NOTIMPL; FIXME("iface %p, format %s, flags %#x, mode_count %p, modes %p partial stub!\n",
iface, debug_dxgi_format(format), flags, mode_count, modes);
return dxgi_output_get_display_mode_list(output,
format, mode_count, modes, DXGI_MODE_STRUCT_VERSION_1);
} }
static HRESULT STDMETHODCALLTYPE dxgi_output_FindClosestMatchingMode1(IDXGIOutput4 *iface, static HRESULT STDMETHODCALLTYPE dxgi_output_FindClosestMatchingMode1(IDXGIOutput4 *iface,