Skip to content

Added reporting of VK_KHR_external_memory_fd vulkan extension as feature #7825

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: trunk
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions wgpu-hal/src/vulkan/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -859,6 +859,10 @@ impl PhysicalDeviceFeatures {
F::VULKAN_EXTERNAL_MEMORY_WIN32,
caps.supports_extension(khr::external_memory_win32::NAME),
);
features.set(
F::VULKAN_EXTERNAL_MEMORY_FD,
caps.supports_extension(khr::external_memory_fd::NAME),
);
features.set(
F::EXPERIMENTAL_MESH_SHADER,
caps.supports_extension(ext::mesh_shader::NAME),
Expand Down
43 changes: 24 additions & 19 deletions wgpu-hal/src/vulkan/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -808,17 +808,6 @@ impl super::Device {
})
}

/// # Safety
///
/// - `vk_buffer`'s memory must be managed by the caller
/// - Externally imported buffers can't be mapped by `wgpu`
pub unsafe fn buffer_from_raw(vk_buffer: vk::Buffer) -> super::Buffer {
super::Buffer {
raw: vk_buffer,
block: None,
}
}

fn create_shader_module_impl(
&self,
spv: &[u32],
Expand Down Expand Up @@ -1153,15 +1142,22 @@ impl crate::Device for super::Device {

Ok(super::Buffer {
raw,
block: Some(Mutex::new(block)),
block: Some(Mutex::new(super::BufferMemoryBacking::Managed(block))),
})
}
unsafe fn destroy_buffer(&self, buffer: super::Buffer) {
unsafe { self.shared.raw.destroy_buffer(buffer.raw, None) };
if let Some(block) = buffer.block {
let block = block.into_inner();
self.counters.buffer_memory.sub(block.size() as isize);
unsafe { self.mem_allocator.lock().dealloc(&*self.shared, block) };
match block {
super::BufferMemoryBacking::Managed(block) => unsafe {
self.mem_allocator.lock().dealloc(&*self.shared, block)
},
super::BufferMemoryBacking::VulkanMemory { memory, .. } => unsafe {
self.shared.raw.free_memory(memory, None);
},
}
}

self.counters.buffers.sub(1);
Expand All @@ -1179,18 +1175,27 @@ impl crate::Device for super::Device {
if let Some(ref block) = buffer.block {
let size = range.end - range.start;
let mut block = block.lock();
let ptr = unsafe { block.map(&*self.shared, range.start, size as usize)? };
let is_coherent = block
.props()
.contains(gpu_alloc::MemoryPropertyFlags::HOST_COHERENT);
Ok(crate::BufferMapping { ptr, is_coherent })
if let super::BufferMemoryBacking::Managed(block) = &mut *block {
let ptr = unsafe { block.map(&*self.shared, range.start, size as usize)? };
let is_coherent = block
.props()
.contains(gpu_alloc::MemoryPropertyFlags::HOST_COHERENT);
Ok(crate::BufferMapping { ptr, is_coherent })
} else {
crate::hal_usage_error("tried to map externally created buffer")
}
} else {
crate::hal_usage_error("tried to map external buffer")
}
}
unsafe fn unmap_buffer(&self, buffer: &super::Buffer) {
if let Some(ref block) = buffer.block {
unsafe { block.lock().unmap(&*self.shared) };
match &mut *block.lock() {
super::BufferMemoryBacking::Managed(block) => unsafe { block.unmap(&*self.shared) },
super::BufferMemoryBacking::VulkanMemory { .. } => {
crate::hal_usage_error("tried to unmap externally created buffer")
}
};
} else {
crate::hal_usage_error("tried to unmap external buffer")
}
Expand Down
63 changes: 61 additions & 2 deletions wgpu-hal/src/vulkan/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -776,11 +776,70 @@ impl Drop for Queue {
unsafe { self.relay_semaphores.lock().destroy(&self.device.raw) };
}
}

#[derive(Debug)]
enum BufferMemoryBacking {
Managed(gpu_alloc::MemoryBlock<vk::DeviceMemory>),
VulkanMemory {
memory: vk::DeviceMemory,
offset: u64,
size: u64,
},
}
impl BufferMemoryBacking {
fn memory(&self) -> &vk::DeviceMemory {
match self {
Self::Managed(m) => m.memory(),
Self::VulkanMemory { memory, .. } => memory,
}
}
fn offset(&self) -> u64 {
match self {
Self::Managed(m) => m.offset(),
Self::VulkanMemory { offset, .. } => *offset,
}
}
fn size(&self) -> u64 {
match self {
Self::Managed(m) => m.size(),
Self::VulkanMemory { size, .. } => *size,
}
}
}
#[derive(Debug)]
pub struct Buffer {
raw: vk::Buffer,
block: Option<Mutex<gpu_alloc::MemoryBlock<vk::DeviceMemory>>>,
block: Option<Mutex<BufferMemoryBacking>>,
}
impl Buffer {
/// # Safety
///
/// - `vk_buffer`'s memory must be managed by the caller
/// - Externally imported buffers can't be mapped by `wgpu`
pub unsafe fn from_raw(vk_buffer: vk::Buffer) -> Self {
Self {
raw: vk_buffer,
block: None,
}
}
/// # Safety
/// - `memory` must not be used further by the caller
/// - Externally imported buffers can't be mapped by `wgpu`
/// - `offset` and `size` must be valid with the allocation of `memory`
pub unsafe fn from_raw_managed(
vk_buffer: vk::Buffer,
memory: vk::DeviceMemory,
offset: u64,
size: u64,
) -> Self {
Self {
raw: vk_buffer,
block: Some(Mutex::new(BufferMemoryBacking::VulkanMemory {
memory,
offset,
size,
})),
}
}
}

impl crate::DynBuffer for Buffer {}
Expand Down
10 changes: 10 additions & 0 deletions wgpu-types/src/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1244,6 +1244,16 @@ bitflags_array! {
///
/// [BlasTriangleGeometrySizeDescriptor::vertex_format]: super::BlasTriangleGeometrySizeDescriptor
const EXTENDED_ACCELERATION_STRUCTURE_VERTEX_FORMATS = 1 << 51;

/// Allows using the [VK_KHR_external_memory_fd] Vulkan extension.
///
/// Supported platforms:
/// - Vulkan (with [VK_KHR_external_memory_fd])
///
/// This is a native only feature.
///
/// [VK_KHR_external_memory_fd]: https://registry.khronos.org/vulkan/specs/latest/man/html/VK_KHR_external_memory_fd.html
const VULKAN_EXTERNAL_MEMORY_FD = 1 << 45;
}

/// Features that are not guaranteed to be supported.
Expand Down
Loading