mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-25 16:25:31 +00:00
Box ValidationError
(#2253)
This commit is contained in:
parent
622ec47970
commit
b74ce40b2c
@ -6,14 +6,14 @@ use raw_window_handle::{
|
||||
HasRawDisplayHandle, HasRawWindowHandle, RawDisplayHandle, RawWindowHandle,
|
||||
};
|
||||
use std::{any::Any, sync::Arc};
|
||||
use vulkano::{instance::Instance, swapchain::Surface, VulkanError};
|
||||
use vulkano::{instance::Instance, swapchain::Surface, Validated, VulkanError};
|
||||
|
||||
/// Creates a Vulkan surface from a generic window which implements `HasRawWindowHandle` and thus
|
||||
/// can reveal the OS-dependent handle.
|
||||
pub fn create_surface_from_handle(
|
||||
window: Arc<impl Any + Send + Sync + HasRawWindowHandle + HasRawDisplayHandle>,
|
||||
instance: Arc<Instance>,
|
||||
) -> Result<Arc<Surface>, VulkanError> {
|
||||
) -> Result<Arc<Surface>, Validated<VulkanError>> {
|
||||
unsafe {
|
||||
match window.raw_window_handle() {
|
||||
RawWindowHandle::AndroidNdk(h) => {
|
||||
@ -82,7 +82,7 @@ pub fn create_surface_from_handle(
|
||||
pub unsafe fn create_surface_from_handle_ref(
|
||||
window: &(impl HasRawWindowHandle + HasRawDisplayHandle),
|
||||
instance: Arc<Instance>,
|
||||
) -> Result<Arc<Surface>, VulkanError> {
|
||||
) -> Result<Arc<Surface>, Validated<VulkanError>> {
|
||||
unsafe {
|
||||
match window.raw_window_handle() {
|
||||
RawWindowHandle::AndroidNdk(h) => {
|
||||
|
@ -6,7 +6,7 @@ use std::{
|
||||
use vulkano::{
|
||||
instance::{Instance, InstanceExtensions},
|
||||
swapchain::Surface,
|
||||
VulkanError, VulkanLibrary,
|
||||
Validated, VulkanError, VulkanLibrary,
|
||||
};
|
||||
use winit::{
|
||||
error::OsError as WindowCreationError,
|
||||
@ -37,7 +37,7 @@ pub fn required_extensions(library: &VulkanLibrary) -> InstanceExtensions {
|
||||
pub fn create_surface_from_winit(
|
||||
window: Arc<Window>,
|
||||
instance: Arc<Instance>,
|
||||
) -> Result<Arc<Surface>, VulkanError> {
|
||||
) -> Result<Arc<Surface>, Validated<VulkanError>> {
|
||||
unsafe { winit_to_surface(instance, window) }
|
||||
}
|
||||
|
||||
@ -65,17 +65,17 @@ impl<E> VkSurfaceBuild<E> for WindowBuilder {
|
||||
#[derive(Debug)]
|
||||
pub enum CreationError {
|
||||
/// Error when creating the surface.
|
||||
VulkanError(VulkanError),
|
||||
Surface(Validated<VulkanError>),
|
||||
|
||||
/// Error when creating the window.
|
||||
WindowCreationError(WindowCreationError),
|
||||
Window(WindowCreationError),
|
||||
}
|
||||
|
||||
impl Error for CreationError {
|
||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||
match self {
|
||||
CreationError::VulkanError(err) => Some(err),
|
||||
CreationError::WindowCreationError(err) => Some(err),
|
||||
CreationError::Surface(err) => Some(err),
|
||||
CreationError::Window(err) => Some(err),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -86,22 +86,22 @@ impl Display for CreationError {
|
||||
f,
|
||||
"{}",
|
||||
match self {
|
||||
CreationError::VulkanError(_) => "error while creating the surface",
|
||||
CreationError::WindowCreationError(_) => "error while creating the window",
|
||||
CreationError::Surface(_) => "error while creating the surface",
|
||||
CreationError::Window(_) => "error while creating the window",
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<VulkanError> for CreationError {
|
||||
fn from(err: VulkanError) -> CreationError {
|
||||
CreationError::VulkanError(err)
|
||||
impl From<Validated<VulkanError>> for CreationError {
|
||||
fn from(err: Validated<VulkanError>) -> CreationError {
|
||||
CreationError::Surface(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<WindowCreationError> for CreationError {
|
||||
fn from(err: WindowCreationError) -> CreationError {
|
||||
CreationError::WindowCreationError(err)
|
||||
CreationError::Window(err)
|
||||
}
|
||||
}
|
||||
|
||||
@ -109,7 +109,7 @@ impl From<WindowCreationError> for CreationError {
|
||||
unsafe fn winit_to_surface(
|
||||
instance: Arc<Instance>,
|
||||
window: Arc<Window>,
|
||||
) -> Result<Arc<Surface>, VulkanError> {
|
||||
) -> Result<Arc<Surface>, Validated<VulkanError>> {
|
||||
use raw_window_handle::HasRawWindowHandle;
|
||||
use raw_window_handle::RawWindowHandle::AndroidNdk;
|
||||
if let AndroidNdk(handle) = window.raw_window_handle() {
|
||||
@ -128,7 +128,7 @@ unsafe fn winit_to_surface(
|
||||
unsafe fn winit_to_surface(
|
||||
instance: Arc<Instance>,
|
||||
window: Arc<Window>,
|
||||
) -> Result<Arc<Surface>, VulkanError> {
|
||||
) -> Result<Arc<Surface>, Validated<VulkanError>> {
|
||||
use winit::platform::{wayland::WindowExtWayland, x11::WindowExtX11};
|
||||
|
||||
match (window.wayland_display(), window.wayland_surface()) {
|
||||
@ -194,7 +194,7 @@ pub(crate) unsafe fn get_metal_layer_macos(view: *mut std::ffi::c_void) -> *mut
|
||||
unsafe fn winit_to_surface(
|
||||
instance: Arc<Instance>,
|
||||
window: Arc<Window>,
|
||||
) -> Result<Arc<Surface>, VulkanError> {
|
||||
) -> Result<Arc<Surface>, Validated<VulkanError>> {
|
||||
use winit::platform::macos::WindowExtMacOS;
|
||||
let layer = get_metal_layer_macos(window.ns_view());
|
||||
Surface::from_mac_os(instance, layer as *const (), Some(window))
|
||||
@ -225,7 +225,7 @@ pub(crate) unsafe fn get_metal_layer_ios(view: *mut std::ffi::c_void) -> IOSMeta
|
||||
unsafe fn winit_to_surface(
|
||||
instance: Arc<Instance>,
|
||||
window: Arc<Window>,
|
||||
) -> Result<Arc<Surface>, VulkanError> {
|
||||
) -> Result<Arc<Surface>, Validated<VulkanError>> {
|
||||
use winit::platform::ios::WindowExtIOS;
|
||||
let layer = get_metal_layer_ios(window.ui_view());
|
||||
Surface::from_ios(instance, layer, Some(window))
|
||||
@ -235,7 +235,7 @@ unsafe fn winit_to_surface(
|
||||
unsafe fn winit_to_surface(
|
||||
instance: Arc<Instance>,
|
||||
window: Arc<Window>,
|
||||
) -> Result<Arc<Surface>, VulkanError> {
|
||||
) -> Result<Arc<Surface>, Validated<VulkanError>> {
|
||||
use winit::platform::windows::WindowExtWindows;
|
||||
|
||||
Surface::from_win32(
|
||||
|
@ -42,13 +42,13 @@ fn errors_output(members: &[ErrorsMember]) -> TokenStream {
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
#[repr(i32)]
|
||||
#[non_exhaustive]
|
||||
pub enum RuntimeError {
|
||||
pub enum VulkanError {
|
||||
#(#enum_items)*
|
||||
Unnamed(ash::vk::Result),
|
||||
}
|
||||
|
||||
impl From<ash::vk::Result> for RuntimeError {
|
||||
fn from(val: ash::vk::Result) -> RuntimeError {
|
||||
impl From<ash::vk::Result> for VulkanError {
|
||||
fn from(val: ash::vk::Result) -> VulkanError {
|
||||
match val {
|
||||
#(#try_from_items)*
|
||||
x => Self::Unnamed(x),
|
||||
|
@ -160,13 +160,13 @@ fn device_extensions_output(members: &[ExtensionsMember]) -> TokenStream {
|
||||
|
||||
quote! {
|
||||
if !(#(#condition_items)||*) {
|
||||
return Err(crate::ValidationError {
|
||||
return Err(Box::new(crate::ValidationError {
|
||||
problem: #problem.into(),
|
||||
requires_one_of: crate::RequiresOneOf(&[
|
||||
#(#requires_one_of_items)*
|
||||
]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -180,10 +180,10 @@ fn device_extensions_output(members: &[ExtensionsMember]) -> TokenStream {
|
||||
quote! {
|
||||
if self.#name {
|
||||
if !supported.#name {
|
||||
return Err(crate::ValidationError {
|
||||
return Err(Box::new(crate::ValidationError {
|
||||
problem: #problem.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
#(#dependency_check_items)*
|
||||
@ -277,7 +277,7 @@ fn device_extensions_output(members: &[ExtensionsMember]) -> TokenStream {
|
||||
supported: &DeviceExtensions,
|
||||
api_version: crate::Version,
|
||||
instance_extensions: &crate::instance::InstanceExtensions,
|
||||
) -> Result<(), crate::ValidationError> {
|
||||
) -> Result<(), Box<crate::ValidationError>> {
|
||||
#(#check_requirements_items)*
|
||||
Ok(())
|
||||
}
|
||||
@ -317,7 +317,7 @@ fn instance_extensions_output(members: &[ExtensionsMember]) -> TokenStream {
|
||||
|
||||
quote! {
|
||||
if !(api_version >= crate::Version::#version) {
|
||||
return Err(crate::ValidationError {
|
||||
return Err(Box::new(crate::ValidationError {
|
||||
problem: #problem.into(),
|
||||
requires_one_of: crate::RequiresOneOf(&[
|
||||
crate::RequiresAllOf(&[
|
||||
@ -325,7 +325,7 @@ fn instance_extensions_output(members: &[ExtensionsMember]) -> TokenStream {
|
||||
]),
|
||||
]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -339,10 +339,10 @@ fn instance_extensions_output(members: &[ExtensionsMember]) -> TokenStream {
|
||||
quote! {
|
||||
if self.#name {
|
||||
if !supported.#name {
|
||||
return Err(crate::ValidationError {
|
||||
return Err(Box::new(crate::ValidationError {
|
||||
problem: #problem.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
#(#dependency_check_items)*
|
||||
@ -435,7 +435,7 @@ fn instance_extensions_output(members: &[ExtensionsMember]) -> TokenStream {
|
||||
&self,
|
||||
supported: &InstanceExtensions,
|
||||
api_version: crate::Version,
|
||||
) -> Result<(), crate::ValidationError> {
|
||||
) -> Result<(), Box<crate::ValidationError>> {
|
||||
#(#check_requirements_items)*
|
||||
Ok(())
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ fn features_output(members: &[FeaturesMember]) -> TokenStream {
|
||||
let name_string = name.to_string();
|
||||
quote! {
|
||||
if self.#name && !supported.#name {
|
||||
return Err(crate::ValidationError {
|
||||
return Err(Box::new(crate::ValidationError {
|
||||
problem: format!(
|
||||
"contains `{}`, but this feature is not supported \
|
||||
by the physical device",
|
||||
@ -109,7 +109,7 @@ fn features_output(members: &[FeaturesMember]) -> TokenStream {
|
||||
)
|
||||
.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -291,7 +291,7 @@ fn features_output(members: &[FeaturesMember]) -> TokenStream {
|
||||
pub(super) fn check_requirements(
|
||||
&self,
|
||||
supported: &Features,
|
||||
) -> Result<(), crate::ValidationError> {
|
||||
) -> Result<(), Box<crate::ValidationError>> {
|
||||
#(#check_requirements_items)*
|
||||
Ok(())
|
||||
}
|
||||
|
@ -97,8 +97,8 @@ use crate::{
|
||||
format::{Format, FormatFeatures},
|
||||
instance::InstanceOwnedDebugWrapper,
|
||||
macros::{impl_id_counter, vulkan_bitflags, vulkan_enum},
|
||||
DeviceSize, NonZeroDeviceSize, Packed24_8, Requires, RequiresAllOf, RequiresOneOf,
|
||||
RuntimeError, ValidationError, VulkanError, VulkanObject,
|
||||
DeviceSize, NonZeroDeviceSize, Packed24_8, Requires, RequiresAllOf, RequiresOneOf, Validated,
|
||||
ValidationError, VulkanError, VulkanObject,
|
||||
};
|
||||
use bytemuck::{Pod, Zeroable};
|
||||
use std::{fmt::Debug, hash::Hash, mem::MaybeUninit, num::NonZeroU64, ptr, sync::Arc};
|
||||
@ -130,7 +130,7 @@ impl AccelerationStructure {
|
||||
pub unsafe fn new(
|
||||
device: Arc<Device>,
|
||||
create_info: AccelerationStructureCreateInfo,
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
) -> Result<Arc<Self>, Validated<VulkanError>> {
|
||||
Self::validate_new(&device, &create_info)?;
|
||||
|
||||
Ok(Self::new_unchecked(device, create_info)?)
|
||||
@ -139,24 +139,24 @@ impl AccelerationStructure {
|
||||
fn validate_new(
|
||||
device: &Device,
|
||||
create_info: &AccelerationStructureCreateInfo,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
if !device.enabled_extensions().khr_acceleration_structure {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::DeviceExtension(
|
||||
"khr_acceleration_structure",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if !device.enabled_features().acceleration_structure {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"acceleration_structure",
|
||||
)])]),
|
||||
vuids: &["VUID-vkCreateAccelerationStructureKHR-accelerationStructure-03611"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// VUID-vkCreateAccelerationStructureKHR-pCreateInfo-parameter
|
||||
@ -171,7 +171,7 @@ impl AccelerationStructure {
|
||||
pub unsafe fn new_unchecked(
|
||||
device: Arc<Device>,
|
||||
create_info: AccelerationStructureCreateInfo,
|
||||
) -> Result<Arc<Self>, RuntimeError> {
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
let &AccelerationStructureCreateInfo {
|
||||
create_flags,
|
||||
ref buffer,
|
||||
@ -200,7 +200,7 @@ impl AccelerationStructure {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
};
|
||||
|
||||
@ -370,7 +370,7 @@ impl AccelerationStructureCreateInfo {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
create_flags,
|
||||
ref buffer,
|
||||
@ -397,26 +397,26 @@ impl AccelerationStructureCreateInfo {
|
||||
.usage()
|
||||
.intersects(BufferUsage::ACCELERATION_STRUCTURE_STORAGE)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "buffer".into(),
|
||||
problem: "the buffer was not created with the `ACCELERATION_STRUCTURE_STORAGE` \
|
||||
usage"
|
||||
.into(),
|
||||
vuids: &["VUID-VkAccelerationStructureCreateInfoKHR-buffer-03614"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// VUID-VkAccelerationStructureCreateInfoKHR-offset-03616
|
||||
// Ensured by the definition of `Subbuffer`.
|
||||
|
||||
if buffer.offset() % 256 != 0 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "buffer".into(),
|
||||
problem: "the offset of the buffer is not a multiple of 256".into(),
|
||||
vuids: &["VUID-VkAccelerationStructureCreateInfoKHR-offset-03734"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -503,7 +503,7 @@ impl AccelerationStructureBuildGeometryInfo {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
flags,
|
||||
ref mode,
|
||||
@ -537,12 +537,12 @@ impl AccelerationStructureBuildGeometryInfo {
|
||||
}
|
||||
|
||||
if geometries.len() as u64 > max_geometry_count {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "geometries".into(),
|
||||
problem: "the length exceeds the `max_geometry_count` limit".into(),
|
||||
vuids: &["VUID-VkAccelerationStructureBuildGeometryInfoKHR-type-03793"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// VUID-VkAccelerationStructureBuildGeometryInfoKHR-type-03795
|
||||
@ -558,12 +558,12 @@ impl AccelerationStructureBuildGeometryInfo {
|
||||
}
|
||||
|
||||
if geometries.len() as u64 > max_geometry_count {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "geometries".into(),
|
||||
problem: "the length exceeds the `max_geometry_count` limit".into(),
|
||||
vuids: &["VUID-VkAccelerationStructureBuildGeometryInfoKHR-type-03793"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// VUID-VkAccelerationStructureBuildGeometryInfoKHR-type-03794
|
||||
@ -589,14 +589,14 @@ impl AccelerationStructureBuildGeometryInfo {
|
||||
BuildAccelerationStructureFlags::PREFER_FAST_TRACE
|
||||
| BuildAccelerationStructureFlags::PREFER_FAST_BUILD,
|
||||
) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "flags".into(),
|
||||
problem: "contains both `BuildAccelerationStructureFlags::PREFER_FAST_TRACE` and \
|
||||
`BuildAccelerationStructureFlags::PREFER_FAST_BUILD`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkAccelerationStructureBuildGeometryInfoKHR-flags-03796"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -997,7 +997,7 @@ impl AccelerationStructureGeometryTrianglesData {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
flags,
|
||||
vertex_format,
|
||||
@ -1034,14 +1034,14 @@ impl AccelerationStructureGeometryTrianglesData {
|
||||
.buffer_features
|
||||
.intersects(FormatFeatures::ACCELERATION_STRUCTURE_VERTEX_BUFFER)
|
||||
} {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "vertex_format".into(),
|
||||
problem: "format features do not contain \
|
||||
`FormatFeature::ACCELERATION_STRUCTURE_VERTEX_BUFFER`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkAccelerationStructureGeometryTrianglesDataKHR-vertexFormat-03797"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
let smallest_component_bits = vertex_format
|
||||
@ -1053,25 +1053,25 @@ impl AccelerationStructureGeometryTrianglesData {
|
||||
let smallest_component_bytes = (smallest_component_bits + 7) & !7;
|
||||
|
||||
if vertex_stride % smallest_component_bytes != 0 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`vertex_stride` is not a multiple of the byte size of the \
|
||||
smallest component of `vertex_format`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkAccelerationStructureGeometryTrianglesDataKHR-vertexStride-03735"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if let Some(index_data) = index_data.as_ref() {
|
||||
if !matches!(index_data, IndexBuffer::U16(_) | IndexBuffer::U32(_)) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "index_data".into(),
|
||||
problem: "is not `IndexBuffer::U16` or `IndexBuffer::U32`".into(),
|
||||
vuids: &[
|
||||
"VUID-VkAccelerationStructureGeometryTrianglesDataKHR-indexType-03798",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1119,7 +1119,7 @@ impl AccelerationStructureGeometryAabbsData {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
flags,
|
||||
data: _,
|
||||
@ -1136,12 +1136,12 @@ impl AccelerationStructureGeometryAabbsData {
|
||||
})?;
|
||||
|
||||
if stride % 8 != 0 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "stride".into(),
|
||||
problem: "is not a multiple of 8".into(),
|
||||
vuids: &["VUID-VkAccelerationStructureGeometryAabbsDataKHR-stride-03545"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -1192,7 +1192,7 @@ impl AccelerationStructureGeometryInstancesData {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
flags,
|
||||
data: _,
|
||||
@ -1390,7 +1390,7 @@ impl CopyAccelerationStructureInfo {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
ref src,
|
||||
ref dst,
|
||||
@ -1413,22 +1413,22 @@ impl CopyAccelerationStructureInfo {
|
||||
mode,
|
||||
CopyAccelerationStructureMode::Compact | CopyAccelerationStructureMode::Clone
|
||||
) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "mode".into(),
|
||||
problem: "is not `CopyAccelerationStructureMode::Compact` or \
|
||||
`CopyAccelerationStructureMode::Clone`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkCopyAccelerationStructureInfoKHR-mode-03410"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if src.buffer() == dst.buffer() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`src` and `dst` share the same buffer".into(),
|
||||
vuids: &["VUID-VkCopyAccelerationStructureInfoKHR-dst-07791"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// VUID-VkCopyAccelerationStructureInfoKHR-src-04963
|
||||
@ -1474,7 +1474,7 @@ impl CopyAccelerationStructureToMemoryInfo {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
ref src,
|
||||
ref dst,
|
||||
@ -1493,12 +1493,12 @@ impl CopyAccelerationStructureToMemoryInfo {
|
||||
})?;
|
||||
|
||||
if !matches!(mode, CopyAccelerationStructureMode::Serialize) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "mode".into(),
|
||||
problem: "is not `CopyAccelerationStructureMode::Serialize`".into(),
|
||||
vuids: &["VUID-VkCopyAccelerationStructureToMemoryInfoKHR-mode-03412"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// VUID-VkCopyAccelerationStructureToMemoryInfoKHR-src-04959
|
||||
@ -1544,7 +1544,7 @@ impl CopyMemoryToAccelerationStructureInfo {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
ref src,
|
||||
ref dst,
|
||||
@ -1563,12 +1563,12 @@ impl CopyMemoryToAccelerationStructureInfo {
|
||||
})?;
|
||||
|
||||
if !matches!(mode, CopyAccelerationStructureMode::Deserialize) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "mode".into(),
|
||||
problem: "is not `CopyAccelerationStructureMode::Deserialize`".into(),
|
||||
vuids: &["VUID-VkCopyMemoryToAccelerationStructureInfoKHR-mode-03413"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// VUID-VkCopyMemoryToAccelerationStructureInfoKHR-src-04960
|
||||
|
@ -22,7 +22,7 @@ use crate::{
|
||||
},
|
||||
DeviceAlignment,
|
||||
},
|
||||
DeviceSize, NonZeroDeviceSize,
|
||||
DeviceSize, NonZeroDeviceSize, Validated,
|
||||
};
|
||||
use crossbeam_queue::ArrayQueue;
|
||||
use std::{
|
||||
@ -355,7 +355,7 @@ where
|
||||
DeviceLayout::from_size_alignment(self.arena_size, 1).unwrap(),
|
||||
)
|
||||
.map_err(|err| match err {
|
||||
BufferAllocateError::AllocateMemory(err) => err,
|
||||
Validated::Error(BufferAllocateError::AllocateMemory(err)) => err,
|
||||
// We don't use sparse-binding, concurrent sharing or external memory, therefore the
|
||||
// other errors can't happen.
|
||||
_ => unreachable!(),
|
||||
|
@ -116,7 +116,7 @@ use crate::{
|
||||
},
|
||||
range_map::RangeMap,
|
||||
sync::{future::AccessError, AccessConflict, CurrentAccess, Sharing},
|
||||
DeviceSize, NonZeroDeviceSize, Requires, RequiresAllOf, RequiresOneOf, RuntimeError,
|
||||
DeviceSize, NonZeroDeviceSize, Requires, RequiresAllOf, RequiresOneOf, Validated,
|
||||
ValidationError, Version, VulkanError, VulkanObject,
|
||||
};
|
||||
use parking_lot::{Mutex, MutexGuard};
|
||||
@ -262,14 +262,14 @@ impl Buffer {
|
||||
/// - Panics if the chosen memory type is not host-visible.
|
||||
pub fn from_data<T>(
|
||||
allocator: &(impl MemoryAllocator + ?Sized),
|
||||
buffer_info: BufferCreateInfo,
|
||||
create_info: BufferCreateInfo,
|
||||
allocation_info: AllocationCreateInfo,
|
||||
data: T,
|
||||
) -> Result<Subbuffer<T>, BufferAllocateError>
|
||||
) -> Result<Subbuffer<T>, Validated<BufferAllocateError>>
|
||||
where
|
||||
T: BufferContents,
|
||||
{
|
||||
let buffer = Buffer::new_sized(allocator, buffer_info, allocation_info)?;
|
||||
let buffer = Buffer::new_sized(allocator, create_info, allocation_info)?;
|
||||
|
||||
{
|
||||
let mut write_guard = buffer
|
||||
@ -295,10 +295,10 @@ impl Buffer {
|
||||
/// - Panics if `iter` is empty.
|
||||
pub fn from_iter<T, I>(
|
||||
allocator: &(impl MemoryAllocator + ?Sized),
|
||||
buffer_info: BufferCreateInfo,
|
||||
create_info: BufferCreateInfo,
|
||||
allocation_info: AllocationCreateInfo,
|
||||
iter: I,
|
||||
) -> Result<Subbuffer<[T]>, BufferAllocateError>
|
||||
) -> Result<Subbuffer<[T]>, Validated<BufferAllocateError>>
|
||||
where
|
||||
T: BufferContents,
|
||||
I: IntoIterator<Item = T>,
|
||||
@ -307,7 +307,7 @@ impl Buffer {
|
||||
let iter = iter.into_iter();
|
||||
let buffer = Buffer::new_slice(
|
||||
allocator,
|
||||
buffer_info,
|
||||
create_info,
|
||||
allocation_info,
|
||||
iter.len().try_into().unwrap(),
|
||||
)?;
|
||||
@ -333,16 +333,16 @@ impl Buffer {
|
||||
/// - Panics if `buffer_info.size` is not zero.
|
||||
pub fn new_sized<T>(
|
||||
allocator: &(impl MemoryAllocator + ?Sized),
|
||||
buffer_info: BufferCreateInfo,
|
||||
create_info: BufferCreateInfo,
|
||||
allocation_info: AllocationCreateInfo,
|
||||
) -> Result<Subbuffer<T>, BufferAllocateError>
|
||||
) -> Result<Subbuffer<T>, Validated<BufferAllocateError>>
|
||||
where
|
||||
T: BufferContents,
|
||||
{
|
||||
let layout = T::LAYOUT.unwrap_sized();
|
||||
let buffer = Subbuffer::new(Buffer::new(
|
||||
allocator,
|
||||
buffer_info,
|
||||
create_info,
|
||||
allocation_info,
|
||||
layout,
|
||||
)?);
|
||||
@ -359,14 +359,14 @@ impl Buffer {
|
||||
/// - Panics if `len` is zero.
|
||||
pub fn new_slice<T>(
|
||||
allocator: &(impl MemoryAllocator + ?Sized),
|
||||
buffer_info: BufferCreateInfo,
|
||||
create_info: BufferCreateInfo,
|
||||
allocation_info: AllocationCreateInfo,
|
||||
len: DeviceSize,
|
||||
) -> Result<Subbuffer<[T]>, BufferAllocateError>
|
||||
) -> Result<Subbuffer<[T]>, Validated<BufferAllocateError>>
|
||||
where
|
||||
T: BufferContents,
|
||||
{
|
||||
Buffer::new_unsized(allocator, buffer_info, allocation_info, len)
|
||||
Buffer::new_unsized(allocator, create_info, allocation_info, len)
|
||||
}
|
||||
|
||||
/// Creates a new uninitialized `Buffer` for unsized data. Returns a [`Subbuffer`] spanning the
|
||||
@ -378,10 +378,10 @@ impl Buffer {
|
||||
/// - Panics if `len` is zero.
|
||||
pub fn new_unsized<T>(
|
||||
allocator: &(impl MemoryAllocator + ?Sized),
|
||||
buffer_info: BufferCreateInfo,
|
||||
create_info: BufferCreateInfo,
|
||||
allocation_info: AllocationCreateInfo,
|
||||
len: DeviceSize,
|
||||
) -> Result<Subbuffer<T>, BufferAllocateError>
|
||||
) -> Result<Subbuffer<T>, Validated<BufferAllocateError>>
|
||||
where
|
||||
T: BufferContents + ?Sized,
|
||||
{
|
||||
@ -389,7 +389,7 @@ impl Buffer {
|
||||
let layout = T::LAYOUT.layout_for_len(len).unwrap();
|
||||
let buffer = Subbuffer::new(Buffer::new(
|
||||
allocator,
|
||||
buffer_info,
|
||||
create_info,
|
||||
allocation_info,
|
||||
layout,
|
||||
)?);
|
||||
@ -405,24 +405,27 @@ impl Buffer {
|
||||
/// - Panics if `layout.alignment()` is greater than 64.
|
||||
pub fn new(
|
||||
allocator: &(impl MemoryAllocator + ?Sized),
|
||||
mut buffer_info: BufferCreateInfo,
|
||||
mut create_info: BufferCreateInfo,
|
||||
allocation_info: AllocationCreateInfo,
|
||||
layout: DeviceLayout,
|
||||
) -> Result<Arc<Self>, BufferAllocateError> {
|
||||
) -> Result<Arc<Self>, Validated<BufferAllocateError>> {
|
||||
assert!(layout.alignment().as_devicesize() <= 64);
|
||||
// TODO: Enable once sparse binding materializes
|
||||
// assert!(!allocate_info.flags.contains(BufferCreateFlags::SPARSE_BINDING));
|
||||
|
||||
assert!(
|
||||
buffer_info.size == 0,
|
||||
create_info.size == 0,
|
||||
"`Buffer::new*` functions set the `buffer_info.size` field themselves, you should not \
|
||||
set it yourself",
|
||||
);
|
||||
|
||||
buffer_info.size = layout.size();
|
||||
create_info.size = layout.size();
|
||||
|
||||
let raw_buffer = RawBuffer::new(allocator.device().clone(), buffer_info)
|
||||
.map_err(BufferAllocateError::CreateBuffer)?;
|
||||
let raw_buffer =
|
||||
RawBuffer::new(allocator.device().clone(), create_info).map_err(|err| match err {
|
||||
Validated::Error(err) => Validated::Error(BufferAllocateError::CreateBuffer(err)),
|
||||
Validated::ValidationError(err) => err.into(),
|
||||
})?;
|
||||
let mut requirements = *raw_buffer.memory_requirements();
|
||||
requirements.layout = requirements.layout.align_to(layout.alignment()).unwrap();
|
||||
|
||||
@ -448,7 +451,7 @@ impl Buffer {
|
||||
|
||||
unsafe { raw_buffer.bind_memory_unchecked(allocation) }
|
||||
.map(Arc::new)
|
||||
.map_err(|(err, _, _)| BufferAllocateError::BindMemory(err))
|
||||
.map_err(|(err, _, _)| BufferAllocateError::BindMemory(err).into())
|
||||
}
|
||||
|
||||
fn from_raw(inner: RawBuffer, memory: BufferMemory) -> Self {
|
||||
@ -505,32 +508,32 @@ impl Buffer {
|
||||
|
||||
/// Returns the device address for this buffer.
|
||||
// TODO: Caching?
|
||||
pub fn device_address(&self) -> Result<NonZeroDeviceSize, ValidationError> {
|
||||
pub fn device_address(&self) -> Result<NonZeroDeviceSize, Box<ValidationError>> {
|
||||
self.validate_device_address()?;
|
||||
|
||||
unsafe { Ok(self.device_address_unchecked()) }
|
||||
}
|
||||
|
||||
fn validate_device_address(&self) -> Result<(), ValidationError> {
|
||||
fn validate_device_address(&self) -> Result<(), Box<ValidationError>> {
|
||||
let device = self.device();
|
||||
|
||||
if !device.enabled_features().buffer_device_address {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"buffer_device_address",
|
||||
)])]),
|
||||
vuids: &["VUID-vkGetBufferDeviceAddress-bufferDeviceAddress-03324"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if !self.usage().intersects(BufferUsage::SHADER_DEVICE_ADDRESS) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "self.usage()".into(),
|
||||
problem: "does not contain `BufferUsage::SHADER_DEVICE_ADDRESS`".into(),
|
||||
vuids: &["VUID-VkBufferDeviceAddressInfo-buffer-02601"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -601,7 +604,7 @@ impl Hash for Buffer {
|
||||
pub enum BufferAllocateError {
|
||||
CreateBuffer(VulkanError),
|
||||
AllocateMemory(MemoryAllocatorError),
|
||||
BindMemory(RuntimeError),
|
||||
BindMemory(VulkanError),
|
||||
}
|
||||
|
||||
impl Error for BufferAllocateError {
|
||||
@ -624,6 +627,12 @@ impl Display for BufferAllocateError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BufferAllocateError> for Validated<BufferAllocateError> {
|
||||
fn from(err: BufferAllocateError) -> Self {
|
||||
Self::Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
/// The current state of a buffer.
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct BufferState {
|
||||
@ -915,7 +924,10 @@ impl ExternalBufferInfo {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn validate(&self, physical_device: &PhysicalDevice) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(
|
||||
&self,
|
||||
physical_device: &PhysicalDevice,
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
handle_type,
|
||||
usage,
|
||||
@ -932,12 +944,12 @@ impl ExternalBufferInfo {
|
||||
})?;
|
||||
|
||||
if usage.is_empty() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "usage".into(),
|
||||
problem: "is empty".into(),
|
||||
vuids: &["VUID-VkPhysicalDeviceExternalBufferInfo-usage-requiredbitmask"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
handle_type
|
||||
|
@ -134,7 +134,7 @@ impl<T: ?Sized> Subbuffer<T> {
|
||||
}
|
||||
|
||||
/// Returns the device address for this subbuffer.
|
||||
pub fn device_address(&self) -> Result<NonZeroDeviceSize, ValidationError> {
|
||||
pub fn device_address(&self) -> Result<NonZeroDeviceSize, Box<ValidationError>> {
|
||||
self.buffer().device_address().map(|ptr| {
|
||||
// SAFETY: The original address came from the Vulkan implementation, and allocation
|
||||
// sizes are guaranteed to not exceed `DeviceLayout::MAX_SIZE`, so the offset better be
|
||||
|
@ -24,7 +24,7 @@ use crate::{
|
||||
MemoryPropertyFlags, MemoryRequirements,
|
||||
},
|
||||
sync::Sharing,
|
||||
DeviceSize, Requires, RequiresAllOf, RequiresOneOf, RuntimeError, ValidationError, Version,
|
||||
DeviceSize, Requires, RequiresAllOf, RequiresOneOf, Validated, ValidationError, Version,
|
||||
VulkanError, VulkanObject,
|
||||
};
|
||||
use smallvec::SmallVec;
|
||||
@ -60,7 +60,10 @@ impl RawBuffer {
|
||||
/// - Panics if `create_info.size` is zero.
|
||||
/// - Panics if `create_info.usage` is empty.
|
||||
#[inline]
|
||||
pub fn new(device: Arc<Device>, create_info: BufferCreateInfo) -> Result<Self, VulkanError> {
|
||||
pub fn new(
|
||||
device: Arc<Device>,
|
||||
create_info: BufferCreateInfo,
|
||||
) -> Result<Self, Validated<VulkanError>> {
|
||||
Self::validate_new(&device, &create_info)?;
|
||||
|
||||
unsafe { Ok(Self::new_unchecked(device, create_info)?) }
|
||||
@ -69,7 +72,7 @@ impl RawBuffer {
|
||||
fn validate_new(
|
||||
device: &Device,
|
||||
create_info: &BufferCreateInfo,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
create_info
|
||||
.validate(device)
|
||||
.map_err(|err| err.add_context("create_info"))?;
|
||||
@ -81,7 +84,7 @@ impl RawBuffer {
|
||||
pub unsafe fn new_unchecked(
|
||||
device: Arc<Device>,
|
||||
create_info: BufferCreateInfo,
|
||||
) -> Result<Self, RuntimeError> {
|
||||
) -> Result<Self, VulkanError> {
|
||||
let &BufferCreateInfo {
|
||||
flags,
|
||||
ref sharing,
|
||||
@ -133,7 +136,7 @@ impl RawBuffer {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
};
|
||||
|
||||
@ -274,7 +277,7 @@ impl RawBuffer {
|
||||
pub fn bind_memory(
|
||||
self,
|
||||
allocation: MemoryAlloc,
|
||||
) -> Result<Buffer, (VulkanError, RawBuffer, MemoryAlloc)> {
|
||||
) -> Result<Buffer, (Validated<VulkanError>, RawBuffer, MemoryAlloc)> {
|
||||
if let Err(err) = self.validate_bind_memory(&allocation) {
|
||||
return Err((err.into(), self, allocation));
|
||||
}
|
||||
@ -283,7 +286,7 @@ impl RawBuffer {
|
||||
.map_err(|(err, buffer, allocation)| (err.into(), buffer, allocation))
|
||||
}
|
||||
|
||||
fn validate_bind_memory(&self, allocation: &MemoryAlloc) -> Result<(), ValidationError> {
|
||||
fn validate_bind_memory(&self, allocation: &MemoryAlloc) -> Result<(), Box<ValidationError>> {
|
||||
assert_ne!(allocation.allocation_type(), AllocationType::NonLinear);
|
||||
|
||||
let memory_requirements = &self.memory_requirements;
|
||||
@ -309,58 +312,58 @@ impl RawBuffer {
|
||||
// Assume that `allocation` was created correctly.
|
||||
|
||||
if memory_requirements.memory_type_bits & (1 << memory.memory_type_index()) == 0 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`allocation.device_memory().memory_type_index()` is not a bit set in \
|
||||
`self.memory_requirements().memory_type_bits`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkBindBufferMemoryInfo-memory-01035"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if !is_aligned(memory_offset, memory_requirements.layout.alignment()) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`allocation.offset()` is not aligned according to \
|
||||
`self.memory_requirements().layout.alignment()`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkBindBufferMemoryInfo-memoryOffset-01036"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if allocation.size() < memory_requirements.layout.size() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`allocation.size()` is less than \
|
||||
`self.memory_requirements().layout.size()`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkBindBufferMemoryInfo-size-01037"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if let Some(dedicated_to) = memory.dedicated_to() {
|
||||
match dedicated_to {
|
||||
DedicatedTo::Buffer(id) if id == self.id => {}
|
||||
_ => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`allocation.device_memory()` is a dedicated allocation, but \
|
||||
it is not dedicated to this buffer"
|
||||
.into(),
|
||||
vuids: &["VUID-VkBindBufferMemoryInfo-memory-01508"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
debug_assert!(memory_offset == 0); // This should be ensured by the allocator
|
||||
} else {
|
||||
if memory_requirements.requires_dedicated_allocation {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`self.memory_requirements().requires_dedicated_allocation` is \
|
||||
`true`, but `allocation.device_memory()` is not a dedicated allocation"
|
||||
.into(),
|
||||
vuids: &["VUID-VkBindBufferMemoryInfo-buffer-01444"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -368,13 +371,13 @@ impl RawBuffer {
|
||||
.property_flags
|
||||
.intersects(MemoryPropertyFlags::PROTECTED)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the `property_flags` of the memory type of \
|
||||
`allocation.device_memory()` contains `MemoryPropertyFlags::PROTECTED`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkBindBufferMemoryInfo-None-01899"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if !memory.export_handle_types().is_empty()
|
||||
@ -382,26 +385,26 @@ impl RawBuffer {
|
||||
.external_memory_handle_types
|
||||
.intersects(memory.export_handle_types())
|
||||
{
|
||||
return Err(ValidationError {
|
||||
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()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if let Some(handle_type) = memory.imported_handle_type() {
|
||||
if !self.external_memory_handle_types.contains_enum(handle_type) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`allocation.device_memory()` is imported, but \
|
||||
`self.external_memory_handle_types()` does not contain the imported \
|
||||
handle type"
|
||||
.into(),
|
||||
vuids: &["VUID-VkBindBufferMemoryInfo-memory-02985"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -411,14 +414,14 @@ impl RawBuffer {
|
||||
.flags()
|
||||
.intersects(MemoryAllocateFlags::DEVICE_ADDRESS)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`self.usage()` contains `BufferUsage::SHADER_DEVICE_ADDRESS`, but \
|
||||
`allocation.device_memory().flags()` does not contain \
|
||||
`MemoryAllocateFlags::DEVICE_ADDRESS`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkBindBufferMemoryInfo-bufferDeviceAddress-03339"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -428,7 +431,7 @@ impl RawBuffer {
|
||||
pub unsafe fn bind_memory_unchecked(
|
||||
self,
|
||||
allocation: MemoryAlloc,
|
||||
) -> Result<Buffer, (RuntimeError, RawBuffer, MemoryAlloc)> {
|
||||
) -> Result<Buffer, (VulkanError, RawBuffer, MemoryAlloc)> {
|
||||
let memory = allocation.device_memory();
|
||||
let memory_offset = allocation.offset();
|
||||
|
||||
@ -468,7 +471,7 @@ impl RawBuffer {
|
||||
.result();
|
||||
|
||||
if let Err(err) = result {
|
||||
return Err((RuntimeError::from(err), self, allocation));
|
||||
return Err((VulkanError::from(err), self, allocation));
|
||||
}
|
||||
|
||||
Ok(Buffer::from_raw(self, BufferMemory::Normal(allocation)))
|
||||
@ -594,7 +597,7 @@ impl Default for BufferCreateInfo {
|
||||
}
|
||||
|
||||
impl BufferCreateInfo {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
flags,
|
||||
ref sharing,
|
||||
@ -621,56 +624,56 @@ impl BufferCreateInfo {
|
||||
})?;
|
||||
|
||||
if usage.is_empty() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "usage".into(),
|
||||
problem: "is empty".into(),
|
||||
vuids: &["VUID-VkBufferCreateInfo-usage-requiredbitmask"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if size == 0 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "size".into(),
|
||||
problem: "is zero".into(),
|
||||
vuids: &["VUID-VkBufferCreateInfo-size-00912"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
/* Enable when sparse binding is properly handled
|
||||
if let Some(sparse_level) = sparse {
|
||||
if !device.enabled_features().sparse_binding {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "sparse".into(),
|
||||
problem: "is `Some`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"sparse_binding",
|
||||
)])]),
|
||||
vuids: &["VUID-VkBufferCreateInfo-flags-00915"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if sparse_level.sparse_residency && !device.enabled_features().sparse_residency_buffer {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "sparse".into(),
|
||||
problem: "contains `BufferCreateFlags::SPARSE_RESIDENCY`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"sparse_residency_buffer",
|
||||
)])]),
|
||||
vuids: &["VUID-VkBufferCreateInfo-flags-00916"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if sparse_level.sparse_aliased && !device.enabled_features().sparse_residency_aliased {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "sparse".into(),
|
||||
problem: "contains `BufferCreateFlags::SPARSE_ALIASED`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"sparse_residency_aliased",
|
||||
)])]),
|
||||
vuids: &["VUID-VkBufferCreateInfo-flags-00917"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// TODO:
|
||||
@ -681,13 +684,13 @@ impl BufferCreateInfo {
|
||||
Sharing::Exclusive => (),
|
||||
Sharing::Concurrent(queue_family_indices) => {
|
||||
if queue_family_indices.len() < 2 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "sharing".into(),
|
||||
problem: "is `Sharing::Concurrent`, but contains less than 2 elements"
|
||||
.into(),
|
||||
vuids: &["VUID-VkBufferCreateInfo-sharingMode-00914"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
let queue_family_count =
|
||||
@ -695,7 +698,7 @@ impl BufferCreateInfo {
|
||||
|
||||
for (index, &queue_family_index) in queue_family_indices.iter().enumerate() {
|
||||
if queue_family_indices[..index].contains(&queue_family_index) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "queue_family_indices".into(),
|
||||
problem: format!(
|
||||
"the queue family index in the list at index {} is contained in \
|
||||
@ -705,17 +708,17 @@ impl BufferCreateInfo {
|
||||
.into(),
|
||||
vuids: &["VUID-VkBufferCreateInfo-sharingMode-01419"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if queue_family_index >= queue_family_count {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("sharing[{}]", index).into(),
|
||||
problem: "is not less than the number of queue families in the device"
|
||||
.into(),
|
||||
vuids: &["VUID-VkBufferCreateInfo-sharingMode-01419"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -723,12 +726,12 @@ impl BufferCreateInfo {
|
||||
|
||||
if let Some(max_buffer_size) = device.physical_device().properties().max_buffer_size {
|
||||
if size > max_buffer_size {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "size".into(),
|
||||
problem: "exceeds the `max_buffer_size` limit".into(),
|
||||
vuids: &["VUID-VkBufferCreateInfo-size-06409"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -736,7 +739,7 @@ impl BufferCreateInfo {
|
||||
if !(device.api_version() >= Version::V1_1
|
||||
|| device.enabled_extensions().khr_external_memory)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "external_memory_handle_types".into(),
|
||||
problem: "is not empty".into(),
|
||||
requires_one_of: RequiresOneOf(&[
|
||||
@ -744,7 +747,7 @@ impl BufferCreateInfo {
|
||||
RequiresAllOf(&[Requires::DeviceExtension("khr_external_memory")]),
|
||||
]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
external_memory_handle_types
|
||||
|
@ -53,7 +53,7 @@ use crate::{
|
||||
format::{Format, FormatFeatures},
|
||||
macros::impl_id_counter,
|
||||
memory::{is_aligned, DeviceAlignment},
|
||||
DeviceSize, RuntimeError, ValidationError, Version, VulkanError, VulkanObject,
|
||||
DeviceSize, Validated, ValidationError, Version, VulkanError, VulkanObject,
|
||||
};
|
||||
use std::{mem::MaybeUninit, num::NonZeroU64, ops::Range, ptr, sync::Arc};
|
||||
|
||||
@ -76,7 +76,7 @@ impl BufferView {
|
||||
pub fn new(
|
||||
subbuffer: Subbuffer<impl ?Sized>,
|
||||
create_info: BufferViewCreateInfo,
|
||||
) -> Result<Arc<BufferView>, VulkanError> {
|
||||
) -> Result<Arc<BufferView>, Validated<VulkanError>> {
|
||||
let subbuffer = subbuffer.into_bytes();
|
||||
Self::validate_new(&subbuffer, &create_info)?;
|
||||
|
||||
@ -86,7 +86,7 @@ impl BufferView {
|
||||
fn validate_new(
|
||||
subbuffer: &Subbuffer<[u8]>,
|
||||
create_info: &BufferViewCreateInfo,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
let device = subbuffer.device();
|
||||
|
||||
create_info
|
||||
@ -110,66 +110,66 @@ impl BufferView {
|
||||
.usage()
|
||||
.intersects(BufferUsage::UNIFORM_TEXEL_BUFFER | BufferUsage::STORAGE_TEXEL_BUFFER)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "subbuffer".into(),
|
||||
problem: "was not created with the `BufferUsage::UNIFORM_TEXEL_BUFFER` \
|
||||
or `BufferUsage::STORAGE_TEXEL_BUFFER` usage"
|
||||
.into(),
|
||||
vuids: &["VUID-VkBufferViewCreateInfo-buffer-00932"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if buffer.usage().intersects(BufferUsage::UNIFORM_TEXEL_BUFFER)
|
||||
&& !format_features.intersects(FormatFeatures::UNIFORM_TEXEL_BUFFER)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`subbuffer` was created with the `BufferUsage::UNIFORM_TEXEL_BUFFER` \
|
||||
usage, but the format features of `create_info.format` do not include \
|
||||
`FormatFeatures::UNIFORM_TEXEL_BUFFER`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkBufferViewCreateInfo-buffer-00933"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if buffer.usage().intersects(BufferUsage::STORAGE_TEXEL_BUFFER)
|
||||
&& !format_features.intersects(FormatFeatures::STORAGE_TEXEL_BUFFER)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`subbuffer` was created with the `BufferUsage::STORAGE_TEXEL_BUFFER` \
|
||||
usage, but the format features of `create_info.format` do not include \
|
||||
`FormatFeatures::STORAGE_TEXEL_BUFFER`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkBufferViewCreateInfo-buffer-00934"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
let block_size = format.block_size().unwrap();
|
||||
let texels_per_block = format.texels_per_block();
|
||||
|
||||
if subbuffer.size() % block_size != 0 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`subbuffer.size()` is not a multiple of \
|
||||
`create_info.format.block_size()`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkBufferViewCreateInfo-range-00929"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if ((subbuffer.size() / block_size) * texels_per_block as DeviceSize) as u32
|
||||
> properties.max_texel_buffer_elements
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`subbuffer.size() / create_info.format.block_size() * \
|
||||
create_info.format.texels_per_block()` is greater than the \
|
||||
`max_texel_buffer_elements` limit"
|
||||
.into(),
|
||||
vuids: &["VUID-VkBufferViewCreateInfo-range-00930"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if device.api_version() >= Version::V1_3 || device.enabled_features().texel_buffer_alignment
|
||||
@ -193,7 +193,7 @@ impl BufferView {
|
||||
.unwrap()
|
||||
.min(element_size),
|
||||
) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`subbuffer` was created with the \
|
||||
`BufferUsage::STORAGE_TEXEL_BUFFER` usage, and the \
|
||||
`storage_texel_buffer_offset_single_texel_alignment` \
|
||||
@ -204,7 +204,7 @@ impl BufferView {
|
||||
.into(),
|
||||
vuids: &["VUID-VkBufferViewCreateInfo-buffer-02750"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
} else {
|
||||
if !is_aligned(
|
||||
@ -213,7 +213,7 @@ impl BufferView {
|
||||
.storage_texel_buffer_offset_alignment_bytes
|
||||
.unwrap(),
|
||||
) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`subbuffer` was created with the \
|
||||
`BufferUsage::STORAGE_TEXEL_BUFFER` usage, and the \
|
||||
`storage_texel_buffer_offset_single_texel_alignment` \
|
||||
@ -223,7 +223,7 @@ impl BufferView {
|
||||
.into(),
|
||||
vuids: &["VUID-VkBufferViewCreateInfo-buffer-02750"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -240,7 +240,7 @@ impl BufferView {
|
||||
.unwrap()
|
||||
.min(element_size),
|
||||
) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`subbuffer` was created with the \
|
||||
`BufferUsage::UNIFORM_TEXEL_BUFFER` usage, and the \
|
||||
`uniform_texel_buffer_offset_single_texel_alignment` \
|
||||
@ -251,7 +251,7 @@ impl BufferView {
|
||||
.into(),
|
||||
vuids: &["VUID-VkBufferViewCreateInfo-buffer-02751"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
} else {
|
||||
if !is_aligned(
|
||||
@ -260,7 +260,7 @@ impl BufferView {
|
||||
.uniform_texel_buffer_offset_alignment_bytes
|
||||
.unwrap(),
|
||||
) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`subbuffer` was created with the \
|
||||
`BufferUsage::UNIFORM_TEXEL_BUFFER` usage, and the \
|
||||
`uniform_texel_buffer_offset_single_texel_alignment` \
|
||||
@ -270,7 +270,7 @@ impl BufferView {
|
||||
.into(),
|
||||
vuids: &["VUID-VkBufferViewCreateInfo-buffer-02751"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -279,13 +279,13 @@ impl BufferView {
|
||||
subbuffer.offset(),
|
||||
properties.min_texel_buffer_offset_alignment,
|
||||
) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`subbuffer.offset()` is not a multiple of the \
|
||||
`min_texel_buffer_offset_alignment` limit"
|
||||
.into(),
|
||||
vuids: &["VUID-VkBufferViewCreateInfo-offset-02749"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -296,7 +296,7 @@ impl BufferView {
|
||||
pub unsafe fn new_unchecked(
|
||||
subbuffer: Subbuffer<impl ?Sized>,
|
||||
create_info: BufferViewCreateInfo,
|
||||
) -> Result<Arc<BufferView>, RuntimeError> {
|
||||
) -> Result<Arc<BufferView>, VulkanError> {
|
||||
let &BufferViewCreateInfo { format, _ne: _ } = &create_info;
|
||||
|
||||
let device = subbuffer.device();
|
||||
@ -320,7 +320,7 @@ impl BufferView {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
};
|
||||
|
||||
@ -438,7 +438,7 @@ impl Default for BufferViewCreateInfo {
|
||||
}
|
||||
|
||||
impl BufferViewCreateInfo {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let Self { format, _ne: _ } = self;
|
||||
|
||||
let format = format.ok_or(ValidationError {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -766,14 +766,14 @@ where
|
||||
pipeline_layout: &PipelineLayout,
|
||||
set_num: u32,
|
||||
descriptor_writes: &[WriteDescriptorSet],
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
if !self.device().enabled_extensions().khr_push_descriptor {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::DeviceExtension(
|
||||
"khr_push_descriptor",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
pipeline_bind_point
|
||||
@ -792,7 +792,7 @@ where
|
||||
.queue_flags
|
||||
.intersects(QueueFlags::COMPUTE)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "self".into(),
|
||||
problem: "`pipeline_bind_point` is `PipelineBindPoint::Compute`, and the \
|
||||
queue family does not support compute operations"
|
||||
@ -802,7 +802,7 @@ where
|
||||
"VUID-vkCmdPushDescriptorSetKHR-commandBuffer-cmdpool",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
PipelineBindPoint::Graphics => {
|
||||
@ -810,7 +810,7 @@ where
|
||||
.queue_flags
|
||||
.intersects(QueueFlags::GRAPHICS)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "self".into(),
|
||||
problem: "`pipeline_bind_point` is `PipelineBindPoint::Graphics`, and the \
|
||||
queue family does not support graphics operations"
|
||||
@ -820,7 +820,7 @@ where
|
||||
"VUID-vkCmdPushDescriptorSetKHR-commandBuffer-cmdpool",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -829,13 +829,13 @@ where
|
||||
assert_eq!(self.device(), pipeline_layout.device());
|
||||
|
||||
if set_num as usize > pipeline_layout.set_layouts().len() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`set_num` is greater than the number of descriptor set layouts in \
|
||||
`pipeline_layout`"
|
||||
.into(),
|
||||
vuids: &["VUID-vkCmdPushDescriptorSetKHR-set-00364"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
let descriptor_set_layout = &pipeline_layout.set_layouts()[set_num as usize];
|
||||
@ -844,14 +844,14 @@ where
|
||||
.flags()
|
||||
.intersects(DescriptorSetLayoutCreateFlags::PUSH_DESCRIPTOR)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the descriptor set layout with the number `set_num` in \
|
||||
`pipeline_layout` was not created with the \
|
||||
`DescriptorSetLayoutCreateFlags::PUSH_DESCRIPTOR` flag"
|
||||
.into(),
|
||||
vuids: &["VUID-vkCmdPushDescriptorSetKHR-set-00365"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
for (index, write) in descriptor_writes.iter().enumerate() {
|
||||
|
@ -2675,7 +2675,7 @@ pub enum DescriptorResourceInvalidError {
|
||||
image_view_set_num: u32,
|
||||
image_view_binding_num: u32,
|
||||
image_view_index: u32,
|
||||
error: ValidationError,
|
||||
error: Box<ValidationError>,
|
||||
},
|
||||
SamplerUnnormalizedCoordinatesNotAllowed,
|
||||
SamplerYcbcrConversionNotAllowed,
|
||||
|
@ -20,7 +20,7 @@ use crate::{
|
||||
device::{Device, DeviceOwned},
|
||||
instance::InstanceOwnedDebugWrapper,
|
||||
macros::impl_id_counter,
|
||||
OomError, Requires, RequiresAllOf, RequiresOneOf, RuntimeError, Version, VulkanObject,
|
||||
OomError, Requires, RequiresAllOf, RequiresOneOf, Version, VulkanError, VulkanObject,
|
||||
};
|
||||
use smallvec::SmallVec;
|
||||
use std::{
|
||||
@ -170,7 +170,7 @@ impl CommandPool {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
};
|
||||
|
||||
@ -196,7 +196,7 @@ impl CommandPool {
|
||||
let fns = self.device.fns();
|
||||
(fns.v1_0.reset_command_pool)(self.device.handle(), self.handle, flags)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -233,7 +233,7 @@ impl CommandPool {
|
||||
out.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
out.set_len(command_buffer_count as usize);
|
||||
out
|
||||
}
|
||||
@ -390,10 +390,10 @@ impl Display for CommandPoolCreationError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RuntimeError> for CommandPoolCreationError {
|
||||
fn from(err: RuntimeError) -> Self {
|
||||
impl From<VulkanError> for CommandPoolCreationError {
|
||||
fn from(err: VulkanError) -> Self {
|
||||
match err {
|
||||
err @ RuntimeError::OutOfHostMemory => Self::OomError(OomError::from(err)),
|
||||
err @ VulkanError::OutOfHostMemory => Self::OomError(OomError::from(err)),
|
||||
_ => panic!("unexpected error: {:?}", err),
|
||||
}
|
||||
}
|
||||
@ -522,8 +522,8 @@ impl Display for CommandPoolTrimError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RuntimeError> for CommandPoolTrimError {
|
||||
fn from(err: RuntimeError) -> CommandPoolTrimError {
|
||||
impl From<VulkanError> for CommandPoolTrimError {
|
||||
fn from(err: VulkanError) -> CommandPoolTrimError {
|
||||
panic!("unexpected error: {:?}", err)
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ use crate::{
|
||||
},
|
||||
device::{Device, DeviceOwned},
|
||||
query::QueryControlFlags,
|
||||
OomError, RuntimeError, VulkanObject,
|
||||
OomError, VulkanError, VulkanObject,
|
||||
};
|
||||
use smallvec::SmallVec;
|
||||
use std::{fmt::Debug, ptr, sync::Arc};
|
||||
@ -173,7 +173,7 @@ where
|
||||
let fns = builder_alloc.device().fns();
|
||||
(fns.v1_0.begin_command_buffer)(builder_alloc.inner().handle(), &begin_info_vk)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
}
|
||||
|
||||
Ok(UnsafeCommandBufferBuilder {
|
||||
@ -191,7 +191,7 @@ where
|
||||
let fns = self.device().fns();
|
||||
(fns.v1_0.end_command_buffer)(self.handle())
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
Ok(UnsafeCommandBuffer {
|
||||
alloc: self.builder_alloc.into_alloc(),
|
||||
|
@ -19,7 +19,7 @@
|
||||
use crate::{
|
||||
device::{Device, DeviceOwned},
|
||||
instance::InstanceOwnedDebugWrapper,
|
||||
Requires, RequiresAllOf, RequiresOneOf, RuntimeError, VulkanObject,
|
||||
Requires, RequiresAllOf, RequiresOneOf, VulkanError, VulkanObject,
|
||||
};
|
||||
use std::{
|
||||
error::Error,
|
||||
@ -66,7 +66,7 @@ impl DeferredOperation {
|
||||
}
|
||||
|
||||
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
||||
pub unsafe fn new_unchecked(device: Arc<Device>) -> Result<Arc<Self>, RuntimeError> {
|
||||
pub unsafe fn new_unchecked(device: Arc<Device>) -> Result<Arc<Self>, VulkanError> {
|
||||
let handle = {
|
||||
let fns = device.fns();
|
||||
let mut output = MaybeUninit::uninit();
|
||||
@ -75,7 +75,7 @@ impl DeferredOperation {
|
||||
device.handle(), ptr::null(), output.as_mut_ptr()
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
};
|
||||
|
||||
@ -99,7 +99,7 @@ impl DeferredOperation {
|
||||
}
|
||||
|
||||
/// Executes a portion of the operation on the current thread.
|
||||
pub fn join(&self) -> Result<DeferredOperationJoinStatus, RuntimeError> {
|
||||
pub fn join(&self) -> Result<DeferredOperationJoinStatus, VulkanError> {
|
||||
let result = unsafe {
|
||||
let fns = self.device.fns();
|
||||
(fns.khr_deferred_host_operations.deferred_operation_join_khr)(
|
||||
@ -112,12 +112,12 @@ impl DeferredOperation {
|
||||
ash::vk::Result::SUCCESS => Ok(DeferredOperationJoinStatus::Complete),
|
||||
ash::vk::Result::THREAD_DONE_KHR => Ok(DeferredOperationJoinStatus::ThreadDone),
|
||||
ash::vk::Result::THREAD_IDLE_KHR => Ok(DeferredOperationJoinStatus::ThreadIdle),
|
||||
err => Err(RuntimeError::from(err)),
|
||||
err => Err(VulkanError::from(err)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the result of the operation, or `None` if the operation is not yet complete.
|
||||
pub fn result(&self) -> Option<Result<(), RuntimeError>> {
|
||||
pub fn result(&self) -> Option<Result<(), VulkanError>> {
|
||||
let result = unsafe {
|
||||
let fns = self.device.fns();
|
||||
(fns.khr_deferred_host_operations
|
||||
@ -127,12 +127,12 @@ impl DeferredOperation {
|
||||
match result {
|
||||
ash::vk::Result::NOT_READY => None,
|
||||
ash::vk::Result::SUCCESS => Some(Ok(())),
|
||||
err => Some(Err(RuntimeError::from(err))),
|
||||
err => Some(Err(VulkanError::from(err))),
|
||||
}
|
||||
}
|
||||
|
||||
/// Waits for the operation to complete, then returns its result.
|
||||
pub fn wait(&self) -> Result<Result<(), RuntimeError>, RuntimeError> {
|
||||
pub fn wait(&self) -> Result<Result<(), VulkanError>, VulkanError> {
|
||||
// Based on example code on the extension's spec page.
|
||||
|
||||
// Call `join` until we get `Complete` or `ThreadDone`.
|
||||
@ -210,7 +210,7 @@ unsafe impl DeviceOwned for DeferredOperation {
|
||||
/// Error that can happen when creating a `DeferredOperation`.
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum DeferredOperationCreateError {
|
||||
RuntimeError(RuntimeError),
|
||||
VulkanError(VulkanError),
|
||||
|
||||
RequirementNotMet {
|
||||
required_for: &'static str,
|
||||
@ -221,7 +221,7 @@ pub enum DeferredOperationCreateError {
|
||||
impl Display for DeferredOperationCreateError {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::RuntimeError(_) => write!(f, "a runtime error occurred"),
|
||||
Self::VulkanError(_) => write!(f, "a runtime error occurred"),
|
||||
Self::RequirementNotMet {
|
||||
required_for,
|
||||
requires_one_of,
|
||||
@ -237,15 +237,15 @@ impl Display for DeferredOperationCreateError {
|
||||
impl Error for DeferredOperationCreateError {
|
||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||
match self {
|
||||
Self::RuntimeError(err) => Some(err),
|
||||
Self::VulkanError(err) => Some(err),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RuntimeError> for DeferredOperationCreateError {
|
||||
fn from(err: RuntimeError) -> Self {
|
||||
Self::RuntimeError(err)
|
||||
impl From<VulkanError> for DeferredOperationCreateError {
|
||||
fn from(err: VulkanError) -> Self {
|
||||
Self::VulkanError(err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ use crate::{
|
||||
descriptor_set::layout::{DescriptorSetLayoutCreateFlags, DescriptorType},
|
||||
device::{Device, DeviceOwned},
|
||||
instance::InstanceOwnedDebugWrapper,
|
||||
RuntimeError, VulkanError,
|
||||
Validated, VulkanError,
|
||||
};
|
||||
use crossbeam_queue::ArrayQueue;
|
||||
use std::{cell::UnsafeCell, mem::ManuallyDrop, num::NonZeroU64, sync::Arc, thread};
|
||||
@ -60,7 +60,7 @@ pub unsafe trait DescriptorSetAllocator: DeviceOwned {
|
||||
&self,
|
||||
layout: &Arc<DescriptorSetLayout>,
|
||||
variable_descriptor_count: u32,
|
||||
) -> Result<Self::Alloc, RuntimeError>;
|
||||
) -> Result<Self::Alloc, VulkanError>;
|
||||
}
|
||||
|
||||
/// An allocated descriptor set.
|
||||
@ -154,7 +154,7 @@ unsafe impl DescriptorSetAllocator for StandardDescriptorSetAllocator {
|
||||
&self,
|
||||
layout: &Arc<DescriptorSetLayout>,
|
||||
variable_descriptor_count: u32,
|
||||
) -> Result<StandardDescriptorSetAlloc, RuntimeError> {
|
||||
) -> Result<StandardDescriptorSetAlloc, VulkanError> {
|
||||
assert!(
|
||||
!layout
|
||||
.flags()
|
||||
@ -197,7 +197,7 @@ unsafe impl DescriptorSetAllocator for Arc<StandardDescriptorSetAllocator> {
|
||||
&self,
|
||||
layout: &Arc<DescriptorSetLayout>,
|
||||
variable_descriptor_count: u32,
|
||||
) -> Result<Self::Alloc, RuntimeError> {
|
||||
) -> Result<Self::Alloc, VulkanError> {
|
||||
(**self).allocate(layout, variable_descriptor_count)
|
||||
}
|
||||
}
|
||||
@ -221,7 +221,7 @@ struct FixedEntry {
|
||||
}
|
||||
|
||||
impl FixedEntry {
|
||||
fn new(layout: Arc<DescriptorSetLayout>) -> Result<Self, RuntimeError> {
|
||||
fn new(layout: Arc<DescriptorSetLayout>) -> Result<Self, VulkanError> {
|
||||
Ok(FixedEntry {
|
||||
pool: FixedPool::new(&layout, MAX_SETS)?,
|
||||
set_count: MAX_SETS,
|
||||
@ -229,7 +229,7 @@ impl FixedEntry {
|
||||
})
|
||||
}
|
||||
|
||||
fn allocate(&mut self) -> Result<StandardDescriptorSetAlloc, RuntimeError> {
|
||||
fn allocate(&mut self) -> Result<StandardDescriptorSetAlloc, VulkanError> {
|
||||
let inner = if let Some(inner) = self.pool.reserve.pop() {
|
||||
inner
|
||||
} else {
|
||||
@ -257,7 +257,7 @@ struct FixedPool {
|
||||
}
|
||||
|
||||
impl FixedPool {
|
||||
fn new(layout: &Arc<DescriptorSetLayout>, set_count: usize) -> Result<Arc<Self>, RuntimeError> {
|
||||
fn new(layout: &Arc<DescriptorSetLayout>, set_count: usize) -> Result<Arc<Self>, VulkanError> {
|
||||
let inner = DescriptorPool::new(
|
||||
layout.device().clone(),
|
||||
DescriptorPoolCreateInfo {
|
||||
@ -273,7 +273,7 @@ impl FixedPool {
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
.map_err(VulkanError::unwrap_runtime)?;
|
||||
.map_err(Validated::unwrap)?;
|
||||
|
||||
let allocate_infos = (0..set_count).map(|_| DescriptorSetAllocateInfo {
|
||||
layout,
|
||||
@ -284,12 +284,12 @@ impl FixedPool {
|
||||
inner
|
||||
.allocate_descriptor_sets(allocate_infos)
|
||||
.map_err(|err| match err {
|
||||
RuntimeError::OutOfHostMemory | RuntimeError::OutOfDeviceMemory => err,
|
||||
RuntimeError::FragmentedPool => {
|
||||
VulkanError::OutOfHostMemory | VulkanError::OutOfDeviceMemory => err,
|
||||
VulkanError::FragmentedPool => {
|
||||
// This can't happen as we don't free individual sets.
|
||||
unreachable!();
|
||||
}
|
||||
RuntimeError::OutOfPoolMemory => {
|
||||
VulkanError::OutOfPoolMemory => {
|
||||
// We created the pool with an exact size.
|
||||
unreachable!();
|
||||
}
|
||||
@ -326,7 +326,7 @@ struct VariableEntry {
|
||||
}
|
||||
|
||||
impl VariableEntry {
|
||||
fn new(layout: Arc<DescriptorSetLayout>) -> Result<Self, RuntimeError> {
|
||||
fn new(layout: Arc<DescriptorSetLayout>) -> Result<Self, VulkanError> {
|
||||
let reserve = Arc::new(ArrayQueue::new(MAX_POOLS));
|
||||
|
||||
Ok(VariableEntry {
|
||||
@ -340,7 +340,7 @@ impl VariableEntry {
|
||||
fn allocate(
|
||||
&mut self,
|
||||
variable_descriptor_count: u32,
|
||||
) -> Result<StandardDescriptorSetAlloc, RuntimeError> {
|
||||
) -> Result<StandardDescriptorSetAlloc, VulkanError> {
|
||||
if self.allocations >= MAX_SETS {
|
||||
self.pool = if let Some(inner) = self.reserve.pop() {
|
||||
Arc::new(VariablePool {
|
||||
@ -363,12 +363,12 @@ impl VariableEntry {
|
||||
.inner
|
||||
.allocate_descriptor_sets([allocate_info])
|
||||
.map_err(|err| match err {
|
||||
RuntimeError::OutOfHostMemory | RuntimeError::OutOfDeviceMemory => err,
|
||||
RuntimeError::FragmentedPool => {
|
||||
VulkanError::OutOfHostMemory | VulkanError::OutOfDeviceMemory => err,
|
||||
VulkanError::FragmentedPool => {
|
||||
// This can't happen as we don't free individual sets.
|
||||
unreachable!();
|
||||
}
|
||||
RuntimeError::OutOfPoolMemory => {
|
||||
VulkanError::OutOfPoolMemory => {
|
||||
// We created the pool to fit the maximum variable descriptor count.
|
||||
unreachable!();
|
||||
}
|
||||
@ -399,7 +399,7 @@ impl VariablePool {
|
||||
fn new(
|
||||
layout: &Arc<DescriptorSetLayout>,
|
||||
reserve: Arc<ArrayQueue<DescriptorPool>>,
|
||||
) -> Result<Arc<Self>, RuntimeError> {
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
DescriptorPool::new(
|
||||
layout.device().clone(),
|
||||
DescriptorPoolCreateInfo {
|
||||
@ -421,7 +421,7 @@ impl VariablePool {
|
||||
reserve,
|
||||
})
|
||||
})
|
||||
.map_err(VulkanError::unwrap_runtime)
|
||||
.map_err(Validated::unwrap)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ use crate::{
|
||||
instance::InstanceOwnedDebugWrapper,
|
||||
macros::{impl_id_counter, vulkan_bitflags, vulkan_enum},
|
||||
shader::{DescriptorBindingRequirements, ShaderStages},
|
||||
Requires, RequiresAllOf, RequiresOneOf, RuntimeError, ValidationError, Version, VulkanError,
|
||||
Requires, RequiresAllOf, RequiresOneOf, Validated, ValidationError, Version, VulkanError,
|
||||
VulkanObject,
|
||||
};
|
||||
use ahash::HashMap;
|
||||
@ -42,7 +42,7 @@ impl DescriptorSetLayout {
|
||||
pub fn new(
|
||||
device: Arc<Device>,
|
||||
create_info: DescriptorSetLayoutCreateInfo,
|
||||
) -> Result<Arc<DescriptorSetLayout>, VulkanError> {
|
||||
) -> Result<Arc<DescriptorSetLayout>, Validated<VulkanError>> {
|
||||
Self::validate_new(&device, &create_info)?;
|
||||
|
||||
unsafe { Ok(Self::new_unchecked(device, create_info)?) }
|
||||
@ -51,7 +51,7 @@ impl DescriptorSetLayout {
|
||||
fn validate_new(
|
||||
device: &Device,
|
||||
create_info: &DescriptorSetLayoutCreateInfo,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
// VUID-vkCreateDescriptorSetLayout-pCreateInfo-parameter
|
||||
create_info
|
||||
.validate(device)
|
||||
@ -77,13 +77,13 @@ impl DescriptorSetLayout {
|
||||
.is_none()
|
||||
}
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the total number of descriptors across all bindings is greater than \
|
||||
the `max_per_set_descriptors` limit, and \
|
||||
`device.descriptor_set_layout_support` returned `None`"
|
||||
.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -94,7 +94,7 @@ impl DescriptorSetLayout {
|
||||
pub unsafe fn new_unchecked(
|
||||
device: Arc<Device>,
|
||||
create_info: DescriptorSetLayoutCreateInfo,
|
||||
) -> Result<Arc<DescriptorSetLayout>, RuntimeError> {
|
||||
) -> Result<Arc<DescriptorSetLayout>, VulkanError> {
|
||||
let &DescriptorSetLayoutCreateInfo {
|
||||
flags,
|
||||
ref bindings,
|
||||
@ -177,7 +177,7 @@ impl DescriptorSetLayout {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
};
|
||||
|
||||
@ -322,7 +322,7 @@ pub struct DescriptorSetLayoutCreateInfo {
|
||||
}
|
||||
|
||||
impl DescriptorSetLayoutCreateInfo {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
flags,
|
||||
ref bindings,
|
||||
@ -366,7 +366,7 @@ impl DescriptorSetLayoutCreateInfo {
|
||||
| DescriptorType::StorageBufferDynamic
|
||||
| DescriptorType::InlineUniformBlock
|
||||
) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: format!(
|
||||
"`flags` contains `DescriptorSetLayoutCreateFlags::PUSH_DESCRIPTOR`, \
|
||||
and `bindings[{}].descriptor_type` is
|
||||
@ -381,11 +381,11 @@ impl DescriptorSetLayoutCreateInfo {
|
||||
"VUID-VkDescriptorSetLayoutCreateInfo-flags-02208",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if binding_flags.intersects(DescriptorBindingFlags::VARIABLE_DESCRIPTOR_COUNT) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: format!(
|
||||
"`flags` contains `DescriptorSetLayoutCreateFlags::PUSH_DESCRIPTOR`, \
|
||||
and `bindings[{}].flags` contains \
|
||||
@ -395,14 +395,14 @@ impl DescriptorSetLayoutCreateInfo {
|
||||
.into(),
|
||||
vuids: &["VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-flags-03003"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
if binding_flags.intersects(DescriptorBindingFlags::VARIABLE_DESCRIPTOR_COUNT)
|
||||
&& Some(binding_num) != highest_binding_num
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: format!(
|
||||
"`bindings[{}].flags` contains \
|
||||
`DescriptorBindingFlags::VARIABLE_DESCRIPTOR_COUNT`, but {0} is not the
|
||||
@ -414,7 +414,7 @@ impl DescriptorSetLayoutCreateInfo {
|
||||
"VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-pBindingFlags-03004",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -427,14 +427,14 @@ impl DescriptorSetLayoutCreateInfo {
|
||||
if flags.intersects(DescriptorSetLayoutCreateFlags::PUSH_DESCRIPTOR)
|
||||
&& total_descriptor_count > max_push_descriptors
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`flags` contains `DescriptorSetLayoutCreateFlags::PUSH_DESCRIPTOR`, and \
|
||||
the total number of descriptors in `bindings` exceeds the \
|
||||
`max_push_descriptors` limit"
|
||||
.into(),
|
||||
vuids: &["VUID-VkDescriptorSetLayoutCreateInfo-flags-00281"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -563,10 +563,10 @@ impl DescriptorSetLayoutBinding {
|
||||
/// Checks whether the descriptor of a pipeline layout `self` is compatible with the
|
||||
/// requirements of a shader `other`.
|
||||
#[inline]
|
||||
pub fn ensure_compatible_with_shader(
|
||||
pub(crate) fn ensure_compatible_with_shader(
|
||||
&self,
|
||||
binding_requirements: &DescriptorBindingRequirements,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
let &DescriptorBindingRequirements {
|
||||
ref descriptor_types,
|
||||
descriptor_count,
|
||||
@ -579,38 +579,38 @@ impl DescriptorSetLayoutBinding {
|
||||
} = binding_requirements;
|
||||
|
||||
if !descriptor_types.contains(&self.descriptor_type) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the descriptor type is not one of the types allowed by the \
|
||||
descriptor binding requirements"
|
||||
.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if let Some(required) = descriptor_count {
|
||||
if self.descriptor_count < required {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the descriptor count is less than the count required by the \
|
||||
descriptor binding requirements"
|
||||
.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
if !self.stages.contains(stages) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the stages are not a superset of the stages required by the \
|
||||
descriptor binding requirements"
|
||||
.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
binding_flags,
|
||||
descriptor_type,
|
||||
@ -640,24 +640,24 @@ impl DescriptorSetLayoutBinding {
|
||||
|
||||
if descriptor_type == DescriptorType::InlineUniformBlock {
|
||||
if !device.enabled_features().inline_uniform_block {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "descriptor_type".into(),
|
||||
problem: "`DescriptorType::InlineUniformBlock`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"inline_uniform_block",
|
||||
)])]),
|
||||
vuids: &["VUID-VkDescriptorSetLayoutBinding-descriptorType-04604"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if descriptor_count % 4 != 0 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`descriptor_type` is `DescriptorType::InlineUniformBlock`, and \
|
||||
`descriptor_count` is not a multiple of 4"
|
||||
.into(),
|
||||
vuids: &["VUID-VkDescriptorSetLayoutBinding-descriptorType-02209"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if descriptor_count
|
||||
@ -667,14 +667,14 @@ impl DescriptorSetLayoutBinding {
|
||||
.max_inline_uniform_block_size
|
||||
.unwrap_or(0)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`descriptor_type` is `DescriptorType::InlineUniformBlock`, and \
|
||||
`descriptor_count` is greater than the `max_inline_uniform_block_size` \
|
||||
limit"
|
||||
.into(),
|
||||
vuids: &["VUID-VkDescriptorSetLayoutBinding-descriptorType-08004"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -690,25 +690,25 @@ impl DescriptorSetLayoutBinding {
|
||||
if descriptor_type == DescriptorType::InputAttachment
|
||||
&& !(stages.is_empty() || stages == ShaderStages::FRAGMENT)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`descriptor_type` is `DescriptorType::InputAttachment`, but \
|
||||
`stages` is not either empty or equal to `ShaderStages::FRAGMENT`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkDescriptorSetLayoutBinding-descriptorType-01510"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
if !immutable_samplers.is_empty() {
|
||||
if descriptor_count != immutable_samplers.len() as u32 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`immutable_samplers` is not empty, but its length does not equal \
|
||||
`descriptor_count`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkDescriptorSetLayoutBinding-descriptorType-00282"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
let mut has_sampler_ycbcr_conversion = false;
|
||||
@ -721,27 +721,27 @@ impl DescriptorSetLayoutBinding {
|
||||
|
||||
if has_sampler_ycbcr_conversion {
|
||||
if !matches!(descriptor_type, DescriptorType::CombinedImageSampler) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`immutable_samplers` contains a sampler with a \
|
||||
sampler YCbCr conversion, but `descriptor_type` is not \
|
||||
`DescriptorType::CombinedImageSampler`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkDescriptorSetLayoutBinding-descriptorType-00282"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
} else {
|
||||
if !matches!(
|
||||
descriptor_type,
|
||||
DescriptorType::Sampler | DescriptorType::CombinedImageSampler
|
||||
) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`immutable_samplers` is not empty, but `descriptor_type` is not \
|
||||
`DescriptorType::Sampler` or `DescriptorType::CombinedImageSampler`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkDescriptorSetLayoutBinding-descriptorType-00282"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -751,21 +751,21 @@ impl DescriptorSetLayoutBinding {
|
||||
.enabled_features()
|
||||
.descriptor_binding_variable_descriptor_count
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "binding_flags".into(),
|
||||
problem: "contains `DescriptorBindingFlags::VARIABLE_DESCRIPTOR_COUNT`".into(),
|
||||
requires_one_of: RequiresOneOf(&[
|
||||
RequiresAllOf(&[Requires::Feature("descriptor_binding_variable_descriptor_count")])
|
||||
]),
|
||||
vuids: &["VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-descriptorBindingVariableDescriptorCount-03014"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if matches!(
|
||||
descriptor_type,
|
||||
DescriptorType::UniformBufferDynamic | DescriptorType::StorageBufferDynamic
|
||||
) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`binding_flags` contains \
|
||||
`DescriptorBindingFlags::VARIABLE_DESCRIPTOR_COUNT`, and \
|
||||
`descriptor_type` is `DescriptorType::UniformBufferDynamic` or \
|
||||
@ -775,7 +775,7 @@ impl DescriptorSetLayoutBinding {
|
||||
"VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-pBindingFlags-03015",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -169,7 +169,7 @@ impl DescriptorSetInner {
|
||||
variable_descriptor_count: u32,
|
||||
descriptor_writes: impl IntoIterator<Item = WriteDescriptorSet>,
|
||||
descriptor_copies: impl IntoIterator<Item = CopyDescriptorSet>,
|
||||
) -> Result<Self, ValidationError> {
|
||||
) -> Result<Self, Box<ValidationError>> {
|
||||
assert!(
|
||||
!layout
|
||||
.flags()
|
||||
|
@ -31,7 +31,7 @@ use crate::{
|
||||
UnsafeDescriptorSet,
|
||||
},
|
||||
device::{Device, DeviceOwned},
|
||||
VulkanError, VulkanObject,
|
||||
Validated, VulkanError, VulkanObject,
|
||||
};
|
||||
use std::{
|
||||
hash::{Hash, Hasher},
|
||||
@ -54,7 +54,7 @@ impl PersistentDescriptorSet {
|
||||
layout: Arc<DescriptorSetLayout>,
|
||||
descriptor_writes: impl IntoIterator<Item = WriteDescriptorSet>,
|
||||
descriptor_copies: impl IntoIterator<Item = CopyDescriptorSet>,
|
||||
) -> Result<Arc<PersistentDescriptorSet<A::Alloc>>, VulkanError>
|
||||
) -> Result<Arc<PersistentDescriptorSet<A::Alloc>>, Validated<VulkanError>>
|
||||
where
|
||||
A: DescriptorSetAllocator + ?Sized,
|
||||
{
|
||||
@ -74,7 +74,7 @@ impl PersistentDescriptorSet {
|
||||
variable_descriptor_count: u32,
|
||||
descriptor_writes: impl IntoIterator<Item = WriteDescriptorSet>,
|
||||
descriptor_copies: impl IntoIterator<Item = CopyDescriptorSet>,
|
||||
) -> Result<Arc<PersistentDescriptorSet<A::Alloc>>, VulkanError>
|
||||
) -> Result<Arc<PersistentDescriptorSet<A::Alloc>>, Validated<VulkanError>>
|
||||
where
|
||||
A: DescriptorSetAllocator + ?Sized,
|
||||
{
|
||||
|
@ -15,7 +15,7 @@ use crate::{
|
||||
device::{Device, DeviceOwned},
|
||||
instance::InstanceOwnedDebugWrapper,
|
||||
macros::{impl_id_counter, vulkan_bitflags},
|
||||
Requires, RequiresAllOf, RequiresOneOf, RuntimeError, ValidationError, Version, VulkanError,
|
||||
Requires, RequiresAllOf, RequiresOneOf, Validated, ValidationError, Version, VulkanError,
|
||||
VulkanObject,
|
||||
};
|
||||
use ahash::HashMap;
|
||||
@ -47,7 +47,7 @@ impl DescriptorPool {
|
||||
pub fn new(
|
||||
device: Arc<Device>,
|
||||
create_info: DescriptorPoolCreateInfo,
|
||||
) -> Result<DescriptorPool, VulkanError> {
|
||||
) -> Result<DescriptorPool, Validated<VulkanError>> {
|
||||
Self::validate_new(&device, &create_info)?;
|
||||
|
||||
unsafe { Ok(Self::new_unchecked(device, create_info)?) }
|
||||
@ -57,7 +57,7 @@ impl DescriptorPool {
|
||||
pub unsafe fn new_unchecked(
|
||||
device: Arc<Device>,
|
||||
create_info: DescriptorPoolCreateInfo,
|
||||
) -> Result<DescriptorPool, RuntimeError> {
|
||||
) -> Result<DescriptorPool, VulkanError> {
|
||||
let &DescriptorPoolCreateInfo {
|
||||
flags,
|
||||
max_sets,
|
||||
@ -106,7 +106,7 @@ impl DescriptorPool {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
};
|
||||
|
||||
@ -116,7 +116,7 @@ impl DescriptorPool {
|
||||
fn validate_new(
|
||||
device: &Device,
|
||||
create_info: &DescriptorPoolCreateInfo,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
// VUID-vkCreateDescriptorPool-pCreateInfo-parameter
|
||||
create_info
|
||||
.validate(device)
|
||||
@ -205,7 +205,7 @@ impl DescriptorPool {
|
||||
pub unsafe fn allocate_descriptor_sets<'a>(
|
||||
&self,
|
||||
allocate_info: impl IntoIterator<Item = DescriptorSetAllocateInfo<'a>>,
|
||||
) -> Result<impl ExactSizeIterator<Item = UnsafeDescriptorSet>, RuntimeError> {
|
||||
) -> Result<impl ExactSizeIterator<Item = UnsafeDescriptorSet>, VulkanError> {
|
||||
let (layouts, variable_descriptor_counts): (SmallVec<[_; 1]>, SmallVec<[_; 1]>) =
|
||||
allocate_info
|
||||
.into_iter()
|
||||
@ -256,15 +256,15 @@ impl DescriptorPool {
|
||||
let fns = self.device.fns();
|
||||
(fns.v1_0.allocate_descriptor_sets)(self.device.handle(), &infos, output.as_mut_ptr())
|
||||
.result()
|
||||
.map_err(RuntimeError::from)
|
||||
.map_err(VulkanError::from)
|
||||
.map_err(|err| match err {
|
||||
RuntimeError::OutOfHostMemory
|
||||
| RuntimeError::OutOfDeviceMemory
|
||||
| RuntimeError::OutOfPoolMemory => err,
|
||||
VulkanError::OutOfHostMemory
|
||||
| VulkanError::OutOfDeviceMemory
|
||||
| VulkanError::OutOfPoolMemory => err,
|
||||
// According to the specs, because `VK_ERROR_FRAGMENTED_POOL` was added after
|
||||
// version 1.0 of Vulkan, any negative return value except out-of-memory errors
|
||||
// must be considered as a fragmented pool error.
|
||||
_ => RuntimeError::FragmentedPool,
|
||||
_ => VulkanError::FragmentedPool,
|
||||
})?;
|
||||
|
||||
output.set_len(layouts.len());
|
||||
@ -288,7 +288,7 @@ impl DescriptorPool {
|
||||
pub unsafe fn free_descriptor_sets(
|
||||
&self,
|
||||
descriptor_sets: impl IntoIterator<Item = UnsafeDescriptorSet>,
|
||||
) -> Result<(), RuntimeError> {
|
||||
) -> Result<(), VulkanError> {
|
||||
let sets: SmallVec<[_; 8]> = descriptor_sets.into_iter().map(|s| s.handle()).collect();
|
||||
if !sets.is_empty() {
|
||||
let fns = self.device.fns();
|
||||
@ -299,7 +299,7 @@ impl DescriptorPool {
|
||||
sets.as_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -309,7 +309,7 @@ impl DescriptorPool {
|
||||
///
|
||||
/// This destroys all descriptor sets and empties the pool.
|
||||
#[inline]
|
||||
pub unsafe fn reset(&self) -> Result<(), RuntimeError> {
|
||||
pub unsafe fn reset(&self) -> Result<(), VulkanError> {
|
||||
let fns = self.device.fns();
|
||||
(fns.v1_0.reset_descriptor_pool)(
|
||||
self.device.handle(),
|
||||
@ -317,7 +317,7 @@ impl DescriptorPool {
|
||||
ash::vk::DescriptorPoolResetFlags::empty(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -399,7 +399,7 @@ impl Default for DescriptorPoolCreateInfo {
|
||||
}
|
||||
|
||||
impl DescriptorPoolCreateInfo {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
flags,
|
||||
max_sets,
|
||||
@ -417,21 +417,21 @@ impl DescriptorPoolCreateInfo {
|
||||
})?;
|
||||
|
||||
if max_sets == 0 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "max_sets".into(),
|
||||
problem: "is zero".into(),
|
||||
vuids: &["VUID-VkDescriptorPoolCreateInfo-maxSets-00301"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if pool_sizes.is_empty() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "pool_sizes".into(),
|
||||
problem: "is empty".into(),
|
||||
// vuids?
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// VUID-VkDescriptorPoolCreateInfo-pPoolSizes-parameter
|
||||
@ -445,21 +445,21 @@ impl DescriptorPoolCreateInfo {
|
||||
})?;
|
||||
|
||||
if pool_size == 0 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("pool_sizes[DescriptorType::{:?}]", descriptor_type).into(),
|
||||
problem: "is zero".into(),
|
||||
vuids: &["VUID-VkDescriptorPoolSize-descriptorCount-00302"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if descriptor_type == DescriptorType::InlineUniformBlock {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "pool_sizes[DescriptorType::InlineUniformBlock]".into(),
|
||||
problem: "is not a multiple of 4".into(),
|
||||
vuids: &["VUID-VkDescriptorPoolSize-type-02218"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -467,7 +467,7 @@ impl DescriptorPoolCreateInfo {
|
||||
&& !(device.api_version() >= Version::V1_3
|
||||
|| device.enabled_extensions().ext_inline_uniform_block)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "max_inline_uniform_block_bindings".into(),
|
||||
problem: "is not zero".into(),
|
||||
requires_one_of: RequiresOneOf(&[
|
||||
@ -476,7 +476,7 @@ impl DescriptorPoolCreateInfo {
|
||||
]),
|
||||
// vuids?
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -367,7 +367,7 @@ impl WriteDescriptorSet {
|
||||
&self,
|
||||
layout: &DescriptorSetLayout,
|
||||
variable_descriptor_count: u32,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
fn provided_element_type(elements: &WriteDescriptorSetElements) -> &'static str {
|
||||
match elements {
|
||||
WriteDescriptorSetElements::None(_) => "none",
|
||||
@ -392,12 +392,12 @@ impl WriteDescriptorSet {
|
||||
let layout_binding = match layout.bindings().get(&binding) {
|
||||
Some(layout_binding) => layout_binding,
|
||||
None => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "binding".into(),
|
||||
problem: "does not exist in the descriptor set layout".into(),
|
||||
vuids: &["VUID-VkWriteDescriptorSet-dstBinding-00315"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
@ -415,34 +415,34 @@ impl WriteDescriptorSet {
|
||||
|
||||
// VUID-VkWriteDescriptorSet-dstArrayElement-00321
|
||||
if first_array_element + array_element_count > max_descriptor_count {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`first_array_element` + the number of provided elements is greater than \
|
||||
the number of descriptors in the descriptor set binding"
|
||||
.into(),
|
||||
vuids: &["VUID-VkWriteDescriptorSet-dstArrayElement-00321"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
let validate_image_view =
|
||||
|image_view: &ImageView, index: usize| -> Result<(), ValidationError> {
|
||||
|image_view: &ImageView, index: usize| -> Result<(), Box<ValidationError>> {
|
||||
if image_view.image().image_type() == ImageType::Dim3d {
|
||||
if image_view.view_type() == ImageViewType::Dim2dArray {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("elements[{}]", index).into(),
|
||||
problem: "the image view's type is `ImageViewType::Dim2dArray`, and \
|
||||
was created from a 3D image"
|
||||
.into(),
|
||||
vuids: &["VUID-VkDescriptorImageInfo-imageView-00343"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
} else if image_view.view_type() == ImageViewType::Dim2d {
|
||||
if !image_view
|
||||
.image()
|
||||
.flags()
|
||||
.intersects(ImageCreateFlags::DIM2D_VIEW_COMPATIBLE)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("elements[{}]", index).into(),
|
||||
problem: "the image view's type is `ImageViewType::Dim2d`, and \
|
||||
was created from a 3D image, but the image's flags do not \
|
||||
@ -450,13 +450,13 @@ impl WriteDescriptorSet {
|
||||
.into(),
|
||||
vuids: &["VUID-VkDescriptorImageInfo-imageView-07796"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
match layout_binding.descriptor_type {
|
||||
DescriptorType::StorageImage => {
|
||||
if !device.enabled_features().image2_d_view_of3_d {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("elements[{}]", index).into(),
|
||||
problem: format!(
|
||||
"the descriptor type is `DescriptorType::{:?}`, and \
|
||||
@ -469,12 +469,12 @@ impl WriteDescriptorSet {
|
||||
Requires::Feature("image2_d_view_of3_d"),
|
||||
])]),
|
||||
vuids: &["VUID-VkDescriptorImageInfo-descriptorType-06713"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
DescriptorType::SampledImage | DescriptorType::CombinedImageSampler => {
|
||||
if !device.enabled_features().sampler2_d_view_of3_d {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("elements[{}]", index).into(),
|
||||
problem: format!(
|
||||
"the descriptor type is `DescriptorType::{:?}`, and \
|
||||
@ -487,11 +487,11 @@ impl WriteDescriptorSet {
|
||||
Requires::Feature("sampler2_d_view_of3_d"),
|
||||
])]),
|
||||
vuids: &["VUID-VkDescriptorImageInfo-descriptorType-06714"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("elements[{}]", index).into(),
|
||||
problem: "the descriptor type is not \
|
||||
`DescriptorType::StorageImage`, \
|
||||
@ -502,7 +502,7 @@ impl WriteDescriptorSet {
|
||||
.into(),
|
||||
vuids: &["VUID-VkDescriptorImageInfo-imageView-07795"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -513,14 +513,14 @@ impl WriteDescriptorSet {
|
||||
.aspects
|
||||
.contains(ImageAspects::DEPTH | ImageAspects::STENCIL)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("elements[{}]", index).into(),
|
||||
problem: "the image view's aspects include both a depth and a \
|
||||
stencil component"
|
||||
.into(),
|
||||
vuids: &["VUID-VkDescriptorImageInfo-imageView-01976"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -539,7 +539,7 @@ impl WriteDescriptorSet {
|
||||
if let WriteDescriptorSetElements::None(_) = elements {
|
||||
// Do nothing
|
||||
} else {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "elements".into(),
|
||||
problem: format!(
|
||||
"contains `{}` elements, but the descriptor set \
|
||||
@ -549,25 +549,25 @@ impl WriteDescriptorSet {
|
||||
.into(),
|
||||
// vuids?
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
} else {
|
||||
// For regular descriptors, no element must be written.
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "binding".into(),
|
||||
problem: "no descriptors must be written to this \
|
||||
descriptor set binding"
|
||||
.into(),
|
||||
// vuids?
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
let elements = if let WriteDescriptorSetElements::Sampler(elements) = elements {
|
||||
elements
|
||||
} else {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "elements".into(),
|
||||
problem: format!(
|
||||
"contains `{}` elements, but the descriptor set \
|
||||
@ -577,14 +577,14 @@ impl WriteDescriptorSet {
|
||||
.into(),
|
||||
// vuids?
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
};
|
||||
|
||||
for (index, sampler) in elements.iter().enumerate() {
|
||||
assert_eq!(device, sampler.device());
|
||||
|
||||
if sampler.sampler_ycbcr_conversion().is_some() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("elements[{}]", index).into(),
|
||||
problem: "the descriptor type is not \
|
||||
`DescriptorType::CombinedImageSampler`, and the sampler has a \
|
||||
@ -592,14 +592,14 @@ impl WriteDescriptorSet {
|
||||
.into(),
|
||||
// vuids?
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if device.enabled_extensions().khr_portability_subset
|
||||
&& !device.enabled_features().mutable_comparison_samplers
|
||||
&& sampler.compare().is_some()
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("elements[{}]", index).into(),
|
||||
problem: "this device is a portability subset device, and \
|
||||
the sampler has depth comparison enabled"
|
||||
@ -608,7 +608,7 @@ impl WriteDescriptorSet {
|
||||
"mutable_comparison_samplers",
|
||||
)])]),
|
||||
vuids: &["VUID-VkDescriptorImageInfo-mutableComparisonSamplers-04450"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -619,7 +619,7 @@ impl WriteDescriptorSet {
|
||||
if let WriteDescriptorSetElements::ImageViewSampler(elements) = elements {
|
||||
elements
|
||||
} else {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "elements".into(),
|
||||
problem: format!(
|
||||
"contains `{}` elements, but the descriptor set \
|
||||
@ -629,7 +629,7 @@ impl WriteDescriptorSet {
|
||||
.into(),
|
||||
// vuids?
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
};
|
||||
|
||||
for (index, (image_view_info, sampler)) in elements.iter().enumerate() {
|
||||
@ -648,7 +648,7 @@ impl WriteDescriptorSet {
|
||||
validate_image_view(image_view.as_ref(), index)?;
|
||||
|
||||
if !image_view.usage().intersects(ImageUsage::SAMPLED) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("elements[{}]", index).into(),
|
||||
problem: "the descriptor type is \
|
||||
`DescriptorType::SampledImage` or \
|
||||
@ -657,7 +657,7 @@ impl WriteDescriptorSet {
|
||||
.into(),
|
||||
vuids: &["VUID-VkWriteDescriptorSet-descriptorType-00337"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if !matches!(
|
||||
@ -670,7 +670,7 @@ impl WriteDescriptorSet {
|
||||
| ImageLayout::DepthReadOnlyOptimal
|
||||
| ImageLayout::StencilReadOnlyOptimal,
|
||||
) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("elements[{}]", index).into(),
|
||||
problem: "the descriptor type is \
|
||||
`DescriptorType::CombinedImageSampler`, and the image layout \
|
||||
@ -678,14 +678,14 @@ impl WriteDescriptorSet {
|
||||
.into(),
|
||||
vuids: &["VUID-VkWriteDescriptorSet-descriptorType-04150"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if device.enabled_extensions().khr_portability_subset
|
||||
&& !device.enabled_features().mutable_comparison_samplers
|
||||
&& sampler.compare().is_some()
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("elements[{}]", index).into(),
|
||||
problem: "this device is a portability subset device, and \
|
||||
the sampler has depth comparison enabled"
|
||||
@ -696,27 +696,27 @@ impl WriteDescriptorSet {
|
||||
vuids: &[
|
||||
"VUID-VkDescriptorImageInfo-mutableComparisonSamplers-04450",
|
||||
],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if image_view.sampler_ycbcr_conversion().is_some() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("elements[{}]", index).into(),
|
||||
problem: "the image view has a sampler YCbCr conversion, and the \
|
||||
descriptor set layout was not created with immutable samplers"
|
||||
.into(),
|
||||
vuids: &["VUID-VkWriteDescriptorSet-descriptorType-02738"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if sampler.sampler_ycbcr_conversion().is_some() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("elements[{}]", index).into(),
|
||||
problem: "the sampler has a sampler YCbCr conversion".into(),
|
||||
// vuids?
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
sampler
|
||||
@ -728,7 +728,7 @@ impl WriteDescriptorSet {
|
||||
{
|
||||
elements
|
||||
} else {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "elements".into(),
|
||||
problem: format!(
|
||||
"contains `{}` elements, but the descriptor set \
|
||||
@ -737,7 +737,7 @@ impl WriteDescriptorSet {
|
||||
)
|
||||
.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
};
|
||||
|
||||
let immutable_samplers = &layout_binding.immutable_samplers
|
||||
@ -760,7 +760,7 @@ impl WriteDescriptorSet {
|
||||
validate_image_view(image_view.as_ref(), index)?;
|
||||
|
||||
if !image_view.usage().intersects(ImageUsage::SAMPLED) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("elements[{}]", index).into(),
|
||||
problem: "the descriptor type is \
|
||||
`DescriptorType::SampledImage` or \
|
||||
@ -769,7 +769,7 @@ impl WriteDescriptorSet {
|
||||
.into(),
|
||||
vuids: &["VUID-VkWriteDescriptorSet-descriptorType-00337"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if !matches!(
|
||||
@ -782,7 +782,7 @@ impl WriteDescriptorSet {
|
||||
| ImageLayout::DepthReadOnlyOptimal
|
||||
| ImageLayout::StencilReadOnlyOptimal,
|
||||
) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("elements[{}]", index).into(),
|
||||
problem: "the descriptor type is \
|
||||
`DescriptorType::CombinedImageSampler`, and the image layout \
|
||||
@ -790,7 +790,7 @@ impl WriteDescriptorSet {
|
||||
.into(),
|
||||
vuids: &["VUID-VkWriteDescriptorSet-descriptorType-04150"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
sampler
|
||||
@ -804,7 +804,7 @@ impl WriteDescriptorSet {
|
||||
let elements = if let WriteDescriptorSetElements::ImageView(elements) = elements {
|
||||
elements
|
||||
} else {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "elements".into(),
|
||||
problem: format!(
|
||||
"contains `{}` elements, but the descriptor set \
|
||||
@ -814,7 +814,7 @@ impl WriteDescriptorSet {
|
||||
.into(),
|
||||
// vuids?
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
};
|
||||
|
||||
for (index, image_view_info) in elements.iter().enumerate() {
|
||||
@ -832,7 +832,7 @@ impl WriteDescriptorSet {
|
||||
validate_image_view(image_view.as_ref(), index)?;
|
||||
|
||||
if !image_view.usage().intersects(ImageUsage::SAMPLED) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("elements[{}]", index).into(),
|
||||
problem: "the descriptor type is \
|
||||
`DescriptorType::SampledImage` or \
|
||||
@ -841,7 +841,7 @@ impl WriteDescriptorSet {
|
||||
.into(),
|
||||
vuids: &["VUID-VkWriteDescriptorSet-descriptorType-00337"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if !matches!(
|
||||
@ -854,7 +854,7 @@ impl WriteDescriptorSet {
|
||||
| ImageLayout::DepthReadOnlyOptimal
|
||||
| ImageLayout::StencilReadOnlyOptimal,
|
||||
) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("elements[{}]", index).into(),
|
||||
problem: "the descriptor type is \
|
||||
`DescriptorType::SampledImage`, and the image layout is \
|
||||
@ -862,18 +862,18 @@ impl WriteDescriptorSet {
|
||||
.into(),
|
||||
vuids: &["VUID-VkWriteDescriptorSet-descriptorType-04149"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if image_view.sampler_ycbcr_conversion().is_some() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("elements[{}]", index).into(),
|
||||
problem: "the descriptor type is `DescriptorType::SampledImage`, and \
|
||||
the image view has a sampler YCbCr conversion"
|
||||
.into(),
|
||||
vuids: &["VUID-VkWriteDescriptorSet-descriptorType-01946"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -882,7 +882,7 @@ impl WriteDescriptorSet {
|
||||
let elements = if let WriteDescriptorSetElements::ImageView(elements) = elements {
|
||||
elements
|
||||
} else {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "elements".into(),
|
||||
problem: format!(
|
||||
"contains `{}` elements, but the descriptor set \
|
||||
@ -892,7 +892,7 @@ impl WriteDescriptorSet {
|
||||
.into(),
|
||||
// vuids?
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
};
|
||||
|
||||
for (index, image_view_info) in elements.iter().enumerate() {
|
||||
@ -910,7 +910,7 @@ impl WriteDescriptorSet {
|
||||
validate_image_view(image_view.as_ref(), index)?;
|
||||
|
||||
if !image_view.usage().intersects(ImageUsage::STORAGE) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("elements[{}]", index).into(),
|
||||
problem: "the descriptor type is \
|
||||
`DescriptorType::StorageImage`, and the image was not \
|
||||
@ -918,11 +918,11 @@ impl WriteDescriptorSet {
|
||||
.into(),
|
||||
vuids: &["VUID-VkWriteDescriptorSet-descriptorType-00339"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if !matches!(image_layout, ImageLayout::General) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("elements[{}]", index).into(),
|
||||
problem: "the descriptor type is \
|
||||
`DescriptorType::StorageImage`, and the image layout is \
|
||||
@ -930,11 +930,11 @@ impl WriteDescriptorSet {
|
||||
.into(),
|
||||
vuids: &["VUID-VkWriteDescriptorSet-descriptorType-04152"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if !image_view.component_mapping().is_identity() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("elements[{}]", index).into(),
|
||||
problem: "the descriptor type is `DescriptorType::StorageImage` or \
|
||||
`DescriptorType::InputAttachment`, and the image view is not \
|
||||
@ -942,16 +942,16 @@ impl WriteDescriptorSet {
|
||||
.into(),
|
||||
vuids: &["VUID-VkWriteDescriptorSet-descriptorType-00336"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if image_view.sampler_ycbcr_conversion().is_some() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("elements[{}]", index).into(),
|
||||
problem: "the image view has a sampler YCbCr conversion".into(),
|
||||
// vuids?
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -960,7 +960,7 @@ impl WriteDescriptorSet {
|
||||
let elements = if let WriteDescriptorSetElements::BufferView(elements) = elements {
|
||||
elements
|
||||
} else {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "elements".into(),
|
||||
problem: format!(
|
||||
"contains `{}` elements, but the descriptor set \
|
||||
@ -970,7 +970,7 @@ impl WriteDescriptorSet {
|
||||
.into(),
|
||||
// vuids?
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
};
|
||||
|
||||
for (index, buffer_view) in elements.iter().enumerate() {
|
||||
@ -982,7 +982,7 @@ impl WriteDescriptorSet {
|
||||
.usage()
|
||||
.intersects(BufferUsage::UNIFORM_TEXEL_BUFFER)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("elements[{}]", index).into(),
|
||||
problem: "the descriptor type is \
|
||||
`DescriptorType::UniformTexelBuffer`, and the buffer was not \
|
||||
@ -990,7 +990,7 @@ impl WriteDescriptorSet {
|
||||
.into(),
|
||||
vuids: &["VUID-VkWriteDescriptorSet-descriptorType-00334"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -999,7 +999,7 @@ impl WriteDescriptorSet {
|
||||
let elements = if let WriteDescriptorSetElements::BufferView(elements) = elements {
|
||||
elements
|
||||
} else {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "elements".into(),
|
||||
problem: format!(
|
||||
"contains `{}` elements, but the descriptor set \
|
||||
@ -1009,7 +1009,7 @@ impl WriteDescriptorSet {
|
||||
.into(),
|
||||
// vuids?
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
};
|
||||
|
||||
for (index, buffer_view) in elements.iter().enumerate() {
|
||||
@ -1022,7 +1022,7 @@ impl WriteDescriptorSet {
|
||||
.usage()
|
||||
.intersects(BufferUsage::STORAGE_TEXEL_BUFFER)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("elements[{}]", index).into(),
|
||||
problem: "the descriptor type is \
|
||||
`DescriptorType::StorageTexelBuffer`, and the buffer was not \
|
||||
@ -1030,7 +1030,7 @@ impl WriteDescriptorSet {
|
||||
.into(),
|
||||
vuids: &["VUID-VkWriteDescriptorSet-descriptorType-00335"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1039,7 +1039,7 @@ impl WriteDescriptorSet {
|
||||
let elements = if let WriteDescriptorSetElements::Buffer(elements) = elements {
|
||||
elements
|
||||
} else {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "elements".into(),
|
||||
problem: format!(
|
||||
"contains `{}` elements, but the descriptor set \
|
||||
@ -1049,7 +1049,7 @@ impl WriteDescriptorSet {
|
||||
.into(),
|
||||
// vuids?
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
};
|
||||
|
||||
for (index, buffer_info) in elements.iter().enumerate() {
|
||||
@ -1062,7 +1062,7 @@ impl WriteDescriptorSet {
|
||||
.usage()
|
||||
.intersects(BufferUsage::UNIFORM_BUFFER)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("elements[{}]", index).into(),
|
||||
problem: "the descriptor type is `DescriptorType::UniformBuffer` or \
|
||||
`DescriptorType::UniformBufferDynamic`, and the buffer was not \
|
||||
@ -1070,19 +1070,19 @@ impl WriteDescriptorSet {
|
||||
.into(),
|
||||
vuids: &["VUID-VkWriteDescriptorSet-descriptorType-00330"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
assert!(!range.is_empty());
|
||||
|
||||
if range.end > buffer.size() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("elements[{}]", index).into(),
|
||||
problem: "the end of the range is greater than the size of the buffer"
|
||||
.into(),
|
||||
vuids: &["VUID-VkDescriptorBufferInfo-range-00342"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1091,7 +1091,7 @@ impl WriteDescriptorSet {
|
||||
let elements = if let WriteDescriptorSetElements::Buffer(elements) = elements {
|
||||
elements
|
||||
} else {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "elements".into(),
|
||||
problem: format!(
|
||||
"contains `{}` elements, but the descriptor set \
|
||||
@ -1101,7 +1101,7 @@ impl WriteDescriptorSet {
|
||||
.into(),
|
||||
// vuids?
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
};
|
||||
|
||||
for (index, buffer_info) in elements.iter().enumerate() {
|
||||
@ -1114,7 +1114,7 @@ impl WriteDescriptorSet {
|
||||
.usage()
|
||||
.intersects(BufferUsage::STORAGE_BUFFER)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("elements[{}]", index).into(),
|
||||
problem: "the descriptor type is `DescriptorType::StorageBuffer` or \
|
||||
`DescriptorType::StorageBufferDynamic`, and the buffer was not \
|
||||
@ -1122,19 +1122,19 @@ impl WriteDescriptorSet {
|
||||
.into(),
|
||||
vuids: &["VUID-VkWriteDescriptorSet-descriptorType-00331"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
assert!(!range.is_empty());
|
||||
|
||||
if range.end > buffer.size() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("elements[{}]", index).into(),
|
||||
problem: "the end of the range is greater than the size of the buffer"
|
||||
.into(),
|
||||
vuids: &["VUID-VkDescriptorBufferInfo-range-00342"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1143,7 +1143,7 @@ impl WriteDescriptorSet {
|
||||
let elements = if let WriteDescriptorSetElements::ImageView(elements) = elements {
|
||||
elements
|
||||
} else {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "elements".into(),
|
||||
problem: format!(
|
||||
"contains `{}` elements, but the descriptor set \
|
||||
@ -1153,7 +1153,7 @@ impl WriteDescriptorSet {
|
||||
.into(),
|
||||
// vuids?
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
};
|
||||
|
||||
for (index, image_view_info) in elements.iter().enumerate() {
|
||||
@ -1171,7 +1171,7 @@ impl WriteDescriptorSet {
|
||||
validate_image_view(image_view.as_ref(), index)?;
|
||||
|
||||
if !image_view.usage().intersects(ImageUsage::INPUT_ATTACHMENT) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("elements[{}]", index).into(),
|
||||
problem: "the descriptor type is \
|
||||
`DescriptorType::InputAttachment`, and the image was not \
|
||||
@ -1179,7 +1179,7 @@ impl WriteDescriptorSet {
|
||||
.into(),
|
||||
vuids: &["VUID-VkWriteDescriptorSet-descriptorType-00338"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if !matches!(
|
||||
@ -1192,7 +1192,7 @@ impl WriteDescriptorSet {
|
||||
| ImageLayout::DepthReadOnlyOptimal
|
||||
| ImageLayout::StencilReadOnlyOptimal,
|
||||
) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("elements[{}]", index).into(),
|
||||
problem: "the descriptor type is \
|
||||
`DescriptorType::InputAttachment`, and the image layout is \
|
||||
@ -1200,11 +1200,11 @@ impl WriteDescriptorSet {
|
||||
.into(),
|
||||
vuids: &["VUID-VkWriteDescriptorSet-descriptorType-04151"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if !image_view.component_mapping().is_identity() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("elements[{}]", index).into(),
|
||||
problem: "the descriptor type is `DescriptorType::StorageImage` or \
|
||||
`DescriptorType::InputAttachment`, and the image view is not \
|
||||
@ -1212,18 +1212,18 @@ impl WriteDescriptorSet {
|
||||
.into(),
|
||||
vuids: &["VUID-VkWriteDescriptorSet-descriptorType-00336"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if image_view.sampler_ycbcr_conversion().is_some() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("elements[{}]", index).into(),
|
||||
problem: "the descriptor type is `DescriptorType::InputAttachment`, \
|
||||
and the image view has a sampler YCbCr conversion"
|
||||
.into(),
|
||||
// vuids?
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1232,7 +1232,7 @@ impl WriteDescriptorSet {
|
||||
let data = if let WriteDescriptorSetElements::InlineUniformBlock(data) = elements {
|
||||
data
|
||||
} else {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "elements".into(),
|
||||
problem: format!(
|
||||
"contains `{}` elements, but the descriptor set \
|
||||
@ -1241,11 +1241,11 @@ impl WriteDescriptorSet {
|
||||
)
|
||||
.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
};
|
||||
|
||||
if data.is_empty() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "data".into(),
|
||||
problem: "is empty".into(),
|
||||
vuids: &[
|
||||
@ -1253,11 +1253,11 @@ impl WriteDescriptorSet {
|
||||
"VUID-VkWriteDescriptorSet-descriptorCount-arraylength",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if data.len() % 4 != 0 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "data".into(),
|
||||
problem: "the length is not a multiple of 4".into(),
|
||||
vuids: &[
|
||||
@ -1265,16 +1265,16 @@ impl WriteDescriptorSet {
|
||||
"VUID-VkWriteDescriptorSet-descriptorType-02220",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if first_array_element % 4 != 0 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "offset".into(),
|
||||
problem: "is not a multiple of 4".into(),
|
||||
vuids: &["VUID-VkWriteDescriptorSet-descriptorType-02219"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1283,7 +1283,7 @@ impl WriteDescriptorSet {
|
||||
if let WriteDescriptorSetElements::AccelerationStructure(elements) = elements {
|
||||
elements
|
||||
} else {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "elements".into(),
|
||||
problem: format!(
|
||||
"contains `{}` elements, but the descriptor set \
|
||||
@ -1292,7 +1292,7 @@ impl WriteDescriptorSet {
|
||||
)
|
||||
.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
};
|
||||
|
||||
for (index, acceleration_structure) in elements.iter().enumerate() {
|
||||
@ -1302,7 +1302,7 @@ impl WriteDescriptorSet {
|
||||
acceleration_structure.ty(),
|
||||
AccelerationStructureType::TopLevel | AccelerationStructureType::Generic
|
||||
) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("elements[{}]", index).into(),
|
||||
problem: "the acceleration structure's type is not \
|
||||
`AccelerationStructureType::TopLevel` or \
|
||||
@ -1310,7 +1310,7 @@ impl WriteDescriptorSet {
|
||||
.into(),
|
||||
vuids: &["VUID-VkWriteDescriptorSetAccelerationStructureKHR-pAccelerationStructures-03579"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1620,7 +1620,7 @@ impl CopyDescriptorSet {
|
||||
&self,
|
||||
dst_set_layout: &DescriptorSetLayout,
|
||||
dst_set_variable_descriptor_count: u32,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
ref src_set,
|
||||
src_binding,
|
||||
@ -1637,13 +1637,13 @@ impl CopyDescriptorSet {
|
||||
let src_layout_binding = match src_set.layout().bindings().get(&src_binding) {
|
||||
Some(layout_binding) => layout_binding,
|
||||
None => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`src_binding` does not exist in the descriptor set layout of \
|
||||
`src_set`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkCopyDescriptorSet-srcBinding-00345"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
@ -1657,25 +1657,25 @@ impl CopyDescriptorSet {
|
||||
};
|
||||
|
||||
if src_first_array_element + descriptor_count > src_max_descriptor_count {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`src_first_array_element` + `descriptor_count` is greater than \
|
||||
the number of descriptors in `src_set`'s descriptor set binding"
|
||||
.into(),
|
||||
vuids: &["VUID-VkCopyDescriptorSet-srcArrayElement-00346"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
let dst_layout_binding = match dst_set_layout.bindings().get(&dst_binding) {
|
||||
Some(layout_binding) => layout_binding,
|
||||
None => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`dst_binding` does not exist in the descriptor set layout of \
|
||||
`dst_set`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkCopyDescriptorSet-dstBinding-00347"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
@ -1689,70 +1689,70 @@ impl CopyDescriptorSet {
|
||||
};
|
||||
|
||||
if dst_first_array_element + descriptor_count > dst_max_descriptor_count {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`dst_first_array_element` + `descriptor_count` is greater than \
|
||||
the number of descriptors in `dst_set`'s descriptor set binding"
|
||||
.into(),
|
||||
vuids: &["VUID-VkCopyDescriptorSet-dstArrayElement-00348"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if src_layout_binding.descriptor_type != dst_layout_binding.descriptor_type {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the descriptor type of `src_binding` within `src_set` does not equal \
|
||||
the descriptor type of `dst_binding` within `dst_set`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkCopyDescriptorSet-dstBinding-02632"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if dst_layout_binding.descriptor_type == DescriptorType::Sampler
|
||||
&& !dst_layout_binding.immutable_samplers.is_empty()
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the descriptor type of `dst_binding` within `dst_set` is \
|
||||
`DescriptorType::Sampler`, and the layout was created with immutable samplers \
|
||||
for `dst_binding`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkCopyDescriptorSet-dstBinding-02753"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if dst_layout_binding.descriptor_type == DescriptorType::InlineUniformBlock {
|
||||
if src_first_array_element % 4 != 0 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the descriptor type of `src_binding` within `src_set` is \
|
||||
`DescriptorType::InlineUniformBlock`, and `src_first_array_element` is \
|
||||
not a multiple of 4"
|
||||
.into(),
|
||||
vuids: &["VUID-VkCopyDescriptorSet-srcBinding-02223"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if dst_first_array_element % 4 != 0 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the descriptor type of `dst_binding` within `dst_set` is \
|
||||
`DescriptorType::InlineUniformBlock`, and `dst_first_array_element` is \
|
||||
not a multiple of 4"
|
||||
.into(),
|
||||
vuids: &["VUID-VkCopyDescriptorSet-dstBinding-02224"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if descriptor_count % 4 != 0 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the descriptor type of `dst_binding` within `dst_set` is \
|
||||
`DescriptorType::InlineUniformBlock`, and `descriptor_count` is \
|
||||
not a multiple of 4"
|
||||
.into(),
|
||||
vuids: &["VUID-VkCopyDescriptorSet-srcBinding-02225"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,7 +119,7 @@ use crate::{
|
||||
instance::{Instance, InstanceOwned, InstanceOwnedDebugWrapper},
|
||||
macros::{impl_id_counter, vulkan_bitflags},
|
||||
memory::ExternalMemoryHandleType,
|
||||
OomError, Requires, RequiresAllOf, RequiresOneOf, RuntimeError, ValidationError, Version,
|
||||
OomError, Requires, RequiresAllOf, RequiresOneOf, Validated, ValidationError, Version,
|
||||
VulkanError, VulkanObject,
|
||||
};
|
||||
use ash::vk::Handle;
|
||||
@ -178,7 +178,8 @@ impl Device {
|
||||
pub fn new(
|
||||
physical_device: Arc<PhysicalDevice>,
|
||||
create_info: DeviceCreateInfo,
|
||||
) -> Result<(Arc<Device>, impl ExactSizeIterator<Item = Arc<Queue>>), VulkanError> {
|
||||
) -> Result<(Arc<Device>, impl ExactSizeIterator<Item = Arc<Queue>>), Validated<VulkanError>>
|
||||
{
|
||||
Self::validate_new(&physical_device, &create_info)?;
|
||||
|
||||
unsafe { Ok(Self::new_unchecked(physical_device, create_info)?) }
|
||||
@ -187,7 +188,7 @@ impl Device {
|
||||
fn validate_new(
|
||||
physical_device: &PhysicalDevice,
|
||||
create_info: &DeviceCreateInfo,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
create_info
|
||||
.validate(physical_device)
|
||||
.map_err(|err| err.add_context("create_info"))?;
|
||||
@ -205,13 +206,13 @@ impl Device {
|
||||
.iter()
|
||||
.any(|p| p.as_ref() == physical_device)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`create_info.physical_devices` is not empty, but does not contain \
|
||||
`physical_device`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkDeviceGroupDeviceCreateInfo-physicalDeviceCount-00377"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -221,7 +222,7 @@ impl Device {
|
||||
pub unsafe fn new_unchecked(
|
||||
physical_device: Arc<PhysicalDevice>,
|
||||
mut create_info: DeviceCreateInfo,
|
||||
) -> Result<(Arc<Device>, impl ExactSizeIterator<Item = Arc<Queue>>), RuntimeError> {
|
||||
) -> Result<(Arc<Device>, impl ExactSizeIterator<Item = Arc<Queue>>), VulkanError> {
|
||||
// VUID-vkCreateDevice-ppEnabledExtensionNames-01387
|
||||
create_info.enabled_extensions.enable_dependencies(
|
||||
physical_device.api_version(),
|
||||
@ -377,7 +378,7 @@ impl Device {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
};
|
||||
|
||||
@ -574,7 +575,7 @@ impl Device {
|
||||
build_type: AccelerationStructureBuildType,
|
||||
build_info: &AccelerationStructureBuildGeometryInfo,
|
||||
max_primitive_counts: &[u32],
|
||||
) -> Result<AccelerationStructureBuildSizesInfo, ValidationError> {
|
||||
) -> Result<AccelerationStructureBuildSizesInfo, Box<ValidationError>> {
|
||||
self.validate_acceleration_structure_build_sizes(
|
||||
build_type,
|
||||
build_info,
|
||||
@ -595,18 +596,18 @@ impl Device {
|
||||
build_type: AccelerationStructureBuildType,
|
||||
build_info: &AccelerationStructureBuildGeometryInfo,
|
||||
max_primitive_counts: &[u32],
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
if !self.enabled_extensions().khr_acceleration_structure {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::DeviceExtension(
|
||||
"khr_acceleration_structure",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if !self.enabled_features().acceleration_structure {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"acceleration_structure",
|
||||
)])]),
|
||||
@ -614,7 +615,7 @@ impl Device {
|
||||
"VUID-vkGetAccelerationStructureBuildSizesKHR-accelerationStructure-08933",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
build_type
|
||||
@ -645,12 +646,12 @@ impl Device {
|
||||
AccelerationStructureGeometries::Triangles(geometries) => {
|
||||
for (index, &primitive_count) in max_primitive_counts.iter().enumerate() {
|
||||
if primitive_count as u64 > max_primitive_count {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("max_primitive_counts[{}]", index).into(),
|
||||
problem: "exceeds the `max_primitive_count` limit".into(),
|
||||
vuids: &["VUID-VkAccelerationStructureBuildGeometryInfoKHR-type-03795"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -659,12 +660,12 @@ impl Device {
|
||||
AccelerationStructureGeometries::Aabbs(geometries) => {
|
||||
for (index, &primitive_count) in max_primitive_counts.iter().enumerate() {
|
||||
if primitive_count as u64 > max_primitive_count {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("max_primitive_counts[{}]", index).into(),
|
||||
problem: "exceeds the `max_primitive_count` limit".into(),
|
||||
vuids: &["VUID-VkAccelerationStructureBuildGeometryInfoKHR-type-03794"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -673,14 +674,14 @@ impl Device {
|
||||
AccelerationStructureGeometries::Instances(_) => {
|
||||
for (index, &instance_count) in max_primitive_counts.iter().enumerate() {
|
||||
if instance_count as u64 > max_instance_count {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("max_primitive_counts[{}]", index).into(),
|
||||
problem: "exceeds the `max_instance_count` limit".into(),
|
||||
vuids: &[
|
||||
"VUID-vkGetAccelerationStructureBuildSizesKHR-pBuildInfo-03785",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -689,13 +690,13 @@ impl Device {
|
||||
};
|
||||
|
||||
if max_primitive_counts.len() != geometry_count {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`build_info.geometries` and `max_primitive_counts` \
|
||||
do not have the same length"
|
||||
.into(),
|
||||
vuids: &["VUID-vkGetAccelerationStructureBuildSizesKHR-pBuildInfo-03619"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -741,7 +742,7 @@ impl Device {
|
||||
pub fn acceleration_structure_is_compatible(
|
||||
&self,
|
||||
version_data: &[u8; 2 * ash::vk::UUID_SIZE],
|
||||
) -> Result<bool, ValidationError> {
|
||||
) -> Result<bool, Box<ValidationError>> {
|
||||
self.validate_acceleration_structure_is_compatible(version_data)?;
|
||||
|
||||
unsafe { Ok(self.acceleration_structure_is_compatible_unchecked(version_data)) }
|
||||
@ -750,24 +751,24 @@ impl Device {
|
||||
fn validate_acceleration_structure_is_compatible(
|
||||
&self,
|
||||
_version_data: &[u8; 2 * ash::vk::UUID_SIZE],
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
if !self.enabled_extensions().khr_acceleration_structure {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::DeviceExtension(
|
||||
"khr_acceleration_structure",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if !self.enabled_features().acceleration_structure {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[
|
||||
RequiresAllOf(&[Requires::Feature("acceleration_structure")]),
|
||||
]),
|
||||
vuids: &["VUID-vkGetDeviceAccelerationStructureCompatibilityKHR-accelerationStructure-08928"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -812,7 +813,7 @@ impl Device {
|
||||
pub fn descriptor_set_layout_support(
|
||||
&self,
|
||||
create_info: &DescriptorSetLayoutCreateInfo,
|
||||
) -> Result<Option<DescriptorSetLayoutSupport>, ValidationError> {
|
||||
) -> Result<Option<DescriptorSetLayoutSupport>, Box<ValidationError>> {
|
||||
self.validate_descriptor_set_layout_support(create_info)?;
|
||||
|
||||
unsafe { Ok(self.descriptor_set_layout_support_unchecked(create_info)) }
|
||||
@ -821,15 +822,15 @@ impl Device {
|
||||
fn validate_descriptor_set_layout_support(
|
||||
&self,
|
||||
create_info: &DescriptorSetLayoutCreateInfo,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
if !(self.api_version() >= Version::V1_1 || self.enabled_extensions().khr_maintenance3) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[
|
||||
RequiresAllOf(&[Requires::APIVersion(Version::V1_1)]),
|
||||
RequiresAllOf(&[Requires::DeviceExtension("khr_maintenance3")]),
|
||||
]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// VUID-vkGetDescriptorSetLayoutSupport-pCreateInfo-parameter
|
||||
@ -957,7 +958,7 @@ impl Device {
|
||||
&self,
|
||||
handle_type: ExternalMemoryHandleType,
|
||||
file: File,
|
||||
) -> Result<MemoryFdProperties, VulkanError> {
|
||||
) -> Result<MemoryFdProperties, Validated<VulkanError>> {
|
||||
self.validate_memory_fd_properties(handle_type, &file)?;
|
||||
|
||||
Ok(self.memory_fd_properties_unchecked(handle_type, file)?)
|
||||
@ -967,14 +968,14 @@ impl Device {
|
||||
&self,
|
||||
handle_type: ExternalMemoryHandleType,
|
||||
_file: &File,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
if !self.enabled_extensions().khr_external_memory_fd {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::DeviceExtension(
|
||||
"khr_external_memory_fd",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
handle_type
|
||||
@ -986,12 +987,12 @@ impl Device {
|
||||
})?;
|
||||
|
||||
if handle_type == ExternalMemoryHandleType::OpaqueFd {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "handle_type".into(),
|
||||
problem: "is `ExternalMemoryHandleType::OpaqueFd`".into(),
|
||||
vuids: &["VUID-vkGetMemoryFdPropertiesKHR-handleType-00674"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -1003,7 +1004,7 @@ impl Device {
|
||||
&self,
|
||||
handle_type: ExternalMemoryHandleType,
|
||||
file: File,
|
||||
) -> Result<MemoryFdProperties, RuntimeError> {
|
||||
) -> Result<MemoryFdProperties, VulkanError> {
|
||||
#[cfg(not(unix))]
|
||||
unreachable!("`khr_external_memory_fd` was somehow enabled on a non-Unix system");
|
||||
|
||||
@ -1021,7 +1022,7 @@ impl Device {
|
||||
&mut memory_fd_properties,
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
Ok(MemoryFdProperties {
|
||||
memory_type_bits: memory_fd_properties.memory_type_bits,
|
||||
@ -1056,7 +1057,7 @@ impl Device {
|
||||
let fns = self.instance().fns();
|
||||
(fns.ext_debug_utils.set_debug_utils_object_name_ext)(self.handle, &info)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -1077,7 +1078,7 @@ impl Device {
|
||||
let fns = self.fns();
|
||||
(fns.v1_0.device_wait_idle)(self.handle)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -1230,7 +1231,10 @@ impl Default for DeviceCreateInfo {
|
||||
}
|
||||
|
||||
impl DeviceCreateInfo {
|
||||
pub(crate) fn validate(&self, physical_device: &PhysicalDevice) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(
|
||||
&self,
|
||||
physical_device: &PhysicalDevice,
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
ref queue_create_infos,
|
||||
ref enabled_extensions,
|
||||
@ -1240,12 +1244,12 @@ impl DeviceCreateInfo {
|
||||
} = self;
|
||||
|
||||
if queue_create_infos.is_empty() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "queue_create_infos".into(),
|
||||
problem: "is empty".into(),
|
||||
vuids: &["VUID-VkDeviceCreateInfo-queueCreateInfoCount-arraylength"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
for (index, queue_create_info) in queue_create_infos.iter().enumerate() {
|
||||
@ -1266,7 +1270,7 @@ impl DeviceCreateInfo {
|
||||
.count()
|
||||
!= 1
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: format!(
|
||||
"`queue_create_infos[{}].queue_family_index` occurs more than once in \
|
||||
`queue_create_infos`",
|
||||
@ -1275,7 +1279,7 @@ impl DeviceCreateInfo {
|
||||
.into(),
|
||||
vuids: &["VUID-VkDeviceCreateInfo-queueFamilyIndex-02802"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1312,175 +1316,175 @@ impl DeviceCreateInfo {
|
||||
|
||||
if enabled_extensions.ext_buffer_device_address {
|
||||
if enabled_extensions.khr_buffer_device_address {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "enabled_extensions".into(),
|
||||
problem: "contains `khr_buffer_device_address`, \
|
||||
but also contains `ext_buffer_device_address`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-03328"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
} else if dependency_extensions.khr_buffer_device_address {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "enabled_extensions".into(),
|
||||
problem: "contains an extension that requires `khr_buffer_device_address`, \
|
||||
but also contains `ext_buffer_device_address`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-03328"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if physical_device.api_version() >= Version::V1_2
|
||||
&& enabled_features.buffer_device_address
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the physical device API version is at least 1.2, \
|
||||
`enabled_features` contains `buffer_device_address`, and \
|
||||
`enabled_extensions` contains `ext_buffer_device_address`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkDeviceCreateInfo-pNext-04748"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
if enabled_features.shading_rate_image {
|
||||
if enabled_features.pipeline_fragment_shading_rate {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "enabled_features".into(),
|
||||
problem: "contains both `shading_rate_image` and \
|
||||
`pipeline_fragment_shading_rate`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkDeviceCreateInfo-shadingRateImage-04478"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if enabled_features.primitive_fragment_shading_rate {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "enabled_features".into(),
|
||||
problem: "contains both `shading_rate_image` and \
|
||||
`primitive_fragment_shading_rate`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkDeviceCreateInfo-shadingRateImage-04479"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if enabled_features.attachment_fragment_shading_rate {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "enabled_features".into(),
|
||||
problem: "contains both `shading_rate_image` and \
|
||||
`attachment_fragment_shading_rate`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkDeviceCreateInfo-shadingRateImage-04480"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
if enabled_features.fragment_density_map {
|
||||
if enabled_features.pipeline_fragment_shading_rate {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "enabled_features".into(),
|
||||
problem: "contains both `fragment_density_map` and \
|
||||
`pipeline_fragment_shading_rate`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkDeviceCreateInfo-shadingRateImage-04481"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if enabled_features.primitive_fragment_shading_rate {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "enabled_features".into(),
|
||||
problem: "contains both `fragment_density_map` and \
|
||||
`primitive_fragment_shading_rate`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkDeviceCreateInfo-shadingRateImage-04482"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if enabled_features.attachment_fragment_shading_rate {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "enabled_features".into(),
|
||||
problem: "contains both `fragment_density_map` and \
|
||||
`attachment_fragment_shading_rate`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkDeviceCreateInfo-shadingRateImage-04483"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
if enabled_features.sparse_image_int64_atomics
|
||||
&& !enabled_features.shader_image_int64_atomics
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "enabled_features".into(),
|
||||
problem: "contains `sparse_image_int64_atomics`, but does not contain \
|
||||
`shader_image_int64_atomics`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkDeviceCreateInfo-None-04896"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if enabled_features.sparse_image_float32_atomics
|
||||
&& !enabled_features.shader_image_float32_atomics
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "enabled_features".into(),
|
||||
problem: "contains `sparse_image_float32_atomics`, but does not contain \
|
||||
`shader_image_float32_atomics`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkDeviceCreateInfo-None-04897"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if enabled_features.sparse_image_float32_atomic_add
|
||||
&& !enabled_features.shader_image_float32_atomic_add
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "enabled_features".into(),
|
||||
problem: "contains `sparse_image_float32_atomic_add`, but does not contain \
|
||||
`shader_image_float32_atomic_add`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkDeviceCreateInfo-None-04898"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if enabled_features.sparse_image_float32_atomic_min_max
|
||||
&& !enabled_features.shader_image_float32_atomic_min_max
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "enabled_features".into(),
|
||||
problem: "contains `sparse_image_float32_atomic_min_max`, but does not contain \
|
||||
`shader_image_float32_atomic_min_max`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkDeviceCreateInfo-sparseImageFloat32AtomicMinMax-04975"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if enabled_features.descriptor_buffer && enabled_extensions.amd_shader_fragment_mask {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`enabled_features` contains `descriptor_buffer`, and \
|
||||
`enabled_extensions` contains `amd_shader_fragment_mask`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkDeviceCreateInfo-None-08095"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if physical_devices.len() > 1 {
|
||||
for (index, group_physical_device) in physical_devices.iter().enumerate() {
|
||||
if physical_devices[..index].contains(group_physical_device) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "physical_devices".into(),
|
||||
problem: format!(
|
||||
"the physical device at index {} is contained in the list more than \
|
||||
@ -1490,7 +1494,7 @@ impl DeviceCreateInfo {
|
||||
.into(),
|
||||
vuids: &["VUID-VkDeviceGroupDeviceCreateInfo-pPhysicalDevices-00375"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1500,7 +1504,7 @@ impl DeviceCreateInfo {
|
||||
.enabled_extensions()
|
||||
.khr_device_group_creation)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "physical_devices".into(),
|
||||
problem: "the length is greater than 1".into(),
|
||||
requires_one_of: RequiresOneOf(&[
|
||||
@ -1508,20 +1512,20 @@ impl DeviceCreateInfo {
|
||||
RequiresAllOf(&[Requires::InstanceExtension("khr_device_group_creation")]),
|
||||
]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if !physical_device
|
||||
.instance()
|
||||
.is_same_device_group(physical_devices.iter().map(AsRef::as_ref))
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "physical_devices".into(),
|
||||
problem: "the physical devices do not all belong to the same device group"
|
||||
.into(),
|
||||
vuids: &["VUID-VkDeviceGroupDeviceCreateInfo-pPhysicalDevices-00376"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1573,7 +1577,7 @@ impl QueueCreateInfo {
|
||||
physical_device: &PhysicalDevice,
|
||||
device_extensions: &DeviceExtensions,
|
||||
device_features: &Features,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
flags,
|
||||
queue_family_index,
|
||||
@ -1606,32 +1610,32 @@ impl QueueCreateInfo {
|
||||
})?;
|
||||
|
||||
if queues.is_empty() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "queues".into(),
|
||||
problem: "is empty".into(),
|
||||
vuids: &["VUID-VkDeviceQueueCreateInfo-queueCount-arraylength"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if queues.len() > queue_family_properties.queue_count as usize {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the length of `queues` is greater than the number of queues in the
|
||||
queue family indicated by `queue_family_index`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkDeviceQueueCreateInfo-queueCount-00382"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
for (index, &priority) in queues.iter().enumerate() {
|
||||
if !(0.0..=1.0).contains(&priority) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("queues[{}]", index).into(),
|
||||
problem: "is not between 0.0 and 1.0 inclusive".into(),
|
||||
vuids: &["VUID-VkDeviceQueueCreateInfo-pQueuePriorities-00383"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ use crate::{
|
||||
semaphore::{ExternalSemaphoreInfo, ExternalSemaphoreProperties},
|
||||
Sharing,
|
||||
},
|
||||
DebugWrapper, ExtensionProperties, Requires, RequiresAllOf, RequiresOneOf, RuntimeError,
|
||||
DebugWrapper, ExtensionProperties, Requires, RequiresAllOf, RequiresOneOf, Validated,
|
||||
ValidationError, Version, VulkanError, VulkanObject,
|
||||
};
|
||||
use bytemuck::cast_slice;
|
||||
@ -95,7 +95,7 @@ impl PhysicalDevice {
|
||||
pub unsafe fn from_handle(
|
||||
instance: Arc<Instance>,
|
||||
handle: ash::vk::PhysicalDevice,
|
||||
) -> Result<Arc<Self>, RuntimeError> {
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
let api_version = Self::get_api_version(handle, &instance);
|
||||
let extension_properties = Self::get_extension_properties(handle, &instance)?;
|
||||
let supported_extensions: DeviceExtensions = extension_properties
|
||||
@ -160,7 +160,7 @@ impl PhysicalDevice {
|
||||
unsafe fn get_extension_properties(
|
||||
handle: ash::vk::PhysicalDevice,
|
||||
instance: &Instance,
|
||||
) -> Result<Vec<ExtensionProperties>, RuntimeError> {
|
||||
) -> Result<Vec<ExtensionProperties>, VulkanError> {
|
||||
let fns = instance.fns();
|
||||
|
||||
loop {
|
||||
@ -172,7 +172,7 @@ impl PhysicalDevice {
|
||||
ptr::null_mut(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
let mut output = Vec::with_capacity(count as usize);
|
||||
let result = (fns.v1_0.enumerate_device_extension_properties)(
|
||||
@ -188,7 +188,7 @@ impl PhysicalDevice {
|
||||
return Ok(output.into_iter().map(Into::into).collect());
|
||||
}
|
||||
ash::vk::Result::INCOMPLETE => (),
|
||||
err => return Err(RuntimeError::from(err)),
|
||||
err => return Err(VulkanError::from(err)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -429,7 +429,7 @@ impl PhysicalDevice {
|
||||
&self,
|
||||
queue_family_index: u32,
|
||||
dfb: *const D,
|
||||
) -> Result<bool, ValidationError> {
|
||||
) -> Result<bool, Box<ValidationError>> {
|
||||
self.validate_directfb_presentation_support(queue_family_index, dfb)?;
|
||||
|
||||
Ok(self.directfb_presentation_support_unchecked(queue_family_index, dfb))
|
||||
@ -439,18 +439,18 @@ impl PhysicalDevice {
|
||||
&self,
|
||||
queue_family_index: u32,
|
||||
_dfb: *const D,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
if !self.instance.enabled_extensions().ext_directfb_surface {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||
"ext_directfb_surface",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if queue_family_index >= self.queue_family_properties.len() as u32 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "queue_family_index".into(),
|
||||
problem: "is not less than the number of queue families in the physical device"
|
||||
.into(),
|
||||
@ -458,7 +458,7 @@ impl PhysicalDevice {
|
||||
"VUID-vkGetPhysicalDeviceDirectFBPresentationSupportEXT-queueFamilyIndex-04119",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// VUID-vkGetPhysicalDeviceDirectFBPresentationSupportEXT-dfb-parameter
|
||||
@ -496,7 +496,7 @@ impl PhysicalDevice {
|
||||
pub fn external_buffer_properties(
|
||||
&self,
|
||||
info: ExternalBufferInfo,
|
||||
) -> Result<ExternalBufferProperties, ValidationError> {
|
||||
) -> Result<ExternalBufferProperties, Box<ValidationError>> {
|
||||
self.validate_external_buffer_properties(&info)?;
|
||||
|
||||
unsafe { Ok(self.external_buffer_properties_unchecked(info)) }
|
||||
@ -505,14 +505,14 @@ impl PhysicalDevice {
|
||||
fn validate_external_buffer_properties(
|
||||
&self,
|
||||
info: &ExternalBufferInfo,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
if !(self.instance.api_version() >= Version::V1_1
|
||||
|| self
|
||||
.instance
|
||||
.enabled_extensions()
|
||||
.khr_external_memory_capabilities)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[
|
||||
RequiresAllOf(&[Requires::APIVersion(Version::V1_1)]),
|
||||
RequiresAllOf(&[Requires::InstanceExtension(
|
||||
@ -520,7 +520,7 @@ impl PhysicalDevice {
|
||||
)]),
|
||||
]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
info.validate(self).map_err(|err| err.add_context("info"))?;
|
||||
@ -596,7 +596,7 @@ impl PhysicalDevice {
|
||||
pub fn external_fence_properties(
|
||||
&self,
|
||||
info: ExternalFenceInfo,
|
||||
) -> Result<ExternalFenceProperties, ValidationError> {
|
||||
) -> Result<ExternalFenceProperties, Box<ValidationError>> {
|
||||
self.validate_external_fence_properties(&info)?;
|
||||
|
||||
unsafe { Ok(self.external_fence_properties_unchecked(info)) }
|
||||
@ -605,14 +605,14 @@ impl PhysicalDevice {
|
||||
fn validate_external_fence_properties(
|
||||
&self,
|
||||
info: &ExternalFenceInfo,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
if !(self.instance.api_version() >= Version::V1_1
|
||||
|| self
|
||||
.instance
|
||||
.enabled_extensions()
|
||||
.khr_external_fence_capabilities)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[
|
||||
RequiresAllOf(&[Requires::APIVersion(Version::V1_1)]),
|
||||
RequiresAllOf(&[Requires::InstanceExtension(
|
||||
@ -620,7 +620,7 @@ impl PhysicalDevice {
|
||||
)]),
|
||||
]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
info.validate(self).map_err(|err| err.add_context("info"))?;
|
||||
@ -699,7 +699,7 @@ impl PhysicalDevice {
|
||||
pub fn external_semaphore_properties(
|
||||
&self,
|
||||
info: ExternalSemaphoreInfo,
|
||||
) -> Result<ExternalSemaphoreProperties, ValidationError> {
|
||||
) -> Result<ExternalSemaphoreProperties, Box<ValidationError>> {
|
||||
self.validate_external_semaphore_properties(&info)?;
|
||||
|
||||
unsafe { Ok(self.external_semaphore_properties_unchecked(info)) }
|
||||
@ -708,14 +708,14 @@ impl PhysicalDevice {
|
||||
fn validate_external_semaphore_properties(
|
||||
&self,
|
||||
info: &ExternalSemaphoreInfo,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
if !(self.instance.api_version() >= Version::V1_1
|
||||
|| self
|
||||
.instance
|
||||
.enabled_extensions()
|
||||
.khr_external_semaphore_capabilities)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[
|
||||
RequiresAllOf(&[Requires::APIVersion(Version::V1_1)]),
|
||||
RequiresAllOf(&[Requires::InstanceExtension(
|
||||
@ -723,7 +723,7 @@ impl PhysicalDevice {
|
||||
)]),
|
||||
]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
info.validate(self).map_err(|err| err.add_context("info"))?;
|
||||
@ -797,13 +797,16 @@ impl PhysicalDevice {
|
||||
/// The results of this function are cached, so that future calls with the same arguments
|
||||
/// do not need to make a call to the Vulkan API again.
|
||||
#[inline]
|
||||
pub fn format_properties(&self, format: Format) -> Result<FormatProperties, ValidationError> {
|
||||
pub fn format_properties(
|
||||
&self,
|
||||
format: Format,
|
||||
) -> Result<FormatProperties, Box<ValidationError>> {
|
||||
self.validate_format_properties(format)?;
|
||||
|
||||
unsafe { Ok(self.format_properties_unchecked(format)) }
|
||||
}
|
||||
|
||||
fn validate_format_properties(&self, format: Format) -> Result<(), ValidationError> {
|
||||
fn validate_format_properties(&self, format: Format) -> Result<(), Box<ValidationError>> {
|
||||
format
|
||||
.validate_physical_device(self)
|
||||
.map_err(|err| ValidationError {
|
||||
@ -993,7 +996,7 @@ impl PhysicalDevice {
|
||||
pub fn image_format_properties(
|
||||
&self,
|
||||
image_format_info: ImageFormatInfo,
|
||||
) -> Result<Option<ImageFormatProperties>, VulkanError> {
|
||||
) -> Result<Option<ImageFormatProperties>, Validated<VulkanError>> {
|
||||
self.validate_image_format_properties(&image_format_info)?;
|
||||
|
||||
unsafe { Ok(self.image_format_properties_unchecked(image_format_info)?) }
|
||||
@ -1002,7 +1005,7 @@ impl PhysicalDevice {
|
||||
fn validate_image_format_properties(
|
||||
&self,
|
||||
image_format_info: &ImageFormatInfo,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
image_format_info
|
||||
.validate(self)
|
||||
.map_err(|err| err.add_context("image_format_info"))?;
|
||||
@ -1015,7 +1018,7 @@ impl PhysicalDevice {
|
||||
pub unsafe fn image_format_properties_unchecked(
|
||||
&self,
|
||||
mut image_format_info: ImageFormatInfo,
|
||||
) -> Result<Option<ImageFormatProperties>, RuntimeError> {
|
||||
) -> Result<Option<ImageFormatProperties>, VulkanError> {
|
||||
{
|
||||
let ImageFormatInfo {
|
||||
format,
|
||||
@ -1193,7 +1196,7 @@ impl PhysicalDevice {
|
||||
)
|
||||
}
|
||||
.result()
|
||||
.map_err(RuntimeError::from)
|
||||
.map_err(VulkanError::from)
|
||||
};
|
||||
|
||||
Ok(match result {
|
||||
@ -1211,7 +1214,7 @@ impl PhysicalDevice {
|
||||
}),
|
||||
..properties2_vk.image_format_properties.into()
|
||||
}),
|
||||
Err(RuntimeError::FormatNotSupported) => None,
|
||||
Err(VulkanError::FormatNotSupported) => None,
|
||||
Err(err) => return Err(err),
|
||||
})
|
||||
})
|
||||
@ -1227,7 +1230,7 @@ impl PhysicalDevice {
|
||||
&self,
|
||||
queue_family_index: u32,
|
||||
window: *const W,
|
||||
) -> Result<bool, ValidationError> {
|
||||
) -> Result<bool, Box<ValidationError>> {
|
||||
self.validate_qnx_screen_presentation_support(queue_family_index, window)?;
|
||||
|
||||
Ok(self.qnx_screen_presentation_support_unchecked(queue_family_index, window))
|
||||
@ -1237,18 +1240,18 @@ impl PhysicalDevice {
|
||||
&self,
|
||||
queue_family_index: u32,
|
||||
_window: *const W,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
if !self.instance.enabled_extensions().qnx_screen_surface {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||
"qnx_screen_surface",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if queue_family_index >= self.queue_family_properties.len() as u32 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "queue_family_index".into(),
|
||||
problem: "is not less than the number of queue families in the physical device"
|
||||
.into(),
|
||||
@ -1256,7 +1259,7 @@ impl PhysicalDevice {
|
||||
"VUID-vkGetPhysicalDeviceScreenPresentationSupportQNX-queueFamilyIndex-04743",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// VUID-vkGetPhysicalDeviceScreenPresentationSupportQNX-window-parameter
|
||||
@ -1292,7 +1295,7 @@ impl PhysicalDevice {
|
||||
pub fn sparse_image_format_properties(
|
||||
&self,
|
||||
format_info: SparseImageFormatInfo,
|
||||
) -> Result<Vec<SparseImageFormatProperties>, ValidationError> {
|
||||
) -> Result<Vec<SparseImageFormatProperties>, Box<ValidationError>> {
|
||||
self.validate_sparse_image_format_properties(&format_info)?;
|
||||
|
||||
unsafe { Ok(self.sparse_image_format_properties_unchecked(format_info)) }
|
||||
@ -1301,7 +1304,7 @@ impl PhysicalDevice {
|
||||
fn validate_sparse_image_format_properties(
|
||||
&self,
|
||||
format_info: &SparseImageFormatInfo,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
format_info
|
||||
.validate(self)
|
||||
.map_err(|err| err.add_context("format_info"))?;
|
||||
@ -1470,7 +1473,7 @@ impl PhysicalDevice {
|
||||
&self,
|
||||
surface: &Surface,
|
||||
surface_info: SurfaceInfo,
|
||||
) -> Result<SurfaceCapabilities, VulkanError> {
|
||||
) -> Result<SurfaceCapabilities, Validated<VulkanError>> {
|
||||
self.validate_surface_capabilities(surface, &surface_info)?;
|
||||
|
||||
unsafe { Ok(self.surface_capabilities_unchecked(surface, surface_info)?) }
|
||||
@ -1480,20 +1483,20 @@ impl PhysicalDevice {
|
||||
&self,
|
||||
surface: &Surface,
|
||||
surface_info: &SurfaceInfo,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
if !(self
|
||||
.instance
|
||||
.enabled_extensions()
|
||||
.khr_get_surface_capabilities2
|
||||
|| self.instance.enabled_extensions().khr_surface)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[
|
||||
RequiresAllOf(&[Requires::InstanceExtension("khr_get_surface_capabilities2")]),
|
||||
RequiresAllOf(&[Requires::InstanceExtension("khr_surface")]),
|
||||
]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// VUID-vkGetPhysicalDeviceSurfaceCapabilities2KHR-commonparent
|
||||
@ -1503,12 +1506,12 @@ impl PhysicalDevice {
|
||||
self.surface_support_unchecked(index, surface)
|
||||
.unwrap_or_default()
|
||||
}) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "surface".into(),
|
||||
problem: "is not supported by the physical device".into(),
|
||||
vuids: &["VUID-vkGetPhysicalDeviceSurfaceCapabilities2KHR-pSurfaceInfo-06210"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
surface_info
|
||||
@ -1533,11 +1536,11 @@ impl PhysicalDevice {
|
||||
};
|
||||
|
||||
if !present_modes.any(|mode| mode == present_mode) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`surface_info.present_mode` is not supported for `surface`".into(),
|
||||
vuids: &["VUID-VkSurfacePresentModeEXT-presentMode-07780"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1547,7 +1550,7 @@ impl PhysicalDevice {
|
||||
win32_monitor.is_some(),
|
||||
) {
|
||||
(true, false) => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`surface` is a Win32 surface, and \
|
||||
`surface_info.full_screen_exclusive` is \
|
||||
`FullScreenExclusive::ApplicationControlled`, but \
|
||||
@ -1555,17 +1558,17 @@ impl PhysicalDevice {
|
||||
.into(),
|
||||
vuids: &["VUID-VkPhysicalDeviceSurfaceInfo2KHR-pNext-02672"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
(false, true) => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`surface` is not a Win32 surface, or \
|
||||
`surface_info.full_screen_exclusive` is not \
|
||||
`FullScreenExclusive::ApplicationControlled`, but \
|
||||
`surface_info.win32_monitor` is `Some`"
|
||||
.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
(true, true) | (false, false) => (),
|
||||
}
|
||||
@ -1578,7 +1581,7 @@ impl PhysicalDevice {
|
||||
&self,
|
||||
surface: &Surface,
|
||||
surface_info: SurfaceInfo,
|
||||
) -> Result<SurfaceCapabilities, RuntimeError> {
|
||||
) -> Result<SurfaceCapabilities, VulkanError> {
|
||||
/* Input */
|
||||
|
||||
let SurfaceInfo {
|
||||
@ -1696,7 +1699,7 @@ impl PhysicalDevice {
|
||||
&mut capabilities_vk,
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
} else {
|
||||
(fns.khr_surface.get_physical_device_surface_capabilities_khr)(
|
||||
self.handle(),
|
||||
@ -1704,7 +1707,7 @@ impl PhysicalDevice {
|
||||
&mut capabilities_vk.surface_capabilities,
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
};
|
||||
|
||||
Ok(SurfaceCapabilities {
|
||||
@ -1835,7 +1838,7 @@ impl PhysicalDevice {
|
||||
&self,
|
||||
surface: &Surface,
|
||||
surface_info: SurfaceInfo,
|
||||
) -> Result<Vec<(Format, ColorSpace)>, VulkanError> {
|
||||
) -> Result<Vec<(Format, ColorSpace)>, Validated<VulkanError>> {
|
||||
self.validate_surface_formats(surface, &surface_info)?;
|
||||
|
||||
unsafe { Ok(self.surface_formats_unchecked(surface, surface_info)?) }
|
||||
@ -1845,20 +1848,20 @@ impl PhysicalDevice {
|
||||
&self,
|
||||
surface: &Surface,
|
||||
surface_info: &SurfaceInfo,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
if !(self
|
||||
.instance
|
||||
.enabled_extensions()
|
||||
.khr_get_surface_capabilities2
|
||||
|| self.instance.enabled_extensions().khr_surface)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[
|
||||
RequiresAllOf(&[Requires::InstanceExtension("khr_get_surface_capabilities2")]),
|
||||
RequiresAllOf(&[Requires::InstanceExtension("khr_surface")]),
|
||||
]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// VUID-vkGetPhysicalDeviceSurfaceFormats2KHR-commonparent
|
||||
@ -1868,12 +1871,12 @@ impl PhysicalDevice {
|
||||
self.surface_support_unchecked(index, surface)
|
||||
.unwrap_or_default()
|
||||
}) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "surface".into(),
|
||||
problem: "is not supported by the physical device".into(),
|
||||
vuids: &["VUID-vkGetPhysicalDeviceSurfaceFormats2KHR-pSurfaceInfo-06522"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
surface_info
|
||||
@ -1898,11 +1901,11 @@ impl PhysicalDevice {
|
||||
};
|
||||
|
||||
if !present_modes.any(|mode| mode == present_mode) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`surface_info.present_mode` is not supported for `surface`".into(),
|
||||
vuids: &["VUID-VkSurfacePresentModeEXT-presentMode-07780"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1912,25 +1915,25 @@ impl PhysicalDevice {
|
||||
.khr_get_surface_capabilities2
|
||||
{
|
||||
if full_screen_exclusive != FullScreenExclusive::Default {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "surface_info.full_screen_exclusive".into(),
|
||||
problem: "is not `FullScreenExclusive::Default`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[
|
||||
Requires::InstanceExtension("khr_get_surface_capabilities2"),
|
||||
])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if win32_monitor.is_some() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "surface_info.win32_monitor".into(),
|
||||
problem: "is `Some`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[
|
||||
Requires::InstanceExtension("khr_get_surface_capabilities2"),
|
||||
])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1940,7 +1943,7 @@ impl PhysicalDevice {
|
||||
win32_monitor.is_some(),
|
||||
) {
|
||||
(true, false) => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`surface` is a Win32 surface, and \
|
||||
`surface_info.full_screen_exclusive` is \
|
||||
`FullScreenExclusive::ApplicationControlled`, but \
|
||||
@ -1948,17 +1951,17 @@ impl PhysicalDevice {
|
||||
.into(),
|
||||
vuids: &["VUID-VkPhysicalDeviceSurfaceInfo2KHR-pNext-02672"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
(false, true) => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`surface` is not a Win32 surface, or \
|
||||
`surface_info.full_screen_exclusive` is not \
|
||||
`FullScreenExclusive::ApplicationControlled`, but \
|
||||
`surface_info.win32_monitor` is `Some`"
|
||||
.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
(true, true) | (false, false) => (),
|
||||
}
|
||||
@ -1971,7 +1974,7 @@ impl PhysicalDevice {
|
||||
&self,
|
||||
surface: &Surface,
|
||||
surface_info: SurfaceInfo,
|
||||
) -> Result<Vec<(Format, ColorSpace)>, RuntimeError> {
|
||||
) -> Result<Vec<(Format, ColorSpace)>, VulkanError> {
|
||||
surface.surface_formats.get_or_try_insert(
|
||||
(self.handle, surface_info),
|
||||
|(_, surface_info)| {
|
||||
@ -2041,7 +2044,7 @@ impl PhysicalDevice {
|
||||
ptr::null_mut(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
let mut surface_format2s_vk =
|
||||
vec![ash::vk::SurfaceFormat2KHR::default(); count as usize];
|
||||
@ -2060,7 +2063,7 @@ impl PhysicalDevice {
|
||||
break surface_format2s_vk;
|
||||
}
|
||||
ash::vk::Result::INCOMPLETE => (),
|
||||
err => return Err(RuntimeError::from(err)),
|
||||
err => return Err(VulkanError::from(err)),
|
||||
}
|
||||
};
|
||||
|
||||
@ -2081,7 +2084,7 @@ impl PhysicalDevice {
|
||||
ptr::null_mut(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
let mut surface_formats = Vec::with_capacity(count as usize);
|
||||
let result = (fns.khr_surface.get_physical_device_surface_formats_khr)(
|
||||
@ -2097,7 +2100,7 @@ impl PhysicalDevice {
|
||||
break surface_formats;
|
||||
}
|
||||
ash::vk::Result::INCOMPLETE => (),
|
||||
err => return Err(RuntimeError::from(err)),
|
||||
err => return Err(VulkanError::from(err)),
|
||||
}
|
||||
};
|
||||
|
||||
@ -2124,20 +2127,23 @@ impl PhysicalDevice {
|
||||
pub fn surface_present_modes(
|
||||
&self,
|
||||
surface: &Surface,
|
||||
) -> Result<impl Iterator<Item = PresentMode>, VulkanError> {
|
||||
) -> Result<impl Iterator<Item = PresentMode>, Validated<VulkanError>> {
|
||||
self.validate_surface_present_modes(surface)?;
|
||||
|
||||
unsafe { Ok(self.surface_present_modes_unchecked(surface)?) }
|
||||
}
|
||||
|
||||
fn validate_surface_present_modes(&self, surface: &Surface) -> Result<(), ValidationError> {
|
||||
fn validate_surface_present_modes(
|
||||
&self,
|
||||
surface: &Surface,
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
if !self.instance.enabled_extensions().khr_surface {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||
"khr_surface",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// VUID-vkGetPhysicalDeviceSurfacePresentModesKHR-commonparent
|
||||
@ -2147,12 +2153,12 @@ impl PhysicalDevice {
|
||||
self.surface_support_unchecked(index, surface)
|
||||
.unwrap_or_default()
|
||||
}) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "surface".into(),
|
||||
problem: "is not supported by the physical device".into(),
|
||||
vuids: &["VUID-vkGetPhysicalDeviceSurfacePresentModesKHR-surface-06525"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -2162,7 +2168,7 @@ impl PhysicalDevice {
|
||||
pub unsafe fn surface_present_modes_unchecked(
|
||||
&self,
|
||||
surface: &Surface,
|
||||
) -> Result<impl Iterator<Item = PresentMode>, RuntimeError> {
|
||||
) -> Result<impl Iterator<Item = PresentMode>, VulkanError> {
|
||||
surface
|
||||
.surface_present_modes
|
||||
.get_or_try_insert(self.handle, |_| {
|
||||
@ -2178,7 +2184,7 @@ impl PhysicalDevice {
|
||||
ptr::null_mut(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
let mut modes = Vec::with_capacity(count as usize);
|
||||
let result = (fns
|
||||
@ -2196,7 +2202,7 @@ impl PhysicalDevice {
|
||||
break modes;
|
||||
}
|
||||
ash::vk::Result::INCOMPLETE => (),
|
||||
err => return Err(RuntimeError::from(err)),
|
||||
err => return Err(VulkanError::from(err)),
|
||||
}
|
||||
};
|
||||
|
||||
@ -2217,7 +2223,7 @@ impl PhysicalDevice {
|
||||
&self,
|
||||
queue_family_index: u32,
|
||||
surface: &Surface,
|
||||
) -> Result<bool, VulkanError> {
|
||||
) -> Result<bool, Validated<VulkanError>> {
|
||||
self.validate_surface_support(queue_family_index, surface)?;
|
||||
|
||||
unsafe { Ok(self.surface_support_unchecked(queue_family_index, surface)?) }
|
||||
@ -2227,24 +2233,24 @@ impl PhysicalDevice {
|
||||
&self,
|
||||
queue_family_index: u32,
|
||||
_surface: &Surface,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
if !self.instance.enabled_extensions().khr_surface {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||
"khr_surface",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if queue_family_index >= self.queue_family_properties.len() as u32 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "queue_family_index".into(),
|
||||
problem: "is not less than the number of queue families in the physical device"
|
||||
.into(),
|
||||
vuids: &["VUID-vkGetPhysicalDeviceSurfaceSupportKHR-queueFamilyIndex-01269"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -2255,7 +2261,7 @@ impl PhysicalDevice {
|
||||
&self,
|
||||
queue_family_index: u32,
|
||||
surface: &Surface,
|
||||
) -> Result<bool, RuntimeError> {
|
||||
) -> Result<bool, VulkanError> {
|
||||
surface
|
||||
.surface_support
|
||||
.get_or_try_insert((self.handle, queue_family_index), |_| {
|
||||
@ -2269,7 +2275,7 @@ impl PhysicalDevice {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
Ok(output.assume_init() != 0)
|
||||
})
|
||||
@ -2284,21 +2290,21 @@ impl PhysicalDevice {
|
||||
/// [`ext_tooling_info`](crate::device::DeviceExtensions::ext_tooling_info)
|
||||
/// extension must be supported by the physical device.
|
||||
#[inline]
|
||||
pub fn tool_properties(&self) -> Result<Vec<ToolProperties>, VulkanError> {
|
||||
pub fn tool_properties(&self) -> Result<Vec<ToolProperties>, Validated<VulkanError>> {
|
||||
self.validate_tool_properties()?;
|
||||
|
||||
unsafe { Ok(self.tool_properties_unchecked()?) }
|
||||
}
|
||||
|
||||
fn validate_tool_properties(&self) -> Result<(), ValidationError> {
|
||||
fn validate_tool_properties(&self) -> Result<(), Box<ValidationError>> {
|
||||
if !(self.api_version() >= Version::V1_3 || self.supported_extensions().ext_tooling_info) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[
|
||||
RequiresAllOf(&[Requires::APIVersion(Version::V1_3)]),
|
||||
RequiresAllOf(&[Requires::DeviceExtension("ext_tooling_info")]),
|
||||
]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -2306,7 +2312,7 @@ impl PhysicalDevice {
|
||||
|
||||
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
||||
#[inline]
|
||||
pub unsafe fn tool_properties_unchecked(&self) -> Result<Vec<ToolProperties>, RuntimeError> {
|
||||
pub unsafe fn tool_properties_unchecked(&self) -> Result<Vec<ToolProperties>, VulkanError> {
|
||||
let fns = self.instance.fns();
|
||||
|
||||
loop {
|
||||
@ -2326,7 +2332,7 @@ impl PhysicalDevice {
|
||||
)
|
||||
}
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
let mut tool_properties = Vec::with_capacity(count as usize);
|
||||
let result = if self.api_version() >= Version::V1_3 {
|
||||
@ -2375,7 +2381,7 @@ impl PhysicalDevice {
|
||||
})
|
||||
.collect());
|
||||
}
|
||||
err => return Err(RuntimeError::from(err)),
|
||||
err => return Err(VulkanError::from(err)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2390,7 +2396,7 @@ impl PhysicalDevice {
|
||||
&self,
|
||||
queue_family_index: u32,
|
||||
display: *const D,
|
||||
) -> Result<bool, ValidationError> {
|
||||
) -> Result<bool, Box<ValidationError>> {
|
||||
self.validate_wayland_presentation_support(queue_family_index, display)?;
|
||||
|
||||
Ok(self.wayland_presentation_support_unchecked(queue_family_index, display))
|
||||
@ -2400,18 +2406,18 @@ impl PhysicalDevice {
|
||||
&self,
|
||||
queue_family_index: u32,
|
||||
_display: *const D,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
if !self.instance.enabled_extensions().khr_wayland_surface {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||
"khr_wayland_surface",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if queue_family_index >= self.queue_family_properties.len() as u32 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "queue_family_index".into(),
|
||||
problem: "is not less than the number of queue families in the physical device"
|
||||
.into(),
|
||||
@ -2419,7 +2425,7 @@ impl PhysicalDevice {
|
||||
"VUID-vkGetPhysicalDeviceWaylandPresentationSupportKHR-queueFamilyIndex-01306",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// VUID-vkGetPhysicalDeviceWaylandPresentationSupportKHR-display-parameter
|
||||
@ -2449,7 +2455,7 @@ impl PhysicalDevice {
|
||||
pub fn win32_presentation_support(
|
||||
&self,
|
||||
queue_family_index: u32,
|
||||
) -> Result<bool, ValidationError> {
|
||||
) -> Result<bool, Box<ValidationError>> {
|
||||
self.validate_win32_presentation_support(queue_family_index)?;
|
||||
|
||||
unsafe { Ok(self.win32_presentation_support_unchecked(queue_family_index)) }
|
||||
@ -2458,18 +2464,18 @@ impl PhysicalDevice {
|
||||
fn validate_win32_presentation_support(
|
||||
&self,
|
||||
queue_family_index: u32,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
if !self.instance.enabled_extensions().khr_win32_surface {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||
"khr_win32_surface",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if queue_family_index >= self.queue_family_properties.len() as u32 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "queue_family_index".into(),
|
||||
problem: "is not less than the number of queue families in the physical device"
|
||||
.into(),
|
||||
@ -2477,7 +2483,7 @@ impl PhysicalDevice {
|
||||
"VUID-vkGetPhysicalDeviceWin32PresentationSupportKHR-queueFamilyIndex-01309",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -2504,7 +2510,7 @@ impl PhysicalDevice {
|
||||
queue_family_index: u32,
|
||||
connection: *const C,
|
||||
visual_id: ash::vk::xcb_visualid_t,
|
||||
) -> Result<bool, ValidationError> {
|
||||
) -> Result<bool, Box<ValidationError>> {
|
||||
self.validate_xcb_presentation_support(queue_family_index, connection, visual_id)?;
|
||||
|
||||
Ok(self.xcb_presentation_support_unchecked(queue_family_index, connection, visual_id))
|
||||
@ -2515,18 +2521,18 @@ impl PhysicalDevice {
|
||||
queue_family_index: u32,
|
||||
_connection: *const C,
|
||||
_visual_id: ash::vk::xcb_visualid_t,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
if !self.instance.enabled_extensions().khr_xcb_surface {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||
"khr_xcb_surface",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if queue_family_index >= self.queue_family_properties.len() as u32 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "queue_family_index".into(),
|
||||
problem: "is not less than the number of queue families in the physical device"
|
||||
.into(),
|
||||
@ -2534,7 +2540,7 @@ impl PhysicalDevice {
|
||||
"VUID-vkGetPhysicalDeviceXcbPresentationSupportKHR-queueFamilyIndex-01312",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// VUID-vkGetPhysicalDeviceXcbPresentationSupportKHR-connection-parameter
|
||||
@ -2571,7 +2577,7 @@ impl PhysicalDevice {
|
||||
queue_family_index: u32,
|
||||
display: *const D,
|
||||
visual_id: ash::vk::VisualID,
|
||||
) -> Result<bool, ValidationError> {
|
||||
) -> Result<bool, Box<ValidationError>> {
|
||||
self.validate_xlib_presentation_support(queue_family_index, display, visual_id)?;
|
||||
|
||||
Ok(self.xlib_presentation_support_unchecked(queue_family_index, display, visual_id))
|
||||
@ -2582,18 +2588,18 @@ impl PhysicalDevice {
|
||||
queue_family_index: u32,
|
||||
_display: *const D,
|
||||
_visual_id: ash::vk::VisualID,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
if !self.instance.enabled_extensions().khr_xlib_surface {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||
"khr_xlib_surface",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if queue_family_index >= self.queue_family_properties.len() as u32 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "queue_family_index".into(),
|
||||
problem: "is not less than the number of queue families in the physical device"
|
||||
.into(),
|
||||
@ -2601,7 +2607,7 @@ impl PhysicalDevice {
|
||||
"VUID-vkGetPhysicalDeviceXlibPresentationSupportKHR-queueFamilyIndex-01315",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// VUID-vkGetPhysicalDeviceXlibPresentationSupportKHR-dpy-parameter
|
||||
|
@ -26,7 +26,7 @@ use crate::{
|
||||
future::{AccessCheckError, FlushError, GpuFuture},
|
||||
semaphore::SemaphoreState,
|
||||
},
|
||||
OomError, Requires, RequiresAllOf, RequiresOneOf, RuntimeError, ValidationError, Version,
|
||||
OomError, Requires, RequiresAllOf, RequiresOneOf, ValidationError, Version, VulkanError,
|
||||
VulkanObject,
|
||||
};
|
||||
use ahash::HashMap;
|
||||
@ -202,7 +202,7 @@ impl<'a> QueueGuard<'a> {
|
||||
&mut self,
|
||||
bind_infos: impl IntoIterator<Item = BindSparseInfo>,
|
||||
fence: Option<Arc<Fence>>,
|
||||
) -> Result<(), RuntimeError> {
|
||||
) -> Result<(), VulkanError> {
|
||||
let bind_infos: SmallVec<[_; 4]> = bind_infos.into_iter().collect();
|
||||
let mut states = States::from_bind_infos(&bind_infos);
|
||||
|
||||
@ -221,7 +221,7 @@ impl<'a> QueueGuard<'a> {
|
||||
bind_infos: &SmallVec<[BindSparseInfo; 4]>,
|
||||
fence: Option<(&Arc<Fence>, MutexGuard<'_, FenceState>)>,
|
||||
states: &mut States<'_>,
|
||||
) -> Result<(), RuntimeError> {
|
||||
) -> Result<(), VulkanError> {
|
||||
struct PerBindSparseInfo {
|
||||
wait_semaphores_vk: SmallVec<[ash::vk::Semaphore; 4]>,
|
||||
buffer_bind_infos_vk: SmallVec<[ash::vk::SparseBufferMemoryBindInfo; 4]>,
|
||||
@ -478,7 +478,7 @@ impl<'a> QueueGuard<'a> {
|
||||
.map_or_else(Default::default, |(fence, _)| fence.handle()),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
for bind_info in bind_infos {
|
||||
let BindSparseInfo {
|
||||
@ -518,7 +518,7 @@ impl<'a> QueueGuard<'a> {
|
||||
pub unsafe fn present_unchecked(
|
||||
&mut self,
|
||||
present_info: PresentInfo,
|
||||
) -> Result<impl ExactSizeIterator<Item = Result<bool, RuntimeError>>, RuntimeError> {
|
||||
) -> Result<impl ExactSizeIterator<Item = Result<bool, VulkanError>>, VulkanError> {
|
||||
let mut states = States::from_present_info(&present_info);
|
||||
self.present_unchecked_locked(&present_info, &mut states)
|
||||
}
|
||||
@ -527,7 +527,7 @@ impl<'a> QueueGuard<'a> {
|
||||
&mut self,
|
||||
present_info: &PresentInfo,
|
||||
states: &mut States<'_>,
|
||||
) -> Result<impl ExactSizeIterator<Item = Result<bool, RuntimeError>>, RuntimeError> {
|
||||
) -> Result<impl ExactSizeIterator<Item = Result<bool, VulkanError>>, VulkanError> {
|
||||
let PresentInfo {
|
||||
wait_semaphores,
|
||||
swapchain_infos,
|
||||
@ -657,7 +657,7 @@ impl<'a> QueueGuard<'a> {
|
||||
| ash::vk::Result::ERROR_SURFACE_LOST_KHR
|
||||
| ash::vk::Result::ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT,
|
||||
) {
|
||||
return Err(RuntimeError::from(result));
|
||||
return Err(VulkanError::from(result));
|
||||
}
|
||||
|
||||
for semaphore in wait_semaphores {
|
||||
@ -683,7 +683,7 @@ impl<'a> QueueGuard<'a> {
|
||||
Ok(results.into_iter().map(|result| match result {
|
||||
ash::vk::Result::SUCCESS => Ok(false),
|
||||
ash::vk::Result::SUBOPTIMAL_KHR => Ok(true),
|
||||
err => Err(RuntimeError::from(err)),
|
||||
err => Err(VulkanError::from(err)),
|
||||
}))
|
||||
}
|
||||
|
||||
@ -817,7 +817,7 @@ impl<'a> QueueGuard<'a> {
|
||||
&mut self,
|
||||
submit_infos: impl IntoIterator<Item = SubmitInfo>,
|
||||
fence: Option<Arc<Fence>>,
|
||||
) -> Result<(), RuntimeError> {
|
||||
) -> Result<(), VulkanError> {
|
||||
let submit_infos: SmallVec<[_; 4]> = submit_infos.into_iter().collect();
|
||||
let mut states = States::from_submit_infos(&submit_infos);
|
||||
|
||||
@ -836,7 +836,7 @@ impl<'a> QueueGuard<'a> {
|
||||
submit_infos: &SmallVec<[SubmitInfo; 4]>,
|
||||
fence: Option<(&Arc<Fence>, MutexGuard<'_, FenceState>)>,
|
||||
states: &mut States<'_>,
|
||||
) -> Result<(), RuntimeError> {
|
||||
) -> Result<(), VulkanError> {
|
||||
if self.queue.device.enabled_features().synchronization2 {
|
||||
struct PerSubmitInfo {
|
||||
wait_semaphore_infos_vk: SmallVec<[ash::vk::SemaphoreSubmitInfo; 4]>,
|
||||
@ -965,7 +965,7 @@ impl<'a> QueueGuard<'a> {
|
||||
)
|
||||
}
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
} else {
|
||||
struct PerSubmitInfo {
|
||||
wait_semaphores_vk: SmallVec<[ash::vk::Semaphore; 4]>,
|
||||
@ -1067,7 +1067,7 @@ impl<'a> QueueGuard<'a> {
|
||||
.map_or_else(Default::default, |(fence, _)| fence.handle()),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
}
|
||||
|
||||
for submit_info in submit_infos {
|
||||
@ -1155,7 +1155,7 @@ impl<'a> QueueGuard<'a> {
|
||||
pub fn begin_debug_utils_label(
|
||||
&mut self,
|
||||
label_info: DebugUtilsLabel,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
self.validate_begin_debug_utils_label(&label_info)?;
|
||||
|
||||
unsafe {
|
||||
@ -1167,7 +1167,7 @@ impl<'a> QueueGuard<'a> {
|
||||
fn validate_begin_debug_utils_label(
|
||||
&self,
|
||||
_label_info: &DebugUtilsLabel,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
if !self
|
||||
.queue
|
||||
.device
|
||||
@ -1175,12 +1175,12 @@ impl<'a> QueueGuard<'a> {
|
||||
.enabled_extensions()
|
||||
.ext_debug_utils
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||
"ext_debug_utils",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -1216,14 +1216,14 @@ impl<'a> QueueGuard<'a> {
|
||||
/// - There must be an outstanding queue label region begun with `begin_debug_utils_label` in
|
||||
/// the queue.
|
||||
#[inline]
|
||||
pub unsafe fn end_debug_utils_label(&mut self) -> Result<(), ValidationError> {
|
||||
pub unsafe fn end_debug_utils_label(&mut self) -> Result<(), Box<ValidationError>> {
|
||||
self.validate_end_debug_utils_label()?;
|
||||
self.end_debug_utils_label_unchecked();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn validate_end_debug_utils_label(&self) -> Result<(), ValidationError> {
|
||||
fn validate_end_debug_utils_label(&self) -> Result<(), Box<ValidationError>> {
|
||||
if !self
|
||||
.queue
|
||||
.device
|
||||
@ -1231,12 +1231,12 @@ impl<'a> QueueGuard<'a> {
|
||||
.enabled_extensions()
|
||||
.ext_debug_utils
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||
"ext_debug_utils",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// VUID-vkQueueEndDebugUtilsLabelEXT-None-01911
|
||||
@ -1260,7 +1260,7 @@ impl<'a> QueueGuard<'a> {
|
||||
pub fn insert_debug_utils_label(
|
||||
&mut self,
|
||||
label_info: DebugUtilsLabel,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
self.validate_insert_debug_utils_label(&label_info)?;
|
||||
|
||||
unsafe {
|
||||
@ -1272,7 +1272,7 @@ impl<'a> QueueGuard<'a> {
|
||||
fn validate_insert_debug_utils_label(
|
||||
&self,
|
||||
_label_info: &DebugUtilsLabel,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
if !self
|
||||
.queue
|
||||
.device
|
||||
@ -1280,12 +1280,12 @@ impl<'a> QueueGuard<'a> {
|
||||
.enabled_extensions()
|
||||
.ext_debug_utils
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||
"ext_debug_utils",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -1323,7 +1323,7 @@ impl QueueState {
|
||||
let fns = device.fns();
|
||||
(fns.v1_0.queue_wait_idle)(handle)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
// Since we now know that the queue is finished with all work,
|
||||
// we can safely release all resources.
|
||||
|
@ -75,7 +75,7 @@ use crate::{
|
||||
range_map::RangeMap,
|
||||
swapchain::Swapchain,
|
||||
sync::{future::AccessError, AccessConflict, CurrentAccess, Sharing},
|
||||
DeviceSize, Requires, RequiresAllOf, RequiresOneOf, RuntimeError, ValidationError, Version,
|
||||
DeviceSize, Requires, RequiresAllOf, RequiresOneOf, Validated, ValidationError, Version,
|
||||
VulkanError, VulkanObject,
|
||||
};
|
||||
use parking_lot::{Mutex, MutexGuard};
|
||||
@ -146,15 +146,18 @@ impl Image {
|
||||
/// Creates a new uninitialized `Image`.
|
||||
pub fn new(
|
||||
allocator: &(impl MemoryAllocator + ?Sized),
|
||||
image_info: ImageCreateInfo,
|
||||
create_info: ImageCreateInfo,
|
||||
allocation_info: AllocationCreateInfo,
|
||||
) -> Result<Arc<Self>, ImageAllocateError> {
|
||||
) -> Result<Arc<Self>, Validated<ImageAllocateError>> {
|
||||
// TODO: adjust the code below to make this safe
|
||||
assert!(!image_info.flags.intersects(ImageCreateFlags::DISJOINT));
|
||||
assert!(!create_info.flags.intersects(ImageCreateFlags::DISJOINT));
|
||||
|
||||
let allocation_type = image_info.tiling.into();
|
||||
let raw_image = RawImage::new(allocator.device().clone(), image_info)
|
||||
.map_err(ImageAllocateError::CreateImage)?;
|
||||
let allocation_type = create_info.tiling.into();
|
||||
let raw_image =
|
||||
RawImage::new(allocator.device().clone(), create_info).map_err(|err| match err {
|
||||
Validated::Error(err) => Validated::Error(ImageAllocateError::CreateImage(err)),
|
||||
Validated::ValidationError(err) => err.into(),
|
||||
})?;
|
||||
let requirements = raw_image.memory_requirements()[0];
|
||||
|
||||
let allocation = unsafe {
|
||||
@ -207,7 +210,7 @@ impl Image {
|
||||
handle: ash::vk::Image,
|
||||
swapchain: Arc<Swapchain>,
|
||||
image_index: u32,
|
||||
) -> Result<Self, RuntimeError> {
|
||||
) -> Result<Self, VulkanError> {
|
||||
let create_info = ImageCreateInfo {
|
||||
flags: ImageCreateFlags::empty(),
|
||||
image_type: ImageType::Dim2d,
|
||||
@ -381,7 +384,7 @@ impl Image {
|
||||
aspect: ImageAspect,
|
||||
mip_level: u32,
|
||||
array_layer: u32,
|
||||
) -> Result<SubresourceLayout, ValidationError> {
|
||||
) -> Result<SubresourceLayout, Box<ValidationError>> {
|
||||
self.inner
|
||||
.subresource_layout(aspect, mip_level, array_layer)
|
||||
}
|
||||
@ -570,7 +573,7 @@ impl Hash for Image {
|
||||
pub enum ImageAllocateError {
|
||||
CreateImage(VulkanError),
|
||||
AllocateMemory(MemoryAllocatorError),
|
||||
BindMemory(RuntimeError),
|
||||
BindMemory(VulkanError),
|
||||
}
|
||||
|
||||
impl Error for ImageAllocateError {
|
||||
@ -593,6 +596,12 @@ impl Display for ImageAllocateError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ImageAllocateError> for Validated<ImageAllocateError> {
|
||||
fn from(err: ImageAllocateError) -> Self {
|
||||
Self::Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
/// The current state of an image.
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct ImageState {
|
||||
@ -1378,7 +1387,7 @@ impl ImageSubresourceLayers {
|
||||
}
|
||||
|
||||
impl ImageSubresourceLayers {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
aspects,
|
||||
mip_level: _,
|
||||
@ -1394,34 +1403,34 @@ impl ImageSubresourceLayers {
|
||||
})?;
|
||||
|
||||
if aspects.is_empty() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "aspects".into(),
|
||||
problem: "is empty".into(),
|
||||
vuids: &["VUID-VkImageSubresourceLayers-aspectMask-requiredbitmask"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if aspects.intersects(ImageAspects::COLOR)
|
||||
&& aspects.intersects(ImageAspects::DEPTH | ImageAspects::STENCIL)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "aspects".into(),
|
||||
problem: "contains both `ImageAspects::COLOR`, and either `ImageAspects::DEPTH` \
|
||||
or `ImageAspects::STENCIL`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkImageSubresourceLayers-aspectMask-00167"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if aspects.intersects(ImageAspects::METADATA) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "aspects".into(),
|
||||
problem: "contains `ImageAspects::METADATA`".into(),
|
||||
vuids: &["VUID-VkImageSubresourceLayers-aspectMask-00168"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if aspects.intersects(
|
||||
@ -1430,7 +1439,7 @@ impl ImageSubresourceLayers {
|
||||
| ImageAspects::MEMORY_PLANE_2
|
||||
| ImageAspects::MEMORY_PLANE_3,
|
||||
) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "aspects".into(),
|
||||
problem: "contains `ImageAspects::MEMORY_PLANE_0`, \
|
||||
`ImageAspects::MEMORY_PLANE_1`, `ImageAspects::MEMORY_PLANE_2` or \
|
||||
@ -1438,16 +1447,16 @@ impl ImageSubresourceLayers {
|
||||
.into(),
|
||||
vuids: &["VUID-VkImageSubresourceLayers-aspectMask-02247"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if array_layers.is_empty() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "array_layers".into(),
|
||||
problem: "is empty".into(),
|
||||
vuids: &["VUID-VkImageSubresourceLayers-layerCount-01700"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -1511,7 +1520,7 @@ impl ImageSubresourceRange {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
aspects,
|
||||
ref mip_levels,
|
||||
@ -1527,44 +1536,44 @@ impl ImageSubresourceRange {
|
||||
})?;
|
||||
|
||||
if aspects.is_empty() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "aspects".into(),
|
||||
problem: "is empty".into(),
|
||||
vuids: &["VUID-VkImageSubresourceRange-aspectMask-requiredbitmask"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if mip_levels.is_empty() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "mip_levels".into(),
|
||||
problem: "is empty".into(),
|
||||
vuids: &["VUID-VkImageSubresourceRange-levelCount-01720"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if array_layers.is_empty() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "array_layers".into(),
|
||||
problem: "is empty".into(),
|
||||
vuids: &["VUID-VkImageSubresourceRange-layerCount-01721"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if aspects.intersects(ImageAspects::COLOR)
|
||||
&& aspects
|
||||
.intersects(ImageAspects::PLANE_0 | ImageAspects::PLANE_1 | ImageAspects::PLANE_2)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "aspects".into(),
|
||||
problem: "contains both `ImageAspects::COLOR`, and one of \
|
||||
`ImageAspects::PLANE_0`, `ImageAspects::PLANE_1` or `ImageAspects::PLANE_2`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkImageSubresourceRange-aspectMask-01670"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if aspects.intersects(
|
||||
@ -1573,7 +1582,7 @@ impl ImageSubresourceRange {
|
||||
| ImageAspects::MEMORY_PLANE_2
|
||||
| ImageAspects::MEMORY_PLANE_3,
|
||||
) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "aspects".into(),
|
||||
problem: "contains `ImageAspects::MEMORY_PLANE_0`, \
|
||||
`ImageAspects::MEMORY_PLANE_1`, `ImageAspects::MEMORY_PLANE_2` or \
|
||||
@ -1581,7 +1590,7 @@ impl ImageSubresourceRange {
|
||||
.into(),
|
||||
vuids: &["VUID-VkImageSubresourceLayers-aspectMask-02247"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -1733,7 +1742,10 @@ impl Default for ImageFormatInfo {
|
||||
}
|
||||
|
||||
impl ImageFormatInfo {
|
||||
pub(crate) fn validate(&self, physical_device: &PhysicalDevice) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(
|
||||
&self,
|
||||
physical_device: &PhysicalDevice,
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
flags,
|
||||
format,
|
||||
@ -1796,12 +1808,12 @@ impl ImageFormatInfo {
|
||||
})?;
|
||||
|
||||
if usage.is_empty() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "usage".into(),
|
||||
problem: "is empty".into(),
|
||||
vuids: &["VUID-VkPhysicalDeviceImageFormatInfo2-usage-requiredbitmask"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
let has_separate_stencil_usage = if aspects
|
||||
@ -1820,7 +1832,7 @@ impl ImageFormatInfo {
|
||||
.supported_extensions()
|
||||
.ext_separate_stencil_usage)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`stencil_usage` is `Some`, and `format` has both a depth and a \
|
||||
stencil aspect"
|
||||
.into(),
|
||||
@ -1829,7 +1841,7 @@ impl ImageFormatInfo {
|
||||
RequiresAllOf(&[Requires::DeviceExtension("ext_separate_stencil_usage")]),
|
||||
]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
stencil_usage
|
||||
@ -1841,12 +1853,12 @@ impl ImageFormatInfo {
|
||||
})?;
|
||||
|
||||
if stencil_usage.is_empty() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "stencil_usage".into(),
|
||||
problem: "is empty".into(),
|
||||
vuids: &["VUID-VkImageStencilUsageCreateInfo-usage-requiredbitmask"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1857,7 +1869,7 @@ impl ImageFormatInfo {
|
||||
.enabled_extensions()
|
||||
.khr_external_memory_capabilities)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`external_memory_handle_type` is `Some`".into(),
|
||||
requires_one_of: RequiresOneOf(&[
|
||||
RequiresAllOf(&[Requires::APIVersion(Version::V1_1)]),
|
||||
@ -1866,7 +1878,7 @@ impl ImageFormatInfo {
|
||||
)]),
|
||||
]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
handle_type
|
||||
@ -1880,13 +1892,13 @@ impl ImageFormatInfo {
|
||||
|
||||
if let Some(image_view_type) = image_view_type {
|
||||
if !physical_device.supported_extensions().ext_filter_cubic {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`image_view_type` is `Some`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::DeviceExtension(
|
||||
"ext_filter_cubic",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
image_view_type
|
||||
@ -1905,14 +1917,14 @@ impl ImageFormatInfo {
|
||||
.supported_extensions()
|
||||
.ext_image_drm_format_modifier
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "drm_format_modifier_info".into(),
|
||||
problem: "is `Some`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::DeviceExtension(
|
||||
"ext_image_drm_format_modifier",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
drm_format_modifier_info
|
||||
@ -1920,32 +1932,32 @@ impl ImageFormatInfo {
|
||||
.map_err(|err| err.add_context("drm_format_modifier_info"))?;
|
||||
|
||||
if tiling != ImageTiling::DrmFormatModifier {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`drm_format_modifier_info` is `Some` but \
|
||||
`tiling` is not `ImageTiling::DrmFormatModifier`"
|
||||
.into(),
|
||||
vuids: &[" VUID-VkPhysicalDeviceImageFormatInfo2-tiling-02249"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if flags.intersects(ImageCreateFlags::MUTABLE_FORMAT) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`tiling` is `ImageTiling::DrmFormatModifier`, but \
|
||||
`flags` contains `ImageCreateFlags::MUTABLE_FORMAT`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkPhysicalDeviceImageFormatInfo2-tiling-02313"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
} else if tiling == ImageTiling::DrmFormatModifier {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`tiling` is `ImageTiling::DrmFormatModifier`, but \
|
||||
`drm_format_modifier_info` is `None`"
|
||||
.into(),
|
||||
vuids: &[" VUID-VkPhysicalDeviceImageFormatInfo2-tiling-02249"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -1981,7 +1993,10 @@ impl Default for ImageDrmFormatModifierInfo {
|
||||
}
|
||||
|
||||
impl ImageDrmFormatModifierInfo {
|
||||
pub(crate) fn validate(&self, physical_device: &PhysicalDevice) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(
|
||||
&self,
|
||||
physical_device: &PhysicalDevice,
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
drm_format_modifier: _,
|
||||
ref sharing,
|
||||
@ -1992,7 +2007,7 @@ impl ImageDrmFormatModifierInfo {
|
||||
Sharing::Exclusive => (),
|
||||
Sharing::Concurrent(queue_family_indices) => {
|
||||
if queue_family_indices.len() < 2 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "sharing".into(),
|
||||
problem: "is `Sharing::Concurrent`, but contains less than 2 elements"
|
||||
.into(),
|
||||
@ -2000,14 +2015,14 @@ impl ImageDrmFormatModifierInfo {
|
||||
"VUID-VkPhysicalDeviceImageDrmFormatModifierInfoEXT-sharingMode-02315",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
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) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "queue_family_indices".into(),
|
||||
problem: format!(
|
||||
"the queue family index in the list at index {} is contained in \
|
||||
@ -2017,17 +2032,17 @@ impl ImageDrmFormatModifierInfo {
|
||||
.into(),
|
||||
vuids: &[" VUID-VkPhysicalDeviceImageDrmFormatModifierInfoEXT-sharingMode-02316"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if queue_family_index >= queue_family_count {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("sharing[{}]", index).into(),
|
||||
problem: "is not less than the number of queue families in the device"
|
||||
.into(),
|
||||
vuids: &[" VUID-VkPhysicalDeviceImageDrmFormatModifierInfoEXT-sharingMode-02316"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2139,7 +2154,10 @@ impl Default for SparseImageFormatInfo {
|
||||
}
|
||||
|
||||
impl SparseImageFormatInfo {
|
||||
pub(crate) fn validate(&self, physical_device: &PhysicalDevice) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(
|
||||
&self,
|
||||
physical_device: &PhysicalDevice,
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
format,
|
||||
image_type,
|
||||
@ -2189,12 +2207,12 @@ impl SparseImageFormatInfo {
|
||||
})?;
|
||||
|
||||
if usage.is_empty() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "usage".into(),
|
||||
problem: "is empty".into(),
|
||||
vuids: &["VUID-VkPhysicalDeviceSparseImageFormatInfo2-usage-requiredbitmask"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
tiling
|
||||
|
@ -58,8 +58,7 @@ use crate::{
|
||||
macros::{impl_id_counter, vulkan_enum},
|
||||
pipeline::graphics::depth_stencil::CompareOp,
|
||||
shader::ShaderScalarType,
|
||||
Requires, RequiresAllOf, RequiresOneOf, RuntimeError, ValidationError, VulkanError,
|
||||
VulkanObject,
|
||||
Requires, RequiresAllOf, RequiresOneOf, Validated, ValidationError, VulkanError, VulkanObject,
|
||||
};
|
||||
use std::{mem::MaybeUninit, num::NonZeroU64, ops::RangeInclusive, ptr, sync::Arc};
|
||||
|
||||
@ -118,7 +117,7 @@ impl Sampler {
|
||||
pub fn new(
|
||||
device: Arc<Device>,
|
||||
create_info: SamplerCreateInfo,
|
||||
) -> Result<Arc<Sampler>, VulkanError> {
|
||||
) -> Result<Arc<Sampler>, Validated<VulkanError>> {
|
||||
Self::validate_new(&device, &create_info)?;
|
||||
|
||||
unsafe { Ok(Self::new_unchecked(device, create_info)?) }
|
||||
@ -127,7 +126,7 @@ impl Sampler {
|
||||
fn validate_new(
|
||||
device: &Device,
|
||||
create_info: &SamplerCreateInfo,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
create_info
|
||||
.validate(device)
|
||||
.map_err(|err| err.add_context("create_info"))?;
|
||||
@ -139,7 +138,7 @@ impl Sampler {
|
||||
pub unsafe fn new_unchecked(
|
||||
device: Arc<Device>,
|
||||
create_info: SamplerCreateInfo,
|
||||
) -> Result<Arc<Sampler>, RuntimeError> {
|
||||
) -> Result<Arc<Sampler>, VulkanError> {
|
||||
let &SamplerCreateInfo {
|
||||
mag_filter,
|
||||
min_filter,
|
||||
@ -223,7 +222,7 @@ impl Sampler {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
};
|
||||
|
||||
@ -281,7 +280,10 @@ impl Sampler {
|
||||
}
|
||||
|
||||
/// Checks whether this sampler is compatible with `image_view`.
|
||||
pub fn check_can_sample(&self, image_view: &ImageView) -> Result<(), ValidationError> {
|
||||
pub(crate) fn check_can_sample(
|
||||
&self,
|
||||
image_view: &ImageView,
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
/*
|
||||
NOTE: Most of these checks come from the Instruction/Sampler/Image View Validation
|
||||
section, and are not strictly VUIDs.
|
||||
@ -294,13 +296,13 @@ impl Sampler {
|
||||
.format_features()
|
||||
.intersects(FormatFeatures::SAMPLED_IMAGE_DEPTH_COMPARISON)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the sampler has depth comparison enabled, and \
|
||||
the image view's format features do not include \
|
||||
`FormatFeatures::SAMPLED_IMAGE_DEPTH_COMPARISON`"
|
||||
.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// The SPIR-V instruction is one of the OpImage*Dref* instructions, the image
|
||||
@ -311,12 +313,12 @@ impl Sampler {
|
||||
.aspects
|
||||
.intersects(ImageAspects::DEPTH)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the sampler has depth comparison enabled, and \
|
||||
the image view's aspects do not include `ImageAspects::DEPTH`"
|
||||
.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
} else {
|
||||
if !image_view
|
||||
@ -325,24 +327,24 @@ impl Sampler {
|
||||
{
|
||||
// VUID-vkCmdDispatch-magFilter-04553
|
||||
if self.mag_filter == Filter::Linear || self.min_filter == Filter::Linear {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the sampler's `mag_filter` or `min_filter` is `Filter::Linear`, \
|
||||
and the image view's format features do not include \
|
||||
`FormatFeatures::SAMPLED_IMAGE_FILTER_LINEAR`"
|
||||
.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// VUID-vkCmdDispatch-mipmapMode-04770
|
||||
if self.mipmap_mode == SamplerMipmapMode::Linear {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the sampler's `mipmap_mode` is `SamplerMipmapMpde::Linear`, and \
|
||||
the image view's format features do not include \
|
||||
`FormatFeatures::SAMPLED_IMAGE_FILTER_LINEAR`"
|
||||
.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -353,24 +355,24 @@ impl Sampler {
|
||||
.format_features()
|
||||
.intersects(FormatFeatures::SAMPLED_IMAGE_FILTER_CUBIC)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the sampler's `mag_filter` or `min_filter` is `Filter::Cubic`, and \
|
||||
the image view's format features do not include \
|
||||
`FormatFeatures::SAMPLED_IMAGE_FILTER_CUBIC`"
|
||||
.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// VUID-vkCmdDispatch-filterCubic-02694
|
||||
if !image_view.filter_cubic() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the sampler's `mag_filter` or `min_filter` is Filter::Cubic, and \
|
||||
the image view does not support this, as returned by \
|
||||
`PhysicalDevice::image_format_properties`"
|
||||
.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// VUID-vkCmdDispatch-filterCubicMinmax-02695
|
||||
@ -379,7 +381,7 @@ impl Sampler {
|
||||
SamplerReductionMode::Min | SamplerReductionMode::Max
|
||||
) && !image_view.filter_cubic_minmax()
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the sampler's `mag_filter` or `min_filter` is `Filter::Cubic`, and \
|
||||
the its `reduction_mode` is `SamplerReductionMode::Min` or \
|
||||
`SamplerReductionMode::Max`, and \
|
||||
@ -387,7 +389,7 @@ impl Sampler {
|
||||
`PhysicalDevice::image_format_properties`"
|
||||
.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -423,12 +425,12 @@ impl Sampler {
|
||||
view_scalar_type,
|
||||
ShaderScalarType::Sint | ShaderScalarType::Uint
|
||||
) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the sampler has an integer border color, and \
|
||||
the image view does not have an integer format"
|
||||
.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
BorderColor::FloatTransparentBlack
|
||||
@ -438,12 +440,12 @@ impl Sampler {
|
||||
// format is not one of the VkFormat float types or a depth
|
||||
// component of a depth/stencil format.
|
||||
if !matches!(view_scalar_type, ShaderScalarType::Float) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the sampler has an floating-point border color, and \
|
||||
the image view does not have a floating-point format"
|
||||
.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -460,12 +462,12 @@ impl Sampler {
|
||||
BorderColor::FloatOpaqueBlack | BorderColor::IntOpaqueBlack
|
||||
) && !image_view.component_mapping().is_identity()
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the sampler has an opaque black border color, and \
|
||||
the image view is not identity swizzled"
|
||||
.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -480,13 +482,13 @@ impl Sampler {
|
||||
image_view.view_type(),
|
||||
ImageViewType::Dim1d | ImageViewType::Dim2d
|
||||
) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the sampler uses unnormalized coordinates, and \
|
||||
the image view's type is not `ImageViewtype::Dim1d` or \
|
||||
`ImageViewType::Dim2d`"
|
||||
.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// The image view must have a single layer and a single mip level.
|
||||
@ -494,12 +496,12 @@ impl Sampler {
|
||||
- image_view.subresource_range().mip_levels.start
|
||||
!= 1
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the sampler uses unnormalized coordinates, and \
|
||||
the image view has more than one mip level"
|
||||
.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -797,7 +799,7 @@ impl SamplerCreateInfo {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
mag_filter,
|
||||
min_filter,
|
||||
@ -875,7 +877,7 @@ impl SamplerCreateInfo {
|
||||
if !(device.enabled_features().sampler_mirror_clamp_to_edge
|
||||
|| device.enabled_extensions().khr_sampler_mirror_clamp_to_edge)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "address_mode".into(),
|
||||
problem: "contains `SamplerAddressMode::MirrorClampToEdge`".into(),
|
||||
requires_one_of: RequiresOneOf(&[
|
||||
@ -885,34 +887,34 @@ impl SamplerCreateInfo {
|
||||
)]),
|
||||
]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
if lod.is_empty() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "lod".into(),
|
||||
problem: "is empty".into(),
|
||||
vuids: &["VUID-VkSamplerCreateInfo-maxLod-01973"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if mip_lod_bias.abs() > properties.max_sampler_lod_bias {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "lod".into(),
|
||||
problem: "the absolute value is greater than the `max_sampler_lod_bias` limit"
|
||||
.into(),
|
||||
vuids: &["VUID-VkSamplerCreateInfo-mipLodBias-01069"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if device.enabled_extensions().khr_portability_subset
|
||||
&& !device.enabled_features().sampler_mip_lod_bias
|
||||
&& mip_lod_bias != 0.0
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "this device is a portability subset device, and \
|
||||
`mip_lod_bias` is not zero"
|
||||
.into(),
|
||||
@ -921,47 +923,47 @@ impl SamplerCreateInfo {
|
||||
)])]),
|
||||
vuids: &["VUID-VkSamplerCreateInfo-samplerMipLodBias-04467"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if let Some(max_anisotropy) = anisotropy {
|
||||
if !device.enabled_features().sampler_anisotropy {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "anisotropy".into(),
|
||||
problem: "is `Some`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"sampler_anisotropy",
|
||||
)])]),
|
||||
vuids: &["VUID-VkSamplerCreateInfo-anisotropyEnable-01070"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if max_anisotropy < 1.0 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "anisotropy".into(),
|
||||
problem: "is less than 1.0".into(),
|
||||
vuids: &["VUID-VkSamplerCreateInfo-anisotropyEnable-01071"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if max_anisotropy > properties.max_sampler_anisotropy {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "anisotropy".into(),
|
||||
problem: "is greater than the `max_sampler_anisotropy` limit".into(),
|
||||
vuids: &["VUID-VkSamplerCreateInfo-anisotropyEnable-01071"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if [mag_filter, min_filter].contains(&Filter::Cubic) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`anisotropy` is `Some`, but `mag_filter` or `min_filter` is \
|
||||
`Filter::Cubic`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkSamplerCreateInfo-magFilter-01081"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -975,45 +977,45 @@ impl SamplerCreateInfo {
|
||||
})?;
|
||||
|
||||
if reduction_mode != SamplerReductionMode::WeightedAverage {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`compare` is `Some`, but `reduction_mode` is not \
|
||||
`SamplerReductionMode::WeightedAverage`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkSamplerCreateInfo-compareEnable-01423"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
if unnormalized_coordinates {
|
||||
if min_filter != mag_filter {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`unnormalized_coordinates` is `true`, but \
|
||||
`min_filter` and `mag_filter` are not equal"
|
||||
.into(),
|
||||
vuids: &["VUID-VkSamplerCreateInfo-unnormalizedCoordinates-01072"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if mipmap_mode != SamplerMipmapMode::Nearest {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`unnormalized_coordinates` is `true`, but \
|
||||
`mipmap_mode` is not `SamplerMipmapMode::Nearest`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkSamplerCreateInfo-unnormalizedCoordinates-01073"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if *lod != (0.0..=0.0) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`unnormalized_coordinates` is `true`, but \
|
||||
`lod` is not `0.0..=1.0`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkSamplerCreateInfo-unnormalizedCoordinates-01074"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if address_mode[0..2].iter().any(|mode| {
|
||||
@ -1022,31 +1024,31 @@ impl SamplerCreateInfo {
|
||||
SamplerAddressMode::ClampToEdge | SamplerAddressMode::ClampToBorder
|
||||
)
|
||||
}) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`unnormalized_coordinates` is `true`, but \
|
||||
`address_mode[0]` or `address_mode[1]` are not \
|
||||
`SamplerAddressMode::ClampToEdge` or `SamplerAddressMode::ClampToBorder`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkSamplerCreateInfo-unnormalizedCoordinates-01075"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if anisotropy.is_some() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`unnormalized_coordinates` is `true`, but `anisotropy` is `Some`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkSamplerCreateInfo-unnormalizedCoordinates-01076"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if compare.is_some() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`unnormalized_coordinates` is `true`, but `compare` is `Some`".into(),
|
||||
vuids: &["VUID-VkSamplerCreateInfo-unnormalizedCoordinates-0107"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1054,7 +1056,7 @@ impl SamplerCreateInfo {
|
||||
if !(device.enabled_features().sampler_filter_minmax
|
||||
|| device.enabled_extensions().ext_sampler_filter_minmax)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "reduction_mode".into(),
|
||||
problem: "is not `SamplerReductionMode::WeightedAverage`".into(),
|
||||
requires_one_of: RequiresOneOf(&[
|
||||
@ -1062,7 +1064,7 @@ impl SamplerCreateInfo {
|
||||
RequiresAllOf(&[Requires::DeviceExtension("ext_sampler_filter_minmax")]),
|
||||
]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1084,7 +1086,7 @@ impl SamplerCreateInfo {
|
||||
) && !(mag_filter == sampler_ycbcr_conversion.chroma_filter()
|
||||
&& min_filter == sampler_ycbcr_conversion.chroma_filter())
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`sampler_ycbcr_conversion` is `Some`, and \
|
||||
the potential format features of `sampler_ycbcr_conversion.format()` \
|
||||
do not include `FormatFeatures::\
|
||||
@ -1094,51 +1096,51 @@ impl SamplerCreateInfo {
|
||||
.into(),
|
||||
vuids: &["VUID-VkSamplerCreateInfo-minFilter-01645"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if address_mode
|
||||
.into_iter()
|
||||
.any(|mode| !matches!(mode, SamplerAddressMode::ClampToEdge))
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`sampler_ycbcr_conversion` is `Some`, but \
|
||||
not all elements of `address_mode` are \
|
||||
`SamplerAddressMode::ClampToEdge`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkSamplerCreateInfo-addressModeU-01646"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if anisotropy.is_some() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`sampler_ycbcr_conversion` is `Some`, but \
|
||||
`anisotropy` is `Some`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkSamplerCreateInfo-addressModeU-01646"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if unnormalized_coordinates {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`sampler_ycbcr_conversion` is `Some`, but \
|
||||
`unnormalized_coordinates` is `true`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkSamplerCreateInfo-addressModeU-01646"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if reduction_mode != SamplerReductionMode::WeightedAverage {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`sampler_ycbcr_conversion` is `Some`, but \
|
||||
`reduction_mode` is not `SamplerReductionMode::WeightedAverage`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkSamplerCreateInfo-None-01647"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1248,7 +1250,7 @@ impl ComponentMapping {
|
||||
]
|
||||
}
|
||||
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self { r, g, b, a } = self;
|
||||
|
||||
r.validate_device(device).map_err(|err| ValidationError {
|
||||
@ -1493,7 +1495,7 @@ mod tests {
|
||||
Filter, Sampler, SamplerAddressMode, SamplerCreateInfo, SamplerReductionMode,
|
||||
},
|
||||
pipeline::graphics::depth_stencil::CompareOp,
|
||||
Requires, RequiresAllOf, RequiresOneOf, ValidationError, VulkanError,
|
||||
Requires, RequiresAllOf, RequiresOneOf, Validated, ValidationError,
|
||||
};
|
||||
|
||||
#[test]
|
||||
@ -1628,7 +1630,7 @@ mod tests {
|
||||
);
|
||||
|
||||
match r {
|
||||
Err(VulkanError::ValidationError(_)) => (),
|
||||
Err(Validated::ValidationError(_)) => (),
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
@ -1651,7 +1653,7 @@ mod tests {
|
||||
);
|
||||
|
||||
match r {
|
||||
Err(VulkanError::ValidationError(_)) => (),
|
||||
Err(Validated::ValidationError(_)) => (),
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
@ -1673,7 +1675,7 @@ mod tests {
|
||||
);
|
||||
|
||||
match r {
|
||||
Err(VulkanError::ValidationError(_)) => (),
|
||||
Err(Validated::ValidationError(_)) => (),
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
@ -1695,15 +1697,19 @@ mod tests {
|
||||
);
|
||||
|
||||
match r {
|
||||
Err(VulkanError::ValidationError(ValidationError {
|
||||
requires_one_of:
|
||||
RequiresOneOf(
|
||||
[RequiresAllOf([Requires::Feature("sampler_mirror_clamp_to_edge")]), RequiresAllOf(
|
||||
[Requires::DeviceExtension("khr_sampler_mirror_clamp_to_edge")],
|
||||
)],
|
||||
),
|
||||
..
|
||||
})) => {}
|
||||
Err(Validated::ValidationError(err))
|
||||
if matches!(
|
||||
*err,
|
||||
ValidationError {
|
||||
requires_one_of: RequiresOneOf([
|
||||
RequiresAllOf([Requires::Feature("sampler_mirror_clamp_to_edge")]),
|
||||
RequiresAllOf([Requires::DeviceExtension(
|
||||
"khr_sampler_mirror_clamp_to_edge"
|
||||
)],)
|
||||
],),
|
||||
..
|
||||
}
|
||||
) => {}
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
@ -1723,13 +1729,17 @@ mod tests {
|
||||
);
|
||||
|
||||
match r {
|
||||
Err(VulkanError::ValidationError(ValidationError {
|
||||
requires_one_of:
|
||||
RequiresOneOf(
|
||||
[RequiresAllOf([Requires::Feature("sampler_filter_minmax")]), RequiresAllOf([Requires::DeviceExtension("ext_sampler_filter_minmax")])],
|
||||
),
|
||||
..
|
||||
})) => {}
|
||||
Err(Validated::ValidationError(err))
|
||||
if matches!(
|
||||
*err,
|
||||
ValidationError {
|
||||
requires_one_of: RequiresOneOf([
|
||||
RequiresAllOf([Requires::Feature("sampler_filter_minmax")]),
|
||||
RequiresAllOf([Requires::DeviceExtension("ext_sampler_filter_minmax")])
|
||||
],),
|
||||
..
|
||||
}
|
||||
) => {}
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ use crate::{
|
||||
image::sampler::{ComponentMapping, ComponentSwizzle, Filter},
|
||||
instance::InstanceOwnedDebugWrapper,
|
||||
macros::{impl_id_counter, vulkan_enum},
|
||||
Requires, RequiresAllOf, RequiresOneOf, RuntimeError, ValidationError, Version, VulkanError,
|
||||
Requires, RequiresAllOf, RequiresOneOf, Validated, ValidationError, Version, VulkanError,
|
||||
VulkanObject,
|
||||
};
|
||||
use std::{mem::MaybeUninit, num::NonZeroU64, ptr, sync::Arc};
|
||||
@ -145,7 +145,7 @@ impl SamplerYcbcrConversion {
|
||||
pub fn new(
|
||||
device: Arc<Device>,
|
||||
create_info: SamplerYcbcrConversionCreateInfo,
|
||||
) -> Result<Arc<SamplerYcbcrConversion>, VulkanError> {
|
||||
) -> Result<Arc<SamplerYcbcrConversion>, Validated<VulkanError>> {
|
||||
Self::validate_new(&device, &create_info)?;
|
||||
|
||||
unsafe { Ok(Self::new_unchecked(device, create_info)?) }
|
||||
@ -154,15 +154,15 @@ impl SamplerYcbcrConversion {
|
||||
fn validate_new(
|
||||
device: &Device,
|
||||
create_info: &SamplerYcbcrConversionCreateInfo,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
if !device.enabled_features().sampler_ycbcr_conversion {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"sampler_ycbcr_conversion",
|
||||
)])]),
|
||||
vuids: &["VUID-vkCreateSamplerYcbcrConversion-None-01648"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
create_info
|
||||
@ -176,7 +176,7 @@ impl SamplerYcbcrConversion {
|
||||
pub unsafe fn new_unchecked(
|
||||
device: Arc<Device>,
|
||||
create_info: SamplerYcbcrConversionCreateInfo,
|
||||
) -> Result<Arc<SamplerYcbcrConversion>, RuntimeError> {
|
||||
) -> Result<Arc<SamplerYcbcrConversion>, VulkanError> {
|
||||
let &SamplerYcbcrConversionCreateInfo {
|
||||
format,
|
||||
ycbcr_model,
|
||||
@ -217,7 +217,7 @@ impl SamplerYcbcrConversion {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
};
|
||||
|
||||
@ -456,7 +456,7 @@ impl Default for SamplerYcbcrConversionCreateInfo {
|
||||
}
|
||||
|
||||
impl SamplerYcbcrConversionCreateInfo {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
format,
|
||||
ycbcr_model,
|
||||
@ -527,12 +527,12 @@ impl SamplerYcbcrConversionCreateInfo {
|
||||
.type_color()
|
||||
.map_or(false, |ty| ty == NumericType::UNORM)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "format".into(),
|
||||
problem: "the numeric type is not `UNORM`".into(),
|
||||
vuids: &["VUID-VkSamplerYcbcrConversionCreateInfo-format-04061"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// Use unchecked, because all validation has been done above.
|
||||
@ -546,7 +546,7 @@ impl SamplerYcbcrConversionCreateInfo {
|
||||
if !potential_format_features.intersects(
|
||||
FormatFeatures::MIDPOINT_CHROMA_SAMPLES | FormatFeatures::COSITED_CHROMA_SAMPLES,
|
||||
) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "format".into(),
|
||||
problem: "the potential format features do not contain \
|
||||
`FormatFeatures::MIDPOINT_CHROMA_SAMPLES` or \
|
||||
@ -554,7 +554,7 @@ impl SamplerYcbcrConversionCreateInfo {
|
||||
.into(),
|
||||
vuids: &["VUID-VkSamplerYcbcrConversionCreateInfo-format-01650"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if let Some(chroma_sampling @ (ChromaSampling::Mode422 | ChromaSampling::Mode420)) =
|
||||
@ -566,7 +566,7 @@ impl SamplerYcbcrConversionCreateInfo {
|
||||
&& !potential_format_features
|
||||
.intersects(FormatFeatures::COSITED_CHROMA_SAMPLES)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`format` has both horizontal and vertical chroma \
|
||||
subsampling, and \
|
||||
its potential format features do not \
|
||||
@ -576,14 +576,14 @@ impl SamplerYcbcrConversionCreateInfo {
|
||||
.into(),
|
||||
vuids: &["VUID-VkSamplerYcbcrConversionCreateInfo-xChromaOffset-01651"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if chroma_offset.contains(&ChromaLocation::Midpoint)
|
||||
&& !potential_format_features
|
||||
.intersects(FormatFeatures::MIDPOINT_CHROMA_SAMPLES)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`format` has both horizontal and vertical chroma \
|
||||
subsampling, and \
|
||||
its potential format features do not \
|
||||
@ -593,7 +593,7 @@ impl SamplerYcbcrConversionCreateInfo {
|
||||
.into(),
|
||||
vuids: &["VUID-VkSamplerYcbcrConversionCreateInfo-xChromaOffset-01652"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
ChromaSampling::Mode422 => {
|
||||
@ -601,7 +601,7 @@ impl SamplerYcbcrConversionCreateInfo {
|
||||
&& !potential_format_features
|
||||
.intersects(FormatFeatures::COSITED_CHROMA_SAMPLES)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`format` has horizontal chroma subsampling, and \
|
||||
its potential format features do not \
|
||||
contain `FormatFeatures::COSITED_CHROMA_SAMPLES`, but \
|
||||
@ -610,14 +610,14 @@ impl SamplerYcbcrConversionCreateInfo {
|
||||
.into(),
|
||||
vuids: &["VUID-VkSamplerYcbcrConversionCreateInfo-xChromaOffset-01651"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if chroma_offset[0] == ChromaLocation::Midpoint
|
||||
&& !potential_format_features
|
||||
.intersects(FormatFeatures::MIDPOINT_CHROMA_SAMPLES)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`format` has horizontal chroma subsampling, and \
|
||||
its potential format features do not \
|
||||
contain `FormatFeatures::MIDPOINT_CHROMA_SAMPLES`, but \
|
||||
@ -626,20 +626,20 @@ impl SamplerYcbcrConversionCreateInfo {
|
||||
.into(),
|
||||
vuids: &["VUID-VkSamplerYcbcrConversionCreateInfo-xChromaOffset-01652"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
||||
if !component_mapping.g_is_identity() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`format` has chroma subsampling, but \
|
||||
`component_mapping.g` is not identity swizzled"
|
||||
.into(),
|
||||
vuids: &["VUID-VkSamplerYcbcrConversionCreateInfo-components-02581"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if !(component_mapping.a_is_identity()
|
||||
@ -648,7 +648,7 @@ impl SamplerYcbcrConversionCreateInfo {
|
||||
ComponentSwizzle::One | ComponentSwizzle::Zero
|
||||
))
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "component_mapping.a".into(),
|
||||
problem: "`format` has chroma subsampling, but \
|
||||
`component_mapping.a` is not identity swizzled, or \
|
||||
@ -656,33 +656,33 @@ impl SamplerYcbcrConversionCreateInfo {
|
||||
.into(),
|
||||
vuids: &["VUID-VkSamplerYcbcrConversionCreateInfo-components-02582"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if !(component_mapping.r_is_identity()
|
||||
|| matches!(component_mapping.r, ComponentSwizzle::Blue))
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`format` has chroma subsampling, but \
|
||||
`component_mapping.r` is not identity swizzled, or \
|
||||
`ComponentSwizzle::Blue`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkSamplerYcbcrConversionCreateInfo-components-02583"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if !(component_mapping.b_is_identity()
|
||||
|| matches!(component_mapping.b, ComponentSwizzle::Red))
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`format` has chroma subsampling, but \
|
||||
`component_mapping.b` is not identity swizzled, or \
|
||||
`ComponentSwizzle::Red`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkSamplerYcbcrConversionCreateInfo-components-02584"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
match (
|
||||
@ -690,24 +690,24 @@ impl SamplerYcbcrConversionCreateInfo {
|
||||
component_mapping.b_is_identity(),
|
||||
) {
|
||||
(true, false) => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`format` has chroma subsampling, and \
|
||||
`component_mapping.r` is identity swizzled, but \
|
||||
`component_mapping.b` is not identity swizzled"
|
||||
.into(),
|
||||
vuids: &["VUID-VkSamplerYcbcrConversionCreateInfo-components-02585"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
(false, true) => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`format` has chroma subsampling, and \
|
||||
`component_mapping.b` is identity swizzled, but \
|
||||
`component_mapping.r` is not identity swizzled"
|
||||
.into(),
|
||||
vuids: &["VUID-VkSamplerYcbcrConversionCreateInfo-components-02585"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
@ -723,47 +723,47 @@ impl SamplerYcbcrConversionCreateInfo {
|
||||
// VUID-VkSamplerYcbcrConversionCreateInfo-ycbcrModel-01655
|
||||
if ycbcr_model != SamplerYcbcrModelConversion::RgbIdentity {
|
||||
if components_bits[0].map_or(true, |bits| bits == 0) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`ycbcr_model` is not `SamplerYcbcrModelConversion::RgbIdentity`, \
|
||||
and `component_mapping.r` does not map to a component that exists in \
|
||||
`format`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkSamplerYcbcrConversionCreateInfo-components-02585"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if components_bits[1].map_or(true, |bits| bits == 0) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`ycbcr_model` is not `SamplerYcbcrModelConversion::RgbIdentity`, \
|
||||
and `component_mapping.g` does not map to a component that exists in \
|
||||
`format`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkSamplerYcbcrConversionCreateInfo-components-02585"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if components_bits[2].map_or(true, |bits| bits == 0) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`ycbcr_model` is not `SamplerYcbcrModelConversion::RgbIdentity`, \
|
||||
and `component_mapping.b` does not map to a component that exists in \
|
||||
`format`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkSamplerYcbcrConversionCreateInfo-components-02585"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if components_bits[3].map_or(true, |bits| bits == 0) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`ycbcr_model` is not `SamplerYcbcrModelConversion::RgbIdentity`, \
|
||||
and `component_mapping.a` does not map to a component that exists in \
|
||||
`format`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkSamplerYcbcrConversionCreateInfo-components-02585"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -772,47 +772,47 @@ impl SamplerYcbcrConversionCreateInfo {
|
||||
// just skip them for now.
|
||||
|
||||
if components_bits[0].map_or(false, |bits| bits < 8) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`ycbcr_range` is `SamplerYcbcrRange::ItuNarrow`, and \
|
||||
`component_mapping.r` maps to a component in `format` with less than \
|
||||
8 bits"
|
||||
.into(),
|
||||
vuids: &["VUID-VkSamplerYcbcrConversionCreateInfo-ycbcrRange-02748"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if components_bits[1].map_or(false, |bits| bits < 8) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`ycbcr_range` is `SamplerYcbcrRange::ItuNarrow`, and \
|
||||
`component_mapping.g` maps to a component in `format` with less than \
|
||||
8 bits"
|
||||
.into(),
|
||||
vuids: &["VUID-VkSamplerYcbcrConversionCreateInfo-ycbcrRange-02748"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if components_bits[2].map_or(false, |bits| bits < 8) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`ycbcr_range` is `SamplerYcbcrRange::ItuNarrow`, and \
|
||||
`component_mapping.b` maps to a component in `format` with less than \
|
||||
8 bits"
|
||||
.into(),
|
||||
vuids: &["VUID-VkSamplerYcbcrConversionCreateInfo-ycbcrRange-02748"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if components_bits[3].map_or(false, |bits| bits < 8) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`ycbcr_range` is `SamplerYcbcrRange::ItuNarrow`, and \
|
||||
`component_mapping.a` maps to a component in `format` with less than \
|
||||
8 bits"
|
||||
.into(),
|
||||
vuids: &["VUID-VkSamplerYcbcrConversionCreateInfo-ycbcrRange-02748"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -820,14 +820,14 @@ impl SamplerYcbcrConversionCreateInfo {
|
||||
&& !potential_format_features.intersects(FormatFeatures::
|
||||
SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`force_explicit_reconstruction` is `true`, but the \
|
||||
potential format features of `format` do not include `FormatFeatures::\
|
||||
SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkSamplerYcbcrConversionCreateInfo-forceExplicitReconstruction-01656"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
match chroma_filter {
|
||||
@ -836,23 +836,23 @@ impl SamplerYcbcrConversionCreateInfo {
|
||||
if !potential_format_features
|
||||
.intersects(FormatFeatures::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`chroma_filter` is `Filter::Linear`, but the \
|
||||
potential format features of `format` do not include `FormatFeatures::\
|
||||
SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkSamplerYcbcrConversionCreateInfo-chromaFilter-01657"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
Filter::Cubic => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "chroma_filter".into(),
|
||||
problem: "is `Filter::Cubic`".into(),
|
||||
// vuids?
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -918,7 +918,7 @@ vulkan_enum! {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::SamplerYcbcrConversion;
|
||||
use crate::{Requires, RequiresAllOf, RequiresOneOf, ValidationError, VulkanError};
|
||||
use crate::{Requires, RequiresAllOf, RequiresOneOf, Validated, ValidationError};
|
||||
|
||||
#[test]
|
||||
fn feature_not_enabled() {
|
||||
@ -927,11 +927,16 @@ mod tests {
|
||||
let r = SamplerYcbcrConversion::new(device, Default::default());
|
||||
|
||||
match r {
|
||||
Err(VulkanError::ValidationError(ValidationError {
|
||||
requires_one_of:
|
||||
RequiresOneOf([RequiresAllOf([Requires::Feature("sampler_ycbcr_conversion")])]),
|
||||
..
|
||||
})) => (),
|
||||
Err(Validated::ValidationError(err))
|
||||
if matches!(
|
||||
*err,
|
||||
ValidationError {
|
||||
requires_one_of: RequiresOneOf([RequiresAllOf([Requires::Feature(
|
||||
"sampler_ycbcr_conversion"
|
||||
)])]),
|
||||
..
|
||||
}
|
||||
) => {}
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -26,7 +26,7 @@ use crate::{
|
||||
ImageAspects, ImageCreateFlags, ImageTiling, ImageType, SampleCount,
|
||||
},
|
||||
macros::{impl_id_counter, vulkan_enum},
|
||||
Requires, RequiresAllOf, RequiresOneOf, RuntimeError, ValidationError, Version, VulkanError,
|
||||
Requires, RequiresAllOf, RequiresOneOf, Validated, ValidationError, Version, VulkanError,
|
||||
VulkanObject,
|
||||
};
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
@ -61,7 +61,7 @@ impl ImageView {
|
||||
pub fn new(
|
||||
image: Arc<Image>,
|
||||
create_info: ImageViewCreateInfo,
|
||||
) -> Result<Arc<ImageView>, VulkanError> {
|
||||
) -> Result<Arc<ImageView>, Validated<VulkanError>> {
|
||||
Self::validate_new(&image, &create_info)?;
|
||||
|
||||
unsafe { Ok(Self::new_unchecked(image, create_info)?) }
|
||||
@ -70,7 +70,7 @@ impl ImageView {
|
||||
fn validate_new(
|
||||
image: &Image,
|
||||
create_info: &ImageViewCreateInfo,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
let device = image.device();
|
||||
|
||||
create_info
|
||||
@ -91,47 +91,47 @@ impl ImageView {
|
||||
let format_features = unsafe { get_format_features(format, image) };
|
||||
|
||||
if format_features.is_empty() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "create_info.format".into(),
|
||||
problem: "the format features are empty".into(),
|
||||
vuids: &["VUID-VkImageViewCreateInfo-None-02273"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
let image_type = image.image_type();
|
||||
|
||||
if !view_type.is_compatible_with(image_type) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`create_info.view_type` is not compatible with \
|
||||
`image.image_type()`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkImageViewCreateInfo-subResourceRange-01021"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if subresource_range.mip_levels.end > image.mip_levels() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`create_info.subresource_range.mip_levels.end` is greater than \
|
||||
`image.mip_levels()`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkImageViewCreateInfo-subresourceRange-01718"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if matches!(view_type, ImageViewType::Cube | ImageViewType::CubeArray)
|
||||
&& !image.flags().intersects(ImageCreateFlags::CUBE_COMPATIBLE)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`create_info.view_type` is `ImageViewType::Cube` or \
|
||||
`ImageViewType::CubeArray`, but \
|
||||
`image.flags()` does not contain `ImageCreateFlags::CUBE_COMPATIBLE`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkImageViewCreateInfo-image-01003"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if matches!(view_type, ImageViewType::Dim2d | ImageViewType::Dim2dArray)
|
||||
@ -143,7 +143,7 @@ impl ImageView {
|
||||
.flags()
|
||||
.intersects(ImageCreateFlags::DIM2D_ARRAY_COMPATIBLE)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`create_info.view_type` is `ImageViewType::Dim2d`, and \
|
||||
`image.image_type()` is `ImageType::Dim3d`, but \
|
||||
`image.flags()` does not contain \
|
||||
@ -152,7 +152,7 @@ impl ImageView {
|
||||
.into(),
|
||||
vuids: &["VUID-VkImageViewCreateInfo-image-06728"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
ImageViewType::Dim2dArray => {
|
||||
@ -160,7 +160,7 @@ impl ImageView {
|
||||
.flags()
|
||||
.intersects(ImageCreateFlags::DIM2D_ARRAY_COMPATIBLE)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`create_info.view_type` is `ImageViewType::Dim2dArray`, and \
|
||||
`image.image_type()` is `ImageType::Dim3d`, but \
|
||||
`image.flags()` does not contain \
|
||||
@ -168,14 +168,14 @@ impl ImageView {
|
||||
.into(),
|
||||
vuids: &["VUID-VkImageViewCreateInfo-image-06723"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
||||
if subresource_range.mip_levels.len() != 1 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`create_info.view_type` is `ImageViewType::Dim2d` or \
|
||||
`ImageViewType::Dim2dArray`, and \
|
||||
`image.image_type()` is `ImageType::Dim3d`, but \
|
||||
@ -183,7 +183,7 @@ impl ImageView {
|
||||
.into(),
|
||||
vuids: &["VUID-VkImageViewCreateInfo-image-04970"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// We're using the depth dimension as array layers, but because of mip scaling, the
|
||||
@ -193,7 +193,7 @@ impl ImageView {
|
||||
mip_level_extent(image.extent(), subresource_range.mip_levels.start).unwrap();
|
||||
|
||||
if subresource_range.array_layers.end > mip_level_extent[2] {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`create_info.view_type` is `ImageViewType::Dim2d` or \
|
||||
`ImageViewType::Dim2dArray`, and \
|
||||
`image.image_type()` is `ImageType::Dim3d`, but \
|
||||
@ -206,11 +206,11 @@ impl ImageView {
|
||||
"VUID-VkImageViewCreateInfo-subresourceRange-02725",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
} else {
|
||||
if subresource_range.array_layers.end > image.array_layers() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`create_info.subresource_range.array_layers.end` is greater than \
|
||||
`image.array_layers()`"
|
||||
.into(),
|
||||
@ -219,21 +219,21 @@ impl ImageView {
|
||||
"VUID-VkImageViewCreateInfo-subresourceRange-06725",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
if image.samples() != SampleCount::Sample1
|
||||
&& !matches!(view_type, ImageViewType::Dim2d | ImageViewType::Dim2dArray)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`image.samples()` is not `SampleCount::Sample1`, but \
|
||||
`create_info.view_type` is not `ImageViewType::Dim2d` or \
|
||||
`ImageViewType::Dim2dArray`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkImageViewCreateInfo-image-04972"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
/* Check usage requirements */
|
||||
@ -251,7 +251,7 @@ impl ImageView {
|
||||
if !(device.api_version() >= Version::V1_1
|
||||
|| device.enabled_extensions().khr_maintenance2)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`create_info.usage` is not the implicit default usage \
|
||||
(calculated from `image` and `create_info.subresource_range.aspects`)"
|
||||
.into(),
|
||||
@ -260,7 +260,7 @@ impl ImageView {
|
||||
RequiresAllOf(&[Requires::DeviceExtension("khr_maintenance2")]),
|
||||
]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// VUID-VkImageViewUsageCreateInfo-usage-requiredbitmask
|
||||
@ -268,7 +268,7 @@ impl ImageView {
|
||||
// (which is already validated to not be empty).
|
||||
|
||||
if !implicit_default_usage.contains(usage) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`create_info.usage` is not a subset of the implicit default usage \
|
||||
(calculated from `image` and `create_info.subresource_range.aspects`)"
|
||||
.into(),
|
||||
@ -278,7 +278,7 @@ impl ImageView {
|
||||
"VUID-VkImageViewCreateInfo-pNext-02664",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -290,7 +290,7 @@ impl ImageView {
|
||||
| ImageUsage::INPUT_ATTACHMENT
|
||||
| ImageUsage::TRANSIENT_ATTACHMENT,
|
||||
) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "image.usage()".into(),
|
||||
problem: "does not contain one of `ImageUsage::SAMPLED`, `ImageUsage::STORAGE`, \
|
||||
`ImageUsage::COLOR_ATTACHMENT`, `ImageUsage::DEPTH_STENCIL_ATTACHMENT`, \
|
||||
@ -298,13 +298,13 @@ impl ImageView {
|
||||
.into(),
|
||||
vuids: &["VUID-VkImageViewCreateInfo-image-04441"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if usage.intersects(ImageUsage::SAMPLED)
|
||||
&& !format_features.intersects(FormatFeatures::SAMPLED_IMAGE)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`create_info.usage` or the implicit default usage \
|
||||
(calculated from `image` and `create_info.subresource_range.aspects`) \
|
||||
contains `ImageUsage::SAMPLED`, but \
|
||||
@ -313,13 +313,13 @@ impl ImageView {
|
||||
.into(),
|
||||
vuids: &["VUID-VkImageViewCreateInfo-usage-02274"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if usage.intersects(ImageUsage::STORAGE)
|
||||
&& !format_features.intersects(FormatFeatures::STORAGE_IMAGE)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`create_info.usage` or the implicit default usage \
|
||||
(calculated from `image` and `create_info.subresource_range.aspects`) \
|
||||
contains `ImageUsage::STORAGE`, but \
|
||||
@ -328,13 +328,13 @@ impl ImageView {
|
||||
.into(),
|
||||
vuids: &["VUID-VkImageViewCreateInfo-usage-02275"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if usage.intersects(ImageUsage::COLOR_ATTACHMENT)
|
||||
&& !format_features.intersects(FormatFeatures::COLOR_ATTACHMENT)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`create_info.usage` or the implicit default usage \
|
||||
(calculated from `image` and `create_info.subresource_range.aspects`) \
|
||||
contains `ImageUsage::COLOR_ATTACHMENT`, but \
|
||||
@ -343,13 +343,13 @@ impl ImageView {
|
||||
.into(),
|
||||
vuids: &["VUID-VkImageViewCreateInfo-usage-02276"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if usage.intersects(ImageUsage::DEPTH_STENCIL_ATTACHMENT)
|
||||
&& !format_features.intersects(FormatFeatures::DEPTH_STENCIL_ATTACHMENT)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`create_info.usage` or the implicit default usage \
|
||||
(calculated from `image` and `create_info.subresource_range.aspects`) \
|
||||
contains `ImageUsage::DEPTH_STENCIL_ATTACHMENT`, but \
|
||||
@ -358,7 +358,7 @@ impl ImageView {
|
||||
.into(),
|
||||
vuids: &["VUID-VkImageViewCreateInfo-usage-02277"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if usage.intersects(ImageUsage::INPUT_ATTACHMENT)
|
||||
@ -366,7 +366,7 @@ impl ImageView {
|
||||
FormatFeatures::COLOR_ATTACHMENT | FormatFeatures::DEPTH_STENCIL_ATTACHMENT,
|
||||
)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`create_info.usage` or the implicit default usage \
|
||||
(calculated from `image` and `create_info.subresource_range.aspects`) \
|
||||
contains `ImageUsage::INPUT_ATTACHMENT`, but \
|
||||
@ -376,7 +376,7 @@ impl ImageView {
|
||||
.into(),
|
||||
vuids: &["VUID-VkImageViewCreateInfo-usage-02652"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
/* Check flags requirements */
|
||||
@ -385,24 +385,24 @@ impl ImageView {
|
||||
if !image.format().unwrap().planes().is_empty()
|
||||
&& subresource_range.aspects.intersects(ImageAspects::COLOR)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`image.format()` is a multi-planar format, and \
|
||||
`create_info.subresource_range.aspects` contains `ImageAspects::COLOR`, \
|
||||
but `create_info.format` does not equal `image.format()`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkImageViewCreateInfo-image-01762"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if !image.flags().intersects(ImageCreateFlags::MUTABLE_FORMAT) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`create_info.format` does not equal `image.format()`, but \
|
||||
`image.flags()` does not contain `ImageCreateFlags::MUTABLE_FORMAT`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkImageViewCreateInfo-image-01762"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// TODO: it is unclear what the number of bits is for compressed formats.
|
||||
@ -411,7 +411,7 @@ impl ImageView {
|
||||
&& !device.enabled_features().image_view_format_reinterpretation
|
||||
&& format.components() != image.format().unwrap().components()
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "this device is a portability subset device, and \
|
||||
`create_info.format` does not have the same components and \
|
||||
number of bits per component as `image.format()`"
|
||||
@ -421,7 +421,7 @@ impl ImageView {
|
||||
)])]),
|
||||
vuids: &["VUID-VkImageViewCreateInfo-imageViewFormatReinterpretation-04466"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if image
|
||||
@ -431,7 +431,7 @@ impl ImageView {
|
||||
if !(format.compatibility() == image.format().unwrap().compatibility()
|
||||
|| format.block_size() == image.format().unwrap().block_size())
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`image.flags()` contains \
|
||||
`ImageCreateFlags::BLOCK_TEXEL_VIEW_COMPATIBLE`, but \
|
||||
`create_info.format` is not compatible with `image.format()`, or \
|
||||
@ -439,12 +439,12 @@ impl ImageView {
|
||||
.into(),
|
||||
vuids: &["VUID-VkImageViewCreateInfo-image-01583"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if format.compression().is_none() {
|
||||
if subresource_range.array_layers.len() != 1 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`image.flags()` contains \
|
||||
`ImageCreateFlags::BLOCK_TEXEL_VIEW_COMPATIBLE`, and \
|
||||
`create_info.format` is not a compressed format, but \
|
||||
@ -453,11 +453,11 @@ impl ImageView {
|
||||
.into(),
|
||||
vuids: &["VUID-VkImageViewCreateInfo-image-07072"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if subresource_range.mip_levels.len() != 1 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`image.flags()` contains \
|
||||
`ImageCreateFlags::BLOCK_TEXEL_VIEW_COMPATIBLE`, and \
|
||||
`create_info.format` is not a compressed format, but \
|
||||
@ -466,13 +466,13 @@ impl ImageView {
|
||||
.into(),
|
||||
vuids: &["VUID-VkImageViewCreateInfo-image-07072"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if image.format().unwrap().planes().is_empty() {
|
||||
if format.compatibility() != image.format().unwrap().compatibility() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`image.flags()` does not contain \
|
||||
`ImageCreateFlags::BLOCK_TEXEL_VIEW_COMPATIBLE`, and \
|
||||
`image.format()` is not a multi-planar format, but \
|
||||
@ -480,7 +480,7 @@ impl ImageView {
|
||||
.into(),
|
||||
vuids: &["VUID-VkImageViewCreateInfo-image-01761"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
} else if subresource_range.aspects.intersects(
|
||||
ImageAspects::PLANE_0 | ImageAspects::PLANE_1 | ImageAspects::PLANE_2,
|
||||
@ -497,7 +497,7 @@ impl ImageView {
|
||||
let plane_format = image.format().unwrap().planes()[plane];
|
||||
|
||||
if format.compatibility() != plane_format.compatibility() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`image.flags()` does not contain \
|
||||
`ImageCreateFlags::BLOCK_TEXEL_VIEW_COMPATIBLE`, and \
|
||||
`image.format()` is a multi-planar format, but \
|
||||
@ -506,7 +506,7 @@ impl ImageView {
|
||||
.into(),
|
||||
vuids: &["VUID-VkImageViewCreateInfo-image-01586"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -517,7 +517,7 @@ impl ImageView {
|
||||
ChromaSampling::Mode444 => (),
|
||||
ChromaSampling::Mode422 => {
|
||||
if image.extent()[0] % 2 != 0 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`create_info.format` is a YCbCr format with horizontal \
|
||||
chroma subsampling, but \
|
||||
`image.extent()[0]` is not \
|
||||
@ -525,12 +525,12 @@ impl ImageView {
|
||||
.into(),
|
||||
vuids: &["VUID-VkImageViewCreateInfo-format-04714"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
ChromaSampling::Mode420 => {
|
||||
if !(image.extent()[0] % 2 == 0 && image.extent()[1] % 2 == 0) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`create_info.format` is a YCbCr format with horizontal \
|
||||
and vertical chroma subsampling, but \
|
||||
`image.extent()[0]` and `image.extent()[1]` \
|
||||
@ -541,7 +541,7 @@ impl ImageView {
|
||||
"VUID-VkImageViewCreateInfo-format-04715",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -554,7 +554,7 @@ impl ImageView {
|
||||
pub unsafe fn new_unchecked(
|
||||
image: Arc<Image>,
|
||||
create_info: ImageViewCreateInfo,
|
||||
) -> Result<Arc<Self>, RuntimeError> {
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
let &ImageViewCreateInfo {
|
||||
view_type,
|
||||
format,
|
||||
@ -618,7 +618,7 @@ impl ImageView {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
};
|
||||
|
||||
@ -627,7 +627,7 @@ impl ImageView {
|
||||
|
||||
/// Creates a default `ImageView`. Equivalent to
|
||||
/// `ImageView::new(image, ImageViewCreateInfo::from_image(image))`.
|
||||
pub fn new_default(image: Arc<Image>) -> Result<Arc<ImageView>, VulkanError> {
|
||||
pub fn new_default(image: Arc<Image>) -> Result<Arc<ImageView>, Validated<VulkanError>> {
|
||||
let create_info = ImageViewCreateInfo::from_image(&image);
|
||||
|
||||
Self::new(image, create_info)
|
||||
@ -643,7 +643,7 @@ impl ImageView {
|
||||
image: Arc<Image>,
|
||||
handle: ash::vk::ImageView,
|
||||
create_info: ImageViewCreateInfo,
|
||||
) -> Result<Arc<Self>, RuntimeError> {
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
let ImageViewCreateInfo {
|
||||
view_type,
|
||||
format,
|
||||
@ -921,7 +921,7 @@ impl ImageViewCreateInfo {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
view_type,
|
||||
format,
|
||||
@ -973,48 +973,48 @@ impl ImageViewCreateInfo {
|
||||
match view_type {
|
||||
ImageViewType::Dim1d | ImageViewType::Dim2d | ImageViewType::Dim3d => {
|
||||
if subresource_range.array_layers.len() != 1 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`view_type` is `ImageViewType::Dim1d`, \
|
||||
`ImageViewType::Dim2d` or `ImageViewType::Dim3d`, but \
|
||||
the length of `subresource_range.array_layers` is not 1"
|
||||
.into(),
|
||||
vuids: &["VUID-VkImageViewCreateInfo-imageViewType-04973"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
ImageViewType::Cube => {
|
||||
if subresource_range.array_layers.len() != 6 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`view_type` is `ImageViewType::Cube`, but \
|
||||
the length of `subresource_range.array_layers` is not 6"
|
||||
.into(),
|
||||
vuids: &["VUID-VkImageViewCreateInfo-viewType-02960"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
ImageViewType::CubeArray => {
|
||||
if !device.enabled_features().image_cube_array {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "view_type".into(),
|
||||
problem: "is `ImageViewType::CubeArray`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"image_cube_array",
|
||||
)])]),
|
||||
vuids: &["VUID-VkImageViewCreateInfo-viewType-01004"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if subresource_range.array_layers.len() % 6 != 0 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`view_type` is `ImageViewType::CubeArray`, but \
|
||||
the length of `subresource_range.array_layers` is not \
|
||||
a multiple of 6"
|
||||
.into(),
|
||||
vuids: &["VUID-VkImageViewCreateInfo-viewType-02961"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
@ -1026,21 +1026,21 @@ impl ImageViewCreateInfo {
|
||||
.count()
|
||||
> 1
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "subresource_range.aspects".into(),
|
||||
problem: "contains more than one of `ImageAspects::PLANE_0`, \
|
||||
`ImageAspects::PLANE_1` and `ImageAspects::PLANE_2`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkImageViewCreateInfo-subresourceRange-07818"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if device.enabled_extensions().khr_portability_subset
|
||||
&& !device.enabled_features().image_view_format_swizzle
|
||||
&& !component_mapping.is_identity()
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "this device is a portability subset device, and \
|
||||
`component_mapping` is not the identity mapping"
|
||||
.into(),
|
||||
@ -1049,7 +1049,7 @@ impl ImageViewCreateInfo {
|
||||
)])]),
|
||||
vuids: &["VUID-VkImageViewCreateInfo-imageViewFormatSwizzle-04465"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// Don't need to check features because you can't create a conversion object without the
|
||||
@ -1058,23 +1058,23 @@ impl ImageViewCreateInfo {
|
||||
assert_eq!(device, conversion.device().as_ref());
|
||||
|
||||
if !component_mapping.is_identity() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`sampler_ycbcr_conversion` is `Some`, but \
|
||||
`component_mapping` is not the identity mapping"
|
||||
.into(),
|
||||
vuids: &["VUID-VkImageViewCreateInfo-pNext-01970"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
} else {
|
||||
if format.ycbcr_chroma_sampling().is_some() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`sampler_ycbcr_conversion` is `None`, but \
|
||||
`format.ycbcr_chroma_sampling()` is `Some`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkImageViewCreateInfo-format-06415"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@
|
||||
use super::{Instance, InstanceExtensions};
|
||||
use crate::{
|
||||
macros::{vulkan_bitflags, vulkan_enum},
|
||||
DebugWrapper, Requires, RequiresAllOf, RequiresOneOf, RuntimeError, ValidationError, Version,
|
||||
DebugWrapper, Requires, RequiresAllOf, RequiresOneOf, Validated, ValidationError, Version,
|
||||
VulkanError, VulkanObject,
|
||||
};
|
||||
use std::{
|
||||
@ -81,7 +81,7 @@ impl DebugUtilsMessenger {
|
||||
pub unsafe fn new(
|
||||
instance: Arc<Instance>,
|
||||
create_info: DebugUtilsMessengerCreateInfo,
|
||||
) -> Result<Self, VulkanError> {
|
||||
) -> Result<Self, Validated<VulkanError>> {
|
||||
Self::validate_new(&instance, &create_info)?;
|
||||
|
||||
Ok(Self::new_unchecked(instance, create_info)?)
|
||||
@ -90,14 +90,14 @@ impl DebugUtilsMessenger {
|
||||
fn validate_new(
|
||||
instance: &Instance,
|
||||
create_info: &DebugUtilsMessengerCreateInfo,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
if !instance.enabled_extensions().ext_debug_utils {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||
"ext_debug_utils",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
create_info
|
||||
@ -111,7 +111,7 @@ impl DebugUtilsMessenger {
|
||||
pub unsafe fn new_unchecked(
|
||||
instance: Arc<Instance>,
|
||||
create_info: DebugUtilsMessengerCreateInfo,
|
||||
) -> Result<Self, RuntimeError> {
|
||||
) -> Result<Self, VulkanError> {
|
||||
let DebugUtilsMessengerCreateInfo {
|
||||
message_severity,
|
||||
message_type,
|
||||
@ -142,7 +142,7 @@ impl DebugUtilsMessenger {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
};
|
||||
|
||||
@ -263,7 +263,7 @@ impl DebugUtilsMessengerCreateInfo {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn validate(&self, instance: &Instance) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, instance: &Instance) -> Result<(), Box<ValidationError>> {
|
||||
self.validate_raw(instance.api_version(), instance.enabled_extensions())
|
||||
}
|
||||
|
||||
@ -271,7 +271,7 @@ impl DebugUtilsMessengerCreateInfo {
|
||||
&self,
|
||||
instance_api_version: Version,
|
||||
instance_extensions: &InstanceExtensions,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
let &DebugUtilsMessengerCreateInfo {
|
||||
message_severity,
|
||||
message_type,
|
||||
@ -288,12 +288,12 @@ impl DebugUtilsMessengerCreateInfo {
|
||||
})?;
|
||||
|
||||
if message_severity.is_empty() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "message_severity".into(),
|
||||
problem: "is empty".into(),
|
||||
vuids: &["VUID-VkDebugUtilsMessengerCreateInfoEXT-messageSeverity-requiredbitmask"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
message_type
|
||||
@ -305,12 +305,12 @@ impl DebugUtilsMessengerCreateInfo {
|
||||
})?;
|
||||
|
||||
if message_type.is_empty() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "message_type".into(),
|
||||
problem: "is empty".into(),
|
||||
vuids: &["VUID-VkDebugUtilsMessengerCreateInfoEXT-messageType-requiredbitmask"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// VUID-PFN_vkDebugUtilsMessengerCallbackEXT-None-04769
|
||||
|
@ -90,8 +90,8 @@ use crate::{
|
||||
},
|
||||
instance::debug::trampoline,
|
||||
macros::{impl_id_counter, vulkan_bitflags},
|
||||
Requires, RequiresAllOf, RequiresOneOf, RuntimeError, ValidationError, VulkanError,
|
||||
VulkanLibrary, VulkanObject,
|
||||
Requires, RequiresAllOf, RequiresOneOf, Validated, ValidationError, VulkanError, VulkanLibrary,
|
||||
VulkanObject,
|
||||
};
|
||||
pub use crate::{fns::InstanceFunctions, version::Version};
|
||||
use ash::vk::Handle;
|
||||
@ -291,7 +291,7 @@ impl Instance {
|
||||
pub fn new(
|
||||
library: Arc<VulkanLibrary>,
|
||||
create_info: InstanceCreateInfo,
|
||||
) -> Result<Arc<Instance>, VulkanError> {
|
||||
) -> Result<Arc<Instance>, Validated<VulkanError>> {
|
||||
unsafe { Self::with_debug_utils_messengers(library, create_info, []) }
|
||||
}
|
||||
|
||||
@ -313,7 +313,7 @@ impl Instance {
|
||||
library: Arc<VulkanLibrary>,
|
||||
mut create_info: InstanceCreateInfo,
|
||||
debug_utils_messengers: impl IntoIterator<Item = DebugUtilsMessengerCreateInfo>,
|
||||
) -> Result<Arc<Instance>, VulkanError> {
|
||||
) -> Result<Arc<Instance>, Validated<VulkanError>> {
|
||||
create_info.max_api_version.get_or_insert_with(|| {
|
||||
let api_version = library.api_version();
|
||||
if api_version < Version::V1_1 {
|
||||
@ -337,7 +337,7 @@ impl Instance {
|
||||
library: &VulkanLibrary,
|
||||
create_info: &InstanceCreateInfo,
|
||||
debug_utils_messengers: &[DebugUtilsMessengerCreateInfo],
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
// VUID-vkCreateInstance-pCreateInfo-parameter
|
||||
create_info
|
||||
.validate(library)
|
||||
@ -373,14 +373,14 @@ impl Instance {
|
||||
|
||||
if !debug_utils_messengers.is_empty() {
|
||||
if !create_info.enabled_extensions.ext_debug_utils {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "debug_utils_messengers".into(),
|
||||
problem: "is not empty".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[
|
||||
Requires::InstanceExtension("ext_debug_utils"),
|
||||
])]),
|
||||
vuids: &["VUID-VkInstanceCreateInfo-pNext-04926"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
for (index, messenger_create_info) in debug_utils_messengers.iter().enumerate() {
|
||||
@ -397,7 +397,7 @@ impl Instance {
|
||||
pub unsafe fn new_unchecked(
|
||||
library: Arc<VulkanLibrary>,
|
||||
create_info: InstanceCreateInfo,
|
||||
) -> Result<Arc<Instance>, RuntimeError> {
|
||||
) -> Result<Arc<Instance>, VulkanError> {
|
||||
Self::with_debug_utils_messengers_unchecked(library, create_info, [])
|
||||
}
|
||||
|
||||
@ -406,7 +406,7 @@ impl Instance {
|
||||
library: Arc<VulkanLibrary>,
|
||||
mut create_info: InstanceCreateInfo,
|
||||
debug_utils_messengers: impl IntoIterator<Item = DebugUtilsMessengerCreateInfo>,
|
||||
) -> Result<Arc<Instance>, RuntimeError> {
|
||||
) -> Result<Arc<Instance>, VulkanError> {
|
||||
create_info.max_api_version.get_or_insert_with(|| {
|
||||
let api_version = library.api_version();
|
||||
if api_version < Version::V1_1 {
|
||||
@ -572,7 +572,7 @@ impl Instance {
|
||||
let fns = library.fns();
|
||||
(fns.v1_0.create_instance)(&create_info_vk, ptr::null(), output.as_mut_ptr())
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
};
|
||||
|
||||
@ -711,7 +711,7 @@ impl Instance {
|
||||
/// ```
|
||||
pub fn enumerate_physical_devices(
|
||||
self: &Arc<Self>,
|
||||
) -> Result<impl ExactSizeIterator<Item = Arc<PhysicalDevice>>, RuntimeError> {
|
||||
) -> Result<impl ExactSizeIterator<Item = Arc<PhysicalDevice>>, VulkanError> {
|
||||
let fns = self.fns();
|
||||
|
||||
unsafe {
|
||||
@ -719,7 +719,7 @@ impl Instance {
|
||||
let mut count = 0;
|
||||
(fns.v1_0.enumerate_physical_devices)(self.handle, &mut count, ptr::null_mut())
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
let mut handles = Vec::with_capacity(count as usize);
|
||||
let result = (fns.v1_0.enumerate_physical_devices)(
|
||||
@ -734,7 +734,7 @@ impl Instance {
|
||||
break handles;
|
||||
}
|
||||
ash::vk::Result::INCOMPLETE => (),
|
||||
err => return Err(RuntimeError::from(err)),
|
||||
err => return Err(VulkanError::from(err)),
|
||||
}
|
||||
};
|
||||
|
||||
@ -769,23 +769,24 @@ impl Instance {
|
||||
#[inline]
|
||||
pub fn enumerate_physical_device_groups(
|
||||
self: &Arc<Self>,
|
||||
) -> Result<impl ExactSizeIterator<Item = PhysicalDeviceGroupProperties>, VulkanError> {
|
||||
) -> Result<impl ExactSizeIterator<Item = PhysicalDeviceGroupProperties>, Validated<VulkanError>>
|
||||
{
|
||||
self.validate_enumerate_physical_device_groups()?;
|
||||
|
||||
unsafe { Ok(self.enumerate_physical_device_groups_unchecked()?) }
|
||||
}
|
||||
|
||||
fn validate_enumerate_physical_device_groups(&self) -> Result<(), ValidationError> {
|
||||
fn validate_enumerate_physical_device_groups(&self) -> Result<(), Box<ValidationError>> {
|
||||
if !(self.api_version() >= Version::V1_1
|
||||
|| self.enabled_extensions().khr_device_group_creation)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[
|
||||
RequiresAllOf(&[Requires::APIVersion(Version::V1_1)]),
|
||||
RequiresAllOf(&[Requires::InstanceExtension("khr_device_group_creation")]),
|
||||
]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -794,7 +795,7 @@ impl Instance {
|
||||
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
||||
pub unsafe fn enumerate_physical_device_groups_unchecked(
|
||||
self: &Arc<Self>,
|
||||
) -> Result<impl ExactSizeIterator<Item = PhysicalDeviceGroupProperties>, RuntimeError> {
|
||||
) -> Result<impl ExactSizeIterator<Item = PhysicalDeviceGroupProperties>, VulkanError> {
|
||||
let fns = self.fns();
|
||||
let enumerate_physical_device_groups = if self.api_version() >= Version::V1_1 {
|
||||
fns.v1_1.enumerate_physical_device_groups
|
||||
@ -808,7 +809,7 @@ impl Instance {
|
||||
|
||||
enumerate_physical_device_groups(self.handle, &mut count, ptr::null_mut())
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
let mut properties = Vec::with_capacity(count as usize);
|
||||
let result =
|
||||
@ -820,7 +821,7 @@ impl Instance {
|
||||
break properties;
|
||||
}
|
||||
ash::vk::Result::INCOMPLETE => (),
|
||||
err => return Err(RuntimeError::from(err)),
|
||||
err => return Err(VulkanError::from(err)),
|
||||
}
|
||||
};
|
||||
|
||||
@ -1068,7 +1069,7 @@ impl InstanceCreateInfo {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn validate(&self, library: &VulkanLibrary) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, library: &VulkanLibrary) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
flags,
|
||||
application_name: _,
|
||||
@ -1087,12 +1088,12 @@ impl InstanceCreateInfo {
|
||||
let api_version = std::cmp::min(max_api_version, library.api_version());
|
||||
|
||||
if max_api_version < Version::V1_0 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "max_api_version".into(),
|
||||
problem: "is less than 1.0".into(),
|
||||
vuids: &["VUID-VkApplicationInfo-apiVersion-04010"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
flags
|
||||
@ -1105,14 +1106,14 @@ impl InstanceCreateInfo {
|
||||
|
||||
if !enabled_validation_features.is_empty() {
|
||||
if !enabled_extensions.ext_validation_features {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "enabled_validation_features".into(),
|
||||
problem: "is not empty".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[
|
||||
Requires::InstanceExtension("ext_validation_features"),
|
||||
])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
for (index, enabled) in enabled_validation_features.iter().enumerate() {
|
||||
@ -1131,7 +1132,7 @@ impl InstanceCreateInfo {
|
||||
.contains(&ValidationFeatureEnable::GpuAssistedReserveBindingSlot)
|
||||
&& !enabled_validation_features.contains(&ValidationFeatureEnable::GpuAssisted)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "enabled_validation_features".into(),
|
||||
problem: "contains `ValidationFeatureEnable::GpuAssistedReserveBindingSlot`, \
|
||||
but does not also contain \
|
||||
@ -1139,33 +1140,33 @@ impl InstanceCreateInfo {
|
||||
.into(),
|
||||
vuids: &["VUID-VkValidationFeaturesEXT-pEnabledValidationFeatures-02967"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if enabled_validation_features.contains(&ValidationFeatureEnable::DebugPrintf)
|
||||
&& enabled_validation_features.contains(&ValidationFeatureEnable::GpuAssisted)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "enabled_validation_features".into(),
|
||||
problem: "contains both `ValidationFeatureEnable::DebugPrintf` and \
|
||||
`ValidationFeatureEnable::GpuAssisted`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkValidationFeaturesEXT-pEnabledValidationFeatures-02968"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
if !disabled_validation_features.is_empty() {
|
||||
if !enabled_extensions.ext_validation_features {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "disabled_validation_features".into(),
|
||||
problem: "is not empty".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[
|
||||
Requires::InstanceExtension("ext_validation_features"),
|
||||
])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
for (index, disabled) in disabled_validation_features.iter().enumerate() {
|
||||
|
@ -290,72 +290,179 @@ impl<T> Deref for DebugWrapper<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// An error that can happen when calling a safe (validated) function that makes a call to the
|
||||
/// Vulkan API.
|
||||
#[derive(Clone)]
|
||||
pub enum VulkanError {
|
||||
/// The function call was invalid in some way.
|
||||
ValidationError(ValidationError),
|
||||
// Generated by build.rs
|
||||
include!(concat!(env!("OUT_DIR"), "/errors.rs"));
|
||||
|
||||
/// The Vulkan driver returned an error and was unable to complete the operation.
|
||||
RuntimeError(RuntimeError),
|
||||
}
|
||||
|
||||
impl VulkanError {
|
||||
/// Returns the contained `RuntimeError` value, or panics if it contains `ValidationError`.
|
||||
#[track_caller]
|
||||
#[inline]
|
||||
pub fn unwrap_runtime(self) -> RuntimeError {
|
||||
match self {
|
||||
VulkanError::ValidationError(err) => {
|
||||
panic!(
|
||||
"called `VulkanError::unwrap_runtime` on a `ValidationError` value: {:?}",
|
||||
err
|
||||
)
|
||||
}
|
||||
VulkanError::RuntimeError(err) => err,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for VulkanError {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||
match self {
|
||||
Self::ValidationError(err) => {
|
||||
write!(f, "a validation error occurred\n\nCaused by:\n {err:?}")
|
||||
}
|
||||
Self::RuntimeError(err) => write!(f, "a runtime error occurred: {err}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Error for VulkanError {}
|
||||
|
||||
impl Display for VulkanError {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||
let msg = match self {
|
||||
VulkanError::OutOfHostMemory => "a host memory allocation has failed",
|
||||
VulkanError::OutOfDeviceMemory => "a device memory allocation has failed",
|
||||
VulkanError::InitializationFailed => {
|
||||
"initialization of an object could not be completed for implementation-specific \
|
||||
reasons"
|
||||
}
|
||||
VulkanError::DeviceLost => "the logical or physical device has been lost",
|
||||
VulkanError::MemoryMapFailed => "mapping of a memory object has failed",
|
||||
VulkanError::LayerNotPresent => {
|
||||
"a requested layer is not present or could not be loaded"
|
||||
}
|
||||
VulkanError::ExtensionNotPresent => "a requested extension is not supported",
|
||||
VulkanError::FeatureNotPresent => "a requested feature is not supported",
|
||||
VulkanError::IncompatibleDriver => {
|
||||
"the requested version of Vulkan is not supported by the driver or is otherwise \
|
||||
incompatible for implementation-specific reasons"
|
||||
}
|
||||
VulkanError::TooManyObjects => "too many objects of the type have already been created",
|
||||
VulkanError::FormatNotSupported => "a requested format is not supported on this device",
|
||||
VulkanError::FragmentedPool => {
|
||||
"a pool allocation has failed due to fragmentation of the pool's memory"
|
||||
}
|
||||
VulkanError::Unknown => {
|
||||
"an unknown error has occurred; either the application has provided invalid input, \
|
||||
or an implementation failure has occurred"
|
||||
}
|
||||
VulkanError::OutOfPoolMemory => "a pool memory allocation has failed",
|
||||
VulkanError::InvalidExternalHandle => {
|
||||
"an external handle is not a valid handle of the specified type"
|
||||
}
|
||||
VulkanError::Fragmentation => {
|
||||
"a descriptor pool creation has failed due to fragmentation"
|
||||
}
|
||||
VulkanError::InvalidOpaqueCaptureAddress => {
|
||||
"a buffer creation or memory allocation failed because the requested address is \
|
||||
not available. A shader group handle assignment failed because the requested \
|
||||
shader group handle information is no longer valid"
|
||||
}
|
||||
VulkanError::IncompatibleDisplay => {
|
||||
"the display used by a swapchain does not use the same presentable image layout, \
|
||||
or is incompatible in a way that prevents sharing an image"
|
||||
}
|
||||
VulkanError::NotPermitted => "a requested operation was not permitted",
|
||||
VulkanError::SurfaceLost => "a surface is no longer available",
|
||||
VulkanError::NativeWindowInUse => {
|
||||
"the requested window is already in use by Vulkan or another API in a manner which \
|
||||
prevents it from being used again"
|
||||
}
|
||||
VulkanError::OutOfDate => {
|
||||
"a surface has changed in such a way that it is no longer compatible with the \
|
||||
swapchain, and further presentation requests using the swapchain will fail"
|
||||
}
|
||||
VulkanError::InvalidVideoStdParameters => {
|
||||
"the provided Video Std parameters do not adhere to the requirements of the used \
|
||||
video compression standard"
|
||||
}
|
||||
VulkanError::ValidationFailed => "validation failed",
|
||||
VulkanError::FullScreenExclusiveModeLost => {
|
||||
"an operation on a swapchain created with application controlled full-screen \
|
||||
access failed as it did not have exclusive full-screen access"
|
||||
}
|
||||
VulkanError::InvalidDrmFormatModifierPlaneLayout => {
|
||||
"the requested DRM format modifier plane layout is invalid"
|
||||
}
|
||||
VulkanError::InvalidShader => "one or more shaders failed to compile or link",
|
||||
VulkanError::ImageUsageNotSupported => "the requested `ImageUsage` are not supported",
|
||||
VulkanError::VideoPictureLayoutNotSupported => {
|
||||
"the requested video picture layout is not supported"
|
||||
}
|
||||
VulkanError::VideoProfileOperationNotSupported => {
|
||||
"a video profile operation specified via `VideoProfileInfo::video_codec_operation` \
|
||||
is not supported"
|
||||
}
|
||||
VulkanError::VideoProfileFormatNotSupported => {
|
||||
"format parameters in a requested `VideoProfileInfo` chain are not supported"
|
||||
}
|
||||
VulkanError::VideoProfileCodecNotSupported => {
|
||||
"codec-specific parameters in a requested `VideoProfileInfo` chain are not \
|
||||
supported"
|
||||
}
|
||||
VulkanError::VideoStdVersionNotSupported => {
|
||||
"the specified video Std header version is not supported"
|
||||
}
|
||||
VulkanError::CompressionExhausted => {
|
||||
"an image creation failed because internal resources required for compression are \
|
||||
exhausted"
|
||||
}
|
||||
VulkanError::Unnamed(result) => {
|
||||
return write!(f, "unnamed error, VkResult value {}", result.as_raw());
|
||||
}
|
||||
};
|
||||
|
||||
write!(f, "{msg}")
|
||||
}
|
||||
}
|
||||
|
||||
impl From<VulkanError> for Validated<VulkanError> {
|
||||
fn from(err: VulkanError) -> Self {
|
||||
Self::Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
/// A wrapper for error types of functions that can return validation errors.
|
||||
#[derive(Clone)]
|
||||
pub enum Validated<E> {
|
||||
/// A non-validation error occurred.
|
||||
Error(E),
|
||||
|
||||
/// A validation error occurred.
|
||||
ValidationError(Box<ValidationError>),
|
||||
}
|
||||
|
||||
impl<E> Validated<E> {
|
||||
/// Returns the inner `Error` value, or panics if it contains `ValidationError`.
|
||||
pub fn unwrap(self) -> E {
|
||||
match self {
|
||||
Self::ValidationError(_) => write!(f, "a validation error occurred"),
|
||||
Self::RuntimeError(_) => write!(f, "a runtime error occurred"),
|
||||
Self::Error(err) => err,
|
||||
Self::ValidationError(err) => {
|
||||
panic!(
|
||||
"called `Validated::unwrap` on a `ValidationError` value: {:?}",
|
||||
err
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Error for VulkanError {
|
||||
impl<E> Error for Validated<E>
|
||||
where
|
||||
E: Error + 'static,
|
||||
{
|
||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||
match self {
|
||||
Self::Error(err) => Some(err),
|
||||
Self::ValidationError(err) => Some(err),
|
||||
Self::RuntimeError(err) => Some(err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ValidationError> for VulkanError {
|
||||
fn from(err: ValidationError) -> Self {
|
||||
Self::ValidationError(err)
|
||||
impl<E> Display for Validated<E> {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||
match self {
|
||||
Self::Error(_) => write!(f, "a non-validation error occurred"),
|
||||
Self::ValidationError(_) => write!(f, "a validation error occurred"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RuntimeError> for VulkanError {
|
||||
fn from(err: RuntimeError) -> Self {
|
||||
Self::RuntimeError(err)
|
||||
impl<E> Debug for Validated<E>
|
||||
where
|
||||
E: Display,
|
||||
{
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||
match self {
|
||||
Self::Error(err) => write!(f, "a non-validation error occurred: {err}"),
|
||||
Self::ValidationError(err) => {
|
||||
write!(f, "a validation error occurred\n\nCaused by:\n {err:?}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<E> From<Box<ValidationError>> for Validated<E> {
|
||||
fn from(err: Box<ValidationError>) -> Self {
|
||||
Self::ValidationError(err)
|
||||
}
|
||||
}
|
||||
|
||||
@ -394,18 +501,14 @@ impl ValidationError {
|
||||
}
|
||||
}
|
||||
|
||||
fn add_context(self, context: impl Into<Cow<'static, str>>) -> Self {
|
||||
fn add_context(mut self: Box<Self>, context: impl Into<Cow<'static, str>>) -> Box<Self> {
|
||||
if self.context.is_empty() {
|
||||
Self {
|
||||
context: context.into(),
|
||||
..self
|
||||
}
|
||||
self.context = context.into();
|
||||
} else {
|
||||
Self {
|
||||
context: format!("{}.{}", context.into(), self.context).into(),
|
||||
..self
|
||||
}
|
||||
self.context = format!("{}.{}", context.into(), self.context).into();
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
@ -595,124 +698,16 @@ impl Display for OomError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RuntimeError> for OomError {
|
||||
fn from(err: RuntimeError) -> OomError {
|
||||
impl From<VulkanError> for OomError {
|
||||
fn from(err: VulkanError) -> OomError {
|
||||
match err {
|
||||
RuntimeError::OutOfHostMemory => OomError::OutOfHostMemory,
|
||||
RuntimeError::OutOfDeviceMemory => OomError::OutOfDeviceMemory,
|
||||
VulkanError::OutOfHostMemory => OomError::OutOfHostMemory,
|
||||
VulkanError::OutOfDeviceMemory => OomError::OutOfDeviceMemory,
|
||||
_ => panic!("unexpected error: {:?}", err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Generated by build.rs
|
||||
include!(concat!(env!("OUT_DIR"), "/errors.rs"));
|
||||
|
||||
impl Error for RuntimeError {}
|
||||
|
||||
impl Display for RuntimeError {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||
let msg = match self {
|
||||
RuntimeError::OutOfHostMemory => "a host memory allocation has failed",
|
||||
RuntimeError::OutOfDeviceMemory => "a device memory allocation has failed",
|
||||
RuntimeError::InitializationFailed => {
|
||||
"initialization of an object could not be completed for implementation-specific \
|
||||
reasons"
|
||||
}
|
||||
RuntimeError::DeviceLost => "the logical or physical device has been lost",
|
||||
RuntimeError::MemoryMapFailed => "mapping of a memory object has failed",
|
||||
RuntimeError::LayerNotPresent => {
|
||||
"a requested layer is not present or could not be loaded"
|
||||
}
|
||||
RuntimeError::ExtensionNotPresent => "a requested extension is not supported",
|
||||
RuntimeError::FeatureNotPresent => "a requested feature is not supported",
|
||||
RuntimeError::IncompatibleDriver => {
|
||||
"the requested version of Vulkan is not supported by the driver or is otherwise \
|
||||
incompatible for implementation-specific reasons"
|
||||
}
|
||||
RuntimeError::TooManyObjects => {
|
||||
"too many objects of the type have already been created"
|
||||
}
|
||||
RuntimeError::FormatNotSupported => {
|
||||
"a requested format is not supported on this device"
|
||||
}
|
||||
RuntimeError::FragmentedPool => {
|
||||
"a pool allocation has failed due to fragmentation of the pool's memory"
|
||||
}
|
||||
RuntimeError::Unknown => {
|
||||
"an unknown error has occurred; either the application has provided invalid input, \
|
||||
or an implementation failure has occurred"
|
||||
}
|
||||
RuntimeError::OutOfPoolMemory => "a pool memory allocation has failed",
|
||||
RuntimeError::InvalidExternalHandle => {
|
||||
"an external handle is not a valid handle of the specified type"
|
||||
}
|
||||
RuntimeError::Fragmentation => {
|
||||
"a descriptor pool creation has failed due to fragmentation"
|
||||
}
|
||||
RuntimeError::InvalidOpaqueCaptureAddress => {
|
||||
"a buffer creation or memory allocation failed because the requested address is \
|
||||
not available. A shader group handle assignment failed because the requested \
|
||||
shader group handle information is no longer valid"
|
||||
}
|
||||
RuntimeError::IncompatibleDisplay => {
|
||||
"the display used by a swapchain does not use the same presentable image layout, \
|
||||
or is incompatible in a way that prevents sharing an image"
|
||||
}
|
||||
RuntimeError::NotPermitted => "a requested operation was not permitted",
|
||||
RuntimeError::SurfaceLost => "a surface is no longer available",
|
||||
RuntimeError::NativeWindowInUse => {
|
||||
"the requested window is already in use by Vulkan or another API in a manner which \
|
||||
prevents it from being used again"
|
||||
}
|
||||
RuntimeError::OutOfDate => {
|
||||
"a surface has changed in such a way that it is no longer compatible with the \
|
||||
swapchain, and further presentation requests using the swapchain will fail"
|
||||
}
|
||||
RuntimeError::InvalidVideoStdParameters => {
|
||||
"the provided Video Std parameters do not adhere to the requirements of the used \
|
||||
video compression standard"
|
||||
}
|
||||
RuntimeError::ValidationFailed => "validation failed",
|
||||
RuntimeError::FullScreenExclusiveModeLost => {
|
||||
"an operation on a swapchain created with application controlled full-screen \
|
||||
access failed as it did not have exclusive full-screen access"
|
||||
}
|
||||
RuntimeError::InvalidDrmFormatModifierPlaneLayout => {
|
||||
"the requested DRM format modifier plane layout is invalid"
|
||||
}
|
||||
RuntimeError::InvalidShader => "one or more shaders failed to compile or link",
|
||||
RuntimeError::ImageUsageNotSupported => "the requested `ImageUsage` are not supported",
|
||||
RuntimeError::VideoPictureLayoutNotSupported => {
|
||||
"the requested video picture layout is not supported"
|
||||
}
|
||||
RuntimeError::VideoProfileOperationNotSupported => {
|
||||
"a video profile operation specified via `VideoProfileInfo::video_codec_operation` \
|
||||
is not supported"
|
||||
}
|
||||
RuntimeError::VideoProfileFormatNotSupported => {
|
||||
"format parameters in a requested `VideoProfileInfo` chain are not supported"
|
||||
}
|
||||
RuntimeError::VideoProfileCodecNotSupported => {
|
||||
"codec-specific parameters in a requested `VideoProfileInfo` chain are not \
|
||||
supported"
|
||||
}
|
||||
RuntimeError::VideoStdVersionNotSupported => {
|
||||
"the specified video Std header version is not supported"
|
||||
}
|
||||
RuntimeError::CompressionExhausted => {
|
||||
"an image creation failed because internal resources required for compression are \
|
||||
exhausted"
|
||||
}
|
||||
RuntimeError::Unnamed(result) => {
|
||||
return write!(f, "unnamed error, VkResult value {}", result.as_raw());
|
||||
}
|
||||
};
|
||||
|
||||
write!(f, "{msg}")
|
||||
}
|
||||
}
|
||||
|
||||
/// A helper type for non-exhaustive structs.
|
||||
///
|
||||
/// This type cannot be constructed outside Vulkano. Structures with a field of this type can only
|
||||
|
@ -21,7 +21,7 @@
|
||||
pub use crate::fns::EntryFunctions;
|
||||
use crate::{
|
||||
instance::{InstanceExtensions, LayerProperties},
|
||||
ExtensionProperties, OomError, RuntimeError, SafeDeref, Version,
|
||||
ExtensionProperties, OomError, SafeDeref, Version, VulkanError,
|
||||
};
|
||||
use libloading::{Error as LibloadingError, Library};
|
||||
use std::{
|
||||
@ -121,7 +121,7 @@ impl VulkanLibrary {
|
||||
}))
|
||||
}
|
||||
|
||||
unsafe fn get_api_version(loader: &impl Loader) -> Result<Version, RuntimeError> {
|
||||
unsafe fn get_api_version(loader: &impl Loader) -> Result<Version, VulkanError> {
|
||||
// Per the Vulkan spec:
|
||||
// If the vkGetInstanceProcAddr returns NULL for vkEnumerateInstanceVersion, it is a
|
||||
// Vulkan 1.0 implementation. Otherwise, the application can call vkEnumerateInstanceVersion
|
||||
@ -133,9 +133,7 @@ impl VulkanLibrary {
|
||||
let version = if let Some(func) = func {
|
||||
let func: ash::vk::PFN_vkEnumerateInstanceVersion = transmute(func);
|
||||
let mut api_version = 0;
|
||||
func(&mut api_version)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
func(&mut api_version).result().map_err(VulkanError::from)?;
|
||||
Version::from(api_version)
|
||||
} else {
|
||||
Version {
|
||||
@ -151,7 +149,7 @@ impl VulkanLibrary {
|
||||
unsafe fn get_extension_properties(
|
||||
fns: &EntryFunctions,
|
||||
layer: Option<&str>,
|
||||
) -> Result<Vec<ExtensionProperties>, RuntimeError> {
|
||||
) -> Result<Vec<ExtensionProperties>, VulkanError> {
|
||||
let layer_vk = layer.map(|layer| CString::new(layer).unwrap());
|
||||
|
||||
loop {
|
||||
@ -164,7 +162,7 @@ impl VulkanLibrary {
|
||||
ptr::null_mut(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
let mut output = Vec::with_capacity(count as usize);
|
||||
let result = (fns.v1_0.enumerate_instance_extension_properties)(
|
||||
@ -181,7 +179,7 @@ impl VulkanLibrary {
|
||||
return Ok(output.into_iter().map(Into::into).collect());
|
||||
}
|
||||
ash::vk::Result::INCOMPLETE => (),
|
||||
err => return Err(RuntimeError::from(err)),
|
||||
err => return Err(VulkanError::from(err)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -243,7 +241,7 @@ impl VulkanLibrary {
|
||||
let mut count = 0;
|
||||
(fns.v1_0.enumerate_instance_layer_properties)(&mut count, ptr::null_mut())
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
let mut properties = Vec::with_capacity(count as usize);
|
||||
let result = (fns.v1_0.enumerate_instance_layer_properties)(
|
||||
@ -257,7 +255,7 @@ impl VulkanLibrary {
|
||||
break properties;
|
||||
}
|
||||
ash::vk::Result::INCOMPLETE => (),
|
||||
err => return Err(RuntimeError::from(err).into()),
|
||||
err => return Err(VulkanError::from(err).into()),
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -272,7 +270,7 @@ impl VulkanLibrary {
|
||||
pub fn layer_extension_properties(
|
||||
&self,
|
||||
layer: &str,
|
||||
) -> Result<Vec<ExtensionProperties>, RuntimeError> {
|
||||
) -> Result<Vec<ExtensionProperties>, VulkanError> {
|
||||
unsafe { Self::get_extension_properties(&self.fns, Some(layer)) }
|
||||
}
|
||||
|
||||
@ -281,7 +279,7 @@ impl VulkanLibrary {
|
||||
pub fn supported_layer_extensions(
|
||||
&self,
|
||||
layer: &str,
|
||||
) -> Result<InstanceExtensions, RuntimeError> {
|
||||
) -> Result<InstanceExtensions, VulkanError> {
|
||||
Ok(self
|
||||
.layer_extension_properties(layer)?
|
||||
.iter()
|
||||
@ -295,7 +293,7 @@ impl VulkanLibrary {
|
||||
pub fn supported_extensions_with_layers<'a>(
|
||||
&self,
|
||||
layers: impl IntoIterator<Item = &'a str>,
|
||||
) -> Result<InstanceExtensions, RuntimeError> {
|
||||
) -> Result<InstanceExtensions, VulkanError> {
|
||||
layers
|
||||
.into_iter()
|
||||
.try_fold(self.supported_extensions, |extensions, layer| {
|
||||
@ -427,14 +425,14 @@ pub enum LoadingError {
|
||||
LibraryLoadFailure(LibloadingError),
|
||||
|
||||
/// The Vulkan driver returned an error and was unable to complete the operation.
|
||||
RuntimeError(RuntimeError),
|
||||
VulkanError(VulkanError),
|
||||
}
|
||||
|
||||
impl Error for LoadingError {
|
||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||
match self {
|
||||
//Self::LibraryLoadFailure(err) => Some(err),
|
||||
Self::RuntimeError(err) => Some(err),
|
||||
Self::VulkanError(err) => Some(err),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@ -444,14 +442,14 @@ impl Display for LoadingError {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||
match self {
|
||||
Self::LibraryLoadFailure(_) => write!(f, "failed to load the Vulkan shared library"),
|
||||
Self::RuntimeError(err) => write!(f, "a runtime error occurred: {err}"),
|
||||
Self::VulkanError(err) => write!(f, "a runtime error occurred: {err}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RuntimeError> for LoadingError {
|
||||
fn from(err: RuntimeError) -> Self {
|
||||
Self::RuntimeError(err)
|
||||
impl From<VulkanError> for LoadingError {
|
||||
fn from(err: VulkanError) -> Self {
|
||||
Self::VulkanError(err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -235,7 +235,7 @@ use super::{
|
||||
use crate::{
|
||||
device::{Device, DeviceOwned},
|
||||
instance::InstanceOwnedDebugWrapper,
|
||||
DeviceSize, Requires, RequiresAllOf, RequiresOneOf, RuntimeError, ValidationError, Version,
|
||||
DeviceSize, Requires, RequiresAllOf, RequiresOneOf, ValidationError, Version, VulkanError,
|
||||
};
|
||||
use ash::vk::{MAX_MEMORY_HEAPS, MAX_MEMORY_TYPES};
|
||||
use parking_lot::RwLock;
|
||||
@ -525,7 +525,7 @@ pub enum MemoryAllocatePreference {
|
||||
/// [memory allocator]: MemoryAllocator
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum MemoryAllocatorError {
|
||||
RuntimeError(RuntimeError),
|
||||
VulkanError(VulkanError),
|
||||
|
||||
/// There is not enough memory in the pool.
|
||||
///
|
||||
@ -555,7 +555,7 @@ pub enum MemoryAllocatorError {
|
||||
impl Error for MemoryAllocatorError {
|
||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||
match self {
|
||||
Self::RuntimeError(err) => Some(err),
|
||||
Self::VulkanError(err) => Some(err),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@ -564,7 +564,7 @@ impl Error for MemoryAllocatorError {
|
||||
impl Display for MemoryAllocatorError {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||
match self {
|
||||
Self::RuntimeError(_) => write!(f, "a runtime error occurred"),
|
||||
Self::VulkanError(_) => write!(f, "a runtime error occurred"),
|
||||
Self::OutOfPoolMemory => write!(f, "the pool doesn't have enough free space"),
|
||||
Self::DedicatedAllocationRequired => write!(
|
||||
f,
|
||||
@ -583,9 +583,9 @@ impl Display for MemoryAllocatorError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RuntimeError> for MemoryAllocatorError {
|
||||
fn from(err: RuntimeError) -> Self {
|
||||
MemoryAllocatorError::RuntimeError(err)
|
||||
impl From<VulkanError> for MemoryAllocatorError {
|
||||
fn from(err: VulkanError) -> Self {
|
||||
MemoryAllocatorError::VulkanError(err)
|
||||
}
|
||||
}
|
||||
|
||||
@ -695,7 +695,7 @@ impl<S: Suballocator> GenericMemoryAllocator<S> {
|
||||
pub fn new(
|
||||
device: Arc<Device>,
|
||||
create_info: GenericMemoryAllocatorCreateInfo<'_, '_>,
|
||||
) -> Result<Self, ValidationError> {
|
||||
) -> Result<Self, Box<ValidationError>> {
|
||||
Self::validate_new(&device, &create_info)?;
|
||||
|
||||
Ok(unsafe { Self::new_unchecked(device, create_info) })
|
||||
@ -704,7 +704,7 @@ impl<S: Suballocator> GenericMemoryAllocator<S> {
|
||||
fn validate_new(
|
||||
device: &Device,
|
||||
create_info: &GenericMemoryAllocatorCreateInfo<'_, '_>,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
let &GenericMemoryAllocatorCreateInfo {
|
||||
block_sizes,
|
||||
allocation_type: _,
|
||||
@ -727,7 +727,7 @@ impl<S: Suballocator> GenericMemoryAllocator<S> {
|
||||
if !(device.api_version() >= Version::V1_1
|
||||
&& device.enabled_extensions().khr_external_memory)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "create_info.export_handle_types".into(),
|
||||
problem: "is not empty".into(),
|
||||
requires_one_of: RequiresOneOf(&[
|
||||
@ -735,7 +735,7 @@ impl<S: Suballocator> GenericMemoryAllocator<S> {
|
||||
RequiresAllOf(&[Requires::DeviceExtension("khr_external_memory")]),
|
||||
]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
assert!(
|
||||
@ -977,7 +977,7 @@ unsafe impl<S: Suballocator> MemoryAllocator for GenericMemoryAllocator<S> {
|
||||
/// [`protected_memory`]: crate::device::Features::protected_memory
|
||||
/// [`DEVICE_COHERENT`]: MemoryPropertyFlags::DEVICE_COHERENT
|
||||
/// [`device_coherent_memory`]: crate::device::Features::device_coherent_memory
|
||||
/// [`TooManyObjects`]: RuntimeError::TooManyObjects
|
||||
/// [`TooManyObjects`]: VulkanError::TooManyObjects
|
||||
/// [`BlockSizeExceeded`]: MemoryAllocatorError::BlockSizeExceeded
|
||||
/// [`SuballocatorBlockSizeExceeded`]: MemoryAllocatorError::SuballocatorBlockSizeExceeded
|
||||
fn allocate_from_type(
|
||||
@ -1134,9 +1134,7 @@ unsafe impl<S: Suballocator> MemoryAllocator for GenericMemoryAllocator<S> {
|
||||
break S::new(MemoryAlloc::new(device_memory)?);
|
||||
}
|
||||
// Retry up to 3 times, halving the allocation size each time.
|
||||
Err(RuntimeError::OutOfHostMemory | RuntimeError::OutOfDeviceMemory)
|
||||
if i < 3 =>
|
||||
{
|
||||
Err(VulkanError::OutOfHostMemory | VulkanError::OutOfDeviceMemory) if i < 3 => {
|
||||
i += 1;
|
||||
}
|
||||
Err(err) => return Err(err.into()),
|
||||
@ -1151,8 +1149,8 @@ unsafe impl<S: Suballocator> MemoryAllocator for GenericMemoryAllocator<S> {
|
||||
Ok(allocation) => Ok(allocation),
|
||||
// This can happen if the block ended up smaller than advertised because there wasn't
|
||||
// enough memory.
|
||||
Err(SuballocatorError::OutOfRegionMemory) => Err(MemoryAllocatorError::RuntimeError(
|
||||
RuntimeError::OutOfDeviceMemory,
|
||||
Err(SuballocatorError::OutOfRegionMemory) => Err(MemoryAllocatorError::VulkanError(
|
||||
VulkanError::OutOfDeviceMemory,
|
||||
)),
|
||||
// This can not happen as the block is fresher than Febreze and we're still holding an
|
||||
// exclusive lock.
|
||||
@ -1195,7 +1193,7 @@ unsafe impl<S: Suballocator> MemoryAllocator for GenericMemoryAllocator<S> {
|
||||
/// `create_info.size` is greater than `BLOCK_SIZE` and a dedicated allocation was not
|
||||
/// created.
|
||||
///
|
||||
/// [`TooManyObjects`]: RuntimeError::TooManyObjects
|
||||
/// [`TooManyObjects`]: VulkanError::TooManyObjects
|
||||
/// [`OutOfPoolMemory`]: MemoryAllocatorError::OutOfPoolMemory
|
||||
/// [`DedicatedAllocationRequired`]: MemoryAllocatorError::DedicatedAllocationRequired
|
||||
/// [`BlockSizeExceeded`]: MemoryAllocatorError::BlockSizeExceeded
|
||||
|
@ -21,7 +21,7 @@ use crate::{
|
||||
device::{Device, DeviceOwned},
|
||||
image::ImageTiling,
|
||||
memory::{is_aligned, DeviceMemory, MemoryPropertyFlags},
|
||||
DeviceSize, NonZeroDeviceSize, RuntimeError, VulkanObject,
|
||||
DeviceSize, NonZeroDeviceSize, VulkanError, VulkanObject,
|
||||
};
|
||||
use crossbeam_queue::ArrayQueue;
|
||||
use parking_lot::Mutex;
|
||||
@ -124,7 +124,7 @@ impl MemoryAlloc {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
Some(NonNull::new(output.assume_init()).unwrap())
|
||||
}
|
||||
@ -229,7 +229,7 @@ impl MemoryAlloc {
|
||||
/// [host-coherent]: crate::memory::MemoryPropertyFlags::HOST_COHERENT
|
||||
/// [`non_coherent_atom_size`]: crate::device::Properties::non_coherent_atom_size
|
||||
#[inline]
|
||||
pub unsafe fn invalidate_range(&self, range: Range<DeviceSize>) -> Result<(), RuntimeError> {
|
||||
pub unsafe fn invalidate_range(&self, range: Range<DeviceSize>) -> Result<(), VulkanError> {
|
||||
// VUID-VkMappedMemoryRange-memory-00684
|
||||
if let Some(atom_size) = self.atom_size {
|
||||
let range = self.create_memory_range(range, atom_size);
|
||||
@ -237,7 +237,7 @@ impl MemoryAlloc {
|
||||
let fns = device.fns();
|
||||
(fns.v1_0.invalidate_mapped_memory_ranges)(device.handle(), 1, &range)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
} else {
|
||||
self.debug_validate_memory_range(&range);
|
||||
}
|
||||
@ -269,7 +269,7 @@ impl MemoryAlloc {
|
||||
/// [host-coherent]: crate::memory::MemoryPropertyFlags::HOST_COHERENT
|
||||
/// [`non_coherent_atom_size`]: crate::device::Properties::non_coherent_atom_size
|
||||
#[inline]
|
||||
pub unsafe fn flush_range(&self, range: Range<DeviceSize>) -> Result<(), RuntimeError> {
|
||||
pub unsafe fn flush_range(&self, range: Range<DeviceSize>) -> Result<(), VulkanError> {
|
||||
// VUID-VkMappedMemoryRange-memory-00684
|
||||
if let Some(atom_size) = self.atom_size {
|
||||
let range = self.create_memory_range(range, atom_size);
|
||||
@ -277,7 +277,7 @@ impl MemoryAlloc {
|
||||
let fns = device.fns();
|
||||
(fns.v1_0.flush_mapped_memory_ranges)(device.handle(), 1, &range)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
} else {
|
||||
self.debug_validate_memory_range(&range);
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ use crate::{
|
||||
instance::InstanceOwnedDebugWrapper,
|
||||
macros::{impl_id_counter, vulkan_bitflags, vulkan_bitflags_enum},
|
||||
memory::{is_aligned, MemoryPropertyFlags},
|
||||
DeviceSize, Requires, RequiresAllOf, RequiresOneOf, RuntimeError, ValidationError, Version,
|
||||
DeviceSize, Requires, RequiresAllOf, RequiresOneOf, Validated, ValidationError, Version,
|
||||
VulkanError, VulkanObject,
|
||||
};
|
||||
use std::{
|
||||
@ -78,7 +78,7 @@ impl DeviceMemory {
|
||||
pub fn allocate(
|
||||
device: Arc<Device>,
|
||||
mut allocate_info: MemoryAllocateInfo<'_>,
|
||||
) -> Result<Self, VulkanError> {
|
||||
) -> Result<Self, Validated<VulkanError>> {
|
||||
if !(device.api_version() >= Version::V1_1
|
||||
|| device.enabled_extensions().khr_dedicated_allocation)
|
||||
{
|
||||
@ -107,7 +107,7 @@ impl DeviceMemory {
|
||||
device: Arc<Device>,
|
||||
mut allocate_info: MemoryAllocateInfo<'_>,
|
||||
import_info: MemoryImportInfo,
|
||||
) -> Result<Self, VulkanError> {
|
||||
) -> Result<Self, Validated<VulkanError>> {
|
||||
if !(device.api_version() >= Version::V1_1
|
||||
|| device.enabled_extensions().khr_dedicated_allocation)
|
||||
{
|
||||
@ -129,7 +129,7 @@ impl DeviceMemory {
|
||||
device: &Device,
|
||||
allocate_info: &MemoryAllocateInfo<'_>,
|
||||
import_info: Option<&MemoryImportInfo>,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
allocate_info
|
||||
.validate(device)
|
||||
.map_err(|err| err.add_context("allocate_info"))?;
|
||||
@ -149,7 +149,7 @@ impl DeviceMemory {
|
||||
device: Arc<Device>,
|
||||
mut allocate_info: MemoryAllocateInfo<'_>,
|
||||
import_info: Option<MemoryImportInfo>,
|
||||
) -> Result<Self, RuntimeError> {
|
||||
) -> Result<Self, VulkanError> {
|
||||
if !(device.api_version() >= Version::V1_1
|
||||
|| device.enabled_extensions().khr_dedicated_allocation)
|
||||
{
|
||||
@ -261,7 +261,7 @@ impl DeviceMemory {
|
||||
.fetch_update(Ordering::Acquire, Ordering::Relaxed, move |count| {
|
||||
(count < max_allocations).then_some(count + 1)
|
||||
})
|
||||
.map_err(|_| RuntimeError::TooManyObjects)?;
|
||||
.map_err(|_| VulkanError::TooManyObjects)?;
|
||||
|
||||
let handle = {
|
||||
let fns = device.fns();
|
||||
@ -275,7 +275,7 @@ impl DeviceMemory {
|
||||
.result()
|
||||
.map_err(|e| {
|
||||
device.allocation_count.fetch_sub(1, Ordering::Release);
|
||||
RuntimeError::from(e)
|
||||
VulkanError::from(e)
|
||||
})?;
|
||||
|
||||
output.assume_init()
|
||||
@ -381,13 +381,13 @@ impl DeviceMemory {
|
||||
///
|
||||
/// [`LAZILY_ALLOCATED`]: crate::memory::MemoryPropertyFlags::LAZILY_ALLOCATED
|
||||
#[inline]
|
||||
pub fn commitment(&self) -> Result<DeviceSize, ValidationError> {
|
||||
pub fn commitment(&self) -> Result<DeviceSize, Box<ValidationError>> {
|
||||
self.validate_commitment()?;
|
||||
|
||||
unsafe { Ok(self.commitment_unchecked()) }
|
||||
}
|
||||
|
||||
fn validate_commitment(&self) -> Result<(), ValidationError> {
|
||||
fn validate_commitment(&self) -> Result<(), Box<ValidationError>> {
|
||||
let memory_type = &self
|
||||
.device
|
||||
.physical_device()
|
||||
@ -398,13 +398,13 @@ impl DeviceMemory {
|
||||
.property_flags
|
||||
.intersects(MemoryPropertyFlags::LAZILY_ALLOCATED)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the `property_flags` of the memory type does not contain the \
|
||||
`MemoryPropertyFlags::LAZILY_ALLOCATED` flag"
|
||||
.into(),
|
||||
vuids: &["VUID-vkGetDeviceMemoryCommitment-memory-00690"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -427,7 +427,10 @@ impl DeviceMemory {
|
||||
///
|
||||
/// - Panics if the user requests an invalid handle type for this device memory object.
|
||||
#[inline]
|
||||
pub fn export_fd(&self, handle_type: ExternalMemoryHandleType) -> Result<File, VulkanError> {
|
||||
pub fn export_fd(
|
||||
&self,
|
||||
handle_type: ExternalMemoryHandleType,
|
||||
) -> Result<File, Validated<VulkanError>> {
|
||||
self.validate_export_fd(handle_type)?;
|
||||
|
||||
unsafe { Ok(self.export_fd_unchecked(handle_type)?) }
|
||||
@ -436,7 +439,7 @@ impl DeviceMemory {
|
||||
fn validate_export_fd(
|
||||
&self,
|
||||
handle_type: ExternalMemoryHandleType,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
handle_type
|
||||
.validate_device(&self.device)
|
||||
.map_err(|err| ValidationError {
|
||||
@ -449,23 +452,23 @@ impl DeviceMemory {
|
||||
handle_type,
|
||||
ExternalMemoryHandleType::OpaqueFd | ExternalMemoryHandleType::DmaBuf
|
||||
) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "handle_type".into(),
|
||||
problem: "is not `ExternalMemoryHandleType::OpaqueFd` or \
|
||||
`ExternalMemoryHandleType::DmaBuf`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkMemoryGetFdInfoKHR-handleType-00672"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if !self.export_handle_types.contains_enum(handle_type) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "handle_type".into(),
|
||||
problem: "is not contained in this memory's `export_handle_types`".into(),
|
||||
vuids: &["VUID-VkMemoryGetFdInfoKHR-handleType-00671"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -475,7 +478,7 @@ impl DeviceMemory {
|
||||
pub unsafe fn export_fd_unchecked(
|
||||
&self,
|
||||
handle_type: ExternalMemoryHandleType,
|
||||
) -> Result<File, RuntimeError> {
|
||||
) -> Result<File, VulkanError> {
|
||||
debug_assert!(self.device().enabled_extensions().khr_external_memory_fd);
|
||||
|
||||
#[cfg(not(unix))]
|
||||
@ -500,7 +503,7 @@ impl DeviceMemory {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
};
|
||||
|
||||
@ -604,7 +607,7 @@ impl<'d> MemoryAllocateInfo<'d> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
allocation_size,
|
||||
memory_type_index,
|
||||
@ -631,7 +634,7 @@ impl<'d> MemoryAllocateInfo<'d> {
|
||||
.intersects(MemoryPropertyFlags::PROTECTED)
|
||||
&& !device.enabled_features().protected_memory
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "memory_type_index".into(),
|
||||
problem: "refers to a memory type where `property_flags` contains \
|
||||
`MemoryPropertyFlags::PROTECTED`"
|
||||
@ -640,7 +643,7 @@ impl<'d> MemoryAllocateInfo<'d> {
|
||||
"protected_memory",
|
||||
)])]),
|
||||
vuids: &["VUID-VkMemoryAllocateInfo-memoryTypeIndex-01872"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if memory_type
|
||||
@ -648,7 +651,7 @@ impl<'d> MemoryAllocateInfo<'d> {
|
||||
.intersects(MemoryPropertyFlags::DEVICE_COHERENT)
|
||||
&& !device.enabled_features().device_coherent_memory
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "memory_type_index".into(),
|
||||
problem: "refers to a memory type where `property_flags` contains \
|
||||
`MemoryPropertyFlags::DEVICE_COHERENT`"
|
||||
@ -657,25 +660,25 @@ impl<'d> MemoryAllocateInfo<'d> {
|
||||
"device_coherent_memory",
|
||||
)])]),
|
||||
vuids: &["VUID-vkAllocateMemory-deviceCoherentMemory-02790"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if allocation_size == 0 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "allocation_size".into(),
|
||||
problem: "is zero".into(),
|
||||
vuids: &["VUID-VkMemoryAllocateInfo-pNext-01874"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if memory_heap.size != 0 && allocation_size > memory_heap.size {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "allocation_size".into(),
|
||||
problem: "is greater than the size of the memory heap".into(),
|
||||
vuids: &["VUID-vkAllocateMemory-pAllocateInfo-01713"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if let Some(dedicated_allocation) = dedicated_allocation {
|
||||
@ -687,13 +690,13 @@ impl<'d> MemoryAllocateInfo<'d> {
|
||||
let required_size = buffer.memory_requirements().layout.size();
|
||||
|
||||
if allocation_size != required_size {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`allocation_size` does not equal the size required for the \
|
||||
buffer specified in `dedicated_allocation`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkMemoryDedicatedAllocateInfo-buffer-02965"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
DedicatedAllocation::Image(image) => {
|
||||
@ -703,13 +706,13 @@ impl<'d> MemoryAllocateInfo<'d> {
|
||||
let required_size = image.memory_requirements()[0].layout.size();
|
||||
|
||||
if allocation_size != required_size {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`allocation_size` does not equal the size required for the \
|
||||
image specified in `dedicated_allocation`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkMemoryDedicatedAllocateInfo-image-02964"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -719,7 +722,7 @@ impl<'d> MemoryAllocateInfo<'d> {
|
||||
if !(device.api_version() >= Version::V1_1
|
||||
|| device.enabled_extensions().khr_external_memory)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "export_handle_types".into(),
|
||||
problem: "is not empty".into(),
|
||||
requires_one_of: RequiresOneOf(&[
|
||||
@ -727,7 +730,7 @@ impl<'d> MemoryAllocateInfo<'d> {
|
||||
RequiresAllOf(&[Requires::DeviceExtension("khr_external_memory")]),
|
||||
]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
export_handle_types
|
||||
@ -749,7 +752,7 @@ impl<'d> MemoryAllocateInfo<'d> {
|
||||
if !(device.physical_device().api_version() >= Version::V1_1
|
||||
|| device.enabled_extensions().khr_device_group)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "flags".into(),
|
||||
problem: "is not empty".into(),
|
||||
requires_one_of: RequiresOneOf(&[
|
||||
@ -757,7 +760,7 @@ impl<'d> MemoryAllocateInfo<'d> {
|
||||
RequiresAllOf(&[Requires::DeviceExtension("khr_device_group")]),
|
||||
]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if flags.intersects(MemoryAllocateFlags::DEVICE_ADDRESS) {
|
||||
@ -765,7 +768,7 @@ impl<'d> MemoryAllocateInfo<'d> {
|
||||
|| device.enabled_extensions().khr_buffer_device_address)
|
||||
&& device.enabled_features().buffer_device_address)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "flags".into(),
|
||||
problem: "contains `MemoryAllocateFlags::DEVICE_ADDRESS`".into(),
|
||||
requires_one_of: RequiresOneOf(&[
|
||||
@ -779,7 +782,7 @@ impl<'d> MemoryAllocateInfo<'d> {
|
||||
]),
|
||||
]),
|
||||
vuids: &["VUID-VkMemoryAllocateInfo-flags-03331"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -843,7 +846,7 @@ pub enum MemoryImportInfo {
|
||||
}
|
||||
|
||||
impl MemoryImportInfo {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
match self {
|
||||
MemoryImportInfo::Fd {
|
||||
#[cfg(unix)]
|
||||
@ -853,13 +856,13 @@ impl MemoryImportInfo {
|
||||
file: _,
|
||||
} => {
|
||||
if !device.enabled_extensions().khr_external_memory_fd {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "is `MemoryImportInfo::Fd`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[
|
||||
Requires::DeviceExtension("khr_external_memory_fd"),
|
||||
])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
#[cfg(not(unix))]
|
||||
@ -888,14 +891,14 @@ impl MemoryImportInfo {
|
||||
}
|
||||
ExternalMemoryHandleType::DmaBuf => {}
|
||||
_ => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "handle_type".into(),
|
||||
problem: "is not `ExternalMemoryHandleType::OpaqueFd` or \
|
||||
`ExternalMemoryHandleType::DmaBuf`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkImportMemoryFdInfoKHR-handleType-00669"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -911,13 +914,13 @@ impl MemoryImportInfo {
|
||||
handle: _,
|
||||
} => {
|
||||
if !device.enabled_extensions().khr_external_memory_win32 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "is `MemoryImportInfo::Win32`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[
|
||||
Requires::DeviceExtension("khr_external_memory_win32"),
|
||||
])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
@ -948,14 +951,14 @@ impl MemoryImportInfo {
|
||||
// Can't validate, must be ensured by user
|
||||
}
|
||||
_ => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "handle_type".into(),
|
||||
problem: "is not `ExternalMemoryHandleType::OpaqueWin32` or \
|
||||
`ExternalMemoryHandleType::OpaqueWin32Kmt`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkImportMemoryWin32HandleInfoKHR-handleType-00660"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1132,7 +1135,10 @@ impl MappedDeviceMemory {
|
||||
///
|
||||
/// - Panics if `range` is empty.
|
||||
#[inline]
|
||||
pub fn new(memory: DeviceMemory, range: Range<DeviceSize>) -> Result<Self, VulkanError> {
|
||||
pub fn new(
|
||||
memory: DeviceMemory,
|
||||
range: Range<DeviceSize>,
|
||||
) -> Result<Self, Validated<VulkanError>> {
|
||||
Self::validate_new(&memory, range.clone())?;
|
||||
|
||||
unsafe { Ok(Self::new_unchecked(memory, range)?) }
|
||||
@ -1141,14 +1147,14 @@ impl MappedDeviceMemory {
|
||||
fn validate_new(
|
||||
memory: &DeviceMemory,
|
||||
range: Range<DeviceSize>,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
if range.is_empty() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "range".into(),
|
||||
problem: "is empty".into(),
|
||||
vuids: &["VUID-vkMapMemory-size-00680"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
let device = memory.device();
|
||||
@ -1159,28 +1165,28 @@ impl MappedDeviceMemory {
|
||||
.property_flags
|
||||
.intersects(MemoryPropertyFlags::HOST_VISIBLE)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "memory".into(),
|
||||
problem: "has a memory type whose `property_flags` does not contain \
|
||||
`MemoryPropertyFlags::HOST_VISIBLE`"
|
||||
.into(),
|
||||
vuids: &["VUID-vkMapMemory-memory-00682"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// VUID-vkMapMemory-memory-00678
|
||||
// Guaranteed because we take ownership of `memory`, no other mapping can exist.
|
||||
|
||||
if range.end > memory.allocation_size {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`range.end` is greater than `memory.allocation_size()`".into(),
|
||||
vuids: &[
|
||||
"VUID-vkMapMemory-offset-00679",
|
||||
"VUID-vkMapMemory-size-00681",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
let is_coherent = memory_type
|
||||
@ -1195,13 +1201,13 @@ impl MappedDeviceMemory {
|
||||
&& (!is_aligned(range.start, atom_size)
|
||||
|| (!is_aligned(range.end, atom_size) && range.end != memory.allocation_size))
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`memory` has a memory type whose `property_flags` does not contain \
|
||||
`MemoryPropertyFlags::HOST_COHERENT`, and `range.start` and/or `range.end` \
|
||||
are not aligned to the `non_coherent_atom_size` device property"
|
||||
.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -1211,7 +1217,7 @@ impl MappedDeviceMemory {
|
||||
pub unsafe fn new_unchecked(
|
||||
memory: DeviceMemory,
|
||||
range: Range<DeviceSize>,
|
||||
) -> Result<Self, RuntimeError> {
|
||||
) -> Result<Self, VulkanError> {
|
||||
let device = memory.device();
|
||||
|
||||
let pointer = unsafe {
|
||||
@ -1226,7 +1232,7 @@ impl MappedDeviceMemory {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
};
|
||||
|
||||
@ -1279,7 +1285,10 @@ impl MappedDeviceMemory {
|
||||
///
|
||||
/// - Panics if `range` is empty.
|
||||
#[inline]
|
||||
pub unsafe fn invalidate_range(&self, range: Range<DeviceSize>) -> Result<(), VulkanError> {
|
||||
pub unsafe fn invalidate_range(
|
||||
&self,
|
||||
range: Range<DeviceSize>,
|
||||
) -> Result<(), Validated<VulkanError>> {
|
||||
self.validate_range(range.clone())?;
|
||||
|
||||
Ok(self.invalidate_range_unchecked(range)?)
|
||||
@ -1289,7 +1298,7 @@ impl MappedDeviceMemory {
|
||||
pub unsafe fn invalidate_range_unchecked(
|
||||
&self,
|
||||
range: Range<DeviceSize>,
|
||||
) -> Result<(), RuntimeError> {
|
||||
) -> Result<(), VulkanError> {
|
||||
if self.is_coherent {
|
||||
return Ok(());
|
||||
}
|
||||
@ -1304,7 +1313,7 @@ impl MappedDeviceMemory {
|
||||
let fns = self.memory.device().fns();
|
||||
(fns.v1_0.invalidate_mapped_memory_ranges)(self.memory.device().handle(), 1, &range)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -1330,7 +1339,10 @@ impl MappedDeviceMemory {
|
||||
///
|
||||
/// - Panics if `range` is empty.
|
||||
#[inline]
|
||||
pub unsafe fn flush_range(&self, range: Range<DeviceSize>) -> Result<(), VulkanError> {
|
||||
pub unsafe fn flush_range(
|
||||
&self,
|
||||
range: Range<DeviceSize>,
|
||||
) -> Result<(), Validated<VulkanError>> {
|
||||
self.validate_range(range.clone())?;
|
||||
|
||||
Ok(self.flush_range_unchecked(range)?)
|
||||
@ -1340,7 +1352,7 @@ impl MappedDeviceMemory {
|
||||
pub unsafe fn flush_range_unchecked(
|
||||
&self,
|
||||
range: Range<DeviceSize>,
|
||||
) -> Result<(), RuntimeError> {
|
||||
) -> Result<(), VulkanError> {
|
||||
if self.is_coherent {
|
||||
return Ok(());
|
||||
}
|
||||
@ -1355,7 +1367,7 @@ impl MappedDeviceMemory {
|
||||
let fns = self.device().fns();
|
||||
(fns.v1_0.flush_mapped_memory_ranges)(self.memory.device().handle(), 1, &range)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -1379,7 +1391,7 @@ impl MappedDeviceMemory {
|
||||
///
|
||||
/// - Panics if `range` is empty.
|
||||
#[inline]
|
||||
pub unsafe fn read(&self, range: Range<DeviceSize>) -> Result<&[u8], ValidationError> {
|
||||
pub unsafe fn read(&self, range: Range<DeviceSize>) -> Result<&[u8], Box<ValidationError>> {
|
||||
self.validate_range(range.clone())?;
|
||||
|
||||
Ok(self.read_unchecked(range))
|
||||
@ -1413,7 +1425,10 @@ impl MappedDeviceMemory {
|
||||
///
|
||||
/// - Panics if `range` is empty.
|
||||
#[inline]
|
||||
pub unsafe fn write(&self, range: Range<DeviceSize>) -> Result<&mut [u8], ValidationError> {
|
||||
pub unsafe fn write(
|
||||
&self,
|
||||
range: Range<DeviceSize>,
|
||||
) -> Result<&mut [u8], Box<ValidationError>> {
|
||||
self.validate_range(range.clone())?;
|
||||
|
||||
Ok(self.write_unchecked(range))
|
||||
@ -1430,25 +1445,25 @@ impl MappedDeviceMemory {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn validate_range(&self, range: Range<DeviceSize>) -> Result<(), ValidationError> {
|
||||
fn validate_range(&self, range: Range<DeviceSize>) -> Result<(), Box<ValidationError>> {
|
||||
// VUID-VkMappedMemoryRange-memory-00684
|
||||
// Guaranteed because `self` owns the memory and it's mapped during our lifetime.
|
||||
|
||||
if range.is_empty() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "range".into(),
|
||||
problem: "is empty".into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if range.start < self.range.start || range.end > self.range.end {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "range".into(),
|
||||
problem: "is not within the mapped range of this mapped device memory".into(),
|
||||
vuids: &["VUID-VkMappedMemoryRange-size-00685"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if !self.is_coherent {
|
||||
@ -1456,7 +1471,7 @@ impl MappedDeviceMemory {
|
||||
|| (!is_aligned(range.end, self.atom_size)
|
||||
&& range.end != self.memory.allocation_size)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "this mapped device memory has a memory type whose `property_flags` \
|
||||
does not contain `MemoryPropertyFlags::HOST_COHERENT`, and \
|
||||
`range.start` and/or `range.end` are not aligned to the \
|
||||
@ -1467,7 +1482,7 @@ impl MappedDeviceMemory {
|
||||
"VUID-VkMappedMemoryRange-size-01390",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ use crate::{
|
||||
device::{Device, DeviceOwned},
|
||||
instance::InstanceOwnedDebugWrapper,
|
||||
macros::{impl_id_counter, vulkan_bitflags},
|
||||
RuntimeError, ValidationError, VulkanError, VulkanObject,
|
||||
Validated, ValidationError, VulkanError, VulkanObject,
|
||||
};
|
||||
use smallvec::SmallVec;
|
||||
use std::{mem::MaybeUninit, num::NonZeroU64, ptr, sync::Arc};
|
||||
@ -92,7 +92,7 @@ impl PipelineCache {
|
||||
pub unsafe fn new(
|
||||
device: Arc<Device>,
|
||||
create_info: PipelineCacheCreateInfo,
|
||||
) -> Result<Arc<PipelineCache>, VulkanError> {
|
||||
) -> Result<Arc<PipelineCache>, Validated<VulkanError>> {
|
||||
Self::validate_new(&device, &create_info)?;
|
||||
|
||||
Ok(Self::new_unchecked(device, create_info)?)
|
||||
@ -101,7 +101,7 @@ impl PipelineCache {
|
||||
fn validate_new(
|
||||
device: &Device,
|
||||
create_info: &PipelineCacheCreateInfo,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
create_info
|
||||
.validate(device)
|
||||
.map_err(|err| err.add_context("create_info"))?;
|
||||
@ -113,7 +113,7 @@ impl PipelineCache {
|
||||
pub unsafe fn new_unchecked(
|
||||
device: Arc<Device>,
|
||||
create_info: PipelineCacheCreateInfo,
|
||||
) -> Result<Arc<PipelineCache>, RuntimeError> {
|
||||
) -> Result<Arc<PipelineCache>, VulkanError> {
|
||||
let &PipelineCacheCreateInfo {
|
||||
flags,
|
||||
ref initial_data,
|
||||
@ -141,7 +141,7 @@ impl PipelineCache {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
};
|
||||
|
||||
@ -205,7 +205,7 @@ impl PipelineCache {
|
||||
/// }
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn get_data(&self) -> Result<Vec<u8>, RuntimeError> {
|
||||
pub fn get_data(&self) -> Result<Vec<u8>, VulkanError> {
|
||||
let fns = self.device.fns();
|
||||
|
||||
let data = unsafe {
|
||||
@ -218,7 +218,7 @@ impl PipelineCache {
|
||||
ptr::null_mut(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
let mut data: Vec<u8> = Vec::with_capacity(count);
|
||||
let result = (fns.v1_0.get_pipeline_cache_data)(
|
||||
@ -234,7 +234,7 @@ impl PipelineCache {
|
||||
break data;
|
||||
}
|
||||
ash::vk::Result::INCOMPLETE => (),
|
||||
err => return Err(RuntimeError::from(err)),
|
||||
err => return Err(VulkanError::from(err)),
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -251,22 +251,22 @@ impl PipelineCache {
|
||||
pub fn merge<'a>(
|
||||
&self,
|
||||
src_caches: impl IntoIterator<Item = &'a PipelineCache>,
|
||||
) -> Result<(), VulkanError> {
|
||||
) -> Result<(), Validated<VulkanError>> {
|
||||
let src_caches: SmallVec<[_; 8]> = src_caches.into_iter().collect();
|
||||
self.validate_merge(&src_caches)?;
|
||||
|
||||
unsafe { Ok(self.merge_unchecked(src_caches)?) }
|
||||
}
|
||||
|
||||
fn validate_merge(&self, src_caches: &[&PipelineCache]) -> Result<(), ValidationError> {
|
||||
fn validate_merge(&self, src_caches: &[&PipelineCache]) -> Result<(), Box<ValidationError>> {
|
||||
for (index, &src_cache) in src_caches.iter().enumerate() {
|
||||
if src_cache == self {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("src_caches[{}]", index).into(),
|
||||
problem: "equals `self`".into(),
|
||||
vuids: &["VUID-vkMergePipelineCaches-dstCache-00770"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -277,7 +277,7 @@ impl PipelineCache {
|
||||
pub unsafe fn merge_unchecked<'a>(
|
||||
&self,
|
||||
src_caches: impl IntoIterator<Item = &'a PipelineCache>,
|
||||
) -> Result<(), RuntimeError> {
|
||||
) -> Result<(), VulkanError> {
|
||||
let src_caches_vk: SmallVec<[_; 8]> =
|
||||
src_caches.into_iter().map(VulkanObject::handle).collect();
|
||||
|
||||
@ -289,7 +289,7 @@ impl PipelineCache {
|
||||
src_caches_vk.as_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -358,7 +358,7 @@ impl Default for PipelineCacheCreateInfo {
|
||||
}
|
||||
|
||||
impl PipelineCacheCreateInfo {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
flags,
|
||||
initial_data: _,
|
||||
|
@ -29,7 +29,7 @@ use crate::{
|
||||
macros::impl_id_counter,
|
||||
pipeline::{cache::PipelineCache, layout::PipelineLayout, Pipeline, PipelineBindPoint},
|
||||
shader::{DescriptorBindingRequirements, ShaderExecution, ShaderStage},
|
||||
RuntimeError, ValidationError, VulkanError, VulkanObject,
|
||||
Validated, ValidationError, VulkanError, VulkanObject,
|
||||
};
|
||||
use ahash::HashMap;
|
||||
use std::{ffi::CString, fmt::Debug, mem::MaybeUninit, num::NonZeroU64, ptr, sync::Arc};
|
||||
@ -59,7 +59,7 @@ impl ComputePipeline {
|
||||
device: Arc<Device>,
|
||||
cache: Option<Arc<PipelineCache>>,
|
||||
create_info: ComputePipelineCreateInfo,
|
||||
) -> Result<Arc<ComputePipeline>, VulkanError> {
|
||||
) -> Result<Arc<ComputePipeline>, Validated<VulkanError>> {
|
||||
Self::validate_new(&device, cache.as_ref().map(AsRef::as_ref), &create_info)?;
|
||||
|
||||
unsafe { Ok(Self::new_unchecked(device, cache, create_info)?) }
|
||||
@ -69,7 +69,7 @@ impl ComputePipeline {
|
||||
device: &Device,
|
||||
cache: Option<&PipelineCache>,
|
||||
create_info: &ComputePipelineCreateInfo,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
// VUID-vkCreateComputePipelines-pipelineCache-parent
|
||||
if let Some(cache) = &cache {
|
||||
assert_eq!(device, cache.device().as_ref());
|
||||
@ -87,7 +87,7 @@ impl ComputePipeline {
|
||||
device: Arc<Device>,
|
||||
cache: Option<Arc<PipelineCache>>,
|
||||
create_info: ComputePipelineCreateInfo,
|
||||
) -> Result<Arc<ComputePipeline>, RuntimeError> {
|
||||
) -> Result<Arc<ComputePipeline>, VulkanError> {
|
||||
let &ComputePipelineCreateInfo {
|
||||
flags,
|
||||
ref stage,
|
||||
@ -170,7 +170,7 @@ impl ComputePipeline {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
};
|
||||
|
||||
@ -312,7 +312,7 @@ impl ComputePipelineCreateInfo {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
flags,
|
||||
ref stage,
|
||||
@ -342,12 +342,12 @@ impl ComputePipelineCreateInfo {
|
||||
let entry_point_info = entry_point.info();
|
||||
|
||||
if !matches!(entry_point_info.execution, ShaderExecution::Compute) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "stage.entry_point".into(),
|
||||
problem: "is not a `ShaderStage::Compute` entry point".into(),
|
||||
vuids: &["VUID-VkComputePipelineCreateInfo-stage-00701"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// TODO: Make sure that all VUIDs are indeed checked.
|
||||
|
@ -145,7 +145,7 @@ impl ColorBlendState {
|
||||
self
|
||||
}
|
||||
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
flags,
|
||||
logic_op,
|
||||
@ -164,14 +164,14 @@ impl ColorBlendState {
|
||||
|
||||
if let Some(logic_op) = logic_op {
|
||||
if !device.enabled_features().logic_op {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "logic_op".into(),
|
||||
problem: "is `Some`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"logic_op",
|
||||
)])]),
|
||||
vuids: &["VUID-VkPipelineColorBlendStateCreateInfo-logicOpEnable-00606"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
match logic_op {
|
||||
@ -188,14 +188,14 @@ impl ColorBlendState {
|
||||
}
|
||||
StateMode::Dynamic => {
|
||||
if !device.enabled_features().extended_dynamic_state2_logic_op {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "logic_op".into(),
|
||||
problem: "is dynamic".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"extended_dynamic_state2_logic_op",
|
||||
)])]),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-04869"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -214,7 +214,7 @@ impl ColorBlendState {
|
||||
|
||||
for (index, state) in attachments.iter().enumerate().skip(1) {
|
||||
if state != first {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: format!(
|
||||
"`attachments[{}]` does not equal `attachments[0]`",
|
||||
index
|
||||
@ -225,7 +225,7 @@ impl ColorBlendState {
|
||||
)])]),
|
||||
vuids: &["VUID-VkPipelineColorBlendStateCreateInfo-pAttachments-00605"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -348,7 +348,7 @@ pub struct ColorBlendAttachmentState {
|
||||
}
|
||||
|
||||
impl ColorBlendAttachmentState {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
ref blend,
|
||||
color_write_mask: _,
|
||||
@ -364,26 +364,26 @@ impl ColorBlendAttachmentState {
|
||||
match color_write_enable {
|
||||
StateMode::Fixed(enable) => {
|
||||
if !enable && !device.enabled_features().color_write_enable {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "color_write_enable".into(),
|
||||
problem: "is `false`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"color_write_enable",
|
||||
)])]),
|
||||
vuids: &["VUID-VkPipelineColorWriteCreateInfoEXT-pAttachments-04801"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
StateMode::Dynamic => {
|
||||
if !device.enabled_features().color_write_enable {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "color_write_enable".into(),
|
||||
problem: "is dynamic".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"color_write_enable",
|
||||
)])]),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-04800"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -459,7 +459,7 @@ impl AttachmentBlend {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
src_color_blend_factor,
|
||||
dst_color_blend_factor,
|
||||
@ -525,14 +525,14 @@ impl AttachmentBlend {
|
||||
| BlendFactor::Src1Alpha
|
||||
| BlendFactor::OneMinusSrc1Alpha
|
||||
) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "src_color_blend_factor".into(),
|
||||
problem: "is `BlendFactor::Src1*`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"dual_src_blend",
|
||||
)])]),
|
||||
vuids: &["VUID-VkPipelineColorBlendAttachmentState-srcColorBlendFactor-00608"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if matches!(
|
||||
@ -542,14 +542,14 @@ impl AttachmentBlend {
|
||||
| BlendFactor::Src1Alpha
|
||||
| BlendFactor::OneMinusSrc1Alpha
|
||||
) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "dst_color_blend_factor".into(),
|
||||
problem: "is `BlendFactor::Src1*`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"dual_src_blend",
|
||||
)])]),
|
||||
vuids: &["VUID-VkPipelineColorBlendAttachmentState-dstColorBlendFactor-00609"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if matches!(
|
||||
@ -559,14 +559,14 @@ impl AttachmentBlend {
|
||||
| BlendFactor::Src1Alpha
|
||||
| BlendFactor::OneMinusSrc1Alpha
|
||||
) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "src_alpha_blend_factor".into(),
|
||||
problem: "is `BlendFactor::Src1*`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"dual_src_blend",
|
||||
)])]),
|
||||
vuids: &["VUID-VkPipelineColorBlendAttachmentState-srcAlphaBlendFactor-00610"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if matches!(
|
||||
@ -576,14 +576,14 @@ impl AttachmentBlend {
|
||||
| BlendFactor::Src1Alpha
|
||||
| BlendFactor::OneMinusSrc1Alpha
|
||||
) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "dst_alpha_blend_factor".into(),
|
||||
problem: "is `BlendFactor::Src1*`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"dual_src_blend",
|
||||
)])]),
|
||||
vuids: &["VUID-VkPipelineColorBlendAttachmentState-dstAlphaBlendFactor-00611"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -594,7 +594,7 @@ impl AttachmentBlend {
|
||||
src_color_blend_factor,
|
||||
BlendFactor::ConstantAlpha | BlendFactor::OneMinusConstantAlpha
|
||||
) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "this device is a portability subset device, and \
|
||||
`src_color_blend_factor` is `BlendFactor::ConstantAlpha` or \
|
||||
`BlendFactor::OneMinusConstantAlpha`".into(),
|
||||
@ -603,14 +603,14 @@ impl AttachmentBlend {
|
||||
)])]),
|
||||
vuids: &["VUID-VkPipelineColorBlendAttachmentState-constantAlphaColorBlendFactors-04454"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if matches!(
|
||||
dst_color_blend_factor,
|
||||
BlendFactor::ConstantAlpha | BlendFactor::OneMinusConstantAlpha
|
||||
) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "this device is a portability subset device, and \
|
||||
`dst_color_blend_factor` is `BlendFactor::ConstantAlpha` or \
|
||||
`BlendFactor::OneMinusConstantAlpha`".into(),
|
||||
@ -619,7 +619,7 @@ impl AttachmentBlend {
|
||||
)])]),
|
||||
vuids: &["VUID-VkPipelineColorBlendAttachmentState-constantAlphaColorBlendFactors-04455"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,7 +87,7 @@ impl DepthStencilState {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
flags,
|
||||
ref depth,
|
||||
@ -112,7 +112,7 @@ impl DepthStencilState {
|
||||
|
||||
if let Some(depth_bounds_state) = depth_bounds {
|
||||
if !device.enabled_features().depth_bounds {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "depth_bounds".into(),
|
||||
problem: "is `Some`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
@ -121,7 +121,7 @@ impl DepthStencilState {
|
||||
vuids: &[
|
||||
"VUID-VkPipelineDepthStencilStateCreateInfo-depthBoundsTestEnable-00598",
|
||||
],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
depth_bounds_state
|
||||
@ -198,7 +198,7 @@ pub struct DepthState {
|
||||
}
|
||||
|
||||
impl DepthState {
|
||||
pub(crate) fn validate(self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let Self {
|
||||
enable_dynamic,
|
||||
write_enable,
|
||||
@ -209,7 +209,7 @@ impl DepthState {
|
||||
&& !(device.api_version() >= Version::V1_3
|
||||
|| device.enabled_features().extended_dynamic_state)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "enable_dynamic".into(),
|
||||
problem: "is `true`".into(),
|
||||
requires_one_of: RequiresOneOf(&[
|
||||
@ -218,7 +218,7 @@ impl DepthState {
|
||||
]),
|
||||
// vuids?
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
match write_enable {
|
||||
@ -227,7 +227,7 @@ impl DepthState {
|
||||
if !(device.api_version() >= Version::V1_3
|
||||
|| device.enabled_features().extended_dynamic_state)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "write_enable".into(),
|
||||
problem: "is dynamic".into(),
|
||||
requires_one_of: RequiresOneOf(&[
|
||||
@ -236,7 +236,7 @@ impl DepthState {
|
||||
]),
|
||||
// vuids?
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -257,7 +257,7 @@ impl DepthState {
|
||||
if !(device.api_version() >= Version::V1_3
|
||||
|| device.enabled_features().extended_dynamic_state)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "compare_op".into(),
|
||||
problem: "is dynamic".into(),
|
||||
requires_one_of: RequiresOneOf(&[
|
||||
@ -266,7 +266,7 @@ impl DepthState {
|
||||
]),
|
||||
// vuids?
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -310,7 +310,7 @@ pub struct DepthBoundsState {
|
||||
}
|
||||
|
||||
impl DepthBoundsState {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
enable_dynamic,
|
||||
ref bounds,
|
||||
@ -320,7 +320,7 @@ impl DepthBoundsState {
|
||||
&& !(device.api_version() >= Version::V1_3
|
||||
|| device.enabled_features().extended_dynamic_state)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "enable_dynamic".into(),
|
||||
problem: "is `true`".into(),
|
||||
requires_one_of: RequiresOneOf(&[
|
||||
@ -329,31 +329,31 @@ impl DepthBoundsState {
|
||||
]),
|
||||
// vuids?
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if let StateMode::Fixed(bounds) = bounds {
|
||||
if !device.enabled_extensions().ext_depth_range_unrestricted {
|
||||
if !(0.0..1.0).contains(bounds.start()) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "bounds.start".into(),
|
||||
problem: "is not between 0.0 and 1.0 inclusive".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[
|
||||
Requires::DeviceExtension("ext_depth_range_unrestricted"),
|
||||
])]),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-02510"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if !(0.0..1.0).contains(bounds.end()) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "bounds.end".into(),
|
||||
problem: "is not between 0.0 and 1.0 inclusive".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[
|
||||
Requires::DeviceExtension("ext_depth_range_unrestricted"),
|
||||
])]),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-02510"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -397,7 +397,7 @@ pub struct StencilState {
|
||||
}
|
||||
|
||||
impl StencilState {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &StencilState {
|
||||
enable_dynamic,
|
||||
ref front,
|
||||
@ -408,7 +408,7 @@ impl StencilState {
|
||||
&& !(device.api_version() >= Version::V1_3
|
||||
|| device.enabled_features().extended_dynamic_state)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "enable_dynamic".into(),
|
||||
problem: "is `true`".into(),
|
||||
requires_one_of: RequiresOneOf(&[
|
||||
@ -417,7 +417,7 @@ impl StencilState {
|
||||
]),
|
||||
// vuids?
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
match (front.ops, back.ops) {
|
||||
@ -433,7 +433,7 @@ impl StencilState {
|
||||
if !(device.api_version() >= Version::V1_3
|
||||
|| device.enabled_features().extended_dynamic_state)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`front.ops` and `back.ops` are dynamic".into(),
|
||||
requires_one_of: RequiresOneOf(&[
|
||||
RequiresAllOf(&[Requires::APIVersion(Version::V1_3)]),
|
||||
@ -441,17 +441,17 @@ impl StencilState {
|
||||
]),
|
||||
// vuids?
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`front.ops` and `back.ops` are \
|
||||
not both fixed or both dynamic"
|
||||
.into(),
|
||||
// vuids?
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -459,39 +459,39 @@ impl StencilState {
|
||||
(front.compare_mask, back.compare_mask),
|
||||
(StateMode::Fixed(_), StateMode::Fixed(_)) | (StateMode::Dynamic, StateMode::Dynamic)
|
||||
) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`front.compare_mask` and `back.compare_mask` are \
|
||||
not both fixed or both dynamic"
|
||||
.into(),
|
||||
// vuids?
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if !matches!(
|
||||
(front.write_mask, back.write_mask),
|
||||
(StateMode::Fixed(_), StateMode::Fixed(_)) | (StateMode::Dynamic, StateMode::Dynamic)
|
||||
) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`front.write_mask` and `back.write_mask` are \
|
||||
not both fixed or both dynamic"
|
||||
.into(),
|
||||
// vuids?
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if !matches!(
|
||||
(front.reference, back.reference),
|
||||
(StateMode::Fixed(_), StateMode::Fixed(_)) | (StateMode::Dynamic, StateMode::Dynamic)
|
||||
) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`front.reference` and `back.reference` are \
|
||||
not both fixed or both dynamic"
|
||||
.into(),
|
||||
// vuids?
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -560,7 +560,7 @@ pub struct StencilOps {
|
||||
}
|
||||
|
||||
impl StencilOps {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
fail_op,
|
||||
pass_op,
|
||||
|
@ -46,7 +46,7 @@ impl DiscardRectangleState {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
mode,
|
||||
ref rectangles,
|
||||
@ -67,14 +67,14 @@ impl DiscardRectangleState {
|
||||
};
|
||||
|
||||
if discard_rectangle_count > properties.max_discard_rectangles.unwrap() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "rectangles".into(),
|
||||
problem: "the length exceeds the `max_discard_rectangles` limit".into(),
|
||||
vuids: &[
|
||||
"VUID-VkPipelineDiscardRectangleStateCreateInfoEXT-discardRectangleCount-00582",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -84,7 +84,7 @@ impl InputAssemblyState {
|
||||
self
|
||||
}
|
||||
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
topology,
|
||||
primitive_restart_enable,
|
||||
@ -106,7 +106,7 @@ impl InputAssemblyState {
|
||||
if device.enabled_extensions().khr_portability_subset
|
||||
&& !device.enabled_features().triangle_fans
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "this device is a portability subset device, and \
|
||||
`topology` is `PrimitiveTopology::TriangleFan`"
|
||||
.into(),
|
||||
@ -115,7 +115,7 @@ impl InputAssemblyState {
|
||||
])]),
|
||||
vuids: &["VUID-VkPipelineInputAssemblyStateCreateInfo-triangleFans-04452"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
PrimitiveTopology::LineListWithAdjacency
|
||||
@ -123,7 +123,7 @@ impl InputAssemblyState {
|
||||
| PrimitiveTopology::TriangleListWithAdjacency
|
||||
| PrimitiveTopology::TriangleStripWithAdjacency => {
|
||||
if !device.enabled_features().geometry_shader {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "topology".into(),
|
||||
problem: "is `PrimitiveTopology::*WithAdjacency`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[
|
||||
@ -132,12 +132,12 @@ impl InputAssemblyState {
|
||||
vuids: &[
|
||||
"VUID-VkPipelineInputAssemblyStateCreateInfo-topology-00429",
|
||||
],
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
PrimitiveTopology::PatchList => {
|
||||
if !device.enabled_features().tessellation_shader {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "topology".into(),
|
||||
problem: "is `PrimitiveTopology::PatchList`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[
|
||||
@ -146,7 +146,7 @@ impl InputAssemblyState {
|
||||
vuids: &[
|
||||
"VUID-VkPipelineInputAssemblyStateCreateInfo-topology-00430",
|
||||
],
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
@ -165,7 +165,7 @@ impl InputAssemblyState {
|
||||
if !(device.api_version() >= Version::V1_3
|
||||
|| device.enabled_features().extended_dynamic_state)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "topology".into(),
|
||||
problem: "is dynamic".into(),
|
||||
requires_one_of: RequiresOneOf(&[
|
||||
@ -174,7 +174,7 @@ impl InputAssemblyState {
|
||||
]),
|
||||
// vuids?
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -191,7 +191,7 @@ impl InputAssemblyState {
|
||||
| PrimitiveTopology::TriangleListWithAdjacency,
|
||||
) => {
|
||||
if !device.enabled_features().primitive_topology_list_restart {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`topology` is `PrimitiveTopology::*List`, and \
|
||||
`primitive_restart_enable` is `true`"
|
||||
.into(),
|
||||
@ -200,7 +200,7 @@ impl InputAssemblyState {
|
||||
])]),
|
||||
vuids: &["VUID-VkPipelineInputAssemblyStateCreateInfo-topology-06252"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
PartialStateMode::Fixed(PrimitiveTopology::PatchList) => {
|
||||
@ -208,7 +208,7 @@ impl InputAssemblyState {
|
||||
.enabled_features()
|
||||
.primitive_topology_patch_list_restart
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`topology` is `PrimitiveTopology::PatchList`, and \
|
||||
`primitive_restart_enable` is `true`"
|
||||
.into(),
|
||||
@ -217,7 +217,7 @@ impl InputAssemblyState {
|
||||
])]),
|
||||
vuids: &["VUID-VkPipelineInputAssemblyStateCreateInfo-topology-06253"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
@ -228,7 +228,7 @@ impl InputAssemblyState {
|
||||
if !(device.api_version() >= Version::V1_3
|
||||
|| device.enabled_features().extended_dynamic_state2)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "primitive_restart_enable".into(),
|
||||
problem: "is dynamic".into(),
|
||||
requires_one_of: RequiresOneOf(&[
|
||||
@ -237,7 +237,7 @@ impl InputAssemblyState {
|
||||
]),
|
||||
// vuids?
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -93,8 +93,7 @@ use crate::{
|
||||
DescriptorBindingRequirements, FragmentShaderExecution, FragmentTestsStages,
|
||||
ShaderExecution, ShaderScalarType, ShaderStage, ShaderStages,
|
||||
},
|
||||
Requires, RequiresAllOf, RequiresOneOf, RuntimeError, ValidationError, VulkanError,
|
||||
VulkanObject,
|
||||
Requires, RequiresAllOf, RequiresOneOf, Validated, ValidationError, VulkanError, VulkanObject,
|
||||
};
|
||||
use ahash::HashMap;
|
||||
use smallvec::SmallVec;
|
||||
@ -154,7 +153,7 @@ impl GraphicsPipeline {
|
||||
device: Arc<Device>,
|
||||
cache: Option<Arc<PipelineCache>>,
|
||||
create_info: GraphicsPipelineCreateInfo,
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
) -> Result<Arc<Self>, Validated<VulkanError>> {
|
||||
Self::validate_new(&device, cache.as_ref().map(AsRef::as_ref), &create_info)?;
|
||||
|
||||
unsafe { Ok(Self::new_unchecked(device, cache, create_info)?) }
|
||||
@ -164,7 +163,7 @@ impl GraphicsPipeline {
|
||||
device: &Device,
|
||||
_cache: Option<&PipelineCache>,
|
||||
create_info: &GraphicsPipelineCreateInfo,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
create_info
|
||||
.validate(device)
|
||||
.map_err(|err| err.add_context("create_info"))?;
|
||||
@ -177,7 +176,7 @@ impl GraphicsPipeline {
|
||||
device: Arc<Device>,
|
||||
cache: Option<Arc<PipelineCache>>,
|
||||
create_info: GraphicsPipelineCreateInfo,
|
||||
) -> Result<Arc<Self>, RuntimeError> {
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
let &GraphicsPipelineCreateInfo {
|
||||
flags,
|
||||
ref stages,
|
||||
@ -1141,7 +1140,7 @@ impl GraphicsPipeline {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
output.assume_init()
|
||||
};
|
||||
@ -1880,7 +1879,7 @@ impl GraphicsPipelineCreateInfo {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
flags,
|
||||
ref stages,
|
||||
@ -1926,7 +1925,7 @@ impl GraphicsPipelineCreateInfo {
|
||||
let stage_flag = ShaderStages::from(stage_enum);
|
||||
|
||||
if stages_present.intersects(stage_flag) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "stages".into(),
|
||||
problem: format!(
|
||||
"contains more than one element whose stage is \
|
||||
@ -1936,7 +1935,7 @@ impl GraphicsPipelineCreateInfo {
|
||||
.into(),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-stage-06897"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
const PRIMITIVE_SHADING_STAGES: ShaderStages = ShaderStages::VERTEX
|
||||
@ -1950,13 +1949,13 @@ impl GraphicsPipelineCreateInfo {
|
||||
|| stage_flag.intersects(MESH_SHADING_STAGES)
|
||||
&& stages_present.intersects(PRIMITIVE_SHADING_STAGES)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "stages".into(),
|
||||
problem: "contains both primitive shading stages and mesh shading stages"
|
||||
.into(),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-pStages-02095"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
let stage_slot = match stage_enum {
|
||||
@ -1966,12 +1965,12 @@ impl GraphicsPipelineCreateInfo {
|
||||
ShaderStage::Geometry => &mut geometry_stage,
|
||||
ShaderStage::Fragment => &mut fragment_stage,
|
||||
_ => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("stages[{}]", stage_index).into(),
|
||||
problem: "is not a pre-rasterization or fragment shader stage".into(),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-pStages-06896"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
@ -1991,24 +1990,24 @@ impl GraphicsPipelineCreateInfo {
|
||||
need_pre_rasterization_shader_state,
|
||||
) {
|
||||
(true, false) => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the pipeline is not being created with \
|
||||
pre-rasterization shader state, but \
|
||||
`rasterization_state` is `Some`"
|
||||
.into(),
|
||||
// vuids?
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
(false, true) => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the pipeline is being created with \
|
||||
pre-rasterization shader state, but \
|
||||
`rasterization_state` is `None`"
|
||||
.into(),
|
||||
// vuids?
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
@ -2032,24 +2031,24 @@ impl GraphicsPipelineCreateInfo {
|
||||
|
||||
match (vertex_stage.is_some(), need_pre_rasterization_shader_state) {
|
||||
(true, false) => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the pipeline is not being created with \
|
||||
pre-rasterization shader state, but `stages` contains a \
|
||||
`ShaderStage::Vertex` stage"
|
||||
.into(),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-pStages-06895"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
(false, true) => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the pipeline is being created with \
|
||||
pre-rasterization shader state, but `stages` does not contain a \
|
||||
`ShaderStage::Vertex` stage"
|
||||
.into(),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-stage-02096"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
@ -2059,14 +2058,14 @@ impl GraphicsPipelineCreateInfo {
|
||||
need_pre_rasterization_shader_state,
|
||||
) {
|
||||
(true, false) => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the pipeline is not being created with \
|
||||
pre-rasterization shader state, but `stages` contains a \
|
||||
`ShaderStage::TessellationControl` stage"
|
||||
.into(),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-pStages-06895"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
(false, true) => (),
|
||||
_ => (),
|
||||
@ -2077,14 +2076,14 @@ impl GraphicsPipelineCreateInfo {
|
||||
need_pre_rasterization_shader_state,
|
||||
) {
|
||||
(true, false) => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the pipeline is not being created with \
|
||||
pre-rasterization shader state, but `stages` contains a \
|
||||
`ShaderStage::TessellationEvaluation` stage"
|
||||
.into(),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-pStages-06895"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
(false, true) => (),
|
||||
_ => (),
|
||||
@ -2093,25 +2092,25 @@ impl GraphicsPipelineCreateInfo {
|
||||
if stages_present.intersects(ShaderStages::TESSELLATION_CONTROL)
|
||||
&& !stages_present.intersects(ShaderStages::TESSELLATION_EVALUATION)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "stages".into(),
|
||||
problem: "contains a `ShaderStage::TessellationControl` stage, but not a \
|
||||
`ShaderStage::TessellationEvaluation` stage"
|
||||
.into(),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-pStages-00729"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
} else if stages_present.intersects(ShaderStages::TESSELLATION_EVALUATION)
|
||||
&& !stages_present.intersects(ShaderStages::TESSELLATION_CONTROL)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "stages".into(),
|
||||
problem: "contains a `ShaderStage::TessellationEvaluation` stage, but not a \
|
||||
`ShaderStage::TessellationControl` stage"
|
||||
.into(),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-pStages-00730"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
match (
|
||||
@ -2119,14 +2118,14 @@ impl GraphicsPipelineCreateInfo {
|
||||
need_pre_rasterization_shader_state,
|
||||
) {
|
||||
(true, false) => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the pipeline is not being created with \
|
||||
pre-rasterization shader state, but `stages` contains a \
|
||||
`ShaderStage::Geometry` stage"
|
||||
.into(),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-pStages-06895"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
(false, true) => (),
|
||||
_ => (),
|
||||
@ -2134,14 +2133,14 @@ impl GraphicsPipelineCreateInfo {
|
||||
|
||||
match (fragment_stage.is_some(), need_fragment_shader_state) {
|
||||
(true, false) => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the pipeline is not being created with \
|
||||
fragment shader state, but `stages` contains a \
|
||||
`ShaderStage::Geometry` stage"
|
||||
.into(),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-pStages-06894"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
(false, true) => (),
|
||||
_ => (),
|
||||
@ -2149,46 +2148,46 @@ impl GraphicsPipelineCreateInfo {
|
||||
|
||||
match (vertex_input_state.is_some(), need_vertex_input_state) {
|
||||
(true, false) => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the pipeline is not being created with \
|
||||
vertex input state, but \
|
||||
`vertex_input_state` is `Some`"
|
||||
.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
(false, true) => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the pipeline is being created with \
|
||||
vertex input state, but \
|
||||
`vertex_input_state` is `None`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-pStages-02097"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
match (input_assembly_state.is_some(), need_vertex_input_state) {
|
||||
(true, false) => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the pipeline is not being created with \
|
||||
vertex input state, but \
|
||||
`input_assembly_state` is `Some`"
|
||||
.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
(false, true) => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the pipeline is being created with \
|
||||
vertex input state, but \
|
||||
`input_assembly_state` is `None`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-pStages-02098"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
@ -2201,17 +2200,17 @@ impl GraphicsPipelineCreateInfo {
|
||||
),
|
||||
) {
|
||||
(true, false) => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the pipeline is not being created with \
|
||||
pre-rasterization state, or \
|
||||
`stages` does not contain tessellation shader stages, but \
|
||||
`tessellation_state` is `Some`"
|
||||
.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
(false, true) => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the pipeline is being created with \
|
||||
pre-rasterization state, and \
|
||||
`stages` contains tessellation shader stages, but \
|
||||
@ -2219,7 +2218,7 @@ impl GraphicsPipelineCreateInfo {
|
||||
.into(),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-pStages-00731"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
@ -2234,17 +2233,17 @@ impl GraphicsPipelineCreateInfo {
|
||||
!= StateMode::Fixed(true),
|
||||
) {
|
||||
(true, false) => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the pipeline is not being created with \
|
||||
pre-rasterization state, or \
|
||||
`rasterization_state.rasterization_discard_enable` is `true`, but \
|
||||
`viewport_state` is `Some`"
|
||||
.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
(false, true) => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the pipeline is being created with \
|
||||
pre-rasterization state, and \
|
||||
`rasterization_state.rasterization_discard_enable` is `false` \
|
||||
@ -2255,30 +2254,30 @@ impl GraphicsPipelineCreateInfo {
|
||||
"VUID-VkGraphicsPipelineCreateInfo-pViewportState-04892",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
match (multisample_state.is_some(), need_fragment_output_state) {
|
||||
(true, false) => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the pipeline is not being created with \
|
||||
fragment output state, but \
|
||||
`multisample_state` is `Some`"
|
||||
.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
(false, true) => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the pipeline is being created with \
|
||||
fragment output state, but \
|
||||
`multisample_state` is `None`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-rasterizerDiscardEnable-00751"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
@ -2298,17 +2297,17 @@ impl GraphicsPipelineCreateInfo {
|
||||
},
|
||||
) {
|
||||
(true, false) => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the pipeline is being created with \
|
||||
fragment output state, and \
|
||||
`subpass` does not have a depth/stencil attachment, but \
|
||||
`depth_stencil_state` is `Some`"
|
||||
.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
(false, true) => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the pipeline is not being created with \
|
||||
fragment output state, or \
|
||||
`subpass` has a depth/stencil attachment, but \
|
||||
@ -2320,7 +2319,7 @@ impl GraphicsPipelineCreateInfo {
|
||||
"VUID-VkGraphicsPipelineCreateInfo-renderPass-06053",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
@ -2339,17 +2338,17 @@ impl GraphicsPipelineCreateInfo {
|
||||
},
|
||||
) {
|
||||
(true, false) => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the pipeline is not being created with \
|
||||
fragment output state, or \
|
||||
`subpass` does not have any color attachments, but \
|
||||
`color_blend_state` is `Some`"
|
||||
.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
(false, true) => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the pipeline is being created with \
|
||||
fragment output state, and \
|
||||
`subpass` has a color attachment, but \
|
||||
@ -2360,7 +2359,7 @@ impl GraphicsPipelineCreateInfo {
|
||||
"VUID-VkGraphicsPipelineCreateInfo-renderPass-06054",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
@ -2372,23 +2371,23 @@ impl GraphicsPipelineCreateInfo {
|
||||
|| need_fragment_output_state,
|
||||
) {
|
||||
(true, false) => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the pipeline is not being created with \
|
||||
pre-rasterization, fragment shader or fragment output state, but \
|
||||
`subpass` is `Some`"
|
||||
.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
(false, true) => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the pipeline is being created with \
|
||||
pre-rasterization, fragment shader or fragment output state, but \
|
||||
`subpass` is `None`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-renderPass-06575"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
@ -2398,14 +2397,14 @@ impl GraphicsPipelineCreateInfo {
|
||||
need_pre_rasterization_shader_state,
|
||||
) {
|
||||
(true, false) => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the pipeline is not being created with \
|
||||
pre-rasterization state, but \
|
||||
`discard_rectangle_state` is `Some`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-04058"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
(false, true) => (),
|
||||
_ => (),
|
||||
@ -2461,7 +2460,7 @@ impl GraphicsPipelineCreateInfo {
|
||||
if let Err(err) = (input.entry_point.info().input_interface)
|
||||
.matches(&output.entry_point.info().output_interface)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "stages".into(),
|
||||
problem: format!(
|
||||
"the output interface of the `ShaderStage::{:?}` stage does not \
|
||||
@ -2476,7 +2475,7 @@ impl GraphicsPipelineCreateInfo {
|
||||
"VUID-VkGraphicsPipelineCreateInfo-None-04889",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2566,7 +2565,7 @@ impl GraphicsPipelineCreateInfo {
|
||||
| ShaderStages::TESSELLATION_EVALUATION,
|
||||
) && !device.enabled_features().multiview_tessellation_shader
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`stages` contains tessellation shaders, and \
|
||||
`subpass` has a non-zero `view_mask`"
|
||||
.into(),
|
||||
@ -2575,13 +2574,13 @@ impl GraphicsPipelineCreateInfo {
|
||||
])]),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-renderPass-06047"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if stages_present.intersects(ShaderStages::GEOMETRY)
|
||||
&& !device.enabled_features().multiview_geometry_shader
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`stages` contains a geometry shader, and \
|
||||
`subpass` has a non-zero `view_mask`"
|
||||
.into(),
|
||||
@ -2590,20 +2589,20 @@ impl GraphicsPipelineCreateInfo {
|
||||
])]),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-renderPass-06048"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
PipelineSubpassType::BeginRendering(rendering_info) => {
|
||||
if !device.enabled_features().dynamic_rendering {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "subpass".into(),
|
||||
problem: "is `PipelineRenderPassType::BeginRendering`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"dynamic_rendering",
|
||||
)])]),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-dynamicRendering-06576"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
rendering_info
|
||||
@ -2624,7 +2623,7 @@ impl GraphicsPipelineCreateInfo {
|
||||
| ShaderStages::TESSELLATION_EVALUATION,
|
||||
) && !device.enabled_features().multiview_tessellation_shader
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`stages` contains tessellation shaders, and \
|
||||
`subpass.view_mask` is not 0"
|
||||
.into(),
|
||||
@ -2633,13 +2632,13 @@ impl GraphicsPipelineCreateInfo {
|
||||
])]),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-renderPass-06057"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if stages_present.intersects(ShaderStages::GEOMETRY)
|
||||
&& !device.enabled_features().multiview_geometry_shader
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`stages` contains a geometry shader, and \
|
||||
`subpass.view_mask` is not 0"
|
||||
.into(),
|
||||
@ -2648,7 +2647,7 @@ impl GraphicsPipelineCreateInfo {
|
||||
])]),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-renderPass-06058"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2657,14 +2656,14 @@ impl GraphicsPipelineCreateInfo {
|
||||
|
||||
if let Some(discard_rectangle_state) = discard_rectangle_state {
|
||||
if !device.enabled_extensions().ext_discard_rectangles {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "discard_rectangle_state".into(),
|
||||
problem: "is `Some`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::DeviceExtension(
|
||||
"ext_discard_rectangles",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
discard_rectangle_state
|
||||
@ -2686,7 +2685,7 @@ impl GraphicsPipelineCreateInfo {
|
||||
let attribute_desc = match vertex_input_state.attributes.get(&location) {
|
||||
Some(attribute_desc) => attribute_desc,
|
||||
None => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: format!(
|
||||
"the vertex shader has an input variable with location {0}, but \
|
||||
`vertex_input_state.attributes` does not contain {0}",
|
||||
@ -2695,7 +2694,7 @@ impl GraphicsPipelineCreateInfo {
|
||||
.into(),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-Input-07905"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
@ -2720,7 +2719,7 @@ impl GraphicsPipelineCreateInfo {
|
||||
) | (ShaderScalarType::Sint, NumericType::SINT)
|
||||
| (ShaderScalarType::Uint, NumericType::UINT)
|
||||
) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: format!(
|
||||
"`vertex_input_state.attributes[{}].format` has a different \
|
||||
scalar type than the vertex shader input variable with \
|
||||
@ -2730,7 +2729,7 @@ impl GraphicsPipelineCreateInfo {
|
||||
.into(),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-Input-07905"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2764,13 +2763,13 @@ impl GraphicsPipelineCreateInfo {
|
||||
|
||||
if let PartialStateMode::Fixed(topology) = input_assembly_state.topology {
|
||||
if !input.is_compatible_with(topology) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`input_assembly_state.topology` is not compatible with the \
|
||||
input topology of the geometry shader"
|
||||
.into(),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-pStages-00738"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2782,12 +2781,12 @@ impl GraphicsPipelineCreateInfo {
|
||||
match subpass {
|
||||
PipelineSubpassType::BeginRenderPass(subpass) => {
|
||||
if !subpass.is_compatible_with(&entry_point_info.output_interface) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`subpass` is not compatible with the \
|
||||
output interface of the fragment shader"
|
||||
.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
PipelineSubpassType::BeginRendering(_) => {
|
||||
@ -2808,13 +2807,13 @@ impl GraphicsPipelineCreateInfo {
|
||||
PartialStateMode::Dynamic(PrimitiveTopologyClass::Patch)
|
||||
| PartialStateMode::Fixed(PrimitiveTopology::PatchList)
|
||||
) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`stages` contains tessellation shaders, but \
|
||||
`input_assembly_state.topology` is not `PrimitiveTopology::PatchList`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-pStages-00736"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2833,7 +2832,7 @@ impl GraphicsPipelineCreateInfo {
|
||||
)
|
||||
&& front_reference != back_reference
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "this device is a portability subset device, \
|
||||
`rasterization_state.cull_mode` is `CullMode::None`, and \
|
||||
`depth_stencil_state.stencil.front.reference` does not equal \
|
||||
@ -2843,7 +2842,7 @@ impl GraphicsPipelineCreateInfo {
|
||||
)])]),
|
||||
vuids: &["VUID-VkPipelineDepthStencilStateCreateInfo-separateStencilMaskRef-04453"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2854,14 +2853,14 @@ impl GraphicsPipelineCreateInfo {
|
||||
PipelineSubpassType::BeginRenderPass(subpass) => {
|
||||
if let Some(samples) = subpass.num_samples() {
|
||||
if multisample_state.rasterization_samples != samples {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`multisample_state.rasterization_samples` does not \
|
||||
equal the number of samples in the color and depth/stencil \
|
||||
attachments of `subpass`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-subpass-00757"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2899,13 +2898,13 @@ impl GraphicsPipelineCreateInfo {
|
||||
};
|
||||
|
||||
if !has_depth_attachment {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`depth_stencil_state.depth` is `Some`, but `subpass` does not \
|
||||
have a depth attachment"
|
||||
.into(),
|
||||
// vuids?
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if let StateMode::Fixed(true) = depth_state.write_enable {
|
||||
@ -2929,14 +2928,14 @@ impl GraphicsPipelineCreateInfo {
|
||||
.intersects(ImageAspects::DEPTH)
|
||||
})
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`depth_stencil_state.depth.write_enable` is `true`, \
|
||||
but `subpass` does not have a depth attachment whose \
|
||||
layout for the depth aspect allows writing"
|
||||
.into(),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-renderPass-06039"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
PipelineSubpassType::BeginRendering(_) => {
|
||||
@ -2966,13 +2965,13 @@ impl GraphicsPipelineCreateInfo {
|
||||
};
|
||||
|
||||
if !has_stencil_attachment {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`depth_stencil_state.stencil` is `Some`, but `subpass` does not \
|
||||
have a stencil attachment"
|
||||
.into(),
|
||||
// vuids?
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2988,7 +2987,7 @@ impl GraphicsPipelineCreateInfo {
|
||||
};
|
||||
|
||||
if color_attachment_count != color_blend_state.attachments.len() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the length of `color_blend_state.attachments` does not equal the \
|
||||
number of color attachments in `subpass`"
|
||||
.into(),
|
||||
@ -2998,7 +2997,7 @@ impl GraphicsPipelineCreateInfo {
|
||||
"VUID-VkGraphicsPipelineCreateInfo-renderPass-06060",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
for (attachment_index, state) in color_blend_state.attachments.iter().enumerate() {
|
||||
@ -3025,7 +3024,7 @@ impl GraphicsPipelineCreateInfo {
|
||||
.potential_format_features()
|
||||
.intersects(FormatFeatures::COLOR_ATTACHMENT_BLEND)
|
||||
}) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: format!(
|
||||
"`color_blend_state.attachments[{}].blend` is `Some`, but \
|
||||
the format features of that color attachment in `subpass` \
|
||||
@ -3038,7 +3037,7 @@ impl GraphicsPipelineCreateInfo {
|
||||
"VUID-VkGraphicsPipelineCreateInfo-renderPass-06062",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ impl MultisampleState {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
rasterization_samples,
|
||||
sample_shading,
|
||||
@ -97,35 +97,35 @@ impl MultisampleState {
|
||||
|
||||
if let Some(min_sample_shading) = sample_shading {
|
||||
if !device.enabled_features().sample_rate_shading {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "min_sample_shading".into(),
|
||||
problem: "is `Some`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"sample_rate_shading",
|
||||
)])]),
|
||||
vuids: &["VUID-VkPipelineMultisampleStateCreateInfo-sampleShadingEnable-00784"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if !(0.0..=1.0).contains(&min_sample_shading) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "min_sample_shading".into(),
|
||||
problem: "is not between 0.0 and 1.0 inclusive".into(),
|
||||
vuids: &["VUID-VkPipelineMultisampleStateCreateInfo-minSampleShading-00786"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
if alpha_to_one_enable && !device.enabled_features().alpha_to_one {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "alpha_to_one_enable".into(),
|
||||
problem: "is `true`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"alpha_to_one",
|
||||
)])]),
|
||||
vuids: &["VUID-VkPipelineMultisampleStateCreateInfo-alphaToOneEnable-00785"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -140,7 +140,7 @@ impl RasterizationState {
|
||||
self
|
||||
}
|
||||
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
depth_clamp_enable,
|
||||
rasterizer_discard_enable,
|
||||
@ -173,25 +173,25 @@ impl RasterizationState {
|
||||
})?;
|
||||
|
||||
if depth_clamp_enable && !device.enabled_features().depth_clamp {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "depth_clamp_enable".into(),
|
||||
problem: "is `true`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"depth_clamp",
|
||||
)])]),
|
||||
vuids: &["VUID-VkPipelineRasterizationStateCreateInfo-depthClampEnable-00782"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if polygon_mode != PolygonMode::Fill && !device.enabled_features().fill_mode_non_solid {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "polygon_mode".into(),
|
||||
problem: "is not `PolygonMode::Fill`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"fill_mode_non_solid",
|
||||
)])]),
|
||||
vuids: &["VUID-VkPipelineRasterizationStateCreateInfo-polygonMode-01507"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
match rasterizer_discard_enable {
|
||||
@ -200,7 +200,7 @@ impl RasterizationState {
|
||||
&& !device.enabled_features().point_polygons
|
||||
&& polygon_mode == PolygonMode::Point
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "this device is a portability subset device, \
|
||||
`rasterizer_discard_enable` is `false`, and \
|
||||
`polygon_mode` is `PolygonMode::Point`"
|
||||
@ -210,14 +210,14 @@ impl RasterizationState {
|
||||
)])]),
|
||||
vuids: &["VUID-VkPipelineRasterizationStateCreateInfo-pointPolygons-04458"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
StateMode::Dynamic => {
|
||||
if !(device.api_version() >= Version::V1_3
|
||||
|| device.enabled_features().extended_dynamic_state2)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "rasterizer_discard_enable".into(),
|
||||
problem: "is dynamic".into(),
|
||||
requires_one_of: RequiresOneOf(&[
|
||||
@ -226,7 +226,7 @@ impl RasterizationState {
|
||||
]),
|
||||
// vuids?
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
@ -246,7 +246,7 @@ impl RasterizationState {
|
||||
if !(device.api_version() >= Version::V1_3
|
||||
|| device.enabled_features().extended_dynamic_state)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "cull_mode".into(),
|
||||
problem: "is dynamic".into(),
|
||||
requires_one_of: RequiresOneOf(&[
|
||||
@ -255,7 +255,7 @@ impl RasterizationState {
|
||||
]),
|
||||
// vuids?
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -274,7 +274,7 @@ impl RasterizationState {
|
||||
if !(device.api_version() >= Version::V1_3
|
||||
|| device.enabled_features().extended_dynamic_state)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "front_face".into(),
|
||||
problem: "is dynamic".into(),
|
||||
requires_one_of: RequiresOneOf(&[
|
||||
@ -283,7 +283,7 @@ impl RasterizationState {
|
||||
]),
|
||||
// vuids?
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -298,7 +298,7 @@ impl RasterizationState {
|
||||
&& !(device.api_version() >= Version::V1_3
|
||||
|| device.enabled_features().extended_dynamic_state2)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "depth_bias.enable_dynamic".into(),
|
||||
problem: "is `true`".into(),
|
||||
requires_one_of: RequiresOneOf(&[
|
||||
@ -307,84 +307,84 @@ impl RasterizationState {
|
||||
]),
|
||||
// vuids?
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if matches!(bias, StateMode::Fixed(bias) if bias.clamp != 0.0)
|
||||
&& !device.enabled_features().depth_bias_clamp
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "depth_bias.bias.clamp".into(),
|
||||
problem: "is not 0.0".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"depth_bias_clamp",
|
||||
)])]),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00754"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
if matches!(line_width, StateMode::Fixed(line_width) if line_width != 1.0)
|
||||
&& !device.enabled_features().wide_lines
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "line_width".into(),
|
||||
problem: "is not 1.0".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"wide_lines",
|
||||
)])]),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00749"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if line_rasterization_mode != LineRasterizationMode::Default {
|
||||
if !device.enabled_extensions().ext_line_rasterization {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "line_rasterization_mode".into(),
|
||||
problem: "`is not `LineRasterizationMode::Default`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::DeviceExtension(
|
||||
"ext_line_rasterization",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
match line_rasterization_mode {
|
||||
LineRasterizationMode::Default => (),
|
||||
LineRasterizationMode::Rectangular => {
|
||||
if !device.enabled_features().rectangular_lines {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "line_rasterization_mode".into(),
|
||||
problem: "is `LineRasterizationMode::Rectangular`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"rectangular_lines",
|
||||
)])]),
|
||||
vuids: &["VUID-VkPipelineRasterizationLineStateCreateInfoEXT-lineRasterizationMode-02768"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
LineRasterizationMode::Bresenham => {
|
||||
if !device.enabled_features().bresenham_lines {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "line_rasterization_mode".into(),
|
||||
problem: "is `LineRasterizationMode::Bresenham`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"bresenham_lines",
|
||||
)])]),
|
||||
vuids: &["VUID-VkPipelineRasterizationLineStateCreateInfoEXT-lineRasterizationMode-02769"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
LineRasterizationMode::RectangularSmooth => {
|
||||
if !device.enabled_features().smooth_lines {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "line_rasterization_mode".into(),
|
||||
problem: "is `LineRasterizationMode::RectangularSmooth`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"smooth_lines",
|
||||
)])]),
|
||||
vuids: &["VUID-VkPipelineRasterizationLineStateCreateInfoEXT-lineRasterizationMode-02770"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -392,33 +392,33 @@ impl RasterizationState {
|
||||
|
||||
if let Some(line_stipple) = line_stipple {
|
||||
if !device.enabled_extensions().ext_line_rasterization {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "line_stipple".into(),
|
||||
problem: "is `Some`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::DeviceExtension(
|
||||
"ext_line_rasterization",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if let StateMode::Fixed(line_stipple) = line_stipple {
|
||||
let &LineStipple { factor, pattern: _ } = line_stipple;
|
||||
|
||||
if !(1..=256).contains(&factor) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "line_stipple.factor".into(),
|
||||
problem: "is not between 1 and 256 inclusive".into(),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-stippledLineEnable-02767"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
match line_rasterization_mode {
|
||||
LineRasterizationMode::Default => {
|
||||
if !device.enabled_features().stippled_rectangular_lines {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`line_stipple` is `Some`, and \
|
||||
`line_rasterization_mode` is \
|
||||
`LineRasterizationMode::Default`".into(),
|
||||
@ -427,23 +427,23 @@ impl RasterizationState {
|
||||
)])]),
|
||||
vuids: &["VUID-VkPipelineRasterizationLineStateCreateInfoEXT-stippledLineEnable-02774"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if !properties.strict_lines {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`line_stipple` is `Some`, and \
|
||||
`line_rasterization_mode` is \
|
||||
`LineRasterizationMode::Default`, \
|
||||
but the `strict_lines` property is `false`".into(),
|
||||
vuids: &["VUID-VkPipelineRasterizationLineStateCreateInfoEXT-stippledLineEnable-02774"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
LineRasterizationMode::Rectangular => {
|
||||
if !device.enabled_features().stippled_rectangular_lines {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`line_stipple` is `Some`, and \
|
||||
`line_rasterization_mode` is \
|
||||
`LineRasterizationMode::Rectangular`".into(),
|
||||
@ -452,12 +452,12 @@ impl RasterizationState {
|
||||
)])]),
|
||||
vuids: &["VUID-VkPipelineRasterizationLineStateCreateInfoEXT-stippledLineEnable-02771"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
LineRasterizationMode::Bresenham => {
|
||||
if !device.enabled_features().stippled_bresenham_lines {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`line_stipple` is `Some`, and \
|
||||
`line_rasterization_mode` is \
|
||||
`LineRasterizationMode::Bresenham`".into(),
|
||||
@ -466,12 +466,12 @@ impl RasterizationState {
|
||||
)])]),
|
||||
vuids: &["VUID-VkPipelineRasterizationLineStateCreateInfoEXT-stippledLineEnable-02772"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
LineRasterizationMode::RectangularSmooth => {
|
||||
if !device.enabled_features().stippled_smooth_lines {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`line_stipple` is `Some`, and \
|
||||
`line_rasterization_mode` is \
|
||||
`LineRasterizationMode::RectangularSmooth`".into(),
|
||||
@ -480,7 +480,7 @@ impl RasterizationState {
|
||||
)])]),
|
||||
vuids: &["VUID-VkPipelineRasterizationLineStateCreateInfoEXT-stippledLineEnable-02773"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -151,7 +151,7 @@ impl PipelineRenderingCreateInfo {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
view_mask,
|
||||
ref color_attachment_formats,
|
||||
@ -163,25 +163,25 @@ impl PipelineRenderingCreateInfo {
|
||||
let properties = device.physical_device().properties();
|
||||
|
||||
if view_mask != 0 && !device.enabled_features().multiview {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "view_mask".into(),
|
||||
problem: "is not zero".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature("multiview")])]),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-multiview-06577"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
let view_count = u32::BITS - view_mask.leading_zeros();
|
||||
|
||||
if view_count > properties.max_multiview_view_count.unwrap_or(0) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "view_mask".into(),
|
||||
problem: "the number of views exceeds the \
|
||||
`max_multiview_view_count` limit"
|
||||
.into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature("multiview")])]),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-renderPass-06578"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
for (attachment_index, format) in color_attachment_formats
|
||||
@ -203,14 +203,14 @@ impl PipelineRenderingCreateInfo {
|
||||
.potential_format_features()
|
||||
.intersects(FormatFeatures::COLOR_ATTACHMENT)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("color_attachment_formats[{}]", attachment_index).into(),
|
||||
problem: "format features do not contain \
|
||||
`FormatFeature::COLOR_ATTACHMENT`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-renderPass-06582"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -227,23 +227,23 @@ impl PipelineRenderingCreateInfo {
|
||||
.potential_format_features()
|
||||
.intersects(FormatFeatures::DEPTH_STENCIL_ATTACHMENT)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "depth_attachment_format".into(),
|
||||
problem: "format features do not contain \
|
||||
`FormatFeature::DEPTH_STENCIL_ATTACHMENT`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-renderPass-06585"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if !format.aspects().intersects(ImageAspects::DEPTH) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "depth_attachment_format".into(),
|
||||
problem: "does not have a depth aspect".into(),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-renderPass-06587"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -260,23 +260,23 @@ impl PipelineRenderingCreateInfo {
|
||||
.potential_format_features()
|
||||
.intersects(FormatFeatures::DEPTH_STENCIL_ATTACHMENT)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "render_pass.stencil_attachment_format".into(),
|
||||
problem: "format features do not contain \
|
||||
`FormatFeature::DEPTH_STENCIL_ATTACHMENT`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-renderPass-06586"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if !format.aspects().intersects(ImageAspects::STENCIL) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "render_pass.stencil_attachment_format".into(),
|
||||
problem: "does not have a stencil aspect".into(),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-renderPass-06588"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -284,13 +284,13 @@ impl PipelineRenderingCreateInfo {
|
||||
(depth_attachment_format, stencil_attachment_format)
|
||||
{
|
||||
if depth_format != stencil_format {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`depth_attachment_format` and `stencil_attachment_format` are both \
|
||||
`Some`, but are not equal"
|
||||
.into(),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-renderPass-06589"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,7 @@ impl TessellationState {
|
||||
self
|
||||
}
|
||||
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
patch_control_points,
|
||||
domain_origin,
|
||||
@ -74,25 +74,25 @@ impl TessellationState {
|
||||
match patch_control_points {
|
||||
StateMode::Fixed(patch_control_points) => {
|
||||
if patch_control_points == 0 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "patch_control_points".into(),
|
||||
problem: "is zero".into(),
|
||||
vuids: &[
|
||||
"VUID-VkPipelineTessellationStateCreateInfo-patchControlPoints-01214",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if patch_control_points > properties.max_tessellation_patch_size {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "patch_control_points".into(),
|
||||
problem: "exceeds the `max_tessellation_patch_size` limit".into(),
|
||||
vuids: &[
|
||||
"VUID-VkPipelineTessellationStateCreateInfo-patchControlPoints-01214",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
StateMode::Dynamic => {
|
||||
@ -100,14 +100,14 @@ impl TessellationState {
|
||||
.enabled_features()
|
||||
.extended_dynamic_state2_patch_control_points
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "patch_control_points".into(),
|
||||
problem: "is dynamic".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"extended_dynamic_state2_patch_control_points",
|
||||
)])]),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-04870"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -126,7 +126,7 @@ impl TessellationState {
|
||||
&& !(device.api_version() >= Version::V1_1
|
||||
|| device.enabled_extensions().khr_maintenance2)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "domain_origin".into(),
|
||||
problem: "is not `TessellationDomainOrigin::UpperLeft`".into(),
|
||||
requires_one_of: RequiresOneOf(&[
|
||||
@ -134,7 +134,7 @@ impl TessellationState {
|
||||
RequiresAllOf(&[Requires::DeviceExtension("khr_maintenance2")]),
|
||||
]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -62,7 +62,10 @@ impl BuffersDefinition {
|
||||
#[allow(deprecated)]
|
||||
unsafe impl VertexDefinition for BuffersDefinition {
|
||||
#[inline]
|
||||
fn definition(&self, interface: &ShaderInterface) -> Result<VertexInputState, ValidationError> {
|
||||
fn definition(
|
||||
&self,
|
||||
interface: &ShaderInterface,
|
||||
) -> Result<VertexInputState, Box<ValidationError>> {
|
||||
self.0.definition(interface)
|
||||
}
|
||||
}
|
||||
|
@ -18,12 +18,18 @@ use crate::{
|
||||
/// Trait for types that can create a [`VertexInputState`] from a [`ShaderInterface`].
|
||||
pub unsafe trait VertexDefinition {
|
||||
/// Builds the `VertexInputState` for the provided `interface`.
|
||||
fn definition(&self, interface: &ShaderInterface) -> Result<VertexInputState, ValidationError>;
|
||||
fn definition(
|
||||
&self,
|
||||
interface: &ShaderInterface,
|
||||
) -> Result<VertexInputState, Box<ValidationError>>;
|
||||
}
|
||||
|
||||
unsafe impl VertexDefinition for &[VertexBufferDescription] {
|
||||
#[inline]
|
||||
fn definition(&self, interface: &ShaderInterface) -> Result<VertexInputState, ValidationError> {
|
||||
fn definition(
|
||||
&self,
|
||||
interface: &ShaderInterface,
|
||||
) -> Result<VertexInputState, Box<ValidationError>> {
|
||||
let bindings = self.iter().enumerate().map(|(binding, buffer)| {
|
||||
(
|
||||
binding as u32,
|
||||
@ -47,14 +53,16 @@ unsafe impl VertexDefinition for &[VertexBufferDescription] {
|
||||
.get(name.as_ref())
|
||||
.map(|infos| (infos.clone(), binding as u32))
|
||||
})
|
||||
.ok_or_else(|| ValidationError {
|
||||
problem: format!(
|
||||
"the shader interface contains a variable named \"{}\", \
|
||||
.ok_or_else(|| {
|
||||
Box::new(ValidationError {
|
||||
problem: format!(
|
||||
"the shader interface contains a variable named \"{}\", \
|
||||
but no such attribute exists in the vertex definition",
|
||||
name,
|
||||
)
|
||||
.into(),
|
||||
..Default::default()
|
||||
name,
|
||||
)
|
||||
.into(),
|
||||
..Default::default()
|
||||
})
|
||||
})?;
|
||||
|
||||
// TODO: ShaderInterfaceEntryType does not properly support 64bit.
|
||||
@ -63,7 +71,7 @@ unsafe impl VertexDefinition for &[VertexBufferDescription] {
|
||||
if infos.num_components() != element.ty.num_components
|
||||
|| infos.num_elements != element.ty.num_locations()
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: format!(
|
||||
"for the variable \"{}\", the number of locations and components \
|
||||
required by the shader don't match the number of locations and components \
|
||||
@ -72,7 +80,7 @@ unsafe impl VertexDefinition for &[VertexBufferDescription] {
|
||||
)
|
||||
.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
let mut offset = infos.offset as DeviceSize;
|
||||
@ -106,21 +114,30 @@ unsafe impl VertexDefinition for &[VertexBufferDescription] {
|
||||
|
||||
unsafe impl<const N: usize> VertexDefinition for [VertexBufferDescription; N] {
|
||||
#[inline]
|
||||
fn definition(&self, interface: &ShaderInterface) -> Result<VertexInputState, ValidationError> {
|
||||
fn definition(
|
||||
&self,
|
||||
interface: &ShaderInterface,
|
||||
) -> Result<VertexInputState, Box<ValidationError>> {
|
||||
self.as_slice().definition(interface)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl VertexDefinition for Vec<VertexBufferDescription> {
|
||||
#[inline]
|
||||
fn definition(&self, interface: &ShaderInterface) -> Result<VertexInputState, ValidationError> {
|
||||
fn definition(
|
||||
&self,
|
||||
interface: &ShaderInterface,
|
||||
) -> Result<VertexInputState, Box<ValidationError>> {
|
||||
self.as_slice().definition(interface)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl VertexDefinition for VertexBufferDescription {
|
||||
#[inline]
|
||||
fn definition(&self, interface: &ShaderInterface) -> Result<VertexInputState, ValidationError> {
|
||||
fn definition(
|
||||
&self,
|
||||
interface: &ShaderInterface,
|
||||
) -> Result<VertexInputState, Box<ValidationError>> {
|
||||
std::slice::from_ref(self).definition(interface)
|
||||
}
|
||||
}
|
||||
|
@ -179,7 +179,7 @@ impl VertexInputState {
|
||||
self
|
||||
}
|
||||
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let Self {
|
||||
bindings,
|
||||
attributes,
|
||||
@ -189,14 +189,14 @@ impl VertexInputState {
|
||||
let properties = device.physical_device().properties();
|
||||
|
||||
if bindings.len() > properties.max_vertex_input_bindings as usize {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "bindings".into(),
|
||||
problem: "the length exceeds the `max_vertex_input_bindings` limit".into(),
|
||||
vuids: &[
|
||||
"VUID-VkPipelineVertexInputStateCreateInfo-vertexBindingDescriptionCount-00613",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// VUID-VkPipelineVertexInputStateCreateInfo-pVertexBindingDescriptions-00616
|
||||
@ -209,14 +209,14 @@ impl VertexInputState {
|
||||
}
|
||||
|
||||
if attributes.len() > properties.max_vertex_input_attributes as usize {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "attributes".into(),
|
||||
problem: "the length exceeds the `max_vertex_input_attributes` limit".into(),
|
||||
vuids: &[
|
||||
"VUID-VkPipelineVertexInputStateCreateInfo-vertexAttributeDescriptionCount-00614",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
for (&location, attribute_desc) in attributes {
|
||||
@ -231,7 +231,7 @@ impl VertexInputState {
|
||||
} = attribute_desc;
|
||||
|
||||
if location > properties.max_vertex_input_attributes {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "attributes".into(),
|
||||
problem: format!(
|
||||
"the location {} exceeds the `max_vertex_input_attributes` limit",
|
||||
@ -240,7 +240,7 @@ impl VertexInputState {
|
||||
.into(),
|
||||
vuids: &["VUID-VkVertexInputAttributeDescription-location-00620"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
let binding_desc = bindings.get(&binding).ok_or(ValidationError {
|
||||
@ -260,7 +260,7 @@ impl VertexInputState {
|
||||
&& offset as DeviceSize + format.block_size().unwrap()
|
||||
> binding_desc.stride as DeviceSize
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: format!(
|
||||
"this device is a portability subset device, and \
|
||||
`attributes[{0}].offset + attributes[{0}].format.block_size()` \
|
||||
@ -273,7 +273,7 @@ impl VertexInputState {
|
||||
)])]),
|
||||
vuids: &["VUID-VkVertexInputAttributeDescription-vertexAttributeAccessBeyondStride-04457"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -286,7 +286,7 @@ impl VertexInputState {
|
||||
|
||||
for location in unassigned_locations {
|
||||
if !attributes.get(&location).is_none() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: format!(
|
||||
"`attributes[{}].format` takes up two locations, but \
|
||||
`attributes` also contains a description for location {}",
|
||||
@ -295,7 +295,7 @@ impl VertexInputState {
|
||||
.into(),
|
||||
vuids: &["VUID-VkPipelineVertexInputStateCreateInfo-pVertexAttributeDescriptions-00617"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -327,18 +327,18 @@ pub struct VertexInputBindingDescription {
|
||||
}
|
||||
|
||||
impl VertexInputBindingDescription {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self { stride, input_rate } = self;
|
||||
|
||||
let properties = device.physical_device().properties();
|
||||
|
||||
if stride > properties.max_vertex_input_binding_stride {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "stride".into(),
|
||||
problem: "exceeds the `max_vertex_input_binding_stride` limit".into(),
|
||||
vuids: &["VUID-VkVertexInputBindingDescription-stride-00619"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if device.enabled_extensions().khr_portability_subset
|
||||
@ -349,14 +349,14 @@ impl VertexInputBindingDescription {
|
||||
.unwrap()
|
||||
!= 0)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "this device is a portability subset device, and \
|
||||
`stride` is not a multiple of, and at least as large as, the \
|
||||
`min_vertex_input_binding_stride_alignment` limit"
|
||||
.into(),
|
||||
vuids: &["VUID-VkVertexInputBindingDescription-stride-04456"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
match input_rate {
|
||||
@ -365,7 +365,7 @@ impl VertexInputBindingDescription {
|
||||
.enabled_features()
|
||||
.vertex_attribute_instance_rate_divisor
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "input_rate".into(),
|
||||
problem: "is `VertexInputRate::Instance`, and \
|
||||
its `divisor` value is not 1".into(),
|
||||
@ -373,7 +373,7 @@ impl VertexInputBindingDescription {
|
||||
"vertex_attribute_instance_rate_divisor",
|
||||
)])]),
|
||||
vuids: &["VUID-VkVertexInputBindingDivisorDescriptionEXT-vertexAttributeInstanceRateDivisor-02229"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if divisor == 0
|
||||
@ -381,7 +381,7 @@ impl VertexInputBindingDescription {
|
||||
.enabled_features()
|
||||
.vertex_attribute_instance_rate_zero_divisor
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "input_rate".into(),
|
||||
problem: "is `VertexInputRate::Instance`, and \
|
||||
its `divisor` value is 0".into(),
|
||||
@ -389,18 +389,18 @@ impl VertexInputBindingDescription {
|
||||
"vertex_attribute_instance_rate_zero_divisor",
|
||||
)])]),
|
||||
vuids: &["VUID-VkVertexInputBindingDivisorDescriptionEXT-vertexAttributeInstanceRateZeroDivisor-02228"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if divisor > properties.max_vertex_attrib_divisor.unwrap() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "input_rate".into(),
|
||||
problem: "is `VertexInputRate::Instance`, and \
|
||||
its `divisor` value exceeds the `max_vertex_attrib_divisor` limit"
|
||||
.into(),
|
||||
vuids: &["VUID-VkVertexInputBindingDivisorDescriptionEXT-divisor-01870"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
@ -430,7 +430,7 @@ pub struct VertexInputAttributeDescription {
|
||||
}
|
||||
|
||||
impl VertexInputAttributeDescription {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
binding,
|
||||
format,
|
||||
@ -448,21 +448,21 @@ impl VertexInputAttributeDescription {
|
||||
})?;
|
||||
|
||||
if binding > properties.max_vertex_input_bindings {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "binding".into(),
|
||||
problem: "exceeds the `max_vertex_input_bindings` limit".into(),
|
||||
vuids: &["VUID-VkVertexInputAttributeDescription-binding-00621"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if offset > properties.max_vertex_input_attribute_offset {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "offset".into(),
|
||||
problem: "exceeds the `max_vertex_input_attribute_offset` limit".into(),
|
||||
vuids: &["VUID-VkVertexInputAttributeDescription-offset-00622"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
let format_features = unsafe {
|
||||
@ -473,13 +473,13 @@ impl VertexInputAttributeDescription {
|
||||
};
|
||||
|
||||
if !format_features.intersects(FormatFeatures::VERTEX_BUFFER) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "format".into(),
|
||||
problem: "the format features do not include `FormatFeatures::VERTEX_BUFFER`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkVertexInputAttributeDescription-format-00623"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -182,7 +182,7 @@ impl ViewportState {
|
||||
None
|
||||
}
|
||||
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let Self {
|
||||
viewports,
|
||||
scissors,
|
||||
@ -194,12 +194,12 @@ impl ViewportState {
|
||||
let viewport_count = match viewports {
|
||||
PartialStateMode::Fixed(viewports) => {
|
||||
if viewports.is_empty() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "viewports".into(),
|
||||
problem: "is empty".into(),
|
||||
vuids: &["VUID-VkPipelineViewportStateCreateInfo-viewportCount-04135"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
for (index, viewport) in viewports.iter().enumerate() {
|
||||
@ -212,12 +212,12 @@ impl ViewportState {
|
||||
}
|
||||
PartialStateMode::Dynamic(StateMode::Fixed(count)) => {
|
||||
if *count == 0 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "viewports".into(),
|
||||
problem: "is empty".into(),
|
||||
vuids: &["VUID-VkPipelineViewportStateCreateInfo-viewportCount-04135"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
*count
|
||||
@ -231,12 +231,12 @@ impl ViewportState {
|
||||
let scissor_count = match scissors {
|
||||
PartialStateMode::Fixed(scissors) => {
|
||||
if scissors.is_empty() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "scissors".into(),
|
||||
problem: "is empty".into(),
|
||||
vuids: &["VUID-VkPipelineViewportStateCreateInfo-scissorCount-04136"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
for (index, scissor) in scissors.iter().enumerate() {
|
||||
@ -250,12 +250,12 @@ impl ViewportState {
|
||||
.and_then(|(o, e)| o.checked_add(e))
|
||||
.is_none()
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("scissors[{}]", index).into(),
|
||||
problem: "`offset[0] + extent[0]` is greater than `i32::MAX`".into(),
|
||||
vuids: &["VUID-VkPipelineViewportStateCreateInfo-offset-02822"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if (i32::try_from(offset[1]).ok())
|
||||
@ -263,12 +263,12 @@ impl ViewportState {
|
||||
.and_then(|(o, e)| o.checked_add(e))
|
||||
.is_none()
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("scissors[{}]", index).into(),
|
||||
problem: "`offset[1] + extent[1]` is greater than `i32::MAX`".into(),
|
||||
vuids: &["VUID-VkPipelineViewportStateCreateInfo-offset-02823"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -276,12 +276,12 @@ impl ViewportState {
|
||||
}
|
||||
PartialStateMode::Dynamic(StateMode::Fixed(count)) => {
|
||||
if *count == 0 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "scissors".into(),
|
||||
problem: "is empty".into(),
|
||||
vuids: &["VUID-VkPipelineViewportStateCreateInfo-scissorCount-04136"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
*count
|
||||
@ -293,52 +293,52 @@ impl ViewportState {
|
||||
};
|
||||
|
||||
if viewport_count != 0 && scissor_count != 0 && viewport_count != scissor_count {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the length of `viewports` and the length of `scissors` are not equal"
|
||||
.into(),
|
||||
vuids: &["VUID-VkPipelineViewportStateCreateInfo-scissorCount-04134"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if viewport_count > 1 && !device.enabled_features().multi_viewport {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "viewports".into(),
|
||||
problem: "the length is greater than 1".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"multi_viewport",
|
||||
)])]),
|
||||
vuids: &["VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if scissor_count > 1 && !device.enabled_features().multi_viewport {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "scissors".into(),
|
||||
problem: "the length is greater than 1".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"multi_viewport",
|
||||
)])]),
|
||||
vuids: &["VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if viewport_count > properties.max_viewports {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "viewports".into(),
|
||||
problem: "the length exceeds the `max_viewports` limit".into(),
|
||||
vuids: &["VUID-VkPipelineViewportStateCreateInfo-viewportCount-01218"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if scissor_count > properties.max_viewports {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "scissors".into(),
|
||||
problem: "the length exceeds the `max_viewports` limit".into(),
|
||||
vuids: &["VUID-VkPipelineViewportStateCreateInfo-scissorCount-01219"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -373,7 +373,7 @@ pub struct Viewport {
|
||||
}
|
||||
|
||||
impl Viewport {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
offset,
|
||||
extent,
|
||||
@ -383,28 +383,28 @@ impl Viewport {
|
||||
let properties = device.physical_device().properties();
|
||||
|
||||
if extent[0] <= 0.0 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "extent[0]".into(),
|
||||
problem: "is not greater than zero".into(),
|
||||
vuids: &["VUID-VkViewport-width-01770"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if extent[0] > properties.max_viewport_dimensions[0] as f32 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "extent[0]".into(),
|
||||
problem: "exceeds the `max_viewport_dimensions[0]` limit".into(),
|
||||
vuids: &["VUID-VkViewport-width-01771"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if extent[1] <= 0.0
|
||||
&& !(device.api_version() >= Version::V1_1
|
||||
|| device.enabled_extensions().khr_maintenance1)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "extent[1]".into(),
|
||||
problem: "is not greater than zero".into(),
|
||||
requires_one_of: RequiresOneOf(&[
|
||||
@ -412,94 +412,94 @@ impl Viewport {
|
||||
RequiresAllOf(&[Requires::DeviceExtension("khr_maintenance1")]),
|
||||
]),
|
||||
vuids: &["VUID-VkViewport-apiVersion-07917"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if extent[1].abs() > properties.max_viewport_dimensions[1] as f32 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "extent[1]".into(),
|
||||
problem: "exceeds the `max_viewport_dimensions[1]` limit".into(),
|
||||
vuids: &["VUID-VkViewport-height-01773"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if offset[0] < properties.viewport_bounds_range[0] {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`offset[0]` is less than the `viewport_bounds_range[0]` property".into(),
|
||||
vuids: &["VUID-VkViewport-x-01774"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if offset[0] + extent[0] > properties.viewport_bounds_range[1] {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`offset[0] + extent[0]` is greater than the \
|
||||
`viewport_bounds_range[1]` property"
|
||||
.into(),
|
||||
vuids: &["VUID-VkViewport-x-01232"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if offset[1] < properties.viewport_bounds_range[0] {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`offset[1]` is less than the `viewport_bounds_range[0]` property".into(),
|
||||
vuids: &["VUID-VkViewport-y-01775"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if offset[1] > properties.viewport_bounds_range[1] {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`offset[1]` is greater than the `viewport_bounds_range[1]` property"
|
||||
.into(),
|
||||
vuids: &["VUID-VkViewport-y-01776"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if offset[1] + extent[1] < properties.viewport_bounds_range[0] {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`offset[1] + extent[1]` is less than the \
|
||||
`viewport_bounds_range[0]` property"
|
||||
.into(),
|
||||
vuids: &["VUID-VkViewport-y-01777"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if offset[1] + extent[1] > properties.viewport_bounds_range[1] {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`offset[1] + extent[1]` is greater than the \
|
||||
`viewport_bounds_range[1]` property"
|
||||
.into(),
|
||||
vuids: &["VUID-VkViewport-y-01233"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if !device.enabled_extensions().ext_depth_range_unrestricted {
|
||||
if *depth_range.start() < 0.0 || *depth_range.start() > 1.0 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`depth_range.start` is not between 0.0 and 1.0 inclusive".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::DeviceExtension(
|
||||
"ext_depth_range_unrestricted",
|
||||
)])]),
|
||||
vuids: &["VUID-VkViewport-minDepth-01234"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if *depth_range.end() < 0.0 || *depth_range.end() > 1.0 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`depth_range.end` is not between 0.0 and 1.0 inclusive".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::DeviceExtension(
|
||||
"ext_depth_range_unrestricted",
|
||||
)])]),
|
||||
vuids: &["VUID-VkViewport-maxDepth-01235"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ use crate::{
|
||||
instance::InstanceOwnedDebugWrapper,
|
||||
macros::{impl_id_counter, vulkan_bitflags},
|
||||
shader::{DescriptorBindingRequirements, ShaderStage, ShaderStages},
|
||||
RuntimeError, ValidationError, VulkanError, VulkanObject,
|
||||
Validated, ValidationError, VulkanError, VulkanObject,
|
||||
};
|
||||
use ahash::HashMap;
|
||||
use smallvec::SmallVec;
|
||||
@ -108,7 +108,7 @@ impl PipelineLayout {
|
||||
pub fn new(
|
||||
device: Arc<Device>,
|
||||
create_info: PipelineLayoutCreateInfo,
|
||||
) -> Result<Arc<PipelineLayout>, VulkanError> {
|
||||
) -> Result<Arc<PipelineLayout>, Validated<VulkanError>> {
|
||||
Self::validate_new(&device, &create_info)?;
|
||||
|
||||
unsafe { Ok(Self::new_unchecked(device, create_info)?) }
|
||||
@ -117,7 +117,7 @@ impl PipelineLayout {
|
||||
fn validate_new(
|
||||
device: &Device,
|
||||
create_info: &PipelineLayoutCreateInfo,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
// VUID-vkCreatePipelineLayout-pCreateInfo-parameter
|
||||
create_info
|
||||
.validate(device)
|
||||
@ -130,7 +130,7 @@ impl PipelineLayout {
|
||||
pub unsafe fn new_unchecked(
|
||||
device: Arc<Device>,
|
||||
create_info: PipelineLayoutCreateInfo,
|
||||
) -> Result<Arc<PipelineLayout>, RuntimeError> {
|
||||
) -> Result<Arc<PipelineLayout>, VulkanError> {
|
||||
let &PipelineLayoutCreateInfo {
|
||||
flags,
|
||||
ref set_layouts,
|
||||
@ -167,7 +167,7 @@ impl PipelineLayout {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
};
|
||||
|
||||
@ -320,13 +320,13 @@ impl PipelineLayout {
|
||||
|
||||
/// Makes sure that `self` is a superset of the provided descriptor set layouts and push
|
||||
/// constant ranges. Returns an `Err` if this is not the case.
|
||||
pub fn ensure_compatible_with_shader<'a>(
|
||||
pub(crate) fn ensure_compatible_with_shader<'a>(
|
||||
&self,
|
||||
descriptor_requirements: impl IntoIterator<
|
||||
Item = ((u32, u32), &'a DescriptorBindingRequirements),
|
||||
>,
|
||||
push_constant_range: Option<&PushConstantRange>,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
for ((set_num, binding_num), reqs) in descriptor_requirements.into_iter() {
|
||||
let layout_binding = self
|
||||
.set_layouts
|
||||
@ -336,7 +336,7 @@ impl PipelineLayout {
|
||||
let layout_binding = match layout_binding {
|
||||
Some(x) => x,
|
||||
None => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: format!(
|
||||
"the requirements for descriptor set {} binding {} were not met: \
|
||||
no such binding exists in the pipeline layout",
|
||||
@ -344,19 +344,19 @@ impl PipelineLayout {
|
||||
)
|
||||
.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
if let Err(error) = layout_binding.ensure_compatible_with_shader(reqs) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: format!(
|
||||
"the requirements for descriptor set {} binding {} were not met: {}",
|
||||
set_num, binding_num, error,
|
||||
)
|
||||
.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -366,12 +366,12 @@ impl PipelineLayout {
|
||||
(range.offset < own_range.offset || // our range must start before and end after the given range
|
||||
own_range.offset + own_range.size < range.offset + range.size)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the required push constant range is larger than the \
|
||||
push constant range in the pipeline layout"
|
||||
.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -447,7 +447,7 @@ impl Default for PipelineLayoutCreateInfo {
|
||||
}
|
||||
|
||||
impl PipelineLayoutCreateInfo {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let properties = device.physical_device().properties();
|
||||
|
||||
let &Self {
|
||||
@ -466,12 +466,12 @@ impl PipelineLayoutCreateInfo {
|
||||
})?;
|
||||
|
||||
if set_layouts.len() > properties.max_bound_descriptor_sets as usize {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "set_layouts".into(),
|
||||
problem: "the length exceeds the `max_bound_descriptor_sets` limit".into(),
|
||||
vuids: &["VUID-VkPipelineLayoutCreateInfo-setLayoutCount-00286"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
struct DescriptorLimit {
|
||||
@ -640,14 +640,14 @@ impl PipelineLayoutCreateInfo {
|
||||
.intersects(DescriptorSetLayoutCreateFlags::PUSH_DESCRIPTOR)
|
||||
{
|
||||
if has_push_descriptor_set {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "set_layouts".into(),
|
||||
problem: "contains more than one descriptor set layout whose flags \
|
||||
include `DescriptorSetLayoutCreateFlags::PUSH_DESCRIPTOR`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkPipelineLayoutCreateInfo-pSetLayouts-00293"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
has_push_descriptor_set = true;
|
||||
@ -688,7 +688,7 @@ impl PipelineLayoutCreateInfo {
|
||||
{
|
||||
if let Some((max_stage, max_count)) = count.into_iter().max_by_key(|(_, c)| *c) {
|
||||
if max_count > (limit.get_limit)(properties) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "set_layouts".into(),
|
||||
problem: format!(
|
||||
"the combined number of {} descriptors accessible to the \
|
||||
@ -706,14 +706,14 @@ impl PipelineLayoutCreateInfo {
|
||||
.into(),
|
||||
vuids: limit.vuids,
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (limit, count) in TOTAL_DESCRIPTOR_LIMITS.iter().zip(total_descriptors) {
|
||||
if count > (limit.get_limit)(properties) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "set_layouts".into(),
|
||||
problem: format!(
|
||||
"the combined number of {} descriptors accessible across all \
|
||||
@ -730,7 +730,7 @@ impl PipelineLayoutCreateInfo {
|
||||
.into(),
|
||||
vuids: limit.vuids,
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -748,12 +748,12 @@ impl PipelineLayoutCreateInfo {
|
||||
} = range;
|
||||
|
||||
if seen_stages.intersects(stages) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "push_constant_ranges".into(),
|
||||
problem: "contains more than one range with the same stage".into(),
|
||||
vuids: &["VUID-VkPipelineLayoutCreateInfo-pPushConstantRanges-00292"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
seen_stages |= stages;
|
||||
@ -812,7 +812,7 @@ impl Default for PushConstantRange {
|
||||
}
|
||||
|
||||
impl PushConstantRange {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
stages,
|
||||
offset,
|
||||
@ -828,12 +828,12 @@ impl PushConstantRange {
|
||||
})?;
|
||||
|
||||
if stages.is_empty() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "stages".into(),
|
||||
problem: "is empty".into(),
|
||||
vuids: &["VUID-VkPushConstantRange-stageFlags-requiredbitmask"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
let max_push_constants_size = device
|
||||
@ -842,48 +842,48 @@ impl PushConstantRange {
|
||||
.max_push_constants_size;
|
||||
|
||||
if offset >= max_push_constants_size {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "offset".into(),
|
||||
problem: "is not less than the `max_push_constants_size` limit".into(),
|
||||
vuids: &["VUID-VkPushConstantRange-offset-00294"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if offset % 4 != 0 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "offset".into(),
|
||||
problem: "is not a multiple of 4".into(),
|
||||
vuids: &["VUID-VkPushConstantRange-offset-00295"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if size == 0 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "size".into(),
|
||||
problem: "is zero".into(),
|
||||
vuids: &["VUID-VkPushConstantRange-size-00296"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if size % 4 != 0 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "size".into(),
|
||||
problem: "is not a multiple of 4".into(),
|
||||
vuids: &["VUID-VkPushConstantRange-size-00297"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if size > max_push_constants_size - offset {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`size` is greater than `max_push_constants_size` limit minus `offset`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkPushConstantRange-size-00298"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -1006,7 +1006,7 @@ impl PipelineDescriptorSetLayoutCreateInfo {
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct IntoPipelineLayoutCreateInfoError {
|
||||
pub set_num: u32,
|
||||
pub error: VulkanError,
|
||||
pub error: Validated<VulkanError>,
|
||||
}
|
||||
|
||||
impl Display for IntoPipelineLayoutCreateInfoError {
|
||||
|
@ -336,7 +336,7 @@ impl PipelineShaderStageCreateInfo {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
flags,
|
||||
ref entry_point,
|
||||
@ -381,7 +381,7 @@ impl PipelineShaderStageCreateInfo {
|
||||
}
|
||||
ShaderStage::TessellationControl | ShaderStage::TessellationEvaluation => {
|
||||
if !device.enabled_features().tessellation_shader {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "entry_point".into(),
|
||||
problem: "specifies a `ShaderStage::TessellationControl` or \
|
||||
`ShaderStage::TessellationEvaluation` entry point"
|
||||
@ -390,7 +390,7 @@ impl PipelineShaderStageCreateInfo {
|
||||
"tessellation_shader",
|
||||
)])]),
|
||||
vuids: &["VUID-VkPipelineShaderStageCreateInfo-stage-00705"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// VUID-VkPipelineShaderStageCreateInfo-stage-00713
|
||||
@ -398,14 +398,14 @@ impl PipelineShaderStageCreateInfo {
|
||||
}
|
||||
ShaderStage::Geometry => {
|
||||
if !device.enabled_features().geometry_shader {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "entry_point".into(),
|
||||
problem: "specifies a `ShaderStage::Geometry` entry point".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"geometry_shader",
|
||||
)])]),
|
||||
vuids: &["VUID-VkPipelineShaderStageCreateInfo-stage-00704"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// TODO:
|
||||
@ -427,26 +427,26 @@ impl PipelineShaderStageCreateInfo {
|
||||
ShaderStage::Callable => (),
|
||||
ShaderStage::Task => {
|
||||
if !device.enabled_features().task_shader {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "entry_point".into(),
|
||||
problem: "specifies a `ShaderStage::Task` entry point".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"task_shader",
|
||||
)])]),
|
||||
vuids: &["VUID-VkPipelineShaderStageCreateInfo-stage-02092"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
ShaderStage::Mesh => {
|
||||
if !device.enabled_features().mesh_shader {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "entry_point".into(),
|
||||
problem: "specifies a `ShaderStage::Mesh` entry point".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"mesh_shader",
|
||||
)])]),
|
||||
vuids: &["VUID-VkPipelineShaderStageCreateInfo-stage-02091"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
ShaderStage::SubpassShading => (),
|
||||
@ -461,7 +461,7 @@ impl PipelineShaderStageCreateInfo {
|
||||
{
|
||||
// Check for equal types rather than only equal size.
|
||||
if !provided_value.eq_type(default_value) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: format!(
|
||||
"`specialization_info[{0}]` does not have the same type as \
|
||||
`entry_point.info().specialization_constants[{0}]`",
|
||||
@ -470,7 +470,7 @@ impl PipelineShaderStageCreateInfo {
|
||||
.into(),
|
||||
vuids: &["VUID-VkSpecializationMapEntry-constantID-00776"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ use crate::{
|
||||
device::{Device, DeviceOwned},
|
||||
instance::InstanceOwnedDebugWrapper,
|
||||
macros::{impl_id_counter, vulkan_bitflags},
|
||||
DeviceSize, OomError, RequirementNotMet, Requires, RequiresAllOf, RequiresOneOf, RuntimeError,
|
||||
DeviceSize, OomError, RequirementNotMet, Requires, RequiresAllOf, RequiresOneOf, VulkanError,
|
||||
VulkanObject,
|
||||
};
|
||||
use std::{
|
||||
@ -96,7 +96,7 @@ impl QueryPool {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
};
|
||||
|
||||
@ -291,13 +291,13 @@ impl From<RequirementNotMet> for QueryPoolCreationError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RuntimeError> for QueryPoolCreationError {
|
||||
fn from(err: RuntimeError) -> QueryPoolCreationError {
|
||||
impl From<VulkanError> for QueryPoolCreationError {
|
||||
fn from(err: VulkanError) -> QueryPoolCreationError {
|
||||
match err {
|
||||
err @ RuntimeError::OutOfHostMemory => {
|
||||
err @ VulkanError::OutOfHostMemory => {
|
||||
QueryPoolCreationError::OomError(OomError::from(err))
|
||||
}
|
||||
err @ RuntimeError::OutOfDeviceMemory => {
|
||||
err @ VulkanError::OutOfDeviceMemory => {
|
||||
QueryPoolCreationError::OomError(OomError::from(err))
|
||||
}
|
||||
_ => panic!("unexpected error: {:?}", err),
|
||||
@ -424,7 +424,7 @@ impl<'a> QueriesRange<'a> {
|
||||
match result {
|
||||
ash::vk::Result::SUCCESS => Ok(true),
|
||||
ash::vk::Result::NOT_READY => Ok(false),
|
||||
err => Err(RuntimeError::from(err).into()),
|
||||
err => Err(VulkanError::from(err).into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -486,13 +486,13 @@ impl Display for GetResultsError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RuntimeError> for GetResultsError {
|
||||
fn from(err: RuntimeError) -> Self {
|
||||
impl From<VulkanError> for GetResultsError {
|
||||
fn from(err: VulkanError) -> Self {
|
||||
match err {
|
||||
RuntimeError::OutOfHostMemory | RuntimeError::OutOfDeviceMemory => {
|
||||
VulkanError::OutOfHostMemory | VulkanError::OutOfDeviceMemory => {
|
||||
Self::OomError(OomError::from(err))
|
||||
}
|
||||
RuntimeError::DeviceLost => Self::DeviceLost,
|
||||
VulkanError::DeviceLost => Self::DeviceLost,
|
||||
_ => panic!("unexpected error: {:?}", err),
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ use super::{AttachmentDescription, AttachmentReference, RenderPass, RenderPassCr
|
||||
use crate::{
|
||||
device::Device,
|
||||
render_pass::{SubpassDependency, SubpassDescription},
|
||||
RuntimeError, Version, VulkanObject,
|
||||
Version, VulkanError, VulkanObject,
|
||||
};
|
||||
use smallvec::SmallVec;
|
||||
use std::{mem::MaybeUninit, ptr};
|
||||
@ -20,7 +20,7 @@ impl RenderPass {
|
||||
pub(super) unsafe fn create_v2(
|
||||
device: &Device,
|
||||
create_info: &RenderPassCreateInfo,
|
||||
) -> Result<ash::vk::RenderPass, RuntimeError> {
|
||||
) -> Result<ash::vk::RenderPass, VulkanError> {
|
||||
let &RenderPassCreateInfo {
|
||||
flags,
|
||||
ref attachments,
|
||||
@ -522,7 +522,7 @@ impl RenderPass {
|
||||
)
|
||||
}
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
output.assume_init()
|
||||
})
|
||||
@ -531,7 +531,7 @@ impl RenderPass {
|
||||
pub(super) unsafe fn create_v1(
|
||||
device: &Device,
|
||||
create_info: &RenderPassCreateInfo,
|
||||
) -> Result<ash::vk::RenderPass, RuntimeError> {
|
||||
) -> Result<ash::vk::RenderPass, VulkanError> {
|
||||
let &RenderPassCreateInfo {
|
||||
flags,
|
||||
ref attachments,
|
||||
@ -891,7 +891,7 @@ impl RenderPass {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
})
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ use crate::{
|
||||
ImageAspects, ImageType, ImageUsage,
|
||||
},
|
||||
macros::{impl_id_counter, vulkan_bitflags},
|
||||
RuntimeError, ValidationError, VulkanError, VulkanObject,
|
||||
Validated, ValidationError, VulkanError, VulkanObject,
|
||||
};
|
||||
use smallvec::SmallVec;
|
||||
use std::{mem::MaybeUninit, num::NonZeroU64, ops::Range, ptr, sync::Arc};
|
||||
@ -61,7 +61,7 @@ impl Framebuffer {
|
||||
pub fn new(
|
||||
render_pass: Arc<RenderPass>,
|
||||
mut create_info: FramebufferCreateInfo,
|
||||
) -> Result<Arc<Framebuffer>, VulkanError> {
|
||||
) -> Result<Arc<Framebuffer>, Validated<VulkanError>> {
|
||||
create_info.set_auto_extent_layers(&render_pass);
|
||||
Self::validate_new(&render_pass, &create_info)?;
|
||||
|
||||
@ -71,7 +71,7 @@ impl Framebuffer {
|
||||
fn validate_new(
|
||||
render_pass: &RenderPass,
|
||||
create_info: &FramebufferCreateInfo,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
// VUID-vkCreateFramebuffer-pCreateInfo-parameter
|
||||
create_info
|
||||
.validate(render_pass.device())
|
||||
@ -86,13 +86,13 @@ impl Framebuffer {
|
||||
} = create_info;
|
||||
|
||||
if attachments.len() != render_pass.attachments().len() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`create_info.attachments` does not have the same length as \
|
||||
`render_pass.attachments()`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkFramebufferCreateInfo-attachmentCount-00876"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
for (index, ((image_view, attachment_desc), attachment_use)) in attachments
|
||||
@ -104,7 +104,7 @@ impl Framebuffer {
|
||||
if attachment_use.color_attachment
|
||||
&& !image_view.usage().intersects(ImageUsage::COLOR_ATTACHMENT)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: format!(
|
||||
"`render_pass` uses `create_info.attachments[{}]` as \
|
||||
a color attachment, but it was not created with the \
|
||||
@ -114,7 +114,7 @@ impl Framebuffer {
|
||||
.into(),
|
||||
vuids: &["VUID-VkFramebufferCreateInfo-pAttachments-00877"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if attachment_use.depth_stencil_attachment
|
||||
@ -122,7 +122,7 @@ impl Framebuffer {
|
||||
.usage()
|
||||
.intersects(ImageUsage::DEPTH_STENCIL_ATTACHMENT)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: format!(
|
||||
"`render_pass` uses `create_info.attachments[{}]` as \
|
||||
a depth or stencil attachment, but it was not created with the \
|
||||
@ -135,13 +135,13 @@ impl Framebuffer {
|
||||
"VUID-VkFramebufferCreateInfo-pAttachments-02634",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if attachment_use.input_attachment
|
||||
&& !image_view.usage().intersects(ImageUsage::INPUT_ATTACHMENT)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: format!(
|
||||
"`render_pass` uses `create_info.attachments[{}]` as \
|
||||
an input attachment, but it was not created with the \
|
||||
@ -151,11 +151,11 @@ impl Framebuffer {
|
||||
.into(),
|
||||
vuids: &["VUID-VkFramebufferCreateInfo-pAttachments-02633"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if image_view.format() != attachment_desc.format {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: format!(
|
||||
"the format of `create_info.attachments[{}]` does not equal \
|
||||
`render_pass.attachments()[{0}].format`",
|
||||
@ -164,11 +164,11 @@ impl Framebuffer {
|
||||
.into(),
|
||||
vuids: &["VUID-VkFramebufferCreateInfo-pAttachments-00880"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if image_view.image().samples() != attachment_desc.samples {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: format!(
|
||||
"the samples of `create_info.attachments[{}]` does not equal \
|
||||
`render_pass.attachments()[{0}].samples`",
|
||||
@ -177,7 +177,7 @@ impl Framebuffer {
|
||||
.into(),
|
||||
vuids: &["VUID-VkFramebufferCreateInfo-pAttachments-00881"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
let image_view_extent = image_view.image().extent();
|
||||
@ -189,7 +189,7 @@ impl Framebuffer {
|
||||
|| attachment_use.depth_stencil_attachment
|
||||
{
|
||||
if image_view_extent[0] < extent[0] || image_view_extent[1] < extent[1] {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: format!(
|
||||
"`render_pass` uses `create_info.attachments[{}]` as an input, color, \
|
||||
depth or stencil attachment, but \
|
||||
@ -202,11 +202,11 @@ impl Framebuffer {
|
||||
"VUID-VkFramebufferCreateInfo-flags-04534",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if image_view_array_layers < layers {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: format!(
|
||||
"`render_pass` uses `create_info.attachments[{}]` as an input, color, \
|
||||
depth or stencil attachment, but \
|
||||
@ -216,11 +216,11 @@ impl Framebuffer {
|
||||
.into(),
|
||||
vuids: &["VUID-VkFramebufferCreateInfo-flags-04535"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if image_view_array_layers < render_pass.views_used() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: format!(
|
||||
"`render_pass` has multiview enabled, and uses \
|
||||
`create_info.attachments[{}]` as an input, color, depth or stencil \
|
||||
@ -231,18 +231,18 @@ impl Framebuffer {
|
||||
.into(),
|
||||
vuids: &["VUID-VkFramebufferCreateInfo-renderPass-04536"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
if render_pass.views_used() != 0 && layers != 1 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`render_pass` has multiview enabled, but \
|
||||
`create_info.layers` is not 1"
|
||||
.into(),
|
||||
vuids: &["VUID-VkFramebufferCreateInfo-renderPass-02531"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -253,7 +253,7 @@ impl Framebuffer {
|
||||
pub unsafe fn new_unchecked(
|
||||
render_pass: Arc<RenderPass>,
|
||||
mut create_info: FramebufferCreateInfo,
|
||||
) -> Result<Arc<Framebuffer>, RuntimeError> {
|
||||
) -> Result<Arc<Framebuffer>, VulkanError> {
|
||||
create_info.set_auto_extent_layers(&render_pass);
|
||||
|
||||
let &FramebufferCreateInfo {
|
||||
@ -288,7 +288,7 @@ impl Framebuffer {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
};
|
||||
|
||||
@ -514,7 +514,7 @@ impl FramebufferCreateInfo {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
flags,
|
||||
ref attachments,
|
||||
@ -538,21 +538,21 @@ impl FramebufferCreateInfo {
|
||||
- image_view.subresource_range().mip_levels.start;
|
||||
|
||||
if image_view_mip_levels != 1 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("attachments[{}]", index).into(),
|
||||
problem: "has more than one mip level".into(),
|
||||
vuids: &["VUID-VkFramebufferCreateInfo-pAttachments-00883"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if !image_view.component_mapping().is_identity() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("attachments[{}]", index).into(),
|
||||
problem: "is not identity swizzled".into(),
|
||||
vuids: &["VUID-VkFramebufferCreateInfo-pAttachments-00884"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
match image_view.view_type() {
|
||||
@ -561,23 +561,23 @@ impl FramebufferCreateInfo {
|
||||
&& (image_view.format().unwrap().aspects())
|
||||
.intersects(ImageAspects::DEPTH | ImageAspects::STENCIL)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("attachments[{}]", index).into(),
|
||||
problem: "is a 2D or 2D array image view, but its format is a \
|
||||
depth/stencil format"
|
||||
.into(),
|
||||
vuids: &["VUID-VkFramebufferCreateInfo-pAttachments-00891"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
ImageViewType::Dim3d => {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("attachments[{}]", index).into(),
|
||||
problem: "is a 3D image view".into(),
|
||||
vuids: &["VUID-VkFramebufferCreateInfo-flags-04113"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
@ -586,57 +586,57 @@ impl FramebufferCreateInfo {
|
||||
let properties = device.physical_device().properties();
|
||||
|
||||
if extent[0] == 0 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "extent[0]".into(),
|
||||
problem: "is zero".into(),
|
||||
vuids: &["VUID-VkFramebufferCreateInfo-width-00885"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if extent[0] > properties.max_framebuffer_width {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "extent[0]".into(),
|
||||
problem: "exceeds the `max_framebuffer_width` limit".into(),
|
||||
vuids: &["VUID-VkFramebufferCreateInfo-width-00886"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if extent[1] == 0 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "extent[1]".into(),
|
||||
problem: "is zero".into(),
|
||||
vuids: &["VUID-VkFramebufferCreateInfo-height-00887"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if extent[1] > properties.max_framebuffer_height {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "extent[1]".into(),
|
||||
problem: "exceeds the `max_framebuffer_height` limit".into(),
|
||||
vuids: &["VUID-VkFramebufferCreateInfo-height-00888"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if layers == 0 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "layers".into(),
|
||||
problem: "is zero".into(),
|
||||
vuids: &["VUID-VkFramebufferCreateInfo-layers-00889"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if layers > properties.max_framebuffer_layers {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "layers".into(),
|
||||
problem: "exceeds the `max_framebuffer_layers` limit".into(),
|
||||
vuids: &["VUID-VkFramebufferCreateInfo-layers-00890"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -141,7 +141,7 @@ use crate::{
|
||||
pipeline::{graphics::input_assembly::PrimitiveTopology, layout::PushConstantRange},
|
||||
shader::spirv::{Capability, Spirv, SpirvError},
|
||||
sync::PipelineStages,
|
||||
OomError, RuntimeError, Version, VulkanObject,
|
||||
OomError, Version, VulkanError, VulkanObject,
|
||||
};
|
||||
use ahash::{HashMap, HashSet};
|
||||
use std::{
|
||||
@ -277,7 +277,7 @@ impl ShaderModule {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
};
|
||||
|
||||
@ -1283,8 +1283,8 @@ impl Display for ShaderModuleCreationError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RuntimeError> for ShaderModuleCreationError {
|
||||
fn from(err: RuntimeError) -> Self {
|
||||
impl From<VulkanError> for ShaderModuleCreationError {
|
||||
fn from(err: VulkanError) -> Self {
|
||||
Self::OomError(err.into())
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ use crate::{
|
||||
future::{AccessCheckError, AccessError, FlushError, GpuFuture, SubmitAnyBuilder},
|
||||
semaphore::{Semaphore, SemaphoreError},
|
||||
},
|
||||
DeviceSize, OomError, RequirementNotMet, Requires, RequiresAllOf, RequiresOneOf, RuntimeError,
|
||||
DeviceSize, OomError, RequirementNotMet, Requires, RequiresAllOf, RequiresOneOf, VulkanError,
|
||||
VulkanObject,
|
||||
};
|
||||
use smallvec::smallvec;
|
||||
@ -132,7 +132,7 @@ pub unsafe fn acquire_next_image_raw(
|
||||
ash::vk::Result::SUBOPTIMAL_KHR => true,
|
||||
ash::vk::Result::NOT_READY => return Err(AcquireError::Timeout),
|
||||
ash::vk::Result::TIMEOUT => return Err(AcquireError::Timeout),
|
||||
err => return Err(RuntimeError::from(err).into()),
|
||||
err => return Err(VulkanError::from(err).into()),
|
||||
};
|
||||
|
||||
if let Some(semaphore) = semaphore {
|
||||
@ -386,15 +386,15 @@ impl From<OomError> for AcquireError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RuntimeError> for AcquireError {
|
||||
fn from(err: RuntimeError) -> AcquireError {
|
||||
impl From<VulkanError> for AcquireError {
|
||||
fn from(err: VulkanError) -> AcquireError {
|
||||
match err {
|
||||
err @ RuntimeError::OutOfHostMemory => AcquireError::OomError(OomError::from(err)),
|
||||
err @ RuntimeError::OutOfDeviceMemory => AcquireError::OomError(OomError::from(err)),
|
||||
RuntimeError::DeviceLost => AcquireError::DeviceLost,
|
||||
RuntimeError::SurfaceLost => AcquireError::SurfaceLost,
|
||||
RuntimeError::OutOfDate => AcquireError::OutOfDate,
|
||||
RuntimeError::FullScreenExclusiveModeLost => AcquireError::FullScreenExclusiveModeLost,
|
||||
err @ VulkanError::OutOfHostMemory => AcquireError::OomError(OomError::from(err)),
|
||||
err @ VulkanError::OutOfDeviceMemory => AcquireError::OomError(OomError::from(err)),
|
||||
VulkanError::DeviceLost => AcquireError::DeviceLost,
|
||||
VulkanError::SurfaceLost => AcquireError::SurfaceLost,
|
||||
VulkanError::OutOfDate => AcquireError::OutOfDate,
|
||||
VulkanError::FullScreenExclusiveModeLost => AcquireError::FullScreenExclusiveModeLost,
|
||||
_ => panic!("unexpected error: {:?}", err),
|
||||
}
|
||||
}
|
||||
@ -918,7 +918,7 @@ pub fn wait_for_present(
|
||||
ash::vk::Result::SUBOPTIMAL_KHR => Ok(true),
|
||||
ash::vk::Result::TIMEOUT => Err(PresentWaitError::Timeout),
|
||||
err => {
|
||||
let err = RuntimeError::from(err).into();
|
||||
let err = VulkanError::from(err).into();
|
||||
|
||||
if let PresentWaitError::FullScreenExclusiveModeLost = &err {
|
||||
swapchain
|
||||
@ -1012,15 +1012,15 @@ impl From<RequirementNotMet> for PresentWaitError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RuntimeError> for PresentWaitError {
|
||||
fn from(err: RuntimeError) -> PresentWaitError {
|
||||
impl From<VulkanError> for PresentWaitError {
|
||||
fn from(err: VulkanError) -> PresentWaitError {
|
||||
match err {
|
||||
err @ RuntimeError::OutOfHostMemory => Self::OomError(OomError::from(err)),
|
||||
err @ RuntimeError::OutOfDeviceMemory => Self::OomError(OomError::from(err)),
|
||||
RuntimeError::DeviceLost => Self::DeviceLost,
|
||||
RuntimeError::SurfaceLost => Self::SurfaceLost,
|
||||
RuntimeError::OutOfDate => Self::OutOfDate,
|
||||
RuntimeError::FullScreenExclusiveModeLost => Self::FullScreenExclusiveModeLost,
|
||||
err @ VulkanError::OutOfHostMemory => Self::OomError(OomError::from(err)),
|
||||
err @ VulkanError::OutOfDeviceMemory => Self::OomError(OomError::from(err)),
|
||||
VulkanError::DeviceLost => Self::DeviceLost,
|
||||
VulkanError::SurfaceLost => Self::SurfaceLost,
|
||||
VulkanError::OutOfDate => Self::OutOfDate,
|
||||
VulkanError::FullScreenExclusiveModeLost => Self::FullScreenExclusiveModeLost,
|
||||
_ => panic!("unexpected error: {:?}", err),
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,7 @@
|
||||
#![allow(unused_variables)] // TODO: this module isn't finished
|
||||
|
||||
use crate::{
|
||||
device::physical::PhysicalDevice, swapchain::SurfaceTransforms, OomError, RuntimeError,
|
||||
device::physical::PhysicalDevice, swapchain::SurfaceTransforms, OomError, VulkanError,
|
||||
VulkanObject,
|
||||
};
|
||||
use std::{
|
||||
@ -71,7 +71,7 @@ impl DisplayPlane {
|
||||
ptr::null_mut(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
let mut properties = Vec::with_capacity(count as usize);
|
||||
let result = (fns
|
||||
@ -88,7 +88,7 @@ impl DisplayPlane {
|
||||
break properties;
|
||||
}
|
||||
ash::vk::Result::INCOMPLETE => (),
|
||||
err => return Err(RuntimeError::from(err).into()),
|
||||
err => return Err(VulkanError::from(err).into()),
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -107,7 +107,7 @@ impl DisplayPlane {
|
||||
ptr::null_mut(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)
|
||||
.map_err(VulkanError::from)
|
||||
.unwrap(); // TODO: shouldn't unwrap
|
||||
|
||||
let mut displays = Vec::with_capacity(count as usize);
|
||||
@ -202,7 +202,7 @@ impl Display {
|
||||
ptr::null_mut(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
let mut properties = Vec::with_capacity(count as usize);
|
||||
let result = (fns.khr_display.get_physical_device_display_properties_khr)(
|
||||
@ -217,7 +217,7 @@ impl Display {
|
||||
break properties;
|
||||
}
|
||||
ash::vk::Result::INCOMPLETE => (),
|
||||
err => return Err(RuntimeError::from(err).into()),
|
||||
err => return Err(VulkanError::from(err).into()),
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -308,7 +308,7 @@ impl Display {
|
||||
ptr::null_mut(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
let mut properties = Vec::with_capacity(count as usize);
|
||||
let result = (fns.khr_display.get_display_mode_properties_khr)(
|
||||
@ -324,7 +324,7 @@ impl Display {
|
||||
break properties;
|
||||
}
|
||||
ash::vk::Result::INCOMPLETE => (),
|
||||
err => return Err(RuntimeError::from(err).into()),
|
||||
err => return Err(VulkanError::from(err).into()),
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -390,7 +390,7 @@ impl DisplayMode {
|
||||
let mut output = mem::uninitialized();
|
||||
(fns.v1_0.CreateDisplayModeKHR)(display.device.handle(),
|
||||
display.display, &infos, ptr::null(),
|
||||
&mut output).result().map_err(RuntimeError::from)?;
|
||||
&mut output).result().map_err(VulkanError::from)?;
|
||||
output
|
||||
};
|
||||
|
||||
|
@ -336,7 +336,7 @@ use crate::{
|
||||
instance::InstanceOwnedDebugWrapper,
|
||||
macros::{impl_id_counter, vulkan_bitflags, vulkan_bitflags_enum, vulkan_enum},
|
||||
sync::Sharing,
|
||||
OomError, Requires, RequiresAllOf, RequiresOneOf, RuntimeError, ValidationError, VulkanError,
|
||||
OomError, Requires, RequiresAllOf, RequiresOneOf, Validated, ValidationError, VulkanError,
|
||||
VulkanObject,
|
||||
};
|
||||
use parking_lot::Mutex;
|
||||
@ -420,7 +420,7 @@ impl Swapchain {
|
||||
device: Arc<Device>,
|
||||
surface: Arc<Surface>,
|
||||
create_info: SwapchainCreateInfo,
|
||||
) -> Result<(Arc<Swapchain>, Vec<Arc<Image>>), VulkanError> {
|
||||
) -> Result<(Arc<Swapchain>, Vec<Arc<Image>>), Validated<VulkanError>> {
|
||||
Self::validate_new_inner(&device, &surface, &create_info)?;
|
||||
|
||||
unsafe { Ok(Self::new_unchecked(device, surface, create_info)?) }
|
||||
@ -432,7 +432,7 @@ impl Swapchain {
|
||||
device: Arc<Device>,
|
||||
surface: Arc<Surface>,
|
||||
create_info: SwapchainCreateInfo,
|
||||
) -> Result<(Arc<Swapchain>, Vec<Arc<Image>>), RuntimeError> {
|
||||
) -> Result<(Arc<Swapchain>, Vec<Arc<Image>>), VulkanError> {
|
||||
let (handle, image_handles) =
|
||||
Self::new_inner_unchecked(&device, &surface, &create_info, None)?;
|
||||
|
||||
@ -449,7 +449,7 @@ impl Swapchain {
|
||||
pub fn recreate(
|
||||
self: &Arc<Self>,
|
||||
create_info: SwapchainCreateInfo,
|
||||
) -> Result<(Arc<Swapchain>, Vec<Arc<Image>>), VulkanError> {
|
||||
) -> Result<(Arc<Swapchain>, Vec<Arc<Image>>), Validated<VulkanError>> {
|
||||
Self::validate_new_inner(&self.device, &self.surface, &create_info)?;
|
||||
|
||||
{
|
||||
@ -457,12 +457,12 @@ impl Swapchain {
|
||||
|
||||
// The swapchain has already been used to create a new one.
|
||||
if *is_retired {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "self".into(),
|
||||
problem: "has already been used to recreate a swapchain".into(),
|
||||
vuids: &["VUID-VkSwapchainCreateInfoKHR-oldSwapchain-01933"],
|
||||
..Default::default()
|
||||
}
|
||||
})
|
||||
.into());
|
||||
} else {
|
||||
// According to the documentation of VkSwapchainCreateInfoKHR:
|
||||
@ -483,7 +483,7 @@ impl Swapchain {
|
||||
pub unsafe fn recreate_unchecked(
|
||||
self: &Arc<Self>,
|
||||
create_info: SwapchainCreateInfo,
|
||||
) -> Result<(Arc<Swapchain>, Vec<Arc<Image>>), RuntimeError> {
|
||||
) -> Result<(Arc<Swapchain>, Vec<Arc<Image>>), VulkanError> {
|
||||
// According to the documentation of VkSwapchainCreateInfoKHR:
|
||||
//
|
||||
// > Upon calling vkCreateSwapchainKHR with a oldSwapchain that is not VK_NULL_HANDLE,
|
||||
@ -520,14 +520,14 @@ impl Swapchain {
|
||||
device: &Device,
|
||||
surface: &Surface,
|
||||
create_info: &SwapchainCreateInfo,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
if !device.enabled_extensions().khr_swapchain {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::DeviceExtension(
|
||||
"khr_swapchain",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
create_info
|
||||
@ -568,12 +568,12 @@ impl Swapchain {
|
||||
.unwrap_or_default()
|
||||
})
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "surface".into(),
|
||||
problem: "is not supported by the physical device".into(),
|
||||
vuids: &["VUID-VkSwapchainCreateInfoKHR-surface-01270"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
let surface_capabilities = unsafe {
|
||||
@ -630,23 +630,23 @@ impl Swapchain {
|
||||
.max_image_count
|
||||
.map_or(false, |c| min_image_count > c)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`create_info.min_image_count` is greater than the `max_image_count` \
|
||||
value of the capabilities of `surface`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkSwapchainCreateInfoKHR-minImageCount-01272"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if min_image_count < surface_capabilities.min_image_count {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`create_info.min_image_count` is less than the `min_image_count` \
|
||||
value of the capabilities of `surface`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkSwapchainCreateInfoKHR-presentMode-02839"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if let Some(image_format) = image_format {
|
||||
@ -654,24 +654,24 @@ impl Swapchain {
|
||||
.iter()
|
||||
.any(|&fc| fc == (image_format, image_color_space))
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the combination of `create_info.image_format` and \
|
||||
`create_info.image_color_space` is not supported for `surface`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkSwapchainCreateInfoKHR-imageFormat-01273"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
if image_array_layers > surface_capabilities.max_image_array_layers {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`create_info.image_array_layers` is greater than the \
|
||||
`max_image_array_layers` value of the capabilities of `surface`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkSwapchainCreateInfoKHR-imageArrayLayers-01275"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if matches!(
|
||||
@ -684,7 +684,7 @@ impl Swapchain {
|
||||
.supported_usage_flags
|
||||
.contains(image_usage)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`create_info.present_mode` is `PresentMode::Immediate`, \
|
||||
`PresentMode::Mailbox`, `PresentMode::Fifo` or `PresentMode::FifoRelaxed`, \
|
||||
and `create_info.image_usage` contains flags that are not set in \
|
||||
@ -692,41 +692,41 @@ impl Swapchain {
|
||||
.into(),
|
||||
vuids: &["VUID-VkSwapchainCreateInfoKHR-presentMode-01427"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if !surface_capabilities
|
||||
.supported_transforms
|
||||
.contains_enum(pre_transform)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`create_info.pre_transform` is not present in the \
|
||||
`supported_transforms` value of the capabilities of `surface`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkSwapchainCreateInfoKHR-preTransform-01279"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if !surface_capabilities
|
||||
.supported_composite_alpha
|
||||
.contains_enum(composite_alpha)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`create_info.composite_alpha` is not present in the \
|
||||
`supported_composite_alpha` value of the capabilities of `surface`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkSwapchainCreateInfoKHR-compositeAlpha-01280"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if !surface_present_modes.contains(&present_mode) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`create_info.present_mode` is not supported for `surface`".into(),
|
||||
vuids: &["VUID-VkSwapchainCreateInfoKHR-presentMode-01281"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if present_modes.is_empty() {
|
||||
@ -735,7 +735,7 @@ impl Swapchain {
|
||||
.supported_present_scaling
|
||||
.contains_enum(scaling_behavior)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`create_info.scaling_behavior` is not present in the \
|
||||
`supported_present_scaling` value of the \
|
||||
capabilities of `surface`"
|
||||
@ -744,7 +744,7 @@ impl Swapchain {
|
||||
"VUID-VkSwapchainPresentScalingCreateInfoEXT-scalingBehavior-07770",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -755,7 +755,7 @@ impl Swapchain {
|
||||
.enumerate()
|
||||
{
|
||||
if !supported_present_gravity.contains_enum(present_gravity) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: format!(
|
||||
"`create_info.present_gravity[{0}]` is not present in the \
|
||||
`supported_present_gravity[{0}]` value of the \
|
||||
@ -768,14 +768,14 @@ impl Swapchain {
|
||||
"VUID-VkSwapchainPresentScalingCreateInfoEXT-presentGravityY-07774",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (index, &present_mode) in present_modes.iter().enumerate() {
|
||||
if !surface_present_modes.contains(&present_mode) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: format!(
|
||||
"`create_info.present_modes[{}]` is not supported for `surface`",
|
||||
index,
|
||||
@ -783,14 +783,14 @@ impl Swapchain {
|
||||
.into(),
|
||||
vuids: &["VUID-VkSwapchainPresentModesCreateInfoEXT-None-07762"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if !surface_capabilities
|
||||
.compatible_present_modes
|
||||
.contains(&present_mode)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: format!(
|
||||
"`create_info.present_modes[{}]` is not present in the \
|
||||
`compatible_present_modes` value of the \
|
||||
@ -800,7 +800,7 @@ impl Swapchain {
|
||||
.into(),
|
||||
vuids: &["VUID-VkSwapchainPresentModesCreateInfoEXT-pPresentModes-07763"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if scaling_behavior.is_some() || present_gravity.is_some() {
|
||||
@ -828,7 +828,7 @@ impl Swapchain {
|
||||
.supported_present_scaling
|
||||
.contains_enum(scaling_behavior)
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: format!(
|
||||
"`create_info.scaling_behavior` is not present in the \
|
||||
`supported_present_scaling` value of the \
|
||||
@ -841,7 +841,7 @@ impl Swapchain {
|
||||
"VUID-VkSwapchainPresentScalingCreateInfoEXT-scalingBehavior-07771",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -853,7 +853,7 @@ impl Swapchain {
|
||||
.enumerate()
|
||||
{
|
||||
if !supported_present_gravity.contains_enum(present_gravity) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: format!(
|
||||
"`create_info.present_gravity[{0}]` is not present in the \
|
||||
`supported_present_gravity[{0}]` value of the \
|
||||
@ -867,7 +867,7 @@ impl Swapchain {
|
||||
"VUID-VkSwapchainPresentScalingCreateInfoEXT-presentGravityY-07775",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -880,7 +880,7 @@ impl Swapchain {
|
||||
if image_extent[0] < min_scaled_image_extent[0]
|
||||
|| image_extent[1] < min_scaled_image_extent[1]
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`scaling_behavior` is `Some`, and an element of \
|
||||
`create_info.image_extent` is less than the corresponding element \
|
||||
of the `min_scaled_image_extent` value of the \
|
||||
@ -888,7 +888,7 @@ impl Swapchain {
|
||||
.into(),
|
||||
vuids: &["VUID-VkSwapchainCreateInfoKHR-pNext-07782"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -896,7 +896,7 @@ impl Swapchain {
|
||||
if image_extent[0] > max_scaled_image_extent[0]
|
||||
|| image_extent[1] > max_scaled_image_extent[1]
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`scaling_behavior` is `Some`, and an element of \
|
||||
`create_info.image_extent` is greater than the corresponding element \
|
||||
of the `max_scaled_image_extent` value of the \
|
||||
@ -904,7 +904,7 @@ impl Swapchain {
|
||||
.into(),
|
||||
vuids: &["VUID-VkSwapchainCreateInfoKHR-pNext-07782"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -919,7 +919,7 @@ impl Swapchain {
|
||||
if image_extent[0] < surface_capabilities.min_image_extent[0]
|
||||
|| image_extent[1] < surface_capabilities.min_image_extent[1]
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`scaling_behavior` is `Some`, and an element of \
|
||||
`create_info.image_extent` is less than the corresponding element \
|
||||
of the `min_image_extent` value of the \
|
||||
@ -927,13 +927,13 @@ impl Swapchain {
|
||||
.into(),
|
||||
vuids: &["VUID-VkSwapchainCreateInfoKHR-pNext-07781"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if image_extent[0] > surface_capabilities.max_image_extent[0]
|
||||
|| image_extent[1] > surface_capabilities.max_image_extent[1]
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`scaling_behavior` is `Some`, and an element of \
|
||||
`create_info.image_extent` is greater than the corresponding element \
|
||||
of the `max_image_extent` value of the \
|
||||
@ -941,7 +941,7 @@ impl Swapchain {
|
||||
.into(),
|
||||
vuids: &["VUID-VkSwapchainCreateInfoKHR-pNext-07781"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
*/
|
||||
}
|
||||
@ -950,7 +950,7 @@ impl Swapchain {
|
||||
&& full_screen_exclusive == FullScreenExclusive::ApplicationControlled
|
||||
{
|
||||
if win32_monitor.is_none() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`surface` is a Win32 surface, and \
|
||||
`create_info.full_screen_exclusive` is \
|
||||
`FullScreenExclusive::ApplicationControlled`, but \
|
||||
@ -958,18 +958,18 @@ impl Swapchain {
|
||||
.into(),
|
||||
vuids: &["VUID-VkSwapchainCreateInfoKHR-pNext-02679"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
} else {
|
||||
if win32_monitor.is_some() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`surface` is not a Win32 surface, or \
|
||||
`create_info.full_screen_exclusive` is not \
|
||||
`FullScreenExclusive::ApplicationControlled`, but \
|
||||
`create_info.win32_monitor` is `Some`"
|
||||
.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -981,7 +981,7 @@ impl Swapchain {
|
||||
surface: &Surface,
|
||||
create_info: &SwapchainCreateInfo,
|
||||
old_swapchain: Option<&Swapchain>,
|
||||
) -> Result<(ash::vk::SwapchainKHR, Vec<ash::vk::Image>), RuntimeError> {
|
||||
) -> Result<(ash::vk::SwapchainKHR, Vec<ash::vk::Image>), VulkanError> {
|
||||
let &SwapchainCreateInfo {
|
||||
flags,
|
||||
min_image_count,
|
||||
@ -1103,7 +1103,7 @@ impl Swapchain {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
};
|
||||
|
||||
@ -1116,7 +1116,7 @@ impl Swapchain {
|
||||
ptr::null_mut(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
let mut images = Vec::with_capacity(count as usize);
|
||||
let result = (fns.khr_swapchain.get_swapchain_images_khr)(
|
||||
@ -1132,7 +1132,7 @@ impl Swapchain {
|
||||
break images;
|
||||
}
|
||||
ash::vk::Result::INCOMPLETE => (),
|
||||
err => return Err(RuntimeError::from(err)),
|
||||
err => return Err(VulkanError::from(err)),
|
||||
}
|
||||
};
|
||||
|
||||
@ -1154,7 +1154,7 @@ impl Swapchain {
|
||||
image_handles: impl IntoIterator<Item = ash::vk::Image>,
|
||||
surface: Arc<Surface>,
|
||||
create_info: SwapchainCreateInfo,
|
||||
) -> Result<(Arc<Swapchain>, Vec<Arc<Image>>), RuntimeError> {
|
||||
) -> Result<(Arc<Swapchain>, Vec<Arc<Image>>), VulkanError> {
|
||||
let SwapchainCreateInfo {
|
||||
flags,
|
||||
min_image_count,
|
||||
@ -1223,7 +1223,7 @@ impl Swapchain {
|
||||
image_index as u32,
|
||||
)?))
|
||||
})
|
||||
.collect::<Result<_, RuntimeError>>()?;
|
||||
.collect::<Result<_, VulkanError>>()?;
|
||||
|
||||
Ok((swapchain, swapchain_images))
|
||||
}
|
||||
@ -1398,7 +1398,7 @@ impl Swapchain {
|
||||
self.device.handle(), self.handle
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -1428,7 +1428,7 @@ impl Swapchain {
|
||||
self.device.handle(), self.handle
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -1662,7 +1662,7 @@ impl Default for SwapchainCreateInfo {
|
||||
}
|
||||
|
||||
impl SwapchainCreateInfo {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
flags,
|
||||
min_image_count: _,
|
||||
@ -1724,12 +1724,12 @@ impl SwapchainCreateInfo {
|
||||
})?;
|
||||
|
||||
if image_usage.is_empty() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "image_usage".into(),
|
||||
problem: "is empty".into(),
|
||||
vuids: &["VUID-VkSwapchainCreateInfoKHR-imageUsage-requiredbitmask"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
pre_transform
|
||||
@ -1757,35 +1757,35 @@ impl SwapchainCreateInfo {
|
||||
})?;
|
||||
|
||||
if image_extent.contains(&0) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "image_extent".into(),
|
||||
problem: "one or more elements are zero".into(),
|
||||
vuids: &["VUID-VkSwapchainCreateInfoKHR-imageExtent-01689"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if image_array_layers == 0 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "image_array_layers".into(),
|
||||
problem: "is zero".into(),
|
||||
vuids: &["VUID-VkSwapchainCreateInfoKHR-imageArrayLayers-01275"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
match image_sharing {
|
||||
Sharing::Exclusive => (),
|
||||
Sharing::Concurrent(queue_family_indices) => {
|
||||
if queue_family_indices.len() < 2 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "image_sharing".into(),
|
||||
problem: "is `Sharing::Concurrent`, and contains less than 2 \
|
||||
queue family indices"
|
||||
.into(),
|
||||
vuids: &["VUID-VkSwapchainCreateInfoKHR-imageSharingMode-01278"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
let queue_family_count =
|
||||
@ -1793,7 +1793,7 @@ impl SwapchainCreateInfo {
|
||||
|
||||
for (index, &queue_family_index) in queue_family_indices.iter().enumerate() {
|
||||
if queue_family_indices[..index].contains(&queue_family_index) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "queue_family_indices".into(),
|
||||
problem: format!(
|
||||
"the queue family index in the list at index {} is contained in \
|
||||
@ -1803,18 +1803,18 @@ impl SwapchainCreateInfo {
|
||||
.into(),
|
||||
vuids: &["VUID-VkSwapchainCreateInfoKHR-imageSharingMode-01428"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if queue_family_index >= queue_family_count {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: format!("queue_family_indices[{}]", index).into(),
|
||||
problem: "is not less than the number of queue families in the \
|
||||
physical device"
|
||||
.into(),
|
||||
vuids: &["VUID-VkSwapchainCreateInfoKHR-imageSharingMode-01428"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1838,25 +1838,25 @@ impl SwapchainCreateInfo {
|
||||
};
|
||||
|
||||
if image_format_properties.is_none() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "the combination of `image_format` and `image_usage` is not supported \
|
||||
for images by the physical device"
|
||||
.into(),
|
||||
vuids: &["VUID-VkSwapchainCreateInfoKHR-imageFormat-01778"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if !present_modes.is_empty() {
|
||||
if !device.enabled_extensions().ext_swapchain_maintenance1 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "present_modes".into(),
|
||||
problem: "is not empty".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::DeviceExtension(
|
||||
"ext_swapchain_maintenance1",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
for (index, &present_mode) in present_modes.iter().enumerate() {
|
||||
@ -1872,25 +1872,25 @@ impl SwapchainCreateInfo {
|
||||
}
|
||||
|
||||
if !present_modes.contains(&present_mode) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`present_modes` is not empty, but does not contain `present_mode`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkSwapchainPresentModesCreateInfoEXT-presentMode-07764"],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(scaling_behavior) = scaling_behavior {
|
||||
if !device.enabled_extensions().ext_swapchain_maintenance1 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "scaling_behavior".into(),
|
||||
problem: "is `Some`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::DeviceExtension(
|
||||
"ext_swapchain_maintenance1",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
scaling_behavior
|
||||
@ -1909,14 +1909,14 @@ impl SwapchainCreateInfo {
|
||||
|
||||
if let Some(present_gravity) = present_gravity {
|
||||
if !device.enabled_extensions().ext_swapchain_maintenance1 {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "present_gravity".into(),
|
||||
problem: "is `Some`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::DeviceExtension(
|
||||
"ext_swapchain_maintenance1",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
for (axis_index, present_gravity) in present_gravity.into_iter().enumerate() {
|
||||
@ -1943,14 +1943,14 @@ impl SwapchainCreateInfo {
|
||||
|
||||
if full_screen_exclusive != FullScreenExclusive::Default {
|
||||
if !device.enabled_extensions().ext_full_screen_exclusive {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "full_screen_exclusive".into(),
|
||||
problem: "is not `FullScreenExclusive::Default`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::DeviceExtension(
|
||||
"ext_full_screen_exclusive",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
full_screen_exclusive
|
||||
@ -2145,17 +2145,17 @@ impl Display for FullScreenExclusiveError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RuntimeError> for FullScreenExclusiveError {
|
||||
fn from(err: RuntimeError) -> FullScreenExclusiveError {
|
||||
impl From<VulkanError> for FullScreenExclusiveError {
|
||||
fn from(err: VulkanError) -> FullScreenExclusiveError {
|
||||
match err {
|
||||
err @ RuntimeError::OutOfHostMemory => {
|
||||
err @ VulkanError::OutOfHostMemory => {
|
||||
FullScreenExclusiveError::OomError(OomError::from(err))
|
||||
}
|
||||
err @ RuntimeError::OutOfDeviceMemory => {
|
||||
err @ VulkanError::OutOfDeviceMemory => {
|
||||
FullScreenExclusiveError::OomError(OomError::from(err))
|
||||
}
|
||||
RuntimeError::SurfaceLost => FullScreenExclusiveError::SurfaceLost,
|
||||
RuntimeError::InitializationFailed => FullScreenExclusiveError::InitializationFailed,
|
||||
VulkanError::SurfaceLost => FullScreenExclusiveError::SurfaceLost,
|
||||
VulkanError::InitializationFailed => FullScreenExclusiveError::InitializationFailed,
|
||||
_ => panic!("unexpected error: {:?}", err),
|
||||
}
|
||||
}
|
||||
|
@ -16,8 +16,8 @@ use crate::{
|
||||
instance::{Instance, InstanceExtensions, InstanceOwned},
|
||||
macros::{impl_id_counter, vulkan_bitflags_enum, vulkan_enum},
|
||||
swapchain::display::{DisplayMode, DisplayPlane},
|
||||
DebugWrapper, Requires, RequiresAllOf, RequiresOneOf, RuntimeError, ValidationError,
|
||||
VulkanError, VulkanObject,
|
||||
DebugWrapper, Requires, RequiresAllOf, RequiresOneOf, Validated, ValidationError, VulkanError,
|
||||
VulkanObject,
|
||||
};
|
||||
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
||||
use objc::{class, msg_send, runtime::Object, sel, sel_impl};
|
||||
@ -83,7 +83,7 @@ impl Surface {
|
||||
pub fn from_window(
|
||||
instance: Arc<Instance>,
|
||||
window: Arc<impl HasRawWindowHandle + HasRawDisplayHandle + Any + Send + Sync>,
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
) -> Result<Arc<Self>, Validated<VulkanError>> {
|
||||
let mut surface = unsafe { Self::from_window_ref(instance, &*window) }?;
|
||||
Arc::get_mut(&mut surface).unwrap().object = Some(window);
|
||||
|
||||
@ -99,7 +99,7 @@ impl Surface {
|
||||
pub unsafe fn from_window_ref(
|
||||
instance: Arc<Instance>,
|
||||
window: &(impl HasRawWindowHandle + HasRawDisplayHandle),
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
) -> Result<Arc<Self>, Validated<VulkanError>> {
|
||||
match (window.raw_window_handle(), window.raw_display_handle()) {
|
||||
(RawWindowHandle::AndroidNdk(window), RawDisplayHandle::Android(_display)) => {
|
||||
Self::from_android(instance, window.a_native_window, None)
|
||||
@ -169,20 +169,20 @@ impl Surface {
|
||||
pub fn headless(
|
||||
instance: Arc<Instance>,
|
||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
) -> Result<Arc<Self>, Validated<VulkanError>> {
|
||||
Self::validate_headless(&instance)?;
|
||||
|
||||
unsafe { Ok(Self::headless_unchecked(instance, object)?) }
|
||||
}
|
||||
|
||||
fn validate_headless(instance: &Instance) -> Result<(), ValidationError> {
|
||||
fn validate_headless(instance: &Instance) -> Result<(), Box<ValidationError>> {
|
||||
if !instance.enabled_extensions().ext_headless_surface {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||
"ext_headless_surface",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -192,7 +192,7 @@ impl Surface {
|
||||
pub unsafe fn headless_unchecked(
|
||||
instance: Arc<Instance>,
|
||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||
) -> Result<Arc<Self>, RuntimeError> {
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
let create_info = ash::vk::HeadlessSurfaceCreateInfoEXT {
|
||||
flags: ash::vk::HeadlessSurfaceCreateFlagsEXT::empty(),
|
||||
..Default::default()
|
||||
@ -208,7 +208,7 @@ impl Surface {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
};
|
||||
|
||||
@ -229,7 +229,7 @@ impl Surface {
|
||||
pub fn from_display_plane(
|
||||
display_mode: &DisplayMode,
|
||||
plane: &DisplayPlane,
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
) -> Result<Arc<Self>, Validated<VulkanError>> {
|
||||
Self::validate_from_display_plane(display_mode, plane)?;
|
||||
|
||||
unsafe { Ok(Self::from_display_plane_unchecked(display_mode, plane)?) }
|
||||
@ -238,7 +238,7 @@ impl Surface {
|
||||
fn validate_from_display_plane(
|
||||
display_mode: &DisplayMode,
|
||||
plane: &DisplayPlane,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
if !display_mode
|
||||
.display()
|
||||
.physical_device()
|
||||
@ -246,12 +246,12 @@ impl Surface {
|
||||
.enabled_extensions()
|
||||
.khr_display
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||
"khr_display",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
@ -267,7 +267,7 @@ impl Surface {
|
||||
pub unsafe fn from_display_plane_unchecked(
|
||||
display_mode: &DisplayMode,
|
||||
plane: &DisplayPlane,
|
||||
) -> Result<Arc<Self>, RuntimeError> {
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
let instance = display_mode.display().physical_device().instance();
|
||||
|
||||
let create_info = ash::vk::DisplaySurfaceCreateInfoKHR {
|
||||
@ -296,7 +296,7 @@ impl Surface {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
};
|
||||
|
||||
@ -319,7 +319,7 @@ impl Surface {
|
||||
instance: Arc<Instance>,
|
||||
window: *const W,
|
||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
) -> Result<Arc<Self>, Validated<VulkanError>> {
|
||||
Self::validate_from_android(&instance, window)?;
|
||||
|
||||
Ok(Self::from_android_unchecked(instance, window, object)?)
|
||||
@ -328,14 +328,14 @@ impl Surface {
|
||||
fn validate_from_android<W>(
|
||||
instance: &Instance,
|
||||
_window: *const W,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
if !instance.enabled_extensions().khr_android_surface {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||
"khr_android_surface",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// VUID-VkAndroidSurfaceCreateInfoKHR-window-01248
|
||||
@ -349,7 +349,7 @@ impl Surface {
|
||||
instance: Arc<Instance>,
|
||||
window: *const W,
|
||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||
) -> Result<Arc<Self>, RuntimeError> {
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
let create_info = ash::vk::AndroidSurfaceCreateInfoKHR {
|
||||
flags: ash::vk::AndroidSurfaceCreateFlagsKHR::empty(),
|
||||
window: window as *mut _,
|
||||
@ -366,7 +366,7 @@ impl Surface {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
};
|
||||
|
||||
@ -391,7 +391,7 @@ impl Surface {
|
||||
dfb: *const D,
|
||||
surface: *const S,
|
||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
) -> Result<Arc<Self>, Validated<VulkanError>> {
|
||||
Self::validate_from_directfb(&instance, dfb, surface)?;
|
||||
|
||||
Ok(Self::from_directfb_unchecked(
|
||||
@ -403,14 +403,14 @@ impl Surface {
|
||||
instance: &Instance,
|
||||
_dfb: *const D,
|
||||
_surface: *const S,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
if !instance.enabled_extensions().ext_directfb_surface {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||
"ext_directfb_surface",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// VUID-VkDirectFBSurfaceCreateInfoEXT-dfb-04117
|
||||
@ -428,7 +428,7 @@ impl Surface {
|
||||
dfb: *const D,
|
||||
surface: *const S,
|
||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||
) -> Result<Arc<Self>, RuntimeError> {
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
let create_info = ash::vk::DirectFBSurfaceCreateInfoEXT {
|
||||
flags: ash::vk::DirectFBSurfaceCreateFlagsEXT::empty(),
|
||||
dfb: dfb as *mut _,
|
||||
@ -446,7 +446,7 @@ impl Surface {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
};
|
||||
|
||||
@ -469,7 +469,7 @@ impl Surface {
|
||||
instance: Arc<Instance>,
|
||||
image_pipe_handle: ash::vk::zx_handle_t,
|
||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
) -> Result<Arc<Self>, Validated<VulkanError>> {
|
||||
Self::validate_from_fuchsia_image_pipe(&instance, image_pipe_handle)?;
|
||||
|
||||
Ok(Self::from_fuchsia_image_pipe_unchecked(
|
||||
@ -482,14 +482,14 @@ impl Surface {
|
||||
fn validate_from_fuchsia_image_pipe(
|
||||
instance: &Instance,
|
||||
_image_pipe_handle: ash::vk::zx_handle_t,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
if !instance.enabled_extensions().fuchsia_imagepipe_surface {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||
"fuchsia_imagepipe_surface",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// VUID-VkImagePipeSurfaceCreateInfoFUCHSIA-imagePipeHandle-04863
|
||||
@ -503,7 +503,7 @@ impl Surface {
|
||||
instance: Arc<Instance>,
|
||||
image_pipe_handle: ash::vk::zx_handle_t,
|
||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||
) -> Result<Arc<Self>, RuntimeError> {
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
let create_info = ash::vk::ImagePipeSurfaceCreateInfoFUCHSIA {
|
||||
flags: ash::vk::ImagePipeSurfaceCreateFlagsFUCHSIA::empty(),
|
||||
image_pipe_handle,
|
||||
@ -521,7 +521,7 @@ impl Surface {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
};
|
||||
|
||||
@ -544,7 +544,7 @@ impl Surface {
|
||||
instance: Arc<Instance>,
|
||||
stream_descriptor: ash::vk::GgpStreamDescriptor,
|
||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
) -> Result<Arc<Self>, Validated<VulkanError>> {
|
||||
Self::validate_from_ggp_stream_descriptor(&instance, stream_descriptor)?;
|
||||
|
||||
Ok(Self::from_ggp_stream_descriptor_unchecked(
|
||||
@ -557,14 +557,14 @@ impl Surface {
|
||||
fn validate_from_ggp_stream_descriptor(
|
||||
instance: &Instance,
|
||||
_stream_descriptor: ash::vk::GgpStreamDescriptor,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
if !instance.enabled_extensions().ggp_stream_descriptor_surface {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||
"ggp_stream_descriptor_surface",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// VUID-VkStreamDescriptorSurfaceCreateInfoGGP-streamDescriptor-02681
|
||||
@ -578,7 +578,7 @@ impl Surface {
|
||||
instance: Arc<Instance>,
|
||||
stream_descriptor: ash::vk::GgpStreamDescriptor,
|
||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||
) -> Result<Arc<Self>, RuntimeError> {
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
let create_info = ash::vk::StreamDescriptorSurfaceCreateInfoGGP {
|
||||
flags: ash::vk::StreamDescriptorSurfaceCreateFlagsGGP::empty(),
|
||||
stream_descriptor,
|
||||
@ -596,7 +596,7 @@ impl Surface {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
};
|
||||
|
||||
@ -621,7 +621,7 @@ impl Surface {
|
||||
instance: Arc<Instance>,
|
||||
metal_layer: IOSMetalLayer,
|
||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
) -> Result<Arc<Self>, Validated<VulkanError>> {
|
||||
Self::validate_from_ios(&instance, &metal_layer)?;
|
||||
|
||||
Ok(Self::from_ios_unchecked(instance, metal_layer, object)?)
|
||||
@ -631,14 +631,14 @@ impl Surface {
|
||||
fn validate_from_ios(
|
||||
instance: &Instance,
|
||||
_metal_layer: &IOSMetalLayer,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
if !instance.enabled_extensions().mvk_ios_surface {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||
"mvk_ios_surface",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// VUID-VkIOSSurfaceCreateInfoMVK-pView-04143
|
||||
@ -656,7 +656,7 @@ impl Surface {
|
||||
instance: Arc<Instance>,
|
||||
metal_layer: IOSMetalLayer,
|
||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||
) -> Result<Arc<Self>, RuntimeError> {
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
let create_info = ash::vk::IOSSurfaceCreateInfoMVK {
|
||||
flags: ash::vk::IOSSurfaceCreateFlagsMVK::empty(),
|
||||
p_view: metal_layer.render_layer.0 as *const _,
|
||||
@ -673,7 +673,7 @@ impl Surface {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
};
|
||||
|
||||
@ -698,7 +698,7 @@ impl Surface {
|
||||
instance: Arc<Instance>,
|
||||
view: *const V,
|
||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
) -> Result<Arc<Self>, Validated<VulkanError>> {
|
||||
Self::validate_from_mac_os(&instance, view)?;
|
||||
|
||||
Ok(Self::from_mac_os_unchecked(instance, view, object)?)
|
||||
@ -708,14 +708,14 @@ impl Surface {
|
||||
fn validate_from_mac_os<V>(
|
||||
instance: &Instance,
|
||||
_view: *const V,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
if !instance.enabled_extensions().mvk_macos_surface {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||
"mvk_macos_surface",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// VUID-VkMacOSSurfaceCreateInfoMVK-pView-04144
|
||||
@ -733,7 +733,7 @@ impl Surface {
|
||||
instance: Arc<Instance>,
|
||||
view: *const V,
|
||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||
) -> Result<Arc<Self>, RuntimeError> {
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
let create_info = ash::vk::MacOSSurfaceCreateInfoMVK {
|
||||
flags: ash::vk::MacOSSurfaceCreateFlagsMVK::empty(),
|
||||
p_view: view as *const _,
|
||||
@ -750,7 +750,7 @@ impl Surface {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
};
|
||||
|
||||
@ -773,7 +773,7 @@ impl Surface {
|
||||
instance: Arc<Instance>,
|
||||
layer: *const L,
|
||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
) -> Result<Arc<Self>, Validated<VulkanError>> {
|
||||
Self::validate_from_metal(&instance, layer)?;
|
||||
|
||||
Ok(Self::from_metal_unchecked(instance, layer, object)?)
|
||||
@ -782,14 +782,14 @@ impl Surface {
|
||||
fn validate_from_metal<L>(
|
||||
instance: &Instance,
|
||||
_layer: *const L,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
if !instance.enabled_extensions().ext_metal_surface {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||
"ext_metal_surface",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -800,7 +800,7 @@ impl Surface {
|
||||
instance: Arc<Instance>,
|
||||
layer: *const L,
|
||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||
) -> Result<Arc<Self>, RuntimeError> {
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
let create_info = ash::vk::MetalSurfaceCreateInfoEXT {
|
||||
flags: ash::vk::MetalSurfaceCreateFlagsEXT::empty(),
|
||||
p_layer: layer as *const _,
|
||||
@ -817,7 +817,7 @@ impl Surface {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
};
|
||||
|
||||
@ -842,7 +842,7 @@ impl Surface {
|
||||
context: *const C,
|
||||
window: *const W,
|
||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
) -> Result<Arc<Self>, Validated<VulkanError>> {
|
||||
Self::validate_from_qnx_screen(&instance, context, window)?;
|
||||
|
||||
Ok(Self::from_qnx_screen_unchecked(
|
||||
@ -854,14 +854,14 @@ impl Surface {
|
||||
instance: &Instance,
|
||||
_context: *const C,
|
||||
_window: *const W,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
if !instance.enabled_extensions().qnx_screen_surface {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||
"qnx_screen_surface",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// VUID-VkScreenSurfaceCreateInfoQNX-context-04741
|
||||
@ -879,7 +879,7 @@ impl Surface {
|
||||
context: *const C,
|
||||
window: *const W,
|
||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||
) -> Result<Arc<Self>, RuntimeError> {
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
let create_info = ash::vk::ScreenSurfaceCreateInfoQNX {
|
||||
flags: ash::vk::ScreenSurfaceCreateFlagsQNX::empty(),
|
||||
context: context as *mut _,
|
||||
@ -897,7 +897,7 @@ impl Surface {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
};
|
||||
|
||||
@ -920,20 +920,23 @@ impl Surface {
|
||||
instance: Arc<Instance>,
|
||||
window: *const W,
|
||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
) -> Result<Arc<Self>, Validated<VulkanError>> {
|
||||
Self::validate_from_vi(&instance, window)?;
|
||||
|
||||
Ok(Self::from_vi_unchecked(instance, window, object)?)
|
||||
}
|
||||
|
||||
fn validate_from_vi<W>(instance: &Instance, _window: *const W) -> Result<(), ValidationError> {
|
||||
fn validate_from_vi<W>(
|
||||
instance: &Instance,
|
||||
_window: *const W,
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
if !instance.enabled_extensions().nn_vi_surface {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||
"nn_vi_surface",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// VUID-VkViSurfaceCreateInfoNN-window-01318
|
||||
@ -947,7 +950,7 @@ impl Surface {
|
||||
instance: Arc<Instance>,
|
||||
window: *const W,
|
||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||
) -> Result<Arc<Self>, RuntimeError> {
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
let create_info = ash::vk::ViSurfaceCreateInfoNN {
|
||||
flags: ash::vk::ViSurfaceCreateFlagsNN::empty(),
|
||||
window: window as *mut _,
|
||||
@ -964,7 +967,7 @@ impl Surface {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
};
|
||||
|
||||
@ -991,7 +994,7 @@ impl Surface {
|
||||
display: *const D,
|
||||
surface: *const S,
|
||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
) -> Result<Arc<Self>, Validated<VulkanError>> {
|
||||
Self::validate_from_wayland(&instance, display, surface)?;
|
||||
|
||||
Ok(Self::from_wayland_unchecked(
|
||||
@ -1003,14 +1006,14 @@ impl Surface {
|
||||
instance: &Instance,
|
||||
_display: *const D,
|
||||
_surface: *const S,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
if !instance.enabled_extensions().khr_wayland_surface {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||
"khr_wayland_surface",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// VUID-VkWaylandSurfaceCreateInfoKHR-display-01304
|
||||
@ -1028,7 +1031,7 @@ impl Surface {
|
||||
display: *const D,
|
||||
surface: *const S,
|
||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||
) -> Result<Arc<Self>, RuntimeError> {
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
let create_info = ash::vk::WaylandSurfaceCreateInfoKHR {
|
||||
flags: ash::vk::WaylandSurfaceCreateFlagsKHR::empty(),
|
||||
display: display as *mut _,
|
||||
@ -1046,7 +1049,7 @@ impl Surface {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
};
|
||||
|
||||
@ -1073,7 +1076,7 @@ impl Surface {
|
||||
hinstance: *const I,
|
||||
hwnd: *const W,
|
||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
) -> Result<Arc<Self>, Validated<VulkanError>> {
|
||||
Self::validate_from_win32(&instance, hinstance, hwnd)?;
|
||||
|
||||
Ok(Self::from_win32_unchecked(
|
||||
@ -1085,14 +1088,14 @@ impl Surface {
|
||||
instance: &Instance,
|
||||
_hinstance: *const I,
|
||||
_hwnd: *const W,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
if !instance.enabled_extensions().khr_win32_surface {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||
"khr_win32_surface",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// VUID-VkWin32SurfaceCreateInfoKHR-hinstance-01307
|
||||
@ -1110,7 +1113,7 @@ impl Surface {
|
||||
hinstance: *const I,
|
||||
hwnd: *const W,
|
||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||
) -> Result<Arc<Self>, RuntimeError> {
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
let create_info = ash::vk::Win32SurfaceCreateInfoKHR {
|
||||
flags: ash::vk::Win32SurfaceCreateFlagsKHR::empty(),
|
||||
hinstance: hinstance as *mut _,
|
||||
@ -1128,7 +1131,7 @@ impl Surface {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
};
|
||||
|
||||
@ -1155,7 +1158,7 @@ impl Surface {
|
||||
connection: *const C,
|
||||
window: ash::vk::xcb_window_t,
|
||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
) -> Result<Arc<Self>, Validated<VulkanError>> {
|
||||
Self::validate_from_xcb(&instance, connection, window)?;
|
||||
|
||||
Ok(Self::from_xcb_unchecked(
|
||||
@ -1167,14 +1170,14 @@ impl Surface {
|
||||
instance: &Instance,
|
||||
_connection: *const C,
|
||||
_window: ash::vk::xcb_window_t,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
if !instance.enabled_extensions().khr_xcb_surface {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||
"khr_xcb_surface",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// VUID-VkXcbSurfaceCreateInfoKHR-connection-01310
|
||||
@ -1192,7 +1195,7 @@ impl Surface {
|
||||
connection: *const C,
|
||||
window: ash::vk::xcb_window_t,
|
||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||
) -> Result<Arc<Self>, RuntimeError> {
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
let create_info = ash::vk::XcbSurfaceCreateInfoKHR {
|
||||
flags: ash::vk::XcbSurfaceCreateFlagsKHR::empty(),
|
||||
connection: connection as *mut _,
|
||||
@ -1210,7 +1213,7 @@ impl Surface {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
};
|
||||
|
||||
@ -1237,7 +1240,7 @@ impl Surface {
|
||||
display: *const D,
|
||||
window: ash::vk::Window,
|
||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
) -> Result<Arc<Self>, Validated<VulkanError>> {
|
||||
Self::validate_from_xlib(&instance, display, window)?;
|
||||
|
||||
Ok(Self::from_xlib_unchecked(
|
||||
@ -1249,14 +1252,14 @@ impl Surface {
|
||||
instance: &Instance,
|
||||
_display: *const D,
|
||||
_window: ash::vk::Window,
|
||||
) -> Result<(), ValidationError> {
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
if !instance.enabled_extensions().khr_xlib_surface {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||
"khr_xlib_surface",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// VUID-VkXlibSurfaceCreateInfoKHR-dpy-01313
|
||||
@ -1274,7 +1277,7 @@ impl Surface {
|
||||
display: *const D,
|
||||
window: ash::vk::Window,
|
||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||
) -> Result<Arc<Self>, RuntimeError> {
|
||||
) -> Result<Arc<Self>, VulkanError> {
|
||||
let create_info = ash::vk::XlibSurfaceCreateInfoKHR {
|
||||
flags: ash::vk::XlibSurfaceCreateFlagsKHR::empty(),
|
||||
dpy: display as *mut _,
|
||||
@ -1292,7 +1295,7 @@ impl Surface {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
};
|
||||
|
||||
@ -1850,7 +1853,10 @@ impl Default for SurfaceInfo {
|
||||
}
|
||||
|
||||
impl SurfaceInfo {
|
||||
pub(crate) fn validate(&self, physical_device: &PhysicalDevice) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(
|
||||
&self,
|
||||
physical_device: &PhysicalDevice,
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
present_mode,
|
||||
full_screen_exclusive,
|
||||
@ -1864,14 +1870,14 @@ impl SurfaceInfo {
|
||||
.enabled_extensions()
|
||||
.ext_surface_maintenance1
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "present_mode".into(),
|
||||
problem: "is `Some`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[
|
||||
Requires::InstanceExtension("ext_surface_maintenance1"),
|
||||
])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
present_mode
|
||||
@ -1888,14 +1894,14 @@ impl SurfaceInfo {
|
||||
.supported_extensions()
|
||||
.ext_full_screen_exclusive
|
||||
{
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "full_screen_exclusive".into(),
|
||||
problem: "is not `FullScreenExclusive::Default`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::DeviceExtension(
|
||||
"ext_full_screen_exclusive",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -2029,7 +2035,7 @@ pub struct SurfaceCapabilities {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{
|
||||
swapchain::Surface, Requires, RequiresAllOf, RequiresOneOf, ValidationError, VulkanError,
|
||||
swapchain::Surface, Requires, RequiresAllOf, RequiresOneOf, Validated, ValidationError,
|
||||
};
|
||||
use std::ptr;
|
||||
|
||||
@ -2037,11 +2043,16 @@ mod tests {
|
||||
fn khr_win32_surface_ext_missing() {
|
||||
let instance = instance!();
|
||||
match unsafe { Surface::from_win32(instance, ptr::null::<u8>(), ptr::null::<u8>(), None) } {
|
||||
Err(VulkanError::ValidationError(ValidationError {
|
||||
requires_one_of:
|
||||
RequiresOneOf([RequiresAllOf([Requires::InstanceExtension("khr_win32_surface")])]),
|
||||
..
|
||||
})) => (),
|
||||
Err(Validated::ValidationError(err))
|
||||
if matches!(
|
||||
*err,
|
||||
ValidationError {
|
||||
requires_one_of: RequiresOneOf([RequiresAllOf([
|
||||
Requires::InstanceExtension("khr_win32_surface")
|
||||
])]),
|
||||
..
|
||||
}
|
||||
) => {}
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
@ -2050,11 +2061,16 @@ mod tests {
|
||||
fn khr_xcb_surface_ext_missing() {
|
||||
let instance = instance!();
|
||||
match unsafe { Surface::from_xcb(instance, ptr::null::<u8>(), 0, None) } {
|
||||
Err(VulkanError::ValidationError(ValidationError {
|
||||
requires_one_of:
|
||||
RequiresOneOf([RequiresAllOf([Requires::InstanceExtension("khr_xcb_surface")])]),
|
||||
..
|
||||
})) => (),
|
||||
Err(Validated::ValidationError(err))
|
||||
if matches!(
|
||||
*err,
|
||||
ValidationError {
|
||||
requires_one_of: RequiresOneOf([RequiresAllOf([
|
||||
Requires::InstanceExtension("khr_xcb_surface")
|
||||
])]),
|
||||
..
|
||||
}
|
||||
) => {}
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
@ -2063,11 +2079,16 @@ mod tests {
|
||||
fn khr_xlib_surface_ext_missing() {
|
||||
let instance = instance!();
|
||||
match unsafe { Surface::from_xlib(instance, ptr::null::<u8>(), 0, None) } {
|
||||
Err(VulkanError::ValidationError(ValidationError {
|
||||
requires_one_of:
|
||||
RequiresOneOf([RequiresAllOf([Requires::InstanceExtension("khr_xlib_surface")])]),
|
||||
..
|
||||
})) => (),
|
||||
Err(Validated::ValidationError(err))
|
||||
if matches!(
|
||||
*err,
|
||||
ValidationError {
|
||||
requires_one_of: RequiresOneOf([RequiresAllOf([
|
||||
Requires::InstanceExtension("khr_xlib_surface")
|
||||
])]),
|
||||
..
|
||||
}
|
||||
) => {}
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
@ -2077,11 +2098,16 @@ mod tests {
|
||||
let instance = instance!();
|
||||
match unsafe { Surface::from_wayland(instance, ptr::null::<u8>(), ptr::null::<u8>(), None) }
|
||||
{
|
||||
Err(VulkanError::ValidationError(ValidationError {
|
||||
requires_one_of:
|
||||
RequiresOneOf([RequiresAllOf([Requires::InstanceExtension("khr_wayland_surface")])]),
|
||||
..
|
||||
})) => (),
|
||||
Err(Validated::ValidationError(err))
|
||||
if matches!(
|
||||
*err,
|
||||
ValidationError {
|
||||
requires_one_of: RequiresOneOf([RequiresAllOf([
|
||||
Requires::InstanceExtension("khr_wayland_surface")
|
||||
])]),
|
||||
..
|
||||
}
|
||||
) => {}
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
@ -2090,11 +2116,16 @@ mod tests {
|
||||
fn khr_android_surface_ext_missing() {
|
||||
let instance = instance!();
|
||||
match unsafe { Surface::from_android(instance, ptr::null::<u8>(), None) } {
|
||||
Err(VulkanError::ValidationError(ValidationError {
|
||||
requires_one_of:
|
||||
RequiresOneOf([RequiresAllOf([Requires::InstanceExtension("khr_android_surface")])]),
|
||||
..
|
||||
})) => (),
|
||||
Err(Validated::ValidationError(err))
|
||||
if matches!(
|
||||
*err,
|
||||
ValidationError {
|
||||
requires_one_of: RequiresOneOf([RequiresAllOf([
|
||||
Requires::InstanceExtension("khr_android_surface")
|
||||
])]),
|
||||
..
|
||||
}
|
||||
) => {}
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ use crate::{
|
||||
device::{Device, DeviceOwned},
|
||||
instance::InstanceOwnedDebugWrapper,
|
||||
macros::impl_id_counter,
|
||||
OomError, Requires, RequiresAllOf, RequiresOneOf, RuntimeError, VulkanObject,
|
||||
OomError, Requires, RequiresAllOf, RequiresOneOf, VulkanError, VulkanObject,
|
||||
};
|
||||
use std::{
|
||||
error::Error,
|
||||
@ -86,7 +86,7 @@ impl Event {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
};
|
||||
|
||||
@ -114,7 +114,7 @@ impl Event {
|
||||
let fns = device.fns();
|
||||
(fns.v1_0.reset_event)(device.handle(), handle)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
}
|
||||
Event {
|
||||
handle,
|
||||
@ -163,7 +163,7 @@ impl Event {
|
||||
match result {
|
||||
ash::vk::Result::EVENT_SET => Ok(true),
|
||||
ash::vk::Result::EVENT_RESET => Ok(false),
|
||||
err => Err(RuntimeError::from(err).into()),
|
||||
err => Err(VulkanError::from(err).into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -175,7 +175,7 @@ impl Event {
|
||||
let fns = self.device.fns();
|
||||
(fns.v1_0.set_event)(self.device.handle(), self.handle)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@ -199,7 +199,7 @@ impl Event {
|
||||
let fns = self.device.fns();
|
||||
(fns.v1_0.reset_event)(self.device.handle(), self.handle)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@ -299,10 +299,10 @@ impl Display for EventError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RuntimeError> for EventError {
|
||||
fn from(err: RuntimeError) -> Self {
|
||||
impl From<VulkanError> for EventError {
|
||||
fn from(err: VulkanError) -> Self {
|
||||
match err {
|
||||
e @ RuntimeError::OutOfHostMemory | e @ RuntimeError::OutOfDeviceMemory => {
|
||||
e @ VulkanError::OutOfHostMemory | e @ VulkanError::OutOfDeviceMemory => {
|
||||
Self::OomError(e.into())
|
||||
}
|
||||
_ => panic!("unexpected error: {:?}", err),
|
||||
|
@ -14,8 +14,8 @@ use crate::{
|
||||
device::{physical::PhysicalDevice, Device, DeviceOwned, Queue},
|
||||
instance::InstanceOwnedDebugWrapper,
|
||||
macros::{impl_id_counter, vulkan_bitflags, vulkan_bitflags_enum},
|
||||
OomError, RequirementNotMet, Requires, RequiresAllOf, RequiresOneOf, RuntimeError,
|
||||
ValidationError, Version, VulkanObject,
|
||||
OomError, RequirementNotMet, Requires, RequiresAllOf, RequiresOneOf, ValidationError, Version,
|
||||
VulkanError, VulkanObject,
|
||||
};
|
||||
use parking_lot::{Mutex, MutexGuard};
|
||||
use smallvec::SmallVec;
|
||||
@ -132,7 +132,7 @@ impl Fence {
|
||||
pub unsafe fn new_unchecked(
|
||||
device: Arc<Device>,
|
||||
create_info: FenceCreateInfo,
|
||||
) -> Result<Fence, RuntimeError> {
|
||||
) -> Result<Fence, VulkanError> {
|
||||
let FenceCreateInfo {
|
||||
signaled,
|
||||
export_handle_types,
|
||||
@ -173,7 +173,7 @@ impl Fence {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
output.assume_init()
|
||||
};
|
||||
@ -207,7 +207,7 @@ impl Fence {
|
||||
let fns = device.fns();
|
||||
(fns.v1_0.reset_fences)(device.handle(), 1, &handle)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
}
|
||||
|
||||
Fence {
|
||||
@ -282,7 +282,7 @@ impl Fence {
|
||||
match result {
|
||||
ash::vk::Result::SUCCESS => unsafe { state.set_signaled() },
|
||||
ash::vk::Result::NOT_READY => return Ok(false),
|
||||
err => return Err(RuntimeError::from(err).into()),
|
||||
err => return Err(VulkanError::from(err).into()),
|
||||
}
|
||||
};
|
||||
|
||||
@ -332,7 +332,7 @@ impl Fence {
|
||||
match result {
|
||||
ash::vk::Result::SUCCESS => unsafe { state.set_signaled() },
|
||||
ash::vk::Result::TIMEOUT => return Err(FenceError::Timeout),
|
||||
err => return Err(RuntimeError::from(err).into()),
|
||||
err => return Err(VulkanError::from(err).into()),
|
||||
}
|
||||
};
|
||||
|
||||
@ -434,7 +434,7 @@ impl Fence {
|
||||
.filter_map(|(fence, state)| state.set_signaled().map(|state| (state, fence)))
|
||||
.collect(),
|
||||
ash::vk::Result::TIMEOUT => return Err(FenceError::Timeout),
|
||||
err => return Err(RuntimeError::from(err).into()),
|
||||
err => return Err(VulkanError::from(err).into()),
|
||||
}
|
||||
};
|
||||
|
||||
@ -469,17 +469,17 @@ impl Fence {
|
||||
|
||||
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
||||
#[inline]
|
||||
pub unsafe fn reset_unchecked(&self) -> Result<(), RuntimeError> {
|
||||
pub unsafe fn reset_unchecked(&self) -> Result<(), VulkanError> {
|
||||
let mut state = self.state.lock();
|
||||
|
||||
self.reset_unchecked_locked(&mut state)
|
||||
}
|
||||
|
||||
unsafe fn reset_unchecked_locked(&self, state: &mut FenceState) -> Result<(), RuntimeError> {
|
||||
unsafe fn reset_unchecked_locked(&self, state: &mut FenceState) -> Result<(), VulkanError> {
|
||||
let fns = self.device.fns();
|
||||
(fns.v1_0.reset_fences)(self.device.handle(), 1, &self.handle)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
state.reset();
|
||||
|
||||
@ -532,7 +532,7 @@ impl Fence {
|
||||
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
||||
pub unsafe fn multi_reset_unchecked<'a>(
|
||||
fences: impl IntoIterator<Item = &'a Fence>,
|
||||
) -> Result<(), RuntimeError> {
|
||||
) -> Result<(), VulkanError> {
|
||||
let (fences, mut states): (SmallVec<[_; 8]>, SmallVec<[_; 8]>) = fences
|
||||
.into_iter()
|
||||
.map(|fence| {
|
||||
@ -547,7 +547,7 @@ impl Fence {
|
||||
unsafe fn multi_reset_unchecked_locked(
|
||||
fences: &[&Fence],
|
||||
states: &mut [MutexGuard<'_, FenceState>],
|
||||
) -> Result<(), RuntimeError> {
|
||||
) -> Result<(), VulkanError> {
|
||||
if fences.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
@ -558,7 +558,7 @@ impl Fence {
|
||||
let fns = device.fns();
|
||||
(fns.v1_0.reset_fences)(device.handle(), fences_vk.len() as u32, fences_vk.as_ptr())
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
for state in states {
|
||||
state.reset();
|
||||
@ -654,7 +654,7 @@ impl Fence {
|
||||
pub unsafe fn export_fd_unchecked(
|
||||
&self,
|
||||
handle_type: ExternalFenceHandleType,
|
||||
) -> Result<File, RuntimeError> {
|
||||
) -> Result<File, VulkanError> {
|
||||
let mut state = self.state.lock();
|
||||
self.export_fd_unchecked_locked(handle_type, &mut state)
|
||||
}
|
||||
@ -664,7 +664,7 @@ impl Fence {
|
||||
&self,
|
||||
handle_type: ExternalFenceHandleType,
|
||||
state: &mut FenceState,
|
||||
) -> Result<File, RuntimeError> {
|
||||
) -> Result<File, VulkanError> {
|
||||
use std::os::unix::io::FromRawFd;
|
||||
|
||||
let info_vk = ash::vk::FenceGetFdInfoKHR {
|
||||
@ -681,7 +681,7 @@ impl Fence {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
state.export(handle_type);
|
||||
|
||||
@ -785,7 +785,7 @@ impl Fence {
|
||||
pub unsafe fn export_win32_handle_unchecked(
|
||||
&self,
|
||||
handle_type: ExternalFenceHandleType,
|
||||
) -> Result<*mut std::ffi::c_void, RuntimeError> {
|
||||
) -> Result<*mut std::ffi::c_void, VulkanError> {
|
||||
let mut state = self.state.lock();
|
||||
self.export_win32_handle_unchecked_locked(handle_type, &mut state)
|
||||
}
|
||||
@ -795,7 +795,7 @@ impl Fence {
|
||||
&self,
|
||||
handle_type: ExternalFenceHandleType,
|
||||
state: &mut FenceState,
|
||||
) -> Result<*mut std::ffi::c_void, RuntimeError> {
|
||||
) -> Result<*mut std::ffi::c_void, VulkanError> {
|
||||
let info_vk = ash::vk::FenceGetWin32HandleInfoKHR {
|
||||
fence: self.handle,
|
||||
handle_type: handle_type.into(),
|
||||
@ -810,7 +810,7 @@ impl Fence {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
state.export(handle_type);
|
||||
|
||||
@ -897,7 +897,7 @@ impl Fence {
|
||||
pub unsafe fn import_fd_unchecked(
|
||||
&self,
|
||||
import_fence_fd_info: ImportFenceFdInfo,
|
||||
) -> Result<(), RuntimeError> {
|
||||
) -> Result<(), VulkanError> {
|
||||
let mut state = self.state.lock();
|
||||
self.import_fd_unchecked_locked(import_fence_fd_info, &mut state)
|
||||
}
|
||||
@ -907,7 +907,7 @@ impl Fence {
|
||||
&self,
|
||||
import_fence_fd_info: ImportFenceFdInfo,
|
||||
state: &mut FenceState,
|
||||
) -> Result<(), RuntimeError> {
|
||||
) -> Result<(), VulkanError> {
|
||||
use std::os::unix::io::IntoRawFd;
|
||||
|
||||
let ImportFenceFdInfo {
|
||||
@ -928,7 +928,7 @@ impl Fence {
|
||||
let fns = self.device.fns();
|
||||
(fns.khr_external_fence_fd.import_fence_fd_khr)(self.device.handle(), &info_vk)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
state.import(handle_type, flags.intersects(FenceImportFlags::TEMPORARY));
|
||||
|
||||
@ -1015,7 +1015,7 @@ impl Fence {
|
||||
pub unsafe fn import_win32_handle_unchecked(
|
||||
&self,
|
||||
import_fence_win32_handle_info: ImportFenceWin32HandleInfo,
|
||||
) -> Result<(), RuntimeError> {
|
||||
) -> Result<(), VulkanError> {
|
||||
let mut state = self.state.lock();
|
||||
self.import_win32_handle_unchecked_locked(import_fence_win32_handle_info, &mut state)
|
||||
}
|
||||
@ -1025,7 +1025,7 @@ impl Fence {
|
||||
&self,
|
||||
import_fence_win32_handle_info: ImportFenceWin32HandleInfo,
|
||||
state: &mut FenceState,
|
||||
) -> Result<(), RuntimeError> {
|
||||
) -> Result<(), VulkanError> {
|
||||
let ImportFenceWin32HandleInfo {
|
||||
flags,
|
||||
handle_type,
|
||||
@ -1048,7 +1048,7 @@ impl Fence {
|
||||
&info_vk,
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
state.import(handle_type, flags.intersects(FenceImportFlags::TEMPORARY));
|
||||
|
||||
@ -1420,7 +1420,10 @@ impl ExternalFenceInfo {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn validate(&self, physical_device: &PhysicalDevice) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(
|
||||
&self,
|
||||
physical_device: &PhysicalDevice,
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
handle_type,
|
||||
_ne: _,
|
||||
@ -1595,13 +1598,13 @@ impl Display for FenceError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RuntimeError> for FenceError {
|
||||
fn from(err: RuntimeError) -> Self {
|
||||
impl From<VulkanError> for FenceError {
|
||||
fn from(err: VulkanError) -> Self {
|
||||
match err {
|
||||
e @ RuntimeError::OutOfHostMemory | e @ RuntimeError::OutOfDeviceMemory => {
|
||||
e @ VulkanError::OutOfHostMemory | e @ VulkanError::OutOfDeviceMemory => {
|
||||
Self::OomError(e.into())
|
||||
}
|
||||
RuntimeError::DeviceLost => Self::DeviceLost,
|
||||
VulkanError::DeviceLost => Self::DeviceLost,
|
||||
_ => panic!("unexpected error: {:?}", err),
|
||||
}
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ use crate::{
|
||||
image::{Image, ImageLayout},
|
||||
memory::BindSparseInfo,
|
||||
swapchain::{self, PresentFuture, PresentInfo, Swapchain, SwapchainPresentInfo},
|
||||
DeviceSize, OomError, RuntimeError,
|
||||
DeviceSize, OomError, VulkanError,
|
||||
};
|
||||
use smallvec::SmallVec;
|
||||
use std::{
|
||||
@ -672,16 +672,16 @@ impl From<AccessError> for FlushError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RuntimeError> for FlushError {
|
||||
fn from(err: RuntimeError) -> Self {
|
||||
impl From<VulkanError> for FlushError {
|
||||
fn from(err: VulkanError) -> Self {
|
||||
match err {
|
||||
RuntimeError::OutOfHostMemory | RuntimeError::OutOfDeviceMemory => {
|
||||
VulkanError::OutOfHostMemory | VulkanError::OutOfDeviceMemory => {
|
||||
Self::OomError(err.into())
|
||||
}
|
||||
RuntimeError::DeviceLost => Self::DeviceLost,
|
||||
RuntimeError::SurfaceLost => Self::SurfaceLost,
|
||||
RuntimeError::OutOfDate => Self::OutOfDate,
|
||||
RuntimeError::FullScreenExclusiveModeLost => Self::FullScreenExclusiveModeLost,
|
||||
VulkanError::DeviceLost => Self::DeviceLost,
|
||||
VulkanError::SurfaceLost => Self::SurfaceLost,
|
||||
VulkanError::OutOfDate => Self::OutOfDate,
|
||||
VulkanError::FullScreenExclusiveModeLost => Self::FullScreenExclusiveModeLost,
|
||||
_ => panic!("unexpected error: {:?}", err),
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ pub use self::{
|
||||
MemoryBarrier, PipelineStage, PipelineStages, QueueFamilyOwnershipTransfer,
|
||||
},
|
||||
};
|
||||
use crate::{device::Queue, RuntimeError, ValidationError};
|
||||
use crate::{device::Queue, ValidationError, VulkanError};
|
||||
use std::{
|
||||
error::Error,
|
||||
fmt::{Display, Formatter},
|
||||
@ -103,7 +103,7 @@ pub(crate) enum CurrentAccess {
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum HostAccessError {
|
||||
AccessConflict(AccessConflict),
|
||||
Invalidate(RuntimeError),
|
||||
Invalidate(VulkanError),
|
||||
ValidationError(ValidationError),
|
||||
}
|
||||
|
||||
|
@ -1862,7 +1862,7 @@ impl Default for MemoryBarrier {
|
||||
}
|
||||
|
||||
impl MemoryBarrier {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
src_stages,
|
||||
src_access,
|
||||
@ -1905,71 +1905,71 @@ impl MemoryBarrier {
|
||||
|
||||
if !device.enabled_features().synchronization2 {
|
||||
if src_stages.contains_flags2() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "src_stages".into(),
|
||||
problem: "contains flags from `VkPipelineStageFlagBits2`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"synchronization2",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if dst_stages.contains_flags2() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "dst_stages".into(),
|
||||
problem: "contains flags from `VkPipelineStageFlagBits2`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"synchronization2",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if src_access.contains_flags2() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "src_access".into(),
|
||||
problem: "contains flags from `VkAccessFlagBits2`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"synchronization2",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if dst_access.contains_flags2() {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "dst_access".into(),
|
||||
problem: "contains flags from `VkAccessFlagBits2`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"synchronization2",
|
||||
)])]),
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
if !device.enabled_features().geometry_shader {
|
||||
if src_stages.intersects(PipelineStages::GEOMETRY_SHADER) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "src_stages".into(),
|
||||
problem: "contains `PipelineStages::GEOMETRY_SHADER`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"geometry_shader",
|
||||
)])]),
|
||||
vuids: &["VUID-VkMemoryBarrier2-srcStageMask-03929"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if dst_stages.intersects(PipelineStages::GEOMETRY_SHADER) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "dst_stages".into(),
|
||||
problem: "contains `PipelineStages::GEOMETRY_SHADER`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"geometry_shader",
|
||||
)])]),
|
||||
vuids: &["VUID-VkMemoryBarrier2-dstStageMask-03929"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1978,7 +1978,7 @@ impl MemoryBarrier {
|
||||
PipelineStages::TESSELLATION_CONTROL_SHADER
|
||||
| PipelineStages::TESSELLATION_EVALUATION_SHADER,
|
||||
) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "src_stages".into(),
|
||||
problem: "contains `PipelineStages::TESSELLATION_CONTROL_SHADER` or \
|
||||
`PipelineStages::TESSELLATION_EVALUATION_SHADER`"
|
||||
@ -1987,14 +1987,14 @@ impl MemoryBarrier {
|
||||
"tessellation_shader",
|
||||
)])]),
|
||||
vuids: &["VUID-VkMemoryBarrier2-srcStageMask-03930"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if dst_stages.intersects(
|
||||
PipelineStages::TESSELLATION_CONTROL_SHADER
|
||||
| PipelineStages::TESSELLATION_EVALUATION_SHADER,
|
||||
) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "dst_stages".into(),
|
||||
problem: "contains `PipelineStages::TESSELLATION_CONTROL_SHADER` or \
|
||||
`PipelineStages::TESSELLATION_EVALUATION_SHADER`"
|
||||
@ -2003,127 +2003,127 @@ impl MemoryBarrier {
|
||||
"tessellation_shader",
|
||||
)])]),
|
||||
vuids: &["VUID-VkMemoryBarrier2-dstStageMask-03930"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
if !device.enabled_features().conditional_rendering {
|
||||
if src_stages.intersects(PipelineStages::CONDITIONAL_RENDERING) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "src_stages".into(),
|
||||
problem: "contains `PipelineStages::CONDITIONAL_RENDERING`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"conditional_rendering",
|
||||
)])]),
|
||||
vuids: &["VUID-VkMemoryBarrier2-srcStageMask-03931"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if dst_stages.intersects(PipelineStages::CONDITIONAL_RENDERING) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "dst_stages".into(),
|
||||
problem: "contains `PipelineStages::CONDITIONAL_RENDERING`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"conditional_rendering",
|
||||
)])]),
|
||||
vuids: &["VUID-VkMemoryBarrier2-dstStageMask-03931"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
if !device.enabled_features().fragment_density_map {
|
||||
if src_stages.intersects(PipelineStages::FRAGMENT_DENSITY_PROCESS) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "src_stages".into(),
|
||||
problem: "contains `PipelineStages::FRAGMENT_DENSITY_PROCESS`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"fragment_density_map",
|
||||
)])]),
|
||||
vuids: &["VUID-VkMemoryBarrier2-srcStageMask-03932"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if dst_stages.intersects(PipelineStages::FRAGMENT_DENSITY_PROCESS) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "dst_stages".into(),
|
||||
problem: "contains `PipelineStages::FRAGMENT_DENSITY_PROCESS`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"fragment_density_map",
|
||||
)])]),
|
||||
vuids: &["VUID-VkMemoryBarrier2-dstStageMask-03932"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
if !device.enabled_features().transform_feedback {
|
||||
if src_stages.intersects(PipelineStages::TRANSFORM_FEEDBACK) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "src_stages".into(),
|
||||
problem: "contains `PipelineStages::TRANSFORM_FEEDBACK`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"transform_feedback",
|
||||
)])]),
|
||||
vuids: &["VUID-VkMemoryBarrier2-srcStageMask-03933"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if dst_stages.intersects(PipelineStages::TRANSFORM_FEEDBACK) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "dst_stages".into(),
|
||||
problem: "contains `PipelineStages::TRANSFORM_FEEDBACK`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"transform_feedback",
|
||||
)])]),
|
||||
vuids: &["VUID-VkMemoryBarrier2-dstStageMask-03933"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
if !device.enabled_features().mesh_shader {
|
||||
if src_stages.intersects(PipelineStages::MESH_SHADER) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "src_stages".into(),
|
||||
problem: "contains `PipelineStages::MESH_SHADER`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"mesh_shader",
|
||||
)])]),
|
||||
vuids: &["VUID-VkMemoryBarrier2-srcStageMask-03934"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if dst_stages.intersects(PipelineStages::MESH_SHADER) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "dst_stages".into(),
|
||||
problem: "contains `PipelineStages::MESH_SHADER`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"mesh_shader",
|
||||
)])]),
|
||||
vuids: &["VUID-VkMemoryBarrier2-dstStageMask-03934"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
if !device.enabled_features().task_shader {
|
||||
if src_stages.intersects(PipelineStages::TASK_SHADER) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "src_stages".into(),
|
||||
problem: "contains `PipelineStages::TASK_SHADER`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"task_shader",
|
||||
)])]),
|
||||
vuids: &["VUID-VkMemoryBarrier2-srcStageMask-03935"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if dst_stages.intersects(PipelineStages::TASK_SHADER) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "dst_stages".into(),
|
||||
problem: "contains `PipelineStages::TASK_SHADER`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"task_shader",
|
||||
)])]),
|
||||
vuids: &["VUID-VkMemoryBarrier2-dstStageMask-03935"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2131,7 +2131,7 @@ impl MemoryBarrier {
|
||||
|| device.enabled_features().shading_rate_image)
|
||||
{
|
||||
if src_stages.intersects(PipelineStages::FRAGMENT_SHADING_RATE_ATTACHMENT) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "src_stages".into(),
|
||||
problem: "contains `PipelineStages::FRAGMENT_SHADING_RATE_ATTACHMENT`".into(),
|
||||
requires_one_of: RequiresOneOf(&[
|
||||
@ -2139,11 +2139,11 @@ impl MemoryBarrier {
|
||||
RequiresAllOf(&[Requires::Feature("shading_rate_image")]),
|
||||
]),
|
||||
vuids: &["VUID-VkMemoryBarrier2-shadingRateImage-07316"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if dst_stages.intersects(PipelineStages::FRAGMENT_SHADING_RATE_ATTACHMENT) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "dst_stages".into(),
|
||||
problem: "contains `PipelineStages::FRAGMENT_SHADING_RATE_ATTACHMENT`".into(),
|
||||
requires_one_of: RequiresOneOf(&[
|
||||
@ -2151,55 +2151,55 @@ impl MemoryBarrier {
|
||||
RequiresAllOf(&[Requires::Feature("shading_rate_image")]),
|
||||
]),
|
||||
vuids: &["VUID-VkMemoryBarrier2-shadingRateImage-07316"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
if !device.enabled_features().subpass_shading {
|
||||
if src_stages.intersects(PipelineStages::SUBPASS_SHADING) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "src_stages".into(),
|
||||
problem: "contains `PipelineStages::SUBPASS_SHADING`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"subpass_shading",
|
||||
)])]),
|
||||
vuids: &["VUID-VkMemoryBarrier2-srcStageMask-04957"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if dst_stages.intersects(PipelineStages::SUBPASS_SHADING) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "dst_stages".into(),
|
||||
problem: "contains `PipelineStages::SUBPASS_SHADING`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"subpass_shading",
|
||||
)])]),
|
||||
vuids: &["VUID-VkMemoryBarrier2-dstStageMask-04957"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
if !device.enabled_features().invocation_mask {
|
||||
if src_stages.intersects(PipelineStages::INVOCATION_MASK) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "src_stages".into(),
|
||||
problem: "contains `PipelineStages::INVOCATION_MASK`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"invocation_mask",
|
||||
)])]),
|
||||
vuids: &["VUID-VkMemoryBarrier2-srcStageMask-04995"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if dst_stages.intersects(PipelineStages::INVOCATION_MASK) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "dst_stages".into(),
|
||||
problem: "contains `PipelineStages::INVOCATION_MASK`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"invocation_mask",
|
||||
)])]),
|
||||
vuids: &["VUID-VkMemoryBarrier2-dstStageMask-04995"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2207,30 +2207,30 @@ impl MemoryBarrier {
|
||||
|| device.enabled_features().ray_tracing_pipeline)
|
||||
{
|
||||
if src_stages.intersects(PipelineStages::RAY_TRACING_SHADER) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "src_stages".into(),
|
||||
problem: "contains `PipelineStages::RAY_TRACING_SHADER`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"ray_tracing_pipeline",
|
||||
)])]),
|
||||
vuids: &["VUID-VkMemoryBarrier2-srcStageMask-07946"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if dst_stages.intersects(PipelineStages::RAY_TRACING_SHADER) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "dst_stages".into(),
|
||||
problem: "contains `PipelineStages::RAY_TRACING_SHADER`".into(),
|
||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
|
||||
"ray_tracing_pipeline",
|
||||
)])]),
|
||||
vuids: &["VUID-VkMemoryBarrier2-dstStageMask-07946"],
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
if !AccessFlags::from(src_stages).contains(src_access) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`src_access` contains one or more access types that are not performed \
|
||||
by any stage in `src_stages`"
|
||||
.into(),
|
||||
@ -2278,11 +2278,11 @@ impl MemoryBarrier {
|
||||
"VUID-VkMemoryBarrier2-srcAccessMask-08118",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if !AccessFlags::from(dst_stages).contains(dst_access) {
|
||||
return Err(ValidationError {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`dst_access` contains one or more access types that are not performed \
|
||||
by any stage in `dst_stages`"
|
||||
.into(),
|
||||
@ -2330,7 +2330,7 @@ impl MemoryBarrier {
|
||||
"VUID-VkMemoryBarrier2-dstAccessMask-08118",
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -14,8 +14,8 @@ use crate::{
|
||||
device::{physical::PhysicalDevice, Device, DeviceOwned, Queue},
|
||||
instance::InstanceOwnedDebugWrapper,
|
||||
macros::{impl_id_counter, vulkan_bitflags, vulkan_bitflags_enum},
|
||||
OomError, RequirementNotMet, Requires, RequiresAllOf, RequiresOneOf, RuntimeError,
|
||||
ValidationError, Version, VulkanObject,
|
||||
OomError, RequirementNotMet, Requires, RequiresAllOf, RequiresOneOf, ValidationError, Version,
|
||||
VulkanError, VulkanObject,
|
||||
};
|
||||
use parking_lot::{Mutex, MutexGuard};
|
||||
#[cfg(unix)]
|
||||
@ -113,7 +113,7 @@ impl Semaphore {
|
||||
pub unsafe fn new_unchecked(
|
||||
device: Arc<Device>,
|
||||
create_info: SemaphoreCreateInfo,
|
||||
) -> Result<Semaphore, RuntimeError> {
|
||||
) -> Result<Semaphore, VulkanError> {
|
||||
let SemaphoreCreateInfo {
|
||||
export_handle_types,
|
||||
_ne: _,
|
||||
@ -147,7 +147,7 @@ impl Semaphore {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
output.assume_init()
|
||||
};
|
||||
|
||||
@ -310,7 +310,7 @@ impl Semaphore {
|
||||
pub unsafe fn export_fd_unchecked(
|
||||
&self,
|
||||
handle_type: ExternalSemaphoreHandleType,
|
||||
) -> Result<File, RuntimeError> {
|
||||
) -> Result<File, VulkanError> {
|
||||
let mut state = self.state.lock();
|
||||
self.export_fd_unchecked_locked(handle_type, &mut state)
|
||||
}
|
||||
@ -320,7 +320,7 @@ impl Semaphore {
|
||||
&self,
|
||||
handle_type: ExternalSemaphoreHandleType,
|
||||
state: &mut SemaphoreState,
|
||||
) -> Result<File, RuntimeError> {
|
||||
) -> Result<File, VulkanError> {
|
||||
use std::os::unix::io::FromRawFd;
|
||||
|
||||
let info = ash::vk::SemaphoreGetFdInfoKHR {
|
||||
@ -337,7 +337,7 @@ impl Semaphore {
|
||||
output.as_mut_ptr(),
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
state.export(handle_type);
|
||||
|
||||
@ -454,7 +454,7 @@ impl Semaphore {
|
||||
pub unsafe fn export_win32_handle_unchecked(
|
||||
&self,
|
||||
handle_type: ExternalSemaphoreHandleType,
|
||||
) -> Result<*mut std::ffi::c_void, RuntimeError> {
|
||||
) -> Result<*mut std::ffi::c_void, VulkanError> {
|
||||
let mut state = self.state.lock();
|
||||
self.export_win32_handle_unchecked_locked(handle_type, &mut state)
|
||||
}
|
||||
@ -464,7 +464,7 @@ impl Semaphore {
|
||||
&self,
|
||||
handle_type: ExternalSemaphoreHandleType,
|
||||
state: &mut SemaphoreState,
|
||||
) -> Result<*mut std::ffi::c_void, RuntimeError> {
|
||||
) -> Result<*mut std::ffi::c_void, VulkanError> {
|
||||
let info_vk = ash::vk::SemaphoreGetWin32HandleInfoKHR {
|
||||
semaphore: self.handle,
|
||||
handle_type: handle_type.into(),
|
||||
@ -478,7 +478,7 @@ impl Semaphore {
|
||||
self.device.handle(), &info_vk, output.as_mut_ptr()
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
state.export(handle_type);
|
||||
|
||||
@ -574,7 +574,7 @@ impl Semaphore {
|
||||
pub unsafe fn export_zircon_handle_unchecked(
|
||||
&self,
|
||||
handle_type: ExternalSemaphoreHandleType,
|
||||
) -> Result<ash::vk::zx_handle_t, RuntimeError> {
|
||||
) -> Result<ash::vk::zx_handle_t, VulkanError> {
|
||||
let mut state = self.state.lock();
|
||||
self.export_zircon_handle_unchecked_locked(handle_type, &mut state)
|
||||
}
|
||||
@ -584,7 +584,7 @@ impl Semaphore {
|
||||
&self,
|
||||
handle_type: ExternalSemaphoreHandleType,
|
||||
state: &mut SemaphoreState,
|
||||
) -> Result<ash::vk::zx_handle_t, RuntimeError> {
|
||||
) -> Result<ash::vk::zx_handle_t, VulkanError> {
|
||||
let info = ash::vk::SemaphoreGetZirconHandleInfoFUCHSIA {
|
||||
semaphore: self.handle,
|
||||
handle_type: handle_type.into(),
|
||||
@ -598,7 +598,7 @@ impl Semaphore {
|
||||
self.device.handle(), &info, output.as_mut_ptr()
|
||||
)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
state.export(handle_type);
|
||||
|
||||
@ -688,7 +688,7 @@ impl Semaphore {
|
||||
pub unsafe fn import_fd_unchecked(
|
||||
&self,
|
||||
import_semaphore_fd_info: ImportSemaphoreFdInfo,
|
||||
) -> Result<(), RuntimeError> {
|
||||
) -> Result<(), VulkanError> {
|
||||
let mut state = self.state.lock();
|
||||
self.import_fd_unchecked_locked(import_semaphore_fd_info, &mut state)
|
||||
}
|
||||
@ -698,7 +698,7 @@ impl Semaphore {
|
||||
&self,
|
||||
import_semaphore_fd_info: ImportSemaphoreFdInfo,
|
||||
state: &mut SemaphoreState,
|
||||
) -> Result<(), RuntimeError> {
|
||||
) -> Result<(), VulkanError> {
|
||||
use std::os::unix::io::IntoRawFd;
|
||||
|
||||
let ImportSemaphoreFdInfo {
|
||||
@ -719,7 +719,7 @@ impl Semaphore {
|
||||
let fns = self.device.fns();
|
||||
(fns.khr_external_semaphore_fd.import_semaphore_fd_khr)(self.device.handle(), &info_vk)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
state.import(
|
||||
handle_type,
|
||||
@ -817,7 +817,7 @@ impl Semaphore {
|
||||
pub unsafe fn import_win32_handle_unchecked(
|
||||
&self,
|
||||
import_semaphore_win32_handle_info: ImportSemaphoreWin32HandleInfo,
|
||||
) -> Result<(), RuntimeError> {
|
||||
) -> Result<(), VulkanError> {
|
||||
let mut state = self.state.lock();
|
||||
self.import_win32_handle_unchecked_locked(import_semaphore_win32_handle_info, &mut state)
|
||||
}
|
||||
@ -827,7 +827,7 @@ impl Semaphore {
|
||||
&self,
|
||||
import_semaphore_win32_handle_info: ImportSemaphoreWin32HandleInfo,
|
||||
state: &mut SemaphoreState,
|
||||
) -> Result<(), RuntimeError> {
|
||||
) -> Result<(), VulkanError> {
|
||||
let ImportSemaphoreWin32HandleInfo {
|
||||
flags,
|
||||
handle_type,
|
||||
@ -848,7 +848,7 @@ impl Semaphore {
|
||||
(fns.khr_external_semaphore_win32
|
||||
.import_semaphore_win32_handle_khr)(self.device.handle(), &info_vk)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
state.import(
|
||||
handle_type,
|
||||
@ -938,7 +938,7 @@ impl Semaphore {
|
||||
pub unsafe fn import_zircon_handle_unchecked(
|
||||
&self,
|
||||
import_semaphore_zircon_handle_info: ImportSemaphoreZirconHandleInfo,
|
||||
) -> Result<(), RuntimeError> {
|
||||
) -> Result<(), VulkanError> {
|
||||
let mut state = self.state.lock();
|
||||
self.import_zircon_handle_unchecked_locked(import_semaphore_zircon_handle_info, &mut state)
|
||||
}
|
||||
@ -948,7 +948,7 @@ impl Semaphore {
|
||||
&self,
|
||||
import_semaphore_zircon_handle_info: ImportSemaphoreZirconHandleInfo,
|
||||
state: &mut SemaphoreState,
|
||||
) -> Result<(), RuntimeError> {
|
||||
) -> Result<(), VulkanError> {
|
||||
let ImportSemaphoreZirconHandleInfo {
|
||||
flags,
|
||||
handle_type,
|
||||
@ -968,7 +968,7 @@ impl Semaphore {
|
||||
(fns.fuchsia_external_semaphore
|
||||
.import_semaphore_zircon_handle_fuchsia)(self.device.handle(), &info_vk)
|
||||
.result()
|
||||
.map_err(RuntimeError::from)?;
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
state.import(
|
||||
handle_type,
|
||||
@ -1378,7 +1378,10 @@ impl ExternalSemaphoreInfo {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn validate(&self, physical_device: &PhysicalDevice) -> Result<(), ValidationError> {
|
||||
pub(crate) fn validate(
|
||||
&self,
|
||||
physical_device: &PhysicalDevice,
|
||||
) -> Result<(), Box<ValidationError>> {
|
||||
let &Self {
|
||||
handle_type,
|
||||
_ne: _,
|
||||
@ -1556,10 +1559,10 @@ impl Display for SemaphoreError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RuntimeError> for SemaphoreError {
|
||||
fn from(err: RuntimeError) -> Self {
|
||||
impl From<VulkanError> for SemaphoreError {
|
||||
fn from(err: VulkanError) -> Self {
|
||||
match err {
|
||||
e @ RuntimeError::OutOfHostMemory | e @ RuntimeError::OutOfDeviceMemory => {
|
||||
e @ VulkanError::OutOfHostMemory | e @ VulkanError::OutOfDeviceMemory => {
|
||||
Self::OomError(e.into())
|
||||
}
|
||||
_ => panic!("unexpected error: {:?}", err),
|
||||
|
Loading…
Reference in New Issue
Block a user