Skip to content

Commit 18691f5

Browse files
Rework of wgpu_hal vulkan buffer importing (#7824)
Co-authored-by: Connor Fitzgerald <connorwadefitzgerald@gmail.com>
1 parent c0a580d commit 18691f5

File tree

2 files changed

+85
-21
lines changed

2 files changed

+85
-21
lines changed

wgpu-hal/src/vulkan/device.rs

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -808,17 +808,6 @@ impl super::Device {
808808
})
809809
}
810810

811-
/// # Safety
812-
///
813-
/// - `vk_buffer`'s memory must be managed by the caller
814-
/// - Externally imported buffers can't be mapped by `wgpu`
815-
pub unsafe fn buffer_from_raw(vk_buffer: vk::Buffer) -> super::Buffer {
816-
super::Buffer {
817-
raw: vk_buffer,
818-
block: None,
819-
}
820-
}
821-
822811
fn create_shader_module_impl(
823812
&self,
824813
spv: &[u32],
@@ -1153,15 +1142,22 @@ impl crate::Device for super::Device {
11531142

11541143
Ok(super::Buffer {
11551144
raw,
1156-
block: Some(Mutex::new(block)),
1145+
block: Some(Mutex::new(super::BufferMemoryBacking::Managed(block))),
11571146
})
11581147
}
11591148
unsafe fn destroy_buffer(&self, buffer: super::Buffer) {
11601149
unsafe { self.shared.raw.destroy_buffer(buffer.raw, None) };
11611150
if let Some(block) = buffer.block {
11621151
let block = block.into_inner();
11631152
self.counters.buffer_memory.sub(block.size() as isize);
1164-
unsafe { self.mem_allocator.lock().dealloc(&*self.shared, block) };
1153+
match block {
1154+
super::BufferMemoryBacking::Managed(block) => unsafe {
1155+
self.mem_allocator.lock().dealloc(&*self.shared, block)
1156+
},
1157+
super::BufferMemoryBacking::VulkanMemory { memory, .. } => unsafe {
1158+
self.shared.raw.free_memory(memory, None);
1159+
},
1160+
}
11651161
}
11661162

11671163
self.counters.buffers.sub(1);
@@ -1179,18 +1175,27 @@ impl crate::Device for super::Device {
11791175
if let Some(ref block) = buffer.block {
11801176
let size = range.end - range.start;
11811177
let mut block = block.lock();
1182-
let ptr = unsafe { block.map(&*self.shared, range.start, size as usize)? };
1183-
let is_coherent = block
1184-
.props()
1185-
.contains(gpu_alloc::MemoryPropertyFlags::HOST_COHERENT);
1186-
Ok(crate::BufferMapping { ptr, is_coherent })
1178+
if let super::BufferMemoryBacking::Managed(ref mut block) = *block {
1179+
let ptr = unsafe { block.map(&*self.shared, range.start, size as usize)? };
1180+
let is_coherent = block
1181+
.props()
1182+
.contains(gpu_alloc::MemoryPropertyFlags::HOST_COHERENT);
1183+
Ok(crate::BufferMapping { ptr, is_coherent })
1184+
} else {
1185+
crate::hal_usage_error("tried to map externally created buffer")
1186+
}
11871187
} else {
11881188
crate::hal_usage_error("tried to map external buffer")
11891189
}
11901190
}
11911191
unsafe fn unmap_buffer(&self, buffer: &super::Buffer) {
11921192
if let Some(ref block) = buffer.block {
1193-
unsafe { block.lock().unmap(&*self.shared) };
1193+
match &mut *block.lock() {
1194+
super::BufferMemoryBacking::Managed(block) => unsafe { block.unmap(&*self.shared) },
1195+
super::BufferMemoryBacking::VulkanMemory { .. } => {
1196+
crate::hal_usage_error("tried to unmap externally created buffer")
1197+
}
1198+
};
11941199
} else {
11951200
crate::hal_usage_error("tried to unmap external buffer")
11961201
}

wgpu-hal/src/vulkan/mod.rs

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -776,11 +776,70 @@ impl Drop for Queue {
776776
unsafe { self.relay_semaphores.lock().destroy(&self.device.raw) };
777777
}
778778
}
779-
779+
#[derive(Debug)]
780+
enum BufferMemoryBacking {
781+
Managed(gpu_alloc::MemoryBlock<vk::DeviceMemory>),
782+
VulkanMemory {
783+
memory: vk::DeviceMemory,
784+
offset: u64,
785+
size: u64,
786+
},
787+
}
788+
impl BufferMemoryBacking {
789+
fn memory(&self) -> &vk::DeviceMemory {
790+
match self {
791+
Self::Managed(m) => m.memory(),
792+
Self::VulkanMemory { memory, .. } => memory,
793+
}
794+
}
795+
fn offset(&self) -> u64 {
796+
match self {
797+
Self::Managed(m) => m.offset(),
798+
Self::VulkanMemory { offset, .. } => *offset,
799+
}
800+
}
801+
fn size(&self) -> u64 {
802+
match self {
803+
Self::Managed(m) => m.size(),
804+
Self::VulkanMemory { size, .. } => *size,
805+
}
806+
}
807+
}
780808
#[derive(Debug)]
781809
pub struct Buffer {
782810
raw: vk::Buffer,
783-
block: Option<Mutex<gpu_alloc::MemoryBlock<vk::DeviceMemory>>>,
811+
block: Option<Mutex<BufferMemoryBacking>>,
812+
}
813+
impl Buffer {
814+
/// # Safety
815+
///
816+
/// - `vk_buffer`'s memory must be managed by the caller
817+
/// - Externally imported buffers can't be mapped by `wgpu`
818+
pub unsafe fn from_raw(vk_buffer: vk::Buffer) -> Self {
819+
Self {
820+
raw: vk_buffer,
821+
block: None,
822+
}
823+
}
824+
/// # Safety
825+
/// - We will use this buffer and the buffer's backing memory range as if we have exclusive ownership over it, until the wgpu resource is dropped and the wgpu-hal object is cleaned up
826+
/// - Externally imported buffers can't be mapped by `wgpu`
827+
/// - `offset` and `size` must be valid with the allocation of `memory`
828+
pub unsafe fn from_raw_managed(
829+
vk_buffer: vk::Buffer,
830+
memory: vk::DeviceMemory,
831+
offset: u64,
832+
size: u64,
833+
) -> Self {
834+
Self {
835+
raw: vk_buffer,
836+
block: Some(Mutex::new(BufferMemoryBacking::VulkanMemory {
837+
memory,
838+
offset,
839+
size,
840+
})),
841+
}
842+
}
784843
}
785844

786845
impl crate::DynBuffer for Buffer {}

0 commit comments

Comments
 (0)