@@ -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,
0 commit comments