Skip to content

Commit

Permalink
Dynamically detect D3D12 feature level
Browse files Browse the repository at this point in the history
  • Loading branch information
SafariMonkey committed Dec 10, 2023
1 parent bcc7d94 commit 0a72a25
Showing 1 changed file with 40 additions and 10 deletions.
50 changes: 40 additions & 10 deletions src/graphics/d3d12.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use openxr as xr;
use wgpu::Instance;
use wgpu_hal::{Adapter as HalAdapter, Instance as HalInstance};
use winapi::shared::dxgiformat::{self, DXGI_FORMAT};
use winapi::um::d3dcommon;
use winapi::um::{d3d12 as winapi_d3d12, d3dcommon};

use crate::input::XrInput;
use crate::resources::{
Expand Down Expand Up @@ -82,16 +82,7 @@ pub fn initialize_xr_graphics(

let blend_mode = xr_instance.enumerate_environment_blend_modes(xr_system_id, VIEW_TYPE)?[0];

// wgpu hardcodes this, so we'll hardcode it here too
let d3d_target_version: u32 = d3dcommon::D3D_FEATURE_LEVEL_11_0;

let reqs = xr_instance.graphics_requirements::<xr::D3D12>(xr_system_id)?;
if (d3d_target_version) < (reqs.min_feature_level as u32) {
panic!(
"OpenXR runtime requires D3D12 feature level >= {}",
reqs.min_feature_level
);
}

let instance_descriptor = &wgpu_hal::InstanceDescriptor {
name: option_env!("CARGO_BIN_NAME").unwrap_or("bevy"),
Expand Down Expand Up @@ -140,6 +131,15 @@ pub fn initialize_xr_graphics(
.open(wgpu_features, &wgpu_limits)?
};

let device_supported_feature_level: d3d12::FeatureLevel = get_device_feature_level(wgpu_open_device.device.raw_device());

if (device_supported_feature_level as u32) < (reqs.min_feature_level as u32) {
panic!(
"OpenXR runtime requires D3D12 feature level >= {}",
reqs.min_feature_level
);
}

let (session, frame_wait, frame_stream) = unsafe {
xr_instance.create_session::<xr::D3D12>(
xr_system_id,
Expand Down Expand Up @@ -291,6 +291,36 @@ pub fn initialize_xr_graphics(
))
}

// Extracted from https://github.com/gfx-rs/wgpu/blob/1161a22f4fbb4fc204eb06f2ac4243f83e0e980d/wgpu-hal/src/dx12/adapter.rs#L73-L94
// license: MIT OR Apache-2.0
fn get_device_feature_level(device: &d3d12::ComPtr<winapi_d3d12::ID3D12Device>) -> d3d12::FeatureLevel {
// Detect the highest supported feature level.
let d3d_feature_level = [
d3d12::FeatureLevel::L12_1,
d3d12::FeatureLevel::L12_0,
d3d12::FeatureLevel::L11_1,
d3d12::FeatureLevel::L11_0,
];
type FeatureLevelsInfo = winapi_d3d12::D3D12_FEATURE_DATA_FEATURE_LEVELS;
let mut device_levels: FeatureLevelsInfo =
unsafe { std::mem::zeroed() };
device_levels.NumFeatureLevels = d3d_feature_level.len() as u32;
device_levels.pFeatureLevelsRequested = d3d_feature_level.as_ptr().cast();
unsafe {
device.CheckFeatureSupport(
winapi_d3d12::D3D12_FEATURE_FEATURE_LEVELS,
(&mut device_levels as *mut FeatureLevelsInfo).cast(),
std::mem::size_of::<FeatureLevelsInfo>() as _,
)
};
// This cast should never fail because we only requested feature levels that are already in the enum.
let max_feature_level =
d3d12::FeatureLevel::try_from(device_levels.MaxSupportedFeatureLevel)
.expect("Unexpected feature level");
max_feature_level
}


fn wgpu_to_d3d12(format: wgpu::TextureFormat) -> Option<DXGI_FORMAT> {
// Copied wholesale from:
// https://github.com/gfx-rs/wgpu/blob/a7defb723f856d946d6d220e9897d20dbb7b8f61/wgpu-hal/src/auxil/dxgi/conv.rs#L4-L84
Expand Down

0 comments on commit 0a72a25

Please sign in to comment.