[PATCH v4 9/9] d3dx10/tests: Add D3DX10CreateThreadPump tests.
Piotr Caban
wine at gitlab.winehq.org
Sun Jun 26 11:09:28 CDT 2022
From: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Piotr Caban <piotr at codeweavers.com>
---
dlls/d3dx10_43/tests/d3dx10.c | 357 ++++++++++++++++++++++++++++++++++
1 file changed, 357 insertions(+)
diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c
index d1c772197b9..f5708e569ed 100644
--- a/dlls/d3dx10_43/tests/d3dx10.c
+++ b/dlls/d3dx10_43/tests/d3dx10.c
@@ -2066,6 +2066,362 @@ static void test_D3DX10CreateAsyncTextureProcessor(void)
ok(!ID3D10Device_Release(device), "Unexpected refcount.\n");
}
+static DWORD main_tid;
+static DWORD io_tid;
+
+struct data_object
+{
+ ID3DX10DataLoader ID3DX10DataLoader_iface;
+ ID3DX10DataProcessor ID3DX10DataProcessor_iface;
+
+ HANDLE load_started;
+ HANDLE load_done;
+ HANDLE decompress_done;
+ HRESULT load_ret;
+
+ DWORD process_tid;
+};
+
+static struct data_object *data_object_from_ID3DX10DataLoader(ID3DX10DataLoader *iface)
+{
+ return CONTAINING_RECORD(iface, struct data_object, ID3DX10DataLoader_iface);
+}
+
+static LONG data_loader_load_count;
+static WINAPI HRESULT data_loader_Load(ID3DX10DataLoader *iface)
+{
+ struct data_object *data_object = data_object_from_ID3DX10DataLoader(iface);
+ DWORD ret;
+
+ ok(InterlockedDecrement(&data_loader_load_count) >= 0, "Got unexpected call.\n");
+
+ if (!io_tid)
+ io_tid = GetCurrentThreadId();
+ ok(io_tid != main_tid, "Load called in main thread.\n");
+ ok(io_tid == GetCurrentThreadId(), "Load called in wrong thread.\n");
+
+ SetEvent(data_object->load_started);
+ ret = WaitForSingleObject(data_object->load_done, INFINITE);
+ ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %x.\n", ret);
+ return data_object->load_ret;
+}
+
+static LONG data_loader_decompress_count;
+static WINAPI HRESULT data_loader_Decompress(ID3DX10DataLoader *iface, void **data, SIZE_T *bytes)
+{
+ struct data_object *data_object = data_object_from_ID3DX10DataLoader(iface);
+ DWORD ret;
+
+ ok(InterlockedDecrement(&data_loader_decompress_count) >= 0, "Got unexpected call.\n");
+ ok(data != NULL, "Got unexpected data = NULL.\n");
+ ok(bytes != NULL, "Got unexpected bytes = NULL.\n");
+
+ data_object->process_tid = GetCurrentThreadId();
+ ok(data_object->process_tid != main_tid, "Decompress called in main thread.\n");
+ ok(data_object->process_tid != io_tid, "Decompress called in IO thread.\n");
+
+ *data = (void*)0xdeadbeef;
+ *bytes = 0xdead;
+ ret = WaitForSingleObject(data_object->decompress_done, INFINITE);
+ ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %x.\n", ret);
+ return S_OK;
+}
+
+static LONG data_loader_destroy_count;
+static WINAPI HRESULT data_loader_Destroy(ID3DX10DataLoader *iface)
+{
+ ok(InterlockedDecrement(&data_loader_destroy_count) >= 0, "Got unexpected call.\n");
+ return S_OK;
+}
+
+static ID3DX10DataLoaderVtbl D3DX10DataLoaderVtbl =
+{
+ data_loader_Load,
+ data_loader_Decompress,
+ data_loader_Destroy
+};
+
+static struct data_object* data_object_from_ID3DX10DataProcessor(ID3DX10DataProcessor *iface)
+{
+ return CONTAINING_RECORD(iface, struct data_object, ID3DX10DataProcessor_iface);
+}
+
+static LONG data_processor_process_count;
+static HRESULT WINAPI data_processor_Process(ID3DX10DataProcessor *iface, void *data, SIZE_T bytes)
+{
+ struct data_object *data_object = data_object_from_ID3DX10DataProcessor(iface);
+
+ ok(InterlockedDecrement(&data_processor_process_count) >= 0, "Got unexpected call.\n");
+ ok(data_object->process_tid == GetCurrentThreadId(), "Process called in wrong thread.\n");
+
+ ok(data == (void*)0xdeadbeef, "data = %p\n", data);
+ ok(bytes == 0xdead, "bytes = %lu\n", bytes);
+ return S_OK;
+}
+
+static LONG data_processor_create_count;
+static HRESULT WINAPI data_processor_CreateDeviceObject(ID3DX10DataProcessor *iface, void **object)
+{
+ ok(InterlockedDecrement(&data_processor_create_count) >= 0, "Got unexpected call.\n");
+ ok(main_tid == GetCurrentThreadId(), "CreateDeviceObject not called in main thread.\n");
+
+ *object = (void*)0xdeadf00d;
+ return S_OK;
+}
+
+static LONG data_processor_destroy_count;
+static HRESULT WINAPI data_processor_Destroy(ID3DX10DataProcessor *iface)
+{
+ struct data_object *data_object = data_object_from_ID3DX10DataProcessor(iface);
+
+ ok(InterlockedDecrement(&data_processor_destroy_count) >= 0, "Got unexpected call.\n");
+
+ CloseHandle(data_object->load_started);
+ CloseHandle(data_object->load_done);
+ CloseHandle(data_object->decompress_done);
+ free(data_object);
+ return S_OK;
+}
+
+static ID3DX10DataProcessorVtbl D3DX10DataProcessorVtbl =
+{
+ data_processor_Process,
+ data_processor_CreateDeviceObject,
+ data_processor_Destroy
+};
+
+static struct data_object* create_data_object(HRESULT load_ret)
+{
+ struct data_object *data_object = malloc(sizeof(*data_object));
+
+ data_object->ID3DX10DataLoader_iface.lpVtbl = &D3DX10DataLoaderVtbl;
+ data_object->ID3DX10DataProcessor_iface.lpVtbl = &D3DX10DataProcessorVtbl;
+
+ data_object->load_started = CreateEventW(NULL, FALSE, FALSE, NULL);
+ ok(data_object->load_started != NULL, "CreateEvent failed, error %u.\n", GetLastError());
+ data_object->load_done = CreateEventW(NULL, FALSE, FALSE, NULL);
+ ok(data_object->load_done != NULL, "CreateEvent failed, error %u.\n", GetLastError());
+ data_object->decompress_done = CreateEventW(NULL, FALSE, FALSE, NULL);
+ ok(data_object->decompress_done != NULL, "CreateEvent failed, error %u.\n", GetLastError());
+ data_object->load_ret = load_ret;
+
+ return data_object;
+}
+
+static void test_D3DX10CreateThreadPump(void)
+{
+ UINT io_count, process_count, device_count, count;
+ struct data_object *data_object[2];
+ ID3DX10DataProcessor *processor;
+ D3DX10_IMAGE_INFO image_info;
+ ID3DX10DataLoader *loader;
+ HRESULT hr, work_item_hr;
+ ID3D10Resource *resource;
+ ID3DX10ThreadPump *pump;
+ ID3D10Device *device;
+ SYSTEM_INFO info;
+ void *object;
+ DWORD ret;
+ int i;
+
+ main_tid = GetCurrentThreadId();
+
+ hr = D3DX10CreateThreadPump(1024, 0, &pump);
+ ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
+ hr = D3DX10CreateThreadPump(0, 1024, &pump);
+ ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
+
+ GetSystemInfo(&info);
+ if (info.dwNumberOfProcessors > 1)
+ hr = D3DX10CreateThreadPump(0, 0, &pump);
+ else
+ hr = D3DX10CreateThreadPump(0, 2, &pump);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+
+ count = ID3DX10ThreadPump_GetWorkItemCount(pump);
+ ok(!count, "GetWorkItemCount returned %u.\n", count);
+ hr = ID3DX10ThreadPump_GetQueueStatus(pump, &io_count, &process_count, &device_count);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ ok(!io_count, "Got unexpected io_count = %u.\n", io_count);
+ ok(!process_count, "Got unexpected process_count = %u.\n", process_count);
+ ok(!device_count, "Got unexpected device_count = %u.\n", device_count);
+
+ data_object[0] = create_data_object(E_NOTIMPL);
+ data_object[1] = create_data_object(S_OK);
+
+ data_loader_load_count = 1;
+ hr = ID3DX10ThreadPump_AddWorkItem(pump, &data_object[0]->ID3DX10DataLoader_iface,
+ &data_object[0]->ID3DX10DataProcessor_iface, &work_item_hr, NULL);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ ret = WaitForSingleObject(data_object[0]->load_started, INFINITE);
+ ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %x.\n", ret);
+ ok(!data_loader_load_count, "Got unexpected data_loader_load_count %d.\n", data_loader_load_count);
+ count = ID3DX10ThreadPump_GetWorkItemCount(pump);
+ ok(count == 1, "GetWorkItemCount returned %u.\n", count);
+ hr = ID3DX10ThreadPump_GetQueueStatus(pump, &io_count, &process_count, &device_count);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ ok(!io_count, "Got unexpected io_count = %u.\n", io_count);
+ ok(!process_count, "Got unexpected process_count = %u.\n", process_count);
+ ok(!device_count, "Got unexpected device_count = %u.\n", device_count);
+
+ hr = ID3DX10ThreadPump_AddWorkItem(pump, &data_object[1]->ID3DX10DataLoader_iface,
+ &data_object[1]->ID3DX10DataProcessor_iface, NULL, &object);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ ret = WaitForSingleObject(data_object[0]->load_started, 50);
+ ok(ret == WAIT_TIMEOUT, "WaitForSingleObject returned %x.\n", ret);
+ count = ID3DX10ThreadPump_GetWorkItemCount(pump);
+ ok(count == 2, "GetWorkItemCount returned %u.\n", count);
+ hr = ID3DX10ThreadPump_GetQueueStatus(pump, &io_count, &process_count, &device_count);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ ok(io_count == 1, "Got unexpected io_count = %u.\n", io_count);
+ ok(!process_count, "Got unexpected process_count = %u.\n", process_count);
+ ok(!device_count, "Got unexpected device_count = %u.\n", device_count);
+
+ data_loader_load_count = 1;
+ data_loader_destroy_count = 1;
+ data_processor_destroy_count = 1;
+ SetEvent(data_object[0]->load_done);
+ ret = WaitForSingleObject(data_object[1]->load_started, INFINITE);
+ ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %x.\n", ret);
+ ok(work_item_hr == E_NOTIMPL, "Got unexpected work_item_hr = %#x.\n", work_item_hr);
+ ok(!data_loader_destroy_count, "Got unexpected data_loader_destroy_count %d.\n", data_loader_destroy_count);
+ ok(!data_processor_destroy_count, "Got unexpected data_processor_destroy_count %d.\n",
+ data_processor_destroy_count);
+ ok(!data_loader_load_count, "Got unexpected data_loader_load_count %d.\n", data_loader_load_count);
+
+ data_loader_decompress_count = 1;
+ data_processor_process_count = 1;
+ SetEvent(data_object[1]->load_done);
+ SetEvent(data_object[1]->decompress_done);
+
+ data_processor_create_count = 1;
+ data_loader_destroy_count = 1;
+ data_processor_destroy_count = 1;
+ hr = ID3DX10ThreadPump_WaitForAllItems(pump);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ ok(object == (void*)0xdeadf00d, "Got unexpected object = %p.\n", object);
+ ok(!data_loader_decompress_count, "Got unexpected data_loader_decompress_count %d.\n", data_loader_decompress_count);
+ ok(!data_processor_process_count, "Got unexpected data_processor_process_count %d.\n", data_processor_process_count);
+ ok(!data_processor_create_count, "Got unexpected data_processor_create_count %d.\n", data_processor_create_count);
+ ok(!data_loader_destroy_count, "Got unexpected data_loader_destroy_count %d.\n", data_loader_destroy_count);
+ ok(!data_processor_destroy_count, "Got unexpected data_processor_destroy_count %d.\n", data_processor_destroy_count);
+
+ data_object[0] = create_data_object(S_OK);
+ data_object[1] = create_data_object(S_OK);
+ SetEvent(data_object[0]->load_done);
+ SetEvent(data_object[1]->load_done);
+ SetEvent(data_object[1]->decompress_done);
+
+ data_loader_load_count = 2;
+ data_loader_decompress_count = 2;
+ data_processor_process_count = 1;
+ hr = ID3DX10ThreadPump_AddWorkItem(pump, &data_object[0]->ID3DX10DataLoader_iface,
+ &data_object[0]->ID3DX10DataProcessor_iface, NULL, &object);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ hr = ID3DX10ThreadPump_AddWorkItem(pump, &data_object[1]->ID3DX10DataLoader_iface,
+ &data_object[1]->ID3DX10DataProcessor_iface, NULL, &object);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ while(1)
+ {
+ hr = ID3DX10ThreadPump_GetQueueStatus(pump, &io_count, &process_count, &device_count);
+ if (hr != S_OK || device_count)
+ break;
+ Sleep(1);
+ }
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ ok(!io_count, "Got unexpected io_count = %u.\n", io_count);
+ ok(!process_count, "Got unexpected process_count = %u.\n", process_count);
+ ok(device_count == 1, "Got unexpected device_count = %u.\n", device_count);
+ ok(!data_loader_load_count, "Got unexpected data_loader_load_count %d.\n", data_loader_load_count);
+ ok(!data_loader_decompress_count, "Got unexpected data_loader_decompress_count %d.\n", data_loader_decompress_count);
+ ok(!data_processor_process_count, "Got unexpected data_processor_process_count %d.\n", data_processor_process_count);
+
+ hr = ID3DX10ThreadPump_ProcessDeviceWorkItems(pump, 0);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ hr = ID3DX10ThreadPump_GetQueueStatus(pump, &io_count, &process_count, &device_count);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ ok(!io_count, "Got unexpected io_count = %u.\n", io_count);
+ ok(!process_count, "Got unexpected process_count = %u.\n", process_count);
+ ok(device_count == 1, "Got unexpected device_count = %u.\n", device_count);
+
+ data_processor_create_count = 1;
+ data_loader_destroy_count = 1;
+ data_processor_destroy_count = 1;
+ hr = ID3DX10ThreadPump_ProcessDeviceWorkItems(pump, 1);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ hr = ID3DX10ThreadPump_GetQueueStatus(pump, &io_count, &process_count, &device_count);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ ok(!io_count, "Got unexpected io_count = %u.\n", io_count);
+ ok(!process_count, "Got unexpected process_count = %u.\n", process_count);
+ ok(!device_count, "Got unexpected device_count = %u.\n", device_count);
+ ok(!data_processor_create_count, "Got unexpected data_processor_create_count %d.\n", data_processor_create_count);
+ ok(!data_loader_destroy_count, "Got unexpected data_loader_destroy_count %d.\n", data_loader_destroy_count);
+ ok(!data_processor_destroy_count, "Got unexpected data_processor_destroy_count %d.\n", data_processor_destroy_count);
+
+ data_processor_process_count = 1;
+ data_loader_destroy_count = 1;
+ data_processor_destroy_count = 1;
+ SetEvent(data_object[0]->decompress_done);
+ hr = ID3DX10ThreadPump_PurgeAllItems(pump);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ data_processor_process_count = 0;
+ ok(!data_loader_destroy_count, "Got unexpected data_loader_destroy_count %d.\n", data_loader_destroy_count);
+ ok(!data_processor_destroy_count, "Got unexpected data_processor_destroy_count %d.\n", data_processor_destroy_count);
+
+ device = create_device();
+ if (!device)
+ {
+ skip("Failed to create device, skipping tests.\n");
+ ID3DX10ThreadPump_Release(pump);
+ return;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(test_image); ++i)
+ {
+ winetest_push_context("Test %u", i);
+
+ hr = D3DX10CreateAsyncMemoryLoader(test_image[i].data, test_image[i].size, &loader);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ hr = D3DX10CreateAsyncTextureInfoProcessor(&image_info, &processor);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ hr = ID3DX10ThreadPump_AddWorkItem(pump, loader, processor, &work_item_hr, NULL);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ hr = ID3DX10ThreadPump_WaitForAllItems(pump);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ ok(work_item_hr == S_OK || (work_item_hr == E_FAIL
+ && test_image[i].expected_info.ImageFileFormat == D3DX10_IFF_WMP),
+ "Got unexpected hr %#x.\n", work_item_hr);
+ if (work_item_hr == S_OK)
+ check_image_info(&image_info, test_image + i, __LINE__);
+
+ hr = D3DX10CreateAsyncMemoryLoader(test_image[i].data, test_image[i].size, &loader);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ hr = D3DX10CreateAsyncTextureProcessor(device, NULL, &processor);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ hr = ID3DX10ThreadPump_AddWorkItem(pump, loader, processor, &work_item_hr, (void **)&resource);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ hr = ID3DX10ThreadPump_WaitForAllItems(pump);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ todo_wine_if(test_image[i].expected_info.MiscFlags & D3D10_RESOURCE_MISC_TEXTURECUBE)
+ ok(work_item_hr == S_OK || (work_item_hr == E_FAIL
+ && test_image[i].expected_info.ImageFileFormat == D3DX10_IFF_WMP),
+ "Got unexpected hr %#x.\n", work_item_hr);
+ if (work_item_hr == S_OK)
+ {
+ check_resource_info(resource, test_image + i, __LINE__);
+ check_resource_data(resource, test_image + i, __LINE__);
+ ID3D10Resource_Release(resource);
+ }
+
+ winetest_pop_context();
+ }
+
+ ok(!ID3D10Device_Release(device), "Got unexpected refcount.\n");
+
+ ret = ID3DX10ThreadPump_Release(pump);
+ ok(!ret, "Got unexpected refcount %u.\n", ret);
+}
+
static void test_get_image_info(void)
{
static const WCHAR test_resource_name[] = L"resource.data";
@@ -3573,6 +3929,7 @@ START_TEST(d3dx10)
test_D3DX10CreateAsyncResourceLoader();
test_D3DX10CreateAsyncTextureInfoProcessor();
test_D3DX10CreateAsyncTextureProcessor();
+ test_D3DX10CreateThreadPump();
test_get_image_info();
test_create_texture();
test_font();
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/272
More information about the wine-devel
mailing list