@@ -686,6 +686,7 @@ impl super::Device {
686686 super :: Texture {
687687 raw : vk_image,
688688 drop_guard,
689+ external_memory : None ,
689690 block : None ,
690691 usage : desc. usage ,
691692 format : desc. format ,
@@ -695,6 +696,127 @@ impl super::Device {
695696 }
696697 }
697698
699+ #[ cfg( windows) ]
700+ unsafe fn find_memory_type_index (
701+ & self ,
702+ type_bits : u32 ,
703+ flags : vk:: MemoryPropertyFlags ,
704+ ) -> Option < usize > {
705+ let mem_properties = self
706+ . shared
707+ . instance
708+ . raw
709+ . get_physical_device_memory_properties ( self . shared . physical_device ) ;
710+
711+ for ( i, mem_ty) in mem_properties
712+ . memory_types_as_slice ( )
713+ . into_iter ( )
714+ . enumerate ( )
715+ {
716+ if type_bits & ( 1 << i) != 0 && mem_ty. property_flags & flags == flags {
717+ return Some ( i) ;
718+ }
719+ }
720+
721+ None
722+ }
723+
724+ /// # Safety
725+ ///
726+ #[ cfg( windows) ]
727+ pub unsafe fn texture_from_d3d11_shared_handle (
728+ & self ,
729+ d3d11_shared_handle : vk:: HANDLE ,
730+ desc : & crate :: TextureDescriptor ,
731+ ) -> ash:: prelude:: VkResult < super :: Texture > {
732+ let copy_size = desc. copy_extent ( ) ;
733+
734+ let mut raw_flags = vk:: ImageCreateFlags :: empty ( ) ;
735+ if desc. is_cube_compatible ( ) {
736+ raw_flags |= vk:: ImageCreateFlags :: CUBE_COMPATIBLE ;
737+ }
738+
739+ let original_format = self . shared . private_caps . map_texture_format ( desc. format ) ;
740+ let mut vk_view_formats = vec ! [ ] ;
741+ let mut wgt_view_formats = vec ! [ ] ;
742+ if !desc. view_formats . is_empty ( ) {
743+ raw_flags |= vk:: ImageCreateFlags :: MUTABLE_FORMAT ;
744+ wgt_view_formats. clone_from ( & desc. view_formats ) ;
745+ wgt_view_formats. push ( desc. format ) ;
746+
747+ if self . shared . private_caps . image_format_list {
748+ vk_view_formats = desc
749+ . view_formats
750+ . iter ( )
751+ . map ( |f| self . shared . private_caps . map_texture_format ( * f) )
752+ . collect ( ) ;
753+ vk_view_formats. push ( original_format)
754+ }
755+ }
756+ if desc. format . is_multi_planar_format ( ) {
757+ raw_flags |= vk:: ImageCreateFlags :: MUTABLE_FORMAT ;
758+ }
759+
760+ let mut vk_info = vk:: ImageCreateInfo :: default ( )
761+ . flags ( raw_flags)
762+ . image_type ( conv:: map_texture_dimension ( desc. dimension ) )
763+ . format ( original_format)
764+ . extent ( conv:: map_copy_extent ( & copy_size) )
765+ . mip_levels ( desc. mip_level_count )
766+ . array_layers ( desc. array_layer_count ( ) )
767+ . samples ( vk:: SampleCountFlags :: from_raw ( desc. sample_count ) )
768+ . tiling ( vk:: ImageTiling :: OPTIMAL )
769+ . usage ( conv:: map_texture_usage ( desc. usage ) )
770+ . sharing_mode ( vk:: SharingMode :: EXCLUSIVE )
771+ . initial_layout ( vk:: ImageLayout :: UNDEFINED ) ;
772+
773+ let mut format_list_info = vk:: ImageFormatListCreateInfo :: default ( ) ;
774+ if !vk_view_formats. is_empty ( ) {
775+ format_list_info = format_list_info. view_formats ( & vk_view_formats) ;
776+ vk_info = vk_info. push_next ( & mut format_list_info) ;
777+ }
778+
779+ let mut external_memory_image_info = vk:: ExternalMemoryImageCreateInfo :: default ( )
780+ . handle_types ( vk:: ExternalMemoryHandleTypeFlags :: D3D11_TEXTURE_KMT ) ;
781+ vk_info = vk_info. push_next ( & mut external_memory_image_info) ;
782+
783+ let raw = unsafe { self . shared . raw . create_image ( & vk_info, None ) ? } ;
784+ let req = unsafe { self . shared . raw . get_image_memory_requirements ( raw) } ;
785+
786+ let mut import_memory_info = vk:: ImportMemoryWin32HandleInfoKHR :: default ( )
787+ . handle_type ( vk:: ExternalMemoryHandleTypeFlags :: D3D11_TEXTURE_KMT )
788+ . handle ( d3d11_shared_handle) ;
789+
790+ let Some ( mem_type_index) = self
791+ . find_memory_type_index ( req. memory_type_bits , vk:: MemoryPropertyFlags :: DEVICE_LOCAL )
792+ else {
793+ return Err ( vk:: Result :: ERROR_UNKNOWN ) ;
794+ } ;
795+
796+ let memory_allocate_info = vk:: MemoryAllocateInfo :: default ( )
797+ . allocation_size ( req. size )
798+ . memory_type_index ( mem_type_index as _ )
799+ . push_next ( & mut import_memory_info) ;
800+ let memory = unsafe {
801+ self . shared
802+ . raw
803+ . allocate_memory ( & memory_allocate_info, None ) ?
804+ } ;
805+ unsafe { self . shared . raw . bind_image_memory ( raw, memory, 0 ) ? } ;
806+
807+ Ok ( super :: Texture {
808+ raw,
809+ drop_guard : None ,
810+ external_memory : Some ( memory) ,
811+ block : None ,
812+ usage : desc. usage ,
813+ format : desc. format ,
814+ raw_flags,
815+ copy_size,
816+ view_formats : wgt_view_formats,
817+ } )
818+ }
819+
698820 /// # Safety
699821 ///
700822 /// - `vk_buffer`'s memory must be managed by the caller
@@ -1117,6 +1239,7 @@ impl crate::Device for super::Device {
11171239 Ok ( super :: Texture {
11181240 raw,
11191241 drop_guard : None ,
1242+ external_memory : None ,
11201243 block : Some ( block) ,
11211244 usage : desc. usage ,
11221245 format : desc. format ,
@@ -1129,6 +1252,9 @@ impl crate::Device for super::Device {
11291252 if texture. drop_guard . is_none ( ) {
11301253 unsafe { self . shared . raw . destroy_image ( texture. raw , None ) } ;
11311254 }
1255+ if let Some ( memory) = texture. external_memory {
1256+ self . shared . raw . free_memory ( memory, None ) ;
1257+ }
11321258 if let Some ( block) = texture. block {
11331259 self . counters . texture_memory . sub ( block. size ( ) as isize ) ;
11341260
0 commit comments