Revert making Raw{Buffer,Image}::bind_memory unsafe (#2595)

This commit is contained in:
marc0246 2024-10-30 16:22:55 +01:00 committed by GitHub
parent 726c4bec05
commit a44a77869a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 56 additions and 57 deletions

View File

@ -325,9 +325,9 @@ mod linux {
.export_fd(ExternalMemoryHandleType::OpaqueFd) .export_fd(ExternalMemoryHandleType::OpaqueFd)
.unwrap(); .unwrap();
// SAFETY: we just created this raw image and hasn't bound any memory to it.
let image = Arc::new( let image = Arc::new(
unsafe { raw_image.bind_memory([ResourceMemory::new_dedicated(image_memory)]) } raw_image
.bind_memory([ResourceMemory::new_dedicated(image_memory)])
.map_err(|(err, _, _)| err) .map_err(|(err, _, _)| err)
.unwrap(), .unwrap(),
); );

View File

@ -404,8 +404,7 @@ impl Buffer {
.map_err(AllocateBufferError::AllocateMemory)?; .map_err(AllocateBufferError::AllocateMemory)?;
let allocation = unsafe { ResourceMemory::from_allocation(allocator, allocation) }; let allocation = unsafe { ResourceMemory::from_allocation(allocator, allocation) };
// SAFETY: we just created this raw buffer and hasn't bound any memory to it. let buffer = raw_buffer.bind_memory(allocation).map_err(|(err, _, _)| {
let buffer = unsafe { raw_buffer.bind_memory(allocation) }.map_err(|(err, _, _)| {
err.map(AllocateBufferError::BindMemory) err.map(AllocateBufferError::BindMemory)
.map_validation(|err| err.add_context("RawBuffer::bind_memory")) .map_validation(|err| err.add_context("RawBuffer::bind_memory"))
})?; })?;

View File

@ -103,6 +103,8 @@ impl RawBuffer {
/// ///
/// - `handle` must be a valid Vulkan object handle created from `device`. /// - `handle` must be a valid Vulkan object handle created from `device`.
/// - `create_info` must match the info used to create the object. /// - `create_info` must match the info used to create the object.
/// - If the buffer has memory bound to it, `bind_memory` must not be called on the returned
/// `RawBuffer`.
#[inline] #[inline]
pub unsafe fn from_handle( pub unsafe fn from_handle(
device: Arc<Device>, device: Arc<Device>,
@ -119,6 +121,8 @@ impl RawBuffer {
/// ///
/// - `handle` must be a valid Vulkan object handle created from `device`. /// - `handle` must be a valid Vulkan object handle created from `device`.
/// - `create_info` must match the info used to create the object. /// - `create_info` must match the info used to create the object.
/// - If the buffer has memory bound to it, `bind_memory` must not be called on the returned
/// `RawBuffer`.
/// - Caller must ensure that the handle will not be destroyed for the lifetime of returned /// - Caller must ensure that the handle will not be destroyed for the lifetime of returned
/// `RawBuffer`. /// `RawBuffer`.
#[inline] #[inline]
@ -241,11 +245,7 @@ impl RawBuffer {
} }
/// Binds device memory to this buffer. /// Binds device memory to this buffer.
/// pub fn bind_memory(
/// # Safety
///
/// - The buffer must not already have memory bound to it.
pub unsafe fn bind_memory(
self, self,
allocation: ResourceMemory, allocation: ResourceMemory,
) -> Result<Buffer, (Validated<VulkanError>, RawBuffer, ResourceMemory)> { ) -> Result<Buffer, (Validated<VulkanError>, RawBuffer, ResourceMemory)> {
@ -257,15 +257,6 @@ impl RawBuffer {
.map_err(|(err, buffer, allocation)| (err.into(), buffer, allocation)) .map_err(|(err, buffer, allocation)| (err.into(), buffer, allocation))
} }
/// Assume this buffer has memory bound to it.
///
/// # Safety
///
/// - The buffer must have memory bound to it.
pub unsafe fn assume_bound(self) -> Buffer {
Buffer::from_raw(self, BufferMemory::External)
}
fn validate_bind_memory( fn validate_bind_memory(
&self, &self,
allocation: &ResourceMemory, allocation: &ResourceMemory,
@ -520,6 +511,15 @@ impl RawBuffer {
Ok(Buffer::from_raw(self, BufferMemory::Normal(allocation))) Ok(Buffer::from_raw(self, BufferMemory::Normal(allocation)))
} }
/// Assume this buffer has memory bound to it.
///
/// # Safety
///
/// - The buffer must have memory bound to it.
pub unsafe fn assume_bound(self) -> Buffer {
Buffer::from_raw(self, BufferMemory::External)
}
/// Returns the memory requirements for this buffer. /// Returns the memory requirements for this buffer.
pub fn memory_requirements(&self) -> &MemoryRequirements { pub fn memory_requirements(&self) -> &MemoryRequirements {
&self.memory_requirements &self.memory_requirements

View File

@ -166,7 +166,7 @@ impl Image {
let allocation = unsafe { ResourceMemory::from_allocation(allocator, allocation) }; let allocation = unsafe { ResourceMemory::from_allocation(allocator, allocation) };
// SAFETY: we just created this raw image and hasn't bound any memory to it. // SAFETY: we just created this raw image and hasn't bound any memory to it.
let image = unsafe { raw_image.bind_memory([allocation]) }.map_err(|(err, _, _)| { let image = raw_image.bind_memory([allocation]).map_err(|(err, _, _)| {
err.map(AllocateImageError::BindMemory) err.map(AllocateImageError::BindMemory)
.map_validation(|err| err.add_context("RawImage::bind_memory")) .map_validation(|err| err.add_context("RawImage::bind_memory"))
})?; })?;

View File

@ -129,6 +129,8 @@ impl RawImage {
/// ///
/// - `handle` must be a valid Vulkan object handle created from `device`. /// - `handle` must be a valid Vulkan object handle created from `device`.
/// - `create_info` must match the info used to create the object. /// - `create_info` must match the info used to create the object.
/// - If the image has memory bound to it, `bind_memory` must not be called on the returned
/// `RawImage`.
#[inline] #[inline]
pub unsafe fn from_handle( pub unsafe fn from_handle(
device: Arc<Device>, device: Arc<Device>,
@ -145,6 +147,8 @@ impl RawImage {
/// ///
/// - `handle` must be a valid Vulkan object handle created from `device`. /// - `handle` must be a valid Vulkan object handle created from `device`.
/// - `create_info` must match the info used to create the object. /// - `create_info` must match the info used to create the object.
/// - If the image has memory bound to it, `bind_memory` must not be called on the returned
/// `RawImage`.
/// - Caller must ensure the handle will not be destroyed for the lifetime of returned /// - Caller must ensure the handle will not be destroyed for the lifetime of returned
/// `RawImage`. /// `RawImage`.
#[inline] #[inline]
@ -475,11 +479,7 @@ impl RawImage {
/// - If `self.flags()` contains `ImageCreateFlags::DISJOINT`, and `self.tiling()` is /// - If `self.flags()` contains `ImageCreateFlags::DISJOINT`, and `self.tiling()` is
/// `ImageTiling::DrmFormatModifier`, then `allocations` must contain exactly /// `ImageTiling::DrmFormatModifier`, then `allocations` must contain exactly
/// `self.drm_format_modifier().unwrap().1` elements. /// `self.drm_format_modifier().unwrap().1` elements.
/// pub fn bind_memory(
/// # Safety
///
/// - The image must not already have memory bound to it.
pub unsafe fn bind_memory(
self, self,
allocations: impl IntoIterator<Item = ResourceMemory>, allocations: impl IntoIterator<Item = ResourceMemory>,
) -> Result< ) -> Result<
@ -833,39 +833,6 @@ impl RawImage {
Ok(()) Ok(())
} }
/// Assume that this image already has memory backing it.
///
/// # Safety
///
/// - The image must be backed by suitable memory allocations.
pub unsafe fn assume_bound(self) -> Image {
let usage = self
.usage
.difference(ImageUsage::TRANSFER_SRC | ImageUsage::TRANSFER_DST);
let layout = if usage.intersects(ImageUsage::SAMPLED | ImageUsage::INPUT_ATTACHMENT)
&& usage
.difference(ImageUsage::SAMPLED | ImageUsage::INPUT_ATTACHMENT)
.is_empty()
{
ImageLayout::ShaderReadOnlyOptimal
} else if usage.intersects(ImageUsage::COLOR_ATTACHMENT)
&& usage.difference(ImageUsage::COLOR_ATTACHMENT).is_empty()
{
ImageLayout::ColorAttachmentOptimal
} else if usage.intersects(ImageUsage::DEPTH_STENCIL_ATTACHMENT)
&& usage
.difference(ImageUsage::DEPTH_STENCIL_ATTACHMENT)
.is_empty()
{
ImageLayout::DepthStencilAttachmentOptimal
} else {
ImageLayout::General
};
Image::from_raw(self, ImageMemory::External, layout)
}
/// # Safety /// # Safety
/// ///
/// - If `self.flags()` does not contain `ImageCreateFlags::DISJOINT`, then `allocations` must /// - If `self.flags()` does not contain `ImageCreateFlags::DISJOINT`, then `allocations` must
@ -1011,6 +978,39 @@ impl RawImage {
)) ))
} }
/// Assume that this image already has memory backing it.
///
/// # Safety
///
/// - The image must be backed by suitable memory allocations.
pub unsafe fn assume_bound(self) -> Image {
let usage = self
.usage
.difference(ImageUsage::TRANSFER_SRC | ImageUsage::TRANSFER_DST);
let layout = if usage.intersects(ImageUsage::SAMPLED | ImageUsage::INPUT_ATTACHMENT)
&& usage
.difference(ImageUsage::SAMPLED | ImageUsage::INPUT_ATTACHMENT)
.is_empty()
{
ImageLayout::ShaderReadOnlyOptimal
} else if usage.intersects(ImageUsage::COLOR_ATTACHMENT)
&& usage.difference(ImageUsage::COLOR_ATTACHMENT).is_empty()
{
ImageLayout::ColorAttachmentOptimal
} else if usage.intersects(ImageUsage::DEPTH_STENCIL_ATTACHMENT)
&& usage
.difference(ImageUsage::DEPTH_STENCIL_ATTACHMENT)
.is_empty()
{
ImageLayout::DepthStencilAttachmentOptimal
} else {
ImageLayout::General
};
Image::from_raw(self, ImageMemory::External, layout)
}
/// Returns the memory requirements for this image. /// Returns the memory requirements for this image.
/// ///
/// - If the image is a swapchain image, this returns a slice with a length of 0. /// - If the image is a swapchain image, this returns a slice with a length of 0.