@@ -807,7 +807,8 @@ impl crate::Device for super::Device {
807807 | wgt:: BindingType :: StorageTexture { .. }
808808 | wgt:: BindingType :: AccelerationStructure { .. } => num_views += count,
809809 wgt:: BindingType :: Sampler { .. } => has_sampler_in_group = true ,
810- wgt:: BindingType :: ExternalTexture => unimplemented ! ( ) ,
810+ // Three texture planes and one params buffer
811+ wgt:: BindingType :: ExternalTexture => num_views += 4 * count,
811812 }
812813 }
813814
@@ -880,6 +881,7 @@ impl crate::Device for super::Device {
880881
881882 let mut binding_map = hlsl:: BindingMap :: default ( ) ;
882883 let mut sampler_buffer_binding_map = hlsl:: SamplerIndexBufferBindingMap :: default ( ) ;
884+ let mut external_texture_binding_map = hlsl:: ExternalTextureBindingMap :: default ( ) ;
883885 let mut bind_cbv = hlsl:: BindTarget :: default ( ) ;
884886 let mut bind_srv = hlsl:: BindTarget :: default ( ) ;
885887 let mut bind_uav = hlsl:: BindTarget :: default ( ) ;
@@ -939,6 +941,8 @@ impl crate::Device for super::Device {
939941 ..
940942 } => { }
941943 wgt:: BindingType :: Sampler ( _) => sampler_in_bind_group = true ,
944+ // Three texture planes and one params buffer
945+ wgt:: BindingType :: ExternalTexture => total_non_dynamic_entries += 4 ,
942946 _ => total_non_dynamic_entries += 1 ,
943947 }
944948 }
@@ -993,61 +997,110 @@ impl crate::Device for super::Device {
993997 // SRV/CBV/UAV descriptor tables
994998 let range_base = ranges. len ( ) ;
995999 for entry in bgl. entries . iter ( ) {
996- let ( range_ty, has_dynamic_offset) = match entry. ty {
997- wgt:: BindingType :: Buffer {
998- ty,
999- has_dynamic_offset : true ,
1000- ..
1001- } => match ty {
1002- wgt:: BufferBindingType :: Uniform => continue ,
1003- wgt:: BufferBindingType :: Storage { .. } => {
1004- ( conv:: map_binding_type ( & entry. ty ) , true )
1005- }
1006- } ,
1007- ref other => ( conv:: map_binding_type ( other) , false ) ,
1008- } ;
1009- let bt = match range_ty {
1010- Direct3D12 :: D3D12_DESCRIPTOR_RANGE_TYPE_CBV => & mut bind_cbv,
1011- Direct3D12 :: D3D12_DESCRIPTOR_RANGE_TYPE_SRV => & mut bind_srv,
1012- Direct3D12 :: D3D12_DESCRIPTOR_RANGE_TYPE_UAV => & mut bind_uav,
1013- Direct3D12 :: D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER => continue ,
1014- _ => todo ! ( ) ,
1015- } ;
1016-
1017- let binding_array_size = entry. count . map ( NonZeroU32 :: get) ;
1018-
1019- let dynamic_storage_buffer_offsets_index = if has_dynamic_offset {
1020- debug_assert ! (
1021- binding_array_size. is_none( ) ,
1022- "binding arrays and dynamic buffers are mutually exclusive"
1000+ let count = entry. count . map_or ( 1 , NonZeroU32 :: get) ;
1001+ if let wgt:: BindingType :: ExternalTexture = entry. ty {
1002+ // External textures need 3 SRVs (a texture for each plane)
1003+ // and 1 CBV for the parameters buffer.
1004+ let bind_target = hlsl:: ExternalTextureBindTarget {
1005+ planes : core:: array:: from_fn ( |_| hlsl:: BindTarget {
1006+ register : {
1007+ let register = bind_srv. register ;
1008+ bind_srv. register += count;
1009+ register
1010+ } ,
1011+ ..bind_srv
1012+ } ) ,
1013+ params : hlsl:: BindTarget {
1014+ register : {
1015+ let register = bind_cbv. register ;
1016+ bind_cbv. register += count;
1017+ register
1018+ } ,
1019+ ..bind_cbv
1020+ } ,
1021+ } ;
1022+ external_texture_binding_map. insert (
1023+ naga:: ResourceBinding {
1024+ group : index as u32 ,
1025+ binding : entry. binding ,
1026+ } ,
1027+ bind_target,
10231028 ) ;
1024- let ret = Some ( dynamic_storage_buffers) ;
1025- dynamic_storage_buffers += 1 ;
1026- ret
1029+ for bt in bind_target. planes {
1030+ ranges. push ( Direct3D12 :: D3D12_DESCRIPTOR_RANGE {
1031+ RangeType : Direct3D12 :: D3D12_DESCRIPTOR_RANGE_TYPE_SRV ,
1032+ NumDescriptors : count,
1033+ BaseShaderRegister : bt. register ,
1034+ RegisterSpace : bt. space as u32 ,
1035+ OffsetInDescriptorsFromTableStart :
1036+ Direct3D12 :: D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND ,
1037+ } ) ;
1038+ }
1039+ ranges. push ( Direct3D12 :: D3D12_DESCRIPTOR_RANGE {
1040+ RangeType : Direct3D12 :: D3D12_DESCRIPTOR_RANGE_TYPE_CBV ,
1041+ NumDescriptors : count,
1042+ BaseShaderRegister : bind_target. params . register ,
1043+ RegisterSpace : bind_target. params . space as u32 ,
1044+ OffsetInDescriptorsFromTableStart :
1045+ Direct3D12 :: D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND ,
1046+ } ) ;
10271047 } else {
1028- None
1029- } ;
1048+ let ( range_ty, has_dynamic_offset) = match entry. ty {
1049+ wgt:: BindingType :: Buffer {
1050+ ty,
1051+ has_dynamic_offset : true ,
1052+ ..
1053+ } => match ty {
1054+ wgt:: BufferBindingType :: Uniform => continue ,
1055+ wgt:: BufferBindingType :: Storage { .. } => {
1056+ ( conv:: map_binding_type ( & entry. ty ) , true )
1057+ }
1058+ } ,
1059+ ref other => ( conv:: map_binding_type ( other) , false ) ,
1060+ } ;
1061+ let bt = match range_ty {
1062+ Direct3D12 :: D3D12_DESCRIPTOR_RANGE_TYPE_CBV => & mut bind_cbv,
1063+ Direct3D12 :: D3D12_DESCRIPTOR_RANGE_TYPE_SRV => & mut bind_srv,
1064+ Direct3D12 :: D3D12_DESCRIPTOR_RANGE_TYPE_UAV => & mut bind_uav,
1065+ Direct3D12 :: D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER => continue ,
1066+ _ => todo ! ( ) ,
1067+ } ;
10301068
1031- binding_map. insert (
1032- naga:: ResourceBinding {
1033- group : index as u32 ,
1034- binding : entry. binding ,
1035- } ,
1036- hlsl:: BindTarget {
1037- binding_array_size,
1038- dynamic_storage_buffer_offsets_index,
1039- ..* bt
1040- } ,
1041- ) ;
1042- ranges. push ( Direct3D12 :: D3D12_DESCRIPTOR_RANGE {
1043- RangeType : range_ty,
1044- NumDescriptors : entry. count . map_or ( 1 , |count| count. get ( ) ) ,
1045- BaseShaderRegister : bt. register ,
1046- RegisterSpace : bt. space as u32 ,
1047- OffsetInDescriptorsFromTableStart :
1048- Direct3D12 :: D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND ,
1049- } ) ;
1050- bt. register += entry. count . map ( NonZeroU32 :: get) . unwrap_or ( 1 ) ;
1069+ let binding_array_size = entry. count . map ( NonZeroU32 :: get) ;
1070+
1071+ let dynamic_storage_buffer_offsets_index = if has_dynamic_offset {
1072+ debug_assert ! (
1073+ binding_array_size. is_none( ) ,
1074+ "binding arrays and dynamic buffers are mutually exclusive"
1075+ ) ;
1076+ let ret = Some ( dynamic_storage_buffers) ;
1077+ dynamic_storage_buffers += 1 ;
1078+ ret
1079+ } else {
1080+ None
1081+ } ;
1082+
1083+ binding_map. insert (
1084+ naga:: ResourceBinding {
1085+ group : index as u32 ,
1086+ binding : entry. binding ,
1087+ } ,
1088+ hlsl:: BindTarget {
1089+ binding_array_size,
1090+ dynamic_storage_buffer_offsets_index,
1091+ ..* bt
1092+ } ,
1093+ ) ;
1094+ ranges. push ( Direct3D12 :: D3D12_DESCRIPTOR_RANGE {
1095+ RangeType : range_ty,
1096+ NumDescriptors : count,
1097+ BaseShaderRegister : bt. register ,
1098+ RegisterSpace : bt. space as u32 ,
1099+ OffsetInDescriptorsFromTableStart :
1100+ Direct3D12 :: D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND ,
1101+ } ) ;
1102+ bt. register += count;
1103+ }
10511104 }
10521105
10531106 let mut sampler_index_within_bind_group = 0 ;
@@ -1388,7 +1441,7 @@ impl crate::Device for super::Device {
13881441 restrict_indexing : true ,
13891442 sampler_heap_target,
13901443 sampler_buffer_binding_map,
1391- external_texture_binding_map : hlsl :: ExternalTextureBindingMap :: default ( ) ,
1444+ external_texture_binding_map,
13921445 force_loop_bounding : true ,
13931446 } ,
13941447 } )
@@ -1574,7 +1627,31 @@ impl crate::Device for super::Device {
15741627 inner. stage . push ( handle) ;
15751628 }
15761629 }
1577- wgt:: BindingType :: ExternalTexture => unimplemented ! ( ) ,
1630+ wgt:: BindingType :: ExternalTexture => {
1631+ // We don't yet support binding arrays of external textures.
1632+ // https://github.com/gfx-rs/wgpu/issues/8027
1633+ assert_eq ! ( entry. count, 1 ) ;
1634+ let external_texture = & desc. external_textures [ entry. resource_index as usize ] ;
1635+ for plane in & external_texture. planes {
1636+ let plane_handle = plane. view . handle_srv . unwrap ( ) ;
1637+ cpu_views. as_mut ( ) . unwrap ( ) . stage . push ( plane_handle. raw ) ;
1638+ }
1639+ let gpu_address = external_texture. params . resolve_address ( ) ;
1640+ let size = external_texture. params . resolve_size ( ) as u32 ;
1641+ let inner = cpu_views. as_mut ( ) . unwrap ( ) ;
1642+ let cpu_index = inner. stage . len ( ) as u32 ;
1643+ let params_handle = desc. layout . cpu_heap_views . as_ref ( ) . unwrap ( ) . at ( cpu_index) ;
1644+ let size_mask = Direct3D12 :: D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT - 1 ;
1645+ let raw_desc = Direct3D12 :: D3D12_CONSTANT_BUFFER_VIEW_DESC {
1646+ BufferLocation : gpu_address,
1647+ SizeInBytes : ( ( size - 1 ) | size_mask) + 1 ,
1648+ } ;
1649+ unsafe {
1650+ self . raw
1651+ . CreateConstantBufferView ( Some ( & raw_desc) , params_handle)
1652+ } ;
1653+ inner. stage . push ( params_handle) ;
1654+ }
15781655 }
15791656 }
15801657
0 commit comments