mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-25 16:25:31 +00:00
Add validation for VkExportMemoryAllocateInfo
(#2258)
* Add validation for `VkExportMemoryAllocateInfo` * Fix oopsie
This commit is contained in:
parent
3ae450ada0
commit
c0bc610037
@ -890,18 +890,19 @@ vulkan_bitflags! {
|
||||
},*/
|
||||
}
|
||||
|
||||
/// The buffer configuration to query in
|
||||
/// [`PhysicalDevice::external_buffer_properties`](crate::device::physical::PhysicalDevice::external_buffer_properties).
|
||||
/// The buffer configuration to query in [`PhysicalDevice::external_buffer_properties`].
|
||||
///
|
||||
/// [`PhysicalDevice::external_buffer_properties`]: crate::device::physical::PhysicalDevice::external_buffer_properties
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct ExternalBufferInfo {
|
||||
/// The external handle type that will be used with the buffer.
|
||||
pub handle_type: ExternalMemoryHandleType,
|
||||
/// The flags that will be used.
|
||||
pub flags: BufferCreateFlags,
|
||||
|
||||
/// The usage that the buffer will have.
|
||||
pub usage: BufferUsage,
|
||||
|
||||
/// The sparse binding parameters that will be used.
|
||||
pub sparse: Option<BufferCreateFlags>,
|
||||
/// The external handle type that will be used with the buffer.
|
||||
pub handle_type: ExternalMemoryHandleType,
|
||||
|
||||
pub _ne: crate::NonExhaustive,
|
||||
}
|
||||
@ -911,9 +912,9 @@ impl ExternalBufferInfo {
|
||||
#[inline]
|
||||
pub fn handle_type(handle_type: ExternalMemoryHandleType) -> Self {
|
||||
Self {
|
||||
handle_type,
|
||||
flags: BufferCreateFlags::empty(),
|
||||
usage: BufferUsage::empty(),
|
||||
sparse: None,
|
||||
handle_type,
|
||||
_ne: crate::NonExhaustive(()),
|
||||
}
|
||||
}
|
||||
@ -923,12 +924,20 @@ impl ExternalBufferInfo {
|
||||
physical_device: &PhysicalDevice,
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
handle_type,
|
||||
flags,
|
||||
usage,
|
||||
sparse: _,
|
||||
handle_type,
|
||||
_ne: _,
|
||||
} = self;
|
||||
|
||||
flags
|
||||
.validate_physical_device(physical_device)
|
||||
.map_err(|err| ValidationError {
|
||||
context: "flags".into(),
|
||||
vuids: &["VUID-VkPhysicalDeviceExternalBufferInfo-flags-parameter"],
|
||||
..ValidationError::from_requirement(err)
|
||||
})?;
|
||||
|
||||
usage
|
||||
.validate_physical_device(physical_device)
|
||||
.map_err(|err| ValidationError {
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
use super::{Buffer, BufferCreateFlags, BufferMemory, BufferUsage};
|
||||
use crate::{
|
||||
buffer::ExternalBufferInfo,
|
||||
device::{Device, DeviceOwned},
|
||||
instance::InstanceOwnedDebugWrapper,
|
||||
macros::impl_id_counter,
|
||||
@ -289,14 +290,13 @@ impl RawBuffer {
|
||||
fn validate_bind_memory(&self, allocation: &MemoryAlloc) -> Result<(), Box<ValidationError>> {
|
||||
assert_ne!(allocation.allocation_type(), AllocationType::NonLinear);
|
||||
|
||||
let physical_device = self.device().physical_device();
|
||||
|
||||
let memory_requirements = &self.memory_requirements;
|
||||
let memory = allocation.device_memory();
|
||||
let memory_offset = allocation.offset();
|
||||
let memory_type = &self
|
||||
.device
|
||||
.physical_device()
|
||||
.memory_properties()
|
||||
.memory_types[memory.memory_type_index() as usize];
|
||||
let memory_type =
|
||||
&physical_device.memory_properties().memory_types[memory.memory_type_index() as usize];
|
||||
|
||||
// VUID-VkBindBufferMemoryInfo-commonparent
|
||||
assert_eq!(self.device(), memory.device());
|
||||
@ -380,19 +380,86 @@ impl RawBuffer {
|
||||
}));
|
||||
}
|
||||
|
||||
if !memory.export_handle_types().is_empty()
|
||||
&& !self
|
||||
if !memory.export_handle_types().is_empty() {
|
||||
if !self
|
||||
.external_memory_handle_types
|
||||
.intersects(memory.export_handle_types())
|
||||
{
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`allocation.device_memory().export_handle_types()` is not empty, but \
|
||||
it does not share at least one memory type with \
|
||||
`self.external_memory_handle_types()`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkBindBufferMemoryInfo-memory-02726"],
|
||||
..Default::default()
|
||||
}));
|
||||
{
|
||||
return Err(Box::new(ValidationError {
|
||||
problem:
|
||||
"`allocation.device_memory().export_handle_types()` is not empty, but \
|
||||
it does not share at least one handle type with \
|
||||
`self.external_memory_handle_types()`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkBindBufferMemoryInfo-memory-02726"],
|
||||
..Default::default()
|
||||
}));
|
||||
}
|
||||
|
||||
for handle_type in memory.export_handle_types() {
|
||||
let external_buffer_properties = unsafe {
|
||||
physical_device.external_buffer_properties_unchecked(ExternalBufferInfo {
|
||||
flags: self.flags,
|
||||
usage: self.usage,
|
||||
handle_type,
|
||||
_ne: crate::NonExhaustive(()),
|
||||
})
|
||||
};
|
||||
|
||||
if external_buffer_properties
|
||||
.external_memory_properties
|
||||
.dedicated_only
|
||||
&& !memory.is_dedicated()
|
||||
{
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: format!(
|
||||
"`allocation.device_memory().export_handle_types()` has the `{:?}` \
|
||||
flag set, which requires a dedicated allocation as returned by \
|
||||
`PhysicalDevice::external_buffer_properties`, but \
|
||||
`allocation.device_memory()` is not a dedicated allocation",
|
||||
handle_type,
|
||||
)
|
||||
.into(),
|
||||
vuids: &["VUID-VkMemoryAllocateInfo-pNext-00639"],
|
||||
..Default::default()
|
||||
}));
|
||||
}
|
||||
|
||||
if !external_buffer_properties
|
||||
.external_memory_properties
|
||||
.exportable
|
||||
{
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: format!(
|
||||
"`allocation.device_memory().export_handle_types()` has the `{:?}` \
|
||||
flag set, but the flag is not supported for exporting, as returned by \
|
||||
`PhysicalDevice::external_buffer_properties`",
|
||||
handle_type,
|
||||
)
|
||||
.into(),
|
||||
vuids: &["VUID-VkExportMemoryAllocateInfo-handleTypes-00656"],
|
||||
..Default::default()
|
||||
}));
|
||||
}
|
||||
|
||||
if !external_buffer_properties
|
||||
.external_memory_properties
|
||||
.compatible_handle_types
|
||||
.contains(memory.export_handle_types())
|
||||
{
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: format!(
|
||||
"`allocation.device_memory().export_handle_types()` has the `{:?}` \
|
||||
flag set, but the flag is not compatible with the other flags set, as \
|
||||
returned by `PhysicalDevice::external_buffer_properties`",
|
||||
handle_type,
|
||||
)
|
||||
.into(),
|
||||
vuids: &["VUID-VkExportMemoryAllocateInfo-handleTypes-00656"],
|
||||
..Default::default()
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(handle_type) = memory.imported_handle_type() {
|
||||
|
@ -538,14 +538,14 @@ impl PhysicalDevice {
|
||||
/* Input */
|
||||
|
||||
let &ExternalBufferInfo {
|
||||
handle_type,
|
||||
flags,
|
||||
usage,
|
||||
sparse,
|
||||
handle_type,
|
||||
_ne: _,
|
||||
} = info;
|
||||
|
||||
let external_buffer_info = ash::vk::PhysicalDeviceExternalBufferInfo {
|
||||
flags: sparse.map(Into::into).unwrap_or_default(),
|
||||
flags: flags.into(),
|
||||
usage: usage.into(),
|
||||
handle_type: handle_type.into(),
|
||||
..Default::default()
|
||||
|
@ -730,6 +730,8 @@ impl RawImage {
|
||||
&self,
|
||||
allocations: &[MemoryAlloc],
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
let physical_device = self.device().physical_device();
|
||||
|
||||
if self.flags.intersects(ImageCreateFlags::DISJOINT) {
|
||||
match self.tiling {
|
||||
ImageTiling::Optimal | ImageTiling::Linear => {
|
||||
@ -768,7 +770,8 @@ impl RawImage {
|
||||
}
|
||||
}
|
||||
|
||||
for (index, (allocation, memory_requirements)) in (allocations.iter())
|
||||
for (index, (allocation, memory_requirements)) in allocations
|
||||
.iter()
|
||||
.zip(self.memory_requirements.iter())
|
||||
.enumerate()
|
||||
{
|
||||
@ -807,11 +810,8 @@ impl RawImage {
|
||||
|
||||
let memory = allocation.device_memory();
|
||||
let memory_offset = allocation.offset();
|
||||
let memory_type = &self
|
||||
.device
|
||||
.physical_device()
|
||||
.memory_properties()
|
||||
.memory_types[memory.memory_type_index() as usize];
|
||||
let memory_type = &physical_device.memory_properties().memory_types
|
||||
[memory.memory_type_index() as usize];
|
||||
|
||||
// VUID-VkBindImageMemoryInfo-commonparent
|
||||
assert_eq!(self.device(), memory.device());
|
||||
@ -924,22 +924,106 @@ impl RawImage {
|
||||
}));
|
||||
}
|
||||
|
||||
if !memory.export_handle_types().is_empty()
|
||||
&& !memory
|
||||
.export_handle_types()
|
||||
.intersects(self.external_memory_handle_types)
|
||||
{
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: format!(
|
||||
"`allocations[{}].device_memory().export_handle_types()` is not empty, \
|
||||
but it does not share at least one memory type with \
|
||||
`self.external_memory_handle_types()`",
|
||||
index
|
||||
)
|
||||
.into(),
|
||||
vuids: &["VUID-VkBindImageMemoryInfo-memory-02728"],
|
||||
..Default::default()
|
||||
}));
|
||||
if !memory.export_handle_types().is_empty() {
|
||||
if !self
|
||||
.external_memory_handle_types
|
||||
.intersects(memory.export_handle_types())
|
||||
{
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: format!(
|
||||
"`allocations[{}].device_memory().export_handle_types()` is not empty, \
|
||||
but it does not share at least one memory type with \
|
||||
`self.external_memory_handle_types()`",
|
||||
index
|
||||
)
|
||||
.into(),
|
||||
vuids: &["VUID-VkBindImageMemoryInfo-memory-02728"],
|
||||
..Default::default()
|
||||
}));
|
||||
}
|
||||
|
||||
for handle_type in memory.export_handle_types() {
|
||||
let image_format_properties = unsafe {
|
||||
physical_device.image_format_properties_unchecked(ImageFormatInfo {
|
||||
flags: self.flags,
|
||||
format: self.format,
|
||||
image_type: self.image_type,
|
||||
tiling: self.tiling,
|
||||
usage: self.usage,
|
||||
stencil_usage: self.stencil_usage,
|
||||
external_memory_handle_type: Some(handle_type),
|
||||
image_view_type: None,
|
||||
drm_format_modifier_info: self.drm_format_modifier().map(
|
||||
|(drm_format_modifier, _)| ImageDrmFormatModifierInfo {
|
||||
drm_format_modifier,
|
||||
sharing: self.sharing.clone(),
|
||||
_ne: crate::NonExhaustive(()),
|
||||
},
|
||||
),
|
||||
_ne: crate::NonExhaustive(()),
|
||||
})
|
||||
}
|
||||
.map_err(|_| ValidationError {
|
||||
problem: "`PhysicalDevice::image_format_properties` returned an error"
|
||||
.into(),
|
||||
..Default::default()
|
||||
})?
|
||||
.unwrap();
|
||||
|
||||
if image_format_properties
|
||||
.external_memory_properties
|
||||
.dedicated_only
|
||||
&& !memory.is_dedicated()
|
||||
{
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: format!(
|
||||
"`allocations[{}].device_memory().export_handle_types()` has the \
|
||||
`{:?}` flag set, which requires a dedicated allocation as returned \
|
||||
by `PhysicalDevice::image_format_properties`, but \
|
||||
`allocations[{}].device_memory()` is not a dedicated allocation",
|
||||
index, handle_type, index,
|
||||
)
|
||||
.into(),
|
||||
vuids: &["VUID-VkMemoryAllocateInfo-pNext-00639"],
|
||||
..Default::default()
|
||||
}));
|
||||
}
|
||||
|
||||
if !image_format_properties
|
||||
.external_memory_properties
|
||||
.exportable
|
||||
{
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: format!(
|
||||
"`allocations[{}].device_memory().export_handle_types()` has the \
|
||||
`{:?}` flag set, but the flag is not supported for exporting, as \
|
||||
returned by `PhysicalDevice::image_format_properties`",
|
||||
index, handle_type,
|
||||
)
|
||||
.into(),
|
||||
vuids: &["VUID-VkExportMemoryAllocateInfo-handleTypes-00656"],
|
||||
..Default::default()
|
||||
}));
|
||||
}
|
||||
|
||||
if !image_format_properties
|
||||
.external_memory_properties
|
||||
.compatible_handle_types
|
||||
.contains(memory.export_handle_types())
|
||||
{
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: format!(
|
||||
"`allocation.device_memory().export_handle_types()` has the `{:?}` \
|
||||
flag set, but the flag is not compatible with the other flags set, \
|
||||
as returned by `PhysicalDevice::image_format_properties`",
|
||||
handle_type,
|
||||
)
|
||||
.into(),
|
||||
vuids: &["VUID-VkExportMemoryAllocateInfo-handleTypes-00656"],
|
||||
..Default::default()
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(handle_type) = memory.imported_handle_type() {
|
||||
@ -2397,8 +2481,7 @@ impl ImageCreateInfo {
|
||||
}));
|
||||
}
|
||||
|
||||
let queue_family_count =
|
||||
device.physical_device().queue_family_properties().len() as u32;
|
||||
let queue_family_count = physical_device.queue_family_properties().len() as u32;
|
||||
|
||||
for (index, &queue_family_index) in queue_family_indices.iter().enumerate() {
|
||||
if queue_family_indices[..index].contains(&queue_family_index) {
|
||||
@ -2611,8 +2694,7 @@ impl ImageCreateInfo {
|
||||
for drm_format_modifier in iter_or_none(drm_format_modifiers.iter().copied()) {
|
||||
for external_memory_handle_type in iter_or_none(external_memory_handle_types) {
|
||||
let image_format_properties = unsafe {
|
||||
device
|
||||
.physical_device()
|
||||
physical_device
|
||||
.image_format_properties_unchecked(ImageFormatInfo {
|
||||
flags,
|
||||
format: Some(format),
|
||||
|
@ -743,9 +743,8 @@ impl<'d> MemoryAllocateInfo<'d> {
|
||||
|
||||
// VUID-VkMemoryAllocateInfo-pNext-00639
|
||||
// VUID-VkExportMemoryAllocateInfo-handleTypes-00656
|
||||
// TODO: how do you fullfill this when you don't know the image or buffer parameters?
|
||||
// Does exporting memory require specifying these parameters up front, and does it tie
|
||||
// the allocation to only images or buffers of that type?
|
||||
// Impossible to validate here, instead this is validated in `RawBuffer::bind_memory`
|
||||
// and `RawImage::bind_memory`.
|
||||
}
|
||||
|
||||
if !flags.is_empty() {
|
||||
|
Loading…
Reference in New Issue
Block a user