Zhiyi Zhang : dxgi: Implement dxgi_adapter_QueryVideoMemoryInfo() with D3DKMTQueryVideoMemoryInfo().

Alexandre Julliard julliard at winehq.org
Fri May 20 15:26:47 CDT 2022


Module: wine
Branch: master
Commit: 0f7c7cd7a089d70c4be7bdd6b57ca200dbc93752
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=0f7c7cd7a089d70c4be7bdd6b57ca200dbc93752

Author: Zhiyi Zhang <zzhang at codeweavers.com>
Date:   Wed May 18 14:49:14 2022 +0800

dxgi: Implement dxgi_adapter_QueryVideoMemoryInfo() with D3DKMTQueryVideoMemoryInfo().

Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/dxgi/adapter.c       | 49 +++++++++++++++------------------------
 dlls/wined3d/directx.c    | 59 +++++++++++++++++++++++++++++++++++++++++++++++
 dlls/wined3d/wined3d.spec |  1 +
 include/wine/wined3d.h    | 17 ++++++++++++++
 4 files changed, 95 insertions(+), 31 deletions(-)

diff --git a/dlls/dxgi/adapter.c b/dlls/dxgi/adapter.c
index 8962c082c17..20c017eba08 100644
--- a/dlls/dxgi/adapter.c
+++ b/dlls/dxgi/adapter.c
@@ -21,6 +21,15 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(dxgi);
 
+static void dxgi_video_memory_info_from_wined3d(DXGI_QUERY_VIDEO_MEMORY_INFO *info,
+        const struct wined3d_video_memory_info *wined3d_info)
+{
+    info->Budget = wined3d_info->budget;
+    info->CurrentUsage = wined3d_info->current_usage;
+    info->CurrentReservation = wined3d_info->current_reservation;
+    info->AvailableForReservation = wined3d_info->available_reservation;
+}
+
 static inline struct dxgi_adapter *impl_from_IWineDXGIAdapter(IWineDXGIAdapter *iface)
 {
     return CONTAINING_RECORD(iface, struct dxgi_adapter, IWineDXGIAdapter_iface);
@@ -292,44 +301,22 @@ static HRESULT STDMETHODCALLTYPE dxgi_adapter_QueryVideoMemoryInfo(IWineDXGIAdap
         UINT node_index, DXGI_MEMORY_SEGMENT_GROUP segment_group, DXGI_QUERY_VIDEO_MEMORY_INFO *info)
 {
     struct dxgi_adapter *adapter = impl_from_IWineDXGIAdapter(iface);
-    struct wined3d_adapter_identifier adapter_id;
-    static unsigned int once;
+    struct wined3d_video_memory_info wined3d_info;
     HRESULT hr;
 
     TRACE("iface %p, node_index %u, segment_group %#x, info %p.\n",
             iface, node_index, segment_group, info);
 
-    if (!once++)
-        FIXME("Returning fake video memory info.\n");
-
-    if (node_index)
-        FIXME("Ignoring node index %u.\n", node_index);
-
-    adapter_id.driver_size = 0;
-    adapter_id.description_size = 0;
-
-    if (FAILED(hr = wined3d_adapter_get_identifier(adapter->wined3d_adapter, 0, &adapter_id)))
-        return hr;
-
-    switch (segment_group)
+    if (SUCCEEDED(hr = wined3d_adapter_get_video_memory_info(adapter->wined3d_adapter, node_index,
+            (enum wined3d_memory_segment_group)segment_group, &wined3d_info)))
     {
-        case DXGI_MEMORY_SEGMENT_GROUP_LOCAL:
-            info->Budget = adapter_id.video_memory;
-            info->CurrentUsage = 0;
-            info->AvailableForReservation = adapter_id.video_memory / 2;
-            info->CurrentReservation = 0;
-            break;
-        case DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL:
-            memset(info, 0, sizeof(*info));
-            break;
-        default:
-            WARN("Invalid memory segment group %#x.\n", segment_group);
-            return E_INVALIDARG;
-    }
+        dxgi_video_memory_info_from_wined3d(info, &wined3d_info);
 
-    TRACE("Budget 0x%s, usage 0x%s, available for reservation 0x%s, reservation 0x%s.\n",
-            wine_dbgstr_longlong(info->Budget), wine_dbgstr_longlong(info->CurrentUsage),
-            wine_dbgstr_longlong(info->AvailableForReservation), wine_dbgstr_longlong(info->CurrentReservation));
+        TRACE("Budget 0x%s, usage 0x%s, available for reservation 0x%s, reservation 0x%s.\n",
+                wine_dbgstr_longlong(info->Budget), wine_dbgstr_longlong(info->CurrentUsage),
+                wine_dbgstr_longlong(info->AvailableForReservation),
+                wine_dbgstr_longlong(info->CurrentReservation));
+    }
 
     return hr;
 }
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 5b65e3b49f9..f8a44be0b3e 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -987,6 +987,65 @@ unsigned int CDECL wined3d_adapter_get_output_count(const struct wined3d_adapter
     return adapter->output_count;
 }
 
+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)
+{
+    static unsigned int once;
+    D3DKMT_QUERYVIDEOMEMORYINFO query_memory_info;
+    struct wined3d_adapter_identifier adapter_id;
+    NTSTATUS status;
+    HRESULT hr;
+
+    TRACE("adapter %p, node_idx %u, group %d, info %p.\n", adapter, node_idx, group, info);
+
+    if (group > WINED3D_MEMORY_SEGMENT_GROUP_NON_LOCAL)
+    {
+        WARN("Invalid memory segment group %#x.\n", group);
+        return E_INVALIDARG;
+    }
+
+    query_memory_info.hProcess = NULL;
+    query_memory_info.hAdapter = adapter->kmt_adapter;
+    query_memory_info.PhysicalAdapterIndex = node_idx;
+    query_memory_info.MemorySegmentGroup = (D3DKMT_MEMORY_SEGMENT_GROUP)group;
+    status = D3DKMTQueryVideoMemoryInfo(&query_memory_info);
+    if (status == STATUS_SUCCESS)
+    {
+        info->budget = query_memory_info.Budget;
+        info->current_usage = query_memory_info.CurrentUsage;
+        info->current_reservation = query_memory_info.CurrentReservation;
+        info->available_reservation = query_memory_info.AvailableForReservation;
+        return WINED3D_OK;
+    }
+
+    /* D3DKMTQueryVideoMemoryInfo() failed, fallback to fake memory info */
+    if (!once++)
+        FIXME("Returning fake video memory info.\n");
+
+    if (node_idx)
+        FIXME("Ignoring node index %u.\n", node_idx);
+
+    adapter_id.driver_size = 0;
+    adapter_id.description_size = 0;
+    if (FAILED(hr = wined3d_adapter_get_identifier(adapter, 0, &adapter_id)))
+        return hr;
+
+    switch (group)
+    {
+        case WINED3D_MEMORY_SEGMENT_GROUP_LOCAL:
+            info->budget = adapter_id.video_memory;
+            info->current_usage = 0;
+            info->available_reservation = adapter_id.video_memory / 2;
+            info->current_reservation = 0;
+            break;
+        case WINED3D_MEMORY_SEGMENT_GROUP_NON_LOCAL:
+            memset(info, 0, sizeof(*info));
+            break;
+    }
+    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);
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index 1b1c82f90bb..845ca0fb170 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -21,6 +21,7 @@
 @ cdecl wined3d_adapter_get_identifier(ptr long ptr)
 @ 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_blend_state_create(ptr ptr ptr ptr ptr)
 @ cdecl wined3d_blend_state_decref(ptr)
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index ee241ab3b1d..2b7a626f751 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -876,6 +876,12 @@ enum wined3d_pipeline
     WINED3D_PIPELINE_COUNT,
 };
 
+enum wined3d_memory_segment_group
+{
+    WINED3D_MEMORY_SEGMENT_GROUP_LOCAL = 0,
+    WINED3D_MEMORY_SEGMENT_GROUP_NON_LOCAL = 1,
+};
+
 #define WINED3DCOLORWRITEENABLE_RED                             (1u << 0)
 #define WINED3DCOLORWRITEENABLE_GREEN                           (1u << 1)
 #define WINED3DCOLORWRITEENABLE_BLUE                            (1u << 2)
@@ -1765,6 +1771,14 @@ struct wined3d_adapter_identifier
     SIZE_T shared_system_memory;
 };
 
+struct wined3d_video_memory_info
+{
+    UINT64 budget;
+    UINT64 current_usage;
+    UINT64 current_reservation;
+    UINT64 available_reservation;
+};
+
 struct wined3d_swapchain_desc
 {
     struct wined3d_output *output;
@@ -2347,6 +2361,9 @@ HRESULT __cdecl wined3d_adapter_get_identifier(const struct wined3d_adapter *ada
 struct wined3d_output * __cdecl wined3d_adapter_get_output(const struct wined3d_adapter *adapter,
         unsigned int idx);
 unsigned int __cdecl wined3d_adapter_get_output_count(const struct wined3d_adapter *adapter);
+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_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,




More information about the wine-cvs mailing list