[PATCH] dxgi: Sort reported output modes

Andrew Eikum aeikum at codeweavers.com
Thu Oct 24 08:03:39 CDT 2019


If this patch looks OK, Gijs pointed out that it could be resent with
this tag:

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45433

On Wed, Oct 23, 2019 at 03:32:25PM -0500, Andrew Eikum wrote:
> Sekiro: Shadows Die Twice depends on this for its mode switching.
> 
> Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>
> ---
>  dlls/dxgi/output.c     | 64 ++++++++++++++++++++++++++++++++++++++++++
>  dlls/dxgi/tests/dxgi.c | 32 ++++++++++++++++++++-
>  2 files changed, 95 insertions(+), 1 deletion(-)
> 
> diff --git a/dlls/dxgi/output.c b/dlls/dxgi/output.c
> index abe1aef950c..c54c8b165ed 100644
> --- a/dlls/dxgi/output.c
> +++ b/dlls/dxgi/output.c
> @@ -75,6 +75,60 @@ static HRESULT dxgi_output_find_closest_matching_mode(struct dxgi_output *output
>      return hr;
>  }
>  
> +static int dxgi_mode_desc_compar(const void *l, const void *r)
> +{
> +    const DXGI_MODE_DESC *left = l, *right = r;
> +
> +    if (left->Width < right->Width)
> +        return -1;
> +
> +    if (left->Width > right->Width)
> +        return 1;
> +
> +    if (left->Height < right->Height)
> +        return -1;
> +
> +    if (left->Height > right->Height)
> +        return 1;
> +
> +    if (left->RefreshRate.Numerator * right->RefreshRate.Denominator <
> +            right->RefreshRate.Numerator * left->RefreshRate.Denominator)
> +        return -1;
> +
> +    if (left->RefreshRate.Numerator * right->RefreshRate.Denominator >
> +            right->RefreshRate.Numerator * left->RefreshRate.Denominator)
> +        return 1;
> +
> +    return 0;
> +}
> +
> +static int dxgi_mode_desc1_compar(const void *l, const void *r)
> +{
> +    const DXGI_MODE_DESC1 *left = l, *right = r;
> +
> +    if (left->Width < right->Width)
> +        return -1;
> +
> +    if (left->Width > right->Width)
> +        return 1;
> +
> +    if (left->Height < right->Height)
> +        return -1;
> +
> +    if (left->Height > right->Height)
> +        return 1;
> +
> +    if (left->RefreshRate.Numerator * right->RefreshRate.Denominator <
> +            right->RefreshRate.Numerator * left->RefreshRate.Denominator)
> +        return -1;
> +
> +    if (left->RefreshRate.Numerator * right->RefreshRate.Denominator >
> +            right->RefreshRate.Numerator * left->RefreshRate.Denominator)
> +        return 1;
> +
> +    return 0;
> +}
> +
>  enum dxgi_mode_struct_version
>  {
>      DXGI_MODE_STRUCT_VERSION_0,
> @@ -151,6 +205,16 @@ static HRESULT dxgi_output_get_display_mode_list(struct dxgi_output *output,
>      }
>      wined3d_mutex_unlock();
>  
> +    switch (struct_version)
> +    {
> +        case DXGI_MODE_STRUCT_VERSION_0:
> +            qsort(modes, *mode_count, sizeof(DXGI_MODE_DESC), dxgi_mode_desc_compar);
> +            break;
> +        case DXGI_MODE_STRUCT_VERSION_1:
> +            qsort(modes, *mode_count, sizeof(DXGI_MODE_DESC1), dxgi_mode_desc1_compar);
> +            break;
> +    }
> +
>      return S_OK;
>  }
>  
> diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c
> index a7517c8b0ab..be18943748c 100644
> --- a/dlls/dxgi/tests/dxgi.c
> +++ b/dlls/dxgi/tests/dxgi.c
> @@ -1158,7 +1158,8 @@ static void test_output(void)
>      HRESULT hr;
>      IDXGIOutput *output;
>      ULONG refcount;
> -    UINT mode_count, mode_count_comp, i;
> +    UINT mode_count, mode_count_comp, i, last_height, last_width;
> +    double last_refresh_rate;
>      DXGI_MODE_DESC *modes;
>  
>      if (!(device = create_device(0)))
> @@ -1227,9 +1228,38 @@ static void test_output(void)
>      ok(SUCCEEDED(hr), "Failed to list modes, hr %#x.\n", hr);
>      ok(mode_count == mode_count_comp, "Got unexpected mode_count %u, expected %u.\n", mode_count, mode_count_comp);
>  
> +    last_width = last_height = 0;
> +    last_refresh_rate = 0.;
>      for (i = 0; i < mode_count; i++)
>      {
>          ok(modes[i].Height && modes[i].Width, "Proper mode was expected\n");
> +
> +        ok(modes[i].Width >= last_width,
> +                "Modes should have been sorted, mode %u width %u < %u\n", i, modes[i].Width, last_width);
> +        if (modes[i].Width == last_width)
> +        {
> +            ok(modes[i].Height >= last_height,
> +                    "Modes should have been sorted, mode %u height %u < %u\n", i, modes[i].Height, last_height);
> +            if (modes[i].Height == last_height)
> +            {
> +                double refresh_rate = modes[i].RefreshRate.Numerator / (double)modes[i].RefreshRate.Denominator;
> +                ok(refresh_rate >= last_refresh_rate,
> +                        "Modes should have been sorted, mode %u refresh rate %f < %f\n", i, refresh_rate, last_refresh_rate);
> +                if (refresh_rate != last_refresh_rate)
> +                    last_refresh_rate = refresh_rate;
> +            }
> +            else
> +            {
> +                last_height = modes[i].Height;
> +                last_refresh_rate = 0.;
> +            }
> +        }
> +        else
> +        {
> +            last_width = modes[i].Width;
> +            last_height = 0;
> +            last_refresh_rate = 0.;
> +        }
>      }
>  
>      mode_count += 5;
> -- 
> 2.23.0
> 
> 



More information about the wine-devel mailing list