From: Krzysztof Bogacki krzysztof.bogacki@leancode.pl
Signed-off-by: Krzysztof Bogacki krzysztof.bogacki@leancode.pl --- dlls/win32u/dibdrv/dc.c | 2 + dlls/win32u/driver.c | 75 ++++++++++++++++++++++++++++++++++++-- dlls/win32u/emfdrv.c | 1 + dlls/win32u/font.c | 1 + dlls/win32u/path.c | 1 + dlls/winex11.drv/xrender.c | 1 + include/wine/gdi_driver.h | 1 + 7 files changed, 78 insertions(+), 4 deletions(-)
diff --git a/dlls/win32u/dibdrv/dc.c b/dlls/win32u/dibdrv/dc.c index 7fe4b765a78..0a4b0ac3da0 100644 --- a/dlls/win32u/dibdrv/dc.c +++ b/dlls/win32u/dibdrv/dc.c @@ -709,6 +709,7 @@ const struct gdi_dc_funcs dib_driver = NULL, /* pUnrealizePalette */ NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */ NULL, /* pD3DKMTCloseAdapter */ + NULL, /* pD3DKMTEnumAdapters2 */ NULL, /* pD3DKMTOpenAdapterFromLuid */ NULL, /* pD3DKMTQueryVideoMemoryInfo */ NULL, /* pD3DKMTSetVidPnSourceOwner */ @@ -1270,6 +1271,7 @@ static const struct gdi_dc_funcs window_driver = NULL, /* pUnrealizePalette */ NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */ NULL, /* pD3DKMTCloseAdapter */ + NULL, /* pD3DKMTEnumAdapters2 */ NULL, /* pD3DKMTOpenAdapterFromLuid */ NULL, /* pD3DKMTQueryVideoMemoryInfo */ NULL, /* pD3DKMTSetVidPnSourceOwner */ diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c index 94fe968f2fe..4f524baa3e2 100644 --- a/dlls/win32u/driver.c +++ b/dlls/win32u/driver.c @@ -54,6 +54,7 @@ static struct user_driver_funcs null_user_driver;
static struct list d3dkmt_adapters = LIST_INIT( d3dkmt_adapters ); static struct list d3dkmt_devices = LIST_INIT( d3dkmt_devices ); +static D3DKMT_HANDLE adapter_handle_start = 0;
static pthread_mutex_t driver_lock = PTHREAD_MUTEX_INITIALIZER; static WCHAR driver_load_error[80]; @@ -549,6 +550,11 @@ static NTSTATUS nulldrv_D3DKMTCloseAdapter( const D3DKMT_CLOSEADAPTER *desc ) return STATUS_PROCEDURE_NOT_FOUND; }
+static NTSTATUS nulldrv_D3DKMTEnumAdapters2( D3DKMT_ENUMADAPTERS2 *desc ) +{ + return STATUS_PROCEDURE_NOT_FOUND; +} + static NTSTATUS nulldrv_D3DKMTOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *desc ) { return STATUS_PROCEDURE_NOT_FOUND; @@ -657,6 +663,7 @@ const struct gdi_dc_funcs null_driver = nulldrv_UnrealizePalette, /* pUnrealizePalette */ nulldrv_D3DKMTCheckVidPnExclusiveOwnership, /* pD3DKMTCheckVidPnExclusiveOwnership */ nulldrv_D3DKMTCloseAdapter, /* pD3DKMTCloseAdapter */ + nulldrv_D3DKMTEnumAdapters2, /* pD3DKMTEnumAdapters2 */ nulldrv_D3DKMTOpenAdapterFromLuid, /* pD3DKMTOpenAdapterFromLuid */ nulldrv_D3DKMTQueryVideoMemoryInfo, /* pD3DKMTQueryVideoMemoryInfo */ nulldrv_D3DKMTSetVidPnSourceOwner, /* pD3DKMTSetVidPnSourceOwner */ @@ -1518,8 +1525,69 @@ NTSTATUS WINAPI NtGdiDdDDICloseAdapter( const D3DKMT_CLOSEADAPTER *desc ) */ NTSTATUS WINAPI NtGdiDdDDIEnumAdapters2( D3DKMT_ENUMADAPTERS2 *desc ) { - FIXME("(%p): stub\n", desc); - return STATUS_PROCEDURE_NOT_FOUND; + D3DKMT_ADAPTERINFO *adapter_infos = NULL; + struct d3dkmt_adapter *adapter, *prev; + D3DKMT_ENUMADAPTERS2 local_desc; + NTSTATUS status; + ULONG i; + + TRACE("(%p)\n", desc); + + if (!desc) return STATUS_INVALID_PARAMETER; + + if (!get_display_driver()->pD3DKMTEnumAdapters2) return STATUS_PROCEDURE_NOT_FOUND; + + if (!desc->NumAdapters || !desc->pAdapters) + /* Querying the size or zero length array, no need to allocate handles */ + return get_display_driver()->pD3DKMTEnumAdapters2( desc ); + + if (!(adapter_infos = calloc( desc->NumAdapters, sizeof(*adapter_infos) ))) return STATUS_NO_MEMORY; + + pthread_mutex_lock( &driver_lock ); + + for (i = 0; i < desc->NumAdapters; ++i) + { + if (!(adapter = malloc( sizeof( *adapter ) ))) + { + pthread_mutex_unlock( &driver_lock ); + free( adapter_infos ); + return STATUS_NO_MEMORY; + } + + adapter_infos[i].hAdapter = adapter->handle = ++adapter_handle_start; + list_add_tail( &d3dkmt_adapters, &adapter->entry ); + } + + /* This lets us avoid modifying desc->pAdapters until we know how many elements we are allowed to touch */ + local_desc.NumAdapters = desc->NumAdapters; + local_desc.pAdapters = adapter_infos; + status = get_display_driver()->pD3DKMTEnumAdapters2( &local_desc ); + + if (status != STATUS_SUCCESS) + /* Driver failed, free all the adapter handles we allocated earlier */ + local_desc.NumAdapters = 0; + + /* Some (or all) handles may remain unused, free them */ + LIST_FOR_EACH_ENTRY_SAFE_REV( adapter, prev, &d3dkmt_adapters, struct d3dkmt_adapter, entry ) + { + if (i-- <= local_desc.NumAdapters) break; + + list_remove( &adapter->entry ); + free( adapter ); + } + + pthread_mutex_unlock( &driver_lock ); + + if (status == STATUS_SUCCESS) + { + /* Update desc only once the call succeeded and we know the result */ + if ((desc->NumAdapters = local_desc.NumAdapters)) + memcpy( desc->pAdapters, adapter_infos, local_desc.NumAdapters * sizeof( *adapter_infos ) ); + } + + free( adapter_infos ); + + return status; }
/****************************************************************************** @@ -1547,13 +1615,12 @@ NTSTATUS WINAPI NtGdiDdDDIOpenAdapterFromDeviceName( D3DKMT_OPENADAPTERFROMDEVIC */ NTSTATUS WINAPI NtGdiDdDDIOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *desc ) { - static D3DKMT_HANDLE handle_start = 0; struct d3dkmt_adapter *adapter;
if (!(adapter = malloc( sizeof( *adapter ) ))) return STATUS_NO_MEMORY;
pthread_mutex_lock( &driver_lock ); - desc->hAdapter = adapter->handle = ++handle_start; + desc->hAdapter = adapter->handle = ++adapter_handle_start; list_add_tail( &d3dkmt_adapters, &adapter->entry ); pthread_mutex_unlock( &driver_lock );
diff --git a/dlls/win32u/emfdrv.c b/dlls/win32u/emfdrv.c index 069ad9d1297..9c07f9ef341 100644 --- a/dlls/win32u/emfdrv.c +++ b/dlls/win32u/emfdrv.c @@ -521,6 +521,7 @@ static const struct gdi_dc_funcs emfdrv_driver = NULL, /* pUnrealizePalette */ NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */ NULL, /* pD3DKMTCloseAdapter */ + NULL, /* pD3DKMTEnumAdapters2 */ NULL, /* pD3DKMTOpenAdapterFromLuid */ NULL, /* pD3DKMTQueryVideoMemoryInfo */ NULL, /* pD3DKMTSetVidPnSourceOwner */ diff --git a/dlls/win32u/font.c b/dlls/win32u/font.c index af1a9b97f67..2f84ff37e39 100644 --- a/dlls/win32u/font.c +++ b/dlls/win32u/font.c @@ -4774,6 +4774,7 @@ const struct gdi_dc_funcs font_driver = NULL, /* pUnrealizePalette */ NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */ NULL, /* pD3DKMTCloseAdapter */ + NULL, /* pD3DKMTEnumAdapters2 */ NULL, /* pD3DKMTOpenAdapterFromLuid */ NULL, /* pD3DKMTQueryVideoMemoryInfo */ NULL, /* pD3DKMTSetVidPnSourceOwner */ diff --git a/dlls/win32u/path.c b/dlls/win32u/path.c index e0c96f5ef6f..6d494a92233 100644 --- a/dlls/win32u/path.c +++ b/dlls/win32u/path.c @@ -2120,6 +2120,7 @@ const struct gdi_dc_funcs path_driver = NULL, /* pUnrealizePalette */ NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */ NULL, /* pD3DKMTCloseAdapter */ + NULL, /* pD3DKMTEnumAdapters2 */ NULL, /* pD3DKMTOpenAdapterFromLuid */ NULL, /* pD3DKMTQueryVideoMemoryInfo */ NULL, /* pD3DKMTSetVidPnSourceOwner */ diff --git a/dlls/winex11.drv/xrender.c b/dlls/winex11.drv/xrender.c index 74723915fc5..7e605f9b3d5 100644 --- a/dlls/winex11.drv/xrender.c +++ b/dlls/winex11.drv/xrender.c @@ -2236,6 +2236,7 @@ static const struct gdi_dc_funcs xrender_funcs = NULL, /* pUnrealizePalette */ NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */ NULL, /* pD3DKMTCloseAdapter */ + NULL, /* pD3DKMTEnumAdapters2 */ NULL, /* pD3DKMTOpenAdapterFromLuid */ NULL, /* pD3DKMTQueryVideoMemoryInfo */ NULL, /* pD3DKMTSetVidPnSourceOwner */ diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index 26562bfef2b..ba37098f7ad 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -168,6 +168,7 @@ struct gdi_dc_funcs BOOL (*pUnrealizePalette)(HPALETTE); NTSTATUS (*pD3DKMTCheckVidPnExclusiveOwnership)(const D3DKMT_CHECKVIDPNEXCLUSIVEOWNERSHIP *); NTSTATUS (*pD3DKMTCloseAdapter)(const D3DKMT_CLOSEADAPTER *); + NTSTATUS (*pD3DKMTEnumAdapters2)(D3DKMT_ENUMADAPTERS2 *); NTSTATUS (*pD3DKMTOpenAdapterFromLuid)(D3DKMT_OPENADAPTERFROMLUID *); NTSTATUS (*pD3DKMTQueryVideoMemoryInfo)(D3DKMT_QUERYVIDEOMEMORYINFO *); NTSTATUS (*pD3DKMTSetVidPnSourceOwner)(const D3DKMT_SETVIDPNSOURCEOWNER *);