[PATCH 5/5] d3d11/tests: Run the tests in parallel.

Henri Verbeet hverbeet at codeweavers.com
Wed Aug 15 04:56:25 CDT 2018


It's hard enough for a single CPU core to keep a modern GPU busy in the
optimal case, but with typical batch sizes of 4 vertices and trivial shaders,
our tests are extremely CPU bound. With 8+-core CPU's being generally
available, there's a lot to be gained. Generally speaking, not all tests can
be run in parallel; tests that touch global state, like e.g. the display mode,
can't. Fortunately, none of the d3d11 tests currently do that.

Unfortunately, this currently doesn't help quite as much on Wine as it does on
Windows. The big wined3d lock prevents a lot of parallelism, even though the
tests use separate Direct3D devices. In the specific case of these tests,
simply disabling the lock is safe, and shows how much could be gained by
simply pushing the lock down a layer to the device.

Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
 dlls/d3d11/tests/d3d11.c | 369 ++++++++++++++++++++++++++++++-----------------
 1 file changed, 234 insertions(+), 135 deletions(-)

diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c
index 5e324b18ba6..2d62342fa98 100644
--- a/dlls/d3d11/tests/d3d11.c
+++ b/dlls/d3d11/tests/d3d11.c
@@ -37,6 +37,21 @@
 
 #define SWAPCHAIN_FLAG_SHADER_INPUT             0x1
 
+static unsigned int use_adapter_idx;
+static BOOL use_warp_adapter;
+static BOOL use_mt = TRUE;
+
+static struct test_entry
+{
+    union
+    {
+        void (*test)(void);
+        void (*test_fl)(D3D_FEATURE_LEVEL fl);
+    } u;
+    D3D_FEATURE_LEVEL fl;
+} *mt_tests;
+size_t mt_tests_size, mt_test_count;
+
 struct format_support
 {
     DXGI_FORMAT format;
@@ -95,6 +110,89 @@ struct swapchain_desc
     DWORD flags;
 };
 
+static void queue_test_entry(const struct test_entry *t)
+{
+    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(*t));
+    }
+    mt_tests[mt_test_count++] = *t;
+}
+
+static void queue_test_fl(void (*test)(const D3D_FEATURE_LEVEL fl), D3D_FEATURE_LEVEL fl)
+{
+    struct test_entry t;
+
+    t.u.test_fl = test;
+    t.fl = fl;
+    queue_test_entry(&t);
+}
+
+static void queue_test(void (*test)(void))
+{
+    struct test_entry t;
+
+    t.u.test = test;
+    t.fl = 0;
+    queue_test_entry(&t);
+}
+
+static void run_mt_test(const struct test_entry *t)
+{
+    if (t->fl)
+        t->u.test_fl(t->fl);
+    else
+        t->u.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)
+            run_mt_test(&mt_tests[j]);
+    }
+
+    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)
+        {
+            run_mt_test(&mt_tests[i]);
+        }
+
+        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 void set_box(D3D11_BOX *box, UINT left, UINT top, UINT front, UINT right, UINT bottom, UINT back)
 {
     box->left = left;
@@ -1139,9 +1237,6 @@ static void check_texture_uvec4_(unsigned int line, ID3D11Texture2D *texture,
         check_texture_sub_resource_uvec4_(line, texture, sub_resource_idx, NULL, expected_value);
 }
 
-static BOOL use_warp_adapter;
-static unsigned int use_adapter_idx;
-
 static IDXGIAdapter *create_adapter(void)
 {
     IDXGIFactory4 *factory4;
@@ -17297,7 +17392,7 @@ static void test_fl9_draw(const D3D_FEATURE_LEVEL feature_level)
     release_test_context(&test_context);
 }
 
-static void run_for_each_feature_level_in_range(D3D_FEATURE_LEVEL begin,
+static void queue_for_each_feature_level_in_range(D3D_FEATURE_LEVEL begin,
         D3D_FEATURE_LEVEL end, void (*test_func)(const D3D_FEATURE_LEVEL fl))
 {
     static const D3D_FEATURE_LEVEL feature_levels[] =
@@ -17316,19 +17411,19 @@ static void run_for_each_feature_level_in_range(D3D_FEATURE_LEVEL begin,
     for (i = 0; i < ARRAY_SIZE(feature_levels); ++i)
     {
         if (begin <= feature_levels[i] && feature_levels[i] <= end)
-            test_func(feature_levels[i]);
+            queue_test_fl(test_func, feature_levels[i]);
     }
 }
 
-static void run_for_each_feature_level(void (*test_func)(const D3D_FEATURE_LEVEL fl))
+static void queue_for_each_feature_level(void (*test_func)(const D3D_FEATURE_LEVEL fl))
 {
-    run_for_each_feature_level_in_range(D3D_FEATURE_LEVEL_9_1,
+    queue_for_each_feature_level_in_range(D3D_FEATURE_LEVEL_9_1,
             D3D_FEATURE_LEVEL_11_1, test_func);
 }
 
-static void run_for_each_9_x_feature_level(void (*test_func)(const D3D_FEATURE_LEVEL fl))
+static void queue_for_each_9_x_feature_level(void (*test_func)(const D3D_FEATURE_LEVEL fl))
 {
-    run_for_each_feature_level_in_range(D3D_FEATURE_LEVEL_9_1,
+    queue_for_each_feature_level_in_range(D3D_FEATURE_LEVEL_9_1,
             D3D_FEATURE_LEVEL_9_3, test_func);
 }
 
@@ -27730,135 +27825,139 @@ START_TEST(d3d11)
             use_warp_adapter = TRUE;
         else if (!strcmp(argv[i], "--adapter") && i + 1 < argc)
             use_adapter_idx = atoi(argv[++i]);
+        else if (!strcmp(argv[i], "--single"))
+            use_mt = FALSE;
     }
 
     print_adapter_info();
 
-    test_create_device();
-    run_for_each_feature_level(test_device_interfaces);
-    test_get_immediate_context();
-    test_create_texture1d();
-    test_texture1d_interfaces();
-    test_create_texture2d();
-    test_texture2d_interfaces();
-    test_create_texture3d();
-    test_texture3d_interfaces();
-    test_create_buffer();
-    test_create_depthstencil_view();
-    test_depthstencil_view_interfaces();
-    test_create_rendertarget_view();
-    test_create_shader_resource_view();
-    run_for_each_feature_level(test_create_shader);
-    test_create_sampler_state();
-    test_create_blend_state();
-    test_create_depthstencil_state();
-    test_create_rasterizer_state();
-    test_create_query();
-    test_occlusion_query();
-    test_pipeline_statistics_query();
-    test_timestamp_query();
-    test_device_removed_reason();
-    test_private_data();
-    run_for_each_feature_level(test_state_refcounting);
-    test_device_context_state();
-    test_blend();
-    test_texture1d();
-    test_texture();
-    test_cube_maps();
-    test_depth_stencil_sampling();
-    test_sample_c_lz();
-    test_multiple_render_targets();
-    test_render_target_views();
-    test_layered_rendering();
-    test_scissor();
-    test_clear_state();
-    test_il_append_aligned();
-    test_instance_id();
-    test_fragment_coords();
-    test_update_subresource();
-    test_copy_subresource_region();
-    test_resource_map();
-    run_for_each_feature_level(test_resource_access);
-    test_check_multisample_quality_levels();
-    run_for_each_feature_level(test_swapchain_formats);
-    test_swapchain_views();
-    test_swapchain_flip();
-    test_clear_render_target_view_1d();
-    test_clear_render_target_view_2d();
-    test_clear_render_target_view_3d();
-    test_clear_depth_stencil_view();
-    test_clear_buffer_unordered_access_view();
-    test_initial_depth_stencil_state();
-    test_draw_depth_only();
-    test_draw_uav_only();
-    test_cb_relative_addressing();
-    test_vs_input_relative_addressing();
-    test_getdc();
-    test_shader_stage_input_output_matching();
-    test_shader_interstage_interface();
-    test_sm4_if_instruction();
-    test_sm4_breakc_instruction();
-    test_sm4_continuec_instruction();
-    test_sm4_discard_instruction();
-    test_sm5_swapc_instruction();
-    test_create_input_layout();
-    test_input_assembler();
-    test_null_sampler();
-    test_check_feature_support();
-    test_create_unordered_access_view();
-    test_immediate_constant_buffer();
-    test_fp_specials();
-    test_uint_shader_instructions();
-    test_index_buffer_offset();
-    test_face_culling();
-    test_line_antialiasing_blending();
-    run_for_each_feature_level(test_required_format_support);
-    run_for_each_9_x_feature_level(test_fl9_draw);
-    test_ddy();
-    test_shader_input_registers_limits();
-    test_unbind_shader_resource_view();
-    test_stencil_separate();
-    test_uav_load();
-    test_cs_uav_store();
-    test_uav_store_immediate_constant();
-    test_ps_cs_uav_binding();
-    test_atomic_instructions();
-    test_sm4_ret_instruction();
-    test_primitive_restart();
-    test_resinfo_instruction();
-    test_sm5_bufinfo_instruction();
-    test_sampleinfo_instruction();
-    test_render_target_device_mismatch();
-    test_buffer_srv();
-    run_for_each_feature_level_in_range(D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_11_0,
+    queue_test(test_create_device);
+    queue_for_each_feature_level(test_device_interfaces);
+    queue_test(test_get_immediate_context);
+    queue_test(test_create_texture1d);
+    queue_test(test_texture1d_interfaces);
+    queue_test(test_create_texture2d);
+    queue_test(test_texture2d_interfaces);
+    queue_test(test_create_texture3d);
+    queue_test(test_texture3d_interfaces);
+    queue_test(test_create_buffer);
+    queue_test(test_create_depthstencil_view);
+    queue_test(test_depthstencil_view_interfaces);
+    queue_test(test_create_rendertarget_view);
+    queue_test(test_create_shader_resource_view);
+    queue_for_each_feature_level(test_create_shader);
+    queue_test(test_create_sampler_state);
+    queue_test(test_create_blend_state);
+    queue_test(test_create_depthstencil_state);
+    queue_test(test_create_rasterizer_state);
+    queue_test(test_create_query);
+    queue_test(test_occlusion_query);
+    queue_test(test_pipeline_statistics_query);
+    queue_test(test_timestamp_query);
+    queue_test(test_device_removed_reason);
+    queue_test(test_private_data);
+    queue_for_each_feature_level(test_state_refcounting);
+    queue_test(test_device_context_state);
+    queue_test(test_blend);
+    queue_test(test_texture1d);
+    queue_test(test_texture);
+    queue_test(test_cube_maps);
+    queue_test(test_depth_stencil_sampling);
+    queue_test(test_sample_c_lz);
+    queue_test(test_multiple_render_targets);
+    queue_test(test_render_target_views);
+    queue_test(test_layered_rendering);
+    queue_test(test_scissor);
+    queue_test(test_clear_state);
+    queue_test(test_il_append_aligned);
+    queue_test(test_instance_id);
+    queue_test(test_fragment_coords);
+    queue_test(test_update_subresource);
+    queue_test(test_copy_subresource_region);
+    queue_test(test_resource_map);
+    queue_for_each_feature_level(test_resource_access);
+    queue_test(test_check_multisample_quality_levels);
+    queue_for_each_feature_level(test_swapchain_formats);
+    queue_test(test_swapchain_views);
+    queue_test(test_swapchain_flip);
+    queue_test(test_clear_render_target_view_1d);
+    queue_test(test_clear_render_target_view_2d);
+    queue_test(test_clear_render_target_view_3d);
+    queue_test(test_clear_depth_stencil_view);
+    queue_test(test_clear_buffer_unordered_access_view);
+    queue_test(test_initial_depth_stencil_state);
+    queue_test(test_draw_depth_only);
+    queue_test(test_draw_uav_only);
+    queue_test(test_cb_relative_addressing);
+    queue_test(test_vs_input_relative_addressing);
+    queue_test(test_getdc);
+    queue_test(test_shader_stage_input_output_matching);
+    queue_test(test_shader_interstage_interface);
+    queue_test(test_sm4_if_instruction);
+    queue_test(test_sm4_breakc_instruction);
+    queue_test(test_sm4_continuec_instruction);
+    queue_test(test_sm4_discard_instruction);
+    queue_test(test_sm5_swapc_instruction);
+    queue_test(test_create_input_layout);
+    queue_test(test_input_assembler);
+    queue_test(test_null_sampler);
+    queue_test(test_check_feature_support);
+    queue_test(test_create_unordered_access_view);
+    queue_test(test_immediate_constant_buffer);
+    queue_test(test_fp_specials);
+    queue_test(test_uint_shader_instructions);
+    queue_test(test_index_buffer_offset);
+    queue_test(test_face_culling);
+    queue_test(test_line_antialiasing_blending);
+    queue_for_each_feature_level(test_required_format_support);
+    queue_for_each_9_x_feature_level(test_fl9_draw);
+    queue_test(test_ddy);
+    queue_test(test_shader_input_registers_limits);
+    queue_test(test_unbind_shader_resource_view);
+    queue_test(test_stencil_separate);
+    queue_test(test_uav_load);
+    queue_test(test_cs_uav_store);
+    queue_test(test_uav_store_immediate_constant);
+    queue_test(test_ps_cs_uav_binding);
+    queue_test(test_atomic_instructions);
+    queue_test(test_sm4_ret_instruction);
+    queue_test(test_primitive_restart);
+    queue_test(test_resinfo_instruction);
+    queue_test(test_sm5_bufinfo_instruction);
+    queue_test(test_sampleinfo_instruction);
+    queue_test(test_render_target_device_mismatch);
+    queue_test(test_buffer_srv);
+    queue_for_each_feature_level_in_range(D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_11_0,
             test_unaligned_raw_buffer_access);
-    test_uav_counters();
-    test_dispatch_indirect();
-    test_compute_shader_registers();
-    test_tgsm();
-    test_geometry_shader();
-    test_quad_tessellation();
-    test_stream_output();
-    test_fl10_stream_output_desc();
-    test_stream_output_resume();
-    test_stream_output_components();
-    test_stream_output_vs();
-    test_gather();
-    test_gather_c();
-    test_depth_bias();
-    test_fractional_viewports();
-    run_for_each_feature_level_in_range(D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_11_0, test_negative_viewports);
-    test_early_depth_stencil();
-    test_conservative_depth_output();
-    test_format_compatibility();
-    test_clip_distance();
-    test_combined_clip_and_cull_distances();
-    test_generate_mips();
-    test_alpha_to_coverage();
-    test_unbound_multisample_texture();
-    test_multiple_viewports();
-    test_multisample_resolve();
-    test_sample_shading();
-    test_sample_mask();
-    test_depth_clip();
+    queue_test(test_uav_counters);
+    queue_test(test_dispatch_indirect);
+    queue_test(test_compute_shader_registers);
+    queue_test(test_tgsm);
+    queue_test(test_geometry_shader);
+    queue_test(test_quad_tessellation);
+    queue_test(test_stream_output);
+    queue_test(test_fl10_stream_output_desc);
+    queue_test(test_stream_output_resume);
+    queue_test(test_stream_output_components);
+    queue_test(test_stream_output_vs);
+    queue_test(test_gather);
+    queue_test(test_gather_c);
+    queue_test(test_depth_bias);
+    queue_test(test_fractional_viewports);
+    queue_for_each_feature_level_in_range(D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_11_0, test_negative_viewports);
+    queue_test(test_early_depth_stencil);
+    queue_test(test_conservative_depth_output);
+    queue_test(test_format_compatibility);
+    queue_test(test_clip_distance);
+    queue_test(test_combined_clip_and_cull_distances);
+    queue_test(test_generate_mips);
+    queue_test(test_alpha_to_coverage);
+    queue_test(test_unbound_multisample_texture);
+    queue_test(test_multiple_viewports);
+    queue_test(test_multisample_resolve);
+    queue_test(test_sample_shading);
+    queue_test(test_sample_mask);
+    queue_test(test_depth_clip);
+
+    run_queued_tests();
 }
-- 
2.11.0




More information about the wine-devel mailing list