[PATCH] dxgi: Sort reported output modes
Andrew Eikum
aeikum at codeweavers.com
Wed Oct 23 15:32:25 CDT 2019
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