[PATCH v2] ddraw/tests: Run the tests in parallel.

Henri Verbeet hverbeet at codeweavers.com
Wed Aug 14 08:41:19 CDT 2019


Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
v2: Get rid of a leftover debug line.

This supersedes patch 168626.

 dlls/ddraw/tests/ddraw1.c | 187 +++++++++++++++++++++++++----------
 dlls/ddraw/tests/ddraw2.c | 204 ++++++++++++++++++++++++++------------
 dlls/ddraw/tests/ddraw4.c | 229 +++++++++++++++++++++++++++++--------------
 dlls/ddraw/tests/ddraw7.c | 243 ++++++++++++++++++++++++++++++----------------
 4 files changed, 593 insertions(+), 270 deletions(-)

diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c
index cc228028e17..6f5fc64ca83 100644
--- a/dlls/ddraw/tests/ddraw1.c
+++ b/dlls/ddraw/tests/ddraw1.c
@@ -28,6 +28,13 @@
 
 static BOOL is_ddraw64 = sizeof(DWORD) != sizeof(DWORD *);
 static DEVMODEW registry_mode;
+static BOOL use_mt;
+
+static struct test_entry
+{
+    void (*test)(void);
+} *mt_tests;
+static size_t mt_tests_size, mt_test_count;
 
 static HRESULT (WINAPI *pDwmIsCompositionEnabled)(BOOL *);
 
@@ -49,6 +56,63 @@ struct create_window_thread_param
     HANDLE thread;
 };
 
+static void queue_test(void (*test)(void))
+{
+    if (mt_test_count >= mt_tests_size)
+    {
+        mt_tests_size = max(16, mt_tests_size * 2);
+        mt_tests = heap_realloc(mt_tests, mt_tests_size * sizeof(*mt_tests));
+    }
+    mt_tests[mt_test_count++].test = test;
+}
+
+static DWORD WINAPI thread_func(void *ctx)
+{
+    LONG *i = ctx, j;
+
+    while (*i < mt_test_count)
+    {
+        j = *i;
+        if (InterlockedCompareExchange(i, j + 1, j) == j)
+            mt_tests[j].test();
+    }
+
+    return 0;
+}
+
+static void run_queued_tests(void)
+{
+    unsigned int thread_count, i;
+    HANDLE *threads;
+    SYSTEM_INFO si;
+    LONG test_idx;
+
+    if (!use_mt)
+    {
+        for (i = 0; i < mt_test_count; ++i)
+        {
+            mt_tests[i].test();
+        }
+
+        return;
+    }
+
+    GetSystemInfo(&si);
+    thread_count = si.dwNumberOfProcessors;
+    threads = heap_calloc(thread_count, sizeof(*threads));
+    for (i = 0, test_idx = 0; i < thread_count; ++i)
+    {
+        threads[i] = CreateThread(NULL, 0, thread_func, &test_idx, 0, NULL);
+        ok(!!threads[i], "Failed to create thread %u.\n", i);
+    }
+    WaitForMultipleObjects(thread_count, threads, TRUE, INFINITE);
+    for (i = 0; i < thread_count; ++i)
+    {
+        CloseHandle(threads[i]);
+    }
+    heap_free(threads);
+}
+
 static BOOL compare_color(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
 {
     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
@@ -13069,8 +13133,19 @@ START_TEST(ddraw1)
 {
     DDDEVICEIDENTIFIER identifier;
     DEVMODEW current_mode;
+    unsigned int argc, i;
     IDirectDraw *ddraw;
     HMODULE dwmapi;
+    char **argv;
+
+    use_mt = !getenv("WINETEST_NO_MT_D3D");
+
+    argc = winetest_get_mainargs(&argv);
+    for (i = 2; i < argc; ++i)
+    {
+        if (!strcmp(argv[i], "--single"))
+            use_mt = FALSE;
+    }
 
     if (!(ddraw = create_ddraw()))
     {
@@ -13103,78 +13178,84 @@ START_TEST(ddraw1)
     if ((dwmapi = LoadLibraryA("dwmapi.dll")))
         pDwmIsCompositionEnabled = (void *)GetProcAddress(dwmapi, "DwmIsCompositionEnabled");
 
+    queue_test(test_clipper_blt);
+    queue_test(test_surface_interface_mismatch);
+    queue_test(test_viewport_object);
+    queue_test(test_zenable);
+    queue_test(test_ck_rgba);
+    queue_test(test_ck_default);
+    queue_test(test_surface_qi);
+    queue_test(test_device_qi);
+    queue_test(test_initialize);
+    queue_test(test_coop_level_surf_create);
+    queue_test(test_coop_level_multi_window);
+    queue_test(test_clear_rect_count);
+    queue_test(test_unsupported_formats);
+    queue_test(test_rt_caps);
+    queue_test(test_surface_lock);
+    queue_test(test_surface_discard);
+    queue_test(test_sysmem_overlay);
+    queue_test(test_pixel_format);
+    queue_test(test_create_surface_pitch);
+    queue_test(test_mipmap);
+    queue_test(test_palette_complex);
+    queue_test(test_p8_blit);
+    queue_test(test_material);
+    queue_test(test_lighting);
+    queue_test(test_specular_lighting);
+    queue_test(test_surface_desc_lock);
+    queue_test(test_texturemapblend);
+    queue_test(test_viewport_clear_rect);
+    queue_test(test_color_fill);
+    queue_test(test_range_colorkey);
+    queue_test(test_shademode);
+    queue_test(test_lockrect_invalid);
+    queue_test(test_yv12_overlay);
+    queue_test(test_overlay_rect);
+    queue_test(test_blt);
+    queue_test(test_blt_z_alpha);
+    queue_test(test_getdc);
+    queue_test(test_transform_vertices);
+    queue_test(test_surface_desc_size);
+    queue_test(test_texture_load);
+    queue_test(test_ck_operation);
+    queue_test(test_depth_readback);
+    queue_test(test_clear);
+    queue_test(test_enum_surfaces);
+    queue_test(test_execute_data);
+    queue_test(test_viewport);
+    queue_test(test_find_device);
+    queue_test(test_alphatest);
+    queue_test(test_clipper_refcount);
+    queue_test(test_d32_support);
+
+    run_queued_tests();
+
+    /* These tests don't work reliably when run in parallel. */
+    test_colorkey_precision();
+    test_offscreen_overlay();
+    test_caps();
+    /* These tests use full-screen/exclusive mode, so shouldn't run in
+     * parallel. */
     test_coop_level_create_device_window();
-    test_clipper_blt();
     test_coop_level_d3d_state();
-    test_surface_interface_mismatch();
     test_coop_level_threaded();
-    test_viewport_object();
-    test_zenable();
-    test_ck_rgba();
-    test_ck_default();
     test_ck_complex();
-    test_surface_qi();
-    test_device_qi();
     test_wndproc();
     test_window_style();
     test_redundant_mode_set();
     test_coop_level_mode_set();
     test_coop_level_mode_set_multi();
-    test_initialize();
-    test_coop_level_surf_create();
-    test_coop_level_multi_window();
-    test_clear_rect_count();
     test_coop_level_activateapp();
-    test_unsupported_formats();
-    test_rt_caps();
     test_primary_caps();
-    test_surface_lock();
-    test_surface_discard();
     test_flip();
-    test_sysmem_overlay();
     test_primary_palette();
     test_surface_attachment();
-    test_pixel_format();
-    test_create_surface_pitch();
-    test_mipmap();
-    test_palette_complex();
-    test_p8_blit();
-    test_material();
-    test_lighting();
-    test_specular_lighting();
     test_palette_gdi();
     test_palette_alpha();
     test_lost_device();
-    test_surface_desc_lock();
-    test_texturemapblend();
-    test_viewport_clear_rect();
-    test_color_fill();
-    test_colorkey_precision();
-    test_range_colorkey();
-    test_shademode();
-    test_lockrect_invalid();
-    test_yv12_overlay();
-    test_offscreen_overlay();
-    test_overlay_rect();
-    test_blt();
-    test_blt_z_alpha();
     test_cross_device_blt();
-    test_getdc();
-    test_transform_vertices();
     test_display_mode_surface_pixel_format();
-    test_surface_desc_size();
-    test_texture_load();
-    test_ck_operation();
-    test_depth_readback();
-    test_clear();
-    test_enum_surfaces();
-    test_execute_data();
-    test_viewport();
-    test_find_device();
     test_killfocus();
     test_gdi_surface();
-    test_alphatest();
-    test_clipper_refcount();
-    test_caps();
-    test_d32_support();
 }
diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c
index 595157b486f..bf1c99e501f 100644
--- a/dlls/ddraw/tests/ddraw2.c
+++ b/dlls/ddraw/tests/ddraw2.c
@@ -17,11 +17,10 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
-
-#include <math.h>
-
 #define COBJMACROS
+
 #include "wine/test.h"
+#include "wine/heap.h"
 #include <limits.h>
 #include <math.h>
 #include "ddrawi.h"
@@ -29,6 +28,13 @@
 
 static BOOL is_ddraw64 = sizeof(DWORD) != sizeof(DWORD *);
 static DEVMODEW registry_mode;
+static BOOL use_mt;
+
+static struct test_entry
+{
+    void (*test)(void);
+} *mt_tests;
+static size_t mt_tests_size, mt_test_count;
 
 static HRESULT (WINAPI *pDwmIsCompositionEnabled)(BOOL *);
 
@@ -50,6 +56,63 @@ struct create_window_thread_param
     HANDLE thread;
 };
 
+static void queue_test(void (*test)(void))
+{
+    if (mt_test_count >= mt_tests_size)
+    {
+        mt_tests_size = max(16, mt_tests_size * 2);
+        mt_tests = heap_realloc(mt_tests, mt_tests_size * sizeof(*mt_tests));
+    }
+    mt_tests[mt_test_count++].test = test;
+}
+
+static DWORD WINAPI thread_func(void *ctx)
+{
+    LONG *i = ctx, j;
+
+    while (*i < mt_test_count)
+    {
+        j = *i;
+        if (InterlockedCompareExchange(i, j + 1, j) == j)
+            mt_tests[j].test();
+    }
+
+    return 0;
+}
+
+static void run_queued_tests(void)
+{
+    unsigned int thread_count, i;
+    HANDLE *threads;
+    SYSTEM_INFO si;
+    LONG test_idx;
+
+    if (!use_mt)
+    {
+        for (i = 0; i < mt_test_count; ++i)
+        {
+            mt_tests[i].test();
+        }
+
+        return;
+    }
+
+    GetSystemInfo(&si);
+    thread_count = si.dwNumberOfProcessors;
+    threads = heap_calloc(thread_count, sizeof(*threads));
+    for (i = 0, test_idx = 0; i < thread_count; ++i)
+    {
+        threads[i] = CreateThread(NULL, 0, thread_func, &test_idx, 0, NULL);
+        ok(!!threads[i], "Failed to create thread %u.\n", i);
+    }
+    WaitForMultipleObjects(thread_count, threads, TRUE, INFINITE);
+    for (i = 0; i < thread_count; ++i)
+    {
+        CloseHandle(threads[i]);
+    }
+    heap_free(threads);
+}
+
 static BOOL compare_color(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
 {
     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
@@ -13953,8 +14016,19 @@ START_TEST(ddraw2)
 {
     DDDEVICEIDENTIFIER identifier;
     DEVMODEW current_mode;
+    unsigned int argc, i;
     IDirectDraw2 *ddraw;
     HMODULE dwmapi;
+    char **argv;
+
+    use_mt = !getenv("WINETEST_NO_MT_D3D");
+
+    argc = winetest_get_mainargs(&argv);
+    for (i = 2; i < argc; ++i)
+    {
+        if (!strcmp(argv[i], "--single"))
+            use_mt = FALSE;
+    }
 
     if (!(ddraw = create_ddraw()))
     {
@@ -13987,85 +14061,91 @@ START_TEST(ddraw2)
     if ((dwmapi = LoadLibraryA("dwmapi.dll")))
         pDwmIsCompositionEnabled = (void *)GetProcAddress(dwmapi, "DwmIsCompositionEnabled");
 
+    queue_test(test_clipper_blt);
+    queue_test(test_surface_interface_mismatch);
+    queue_test(test_depth_blit);
+    queue_test(test_texture_load_ckey);
+    queue_test(test_viewport_object);
+    queue_test(test_zenable);
+    queue_test(test_ck_rgba);
+    queue_test(test_ck_default);
+    queue_test(test_surface_qi);
+    queue_test(test_device_qi);
+    queue_test(test_initialize);
+    queue_test(test_coop_level_surf_create);
+    queue_test(test_coop_level_multi_window);
+    queue_test(test_clear_rect_count);
+    queue_test(test_lighting_interface_versions);
+    queue_test(test_unsupported_formats);
+    queue_test(test_rt_caps);
+    queue_test(test_surface_lock);
+    queue_test(test_surface_discard);
+    queue_test(test_set_surface_desc);
+    queue_test(test_user_memory_getdc);
+    queue_test(test_sysmem_overlay);
+    queue_test(test_pixel_format);
+    queue_test(test_create_surface_pitch);
+    queue_test(test_mipmap);
+    queue_test(test_palette_complex);
+    queue_test(test_p8_blit);
+    queue_test(test_material);
+    queue_test(test_lighting);
+    queue_test(test_specular_lighting);
+    queue_test(test_surface_desc_lock);
+    queue_test(test_texturemapblend);
+    queue_test(test_viewport_clear_rect);
+    queue_test(test_color_fill);
+    queue_test(test_range_colorkey);
+    queue_test(test_shademode);
+    queue_test(test_lockrect_invalid);
+    queue_test(test_yv12_overlay);
+    queue_test(test_overlay_rect);
+    queue_test(test_blt);
+    queue_test(test_blt_z_alpha);
+    queue_test(test_getdc);
+    queue_test(test_draw_primitive);
+    queue_test(test_edge_antialiasing_blending);
+    queue_test(test_transform_vertices);
+    queue_test(test_surface_desc_size);
+    queue_test(test_ck_operation);
+    queue_test(test_set_render_state);
+    queue_test(test_depth_readback);
+    queue_test(test_clear);
+    queue_test(test_enum_surfaces);
+    queue_test(test_viewport);
+    queue_test(test_find_device);
+    queue_test(test_alphatest);
+    queue_test(test_clipper_refcount);
+    queue_test(test_d32_support);
+
+    run_queued_tests();
+
+    /* These tests don't work reliably when run in parallel. */
+    test_colorkey_precision();
+    test_offscreen_overlay();
+    test_caps();
+    /* These tests use full-screen/exclusive mode, so shouldn't run in
+     * parallel. */
     test_coop_level_create_device_window();
-    test_clipper_blt();
     test_coop_level_d3d_state();
-    test_surface_interface_mismatch();
     test_coop_level_threaded();
-    test_depth_blit();
-    test_texture_load_ckey();
-    test_viewport_object();
-    test_zenable();
-    test_ck_rgba();
-    test_ck_default();
     test_ck_complex();
-    test_surface_qi();
-    test_device_qi();
     test_wndproc();
     test_window_style();
     test_redundant_mode_set();
     test_coop_level_mode_set();
     test_coop_level_mode_set_multi();
-    test_initialize();
-    test_coop_level_surf_create();
-    test_coop_level_multi_window();
-    test_clear_rect_count();
     test_coop_level_versions();
-    test_lighting_interface_versions();
     test_coop_level_activateapp();
-    test_unsupported_formats();
-    test_rt_caps();
     test_primary_caps();
-    test_surface_lock();
-    test_surface_discard();
     test_flip();
-    test_set_surface_desc();
-    test_user_memory_getdc();
-    test_sysmem_overlay();
     test_primary_palette();
     test_surface_attachment();
-    test_pixel_format();
-    test_create_surface_pitch();
-    test_mipmap();
-    test_palette_complex();
-    test_p8_blit();
-    test_material();
-    test_lighting();
-    test_specular_lighting();
     test_palette_gdi();
     test_palette_alpha();
     test_lost_device();
-    test_surface_desc_lock();
-    test_texturemapblend();
-    test_viewport_clear_rect();
-    test_color_fill();
-    test_colorkey_precision();
-    test_range_colorkey();
-    test_shademode();
-    test_lockrect_invalid();
-    test_yv12_overlay();
-    test_offscreen_overlay();
-    test_overlay_rect();
-    test_blt();
-    test_blt_z_alpha();
     test_cross_device_blt();
-    test_getdc();
-    test_draw_primitive();
-    test_edge_antialiasing_blending();
-    test_transform_vertices();
     test_display_mode_surface_pixel_format();
-    test_surface_desc_size();
-    test_ck_operation();
-    test_set_render_state();
-    test_depth_readback();
-    test_clear();
-    test_enum_surfaces();
-    test_viewport();
-    test_find_device();
     test_killfocus();
     test_gdi_surface();
-    test_alphatest();
-    test_clipper_refcount();
-    test_caps();
-    test_d32_support();
 }
diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c
index 567a8f38c01..4cb67421722 100644
--- a/dlls/ddraw/tests/ddraw4.c
+++ b/dlls/ddraw/tests/ddraw4.c
@@ -30,6 +30,13 @@ HRESULT WINAPI GetSurfaceFromDC(HDC dc, struct IDirectDrawSurface **surface, HDC
 
 static BOOL is_ddraw64 = sizeof(DWORD) != sizeof(DWORD *);
 static DEVMODEW registry_mode;
+static BOOL use_mt;
+
+static struct test_entry
+{
+    void (*test)(void);
+} *mt_tests;
+static size_t mt_tests_size, mt_test_count;
 
 static HRESULT (WINAPI *pDwmIsCompositionEnabled)(BOOL *);
 
@@ -56,6 +63,63 @@ struct create_window_thread_param
     HANDLE thread;
 };
 
+static void queue_test(void (*test)(void))
+{
+    if (mt_test_count >= mt_tests_size)
+    {
+        mt_tests_size = max(16, mt_tests_size * 2);
+        mt_tests = heap_realloc(mt_tests, mt_tests_size * sizeof(*mt_tests));
+    }
+    mt_tests[mt_test_count++].test = test;
+}
+
+static DWORD WINAPI thread_func(void *ctx)
+{
+    LONG *i = ctx, j;
+
+    while (*i < mt_test_count)
+    {
+        j = *i;
+        if (InterlockedCompareExchange(i, j + 1, j) == j)
+            mt_tests[j].test();
+    }
+
+    return 0;
+}
+
+static void run_queued_tests(void)
+{
+    unsigned int thread_count, i;
+    HANDLE *threads;
+    SYSTEM_INFO si;
+    LONG test_idx;
+
+    if (!use_mt)
+    {
+        for (i = 0; i < mt_test_count; ++i)
+        {
+            mt_tests[i].test();
+        }
+
+        return;
+    }
+
+    GetSystemInfo(&si);
+    thread_count = si.dwNumberOfProcessors;
+    threads = heap_calloc(thread_count, sizeof(*threads));
+    for (i = 0, test_idx = 0; i < thread_count; ++i)
+    {
+        threads[i] = CreateThread(NULL, 0, thread_func, &test_idx, 0, NULL);
+        ok(!!threads[i], "Failed to create thread %u.\n", i);
+    }
+    WaitForMultipleObjects(thread_count, threads, TRUE, INFINITE);
+    for (i = 0; i < thread_count; ++i)
+    {
+        CloseHandle(threads[i]);
+    }
+    heap_free(threads);
+}
+
 static BOOL compare_float(float f, float g, unsigned int ulps)
 {
     int x = *(int *)&f;
@@ -16508,8 +16572,19 @@ START_TEST(ddraw4)
 {
     DDDEVICEIDENTIFIER identifier;
     DEVMODEW current_mode;
+    unsigned int argc, i;
     IDirectDraw4 *ddraw;
     HMODULE dwmapi;
+    char **argv;
+
+    use_mt = !getenv("WINETEST_NO_MT_D3D");
+
+    argc = winetest_get_mainargs(&argv);
+    for (i = 2; i < argc; ++i)
+    {
+        if (!strcmp(argv[i], "--single"))
+            use_mt = FALSE;
+    }
 
     if (!(ddraw = create_ddraw()))
     {
@@ -16542,100 +16617,106 @@ START_TEST(ddraw4)
     if ((dwmapi = LoadLibraryA("dwmapi.dll")))
         pDwmIsCompositionEnabled = (void *)GetProcAddress(dwmapi, "DwmIsCompositionEnabled");
 
-    test_process_vertices();
+    queue_test(test_process_vertices);
+    queue_test(test_clipper_blt);
+    queue_test(test_surface_interface_mismatch);
+    queue_test(test_depth_blit);
+    queue_test(test_texture_load_ckey);
+    queue_test(test_viewport_object);
+    queue_test(test_zenable);
+    queue_test(test_ck_rgba);
+    queue_test(test_ck_default);
+    queue_test(test_surface_qi);
+    queue_test(test_device_qi);
+    queue_test(test_initialize);
+    queue_test(test_coop_level_surf_create);
+    queue_test(test_vb_discard);
+    queue_test(test_coop_level_multi_window);
+    queue_test(test_draw_strided);
+    queue_test(test_lighting);
+    queue_test(test_specular_lighting);
+    queue_test(test_clear_rect_count);
+    queue_test(test_lighting_interface_versions);
+    queue_test(test_texturemanage);
+    queue_test(test_block_formats_creation);
+    queue_test(test_unsupported_formats);
+    queue_test(test_rt_caps);
+    queue_test(test_surface_lock);
+    queue_test(test_surface_discard);
+    queue_test(test_set_surface_desc);
+    queue_test(test_user_memory_getdc);
+    queue_test(test_sysmem_overlay);
+    queue_test(test_private_data);
+    queue_test(test_pixel_format);
+    queue_test(test_create_surface_pitch);
+    queue_test(test_mipmap);
+    queue_test(test_palette_complex);
+    queue_test(test_p8_blit);
+    queue_test(test_material);
+    queue_test(test_vb_writeonly);
+    queue_test(test_surface_desc_lock);
+    queue_test(test_texturemapblend);
+    queue_test(test_signed_formats);
+    queue_test(test_color_fill);
+    queue_test(test_texcoordindex);
+    queue_test(test_range_colorkey);
+    queue_test(test_shademode);
+    queue_test(test_lockrect_invalid);
+    queue_test(test_yv12_overlay);
+    queue_test(test_overlay_rect);
+    queue_test(test_blt);
+    queue_test(test_blt_z_alpha);
+    queue_test(test_color_clamping);
+    queue_test(test_getdc);
+    queue_test(test_draw_primitive);
+    queue_test(test_edge_antialiasing_blending);
+    queue_test(test_transform_vertices);
+    queue_test(test_surface_desc_size);
+    queue_test(test_get_surface_from_dc);
+    queue_test(test_ck_operation);
+    queue_test(test_vb_refcount);
+    queue_test(test_compute_sphere_visibility);
+    queue_test(test_texture_stages_limits);
+    queue_test(test_set_render_state);
+    queue_test(test_depth_readback);
+    queue_test(test_clear);
+    queue_test(test_enum_surfaces);
+    queue_test(test_viewport);
+    queue_test(test_find_device);
+    queue_test(test_sysmem_draw);
+    queue_test(test_alphatest);
+    queue_test(test_clipper_refcount);
+    queue_test(test_d32_support);
+
+    run_queued_tests();
+
+    /* These tests don't work reliably when run in parallel. */
+    test_colorkey_precision();
+    test_offscreen_overlay();
+    test_map_synchronisation();
+    test_caps();
+    /* These tests use full-screen/exclusive mode, so shouldn't run in
+     * parallel. */
     test_coop_level_create_device_window();
-    test_clipper_blt();
     test_coop_level_d3d_state();
-    test_surface_interface_mismatch();
     test_coop_level_threaded();
-    test_depth_blit();
-    test_texture_load_ckey();
-    test_viewport_object();
-    test_zenable();
-    test_ck_rgba();
-    test_ck_default();
     test_ck_complex();
-    test_surface_qi();
-    test_device_qi();
     test_wndproc();
     test_window_style();
     test_redundant_mode_set();
     test_coop_level_mode_set();
     test_coop_level_mode_set_multi();
-    test_initialize();
-    test_coop_level_surf_create();
-    test_vb_discard();
-    test_coop_level_multi_window();
-    test_draw_strided();
-    test_lighting();
-    test_specular_lighting();
-    test_clear_rect_count();
     test_coop_level_versions();
-    test_lighting_interface_versions();
     test_coop_level_activateapp();
-    test_texturemanage();
-    test_block_formats_creation();
-    test_unsupported_formats();
-    test_rt_caps();
     test_primary_caps();
-    test_surface_lock();
-    test_surface_discard();
     test_flip();
-    test_set_surface_desc();
-    test_user_memory_getdc();
-    test_sysmem_overlay();
     test_primary_palette();
     test_surface_attachment();
-    test_private_data();
-    test_pixel_format();
-    test_create_surface_pitch();
-    test_mipmap();
-    test_palette_complex();
-    test_p8_blit();
-    test_material();
     test_palette_gdi();
     test_palette_alpha();
-    test_vb_writeonly();
     test_lost_device();
-    test_surface_desc_lock();
-    test_texturemapblend();
-    test_signed_formats();
-    test_color_fill();
-    test_texcoordindex();
-    test_colorkey_precision();
-    test_range_colorkey();
-    test_shademode();
-    test_lockrect_invalid();
-    test_yv12_overlay();
-    test_offscreen_overlay();
-    test_overlay_rect();
-    test_blt();
-    test_blt_z_alpha();
     test_cross_device_blt();
-    test_color_clamping();
-    test_getdc();
-    test_draw_primitive();
-    test_edge_antialiasing_blending();
-    test_transform_vertices();
     test_display_mode_surface_pixel_format();
-    test_surface_desc_size();
-    test_get_surface_from_dc();
-    test_ck_operation();
-    test_vb_refcount();
-    test_compute_sphere_visibility();
-    test_texture_stages_limits();
-    test_set_render_state();
-    test_map_synchronisation();
-    test_depth_readback();
-    test_clear();
-    test_enum_surfaces();
-    test_viewport();
-    test_find_device();
     test_killfocus();
-    test_sysmem_draw();
     test_gdi_surface();
-    test_alphatest();
-    test_clipper_refcount();
-    test_caps();
-    test_d32_support();
 }
diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c
index 116e34a1768..b5601bcc118 100644
--- a/dlls/ddraw/tests/ddraw7.c
+++ b/dlls/ddraw/tests/ddraw7.c
@@ -30,6 +30,13 @@ HRESULT WINAPI GetSurfaceFromDC(HDC dc, struct IDirectDrawSurface **surface, HDC
 static HRESULT (WINAPI *pDirectDrawCreateEx)(GUID *guid, void **ddraw, REFIID iid, IUnknown *outer_unknown);
 static BOOL is_ddraw64 = sizeof(DWORD) != sizeof(DWORD *);
 static DEVMODEW registry_mode;
+static BOOL use_mt;
+
+static struct test_entry
+{
+    void (*test)(void);
+} *mt_tests;
+static size_t mt_tests_size, mt_test_count;
 
 static HRESULT (WINAPI *pDwmIsCompositionEnabled)(BOOL *);
 
@@ -56,6 +63,63 @@ struct create_window_thread_param
     HANDLE thread;
 };
 
+static void queue_test(void (*test)(void))
+{
+    if (mt_test_count >= mt_tests_size)
+    {
+        mt_tests_size = max(16, mt_tests_size * 2);
+        mt_tests = heap_realloc(mt_tests, mt_tests_size * sizeof(*mt_tests));
+    }
+    mt_tests[mt_test_count++].test = test;
+}
+
+static DWORD WINAPI thread_func(void *ctx)
+{
+    LONG *i = ctx, j;
+
+    while (*i < mt_test_count)
+    {
+        j = *i;
+        if (InterlockedCompareExchange(i, j + 1, j) == j)
+            mt_tests[j].test();
+    }
+
+    return 0;
+}
+
+static void run_queued_tests(void)
+{
+    unsigned int thread_count, i;
+    HANDLE *threads;
+    SYSTEM_INFO si;
+    LONG test_idx;
+
+    if (!use_mt)
+    {
+        for (i = 0; i < mt_test_count; ++i)
+        {
+            mt_tests[i].test();
+        }
+
+        return;
+    }
+
+    GetSystemInfo(&si);
+    thread_count = si.dwNumberOfProcessors;
+    threads = heap_calloc(thread_count, sizeof(*threads));
+    for (i = 0, test_idx = 0; i < thread_count; ++i)
+    {
+        threads[i] = CreateThread(NULL, 0, thread_func, &test_idx, 0, NULL);
+        ok(!!threads[i], "Failed to create thread %u.\n", i);
+    }
+    WaitForMultipleObjects(thread_count, threads, TRUE, INFINITE);
+    for (i = 0; i < thread_count; ++i)
+    {
+        CloseHandle(threads[i]);
+    }
+    heap_free(threads);
+}
+
 static BOOL compare_float(float f, float g, unsigned int ulps)
 {
     int x = *(int *)&f;
@@ -16480,7 +16544,18 @@ START_TEST(ddraw7)
     DDDEVICEIDENTIFIER2 identifier;
     HMODULE module, dwmapi;
     DEVMODEW current_mode;
+    unsigned int argc, i;
     IDirectDraw7 *ddraw;
+    char **argv;
+
+    use_mt = !getenv("WINETEST_NO_MT_D3D");
+
+    argc = winetest_get_mainargs(&argv);
+    for (i = 2; i < argc; ++i)
+    {
+        if (!strcmp(argv[i], "--single"))
+            use_mt = FALSE;
+    }
 
     module = GetModuleHandleA("ddraw.dll");
     if (!(pDirectDrawCreateEx = (void *)GetProcAddress(module, "DirectDrawCreateEx")))
@@ -16520,107 +16595,113 @@ START_TEST(ddraw7)
     if ((dwmapi = LoadLibraryA("dwmapi.dll")))
         pDwmIsCompositionEnabled = (void *)GetProcAddress(dwmapi, "DwmIsCompositionEnabled");
 
-    test_process_vertices();
+    queue_test(test_process_vertices);
+    queue_test(test_clipper_blt);
+    queue_test(test_surface_interface_mismatch);
+    queue_test(test_depth_blit);
+    queue_test(test_texture_load_ckey);
+    queue_test(test_zenable);
+    queue_test(test_ck_rgba);
+    queue_test(test_ck_default);
+    queue_test(test_surface_qi);
+    queue_test(test_device_qi);
+    queue_test(test_initialize);
+    queue_test(test_coop_level_surf_create);
+    queue_test(test_vb_discard);
+    queue_test(test_coop_level_multi_window);
+    queue_test(test_draw_strided);
+    queue_test(test_lighting);
+    queue_test(test_specular_lighting);
+    queue_test(test_clear_rect_count);
+    queue_test(test_fog_special);
+    queue_test(test_lighting_interface_versions);
+    queue_test(test_texturemanage);
+    queue_test(test_block_formats_creation);
+    queue_test(test_unsupported_formats);
+    queue_test(test_rt_caps);
+    queue_test(test_surface_lock);
+    queue_test(test_surface_discard);
+    queue_test(test_set_surface_desc);
+    queue_test(test_user_memory_getdc);
+    queue_test(test_sysmem_overlay);
+    queue_test(test_private_data);
+    queue_test(test_pixel_format);
+    queue_test(test_create_surface_pitch);
+    queue_test(test_mipmap);
+    queue_test(test_palette_complex);
+    queue_test(test_p8_blit);
+    queue_test(test_material);
+    queue_test(test_vb_writeonly);
+    queue_test(test_resource_priority);
+    queue_test(test_surface_desc_lock);
+    queue_test(test_fog_interpolation);
+    queue_test(test_fog_process_vertices);
+    queue_test(test_negative_fixedfunction_fog);
+    queue_test(test_table_fog_zw);
+    queue_test(test_signed_formats);
+    queue_test(test_color_fill);
+    queue_test(test_texcoordindex);
+    queue_test(test_range_colorkey);
+    queue_test(test_shademode);
+    queue_test(test_lockrect_invalid);
+    queue_test(test_yv12_overlay);
+    queue_test(test_overlay_rect);
+    queue_test(test_blt);
+    queue_test(test_blt_z_alpha);
+    queue_test(test_color_clamping);
+    queue_test(test_getdc);
+    queue_test(test_draw_primitive);
+    queue_test(test_edge_antialiasing_blending);
+    queue_test(test_surface_desc_size);
+    queue_test(test_get_surface_from_dc);
+    queue_test(test_ck_operation);
+    queue_test(test_vb_refcount);
+    queue_test(test_compute_sphere_visibility);
+    queue_test(test_clip_planes_limits);
+    queue_test(test_texture_stages_limits);
+    queue_test(test_set_render_state);
+    queue_test(test_depth_readback);
+    queue_test(test_clear);
+    queue_test(test_enum_surfaces);
+    queue_test(test_viewport);
+    queue_test(test_device_load);
+    queue_test(test_color_vertex);
+    queue_test(test_sysmem_draw);
+    queue_test(test_multiply_transform);
+    queue_test(test_alphatest);
+    queue_test(test_clipper_refcount);
+    queue_test(test_begin_end_state_block);
+    queue_test(test_d32_support);
+
+    run_queued_tests();
+
+    /* These tests don't work reliably when run in parallel. */
+    test_colorkey_precision();
+    test_offscreen_overlay();
+    test_map_synchronisation();
+    test_caps();
+    /* These tests use full-screen/exclusive mode, so shouldn't run in
+     * parallel. */
     test_coop_level_create_device_window();
-    test_clipper_blt();
     test_coop_level_d3d_state();
-    test_surface_interface_mismatch();
     test_coop_level_threaded();
-    test_depth_blit();
-    test_texture_load_ckey();
-    test_zenable();
-    test_ck_rgba();
-    test_ck_default();
     test_ck_complex();
-    test_surface_qi();
-    test_device_qi();
     test_wndproc();
     test_window_style();
     test_redundant_mode_set();
     test_coop_level_mode_set();
     test_coop_level_mode_set_multi();
-    test_initialize();
-    test_coop_level_surf_create();
-    test_vb_discard();
-    test_coop_level_multi_window();
-    test_draw_strided();
-    test_lighting();
-    test_specular_lighting();
-    test_clear_rect_count();
     test_coop_level_versions();
-    test_fog_special();
-    test_lighting_interface_versions();
     test_coop_level_activateapp();
-    test_texturemanage();
-    test_block_formats_creation();
-    test_unsupported_formats();
-    test_rt_caps();
     test_primary_caps();
-    test_surface_lock();
-    test_surface_discard();
     test_flip();
-    test_set_surface_desc();
-    test_user_memory_getdc();
-    test_sysmem_overlay();
     test_primary_palette();
     test_surface_attachment();
-    test_private_data();
-    test_pixel_format();
-    test_create_surface_pitch();
-    test_mipmap();
-    test_palette_complex();
-    test_p8_blit();
-    test_material();
     test_palette_gdi();
     test_palette_alpha();
-    test_vb_writeonly();
     test_lost_device();
-    test_resource_priority();
-    test_surface_desc_lock();
-    test_fog_interpolation();
-    test_fog_process_vertices();
-    test_negative_fixedfunction_fog();
-    test_table_fog_zw();
-    test_signed_formats();
-    test_color_fill();
-    test_texcoordindex();
-    test_colorkey_precision();
-    test_range_colorkey();
-    test_shademode();
-    test_lockrect_invalid();
-    test_yv12_overlay();
-    test_offscreen_overlay();
-    test_overlay_rect();
-    test_blt();
-    test_blt_z_alpha();
     test_cross_device_blt();
-    test_color_clamping();
-    test_getdc();
-    test_draw_primitive();
-    test_edge_antialiasing_blending();
     test_display_mode_surface_pixel_format();
-    test_surface_desc_size();
-    test_get_surface_from_dc();
-    test_ck_operation();
-    test_vb_refcount();
-    test_compute_sphere_visibility();
-    test_clip_planes_limits();
-    test_texture_stages_limits();
-    test_set_render_state();
-    test_map_synchronisation();
-    test_depth_readback();
-    test_clear();
-    test_enum_surfaces();
-    test_viewport();
-    test_device_load();
-    test_color_vertex();
     test_killfocus();
-    test_sysmem_draw();
     test_gdi_surface();
-    test_multiply_transform();
-    test_alphatest();
-    test_clipper_refcount();
-    test_begin_end_state_block();
-    test_caps();
-    test_d32_support();
 }
-- 
2.11.0




More information about the wine-devel mailing list