Skip to content

Commit fec7140

Browse files
committed
[d3d12] add support for optional adapter telemetry
1 parent 7572bf2 commit fec7140

File tree

13 files changed

+178
-77
lines changed

13 files changed

+178
-77
lines changed

deno_webgpu/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ impl GPU {
180180
noop: wgpu_types::NoopBackendOptions::default(),
181181
},
182182
},
183+
None,
183184
)));
184185
state.borrow::<Instance>()
185186
};

player/src/bin/play.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ fn main() {
7070
.unwrap();
7171

7272
let instance_desc = wgt::InstanceDescriptor::from_env_or_default();
73-
let instance = wgc::instance::Instance::new("player", &instance_desc);
73+
let instance = wgc::instance::Instance::new("player", &instance_desc, None);
7474

7575
#[cfg(feature = "winit")]
7676
let surface = unsafe {

player/tests/player/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ impl Corpus {
182182
println!("\t\tTest '{test_path:?}'");
183183

184184
let instance_desc = wgt::InstanceDescriptor::from_env_or_default();
185-
let instance = wgc::instance::Instance::new("test", &instance_desc);
185+
let instance = wgc::instance::Instance::new("test", &instance_desc, None);
186186
let adapter = match instance.request_adapter(
187187
&wgt::RequestAdapterOptions {
188188
power_preference: wgt::PowerPreference::None,

wgpu-core/src/global.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,14 @@ pub struct Global {
3131
}
3232

3333
impl Global {
34-
pub fn new(name: &str, instance_desc: &wgt::InstanceDescriptor) -> Self {
34+
pub fn new(
35+
name: &str,
36+
instance_desc: &wgt::InstanceDescriptor,
37+
telemetry: Option<hal::Telemetry>,
38+
) -> Self {
3539
profiling::scope!("Global::new");
3640
Self {
37-
instance: Instance::new(name, instance_desc),
41+
instance: Instance::new(name, instance_desc, telemetry),
3842
surfaces: Registry::new(),
3943
hub: Hub::new(),
4044
}

wgpu-core/src/instance.rs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,11 @@ pub struct Instance {
9292
}
9393

9494
impl Instance {
95-
pub fn new(name: &str, instance_desc: &wgt::InstanceDescriptor) -> Self {
95+
pub fn new(
96+
name: &str,
97+
instance_desc: &wgt::InstanceDescriptor,
98+
telemetry: Option<hal::Telemetry>,
99+
) -> Self {
96100
let mut this = Self {
97101
name: name.to_owned(),
98102
instance_per_backend: Vec::new(),
@@ -102,21 +106,26 @@ impl Instance {
102106
};
103107

104108
#[cfg(vulkan)]
105-
this.try_add_hal(hal::api::Vulkan, instance_desc);
109+
this.try_add_hal(hal::api::Vulkan, instance_desc, telemetry);
106110
#[cfg(metal)]
107-
this.try_add_hal(hal::api::Metal, instance_desc);
111+
this.try_add_hal(hal::api::Metal, instance_desc, telemetry);
108112
#[cfg(dx12)]
109-
this.try_add_hal(hal::api::Dx12, instance_desc);
113+
this.try_add_hal(hal::api::Dx12, instance_desc, telemetry);
110114
#[cfg(gles)]
111-
this.try_add_hal(hal::api::Gles, instance_desc);
115+
this.try_add_hal(hal::api::Gles, instance_desc, telemetry);
112116
#[cfg(feature = "noop")]
113-
this.try_add_hal(hal::api::Noop, instance_desc);
117+
this.try_add_hal(hal::api::Noop, instance_desc, telemetry);
114118

115119
this
116120
}
117121

118122
/// Helper for `Instance::new()`; attempts to add a single `wgpu-hal` backend to this instance.
119-
fn try_add_hal<A: hal::Api>(&mut self, _: A, instance_desc: &wgt::InstanceDescriptor) {
123+
fn try_add_hal<A: hal::Api>(
124+
&mut self,
125+
_: A,
126+
instance_desc: &wgt::InstanceDescriptor,
127+
telemetry: Option<hal::Telemetry>,
128+
) {
120129
// Whether or not the backend was requested, and whether or not it succeeds,
121130
// note that we *could* try it.
122131
self.supported_backends |= A::VARIANT.into();
@@ -131,6 +140,7 @@ impl Instance {
131140
flags: self.flags,
132141
memory_budget_thresholds: instance_desc.memory_budget_thresholds,
133142
backend_options: instance_desc.backend_options.clone(),
143+
telemetry,
134144
};
135145

136146
use hal::Instance as _;

wgpu-hal/examples/halmark/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ impl<A: hal::Api> Example<A> {
9999
memory_budget_thresholds: wgpu_types::MemoryBudgetThresholds::default(),
100100
// Can't rely on having DXC available, so use FXC instead
101101
backend_options: wgpu_types::BackendOptions::default(),
102+
telemetry: None,
102103
};
103104
let instance = unsafe { A::Instance::init(&instance_desc)? };
104105
let surface = {

wgpu-hal/examples/ray-traced-triangle/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ impl<A: hal::Api> Example<A> {
246246
},
247247
..Default::default()
248248
},
249+
telemetry: None,
249250
};
250251
let instance = unsafe { A::Instance::init(&instance_desc)? };
251252
let surface = {

wgpu-hal/src/dx12/adapter.rs

Lines changed: 125 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ impl super::Adapter {
5858
&self.raw
5959
}
6060

61+
#[allow(clippy::too_many_arguments)]
6162
pub(super) fn expose(
6263
adapter: DxgiAdapter,
6364
library: &Arc<D3D12Lib>,
@@ -66,19 +67,62 @@ impl super::Adapter {
6667
memory_budget_thresholds: wgt::MemoryBudgetThresholds,
6768
compiler_container: Arc<shader_compilation::CompilerContainer>,
6869
backend_options: wgt::Dx12BackendOptions,
70+
telemetry: Option<crate::Telemetry>,
6971
) -> Option<crate::ExposedAdapter<super::Api>> {
72+
let desc = unsafe { adapter.GetDesc2() }.unwrap();
73+
let driver_version =
74+
unsafe { adapter.CheckInterfaceSupport(&Dxgi::IDXGIDevice::IID) }.unwrap() as u64;
75+
let driver_version = [
76+
(driver_version >> 48) as u16,
77+
(driver_version >> 32) as u16,
78+
(driver_version >> 16) as u16,
79+
driver_version as u16,
80+
];
81+
82+
let get_telemetry_key = || {
83+
// The key must be under 111 bytes:
84+
// - backend identifier 'D' = 1 byte
85+
// - 4 * u32's formatted as hex = 4 * 8 = 32 bytes
86+
// - 4 * u16's formatted as dec = 4 * 5 = 20 bytes
87+
// - separators = 8 bytes
88+
// total = 61 bytes
89+
format!(
90+
"D:{:X}:{:X}:{:X}:{:X}:{}.{}.{}.{}",
91+
desc.VendorId,
92+
desc.DeviceId,
93+
desc.SubSysId,
94+
desc.Revision,
95+
driver_version[0],
96+
driver_version[1],
97+
driver_version[2],
98+
driver_version[3],
99+
)
100+
};
101+
70102
// Create the device so that we can get the capabilities.
71-
let device = {
103+
let res = {
72104
profiling::scope!("ID3D12Device::create_device");
73-
library
74-
.create_device(&adapter, Direct3D::D3D_FEATURE_LEVEL_11_0)
75-
.ok()??
105+
library.create_device(&adapter, Direct3D::D3D_FEATURE_LEVEL_11_0)
76106
};
107+
if let Some(telemetry) = telemetry {
108+
if let Err(ref err) = res {
109+
let category = match err {
110+
crate::dx12::CreateDeviceError::GetProcAddress => "NONE:GetProcAddress",
111+
crate::dx12::CreateDeviceError::D3D12CreateDevice(hresult) => {
112+
&format!("NONE:D3D12CreateDevice:{:X}", hresult.0)
113+
}
114+
crate::dx12::CreateDeviceError::RetDeviceIsNull => "NONE:RetDeviceIsNull",
115+
};
116+
(telemetry.expose_adapter)(&get_telemetry_key(), category);
117+
}
118+
}
119+
let device = res.ok()?;
77120

78121
profiling::scope!("feature queries");
79122

80123
// Detect the highest supported feature level.
81124
let d3d_feature_level = [
125+
Direct3D::D3D_FEATURE_LEVEL_12_2,
82126
Direct3D::D3D_FEATURE_LEVEL_12_1,
83127
Direct3D::D3D_FEATURE_LEVEL_12_0,
84128
Direct3D::D3D_FEATURE_LEVEL_11_1,
@@ -99,10 +143,6 @@ impl super::Adapter {
99143
.unwrap();
100144
let max_feature_level = device_levels.MaxSupportedFeatureLevel;
101145

102-
// We have found a possible adapter.
103-
// Acquire the device information.
104-
let desc = unsafe { adapter.GetDesc2() }.unwrap();
105-
106146
let device_name = auxil::dxgi::conv::map_adapter_name(desc.Description);
107147

108148
let mut features_architecture = Direct3D12::D3D12_FEATURE_DATA_ARCHITECTURE::default();
@@ -116,14 +156,6 @@ impl super::Adapter {
116156
}
117157
.unwrap();
118158

119-
let driver_version = unsafe { adapter.CheckInterfaceSupport(&Dxgi::IDXGIDevice::IID) }
120-
.ok()
121-
.map(|i| {
122-
const MASK: i64 = 0xFFFF;
123-
(i >> 48, (i >> 32) & MASK, (i >> 16) & MASK, i & MASK)
124-
})
125-
.unwrap_or((0, 0, 0, 0));
126-
127159
let mut workarounds = super::Workarounds::default();
128160

129161
let is_warp = device_name.contains("Microsoft Basic Render Driver");
@@ -132,7 +164,7 @@ impl super::Adapter {
132164
// use a version that starts with 10.x.x.x. Versions that ship from Nuget use 1.0.x.x.
133165
//
134166
// As far as we know, this is only an issue on the Nuget versions.
135-
if is_warp && driver_version >= (1, 0, 13, 0) && driver_version.0 < 10 {
167+
if is_warp && driver_version >= [1, 0, 13, 0] && driver_version[0] < 10 {
136168
workarounds.avoid_shader_debug_info = true;
137169
}
138170

@@ -153,7 +185,7 @@ impl super::Adapter {
153185
device_pci_bus_id: get_adapter_pci_info(desc.VendorId, desc.DeviceId),
154186
driver: format!(
155187
"{}.{}.{}.{}",
156-
driver_version.0, driver_version.1, driver_version.2, driver_version.3
188+
driver_version[0], driver_version[1], driver_version[2], driver_version[3]
157189
),
158190
driver_info: String::new(),
159191
transient_saves_memory: false,
@@ -170,6 +202,10 @@ impl super::Adapter {
170202
.unwrap();
171203

172204
if options.ResourceBindingTier.0 < Direct3D12::D3D12_RESOURCE_BINDING_TIER_2.0 {
205+
if let Some(telemetry) = telemetry {
206+
let category = "NONE:REQ_RBT2";
207+
(telemetry.expose_adapter)(&get_telemetry_key(), category);
208+
}
173209
// We require Tier 2 or higher for the ability to make samplers bindless in all cases.
174210
return None;
175211
}
@@ -263,6 +299,40 @@ impl super::Adapter {
263299
}
264300
};
265301

302+
let mut all_shader_models = [
303+
Direct3D12::D3D_SHADER_MODEL_6_9,
304+
Direct3D12::D3D_SHADER_MODEL_6_8,
305+
Direct3D12::D3D_SHADER_MODEL_6_7,
306+
Direct3D12::D3D_SHADER_MODEL_6_6,
307+
Direct3D12::D3D_SHADER_MODEL_6_5,
308+
Direct3D12::D3D_SHADER_MODEL_6_4,
309+
Direct3D12::D3D_SHADER_MODEL_6_3,
310+
Direct3D12::D3D_SHADER_MODEL_6_2,
311+
Direct3D12::D3D_SHADER_MODEL_6_1,
312+
Direct3D12::D3D_SHADER_MODEL_6_0,
313+
]
314+
.iter();
315+
let highest_shader_model = loop {
316+
if let Some(&sm) = all_shader_models.next() {
317+
let mut sm = Direct3D12::D3D12_FEATURE_DATA_SHADER_MODEL {
318+
HighestShaderModel: sm,
319+
};
320+
if unsafe {
321+
device.CheckFeatureSupport(
322+
Direct3D12::D3D12_FEATURE_SHADER_MODEL,
323+
<*mut _>::cast(&mut sm),
324+
size_of_val(&sm) as u32,
325+
)
326+
}
327+
.is_ok()
328+
{
329+
break sm.HighestShaderModel;
330+
}
331+
} else {
332+
break Direct3D12::D3D_SHADER_MODEL_5_1;
333+
}
334+
};
335+
266336
let shader_model = if let Some(max_shader_model) = compiler_container.max_shader_model() {
267337
let max_shader_model = match max_shader_model {
268338
wgt::DxcShaderModel::V6_0 => Direct3D12::D3D_SHADER_MODEL_6_0,
@@ -275,42 +345,18 @@ impl super::Adapter {
275345
wgt::DxcShaderModel::V6_7 => Direct3D12::D3D_SHADER_MODEL_6_7,
276346
};
277347

278-
let mut versions = [
279-
Direct3D12::D3D_SHADER_MODEL_6_7,
280-
Direct3D12::D3D_SHADER_MODEL_6_6,
281-
Direct3D12::D3D_SHADER_MODEL_6_5,
282-
Direct3D12::D3D_SHADER_MODEL_6_4,
283-
Direct3D12::D3D_SHADER_MODEL_6_3,
284-
Direct3D12::D3D_SHADER_MODEL_6_2,
285-
Direct3D12::D3D_SHADER_MODEL_6_1,
286-
Direct3D12::D3D_SHADER_MODEL_6_0,
287-
]
288-
.iter()
289-
.filter(|shader_model| shader_model.0 <= max_shader_model.0);
290-
291-
let highest_shader_model = loop {
292-
if let Some(&sm) = versions.next() {
293-
let mut sm = Direct3D12::D3D12_FEATURE_DATA_SHADER_MODEL {
294-
HighestShaderModel: sm,
295-
};
296-
if unsafe {
297-
device.CheckFeatureSupport(
298-
Direct3D12::D3D12_FEATURE_SHADER_MODEL,
299-
<*mut _>::cast(&mut sm),
300-
size_of_val(&sm) as u32,
301-
)
302-
}
303-
.is_ok()
304-
{
305-
break sm.HighestShaderModel;
348+
let shader_model =
349+
Direct3D12::D3D_SHADER_MODEL(highest_shader_model.0.min(max_shader_model.0));
350+
351+
match shader_model {
352+
Direct3D12::D3D_SHADER_MODEL_5_1 => {
353+
if let Some(telemetry) = telemetry {
354+
let category = "NONE:REQ_SM6";
355+
(telemetry.expose_adapter)(&get_telemetry_key(), category);
306356
}
307-
} else {
308-
break Direct3D12::D3D_SHADER_MODEL_5_1;
357+
// don't expose this adapter if it doesn't support DXIL
358+
return None;
309359
}
310-
};
311-
312-
match highest_shader_model {
313-
Direct3D12::D3D_SHADER_MODEL_5_1 => return None, // don't expose this adapter if it doesn't support DXIL
314360
Direct3D12::D3D_SHADER_MODEL_6_0 => naga::back::hlsl::ShaderModel::V6_0,
315361
Direct3D12::D3D_SHADER_MODEL_6_1 => naga::back::hlsl::ShaderModel::V6_1,
316362
Direct3D12::D3D_SHADER_MODEL_6_2 => naga::back::hlsl::ShaderModel::V6_2,
@@ -646,6 +692,33 @@ impl super::Adapter {
646692
// See https://microsoft.github.io/DirectX-Specs/d3d/ViewInstancing.html#maximum-viewinstancecount
647693
let max_multiview_view_count = if view_instancing { 4 } else { 0 };
648694

695+
if let Some(telemetry) = telemetry {
696+
let fl = match max_feature_level {
697+
Direct3D::D3D_FEATURE_LEVEL_12_2 => "12_2",
698+
Direct3D::D3D_FEATURE_LEVEL_12_1 => "12_1",
699+
Direct3D::D3D_FEATURE_LEVEL_12_0 => "12_0",
700+
Direct3D::D3D_FEATURE_LEVEL_11_1 => "11_1",
701+
Direct3D::D3D_FEATURE_LEVEL_11_0 => "11_0",
702+
_ => unreachable!(),
703+
};
704+
let sm = match highest_shader_model {
705+
Direct3D12::D3D_SHADER_MODEL_6_9 => "6.9",
706+
Direct3D12::D3D_SHADER_MODEL_6_8 => "6.8",
707+
Direct3D12::D3D_SHADER_MODEL_6_7 => "6.7",
708+
Direct3D12::D3D_SHADER_MODEL_6_6 => "6.6",
709+
Direct3D12::D3D_SHADER_MODEL_6_5 => "6.5",
710+
Direct3D12::D3D_SHADER_MODEL_6_4 => "6.4",
711+
Direct3D12::D3D_SHADER_MODEL_6_3 => "6.3",
712+
Direct3D12::D3D_SHADER_MODEL_6_2 => "6.2",
713+
Direct3D12::D3D_SHADER_MODEL_6_1 => "6.1",
714+
Direct3D12::D3D_SHADER_MODEL_6_0 => "6.0",
715+
Direct3D12::D3D_SHADER_MODEL_5_1 => "5.1",
716+
_ => unreachable!(),
717+
};
718+
let category = &format!("SOME:FL{fl}:SM{sm}");
719+
(telemetry.expose_adapter)(&get_telemetry_key(), category);
720+
}
721+
649722
Some(crate::ExposedAdapter {
650723
adapter: super::Adapter {
651724
raw: adapter,

wgpu-hal/src/dx12/instance.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ impl crate::Instance for super::Instance {
112112
memory_budget_thresholds: desc.memory_budget_thresholds,
113113
compiler_container: Arc::new(compiler_container),
114114
options: desc.backend_options.dx12.clone(),
115+
telemetry: desc.telemetry,
115116
})
116117
}
117118

@@ -164,6 +165,7 @@ impl crate::Instance for super::Instance {
164165
self.memory_budget_thresholds,
165166
self.compiler_container.clone(),
166167
self.options.clone(),
168+
self.telemetry,
167169
)
168170
})
169171
.collect()

0 commit comments

Comments
 (0)