From 8bc0c8d64604945540ba37b41becf343a2ae4a37 Mon Sep 17 00:00:00 2001 From: Zhiyi Zhang Date: Tue, 17 May 2022 14:18:12 +0800 Subject: [PATCH] gdi32: Implement D3DKMTQueryVideoMemoryInfo(). Signed-off-by: Zhiyi Zhang Signed-off-by: Huw Davies Signed-off-by: Alexandre Julliard --- dlls/gdi32/gdi32.spec | 1 + dlls/gdi32/tests/driver.c | 2 +- dlls/win32u/dibdrv/dc.c | 2 ++ dlls/win32u/driver.c | 37 +++++++++++++++++++++ dlls/win32u/emfdrv.c | 1 + dlls/win32u/font.c | 1 + dlls/win32u/gdiobj.c | 1 + dlls/win32u/path.c | 1 + dlls/win32u/win32u.spec | 2 +- dlls/win32u/win32u_private.h | 1 + dlls/win32u/wrappers.c | 6 ++++ dlls/wineps.drv/init.c | 1 + dlls/winex11.drv/init.c | 1 + dlls/winex11.drv/x11drv.h | 1 + dlls/winex11.drv/x11drv_main.c | 59 ++++++++++++++++++++++++++++++++++ dlls/winex11.drv/xrender.c | 1 + include/ntgdi.h | 1 + include/wine/gdi_driver.h | 1 + 18 files changed, 118 insertions(+), 2 deletions(-) diff --git a/dlls/gdi32/gdi32.spec b/dlls/gdi32/gdi32.spec index d0ffe827539..d6a0ad90e1e 100644 --- a/dlls/gdi32/gdi32.spec +++ b/dlls/gdi32/gdi32.spec @@ -85,6 +85,7 @@ @ stdcall D3DKMTOpenAdapterFromHdc(ptr) win32u.NtGdiDdDDIOpenAdapterFromHdc @ stdcall D3DKMTOpenAdapterFromLuid(ptr) win32u.NtGdiDdDDIOpenAdapterFromLuid @ stdcall D3DKMTQueryStatistics(ptr) win32u.NtGdiDdDDIQueryStatistics +@ stdcall D3DKMTQueryVideoMemoryInfo(ptr) win32u.NtGdiDdDDIQueryVideoMemoryInfo @ stdcall D3DKMTSetQueuedLimit(ptr) win32u.NtGdiDdDDISetQueuedLimit @ stdcall D3DKMTSetVidPnSourceOwner(ptr) win32u.NtGdiDdDDISetVidPnSourceOwner @ stdcall DPtoLP(long ptr long) diff --git a/dlls/gdi32/tests/driver.c b/dlls/gdi32/tests/driver.c index 5117d34908d..79eedda1241 100644 --- a/dlls/gdi32/tests/driver.c +++ b/dlls/gdi32/tests/driver.c @@ -918,7 +918,7 @@ static void test_D3DKMTQueryVideoMemoryInfo(void) if (!pD3DKMTQueryVideoMemoryInfo) { - skip("D3DKMTQueryVideoMemoryInfo() is unavailable.\n"); + win_skip("D3DKMTQueryVideoMemoryInfo() is unavailable.\n"); return; } diff --git a/dlls/win32u/dibdrv/dc.c b/dlls/win32u/dibdrv/dc.c index caa3cc92587..7c60466d9ee 100644 --- a/dlls/win32u/dibdrv/dc.c +++ b/dlls/win32u/dibdrv/dc.c @@ -711,6 +711,7 @@ const struct gdi_dc_funcs dib_driver = NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */ NULL, /* pD3DKMTCloseAdapter */ NULL, /* pD3DKMTOpenAdapterFromLuid */ + NULL, /* pD3DKMTQueryVideoMemoryInfo */ NULL, /* pD3DKMTSetVidPnSourceOwner */ GDI_PRIORITY_DIB_DRV /* priority */ }; @@ -1267,6 +1268,7 @@ static const struct gdi_dc_funcs window_driver = NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */ NULL, /* pD3DKMTCloseAdapter */ NULL, /* pD3DKMTOpenAdapterFromLuid */ + NULL, /* pD3DKMTQueryVideoMemoryInfo */ NULL, /* pD3DKMTSetVidPnSourceOwner */ GDI_PRIORITY_DIB_DRV + 10 /* priority */ }; diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c index 31383330bc4..9185069208a 100644 --- a/dlls/win32u/driver.c +++ b/dlls/win32u/driver.c @@ -560,6 +560,11 @@ static NTSTATUS CDECL nulldrv_D3DKMTOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROML return STATUS_PROCEDURE_NOT_FOUND; } +static NTSTATUS CDECL nulldrv_D3DKMTQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO *desc ) +{ + return STATUS_PROCEDURE_NOT_FOUND; +} + static NTSTATUS CDECL nulldrv_D3DKMTSetVidPnSourceOwner( const D3DKMT_SETVIDPNSOURCEOWNER *desc ) { return STATUS_PROCEDURE_NOT_FOUND; @@ -659,6 +664,7 @@ const struct gdi_dc_funcs null_driver = nulldrv_D3DKMTCheckVidPnExclusiveOwnership, /* pD3DKMTCheckVidPnExclusiveOwnership */ nulldrv_D3DKMTCloseAdapter, /* pD3DKMTCloseAdapter */ nulldrv_D3DKMTOpenAdapterFromLuid, /* pD3DKMTOpenAdapterFromLuid */ + nulldrv_D3DKMTQueryVideoMemoryInfo, /* pD3DKMTQueryVideoMemoryInfo */ nulldrv_D3DKMTSetVidPnSourceOwner, /* pD3DKMTSetVidPnSourceOwner */ GDI_PRIORITY_NULL_DRV /* priority */ @@ -1475,6 +1481,37 @@ NTSTATUS WINAPI NtGdiDdDDIQueryStatistics( D3DKMT_QUERYSTATISTICS *stats ) return STATUS_SUCCESS; } +/****************************************************************************** + * NtGdiDdDDIQueryVideoMemoryInfo (win32u.@) + */ +NTSTATUS WINAPI NtGdiDdDDIQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO *desc ) +{ + OBJECT_BASIC_INFORMATION info; + NTSTATUS status; + + TRACE("(%p)\n", desc); + + if (!desc || !desc->hAdapter || + (desc->MemorySegmentGroup != D3DKMT_MEMORY_SEGMENT_GROUP_LOCAL && + desc->MemorySegmentGroup != D3DKMT_MEMORY_SEGMENT_GROUP_NON_LOCAL)) + return STATUS_INVALID_PARAMETER; + + /* FIXME: Wine currently doesn't support linked adapters */ + if (desc->PhysicalAdapterIndex > 0) + return STATUS_INVALID_PARAMETER; + + status = NtQueryObject(desc->hProcess ? desc->hProcess : GetCurrentProcess(), + ObjectBasicInformation, &info, sizeof(info), NULL); + if (status != STATUS_SUCCESS) + return status; + if (!(info.GrantedAccess & PROCESS_QUERY_INFORMATION)) + return STATUS_ACCESS_DENIED; + + if (!get_display_driver()->pD3DKMTQueryVideoMemoryInfo) + return STATUS_PROCEDURE_NOT_FOUND; + return get_display_driver()->pD3DKMTQueryVideoMemoryInfo(desc); +} + /****************************************************************************** * NtGdiDdDDISetQueuedLimit (win32u.@) */ diff --git a/dlls/win32u/emfdrv.c b/dlls/win32u/emfdrv.c index fafceb71438..848a5bbaa4b 100644 --- a/dlls/win32u/emfdrv.c +++ b/dlls/win32u/emfdrv.c @@ -525,6 +525,7 @@ static const struct gdi_dc_funcs emfdrv_driver = NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */ NULL, /* pD3DKMTCloseAdapter */ NULL, /* pD3DKMTOpenAdapterFromLuid */ + NULL, /* pD3DKMTQueryVideoMemoryInfo */ NULL, /* pD3DKMTSetVidPnSourceOwner */ GDI_PRIORITY_GRAPHICS_DRV /* priority */ }; diff --git a/dlls/win32u/font.c b/dlls/win32u/font.c index 6e0207b7bb6..571379976a5 100644 --- a/dlls/win32u/font.c +++ b/dlls/win32u/font.c @@ -4270,6 +4270,7 @@ const struct gdi_dc_funcs font_driver = NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */ NULL, /* pD3DKMTCloseAdapter */ NULL, /* pD3DKMTOpenAdapterFromLuid */ + NULL, /* pD3DKMTQueryVideoMemoryInfo */ NULL, /* pD3DKMTSetVidPnSourceOwner */ GDI_PRIORITY_FONT_DRV /* priority */ }; diff --git a/dlls/win32u/gdiobj.c b/dlls/win32u/gdiobj.c index 8d19e231f46..96d52e4d38e 100644 --- a/dlls/win32u/gdiobj.c +++ b/dlls/win32u/gdiobj.c @@ -1053,6 +1053,7 @@ static struct unix_funcs unix_funcs = NtGdiDdDDIEscape, NtGdiDdDDIOpenAdapterFromDeviceName, NtGdiDdDDIOpenAdapterFromLuid, + NtGdiDdDDIQueryVideoMemoryInfo, NtGdiDdDDISetVidPnSourceOwner, NtGdiDeleteObjectApp, NtGdiDoPalette, diff --git a/dlls/win32u/path.c b/dlls/win32u/path.c index 00a1f58e969..0032ee1a5ab 100644 --- a/dlls/win32u/path.c +++ b/dlls/win32u/path.c @@ -2122,6 +2122,7 @@ const struct gdi_dc_funcs path_driver = NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */ NULL, /* pD3DKMTCloseAdapter */ NULL, /* pD3DKMTOpenAdapterFromLuid */ + NULL, /* pD3DKMTQueryVideoMemoryInfo */ NULL, /* pD3DKMTSetVidPnSourceOwner */ GDI_PRIORITY_PATH_DRV /* priority */ }; diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec index 2f0682fe915..1c3cbc59dc2 100644 --- a/dlls/win32u/win32u.spec +++ b/dlls/win32u/win32u.spec @@ -307,7 +307,7 @@ @ stub NtGdiDdDDIQueryResourceInfoFromNtHandle @ stdcall -syscall NtGdiDdDDIQueryStatistics(ptr) @ stub NtGdiDdDDIQueryVidPnExclusiveOwnership -@ stub NtGdiDdDDIQueryVideoMemoryInfo +@ stdcall NtGdiDdDDIQueryVideoMemoryInfo(ptr) @ stub NtGdiDdDDIReclaimAllocations @ stub NtGdiDdDDIReclaimAllocations2 @ stub NtGdiDdDDIReleaseKeyedMutex diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index e221dff4d01..02784df64f8 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -65,6 +65,7 @@ struct unix_funcs NTSTATUS (WINAPI *pNtGdiDdDDIEscape)( const D3DKMT_ESCAPE *desc ); NTSTATUS (WINAPI *pNtGdiDdDDIOpenAdapterFromDeviceName)( D3DKMT_OPENADAPTERFROMDEVICENAME *desc ); NTSTATUS (WINAPI *pNtGdiDdDDIOpenAdapterFromLuid)( D3DKMT_OPENADAPTERFROMLUID *desc ); + NTSTATUS (WINAPI *pNtGdiDdDDIQueryVideoMemoryInfo)( D3DKMT_QUERYVIDEOMEMORYINFO *desc ); NTSTATUS (WINAPI *pNtGdiDdDDISetVidPnSourceOwner)( const D3DKMT_SETVIDPNSOURCEOWNER *desc ); BOOL (WINAPI *pNtGdiDeleteObjectApp)( HGDIOBJ obj ); LONG (WINAPI *pNtGdiDoPalette)( HGDIOBJ handle, WORD start, WORD count, void *entries, diff --git a/dlls/win32u/wrappers.c b/dlls/win32u/wrappers.c index 9438660d3ec..4e750e5aea2 100644 --- a/dlls/win32u/wrappers.c +++ b/dlls/win32u/wrappers.c @@ -713,6 +713,12 @@ NTSTATUS WINAPI NtGdiDdDDIOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *desc return unix_funcs->pNtGdiDdDDIOpenAdapterFromLuid( desc ); } +NTSTATUS WINAPI NtGdiDdDDIQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO *desc ) +{ + if (!unix_funcs) return STATUS_NOT_SUPPORTED; + return unix_funcs->pNtGdiDdDDIQueryVideoMemoryInfo( desc ); +} + NTSTATUS WINAPI NtGdiDdDDISetVidPnSourceOwner( const D3DKMT_SETVIDPNSOURCEOWNER *desc ) { if (!unix_funcs) return STATUS_NOT_SUPPORTED; diff --git a/dlls/wineps.drv/init.c b/dlls/wineps.drv/init.c index d02c2cfc4c2..0d4467b6964 100644 --- a/dlls/wineps.drv/init.c +++ b/dlls/wineps.drv/init.c @@ -859,6 +859,7 @@ static const struct gdi_dc_funcs psdrv_funcs = NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */ NULL, /* pD3DKMTCloseAdapter */ NULL, /* pD3DKMTOpenAdapterFromLuid */ + NULL, /* pD3DKMTQueryVideoMemoryInfo */ NULL, /* pD3DKMTSetVidPnSourceOwner */ GDI_PRIORITY_GRAPHICS_DRV /* priority */ }; diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c index bff2d9db4c5..fc190805401 100644 --- a/dlls/winex11.drv/init.c +++ b/dlls/winex11.drv/init.c @@ -388,6 +388,7 @@ static const struct user_driver_funcs x11drv_funcs = .dc_funcs.pD3DKMTCheckVidPnExclusiveOwnership = X11DRV_D3DKMTCheckVidPnExclusiveOwnership, .dc_funcs.pD3DKMTCloseAdapter = X11DRV_D3DKMTCloseAdapter, .dc_funcs.pD3DKMTOpenAdapterFromLuid = X11DRV_D3DKMTOpenAdapterFromLuid, + .dc_funcs.pD3DKMTQueryVideoMemoryInfo = X11DRV_D3DKMTQueryVideoMemoryInfo, .dc_funcs.pD3DKMTSetVidPnSourceOwner = X11DRV_D3DKMTSetVidPnSourceOwner, .dc_funcs.priority = GDI_PRIORITY_GRAPHICS_DRV, diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index a4f93150ed9..9a775215321 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -157,6 +157,7 @@ extern BOOL CDECL X11DRV_Chord( PHYSDEV dev, INT left, INT top, INT right, INT b extern NTSTATUS CDECL X11DRV_D3DKMTCheckVidPnExclusiveOwnership( const D3DKMT_CHECKVIDPNEXCLUSIVEOWNERSHIP *desc ) DECLSPEC_HIDDEN; extern NTSTATUS CDECL X11DRV_D3DKMTCloseAdapter( const D3DKMT_CLOSEADAPTER *desc ) DECLSPEC_HIDDEN; extern NTSTATUS CDECL X11DRV_D3DKMTOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *desc ) DECLSPEC_HIDDEN; +extern NTSTATUS CDECL X11DRV_D3DKMTQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO *desc ) DECLSPEC_HIDDEN; extern NTSTATUS CDECL X11DRV_D3DKMTSetVidPnSourceOwner( const D3DKMT_SETVIDPNSOURCEOWNER *desc ) DECLSPEC_HIDDEN; extern BOOL CDECL X11DRV_Ellipse( PHYSDEV dev, INT left, INT top, INT right, INT bottom ) DECLSPEC_HIDDEN; extern BOOL CDECL X11DRV_ExtFloodFill( PHYSDEV dev, INT x, INT y, COLORREF color, UINT fillType ) DECLSPEC_HIDDEN; diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c index 77f1ec87a31..40d0e750d1b 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c @@ -1228,6 +1228,65 @@ done: return status; } +NTSTATUS CDECL X11DRV_D3DKMTQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO *desc ) +{ + const struct vulkan_funcs *vulkan_funcs = get_vulkan_driver(WINE_VULKAN_DRIVER_VERSION); + PFN_vkGetPhysicalDeviceMemoryProperties2KHR pvkGetPhysicalDeviceMemoryProperties2KHR; + VkPhysicalDeviceMemoryBudgetPropertiesEXT budget; + VkPhysicalDeviceMemoryProperties2 properties2; + NTSTATUS status = STATUS_INVALID_PARAMETER; + struct x11_d3dkmt_adapter *adapter; + unsigned int i; + + desc->Budget = 0; + desc->CurrentUsage = 0; + desc->CurrentReservation = 0; + desc->AvailableForReservation = 0; + + if (!vulkan_funcs) + { + WARN("Vulkan is unavailable.\n"); + return STATUS_UNSUCCESSFUL; + } + + pthread_mutex_lock(&d3dkmt_mutex); + LIST_FOR_EACH_ENTRY(adapter, &x11_d3dkmt_adapters, struct x11_d3dkmt_adapter, entry) + { + if (adapter->handle != desc->hAdapter) + continue; + + if (!(pvkGetPhysicalDeviceMemoryProperties2KHR = (void *)vulkan_funcs->p_vkGetInstanceProcAddr(adapter->vk_instance, "vkGetPhysicalDeviceMemoryProperties2KHR"))) + { + WARN("Failed to load vkGetPhysicalDeviceMemoryProperties2KHR.\n"); + status = STATUS_UNSUCCESSFUL; + goto done; + } + + memset(&budget, 0, sizeof(budget)); + budget.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT; + properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2; + properties2.pNext = &budget; + pvkGetPhysicalDeviceMemoryProperties2KHR(adapter->vk_device, &properties2); + for (i = 0; i < properties2.memoryProperties.memoryHeapCount; ++i) + { + if ((desc->MemorySegmentGroup == D3DKMT_MEMORY_SEGMENT_GROUP_LOCAL + && properties2.memoryProperties.memoryHeaps[i].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) + || (desc->MemorySegmentGroup == D3DKMT_MEMORY_SEGMENT_GROUP_NON_LOCAL + && !(properties2.memoryProperties.memoryHeaps[i].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT))) + { + desc->Budget += budget.heapBudget[i]; + desc->CurrentUsage += budget.heapUsage[i]; + } + } + desc->AvailableForReservation = desc->Budget / 2; + status = STATUS_SUCCESS; + break; + } +done: + pthread_mutex_unlock(&d3dkmt_mutex); + return status; +} + NTSTATUS x11drv_client_func( enum x11drv_client_funcs id, const void *params, ULONG size ) { void *ret_ptr; diff --git a/dlls/winex11.drv/xrender.c b/dlls/winex11.drv/xrender.c index 697fe0432ae..585299cba9e 100644 --- a/dlls/winex11.drv/xrender.c +++ b/dlls/winex11.drv/xrender.c @@ -2238,6 +2238,7 @@ static const struct gdi_dc_funcs xrender_funcs = NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */ NULL, /* pD3DKMTCloseAdapter */ NULL, /* pD3DKMTOpenAdapterFromLuid */ + NULL, /* pD3DKMTQueryVideoMemoryInfo */ NULL, /* pD3DKMTSetVidPnSourceOwner */ GDI_PRIORITY_GRAPHICS_DRV + 10 /* priority */ }; diff --git a/include/ntgdi.h b/include/ntgdi.h index 78d0f620be3..5a9d5a798fe 100644 --- a/include/ntgdi.h +++ b/include/ntgdi.h @@ -472,6 +472,7 @@ NTSTATUS WINAPI NtGdiDdDDIOpenAdapterFromHdc( D3DKMT_OPENADAPTERFROMHDC *desc ); NTSTATUS WINAPI NtGdiDdDDIOpenAdapterFromDeviceName( D3DKMT_OPENADAPTERFROMDEVICENAME *desc ); NTSTATUS WINAPI NtGdiDdDDIOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *desc ); NTSTATUS WINAPI NtGdiDdDDIQueryStatistics( D3DKMT_QUERYSTATISTICS *stats ); +NTSTATUS WINAPI NtGdiDdDDIQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO *desc ); NTSTATUS WINAPI NtGdiDdDDISetQueuedLimit( D3DKMT_SETQUEUEDLIMIT *desc ); NTSTATUS WINAPI NtGdiDdDDISetVidPnSourceOwner( const D3DKMT_SETVIDPNSOURCEOWNER *desc ); diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index f16b1456483..82bac557c2a 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -160,6 +160,7 @@ struct gdi_dc_funcs NTSTATUS (CDECL *pD3DKMTCheckVidPnExclusiveOwnership)(const D3DKMT_CHECKVIDPNEXCLUSIVEOWNERSHIP *); NTSTATUS (CDECL *pD3DKMTCloseAdapter)(const D3DKMT_CLOSEADAPTER *); NTSTATUS (CDECL *pD3DKMTOpenAdapterFromLuid)(D3DKMT_OPENADAPTERFROMLUID *); + NTSTATUS (CDECL *pD3DKMTQueryVideoMemoryInfo)(D3DKMT_QUERYVIDEOMEMORYINFO *); NTSTATUS (CDECL *pD3DKMTSetVidPnSourceOwner)(const D3DKMT_SETVIDPNSOURCEOWNER *); /* priority order for the driver on the stack */