Skip to content

Commit

Permalink
vulkan: texture_from_d3d11_shared_handle
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaopengli89 committed Aug 22, 2024
1 parent cc11260 commit 97ed540
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 0 deletions.
126 changes: 126 additions & 0 deletions wgpu-hal/src/vulkan/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,7 @@ impl super::Device {
super::Texture {
raw: vk_image,
drop_guard,
external_memory: None,
block: None,
usage: desc.usage,
format: desc.format,
Expand All @@ -685,6 +686,127 @@ impl super::Device {
}
}

#[cfg(windows)]
unsafe fn find_memory_type_index(
&self,
type_bits: u32,
flags: vk::MemoryPropertyFlags,
) -> Option<usize> {
let mem_properties = self
.shared
.instance
.raw
.get_physical_device_memory_properties(self.shared.physical_device);

for (i, mem_ty) in mem_properties
.memory_types_as_slice()
.into_iter()
.enumerate()
{
if type_bits & (1 << i) != 0 && mem_ty.property_flags & flags == flags {
return Some(i);
}
}

None
}

/// # Safety
///
#[cfg(windows)]
pub unsafe fn texture_from_d3d11_shared_handle(
&self,
d3d11_shared_handle: vk::HANDLE,
desc: &crate::TextureDescriptor,
) -> ash::prelude::VkResult<super::Texture> {
let copy_size = desc.copy_extent();

let mut raw_flags = vk::ImageCreateFlags::empty();
if desc.is_cube_compatible() {
raw_flags |= vk::ImageCreateFlags::CUBE_COMPATIBLE;
}

let original_format = self.shared.private_caps.map_texture_format(desc.format);
let mut vk_view_formats = vec![];
let mut wgt_view_formats = vec![];
if !desc.view_formats.is_empty() {
raw_flags |= vk::ImageCreateFlags::MUTABLE_FORMAT;
wgt_view_formats.clone_from(&desc.view_formats);
wgt_view_formats.push(desc.format);

if self.shared.private_caps.image_format_list {
vk_view_formats = desc
.view_formats
.iter()
.map(|f| self.shared.private_caps.map_texture_format(*f))
.collect();
vk_view_formats.push(original_format)
}
}
if desc.format.is_multi_planar_format() {
raw_flags |= vk::ImageCreateFlags::MUTABLE_FORMAT;
}

let mut vk_info = vk::ImageCreateInfo::default()
.flags(raw_flags)
.image_type(conv::map_texture_dimension(desc.dimension))
.format(original_format)
.extent(conv::map_copy_extent(&copy_size))
.mip_levels(desc.mip_level_count)
.array_layers(desc.array_layer_count())
.samples(vk::SampleCountFlags::from_raw(desc.sample_count))
.tiling(vk::ImageTiling::OPTIMAL)
.usage(conv::map_texture_usage(desc.usage))
.sharing_mode(vk::SharingMode::EXCLUSIVE)
.initial_layout(vk::ImageLayout::UNDEFINED);

let mut format_list_info = vk::ImageFormatListCreateInfo::default();
if !vk_view_formats.is_empty() {
format_list_info = format_list_info.view_formats(&vk_view_formats);
vk_info = vk_info.push_next(&mut format_list_info);
}

let mut external_memory_image_info = vk::ExternalMemoryImageCreateInfo::default()
.handle_types(vk::ExternalMemoryHandleTypeFlags::D3D11_TEXTURE_KMT);
vk_info = vk_info.push_next(&mut external_memory_image_info);

let raw = unsafe { self.shared.raw.create_image(&vk_info, None)? };
let req = unsafe { self.shared.raw.get_image_memory_requirements(raw) };

let mut import_memory_info = vk::ImportMemoryWin32HandleInfoKHR::default()
.handle_type(vk::ExternalMemoryHandleTypeFlags::D3D11_TEXTURE_KMT)
.handle(d3d11_shared_handle);

let Some(mem_type_index) = self
.find_memory_type_index(req.memory_type_bits, vk::MemoryPropertyFlags::DEVICE_LOCAL)
else {
return Err(vk::Result::ERROR_UNKNOWN);
};

let memory_allocate_info = vk::MemoryAllocateInfo::default()
.allocation_size(req.size)
.memory_type_index(mem_type_index as _)
.push_next(&mut import_memory_info);
let memory = unsafe {
self.shared
.raw
.allocate_memory(&memory_allocate_info, None)?
};
unsafe { self.shared.raw.bind_image_memory(raw, memory, 0)? };

Ok(super::Texture {
raw,
drop_guard: None,
external_memory: Some(memory),
block: None,
usage: desc.usage,
format: desc.format,
raw_flags,
copy_size,
view_formats: wgt_view_formats,
})
}

/// # Safety
///
/// - `vk_buffer`'s memory must be managed by the caller
Expand Down Expand Up @@ -1103,6 +1225,7 @@ impl crate::Device for super::Device {
Ok(super::Texture {
raw,
drop_guard: None,
external_memory: None,
block: Some(block),
usage: desc.usage,
format: desc.format,
Expand All @@ -1115,6 +1238,9 @@ impl crate::Device for super::Device {
if texture.drop_guard.is_none() {
unsafe { self.shared.raw.destroy_image(texture.raw, None) };
}
if let Some(memory) = texture.external_memory {
self.shared.raw.free_memory(memory, None);
}
if let Some(block) = texture.block {
self.counters.texture_memory.sub(block.size() as isize);

Expand Down
1 change: 1 addition & 0 deletions wgpu-hal/src/vulkan/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,7 @@ impl crate::DynAccelerationStructure for AccelerationStructure {}
pub struct Texture {
raw: vk::Image,
drop_guard: Option<crate::DropGuard>,
external_memory: Option<vk::DeviceMemory>,
block: Option<gpu_alloc::MemoryBlock<vk::DeviceMemory>>,
usage: crate::TextureUses,
format: wgt::TextureFormat,
Expand Down

0 comments on commit 97ed540

Please sign in to comment.