Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
June 2022
- 68 participants
- 3274 messages
[PATCH v4 4/9] d3dx10: Add ID3DX10ThreadPump:GetWorkItemCount implementation.
by Piotr Caban
From: Piotr Caban <piotr(a)codeweavers.com>
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
---
dlls/d3dx10_43/async.c | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/dlls/d3dx10_43/async.c b/dlls/d3dx10_43/async.c
index a3d1014986b..33dd3ceca9a 100644
--- a/dlls/d3dx10_43/async.c
+++ b/dlls/d3dx10_43/async.c
@@ -636,6 +636,8 @@ struct thread_pump
ID3DX10ThreadPump ID3DX10ThreadPump_iface;
LONG refcount;
+ LONG processing_count;
+
SRWLOCK io_lock;
CONDITION_VARIABLE io_cv;
unsigned int io_count;
@@ -758,6 +760,7 @@ static HRESULT WINAPI thread_pump_AddWorkItem(ID3DX10ThreadPump *iface, ID3DX10D
if (object)
*object = NULL;
+ InterlockedIncrement(&thread_pump->processing_count);
AcquireSRWLockExclusive(&thread_pump->io_lock);
++thread_pump->io_count;
list_add_tail(&thread_pump->io_queue, &work_item->entry);
@@ -768,8 +771,15 @@ static HRESULT WINAPI thread_pump_AddWorkItem(ID3DX10ThreadPump *iface, ID3DX10D
static UINT WINAPI thread_pump_GetWorkItemCount(ID3DX10ThreadPump *iface)
{
- FIXME("iface %p stub!\n", iface);
- return 0;
+ struct thread_pump *thread_pump = impl_from_ID3DX10ThreadPump(iface);
+ UINT ret;
+
+ TRACE("iface %p.\n", iface);
+
+ AcquireSRWLockExclusive(&thread_pump->device_lock);
+ ret = thread_pump->processing_count + thread_pump->device_count;
+ ReleaseSRWLockExclusive(&thread_pump->device_lock);
+ return ret;
}
static HRESULT WINAPI thread_pump_WaitForAllItems(ID3DX10ThreadPump *iface)
@@ -842,6 +852,7 @@ static DWORD WINAPI io_thread(void *arg)
if (work_item->result)
*work_item->result = hr;
work_item_free(work_item, FALSE);
+ InterlockedDecrement(&thread_pump->processing_count);
continue;
}
@@ -894,6 +905,7 @@ static DWORD WINAPI proc_thread(void *arg)
if (work_item->result)
*work_item->result = hr;
work_item_free(work_item, FALSE);
+ InterlockedDecrement(&thread_pump->processing_count);
continue;
}
@@ -908,6 +920,7 @@ static DWORD WINAPI proc_thread(void *arg)
if (work_item->result)
*work_item->result = hr;
work_item_free(work_item, FALSE);
+ InterlockedDecrement(&thread_pump->processing_count);
continue;
}
@@ -921,6 +934,7 @@ static DWORD WINAPI proc_thread(void *arg)
list_add_tail(&thread_pump->device_queue, &work_item->entry);
++thread_pump->device_count;
+ InterlockedDecrement(&thread_pump->processing_count);
ReleaseSRWLockExclusive(&thread_pump->device_lock);
}
return 0;
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/272
June 26, 2022
[PATCH v4 3/9] d3dx10: Add ID3DX10ThreadPump:AddWorkItem implementation.
by Piotr Caban
From: Piotr Caban <piotr(a)codeweavers.com>
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
---
dlls/d3dx10_43/async.c | 248 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 245 insertions(+), 3 deletions(-)
diff --git a/dlls/d3dx10_43/async.c b/dlls/d3dx10_43/async.c
index 7913f634c21..a3d1014986b 100644
--- a/dlls/d3dx10_43/async.c
+++ b/dlls/d3dx10_43/async.c
@@ -23,6 +23,7 @@
#include "dxhelpers.h"
#include "wine/debug.h"
+#include "wine/list.h"
WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
@@ -610,10 +611,47 @@ HRESULT WINAPI D3DX10PreprocessShaderFromMemory(const char *data, SIZE_T data_si
return E_NOTIMPL;
}
+struct work_item
+{
+ struct list entry;
+
+ ID3DX10DataLoader *loader;
+ ID3DX10DataProcessor *processor;
+ HRESULT *result;
+ void **object;
+};
+
+static inline void work_item_free(struct work_item *work_item, BOOL cancel)
+{
+ ID3DX10DataLoader_Destroy(work_item->loader);
+ ID3DX10DataProcessor_Destroy(work_item->processor);
+ if (cancel && work_item->result)
+ *work_item->result = S_FALSE;
+ free(work_item);
+}
+
+#define THREAD_PUMP_EXITING UINT_MAX
struct thread_pump
{
ID3DX10ThreadPump ID3DX10ThreadPump_iface;
LONG refcount;
+
+ SRWLOCK io_lock;
+ CONDITION_VARIABLE io_cv;
+ unsigned int io_count;
+ struct list io_queue;
+
+ SRWLOCK proc_lock;
+ CONDITION_VARIABLE proc_cv;
+ unsigned int proc_count;
+ struct list proc_queue;
+
+ SRWLOCK device_lock;
+ unsigned int device_count;
+ struct list device_queue;
+
+ unsigned int thread_count;
+ HANDLE threads[1];
};
static inline struct thread_pump *impl_from_ID3DX10ThreadPump(ID3DX10ThreadPump *iface)
@@ -652,11 +690,49 @@ static ULONG WINAPI thread_pump_Release(ID3DX10ThreadPump *iface)
{
struct thread_pump *thread_pump = impl_from_ID3DX10ThreadPump(iface);
ULONG refcount = InterlockedDecrement(&thread_pump->refcount);
+ struct work_item *item, *next;
+ struct list list;
+ unsigned int i;
TRACE("%p decreasing refcount to %lu.\n", iface, refcount);
if (!refcount)
+ {
+ AcquireSRWLockExclusive(&thread_pump->io_lock);
+ thread_pump->io_count = THREAD_PUMP_EXITING;
+ ReleaseSRWLockExclusive(&thread_pump->io_lock);
+ WakeAllConditionVariable(&thread_pump->io_cv);
+
+ AcquireSRWLockExclusive(&thread_pump->proc_lock);
+ thread_pump->proc_count = THREAD_PUMP_EXITING;
+ ReleaseSRWLockExclusive(&thread_pump->proc_lock);
+ WakeAllConditionVariable(&thread_pump->proc_cv);
+
+ AcquireSRWLockExclusive(&thread_pump->device_lock);
+ thread_pump->device_count = THREAD_PUMP_EXITING;
+ ReleaseSRWLockExclusive(&thread_pump->device_lock);
+
+ for (i = 0; i < thread_pump->thread_count; ++i)
+ {
+ if (!thread_pump->threads[i])
+ continue;
+
+ WaitForSingleObject(thread_pump->threads[i], INFINITE);
+ CloseHandle(thread_pump->threads[i]);
+ }
+
+ list_init(&list);
+ list_move_tail(&list, &thread_pump->io_queue);
+ list_move_tail(&list, &thread_pump->proc_queue);
+ list_move_tail(&list, &thread_pump->device_queue);
+ LIST_FOR_EACH_ENTRY_SAFE(item, next, &list, struct work_item, entry)
+ {
+ list_remove(&item->entry);
+ work_item_free(item, TRUE);
+ }
+
free(thread_pump);
+ }
return refcount;
}
@@ -664,9 +740,30 @@ static ULONG WINAPI thread_pump_Release(ID3DX10ThreadPump *iface)
static HRESULT WINAPI thread_pump_AddWorkItem(ID3DX10ThreadPump *iface, ID3DX10DataLoader *loader,
ID3DX10DataProcessor *processor, HRESULT *result, void **object)
{
- FIXME("iface %p, loader %p, processor %p, result %p, object %p stub!\n",
+ struct thread_pump *thread_pump = impl_from_ID3DX10ThreadPump(iface);
+ struct work_item *work_item;
+
+ TRACE("iface %p, loader %p, processor %p, result %p, object %p.\n",
iface, loader, processor, result, object);
- return E_NOTIMPL;
+
+ work_item = malloc(sizeof(*work_item));
+ if (!work_item)
+ return E_OUTOFMEMORY;
+
+ work_item->loader = loader;
+ work_item->processor = processor;
+ work_item->result = result;
+ work_item->object = object;
+
+ if (object)
+ *object = NULL;
+
+ AcquireSRWLockExclusive(&thread_pump->io_lock);
+ ++thread_pump->io_count;
+ list_add_tail(&thread_pump->io_queue, &work_item->entry);
+ ReleaseSRWLockExclusive(&thread_pump->io_lock);
+ WakeConditionVariable(&thread_pump->io_cv);
+ return S_OK;
}
static UINT WINAPI thread_pump_GetWorkItemCount(ID3DX10ThreadPump *iface)
@@ -714,20 +811,165 @@ static const ID3DX10ThreadPumpVtbl thread_pump_vtbl =
thread_pump_GetQueueStatus
};
+static DWORD WINAPI io_thread(void *arg)
+{
+ struct thread_pump *thread_pump = arg;
+ struct work_item *work_item;
+ HRESULT hr;
+
+ TRACE("%p thread started.\n", thread_pump);
+
+ for (;;)
+ {
+ AcquireSRWLockExclusive(&thread_pump->io_lock);
+
+ while (!thread_pump->io_count)
+ SleepConditionVariableSRW(&thread_pump->io_cv, &thread_pump->io_lock, INFINITE, 0);
+
+ if (thread_pump->io_count == THREAD_PUMP_EXITING)
+ {
+ ReleaseSRWLockExclusive(&thread_pump->io_lock);
+ return 0;
+ }
+
+ thread_pump->io_count--;
+ work_item = LIST_ENTRY(list_head(&thread_pump->io_queue), struct work_item, entry);
+ list_remove(&work_item->entry);
+ ReleaseSRWLockExclusive(&thread_pump->io_lock);
+
+ if (FAILED(hr = ID3DX10DataLoader_Load(work_item->loader)))
+ {
+ if (work_item->result)
+ *work_item->result = hr;
+ work_item_free(work_item, FALSE);
+ continue;
+ }
+
+ AcquireSRWLockExclusive(&thread_pump->proc_lock);
+ if (thread_pump->proc_count == THREAD_PUMP_EXITING)
+ {
+ ReleaseSRWLockExclusive(&thread_pump->proc_lock);
+ work_item_free(work_item, TRUE);
+ return 0;
+ }
+
+ list_add_tail(&thread_pump->proc_queue, &work_item->entry);
+ ++thread_pump->proc_count;
+ ReleaseSRWLockExclusive(&thread_pump->proc_lock);
+ WakeConditionVariable(&thread_pump->proc_cv);
+ }
+ return 0;
+}
+
+static DWORD WINAPI proc_thread(void *arg)
+{
+ struct thread_pump *thread_pump = arg;
+ struct work_item *work_item;
+ SIZE_T size;
+ void *data;
+ HRESULT hr;
+
+ TRACE("%p thread started.\n", thread_pump);
+
+ for (;;)
+ {
+ AcquireSRWLockExclusive(&thread_pump->proc_lock);
+
+ while (!thread_pump->proc_count)
+ SleepConditionVariableSRW(&thread_pump->proc_cv, &thread_pump->proc_lock, INFINITE, 0);
+
+ if (thread_pump->proc_count == THREAD_PUMP_EXITING)
+ {
+ ReleaseSRWLockExclusive(&thread_pump->proc_lock);
+ return 0;
+ }
+
+ thread_pump->proc_count--;
+ work_item = LIST_ENTRY(list_head(&thread_pump->proc_queue), struct work_item, entry);
+ list_remove(&work_item->entry);
+ ReleaseSRWLockExclusive(&thread_pump->proc_lock);
+
+ if (FAILED(hr = ID3DX10DataLoader_Decompress(work_item->loader, &data, &size)))
+ {
+ if (work_item->result)
+ *work_item->result = hr;
+ work_item_free(work_item, FALSE);
+ continue;
+ }
+
+ if (thread_pump->device_count == THREAD_PUMP_EXITING)
+ {
+ work_item_free(work_item, TRUE);
+ return 0;
+ }
+
+ if (FAILED(hr = ID3DX10DataProcessor_Process(work_item->processor, data, size)))
+ {
+ if (work_item->result)
+ *work_item->result = hr;
+ work_item_free(work_item, FALSE);
+ continue;
+ }
+
+ AcquireSRWLockExclusive(&thread_pump->device_lock);
+ if (thread_pump->device_count == THREAD_PUMP_EXITING)
+ {
+ ReleaseSRWLockExclusive(&thread_pump->device_lock);
+ work_item_free(work_item, TRUE);
+ return 0;
+ }
+
+ list_add_tail(&thread_pump->device_queue, &work_item->entry);
+ ++thread_pump->device_count;
+ ReleaseSRWLockExclusive(&thread_pump->device_lock);
+ }
+ return 0;
+}
+
HRESULT WINAPI D3DX10CreateThreadPump(UINT io_threads, UINT proc_threads, ID3DX10ThreadPump **pump)
{
struct thread_pump *object;
+ int i;
TRACE("io_threads %u, proc_threads %u, pump %p.\n", io_threads, proc_threads, pump);
if (io_threads >= 1024 || proc_threads >= 1024)
return E_FAIL;
- if (!(object = calloc(1, sizeof(*object))))
+ if (!io_threads)
+ io_threads = 1;
+ if (!proc_threads)
+ {
+ SYSTEM_INFO info;
+
+ GetSystemInfo(&info);
+ proc_threads = info.dwNumberOfProcessors;
+ }
+
+ if (!(object = calloc(1, FIELD_OFFSET(struct thread_pump, threads[io_threads + proc_threads]))))
return E_OUTOFMEMORY;
object->ID3DX10ThreadPump_iface.lpVtbl = &thread_pump_vtbl;
object->refcount = 1;
+ InitializeSRWLock(&object->io_lock);
+ InitializeConditionVariable(&object->io_cv);
+ list_init(&object->io_queue);
+ InitializeSRWLock(&object->proc_lock);
+ InitializeConditionVariable(&object->proc_cv);
+ list_init(&object->proc_queue);
+ InitializeSRWLock(&object->device_lock);
+ list_init(&object->device_queue);
+ object->thread_count = io_threads + proc_threads;
+
+ for (i = 0; i < object->thread_count; ++i)
+ {
+ object->threads[i] = CreateThread(NULL, 0, i < io_threads ? io_thread : proc_thread, object, 0, NULL);
+ if (!object->threads[i])
+ {
+ ID3DX10ThreadPump_Release(&object->ID3DX10ThreadPump_iface);
+ return E_FAIL;
+ }
+ }
*pump = &object->ID3DX10ThreadPump_iface;
return S_OK;
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/272
June 26, 2022
[PATCH v4 2/9] d3dx10: Add D3DX10CreateThreadPump stub.
by Piotr Caban
From: Piotr Caban <piotr(a)codeweavers.com>
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
---
dlls/d3dx10_43/async.c | 123 ++++++++++++++++++++++++++++++++++
dlls/d3dx10_43/d3dx10_43.spec | 2 +-
include/d3dx10core.h | 1 +
3 files changed, 125 insertions(+), 1 deletion(-)
diff --git a/dlls/d3dx10_43/async.c b/dlls/d3dx10_43/async.c
index bb1cf30a217..7913f634c21 100644
--- a/dlls/d3dx10_43/async.c
+++ b/dlls/d3dx10_43/async.c
@@ -609,3 +609,126 @@ HRESULT WINAPI D3DX10PreprocessShaderFromMemory(const char *data, SIZE_T data_si
return E_NOTIMPL;
}
+
+struct thread_pump
+{
+ ID3DX10ThreadPump ID3DX10ThreadPump_iface;
+ LONG refcount;
+};
+
+static inline struct thread_pump *impl_from_ID3DX10ThreadPump(ID3DX10ThreadPump *iface)
+{
+ return CONTAINING_RECORD(iface, struct thread_pump, ID3DX10ThreadPump_iface);
+}
+
+static HRESULT WINAPI thread_pump_QueryInterface(ID3DX10ThreadPump *iface, REFIID riid, void **out)
+{
+ TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
+
+ if (IsEqualGUID(riid, &IID_ID3DX10ThreadPump)
+ || IsEqualGUID(riid, &IID_IUnknown))
+ {
+ ID3DX10ThreadPump_AddRef(iface);
+ *out = iface;
+ return S_OK;
+ }
+
+ WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
+ *out = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI thread_pump_AddRef(ID3DX10ThreadPump *iface)
+{
+ struct thread_pump *thread_pump = impl_from_ID3DX10ThreadPump(iface);
+ ULONG refcount = InterlockedIncrement(&thread_pump->refcount);
+
+ TRACE("%p increasing refcount to %lu.\n", iface, refcount);
+
+ return refcount;
+}
+
+static ULONG WINAPI thread_pump_Release(ID3DX10ThreadPump *iface)
+{
+ struct thread_pump *thread_pump = impl_from_ID3DX10ThreadPump(iface);
+ ULONG refcount = InterlockedDecrement(&thread_pump->refcount);
+
+ TRACE("%p decreasing refcount to %lu.\n", iface, refcount);
+
+ if (!refcount)
+ free(thread_pump);
+
+ return refcount;
+}
+
+static HRESULT WINAPI thread_pump_AddWorkItem(ID3DX10ThreadPump *iface, ID3DX10DataLoader *loader,
+ ID3DX10DataProcessor *processor, HRESULT *result, void **object)
+{
+ FIXME("iface %p, loader %p, processor %p, result %p, object %p stub!\n",
+ iface, loader, processor, result, object);
+ return E_NOTIMPL;
+}
+
+static UINT WINAPI thread_pump_GetWorkItemCount(ID3DX10ThreadPump *iface)
+{
+ FIXME("iface %p stub!\n", iface);
+ return 0;
+}
+
+static HRESULT WINAPI thread_pump_WaitForAllItems(ID3DX10ThreadPump *iface)
+{
+ FIXME("iface %p stub!\n", iface);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI thread_pump_ProcessDeviceWorkItems(ID3DX10ThreadPump *iface, UINT count)
+{
+ FIXME("iface %p, count %u stub!\n", iface, count);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI thread_pump_PurgeAllItems(ID3DX10ThreadPump *iface)
+{
+ FIXME("iface %p stub!\n", iface);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI thread_pump_GetQueueStatus(ID3DX10ThreadPump *iface,
+ UINT *io_queue, UINT *process_queue, UINT *device_queue)
+{
+ FIXME("iface %p, io_queue %p, process_queue %p, device_queue %p stub!\n",
+ iface, io_queue, process_queue, device_queue);
+ return E_NOTIMPL;
+}
+
+static const ID3DX10ThreadPumpVtbl thread_pump_vtbl =
+{
+ thread_pump_QueryInterface,
+ thread_pump_AddRef,
+ thread_pump_Release,
+ thread_pump_AddWorkItem,
+ thread_pump_GetWorkItemCount,
+ thread_pump_WaitForAllItems,
+ thread_pump_ProcessDeviceWorkItems,
+ thread_pump_PurgeAllItems,
+ thread_pump_GetQueueStatus
+};
+
+HRESULT WINAPI D3DX10CreateThreadPump(UINT io_threads, UINT proc_threads, ID3DX10ThreadPump **pump)
+{
+ struct thread_pump *object;
+
+ TRACE("io_threads %u, proc_threads %u, pump %p.\n", io_threads, proc_threads, pump);
+
+ if (io_threads >= 1024 || proc_threads >= 1024)
+ return E_FAIL;
+
+ if (!(object = calloc(1, sizeof(*object))))
+ return E_OUTOFMEMORY;
+
+ object->ID3DX10ThreadPump_iface.lpVtbl = &thread_pump_vtbl;
+ object->refcount = 1;
+
+ *pump = &object->ID3DX10ThreadPump_iface;
+ return S_OK;
+}
diff --git a/dlls/d3dx10_43/d3dx10_43.spec b/dlls/d3dx10_43/d3dx10_43.spec
index 95160a067c5..2359c7c6f02 100644
--- a/dlls/d3dx10_43/d3dx10_43.spec
+++ b/dlls/d3dx10_43/d3dx10_43.spec
@@ -1,4 +1,4 @@
-@ stub D3DX10CreateThreadPump(long long ptr)
+@ stdcall D3DX10CreateThreadPump(long long ptr)
@ stdcall D3DX10CheckVersion(long long)
@ stub D3DX10CompileFromFileA(str ptr ptr str str long long ptr ptr ptr ptr)
@ stub D3DX10CompileFromFileW(wstr ptr ptr str str long long ptr ptr ptr ptr)
diff --git a/include/d3dx10core.h b/include/d3dx10core.h
index a9ba7854e90..cca9052cc13 100644
--- a/include/d3dx10core.h
+++ b/include/d3dx10core.h
@@ -298,3 +298,4 @@ HRESULT WINAPI D3DX10CreateFontW(ID3D10Device *device, INT height, UINT width, U
UINT miplevels, BOOL italic, UINT charset, UINT precision, UINT quality,
UINT pitchandfamily, const WCHAR *facename, ID3DX10Font **font);
HRESULT WINAPI D3DX10CreateSprite(ID3D10Device *device, UINT size, ID3DX10Sprite **sprite);
+HRESULT WINAPI D3DX10CreateThreadPump(UINT io_threads, UINT proc_threads, ID3DX10ThreadPump **pump);
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/272
June 26, 2022
[PATCH v4 1/9] d3dx10/tests: Fix texture leak in check_resource_data.
by Piotr Caban
From: Piotr Caban <piotr(a)codeweavers.com>
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
---
dlls/d3dx10_43/tests/d3dx10.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c
index 1c28a62b700..d1c772197b9 100644
--- a/dlls/d3dx10_43/tests/d3dx10.c
+++ b/dlls/d3dx10_43/tests/d3dx10.c
@@ -1237,7 +1237,7 @@ static void check_resource_data(ID3D10Resource *resource, const struct test_imag
ok_(__FILE__, line)(hr == S_OK, "Map failed, hr %#x.\n", hr);
if (hr != S_OK)
{
- ID3D10Texture2D_Unmap(readback, 0);
+ ID3D10Texture2D_Release(readback);
return;
}
@@ -1253,6 +1253,7 @@ static void check_resource_data(ID3D10Resource *resource, const struct test_imag
}
ID3D10Texture2D_Unmap(readback, 0);
+ ID3D10Texture2D_Release(readback);
}
static void test_D3DX10UnsetAllDeviceObjects(void)
@@ -2062,7 +2063,7 @@ static void test_D3DX10CreateAsyncTextureProcessor(void)
CoUninitialize();
- ID3D10Device_Release(device);
+ ok(!ID3D10Device_Release(device), "Unexpected refcount.\n");
}
static void test_get_image_info(void)
@@ -2417,7 +2418,7 @@ static void test_create_texture(void)
CoUninitialize();
- ID3D10Device_Release(device);
+ ok(!ID3D10Device_Release(device), "Unexpected refcount.\n");
}
#define check_rect(rect, left, top, right, bottom) _check_rect(__LINE__, rect, left, top, right, bottom)
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/272
June 26, 2022
[PATCH v4 0/9] MR272: d3dx10: Add D3DX10CreateThreadPump implementation.
by Piotr Caban (@piotr)
The GetWorkItemCount implementation may look strange. It's done this way because of how WaitForAllItems is implemented. Alternative solution is to introduce separate counter for GetWorkItemCount.
--
v4: d3dx10/tests: Add D3DX10CreateThreadPump tests.
d3dx10: Add ID3DX10ThreadPump:PurgeAllItems implementation.
d3dx10: Add ID3DX10ThreadPump:GetQueueStatus implementation.
d3dx10: Add ID3DX10ThreadPump:WaitForAllItems implementation.
d3dx10: Add ID3DX10ThreadPump:ProcessDeviceWorkItems implementation.
d3dx10: Add ID3DX10ThreadPump:GetWorkItemCount implementation.
d3dx10: Add ID3DX10ThreadPump:AddWorkItem implementation.
d3dx10: Add D3DX10CreateThreadPump stub.
d3dx10/tests: Fix texture leak in check_resource_data.
https://gitlab.winehq.org/wine/wine/-/merge_requests/272
June 26, 2022
Re: [PATCH 0/6] MR265: kernelbase: Implement PrefetchVirtualMemory.
by Jinoh Kang (@iamahuman)
On Wed Jun 22 22:26:03 2022 +0000, Etaash Mathamsetty wrote:
> what exactly is this for?
> the if(!once++)
It causes the log to be emitted only once. `if (!once++)` is a common pattern throughout the wine codebase.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/265#note_2723
June 26, 2022
[PATCH 2/2] ntdll: Preserve EFLAGS across syscall on x64.
by Jinoh Kang
From: Jinoh Kang <jinoh.kang.kr(a)gmail.com>
Signed-off-by: Jinoh Kang <jinoh.kang.kr(a)gmail.com>
---
dlls/ntdll/tests/exception.c | 1 -
dlls/ntdll/unix/signal_x86_64.c | 10 ++++++----
2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c
index 006da0336be..9f4477a4da1 100644
--- a/dlls/ntdll/tests/exception.c
+++ b/dlls/ntdll/tests/exception.c
@@ -5010,7 +5010,6 @@ static void test_syscall_clobbered_regs(void)
ok(status == STATUS_INVALID_PARAMETER_1, "Got unexpected status %#lx.\n", status);
ok((BYTE *)regs.rcx > (BYTE *)pNtWaitForMultipleObjects && (BYTE *)regs.rcx < (BYTE *)pNtWaitForMultipleObjects + 0x20,
"Got unexpected rcx %s, pNtWaitForMultipleObjects %p.\n", wine_dbgstr_longlong(regs.rcx), pNtWaitForMultipleObjects);
- todo_wine
ok((regs.eflags & 0x400) != 0, "Expected direction flag to be set in EFLAGS (%#x).\n", regs.eflags);
context.ContextFlags = CONTEXT_CONTROL;
diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c
index 6c87e347eac..87ff148a628 100644
--- a/dlls/ntdll/unix/signal_x86_64.c
+++ b/dlls/ntdll/unix/signal_x86_64.c
@@ -3415,13 +3415,15 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher,
"movq 0x28(%rcx),%rdi\n\t"
"movq 0x20(%rcx),%rsi\n\t"
"movq 0x08(%rcx),%rbx\n\t"
+ "leaq 0x70(%rcx),%rsp\n\t"
"testl $0x3,%edx\n\t" /* CONTEXT_CONTROL | CONTEXT_INTEGER */
"jnz 1f\n\t"
- "movq 0x88(%rcx),%rsp\n\t"
- "movq 0x70(%rcx),%rcx\n\t" /* frame->rip */
+ "pop %rcx\n\t" /* frame->rip */
+ "add $8,%rsp\n\t"
+ "popfq\n\t"
+ "pop %rsp\n\t"
"jmpq *%rcx\n\t"
- "1:\tleaq 0x70(%rcx),%rsp\n\t"
- "testl $0x2,%edx\n\t" /* CONTEXT_INTEGER */
+ "1:\ttestl $0x2,%edx\n\t" /* CONTEXT_INTEGER */
"jnz 1f\n\t"
"movq (%rsp),%rcx\n\t" /* frame->rip */
"iretq\n"
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/314
June 26, 2022
[PATCH 1/2] ntdll/tests: Test for preservation of EFLAGS across syscall on x64.
by Jinoh Kang
From: Jinoh Kang <jinoh.kang.kr(a)gmail.com>
Signed-off-by: Jinoh Kang <jinoh.kang.kr(a)gmail.com>
---
dlls/ntdll/tests/exception.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c
index 820e435bc1b..006da0336be 100644
--- a/dlls/ntdll/tests/exception.c
+++ b/dlls/ntdll/tests/exception.c
@@ -4949,6 +4949,7 @@ static void test_syscall_clobbered_regs(void)
struct regs
{
UINT64 rcx;
+ UINT32 eflags;
};
static const BYTE code[] =
{
@@ -4959,6 +4960,7 @@ static void test_syscall_clobbered_regs(void)
0x48, 0x83, 0xe8, 0x08, /* subq $8,%rax */
0x48, 0x89, 0x20, /* movq %rsp,0(%rax) */
0x48, 0x89, 0xc4, /* movq %rax,%rsp */
+ 0xfd, /* std */
0x41, 0x50, /* push %r8 */
0x53, 0x55, 0x57, 0x56, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57,
/* push %rbx, %rbp, %rdi, %rsi, %r12, %r13, %r14, %r15 */
@@ -4967,12 +4969,17 @@ static void test_syscall_clobbered_regs(void)
/* pop %r15, %r14, %r13, %r12, %rsi, %rdi, %rbp, %rbx */
0x41, 0x58, /* pop %r8 */
0x49, 0x89, 0x48, 0x00, /* mov %rcx,(%r8) */
+ 0x9c, /* pushfq */
+ 0x59, /* pop %rcx */
+ 0xfc, /* cld */
+ 0x41, 0x89, 0x48, 0x08, /* mov %ecx,0x8(%r8) */
0x5c, /* pop %rsp */
0xc3, /* ret */
};
NTSTATUS (WINAPI *func)(void *arg1, void *arg2, struct regs *, void *call_addr);
NTSTATUS (WINAPI *pNtCancelTimer)(HANDLE, BOOLEAN *);
+ NTSTATUS (WINAPI *pNtWaitForMultipleObjects)(DWORD, const HANDLE *, BOOLEAN, BOOLEAN, const LARGE_INTEGER *);
HMODULE hntdll = GetModuleHandleA("ntdll.dll");
struct regs regs;
CONTEXT context;
@@ -4985,6 +4992,7 @@ static void test_syscall_clobbered_regs(void)
memset(®s, 0, sizeof(regs));
status = func((HANDLE)0xdeadbeef, NULL, ®s, pNtCancelTimer);
ok(status == STATUS_INVALID_HANDLE, "Got unexpected status %#lx.\n", status);
+ ok((regs.eflags & 0x400) != 0, "Expected direction flag to be set in EFLAGS (%#x).\n", regs.eflags);
/* After the syscall instruction rcx contains the address of the instruction next after syscall. */
ok((BYTE *)regs.rcx > (BYTE *)pNtCancelTimer && (BYTE *)regs.rcx < (BYTE *)pNtCancelTimer + 0x20,
@@ -4994,28 +5002,42 @@ static void test_syscall_clobbered_regs(void)
ok(status == STATUS_ACCESS_VIOLATION, "Got unexpected status %#lx.\n", status);
ok((BYTE *)regs.rcx > (BYTE *)pNtCancelTimer && (BYTE *)regs.rcx < (BYTE *)pNtCancelTimer + 0x20,
"Got unexpected rcx %s, pNtCancelTimer %p.\n", wine_dbgstr_longlong(regs.rcx), pNtCancelTimer);
+ ok((regs.eflags & 0x400) != 0, "Expected direction flag to be set in EFLAGS (%#x).\n", regs.eflags);
+
+ pNtWaitForMultipleObjects = (void *)GetProcAddress(hntdll, "NtWaitForMultipleObjects");
+ ok(!!pNtWaitForMultipleObjects, "NtWaitForMultipleObjects not found.\n");
+ status = func((DWORD)0, (HANDLE *)NULL, ®s, pNtWaitForMultipleObjects);
+ ok(status == STATUS_INVALID_PARAMETER_1, "Got unexpected status %#lx.\n", status);
+ ok((BYTE *)regs.rcx > (BYTE *)pNtWaitForMultipleObjects && (BYTE *)regs.rcx < (BYTE *)pNtWaitForMultipleObjects + 0x20,
+ "Got unexpected rcx %s, pNtWaitForMultipleObjects %p.\n", wine_dbgstr_longlong(regs.rcx), pNtWaitForMultipleObjects);
+ todo_wine
+ ok((regs.eflags & 0x400) != 0, "Expected direction flag to be set in EFLAGS (%#x).\n", regs.eflags);
context.ContextFlags = CONTEXT_CONTROL;
status = func(GetCurrentThread(), &context, ®s, pNtGetContextThread);
ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
ok((BYTE *)regs.rcx > (BYTE *)pNtGetContextThread && (BYTE *)regs.rcx < (BYTE *)pNtGetContextThread + 0x20,
"Got unexpected rcx %s, pNtGetContextThread %p.\n", wine_dbgstr_longlong(regs.rcx), pNtGetContextThread);
+ ok((regs.eflags & 0x400) != 0, "Expected direction flag to be set in EFLAGS (%#x).\n", regs.eflags);
status = func(GetCurrentThread(), &context, ®s, pNtSetContextThread);
ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
ok((BYTE *)regs.rcx > (BYTE *)pNtGetContextThread && (BYTE *)regs.rcx < (BYTE *)pNtGetContextThread + 0x20,
"Got unexpected rcx %s, pNtGetContextThread %p.\n", wine_dbgstr_longlong(regs.rcx), pNtGetContextThread);
+ ok((regs.eflags & 0x400) != 0, "Expected direction flag to be set in EFLAGS (%#x).\n", regs.eflags);
context.ContextFlags = CONTEXT_INTEGER;
status = func(GetCurrentThread(), &context, ®s, pNtGetContextThread);
ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
ok((BYTE *)regs.rcx > (BYTE *)pNtGetContextThread && (BYTE *)regs.rcx < (BYTE *)pNtGetContextThread + 0x20,
"Got unexpected rcx %s, pNtGetContextThread %p.\n", wine_dbgstr_longlong(regs.rcx), pNtGetContextThread);
+ ok((regs.eflags & 0x400) != 0, "Expected direction flag to be set in EFLAGS (%#x).\n", regs.eflags);
status = func(GetCurrentThread(), &context, ®s, pNtSetContextThread);
ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
ok((BYTE *)regs.rcx > (BYTE *)pNtSetContextThread && (BYTE *)regs.rcx < (BYTE *)pNtSetContextThread + 0x20,
"Got unexpected rcx %s, pNtSetContextThread %p.\n", wine_dbgstr_longlong(regs.rcx), pNtSetContextThread);
+ ok((regs.eflags & 0x400) != 0, "Expected direction flag to be set in EFLAGS (%#x).\n", regs.eflags);
}
#elif defined(__arm__)
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/314
June 26, 2022
[PATCH 0/2] MR314: ntdll/tests: Preserve EFLAGS across syscall on x64.
by Jinoh Kang (@iamahuman)
Signed-off-by: Jinoh Kang <jinoh.kang.kr(a)gmail.com>
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/314
June 26, 2022
Re: [PATCH v3 0/9] MR272: d3dx10: Add D3DX10CreateThreadPump implementation.
by Piotr Caban (@piotr)
On Wed Jun 22 18:22:04 2022 +0000, Josh Simmons wrote:
> Unsolicited nit, but since these are separately locked queues they
> should probably be padded out to be on their own cache lines to avoid
> false sharing.
> (No idea whether this API is hot enough for that to be truly important, though)
I don't think it will need additional optimizations. The fact that I have used separate locks is just an implementation detail. We can try to optimize it further in future if needed.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/272#note_2719
June 26, 2022