A Rust registry for Vulkan vendor IDs, reviewed device IDs, chip labels, and
architecture categories. The library supports no_std, performs no allocations,
and requires Rust 1.88+. Optional ash integration is enabled by default.
Builds use a checked-in registry snapshot without downloading upstream data.
Add the crate to your Cargo.toml:
[dependencies]
vk-device-id = "0.1"use vk_device_id::{Architecture, Chip, DeviceId, Vendor, VendorId, device, lookup};
// Pass properties.vendor_id and properties.device_id to lookup when using ash.
let gpu: &DeviceId = lookup(0x10de, 0x2684).unwrap();
assert_eq!(gpu.vendor(), Some(Vendor::Nvidia));
assert_eq!(gpu.chip(), Some(Chip::NvidiaAd102));
assert_eq!(gpu.architecture(), Some(Architecture::NvidiaAdaLovelace));
assert_eq!(gpu.name(), Some("GeForce RTX 4090"));
// Named constants represent Vulkan IDs in their vendor's namespace.
assert_eq!(
lookup(VendorId::NVIDIA.as_raw(), device::nvidia::GEFORCE_RTX_4090.as_raw()),
Some(gpu),
);The API accepts raw u32 fields from any Vulkan binding. It requires no Vulkan
SDK or loader.
The default ash feature enables two safe conversions from ash 0.38 properties:
use ash::vk;
use vk_device_id::DeviceId;
let property = vk::PhysicalDeviceProperties {
vendor_id: 0x10de,
device_id: 0x2204,
..Default::default()
};
if let Some(gpu) = DeviceId::try_from_property(&property) {
println!("{gpu}"); // Nvidia GeForce RTX 3090
}
let property2 = vk::PhysicalDeviceProperties2 {
properties: property,
..Default::default()
};
let gpu = DeviceId::try_from_property2(&property2);Both return Option<&'static DeviceId>, matching lookup, including None for
unknown or feature-disabled devices. They read only the vendor/device IDs and
retain no reference to the input or its extension chain.
Standard TryFrom / TryInto conversions also accept owned or borrowed versions
of both ash structs:
use vk_device_id::DeviceId;
fn identify(property: &ash::vk::PhysicalDeviceProperties) -> Result<DeviceId, DeviceId> {
property.try_into()
// Equivalently: DeviceId::try_from(property)
}Trait conversions return Ok with a recognized identity or Err with an unknown
identity, both using DeviceId. An unknown value retains the full vendor/device
IDs internally: vendor() can still identify the vendor, while name(),
chip(), and architecture() return None. Distinct unknown IDs remain distinct
when compared. No input reference or driver-provided name is retained.
DeviceId implements core::error::Error for use with ? and general error
containers. Both conversion outcomes are allocation-free and Copy. The named
try_from_property / try_from_property2 functions provide an optional static
reference instead; a registry miss is simply None there.
use ash::vk;
use vk_device_id::{DeviceId, Vendor};
let property = vk::PhysicalDeviceProperties {
vendor_id: 0x10de,
device_id: 0xffff_2204,
..Default::default()
};
let unknown = DeviceId::try_from(&property).unwrap_err();
assert_eq!(unknown.vendor(), Some(Vendor::Nvidia));
assert_eq!(unknown.name(), None);
println!("{unknown}"); // Nvidia unknown deviceThe ash dependency has default-features = false: this crate does not enable
ash's std, debug, or Vulkan loader features. Ash itself uses Rust's alloc
crate; the conversion functions perform no allocations. For the dependency-free
core, disable default features and select only the hardware groups you need:
vk-device-id = { version = "0.1", default-features = false, features = ["desktop"] }DeviceId implements Display using the vendor and product name:
use vk_device_id::lookup;
let vendor_id = 0x10de;
let device_id = 0x2204;
if let Some(info) = lookup(vendor_id, device_id) {
println!("{info}");
// Nvidia GeForce RTX 3090
} else {
println!("Unknown GPU ({vendor_id:04x}:{device_id:04x})");
}Vendor, Chip, and Architecture display their readable labels, such as
Nvidia, GA102, and Ampere. VendorId and RawDeviceId display numeric IDs.
Formatting writes directly to the formatter, preserving no_std and avoiding
heap allocation. Shared product names remain intact. Use Debug, chip(),
architecture(), or vendor() for diagnostic details. name() returns the optional
product label, such as Some("GeForce RTX 3090"), for a custom UI layout. Unknown
identities display as Nvidia unknown device when the vendor is recognized, or
Unknown device otherwise. Source citations live in
res/override.toml and res/registry.toml rather than runtime records.
Four additive features select device constants and lookup records:
desktop: consumer desktop GPUs.server: server GPUs.workstation: professional workstation GPUs.mobile: laptop and mobile GPUs.
All four hardware features and ash are enabled by default. Select a smaller
registry while retaining ash conversion support with:
[dependencies]
vk-device-id = { version = "0.1", default-features = false, features = ["ash", "desktop", "mobile"] }Each reviewed pair has a nonempty class list in res/override.toml. A pair
is included when any of its classes is enabled. Shared IDs appear only once:
AMD 1002:744c covers both desktop RX 7900 products and the mobile RX 7900M;
1002:7480 covers desktop RX 7600 products, mobile variants, and PRO W7600.
Classes describe the reviewed product group, not the machine in which an
adapter happens to be installed, and are never inferred from a name or ID range.
Disabled device constants are absent, and lookup for disabled pairs returns
None. With no features, DEVICE is empty. Vendor, VendorId constants,
Chip, and Architecture catalogs remain available with every hardware feature selection.
VendorIdandRawDeviceIdpreserve all 32 bits, including unknown IDs.lookup(vendor_id, device_id)takes Vulkan's raw IDs; a device ID alone is not globally unique. It returnsOption<&'static DeviceId>using const-compatible, allocation-free binary search, O(log n).DeviceId::chip()andarchitecture()are independently optional. A chip such as AD102 is distinct from its Ada Lovelace architecture.DeviceIdis the main read-only identification type with a private known/unknown representation. It exposesvendor(),chip(),architecture(), andname()rather than fields or a public constructor.vendor()returns an optional recognized vendor;name()returnsOption<&'static str>, borrowing the product label for a known identity and returningNonefor an unknown identity. Provenance remains in the TOML resources without embedding source URLs in the runtime table.device::{amd,intel,nvidia}provides vendor-scopedRawDeviceIdconstants.DEVICElists only enabled, recognized identities for enumeration. The enumALLslices list their full catalogs.- Public enums are non-exhaustive. Keep default branches in application policies.
With all features, coverage is 21 vendors, 203 reviewed device pairs, 96 chip
labels, and 18 architecture categories. The desktop feature includes 106
pairs: 77 NVIDIA, 22 AMD, and 7 Intel.
- NVIDIA desktop: selected GTX 600/700, GTX 900, GTX 10/16, and RTX 20/30/40/50 products, spanning Kepler through Blackwell. Distinct VRAM, LHR, SUPER, Ti, and regional variants have separate constants where the reviewed IDs differ.
- AMD desktop: HD 7900, R9 200/300, Fury/Nano, RX 400/500, Vega, Radeon VII,
and RX 5000/6000/7000/9000 products, spanning GCN 1 through RDNA 4. Shared
retail identities use ID-qualified constants such as
NAVI_48_7550. - Intel desktop: Arc A310, A380, A580, A750, A770, B570, and B580, covering DG2 and Battlemage G21.
- Server (22 pairs): NVIDIA Tesla M10/M60/P4/P40/T4, A2/A16/A10/A40, L2/L4/L20/L40/L40S, and RTX PRO Blackwell server editions; AMD Radeon Pro V-series; Intel Flex 140/170.
- Workstation (41 pairs): NVIDIA Quadro P/RTX, RTX A-series, Ada and Blackwell professional GPUs; AMD Radeon Pro WX/W-series; Intel Arc Pro A/B. This includes 13 mobile workstation IDs and the shared Navi 33 / PRO W7600 ID.
- Mobile (54 pairs): discrete GeForce GTX 10/16 and RTX 20/30/40/50 laptop GPUs, Intel Arc A-series, Radeon RX 7600M variants, mobile workstation GPUs, and six shared AMD desktop/mobile IDs. This selection focuses on laptop GPUs.
Feature counts overlap: enabling mobile and workstation includes a mobile
workstation pair once. NVIDIA RTX PRO 6000 Blackwell workstation and server
editions have separate IDs and constants.
The complete reviewed list and per-pair citations are in res/override.toml.
Coverage is broad but not exhaustive; alternate OEM IDs and unreviewed products
still return None.
Only explicitly reviewed GPU pairs are imported. Dawn architecture masks do not add devices automatically. PCI membership, product class, and architecture labels do not prove Vulkan capabilities; query Vulkan features and limits. Chip labels retain their source's precision, including family-level DG2 and shared retail names. Constants identify exact IDs, not every SKU of a product.
Upstream revisions and checksums are pinned in res/source.toml. Reviewed device
pairs, hardware classes, and citations live in res/override.toml. After editing
either file, regenerate res/registry.toml with the updater:
# Fetch missing pinned inputs, validate checksums, and refresh the TOML snapshot.
cargo run --features update-registry --bin update-registry -- --fetch
# Verify the checked-in snapshot without changing it.
cargo run --features update-registry --bin update-registry -- --fetch --check
# Deliberately update one source and its snapshot.
cargo run --features update-registry --bin update-registry -- --pin dawn <40-character-commit-sha>Supported source names are pci, dawn, and vulkan. Inputs are cached in
target/registry-source; omit --fetch to use only cached inputs. Pin updates
do not expand the reviewed device list. Review resource changes and upstream
license notices before committing.
Handwritten code: MIT. Imported registry content also carries BSD-3-Clause terms;
the combined crate declares MIT AND BSD-3-Clause. See
THIRD-PARTY-NOTICE and the pinned sources in
res/source.toml.