diff --git a/src/backend/gl/src/device.rs b/src/backend/gl/src/device.rs index c155ddc35bb..b95b5a872f1 100644 --- a/src/backend/gl/src/device.rs +++ b/src/backend/gl/src/device.rs @@ -478,21 +478,19 @@ impl d::Device for Device { //TODO: use *Named calls to avoid binding gl.bind_buffer(target, Some(raw)); if self.share.private_caps.buffer_storage { - let flags = if is_device_local_memory { - 0 - } else { - assert!(is_cpu_visible_memory); - let read_flag = if is_readable_memory { - glow::MAP_READ_BIT - } else { - 0 - }; - read_flag - | glow::MAP_WRITE_BIT + let mut storage_flags = 0; + if is_cpu_visible_memory { + storage_flags |= glow::MAP_WRITE_BIT | glow::MAP_PERSISTENT_BIT - | glow::DYNAMIC_STORAGE_BIT - }; - gl.buffer_storage(target, size as i32, None, flags); + | glow::DYNAMIC_STORAGE_BIT; + if is_readable_memory { + storage_flags |= glow::MAP_READ_BIT; + } + if is_coherent_memory { + storage_flags |= glow::MAP_COHERENT_BIT; + } + } + gl.buffer_storage(target, size as i32, None, storage_flags); } else { let usage = if is_device_local_memory { glow::STATIC_DRAW @@ -513,15 +511,14 @@ impl d::Device for Device { if is_readable_memory { map_flags |= glow::MAP_READ_BIT; } - if !is_coherent_memory { + if is_coherent_memory { map_flags |= glow::MAP_COHERENT_BIT; } Ok(n::Memory { properties: memory_type.properties, - buffer: Some(raw), + buffer: Some((raw, target)), size, - target, map_flags, emulate_map_allocation: Cell::new(None), }) @@ -533,7 +530,6 @@ impl d::Device for Device { properties: memory::Properties::DEVICE_LOCAL, buffer: None, size, - target: 0, map_flags: 0, emulate_map_allocation: Cell::new(None), }) @@ -1051,19 +1047,12 @@ impl d::Device for Device { n::Buffer::Bound { .. } => panic!("Unexpected Buffer::Bound"), }; - let alignment = if usage.contains(buffer::Usage::INDEX) { - // Alignment of 4 covers indexes of type u16 and u32 - 4 - } else { - 1 - }; - - let type_mask = self.share.buffer_memory_type_mask(usage); - memory::Requirements { size: size as u64, - alignment, - type_mask, + // Alignment of 4 covers indexes of type u16 and u32 in index buffers, which is + // currently the only alignment requirement. + alignment: 4, + type_mask: self.share.buffer_memory_type_mask(usage), } } @@ -1079,7 +1068,7 @@ impl d::Device for Device { }; *buffer = n::Buffer::Bound { - buffer: memory.buffer.expect("Improper memory type used for buffer memory"), + buffer: memory.buffer.expect("Improper memory type used for buffer memory").0, range: offset..offset + size, }; @@ -1098,7 +1087,7 @@ impl d::Device for Device { let offset = *range.start().unwrap_or(&0); let size = *range.end().unwrap_or(&memory.size) - offset; - let buffer = memory.buffer.expect("cannot map image memory"); + let (buffer, target) = memory.buffer.expect("cannot map image memory"); let ptr = if caps.emulate_map { let ptr: *mut u8 = if let Some(ptr) = memory.emulate_map_allocation.get() { ptr @@ -1110,9 +1099,9 @@ impl d::Device for Device { ptr.offset(offset as isize) } else { - gl.bind_buffer(memory.target, Some(buffer)); - let raw = gl.map_buffer_range(memory.target, offset as i32, size as i32, memory.map_flags); - gl.bind_buffer(memory.target, None); + gl.bind_buffer(target, Some(buffer)); + let raw = gl.map_buffer_range(target, offset as i32, size as i32, memory.map_flags); + gl.bind_buffer(target, None); raw }; @@ -1125,18 +1114,18 @@ impl d::Device for Device { unsafe fn unmap_memory(&self, memory: &n::Memory) { let gl = &self.share.context; - let buffer = memory.buffer.expect("cannot unmap image memory"); + let (buffer, target) = memory.buffer.expect("cannot unmap image memory"); - gl.bind_buffer(memory.target, Some(buffer)); + gl.bind_buffer(target, Some(buffer)); if self.share.private_caps.emulate_map { let ptr = memory.emulate_map_allocation.replace(None).unwrap(); let _ = Box::from_raw(slice::from_raw_parts_mut(ptr, memory.size as usize)); } else { - gl.unmap_buffer(memory.target); + gl.unmap_buffer(target); } - gl.bind_buffer(memory.target, None); + gl.bind_buffer(target, None); if let Err(err) = self.share.check() { panic!("Error unmapping memory: {:?} for memory {:?}", err, memory); @@ -1153,8 +1142,8 @@ impl d::Device for Device { for i in ranges { let (mem, range) = i.borrow(); - let buffer = mem.buffer.expect("cannot flush image memory"); - gl.bind_buffer(mem.target, Some(buffer)); + let (buffer, target) = mem.buffer.expect("cannot flush image memory"); + gl.bind_buffer(target, Some(buffer)); let offset = *range.start().unwrap_or(&0); let size = *range.end().unwrap_or(&mem.size) - offset; @@ -1162,11 +1151,11 @@ impl d::Device for Device { if self.share.private_caps.emulate_map { let ptr = mem.emulate_map_allocation.get().unwrap(); let slice = slice::from_raw_parts_mut(ptr.offset(offset as isize), size as usize); - gl.buffer_sub_data_u8_slice(mem.target, offset as i32, slice); + gl.buffer_sub_data_u8_slice(target, offset as i32, slice); } else { - gl.flush_mapped_buffer_range(mem.target, offset as i32, size as i32); + gl.flush_mapped_buffer_range(target, offset as i32, size as i32); } - gl.bind_buffer(mem.target, None); + gl.bind_buffer(target, None); if let Err(err) = self.share.check() { panic!("Error flushing memory range: {:?} for memory {:?}", err, mem); } @@ -1188,8 +1177,8 @@ impl d::Device for Device { for i in ranges { let (mem, range) = i.borrow(); - let buffer = mem.buffer.expect("cannot invalidate DEVICE_LOCAL memory"); - gl.bind_buffer(mem.target, Some(buffer)); + let (buffer, target) = mem.buffer.expect("cannot invalidate image memory"); + gl.bind_buffer(target, Some(buffer)); let offset = *range.start().unwrap_or(&0); let size = *range.end().unwrap_or(&mem.size) - offset; @@ -1197,10 +1186,10 @@ impl d::Device for Device { if self.share.private_caps.emulate_map { let ptr = mem.emulate_map_allocation.get().unwrap(); let slice = slice::from_raw_parts_mut(ptr.offset(offset as isize), size as usize); - gl.get_buffer_sub_data(mem.target, offset as i32, slice); + gl.get_buffer_sub_data(target, offset as i32, slice); } else { - gl.invalidate_buffer_sub_data(mem.target, offset as i32, size as i32); - gl.bind_buffer(mem.target, None); + gl.invalidate_buffer_sub_data(target, offset as i32, size as i32); + gl.bind_buffer(target, None); } if let Err(err) = self.share.check() { @@ -1613,7 +1602,7 @@ impl d::Device for Device { } unsafe fn free_memory(&self, memory: n::Memory) { - if let Some(buffer) = memory.buffer { + if let Some((buffer, _)) = memory.buffer { self.share.context.delete_buffer(buffer); } } diff --git a/src/backend/gl/src/lib.rs b/src/backend/gl/src/lib.rs index e629abe9b98..be7b763a110 100644 --- a/src/backend/gl/src/lib.rs +++ b/src/backend/gl/src/lib.rs @@ -363,6 +363,10 @@ impl PhysicalDevice { properties: memory::Properties::CPU_VISIBLE | memory::Properties::CPU_CACHED | memory::Properties::COHERENT, heap_index: CPU_VISIBLE_HEAP, }); + buffer_role_memory_types.push(hal::MemoryType { + properties: memory::Properties::CPU_VISIBLE | memory::Properties::COHERENT, + heap_index: CPU_VISIBLE_HEAP, + }); buffer_role_memory_types.push(hal::MemoryType { properties: memory::Properties::CPU_VISIBLE | memory::Properties::CPU_CACHED, heap_index: CPU_VISIBLE_HEAP, @@ -397,14 +401,7 @@ impl PhysicalDevice { memory_types.push(( buffer_role_memory_type, MemoryRole::Buffer { - allowed_usage: buffer::Usage::TRANSFER_SRC - | buffer::Usage::TRANSFER_DST - | buffer::Usage::UNIFORM_TEXEL - | buffer::Usage::STORAGE_TEXEL - | buffer::Usage::UNIFORM - | buffer::Usage::STORAGE - | buffer::Usage::VERTEX - | buffer::Usage::INDIRECT, + allowed_usage: buffer::Usage::all() - buffer::Usage::INDEX, target: glow::PIXEL_PACK_BUFFER, } )); @@ -414,15 +411,7 @@ impl PhysicalDevice { memory_types.push(( buffer_role_memory_type, MemoryRole::Buffer { - allowed_usage: buffer::Usage::TRANSFER_SRC - | buffer::Usage::TRANSFER_DST - | buffer::Usage::UNIFORM_TEXEL - | buffer::Usage::STORAGE_TEXEL - | buffer::Usage::UNIFORM - | buffer::Usage::STORAGE - | buffer::Usage::INDEX - | buffer::Usage::VERTEX - | buffer::Usage::INDIRECT, + allowed_usage: buffer::Usage::all(), target: glow::PIXEL_PACK_BUFFER, } )); diff --git a/src/backend/gl/src/native.rs b/src/backend/gl/src/native.rs index 12f2e77bf2a..ec80f881730 100644 --- a/src/backend/gl/src/native.rs +++ b/src/backend/gl/src/native.rs @@ -248,11 +248,11 @@ pub enum ShaderModule { #[derive(Debug)] pub struct Memory { pub(crate) properties: Properties, - // Image memory is faked and has no associated gl buffer - pub(crate) buffer: Option, + /// Gl buffer and the target that should be used for transfer operations. Image memory is faked + /// and has no associated buffer, so this will be None for image memory. + pub(crate) buffer: Option<(RawBuffer, u32)>, /// Allocation size pub(crate) size: u64, - pub(crate) target: u32, pub(crate) map_flags: u32, pub(crate) emulate_map_allocation: Cell>, }