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

Zhiyi Zhang zzhang at codeweavers.com
Fri May 20 02:05:15 CDT 2022



On 5/20/22 14:16, Zebediah Figura wrote:
> 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?)

I can probably reduce the timeout in the test. It was picked rather randomly and didn't mean the test would fail intermittently.


>
>> +    }
>> +
>> +    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?

Because the thread also calls wined3d_mutex_lock/unlock().

>
>> +    return WINED3D_OK;
>> +}
>




More information about the wine-devel mailing list