mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-06 08:39:34 +00:00
dxgi: Implement adapter video memory budget change notification.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51665 Signed-off-by: Zhiyi Zhang <zzhang@codeweavers.com> Signed-off-by: Zebediah Figura <zfigura@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
54c27f69f6
commit
fd6e137dfe
|
@ -333,15 +333,22 @@ static HRESULT STDMETHODCALLTYPE dxgi_adapter_SetVideoMemoryReservation(IWineDXG
|
|||
static HRESULT STDMETHODCALLTYPE dxgi_adapter_RegisterVideoMemoryBudgetChangeNotificationEvent(
|
||||
IWineDXGIAdapter *iface, HANDLE event, DWORD *cookie)
|
||||
{
|
||||
FIXME("iface %p, event %p, cookie %p stub!\n", iface, event, cookie);
|
||||
struct dxgi_adapter *adapter = impl_from_IWineDXGIAdapter(iface);
|
||||
|
||||
return E_NOTIMPL;
|
||||
TRACE("iface %p, event %p, cookie %p.\n", iface, event, cookie);
|
||||
|
||||
if (!event || !cookie)
|
||||
return DXGI_ERROR_INVALID_CALL;
|
||||
|
||||
return wined3d_adapter_register_budget_change_notification(adapter->wined3d_adapter, event, cookie);
|
||||
}
|
||||
|
||||
static void STDMETHODCALLTYPE dxgi_adapter_UnregisterVideoMemoryBudgetChangeNotification(
|
||||
IWineDXGIAdapter *iface, DWORD cookie)
|
||||
{
|
||||
FIXME("iface %p, cookie %#lx stub!\n", iface, cookie);
|
||||
TRACE("iface %p, cookie %#lx.\n", iface, cookie);
|
||||
|
||||
wined3d_adapter_unregister_budget_change_notification(cookie);
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE dxgi_adapter_GetDesc3(IWineDXGIAdapter *iface, DXGI_ADAPTER_DESC3 *desc)
|
||||
|
|
|
@ -7539,16 +7539,13 @@ static void test_video_memory_budget_notification(void)
|
|||
goto done;
|
||||
|
||||
hr = IDXGIAdapter3_RegisterVideoMemoryBudgetChangeNotificationEvent(adapter3, NULL, &cookie);
|
||||
todo_wine
|
||||
ok(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#lx.\n", hr);
|
||||
|
||||
event = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||
hr = IDXGIAdapter3_RegisterVideoMemoryBudgetChangeNotificationEvent(adapter3, event, NULL);
|
||||
todo_wine
|
||||
ok(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#lx.\n", hr);
|
||||
|
||||
hr = IDXGIAdapter3_RegisterVideoMemoryBudgetChangeNotificationEvent(adapter3, event, &cookie);
|
||||
todo_wine
|
||||
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
hr = IDXGIAdapter3_QueryVideoMemoryInfo(adapter3, 0, DXGI_MEMORY_SEGMENT_GROUP_LOCAL, &memory_info);
|
||||
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
|
@ -7560,7 +7557,6 @@ static void test_video_memory_budget_notification(void)
|
|||
if (memory_info.Budget)
|
||||
{
|
||||
ret = WaitForSingleObject(event, 1000);
|
||||
todo_wine
|
||||
ok(ret == WAIT_OBJECT_0, "Expected event fired.\n");
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include "wined3d_private.h"
|
||||
#include "winternl.h"
|
||||
#include "wine/list.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
|
||||
WINE_DECLARE_DEBUG_CHANNEL(winediag);
|
||||
|
@ -38,6 +39,19 @@ enum wined3d_driver_model
|
|||
DRIVER_MODEL_NT6X
|
||||
};
|
||||
|
||||
struct wined3d_adapter_budget_change_notification
|
||||
{
|
||||
const struct wined3d_adapter *adapter;
|
||||
HANDLE event;
|
||||
DWORD cookie;
|
||||
UINT64 last_local_budget;
|
||||
UINT64 last_non_local_budget;
|
||||
struct list entry;
|
||||
};
|
||||
|
||||
static struct list adapter_budget_change_notifications = LIST_INIT( adapter_budget_change_notifications );
|
||||
static HANDLE notification_thread, notification_thread_stop_event;
|
||||
|
||||
/* The d3d device ID */
|
||||
static const GUID IID_D3DDEVICE_D3DUID = { 0xaeb2cdd4, 0x6e41, 0x43ea, { 0x94,0x1c,0x83,0x61,0xcc,0x76,0x07,0x81 } };
|
||||
|
||||
|
@ -1046,6 +1060,131 @@ HRESULT CDECL wined3d_adapter_get_video_memory_info(const struct wined3d_adapter
|
|||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
static DWORD CALLBACK notification_thread_func(void *stop_event)
|
||||
{
|
||||
struct wined3d_adapter_budget_change_notification *notification;
|
||||
struct wined3d_video_memory_info info;
|
||||
HRESULT hr;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
wined3d_mutex_lock();
|
||||
LIST_FOR_EACH_ENTRY(notification, &adapter_budget_change_notifications,
|
||||
struct wined3d_adapter_budget_change_notification, entry)
|
||||
{
|
||||
hr = wined3d_adapter_get_video_memory_info(notification->adapter, 0,
|
||||
WINED3D_MEMORY_SEGMENT_GROUP_LOCAL, &info);
|
||||
if (SUCCEEDED(hr) && info.budget != notification->last_local_budget)
|
||||
{
|
||||
notification->last_local_budget = info.budget;
|
||||
SetEvent(notification->event);
|
||||
continue;
|
||||
}
|
||||
|
||||
hr = wined3d_adapter_get_video_memory_info(notification->adapter, 0,
|
||||
WINED3D_MEMORY_SEGMENT_GROUP_NON_LOCAL, &info);
|
||||
if (SUCCEEDED(hr) && info.budget != notification->last_non_local_budget)
|
||||
{
|
||||
notification->last_non_local_budget = info.budget;
|
||||
SetEvent(notification->event);
|
||||
}
|
||||
}
|
||||
wined3d_mutex_unlock();
|
||||
|
||||
if (WaitForSingleObject(stop_event, 1000) == WAIT_OBJECT_0)
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
HRESULT CDECL wined3d_adapter_register_budget_change_notification(const struct wined3d_adapter *adapter,
|
||||
HANDLE event, DWORD *cookie)
|
||||
{
|
||||
static DWORD cookie_counter;
|
||||
static BOOL wrapped;
|
||||
struct wined3d_adapter_budget_change_notification *notification, *new_notification;
|
||||
BOOL found = FALSE;
|
||||
|
||||
new_notification = heap_alloc_zero(sizeof(*new_notification));
|
||||
if (!new_notification)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
wined3d_mutex_lock();
|
||||
new_notification->adapter = adapter;
|
||||
new_notification->event = event;
|
||||
new_notification->cookie = cookie_counter++;
|
||||
if (cookie_counter < new_notification->cookie)
|
||||
wrapped = TRUE;
|
||||
if (wrapped)
|
||||
{
|
||||
while (TRUE)
|
||||
{
|
||||
LIST_FOR_EACH_ENTRY(notification, &adapter_budget_change_notifications,
|
||||
struct wined3d_adapter_budget_change_notification, entry)
|
||||
{
|
||||
if (notification->cookie == new_notification->cookie)
|
||||
{
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
break;
|
||||
|
||||
new_notification->cookie = cookie_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
*cookie = new_notification->cookie;
|
||||
list_add_head(&adapter_budget_change_notifications, &new_notification->entry);
|
||||
|
||||
if (!notification_thread)
|
||||
{
|
||||
notification_thread_stop_event = CreateEventW(0, FALSE, FALSE, NULL);
|
||||
notification_thread = CreateThread(NULL, 0, notification_thread_func,
|
||||
notification_thread_stop_event, 0, NULL);
|
||||
}
|
||||
wined3d_mutex_unlock();
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
HRESULT CDECL wined3d_adapter_unregister_budget_change_notification(DWORD cookie)
|
||||
{
|
||||
struct wined3d_adapter_budget_change_notification *notification;
|
||||
HANDLE thread, thread_stop_event;
|
||||
|
||||
wined3d_mutex_lock();
|
||||
LIST_FOR_EACH_ENTRY(notification, &adapter_budget_change_notifications,
|
||||
struct wined3d_adapter_budget_change_notification, entry)
|
||||
{
|
||||
if (notification->cookie == cookie)
|
||||
{
|
||||
list_remove(¬ification->entry);
|
||||
heap_free(notification);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!list_empty(&adapter_budget_change_notifications))
|
||||
{
|
||||
wined3d_mutex_unlock();
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
thread = notification_thread;
|
||||
thread_stop_event = notification_thread_stop_event;
|
||||
notification_thread = NULL;
|
||||
notification_thread_stop_event = NULL;
|
||||
wined3d_mutex_unlock();
|
||||
SetEvent(thread_stop_event);
|
||||
WaitForSingleObject(thread, INFINITE);
|
||||
CloseHandle(thread);
|
||||
CloseHandle(thread_stop_event);
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
HRESULT CDECL wined3d_register_software_device(struct wined3d *wined3d, void *init_function)
|
||||
{
|
||||
FIXME("wined3d %p, init_function %p stub!\n", wined3d, init_function);
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
@ cdecl wined3d_adapter_get_output(ptr long)
|
||||
@ cdecl wined3d_adapter_get_output_count(ptr)
|
||||
@ cdecl wined3d_adapter_get_video_memory_info(ptr long long ptr)
|
||||
@ cdecl wined3d_adapter_register_budget_change_notification(ptr ptr ptr)
|
||||
@ cdecl wined3d_adapter_unregister_budget_change_notification(long)
|
||||
|
||||
@ cdecl wined3d_blend_state_create(ptr ptr ptr ptr ptr)
|
||||
@ cdecl wined3d_blend_state_decref(ptr)
|
||||
|
|
|
@ -2364,6 +2364,9 @@ unsigned int __cdecl wined3d_adapter_get_output_count(const struct wined3d_adapt
|
|||
HRESULT __cdecl wined3d_adapter_get_video_memory_info(const struct wined3d_adapter *adapter,
|
||||
unsigned int node_idx, enum wined3d_memory_segment_group group,
|
||||
struct wined3d_video_memory_info *info);
|
||||
HRESULT __cdecl wined3d_adapter_register_budget_change_notification(const struct wined3d_adapter *adapter,
|
||||
HANDLE event, DWORD *cookie);
|
||||
HRESULT __cdecl wined3d_adapter_unregister_budget_change_notification(DWORD cookie);
|
||||
|
||||
HRESULT __cdecl wined3d_buffer_create(struct wined3d_device *device, const struct wined3d_buffer_desc *desc,
|
||||
const struct wined3d_sub_resource_data *data, void *parent, const struct wined3d_parent_ops *parent_ops,
|
||||
|
|
Loading…
Reference in a new issue