Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
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,
--
2.34.1