From 0f7c7cd7a089d70c4be7bdd6b57ca200dbc93752 Mon Sep 17 00:00:00 2001 From: Zhiyi Zhang Date: Wed, 18 May 2022 14:49:14 +0800 Subject: [PATCH] dxgi: Implement dxgi_adapter_QueryVideoMemoryInfo() with D3DKMTQueryVideoMemoryInfo(). Signed-off-by: Zhiyi Zhang Signed-off-by: Zebediah Figura Signed-off-by: Alexandre Julliard --- 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,