[PATCH 5/5] dxgi: Implement adapter video memory budget change notification.

Zebediah Figura zfigura at codeweavers.com
Fri May 20 01:16:39 CDT 2022


On 5/18/22 01:49, Zhiyi Zhang wrote:
> @@ -1046,6 +1060,135 @@ 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;

The test also waits for 1 second, which seems like it'd be liable to 
fail intermittently, if I read this correctly. Should we increase the 
polling interval here? (Or reduce it in the test?)

> +    }
> +
> +    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;
> +    HANDLE thread = NULL;
> +    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);
> +        thread = CreateThread(NULL, 0, notification_thread_func, notification_thread_stop_event,
> +                CREATE_SUSPENDED, NULL);
> +        notification_thread = thread;
> +    }
> +    wined3d_mutex_unlock();
> +    if (thread)
> +        ResumeThread(thread);

What's the reason for creating the thread suspended?

> +    return WINED3D_OK;
> +}



More information about the wine-devel mailing list