[PATCH 04/10] wined3d: Add functions to support device local and non-local memory info management.

Conor McCarthy cmccarthy at codeweavers.com
Thu Nov 7 08:54:36 CST 2019


Signed-off-by: Conor McCarthy <cmccarthy at codeweavers.com>
---
 dlls/wined3d/directx.c    | 178 ++++++++++++++++++++++++++++++++++++++
 dlls/wined3d/wined3d.spec |   5 ++
 include/wine/wined3d.h    |  17 ++++
 3 files changed, 200 insertions(+)

diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index bf4fad31..ee6715ca 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -1377,6 +1377,184 @@ fail:
     return WINED3DERR_INVALIDCALL;
 }
 
+HRESULT CDECL wined3d_update_adapter_memory_info(const struct wined3d *wined3d, unsigned int adapter_idx,
+        unsigned int non_local, UINT64 bytes_total, UINT64 bytes_used)
+{
+    struct wined3d_adapter *adapter;
+    DWORD i;
+
+    wined3d_mutex_lock();
+
+    if (adapter_idx >= wined3d->adapter_count || non_local >= ARRAY_SIZE(adapter->memory_usage))
+        goto fail;
+
+    adapter = wined3d->adapters[adapter_idx];
+    adapter->memory_usage[non_local].bytes_used = bytes_used;
+    if (non_local)
+        adapter->driver_info.sysmem_bytes = bytes_total;
+    else
+        adapter->driver_info.vram_bytes = bytes_total;
+
+    for (i = 0; i < adapter->event_count; ++i)
+        if (adapter->memory_events[i])
+            SetEvent(adapter->memory_events[i]);
+
+    wined3d_mutex_unlock();
+
+    return WINED3D_OK;
+
+fail:
+    wined3d_mutex_unlock();
+    return E_INVALIDARG;
+}
+
+HRESULT CDECL wined3d_get_adapter_memory_info(const struct wined3d *wined3d, unsigned int adapter_idx,
+        unsigned int non_local, struct wined3d_adapter_memory_info *info)
+{
+    const struct wined3d_adapter *adapter;
+
+    TRACE("wined3d %p, adapter_idx %u, non_local %u, info %p.\n",
+            wined3d, adapter_idx, non_local, info);
+
+    wined3d_mutex_lock();
+
+    if (adapter_idx >= wined3d->adapter_count || non_local >= ARRAY_SIZE(adapter->memory_usage))
+        goto fail;
+
+    adapter = wined3d->adapters[adapter_idx];
+
+    /* vram_bytes may be zero for a UMA adapter. DXGI defines all memory as local for UMA adapters. */
+    if (!adapter->driver_info.vram_bytes)
+        info->total = non_local ? 0 : adapter->driver_info.sysmem_bytes;
+    else
+        info->total = non_local ? adapter->driver_info.sysmem_bytes : adapter->driver_info.vram_bytes;
+    info->used = adapter->memory_usage[non_local].bytes_used;
+    info->reserved = adapter->memory_usage[non_local].bytes_reserved;
+
+    wined3d_mutex_unlock();
+
+    return WINED3D_OK;
+
+fail:
+    wined3d_mutex_unlock();
+    return E_INVALIDARG;
+}
+
+HRESULT CDECL wined3d_set_adapter_reserved_memory(const struct wined3d *wined3d, unsigned int adapter_idx,
+        unsigned int non_local, UINT64 reservation)
+{
+    struct wined3d_adapter_memory_info memory_info;
+    struct wined3d_adapter *adapter;
+    HRESULT hr;
+
+    TRACE("wined3d %p, adapter_idx %u, non_local %u, reservation 0x%s.\n",
+            wined3d, adapter_idx, non_local, wine_dbgstr_longlong(reservation));
+
+    if (FAILED(hr = wined3d_get_adapter_memory_info(wined3d, adapter_idx, non_local, &memory_info)))
+        return hr;
+    if (memory_info.total && reservation > memory_info.total)
+        return E_INVALIDARG;
+
+    /* FIXME: Windows returns E_INVALIDARG if non-local and a non-zero reservation are specified for
+     * a UMA adapter. UMA status is unknown unless adapter->driver_info.vram_bytes is zero. */
+
+    wined3d_mutex_lock();
+
+    if (adapter_idx >= wined3d->adapter_count || non_local >= ARRAY_SIZE(adapter->memory_usage))
+        goto fail;
+
+    FIXME("Memory reservation sizes are returned if queried but otherwise are ignored.\n");
+    adapter = wined3d->adapters[adapter_idx];
+    adapter->memory_usage[non_local].bytes_reserved = reservation;
+
+    wined3d_mutex_unlock();
+
+    return WINED3D_OK;
+
+fail:
+    wined3d_mutex_unlock();
+    return E_INVALIDARG;
+}
+
+static BOOL wined3d_set_unused_event_handle(struct wined3d_adapter *adapter, HANDLE event, DWORD *cookie)
+{
+    DWORD i;
+    for (i = 0; i < adapter->event_count; ++i)
+    {
+        if (!adapter->memory_events[i])
+        {
+            adapter->memory_events[i] = event;
+            *cookie = i;
+            return TRUE;
+        }
+    }
+    return FALSE;
+}
+
+HRESULT CDECL wined3d_register_adapter_memory_event(const struct wined3d *wined3d, unsigned int adapter_idx,
+        HANDLE event, DWORD *cookie)
+{
+    HRESULT hr = E_INVALIDARG;
+    struct wined3d_adapter *adapter;
+    HANDLE *new_buffer;
+
+    TRACE("wined3d %p, adapter_idx %u, event %p, cookie %p.\n",
+            wined3d, adapter_idx, event, cookie);
+
+    if (!cookie)
+        return E_INVALIDARG;
+
+    wined3d_mutex_lock();
+
+    if (adapter_idx >= wined3d->adapter_count)
+        goto done;
+
+    adapter = wined3d->adapters[adapter_idx];
+    if (!wined3d_set_unused_event_handle(adapter, event, cookie))
+    {
+        if(!(new_buffer = heap_realloc(adapter->memory_events, (adapter->event_count + 1) * sizeof(*adapter->memory_events))))
+        {
+            hr = E_OUTOFMEMORY;
+            goto done;
+        }
+        adapter->memory_events = new_buffer;
+        adapter->memory_events[adapter->event_count] = event;
+        *cookie = adapter->event_count++;
+    }
+
+    hr = WINED3D_OK;
+
+done:
+    wined3d_mutex_unlock();
+    return hr;
+}
+
+HRESULT CDECL wined3d_unregister_adapter_memory_event(const struct wined3d *wined3d, unsigned int adapter_idx,
+        DWORD cookie)
+{
+    struct wined3d_adapter *adapter;
+
+    TRACE("wined3d %p, adapter_idx %u, cookie %u.\n", wined3d, adapter_idx, cookie);
+
+    wined3d_mutex_lock();
+
+    if (adapter_idx >= wined3d->adapter_count)
+        goto fail;
+
+    adapter = wined3d->adapters[adapter_idx];
+    if (cookie >= adapter->event_count)
+        goto fail;
+    adapter->memory_events[cookie] = NULL;
+
+    wined3d_mutex_unlock();
+
+    return WINED3D_OK;
+
+fail:
+    wined3d_mutex_unlock();
+    return E_INVALIDARG;
+}
+
 HRESULT CDECL wined3d_get_adapter_raster_status(const struct wined3d *wined3d, UINT adapter_idx,
         struct wined3d_raster_status *raster_status)
 {
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index 4f3cdf9b..24b80df8 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -14,15 +14,20 @@
 @ cdecl wined3d_get_adapter_count(ptr)
 @ cdecl wined3d_get_adapter_display_mode(ptr long ptr ptr)
 @ cdecl wined3d_get_adapter_identifier(ptr long long ptr)
+@ cdecl wined3d_get_adapter_memory_info(ptr long long ptr)
 @ cdecl wined3d_get_adapter_mode_count(ptr long long long)
 @ cdecl wined3d_get_adapter_output(ptr long ptr)
 @ cdecl wined3d_get_adapter_raster_status(ptr long ptr)
 @ cdecl wined3d_get_device_caps(ptr long long ptr)
 @ cdecl wined3d_get_output_desc(ptr long ptr)
 @ cdecl wined3d_incref(ptr)
+@ cdecl wined3d_register_adapter_memory_event(ptr long ptr ptr)
 @ cdecl wined3d_register_software_device(ptr ptr)
 @ cdecl wined3d_register_window(ptr ptr ptr long)
 @ cdecl wined3d_set_adapter_display_mode(ptr long ptr)
+@ cdecl wined3d_set_adapter_reserved_memory(ptr long long int64);
+@ cdecl wined3d_unregister_adapter_memory_event(ptr long long);
+@ cdecl wined3d_update_adapter_memory_info(ptr long long int64 int64);
 @ cdecl wined3d_unregister_windows(ptr)
 
 @ cdecl wined3d_blend_state_create(ptr ptr ptr ptr ptr)
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 0b535475..0dca0b76 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -1742,6 +1742,13 @@ struct wined3d_adapter_identifier
     SIZE_T shared_system_memory;
 };
 
+struct wined3d_adapter_memory_info
+{
+    UINT64 total;
+    UINT64 used;
+    UINT64 reserved;
+};
+
 struct wined3d_swapchain_desc
 {
     unsigned int backbuffer_width;
@@ -2206,6 +2213,8 @@ HRESULT __cdecl wined3d_get_adapter_display_mode(const struct wined3d *wined3d,
         struct wined3d_display_mode *mode, enum wined3d_display_rotation *rotation);
 HRESULT __cdecl wined3d_get_adapter_identifier(const struct wined3d *wined3d, UINT adapter_idx,
         DWORD flags, struct wined3d_adapter_identifier *identifier);
+HRESULT __cdecl wined3d_get_adapter_memory_info(const struct wined3d *wined3d, unsigned int adapter_idx,
+        unsigned int non_local, struct wined3d_adapter_memory_info *info);
 UINT __cdecl wined3d_get_adapter_mode_count(const struct wined3d *wined3d, UINT adapter_idx,
         enum wined3d_format_id format_id, enum wined3d_scanline_ordering scanline_ordering);
 struct wined3d_output * __cdecl wined3d_get_adapter_output(const struct wined3d *wined3d, unsigned int adapter_idx);
@@ -2216,11 +2225,19 @@ HRESULT __cdecl wined3d_get_device_caps(const struct wined3d *wined3d, unsigned
 HRESULT __cdecl wined3d_get_output_desc(const struct wined3d *wined3d, unsigned int adapter_idx,
         struct wined3d_output_desc *desc);
 ULONG __cdecl wined3d_incref(struct wined3d *wined3d);
+HRESULT __cdecl wined3d_register_adapter_memory_event(const struct wined3d *wined3d, unsigned int adapter_idx,
+        HANDLE event, DWORD *cookie);
 HRESULT __cdecl wined3d_register_software_device(struct wined3d *wined3d, void *init_function);
 BOOL __cdecl wined3d_register_window(struct wined3d *wined3d, HWND window,
         struct wined3d_device *device, unsigned int flags);
 HRESULT __cdecl wined3d_set_adapter_display_mode(struct wined3d *wined3d,
         UINT adapter_idx, const struct wined3d_display_mode *mode);
+HRESULT __cdecl wined3d_set_adapter_reserved_memory(const struct wined3d *wined3d, unsigned int adapter_idx,
+        unsigned int non_local, UINT64 reservation);
+HRESULT __cdecl wined3d_unregister_adapter_memory_event(const struct wined3d *wined3d, unsigned int adapter_idx,
+        DWORD cookie);
+HRESULT __cdecl wined3d_update_adapter_memory_info(const struct wined3d *wined3d, unsigned int adapter_idx,
+        unsigned int non_local, UINT64 bytes_total, UINT64 bytes_used);
 void __cdecl wined3d_unregister_windows(struct wined3d *wined3d);
 
 HRESULT __cdecl wined3d_buffer_create(struct wined3d_device *device, const struct wined3d_buffer_desc *desc,
-- 
2.23.0




More information about the wine-devel mailing list