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 7/8] d3dx10: Add ID3DX10ThreadPump:PurgeAllItems implementation.
by Piotr Caban
From: Piotr Caban <piotr(a)codeweavers.com>
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
---
dlls/d3dx10_43/d3dx10_43_main.c | 48 +++++++++++++++++++++++++++++++--
1 file changed, 46 insertions(+), 2 deletions(-)
diff --git a/dlls/d3dx10_43/d3dx10_43_main.c b/dlls/d3dx10_43/d3dx10_43_main.c
index 5804a1058b0..df1e3f413f5 100644
--- a/dlls/d3dx10_43/d3dx10_43_main.c
+++ b/dlls/d3dx10_43/d3dx10_43_main.c
@@ -404,8 +404,52 @@ static HRESULT WINAPI thread_pump_ProcessDeviceWorkItems(ID3DX10ThreadPump *ifac
static HRESULT WINAPI thread_pump_PurgeAllItems(ID3DX10ThreadPump *iface)
{
- FIXME("iface %p stub!\n", iface);
- return E_NOTIMPL;
+ struct thread_pump *thread_pump = impl_from_ID3DX10ThreadPump(iface);
+ struct list list = LIST_INIT(list);
+ struct work_item *work_item;
+ LONG v;
+
+ TRACE("iface %p.\n", iface);
+
+ while (1)
+ {
+ AcquireSRWLockExclusive(&thread_pump->io_lock);
+ list_move_tail(&list, &thread_pump->io_queue);
+ thread_pump->io_count = 0;
+ ReleaseSRWLockExclusive(&thread_pump->io_lock);
+
+ AcquireSRWLockExclusive(&thread_pump->proc_lock);
+ list_move_tail(&list, &thread_pump->proc_queue);
+ thread_pump->proc_count = 0;
+ ReleaseSRWLockExclusive(&thread_pump->proc_lock);
+
+ while (!list_empty(&list))
+ {
+ work_item = LIST_ENTRY(list_head(&list), struct work_item, entry);
+ list_remove(&work_item->entry);
+ work_item_free(work_item, TRUE);
+ if (!InterlockedDecrement(&thread_pump->processing_count))
+ RtlWakeAddressAll((void *)&thread_pump->processing_count);
+ }
+
+ if (!(v = thread_pump->processing_count))
+ break;
+
+ RtlWaitOnAddress((void *)&thread_pump->processing_count, &v, sizeof(v), NULL);
+ }
+
+ AcquireSRWLockExclusive(&thread_pump->device_lock);
+ list_move_tail(&list, &thread_pump->device_queue);
+ thread_pump->device_count = 0;
+ ReleaseSRWLockExclusive(&thread_pump->device_lock);
+
+ while(!list_empty(&list))
+ {
+ work_item = LIST_ENTRY(list_head(&list), struct work_item, entry);
+ list_remove(&work_item->entry);
+ work_item_free(work_item, TRUE);
+ }
+ return S_OK;
}
static HRESULT WINAPI thread_pump_GetQueueStatus(ID3DX10ThreadPump *iface,
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/272
June 18, 2022
[PATCH 6/8] d3dx10: Add ID3DX10ThreadPump:GetQueueStatus implementation.
by Piotr Caban
From: Piotr Caban <piotr(a)codeweavers.com>
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
---
dlls/d3dx10_43/d3dx10_43_main.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/dlls/d3dx10_43/d3dx10_43_main.c b/dlls/d3dx10_43/d3dx10_43_main.c
index 198cf14b7d0..5804a1058b0 100644
--- a/dlls/d3dx10_43/d3dx10_43_main.c
+++ b/dlls/d3dx10_43/d3dx10_43_main.c
@@ -411,9 +411,15 @@ static HRESULT WINAPI thread_pump_PurgeAllItems(ID3DX10ThreadPump *iface)
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",
+ struct thread_pump *thread_pump = impl_from_ID3DX10ThreadPump(iface);
+
+ TRACE("iface %p, io_queue %p, process_queue %p, device_queue %p.\n",
iface, io_queue, process_queue, device_queue);
- return E_NOTIMPL;
+
+ *io_queue = thread_pump->io_count;
+ *process_queue = thread_pump->proc_count;
+ *device_queue = thread_pump->device_count;
+ return S_OK;
}
static const ID3DX10ThreadPumpVtbl thread_pump_vtbl =
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/272
June 18, 2022
[PATCH 5/8] d3dx10: Add ID3DX10ThreadPump:WaitForAllItems implementation.
by Piotr Caban
From: Piotr Caban <piotr(a)codeweavers.com>
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
---
dlls/d3dx10_43/d3dx10_43_main.c | 30 +++++++++++++++++++++++++-----
1 file changed, 25 insertions(+), 5 deletions(-)
diff --git a/dlls/d3dx10_43/d3dx10_43_main.c b/dlls/d3dx10_43/d3dx10_43_main.c
index 795d052af83..198cf14b7d0 100644
--- a/dlls/d3dx10_43/d3dx10_43_main.c
+++ b/dlls/d3dx10_43/d3dx10_43_main.c
@@ -350,8 +350,24 @@ static UINT WINAPI thread_pump_GetWorkItemCount(ID3DX10ThreadPump *iface)
static HRESULT WINAPI thread_pump_WaitForAllItems(ID3DX10ThreadPump *iface)
{
- FIXME("iface %p stub!\n", iface);
- return E_NOTIMPL;
+ struct thread_pump *thread_pump = impl_from_ID3DX10ThreadPump(iface);
+ HRESULT hr;
+ LONG v;
+
+ TRACE("iface %p.\n", iface);
+
+ while(1)
+ {
+ if (FAILED((hr = ID3DX10ThreadPump_ProcessDeviceWorkItems(iface, UINT_MAX))))
+ return hr;
+
+ if (!(v = thread_pump->processing_count))
+ break;
+
+ RtlWaitOnAddress((void *)&thread_pump->processing_count, &v, sizeof(v), NULL);
+ }
+
+ return ID3DX10ThreadPump_ProcessDeviceWorkItems(iface, UINT_MAX);
}
static HRESULT WINAPI thread_pump_ProcessDeviceWorkItems(ID3DX10ThreadPump *iface, UINT count)
@@ -447,7 +463,8 @@ 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);
+ if (!InterlockedDecrement(&thread_pump->processing_count))
+ RtlWakeAddressAll((void *)&thread_pump->processing_count);
continue;
}
@@ -503,7 +520,8 @@ 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);
+ if (!InterlockedDecrement(&thread_pump->processing_count))
+ RtlWakeAddressAll((void *)&thread_pump->processing_count);
continue;
}
@@ -518,7 +536,8 @@ 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);
+ if (!InterlockedDecrement(&thread_pump->processing_count))
+ RtlWakeAddressAll((void *)&thread_pump->processing_count);
continue;
}
@@ -533,6 +552,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);
+ RtlWakeAddressAll((void *)&thread_pump->processing_count);
ReleaseSRWLockExclusive(&thread_pump->device_lock);
}
return 0;
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/272
June 18, 2022
[PATCH 4/8] d3dx10: Add ID3DX10ThreadPump:ProcessDeviceWorkItems implementation.
by Piotr Caban
From: Piotr Caban <piotr(a)codeweavers.com>
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
---
dlls/d3dx10_43/d3dx10_43_main.c | 30 ++++++++++++++++++++++++++++--
1 file changed, 28 insertions(+), 2 deletions(-)
diff --git a/dlls/d3dx10_43/d3dx10_43_main.c b/dlls/d3dx10_43/d3dx10_43_main.c
index 5d718f6de2b..795d052af83 100644
--- a/dlls/d3dx10_43/d3dx10_43_main.c
+++ b/dlls/d3dx10_43/d3dx10_43_main.c
@@ -356,8 +356,34 @@ static HRESULT WINAPI thread_pump_WaitForAllItems(ID3DX10ThreadPump *iface)
static HRESULT WINAPI thread_pump_ProcessDeviceWorkItems(ID3DX10ThreadPump *iface, UINT count)
{
- FIXME("iface %p, count %u stub!\n", iface, count);
- return E_NOTIMPL;
+ struct thread_pump *thread_pump = impl_from_ID3DX10ThreadPump(iface);
+ struct work_item *work_item;
+ HRESULT hr;
+ UINT i;
+
+ TRACE("iface %p, count %u.\n", iface, count);
+
+ for (i = 0; i < count; i++)
+ {
+ AcquireSRWLockExclusive(&thread_pump->device_lock);
+ if (!thread_pump->device_count)
+ {
+ ReleaseSRWLockExclusive(&thread_pump->device_lock);
+ break;
+ }
+
+ thread_pump->device_count--;
+ work_item = LIST_ENTRY(list_head(&thread_pump->device_queue), struct work_item, entry);
+ list_remove(&work_item->entry);
+ ReleaseSRWLockExclusive(&thread_pump->device_lock);
+
+ hr = ID3DX10DataProcessor_CreateDeviceObject(work_item->processor, work_item->object);
+ if (work_item->result)
+ *work_item->result = hr;
+ work_item_free(work_item, FALSE);
+ }
+
+ return S_OK;
}
static HRESULT WINAPI thread_pump_PurgeAllItems(ID3DX10ThreadPump *iface)
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/272
June 18, 2022
[PATCH 3/8] 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/d3dx10_43_main.c | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/dlls/d3dx10_43/d3dx10_43_main.c b/dlls/d3dx10_43/d3dx10_43_main.c
index d66d83d3e7f..5d718f6de2b 100644
--- a/dlls/d3dx10_43/d3dx10_43_main.c
+++ b/dlls/d3dx10_43/d3dx10_43_main.c
@@ -205,6 +205,8 @@ struct thread_pump
ID3DX10ThreadPump ID3DX10ThreadPump_iface;
LONG refcount;
+ LONG processing_count;
+
SRWLOCK io_lock;
UINT io_count;
struct list io_queue;
@@ -324,6 +326,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);
@@ -334,8 +337,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)
@@ -411,6 +421,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;
}
@@ -466,6 +477,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;
}
@@ -480,6 +492,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;
}
@@ -493,6 +506,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 18, 2022
[PATCH 2/8] 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/d3dx10_43_main.c | 251 +++++++++++++++++++++++++++++++-
1 file changed, 248 insertions(+), 3 deletions(-)
diff --git a/dlls/d3dx10_43/d3dx10_43_main.c b/dlls/d3dx10_43/d3dx10_43_main.c
index 357b0257496..d66d83d3e7f 100644
--- a/dlls/d3dx10_43/d3dx10_43_main.c
+++ b/dlls/d3dx10_43/d3dx10_43_main.c
@@ -29,10 +29,13 @@
#include "winbase.h"
#include "winuser.h"
#include "objbase.h"
+#include "winternl.h"
#include "d3d10_1.h"
#include "d3dx10.h"
+#include "wine/list.h"
+
WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
/***********************************************************************
@@ -177,10 +180,45 @@ HRESULT WINAPI D3DX10LoadTextureFromTexture(ID3D10Resource *src_texture, D3DX10_
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;
+ UINT io_count;
+ struct list io_queue;
+
+ SRWLOCK proc_lock;
+ UINT proc_count;
+ struct list proc_queue;
+
+ SRWLOCK device_lock;
+ UINT device_count;
+ struct list device_queue;
+
+ int threads_no;
+ HANDLE threads[1];
};
static inline struct thread_pump *impl_from_ID3DX10ThreadPump(ID3DX10ThreadPump *iface)
@@ -219,11 +257,48 @@ 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 *iter, *next;
+ struct list list;
+ 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);
+ RtlWakeAddressAll((void *)&thread_pump->io_count);
+
+ AcquireSRWLockExclusive(&thread_pump->proc_lock);
+ thread_pump->proc_count = THREAD_PUMP_EXITING;
+ ReleaseSRWLockExclusive(&thread_pump->proc_lock);
+ RtlWakeAddressAll((void *)&thread_pump->proc_count);
+
+ AcquireSRWLockExclusive(&thread_pump->device_lock);
+ thread_pump->device_count = THREAD_PUMP_EXITING;
+ ReleaseSRWLockExclusive(&thread_pump->device_lock);
+
+ for (i = 0; i < thread_pump->threads_no; 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(iter, next, &list, struct work_item, entry)
+ {
+ list_remove(&iter->entry);
+ work_item_free(iter, TRUE);
+ }
+
free(thread_pump);
+ }
return refcount;
}
@@ -231,9 +306,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);
+ RtlWakeAddressAll((void *)&thread_pump->io_count);
+ return S_OK;
}
static UINT WINAPI thread_pump_GetWorkItemCount(ID3DX10ThreadPump *iface)
@@ -281,20 +377,169 @@ 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;
+ UINT zero = 0;
+ HRESULT hr;
+
+ TRACE("%p thread started.\n", thread_pump);
+
+ while (1)
+ {
+ RtlWaitOnAddress((void *)&thread_pump->io_count, &zero, sizeof(zero), NULL);
+ AcquireSRWLockExclusive(&thread_pump->io_lock);
+ if (!thread_pump->io_count)
+ {
+ ReleaseSRWLockExclusive(&thread_pump->io_lock);
+ continue;
+ }
+ 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);
+ RtlWakeAddressAll((void *)&thread_pump->proc_count);
+ }
+ return 0;
+}
+
+static DWORD WINAPI proc_thread(void *arg)
+{
+ struct thread_pump *thread_pump = arg;
+ struct work_item *work_item;
+ UINT zero = 0;
+ SIZE_T size;
+ void *data;
+ HRESULT hr;
+
+ TRACE("%p thread started.\n", thread_pump);
+
+ while (1)
+ {
+ RtlWaitOnAddress((void *)&thread_pump->proc_count, &zero, sizeof(zero), NULL);
+ AcquireSRWLockExclusive(&thread_pump->proc_lock);
+ if (!thread_pump->proc_count)
+ {
+ ReleaseSRWLockExclusive(&thread_pump->proc_lock);
+ continue;
+ }
+ 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);
+ list_init(&object->io_queue);
+ InitializeSRWLock(&object->proc_lock);
+ list_init(&object->proc_queue);
+ InitializeSRWLock(&object->device_lock);
+ list_init(&object->device_queue);
+ object->threads_no = io_threads + proc_threads;
+
+ for (i = 0; i < object->threads_no; 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 18, 2022
[PATCH 1/8] 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/d3dx10_43.spec | 2 +-
dlls/d3dx10_43/d3dx10_43_main.c | 123 ++++++++++++++++++++++++++++++++
include/d3dx10core.h | 1 +
3 files changed, 125 insertions(+), 1 deletion(-)
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/dlls/d3dx10_43/d3dx10_43_main.c b/dlls/d3dx10_43/d3dx10_43_main.c
index ec7407508d3..357b0257496 100644
--- a/dlls/d3dx10_43/d3dx10_43_main.c
+++ b/dlls/d3dx10_43/d3dx10_43_main.c
@@ -176,3 +176,126 @@ HRESULT WINAPI D3DX10LoadTextureFromTexture(ID3D10Resource *src_texture, D3DX10_
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/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 18, 2022
[PATCH 0/8] 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.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/272
June 18, 2022
Re: [PATCH v2 0/5] MR257: d3dx: Add support for ID3DX10ThreadPump parameter in D3DX10CreateTexture* functions
by Piotr Caban (@piotr)
On Sat Jun 18 11:22:29 2022 +0000, Matteo Bruni wrote:
> Any particular reason the new test isn't inside the for loop right above
> so to check every test_image[] with the thread pump?
It will be added in next set of patches that implements D3DX10CreateThreadPump so it also tests thread pump implementation.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/257#note_2310
June 18, 2022
[PATCH] ntdll: Implement NtQueryVolumeInformationFile FileFsFullSizeInformation.
by Michal Suchanek
Some programs refuse to write to disk when they cannot determine there
is enough disk space. Implement the ntdll subfunction for it.
Signed-off-by: Michal Suchanek <msuchanek(a)suse.de>
---
dlls/ntdll/tests/file.c | 8 +-------
dlls/ntdll/unix/file.c | 24 ++++++++++++++++++++++--
2 files changed, 23 insertions(+), 9 deletions(-)
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index 106413a83fc..ede578081fc 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -1289,7 +1289,7 @@ static void test_file_full_size_information(void)
/* Assume No Quota Settings configured on Wine Testbot */
res = pNtQueryVolumeInformationFile(h, &io, &ffsi, sizeof ffsi, FileFsFullSizeInformation);
- todo_wine ok(res == STATUS_SUCCESS, "cannot get attributes, res %lx\n", res);
+ ok(res == STATUS_SUCCESS, "cannot get attributes, res %lx\n", res);
res = pNtQueryVolumeInformationFile(h, &io, &fsi, sizeof fsi, FileFsSizeInformation);
ok(res == STATUS_SUCCESS, "cannot get attributes, res %lx\n", res);
@@ -1305,8 +1305,6 @@ static void test_file_full_size_information(void)
ok(fsi.BytesPerSector == 512, "[fsi] BytesPerSector expected 512, got %ld\n",fsi.BytesPerSector);
ok(fsi.SectorsPerAllocationUnit == 8, "[fsi] SectorsPerAllocationUnit expected 8, got %ld\n",fsi.SectorsPerAllocationUnit);
- todo_wine
- {
ok(ffsi.TotalAllocationUnits.QuadPart > 0,
"[ffsi] TotalAllocationUnits expected positive, got negative value 0x%s\n",
wine_dbgstr_longlong(ffsi.TotalAllocationUnits.QuadPart));
@@ -1324,14 +1322,10 @@ static void test_file_full_size_information(void)
"[ffsi] CallerAvailableAllocationUnits error fsi:0x%s, ffsi: 0x%s\n",
wine_dbgstr_longlong(fsi.AvailableAllocationUnits.QuadPart),
wine_dbgstr_longlong(ffsi.CallerAvailableAllocationUnits.QuadPart));
- }
/* Assume file system is NTFS */
- todo_wine
- {
ok(ffsi.BytesPerSector == 512, "[ffsi] BytesPerSector expected 512, got %ld\n",ffsi.BytesPerSector);
ok(ffsi.SectorsPerAllocationUnit == 8, "[ffsi] SectorsPerAllocationUnit expected 8, got %ld\n",ffsi.SectorsPerAllocationUnit);
- }
CloseHandle( h );
}
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
index cc8bf0c6e82..c2586ca39d8 100644
--- a/dlls/ntdll/unix/file.c
+++ b/dlls/ntdll/unix/file.c
@@ -6630,9 +6630,29 @@ NTSTATUS WINAPI NtQueryVolumeInformationFile( HANDLE handle, IO_STATUS_BLOCK *io
break;
case FileFsFullSizeInformation:
- FIXME( "%p: full size info not supported\n", handle );
- status = STATUS_NOT_IMPLEMENTED;
+ {
+ FILE_FS_FULL_SIZE_INFORMATION *info = buffer;
+ struct statfs stfs;
+ unsigned long sector_size = 512;
+
+ if (length < sizeof(FILE_FS_FULL_SIZE_INFORMATION))
+ {
+ status = STATUS_INFO_LENGTH_MISMATCH;
+ break;
+ }
+
+ status = STATUS_UNSUCCESSFUL;
+ if (!fstatfs( fd, &stfs ))
+ {
+ info->TotalAllocationUnits.QuadPart = stfs.f_blocks;
+ info->CallerAvailableAllocationUnits.QuadPart = stfs.f_bavail;
+ info->ActualAvailableAllocationUnits.QuadPart = stfs.f_bfree;
+ info->SectorsPerAllocationUnit = stfs.f_bsize / sector_size;
+ info->BytesPerSector = sector_size;
+ status = STATUS_SUCCESS;
+ }
break;
+ }
case FileFsObjectIdInformation:
FIXME( "%p: object id info not supported\n", handle );
--
2.36.1
June 18, 2022