mirror of
https://github.com/gfx-rs/wgpu.git
synced 2025-12-08 21:26:17 +00:00
Add pci bus and device uuid to AdapterInfo (#8290)
This commit is contained in:
parent
982a2100f4
commit
0810110bd7
@ -319,6 +319,7 @@ mod tests {
|
||||
vendor: 0x0002_FEED,
|
||||
device: 0xFEFE_FEFE,
|
||||
device_type: wgt::DeviceType::Other,
|
||||
device_pci_bus_id: String::new(),
|
||||
driver: String::new(),
|
||||
driver_info: String::new(),
|
||||
backend: wgt::Backend::Vulkan,
|
||||
|
||||
@ -143,6 +143,8 @@ dx12 = [
|
||||
"dep:range-alloc",
|
||||
"dep:windows-core",
|
||||
"dep:gpu-allocator",
|
||||
"gpu-allocator/d3d12",
|
||||
"windows/Win32_Devices_DeviceAndDriverInstallation",
|
||||
"windows/Win32_Graphics_Direct3D_Fxc",
|
||||
"windows/Win32_Graphics_Direct3D_Dxc",
|
||||
"windows/Win32_Graphics_Direct3D",
|
||||
|
||||
@ -6,6 +6,12 @@ use parking_lot::Mutex;
|
||||
use windows::{
|
||||
core::Interface as _,
|
||||
Win32::{
|
||||
Devices::DeviceAndDriverInstallation::{
|
||||
SetupDiDestroyDeviceInfoList, SetupDiEnumDeviceInfo, SetupDiGetClassDevsW,
|
||||
SetupDiGetDeviceRegistryPropertyW, DIGCF_PRESENT, GUID_DEVCLASS_DISPLAY, HDEVINFO,
|
||||
SPDRP_ADDRESS, SPDRP_BUSNUMBER, SPDRP_HARDWAREID, SP_DEVINFO_DATA,
|
||||
},
|
||||
Foundation::{GetLastError, ERROR_NO_MORE_ITEMS},
|
||||
Graphics::{Direct3D, Direct3D12, Dxgi},
|
||||
UI::WindowsAndMessaging,
|
||||
},
|
||||
@ -127,6 +133,7 @@ impl super::Adapter {
|
||||
} else {
|
||||
wgt::DeviceType::DiscreteGpu
|
||||
},
|
||||
device_pci_bus_id: get_adapter_pci_info(desc.VendorId, desc.DeviceId),
|
||||
driver: {
|
||||
if let Ok(i) = unsafe { adapter.CheckInterfaceSupport(&Dxgi::IDXGIDevice::IID) } {
|
||||
const MASK: i64 = 0xFFFF;
|
||||
@ -1024,3 +1031,147 @@ impl crate::Adapter for super::Adapter {
|
||||
wgt::PresentationTimestamp(self.presentation_timer.get_timestamp_ns())
|
||||
}
|
||||
}
|
||||
|
||||
fn get_adapter_pci_info(vendor_id: u32, device_id: u32) -> String {
|
||||
// SAFETY: SetupDiGetClassDevsW is called with valid parameters
|
||||
let device_info_set = unsafe {
|
||||
match SetupDiGetClassDevsW(Some(&GUID_DEVCLASS_DISPLAY), None, None, DIGCF_PRESENT) {
|
||||
Ok(set) => set,
|
||||
Err(_) => return String::new(),
|
||||
}
|
||||
};
|
||||
|
||||
struct DeviceInfoSetGuard(HDEVINFO);
|
||||
impl Drop for DeviceInfoSetGuard {
|
||||
fn drop(&mut self) {
|
||||
// SAFETY: device_info_set is a valid HDEVINFO and is only dropped once via this guard
|
||||
unsafe {
|
||||
let _ = SetupDiDestroyDeviceInfoList(self.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
let _guard = DeviceInfoSetGuard(device_info_set);
|
||||
|
||||
let mut device_index = 0u32;
|
||||
loop {
|
||||
let mut device_info_data = SP_DEVINFO_DATA {
|
||||
cbSize: size_of::<SP_DEVINFO_DATA>() as u32,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
// SAFETY: device_info_set is a valid HDEVINFO, device_index starts at 0 and
|
||||
// device_info_data is properly initialized above
|
||||
unsafe {
|
||||
if SetupDiEnumDeviceInfo(device_info_set, device_index, &mut device_info_data).is_err()
|
||||
{
|
||||
if GetLastError() == ERROR_NO_MORE_ITEMS {
|
||||
break;
|
||||
}
|
||||
device_index += 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
let mut hardware_id_size = 0u32;
|
||||
// SAFETY: device_info_set and device_info_data are valid
|
||||
unsafe {
|
||||
let _ = SetupDiGetDeviceRegistryPropertyW(
|
||||
device_info_set,
|
||||
&device_info_data,
|
||||
SPDRP_HARDWAREID,
|
||||
None,
|
||||
None,
|
||||
Some(&mut hardware_id_size),
|
||||
);
|
||||
}
|
||||
|
||||
if hardware_id_size == 0 {
|
||||
device_index += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut hardware_id_buffer = vec![0u8; hardware_id_size as usize];
|
||||
// SAFETY: device_info_set and device_info_data are valid
|
||||
unsafe {
|
||||
if SetupDiGetDeviceRegistryPropertyW(
|
||||
device_info_set,
|
||||
&device_info_data,
|
||||
SPDRP_HARDWAREID,
|
||||
None,
|
||||
Some(&mut hardware_id_buffer),
|
||||
Some(&mut hardware_id_size),
|
||||
)
|
||||
.is_err()
|
||||
{
|
||||
device_index += 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
let hardware_id_u16: Vec<u16> = hardware_id_buffer
|
||||
.chunks_exact(2)
|
||||
.map(|chunk| u16::from_le_bytes([chunk[0], chunk[1]]))
|
||||
.collect();
|
||||
let hardware_ids: Vec<String> = hardware_id_u16
|
||||
.split(|&c| c == 0)
|
||||
.filter(|s| !s.is_empty())
|
||||
.map(|s| String::from_utf16_lossy(s).to_uppercase())
|
||||
.collect();
|
||||
|
||||
// https://learn.microsoft.com/en-us/windows-hardware/drivers/install/identifiers-for-pci-devices
|
||||
let expected_id = format!("PCI\\VEN_{vendor_id:04X}&DEV_{device_id:04X}");
|
||||
if !hardware_ids.iter().any(|id| id.contains(&expected_id)) {
|
||||
device_index += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut bus_buffer = [0u8; 4];
|
||||
let mut data_size = bus_buffer.len() as u32;
|
||||
// SAFETY: device_info_set and device_info_data are valid
|
||||
let bus_number = unsafe {
|
||||
if SetupDiGetDeviceRegistryPropertyW(
|
||||
device_info_set,
|
||||
&device_info_data,
|
||||
SPDRP_BUSNUMBER,
|
||||
None,
|
||||
Some(&mut bus_buffer),
|
||||
Some(&mut data_size),
|
||||
)
|
||||
.is_err()
|
||||
{
|
||||
device_index += 1;
|
||||
continue;
|
||||
}
|
||||
u32::from_le_bytes(bus_buffer)
|
||||
};
|
||||
|
||||
let mut addr_buffer = [0u8; 4];
|
||||
let mut addr_size = addr_buffer.len() as u32;
|
||||
// SAFETY: device_info_set and device_info_data are valid
|
||||
unsafe {
|
||||
if SetupDiGetDeviceRegistryPropertyW(
|
||||
device_info_set,
|
||||
&device_info_data,
|
||||
SPDRP_ADDRESS,
|
||||
None,
|
||||
Some(&mut addr_buffer),
|
||||
Some(&mut addr_size),
|
||||
)
|
||||
.is_err()
|
||||
{
|
||||
device_index += 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
let address = u32::from_le_bytes(addr_buffer);
|
||||
|
||||
// https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/obtaining-device-configuration-information-at-irql---dispatch-level
|
||||
let device = (address >> 16) & 0x0000FFFF;
|
||||
let function = address & 0x0000FFFF;
|
||||
|
||||
// domain:bus:device.function
|
||||
return format!("{:04x}:{:02x}:{:02x}.{:x}", 0, bus_number, device, function);
|
||||
}
|
||||
|
||||
String::new()
|
||||
}
|
||||
|
||||
@ -187,6 +187,7 @@ impl super::Adapter {
|
||||
device: 0,
|
||||
device_type: inferred_device_type,
|
||||
driver: "".to_owned(),
|
||||
device_pci_bus_id: String::new(),
|
||||
driver_info: version,
|
||||
backend: wgt::Backend::Gl,
|
||||
transient_saves_memory: false,
|
||||
|
||||
@ -156,6 +156,7 @@ impl crate::Instance for Instance {
|
||||
vendor: 0,
|
||||
device: 0,
|
||||
device_type: shared.private_caps.device_type(),
|
||||
device_pci_bus_id: String::new(),
|
||||
driver: String::new(),
|
||||
driver_info: String::new(),
|
||||
backend: wgt::Backend::Metal,
|
||||
|
||||
@ -137,6 +137,7 @@ pub fn adapter_info() -> wgt::AdapterInfo {
|
||||
vendor: 0,
|
||||
device: 0,
|
||||
device_type: wgt::DeviceType::Cpu,
|
||||
device_pci_bus_id: String::new(),
|
||||
driver: String::from("wgpu"),
|
||||
driver_info: String::new(),
|
||||
backend: wgt::Backend::Noop,
|
||||
|
||||
@ -962,6 +962,10 @@ pub struct PhysicalDeviceProperties {
|
||||
/// `VK_EXT_mesh_shader` extension.
|
||||
mesh_shader: Option<vk::PhysicalDeviceMeshShaderPropertiesEXT<'static>>,
|
||||
|
||||
/// Additional `vk::PhysicalDevice` properties from the
|
||||
/// `VK_EXT_pci_bus_info` extension.
|
||||
pci_bus_info: Option<vk::PhysicalDevicePCIBusInfoPropertiesEXT<'static>>,
|
||||
|
||||
/// The device API version.
|
||||
///
|
||||
/// Which is the version of Vulkan supported for device-level functionality.
|
||||
@ -1392,6 +1396,8 @@ impl super::InstanceShared {
|
||||
>= vk::API_VERSION_1_3
|
||||
|| capabilities.supports_extension(ext::subgroup_size_control::NAME);
|
||||
let supports_robustness2 = capabilities.supports_extension(ext::robustness2::NAME);
|
||||
let supports_pci_bus_info =
|
||||
capabilities.supports_extension(ext::pci_bus_info::NAME);
|
||||
|
||||
let supports_acceleration_structure =
|
||||
capabilities.supports_extension(khr::acceleration_structure::NAME);
|
||||
@ -1448,6 +1454,13 @@ impl super::InstanceShared {
|
||||
properties2 = properties2.push_next(next);
|
||||
}
|
||||
|
||||
if supports_pci_bus_info {
|
||||
let next = capabilities
|
||||
.pci_bus_info
|
||||
.insert(vk::PhysicalDevicePCIBusInfoPropertiesEXT::default());
|
||||
properties2 = properties2.push_next(next);
|
||||
}
|
||||
|
||||
if supports_mesh_shader {
|
||||
let next = capabilities
|
||||
.mesh_shader
|
||||
@ -1672,6 +1685,16 @@ impl super::Instance {
|
||||
vk::PhysicalDeviceType::CPU => wgt::DeviceType::Cpu,
|
||||
_ => wgt::DeviceType::Other,
|
||||
},
|
||||
device_pci_bus_id: phd_capabilities
|
||||
.pci_bus_info
|
||||
.filter(|info| info.pci_bus != 0 || info.pci_device != 0)
|
||||
.map(|info| {
|
||||
format!(
|
||||
"{:04x}:{:02x}:{:02x}.{}",
|
||||
info.pci_domain, info.pci_bus, info.pci_device, info.pci_function
|
||||
)
|
||||
})
|
||||
.unwrap_or_default(),
|
||||
driver: {
|
||||
phd_capabilities
|
||||
.driver
|
||||
|
||||
@ -99,6 +99,7 @@ fn print_adapter(output: &mut impl io::Write, report: &AdapterReport, idx: usize
|
||||
writeln!(output, "\t Name: {}", info.name)?;
|
||||
writeln!(output, "\t VendorID: {:#X?}", info.vendor)?;
|
||||
writeln!(output, "\t DeviceID: {:#X?}", info.device)?;
|
||||
writeln!(output, "\t DevicePCIBusId: {}", print_empty_string(&info.device_pci_bus_id))?;
|
||||
writeln!(output, "\t Type: {:?}", info.device_type)?;
|
||||
writeln!(output, "\t Driver: {}", print_empty_string(&info.driver))?;
|
||||
writeln!(output, "\t DriverInfo: {}", print_empty_string(&info.driver_info))?;
|
||||
|
||||
@ -1409,6 +1409,13 @@ pub struct AdapterInfo {
|
||||
pub device: u32,
|
||||
/// Type of device
|
||||
pub device_type: DeviceType,
|
||||
/// [`Backend`]-specific PCI bus ID of the adapter.
|
||||
///
|
||||
/// * For [`Backend::Vulkan`], [`VkPhysicalDevicePCIBusInfoPropertiesEXT`] is used,
|
||||
/// if available, in the form `bus:device.function`, e.g. `0000:01:00.0`.
|
||||
///
|
||||
/// [`VkPhysicalDevicePCIBusInfoPropertiesEXT`]: https://registry.khronos.org/vulkan/specs/latest/man/html/VkPhysicalDevicePCIBusInfoPropertiesEXT.html
|
||||
pub device_pci_bus_id: String,
|
||||
/// Driver name
|
||||
pub driver: String,
|
||||
/// Driver info
|
||||
|
||||
@ -1707,6 +1707,7 @@ impl dispatch::AdapterInterface for WebAdapter {
|
||||
vendor: 0,
|
||||
device: 0,
|
||||
device_type: wgt::DeviceType::Other,
|
||||
device_pci_bus_id: String::new(),
|
||||
driver: String::new(),
|
||||
driver_info: String::new(),
|
||||
backend: wgt::Backend::BrowserWebGpu,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user