tests: Add test for executing command lists from multiple threads.

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 2018-01-15 13:49:06 +01:00 committed by Alexandre Julliard
parent d18e986b27
commit 8357908bc2

View File

@ -16983,6 +16983,103 @@ static void test_face_culling(void)
destroy_test_context(&context); destroy_test_context(&context);
} }
static void draw_thread_main(void *thread_data)
{
static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
struct test_context *context = thread_data;
ID3D12GraphicsCommandList *command_list;
ID3D12CommandAllocator *allocator;
D3D12_CPU_DESCRIPTOR_HANDLE rtv;
ID3D12Resource *render_target;
ID3D12DescriptorHeap *heap;
ID3D12CommandQueue *queue;
ID3D12Device *device;
unsigned int i;
HRESULT hr;
queue = context->queue;
device = context->device;
heap = create_cpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_RTV, 1);
rtv = get_cpu_descriptor_handle(context, heap, 0);
create_render_target(context, NULL, &render_target, &rtv);
hr = ID3D12Device_CreateCommandAllocator(device, D3D12_COMMAND_LIST_TYPE_DIRECT,
&IID_ID3D12CommandAllocator, (void **)&allocator);
ok(SUCCEEDED(hr), "Failed to create command allocator, hr %#x.\n", hr);
hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT,
allocator, NULL, &IID_ID3D12GraphicsCommandList, (void **)&command_list);
ok(SUCCEEDED(hr), "Failed to create command list, hr %#x.\n", hr);
for (i = 0; i < 100; ++i)
{
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtv, white, 0, NULL);
ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &rtv, FALSE, NULL);
ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context->root_signature);
ID3D12GraphicsCommandList_SetPipelineState(command_list, context->pipeline_state);
ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context->viewport);
ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context->scissor_rect);
ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
transition_resource_state(command_list, render_target,
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
check_sub_resource_uint(render_target, 0, queue, command_list, 0xff00ff00, 0);
reset_command_list(command_list, allocator);
transition_resource_state(command_list, render_target,
D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
}
ID3D12DescriptorHeap_Release(heap);
ID3D12Resource_Release(render_target);
ID3D12CommandAllocator_Release(allocator);
ID3D12GraphicsCommandList_Release(command_list);
}
static void test_multithread_command_queue_exec(void)
{
static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
ID3D12GraphicsCommandList *command_list;
struct test_context context;
ID3D12CommandQueue *queue;
HANDLE threads[10];
unsigned int i;
if (!init_test_context(&context, NULL))
return;
command_list = context.list;
queue = context.queue;
for (i = 0; i < ARRAY_SIZE(threads); ++i)
{
threads[i] = create_thread(draw_thread_main, &context);
ok(threads[i], "Failed to create thread %u.\n", i);
}
for (i = 0; i < 100; ++i)
{
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, FALSE, NULL);
ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
transition_resource_state(command_list, context.render_target,
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
reset_command_list(command_list, context.allocator);
transition_resource_state(command_list, context.render_target,
D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
}
for (i = 0; i < ARRAY_SIZE(threads); ++i)
ok(join_thread(threads[i]), "Failed to join thread %u.\n", i);
destroy_test_context(&context);
}
START_TEST(d3d12) START_TEST(d3d12)
{ {
bool enable_debug_layer = false; bool enable_debug_layer = false;
@ -17085,4 +17182,5 @@ START_TEST(d3d12)
run_test(test_copy_texture_region); run_test(test_copy_texture_region);
run_test(test_separate_bindings); run_test(test_separate_bindings);
run_test(test_face_culling); run_test(test_face_culling);
run_test(test_multithread_command_queue_exec);
} }