I'm getting the following error when getting a D3D12DebugInterface
in Rust using the windows-rs crate:
failed to get d3d12 debug interface: No such interface supported (0x80004002)
Here's the code that I think should work:
#[derive(Default)]
struct DebugLayer {
d3d12_debug: Option<ID3D12Debug6>,
dxgi_debug: Option<IDXGIDebug1>,
}
impl DebugLayer {
fn init() -> Self {
unsafe {
let mut debug_layer = Self::default();
match D3D12GetDebugInterface(&mut debug_layer.d3d12_debug) {
Ok(()) => {
if let Some(ref d3d12_debug) = debug_layer.d3d12_debug {
d3d12_debug.EnableDebugLayer();
println!("d3d12: debug layer enabled");
match DXGIGetDebugInterface1::<IDXGIDebug1>(0) {
Ok(dxgi_debug) => {
dxgi_debug.EnableLeakTrackingForThread();
println!("d3d12: leak tracking enabled");
debug_layer.dxgi_debug = Some(dxgi_debug);
}
Err(err) => println!("failed to get dxgi debug interface: {}", err),
}
}
}
Err(err) => println!("failed to get d3d12 debug interface: {}", err),
}
debug_layer
}
}
}
And the features that I'm enabling in my Cargo.toml:
[target.'cfg(target_os = "windows")'.dependencies.windows]
version = "0.52.0"
features = [
"Win32_Foundation",
"Win32_Graphics_Gdi",
"Win32_Graphics_Direct3D_Fxc",
"Win32_Graphics_Direct3D12",
"Win32_Graphics_Dxgi_Common",
"Win32_Security",
"Win32_System_LibraryLoader",
"Win32_System_Threading",
"Win32_System_WindowsProgramming",
"Win32_UI_Input_KeyboardAndMouse",
"Win32_UI_WindowsAndMessaging",
]
I'm on Windows 10 and I've check in my settings and I have the Graphics Tools installed. What am I missing / doing wrong?
The error diagnostic is spot-on:
ID3D12Debug6
isn't available on your system (or mine1). That's what the error code0x80004002
(i.e.E_NOINTERFACE
) communicates.Here is a minimal sample that illustrates the issue.
Cargo.toml
src/main.rs
Issuing
cargo run
produces the following output1:This isn't something you can "fix" by changing your code. The requested interface (
ID3D12Debug6
) isn't implemented in binaries that ship with your OS distribution.Availability of the debug interfaces depends on the system where the code executes. This is outside your control, and you have to write code that adapts to available features instead.
To illustrate this, the following code initially requests the
ID3D12Debug
interface and subsequently checks whether later interfaces are implemented. It does this by calling thecast()
generic of theComInterface
trait. This iswindows-rs
' implementation ofQueryInterface()
. The trailingok()
convertsResult<T, E>
toOption<T>
for convenience.src/main.rs
Running this produces the following output1:
The code is rather verbose, but you would generally only ask for interfaces you are interested in using. The benefit of the added complexity is that it can take advantage of features as they become available without having to be recompiled and redeployed.
Features become available in one of two ways:
The latter seems to have happened in the past. The documentation for
ID3D12Debug3
lists the minimum system requirements as:As documented, the
ID3D12Debug3
interface shouldn't be available on my system, but the output above clearly disagrees. Writing "version-adaptive code" that checks for feature availability rather than OS version is thus strongly recommended.1 Windows 10 Version 22H2 (OS Build 19045.3693).