implement gpu driver version for nvidia
This commit is contained in:
parent
76fb80eaeb
commit
4d936845f3
2 changed files with 112 additions and 7 deletions
|
@ -32,6 +32,7 @@ pub(crate) struct DirectXRenderer {
|
|||
/// Direct3D objects
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct DirectXDevices {
|
||||
adapter: IDXGIAdapter1,
|
||||
dxgi_factory: IDXGIFactory6,
|
||||
#[cfg(not(feature = "enable-renderdoc"))]
|
||||
dxgi_device: IDXGIDevice,
|
||||
|
@ -97,6 +98,7 @@ impl DirectXDevices {
|
|||
let dxgi_device: IDXGIDevice = device.cast()?;
|
||||
|
||||
Ok(Self {
|
||||
adapter,
|
||||
dxgi_factory,
|
||||
#[cfg(not(feature = "enable-renderdoc"))]
|
||||
dxgi_device,
|
||||
|
@ -396,6 +398,34 @@ impl DirectXRenderer {
|
|||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn gpu_specs(&self) -> Result<GpuSpecs> {
|
||||
let desc = unsafe { self.devices.adapter.GetDesc1() }?;
|
||||
let is_software_emulated = (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE.0 as u32) != 0;
|
||||
let device_name = String::from_utf16_lossy(&desc.Description)
|
||||
.trim_matches(char::from(0))
|
||||
.to_string();
|
||||
let driver_name = match desc.VendorId {
|
||||
0x10DE => "NVIDIA Corporation".to_string(),
|
||||
0x1002 => "AMD Corporation".to_string(),
|
||||
0x8086 => "Intel Corporation".to_string(),
|
||||
_ => "Unknown Vendor".to_string(),
|
||||
};
|
||||
let driver_version = match desc.VendorId {
|
||||
0x10DE => nvidia::get_driver_version().context("Failed to get NVIDIA driver info"),
|
||||
0x1002 => Err(anyhow::anyhow!("AMD driver info not implemented yet")),
|
||||
0x8086 => Err(anyhow::anyhow!("Intel driver info not implemented yet")),
|
||||
_ => Err(anyhow::anyhow!("Unknown vendor detected.")),
|
||||
}
|
||||
.log_err()
|
||||
.unwrap_or("Unknown Driver".to_string());
|
||||
Ok(GpuSpecs {
|
||||
is_software_emulated,
|
||||
device_name,
|
||||
driver_name,
|
||||
driver_info: driver_version,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl DirectXResources {
|
||||
|
@ -936,12 +966,11 @@ fn get_adapter(dxgi_factory: &IDXGIFactory6) -> Result<IDXGIAdapter1> {
|
|||
dxgi_factory
|
||||
.EnumAdapterByGpuPreference(adapter_index, DXGI_GPU_PREFERENCE_MINIMUM_POWER)
|
||||
}?;
|
||||
{
|
||||
let desc = unsafe { adapter.GetDesc1() }?;
|
||||
println!(
|
||||
"Select GPU: {}",
|
||||
String::from_utf16_lossy(&desc.Description)
|
||||
);
|
||||
if let Ok(desc) = unsafe { adapter.GetDesc1() } {
|
||||
let gpu_name = String::from_utf16_lossy(&desc.Description)
|
||||
.trim_matches(char::from(0))
|
||||
.to_string();
|
||||
log::info!("Using GPU: {}", gpu_name);
|
||||
}
|
||||
// Check to see whether the adapter supports Direct3D 11, but don't
|
||||
// create the actual device yet.
|
||||
|
@ -1339,3 +1368,78 @@ mod shader_resources {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod nvidia {
|
||||
use std::os::raw::{c_char, c_int, c_uint};
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use windows::{
|
||||
Win32::System::LibraryLoader::{GetProcAddress, LoadLibraryA},
|
||||
core::s,
|
||||
};
|
||||
|
||||
// https://github.com/NVIDIA/nvapi/blob/7cb76fce2f52de818b3da497af646af1ec16ce27/nvapi_lite_common.h#L180
|
||||
const NVAPI_SHORT_STRING_MAX: usize = 64;
|
||||
|
||||
// https://github.com/NVIDIA/nvapi/blob/7cb76fce2f52de818b3da497af646af1ec16ce27/nvapi_lite_common.h#L235
|
||||
#[allow(non_camel_case_types)]
|
||||
type NvAPI_ShortString = [c_char; NVAPI_SHORT_STRING_MAX];
|
||||
|
||||
// https://github.com/NVIDIA/nvapi/blob/7cb76fce2f52de818b3da497af646af1ec16ce27/nvapi.h#L87
|
||||
#[allow(non_camel_case_types)]
|
||||
type NvAPI_Initialize_t = unsafe extern "C" fn() -> c_int;
|
||||
|
||||
// https://github.com/NVIDIA/nvapi/blob/7cb76fce2f52de818b3da497af646af1ec16ce27/nvapi_lite_common.h#L447
|
||||
#[allow(non_camel_case_types)]
|
||||
type NvAPI_SYS_GetDriverAndBranchVersion_t = unsafe extern "C" fn(
|
||||
driver_version: *mut c_uint,
|
||||
build_branch_string: *mut NvAPI_ShortString,
|
||||
) -> c_int;
|
||||
|
||||
pub(super) fn get_driver_version() -> Result<String> {
|
||||
unsafe {
|
||||
// Try to load the NVIDIA driver DLL
|
||||
let nvidia_dll = LoadLibraryA(s!("nvapi64.dll")).context("Can't load nvapi64.dll")?;
|
||||
let nvapi_query_addr = GetProcAddress(nvidia_dll, s!("nvapi_QueryInterface"))
|
||||
.ok_or_else(|| anyhow::anyhow!("Failed to get nvapi_QueryInterface address"))?;
|
||||
let nvapi_query: extern "C" fn(u32) -> *mut () = std::mem::transmute(nvapi_query_addr);
|
||||
|
||||
// https://github.com/NVIDIA/nvapi/blob/7cb76fce2f52de818b3da497af646af1ec16ce27/nvapi_interface.h#L33
|
||||
let nvapi_init_ptr = nvapi_query(0x0150e828);
|
||||
if nvapi_init_ptr.is_null() {
|
||||
anyhow::bail!("Failed to get NVIDIA API function pointer");
|
||||
}
|
||||
let nvapi_init: NvAPI_Initialize_t = std::mem::transmute(nvapi_init_ptr);
|
||||
|
||||
let result = nvapi_init();
|
||||
if result != 0 {
|
||||
anyhow::bail!("Failed to initialize NVIDIA API, error code: {}", result);
|
||||
}
|
||||
|
||||
// https://github.com/NVIDIA/nvapi/blob/7cb76fce2f52de818b3da497af646af1ec16ce27/nvapi_interface.h#L41
|
||||
let nvapi_get_driver_version_ptr = nvapi_query(0x2926aaad);
|
||||
if nvapi_get_driver_version_ptr.is_null() {
|
||||
anyhow::bail!("Failed to get NVIDIA driver version function pointer");
|
||||
}
|
||||
let nvapi_get_driver_version: NvAPI_SYS_GetDriverAndBranchVersion_t =
|
||||
std::mem::transmute(nvapi_get_driver_version_ptr);
|
||||
|
||||
let mut driver_version: c_uint = 0;
|
||||
let mut build_branch_string: NvAPI_ShortString = [0; NVAPI_SHORT_STRING_MAX];
|
||||
let result = nvapi_get_driver_version(
|
||||
&mut driver_version as *mut c_uint,
|
||||
&mut build_branch_string as *mut NvAPI_ShortString,
|
||||
);
|
||||
|
||||
if result != 0 {
|
||||
anyhow::bail!(
|
||||
"Failed to get NVIDIA driver version, error code: {}",
|
||||
result
|
||||
);
|
||||
}
|
||||
let major = driver_version / 100;
|
||||
let minor = driver_version % 100;
|
||||
Ok(format!("{}.{}", major, minor))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,6 +104,7 @@ impl WindowsWindowState {
|
|||
let restore_from_minimized = None;
|
||||
// let renderer = windows_renderer::init(gpu_context, hwnd, transparent)?;
|
||||
let renderer = DirectXRenderer::new(gpu_context, hwnd)?;
|
||||
println!("GPU specs: {:#?}", renderer.gpu_specs());
|
||||
let callbacks = Callbacks::default();
|
||||
let input_handler = None;
|
||||
let pending_surrogate = None;
|
||||
|
@ -801,7 +802,7 @@ impl PlatformWindow for WindowsWindow {
|
|||
}
|
||||
|
||||
fn update_ime_position(&self, _bounds: Bounds<ScaledPixels>) {
|
||||
// todo(windows)
|
||||
// There is no such thing on Windows.
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue