From: Hieu Le Minh <leminhhieu.opensource@gmail.com> --- dlls/win32u/d3dkmt.c | 63 ++++++++++++++++++++++++++++++++++++++ dlls/win32u/tests/d3dkmt.c | 10 ++++++ include/ddk/d3dkmthk.h | 28 +++++++++++++++++ 3 files changed, 101 insertions(+) diff --git a/dlls/win32u/d3dkmt.c b/dlls/win32u/d3dkmt.c index 9b5d4a8c919..98c6f0cb384 100644 --- a/dlls/win32u/d3dkmt.c +++ b/dlls/win32u/d3dkmt.c @@ -710,6 +710,69 @@ NTSTATUS WINAPI NtGdiDdDDIQueryAdapterInfo( D3DKMT_QUERYADAPTERINFO *desc ) *value = KMT_DRIVERVERSION_WDDM_3_1; return STATUS_SUCCESS; } + case KMTQAITYPE_ADAPTERTYPE: + { + D3DKMT_ADAPTERTYPE *value = desc->pPrivateDriverData; + struct vulkan_physical_device *physical_device; + VkPhysicalDeviceProperties2 device_properties2; + VkQueueFamilyProperties2 *queue_properties2; + struct d3dkmt_adapter *adapter; + + if (desc->PrivateDriverDataSize < sizeof(*value)) + return STATUS_INVALID_PARAMETER; + + if (!(adapter = get_d3dkmt_object( desc->hAdapter, D3DKMT_ADAPTER ))) return STATUS_INVALID_PARAMETER; + + value->Value = 0; + + if ((physical_device = adapter->physical_device)) + { + struct vulkan_instance *instance = physical_device->instance; + VkPhysicalDeviceType device_type; + UINT queue_family_count; + BOOL render_supported = 0; + BOOL compute_supported = 0; + UINT i; + + device_properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; + device_properties2.pNext = NULL; + + instance->p_vkGetPhysicalDeviceProperties2( physical_device->host.physical_device, &device_properties2 ); + device_type = device_properties2.properties.deviceType; + + instance->p_vkGetPhysicalDeviceQueueFamilyProperties2( physical_device->host.physical_device, &queue_family_count, NULL ); + queue_properties2 = malloc( queue_family_count * sizeof(*queue_properties2) ); + if (!queue_properties2) + return STATUS_NO_MEMORY; + + for (i = 0; i < queue_family_count; i++) + { + queue_properties2[i].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2; + queue_properties2[i].pNext = NULL; + } + + instance->p_vkGetPhysicalDeviceQueueFamilyProperties2( physical_device->host.physical_device, &queue_family_count, queue_properties2 ); + for (i = 0; i < queue_family_count; i++) + { + if (queue_properties2[i].queueFamilyProperties.queueFlags & VK_QUEUE_GRAPHICS_BIT) + render_supported = 1; + if (queue_properties2[i].queueFamilyProperties.queueFlags & VK_QUEUE_COMPUTE_BIT) + compute_supported = 1; + } + + value->RenderSupported = render_supported; + value->SoftwareDevice = (device_type == VK_PHYSICAL_DEVICE_TYPE_CPU); + value->HybridDiscrete = (device_type == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU); /* FIXME */ + value->HybridIntegrated = (device_type == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU); /* FIXME */ + value->ComputeOnly = (render_supported == 0 && compute_supported == 1); + + free( queue_properties2 ); + return STATUS_SUCCESS; + } + + ERR( "Failed to find Vulkan physical device\n" ); + return STATUS_DEVICE_REMOVED; + } default: { FIXME( "type %d not handled.\n", desc->Type ); diff --git a/dlls/win32u/tests/d3dkmt.c b/dlls/win32u/tests/d3dkmt.c index 7a33089b73b..e98f86a0725 100644 --- a/dlls/win32u/tests/d3dkmt.c +++ b/dlls/win32u/tests/d3dkmt.c @@ -1579,6 +1579,7 @@ static void test_D3DKMTQueryAdapterInfo(void) { {KMTQAITYPE_CHECKDRIVERUPDATESTATUS, sizeof(BOOL)}, {KMTQAITYPE_DRIVERVERSION, sizeof(D3DKMT_DRIVERVERSION)}, + {KMTQAITYPE_ADAPTERTYPE, sizeof(D3DKMT_ADAPTERTYPE)}, }; ret = get_primary_adapter_name( open_adapter_desc.DeviceName ); @@ -1631,6 +1632,15 @@ static void test_D3DKMTQueryAdapterInfo(void) "Expected %d >= %d.\n", *value, KMT_DRIVERVERSION_WDDM_3_1 ); break; } + case KMTQAITYPE_ADAPTERTYPE: + { + D3DKMT_ADAPTERTYPE *value = query_adapter_info.pPrivateDriverData; + ok( !(value->RenderSupported && value->ComputeOnly), "got %d, %d\n", value->RenderSupported, value->ComputeOnly ); + ok( !(value->SoftwareDevice && value->HybridDiscrete), "got %d, %d\n", value->SoftwareDevice, value->HybridDiscrete ); + ok( !(value->SoftwareDevice && value->HybridIntegrated), "got %d, %d\n", value->SoftwareDevice, value->HybridIntegrated ); + ok( !(value->HybridDiscrete && value->HybridIntegrated), "got %d, %d\n", value->HybridDiscrete, value->HybridIntegrated ); + break; + } default: ok( 0, "Type %d is not handled.\n", tests[i].type ); break; diff --git a/include/ddk/d3dkmthk.h b/include/ddk/d3dkmthk.h index a4da022e9aa..b779b68c70f 100644 --- a/include/ddk/d3dkmthk.h +++ b/include/ddk/d3dkmthk.h @@ -196,6 +196,34 @@ typedef enum _QAI_DRIVERVERSION KMT_DRIVERVERSION_WDDM_3_1 = 3100 } D3DKMT_DRIVERVERSION; +typedef struct _D3DKMT_ADAPTERTYPE +{ + union + { + struct + { + UINT RenderSupported : 1; + UINT DisplaySupported : 1; + UINT SoftwareDevice : 1; + UINT PostDevice : 1; + UINT HybridDiscrete : 1; + UINT HybridIntegrated : 1; + UINT IndirectDisplayDevice : 1; + UINT Paravirtualized : 1; + UINT ACGSupported : 1; + UINT SupportSetTimingsFromVidPn : 1; + UINT Detachable : 1; + UINT ComputeOnly : 1; + UINT Prototype : 1; + UINT RuntimePowerManagement : 1; + UINT TestOnly : 1; + UINT SingleAdapterHybridMode : 1; + UINT Reserved : 16; + }; + UINT Value; + }; +} D3DKMT_ADAPTERTYPE; + typedef enum _KMTQUERYADAPTERINFOTYPE { KMTQAITYPE_UMDRIVERPRIVATE, -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11433