From 747ead830ca7dd8d9a6fb15706e8faf4da8780ef Mon Sep 17 00:00:00 2001 From: Liam Middlebrook Date: Sat, 12 Oct 2024 15:15:30 -0700 Subject: [PATCH] gdi32: Implement D3DKMTEnumAdapters2 Signed-off-by: Liam Middlebrook Note: This commit is specifically targeted towards ValveSoftware/wine experimental_9.0 branch. Upstream wine contains commits which already implement this, but are part of a larger series of changes inter-twined with WoW64 and unification of GDI backends. Link: https://github.com/ValveSoftware/wine/pull/259 --- dlls/gdi32/objects.c | 74 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 3 deletions(-) diff --git a/dlls/gdi32/objects.c b/dlls/gdi32/objects.c index bddc29a30073..093039c35094 100644 --- a/dlls/gdi32/objects.c +++ b/dlls/gdi32/objects.c @@ -971,10 +971,78 @@ NTSTATUS WINAPI D3DKMTOpenAdapterFromGdiDisplayName( D3DKMT_OPENADAPTERFROMGDIDI return status; } -NTSTATUS WINAPI D3DKMTEnumAdapters2( const void *param ) +NTSTATUS WINAPI D3DKMTEnumAdapters2( D3DKMT_ENUMADAPTERS2 *enumAdapters ) { - FIXME( "param %p stub.\n", param ); - return STATUS_NOT_SUPPORTED; + NTSTATUS status = STATUS_SUCCESS; + SP_DEVINFO_DATA device_data; + DEVPROPTYPE type; + HDEVINFO devinfo; + UINT dev_count = 0; + HANDLE mutex; + + TRACE("(%p)\n", enumAdapters); + + mutex = get_display_device_init_mutex(); + devinfo = SetupDiGetClassDevsW(&GUID_DEVCLASS_DISPLAY, L"PCI", NULL, 0); + device_data.cbSize = sizeof(device_data); + + while(SetupDiEnumDeviceInfo(devinfo, dev_count++, &device_data)) + { + D3DKMT_OPENADAPTERFROMLUID luid_desc; + UINT dev_idx = dev_count - 1; + D3DKMT_ADAPTERINFO *adapter; + + TRACE("Device: %u\n", dev_idx); + + /* If nothing to write, just pass through the loop */ + if (!enumAdapters->pAdapters) + continue; + + adapter = (D3DKMT_ADAPTERINFO*)(enumAdapters->pAdapters + dev_idx); + + if (SetupDiGetDevicePropertyW(devinfo, &device_data, &DEVPROPKEY_GPU_LUID, &type, + (BYTE *)&luid_desc.AdapterLuid, sizeof(luid_desc.AdapterLuid), NULL, 0)) + { + /* NumOfSources appears to be in reference to displays. This could mean connected + * displays, maximum number of "heads", surfaces for direct scanout, or something else + * entirely. It's not clear from the MSDN page what kind of value is actually expected + * here. + * + * bPrecisePresentRegionsPreferred sounds like a scanout-level optimization. Again, MSDN + * isn't very descriptive about what this really means. Given that it's typical for + * modern GPUs to scanout an entire surface at once, leave this falsey. + */ + adapter->NumOfSources = 0; + adapter->bPrecisePresentRegionsPreferred = FALSE; + FIXME("NumOfSources and bPrecisePresentRegionsPreferred not set, need implementation.\n"); + + if ((status = NtGdiDdDDIOpenAdapterFromLuid(&luid_desc))) + break; + + adapter->AdapterLuid = luid_desc.AdapterLuid; + adapter->hAdapter = luid_desc.hAdapter; + + TRACE("hAdapter: %u AdapterLuid: %08lx:%08lx NumOfSources: %lu bPrecisePresentRegionsPreferred: %d\n", + adapter->hAdapter, + adapter->AdapterLuid.HighPart, + adapter->AdapterLuid.LowPart, + adapter->NumOfSources, + adapter->bPrecisePresentRegionsPreferred); + } + else + { + TRACE("no known adapter\n"); + } + } + /* decrement dev count to actual count */ + dev_count--; + SetupDiDestroyDeviceInfoList(devinfo); + release_display_device_init_mutex(mutex); + + TRACE("Devices enumerated: %u\n", dev_count); + enumAdapters->NumAdapters = dev_count; + + return status; } /***********************************************************************