diff --git a/blade-graphics/src/gles/egl.rs b/blade-graphics/src/gles/egl.rs index 9230807a..65d23863 100644 --- a/blade-graphics/src/gles/egl.rs +++ b/blade-graphics/src/gles/egl.rs @@ -124,6 +124,7 @@ pub struct Context { inner: Mutex, pub(super) capabilities: super::Capabilities, pub(super) limits: super::Limits, + pub(super) device_information: crate::DeviceInformation, } pub struct ContextLock<'a> { @@ -208,7 +209,7 @@ impl Context { let egl_context = EglContext::init(&desc, egl, display)?; egl_context.make_current(); - let (glow, capabilities, limits) = egl_context.load_functions(&desc); + let (glow, capabilities, device_information, limits) = egl_context.load_functions(&desc); egl_context.unmake_current(); Ok(Self { @@ -220,6 +221,7 @@ impl Context { }), capabilities, limits, + device_information, }) } @@ -322,7 +324,7 @@ impl Context { let egl_context = EglContext::init(&desc, egl, display)?; egl_context.make_current(); - let (glow, capabilities, limits) = egl_context.load_functions(&desc); + let (glow, capabilities, device_information, limits) = egl_context.load_functions(&desc); let renderbuf = glow.create_renderbuffer().unwrap(); let framebuf = glow.create_framebuffer().unwrap(); egl_context.unmake_current(); @@ -341,6 +343,7 @@ impl Context { }), capabilities, limits, + device_information, }) } @@ -773,7 +776,12 @@ impl EglContext { unsafe fn load_functions( &self, desc: &crate::ContextDesc, - ) -> (glow::Context, super::Capabilities, super::Limits) { + ) -> ( + glow::Context, + super::Capabilities, + crate::DeviceInformation, + super::Limits, + ) { let mut gl = glow::Context::from_loader_function(|name| { self.instance .get_proc_address(name) @@ -802,6 +810,12 @@ impl EglContext { log::info!("Vendor: {}", vendor); log::info!("Renderer: {}", renderer); log::info!("Version: {}", version); + let device_information = crate::DeviceInformation { + is_software_emulated: false, + device_name: vendor, + driver_name: renderer, + driver_info: version, + }; let mut capabilities = super::Capabilities::empty(); capabilities.set( @@ -823,7 +837,7 @@ impl EglContext { uniform_buffer_alignment: gl.get_parameter_i32(glow::UNIFORM_BUFFER_OFFSET_ALIGNMENT) as u32, }; - (gl, capabilities, limits) + (gl, capabilities, device_information, limits) } } diff --git a/blade-graphics/src/gles/mod.rs b/blade-graphics/src/gles/mod.rs index 213f1b1d..f2fcbe1e 100644 --- a/blade-graphics/src/gles/mod.rs +++ b/blade-graphics/src/gles/mod.rs @@ -404,6 +404,10 @@ impl Context { ray_query: crate::ShaderVisibility::empty(), } } + + pub fn device_information(&self) -> &crate::DeviceInformation { + &self.device_information + } } #[hidden_trait::expose] diff --git a/blade-graphics/src/gles/web.rs b/blade-graphics/src/gles/web.rs index 4311167c..53282bf5 100644 --- a/blade-graphics/src/gles/web.rs +++ b/blade-graphics/src/gles/web.rs @@ -17,6 +17,7 @@ pub struct Context { swapchain: Swapchain, pub(super) capabilities: super::Capabilities, pub(super) limits: super::Limits, + pub(super) device_information: crate::DeviceInformation, } impl Context { @@ -73,12 +74,20 @@ impl Context { extent: Cell::default(), }; + let device_information = crate::DeviceInformation { + is_software_emulated: false, + device_name: glow.get_parameter_string(glow::VENDOR), + driver_name: glow.get_parameter_string(glow::RENDERER), + driver_info: glow.get_parameter_string(glow::VERSION), + }; + Ok(Self { webgl2, glow, swapchain, capabilities, limits, + device_information, }) } diff --git a/blade-graphics/src/lib.rs b/blade-graphics/src/lib.rs index 8ecb34ad..8f7d03ee 100644 --- a/blade-graphics/src/lib.rs +++ b/blade-graphics/src/lib.rs @@ -114,6 +114,18 @@ pub struct Capabilities { pub ray_query: ShaderVisibility, } +#[derive(Clone, Debug, Default)] +pub struct DeviceInformation { + /// If this is something like llvmpipe, not a real GPU + pub is_software_emulated: bool, + /// The name of the GPU device + pub device_name: String, + /// The driver used to talk to the GPU + pub driver_name: String, + /// Further information about the driver + pub driver_info: String, +} + #[derive(Clone, Copy, Debug, PartialEq)] pub enum Memory { /// Device-local memory. Fast for GPU operations. diff --git a/blade-graphics/src/metal/mod.rs b/blade-graphics/src/metal/mod.rs index 56caf6c9..22352ca8 100644 --- a/blade-graphics/src/metal/mod.rs +++ b/blade-graphics/src/metal/mod.rs @@ -49,6 +49,7 @@ pub struct Context { surface: Option>, capture: Option, info: DeviceInfo, + device_information: crate::DeviceInformation, } #[derive(Clone, Copy, Debug, Hash, PartialEq)] @@ -413,6 +414,12 @@ impl Context { } else { None }; + let device_information = crate::DeviceInformation { + is_software_emulated: false, + device_name: device.name().to_string(), + driver_name: "Metal".to_string(), + driver_info: "".to_string(), + }; Ok(Context { device: Mutex::new(device), @@ -423,6 +430,7 @@ impl Context { //TODO: determine based on OS version language_version: metal::MTLLanguageVersion::V2_4, }, + device_information, }) } @@ -465,6 +473,10 @@ impl Context { } } + pub fn device_information(&self) -> &crate::DeviceInformation { + &self.device_information + } + /// Get the CALayerMetal for this surface, if any. /// This is platform specific API. pub fn metal_layer(&self) -> Option { diff --git a/blade-graphics/src/vulkan/init.rs b/blade-graphics/src/vulkan/init.rs index a2b74c2f..5035155f 100644 --- a/blade-graphics/src/vulkan/init.rs +++ b/blade-graphics/src/vulkan/init.rs @@ -37,6 +37,7 @@ struct SystemBugs { struct AdapterCapabilities { api_version: u32, properties: vk::PhysicalDeviceProperties, + device_information: crate::DeviceInformation, queue_family_index: u32, layered: bool, ray_tracing: bool, @@ -88,12 +89,15 @@ unsafe fn inspect_adapter( vk::PhysicalDeviceAccelerationStructurePropertiesKHR::default(); let mut portability_subset_properties = vk::PhysicalDevicePortabilitySubsetPropertiesKHR::default(); + + let mut driver_properties = vk::PhysicalDeviceDriverPropertiesKHR::default(); let mut properties2_khr = vk::PhysicalDeviceProperties2KHR::default() .push_next(&mut inline_uniform_block_properties) .push_next(&mut timeline_semaphore_properties) .push_next(&mut descriptor_indexing_properties) .push_next(&mut acceleration_structure_properties) - .push_next(&mut portability_subset_properties); + .push_next(&mut portability_subset_properties) + .push_next(&mut driver_properties); instance .get_physical_device_properties2 .get_physical_device_properties2(phd, &mut properties2_khr); @@ -153,6 +157,10 @@ unsafe fn inspect_adapter( .get_physical_device_properties2 .get_physical_device_features2(phd, &mut features2_khr); + instance + .get_physical_device_properties2 + .get_physical_device_properties2(phd, &mut properties2_khr); + let properties = properties2_khr.properties; let name = ffi::CStr::from_ptr(properties.device_name.as_ptr()); log::info!("Adapter {:?}", name); @@ -232,9 +240,23 @@ unsafe fn inspect_adapter( let shader_info = supported_extensions.contains(&vk::AMD_SHADER_INFO_NAME); let full_screen_exclusive = supported_extensions.contains(&vk::EXT_FULL_SCREEN_EXCLUSIVE_NAME); + let device_information = crate::DeviceInformation { + is_software_emulated: properties.device_type == ash::vk::PhysicalDeviceType::CPU, + device_name: ffi::CStr::from_ptr(properties.device_name.as_ptr()) + .to_string_lossy() + .to_string(), + driver_name: ffi::CStr::from_ptr(driver_properties.driver_name.as_ptr()) + .to_string_lossy() + .to_string(), + driver_info: ffi::CStr::from_ptr(driver_properties.driver_info.as_ptr()) + .to_string_lossy() + .to_string(), + }; + Some(AdapterCapabilities { api_version, properties, + device_information, queue_family_index, layered: portability_subset_properties.min_vertex_input_binding_stride_alignment != 0, ray_tracing, @@ -530,6 +552,7 @@ impl super::Context { None }, core: device_core, + device_information: capabilities.device_information, //TODO: detect GPU family workarounds: super::Workarounds { extra_sync_src_access: vk::AccessFlags::TRANSFER_WRITE, @@ -701,6 +724,10 @@ impl super::Context { }, } } + + pub fn device_information(&self) -> &crate::DeviceInformation { + &self.device.device_information + } } impl super::Context { diff --git a/blade-graphics/src/vulkan/mod.rs b/blade-graphics/src/vulkan/mod.rs index 7434721e..5329527d 100644 --- a/blade-graphics/src/vulkan/mod.rs +++ b/blade-graphics/src/vulkan/mod.rs @@ -29,6 +29,7 @@ struct Workarounds { #[derive(Clone)] struct Device { core: ash::Device, + device_information: crate::DeviceInformation, debug_utils: ash::ext::debug_utils::Device, timeline_semaphore: khr::timeline_semaphore::Device, dynamic_rendering: khr::dynamic_rendering::Device, diff --git a/examples/bunnymark/main.rs b/examples/bunnymark/main.rs index 2d2898c3..1e0740d4 100644 --- a/examples/bunnymark/main.rs +++ b/examples/bunnymark/main.rs @@ -73,6 +73,7 @@ impl Example { ) .unwrap() }; + println!("{:?}", context.device_information()); let surface_info = context.resize(gpu::SurfaceConfig { size: gpu::Extent {