[PATCH 5/5] dxgi: Implement adapter video memory budget change notification.
Zhiyi Zhang
zzhang at codeweavers.com
Fri May 20 02:15:53 CDT 2022
On 5/20/22 15:05, Zhiyi Zhang wrote:
>
> 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.
>
Are you worried that the event may not be fired within 1 second? If an adapter has any memory budget, the event will be immediately fired due to
notification->last_local_budget and notification->last_non_local_budget being initialized to zero. The test's purpose is to test the event should be
fired immediately, so the 1 second wait doesn't really matter.
Thanks,
Zhiyi
>>> + }
>>> +
>>> + 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