This commit is contained in:
marc0246 2022-10-04 10:50:58 +02:00 committed by GitHub
parent 7e3515e6eb
commit b8d7cc3241
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
102 changed files with 2176 additions and 2435 deletions

View File

@ -290,14 +290,12 @@ pub enum Error {
}
impl From<IoError> for Error {
#[inline]
fn from(err: IoError) -> Error {
Error::IoError(err)
}
}
impl From<SpirvError> for Error {
#[inline]
fn from(err: SpirvError) -> Error {
Error::SpirvError(err)
}

View File

@ -46,6 +46,7 @@ pub struct VulkanoConfig {
}
impl Default for VulkanoConfig {
#[inline]
fn default() -> Self {
let device_extensions = DeviceExtensions {
khr_swapchain: true,
@ -88,7 +89,7 @@ impl Default for VulkanoConfig {
/// in the creation of [`VulkanoWindowRenderer`](crate::renderer::VulkanoWindowRenderer) through
/// [`VulkanoWindows`](crate::window::VulkanoWindows).
///
/// ## Example
/// ## Examples
///
/// ```no_run
/// use vulkano_util::context::{VulkanoConfig, VulkanoContext};
@ -107,6 +108,7 @@ pub struct VulkanoContext {
}
impl Default for VulkanoContext {
#[inline]
fn default() -> Self {
VulkanoContext::new(VulkanoConfig::default())
}
@ -245,16 +247,19 @@ impl VulkanoContext {
}
/// Returns the name of the device.
#[inline]
pub fn device_name(&self) -> &str {
&self.device.physical_device().properties().device_name
}
/// Returns the type of the device.
#[inline]
pub fn device_type(&self) -> PhysicalDeviceType {
self.device.physical_device().properties().device_type
}
/// Returns the maximum memory allocation of the device.
#[inline]
pub fn max_memory(&self) -> u32 {
self.device
.physical_device()
@ -263,16 +268,19 @@ impl VulkanoContext {
}
/// Returns the instance.
#[inline]
pub fn instance(&self) -> &Arc<Instance> {
&self.instance
}
/// Returns the device.
#[inline]
pub fn device(&self) -> &Arc<Device> {
&self.device
}
/// Returns the graphics queue.
#[inline]
pub fn graphics_queue(&self) -> &Arc<Queue> {
&self.graphics_queue
}
@ -280,6 +288,7 @@ impl VulkanoContext {
/// Returns the compute queue.
///
/// Depending on your device, this might be the same as graphics queue.
#[inline]
pub fn compute_queue(&self) -> &Arc<Queue> {
&self.compute_queue
}

View File

@ -33,11 +33,11 @@ pub type DeviceImageView = Arc<ImageView<StorageImage>>;
/// Most common image format
pub const DEFAULT_IMAGE_FORMAT: Format = Format::R8G8B8A8_UNORM;
/// A window renderer struct holding the winit window surface and functionality for organizing your render
/// between frames.
/// A window renderer struct holding the winit window surface and functionality for organizing your
/// render between frames.
///
/// Begin rendering with [`VulkanoWindowRenderer::acquire`] and finish with [`VulkanoWindowRenderer::present`].
/// Between those, you should execute your command buffers.
/// Begin rendering with [`VulkanoWindowRenderer::acquire`] and finish with
/// [`VulkanoWindowRenderer::present`]. Between those, you should execute your command buffers.
///
/// The intended usage of this struct is through [`crate::window::VulkanoWindows`].
pub struct VulkanoWindowRenderer {
@ -56,8 +56,9 @@ pub struct VulkanoWindowRenderer {
}
impl VulkanoWindowRenderer {
/// Creates a new [`VulkanoWindowRenderer`] which is used to orchestrate your rendering with Vulkano.
/// Pass [`WindowDescriptor`] and optionally a function modifying the [`SwapchainCreateInfo`](vulkano::swapchain::SwapchainCreateInfo) parameters.
/// Creates a new [`VulkanoWindowRenderer`] which is used to orchestrate your rendering with
/// Vulkano. Pass [`WindowDescriptor`] and optionally a function modifying the
/// [`SwapchainCreateInfo`](vulkano::swapchain::SwapchainCreateInfo) parameters.
pub fn new(
vulkano_context: &VulkanoContext,
window: winit::window::Window,
@ -142,6 +143,7 @@ impl VulkanoWindowRenderer {
}
/// Set window renderer present mode. This triggers a swapchain recreation.
#[inline]
pub fn set_present_mode(&mut self, present_mode: vulkano::swapchain::PresentMode) {
if self.present_mode != present_mode {
self.present_mode = present_mode;
@ -149,55 +151,65 @@ impl VulkanoWindowRenderer {
}
}
/// Return swapchain image format
/// Return swapchain image format.
#[inline]
pub fn swapchain_format(&self) -> Format {
self.final_views[self.image_index as usize]
.format()
.unwrap()
}
/// Returns the index of last swapchain image that is the next render target
/// Returns the index of last swapchain image that is the next render target.
#[inline]
pub fn image_index(&self) -> u32 {
self.image_index
}
/// Graphics queue of this window. You also can access this through [`VulkanoContext`]
/// Graphics queue of this window. You also can access this through [`VulkanoContext`].
#[inline]
pub fn graphics_queue(&self) -> Arc<Queue> {
self.graphics_queue.clone()
}
/// Compute queue of this window. You can also access this through [`VulkanoContext`]
/// Compute queue of this window. You can also access this through [`VulkanoContext`].
#[inline]
pub fn compute_queue(&self) -> Arc<Queue> {
self.compute_queue.clone()
}
/// Render target surface
/// Render target surface.
#[inline]
pub fn surface(&self) -> Arc<Surface<Window>> {
self.surface.clone()
}
/// Winit window (you can manipulate window through this).
#[inline]
pub fn window(&self) -> &Window {
self.surface.window()
}
/// Size of the physical window
/// Size of the physical window.
#[inline]
pub fn window_size(&self) -> [f32; 2] {
let size = self.window().inner_size();
[size.width as f32, size.height as f32]
}
/// Size of the final swapchain image (surface)
/// Size of the final swapchain image (surface).
#[inline]
pub fn swapchain_image_size(&self) -> [u32; 2] {
self.final_views[0].image().dimensions().width_height()
}
/// Return the current swapchain image view
/// Return the current swapchain image view.
#[inline]
pub fn swapchain_image_view(&self) -> SwapchainImageView {
self.final_views[self.image_index as usize].clone()
}
/// Return scale factor accounted window size
/// Return scale factor accounted window size.
#[inline]
pub fn resolution(&self) -> [f32; 2] {
let size = self.window().inner_size();
let scale_factor = self.window().scale_factor();
@ -207,17 +219,21 @@ impl VulkanoWindowRenderer {
]
}
#[inline]
pub fn aspect_ratio(&self) -> f32 {
let dims = self.window_size();
dims[0] / dims[1]
}
/// Resize swapchain and camera view images at the beginning of next frame based on window dimensions
/// Resize swapchain and camera view images at the beginning of next frame based on window
/// dimensions.
#[inline]
pub fn resize(&mut self) {
self.recreate_swapchain = true;
}
/// Add interim image view that resizes with window
/// Add interim image view that resizes with window.
#[inline]
pub fn add_additional_image_view(&mut self, key: usize, format: Format, usage: ImageUsage) {
let size = self.swapchain_image_size();
let image = StorageImage::general_purpose_image_view(
@ -230,20 +246,24 @@ impl VulkanoWindowRenderer {
self.additional_image_views.insert(key, image);
}
/// Get additional image view by key
/// Get additional image view by key.
#[inline]
pub fn get_additional_image_view(&mut self, key: usize) -> DeviceImageView {
self.additional_image_views.get(&key).unwrap().clone()
}
/// Remove additional image by key
/// Remove additional image by key.
#[inline]
pub fn remove_additional_image_view(&mut self, key: usize) {
self.additional_image_views.remove(&key);
}
/// Begin your rendering by calling `acquire`.
/// Returns a [`GpuFuture`](vulkano::sync::GpuFuture) representing the time after which the swapchain image has been acquired
/// and previous frame ended.
/// Execute your command buffers after calling this function and finish rendering by calling [`VulkanoWindowRenderer::present`].
/// Returns a [`GpuFuture`](vulkano::sync::GpuFuture) representing the time after which the
/// swapchain image has been acquired and previous frame ended.
/// Execute your command buffers after calling this function and finish rendering by calling
/// [`VulkanoWindowRenderer::present`].
#[inline]
pub fn acquire(&mut self) -> std::result::Result<Box<dyn GpuFuture>, AcquireError> {
// Recreate swap chain if needed (when resizing of window occurs or swapchain is outdated)
// Also resize render views if needed
@ -272,10 +292,13 @@ impl VulkanoWindowRenderer {
Ok(future.boxed())
}
/// Finishes rendering by presenting the swapchain. Pass your last future as an input to this function.
/// Finishes rendering by presenting the swapchain. Pass your last future as an input to this
/// function.
///
/// Depending on your implementation, you may want to wait on your future. For example, a compute shader
/// dispatch using an image that's being later drawn should probably be waited on.
/// Depending on your implementation, you may want to wait on your future. For example, a
/// compute shader dispatch using an image that's being later drawn should probably be waited
/// on.
#[inline]
pub fn present(&mut self, after_future: Box<dyn GpuFuture>, wait_future: bool) {
let future = after_future
.then_swapchain_present(
@ -313,7 +336,7 @@ impl VulkanoWindowRenderer {
}
}
/// Recreates swapchain images and image views which follow the window size
/// Recreates swapchain images and image views which follow the window size.
fn recreate_swapchain_and_views(&mut self) {
let dimensions: [u32; 2] = self.window().inner_size().into();
let (new_swapchain, new_images) = match self.swapchain.recreate(SwapchainCreateInfo {

View File

@ -20,22 +20,25 @@ use winit::{
window::{CursorGrabMode, WindowId},
};
/// A struct organizing windows and their corresponding renderers. This makes it easy to handle multiple windows.
/// A struct organizing windows and their corresponding renderers. This makes it easy to handle
/// multiple windows.
///
/// ## Example
///```
/// ## Examples
///
/// ```
/// use vulkano_util::context::{VulkanoConfig, VulkanoContext};
/// use winit::event_loop::EventLoop;
/// use vulkano_util::window::VulkanoWindows;
///
/// #[test]
/// fn test() {
/// let context = VulkanoContext::new(VulkanoConfig::default());
/// let event_loop = EventLoop::new();
/// let mut vulkano_windows = VulkanoWindows::default();
/// let _id1 = vulkano_windows.create_window(&event_loop, &context, &Default::default(), |_| {});
/// let _id2 = vulkano_windows.create_window(&event_loop, &context, &Default::default(), |_| {});
/// // You should now have two windows
/// let context = VulkanoContext::new(VulkanoConfig::default());
/// let event_loop = EventLoop::new();
/// let mut vulkano_windows = VulkanoWindows::default();
/// let _id1 = vulkano_windows.create_window(&event_loop, &context, &Default::default(), |_| {});
/// let _id2 = vulkano_windows.create_window(&event_loop, &context, &Default::default(), |_| {});
///
/// // You should now have two windows.
/// }
/// ```
#[derive(Default)]
@ -45,8 +48,8 @@ pub struct VulkanoWindows {
}
impl VulkanoWindows {
/// Creates a winit window with [`VulkanoWindowRenderer`] based on the given [`WindowDescriptor`]
/// input and swapchain creation modifications
/// Creates a winit window with [`VulkanoWindowRenderer`] based on the given
/// [`WindowDescriptor`] input and swapchain creation modifications.
pub fn create_window(
&mut self,
event_loop: &winit::event_loop::EventLoopWindowTarget<()>,
@ -171,7 +174,8 @@ impl VulkanoWindows {
id
}
/// Get a mutable reference to the primary window's renderer
/// Get a mutable reference to the primary window's renderer.
#[inline]
pub fn get_primary_renderer_mut(&mut self) -> Option<&mut VulkanoWindowRenderer> {
if self.primary.is_some() {
self.get_renderer_mut(self.primary.unwrap())
@ -180,7 +184,8 @@ impl VulkanoWindows {
}
}
/// Get a reference to the primary window's renderer
/// Get a reference to the primary window's renderer.
#[inline]
pub fn get_primary_renderer(&self) -> Option<&VulkanoWindowRenderer> {
if self.primary.is_some() {
self.get_renderer(self.primary.unwrap())
@ -189,7 +194,8 @@ impl VulkanoWindows {
}
}
/// Get a reference to the primary winit window
/// Get a reference to the primary winit window.
#[inline]
pub fn get_primary_window(&self) -> Option<&winit::window::Window> {
if self.primary.is_some() {
self.get_window(self.primary.unwrap())
@ -198,7 +204,8 @@ impl VulkanoWindows {
}
}
/// Get a mutable reference to the renderer by winit window id
/// Get a mutable reference to the renderer by winit window id.
#[inline]
pub fn get_renderer_mut(
&mut self,
id: winit::window::WindowId,
@ -206,22 +213,26 @@ impl VulkanoWindows {
self.windows.get_mut(&id)
}
/// Get a reference to the renderer by winit window id
/// Get a reference to the renderer by winit window id.
#[inline]
pub fn get_renderer(&self, id: winit::window::WindowId) -> Option<&VulkanoWindowRenderer> {
self.windows.get(&id)
}
/// Get a reference to the winit window by winit window id
/// Get a reference to the winit window by winit window id.
#[inline]
pub fn get_window(&self, id: winit::window::WindowId) -> Option<&winit::window::Window> {
self.windows.get(&id).map(|v_window| v_window.window())
}
/// Return primary window id
/// Return primary window id.
#[inline]
pub fn primary_window_id(&self) -> Option<winit::window::WindowId> {
self.primary
}
/// Remove renderer by window id
/// Remove renderer by window id.
#[inline]
pub fn remove_renderer(&mut self, id: winit::window::WindowId) {
self.windows.remove(&id);
if let Some(primary) = self.primary {
@ -231,12 +242,14 @@ impl VulkanoWindows {
}
}
/// Return iterator over window renderers
/// Return iterator over window renderers.
#[inline]
pub fn iter(&self) -> Iter<'_, WindowId, VulkanoWindowRenderer> {
self.windows.iter()
}
/// Return iterator over mutable window renderers
/// Return iterator over mutable window renderers.
#[inline]
pub fn iter_mut(&mut self) -> IterMut<'_, WindowId, VulkanoWindowRenderer> {
self.windows.iter_mut()
}
@ -301,7 +314,8 @@ pub enum WindowMode {
BorderlessFullscreen,
/// Creates a fullscreen window that will render at desktop resolution.
///
/// The app will use the closest supported size from the given size and scale it to fit the screen.
/// The app will use the closest supported size from the given size and scale it to fit the
/// screen.
SizedFullscreen,
/// Creates a fullscreen window that uses the maximum supported size.
Fullscreen,
@ -328,7 +342,8 @@ pub struct WindowDescriptor {
///
/// If there are some scaling problems on X11 try to set this option to `Some(1.0)`.
pub scale_factor_override: Option<f64>,
/// Sets the title that displays on the window top bar, on the system task bar and other OS specific places.
/// Sets the title that displays on the window top bar, on the system task bar and other OS
/// specific places.
pub title: String,
/// The window's [`PresentMode`].
///
@ -349,6 +364,7 @@ pub struct WindowDescriptor {
}
impl Default for WindowDescriptor {
#[inline]
fn default() -> Self {
WindowDescriptor {
title: "Vulkano App".to_string(),
@ -384,6 +400,7 @@ pub struct WindowResizeConstraints {
}
impl Default for WindowResizeConstraints {
#[inline]
fn default() -> Self {
Self {
min_width: 180.,

View File

@ -36,7 +36,6 @@ pub fn required_extensions(library: &VulkanLibrary) -> InstanceExtensions {
/// Create a surface from a Winit window or a reference to it. The surface takes `W` to prevent it
/// from being dropped before the surface.
#[inline]
pub fn create_surface_from_winit<W>(
window: W,
instance: Arc<Instance>,
@ -56,13 +55,13 @@ pub trait VkSurfaceBuild<E> {
}
impl<E> VkSurfaceBuild<E> for WindowBuilder {
#[inline]
fn build_vk_surface(
self,
event_loop: &EventLoopWindowTarget<E>,
instance: Arc<Instance>,
) -> Result<Arc<Surface<Window>>, CreationError> {
let window = self.build(event_loop)?;
Ok(create_surface_from_winit(window, instance)?)
}
}
@ -77,22 +76,20 @@ pub enum CreationError {
}
impl Error for CreationError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match *self {
CreationError::SurfaceCreationError(ref err) => Some(err),
CreationError::WindowCreationError(ref err) => Some(err),
match self {
CreationError::SurfaceCreationError(err) => Some(err),
CreationError::WindowCreationError(err) => Some(err),
}
}
}
impl Display for CreationError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
write!(
f,
"{}",
match *self {
match self {
CreationError::SurfaceCreationError(_) => "error while creating the surface",
CreationError::WindowCreationError(_) => "error while creating the window",
}
@ -101,21 +98,18 @@ impl Display for CreationError {
}
impl From<SurfaceCreationError> for CreationError {
#[inline]
fn from(err: SurfaceCreationError) -> CreationError {
CreationError::SurfaceCreationError(err)
}
}
impl From<WindowCreationError> for CreationError {
#[inline]
fn from(err: WindowCreationError) -> CreationError {
CreationError::WindowCreationError(err)
}
}
#[cfg(target_os = "android")]
#[inline]
unsafe fn winit_to_surface<W: SafeBorrow<Window>>(
instance: Arc<Instance>,
win: W,
@ -243,7 +237,6 @@ unsafe fn winit_to_surface<W: SafeBorrow<Window>>(
}
#[cfg(target_os = "windows")]
#[inline]
unsafe fn winit_to_surface<W: SafeBorrow<Window>>(
instance: Arc<Instance>,
win: W,

View File

@ -287,20 +287,20 @@ fn features_output(members: &[FeaturesMember]) -> TokenStream {
/// Note that the `robust_buffer_access` is guaranteed to be supported by all Vulkan
/// implementations.
///
/// # Example
/// # Examples
///
/// ```
/// use vulkano::device::Features;
/// # let physical_device: vulkano::device::physical::PhysicalDevice = return;
/// let minimal_features = Features {
/// geometry_shader: true,
/// .. Features::empty()
/// ..Features::empty()
/// };
///
/// let optimal_features = vulkano::device::Features {
/// geometry_shader: true,
/// tessellation_shader: true,
/// .. Features::empty()
/// ..Features::empty()
/// };
///
/// if !physical_device.supported_features().is_superset_of(&minimal_features) {
@ -310,7 +310,6 @@ fn features_output(members: &[FeaturesMember]) -> TokenStream {
/// assert!(optimal_features.is_superset_of(&minimal_features));
/// let features_to_request = optimal_features.intersection(physical_device.supported_features());
/// ```
///
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub struct Features {
#(#struct_items)*
@ -325,7 +324,8 @@ fn features_output(members: &[FeaturesMember]) -> TokenStream {
}
impl Features {
/// Checks enabled features against the device version, device extensions and each other.
/// Checks enabled features against the device version, device extensions and each
/// other.
pub(super) fn check_requirements(
&self,
supported: &Features,

View File

@ -573,7 +573,7 @@ fn formats_output(members: &[FormatMember]) -> TokenStream {
///
/// Note: for 16-bit floating point values, you need to import the [`half::f16`] type.
///
/// # Example
/// # Examples
///
/// ```
/// # #[macro_use] extern crate vulkano;

View File

@ -384,7 +384,7 @@ fn bit_enum_output(enums: &[(Ident, Vec<KindEnumMember>)]) -> TokenStream {
);
quote! {
#[derive(Clone, Debug, PartialEq, Eq)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[allow(non_camel_case_types)]
pub struct #name {
#(#members_items)*
@ -524,7 +524,8 @@ fn value_enum_output(enums: &[(Ident, Vec<KindEnumMember>)]) -> TokenStream {
let derives = match name_string.as_str() {
"ExecutionModel" => quote! { #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)] },
_ => quote! { #[derive(Clone, Debug, PartialEq, Eq)] },
"Decoration" => quote! { #[derive(Clone, Debug, PartialEq, Eq)] },
_ => quote! { #[derive(Clone, Copy, Debug, PartialEq, Eq)] },
};
quote! {

View File

@ -110,7 +110,6 @@ where
/// # Panics
///
/// - Panics if `T` has zero size.
#[inline]
pub unsafe fn uninitialized(
device: Arc<Device>,
usage: BufferUsage,
@ -173,7 +172,6 @@ where
///
/// - Panics if `T` has zero size.
/// - Panics if `len` is zero.
#[inline]
pub unsafe fn uninitialized_array(
device: Arc<Device>,
len: DeviceSize,
@ -274,7 +272,6 @@ where
T: BufferContents + ?Sized,
{
/// Returns the queue families this buffer can be used on.
#[inline]
pub fn queue_family_indices(&self) -> &[u32] {
&self.queue_family_indices
}
@ -294,7 +291,6 @@ where
/// After this function successfully locks the buffer, any attempt to submit a command buffer
/// that uses it in exclusive mode will fail. You can still submit this buffer for non-exclusive
/// accesses (ie. reads).
#[inline]
pub fn read(&self) -> Result<ReadLock<'_, T, A>, ReadLockError> {
let mut state = self.inner.state();
let buffer_range = self.inner().offset..self.inner().offset + self.size();
@ -335,7 +331,6 @@ where
///
/// After this function successfully locks the buffer, any attempt to submit a command buffer
/// that uses it and any attempt to call `read()` will return an error.
#[inline]
pub fn write(&self) -> Result<WriteLock<'_, T, A>, WriteLockError> {
let mut state = self.inner.state();
let buffer_range = self.inner().offset..self.inner().offset + self.size();
@ -370,7 +365,6 @@ where
T: BufferContents + ?Sized,
A: Send + Sync,
{
#[inline]
fn inner(&self) -> BufferInner<'_> {
BufferInner {
buffer: &self.inner,
@ -378,7 +372,6 @@ where
}
}
#[inline]
fn size(&self) -> DeviceSize {
self.inner.size()
}
@ -389,7 +382,6 @@ where
T: BufferContents + ?Sized,
A: Send + Sync + 'static,
{
#[inline]
fn as_buffer_access_object(&self) -> Arc<dyn BufferAccess> {
self.clone()
}
@ -407,7 +399,6 @@ unsafe impl<T, A> DeviceOwned for CpuAccessibleBuffer<T, A>
where
T: BufferContents + ?Sized,
{
#[inline]
fn device(&self) -> &Arc<Device> {
self.inner.device()
}
@ -418,7 +409,6 @@ where
T: BufferContents + ?Sized,
A: Send + Sync,
{
#[inline]
fn eq(&self, other: &Self) -> bool {
self.inner() == other.inner() && self.size() == other.size()
}
@ -436,7 +426,6 @@ where
T: BufferContents + ?Sized,
A: Send + Sync,
{
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.inner().hash(state);
self.size().hash(state);
@ -463,7 +452,6 @@ where
T: BufferContents + ?Sized + 'a,
A: MemoryPoolAlloc,
{
#[inline]
fn drop(&mut self) {
unsafe {
let mut state = self.inner.inner.state();
@ -479,7 +467,6 @@ where
{
type Target = T;
#[inline]
fn deref(&self) -> &T {
self.data
}
@ -506,7 +493,6 @@ where
T: BufferContents + ?Sized + 'a,
A: MemoryPoolAlloc,
{
#[inline]
fn drop(&mut self) {
unsafe {
self.inner
@ -529,7 +515,6 @@ where
{
type Target = T;
#[inline]
fn deref(&self) -> &T {
self.data
}
@ -540,7 +525,6 @@ where
T: BufferContents + ?Sized + 'a,
A: MemoryPoolAlloc,
{
#[inline]
fn deref_mut(&mut self) -> &mut T {
self.data
}
@ -558,7 +542,6 @@ pub enum ReadLockError {
impl Error for ReadLockError {}
impl Display for ReadLockError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
write!(
f,
@ -587,7 +570,6 @@ pub enum WriteLockError {
impl Error for WriteLockError {}
impl Display for WriteLockError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
write!(
f,

View File

@ -59,17 +59,19 @@ use std::{
///
/// # Usage
///
/// Since a `DeviceLocalBuffer` can only be directly accessed by the GPU, data cannot be transfered between
/// the host process and the buffer alone. One must use additional buffers which are accessible to the CPU as
/// staging areas, then use command buffers to execute the necessary data transfers.
/// Since a `DeviceLocalBuffer` can only be directly accessed by the GPU, data cannot be transfered
/// between the host process and the buffer alone. One must use additional buffers which are
/// accessible to the CPU as staging areas, then use command buffers to execute the necessary data
/// transfers.
///
/// Despite this, if one knows in advance that a buffer will not need to be frequently accessed by the host,
/// then there may be significant performance gains by using a `DeviceLocalBuffer` over a buffer type which
/// allows host access.
/// Despite this, if one knows in advance that a buffer will not need to be frequently accessed by
/// the host, then there may be significant performance gains by using a `DeviceLocalBuffer` over a
/// buffer type which allows host access.
///
/// # Example
/// # Examples
///
/// The following example outlines the general strategy one may take when initializing a `DeviceLocalBuffer`.
/// The following example outlines the general strategy one may take when initializing a
/// `DeviceLocalBuffer`.
///
/// ```
/// use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer, DeviceLocalBuffer};
@ -111,21 +113,20 @@ use std::{
/// )
/// .unwrap();
/// cbb.copy_buffer(CopyBufferInfo::buffers(
/// temporary_accessible_buffer,
/// device_local_buffer.clone(),
/// ))
/// .unwrap();
/// temporary_accessible_buffer,
/// device_local_buffer.clone(),
/// ))
/// .unwrap();
/// let cb = cbb.build().unwrap();
///
/// // Execute copy command and wait for completion before proceeding.
/// cb.execute(queue.clone())
/// .unwrap()
/// .then_signal_fence_and_flush()
/// .unwrap()
/// .wait(None /* timeout */)
/// .unwrap()
/// .unwrap()
/// .then_signal_fence_and_flush()
/// .unwrap()
/// .wait(None /* timeout */)
/// .unwrap()
/// ```
///
#[derive(Debug)]
pub struct DeviceLocalBuffer<T, A = PotentialDedicatedAllocation<StandardMemoryPoolAlloc>>
where
@ -153,7 +154,6 @@ where
/// # Panics
///
/// - Panics if `T` has zero size.
#[inline]
pub fn new(
device: Arc<Device>,
usage: BufferUsage,
@ -180,9 +180,9 @@ where
/// Builds a `DeviceLocalBuffer` that copies its data from another buffer.
///
/// This function returns two objects: the newly-created buffer, and a future representing
/// the initial upload operation. In order to be allowed to use the `DeviceLocalBuffer`, you must
/// either submit your operation after this future, or execute this future and wait for it to
/// be finished before submitting your own operation.
/// the initial upload operation. In order to be allowed to use the `DeviceLocalBuffer`, you
/// must either submit your operation after this future, or execute this future and wait for it
/// to be finished before submitting your own operation.
pub fn from_buffer<B>(
source: Arc<B>,
usage: BufferUsage,
@ -242,9 +242,9 @@ where
/// submits the command buffer as a future.
///
/// This function returns two objects: the newly-created buffer, and a future representing
/// the initial upload operation. In order to be allowed to use the `DeviceLocalBuffer`, you must
/// either submit your operation after this future, or execute this future and wait for it to
/// be finished before submitting your own operation.
/// the initial upload operation. In order to be allowed to use the `DeviceLocalBuffer`, you
/// must either submit your operation after this future, or execute this future and wait for it
/// to be finished before submitting your own operation.
///
/// # Panics
///
@ -316,7 +316,6 @@ where
///
/// - Panics if `T` has zero size.
/// - Panics if `len` is zero.
#[inline]
pub fn array(
device: Arc<Device>,
len: DeviceSize,
@ -453,6 +452,7 @@ where
}
};
let mem_reqs = buffer.memory_requirements();
Ok((buffer, mem_reqs))
}
@ -471,7 +471,6 @@ where
T: BufferContents + ?Sized,
{
/// Returns the queue families this buffer can be used on.
#[inline]
pub fn queue_family_indices(&self) -> &[u32] {
&self.queue_family_indices
}
@ -481,7 +480,6 @@ unsafe impl<T, A> DeviceOwned for DeviceLocalBuffer<T, A>
where
T: BufferContents + ?Sized,
{
#[inline]
fn device(&self) -> &Arc<Device> {
self.inner.device()
}
@ -492,7 +490,6 @@ where
T: BufferContents + ?Sized,
A: Send + Sync,
{
#[inline]
fn inner(&self) -> BufferInner<'_> {
BufferInner {
buffer: &self.inner,
@ -500,7 +497,6 @@ where
}
}
#[inline]
fn size(&self) -> DeviceSize {
self.inner.size()
}
@ -511,7 +507,6 @@ where
T: BufferContents + ?Sized,
A: Send + Sync + 'static,
{
#[inline]
fn as_buffer_access_object(&self) -> Arc<dyn BufferAccess> {
self.clone()
}
@ -530,7 +525,6 @@ where
T: BufferContents + ?Sized,
A: Send + Sync,
{
#[inline]
fn eq(&self, other: &Self) -> bool {
self.inner() == other.inner() && self.size() == other.size()
}
@ -548,7 +542,6 @@ where
T: BufferContents + ?Sized,
A: Send + Sync,
{
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.inner().hash(state);
self.size().hash(state);
@ -562,7 +555,6 @@ pub enum DeviceLocalBufferCreationError {
}
impl Error for DeviceLocalBufferCreationError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
Self::DeviceMemoryAllocationError(err) => Some(err),
@ -572,7 +564,6 @@ impl Error for DeviceLocalBufferCreationError {
}
impl Display for DeviceLocalBufferCreationError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match self {
Self::DeviceMemoryAllocationError(err) => err.fmt(f),
@ -582,14 +573,12 @@ impl Display for DeviceLocalBufferCreationError {
}
impl From<DeviceMemoryError> for DeviceLocalBufferCreationError {
#[inline]
fn from(e: DeviceMemoryError) -> Self {
Self::DeviceMemoryAllocationError(e)
}
}
impl From<CommandBufferBeginError> for DeviceLocalBufferCreationError {
#[inline]
fn from(e: CommandBufferBeginError) -> Self {
Self::CommandBufferBeginError(e)
}

View File

@ -125,22 +125,18 @@ unsafe impl<T> BufferContents for T
where
T: Pod + Send + Sync,
{
#[inline]
fn as_bytes(&self) -> &[u8] {
bytes_of(self)
}
#[inline]
fn from_bytes(bytes: &[u8]) -> Result<&T, PodCastError> {
try_from_bytes(bytes)
}
#[inline]
fn from_bytes_mut(bytes: &mut [u8]) -> Result<&mut T, PodCastError> {
try_from_bytes_mut(bytes)
}
#[inline]
fn size_of_element() -> DeviceSize {
1
}
@ -150,22 +146,18 @@ unsafe impl<T> BufferContents for [T]
where
T: Pod + Send + Sync,
{
#[inline]
fn as_bytes(&self) -> &[u8] {
cast_slice(self)
}
#[inline]
fn from_bytes(bytes: &[u8]) -> Result<&[T], PodCastError> {
try_cast_slice(bytes)
}
#[inline]
fn from_bytes_mut(bytes: &mut [u8]) -> Result<&mut [T], PodCastError> {
try_cast_slice_mut(bytes)
}
#[inline]
fn size_of_element() -> DeviceSize {
size_of::<T>() as DeviceSize
}

View File

@ -24,7 +24,7 @@ use std::{
///
/// This object doesn't correspond to any Vulkan object. It exists for API convenience.
///
/// # Example
/// # Examples
///
/// Creating a slice:
///
@ -41,7 +41,7 @@ use std::{
/// # let buffer: std::sync::Arc<vulkano::buffer::DeviceLocalBuffer<[u8]>> = return;
/// let _slice = BufferSlice::from(&buffer).slice(12 .. 14).unwrap();
/// ```
///
#[derive(Debug)]
pub struct BufferSlice<T: ?Sized, B> {
marker: PhantomData<T>,
resource: Arc<B>,
@ -51,7 +51,6 @@ pub struct BufferSlice<T: ?Sized, B> {
// We need to implement `Clone` manually, otherwise the derive adds a `T: Clone` requirement.
impl<T: ?Sized, B> Clone for BufferSlice<T, B> {
#[inline]
fn clone(&self) -> Self {
BufferSlice {
marker: PhantomData,
@ -63,7 +62,6 @@ impl<T: ?Sized, B> Clone for BufferSlice<T, B> {
}
impl<T: ?Sized, B> BufferSlice<T, B> {
#[inline]
pub fn from_typed_buffer_access(r: Arc<B>) -> Arc<BufferSlice<T, B>>
where
B: TypedBufferAccess<Content = T>,
@ -84,13 +82,11 @@ impl<T: ?Sized, B> BufferSlice<T, B> {
}
/// Returns the offset of that slice within the buffer.
#[inline]
pub fn offset(&self) -> DeviceSize {
self.offset
}
/// Returns the size of that slice in bytes.
#[inline]
pub fn size(&self) -> DeviceSize {
self.size
}
@ -100,7 +96,7 @@ impl<T: ?Sized, B> BufferSlice<T, B> {
/// This method builds an object that represents a slice of the buffer. No actual operation
/// is performed.
///
/// # Example
/// # Examples
///
/// TODO
///
@ -111,7 +107,6 @@ impl<T: ?Sized, B> BufferSlice<T, B> {
///
/// You **must** return a reference to an element from the parameter. The closure **must not**
/// panic.
#[inline]
pub unsafe fn slice_custom<F, R: ?Sized>(&self, f: F) -> Arc<BufferSlice<R, B>>
where
F: for<'r> FnOnce(&'r T) -> &'r R, // TODO: bounds on R
@ -136,7 +131,7 @@ impl<T: ?Sized, B> BufferSlice<T, B> {
/// useful when you have a buffer with various types of data and want to create a typed slice
/// of a region that contains a single type of data.
///
/// # Example
/// # Examples
///
/// ```
/// # use std::sync::Arc;
@ -153,7 +148,6 @@ impl<T: ?Sized, B> BufferSlice<T, B> {
///
/// Correct `offset` and `size` must be ensured before using this `BufferSlice` on the device.
/// See `BufferSlice::slice` for adjusting these properties.
#[inline]
pub unsafe fn reinterpret<R: ?Sized>(&self) -> Arc<BufferSlice<R, B>> {
Arc::new(BufferSlice {
marker: PhantomData,
@ -166,7 +160,6 @@ impl<T: ?Sized, B> BufferSlice<T, B> {
impl<T, B> BufferSlice<[T], B> {
/// Returns the number of elements in this slice.
#[inline]
pub fn len(&self) -> DeviceSize {
debug_assert_eq!(self.size() % size_of::<T>() as DeviceSize, 0);
self.size() / size_of::<T>() as DeviceSize
@ -175,7 +168,6 @@ impl<T, B> BufferSlice<[T], B> {
/// Reduces the slice to just one element of the array.
///
/// Returns `None` if out of range.
#[inline]
pub fn index(&self, index: DeviceSize) -> Option<Arc<BufferSlice<T, B>>> {
if index >= self.len() {
return None;
@ -192,7 +184,6 @@ impl<T, B> BufferSlice<[T], B> {
/// Reduces the slice to just a range of the array.
///
/// Returns `None` if out of range.
#[inline]
pub fn slice(&self, range: Range<DeviceSize>) -> Option<Arc<BufferSlice<[T], B>>> {
if range.end > self.len() {
return None;
@ -212,7 +203,6 @@ where
B: BufferAccess,
T: Send + Sync + ?Sized,
{
#[inline]
fn inner(&self) -> BufferInner<'_> {
let inner = self.resource.inner();
BufferInner {
@ -221,7 +211,6 @@ where
}
}
#[inline]
fn size(&self) -> DeviceSize {
self.size
}
@ -232,7 +221,6 @@ where
B: BufferAccess + 'static,
T: Send + Sync + ?Sized + 'static,
{
#[inline]
fn as_buffer_access_object(&self) -> Arc<dyn BufferAccess> {
self.clone()
}
@ -250,14 +238,12 @@ unsafe impl<T: ?Sized, B> DeviceOwned for BufferSlice<T, B>
where
B: DeviceOwned,
{
#[inline]
fn device(&self) -> &Arc<Device> {
self.resource.device()
}
}
impl<T, B> From<BufferSlice<T, B>> for BufferSlice<[T], B> {
#[inline]
fn from(r: BufferSlice<T, B>) -> BufferSlice<[T], B> {
BufferSlice {
marker: PhantomData,
@ -273,7 +259,6 @@ where
T: Send + Sync,
B: BufferAccess,
{
#[inline]
fn eq(&self, other: &Self) -> bool {
self.inner() == other.inner() && self.size() == other.size()
}
@ -291,7 +276,6 @@ where
T: Send + Sync,
B: BufferAccess,
{
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.inner().hash(state);
self.size().hash(state);

View File

@ -279,6 +279,7 @@ impl UnsafeBuffer {
///
/// - `handle` must be a valid Vulkan object handle created from `device`.
/// - `create_info` must match the info used to create the object.
#[inline]
pub unsafe fn from_handle(
device: Arc<Device>,
handle: ash::vk::Buffer,
@ -307,7 +308,6 @@ impl UnsafeBuffer {
/// Returns the memory requirements for this buffer.
pub fn memory_requirements(&self) -> MemoryRequirements {
#[inline]
fn align(val: DeviceSize, al: DeviceSize) -> DeviceSize {
al * (1 + (val - 1) / al)
}
@ -443,6 +443,7 @@ impl UnsafeBuffer {
)
.result()
.map_err(VulkanError::from)?;
Ok(())
}
@ -511,7 +512,6 @@ impl PartialEq for UnsafeBuffer {
impl Eq for UnsafeBuffer {}
impl Hash for UnsafeBuffer {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.handle.hash(state);
self.device.hash(state);
@ -590,17 +590,15 @@ pub enum BufferCreationError {
}
impl Error for BufferCreationError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match *self {
BufferCreationError::AllocError(ref err) => Some(err),
match self {
BufferCreationError::AllocError(err) => Some(err),
_ => None,
}
}
}
impl Display for BufferCreationError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match self {
Self::AllocError(_) => write!(f, "allocating memory failed"),
@ -614,24 +612,24 @@ impl Display for BufferCreationError {
),
Self::MaxBufferSizeExceeded { .. } => write!(
f,
"the specified size exceeded the value of the `max_buffer_size` limit"
"the specified size exceeded the value of the `max_buffer_size` limit",
),
Self::SharingQueueFamilyIndexOutOfRange { .. } => write!(
f,
"the sharing mode was set to `Concurrent`, but one of the specified queue family \
indices was out of range",
),
Self::SharingQueueFamilyIndexOutOfRange { .. } => {
write!(f, "the sharing mode was set to `Concurrent`, but one of the specified queue family indices was out of range")
}
}
}
}
impl From<OomError> for BufferCreationError {
#[inline]
fn from(err: OomError) -> BufferCreationError {
BufferCreationError::AllocError(err.into())
}
}
impl From<VulkanError> for BufferCreationError {
#[inline]
fn from(err: VulkanError) -> BufferCreationError {
match err {
err @ VulkanError::OutOfHostMemory => {
@ -646,7 +644,6 @@ impl From<VulkanError> for BufferCreationError {
}
impl From<RequirementNotMet> for BufferCreationError {
#[inline]
fn from(err: RequirementNotMet) -> Self {
Self::RequirementNotMet {
required_for: err.required_for,

View File

@ -49,7 +49,6 @@ pub unsafe trait BufferAccess: DeviceOwned + Send + Sync {
///
/// This method can be used when you want to perform an operation on some part of the buffer
/// and not on the whole buffer.
#[inline]
fn slice<T>(self: &Arc<Self>, range: Range<DeviceSize>) -> Option<Arc<BufferSlice<[T], Self>>>
where
Self: Sized + TypedBufferAccess<Content = [T]>,
@ -61,7 +60,6 @@ pub unsafe trait BufferAccess: DeviceOwned + Send + Sync {
///
/// This method can be used when you want to perform an operation on a specific element of the
/// buffer and not on the whole buffer.
#[inline]
fn index<T>(self: &Arc<Self>, index: DeviceSize) -> Option<Arc<BufferSlice<T, Self>>>
where
Self: Sized + TypedBufferAccess<Content = [T]>,
@ -121,6 +119,7 @@ pub trait BufferAccessObject {
}
impl BufferAccessObject for Arc<dyn BufferAccess> {
#[inline]
fn as_buffer_access_object(&self) -> Arc<dyn BufferAccess> {
self.clone()
}
@ -141,12 +140,10 @@ where
T: SafeDeref + Send + Sync,
T::Target: BufferAccess,
{
#[inline]
fn inner(&self) -> BufferInner<'_> {
(**self).inner()
}
#[inline]
fn size(&self) -> DeviceSize {
(**self).size()
}
@ -192,7 +189,6 @@ impl PartialEq for dyn BufferAccess {
impl Eq for dyn BufferAccess {}
impl Hash for dyn BufferAccess {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.inner().hash(state);
self.size().hash(state);
@ -213,7 +209,6 @@ pub enum BufferDeviceAddressError {
impl Error for BufferDeviceAddressError {}
impl Display for BufferDeviceAddressError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match self {
Self::RequirementNotMet {
@ -224,7 +219,6 @@ impl Display for BufferDeviceAddressError {
"a requirement was not met for: {}; requires one of: {}",
required_for, requires_one_of,
),
Self::BufferMissingUsage => write!(
f,
"the device address usage flag was not set on this buffer",

View File

@ -15,7 +15,7 @@
//! In order to create a view from a buffer, the buffer must have been created with either the
//! `uniform_texel_buffer` or the `storage_texel_buffer` usage.
//!
//! # Example
//! # Examples
//!
//! ```
//! # use std::sync::Arc;
@ -235,7 +235,6 @@ where
}
/// Returns the buffer associated to this view.
#[inline]
pub fn buffer(&self) -> &Arc<B> {
&self.buffer
}
@ -245,7 +244,6 @@ impl<B> Drop for BufferView<B>
where
B: BufferAccess + ?Sized,
{
#[inline]
fn drop(&mut self) {
unsafe {
let fns = self.buffer.inner().buffer.device().fns();
@ -264,7 +262,6 @@ where
{
type Object = ash::vk::BufferView;
#[inline]
fn internal_object(&self) -> ash::vk::BufferView {
self.handle
}
@ -274,7 +271,6 @@ unsafe impl<B> DeviceOwned for BufferView<B>
where
B: BufferAccess + ?Sized,
{
#[inline]
fn device(&self) -> &Arc<Device> {
self.buffer.device()
}
@ -284,7 +280,6 @@ impl<B> PartialEq for BufferView<B>
where
B: BufferAccess + ?Sized,
{
#[inline]
fn eq(&self, other: &Self) -> bool {
self.handle == other.handle && self.device() == other.device()
}
@ -296,7 +291,6 @@ impl<B> Hash for BufferView<B>
where
B: BufferAccess + ?Sized,
{
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.handle.hash(state);
self.device().hash(state);
@ -359,24 +353,18 @@ pub enum BufferViewCreationError {
}
impl Error for BufferViewCreationError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match *self {
BufferViewCreationError::OomError(ref err) => Some(err),
match self {
BufferViewCreationError::OomError(err) => Some(err),
_ => None,
}
}
}
impl Display for BufferViewCreationError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match self {
Self::OomError(_) => write!(
f,
"out of memory when creating buffer view",
),
Self::OomError(_) => write!(f, "out of memory when creating buffer view"),
Self::RequirementNotMet {
required_for,
requires_one_of,
@ -385,10 +373,10 @@ impl Display for BufferViewCreationError {
"a requirement was not met for: {}; requires one of: {}",
required_for, requires_one_of,
),
Self::BufferMissingUsage => write!(
f,
"the buffer was not created with one of the `storage_texel_buffer` or `uniform_texel_buffer` usages",
"the buffer was not created with one of the `storage_texel_buffer` or \
`uniform_texel_buffer` usages",
),
Self::OffsetNotAligned { .. } => write!(
f,
@ -398,34 +386,29 @@ impl Display for BufferViewCreationError {
f,
"the range within the buffer is not a multiple of the required alignment",
),
Self::UnsupportedFormat => write!(
f,
"the requested format is not supported for this usage",
),
Self::MaxTexelBufferElementsExceeded => write!(
f,
"the `max_texel_buffer_elements` limit has been exceeded",
),
Self::UnsupportedFormat => {
write!(f, "the requested format is not supported for this usage")
}
Self::MaxTexelBufferElementsExceeded => {
write!(f, "the `max_texel_buffer_elements` limit has been exceeded")
}
}
}
}
impl From<OomError> for BufferViewCreationError {
#[inline]
fn from(err: OomError) -> Self {
Self::OomError(err)
}
}
impl From<VulkanError> for BufferViewCreationError {
#[inline]
fn from(err: VulkanError) -> Self {
OomError::from(err).into()
}
}
impl From<RequirementNotMet> for BufferViewCreationError {
#[inline]
fn from(err: RequirementNotMet) -> Self {
Self::RequirementNotMet {
required_for: err.required_for,
@ -455,22 +438,18 @@ where
B: BufferAccess + ?Sized + 'static,
Arc<B>: BufferAccessObject,
{
#[inline]
fn buffer(&self) -> Arc<dyn BufferAccess> {
self.buffer.as_buffer_access_object()
}
#[inline]
fn format(&self) -> Option<Format> {
self.format
}
#[inline]
fn format_features(&self) -> &FormatFeatures {
&self.format_features
}
#[inline]
fn range(&self) -> Range<DeviceSize> {
self.range.clone()
}
@ -486,7 +465,6 @@ impl PartialEq for dyn BufferViewAbstract {
impl Eq for dyn BufferViewAbstract {}
impl Hash for dyn BufferViewAbstract {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.internal_object().hash(state);
self.device().hash(state);

View File

@ -83,14 +83,12 @@ pub(super) enum RenderPassStateType {
}
impl From<BeginRenderPassState> for RenderPassStateType {
#[inline]
fn from(val: BeginRenderPassState) -> Self {
Self::BeginRenderPass(val)
}
}
impl From<BeginRenderingState> for RenderPassStateType {
#[inline]
fn from(val: BeginRenderingState) -> Self {
Self::BeginRendering(val)
}
@ -532,21 +530,18 @@ pub enum CommandBufferBeginError {
}
impl Error for CommandBufferBeginError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match *self {
Self::OomError(ref err) => Some(err),
match self {
Self::OomError(err) => Some(err),
_ => None,
}
}
}
impl Display for CommandBufferBeginError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match self {
Self::OomError(_) => write!(f, "not enough memory available"),
Self::RequirementNotMet {
required_for,
requires_one_of,
@ -555,7 +550,6 @@ impl Display for CommandBufferBeginError {
"a requirement was not met for: {}; requires one of: {}",
required_for, requires_one_of,
),
Self::ColorAttachmentFormatUsageNotSupported { attachment_index } => write!(
f,
"color attachment {} has a format that does not support that usage",
@ -570,10 +564,10 @@ impl Display for CommandBufferBeginError {
"the depth and stencil attachments have different formats",
),
Self::FramebufferNotCompatible => {
write!(f, "the framebuffer is not compatible with the render pass",)
write!(f, "the framebuffer is not compatible with the render pass")
}
Self::MaxMultiviewViewCountExceeded { .. } => {
write!(f, "the `max_multiview_view_count` limit has been exceeded",)
write!(f, "the `max_multiview_view_count` limit has been exceeded")
}
Self::StencilAttachmentFormatUsageNotSupported => write!(
f,
@ -584,14 +578,12 @@ impl Display for CommandBufferBeginError {
}
impl From<OomError> for CommandBufferBeginError {
#[inline]
fn from(err: OomError) -> Self {
Self::OomError(err)
}
}
impl From<RequirementNotMet> for CommandBufferBeginError {
#[inline]
fn from(err: RequirementNotMet) -> Self {
Self::RequirementNotMet {
required_for: err.required_for,
@ -605,7 +597,6 @@ where
P: CommandPoolBuilderAlloc,
{
/// Builds the command buffer.
#[inline]
pub fn build(self) -> Result<PrimaryAutoCommandBuffer<P::Alloc>, BuildError> {
if self.render_pass_state.is_some() {
return Err(BuildError::RenderPassActive);
@ -638,7 +629,6 @@ where
P: CommandPoolBuilderAlloc,
{
/// Builds the command buffer.
#[inline]
pub fn build(self) -> Result<SecondaryAutoCommandBuffer<P::Alloc>, BuildError> {
if !self.query_state.is_empty() {
return Err(BuildError::QueryActive);
@ -676,7 +666,6 @@ pub enum BuildError {
}
impl Error for BuildError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
Self::OomError(err) => Some(err),
@ -698,27 +687,23 @@ impl Display for BuildError {
}
impl From<OomError> for BuildError {
#[inline]
fn from(err: OomError) -> Self {
Self::OomError(err)
}
}
impl<L, P> AutoCommandBufferBuilder<L, P> {
#[inline]
pub(super) fn queue_family_properties(&self) -> &QueueFamilyProperties {
&self.device().physical_device().queue_family_properties()[self.queue_family_index as usize]
}
/// Returns the binding/setting state.
#[inline]
pub fn state(&self) -> CommandBufferState<'_> {
self.inner.state()
}
}
unsafe impl<L, P> DeviceOwned for AutoCommandBufferBuilder<L, P> {
#[inline]
fn device(&self) -> &Arc<Device> {
self.inner.device()
}
@ -733,7 +718,6 @@ pub struct PrimaryAutoCommandBuffer<P = StandardCommandPoolAlloc> {
}
unsafe impl<P> DeviceOwned for PrimaryAutoCommandBuffer<P> {
#[inline]
fn device(&self) -> &Arc<Device> {
self.inner.device()
}
@ -743,12 +727,10 @@ unsafe impl<P> PrimaryCommandBuffer for PrimaryAutoCommandBuffer<P>
where
P: CommandPoolAlloc,
{
#[inline]
fn inner(&self) -> &UnsafeCommandBuffer {
self.inner.as_ref()
}
#[inline]
fn lock_submit(
&self,
future: &dyn GpuFuture,
@ -793,7 +775,6 @@ where
Err(err)
}
#[inline]
unsafe fn unlock(&self) {
// Because of panic safety, we unlock the inner command buffer first.
self.inner.unlock();
@ -812,7 +793,6 @@ where
};
}
#[inline]
fn check_buffer_access(
&self,
buffer: &UnsafeBuffer,
@ -824,7 +804,6 @@ where
.check_buffer_access(buffer, range, exclusive, queue)
}
#[inline]
fn check_image_access(
&self,
image: &UnsafeImage,
@ -848,7 +827,6 @@ pub struct SecondaryAutoCommandBuffer<P = StandardCommandPoolAlloc> {
}
unsafe impl<P> DeviceOwned for SecondaryAutoCommandBuffer<P> {
#[inline]
fn device(&self) -> &Arc<Device> {
self.inner.device()
}
@ -858,12 +836,10 @@ unsafe impl<P> SecondaryCommandBuffer for SecondaryAutoCommandBuffer<P>
where
P: CommandPoolAlloc,
{
#[inline]
fn inner(&self) -> &UnsafeCommandBuffer {
self.inner.as_ref()
}
#[inline]
fn lock_record(&self) -> Result<(), CommandBufferExecError> {
match self.submit_state {
SubmitState::OneTime {
@ -886,7 +862,6 @@ where
Ok(())
}
#[inline]
unsafe fn unlock(&self) {
match self.submit_state {
SubmitState::OneTime {
@ -902,17 +877,14 @@ where
};
}
#[inline]
fn inheritance_info(&self) -> &CommandBufferInheritanceInfo {
&self.inheritance_info
}
#[inline]
fn num_buffers(&self) -> usize {
self.inner.num_buffers()
}
#[inline]
fn buffer(
&self,
index: usize,
@ -924,12 +896,10 @@ where
self.inner.buffer(index)
}
#[inline]
fn num_images(&self) -> usize {
self.inner.num_images()
}
#[inline]
fn image(
&self,
index: usize,

View File

@ -703,7 +703,6 @@ impl SyncCommandBufferBuilder {
}
/// Calls `vkCmdPushConstants` on the builder.
#[inline]
pub unsafe fn push_constants<D>(
&mut self,
pipeline_layout: Arc<PipelineLayout>,
@ -838,7 +837,6 @@ pub struct SyncCommandBufferBuilderBindDescriptorSets<'b> {
impl<'b> SyncCommandBufferBuilderBindDescriptorSets<'b> {
/// Adds a descriptor set to the list.
#[inline]
pub fn add(&mut self, descriptor_set: impl Into<DescriptorSetWithOffsets>) {
self.descriptor_sets.push(descriptor_set.into());
}
@ -1069,7 +1067,6 @@ impl UnsafeCommandBufferBuilder {
}
/// Calls `vkCmdPushConstants` on the builder.
#[inline]
pub unsafe fn push_constants<D>(
&mut self,
pipeline_layout: &PipelineLayout,
@ -1101,7 +1098,6 @@ impl UnsafeCommandBufferBuilder {
/// Calls `vkCmdPushDescriptorSetKHR` on the builder.
///
/// If the list is empty then the command is automatically ignored.
#[inline]
pub unsafe fn push_descriptor_set<'a>(
&mut self,
pipeline_bind_point: PipelineBindPoint,
@ -1162,6 +1158,7 @@ impl UnsafeCommandBufferBuilder {
}
/// Prototype for a `vkCmdBindVertexBuffers`.
#[derive(Debug)]
pub struct UnsafeCommandBufferBuilderBindVertexBuffer {
// Raw handles of the buffers to bind.
pub raw_buffers: SmallVec<[ash::vk::Buffer; 4]>,
@ -1267,7 +1264,6 @@ impl error::Error for BindPushError {
}
impl Display for BindPushError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match self {
Self::RequirementNotMet {
@ -1278,83 +1274,78 @@ impl Display for BindPushError {
"a requirement was not met for: {}; requires one of: {}",
required_for, requires_one_of,
),
Self::DescriptorSetUpdateError(_) => write!(
f,
"a DescriptorSetUpdateError",
),
Self::DescriptorSetUpdateError(_) => write!(f, "a DescriptorSetUpdateError"),
Self::DescriptorSetNotCompatible { set_num } => write!(
f,
"the element of `descriptor_sets` being bound to slot {} is not compatible with the corresponding slot in `pipeline_layout`",
"the element of `descriptor_sets` being bound to slot {} is not compatible with \
the corresponding slot in `pipeline_layout`",
set_num,
),
Self::DescriptorSetNotPush { set_num } => write!(
f,
"the descriptor set number being pushed ({}) is not defined for push descriptor sets in the pipeline layout",
"the descriptor set number being pushed ({}) is not defined for push descriptor \
sets in the pipeline layout",
set_num,
),
Self::DescriptorSetOutOfRange { set_num, pipeline_layout_set_count } => write!(
Self::DescriptorSetOutOfRange {
set_num,
pipeline_layout_set_count,
} => write!(
f,
"the highest descriptor set slot being bound ({}) is greater than the number of sets in `pipeline_layout` ({})",
"the highest descriptor set slot being bound ({}) is greater than the number of \
sets in `pipeline_layout` ({})",
set_num, pipeline_layout_set_count,
),
Self::IndexBufferMissingUsage => write!(
f,
"an index buffer is missing the `index_buffer` usage",
),
Self::MaxVertexInputBindingsExceeded { .. } => write!(
f,
"the `max_vertex_input_bindings` limit has been exceeded",
),
Self::NotSupportedByQueueFamily => write!(
f,
"the queue family doesn't allow this operation",
),
Self::IndexBufferMissingUsage => {
write!(f, "an index buffer is missing the `index_buffer` usage")
}
Self::MaxVertexInputBindingsExceeded { .. } => {
write!(f, "the `max_vertex_input_bindings` limit has been exceeded")
}
Self::NotSupportedByQueueFamily => {
write!(f, "the queue family doesn't allow this operation")
}
Self::PreviousPipelineColorAttachmentFormatMismatch => write!(
f,
"the newly set pipeline has color attachment formats that do not match the previously used pipeline",
"the newly set pipeline has color attachment formats that do not match the \
previously used pipeline",
),
Self::PreviousPipelineDepthAttachmentFormatMismatch => write!(
f,
"the newly set pipeline has a depth attachment format that does not match the previously used pipeline",
"the newly set pipeline has a depth attachment format that does not match the \
previously used pipeline",
),
Self::PreviousPipelineStencilAttachmentFormatMismatch => write!(
f,
"the newly set pipeline has a stencil attachment format that does not match the previously used pipeline"
"the newly set pipeline has a stencil attachment format that does not match the \
previously used pipeline",
),
Self::PushConstantsDataOutOfRange {
offset,
} => write!(
Self::PushConstantsDataOutOfRange { offset } => write!(
f,
"the push constants data to be written at offset {} is not included in any push constant range of the pipeline layout",
"the push constants data to be written at offset {} is not included in any push \
constant range of the pipeline layout",
offset,
),
Self::PushConstantsOffsetNotAligned => write!(
f,
"the push constants offset is not a multiple of 4",
),
Self::PushConstantsSizeNotAligned => write!(
f,
"the push constants size is not a multiple of 4",
),
Self::VertexBufferMissingUsage => write!(
f,
"a vertex buffer is missing the `vertex_buffer` usage",
),
Self::PushConstantsOffsetNotAligned => {
write!(f, "the push constants offset is not a multiple of 4")
}
Self::PushConstantsSizeNotAligned => {
write!(f, "the push constants size is not a multiple of 4")
}
Self::VertexBufferMissingUsage => {
write!(f, "a vertex buffer is missing the `vertex_buffer` usage")
}
}
}
}
impl From<DescriptorSetUpdateError> for BindPushError {
#[inline]
fn from(err: DescriptorSetUpdateError) -> Self {
Self::DescriptorSetUpdateError(err)
}
}
impl From<RequirementNotMet> for BindPushError {
#[inline]
fn from(err: RequirementNotMet) -> Self {
Self::RequirementNotMet {
required_for: err.required_for,

View File

@ -30,7 +30,6 @@ use std::{
/// instance.
impl<L, P> AutoCommandBufferBuilder<L, P> {
/// Opens a command buffer debug label region.
#[inline]
pub fn begin_debug_utils_label(
&mut self,
mut label_info: DebugUtilsLabel,
@ -82,7 +81,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
/// - When submitting the command buffer, there must be an outstanding command buffer label
/// region begun with `begin_debug_utils_label` in the queue, either within this command
/// buffer or a previously submitted one.
#[inline]
pub unsafe fn end_debug_utils_label(&mut self) -> Result<&mut Self, DebugUtilsError> {
self.validate_end_debug_utils_label()?;
@ -126,7 +124,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
}
/// Inserts a command buffer debug label.
#[inline]
pub fn insert_debug_utils_label(
&mut self,
mut label_info: DebugUtilsLabel,
@ -323,7 +320,6 @@ pub enum DebugUtilsError {
impl Error for DebugUtilsError {}
impl Display for DebugUtilsError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match self {
Self::RequirementNotMet {
@ -334,7 +330,6 @@ impl Display for DebugUtilsError {
"a requirement was not met for: {}; requires one of: {}",
required_for, requires_one_of,
),
Self::NotSupportedByQueueFamily => {
write!(f, "the queue family doesn't allow this operation")
}

View File

@ -96,7 +96,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
/// - Panics if the currently bound graphics pipeline already contains this state internally.
/// - If there is a graphics pipeline with color blend state bound, `enables.len()` must equal
/// - [`attachments.len()`](crate::pipeline::graphics::color_blend::ColorBlendState::attachments).
#[inline]
pub fn set_color_write_enable<I>(&mut self, enables: I) -> &mut Self
where
I: IntoIterator<Item = bool>,
@ -166,7 +165,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
/// [`extended_dynamic_state`](crate::device::Features::extended_dynamic_state) feature is
/// not enabled on the device.
/// - Panics if the currently bound graphics pipeline already contains this state internally.
#[inline]
pub fn set_cull_mode(&mut self, cull_mode: CullMode) -> &mut Self {
self.validate_set_cull_mode(cull_mode).unwrap();
@ -215,7 +213,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
/// - Panics if the currently bound graphics pipeline already contains this state internally.
/// - If the [`depth_bias_clamp`](crate::device::Features::depth_bias_clamp)
/// feature is not enabled on the device, panics if `clamp` is not 0.0.
#[inline]
pub fn set_depth_bias(
&mut self,
constant_factor: f32,
@ -271,7 +268,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
/// [`extended_dynamic_state2`](crate::device::Features::extended_dynamic_state2) feature is
/// not enabled on the device.
/// - Panics if the currently bound graphics pipeline already contains this state internally.
#[inline]
pub fn set_depth_bias_enable(&mut self, enable: bool) -> &mut Self {
self.validate_set_depth_bias_enable(enable).unwrap();
@ -371,7 +367,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
/// [`extended_dynamic_state`](crate::device::Features::extended_dynamic_state) feature is
/// not enabled on the device.
/// - Panics if the currently bound graphics pipeline already contains this state internally.
#[inline]
pub fn set_depth_bounds_test_enable(&mut self, enable: bool) -> &mut Self {
self.validate_set_depth_bounds_test_enable(enable).unwrap();
@ -421,7 +416,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
/// [`extended_dynamic_state`](crate::device::Features::extended_dynamic_state) feature is
/// not enabled on the device.
/// - Panics if the currently bound graphics pipeline already contains this state internally.
#[inline]
pub fn set_depth_compare_op(&mut self, compare_op: CompareOp) -> &mut Self {
self.validate_set_depth_compare_op(compare_op).unwrap();
@ -474,7 +468,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
/// [`extended_dynamic_state`](crate::device::Features::extended_dynamic_state) feature is
/// not enabled on the device.
/// - Panics if the currently bound graphics pipeline already contains this state internally.
#[inline]
pub fn set_depth_test_enable(&mut self, enable: bool) -> &mut Self {
self.validate_set_depth_test_enable(enable).unwrap();
@ -521,7 +514,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
/// [`extended_dynamic_state`](crate::device::Features::extended_dynamic_state) feature is
/// not enabled on the device.
/// - Panics if the currently bound graphics pipeline already contains this state internally.
#[inline]
pub fn set_depth_write_enable(&mut self, enable: bool) -> &mut Self {
self.validate_set_depth_write_enable(enable).unwrap();
@ -644,7 +636,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
/// [`extended_dynamic_state`](crate::device::Features::extended_dynamic_state) feature is
/// not enabled on the device.
/// - Panics if the currently bound graphics pipeline already contains this state internally.
#[inline]
pub fn set_front_face(&mut self, face: FrontFace) -> &mut Self {
self.validate_set_front_face(face).unwrap();
@ -694,7 +685,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
/// extension is not enabled on the device.
/// - Panics if the currently bound graphics pipeline already contains this state internally.
/// - Panics if `factor` is not between 1 and 256 inclusive.
#[inline]
pub fn set_line_stipple(&mut self, factor: u32, pattern: u16) -> &mut Self {
self.validate_set_line_stipple(factor, pattern).unwrap();
@ -788,7 +778,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
/// [`extended_dynamic_state2_logic_op`](crate::device::Features::extended_dynamic_state2_logic_op)
/// feature is not enabled on the device.
/// - Panics if the currently bound graphics pipeline already contains this state internally.
#[inline]
pub fn set_logic_op(&mut self, logic_op: LogicOp) -> &mut Self {
self.validate_set_logic_op(logic_op).unwrap();
@ -843,7 +832,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
/// - Panics if `num` is greater than the
/// [`max_tessellation_patch_size`](crate::device::Properties::max_tessellation_patch_size)
/// property of the device.
#[inline]
pub fn set_patch_control_points(&mut self, num: u32) -> &mut Self {
self.validate_set_patch_control_points(num).unwrap();
@ -912,7 +900,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
/// [`extended_dynamic_state2`](crate::device::Features::extended_dynamic_state2) feature is
/// not enabled on the device.
/// - Panics if the currently bound graphics pipeline already contains this state internally.
#[inline]
pub fn set_primitive_restart_enable(&mut self, enable: bool) -> &mut Self {
self.validate_set_primitive_restart_enable(enable).unwrap();
@ -966,7 +953,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
/// enabled, panics if `topology` is a `WithAdjacency` topology.
/// - If the [`tessellation_shader`](crate::device::Features::tessellation_shader) feature is
/// not enabled, panics if `topology` is `PatchList`.
#[inline]
pub fn set_primitive_topology(&mut self, topology: PrimitiveTopology) -> &mut Self {
self.validate_set_primitive_topology(topology).unwrap();
@ -1051,7 +1037,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
/// [`extended_dynamic_state2`](crate::device::Features::extended_dynamic_state2) feature is
/// not enabled on the device.
/// - Panics if the currently bound graphics pipeline already contains this state internally.
#[inline]
pub fn set_rasterizer_discard_enable(&mut self, enable: bool) -> &mut Self {
self.validate_set_rasterizer_discard_enable(enable).unwrap();
@ -1181,7 +1166,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
/// [`max_viewports`](crate::device::Properties::max_viewports) device property.
/// - If the [`multi_viewport`](crate::device::Features::multi_viewport) feature is not enabled,
/// panics if more than 1 scissor is provided.
#[inline]
pub fn set_scissor_with_count(
&mut self,
scissors: impl IntoIterator<Item = Scissor>,
@ -1295,7 +1279,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
/// [`extended_dynamic_state`](crate::device::Features::extended_dynamic_state) feature is
/// not enabled on the device.
/// - Panics if the currently bound graphics pipeline already contains this state internally.
#[inline]
pub fn set_stencil_op(
&mut self,
faces: StencilFaces,
@ -1410,7 +1393,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
/// [`extended_dynamic_state`](crate::device::Features::extended_dynamic_state) feature is
/// not enabled on the device.
/// - Panics if the currently bound graphics pipeline already contains this state internally.
#[inline]
pub fn set_stencil_test_enable(&mut self, enable: bool) -> &mut Self {
self.validate_set_stencil_test_enable(enable).unwrap();
@ -1575,7 +1557,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
/// [`max_viewports`](crate::device::Properties::max_viewports) device property.
/// - If the [`multi_viewport`](crate::device::Features::multi_viewport) feature is not enabled,
/// panics if more than 1 viewport is provided.
#[inline]
pub fn set_viewport_with_count(
&mut self,
viewports: impl IntoIterator<Item = Viewport>,
@ -1665,7 +1646,6 @@ impl SyncCommandBufferBuilder {
/// Calls `vkCmdSetColorWriteEnableEXT` on the builder.
///
/// If the list is empty then the command is automatically ignored.
#[inline]
pub unsafe fn set_color_write_enable(&mut self, enables: impl IntoIterator<Item = bool>) {
struct Cmd<I> {
enables: Mutex<Option<I>>,
@ -1874,7 +1854,6 @@ impl SyncCommandBufferBuilder {
/// Calls `vkCmdSetDiscardRectangle` on the builder.
///
/// If the list is empty then the command is automatically ignored.
#[inline]
pub unsafe fn set_discard_rectangle(
&mut self,
first_rectangle: u32,
@ -2260,7 +2239,6 @@ impl SyncCommandBufferBuilder {
/// Calls `vkCmdSetScissor` on the builder.
///
/// If the list is empty then the command is automatically ignored.
#[inline]
pub unsafe fn set_scissor(
&mut self,
first_scissor: u32,
@ -2297,7 +2275,6 @@ impl SyncCommandBufferBuilder {
/// Calls `vkCmdSetScissorWithCountEXT` on the builder.
///
/// If the list is empty then the command is automatically ignored.
#[inline]
pub unsafe fn set_scissor_with_count(&mut self, scissors: impl IntoIterator<Item = Scissor>) {
struct Cmd {
scissors: Mutex<SmallVec<[Scissor; 2]>>,
@ -2323,7 +2300,6 @@ impl SyncCommandBufferBuilder {
/// Calls `vkCmdSetViewport` on the builder.
///
/// If the list is empty then the command is automatically ignored.
#[inline]
pub unsafe fn set_viewport(
&mut self,
first_viewport: u32,
@ -2360,7 +2336,6 @@ impl SyncCommandBufferBuilder {
/// Calls `vkCmdSetViewportWithCountEXT` on the builder.
///
/// If the list is empty then the command is automatically ignored.
#[inline]
pub unsafe fn set_viewport_with_count(
&mut self,
viewports: impl IntoIterator<Item = Viewport>,
@ -2398,7 +2373,6 @@ impl UnsafeCommandBufferBuilder {
/// Calls `vkCmdSetColorWriteEnableEXT` on the builder.
///
/// If the list is empty then the command is automatically ignored.
#[inline]
pub unsafe fn set_color_write_enable(&mut self, enables: impl IntoIterator<Item = bool>) {
debug_assert!(self.device.enabled_extensions().ext_color_write_enable);
@ -2522,7 +2496,6 @@ impl UnsafeCommandBufferBuilder {
/// Calls `vkCmdSetDiscardRectangleEXT` on the builder.
///
/// If the list is empty then the command is automatically ignored.
#[inline]
pub unsafe fn set_discard_rectangle(
&mut self,
first_rectangle: u32,
@ -2722,7 +2695,6 @@ impl UnsafeCommandBufferBuilder {
/// Calls `vkCmdSetScissor` on the builder.
///
/// If the list is empty then the command is automatically ignored.
#[inline]
pub unsafe fn set_scissor(
&mut self,
first_scissor: u32,
@ -2748,7 +2720,6 @@ impl UnsafeCommandBufferBuilder {
/// Calls `vkCmdSetScissorWithCountEXT` on the builder.
///
/// If the list is empty then the command is automatically ignored.
#[inline]
pub unsafe fn set_scissor_with_count(&mut self, scissors: impl IntoIterator<Item = Scissor>) {
let scissors = scissors
.into_iter()
@ -2780,7 +2751,6 @@ impl UnsafeCommandBufferBuilder {
/// Calls `vkCmdSetViewport` on the builder.
///
/// If the list is empty then the command is automatically ignored.
#[inline]
pub unsafe fn set_viewport(
&mut self,
first_viewport: u32,
@ -2806,7 +2776,6 @@ impl UnsafeCommandBufferBuilder {
/// Calls `vkCmdSetViewportWithCountEXT` on the builder.
///
/// If the list is empty then the command is automatically ignored.
#[inline]
pub unsafe fn set_viewport_with_count(
&mut self,
viewports: impl IntoIterator<Item = Viewport>,
@ -2880,7 +2849,6 @@ enum SetDynamicStateError {
impl Error for SetDynamicStateError {}
impl Display for SetDynamicStateError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match self {
Self::RequirementNotMet {
@ -2891,45 +2859,42 @@ impl Display for SetDynamicStateError {
"a requirement was not met for: {}; requires one of: {}",
required_for, requires_one_of,
),
Self::FactorOutOfRange => write!(
f,
"the provided `factor` is not between 1 and 256 inclusive",
),
Self::MaxDiscardRectanglesExceeded { .. } => write!(
f,
"the `max_discard_rectangles` limit has been exceeded",
),
Self::MaxDiscardRectanglesExceeded { .. } => {
write!(f, "the `max_discard_rectangles` limit has been exceeded")
}
Self::MaxTessellationPatchSizeExceeded { .. } => write!(
f,
"the `max_tessellation_patch_size` limit has been exceeded",
),
Self::MaxViewportsExceeded { .. } => write!(
f,
"the `max_viewports` limit has been exceeded",
),
Self::NotSupportedByQueueFamily => write!(
f,
"the queue family doesn't allow this operation",
),
Self::MaxViewportsExceeded { .. } => {
write!(f, "the `max_viewports` limit has been exceeded")
}
Self::NotSupportedByQueueFamily => {
write!(f, "the queue family doesn't allow this operation")
}
Self::PipelineColorBlendAttachmentCountMismatch {
provided_count,
required_count,
} => write!(
f,
"the provided item count ({}) is different from the number of attachments in the color blend state of the currently bound pipeline ({})",
"the provided item count ({}) is different from the number of attachments in the \
color blend state of the currently bound pipeline ({})",
provided_count, required_count,
),
Self::PipelineHasFixedState => write!(
f,
"the currently bound pipeline contains this state as internally fixed state, which cannot be overridden with dynamic state",
"the currently bound pipeline contains this state as internally fixed state, which \
cannot be overridden with dynamic state",
),
}
}
}
impl From<RequirementNotMet> for SetDynamicStateError {
#[inline]
fn from(err: RequirementNotMet) -> Self {
Self::RequirementNotMet {
required_for: err.required_for,

View File

@ -61,10 +61,9 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
/// If `layer_count` is greater than 1, the blit will happen between each individual layer as
/// if they were separate images.
///
/// # Panic
/// # Panics
///
/// - Panics if the source or the destination was not created with `device`.
#[inline]
pub fn blit_image(&mut self, blit_image_info: BlitImageInfo) -> Result<&mut Self, CopyError> {
self.validate_blit_image(&blit_image_info)?;
@ -561,7 +560,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
}
/// Clears a color image with a specific value.
#[inline]
pub fn clear_color_image(
&mut self,
clear_info: ClearColorImageInfo,
@ -714,7 +712,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
}
/// Clears a depth/stencil image with a specific value.
#[inline]
pub fn clear_depth_stencil_image(
&mut self,
clear_info: ClearDepthStencilImageInfo,
@ -889,7 +886,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
///
/// - Panics if `src_image` or `dst_image` were not created from the same device
/// as `self`.
#[inline]
pub fn resolve_image(
&mut self,
resolve_image_info: ResolveImageInfo,
@ -1271,6 +1267,7 @@ impl SyncCommandBufferBuilder {
///
/// Does nothing if the list of regions is empty, as it would be a no-op and isn't a valid
/// usage of the command anyway.
#[inline]
pub unsafe fn clear_color_image(
&mut self,
clear_info: ClearColorImageInfo,
@ -1341,6 +1338,7 @@ impl SyncCommandBufferBuilder {
///
/// Does nothing if the list of regions is empty, as it would be a no-op and isn't a valid
/// usage of the command anyway.
#[inline]
pub unsafe fn clear_depth_stencil_image(
&mut self,
clear_info: ClearDepthStencilImageInfo,
@ -1678,6 +1676,7 @@ impl UnsafeCommandBufferBuilder {
///
/// Does nothing if the list of regions is empty, as it would be a no-op and isn't a valid
/// usage of the command anyway.
#[inline]
pub unsafe fn clear_color_image(&mut self, clear_info: &ClearColorImageInfo) {
let &ClearColorImageInfo {
ref image,
@ -1713,6 +1712,7 @@ impl UnsafeCommandBufferBuilder {
///
/// Does nothing if the list of regions is empty, as it would be a no-op and isn't a valid
/// usage of the command anyway.
#[inline]
pub unsafe fn clear_depth_stencil_image(&mut self, clear_info: &ClearDepthStencilImageInfo) {
let &ClearDepthStencilImageInfo {
ref image,

View File

@ -124,7 +124,8 @@ pub enum CopyError {
max: DeviceSize,
},
/// Depth/stencil images are not supported by the queue family of this command buffer; a graphics queue family is required.
/// Depth/stencil images are not supported by the queue family of this command buffer; a
/// graphics queue family is required.
DepthStencilNotSupportedByQueueFamily,
/// The image extent of a region is not a multiple of the required image alignment.
@ -275,7 +276,6 @@ pub enum CopyError {
}
impl Error for CopyError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
Self::SyncCommandBufferBuilderError(err) => Some(err),
@ -285,11 +285,9 @@ impl Error for CopyError {
}
impl Display for CopyError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match self {
Self::SyncCommandBufferBuilderError(_) => write!(f, "a SyncCommandBufferBuilderError"),
Self::RequirementNotMet {
required_for,
requires_one_of,
@ -298,21 +296,20 @@ impl Display for CopyError {
"a requirement was not met for: {}; requires one of: {}",
required_for, requires_one_of,
),
Self::ForbiddenInsideRenderPass => {
write!(f, "operation forbidden inside of a render pass")
}
Self::NotSupportedByQueueFamily => {
write!(f, "the queue family doesn't allow this operation")
}
Self::ArrayLayerCountMismatch {
region_index,
src_layer_count,
dst_layer_count,
} => write!(
f,
"the array layer counts of the source and destination subresource ranges of region {} do not match (source: {}; destination: {})",
"the array layer counts of the source and destination subresource ranges of region \
{} do not match (source: {}; destination: {})",
region_index, src_layer_count, dst_layer_count,
),
Self::ArrayLayersOutOfRange {
@ -322,7 +319,8 @@ impl Display for CopyError {
image_array_layers,
} => write!(
f,
"the end of the range of accessed array layers ({}) of the {} subresource range of region {} is greater than the number of array layers in the {} image ({})",
"the end of the range of accessed array layers ({}) of the {} subresource range of \
region {} is greater than the number of array layers in the {} image ({})",
array_layers_range_end, resource, region_index, resource, image_array_layers,
),
Self::AspectsMismatch {
@ -331,7 +329,8 @@ impl Display for CopyError {
dst_aspects,
} => write!(
f,
"the aspects of the source and destination subresource ranges of region {} do not match (source: {:?}; destination: {:?})",
"the aspects of the source and destination subresource ranges of region {} do not \
match (source: {:?}; destination: {:?})",
region_index, src_aspects, dst_aspects,
),
Self::AspectsNotAllowed {
@ -341,7 +340,8 @@ impl Display for CopyError {
allowed_aspects,
} => write!(
f,
"the aspects ({:?}) of the {} subresource range of region {} contain aspects that are not present in the {} image, or that are not allowed ({:?})",
"the aspects ({:?}) of the {} subresource range of region {} contain aspects that \
are not present in the {} image, or that are not allowed ({:?})",
aspects, resource, region_index, resource, allowed_aspects,
),
Self::BufferImageHeightNotAligned {
@ -351,7 +351,8 @@ impl Display for CopyError {
required_alignment,
} => write!(
f,
"the {} buffer image height ({}) of region {} is not a multiple of the required {} buffer alignment ({})",
"the {} buffer image height ({}) of region {} is not a multiple of the required {} \
buffer alignment ({})",
resource, image_height, region_index, resource, required_alignment,
),
Self::BufferRowLengthTooLarge {
@ -360,7 +361,8 @@ impl Display for CopyError {
buffer_row_length,
} => write!(
f,
"the {} buffer row length ({}) of region {} specifies a row of texels that is greater than 0x7FFFFFFF bytes in size",
"the {} buffer row length ({}) of region {} specifies a row of texels that is \
greater than 0x7FFFFFFF bytes in size",
resource, buffer_row_length, region_index,
),
Self::BufferImageHeightTooSmall {
@ -370,7 +372,8 @@ impl Display for CopyError {
min,
} => write!(
f,
"the {} buffer image height ({}) of region {} is smaller than the {} image extent height ({})",
"the {} buffer image height ({}) of region {} is smaller than the {} image extent \
height ({})",
resource, image_height, region_index, resource, min,
),
Self::BufferRowLengthNotAligned {
@ -380,7 +383,8 @@ impl Display for CopyError {
required_alignment,
} => write!(
f,
"the {} buffer row length ({}) of region {} is not a multiple of the required {} buffer alignment ({})",
"the {} buffer row length ({}) of region {} is not a multiple of the required {} \
buffer alignment ({})",
resource, row_length, region_index, resource, required_alignment,
),
Self::BufferRowLengthTooSmall {
@ -390,20 +394,19 @@ impl Display for CopyError {
min,
} => write!(
f,
"the {} buffer row length length ({}) of region {} is smaller than the {} image extent width ({})",
"the {} buffer row length length ({}) of region {} is smaller than the {} image \
extent width ({})",
resource, row_length, region_index, resource, min,
),
Self::DataTooLarge {
size,
max,
} => write!(
Self::DataTooLarge { size, max } => write!(
f,
"the provided data has a size ({}) greater than the maximum allowed ({})",
size, max,
),
Self::DepthStencilNotSupportedByQueueFamily => write!(
f,
"depth/stencil images are not supported by the queue family of this command buffer; a graphics queue family is required",
"depth/stencil images are not supported by the queue family of this command \
buffer; a graphics queue family is required",
),
Self::ExtentNotAlignedForImage {
resource,
@ -412,21 +415,19 @@ impl Display for CopyError {
required_alignment,
} => write!(
f,
"the {} image extent ({:?}) of region {} is not a multiple of the required {} image alignment ({:?})",
"the {} image extent ({:?}) of region {} is not a multiple of the required {} \
image alignment ({:?})",
resource, extent, region_index, resource, required_alignment,
),
Self::FilterNotSupportedForImageType => write!(
f,
"the chosen filter is not supported for the source image type"
"the chosen filter is not supported for the source image type",
),
Self::FilterNotSupportedByFormat => write!(
f,
"the chosen filter is not supported by the format of the source image"
"the chosen filter is not supported by the format of the source image",
),
Self::FormatNotSupported {
resource,
format,
} => write!(
Self::FormatNotSupported { resource, format } => write!(
f,
"the format of the {} image ({:?}) is not supported for this operation",
resource, format,
@ -436,7 +437,8 @@ impl Display for CopyError {
dst_format,
} => write!(
f,
"the format of the source image ({:?}) does not match the format of the destination image ({:?})",
"the format of the source image ({:?}) does not match the format of the \
destination image ({:?})",
src_format, dst_format,
),
Self::FormatsNotCompatible {
@ -444,7 +446,8 @@ impl Display for CopyError {
dst_format,
} => write!(
f,
"the format of the source image subresource ({:?}) is not compatible with the format of the destination image subresource ({:?})",
"the format of the source image subresource ({:?}) is not compatible with the \
format of the destination image subresource ({:?})",
src_format, dst_format,
),
Self::ImageLayoutInvalid {
@ -462,7 +465,8 @@ impl Display for CopyError {
image_mip_levels,
} => write!(
f,
"the end of the range of accessed mip levels ({}) of the {} subresource range of region {} is not less than the number of mip levels in the {} image ({})",
"the end of the range of accessed mip levels ({}) of the {} subresource range of \
region {} is not less than the number of mip levels in the {} image ({})",
mip_levels_range_end, resource, region_index, resource, image_mip_levels,
),
Self::MissingFormatFeature {
@ -484,7 +488,8 @@ impl Display for CopyError {
aspects,
} => write!(
f,
"the {} subresource range of region {} specifies multiple aspects ({:?}), but only one aspect can be selected for the {} image",
"the {} subresource range of region {} specifies multiple aspects ({:?}), but only \
one aspect can be selected for the {} image",
resource, region_index, aspects, resource,
),
Self::OffsetNotAlignedForBuffer {
@ -494,7 +499,8 @@ impl Display for CopyError {
required_alignment,
} => write!(
f,
"the {} buffer offset ({}) of region {} is not a multiple of the required {} buffer alignment ({})",
"the {} buffer offset ({}) of region {} is not a multiple of the required {} \
buffer alignment ({})",
resource, offset, region_index, resource, required_alignment,
),
Self::OffsetNotAlignedForImage {
@ -504,7 +510,8 @@ impl Display for CopyError {
required_alignment,
} => write!(
f,
"the {} image offset ({:?}) of region {} is not a multiple of the required {} image alignment ({:?})",
"the {} image offset ({:?}) of region {} is not a multiple of the required {} \
image alignment ({:?})",
resource, offset, region_index, resource, required_alignment,
),
Self::OffsetsInvalidForImageType {
@ -513,7 +520,8 @@ impl Display for CopyError {
offsets,
} => write!(
f,
"the {} image offsets ({:?}) of region {} are not the values required for that axis ([0, 1]) for the type of the {} image",
"the {} image offsets ({:?}) of region {} are not the values required for that \
axis ([0, 1]) for the type of the {} image",
resource, offsets, region_index, resource,
),
Self::OverlappingRegions {
@ -531,7 +539,9 @@ impl Display for CopyError {
dst_image_layout,
} => write!(
f,
"the source subresources of region {} overlap with the destination subresources of region {}, but the source image layout ({:?}) does not equal the destination image layout ({:?})",
"the source subresources of region {} overlap with the destination subresources of \
region {}, but the source image layout ({:?}) does not equal the destination image \
layout ({:?})",
src_region_index, dst_region_index, src_image_layout, dst_image_layout,
),
Self::RegionOutOfBufferBounds {
@ -541,7 +551,8 @@ impl Display for CopyError {
buffer_size,
} => write!(
f,
"the end of the range of accessed {} byte offsets ({}) of region {} is greater than the size of the {} buffer ({})",
"the end of the range of accessed {} byte offsets ({}) of region {} is greater \
than the size of the {} buffer ({})",
resource, offset_range_end, region_index, resource, buffer_size,
),
Self::RegionOutOfImageBounds {
@ -551,7 +562,8 @@ impl Display for CopyError {
subresource_extent,
} => write!(
f,
"the end of the range of accessed {} texel offsets ({:?}) of region {} is greater than the extent of the selected subresource of the {} image ({:?})",
"the end of the range of accessed {} texel offsets ({:?}) of region {} is greater \
than the extent of the selected subresource of the {} image ({:?})",
resource, offset_range_end, region_index, resource, subresource_extent,
),
Self::SampleCountInvalid {
@ -560,7 +572,8 @@ impl Display for CopyError {
allowed_sample_counts,
} => write!(
f,
"the {} image has a sample count ({:?}) that is not valid for this operation ({:?})",
"the {} image has a sample count ({:?}) that is not valid for this operation \
({:?})",
resource, sample_count, allowed_sample_counts,
),
Self::SampleCountMismatch {
@ -568,7 +581,8 @@ impl Display for CopyError {
dst_sample_count,
} => write!(
f,
"the source image has a different sample count ({:?}) than the destination image ({:?})",
"the source image has a different sample count ({:?}) than the destination image \
({:?})",
src_sample_count, dst_sample_count,
),
Self::SizeNotAlignedForBuffer {
@ -578,7 +592,8 @@ impl Display for CopyError {
required_alignment,
} => write!(
f,
"the {} buffer size ({}) of region {} is not a multiple of the required {} buffer alignment ({})",
"the {} buffer size ({}) of region {} is not a multiple of the required {} buffer \
alignment ({})",
resource, size, region_index, resource, required_alignment,
),
}
@ -586,14 +601,12 @@ impl Display for CopyError {
}
impl From<SyncCommandBufferBuilderError> for CopyError {
#[inline]
fn from(err: SyncCommandBufferBuilderError) -> Self {
Self::SyncCommandBufferBuilderError(err)
}
}
impl From<RequirementNotMet> for CopyError {
#[inline]
fn from(err: RequirementNotMet) -> Self {
Self::RequirementNotMet {
required_for: err.required_for,
@ -610,7 +623,6 @@ pub enum CopyErrorResource {
}
impl Display for CopyErrorResource {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match self {
Self::Source => write!(f, "source"),

View File

@ -55,7 +55,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
/// A compute pipeline must have been bound using
/// [`bind_pipeline_compute`](Self::bind_pipeline_compute). Any resources used by the compute
/// pipeline, such as descriptor sets, must have been set beforehand.
#[inline]
pub fn dispatch(
&mut self,
group_counts: [u32; 3],
@ -116,7 +115,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
/// A compute pipeline must have been bound using
/// [`bind_pipeline_compute`](Self::bind_pipeline_compute). Any resources used by the compute
/// pipeline, such as descriptor sets, must have been set beforehand.
#[inline]
pub fn dispatch_indirect<Inb>(
&mut self,
indirect_buffer: Arc<Inb>,
@ -173,7 +171,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
/// pipeline, such as descriptor sets, vertex buffers and dynamic state, must have been set
/// beforehand. If the bound graphics pipeline uses vertex buffers, then the provided vertex and
/// instance ranges must be in range of the bound vertex buffers.
#[inline]
pub fn draw(
&mut self,
vertex_count: u32,
@ -244,7 +241,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
/// beforehand. If the bound graphics pipeline uses vertex buffers, then the vertex and instance
/// ranges of each `DrawIndirectCommand` in the indirect buffer must be in range of the bound
/// vertex buffers.
#[inline]
pub fn draw_indirect<Inb>(
&mut self,
indirect_buffer: Arc<Inb>,
@ -342,7 +338,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
/// beforehand. If the bound graphics pipeline uses vertex buffers, then the provided instance
/// range must be in range of the bound vertex buffers. The vertex indices in the index buffer
/// must be in range of the bound vertex buffers.
#[inline]
pub fn draw_indexed(
&mut self,
index_count: u32,
@ -435,7 +430,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
/// beforehand. If the bound graphics pipeline uses vertex buffers, then the instance ranges of
/// each `DrawIndexedIndirectCommand` in the indirect buffer must be in range of the bound
/// vertex buffers.
#[inline]
pub fn draw_indexed_indirect<Inb>(
&mut self,
indirect_buffer: Arc<Inb>,
@ -2345,7 +2339,8 @@ pub enum PipelineExecutionError {
/// An indexed draw command was recorded, but no index buffer was bound.
IndexBufferNotBound,
/// The highest index to be drawn exceeds the available number of indices in the bound index buffer.
/// The highest index to be drawn exceeds the available number of indices in the bound index
/// buffer.
IndexBufferRangeOutOfBounds {
highest_index: u32,
max_index_count: u32,
@ -2459,7 +2454,6 @@ pub enum PipelineExecutionError {
}
impl Error for PipelineExecutionError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
Self::SyncCommandBufferBuilderError(err) => Some(err),
@ -2470,11 +2464,9 @@ impl Error for PipelineExecutionError {
}
impl Display for PipelineExecutionError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match self {
Self::SyncCommandBufferBuilderError(_) => write!(f, "a SyncCommandBufferBuilderError"),
Self::RequirementNotMet {
required_for,
requires_one_of,
@ -2483,17 +2475,21 @@ impl Display for PipelineExecutionError {
"a requirement was not met for: {}; requires one of: {}",
required_for, requires_one_of,
),
Self::DescriptorResourceInvalid { set_num, binding_num, index, .. } => write!(
f,
"the resource bound to descriptor set {} binding {} at index {} is not compatible with the requirements of the pipeline and shaders",
set_num, binding_num, index,
),
Self::DescriptorSetNotBound {
Self::DescriptorResourceInvalid {
set_num,
binding_num,
index,
..
} => write!(
f,
"the pipeline layout requires a descriptor set bound to set number {}, but none was bound",
"the resource bound to descriptor set {} binding {} at index {} is not compatible \
with the requirements of the pipeline and shaders",
set_num, binding_num, index,
),
Self::DescriptorSetNotBound { set_num } => write!(
f,
"the pipeline layout requires a descriptor set bound to set number {}, but none \
was bound",
set_num,
),
Self::DynamicColorWriteEnableNotEnoughValues {
@ -2501,23 +2497,24 @@ impl Display for PipelineExecutionError {
attachment_count,
} => write!(
f,
"the bound pipeline uses a dynamic color write enable setting, but the number of provided enable values ({}) is less than the number of attachments in the current render subpass ({})",
color_write_enable_count,
attachment_count,
"the bound pipeline uses a dynamic color write enable setting, but the number of \
provided enable values ({}) is less than the number of attachments in the current \
render subpass ({})",
color_write_enable_count, attachment_count,
),
Self::DynamicPrimitiveTopologyClassMismatch {
provided_class,
required_class,
} => write!(
f,
"The bound pipeline uses a dynamic primitive topology, but the provided topology is of a different topology class ({:?}) than what the pipeline requires ({:?})",
"The bound pipeline uses a dynamic primitive topology, but the provided topology \
is of a different topology class ({:?}) than what the pipeline requires ({:?})",
provided_class, required_class,
),
Self::DynamicPrimitiveTopologyInvalid {
topology,
} => write!(
Self::DynamicPrimitiveTopologyInvalid { topology } => write!(
f,
"the bound pipeline uses a dynamic primitive topology, but the provided topology ({:?}) is not compatible with the shader stages in the pipeline",
"the bound pipeline uses a dynamic primitive topology, but the provided topology \
({:?}) is not compatible with the shader stages in the pipeline",
topology,
),
Self::DynamicStateNotSet { dynamic_state } => write!(
@ -2530,18 +2527,16 @@ impl Display for PipelineExecutionError {
scissor_count,
} => write!(
f,
"the bound pipeline uses a dynamic scissor and/or viewport count, but the scissor count ({}) does not match the viewport count ({})",
scissor_count,
viewport_count,
),
Self::ForbiddenInsideRenderPass => write!(
f,
"operation forbidden inside a render pass",
),
Self::ForbiddenOutsideRenderPass => write!(
f,
"operation forbidden outside a render pass",
"the bound pipeline uses a dynamic scissor and/or viewport count, but the scissor \
count ({}) does not match the viewport count ({})",
scissor_count, viewport_count,
),
Self::ForbiddenInsideRenderPass => {
write!(f, "operation forbidden inside a render pass")
}
Self::ForbiddenOutsideRenderPass => {
write!(f, "operation forbidden outside a render pass")
}
Self::ForbiddenWithSubpassContents { subpass_contents } => write!(
f,
"operation forbidden inside a render subpass with contents {:?}",
@ -2556,9 +2551,9 @@ impl Display for PipelineExecutionError {
max_index_count,
} => write!(
f,
"the highest index to be drawn ({}) exceeds the available number of indices in the bound index buffer ({})",
highest_index,
max_index_count,
"the highest index to be drawn ({}) exceeds the available number of indices in the \
bound index buffer ({})",
highest_index, max_index_count,
),
Self::IndirectBufferMissingUsage => write!(
f,
@ -2568,24 +2563,23 @@ impl Display for PipelineExecutionError {
f,
"the `max_compute_work_group_count` limit has been exceeded",
),
Self::MaxDrawIndirectCountExceeded { .. } => write!(
f,
"the `max_draw_indirect_count` limit has been exceeded",
),
Self::MaxDrawIndirectCountExceeded { .. } => {
write!(f, "the `max_draw_indirect_count` limit has been exceeded")
}
Self::MaxMultiviewInstanceIndexExceeded { .. } => write!(
f,
"the `max_multiview_instance_index` limit has been exceeded",
),
Self::NotSupportedByQueueFamily => write!(
f,
"the queue family doesn't allow this operation",
),
Self::NotSupportedByQueueFamily => {
write!(f, "the queue family doesn't allow this operation")
}
Self::PipelineColorAttachmentCountMismatch {
pipeline_count,
required_count,
} => write!(
f,
"the color attachment count in the bound pipeline ({}) does not match the count of the current render pass ({})",
"the color attachment count in the bound pipeline ({}) does not match the count of \
the current render pass ({})",
pipeline_count, required_count,
),
Self::PipelineColorAttachmentFormatMismatch {
@ -2594,7 +2588,8 @@ impl Display for PipelineExecutionError {
required_format,
} => write!(
f,
"the format of color attachment {} in the bound pipeline ({:?}) does not match the format of the corresponding color attachment in the current render pass ({:?})",
"the format of color attachment {} in the bound pipeline ({:?}) does not match the \
format of the corresponding color attachment in the current render pass ({:?})",
color_attachment_index, pipeline_format, required_format,
),
Self::PipelineDepthAttachmentFormatMismatch {
@ -2602,12 +2597,14 @@ impl Display for PipelineExecutionError {
required_format,
} => write!(
f,
"the format of the depth attachment in the bound pipeline ({:?}) does not match the format of the depth attachment in the current render pass ({:?})",
"the format of the depth attachment in the bound pipeline ({:?}) does not match \
the format of the depth attachment in the current render pass ({:?})",
pipeline_format, required_format,
),
Self::PipelineLayoutNotCompatible => write!(
f,
"the bound pipeline is not compatible with the layout used to bind the descriptor sets",
"the bound pipeline is not compatible with the layout used to bind the descriptor \
sets",
),
Self::PipelineNotBound => write!(
f,
@ -2615,27 +2612,27 @@ impl Display for PipelineExecutionError {
),
Self::PipelineRenderPassNotCompatible => write!(
f,
"the bound graphics pipeline uses a render pass that is not compatible with the currently active render pass",
"the bound graphics pipeline uses a render pass that is not compatible with the \
currently active render pass",
),
Self::PipelineRenderPassTypeMismatch => write!(
f,
"the bound graphics pipeline uses a render pass of a different type than the currently active render pass",
"the bound graphics pipeline uses a render pass of a different type than the \
currently active render pass",
),
Self::PipelineSubpassMismatch {
pipeline,
current,
} => write!(
Self::PipelineSubpassMismatch { pipeline, current } => write!(
f,
"the bound graphics pipeline uses a render subpass index ({}) that doesn't match the currently active subpass index ({})",
pipeline,
current,
"the bound graphics pipeline uses a render subpass index ({}) that doesn't match \
the currently active subpass index ({})",
pipeline, current,
),
Self::PipelineStencilAttachmentFormatMismatch {
pipeline_format,
required_format,
} => write!(
f,
"the format of the stencil attachment in the bound pipeline ({:?}) does not match the format of the stencil attachment in the current render pass ({:?})",
"the format of the stencil attachment in the bound pipeline ({:?}) does not match \
the format of the stencil attachment in the current render pass ({:?})",
pipeline_format, required_format,
),
Self::PipelineViewMaskMismatch {
@ -2643,7 +2640,8 @@ impl Display for PipelineExecutionError {
required_view_mask,
} => write!(
f,
"the view mask of the bound pipeline ({}) does not match the view mask of the current render pass ({})",
"the view mask of the bound pipeline ({}) does not match the view mask of the \
current render pass ({})",
pipeline_view_mask, required_view_mask,
),
Self::PushConstantsNotCompatible => write!(
@ -2654,11 +2652,10 @@ impl Display for PipelineExecutionError {
f,
"not all push constants used by the pipeline have been set",
),
Self::VertexBufferNotBound {
binding_num,
} => write!(
Self::VertexBufferNotBound { binding_num } => write!(
f,
"the bound graphics pipeline requires a vertex buffer bound to binding number {}, but none was bound",
"the bound graphics pipeline requires a vertex buffer bound to binding number {}, \
but none was bound",
binding_num,
),
Self::VertexBufferInstanceRangeOutOfBounds {
@ -2666,7 +2663,8 @@ impl Display for PipelineExecutionError {
instances_in_buffers,
} => write!(
f,
"the number of instances to be drawn ({}) exceeds the available number of instances in the bound vertex buffers ({}) used by the pipeline",
"the number of instances to be drawn ({}) exceeds the available number of \
instances in the bound vertex buffers ({}) used by the pipeline",
instances_needed, instances_in_buffers,
),
Self::VertexBufferVertexRangeOutOfBounds {
@ -2674,7 +2672,8 @@ impl Display for PipelineExecutionError {
vertices_in_buffers,
} => write!(
f,
"the number of vertices to be drawn ({}) exceeds the available number of vertices in the bound vertex buffers ({}) used by the pipeline",
"the number of vertices to be drawn ({}) exceeds the available number of vertices \
in the bound vertex buffers ({}) used by the pipeline",
vertices_needed, vertices_in_buffers,
),
}
@ -2682,7 +2681,6 @@ impl Display for PipelineExecutionError {
}
impl From<SyncCommandBufferBuilderError> for PipelineExecutionError {
#[inline]
fn from(err: SyncCommandBufferBuilderError) -> Self {
Self::SyncCommandBufferBuilderError(err)
}
@ -2734,40 +2732,41 @@ impl Error for DescriptorResourceInvalidError {
}
impl Display for DescriptorResourceInvalidError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match self {
Self::ImageViewFormatMismatch { provided, required } => write!(
f,
"the format of the bound image view ({:?}) does not match what the pipeline requires ({:?})",
provided, required
"the format of the bound image view ({:?}) does not match what the pipeline \
requires ({:?})",
provided, required,
),
Self::ImageViewMultisampledMismatch { provided, required } => write!(
f,
"the multisampling of the bound image ({}) does not match what the pipeline requires ({})",
"the multisampling of the bound image ({}) does not match what the pipeline \
requires ({})",
provided, required,
),
Self::ImageViewScalarTypeMismatch { provided, required } => write!(
f,
"the scalar type of the format and aspect of the bound image view ({:?}) does not match what the pipeline requires ({:?})",
"the scalar type of the format and aspect of the bound image view ({:?}) does not \
match what the pipeline requires ({:?})",
provided, required,
),
Self::ImageViewTypeMismatch { provided, required } => write!(
f,
"the image view type of the bound image view ({:?}) does not match what the pipeline requires ({:?})",
"the image view type of the bound image view ({:?}) does not match what the \
pipeline requires ({:?})",
provided, required,
),
Self::Missing => write!(
f,
"no resource was bound",
),
Self::Missing => write!(f, "no resource was bound"),
Self::SamplerImageViewIncompatible { .. } => write!(
f,
"the bound sampler samples an image view that is not compatible with that sampler",
),
Self::SamplerCompareMismatch { provided, required } => write!(
f,
"the depth comparison state of the bound sampler ({}) does not match what the pipeline requires ({})",
"the depth comparison state of the bound sampler ({}) does not match what the \
pipeline requires ({})",
provided, required,
),
Self::SamplerUnnormalizedCoordinatesNotAllowed => write!(
@ -2784,11 +2783,13 @@ impl Display for DescriptorResourceInvalidError {
),
Self::StorageReadWithoutFormatNotSupported => write!(
f,
"the bound image view or buffer view does not support the `storage_read_without_format` format feature",
"the bound image view or buffer view does not support the \
`storage_read_without_format` format feature",
),
Self::StorageWriteWithoutFormatNotSupported => write!(
f,
"the bound image view or buffer view does not support the `storage_write_without_format` format feature",
"the bound image view or buffer view does not support the \
`storage_write_without_format` format feature",
),
}
}

View File

@ -38,7 +38,9 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
/// The query will be active until [`end_query`](Self::end_query) is called for the same query.
///
/// # Safety
/// The query must be unavailable, ensured by calling [`reset_query_pool`](Self::reset_query_pool).
///
/// The query must be unavailable, ensured by calling
/// [`reset_query_pool`](Self::reset_query_pool).
pub unsafe fn begin_query(
&mut self,
query_pool: Arc<QueryPool>,
@ -211,7 +213,9 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
/// Writes a timestamp to a timestamp query.
///
/// # Safety
/// The query must be unavailable, ensured by calling [`reset_query_pool`](Self::reset_query_pool).
///
/// The query must be unavailable, ensured by calling
/// [`reset_query_pool`](Self::reset_query_pool).
pub unsafe fn write_timestamp(
&mut self,
query_pool: Arc<QueryPool>,
@ -704,7 +708,6 @@ impl UnsafeCommandBufferBuilder {
}
/// Calls `vkCmdCopyQueryPoolResults` on the builder.
#[inline]
pub unsafe fn copy_query_pool_results<D, T>(
&mut self,
queries: QueriesRange<'_>,
@ -805,14 +808,9 @@ pub enum QueryError {
impl Error for QueryError {}
impl Display for QueryError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match *self {
Self::SyncCommandBufferBuilderError(_) => write!(
f,
"a SyncCommandBufferBuilderError",
),
match self {
Self::SyncCommandBufferBuilderError(_) => write!(f, "a SyncCommandBufferBuilderError"),
Self::RequirementNotMet {
required_for,
requires_one_of,
@ -821,7 +819,6 @@ impl Display for QueryError {
"a requirement was not met for: {}; requires one of: {}",
required_for, requires_one_of,
),
Self::BufferTooSmall { .. } => {
write!(f, "the buffer is too small for the copy operation")
}
@ -846,7 +843,8 @@ impl Display for QueryError {
Self::OutOfRange => write!(f, "the provided query index is not valid for this pool"),
Self::OutOfRangeMultiview => write!(
f,
"the provided query index plus the number of views in the current render subpass is greater than the number of queries in the pool",
"the provided query index plus the number of views in the current render subpass \
is greater than the number of queries in the pool",
),
Self::QueryIsActive => write!(
f,
@ -861,14 +859,12 @@ impl Display for QueryError {
}
impl From<SyncCommandBufferBuilderError> for QueryError {
#[inline]
fn from(err: SyncCommandBufferBuilderError) -> Self {
Self::SyncCommandBufferBuilderError(err)
}
}
impl From<RequirementNotMet> for QueryError {
#[inline]
fn from(err: RequirementNotMet) -> Self {
Self::RequirementNotMet {
required_for: err.required_for,

View File

@ -50,7 +50,6 @@ where
///
/// `contents` specifies what kinds of commands will be recorded in the render pass, either
/// draw commands or executions of secondary command buffers.
#[inline]
pub fn begin_render_pass(
&mut self,
mut render_pass_begin_info: RenderPassBeginInfo,
@ -59,14 +58,14 @@ where
self.validate_begin_render_pass(&mut render_pass_begin_info, contents)?;
unsafe {
let &RenderPassBeginInfo {
let RenderPassBeginInfo {
ref render_pass,
ref framebuffer,
render_area_offset,
render_area_extent,
clear_values: _,
_ne: _,
} = &render_pass_begin_info;
} = render_pass_begin_info;
let subpass = render_pass.clone().first_subpass();
let view_mask = subpass.subpass_desc().view_mask;
@ -85,8 +84,8 @@ where
self.inner
.begin_render_pass(render_pass_begin_info, contents)?;
self.render_pass_state = Some(render_pass_state);
Ok(self)
}
}
@ -113,12 +112,12 @@ where
return Err(RenderPassError::ForbiddenInsideRenderPass);
}
let &mut RenderPassBeginInfo {
ref render_pass,
ref framebuffer,
let RenderPassBeginInfo {
render_pass,
framebuffer,
render_area_offset,
render_area_extent,
ref clear_values,
clear_values,
_ne: _,
} = render_pass_begin_info;
@ -208,12 +207,12 @@ where
}
for subpass_desc in render_pass.subpasses() {
let &SubpassDescription {
let SubpassDescription {
view_mask: _,
ref input_attachments,
ref color_attachments,
ref resolve_attachments,
ref depth_stencil_attachment,
input_attachments,
color_attachments,
resolve_attachments,
depth_stencil_attachment,
preserve_attachments: _,
_ne: _,
} = subpass_desc;
@ -288,7 +287,7 @@ where
}
// VUID-VkRenderPassBeginInfo-clearValueCount-04962
for (attachment_index, (attachment_desc, &clear_value)) in render_pass
for (attachment_index, (attachment_desc, &mut clear_value)) in render_pass
.attachments()
.iter()
.zip(clear_values)
@ -396,7 +395,6 @@ where
}
/// Advances to the next subpass of the render pass previously begun with `begin_render_pass`.
#[inline]
pub fn next_subpass(
&mut self,
contents: SubpassContents,
@ -472,7 +470,6 @@ where
/// Ends the render pass previously begun with `begin_render_pass`.
///
/// This must be called after you went through all the subpasses.
#[inline]
pub fn end_render_pass(&mut self) -> Result<&mut Self, RenderPassError> {
self.validate_end_render_pass()?;
@ -538,7 +535,7 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
mut rendering_info: RenderingInfo,
) -> Result<&mut Self, RenderPassError> {
{
let &mut RenderingInfo {
let RenderingInfo {
render_area_offset,
ref mut render_area_extent,
ref mut layer_count,
@ -548,7 +545,7 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
ref stencil_attachment,
contents: _,
_ne: _,
} = &mut rendering_info;
} = rendering_info;
let auto_extent = render_area_extent[0] == 0 || render_area_extent[1] == 0;
let auto_layers = *layer_count == 0;
@ -622,7 +619,7 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
self.validate_begin_rendering(&mut rendering_info)?;
unsafe {
let &RenderingInfo {
let RenderingInfo {
render_area_offset,
render_area_extent,
layer_count: _,
@ -632,7 +629,7 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
ref stencil_attachment,
contents,
_ne: _,
} = &rendering_info;
} = rendering_info;
let render_pass_state = RenderPassState {
contents,
@ -765,10 +762,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
})
{
let attachment_index = attachment_index as u32;
let &RenderingAttachmentInfo {
ref image_view,
let RenderingAttachmentInfo {
image_view,
image_layout,
ref resolve_info,
resolve_info,
load_op,
store_op,
clear_value: _,
@ -920,10 +917,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
}
if let Some(attachment_info) = depth_attachment {
let &RenderingAttachmentInfo {
ref image_view,
let RenderingAttachmentInfo {
image_view,
image_layout,
ref resolve_info,
resolve_info,
load_op,
store_op,
clear_value: _,
@ -1047,10 +1044,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
}
if let Some(attachment_info) = stencil_attachment {
let &RenderingAttachmentInfo {
ref image_view,
let RenderingAttachmentInfo {
image_view,
image_layout,
ref resolve_info,
resolve_info,
load_op,
store_op,
clear_value: _,
@ -1537,9 +1534,9 @@ impl SyncCommandBufferBuilder {
}
}
let &RenderPassBeginInfo {
ref render_pass,
ref framebuffer,
let RenderPassBeginInfo {
render_pass,
framebuffer,
render_area_offset: _,
render_area_extent: _,
clear_values: _,
@ -1658,14 +1655,14 @@ impl SyncCommandBufferBuilder {
}
}
let &RenderingInfo {
let RenderingInfo {
render_area_offset: _,
render_area_extent: _,
layer_count: _,
view_mask: _,
ref color_attachments,
ref depth_attachment,
ref stencil_attachment,
color_attachments,
depth_attachment,
stencil_attachment,
contents: _,
_ne,
} = &rendering_info;
@ -2076,6 +2073,7 @@ impl UnsafeCommandBufferBuilder {
}
/// Calls `vkCmdBeginRendering` on the builder.
#[inline]
pub unsafe fn begin_rendering(&mut self, rendering_info: &RenderingInfo) {
let &RenderingInfo {
render_area_offset,
@ -2178,6 +2176,7 @@ impl UnsafeCommandBufferBuilder {
}
/// Calls `vkCmdEndRendering` on the builder.
#[inline]
pub unsafe fn end_rendering(&mut self) {
let fns = self.device.fns();
@ -2193,7 +2192,6 @@ impl UnsafeCommandBufferBuilder {
///
/// Does nothing if the list of attachments or the list of rects is empty, as it would be a
/// no-op and isn't a valid usage of the command anyway.
#[inline]
pub unsafe fn clear_attachments(
&mut self,
attachments: impl IntoIterator<Item = ClearAttachment>,
@ -2490,7 +2488,9 @@ impl RenderingAttachmentResolveInfo {
}
}
/// Clear attachment type, used in [`clear_attachments`](crate::command_buffer::AutoCommandBufferBuilder::clear_attachments) command.
/// Clear attachment type, used in [`clear_attachments`] command.
///
/// [`clear_attachments`]: crate::command_buffer::AutoCommandBufferBuilder::clear_attachments
#[derive(Clone, Copy, Debug)]
pub enum ClearAttachment {
/// Clear the color attachment at the specified index, with the specified clear value.
@ -2510,6 +2510,7 @@ pub enum ClearAttachment {
}
impl From<ClearAttachment> for ash::vk::ClearAttachment {
#[inline]
fn from(v: ClearAttachment) -> Self {
match v {
ClearAttachment::Color {
@ -2550,7 +2551,9 @@ impl From<ClearAttachment> for ash::vk::ClearAttachment {
}
}
/// Specifies the clear region for the [`clear_attachments`](crate::command_buffer::AutoCommandBufferBuilder::clear_attachments) command.
/// Specifies the clear region for the [`clear_attachments`] command.
///
/// [`clear_attachments`]: crate::command_buffer::AutoCommandBufferBuilder::clear_attachments
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ClearRect {
/// The rectangle offset.
@ -2656,7 +2659,8 @@ pub enum RenderPassError {
attachment_index: u32,
},
/// The contents `SubpassContents::SecondaryCommandBuffers` is not allowed inside a secondary command buffer.
/// The contents `SubpassContents::SecondaryCommandBuffers` is not allowed inside a secondary
/// command buffer.
ContentsForbiddenInSecondaryCommandBuffer,
/// The depth attachment has a format that does not support that usage.
@ -2816,7 +2820,6 @@ pub enum RenderPassError {
}
impl Error for RenderPassError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
Self::SyncCommandBufferBuilderError(err) => Some(err),
@ -2826,11 +2829,9 @@ impl Error for RenderPassError {
}
impl Display for RenderPassError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match self {
Self::SyncCommandBufferBuilderError(_) => write!(f, "a SyncCommandBufferBuilderError"),
Self::RequirementNotMet {
required_for,
requires_one_of,
@ -2839,32 +2840,35 @@ impl Display for RenderPassError {
"a requirement was not met for: {}; requires one of: {}",
required_for, requires_one_of,
),
Self::AttachmentImageMissingUsage { attachment_index, usage } => write!(
Self::AttachmentImageMissingUsage {
attachment_index,
usage,
} => write!(
f,
"the framebuffer image attached to attachment index {} did not have the required usage {} enabled",
"the framebuffer image attached to attachment index {} did not have the required \
usage {} enabled",
attachment_index, usage,
),
Self::AutoExtentAttachmentsEmpty => write!(
f,
"one of the elements of `render_pass_extent` is zero, but no attachment images were given to calculate the extent from",
"one of the elements of `render_pass_extent` is zero, but no attachment images \
were given to calculate the extent from",
),
Self::AutoLayersAttachmentsEmpty => write!(
f,
"`layer_count` is zero, but no attachment images were given to calculate the number of layers from",
"`layer_count` is zero, but no attachment images were given to calculate the \
number of layers from",
),
Self::ClearAttachmentNotCompatible {
clear_attachment,
attachment_format,
} => write!(
f,
"a clear attachment value ({:?}) is not compatible with the attachment's format ({:?})",
clear_attachment,
attachment_format,
"a clear attachment value ({:?}) is not compatible with the attachment's format \
({:?})",
clear_attachment, attachment_format,
),
Self::ClearValueMissing {
attachment_index,
} => write!(
Self::ClearValueMissing { attachment_index } => write!(
f,
"a clear value for render pass attachment {} is missing",
attachment_index,
@ -2875,7 +2879,8 @@ impl Display for RenderPassError {
attachment_format,
} => write!(
f,
"a clear value ({:?}) provided for render pass attachment {} is not compatible with the attachment's format ({:?})",
"a clear value ({:?}) provided for render pass attachment {} is not compatible \
with the attachment's format ({:?})",
clear_value, attachment_index, attachment_format,
),
Self::ColorAttachmentIndexOutOfRange {
@ -2883,84 +2888,74 @@ impl Display for RenderPassError {
num_color_attachments,
} => write!(
f,
"an attachment clear value specifies a `color_attachment` index {} that is not less than the number of color attachments in the subpass ({})",
"an attachment clear value specifies a `color_attachment` index {} that is not \
less than the number of color attachments in the subpass ({})",
color_attachment_index, num_color_attachments,
),
Self::ColorAttachmentLayoutInvalid {
attachment_index,
} => write!(
Self::ColorAttachmentLayoutInvalid { attachment_index } => write!(
f,
"color attachment {} has a layout that is not supported",
attachment_index,
),
Self::ColorAttachmentMissingUsage {
attachment_index,
} => write!(
Self::ColorAttachmentMissingUsage { attachment_index } => write!(
f,
"color attachment {} is missing the `color_attachment` usage",
attachment_index,
),
Self::ColorAttachmentResolveFormatMismatch {
attachment_index,
} => write!(
Self::ColorAttachmentResolveFormatMismatch { attachment_index } => write!(
f,
"color attachment {} has a `format` value different from the corresponding color attachment",
"color attachment {} has a `format` value different from the corresponding color \
attachment",
attachment_index,
),
Self::ColorAttachmentResolveLayoutInvalid {
attachment_index,
} => write!(
Self::ColorAttachmentResolveLayoutInvalid { attachment_index } => write!(
f,
"color resolve attachment {} has a layout that is not supported",
attachment_index,
),
Self::ColorAttachmentResolveModeNotSupported {
attachment_index,
} => write!(
Self::ColorAttachmentResolveModeNotSupported { attachment_index } => write!(
f,
"color resolve attachment {} has a resolve mode that is not supported",
attachment_index,
),
Self::ColorAttachmentResolveMultisampled {
attachment_index,
} => write!(
Self::ColorAttachmentResolveMultisampled { attachment_index } => write!(
f,
"color resolve attachment {} has a `samples` value other than `SampleCount::Sample1`",
"color resolve attachment {} has a `samples` value other than \
`SampleCount::Sample1`",
attachment_index,
),
Self::ColorAttachmentSamplesMismatch {
attachment_index,
} => write!(
Self::ColorAttachmentSamplesMismatch { attachment_index } => write!(
f,
"color attachment {} has a `samples` value that is different from the first color attachment",
"color attachment {} has a `samples` value that is different from the first color \
attachment",
attachment_index,
),
Self::ColorAttachmentWithResolveNotMultisampled {
attachment_index,
} => write!(
Self::ColorAttachmentWithResolveNotMultisampled { attachment_index } => write!(
f,
"color attachment {} with a resolve attachment has a `samples` value of `SampleCount::Sample1`",
"color attachment {} with a resolve attachment has a `samples` value of \
`SampleCount::Sample1`",
attachment_index,
),
Self::ContentsForbiddenInSecondaryCommandBuffer => write!(
f,
"the contents `SubpassContents::SecondaryCommandBuffers` is not allowed inside a secondary command buffer",
"the contents `SubpassContents::SecondaryCommandBuffers` is not allowed inside a \
secondary command buffer",
),
Self::DepthAttachmentFormatUsageNotSupported => write!(
f,
"the depth attachment has a format that does not support that usage",
),
Self::DepthAttachmentLayoutInvalid => write!(
f,
"the depth attachment has a layout that is not supported",
),
Self::DepthAttachmentLayoutInvalid => {
write!(f, "the depth attachment has a layout that is not supported")
}
Self::DepthAttachmentMissingUsage => write!(
f,
"the depth attachment is missing the `depth_stencil_attachment` usage",
),
Self::DepthAttachmentResolveFormatMismatch => write!(
f,
"the depth resolve attachment has a `format` value different from the corresponding depth attachment",
"the depth resolve attachment has a `format` value different from the \
corresponding depth attachment",
),
Self::DepthAttachmentResolveLayoutInvalid => write!(
f,
@ -2972,15 +2967,18 @@ impl Display for RenderPassError {
),
Self::DepthAttachmentResolveMultisampled => write!(
f,
"the depth resolve attachment has a `samples` value other than `SampleCount::Sample1`",
"the depth resolve attachment has a `samples` value other than \
`SampleCount::Sample1`",
),
Self::DepthAttachmentSamplesMismatch => write!(
f,
"the depth attachment has a `samples` value that is different from the first color attachment",
"the depth attachment has a `samples` value that is different from the first color \
attachment",
),
Self::DepthAttachmentWithResolveNotMultisampled => write!(
f,
"the depth attachment has a resolve attachment and has a `samples` value of `SampleCount::Sample1`",
"the depth attachment has a resolve attachment and has a `samples` value of \
`SampleCount::Sample1`",
),
Self::DepthStencilAttachmentImageViewMismatch => write!(
f,
@ -3002,45 +3000,49 @@ impl Display for RenderPassError {
}
Self::ForbiddenWithBeginRendering => write!(
f,
"operation forbidden inside a render pass instance that was begun with `begin_rendering`",
"operation forbidden inside a render pass instance that was begun with \
`begin_rendering`",
),
Self::ForbiddenWithBeginRenderPass => write!(
f,
"operation forbidden inside a render pass instance that was begun with `begin_render_pass`",
"operation forbidden inside a render pass instance that was begun with \
`begin_render_pass`",
),
Self::ForbiddenWithInheritedRenderPass => write!(
f,
"operation forbidden inside a render pass instance that is inherited by a secondary command buffer",
"operation forbidden inside a render pass instance that is inherited by a \
secondary command buffer",
),
Self::ForbiddenWithSubpassContents { contents: subpass_contents } => write!(
Self::ForbiddenWithSubpassContents {
contents: subpass_contents,
} => write!(
f,
"operation forbidden inside a render subpass with contents {:?}",
subpass_contents,
),
Self::FramebufferNotCompatible => write!(
f,
"the framebuffer is not compatible with the render pass",
),
Self::FramebufferNotCompatible => {
write!(f, "the framebuffer is not compatible with the render pass")
}
Self::MaxColorAttachmentsExceeded { .. } => {
write!(f, "the `max_color_attachments` limit has been exceeded",)
write!(f, "the `max_color_attachments` limit has been exceeded")
}
Self::MaxMultiviewViewCountExceeded { .. } => {
write!(f, "the `max_multiview_view_count` limit has been exceeded",)
},
write!(f, "the `max_multiview_view_count` limit has been exceeded")
}
Self::MultiviewLayersInvalid => write!(
f,
"the render pass uses multiview, but `layer_count` was not 0 or 1",
),
Self::MultiviewRectArrayLayersInvalid { rect_index } => write!(
f,
"the render pass uses multiview, and in clear rectangle index {}, `array_layers` was not `0..1`",
"the render pass uses multiview, and in clear rectangle index {}, `array_layers` \
was not `0..1`",
rect_index,
),
Self::NoSubpassesRemaining {
current_subpass,
} => write!(
Self::NoSubpassesRemaining { current_subpass } => write!(
f,
"tried to advance to the next subpass after subpass {}, but there are no subpasses remaining in the render pass",
"tried to advance to the next subpass after subpass {}, but there are no subpasses \
remaining in the render pass",
current_subpass,
),
Self::NotSupportedByQueueFamily => {
@ -3048,7 +3050,7 @@ impl Display for RenderPassError {
}
Self::QueryIsActive => write!(
f,
"a query is active that conflicts with the current operation"
"a query is active that conflicts with the current operation",
),
Self::RectArrayLayersEmpty { rect_index } => write!(
f,
@ -3057,17 +3059,17 @@ impl Display for RenderPassError {
),
Self::RectArrayLayersOutOfBounds { rect_index } => write!(
f,
"clear rectangle index {} `array_layers` is outside the range of layers of the attachments",
rect_index,
),
Self::RectExtentZero { rect_index } => write!(
f,
"clear rectangle index {} `extent` is zero",
"clear rectangle index {} `array_layers` is outside the range of layers of the \
attachments",
rect_index,
),
Self::RectExtentZero { rect_index } => {
write!(f, "clear rectangle index {} `extent` is zero", rect_index)
}
Self::RectOutOfBounds { rect_index } => write!(
f,
"clear rectangle index {} `offset` and `extent` are outside the render area of the render pass instance",
"clear rectangle index {} `offset` and `extent` are outside the render area of the \
render pass instance",
rect_index,
),
Self::RenderAreaOutOfBounds => write!(
@ -3088,7 +3090,8 @@ impl Display for RenderPassError {
),
Self::StencilAttachmentResolveFormatMismatch => write!(
f,
"the stencil resolve attachment has a `format` value different from the corresponding stencil attachment",
"the stencil resolve attachment has a `format` value different from the \
corresponding stencil attachment",
),
Self::StencilAttachmentResolveLayoutInvalid => write!(
f,
@ -3100,22 +3103,26 @@ impl Display for RenderPassError {
),
Self::StencilAttachmentResolveMultisampled => write!(
f,
"the stencil resolve attachment has a `samples` value other than `SampleCount::Sample1`",
"the stencil resolve attachment has a `samples` value other than \
`SampleCount::Sample1`",
),
Self::StencilAttachmentSamplesMismatch => write!(
f,
"the stencil attachment has a `samples` value that is different from the first color attachment",
"the stencil attachment has a `samples` value that is different from the first \
color attachment",
),
Self::StencilAttachmentWithResolveNotMultisampled => write!(
f,
"the stencil attachment has a resolve attachment and has a `samples` value of `SampleCount::Sample1`",
"the stencil attachment has a resolve attachment and has a `samples` value of \
`SampleCount::Sample1`",
),
Self::SubpassesRemaining {
current_subpass,
remaining_subpasses,
} => write!(
f,
"tried to end a render pass at subpass {}, with {} subpasses still remaining in the render pass",
"tried to end a render pass at subpass {}, with {} subpasses still remaining in \
the render pass",
current_subpass, remaining_subpasses,
),
}
@ -3123,14 +3130,12 @@ impl Display for RenderPassError {
}
impl From<SyncCommandBufferBuilderError> for RenderPassError {
#[inline]
fn from(err: SyncCommandBufferBuilderError) -> Self {
Self::SyncCommandBufferBuilderError(err)
}
}
impl From<RequirementNotMet> for RenderPassError {
#[inline]
fn from(err: RequirementNotMet) -> Self {
Self::RequirementNotMet {
required_for: err.required_for,

View File

@ -59,7 +59,8 @@ where
// Secondary command buffer could leave the primary in any state.
self.inner.reset_state();
// If the secondary is non-concurrent or one-time use, that restricts the primary as well.
// If the secondary is non-concurrent or one-time use, that restricts the primary as
// well.
self.usage = std::cmp::min(self.usage, secondary_usage);
}
@ -96,7 +97,8 @@ where
// Secondary command buffer could leave the primary in any state.
self.inner.reset_state();
// If the secondary is non-concurrent or one-time use, that restricts the primary as well.
// If the secondary is non-concurrent or one-time use, that restricts the primary as
// well.
self.usage = std::cmp::min(self.usage, secondary_usage);
}
@ -411,7 +413,6 @@ pub struct SyncCommandBufferBuilderExecuteCommands<'a> {
impl<'a> SyncCommandBufferBuilderExecuteCommands<'a> {
/// Adds a command buffer to the list.
#[inline]
pub fn add(&mut self, command_buffer: impl SecondaryCommandBuffer + 'static) {
self.inner.push(Box::new(command_buffer));
}
@ -541,7 +542,6 @@ impl UnsafeCommandBufferBuilderExecuteCommands {
}
/// Adds a command buffer to the list.
#[inline]
pub fn add(&mut self, cb: &(impl SecondaryCommandBuffer + ?Sized)) {
// TODO: debug assert that it is a secondary command buffer?
self.raw_cbs.push(cb.inner().internal_object());
@ -694,7 +694,6 @@ pub enum ExecuteCommandsError {
}
impl Error for ExecuteCommandsError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
Self::SyncCommandBufferBuilderError(err) => Some(err),
@ -704,11 +703,9 @@ impl Error for ExecuteCommandsError {
}
impl Display for ExecuteCommandsError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match self {
Self::SyncCommandBufferBuilderError(_) => write!(f, "a SyncCommandBufferBuilderError"),
Self::RequirementNotMet {
required_for,
requires_one_of,
@ -717,8 +714,9 @@ impl Display for ExecuteCommandsError {
"a requirement was not met for: {}; requires one of: {}",
required_for, requires_one_of,
),
Self::ForbiddenWithSubpassContents { contents: subpass_contents } => write!(
Self::ForbiddenWithSubpassContents {
contents: subpass_contents,
} => write!(
f,
"operation forbidden inside a render subpass with contents {:?}",
subpass_contents,
@ -730,7 +728,8 @@ impl Display for ExecuteCommandsError {
command_buffer_index,
} => write!(
f,
"a render pass is active, but command buffer {} does not contain occlusion query inheritance info",
"a render pass is active, but command buffer {} does not contain occlusion query \
inheritance info",
command_buffer_index,
),
Self::OcclusionQueryFlagsNotSuperset {
@ -739,7 +738,8 @@ impl Display for ExecuteCommandsError {
inherited_flags,
} => write!(
f,
"the inherited occlusion query control flags ({:?}) of command buffer {} are not a superset of the currently active flags ({:?})",
"the inherited occlusion query control flags ({:?}) of command buffer {} are not a \
superset of the currently active flags ({:?})",
inherited_flags, command_buffer_index, required_flags,
),
Self::PipelineStatisticsQueryFlagsNotSuperset {
@ -748,7 +748,8 @@ impl Display for ExecuteCommandsError {
inherited_flags,
} => write!(
f,
"the inherited pipeline statistics query flags ({:?}) of command buffer {} are not a superset of the currently active flags ({:?})",
"the inherited pipeline statistics query flags ({:?}) of command buffer {} are not \
a superset of the currently active flags ({:?})",
inherited_flags, command_buffer_index, required_flags,
),
Self::RenderPassColorAttachmentCountMismatch {
@ -757,10 +758,9 @@ impl Display for ExecuteCommandsError {
inherited_count,
} => write!(
f,
"the inherited color attachment count ({}) of command buffer {} does not match the current attachment count ({})",
inherited_count,
command_buffer_index,
required_count,
"the inherited color attachment count ({}) of command buffer {} does not match the \
current attachment count ({})",
inherited_count, command_buffer_index, required_count,
),
Self::RenderPassColorAttachmentFormatMismatch {
command_buffer_index,
@ -769,11 +769,9 @@ impl Display for ExecuteCommandsError {
inherited_format,
} => write!(
f,
"the inherited format ({:?}) of color attachment {} of command buffer {} does not match the current attachment format ({:?})",
inherited_format,
color_attachment_index,
command_buffer_index,
required_format,
"the inherited format ({:?}) of color attachment {} of command buffer {} does not \
match the current attachment format ({:?})",
inherited_format, color_attachment_index, command_buffer_index, required_format,
),
Self::RenderPassColorAttachmentSamplesMismatch {
command_buffer_index,
@ -782,11 +780,9 @@ impl Display for ExecuteCommandsError {
inherited_samples,
} => write!(
f,
"the inherited sample count ({:?}) of color attachment {} of command buffer {} does not match the current attachment sample count ({:?})",
inherited_samples,
color_attachment_index,
command_buffer_index,
required_samples,
"the inherited sample count ({:?}) of color attachment {} of command buffer {} \
does not match the current attachment sample count ({:?})",
inherited_samples, color_attachment_index, command_buffer_index, required_samples,
),
Self::RenderPassDepthAttachmentFormatMismatch {
command_buffer_index,
@ -794,10 +790,9 @@ impl Display for ExecuteCommandsError {
inherited_format,
} => write!(
f,
"the inherited format ({:?}) of the depth attachment of command buffer {} does not match the current attachment format ({:?})",
inherited_format,
command_buffer_index,
required_format,
"the inherited format ({:?}) of the depth attachment of command buffer {} does not \
match the current attachment format ({:?})",
inherited_format, command_buffer_index, required_format,
),
Self::RenderPassDepthAttachmentSamplesMismatch {
command_buffer_index,
@ -805,37 +800,40 @@ impl Display for ExecuteCommandsError {
inherited_samples,
} => write!(
f,
"the inherited sample count ({:?}) of the depth attachment of command buffer {} does not match the current attachment sample count ({:?})",
inherited_samples,
command_buffer_index,
required_samples,
"the inherited sample count ({:?}) of the depth attachment of command buffer {} \
does not match the current attachment sample count ({:?})",
inherited_samples, command_buffer_index, required_samples,
),
Self::RenderPassFramebufferMismatch {
command_buffer_index,
} => write!(
f,
"the inherited framebuffer of command buffer {} does not match the current framebuffer",
"the inherited framebuffer of command buffer {} does not match the current \
framebuffer",
command_buffer_index,
),
Self::RenderPassInheritanceRequired {
command_buffer_index,
} => write!(
f,
"a render pass is active, but command buffer {} does not contain render pass inheritance info",
"a render pass is active, but command buffer {} does not contain render pass \
inheritance info",
command_buffer_index,
),
Self::RenderPassInheritanceForbidden {
command_buffer_index,
} => write!(
f,
"a render pass is not active, but command buffer {} contains render pass inheritance info",
"a render pass is not active, but command buffer {} contains render pass \
inheritance info",
command_buffer_index,
),
Self::RenderPassNotCompatible {
command_buffer_index,
} => write!(
f,
"the inherited render pass of command buffer {} is not compatible with the current render pass",
"the inherited render pass of command buffer {} is not compatible with the current \
render pass",
command_buffer_index,
),
Self::RenderPassStencilAttachmentFormatMismatch {
@ -844,10 +842,9 @@ impl Display for ExecuteCommandsError {
inherited_format,
} => write!(
f,
"the inherited format ({:?}) of the stencil attachment of command buffer {} does not match the current attachment format ({:?})",
inherited_format,
command_buffer_index,
required_format,
"the inherited format ({:?}) of the stencil attachment of command buffer {} does \
not match the current attachment format ({:?})",
inherited_format, command_buffer_index, required_format,
),
Self::RenderPassStencilAttachmentSamplesMismatch {
command_buffer_index,
@ -855,10 +852,9 @@ impl Display for ExecuteCommandsError {
inherited_samples,
} => write!(
f,
"the inherited sample count ({:?}) of the stencil attachment of command buffer {} does not match the current attachment sample count ({:?})",
inherited_samples,
command_buffer_index,
required_samples,
"the inherited sample count ({:?}) of the stencil attachment of command buffer {} \
does not match the current attachment sample count ({:?})",
inherited_samples, command_buffer_index, required_samples,
),
Self::RenderPassSubpassMismatch {
command_buffer_index,
@ -866,10 +862,9 @@ impl Display for ExecuteCommandsError {
inherited_subpass,
} => write!(
f,
"the inherited subpass index ({}) of command buffer {} does not match the current subpass index ({})",
inherited_subpass,
command_buffer_index,
required_subpass,
"the inherited subpass index ({}) of command buffer {} does not match the current \
subpass index ({})",
inherited_subpass, command_buffer_index, required_subpass,
),
Self::RenderPassTypeMismatch {
command_buffer_index,
@ -884,17 +879,15 @@ impl Display for ExecuteCommandsError {
inherited_view_mask,
} => write!(
f,
"the inherited view mask ({}) of command buffer {} does not match the current view mask ({})",
inherited_view_mask,
command_buffer_index,
required_view_mask,
"the inherited view mask ({}) of command buffer {} does not match the current view \
mask ({})",
inherited_view_mask, command_buffer_index, required_view_mask,
),
}
}
}
impl From<SyncCommandBufferBuilderError> for ExecuteCommandsError {
#[inline]
fn from(err: SyncCommandBufferBuilderError) -> Self {
Self::SyncCommandBufferBuilderError(err)
}

View File

@ -40,7 +40,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
///
/// - Panics if `src_buffer` or `dst_buffer` were not created from the same device
/// as `self`.
#[inline]
pub fn copy_buffer(
&mut self,
copy_buffer_info: impl Into<CopyBufferInfo>,
@ -192,7 +191,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
///
/// - Panics if `src_image` or `dst_image` were not created from the same device
/// as `self`.
#[inline]
pub fn copy_image(&mut self, copy_image_info: CopyImageInfo) -> Result<&mut Self, CopyError> {
self.validate_copy_image(&copy_image_info)?;
@ -872,7 +870,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
}
/// Copies from a buffer to an image.
#[inline]
pub fn copy_buffer_to_image(
&mut self,
copy_buffer_to_image_info: CopyBufferToImageInfo,
@ -1304,7 +1301,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
}
/// Copies from an image to a buffer.
#[inline]
pub fn copy_image_to_buffer(
&mut self,
copy_image_to_buffer_info: CopyImageToBufferInfo,
@ -1736,7 +1732,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
/// # Panics
///
/// - Panics if `dst_buffer` was not created from the same device as `self`.
#[inline]
pub fn fill_buffer(
&mut self,
fill_buffer_info: FillBufferInfo,
@ -1840,7 +1835,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
/// # Panics
///
/// - Panics if `dst_buffer` was not created from the same device as `self`.
#[inline]
pub fn update_buffer<B, D, Dd>(
&mut self,
data: Dd,
@ -2410,7 +2404,6 @@ impl SyncCommandBufferBuilder {
}
/// Calls `vkCmdUpdateBuffer` on the builder.
#[inline]
pub unsafe fn update_buffer<D, Dd>(
&mut self,
data: Dd,
@ -2998,7 +2991,6 @@ impl UnsafeCommandBufferBuilder {
}
/// Calls `vkCmdUpdateBuffer` on the builder.
#[inline]
pub unsafe fn update_buffer<D>(
&mut self,
data: &D,
@ -3098,7 +3090,6 @@ where
D: TypedBufferAccess<Content = [T]>,
{
/// Returns a `CopyBufferInfoTyped` with the specified `src_buffer` and `dst_buffer`.
#[inline]
pub fn buffers(src_buffer: Arc<S>, dst_buffer: Arc<D>) -> Self {
let region = BufferCopy {
size: min(src_buffer.len(), dst_buffer.len()),
@ -3119,7 +3110,6 @@ where
S: TypedBufferAccess<Content = [T]> + 'static,
D: TypedBufferAccess<Content = [T]> + 'static,
{
#[inline]
fn from(typed: CopyBufferInfoTyped<S, D, T>) -> Self {
let CopyBufferInfoTyped {
src_buffer,

View File

@ -48,12 +48,13 @@ mod sys;
/// free the command buffer, reset the command buffer, or add it to a pool so that it gets reused.
/// If the implementation frees or resets the command buffer, it must not forget that this
/// operation must lock the pool.
///
pub unsafe trait CommandPool: DeviceOwned {
/// See `alloc()`.
type Iter: Iterator<Item = Self::Builder>;
/// Represents a command buffer that has been allocated and that is currently being built.
type Builder: CommandPoolBuilderAlloc<Alloc = Self::Alloc>;
/// Represents a command buffer that has been allocated and that is pending execution or is
/// being executed.
type Alloc: CommandPoolAlloc;
@ -76,7 +77,6 @@ pub unsafe trait CommandPool: DeviceOwned {
/// # Safety
///
/// See `CommandPool` for information about safety.
///
pub unsafe trait CommandPoolBuilderAlloc: DeviceOwned {
/// Return type of `into_alloc`.
type Alloc: CommandPoolAlloc;
@ -96,7 +96,6 @@ pub unsafe trait CommandPoolBuilderAlloc: DeviceOwned {
/// # Safety
///
/// See `CommandPool` for information about safety.
///
pub unsafe trait CommandPoolAlloc: DeviceOwned + Send + Sync {
/// Returns the internal object that contains the command buffer.
fn inner(&self) -> &UnsafeCommandPoolAlloc;

View File

@ -77,6 +77,7 @@ unsafe impl CommandPool for Arc<StandardCommandPool> {
type Builder = StandardCommandPoolBuilder;
type Alloc = StandardCommandPoolAlloc;
#[inline]
fn allocate(
&self,
level: CommandBufferLevel,
@ -212,6 +213,7 @@ unsafe impl DeviceOwned for StandardCommandPoolAlloc {
}
impl Drop for StandardCommandPoolAlloc {
#[inline]
fn drop(&mut self) {
// Safe because `self.cmd` is wrapped in a `ManuallyDrop`.
let cmd: UnsafeCommandPoolAlloc = unsafe { ptr::read(&*self.cmd) };

View File

@ -78,6 +78,7 @@ impl UnsafeCommandPool {
///
/// - `handle` must be a valid Vulkan object handle created from `device`.
/// - `create_info` must match the info used to create the object.
#[inline]
pub unsafe fn from_handle(
device: Arc<Device>,
handle: ash::vk::CommandPool,
@ -175,6 +176,7 @@ impl UnsafeCommandPool {
/// # Safety
///
/// - The command buffers allocated from this pool jump to the initial state.
#[inline]
pub unsafe fn reset(&self, release_resources: bool) -> Result<(), OomError> {
let flags = if release_resources {
ash::vk::CommandPoolResetFlags::RELEASE_RESOURCES
@ -186,10 +188,12 @@ impl UnsafeCommandPool {
(fns.v1_0.reset_command_pool)(self.device.internal_object(), self.handle, flags)
.result()
.map_err(VulkanError::from)?;
Ok(())
}
/// Allocates command buffers.
#[inline]
pub fn allocate_command_buffers(
&self,
allocate_info: CommandBufferAllocateInfo,
@ -269,6 +273,7 @@ impl UnsafeCommandPool {
/// enabled on the device. Otherwise an error is returned.
/// Since this operation is purely an optimization it is legitimate to call this function and
/// simply ignore any possible error.
#[inline]
pub fn trim(&self) -> Result<(), CommandPoolTrimError> {
if !(self.device.api_version() >= Version::V1_1
|| self.device.enabled_extensions().khr_maintenance1)
@ -351,7 +356,6 @@ impl PartialEq for UnsafeCommandPool {
impl Eq for UnsafeCommandPool {}
impl Hash for UnsafeCommandPool {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.handle.hash(state);
self.device().hash(state);
@ -373,26 +377,25 @@ pub enum UnsafeCommandPoolCreationError {
}
impl Error for UnsafeCommandPoolCreationError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match *self {
Self::OomError(ref err) => Some(err),
match self {
Self::OomError(err) => Some(err),
_ => None,
}
}
}
impl Display for UnsafeCommandPoolCreationError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match *self {
match self {
Self::OomError(_) => write!(f, "not enough memory",),
Self::QueueFamilyIndexOutOfRange {
queue_family_index,
queue_family_count,
} => write!(
f,
"the provided `queue_family_index` ({}) was not less than the number of queue families in the physical device ({})",
"the provided `queue_family_index` ({}) was not less than the number of queue \
families in the physical device ({})",
queue_family_index, queue_family_count,
),
}
@ -400,7 +403,6 @@ impl Display for UnsafeCommandPoolCreationError {
}
impl From<VulkanError> for UnsafeCommandPoolCreationError {
#[inline]
fn from(err: VulkanError) -> Self {
match err {
err @ VulkanError::OutOfHostMemory => Self::OomError(OomError::from(err)),
@ -513,7 +515,6 @@ impl PartialEq for UnsafeCommandPoolAlloc {
impl Eq for UnsafeCommandPoolAlloc {}
impl Hash for UnsafeCommandPoolAlloc {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.handle.hash(state);
self.device().hash(state);
@ -532,7 +533,6 @@ pub enum CommandPoolTrimError {
impl Error for CommandPoolTrimError {}
impl Display for CommandPoolTrimError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match self {
Self::RequirementNotMet {
@ -548,7 +548,6 @@ impl Display for CommandPoolTrimError {
}
impl From<VulkanError> for CommandPoolTrimError {
#[inline]
fn from(err: VulkanError) -> CommandPoolTrimError {
panic!("unexpected error: {:?}", err)
}

View File

@ -119,6 +119,7 @@ impl SyncCommandBufferBuilder {
/// # Safety
///
/// See `UnsafeCommandBufferBuilder::new()`.
#[inline]
pub unsafe fn new(
pool_alloc: &UnsafeCommandPoolAlloc,
begin_info: CommandBufferBeginInfo,
@ -131,8 +132,8 @@ impl SyncCommandBufferBuilder {
.unwrap()
.render_pass
.is_some();
let inner = UnsafeCommandBufferBuilder::new(pool_alloc, begin_info)?;
Ok(SyncCommandBufferBuilder::from_unsafe_cmd(
inner,
level,
@ -346,18 +347,17 @@ impl SyncCommandBufferBuilder {
None
}
// Adds a command to be processed by the builder.
//
// The `resources` argument should contain each buffer or image used by the command.
// The function will take care of handling the pipeline barrier or flushing.
//
// - The index of the resource within the `resources` slice maps to the resource accessed
// through `Command::buffer(..)` or `Command::image(..)`.
// - `PipelineMemoryAccess` must match the way the resource has been used.
// - `start_layout` and `end_layout` designate the image layout that the image is expected to be
// in when the command starts, and the image layout that the image will be transitioned to
// during the command. When it comes to buffers, you should pass `Undefined` for both.
#[inline]
/// Adds a command to be processed by the builder.
///
/// The `resources` argument should contain each buffer or image used by the command.
/// The function will take care of handling the pipeline barrier or flushing.
///
/// - The index of the resource within the `resources` slice maps to the resource accessed
/// through `Command::buffer(..)` or `Command::image(..)`.
/// - `PipelineMemoryAccess` must match the way the resource has been used.
/// - `start_layout` and `end_layout` designate the image layout that the image is expected to
/// be in when the command starts, and the image layout that the image will be transitioned to
/// during the command. When it comes to buffers, you should pass `Undefined` for both.
pub(in crate::command_buffer) fn add_resource(
&mut self,
resource: (Cow<'static, str>, Resource),
@ -610,26 +610,30 @@ impl SyncCommandBufferBuilder {
// We can't transition to `Preinitialized`,
// so all we can do here is error out.
// TODO: put this in find_image_conflict instead?
panic!("Command requires Preinitialized layout, but the initial layout of the image is not Preinitialized");
panic!(
"Command requires Preinitialized layout, but the \
initial layout of the image is not Preinitialized"
);
}
_ => {
// Insert a layout transition.
// A layout transition is a write, so if we perform one, we need
// exclusive access.
// A layout transition is a write, so if we perform one, we
// need exclusive access.
state.memory.exclusive = true; // TODO: is this correct?
state.exclusive_any = true;
// Note that we transition from `bottom_of_pipe`, which means that we
// wait for all the previous commands to be entirely finished. This is
// suboptimal, but:
//
// - If we're at the start of the command buffer we have no choice anyway,
// because we have no knowledge about what comes before.
// - If we're in the middle of the command buffer, this pipeline is going
// to be merged with an existing barrier. While it may still be
// suboptimal in some cases, in the general situation it will be ok.
// Note that we transition from `bottom_of_pipe`, which
// means that we wait for all the previous commands to be
// entirely finished. This is suboptimal, but:
//
// - If we're at the start of the command buffer we have no
// choice anyway, because we have no knowledge about what
// comes before.
// - If we're in the middle of the command buffer, this
// pipeline is going to be merged with an existing
// barrier. While it may still be suboptimal in some
// cases, in the general situation it will be ok.
self.pending_barrier.image_memory_barriers.push(
ImageMemoryBarrier {
source_stages: PipelineStages {
@ -862,7 +866,6 @@ unsafe impl DeviceOwned for SyncCommandBufferBuilder {
}
impl Debug for SyncCommandBufferBuilder {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
Debug::fmt(&self.inner, f)
}
@ -885,7 +888,6 @@ pub enum SyncCommandBufferBuilderError {
impl Error for SyncCommandBufferBuilderError {}
impl Display for SyncCommandBufferBuilderError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match self {
SyncCommandBufferBuilderError::Conflict { .. } => write!(f, "unsolvable conflict"),
@ -895,7 +897,6 @@ impl Display for SyncCommandBufferBuilderError {
}
impl From<CommandBufferExecError> for SyncCommandBufferBuilderError {
#[inline]
fn from(val: CommandBufferExecError) -> Self {
SyncCommandBufferBuilderError::ExecError(val)
}
@ -1101,6 +1102,7 @@ pub enum SetOrPush {
}
impl SetOrPush {
#[inline]
pub fn resources(&self) -> &DescriptorSetResources {
match self {
Self::Set(set) => set.as_ref().0.resources(),
@ -1304,7 +1306,8 @@ impl<'a> CommandBufferState<'a> {
self.current_state.rasterizer_discard_enable
}
/// Returns the current scissor for a given viewport slot, or `None` if nothing has been set yet.
/// Returns the current scissor for a given viewport slot, or `None` if nothing has been set
/// yet.
#[inline]
pub fn scissor(&self, num: u32) -> Option<&'a Scissor> {
self.current_state.scissor.get(&num)
@ -1349,7 +1352,8 @@ impl<'a> CommandBufferState<'a> {
self.current_state.stencil_write_mask
}
/// Returns the current viewport for a given viewport slot, or `None` if nothing has been set yet.
/// Returns the current viewport for a given viewport slot, or `None` if nothing has been set
/// yet.
#[inline]
pub fn viewport(&self, num: u32) -> Option<&'a Viewport> {
self.current_state.viewport.get(&num)

View File

@ -131,6 +131,7 @@ impl SyncCommandBuffer {
/// Tries to lock the resources used by the command buffer.
///
/// > **Note**: You should call this in the implementation of the `CommandBuffer` trait.
#[inline]
pub fn lock_submit(
&self,
future: &dyn GpuFuture,
@ -281,7 +282,7 @@ impl SyncCommandBuffer {
/// # Safety
///
/// The command buffer must have been successfully locked with `lock_submit()`.
///
#[inline]
pub unsafe fn unlock(&self) {
for (buffer, range_map) in &self.buffers2 {
let mut buffer_state = buffer.state();

View File

@ -50,6 +50,7 @@ impl UnsafeCommandBufferBuilder {
///
/// - `pool_alloc` must outlive the returned builder and its created command buffer.
/// - `kind` must match how `pool_alloc` was created.
#[inline]
pub unsafe fn new(
pool_alloc: &UnsafeCommandPoolAlloc,
begin_info: CommandBufferBeginInfo,

View File

@ -68,9 +68,9 @@ pub unsafe trait PrimaryCommandBuffer: DeviceOwned + Send + Sync {
///
/// > **Note**: This is just a shortcut for `execute_after(vulkano::sync::now(), queue)`.
///
/// # Panic
/// # Panics
///
/// Panics if the device of the command buffer is not the same as the device of the future.
/// - Panics if the device of the command buffer is not the same as the device of the future.
#[inline]
fn execute(
self,
@ -102,10 +102,9 @@ pub unsafe trait PrimaryCommandBuffer: DeviceOwned + Send + Sync {
/// `std::mem::forget` on that object and "unlock" these resources. For more information about
/// this problem, search the web for "rust thread scoped leakpocalypse".
///
/// # Panic
/// # Panics
///
/// Panics if the device of the command buffer is not the same as the device of the future.
#[inline]
/// - Panics if the device of the command buffer is not the same as the device of the future.
fn execute_after<F>(
self,
future: F,
@ -164,12 +163,10 @@ where
T: SafeDeref + Send + Sync,
T::Target: PrimaryCommandBuffer,
{
#[inline]
fn inner(&self) -> &UnsafeCommandBuffer {
(**self).inner()
}
#[inline]
fn lock_submit(
&self,
future: &dyn GpuFuture,
@ -178,12 +175,10 @@ where
(**self).lock_submit(future, queue)
}
#[inline]
unsafe fn unlock(&self) {
(**self).unlock();
}
#[inline]
fn check_buffer_access(
&self,
buffer: &UnsafeBuffer,
@ -194,7 +189,6 @@ where
(**self).check_buffer_access(buffer, range, exclusive, queue)
}
#[inline]
fn check_image_access(
&self,
image: &UnsafeImage,
@ -266,32 +260,26 @@ where
T: SafeDeref + Send + Sync,
T::Target: SecondaryCommandBuffer,
{
#[inline]
fn inner(&self) -> &UnsafeCommandBuffer {
(**self).inner()
}
#[inline]
fn lock_record(&self) -> Result<(), CommandBufferExecError> {
(**self).lock_record()
}
#[inline]
unsafe fn unlock(&self) {
(**self).unlock();
}
#[inline]
fn inheritance_info(&self) -> &CommandBufferInheritanceInfo {
(**self).inheritance_info()
}
#[inline]
fn num_buffers(&self) -> usize {
(**self).num_buffers()
}
#[inline]
fn buffer(
&self,
index: usize,
@ -303,12 +291,10 @@ where
(**self).buffer(index)
}
#[inline]
fn num_images(&self) -> usize {
(**self).num_images()
}
#[inline]
fn image(
&self,
index: usize,
@ -325,6 +311,7 @@ where
/// Represents a command buffer being executed by the GPU and the moment when the execution
/// finishes.
#[derive(Debug)]
#[must_use = "Dropping this object will immediately block the thread until the GPU has finished processing the submission"]
pub struct CommandBufferExecFuture<F>
where
@ -399,7 +386,6 @@ unsafe impl<F> GpuFuture for CommandBufferExecFuture<F>
where
F: GpuFuture,
{
#[inline]
fn cleanup_finished(&mut self) {
self.previous.cleanup_finished();
}
@ -412,7 +398,6 @@ where
self.build_submission_impl()
}
#[inline]
fn flush(&self) -> Result<(), FlushError> {
unsafe {
let mut submitted = self.submitted.lock();
@ -436,23 +421,19 @@ where
}
}
#[inline]
unsafe fn signal_finished(&self) {
self.finished.store(true, Ordering::SeqCst);
self.previous.signal_finished();
}
#[inline]
fn queue_change_allowed(&self) -> bool {
false
}
#[inline]
fn queue(&self) -> Option<Arc<Queue>> {
Some(self.queue.clone())
}
#[inline]
fn check_buffer_access(
&self,
buffer: &UnsafeBuffer,
@ -472,7 +453,6 @@ where
}
}
#[inline]
fn check_image_access(
&self,
image: &UnsafeImage,
@ -511,7 +491,6 @@ unsafe impl<F> DeviceOwned for CommandBufferExecFuture<F>
where
F: GpuFuture,
{
#[inline]
fn device(&self) -> &Arc<Device> {
self.command_buffer.device()
}
@ -556,32 +535,30 @@ pub enum CommandBufferExecError {
}
impl Error for CommandBufferExecError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match *self {
CommandBufferExecError::AccessError { ref error, .. } => Some(error),
match self {
CommandBufferExecError::AccessError { error, .. } => Some(error),
_ => None,
}
}
}
impl Display for CommandBufferExecError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
write!(
f,
"{}",
match *self {
match self {
CommandBufferExecError::AccessError { .. } =>
"access to a resource has been denied",
CommandBufferExecError::OneTimeSubmitAlreadySubmitted => {
"the command buffer or one of the secondary command buffers it executes was \
created with the \"one time submit\" flag, but has already been submitted in \
the past"
created with the \"one time submit\" flag, but has already been submitted in \
the past"
}
CommandBufferExecError::ExclusiveAlreadyInUse => {
"the command buffer or one of the secondary command buffers it executes is \
already in use was not created with the \"concurrent\" flag"
already in use was not created with the \"concurrent\" flag"
}
}
)

View File

@ -25,7 +25,6 @@ unsafe impl<T> DescriptorSetsCollection for T
where
T: Into<DescriptorSetWithOffsets>,
{
#[inline]
fn into_vec(self) -> Vec<DescriptorSetWithOffsets> {
vec![self.into()]
}
@ -35,7 +34,6 @@ unsafe impl<T> DescriptorSetsCollection for Vec<T>
where
T: Into<DescriptorSetWithOffsets>,
{
#[inline]
fn into_vec(self) -> Vec<DescriptorSetWithOffsets> {
self.into_iter().map(|x| x.into()).collect()
}

View File

@ -43,6 +43,7 @@ pub struct DescriptorSetLayout {
impl DescriptorSetLayout {
/// Creates a new `DescriptorSetLayout`.
#[inline]
pub fn new(
device: Arc<Device>,
mut create_info: DescriptorSetLayoutCreateInfo,
@ -73,6 +74,7 @@ impl DescriptorSetLayout {
///
/// - `handle` must be a valid Vulkan object handle created from `device`.
/// - `create_info` must match the info used to create the object.
#[inline]
pub unsafe fn from_handle(
device: Arc<Device>,
handle: ash::vk::DescriptorSetLayout,
@ -461,7 +463,6 @@ impl PartialEq for DescriptorSetLayout {
impl Eq for DescriptorSetLayout {}
impl Hash for DescriptorSetLayout {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.handle.hash(state);
self.device().hash(state);
@ -520,13 +521,11 @@ impl From<VulkanError> for DescriptorSetLayoutCreationError {
impl Error for DescriptorSetLayoutCreationError {}
impl Display for DescriptorSetLayoutCreationError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match *self {
match self {
Self::OomError(_) => {
write!(f, "out of memory")
}
Self::RequirementNotMet {
required_for,
requires_one_of,
@ -535,15 +534,20 @@ impl Display for DescriptorSetLayoutCreationError {
"a requirement was not met for: {}; requires one of: {}",
required_for, requires_one_of,
),
Self::ImmutableSamplersCountMismatch { binding_num, sampler_count, descriptor_count } => write!(
Self::ImmutableSamplersCountMismatch {
binding_num,
sampler_count,
descriptor_count,
} => write!(
f,
"binding {} includes immutable samplers but their number ({}) differs from `descriptor_count` ({})",
"binding {} includes immutable samplers but their number ({}) differs from \
`descriptor_count` ({})",
binding_num, sampler_count, descriptor_count,
),
Self::ImmutableSamplersDescriptorTypeIncompatible { binding_num } => write!(
f,
"binding {} includes immutable samplers but it has an incompatible `descriptor_type`",
"binding {} includes immutable samplers but it has an incompatible \
`descriptor_type`",
binding_num,
),
Self::MaxPushDescriptorsExceeded {
@ -551,27 +555,35 @@ impl Display for DescriptorSetLayoutCreationError {
max_supported,
} => write!(
f,
"more descriptors were provided in all bindings ({}) than the `max_push_descriptors` limit ({})",
"more descriptors were provided in all bindings ({}) than the \
`max_push_descriptors` limit ({})",
provided, max_supported,
),
Self::PushDescriptorDescriptorTypeIncompatible { binding_num } => write!(
f,
"`push_descriptor` is enabled, but binding {} has an incompatible `descriptor_type`",
"`push_descriptor` is enabled, but binding {} has an incompatible \
`descriptor_type`",
binding_num,
),
Self::PushDescriptorVariableDescriptorCount { binding_num } => write!(
f,
"`push_descriptor` is enabled, but binding {} has `variable_descriptor_count` enabled",
"`push_descriptor` is enabled, but binding {} has `variable_descriptor_count` \
enabled",
binding_num,
),
Self::VariableDescriptorCountBindingNotHighest { binding_num, highest_binding_num } => write!(
Self::VariableDescriptorCountBindingNotHighest {
binding_num,
highest_binding_num,
} => write!(
f,
"binding {} has `variable_descriptor_count` enabled, but it is not the highest-numbered binding ({})",
"binding {} has `variable_descriptor_count` enabled, but it is not the \
highest-numbered binding ({})",
binding_num, highest_binding_num,
),
Self::VariableDescriptorCountDescriptorTypeIncompatible { binding_num } => write!(
f,
"binding {} has `variable_descriptor_count` enabled, but it has an incompatible `descriptor_type`",
"binding {} has `variable_descriptor_count` enabled, but it has an incompatible \
`descriptor_type`",
binding_num,
),
}
@ -579,7 +591,6 @@ impl Display for DescriptorSetLayoutCreationError {
}
impl From<RequirementNotMet> for DescriptorSetLayoutCreationError {
#[inline]
fn from(err: RequirementNotMet) -> Self {
Self::RequirementNotMet {
required_for: err.required_for,
@ -633,7 +644,6 @@ impl Default for DescriptorSetLayoutCreateInfo {
impl DescriptorSetLayoutCreateInfo {
/// Builds a list of `DescriptorSetLayoutCreateInfo` from an iterator of `DescriptorRequirement`
/// originating from a shader.
#[inline]
pub fn from_requirements<'a>(
descriptor_requirements: impl IntoIterator<Item = ((u32, u32), &'a DescriptorRequirements)>,
) -> Vec<Self> {
@ -671,16 +681,17 @@ pub struct DescriptorSetLayoutBinding {
/// Whether the binding has a variable number of descriptors.
///
/// If set to `true`, the
/// [`descriptor_binding_variable_descriptor_count`](crate::device::Features::descriptor_binding_variable_descriptor_count)
/// feature must be enabled. The value of `descriptor_count` specifies the maximum number of
/// descriptors allowed.
/// If set to `true`, the [`descriptor_binding_variable_descriptor_count`] feature must be
/// enabled. The value of `descriptor_count` specifies the maximum number of descriptors
/// allowed.
///
/// There may only be one binding with a variable count in a descriptor set, and it must be the
/// binding with the highest binding number. The `descriptor_type` must not be
/// [`DescriptorType::UniformBufferDynamic`] or [`DescriptorType::StorageBufferDynamic`].
///
/// The default value is `false`.
///
/// [`descriptor_binding_variable_descriptor_count`]: crate::device::Features::descriptor_binding_variable_descriptor_count
pub variable_descriptor_count: bool,
/// Which shader stages are going to access the descriptors in this binding.
@ -768,6 +779,7 @@ impl DescriptorSetLayoutBinding {
}
impl From<&DescriptorRequirements> for DescriptorSetLayoutBinding {
#[inline]
fn from(reqs: &DescriptorRequirements) -> Self {
Self {
descriptor_type: reqs.descriptor_types[0],
@ -802,18 +814,17 @@ pub enum DescriptorRequirementsNotMet {
impl Error for DescriptorRequirementsNotMet {}
impl Display for DescriptorRequirementsNotMet {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match self {
Self::DescriptorType { required, obtained } => write!(
f,
"the descriptor's type ({:?}) is not one of those required ({:?})",
obtained, required
obtained, required,
),
Self::DescriptorCount { required, obtained } => write!(
f,
"the descriptor count ({}) is less than what is required ({})",
obtained, required
obtained, required,
),
Self::ShaderStages { .. } => write!(
f,

View File

@ -22,7 +22,7 @@
//! that are often used together in the same set so that you can keep the same set binding through
//! multiple draws.
//!
//! # Example
//! # Examples
//!
//! > **Note**: This section describes the simple way to bind resources. There are more optimized
//! > ways.
@ -143,7 +143,6 @@ impl PartialEq for dyn DescriptorSet {
impl Eq for dyn DescriptorSet {}
impl Hash for dyn DescriptorSet {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.inner().internal_object().hash(state);
self.device().hash(state);
@ -164,14 +163,16 @@ impl DescriptorSetInner {
) -> Result<Self, DescriptorSetUpdateError> {
assert!(
!layout.push_descriptor(),
"the provided descriptor set layout is for push descriptors, and cannot be used to build a descriptor set object"
"the provided descriptor set layout is for push descriptors, and cannot be used to \
build a descriptor set object",
);
let max_count = layout.variable_descriptor_count();
assert!(
variable_descriptor_count <= max_count,
"the provided variable_descriptor_count ({}) is greater than the maximum number of variable count descriptors in the layout ({})",
"the provided variable_descriptor_count ({}) is greater than the maximum number of \
variable count descriptors in the layout ({})",
variable_descriptor_count,
max_count,
);
@ -247,6 +248,7 @@ pub struct DescriptorSetResources {
impl DescriptorSetResources {
/// Creates a new `DescriptorSetResources` matching the provided descriptor set layout, and
/// all descriptors set to `None`.
#[inline]
pub fn new(layout: &DescriptorSetLayout, variable_descriptor_count: u32) -> Self {
assert!(variable_descriptor_count <= layout.variable_descriptor_count());
@ -309,6 +311,7 @@ impl DescriptorSetResources {
///
/// - Panics if the binding number of a write does not exist in the resources.
/// - See also [`DescriptorBindingResources::update`].
#[inline]
pub fn update(&mut self, write: &WriteDescriptorSet) {
self.binding_resources
.get_mut(&write.binding())
@ -344,6 +347,7 @@ impl DescriptorBindingResources {
///
/// - Panics if the resource types do not match.
/// - Panics if the write goes out of bounds.
#[inline]
pub fn update(&mut self, write: &WriteDescriptorSet) {
fn write_resources<T: Clone>(first: usize, resources: &mut [Option<T>], elements: &[T]) {
resources
@ -406,7 +410,6 @@ pub struct DescriptorSetWithOffsets {
}
impl DescriptorSetWithOffsets {
#[inline]
pub fn new(
descriptor_set: Arc<dyn DescriptorSet>,
dynamic_offsets: impl IntoIterator<Item = u32>,
@ -428,9 +431,10 @@ impl DescriptorSetWithOffsets {
if dynamic_offsets.len() > dynamic_offset_index {
assert!(
dynamic_offsets[dynamic_offset_index] % min_storage_off_align == 0,
"Dynamic storage buffer offset must be a multiple of min_storage_buffer_offset_alignment: got {}, expected a multiple of {}",
"Dynamic storage buffer offset must be a multiple of \
min_storage_buffer_offset_alignment: got {}, expected a multiple of {}",
dynamic_offsets[dynamic_offset_index],
min_storage_off_align
min_storage_off_align,
);
}
dynamic_offset_index += 1;
@ -440,9 +444,10 @@ impl DescriptorSetWithOffsets {
if dynamic_offsets.len() > dynamic_offset_index {
assert!(
dynamic_offsets[dynamic_offset_index] % min_uniform_off_align == 0,
"Dynamic uniform buffer offset must be a multiple of min_uniform_buffer_offset_alignment: got {}, expected a multiple of {}",
"Dynamic uniform buffer offset must be a multiple of \
min_uniform_buffer_offset_alignment: got {}, expected a multiple of {}",
dynamic_offsets[dynamic_offset_index],
min_uniform_off_align
min_uniform_off_align,
);
}
dynamic_offset_index += 1;
@ -455,13 +460,13 @@ impl DescriptorSetWithOffsets {
dynamic_offsets.len() >= dynamic_offset_index,
"Too few dynamic offsets: got {}, expected {}",
dynamic_offsets.len(),
dynamic_offset_index
dynamic_offset_index,
);
assert!(
dynamic_offsets.len() <= dynamic_offset_index,
"Too many dynamic offsets: got {}, expected {}",
dynamic_offsets.len(),
dynamic_offset_index
dynamic_offset_index,
);
DescriptorSetWithOffsets {
@ -485,7 +490,6 @@ impl<S> From<Arc<S>> for DescriptorSetWithOffsets
where
S: DescriptorSet + 'static,
{
#[inline]
fn from(descriptor_set: Arc<S>) -> Self {
DescriptorSetWithOffsets::new(descriptor_set, std::iter::empty())
}
@ -498,7 +502,6 @@ pub enum DescriptorSetCreationError {
}
impl Error for DescriptorSetCreationError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
Self::DescriptorSetUpdateError(err) => Some(err),
@ -508,7 +511,6 @@ impl Error for DescriptorSetCreationError {
}
impl Display for DescriptorSetCreationError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match self {
Self::DescriptorSetUpdateError(_) => {
@ -520,14 +522,12 @@ impl Display for DescriptorSetCreationError {
}
impl From<DescriptorSetUpdateError> for DescriptorSetCreationError {
#[inline]
fn from(err: DescriptorSetUpdateError) -> Self {
Self::DescriptorSetUpdateError(err)
}
}
impl From<OomError> for DescriptorSetCreationError {
#[inline]
fn from(err: OomError) -> Self {
Self::OomError(err)
}

View File

@ -18,7 +18,7 @@
//! > actual allocation, you can skip this allocation and make it acceptable to use a persistent
//! > descriptor set in performance-critical paths..
//!
//! # Example
//! # Examples
//! TODO:
use crate::{
@ -124,17 +124,14 @@ unsafe impl<P> DescriptorSet for PersistentDescriptorSet<P>
where
P: DescriptorPoolAlloc,
{
#[inline]
fn inner(&self) -> &UnsafeDescriptorSet {
self.alloc.inner()
}
#[inline]
fn layout(&self) -> &Arc<DescriptorSetLayout> {
self.inner.layout()
}
#[inline]
fn resources(&self) -> &DescriptorSetResources {
self.inner.resources()
}
@ -144,7 +141,6 @@ unsafe impl<P> DeviceOwned for PersistentDescriptorSet<P>
where
P: DescriptorPoolAlloc,
{
#[inline]
fn device(&self) -> &Arc<Device> {
self.inner.layout().device()
}
@ -154,7 +150,6 @@ impl<P> PartialEq for PersistentDescriptorSet<P>
where
P: DescriptorPoolAlloc,
{
#[inline]
fn eq(&self, other: &Self) -> bool {
self.inner().internal_object() == other.inner().internal_object()
&& self.device() == other.device()
@ -167,7 +162,6 @@ impl<P> Hash for PersistentDescriptorSet<P>
where
P: DescriptorPoolAlloc,
{
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.inner().internal_object().hash(state);
self.device().hash(state);

View File

@ -41,6 +41,7 @@ enum Pool {
impl StandardDescriptorPool {
/// Builds a new `StandardDescriptorPool`.
#[inline]
pub fn new(device: Arc<Device>) -> StandardDescriptorPool {
StandardDescriptorPool {
device,
@ -52,6 +53,7 @@ impl StandardDescriptorPool {
unsafe impl DescriptorPool for StandardDescriptorPool {
type Alloc = StandardDescriptorPoolAlloc;
#[inline]
fn allocate(
&mut self,
layout: &Arc<DescriptorSetLayout>,

View File

@ -124,6 +124,7 @@ impl UnsafeDescriptorPool {
///
/// - `handle` must be a valid Vulkan object handle created from `device`.
/// - `create_info` must match the info used to create the object.
#[inline]
pub unsafe fn from_handle(
device: Arc<Device>,
handle: ash::vk::DescriptorPool,
@ -170,7 +171,7 @@ impl UnsafeDescriptorPool {
/// The `FragmentedPool` errors often can't be prevented. If the function returns this error,
/// you should just create a new pool.
///
/// # Panic
/// # Panics
///
/// - Panics if one of the layouts wasn't created with the same device as the pool.
///
@ -182,7 +183,6 @@ impl UnsafeDescriptorPool {
/// - The total number of descriptor sets allocated from the pool must not overflow the pool.
/// - You must ensure that the allocated descriptor sets are no longer in use when the pool
/// is destroyed, as destroying the pool is equivalent to freeing all the sets.
///
pub unsafe fn allocate_descriptor_sets<'a>(
&mut self,
allocate_info: impl IntoIterator<Item = DescriptorSetAllocateInfo<'a>>,
@ -281,7 +281,6 @@ impl UnsafeDescriptorPool {
/// - The descriptor sets must have been allocated from the pool.
/// - The descriptor sets must not be free'd twice.
/// - The descriptor sets must not be in use by the GPU.
///
pub unsafe fn free_descriptor_sets(
&mut self,
descriptor_sets: impl IntoIterator<Item = UnsafeDescriptorSet>,
@ -308,6 +307,7 @@ impl UnsafeDescriptorPool {
/// Resets the pool.
///
/// This destroys all descriptor sets and empties the pool.
#[inline]
pub unsafe fn reset(&mut self) -> Result<(), OomError> {
let fns = self.device.fns();
(fns.v1_0.reset_descriptor_pool)(
@ -317,6 +317,7 @@ impl UnsafeDescriptorPool {
)
.result()
.map_err(VulkanError::from)?;
Ok(())
}
}
@ -361,7 +362,6 @@ impl PartialEq for UnsafeDescriptorPool {
impl Eq for UnsafeDescriptorPool {}
impl Hash for UnsafeDescriptorPool {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.handle.hash(state);
self.device().hash(state);
@ -429,12 +429,11 @@ pub enum DescriptorPoolAllocError {
impl Error for DescriptorPoolAllocError {}
impl Display for DescriptorPoolAllocError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
write!(
f,
"{}",
match *self {
match self {
DescriptorPoolAllocError::OutOfHostMemory => "no memory available on the host",
DescriptorPoolAllocError::OutOfDeviceMemory => {
"no memory available on the graphical device"

View File

@ -60,6 +60,7 @@ impl SingleLayoutDescSetPool {
/// - Panics if the provided `layout` is for push descriptors rather than regular descriptor
/// sets.
/// - Panics if the provided `layout` has a binding with a variable descriptor count.
#[inline]
pub fn new(layout: Arc<DescriptorSetLayout>) -> Result<Self, OomError> {
assert!(
!layout.push_descriptor(),
@ -81,7 +82,6 @@ impl SingleLayoutDescSetPool {
/// Returns a new descriptor set, either by creating a new one or returning an existing one
/// from the internal reserve.
#[inline]
pub fn next(
&mut self,
descriptor_writes: impl IntoIterator<Item = WriteDescriptorSet>,
@ -186,12 +186,10 @@ pub(crate) struct SingleLayoutPoolAlloc {
}
impl DescriptorPoolAlloc for SingleLayoutPoolAlloc {
#[inline]
fn inner(&self) -> &UnsafeDescriptorSet {
&self.inner
}
#[inline]
fn inner_mut(&mut self) -> &mut UnsafeDescriptorSet {
&mut self.inner
}
@ -245,7 +243,6 @@ impl PartialEq for SingleLayoutDescSet {
impl Eq for SingleLayoutDescSet {}
impl Hash for SingleLayoutDescSet {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.inner().internal_object().hash(state);
self.device().hash(state);
@ -279,6 +276,7 @@ impl SingleLayoutVariableDescSetPool {
///
/// - Panics if the provided `layout` is for push descriptors rather than regular descriptor
/// sets.
#[inline]
pub fn new(layout: Arc<DescriptorSetLayout>) -> Result<Self, OomError> {
assert!(
!layout.push_descriptor(),
@ -301,7 +299,6 @@ impl SingleLayoutVariableDescSetPool {
/// # Panics
///
/// - Panics if the provided `variable_descriptor_count` exceeds the maximum for the layout.
#[inline]
pub fn next(
&mut self,
variable_descriptor_count: u32,
@ -440,12 +437,10 @@ unsafe impl Send for SingleLayoutVariablePoolAlloc {}
unsafe impl Sync for SingleLayoutVariablePoolAlloc {}
impl DescriptorPoolAlloc for SingleLayoutVariablePoolAlloc {
#[inline]
fn inner(&self) -> &UnsafeDescriptorSet {
&self.inner
}
#[inline]
fn inner_mut(&mut self) -> &mut UnsafeDescriptorSet {
&mut self.inner
}
@ -492,7 +487,6 @@ impl PartialEq for SingleLayoutVariableDescSet {
impl Eq for SingleLayoutVariableDescSet {}
impl Hash for SingleLayoutVariableDescSet {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.inner().internal_object().hash(state);
self.device().hash(state);

View File

@ -48,7 +48,6 @@ impl UnsafeDescriptorSet {
/// - Updating a descriptor set obeys synchronization rules that aren't checked here. Once a
/// command buffer contains a pointer/reference to a descriptor set, it is illegal to write
/// to it.
///
pub unsafe fn write<'a>(
&mut self,
layout: &DescriptorSetLayout,

View File

@ -72,7 +72,6 @@ impl WriteDescriptorSet {
}
/// Write a number of consecutive buffer elements.
#[inline]
pub fn buffer_array(
binding: u32,
first_array_element: u32,
@ -94,7 +93,6 @@ impl WriteDescriptorSet {
}
/// Write a number of consecutive buffer view elements.
#[inline]
pub fn buffer_view_array(
binding: u32,
first_array_element: u32,
@ -116,7 +114,6 @@ impl WriteDescriptorSet {
}
/// Write a number of consecutive image view elements.
#[inline]
pub fn image_view_array(
binding: u32,
first_array_element: u32,
@ -142,7 +139,6 @@ impl WriteDescriptorSet {
}
/// Write a number of consecutive image view and sampler elements.
#[inline]
pub fn image_view_sampler_array(
binding: u32,
first_array_element: u32,
@ -164,7 +160,6 @@ impl WriteDescriptorSet {
}
/// Write a number of consecutive sampler elements.
#[inline]
pub fn sampler_array(
binding: u32,
first_array_element: u32,
@ -949,7 +944,6 @@ impl Error for DescriptorSetUpdateError {
}
impl Display for DescriptorSetUpdateError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match self {
Self::ArrayIndexOutOfBounds {
@ -958,66 +952,75 @@ impl Display for DescriptorSetUpdateError {
written_count,
} => write!(
f,
"tried to write up to element {} to binding {}, but only {} descriptors are available",
"tried to write up to element {} to binding {}, but only {} descriptors are \
available",
written_count, binding, available_count,
),
Self::ImageView2dFrom3d { binding, index } => write!(
f,
"tried to write an image view to binding {} index {} with a 2D type and a 3D underlying image",
"tried to write an image view to binding {} index {} with a 2D type and a 3D \
underlying image",
binding, index,
),
Self::ImageViewDepthAndStencil { binding, index } => write!(
f,
"tried to write an image view to binding {} index {} that has both the `depth` and `stencil` aspects",
"tried to write an image view to binding {} index {} that has both the `depth` and \
`stencil` aspects",
binding, index,
),
Self::ImageViewHasSamplerYcbcrConversion { binding, index } => write!(
f,
"tried to write an image view to binding {} index {} with an attached sampler YCbCr conversion to binding that does not support it",
"tried to write an image view to binding {} index {} with an attached sampler \
YCbCr conversion to binding that does not support it",
binding, index,
),
Self::ImageViewIsArrayed { binding, index } => write!(
f,
"tried to write an image view of an arrayed type to binding {} index {}, but this binding has a descriptor type that does not support arrayed image views",
"tried to write an image view of an arrayed type to binding {} index {}, but this \
binding has a descriptor type that does not support arrayed image views",
binding, index,
),
Self::ImageViewIncompatibleSampler { binding, index, .. } => write!(
f,
"tried to write an image view to binding {} index {}, that was not compatible with the sampler that was provided as part of the update or immutably in the layout",
"tried to write an image view to binding {} index {}, that was not compatible with \
the sampler that was provided as part of the update or immutably in the layout",
binding, index,
),
Self::ImageViewNotIdentitySwizzled { binding, index } => write!(
f,
"tried to write an image view with non-identity swizzling to binding {} index {}, but this binding has a descriptor type that requires it to be identity swizzled",
"tried to write an image view with non-identity swizzling to binding {} index {}, \
but this binding has a descriptor type that requires it to be identity swizzled",
binding, index,
),
Self::IncompatibleDescriptorType { binding } => write!(
f,
"tried to write a resource to binding {} whose type was not compatible with the descriptor type",
binding,
),
Self::InvalidBinding { binding } => write!(
f,
"tried to write to a nonexistent binding {}",
"tried to write a resource to binding {} whose type was not compatible with the \
descriptor type",
binding,
),
Self::InvalidBinding { binding } => {
write!(f, "tried to write to a nonexistent binding {}", binding,)
}
Self::MissingUsage {
binding,
index,
usage,
} => write!(
f,
"tried to write a resource to binding {} index {} that did not have the required usage {} enabled",
"tried to write a resource to binding {} index {} that did not have the required \
usage {} enabled",
binding, index, usage,
),
Self::SamplerHasSamplerYcbcrConversion { binding, index } => write!(
f,
"tried to write a sampler to binding {} index {} that has an attached sampler YCbCr conversion",
"tried to write a sampler to binding {} index {} that has an attached sampler \
YCbCr conversion",
binding, index,
),
Self::SamplerIsImmutable { binding } => write!(
f,
"tried to write a sampler to binding {}, which already contains immutable samplers in the descriptor set layout",
"tried to write a sampler to binding {}, which already contains immutable samplers \
in the descriptor set layout",
binding,
),
}

View File

@ -27,7 +27,6 @@ pub struct FeatureRestrictionError {
impl Error for FeatureRestrictionError {}
impl Display for FeatureRestrictionError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
write!(
f,
@ -50,7 +49,6 @@ pub enum FeatureRestriction {
}
impl Display for FeatureRestriction {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match *self {
FeatureRestriction::NotSupported => {

View File

@ -611,6 +611,7 @@ impl Device {
///
/// - `file` must be a handle to external memory that was created outside the Vulkan API.
#[cfg_attr(not(unix), allow(unused_variables))]
#[inline]
pub unsafe fn memory_fd_properties(
&self,
handle_type: ExternalMemoryHandleType,
@ -694,12 +695,13 @@ impl Device {
/// This function is not thread-safe. You must not submit anything to any of the queue
/// of the device (either explicitly or implicitly, for example with a future's destructor)
/// while this function is waiting.
///
#[inline]
pub unsafe fn wait_idle(&self) -> Result<(), OomError> {
let fns = self.fns();
(fns.v1_0.device_wait_idle)(self.handle)
.result()
.map_err(VulkanError::from)?;
Ok(())
}
}
@ -743,7 +745,6 @@ impl PartialEq for Device {
impl Eq for Device {}
impl Hash for Device {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.handle.hash(state);
self.physical_device.hash(state);
@ -781,15 +782,12 @@ pub enum DeviceCreationError {
impl Error for DeviceCreationError {}
impl Display for DeviceCreationError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match *self {
Self::InitializationFailed => {
write!(
f,
"failed to create the device for an implementation-specific reason"
)
}
match self {
Self::InitializationFailed => write!(
f,
"failed to create the device for an implementation-specific reason",
),
Self::OutOfHostMemory => write!(f, "no memory available on the host"),
Self::OutOfDeviceMemory => {
write!(f, "no memory available on the graphical device")
@ -798,24 +796,23 @@ impl Display for DeviceCreationError {
Self::TooManyQueuesForFamily => {
write!(f, "tried to create too many queues for a given family")
}
Self::FeatureNotPresent => {
write!(
f,
"some of the requested features are unsupported by the physical device"
)
}
Self::PriorityOutOfRange => {
write!(
f,
"the priority of one of the queues is out of the [0.0; 1.0] range"
)
}
Self::ExtensionNotPresent => {
write!(f,"some of the requested device extensions are not supported by the physical device")
}
Self::TooManyObjects => {
write!(f,"you have reached the limit to the number of devices that can be created from the same physical device")
}
Self::FeatureNotPresent => write!(
f,
"some of the requested features are unsupported by the physical device",
),
Self::PriorityOutOfRange => write!(
f,
"the priority of one of the queues is out of the [0.0; 1.0] range",
),
Self::ExtensionNotPresent => write!(
f,
"some of the requested device extensions are not supported by the physical device",
),
Self::TooManyObjects => write!(
f,
"you have reached the limit to the number of devices that can be created from the \
same physical device",
),
Self::ExtensionRestrictionNotMet(err) => err.fmt(f),
Self::FeatureRestrictionNotMet(err) => err.fmt(f),
}
@ -823,7 +820,6 @@ impl Display for DeviceCreationError {
}
impl From<VulkanError> for DeviceCreationError {
#[inline]
fn from(err: VulkanError) -> Self {
match err {
VulkanError::InitializationFailed => Self::InitializationFailed,
@ -839,14 +835,12 @@ impl From<VulkanError> for DeviceCreationError {
}
impl From<ExtensionRestrictionError> for DeviceCreationError {
#[inline]
fn from(err: ExtensionRestrictionError) -> Self {
Self::ExtensionRestrictionNotMet(err)
}
}
impl From<FeatureRestrictionError> for DeviceCreationError {
#[inline]
fn from(err: FeatureRestrictionError) -> Self {
Self::FeatureRestrictionNotMet(err)
}
@ -922,7 +916,6 @@ impl Default for QueueCreateInfo {
/// # Safety
///
/// - `device()` must return the correct device.
///
pub unsafe trait DeviceOwned {
/// Returns the device that owns `Self`.
fn device(&self) -> &Arc<Device>;
@ -933,7 +926,6 @@ where
T: Deref,
T::Target: DeviceOwned,
{
#[inline]
fn device(&self) -> &Arc<Device> {
(**self).device()
}
@ -971,11 +963,9 @@ pub enum MemoryFdPropertiesError {
impl Error for MemoryFdPropertiesError {}
impl Display for MemoryFdPropertiesError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match *self {
match self {
Self::OutOfHostMemory => write!(f, "no memory available on the host"),
Self::RequirementNotMet {
required_for,
requires_one_of,
@ -984,7 +974,6 @@ impl Display for MemoryFdPropertiesError {
"a requirement was not met for: {}; requires one of: {}",
required_for, requires_one_of,
),
Self::InvalidExternalHandle => {
write!(f, "the provided external handle was not valid")
}
@ -1000,7 +989,6 @@ impl Display for MemoryFdPropertiesError {
}
impl From<VulkanError> for MemoryFdPropertiesError {
#[inline]
fn from(err: VulkanError) -> Self {
match err {
VulkanError::OutOfHostMemory => Self::OutOfHostMemory,
@ -1011,7 +999,6 @@ impl From<VulkanError> for MemoryFdPropertiesError {
}
impl From<RequirementNotMet> for MemoryFdPropertiesError {
#[inline]
fn from(err: RequirementNotMet) -> Self {
Self::RequirementNotMet {
required_for: err.required_for,

View File

@ -42,7 +42,7 @@ use std::{
/// Represents one of the available physical devices on this machine.
///
/// # Example
/// # Examples
///
/// ```no_run
/// # use vulkano::{
@ -465,6 +465,7 @@ impl PhysicalDevice {
}
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
#[inline]
pub unsafe fn directfb_presentation_support_unchecked<D>(
&self,
queue_family_index: u32,
@ -481,12 +482,13 @@ impl PhysicalDevice {
/// Retrieves the external memory properties supported for buffers with a given configuration.
///
/// Instance API version must be at least 1.1, or the
/// [`khr_external_memory_capabilities`](crate::instance::InstanceExtensions::khr_external_memory_capabilities)
/// Instance API version must be at least 1.1, or the [`khr_external_memory_capabilities`]
/// extension must be enabled on the instance.
///
/// 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.
///
/// [`khr_external_memory_capabilities`]: crate::instance::InstanceExtensions::khr_external_memory_capabilities
#[inline]
pub fn external_buffer_properties(
&self,
@ -537,6 +539,7 @@ impl PhysicalDevice {
}
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
#[inline]
pub unsafe fn external_buffer_properties_unchecked(
&self,
info: ExternalBufferInfo,
@ -592,12 +595,13 @@ impl PhysicalDevice {
/// Retrieves the external handle properties supported for fences with a given
/// configuration.
///
/// The instance API version must be at least 1.1, or the
/// [`khr_external_fence_capabilities`](crate::instance::InstanceExtensions::khr_external_fence_capabilities)
/// The instance API version must be at least 1.1, or the [`khr_external_fence_capabilities`]
/// extension must be enabled on the instance.
///
/// 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.
///
/// [`khr_external_fence_capabilities`]: crate::instance::InstanceExtensions::khr_external_fence_capabilities
#[inline]
pub fn external_fence_properties(
&self,
@ -640,6 +644,7 @@ impl PhysicalDevice {
}
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
#[inline]
pub unsafe fn external_fence_properties_unchecked(
&self,
info: ExternalFenceInfo,
@ -699,11 +704,12 @@ impl PhysicalDevice {
/// configuration.
///
/// The instance API version must be at least 1.1, or the
/// [`khr_external_semaphore_capabilities`](crate::instance::InstanceExtensions::khr_external_semaphore_capabilities)
/// extension must be enabled on the instance.
/// [`khr_external_semaphore_capabilities`] extension must be enabled on the instance.
///
/// 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.
///
/// [`khr_external_semaphore_capabilities`]: crate::instance::InstanceExtensions::khr_external_semaphore_capabilities
#[inline]
pub fn external_semaphore_properties(
&self,
@ -746,6 +752,7 @@ impl PhysicalDevice {
}
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
#[inline]
pub unsafe fn external_semaphore_properties_unchecked(
&self,
info: ExternalSemaphoreInfo,
@ -827,6 +834,7 @@ impl PhysicalDevice {
}
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
#[inline]
pub unsafe fn format_properties_unchecked(&self, format: Format) -> FormatProperties {
self.format_properties.get_or_insert(format, |&format| {
let mut format_properties2 = ash::vk::FormatProperties2::default();
@ -913,6 +921,7 @@ impl PhysicalDevice {
unsafe { Ok(self.image_format_properties_unchecked(image_format_info)?) }
}
// FIXME: Shouldn't this be private?
pub fn validate_image_format_properties(
&self,
image_format_info: &ImageFormatInfo,
@ -1019,6 +1028,7 @@ impl PhysicalDevice {
}
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
#[inline]
pub unsafe fn image_format_properties_unchecked(
&self,
mut image_format_info: ImageFormatInfo,
@ -1200,7 +1210,6 @@ impl PhysicalDevice {
/// # Safety
///
/// - `window` must be a valid QNX Screen `_screen_window` handle.
#[inline]
pub unsafe fn qnx_screen_presentation_support<W>(
&self,
queue_family_index: u32,
@ -1313,6 +1322,7 @@ impl PhysicalDevice {
}
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
#[inline]
pub unsafe fn sparse_image_format_properties_unchecked(
&self,
format_info: SparseImageFormatInfo,
@ -1465,10 +1475,9 @@ 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.
///
/// # Panic
/// # Panics
///
/// - Panics if the physical device and the surface don't belong to the same instance.
#[inline]
pub fn surface_capabilities<W>(
&self,
surface: &Surface<W>,
@ -1700,10 +1709,9 @@ 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.
///
/// # Panic
/// # Panics
///
/// - Panics if the physical device and the surface don't belong to the same instance.
#[inline]
pub fn surface_formats<W>(
&self,
surface: &Surface<W>,
@ -1928,10 +1936,9 @@ 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.
///
/// # Panic
/// # Panics
///
/// - Panics if the physical device and the surface don't belong to the same instance.
#[inline]
pub fn surface_present_modes<W>(
&self,
surface: &Surface<W>,
@ -2116,6 +2123,7 @@ impl PhysicalDevice {
}
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
#[inline]
pub unsafe fn tool_properties_unchecked(&self) -> Result<Vec<ToolProperties>, VulkanError> {
let fns = self.instance.fns();
@ -2190,13 +2198,12 @@ impl PhysicalDevice {
}
}
/// Queries whether the physical device supports presenting to Wayland surfaces from queues of the
/// given queue family.
/// Queries whether the physical device supports presenting to Wayland surfaces from queues of
/// the given queue family.
///
/// # Safety
///
/// - `display` must be a valid Wayland `wl_display` handle.
#[inline]
pub unsafe fn wayland_presentation_support<D>(
&self,
queue_family_index: u32,
@ -2289,6 +2296,7 @@ impl PhysicalDevice {
}
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
#[inline]
pub unsafe fn win32_presentation_support_unchecked(&self, queue_family_index: u32) -> bool {
let fns = self.instance.fns();
(fns.khr_win32_surface
@ -2303,7 +2311,6 @@ impl PhysicalDevice {
/// # Safety
///
/// - `connection` must be a valid X11 `xcb_connection_t` handle.
#[inline]
pub unsafe fn xcb_presentation_support<C>(
&self,
queue_family_index: u32,
@ -2368,7 +2375,6 @@ impl PhysicalDevice {
/// # Safety
///
/// - `display` must be a valid Xlib `Display` handle.
#[inline]
pub unsafe fn xlib_presentation_support<D>(
&self,
queue_family_index: u32,
@ -2447,7 +2453,6 @@ impl PartialEq for PhysicalDevice {
impl Eq for PhysicalDevice {}
impl Hash for PhysicalDevice {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.handle.hash(state);
self.instance.hash(state);
@ -2504,14 +2509,15 @@ impl From<ash::vk::ConformanceVersion> for ConformanceVersion {
}
impl Debug for ConformanceVersion {
fn fmt(&self, formatter: &mut Formatter<'_>) -> Result<(), FmtError> {
write!(formatter, "{}.{}.{}", self.major, self.minor, self.patch)
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
write!(f, "{}.{}.{}", self.major, self.minor, self.patch)
}
}
impl Display for ConformanceVersion {
fn fmt(&self, formatter: &mut Formatter<'_>) -> Result<(), FmtError> {
Debug::fmt(self, formatter)
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
Debug::fmt(self, f)
}
}
@ -2716,24 +2722,18 @@ pub enum PhysicalDeviceError {
}
impl Error for PhysicalDeviceError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match *self {
Self::VulkanError(ref err) => Some(err),
match self {
Self::VulkanError(err) => Some(err),
_ => None,
}
}
}
impl Display for PhysicalDeviceError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match self {
Self::VulkanError(_) => write!(
f,
"a runtime error occurred",
),
Self::VulkanError(_) => write!(f, "a runtime error occurred"),
Self::RequirementNotMet {
required_for,
requires_one_of,
@ -2742,17 +2742,18 @@ impl Display for PhysicalDeviceError {
"a requirement was not met for: {}; requires one of: {}",
required_for, requires_one_of,
),
Self::NotSupported => write!(
f,
"the given `SurfaceInfo` values are not supported for the surface by the physical device",
"the given `SurfaceInfo` values are not supported for the surface by the physical \
device",
),
Self::QueueFamilyIndexOutOfRange {
queue_family_index,
queue_family_count,
} => write!(
f,
"the provided `queue_family_index` ({}) was not less than the number of queue families in the physical device ({})",
"the provided `queue_family_index` ({}) was not less than the number of queue \
families in the physical device ({})",
queue_family_index, queue_family_count,
),
Self::SurfaceNotSupported => write!(
@ -2764,14 +2765,12 @@ impl Display for PhysicalDeviceError {
}
impl From<VulkanError> for PhysicalDeviceError {
#[inline]
fn from(err: VulkanError) -> Self {
Self::VulkanError(err)
}
}
impl From<RequirementNotMet> for PhysicalDeviceError {
#[inline]
fn from(err: RequirementNotMet) -> Self {
Self::RequirementNotMet {
required_for: err.required_for,

View File

@ -47,6 +47,7 @@ pub struct Queue {
}
impl Queue {
// TODO: Make public
#[inline]
pub(super) fn from_handle(
device: Arc<Device>,
@ -110,12 +111,14 @@ unsafe impl VulkanObject for Queue {
}
unsafe impl DeviceOwned for Queue {
#[inline]
fn device(&self) -> &Arc<Device> {
&self.device
}
}
impl PartialEq for Queue {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.id == other.id
&& self.queue_family_index == other.queue_family_index
@ -126,7 +129,6 @@ impl PartialEq for Queue {
impl Eq for Queue {}
impl Hash for Queue {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.id.hash(state);
self.queue_family_index.hash(state);
@ -158,7 +160,6 @@ impl<'a> QueueGuard<'a> {
}
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
#[inline]
pub unsafe fn bind_sparse_unchecked(
&mut self,
bind_infos: impl IntoIterator<Item = BindSparseInfo>,
@ -449,15 +450,16 @@ impl<'a> QueueGuard<'a> {
}
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
#[inline]
pub unsafe fn present_unchecked(
&mut self,
present_info: PresentInfo,
) -> impl ExactSizeIterator<Item = Result<bool, VulkanError>> {
let &PresentInfo {
let PresentInfo {
ref wait_semaphores,
ref swapchain_infos,
_ne: _,
} = &present_info;
} = present_info;
let wait_semaphores_vk: SmallVec<[_; 4]> = wait_semaphores
.iter()
@ -573,7 +575,6 @@ impl<'a> QueueGuard<'a> {
}
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
#[inline]
pub unsafe fn submit_unchecked(
&mut self,
submit_infos: impl IntoIterator<Item = SubmitInfo>,
@ -842,8 +843,9 @@ impl<'a> QueueGuard<'a> {
/// Opens a queue debug label region.
///
/// The [`ext_debug_utils`](crate::instance::InstanceExtensions::ext_debug_utils) must be
/// enabled on the instance.
/// The [`ext_debug_utils`] extension must be enabled on the instance.
///
/// [`ext_debug_utils`]: crate::instance::InstanceExtensions::ext_debug_utils
#[inline]
pub fn begin_debug_utils_label(
&mut self,
@ -881,6 +883,7 @@ impl<'a> QueueGuard<'a> {
}
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
#[inline]
pub unsafe fn begin_debug_utils_label_unchecked(&mut self, label_info: DebugUtilsLabel) {
let DebugUtilsLabel {
label_name,
@ -911,8 +914,8 @@ impl<'a> QueueGuard<'a> {
#[inline]
pub unsafe fn end_debug_utils_label(&mut self) -> Result<(), QueueError> {
self.validate_end_debug_utils_label()?;
self.end_debug_utils_label_unchecked();
Ok(())
}
@ -940,6 +943,7 @@ impl<'a> QueueGuard<'a> {
}
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
#[inline]
pub unsafe fn end_debug_utils_label_unchecked(&mut self) {
let fns = self.queue.device.instance().fns();
(fns.ext_debug_utils.queue_end_debug_utils_label_ext)(self.queue.handle);
@ -986,6 +990,7 @@ impl<'a> QueueGuard<'a> {
}
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
#[inline]
pub unsafe fn insert_debug_utils_label_unchecked(&mut self, label_info: DebugUtilsLabel) {
let DebugUtilsLabel {
label_name,
@ -1106,11 +1111,9 @@ impl Error for QueueError {
}
impl Display for QueueError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match self {
Self::VulkanError(_) => write!(f, "a runtime error occurred",),
Self::VulkanError(_) => write!(f, "a runtime error occurred"),
Self::RequirementNotMet {
required_for,
requires_one_of,
@ -1124,14 +1127,12 @@ impl Display for QueueError {
}
impl From<VulkanError> for QueueError {
#[inline]
fn from(err: VulkanError) -> Self {
Self::VulkanError(err)
}
}
impl From<RequirementNotMet> for QueueError {
#[inline]
fn from(err: RequirementNotMet) -> Self {
Self::RequirementNotMet {
required_for: err.required_for,

View File

@ -50,7 +50,6 @@ pub struct ExtensionRestrictionError {
impl Error for ExtensionRestrictionError {}
impl Display for ExtensionRestrictionError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
write!(
f,
@ -73,7 +72,6 @@ pub enum ExtensionRestriction {
}
impl Display for ExtensionRestriction {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match *self {
ExtensionRestriction::NotSupported => {

View File

@ -173,6 +173,7 @@ impl From<Format> for ash::vk::Format {
// https://registry.khronos.org/vulkan/specs/1.3-extensions/html/chap46.html#spirvenv-image-formats
impl From<ImageFormat> for Option<Format> {
#[inline]
fn from(val: ImageFormat) -> Self {
match val {
ImageFormat::Unknown => None,
@ -252,6 +253,7 @@ pub enum ChromaSampling {
}
impl ChromaSampling {
#[inline]
pub fn subsampled_extent(&self, mut extent: [u32; 3]) -> [u32; 3] {
match self {
ChromaSampling::Mode444 => (),

View File

@ -114,6 +114,7 @@ vulkan_bitflags! {
}
impl ImageAspects {
#[inline]
pub fn iter(&self) -> impl Iterator<Item = ImageAspect> {
let Self {
color,
@ -147,6 +148,7 @@ impl ImageAspects {
}
impl From<ImageAspect> for ImageAspects {
#[inline]
fn from(aspect: ImageAspect) -> Self {
let mut result = Self::empty();

View File

@ -548,15 +548,17 @@ impl AttachmentImage {
}))
}
/// Exports posix file descriptor for the allocated memory
/// requires `khr_external_memory_fd` and `khr_external_memory` extensions to be loaded.
/// Exports posix file descriptor for the allocated memory.
/// Requires `khr_external_memory_fd` and `khr_external_memory` extensions to be loaded.
#[inline]
pub fn export_posix_fd(&self) -> Result<File, DeviceMemoryError> {
self.memory
.memory()
.export_fd(ExternalMemoryHandleType::OpaqueFd)
}
/// Return the size of the allocated memory (used for e.g. with cuda)
/// Return the size of the allocated memory (used e.g. with cuda).
#[inline]
pub fn mem_size(&self) -> DeviceSize {
self.memory.memory().allocation_size()
}
@ -566,7 +568,6 @@ unsafe impl<A> ImageAccess for AttachmentImage<A>
where
A: MemoryPoolAlloc,
{
#[inline]
fn inner(&self) -> ImageInner<'_> {
ImageInner {
image: &self.image,
@ -577,17 +578,14 @@ where
}
}
#[inline]
fn initial_layout_requirement(&self) -> ImageLayout {
self.attachment_layout
}
#[inline]
fn final_layout_requirement(&self) -> ImageLayout {
self.attachment_layout
}
#[inline]
fn descriptor_layouts(&self) -> Option<ImageDescriptorLayouts> {
Some(ImageDescriptorLayouts {
storage_image: ImageLayout::General,
@ -597,12 +595,10 @@ where
})
}
#[inline]
unsafe fn layout_initialized(&self) {
self.initialized.store(true, Ordering::SeqCst);
}
#[inline]
fn is_layout_initialized(&self) -> bool {
self.initialized.load(Ordering::SeqCst)
}
@ -618,7 +614,6 @@ unsafe impl<P, A> ImageContent<P> for AttachmentImage<A>
where
A: MemoryPoolAlloc,
{
#[inline]
fn matches_format(&self) -> bool {
true // FIXME:
}
@ -628,7 +623,6 @@ impl<A> PartialEq for AttachmentImage<A>
where
A: MemoryPoolAlloc,
{
#[inline]
fn eq(&self, other: &Self) -> bool {
self.inner() == other.inner()
}
@ -640,7 +634,6 @@ impl<A> Hash for AttachmentImage<A>
where
A: MemoryPoolAlloc,
{
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.inner().hash(state);
}

View File

@ -99,7 +99,6 @@ fn generate_mipmaps<L>(
impl ImmutableImage {
#[deprecated(note = "use ImmutableImage::uninitialized instead")]
#[inline]
pub fn new(
device: Arc<Device>,
dimensions: ImageDimensions,
@ -117,7 +116,6 @@ impl ImmutableImage {
}
#[deprecated(note = "use ImmutableImage::uninitialized instead")]
#[inline]
pub fn with_mipmaps(
device: Arc<Device>,
dimensions: ImageDimensions,
@ -149,7 +147,8 @@ impl ImmutableImage {
/// Builds an uninitialized immutable image.
///
/// Returns two things: the image, and a special access that should be used for the initial upload to the image.
/// Returns two things: the image, and a special access that should be used for the initial
/// upload to the image.
pub fn uninitialized(
device: Arc<Device>,
dimensions: ImageDimensions,
@ -222,7 +221,6 @@ impl ImmutableImage {
}
/// Construct an ImmutableImage from the contents of `iter`.
#[inline]
pub fn from_iter<Px, I>(
iter: I,
dimensions: ImageDimensions,
@ -318,7 +316,6 @@ unsafe impl<A> ImageAccess for ImmutableImage<A>
where
A: MemoryPoolAlloc,
{
#[inline]
fn inner(&self) -> ImageInner<'_> {
ImageInner {
image: &self.image,
@ -329,22 +326,18 @@ where
}
}
#[inline]
fn is_layout_initialized(&self) -> bool {
true
}
#[inline]
fn initial_layout_requirement(&self) -> ImageLayout {
self.layout
}
#[inline]
fn final_layout_requirement(&self) -> ImageLayout {
self.layout
}
#[inline]
fn descriptor_layouts(&self) -> Option<ImageDescriptorLayouts> {
Some(ImageDescriptorLayouts {
storage_image: ImageLayout::General,
@ -359,7 +352,6 @@ unsafe impl<P, A> ImageContent<P> for ImmutableImage<A>
where
A: MemoryPoolAlloc,
{
#[inline]
fn matches_format(&self) -> bool {
true // FIXME:
}
@ -369,7 +361,6 @@ impl<A> PartialEq for ImmutableImage<A>
where
A: MemoryPoolAlloc,
{
#[inline]
fn eq(&self, other: &Self) -> bool {
self.inner() == other.inner()
}
@ -381,7 +372,6 @@ impl<A> Hash for ImmutableImage<A>
where
A: MemoryPoolAlloc,
{
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.inner().hash(state);
}
@ -402,22 +392,18 @@ unsafe impl<A> ImageAccess for ImmutableImageInitialization<A>
where
A: MemoryPoolAlloc,
{
#[inline]
fn inner(&self) -> ImageInner<'_> {
self.image.inner()
}
#[inline]
fn initial_layout_requirement(&self) -> ImageLayout {
ImageLayout::Undefined
}
#[inline]
fn final_layout_requirement(&self) -> ImageLayout {
self.image.layout
}
#[inline]
fn descriptor_layouts(&self) -> Option<ImageDescriptorLayouts> {
None
}
@ -427,7 +413,6 @@ impl<A> PartialEq for ImmutableImageInitialization<A>
where
A: MemoryPoolAlloc,
{
#[inline]
fn eq(&self, other: &Self) -> bool {
self.inner() == other.inner()
}
@ -439,7 +424,6 @@ impl<A> Hash for ImmutableImageInitialization<A>
where
A: MemoryPoolAlloc,
{
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.inner().hash(state);
}
@ -453,7 +437,6 @@ pub enum ImmutableImageCreationError {
}
impl Error for ImmutableImageCreationError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
Self::ImageCreationError(err) => Some(err),
@ -464,7 +447,6 @@ impl Error for ImmutableImageCreationError {
}
impl Display for ImmutableImageCreationError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match self {
Self::ImageCreationError(err) => err.fmt(f),
@ -475,28 +457,24 @@ impl Display for ImmutableImageCreationError {
}
impl From<ImageCreationError> for ImmutableImageCreationError {
#[inline]
fn from(err: ImageCreationError) -> Self {
Self::ImageCreationError(err)
}
}
impl From<DeviceMemoryError> for ImmutableImageCreationError {
#[inline]
fn from(err: DeviceMemoryError) -> Self {
Self::DeviceMemoryAllocationError(err)
}
}
impl From<OomError> for ImmutableImageCreationError {
#[inline]
fn from(err: OomError) -> Self {
Self::DeviceMemoryAllocationError(err.into())
}
}
impl From<CommandBufferBeginError> for ImmutableImageCreationError {
#[inline]
fn from(err: CommandBufferBeginError) -> Self {
Self::CommandBufferBeginError(err)
}

View File

@ -12,27 +12,28 @@ use crate::{descriptor_set::layout::DescriptorType, macros::vulkan_enum};
vulkan_enum! {
/// In-memory layout of the pixel data of an image.
///
/// The pixel data of a Vulkan image is arranged in a particular way, which is called its *layout*.
/// Each image subresource (mipmap level and array layer) in an image can have a different layout,
/// but usually the whole image has its data in the same layout. Layouts are abstract in the sense
/// that the user does not know the specific details of each layout; the device driver is free to
/// implement each layout in the way it sees fit.
/// The pixel data of a Vulkan image is arranged in a particular way, which is called its
/// *layout*. Each image subresource (mipmap level and array layer) in an image can have a
/// different layout, but usually the whole image has its data in the same layout. Layouts are
/// abstract in the sense that the user does not know the specific details of each layout; the
/// device driver is free to implement each layout in the way it sees fit.
///
/// The layout of a newly created image is either `Undefined` or `Preinitialized`. Every operation
/// that can be performed on an image is only possible with specific layouts, so before the
/// operation is performed, the user must perform a *layout transition* on the image. This
/// rearranges the pixel data from one layout into another. Layout transitions are performed as part
/// of pipeline barriers in a command buffer.
/// The layout of a newly created image is either `Undefined` or `Preinitialized`. Every
/// operation that can be performed on an image is only possible with specific layouts, so
/// before the operation is performed, the user must perform a *layout transition* on the
/// image. This rearranges the pixel data from one layout into another. Layout transitions are
/// performed as part of pipeline barriers in a command buffer.
///
/// The `General` layout is compatible with any operation, so layout transitions are never needed.
/// However, the other layouts, while more restricted, are usually better optimised for a particular
/// type of operation than `General`, so they are usually preferred.
/// The `General` layout is compatible with any operation, so layout transitions are never
/// needed. However, the other layouts, while more restricted, are usually better optimised for
/// a particular type of operation than `General`, so they are usually preferred.
///
/// Vulkan does not keep track of layouts itself, so it is the responsibility of the user to keep
/// track of this information. When performing a layout transition, the previous layout must be
/// specified as well. Some operations allow for different layouts, but require the user to specify
/// which one. Vulkano helps with this by providing sensible defaults, automatically tracking the
/// layout of each image when creating a command buffer, and adding layout transitions where needed.
/// Vulkan does not keep track of layouts itself, so it is the responsibility of the user to
/// keep track of this information. When performing a layout transition, the previous layout
/// must be specified as well. Some operations allow for different layouts, but require the
/// user to specify which one. Vulkano helps with this by providing sensible defaults,
/// automatically tracking the layout of each image when creating a command buffer, and adding
/// layout transitions where needed.
#[non_exhaustive]
ImageLayout = ImageLayout(i32);
@ -73,15 +74,15 @@ vulkan_enum! {
/// tiling, optimal tiling gives undefined results.
Preinitialized = PREINITIALIZED,
// A combination of `DepthStencilReadOnlyOptimal` for the depth aspect of the image,
// and `DepthStencilAttachmentOptimal` for the stencil aspect of the image.
/// A combination of `DepthStencilReadOnlyOptimal` for the depth aspect of the image,
/// and `DepthStencilAttachmentOptimal` for the stencil aspect of the image.
DepthReadOnlyStencilAttachmentOptimal = DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL {
api_version: V1_1,
device_extensions: [khr_maintenance2],
},
// A combination of `DepthStencilAttachmentOptimal` for the depth aspect of the image,
// and `DepthStencilReadOnlyOptimal` for the stencil aspect of the image.
/// A combination of `DepthStencilAttachmentOptimal` for the depth aspect of the image,
/// and `DepthStencilReadOnlyOptimal` for the stencil aspect of the image.
DepthAttachmentStencilReadOnlyOptimal = DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL {
api_version: V1_1,
device_extensions: [khr_maintenance2],

View File

@ -379,7 +379,7 @@ impl ImageDimensions {
///
/// The returned value is always at least 1.
///
/// # Example
/// # Examples
///
/// ```
/// use vulkano::image::ImageDimensions;
@ -392,7 +392,6 @@ impl ImageDimensions {
///
/// assert_eq!(dims.max_mip_levels(), 6);
/// ```
///
#[inline]
pub fn max_mip_levels(&self) -> u32 {
// This calculates `log2(max(width, height, depth)) + 1` using fast integer operations.
@ -413,7 +412,7 @@ impl ImageDimensions {
///
/// Returns `None` if `level` is superior or equal to `max_mip_levels()`.
///
/// # Example
/// # Examples
///
/// ```
/// use vulkano::image::ImageDimensions;
@ -443,11 +442,11 @@ impl ImageDimensions {
/// assert_eq!(dims.mip_level_dimensions(11), None);
/// ```
///
/// # Panic
///
/// In debug mode, Panics if `width`, `height` or `depth` is equal to 0. In release, returns
/// an unspecified value.
/// # Panics
///
/// - In debug mode, panics if `width`, `height` or `depth` is equal to 0. In release, returns
/// an unspecified value.
#[inline]
pub fn mip_level_dimensions(&self, level: u32) -> Option<ImageDimensions> {
if level == 0 {
return Some(*self);
@ -520,6 +519,7 @@ pub struct ImageSubresourceLayers {
}
impl From<ImageSubresourceLayers> for ash::vk::ImageSubresourceLayers {
#[inline]
fn from(val: ImageSubresourceLayers) -> Self {
Self {
aspect_mask: val.aspects.into(),

View File

@ -52,7 +52,6 @@ where
impl StorageImage {
/// Creates a new image with the given dimensions and format.
#[inline]
pub fn new(
device: Arc<Device>,
dimensions: ImageDimensions,
@ -206,6 +205,7 @@ impl StorageImage {
}
/// Allows the creation of a simple 2D general purpose image view from `StorageImage`.
#[inline]
pub fn general_purpose_image_view(
queue: Arc<Queue>,
size: [u32; 2],
@ -226,6 +226,7 @@ impl StorageImage {
flags,
Some(queue.queue_family_index()),
);
match image_result {
Ok(image) => {
let image_view = ImageView::new_default(image);
@ -238,15 +239,17 @@ impl StorageImage {
}
}
/// Exports posix file descriptor for the allocated memory
/// requires `khr_external_memory_fd` and `khr_external_memory` extensions to be loaded.
/// Exports posix file descriptor for the allocated memory.
/// Requires `khr_external_memory_fd` and `khr_external_memory` extensions to be loaded.
#[inline]
pub fn export_posix_fd(&self) -> Result<File, DeviceMemoryError> {
self.memory
.memory()
.export_fd(ExternalMemoryHandleType::OpaqueFd)
}
/// Return the size of the allocated memory (used for e.g. with cuda)
/// Return the size of the allocated memory (used e.g. with cuda).
#[inline]
pub fn mem_size(&self) -> DeviceSize {
self.memory.memory().allocation_size()
}
@ -265,7 +268,6 @@ unsafe impl<A> ImageAccess for StorageImage<A>
where
A: MemoryPool,
{
#[inline]
fn inner(&self) -> ImageInner<'_> {
ImageInner {
image: &self.image,
@ -276,17 +278,14 @@ where
}
}
#[inline]
fn initial_layout_requirement(&self) -> ImageLayout {
ImageLayout::General
}
#[inline]
fn final_layout_requirement(&self) -> ImageLayout {
ImageLayout::General
}
#[inline]
fn descriptor_layouts(&self) -> Option<ImageDescriptorLayouts> {
Some(ImageDescriptorLayouts {
storage_image: ImageLayout::General,
@ -301,7 +300,6 @@ unsafe impl<P, A> ImageContent<P> for StorageImage<A>
where
A: MemoryPool,
{
#[inline]
fn matches_format(&self) -> bool {
true // FIXME:
}
@ -311,7 +309,6 @@ impl<A> PartialEq for StorageImage<A>
where
A: MemoryPool,
{
#[inline]
fn eq(&self, other: &Self) -> bool {
self.inner() == other.inner()
}
@ -323,7 +320,6 @@ impl<A> Hash for StorageImage<A>
where
A: MemoryPool,
{
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.inner().hash(state);
}

View File

@ -55,22 +55,18 @@ where
}
/// Returns the swapchain this image belongs to.
#[inline]
pub fn swapchain(&self) -> &Arc<Swapchain<W>> {
&self.swapchain
}
#[inline]
fn my_image(&self) -> ImageInner<'_> {
self.swapchain.raw_image(self.image_index).unwrap()
}
#[inline]
fn layout_initialized(&self) {
self.swapchain.image_layout_initialized(self.image_index);
}
#[inline]
fn is_layout_initialized(&self) -> bool {
self.swapchain.is_image_layout_initialized(self.image_index)
}
@ -86,22 +82,18 @@ unsafe impl<W> ImageAccess for SwapchainImage<W>
where
W: Send + Sync,
{
#[inline]
fn inner(&self) -> ImageInner<'_> {
self.my_image()
}
#[inline]
fn initial_layout_requirement(&self) -> ImageLayout {
ImageLayout::PresentSrc
}
#[inline]
fn final_layout_requirement(&self) -> ImageLayout {
ImageLayout::PresentSrc
}
#[inline]
fn descriptor_layouts(&self) -> Option<ImageDescriptorLayouts> {
Some(ImageDescriptorLayouts {
storage_image: ImageLayout::General,
@ -111,12 +103,10 @@ where
})
}
#[inline]
unsafe fn layout_initialized(&self) {
self.layout_initialized();
}
#[inline]
fn is_layout_initialized(&self) -> bool {
self.is_layout_initialized()
}
@ -126,7 +116,6 @@ unsafe impl<P, W> ImageContent<P> for SwapchainImage<W>
where
W: Send + Sync,
{
#[inline]
fn matches_format(&self) -> bool {
true // FIXME:
}
@ -136,7 +125,6 @@ impl<W> PartialEq for SwapchainImage<W>
where
W: Send + Sync,
{
#[inline]
fn eq(&self, other: &Self) -> bool {
self.inner() == other.inner()
}
@ -148,7 +136,6 @@ impl<W> Hash for SwapchainImage<W>
where
W: Send + Sync,
{
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.inner().hash(state);
}

View File

@ -802,6 +802,7 @@ impl UnsafeImage {
}
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
#[inline]
pub unsafe fn new_unchecked(
device: Arc<Device>,
create_info: UnsafeImageCreateInfo,
@ -932,6 +933,7 @@ impl UnsafeImage {
///
/// - `handle` must be a valid Vulkan object handle created from `device`.
/// - `create_info` must match the info used to create the object.
#[inline]
pub unsafe fn from_handle(
device: Arc<Device>,
handle: ash::vk::Image,
@ -1079,6 +1081,7 @@ impl UnsafeImage {
}
/// Returns the memory requirements for this image.
#[inline]
pub fn memory_requirements(&self) -> MemoryRequirements {
let image_memory_requirements_info2 = ash::vk::ImageMemoryRequirementsInfo2 {
image: self.handle,
@ -1139,6 +1142,7 @@ impl UnsafeImage {
}
/// Returns the sparse memory requirements for this image.
#[inline]
pub fn sparse_memory_requirements(&self) -> Vec<SparseImageMemoryRequirements> {
let device = &self.device;
@ -1317,6 +1321,7 @@ impl UnsafeImage {
}
}
#[inline]
pub unsafe fn bind_memory(
&self,
memory: &DeviceMemory,
@ -1347,10 +1352,10 @@ impl UnsafeImage {
)
.result()
.map_err(VulkanError::from)?;
Ok(())
}
#[inline]
pub(crate) fn range_size(&self) -> DeviceSize {
self.range_size
}
@ -1360,7 +1365,6 @@ impl UnsafeImage {
/// In ranges, the subresources are "flattened" to `DeviceSize`, where each index in the range
/// is a single array layer. The layers are arranged hierarchically: aspects at the top level,
/// with the mip levels in that aspect, and the array layers in that mip level.
#[inline]
pub(crate) fn iter_ranges(
&self,
subresource_range: ImageSubresourceRange,
@ -1383,7 +1387,6 @@ impl UnsafeImage {
)
}
#[inline]
pub(crate) fn range_to_subresources(
&self,
mut range: Range<DeviceSize>,
@ -1450,7 +1453,6 @@ impl UnsafeImage {
}
}
#[inline]
pub(crate) fn state(&self) -> MutexGuard<'_, ImageState> {
self.state.lock()
}
@ -1596,7 +1598,7 @@ impl UnsafeImage {
/// Note that while Vulkan allows querying the array layers other than 0, it is redundant as
/// you can easily calculate the position of any layer.
///
/// # Panic
/// # Panics
///
/// - Panics if the mipmap level is out of range.
///
@ -1612,7 +1614,7 @@ impl UnsafeImage {
/// Same as `color_linear_layout`, except that it retrieves the depth component of the image.
///
/// # Panic
/// # Panics
///
/// - Panics if the mipmap level is out of range.
///
@ -1628,7 +1630,7 @@ impl UnsafeImage {
/// Same as `color_linear_layout`, except that it retrieves the stencil component of the image.
///
/// # Panic
/// # Panics
///
/// - Panics if the mipmap level is out of range.
///
@ -1645,7 +1647,7 @@ impl UnsafeImage {
/// Same as `color_linear_layout`, except that it retrieves layout for the requested YCbCr
/// component too if the format is a YCbCr format.
///
/// # Panic
/// # Panics
///
/// - Panics if plane aspect is out of range.
/// - Panics if the aspect is not a color or planar aspect.
@ -1724,6 +1726,7 @@ unsafe impl VulkanObject for UnsafeImage {
}
unsafe impl DeviceOwned for UnsafeImage {
#[inline]
fn device(&self) -> &Arc<Device> {
&self.device
}
@ -1739,7 +1742,6 @@ impl PartialEq for UnsafeImage {
impl Eq for UnsafeImage {}
impl Hash for UnsafeImage {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.handle.hash(state);
self.device().hash(state);
@ -1851,6 +1853,7 @@ pub struct UnsafeImageCreateInfo {
}
impl Default for UnsafeImageCreateInfo {
#[inline]
fn default() -> Self {
Self {
dimensions: ImageDimensions::Dim2d {
@ -1997,21 +2000,18 @@ pub enum ImageCreationError {
}
impl Error for ImageCreationError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match *self {
ImageCreationError::AllocError(ref err) => Some(err),
match self {
ImageCreationError::AllocError(err) => Some(err),
_ => None,
}
}
}
impl Display for ImageCreationError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match self {
Self::AllocError(_) => write!(f, "allocating memory failed"),
Self::RequirementNotMet {
required_for,
requires_one_of,
@ -2020,139 +2020,133 @@ impl Display for ImageCreationError {
"a requirement was not met for: {}; requires one of: {}",
required_for, requires_one_of,
),
Self::Array2dCompatibleNot3d => {
write!(
f,
"the array_2d_compatible flag was enabled, but the image type was not 3D"
)
}
Self::BlockTexelViewCompatibleNotCompressed => {
write!(f, "the block_texel_view_compatible flag was enabled, but the given format was not compressed")
}
Self::CubeCompatibleNot2d => {
write!(
f,
"the cube_compatible flag was enabled, but the image type was not 2D"
)
}
Self::CubeCompatibleNotEnoughArrayLayers => {
write!(f, "the cube_compatible flag was enabled, but the number of array layers was less than 6")
}
Self::CubeCompatibleNotSquare => {
write!(f, "the cube_compatible flag was enabled, but the image dimensions were not square")
}
Self::CubeCompatibleMultisampling => {
write!(
f,
"the cube_compatible flag was enabled together with multisampling"
)
}
Self::ExternalMemoryInvalidInitialLayout => {
write!(f, "one or more external memory handle types were provided, but the initial layout was not `Undefined`")
}
Self::Array2dCompatibleNot3d => write!(
f,
"the array_2d_compatible flag was enabled, but the image type was not 3D",
),
Self::BlockTexelViewCompatibleNotCompressed => write!(
f,
"the block_texel_view_compatible flag was enabled, but the given format was not \
compressed",
),
Self::CubeCompatibleNot2d => write!(
f,
"the cube_compatible flag was enabled, but the image type was not 2D",
),
Self::CubeCompatibleNotEnoughArrayLayers => write!(
f,
"the cube_compatible flag was enabled, but the number of array layers was less \
than 6",
),
Self::CubeCompatibleNotSquare => write!(
f,
"the cube_compatible flag was enabled, but the image dimensions were not square",
),
Self::CubeCompatibleMultisampling => write!(
f,
"the cube_compatible flag was enabled together with multisampling",
),
Self::ExternalMemoryInvalidInitialLayout => write!(
f,
"one or more external memory handle types were provided, but the initial layout \
was not `Undefined`",
),
Self::FormatNotSupported => {
write!(f, "the given format was not supported by the device")
}
Self::FormatUsageNotSupported { .. } => {
write!(
f,
"a requested usage flag was not supported by the given format"
)
}
Self::ImageFormatPropertiesNotSupported => {
write!(f, "the image configuration as queried through the `image_format_properties` function was not supported by the device")
}
Self::MaxArrayLayersExceeded { .. } => {
write!(f, "the number of array layers exceeds the maximum supported by the device for this image configuration")
}
Self::MaxDimensionsExceeded { .. } => {
write!(f, "the specified dimensions exceed the maximum supported by the device for this image configuration")
}
Self::MaxFramebufferDimensionsExceeded { .. } => {
write!(f, "the usage included one of the attachment types, and the specified width and height exceeded the `max_framebuffer_width` or `max_framebuffer_height` limits")
}
Self::MaxMipLevelsExceeded { .. } => {
write!(
f,
"the maximum number of mip levels for the given dimensions has been exceeded"
)
}
Self::MultisampleCubeCompatible => {
write!(
f,
"multisampling was enabled, and the `cube_compatible` flag was set"
)
}
Self::FormatUsageNotSupported { .. } => write!(
f,
"a requested usage flag was not supported by the given format",
),
Self::ImageFormatPropertiesNotSupported => write!(
f,
"the image configuration as queried through the `image_format_properties` function \
was not supported by the device",
),
Self::MaxArrayLayersExceeded { .. } => write!(
f,
"the number of array layers exceeds the maximum supported by the device for this \
image configuration",
),
Self::MaxDimensionsExceeded { .. } => write!(
f,
"the specified dimensions exceed the maximum supported by the device for this \
image configuration",
),
Self::MaxFramebufferDimensionsExceeded { .. } => write!(
f,
"the usage included one of the attachment types, and the specified width and \
height exceeded the `max_framebuffer_width` or `max_framebuffer_height` limits",
),
Self::MaxMipLevelsExceeded { .. } => write!(
f,
"the maximum number of mip levels for the given dimensions has been exceeded",
),
Self::MultisampleCubeCompatible => write!(
f,
"multisampling was enabled, and the `cube_compatible` flag was set",
),
Self::MultisampleLinearTiling => {
write!(f, "multisampling was enabled, and tiling was `Linear`")
}
Self::MultisampleMultipleMipLevels => {
write!(
f,
"multisampling was enabled, and multiple mip levels were specified"
)
}
Self::MultisampleNot2d => {
write!(
f,
"multisampling was enabled, but the image type was not 2D"
)
}
Self::SampleCountNotSupported { .. } => {
write!(
f,
"the sample count is not supported by the device for this image configuration"
)
}
Self::SharingQueueFamilyIndexOutOfRange { .. } => {
write!(f, "the sharing mode was set to `Concurrent`, but one of the specified queue family indices was out of range")
}
Self::MultisampleMultipleMipLevels => write!(
f,
"multisampling was enabled, and multiple mip levels were specified",
),
Self::MultisampleNot2d => write!(
f,
"multisampling was enabled, but the image type was not 2D",
),
Self::SampleCountNotSupported { .. } => write!(
f,
"the sample count is not supported by the device for this image configuration",
),
Self::SharingQueueFamilyIndexOutOfRange { .. } => write!(
f,
"the sharing mode was set to `Concurrent`, but one of the specified queue family \
indices was out of range",
),
Self::StencilUsageMismatch {
usage: _,
stencil_usage: _,
} => write!(
f,
"the provided `usage` and `stencil_usage` have different values for `depth_stencil_attachment` or `transient_attachment`",
"the provided `usage` and `stencil_usage` have different values for \
`depth_stencil_attachment` or `transient_attachment`",
),
Self::YcbcrFormatInvalidDimensions => write!(
f,
"a YCbCr format was given, but the specified width and/or height was not a \
multiple of 2 as required by the format's chroma subsampling",
),
Self::YcbcrFormatMultipleMipLevels => write!(
f,
"a YCbCr format was given, and multiple mip levels were specified",
),
Self::YcbcrFormatInvalidDimensions => {
write!(f, "a YCbCr format was given, but the specified width and/or height was not a multiple of 2 as required by the format's chroma subsampling")
}
Self::YcbcrFormatMultipleMipLevels => {
write!(
f,
"a YCbCr format was given, and multiple mip levels were specified"
)
}
Self::YcbcrFormatMultisampling => {
write!(f, "a YCbCr format was given, and multisampling was enabled")
}
Self::YcbcrFormatNot2d => {
write!(f, "a YCbCr format was given, but the image type was not 2D")
}
Self::DirectImageViewCreationFailed(e) => {
write!(f, "Image view creation failed {}", e)
}
Self::DirectImageViewCreationFailed(e) => write!(f, "Image view creation failed {}", e),
}
}
}
impl From<OomError> for ImageCreationError {
#[inline]
fn from(err: OomError) -> Self {
Self::AllocError(DeviceMemoryError::OomError(err))
}
}
impl From<DeviceMemoryError> for ImageCreationError {
#[inline]
fn from(err: DeviceMemoryError) -> Self {
Self::AllocError(err)
}
}
impl From<VulkanError> for ImageCreationError {
#[inline]
fn from(err: VulkanError) -> Self {
match err {
err @ VulkanError::OutOfHostMemory => Self::AllocError(err.into()),
@ -2163,7 +2157,6 @@ impl From<VulkanError> for ImageCreationError {
}
impl From<RequirementNotMet> for ImageCreationError {
#[inline]
fn from(err: RequirementNotMet) -> Self {
Self::RequirementNotMet {
required_for: err.required_for,

View File

@ -247,7 +247,6 @@ impl PartialEq for dyn ImageAccess {
impl Eq for dyn ImageAccess {}
impl Hash for dyn ImageAccess {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.inner().hash(state);
}
@ -274,12 +273,10 @@ unsafe impl<I> ImageAccess for ImageAccessFromUndefinedLayout<I>
where
I: ImageAccess,
{
#[inline]
fn inner(&self) -> ImageInner<'_> {
self.image.inner()
}
#[inline]
fn initial_layout_requirement(&self) -> ImageLayout {
if self.preinitialized {
ImageLayout::Preinitialized
@ -288,12 +285,10 @@ where
}
}
#[inline]
fn final_layout_requirement(&self) -> ImageLayout {
self.image.final_layout_requirement()
}
#[inline]
fn descriptor_layouts(&self) -> Option<ImageDescriptorLayouts> {
self.image.descriptor_layouts()
}
@ -303,7 +298,6 @@ impl<I> PartialEq for ImageAccessFromUndefinedLayout<I>
where
I: ImageAccess,
{
#[inline]
fn eq(&self, other: &Self) -> bool {
self.inner() == other.inner()
}
@ -315,7 +309,6 @@ impl<I> Hash for ImageAccessFromUndefinedLayout<I>
where
I: ImageAccess,
{
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.inner().hash(state);
}
@ -331,32 +324,26 @@ where
T: SafeDeref + Send + Sync,
T::Target: ImageAccess,
{
#[inline]
fn inner(&self) -> ImageInner<'_> {
(**self).inner()
}
#[inline]
fn initial_layout_requirement(&self) -> ImageLayout {
(**self).initial_layout_requirement()
}
#[inline]
fn final_layout_requirement(&self) -> ImageLayout {
(**self).final_layout_requirement()
}
#[inline]
fn descriptor_layouts(&self) -> Option<ImageDescriptorLayouts> {
(**self).descriptor_layouts()
}
#[inline]
unsafe fn layout_initialized(&self) {
(**self).layout_initialized();
}
#[inline]
fn is_layout_initialized(&self) -> bool {
(**self).is_layout_initialized()
}

View File

@ -69,7 +69,6 @@ where
/// `stencil`, `plane0`, `plane1` or `plane2`.
/// - Panics if `create_info.aspects` contains more more than one aspect, unless `depth` and
/// `stencil` are the only aspects selected.
#[inline]
pub fn new(
image: Arc<I>,
create_info: ImageViewCreateInfo,
@ -468,7 +467,6 @@ where
}
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
#[inline]
pub unsafe fn new_unchecked(
image: Arc<I>,
create_info: ImageViewCreateInfo,
@ -557,7 +555,6 @@ where
/// Creates a default `ImageView`. Equivalent to
/// `ImageView::new(image, ImageViewCreateInfo::from_image(image))`.
#[inline]
pub fn new_default(image: Arc<I>) -> Result<Arc<ImageView<I>>, ImageViewCreationError> {
let create_info = ImageViewCreateInfo::from_image(&image);
Self::new(image, create_info)
@ -569,7 +566,6 @@ where
///
/// - `handle` must be a valid Vulkan object handle created from `image`.
/// - `create_info` must match the info used to create the object.
#[inline]
pub unsafe fn from_handle(
image: Arc<I>,
handle: ash::vk::ImageView,
@ -653,7 +649,6 @@ where
}
// https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VkImageViewCreateInfo.html#_description
#[inline]
fn get_default_usage(aspects: ImageAspects, image: &UnsafeImage) -> ImageUsage {
let has_stencil_aspect = aspects.stencil;
let has_non_stencil_aspect = !(ImageAspects {
@ -674,7 +669,6 @@ where
}
// https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/chap12.html#resources-image-view-format-features
#[inline]
unsafe fn get_format_features(format: Format, image: &UnsafeImage) -> FormatFeatures {
let device = image.device();
@ -712,7 +706,6 @@ where
}
/// Returns the wrapped image that this image view was created from.
#[inline]
pub fn image(&self) -> &Arc<I> {
&self.image
}
@ -722,7 +715,6 @@ impl<I> Drop for ImageView<I>
where
I: ImageAccess + ?Sized,
{
#[inline]
fn drop(&mut self) {
unsafe {
let device = self.device();
@ -738,7 +730,6 @@ where
{
type Object = ash::vk::ImageView;
#[inline]
fn internal_object(&self) -> ash::vk::ImageView {
self.handle
}
@ -748,7 +739,6 @@ unsafe impl<I> DeviceOwned for ImageView<I>
where
I: ImageAccess + ?Sized,
{
#[inline]
fn device(&self) -> &Arc<Device> {
self.image.inner().image.device()
}
@ -758,7 +748,6 @@ impl<I> PartialEq for ImageView<I>
where
I: ImageAccess + ?Sized,
{
#[inline]
fn eq(&self, other: &Self) -> bool {
self.handle == other.handle && self.device() == other.device()
}
@ -770,7 +759,6 @@ impl<I> Hash for ImageView<I>
where
I: ImageAccess + ?Sized,
{
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.handle.hash(state);
self.device().hash(state);
@ -981,24 +969,18 @@ pub enum ImageViewCreationError {
}
impl Error for ImageViewCreationError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match *self {
ImageViewCreationError::OomError(ref err) => Some(err),
match self {
ImageViewCreationError::OomError(err) => Some(err),
_ => None,
}
}
}
impl Display for ImageViewCreationError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match self {
Self::OomError(_) => write!(
f,
"allocating memory failed",
),
Self::OomError(_) => write!(f, "allocating memory failed",),
Self::RequirementNotMet {
required_for,
requires_one_of,
@ -1007,10 +989,10 @@ impl Display for ImageViewCreationError {
"a requirement was not met for: {}; requires one of: {}",
required_for, requires_one_of,
),
Self::Array2dCompatibleMultipleMipLevels => write!(
f,
"a 2D image view was requested from a 3D image, but a range of multiple mip levels was specified",
"a 2D image view was requested from a 3D image, but a range of multiple mip levels \
was specified",
),
Self::ArrayLayersOutOfRange { .. } => write!(
f,
@ -1018,35 +1000,37 @@ impl Display for ImageViewCreationError {
),
Self::BlockTexelViewCompatibleMultipleArrayLayers => write!(
f,
"the image has the `block_texel_view_compatible` flag, but a range of multiple array layers was specified",
"the image has the `block_texel_view_compatible` flag, but a range of multiple \
array layers was specified",
),
Self::BlockTexelViewCompatibleMultipleMipLevels => write!(
f,
"the image has the `block_texel_view_compatible` flag, but a range of multiple mip levels was specified",
"the image has the `block_texel_view_compatible` flag, but a range of multiple mip \
levels was specified",
),
Self::BlockTexelViewCompatibleUncompressedIs3d => write!(
f,
"the image has the `block_texel_view_compatible` flag, and an uncompressed format was requested, and the image view type was `Dim3d`",
"the image has the `block_texel_view_compatible` flag, and an uncompressed format \
was requested, and the image view type was `Dim3d`",
),
Self::FormatChromaSubsamplingInvalidImageDimensions => write!(
f,
"the requested format has chroma subsampling, but the width and/or height of the image was not a multiple of 2",
),
Self::FormatNotCompatible => write!(
f,
"the requested format was not compatible with the image",
),
Self::FormatNotSupported => write!(
f,
"the given format was not supported by the device"
"the requested format has chroma subsampling, but the width and/or height of the \
image was not a multiple of 2",
),
Self::FormatNotCompatible => {
write!(f, "the requested format was not compatible with the image")
}
Self::FormatNotSupported => {
write!(f, "the given format was not supported by the device")
}
Self::FormatRequiresSamplerYcbcrConversion { .. } => write!(
f,
"the format requires a sampler YCbCr conversion, but none was provided",
),
Self::FormatUsageNotSupported { .. } => write!(
f,
"a requested usage flag was not supported by the given format"
"a requested usage flag was not supported by the given format",
),
Self::ImageAspectsNotCompatible { .. } => write!(
f,
@ -1058,11 +1042,13 @@ impl Display for ImageViewCreationError {
),
Self::ImageNotArray2dCompatible => write!(
f,
"a 2D image view was requested from a 3D image, but the image was not created with the `array_2d_compatible` flag",
"a 2D image view was requested from a 3D image, but the image was not created with \
the `array_2d_compatible` flag",
),
Self::ImageNotCubeCompatible => write!(
f,
"a cube image view type was requested, but the image was not created with the `cube_compatible` flag",
"a cube image view type was requested, but the image was not created with the \
`cube_compatible` flag",
),
Self::ImageTypeNotCompatible => write!(
f,
@ -1078,23 +1064,28 @@ impl Display for ImageViewCreationError {
),
Self::MultisamplingNot2d => write!(
f,
"the image has multisampling enabled, but the image view type was not `Dim2d` or `Dim2dArray`",
"the image has multisampling enabled, but the image view type was not `Dim2d` or \
`Dim2dArray`",
),
Self::SamplerYcbcrConversionComponentMappingNotIdentity { .. } => write!(
f,
"sampler YCbCr conversion was enabled, but `component_mapping` was not the identity mapping",
"sampler YCbCr conversion was enabled, but `component_mapping` was not the \
identity mapping",
),
Self::TypeCubeArrayNotMultipleOf6ArrayLayers => write!(
f,
"the `CubeArray` image view type was specified, but the range of array layers did not have a size that is a multiple 6"
"the `CubeArray` image view type was specified, but the range of array layers did \
not have a size that is a multiple 6",
),
Self::TypeCubeNot6ArrayLayers => write!(
f,
"the `Cube` image view type was specified, but the range of array layers did not have a size of 6"
"the `Cube` image view type was specified, but the range of array layers did not \
have a size of 6",
),
Self::TypeNonArrayedMultipleArrayLayers => write!(
f,
"a non-arrayed image view type was specified, but a range of multiple array layers was specified"
"a non-arrayed image view type was specified, but a range of multiple array layers \
was specified",
),
Self::UsageNotSupportedByImage {
usage: _,
@ -1108,14 +1099,12 @@ impl Display for ImageViewCreationError {
}
impl From<OomError> for ImageViewCreationError {
#[inline]
fn from(err: OomError) -> ImageViewCreationError {
ImageViewCreationError::OomError(err)
}
}
impl From<VulkanError> for ImageViewCreationError {
#[inline]
fn from(err: VulkanError) -> ImageViewCreationError {
match err {
err @ VulkanError::OutOfHostMemory => OomError::from(err).into(),
@ -1126,7 +1115,6 @@ impl From<VulkanError> for ImageViewCreationError {
}
impl From<RequirementNotMet> for ImageViewCreationError {
#[inline]
fn from(err: RequirementNotMet) -> Self {
Self::RequirementNotMet {
required_for: err.required_for,
@ -1202,6 +1190,7 @@ pub unsafe trait ImageViewAbstract:
fn component_mapping(&self) -> ComponentMapping;
/// Returns the dimensions of this view.
#[inline]
fn dimensions(&self) -> ImageDimensions {
let subresource_range = self.subresource_range();
let array_layers =
@ -1262,52 +1251,42 @@ unsafe impl<I> ImageViewAbstract for ImageView<I>
where
I: ImageAccess + Debug + 'static,
{
#[inline]
fn image(&self) -> Arc<dyn ImageAccess> {
self.image.clone()
}
#[inline]
fn component_mapping(&self) -> ComponentMapping {
self.component_mapping
}
#[inline]
fn filter_cubic(&self) -> bool {
self.filter_cubic
}
#[inline]
fn filter_cubic_minmax(&self) -> bool {
self.filter_cubic_minmax
}
#[inline]
fn format(&self) -> Option<Format> {
self.format
}
#[inline]
fn format_features(&self) -> &FormatFeatures {
&self.format_features
}
#[inline]
fn sampler_ycbcr_conversion(&self) -> Option<&Arc<SamplerYcbcrConversion>> {
self.sampler_ycbcr_conversion.as_ref()
}
#[inline]
fn subresource_range(&self) -> &ImageSubresourceRange {
&self.subresource_range
}
#[inline]
fn usage(&self) -> &ImageUsage {
&self.usage
}
#[inline]
fn view_type(&self) -> ImageViewType {
self.view_type
}
@ -1375,7 +1354,6 @@ impl PartialEq for dyn ImageViewAbstract {
impl Eq for dyn ImageViewAbstract {}
impl Hash for dyn ImageViewAbstract {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.internal_object().hash(state);
self.device().hash(state);

View File

@ -17,7 +17,7 @@
//! Note that the vulkano library can also emit messages to warn you about performance issues.
//! TODO: ^ that's not the case yet, need to choose whether we keep this idea
//!
//! # Example
//! # Examples
//!
//! ```
//! # use vulkano::instance::Instance;
@ -40,7 +40,6 @@
//! Note that you must keep the `_callback` object alive for as long as you want your callback to
//! be callable. If you don't store the return value of `DebugUtilsMessenger`'s constructor in a
//! variable, it will be immediately destroyed and your callback will not work.
//!
use super::Instance;
use crate::{macros::vulkan_bitflags, RequirementNotMet, RequiresOneOf, VulkanError, VulkanObject};
@ -254,7 +253,6 @@ pub enum DebugUtilsMessengerCreationError {
impl Error for DebugUtilsMessengerCreationError {}
impl Display for DebugUtilsMessengerCreationError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match self {
Self::RequirementNotMet {
@ -270,14 +268,12 @@ impl Display for DebugUtilsMessengerCreationError {
}
impl From<VulkanError> for DebugUtilsMessengerCreationError {
#[inline]
fn from(err: VulkanError) -> DebugUtilsMessengerCreationError {
panic!("unexpected error: {:?}", err)
}
}
impl From<RequirementNotMet> for DebugUtilsMessengerCreationError {
#[inline]
fn from(err: RequirementNotMet) -> Self {
Self::RequirementNotMet {
required_for: err.required_for,

View File

@ -22,7 +22,7 @@ impl LayerProperties {
/// If you want to enable this layer on an instance, you need to pass this value to
/// `Instance::new`.
///
/// # Example
/// # Examples
///
/// ```no_run
/// use vulkano::VulkanLibrary;
@ -46,7 +46,7 @@ impl LayerProperties {
///
/// This description is chosen by the layer itself.
///
/// # Example
/// # Examples
///
/// ```no_run
/// use vulkano::VulkanLibrary;
@ -68,7 +68,7 @@ impl LayerProperties {
/// Returns the version of Vulkan supported by this layer.
///
/// # Example
/// # Examples
///
/// ```no_run
/// use vulkano::{Version, VulkanLibrary};
@ -90,7 +90,7 @@ impl LayerProperties {
///
/// The number is chosen by the layer itself. It can be used for bug reports for example.
///
/// # Example
/// # Examples
///
/// ```no_run
/// use vulkano::VulkanLibrary;

View File

@ -202,7 +202,7 @@ mod layers;
/// > `export VK_INSTANCE_LAYERS=VK_LAYER_LUNARG_api_dump` on Linux if you installed the Vulkan SDK
/// > will print the list of raw Vulkan function calls.
///
/// ## Example
/// ## Examples
///
/// ```
/// # use std::{sync::Arc, error::Error};
@ -506,7 +506,7 @@ impl Instance {
/// Returns an iterator that enumerates the physical devices available.
///
/// # Example
/// # Examples
///
/// ```no_run
/// # use vulkano::{
@ -589,7 +589,6 @@ impl PartialEq for Instance {
impl Eq for Instance {}
impl Hash for Instance {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.handle.hash(state);
}
@ -745,17 +744,15 @@ pub enum InstanceCreationError {
}
impl Error for InstanceCreationError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match *self {
Self::OomError(ref err) => Some(err),
match self {
Self::OomError(err) => Some(err),
_ => None,
}
}
}
impl Display for InstanceCreationError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match self {
Self::OomError(_) => write!(f, "not enough memory available"),
@ -764,7 +761,6 @@ impl Display for InstanceCreationError {
Self::ExtensionNotPresent => write!(f, "extension not present"),
Self::IncompatibleDriver => write!(f, "incompatible driver"),
Self::ExtensionRestrictionNotMet(err) => Display::fmt(err, f),
Self::RequirementNotMet {
required_for,
requires_one_of,
@ -778,21 +774,18 @@ impl Display for InstanceCreationError {
}
impl From<OomError> for InstanceCreationError {
#[inline]
fn from(err: OomError) -> Self {
Self::OomError(err)
}
}
impl From<ExtensionRestrictionError> for InstanceCreationError {
#[inline]
fn from(err: ExtensionRestrictionError) -> Self {
Self::ExtensionRestrictionNotMet(err)
}
}
impl From<VulkanError> for InstanceCreationError {
#[inline]
fn from(err: VulkanError) -> Self {
match err {
err @ VulkanError::OutOfHostMemory => Self::OomError(OomError::from(err)),

View File

@ -151,12 +151,11 @@ pub enum OomError {
impl Error for OomError {}
impl Display for OomError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
write!(
f,
"{}",
match *self {
match self {
OomError::OutOfHostMemory => "no memory available on the host",
OomError::OutOfDeviceMemory => "no memory available on the graphical device",
}
@ -165,7 +164,6 @@ impl Display for OomError {
}
impl From<VulkanError> for OomError {
#[inline]
fn from(err: VulkanError) -> OomError {
match err {
VulkanError::OutOfHostMemory => OomError::OutOfHostMemory,
@ -182,117 +180,79 @@ impl Error for VulkanError {}
impl Display for VulkanError {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match self {
VulkanError::OutOfHostMemory => write!(
f,
"A host memory allocation has failed.",
),
VulkanError::OutOfDeviceMemory => write!(
f,
"A device memory allocation has failed.",
),
VulkanError::InitializationFailed => write!(
f,
"Initialization of an object could not be completed for implementation-specific reasons.",
),
VulkanError::DeviceLost => write!(
f,
"The logical or physical device has been lost.",
),
VulkanError::MemoryMapFailed => write!(
f,
"Mapping of a memory object has failed.",
),
VulkanError::LayerNotPresent => write!(
f,
"A requested layer is not present or could not be loaded.",
),
VulkanError::ExtensionNotPresent => write!(
f,
"A requested extension is not supported.",
),
VulkanError::FeatureNotPresent => write!(
f,
"A requested feature is not supported.",
),
VulkanError::IncompatibleDriver => write!(
f,
"The requested version of Vulkan is not supported by the driver or is otherwise incompatible for implementation-specific reasons.",
),
VulkanError::TooManyObjects => write!(
f,
"Too many objects of the type have already been created.",
),
VulkanError::FormatNotSupported => write!(
f,
"A requested format is not supported on this device.",
),
VulkanError::FragmentedPool => write!(
f,
"A pool allocation has failed due to fragmentation of the pool's memory.",
),
VulkanError::Unknown => write!(
f,
"An unknown error has occurred; either the application has provided invalid input, or an implementation failure has occurred.",
),
VulkanError::OutOfPoolMemory => write!(
f,
"A pool memory allocation has failed.",
),
VulkanError::InvalidExternalHandle => write!(
f,
"An external handle is not a valid handle of the specified type.",
),
VulkanError::Fragmentation => write!(
f,
"A descriptor pool creation has failed due to fragmentation.",
),
VulkanError::InvalidOpaqueCaptureAddress => write!(
f,
"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 => write!(
f,
"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 => write!(
f,
"A requested operation was not permitted.",
),
VulkanError::SurfaceLost => write!(
f,
"A surface is no longer available.",
),
VulkanError::NativeWindowInUse => write!(
f,
"The requested window is already in use by Vulkan or another API in a manner which prevents it from being used again.",
),
VulkanError::OutOfDate => write!(
f,
"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::ValidationFailed => write!(
f,
"Validation failed.",
),
VulkanError::FullScreenExclusiveModeLost => write!(
f,
"An operation on a swapchain created with application controlled full-screen access failed as it did not have exclusive full-screen access.",
),
VulkanError::InvalidDrmFormatModifierPlaneLayout => write!(
f,
"The requested DRM format modifier plane layout is invalid.",
),
VulkanError::InvalidShader => write!(
f,
"One or more shaders failed to compile or link.",
),
VulkanError::Unnamed(result) => write!(
f,
"Unnamed error, VkResult value {}",
result.as_raw(),
),
}
write!(
f,
"{}",
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::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::Unnamed(result) =>
return write!(f, "unnamed error, VkResult value {}", result.as_raw()),
}
)
}
}
@ -315,7 +275,6 @@ pub struct RequiresOneOf {
impl RequiresOneOf {
/// Returns whether there is more than one possible requirement.
#[inline]
pub fn len(&self) -> usize {
self.api_version.map_or(0, |_| 1)
+ self.features.len()
@ -325,7 +284,6 @@ impl RequiresOneOf {
}
impl Display for RequiresOneOf {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
let mut members_written = 0;

View File

@ -53,6 +53,7 @@ impl VulkanLibrary {
#[allow(non_snake_case)]
fn def_loader_impl() -> Result<Box<dyn Loader>, LoadingError> {
let loader = crate::statically_linked_vulkan_loader!();
Ok(Box::new(loader))
}
@ -177,6 +178,7 @@ impl VulkanLibrary {
}
/// Returns the highest Vulkan version that is supported for instances.
#[inline]
pub fn api_version(&self) -> Version {
self.api_version
}
@ -205,7 +207,7 @@ impl VulkanLibrary {
/// > here is no longer available when you create the `Instance`. This will lead to an error
/// > when calling `Instance::new`.
///
/// # Example
/// # Examples
///
/// ```no_run
/// use vulkano::VulkanLibrary;
@ -315,7 +317,6 @@ where
T: SafeDeref + Send + Sync,
T::Target: Loader,
{
#[inline]
unsafe fn get_instance_proc_addr(
&self,
instance: ash::vk::Instance,
@ -326,7 +327,6 @@ where
}
impl Debug for dyn Loader {
#[inline]
fn fmt(&self, _f: &mut Formatter<'_>) -> Result<(), FmtError> {
Ok(())
}
@ -416,23 +416,21 @@ pub enum LoadingError {
}
impl Error for LoadingError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match *self {
//Self::LibraryLoadFailure(ref err) => Some(err),
Self::OomError(ref err) => Some(err),
match self {
//Self::LibraryLoadFailure(err) => Some(err),
Self::OomError(err) => Some(err),
_ => None,
}
}
}
impl Display for LoadingError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
write!(
f,
"{}",
match *self {
match self {
Self::LibraryLoadFailure(_) => "failed to load the Vulkan shared library",
Self::OomError(_) => "not enough memory available",
}
@ -441,7 +439,6 @@ impl Display for LoadingError {
}
impl From<VulkanError> for LoadingError {
#[inline]
fn from(err: VulkanError) -> Self {
match err {
err @ VulkanError::OutOfHostMemory => Self::OomError(OomError::from(err)),

View File

@ -29,7 +29,7 @@ use std::{
///
/// The destructor of `DeviceMemory` automatically frees the memory.
///
/// # Example
/// # Examples
///
/// ```
/// use vulkano::memory::{DeviceMemory, MemoryAllocateInfo};
@ -547,6 +547,7 @@ impl DeviceMemory {
}
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
#[inline]
pub unsafe fn commitment_unchecked(&self) -> DeviceSize {
let mut output: DeviceSize = 0;
@ -562,7 +563,7 @@ impl DeviceMemory {
/// Exports the device memory into a Unix file descriptor. The caller owns the returned `File`.
///
/// # Panic
/// # Panics
///
/// - Panics if the user requests an invalid handle type for this device memory object.
#[inline]
@ -617,6 +618,7 @@ impl DeviceMemory {
};
let file = unsafe { std::fs::File::from_raw_fd(fd) };
Ok(file)
}
}
@ -660,7 +662,6 @@ impl PartialEq for DeviceMemory {
impl Eq for DeviceMemory {}
impl Hash for DeviceMemory {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.handle.hash(state);
self.device.hash(state);
@ -709,6 +710,7 @@ impl Default for MemoryAllocateInfo<'static> {
impl<'d> MemoryAllocateInfo<'d> {
/// Returns a `MemoryAllocateInfo` with the specified `dedicated_allocation`.
#[inline]
pub fn dedicated_allocation(dedicated_allocation: DedicatedAllocation<'d>) -> Self {
Self {
allocation_size: 0,
@ -748,6 +750,7 @@ pub enum MemoryImportInfo {
handle_type: ExternalMemoryHandleType,
file: File,
},
/// Import memory from a Windows handle.
///
/// `handle_type` must be either [`ExternalMemoryHandleType::OpaqueWin32`] or
@ -777,8 +780,8 @@ vulkan_enum! {
/// Describes a handle type used for Vulkan external memory apis. This is **not** just a
/// suggestion. Check out vkExternalMemoryHandleTypeFlagBits in the Vulkan spec.
///
/// If you specify an handle type that doesnt make sense (for example, using a dma-buf handle type
/// on Windows) when using this handle, a panic will happen.
/// If you specify an handle type that doesnt make sense (for example, using a dma-buf handle
/// type on Windows) when using this handle, a panic will happen.
#[non_exhaustive]
ExternalMemoryHandleType = ExternalMemoryHandleTypeFlags(u32);
@ -1000,26 +1003,23 @@ pub enum DeviceMemoryError {
}
impl Error for DeviceMemoryError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match *self {
Self::OomError(ref err) => Some(err),
Self::MemoryMapError(ref err) => Some(err),
match self {
Self::OomError(err) => Some(err),
Self::MemoryMapError(err) => Some(err),
_ => None,
}
}
}
impl Display for DeviceMemoryError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match *self {
match self {
Self::OomError(_) => write!(f, "not enough memory available"),
Self::TooManyObjects => {
write!(f, "the maximum number of allocations has been exceeded")
}
Self::MemoryMapError(_) => write!(f, "error occurred when mapping the memory"),
Self::RequirementNotMet {
required_for,
requires_one_of,
@ -1028,22 +1028,25 @@ impl Display for DeviceMemoryError {
"a requirement was not met for: {}; requires one of: {}",
required_for, requires_one_of,
),
Self::DedicatedAllocationSizeMismatch { allocation_size, required_size } => write!(
f,
"`dedicated_allocation` was `Some`, but the provided `allocation_size` ({}) was different from the required size of the buffer or image ({})",
allocation_size, required_size,
),
Self::HandleTypeNotSupported {
handle_type,
Self::DedicatedAllocationSizeMismatch {
allocation_size,
required_size,
} => write!(
f,
"the requested export handle type ({:?}) is not supported for this operation, or was not provided in `export_handle_types` when allocating the memory",
"`dedicated_allocation` was `Some`, but the provided `allocation_size` ({}) was \
different from the required size of the buffer or image ({})",
allocation_size, required_size,
),
Self::HandleTypeNotSupported { handle_type } => write!(
f,
"the requested export handle type ({:?}) is not supported for this operation, or \
was not provided in `export_handle_types` when allocating the memory",
handle_type,
),
Self::ImportFdHandleTypeNotSupported { handle_type } => write!(
f,
"the provided `MemoryImportInfo::Fd::handle_type` ({:?}) is not supported for file descriptors",
"the provided `MemoryImportInfo::Fd::handle_type` ({:?}) is not supported for file \
descriptors",
handle_type,
),
Self::ImportWin32HandleTypeNotSupported { handle_type } => write!(
@ -1051,19 +1054,28 @@ impl Display for DeviceMemoryError {
"the provided `MemoryImportInfo::Win32::handle_type` ({:?}) is not supported",
handle_type,
),
Self::MemoryTypeHeapSizeExceeded { allocation_size, heap_size } => write!(
Self::MemoryTypeHeapSizeExceeded {
allocation_size,
heap_size,
} => write!(
f,
"the provided `allocation_size` ({}) was greater than the memory type's heap size ({})",
"the provided `allocation_size` ({}) was greater than the memory type's heap size \
({})",
allocation_size, heap_size,
),
Self::MemoryTypeIndexOutOfRange { memory_type_index, memory_type_count } => write!(
Self::MemoryTypeIndexOutOfRange {
memory_type_index,
memory_type_count,
} => write!(
f,
"the provided `memory_type_index` ({}) was not less than the number of memory types in the physical device ({})",
"the provided `memory_type_index` ({}) was not less than the number of memory \
types in the physical device ({})",
memory_type_index, memory_type_count,
),
Self::NotLazilyAllocated => write!(
f,
"the memory type from which this memory was allocated does not have the `lazily_allocated` flag set",
"the memory type from which this memory was allocated does not have the \
`lazily_allocated` flag set",
),
Self::SpecViolation(u) => {
@ -1077,7 +1089,6 @@ impl Display for DeviceMemoryError {
}
impl From<VulkanError> for DeviceMemoryError {
#[inline]
fn from(err: VulkanError) -> Self {
match err {
e @ VulkanError::OutOfHostMemory | e @ VulkanError::OutOfDeviceMemory => {
@ -1090,21 +1101,18 @@ impl From<VulkanError> for DeviceMemoryError {
}
impl From<OomError> for DeviceMemoryError {
#[inline]
fn from(err: OomError) -> Self {
Self::OomError(err)
}
}
impl From<MemoryMapError> for DeviceMemoryError {
#[inline]
fn from(err: MemoryMapError) -> Self {
Self::MemoryMapError(err)
}
}
impl From<RequirementNotMet> for DeviceMemoryError {
#[inline]
fn from(err: RequirementNotMet) -> Self {
Self::RequirementNotMet {
required_for: err.required_for,
@ -1118,7 +1126,7 @@ impl From<RequirementNotMet> for DeviceMemoryError {
/// In order to access the contents of the allocated memory, you can use the `read` and `write`
/// methods.
///
/// # Example
/// # Examples
///
/// ```
/// use vulkano::memory::{DeviceMemory, MappedDeviceMemory, MemoryAllocateInfo};
@ -1132,7 +1140,7 @@ impl From<RequirementNotMet> for DeviceMemoryError {
/// .iter()
/// .position(|t| t.property_flags.host_visible)
/// .map(|i| i as u32)
/// .unwrap(); // Vk specs guarantee that this can't fail
/// .unwrap(); // Vk specs guarantee that this can't fail
///
/// // Allocates 1KB of memory.
/// let memory = DeviceMemory::allocate(
@ -1142,7 +1150,8 @@ impl From<RequirementNotMet> for DeviceMemoryError {
/// memory_type_index,
/// ..Default::default()
/// },
/// ).unwrap();
/// )
/// .unwrap();
/// let mapped_memory = MappedDeviceMemory::new(memory, 0..1024).unwrap();
///
/// // Get access to the content.
@ -1167,7 +1176,6 @@ pub struct MappedDeviceMemory {
//
// Vulkan specs, documentation of `vkFreeMemory`:
// > If a memory object is mapped at the time it is freed, it is implicitly unmapped.
//
impl MappedDeviceMemory {
/// Maps a range of memory to be accessed by the CPU.
@ -1248,6 +1256,7 @@ impl MappedDeviceMemory {
}
/// Unmaps the memory. It will no longer be accessible from the CPU.
#[inline]
pub fn unmap(self) -> DeviceMemory {
unsafe {
let device = self.memory.device();
@ -1278,6 +1287,7 @@ impl MappedDeviceMemory {
/// # Panics
///
/// - Panics if `range` is empty.
#[inline]
pub unsafe fn invalidate_range(&self, range: Range<DeviceSize>) -> Result<(), MemoryMapError> {
if self.coherent {
return Ok(());
@ -1327,6 +1337,7 @@ impl MappedDeviceMemory {
/// # Panics
///
/// - Panics if `range` is empty.
#[inline]
pub unsafe fn flush_range(&self, range: Range<DeviceSize>) -> Result<(), MemoryMapError> {
self.check_range(range.clone())?;
@ -1370,6 +1381,7 @@ impl MappedDeviceMemory {
/// # Panics
///
/// - Panics if `range` is empty.
#[inline]
pub unsafe fn read(&self, range: Range<DeviceSize>) -> Result<&[u8], MemoryMapError> {
self.check_range(range.clone())?;
@ -1399,6 +1411,7 @@ impl MappedDeviceMemory {
/// # Panics
///
/// - Panics if `range` is empty.
#[inline]
pub unsafe fn write(&self, range: Range<DeviceSize>) -> Result<&mut [u8], MemoryMapError> {
self.check_range(range.clone())?;
@ -1491,41 +1504,42 @@ pub enum MemoryMapError {
}
impl Error for MemoryMapError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match *self {
Self::OomError(ref err) => Some(err),
match self {
Self::OomError(err) => Some(err),
_ => None,
}
}
}
impl Display for MemoryMapError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match *self {
match self {
Self::OomError(_) => write!(f, "not enough memory available"),
Self::MemoryMapFailed => write!(f, "memory map failed"),
Self::NotHostVisible => write!(
Self::NotHostVisible => {
write!(f, "tried to map memory whose type is not host-visible")
}
Self::OutOfRange {
provided_range,
allowed_range,
} => write!(
f,
"tried to map memory whose type is not host-visible",
),
Self::OutOfRange { ref provided_range, ref allowed_range } => write!(
f,
"the specified `range` ({:?}) was not contained within the allocated or mapped memory range ({:?})",
"the specified `range` ({:?}) was not contained within the allocated or mapped \
memory range ({:?})",
provided_range, allowed_range,
),
Self::RangeNotAlignedToAtomSize { ref range, atom_size } => write!(
Self::RangeNotAlignedToAtomSize { range, atom_size } => write!(
f,
"the memory is not host-coherent, and the specified `range` bounds ({:?}) are not a multiple of the `non_coherent_atom_size` device property ({})",
"the memory is not host-coherent, and the specified `range` bounds ({:?}) are not \
a multiple of the `non_coherent_atom_size` device property ({})",
range, atom_size,
)
),
}
}
}
impl From<VulkanError> for MemoryMapError {
#[inline]
fn from(err: VulkanError) -> Self {
match err {
e @ VulkanError::OutOfHostMemory | e @ VulkanError::OutOfDeviceMemory => {
@ -1538,7 +1552,6 @@ impl From<VulkanError> for MemoryMapError {
}
impl From<OomError> for MemoryMapError {
#[inline]
fn from(err: OomError) -> Self {
Self::OomError(err)
}

View File

@ -41,7 +41,7 @@ impl PipelineCache {
/// implementation. Therefore you can easily crash your application or the system by passing
/// wrong data. Hence why this function is unsafe.
///
/// # Example
/// # Examples
///
/// This example loads a cache from a file, if it exists.
/// See [`get_data`](#method.get_data) for how to store the data in a file.
@ -61,8 +61,12 @@ impl PipelineCache {
/// let mut data = Vec::new();
/// if let Ok(_) = file.read_to_end(&mut data) {
/// Some(data)
/// } else { None }
/// } else { None }
/// } else {
/// None
/// }
/// } else {
/// None
/// }
/// };
///
/// let cache = if let Some(data) = data {
@ -82,7 +86,7 @@ impl PipelineCache {
/// Builds a new empty pipeline cache.
///
/// # Example
/// # Examples
///
/// ```
/// # use std::sync::Arc;
@ -135,7 +139,7 @@ impl PipelineCache {
///
/// It is `self` that is modified here. The pipeline caches passed as parameter are untouched.
///
/// # Panic
/// # Panics
///
/// - Panics if `self` is included in the list of other pipelines.
///
@ -173,7 +177,7 @@ impl PipelineCache {
///
/// This data can be stored and then reloaded and passed to `PipelineCache::with_data`.
///
/// # Example
/// # Examples
///
/// This example stores the data of a pipeline cache on the disk.
/// See [`with_data`](#method.with_data) for how to reload it.
@ -197,6 +201,7 @@ impl PipelineCache {
/// }
/// }
/// ```
#[inline]
pub fn get_data(&self) -> Result<Vec<u8>, OomError> {
let fns = self.device.fns();

View File

@ -273,7 +273,6 @@ impl Pipeline for ComputePipeline {
}
impl Debug for ComputePipeline {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
write!(f, "<Vulkan compute pipeline {:?}>", self.handle)
}
@ -330,25 +329,23 @@ pub enum ComputePipelineCreationError {
}
impl Error for ComputePipelineCreationError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match *self {
Self::OomError(ref err) => Some(err),
Self::DescriptorSetLayoutCreationError(ref err) => Some(err),
Self::PipelineLayoutCreationError(ref err) => Some(err),
Self::IncompatiblePipelineLayout(ref err) => Some(err),
match self {
Self::OomError(err) => Some(err),
Self::DescriptorSetLayoutCreationError(err) => Some(err),
Self::PipelineLayoutCreationError(err) => Some(err),
Self::IncompatiblePipelineLayout(err) => Some(err),
Self::IncompatibleSpecializationConstants => None,
}
}
}
impl Display for ComputePipelineCreationError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
write!(
f,
"{}",
match *self {
match self {
ComputePipelineCreationError::OomError(_) => "not enough memory available",
ComputePipelineCreationError::DescriptorSetLayoutCreationError(_) => {
"error while creating a descriptor set layout object"
@ -360,7 +357,8 @@ impl Display for ComputePipelineCreationError {
"the pipeline layout is not compatible with what the shader expects"
}
ComputePipelineCreationError::IncompatibleSpecializationConstants => {
"the provided specialization constants are not compatible with what the shader expects"
"the provided specialization constants are not compatible with what the shader \
expects"
}
}
)
@ -368,35 +366,30 @@ impl Display for ComputePipelineCreationError {
}
impl From<OomError> for ComputePipelineCreationError {
#[inline]
fn from(err: OomError) -> ComputePipelineCreationError {
Self::OomError(err)
}
}
impl From<DescriptorSetLayoutCreationError> for ComputePipelineCreationError {
#[inline]
fn from(err: DescriptorSetLayoutCreationError) -> Self {
Self::DescriptorSetLayoutCreationError(err)
}
}
impl From<PipelineLayoutCreationError> for ComputePipelineCreationError {
#[inline]
fn from(err: PipelineLayoutCreationError) -> Self {
Self::PipelineLayoutCreationError(err)
}
}
impl From<PipelineLayoutSupersetError> for ComputePipelineCreationError {
#[inline]
fn from(err: PipelineLayoutSupersetError) -> Self {
Self::IncompatiblePipelineLayout(err)
}
}
impl From<VulkanError> for ComputePipelineCreationError {
#[inline]
fn from(err: VulkanError) -> ComputePipelineCreationError {
match err {
err @ VulkanError::OutOfHostMemory => Self::OomError(OomError::from(err)),

View File

@ -151,6 +151,7 @@ where
Fss: SpecializationConstants,
{
/// Builds the graphics pipeline, using an inferred a pipeline layout.
#[inline]
pub fn build(
self,
device: Arc<Device>,
@ -264,6 +265,7 @@ where
/// Does the same as `build`, except that `build` automatically builds the pipeline layout
/// object corresponding to the union of your shaders while this function allows you to specify
/// the pipeline layout.
#[inline]
pub fn with_pipeline_layout(
mut self,
device: Arc<Device>,
@ -293,12 +295,12 @@ where
}
let has = {
let &Self {
ref render_pass,
let Self {
render_pass,
cache: _,
ref vertex_shader,
ref tessellation_shaders,
vertex_shader,
tessellation_shaders,
geometry_shader: _,
fragment_shader: _,
@ -307,7 +309,7 @@ where
tessellation_state: _,
viewport_state: _,
discard_rectangle_state: _,
ref rasterization_state,
rasterization_state,
multisample_state: _,
depth_stencil_state: _,
color_blend_state: _,
@ -423,24 +425,24 @@ where
let physical_device = device.physical_device();
let properties = physical_device.properties();
let &Self {
ref render_pass,
let Self {
render_pass,
cache: _,
ref vertex_shader,
ref tessellation_shaders,
ref geometry_shader,
ref fragment_shader,
vertex_shader,
tessellation_shaders,
geometry_shader,
fragment_shader,
vertex_input_state: _,
ref input_assembly_state,
ref tessellation_state,
ref viewport_state,
ref discard_rectangle_state,
ref rasterization_state,
ref multisample_state,
ref depth_stencil_state,
ref color_blend_state,
input_assembly_state,
tessellation_state,
viewport_state,
discard_rectangle_state,
rasterization_state,
multisample_state,
depth_stencil_state,
color_blend_state,
} = self;
let render_pass = render_pass.as_ref().expect("Missing render pass");
@ -595,9 +597,9 @@ where
// Vertex input state
// VUID-VkGraphicsPipelineCreateInfo-pVertexInputState-04910
{
let &VertexInputState {
ref bindings,
ref attributes,
let VertexInputState {
bindings,
attributes,
} = vertex_input_state;
// VUID-VkPipelineVertexInputStateCreateInfo-vertexBindingDescriptionCount-00613
@ -1406,18 +1408,15 @@ where
// Discard rectangle state
{
let &DiscardRectangleState {
mode,
ref rectangles,
} = discard_rectangle_state;
let DiscardRectangleState { mode, rectangles } = discard_rectangle_state;
if device.enabled_extensions().ext_discard_rectangles {
// VUID-VkPipelineDiscardRectangleStateCreateInfoEXT-discardRectangleMode-parameter
mode.validate_device(device)?;
let discard_rectangle_count = match *rectangles {
PartialStateMode::Dynamic(count) => count,
PartialStateMode::Fixed(ref rectangles) => rectangles.len() as u32,
let discard_rectangle_count = match rectangles {
PartialStateMode::Dynamic(count) => *count,
PartialStateMode::Fixed(rectangles) => rectangles.len() as u32,
};
// VUID-VkPipelineDiscardRectangleStateCreateInfoEXT-discardRectangleCount-00582
@ -1430,9 +1429,9 @@ where
);
}
} else {
let error = match *rectangles {
let error = match rectangles {
PartialStateMode::Dynamic(_) => true,
PartialStateMode::Fixed(ref rectangles) => !rectangles.is_empty(),
PartialStateMode::Fixed(rectangles) => !rectangles.is_empty(),
};
if error {
@ -1503,8 +1502,8 @@ where
// VUID-VkGraphicsPipelineCreateInfo-rasterizerDiscardEnable-00750
// VUID-VkGraphicsPipelineCreateInfo-pViewportState-04892
if has.viewport_state {
let (viewport_count, scissor_count) = match *viewport_state {
ViewportState::Fixed { ref data } => {
let (viewport_count, scissor_count) = match viewport_state {
ViewportState::Fixed { data } => {
let count = data.len() as u32;
assert!(count != 0); // TODO: return error?
@ -1533,7 +1532,7 @@ where
(count, count)
}
ViewportState::FixedViewport {
ref viewports,
viewports,
scissor_count_dynamic,
} => {
let viewport_count = viewports.len() as u32;
@ -1560,7 +1559,7 @@ where
}
// VUID-VkPipelineViewportStateCreateInfo-scissorCount-04136
let scissor_count = if scissor_count_dynamic {
let scissor_count = if *scissor_count_dynamic {
if !(device.api_version() >= Version::V1_3
|| device.enabled_features().extended_dynamic_state)
{
@ -1583,7 +1582,7 @@ where
(viewport_count, scissor_count)
}
ViewportState::FixedScissor {
ref scissors,
scissors,
viewport_count_dynamic,
} => {
let scissor_count = scissors.len() as u32;
@ -1592,7 +1591,7 @@ where
assert!(scissor_count != 0); // TODO: return error?
// VUID-VkPipelineViewportStateCreateInfo-viewportCount-04135
let viewport_count = if viewport_count_dynamic {
let viewport_count = if *viewport_count_dynamic {
if !(device.api_version() >= Version::V1_3
|| device.enabled_features().extended_dynamic_state)
{
@ -1618,7 +1617,7 @@ where
(viewport_count, scissor_count)
}
ViewportState::Dynamic {
&ViewportState::Dynamic {
count,
viewport_count_dynamic,
scissor_count_dynamic,
@ -1764,10 +1763,10 @@ where
// VUID-VkGraphicsPipelineCreateInfo-renderPass-06053
// VUID-VkGraphicsPipelineCreateInfo-renderPass-06590
if has.depth_stencil_state {
let &DepthStencilState {
ref depth,
ref depth_bounds,
ref stencil,
let DepthStencilState {
depth,
depth_bounds,
stencil,
} = depth_stencil_state;
if let Some(depth_state) = depth {
@ -1860,9 +1859,9 @@ where
}
if let Some(depth_bounds_state) = depth_bounds {
let &DepthBoundsState {
let DepthBoundsState {
enable_dynamic,
ref bounds,
bounds,
} = depth_bounds_state;
// VUID-VkPipelineDepthStencilStateCreateInfo-depthBoundsTestEnable-00598
@ -1877,7 +1876,7 @@ where
}
// VUID?
if enable_dynamic
if *enable_dynamic
&& !(device.api_version() >= Version::V1_3
|| device.enabled_features().extended_dynamic_state)
{
@ -1909,10 +1908,10 @@ where
}
if let Some(stencil_state) = stencil {
let &StencilState {
let StencilState {
enable_dynamic,
ref front,
ref back,
front,
back,
} = stencil_state;
let has_stencil_attachment = match render_pass {
@ -1927,7 +1926,7 @@ where
}
// VUID?
if enable_dynamic
if *enable_dynamic
&& !(device.api_version() >= Version::V1_3
|| device.enabled_features().extended_dynamic_state)
{
@ -2089,9 +2088,9 @@ where
// VUID-VkGraphicsPipelineCreateInfo-renderPass-06044
// VUID-VkGraphicsPipelineCreateInfo-renderPass-06054
if has.color_blend_state {
let &ColorBlendState {
let ColorBlendState {
logic_op,
ref attachments,
attachments,
blend_constants: _,
} = color_blend_state;
@ -2446,9 +2445,9 @@ where
{
dynamic_state.insert(DynamicState::VertexInput, false);
let &VertexInputState {
ref bindings,
ref attributes,
let VertexInputState {
bindings,
attributes,
} = vertex_input_state;
vertex_binding_descriptions_vk.extend(bindings.iter().map(
@ -2865,27 +2864,26 @@ where
// Discard rectangle state
if device.enabled_extensions().ext_discard_rectangles {
let &DiscardRectangleState {
mode,
ref rectangles,
} = discard_rectangle_state;
let DiscardRectangleState { mode, rectangles } = discard_rectangle_state;
let discard_rectangle_count = match *rectangles {
PartialStateMode::Fixed(ref rectangles) => {
let discard_rectangle_count = match rectangles {
PartialStateMode::Fixed(rectangles) => {
dynamic_state.insert(DynamicState::DiscardRectangle, false);
discard_rectangles.extend(rectangles.iter().map(|&rect| rect.into()));
discard_rectangles.len() as u32
}
PartialStateMode::Dynamic(count) => {
dynamic_state.insert(DynamicState::DiscardRectangle, true);
count
*count
}
};
let _ = discard_rectangle_state_vk.insert(
ash::vk::PipelineDiscardRectangleStateCreateInfoEXT {
flags: ash::vk::PipelineDiscardRectangleStateCreateFlagsEXT::empty(),
discard_rectangle_mode: mode.into(),
discard_rectangle_mode: (*mode).into(),
discard_rectangle_count,
p_discard_rectangles: discard_rectangles.as_ptr(),
..Default::default()
@ -2920,8 +2918,8 @@ where
// Viewport state
if has.viewport_state {
let (viewport_count, scissor_count) = match *viewport_state {
ViewportState::Fixed { ref data } => {
let (viewport_count, scissor_count) = match viewport_state {
ViewportState::Fixed { data } => {
let count = data.len() as u32;
viewports_vk.extend(data.iter().map(|e| e.0.clone().into()));
dynamic_state.insert(DynamicState::Viewport, false);
@ -2934,7 +2932,7 @@ where
(count, count)
}
ViewportState::FixedViewport {
ref viewports,
viewports,
scissor_count_dynamic,
} => {
let viewport_count = viewports.len() as u32;
@ -2942,7 +2940,7 @@ where
dynamic_state.insert(DynamicState::Viewport, false);
dynamic_state.insert(DynamicState::ViewportWithCount, false);
let scissor_count = if scissor_count_dynamic {
let scissor_count = if *scissor_count_dynamic {
dynamic_state.insert(DynamicState::Scissor, false);
dynamic_state.insert(DynamicState::ScissorWithCount, true);
0
@ -2955,15 +2953,15 @@ where
(viewport_count, scissor_count)
}
ViewportState::FixedScissor {
ref scissors,
scissors,
viewport_count_dynamic,
} => {
let scissor_count = scissors.len() as u32;
scissors_vk.extend(scissors.iter().map(|e| (*e).into()));
scissors_vk.extend(scissors.iter().map(|&e| e.into()));
dynamic_state.insert(DynamicState::Scissor, false);
dynamic_state.insert(DynamicState::ScissorWithCount, false);
let viewport_count = if viewport_count_dynamic {
let viewport_count = if *viewport_count_dynamic {
dynamic_state.insert(DynamicState::Viewport, false);
dynamic_state.insert(DynamicState::ViewportWithCount, true);
0
@ -2975,7 +2973,7 @@ where
(viewport_count, scissor_count)
}
ViewportState::Dynamic {
&ViewportState::Dynamic {
count,
viewport_count_dynamic,
scissor_count_dynamic,
@ -2983,19 +2981,23 @@ where
let viewport_count = if viewport_count_dynamic {
dynamic_state.insert(DynamicState::Viewport, false);
dynamic_state.insert(DynamicState::ViewportWithCount, true);
0
} else {
dynamic_state.insert(DynamicState::Viewport, true);
dynamic_state.insert(DynamicState::ViewportWithCount, false);
count
};
let scissor_count = if scissor_count_dynamic {
dynamic_state.insert(DynamicState::Scissor, false);
dynamic_state.insert(DynamicState::ScissorWithCount, true);
0
} else {
dynamic_state.insert(DynamicState::Scissor, true);
dynamic_state.insert(DynamicState::ScissorWithCount, false);
count
};
@ -3071,10 +3073,10 @@ where
// Depth/stencil state
if has.depth_stencil_state {
let &DepthStencilState {
ref depth,
ref depth_bounds,
ref stencil,
let DepthStencilState {
depth,
depth_bounds,
stencil,
} = depth_stencil_state;
let (depth_test_enable, depth_write_enable, depth_compare_op) =
@ -3120,12 +3122,12 @@ where
let (depth_bounds_test_enable, min_depth_bounds, max_depth_bounds) =
if let Some(depth_bounds_state) = depth_bounds {
let &DepthBoundsState {
let DepthBoundsState {
enable_dynamic,
ref bounds,
bounds,
} = depth_bounds_state;
if enable_dynamic {
if *enable_dynamic {
dynamic_state.insert(DynamicState::DepthBoundsTestEnable, true);
} else {
dynamic_state.insert(DynamicState::DepthBoundsTestEnable, false);
@ -3148,13 +3150,13 @@ where
};
let (stencil_test_enable, front, back) = if let Some(stencil_state) = stencil {
let &StencilState {
let StencilState {
enable_dynamic,
ref front,
ref back,
front,
back,
} = stencil_state;
if enable_dynamic {
if *enable_dynamic {
dynamic_state.insert(DynamicState::StencilTestEnable, true);
} else {
dynamic_state.insert(DynamicState::StencilTestEnable, false);
@ -3501,6 +3503,7 @@ where
)
.result()
.map_err(VulkanError::from)?;
output.assume_init()
};
@ -3530,7 +3533,6 @@ impl<'vs, 'tcs, 'tes, 'gs, 'fs, Vdef, Vss, Tcss, Tess, Gss, Fss>
/// Sets the vertex shader to use.
// TODO: correct specialization constants
#[inline]
pub fn vertex_shader<'vs2, Vss2>(
self,
shader: EntryPoint<'vs2>,
@ -3562,7 +3564,6 @@ impl<'vs, 'tcs, 'tes, 'gs, 'fs, Vdef, Vss, Tcss, Tess, Gss, Fss>
/// Sets the tessellation shaders to use.
// TODO: correct specialization constants
#[inline]
pub fn tessellation_shaders<'tcs2, 'tes2, Tcss2, Tess2>(
self,
control_shader: EntryPoint<'tcs2>,
@ -3600,7 +3601,6 @@ impl<'vs, 'tcs, 'tes, 'gs, 'fs, Vdef, Vss, Tcss, Tess, Gss, Fss>
/// Sets the geometry shader to use.
// TODO: correct specialization constants
#[inline]
pub fn geometry_shader<'gs2, Gss2>(
self,
shader: EntryPoint<'gs2>,
@ -3634,7 +3634,6 @@ impl<'vs, 'tcs, 'tes, 'gs, 'fs, Vdef, Vss, Tcss, Tess, Gss, Fss>
///
/// The fragment shader is run once for each pixel that is covered by each primitive.
// TODO: correct specialization constants
#[inline]
pub fn fragment_shader<'fs2, Fss2>(
self,
shader: EntryPoint<'fs2>,
@ -3667,7 +3666,6 @@ impl<'vs, 'tcs, 'tes, 'gs, 'fs, Vdef, Vss, Tcss, Tess, Gss, Fss>
/// Sets the vertex input state.
///
/// The default value is [`VertexInputState::default()`].
#[inline]
pub fn vertex_input_state<T>(
self,
vertex_input_state: T,
@ -3793,7 +3791,6 @@ impl<'vs, 'tcs, 'tes, 'gs, 'fs, Vdef, Vss, Tcss, Tess, Gss, Fss>
/// You will most likely need to explicitly specify the template parameter to the type of a
/// vertex.
#[deprecated(since = "0.27.0", note = "Use `vertex_input_state` instead")]
#[inline]
pub fn vertex_input_single_buffer<V: Vertex>(
self,
) -> GraphicsPipelineBuilder<
@ -3942,7 +3939,6 @@ impl<'vs, 'tcs, 'tes, 'gs, 'fs, Vdef, Vss, Tcss, Tess, Gss, Fss>
/// Sets the viewports to some value, and the scissor boxes to boxes that always cover the
/// whole viewport.
#[deprecated(since = "0.27.0", note = "Use `viewport_state` instead")]
#[inline]
pub fn viewports<I>(self, viewports: I) -> Self
where
I: IntoIterator<Item = Viewport>,
@ -3952,7 +3948,6 @@ impl<'vs, 'tcs, 'tes, 'gs, 'fs, Vdef, Vss, Tcss, Tess, Gss, Fss>
/// Sets the characteristics of viewports and scissor boxes in advance.
#[deprecated(since = "0.27.0", note = "Use `viewport_state` instead")]
#[inline]
pub fn viewports_scissors<I>(mut self, viewports: I) -> Self
where
I: IntoIterator<Item = (Viewport, Scissor)>,
@ -3966,7 +3961,6 @@ impl<'vs, 'tcs, 'tes, 'gs, 'fs, Vdef, Vss, Tcss, Tess, Gss, Fss>
/// Sets the scissor boxes to some values, and viewports to dynamic. The viewports will
/// need to be set before drawing.
#[deprecated(since = "0.27.0", note = "Use `viewport_state` instead")]
#[inline]
pub fn viewports_dynamic_scissors_fixed<I>(mut self, scissors: I) -> Self
where
I: IntoIterator<Item = Scissor>,
@ -3993,7 +3987,6 @@ impl<'vs, 'tcs, 'tes, 'gs, 'fs, Vdef, Vss, Tcss, Tess, Gss, Fss>
/// Sets the viewports to some values, and scissor boxes to dynamic. The scissor boxes will
/// need to be set before drawing.
#[deprecated(since = "0.27.0", note = "Use `viewport_state` instead")]
#[inline]
pub fn viewports_fixed_scissors_dynamic<I>(mut self, viewports: I) -> Self
where
I: IntoIterator<Item = Viewport>,
@ -4152,10 +4145,9 @@ impl<'vs, 'tcs, 'tes, 'gs, 'fs, Vdef, Vss, Tcss, Tess, Gss, Fss>
///
/// Sample shading is disabled by default.
///
/// # Panic
/// # Panics
///
/// - Panics if `min_fract` is not between 0.0 and 1.0.
///
#[deprecated(since = "0.27.0", note = "Use `multisample_state` instead")]
#[inline]
pub fn sample_shading_enabled(mut self, min_fract: f32) -> Self {
@ -4256,7 +4248,6 @@ impl<'vs, 'tcs, 'tes, 'gs, 'fs, Vdef, Vss, Tcss, Tess, Gss, Fss>
}
#[deprecated(since = "0.27.0", note = "Use `color_blend_state` instead")]
#[inline]
pub fn blend_individual<I>(mut self, blend: I) -> Self
where
I: IntoIterator<Item = AttachmentBlend>,
@ -4336,7 +4327,6 @@ impl<'vs, 'tcs, 'tes, 'gs, 'fs, Vdef, Vss, Tcss, Tess, Gss, Fss>
}
/// Sets the render pass subpass to use.
#[inline]
pub fn render_pass(self, render_pass: impl Into<PipelineRenderPassType>) -> Self {
GraphicsPipelineBuilder {
render_pass: Some(render_pass.into()),

View File

@ -197,23 +197,21 @@ pub enum GraphicsPipelineCreationError {
}
impl Error for GraphicsPipelineCreationError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match *self {
Self::OomError(ref err) => Some(err),
Self::PipelineLayoutCreationError(ref err) => Some(err),
Self::IncompatiblePipelineLayout(ref err) => Some(err),
Self::ShaderStagesMismatch(ref err) => Some(err),
Self::IncompatibleVertexDefinition(ref err) => Some(err),
match self {
Self::OomError(err) => Some(err),
Self::PipelineLayoutCreationError(err) => Some(err),
Self::IncompatiblePipelineLayout(err) => Some(err),
Self::ShaderStagesMismatch(err) => Some(err),
Self::IncompatibleVertexDefinition(err) => Some(err),
_ => None,
}
}
}
impl Display for GraphicsPipelineCreationError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match *self {
match self {
Self::RequirementNotMet {
required_for,
requires_one_of,
@ -222,7 +220,6 @@ impl Display for GraphicsPipelineCreationError {
"a requirement was not met for: {}; requires one of: {}",
required_for, requires_one_of,
),
Self::ColorAttachmentFormatBlendNotSupported { attachment_index } => write!(
f,
"color attachment {} has a format that does not support blending",
@ -243,7 +240,8 @@ impl Display for GraphicsPipelineCreationError {
),
Self::FragmentShaderRenderPassIncompatible => write!(
f,
"the output of the fragment shader is not compatible with what the render pass subpass expects",
"the output of the fragment shader is not compatible with what the render pass \
subpass expects",
),
Self::IncompatiblePipelineLayout(_) => write!(
f,
@ -251,7 +249,8 @@ impl Display for GraphicsPipelineCreationError {
),
Self::IncompatibleSpecializationConstants => write!(
f,
"the provided specialization constants are not compatible with what the shader expects",
"the provided specialization constants are not compatible with what the shader \
expects",
),
Self::IncompatibleVertexDefinition(_) => write!(
f,
@ -259,19 +258,21 @@ impl Display for GraphicsPipelineCreationError {
),
Self::InvalidPrimitiveTopology => write!(
f,
"trying to use a patch list without a tessellation shader, or a non-patch-list with a tessellation shader",
"trying to use a patch list without a tessellation shader, or a non-patch-list \
with a tessellation shader",
),
Self::InvalidNumPatchControlPoints => write!(
f,
"patch_control_points was not greater than 0 and less than or equal to the max_tessellation_patch_size limit",
"patch_control_points was not greater than 0 and less than or equal to the \
max_tessellation_patch_size limit",
),
Self::MaxDiscardRectanglesExceeded { .. } => write!(
f,
"the maximum number of discard rectangles has been exceeded",
),
Self::MaxMultiviewViewCountExceeded { .. } => {
write!(f, "the `max_multiview_view_count` limit has been exceeded",)
},
write!(f, "the `max_multiview_view_count` limit has been exceeded")
}
Self::MaxVertexAttribDivisorExceeded { .. } => write!(
f,
"the maximum value for the instance rate divisor has been exceeded",
@ -284,29 +285,29 @@ impl Display for GraphicsPipelineCreationError {
f,
"the maximum offset for a vertex attribute has been exceeded",
),
Self::MaxVertexInputBindingsExceeded { .. } => write!(
f,
"the maximum number of vertex sources has been exceeded",
),
Self::MaxVertexInputBindingsExceeded { .. } => {
write!(f, "the maximum number of vertex sources has been exceeded")
}
Self::MaxVertexInputBindingStrideExceeded { .. } => write!(
f,
"the maximum stride value for vertex input (ie. the distance between two vertex elements) has been exceeded",
),
Self::MaxViewportsExceeded { .. } => write!(
f,
"the maximum number of viewports has been exceeded",
),
Self::MaxViewportDimensionsExceeded => write!(
f,
"the maximum dimensions of viewports has been exceeded",
"the maximum stride value for vertex input (ie. the distance between two vertex \
elements) has been exceeded",
),
Self::MaxViewportsExceeded { .. } => {
write!(f, "the maximum number of viewports has been exceeded")
}
Self::MaxViewportDimensionsExceeded => {
write!(f, "the maximum dimensions of viewports has been exceeded")
}
Self::MismatchBlendingAttachmentsCount => write!(
f,
"the number of attachments specified in the blending does not match the number of attachments in the subpass",
"the number of attachments specified in the blending does not match the number of \
attachments in the subpass",
),
Self::MultisampleRasterizationSamplesMismatch => write!(
f,
"the provided `rasterization_samples` does not match the number of samples of the render subpass",
"the provided `rasterization_samples` does not match the number of samples of the \
render subpass",
),
Self::NoDepthAttachment => write!(
f,
@ -316,30 +317,25 @@ impl Display for GraphicsPipelineCreationError {
f,
"the stencil attachment of the render pass does not match the stencil test",
),
Self::OomError(_) => write!(
f,
"not enough memory available",
),
Self::DescriptorSetLayoutCreationError(_) => write!(
f,
"error while creating a descriptor set layout object",
),
Self::PipelineLayoutCreationError(_) => write!(
f,
"error while creating the pipeline layout object",
),
Self::OomError(_) => write!(f, "not enough memory available"),
Self::DescriptorSetLayoutCreationError(_) => {
write!(f, "error while creating a descriptor set layout object")
}
Self::PipelineLayoutCreationError(_) => {
write!(f, "error while creating the pipeline layout object")
}
Self::ShaderStagesMismatch(_) => write!(
f,
"the output interface of one shader and the input interface of the next shader do not match",
"the output interface of one shader and the input interface of the next shader do \
not match",
),
Self::StencilAttachmentFormatUsageNotSupported => write!(
f,
"the stencil attachment has a format that does not support that usage",
),
Self::StrictLinesNotSupported => write!(
f,
"the strict_lines device property was false",
),
Self::StrictLinesNotSupported => {
write!(f, "the strict_lines device property was false")
}
Self::TopologyNotMatchingGeometryShader => write!(
f,
"the primitives topology does not match what the geometry shader expects",
@ -350,77 +346,69 @@ impl Display for GraphicsPipelineCreationError {
attribute_type,
} => write!(
f,
"the type of the shader input variable at location {} ({:?}) is not compatible with the format of the corresponding vertex input attribute ({:?})",
"the type of the shader input variable at location {} ({:?}) is not compatible \
with the format of the corresponding vertex input attribute ({:?})",
location, shader_type, attribute_type,
),
Self::VertexInputAttributeInvalidBinding { location, binding } => write!(
f,
"the binding number {} specified by vertex input attribute location {} does not exist in the provided list of binding descriptions",
"the binding number {} specified by vertex input attribute location {} does not \
exist in the provided list of binding descriptions",
binding, location,
),
Self::VertexInputAttributeMissing { location } => write!(
f,
"the vertex shader expects an input variable at location {}, but no vertex input attribute exists for that location",
"the vertex shader expects an input variable at location {}, but no vertex input \
attribute exists for that location",
location,
),
Self::VertexInputAttributeUnsupportedFormat { location, format } => write!(
f,
"the format {:?} specified by vertex input attribute location {} is not supported for vertex buffers",
"the format {:?} specified by vertex input attribute location {} is not supported \
for vertex buffers",
format, location,
),
Self::ViewportBoundsExceeded => write!(
f,
"the minimum or maximum bounds of viewports have been exceeded",
),
Self::WrongShaderType => write!(
f,
"the wrong type of shader has been passed",
),
Self::WrongStencilState => write!(
f,
"the requested stencil test is invalid",
),
Self::WrongShaderType => write!(f, "the wrong type of shader has been passed"),
Self::WrongStencilState => write!(f, "the requested stencil test is invalid"),
}
}
}
impl From<OomError> for GraphicsPipelineCreationError {
#[inline]
fn from(err: OomError) -> GraphicsPipelineCreationError {
Self::OomError(err)
}
}
impl From<DescriptorSetLayoutCreationError> for GraphicsPipelineCreationError {
#[inline]
fn from(err: DescriptorSetLayoutCreationError) -> Self {
Self::DescriptorSetLayoutCreationError(err)
}
}
impl From<PipelineLayoutCreationError> for GraphicsPipelineCreationError {
#[inline]
fn from(err: PipelineLayoutCreationError) -> Self {
Self::PipelineLayoutCreationError(err)
}
}
impl From<PipelineLayoutSupersetError> for GraphicsPipelineCreationError {
#[inline]
fn from(err: PipelineLayoutSupersetError) -> Self {
Self::IncompatiblePipelineLayout(err)
}
}
impl From<IncompatibleVertexDefinitionError> for GraphicsPipelineCreationError {
#[inline]
fn from(err: IncompatibleVertexDefinitionError) -> Self {
Self::IncompatibleVertexDefinition(err)
}
}
impl From<VulkanError> for GraphicsPipelineCreationError {
#[inline]
fn from(err: VulkanError) -> Self {
match err {
err @ VulkanError::OutOfHostMemory => Self::OomError(OomError::from(err)),
@ -431,7 +419,6 @@ impl From<VulkanError> for GraphicsPipelineCreationError {
}
impl From<RequirementNotMet> for GraphicsPipelineCreationError {
#[inline]
fn from(err: RequirementNotMet) -> Self {
Self::RequirementNotMet {
required_for: err.required_for,

View File

@ -183,7 +183,6 @@ pub enum PrimitiveTopologyClass {
impl PrimitiveTopologyClass {
/// Returns a representative example of this topology class.
#[inline]
pub(crate) fn example(&self) -> PrimitiveTopology {
match self {
Self::Point => PrimitiveTopology::PointList,

View File

@ -123,6 +123,7 @@ pub struct GraphicsPipeline {
impl GraphicsPipeline {
/// Starts the building process of a graphics pipeline. Returns a builder object that you can
/// fill with the various parameters.
#[inline]
pub fn start() -> GraphicsPipelineBuilder<
'static,
'static,
@ -155,7 +156,8 @@ impl GraphicsPipeline {
///
/// `None` is returned if the pipeline does not contain this shader.
///
/// Compatibility note: `()` is temporary, it will be replaced with something else in the future.
/// Compatibility note: `()` is temporary, it will be replaced with something else in the
/// future.
// TODO: ^ implement and make this public
#[inline]
pub(crate) fn shader(&self, stage: ShaderStage) -> Option<()> {
@ -230,11 +232,13 @@ impl GraphicsPipeline {
///
/// `None` is returned if the pipeline does not contain this state. Previously set dynamic
/// state is not disturbed when binding it.
#[inline]
pub fn dynamic_state(&self, state: DynamicState) -> Option<bool> {
self.dynamic_state.get(&state).copied()
}
/// Returns all potentially dynamic states in the pipeline, and whether they are dynamic or not.
#[inline]
pub fn dynamic_states(&self) -> impl ExactSizeIterator<Item = (DynamicState, bool)> + '_ {
self.dynamic_state.iter().map(|(k, v)| (*k, *v))
}
@ -265,7 +269,6 @@ unsafe impl DeviceOwned for GraphicsPipeline {
}
impl Debug for GraphicsPipeline {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
write!(f, "<Vulkan graphics pipeline {:?}>", self.handle)
}
@ -300,7 +303,6 @@ impl PartialEq for GraphicsPipeline {
impl Eq for GraphicsPipeline {}
impl Hash for GraphicsPipeline {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.handle.hash(state);
self.device.hash(state);

View File

@ -298,6 +298,7 @@ vulkan_enum! {
impl Default for LineRasterizationMode {
/// Returns `LineRasterizationMode::Default`.
#[inline]
fn default() -> Self {
Self::Default
}

View File

@ -40,6 +40,7 @@ impl TessellationState {
}
/// Sets the number of patch control points to dynamic.
#[inline]
pub fn patch_control_points_dynamic(mut self) -> Self {
self.patch_control_points = StateMode::Dynamic;
self

View File

@ -43,7 +43,6 @@ impl Debug for VertexBuffer {
}
impl From<VertexBuffer> for VertexInputBindingDescription {
#[inline]
fn from(val: VertexBuffer) -> Self {
Self {
stride: val.stride,
@ -54,6 +53,7 @@ impl From<VertexBuffer> for VertexInputBindingDescription {
impl BuffersDefinition {
/// Constructs a new definition.
#[inline]
pub fn new() -> Self {
BuffersDefinition(Vec::new())
}
@ -65,6 +65,7 @@ impl BuffersDefinition {
stride: mem::size_of::<V>() as u32,
input_rate: VertexInputRate::Vertex,
});
self
}
@ -75,31 +76,34 @@ impl BuffersDefinition {
stride: mem::size_of::<V>() as u32,
input_rate: VertexInputRate::Instance { divisor: 1 },
});
self
}
/// Adds a new instance buffer containing elements of type `V` to the definition, with the
/// specified input rate divisor.
///
/// This requires the
/// [`vertex_attribute_instance_rate_divisor`](crate::device::Features::vertex_attribute_instance_rate_divisor)
/// feature has been enabled on the device, unless `divisor` is 1.
/// This requires the [`vertex_attribute_instance_rate_divisor`] feature has been enabled on
/// the device, unless `divisor` is 1.
///
/// `divisor` can be 0 if the
/// [`vertex_attribute_instance_rate_zero_divisor`](crate::device::Features::vertex_attribute_instance_rate_zero_divisor)
/// feature is also enabled. This means that every vertex will use the same vertex and instance
/// data.
/// `divisor` can be 0 if the [`vertex_attribute_instance_rate_zero_divisor`] feature is also
/// enabled. This means that every vertex will use the same vertex and instance data.
///
/// [`vertex_attribute_instance_rate_divisor`]: crate::device::Features::vertex_attribute_instance_rate_divisor
/// [`vertex_attribute_instance_rate_zero_divisor`]: crate::device::Features::vertex_attribute_instance_rate_zero_divisor
pub fn instance_with_divisor<V: Vertex>(mut self, divisor: u32) -> Self {
self.0.push(VertexBuffer {
info_fn: V::member,
stride: mem::size_of::<V>() as u32,
input_rate: VertexInputRate::Instance { divisor },
});
self
}
}
unsafe impl VertexDefinition for BuffersDefinition {
#[inline]
fn definition(
&self,
interface: &ShaderInterface,

View File

@ -25,14 +25,12 @@ impl VertexBuffersCollection for () {
}
impl<T: BufferAccessObject> VertexBuffersCollection for T {
#[inline]
fn into_vec(self) -> Vec<Arc<dyn BufferAccess>> {
vec![self.as_buffer_access_object()]
}
}
impl<T: BufferAccessObject> VertexBuffersCollection for Vec<T> {
#[inline]
fn into_vec(self) -> Vec<Arc<dyn BufferAccess>> {
self.into_iter()
.map(|src| src.as_buffer_access_object())
@ -41,7 +39,6 @@ impl<T: BufferAccessObject> VertexBuffersCollection for Vec<T> {
}
impl<T: BufferAccessObject, const N: usize> VertexBuffersCollection for [T; N] {
#[inline]
fn into_vec(self) -> Vec<Arc<dyn BufferAccess>> {
self.into_iter()
.map(|src| src.as_buffer_access_object())

View File

@ -17,7 +17,7 @@
//! The `Vertex` trait is unsafe, but can be implemented on a struct with the `impl_vertex!`
//! macro.
//!
//! # Example
//! # Examples
//!
//! ```ignore // TODO:
//! # #[macro_use] extern crate vulkano
@ -40,11 +40,11 @@
//!
//! let usage = BufferUsage {
//! vertex_buffer: true,
//! .. BufferUsage::empty()
//! ..BufferUsage::empty()
//! };
//!
//! let vertex_buffer = BufferAccess::<[Vertex], _>::array(&device, 128, &usage, HostVisible, &queue)
//! .expect("failed to create buffer");
//! .expect("failed to create buffer");
//!
//! // TODO: finish example
//! # }
@ -103,11 +103,10 @@ pub enum IncompatibleVertexDefinitionError {
impl Error for IncompatibleVertexDefinitionError {}
impl Display for IncompatibleVertexDefinitionError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match *self {
match self {
IncompatibleVertexDefinitionError::MissingAttribute { .. } => {
write!(f, "an attribute is missing",)
write!(f, "an attribute is missing")
}
IncompatibleVertexDefinitionError::FormatMismatch { .. } => {
write!(f, "the format of an attribute does not match")

View File

@ -10,21 +10,20 @@
use crate::pipeline::graphics::vertex_input::VertexMemberTy;
/// Implements the `Vertex` trait on a struct.
///# Example
///
///```
/// # Examples
///
/// ```
/// # use bytemuck::{Zeroable, Pod};
/// #[repr(C)]
/// #[derive(Clone, Copy, Debug, Default, Zeroable, Pod)]
/// struct Vertex{
/// position: [f32; 3],
/// color: [f32; 4],
/// }
///
///#[repr(C)]
///#[derive(Clone, Copy, Debug, Default, Zeroable, Pod)]
///struct Vertex{
/// position: [f32; 3],
/// color: [f32; 4]
///}
///
///vulkano::impl_vertex!(Vertex, position, color);
///
///```
/// vulkano::impl_vertex!(Vertex, position, color);
/// ```
#[macro_export]
macro_rules! impl_vertex {
($out:ty $(, $member:ident)*) => (
@ -128,7 +127,6 @@ unsafe impl<T> VertexMember for (T,)
where
T: VertexMember,
{
#[inline]
fn format() -> (VertexMemberTy, usize) {
<T as VertexMember>::format()
}
@ -138,7 +136,6 @@ unsafe impl<T> VertexMember for (T, T)
where
T: VertexMember,
{
#[inline]
fn format() -> (VertexMemberTy, usize) {
let (ty, sz) = <T as VertexMember>::format();
(ty, sz * 2)
@ -149,7 +146,6 @@ unsafe impl<T> VertexMember for (T, T, T)
where
T: VertexMember,
{
#[inline]
fn format() -> (VertexMemberTy, usize) {
let (ty, sz) = <T as VertexMember>::format();
(ty, sz * 3)
@ -160,7 +156,6 @@ unsafe impl<T> VertexMember for (T, T, T, T)
where
T: VertexMember,
{
#[inline]
fn format() -> (VertexMemberTy, usize) {
let (ty, sz) = <T as VertexMember>::format();
(ty, sz * 4)
@ -172,7 +167,6 @@ unsafe impl<T> VertexMember for nalgebra::Vector1<T>
where
T: VertexMember,
{
#[inline]
fn format() -> (VertexMemberTy, usize) {
<T as VertexMember>::format()
}
@ -183,7 +177,6 @@ unsafe impl<T> VertexMember for nalgebra::Vector2<T>
where
T: VertexMember,
{
#[inline]
fn format() -> (VertexMemberTy, usize) {
let (ty, sz) = <T as VertexMember>::format();
(ty, sz * 2)
@ -195,7 +188,6 @@ unsafe impl<T> VertexMember for nalgebra::Vector3<T>
where
T: VertexMember,
{
#[inline]
fn format() -> (VertexMemberTy, usize) {
let (ty, sz) = <T as VertexMember>::format();
(ty, sz * 3)
@ -207,7 +199,6 @@ unsafe impl<T> VertexMember for nalgebra::Vector4<T>
where
T: VertexMember,
{
#[inline]
fn format() -> (VertexMemberTy, usize) {
let (ty, sz) = <T as VertexMember>::format();
(ty, sz * 4)
@ -219,7 +210,6 @@ unsafe impl<T> VertexMember for nalgebra::Point1<T>
where
T: VertexMember + nalgebra::Scalar,
{
#[inline]
fn format() -> (VertexMemberTy, usize) {
<T as VertexMember>::format()
}
@ -230,7 +220,6 @@ unsafe impl<T> VertexMember for nalgebra::Point2<T>
where
T: VertexMember + nalgebra::Scalar,
{
#[inline]
fn format() -> (VertexMemberTy, usize) {
let (ty, sz) = <T as VertexMember>::format();
(ty, sz * 2)
@ -242,7 +231,6 @@ unsafe impl<T> VertexMember for nalgebra::Point3<T>
where
T: VertexMember + nalgebra::Scalar,
{
#[inline]
fn format() -> (VertexMemberTy, usize) {
let (ty, sz) = <T as VertexMember>::format();
(ty, sz * 3)
@ -254,7 +242,6 @@ unsafe impl<T> VertexMember for nalgebra::Point4<T>
where
T: VertexMember + nalgebra::Scalar,
{
#[inline]
fn format() -> (VertexMemberTy, usize) {
let (ty, sz) = <T as VertexMember>::format();
(ty, sz * 4)
@ -267,7 +254,6 @@ macro_rules! impl_vm_array {
where
T: VertexMember,
{
#[inline]
fn format() -> (VertexMemberTy, usize) {
let (ty, sz) = <T as VertexMember>::format();
(ty, sz * $sz)

View File

@ -143,7 +143,6 @@ impl VertexInputState {
}
/// Sets all bindings.
#[inline]
pub fn bindings(
mut self,
bindings: impl IntoIterator<Item = (u32, VertexInputBindingDescription)>,
@ -164,7 +163,6 @@ impl VertexInputState {
}
/// Sets all attributes.
#[inline]
pub fn attributes(
mut self,
attributes: impl IntoIterator<Item = (u32, VertexInputAttributeDescription)>,
@ -208,14 +206,14 @@ pub enum VertexInputRate {
/// Each element of the source corresponds to an instance.
///
/// `divisor` indicates how many consecutive instances will use the same instance buffer data.
/// This value must be 1, unless the
/// [`vertex_attribute_instance_rate_divisor`](crate::device::Features::vertex_attribute_instance_rate_divisor)
/// feature has been enabled on the device.
/// This value must be 1, unless the [`vertex_attribute_instance_rate_divisor`] feature has
/// been enabled on the device.
///
/// `divisor` can be 0 if the
/// [`vertex_attribute_instance_rate_zero_divisor`](crate::device::Features::vertex_attribute_instance_rate_zero_divisor)
/// feature is also enabled. This means that every vertex will use the same vertex and instance
/// data.
/// `divisor` can be 0 if the [`vertex_attribute_instance_rate_zero_divisor`] feature is also
/// enabled. This means that every vertex will use the same vertex and instance data.
///
/// [`vertex_attribute_instance_rate_divisor`]: crate::device::Features::vertex_attribute_instance_rate_divisor
/// [`vertex_attribute_instance_rate_zero_divisor`]: crate::device::Features::vertex_attribute_instance_rate_zero_divisor
Instance { divisor: u32 },
}

View File

@ -120,7 +120,6 @@ impl ViewportState {
}
/// Creates a `ViewportState` with fixed state from the given viewports and scissors.
#[inline]
pub fn viewport_fixed_scissor_fixed(
data: impl IntoIterator<Item = (Viewport, Scissor)>,
) -> Self {
@ -131,7 +130,6 @@ impl ViewportState {
/// Creates a `ViewportState` with fixed state from the given viewports, and matching scissors
/// that cover the whole viewport.
#[inline]
pub fn viewport_fixed_scissor_irrelevant(data: impl IntoIterator<Item = Viewport>) -> Self {
Self::Fixed {
data: data
@ -174,6 +172,7 @@ impl ViewportState {
/// Returns the number of viewports and scissors.
///
/// `None` is returned if both `viewport_count_dynamic` and `scissor_count_dynamic` are `true`.
#[inline]
pub fn count(&self) -> Option<u32> {
Some(match *self {
ViewportState::Fixed { ref data } => data.len() as u32,

View File

@ -531,6 +531,7 @@ impl PipelineLayout {
///
/// - `handle` must be a valid Vulkan object handle created from `device`.
/// - `create_info` must match the info used to create the object.
#[inline]
pub unsafe fn from_handle(
device: Arc<Device>,
handle: ash::vk::PipelineLayout,
@ -587,6 +588,7 @@ impl PipelineLayout {
}
/// Returns whether `self` is compatible with `other` for the given number of sets.
#[inline]
pub fn is_compatible_with(&self, other: &PipelineLayout, num_sets: u32) -> bool {
let num_sets = num_sets as usize;
assert!(num_sets >= self.set_layouts.len());
@ -680,6 +682,7 @@ impl Drop for PipelineLayout {
unsafe impl VulkanObject for PipelineLayout {
type Object = ash::vk::PipelineLayout;
#[inline]
fn internal_object(&self) -> Self::Object {
self.handle
}
@ -702,7 +705,6 @@ impl PartialEq for PipelineLayout {
impl Eq for PipelineLayout {}
impl Hash for PipelineLayout {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.handle.hash(state);
self.device().hash(state);
@ -822,21 +824,18 @@ pub enum PipelineLayoutCreationError {
}
impl Error for PipelineLayoutCreationError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match *self {
Self::OomError(ref err) => Some(err),
match self {
Self::OomError(err) => Some(err),
_ => None,
}
}
}
impl Display for PipelineLayoutCreationError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match *self {
match self {
Self::OomError(_) => write!(f, "not enough memory available"),
Self::RequirementNotMet {
required_for,
requires_one_of,
@ -845,90 +844,167 @@ impl Display for PipelineLayoutCreationError {
"a requirement was not met for: {}; requires one of: {}",
required_for, requires_one_of,
),
Self::MaxBoundDescriptorSetsExceeded { provided, max_supported } => write!(
Self::MaxBoundDescriptorSetsExceeded {
provided,
max_supported,
} => write!(
f,
"the number of elements in `set_layouts` ({}) is greater than the `max_bound_descriptor_sets` limit ({})",
"the number of elements in `set_layouts` ({}) is greater than the \
`max_bound_descriptor_sets` limit ({})",
provided, max_supported,
),
Self::MaxDescriptorSetSamplersExceeded { provided, max_supported } => write!(
Self::MaxDescriptorSetSamplersExceeded {
provided,
max_supported,
} => write!(
f,
"the `set_layouts` contain more `DescriptorType::Sampler` and `DescriptorType::CombinedImageSampler` descriptors ({}) than the `max_descriptor_set_samplers` limit ({})",
"the `set_layouts` contain more `DescriptorType::Sampler` and \
`DescriptorType::CombinedImageSampler` descriptors ({}) than the \
`max_descriptor_set_samplers` limit ({})",
provided, max_supported,
),
Self::MaxDescriptorSetUniformBuffersExceeded { provided, max_supported } => write!(
Self::MaxDescriptorSetUniformBuffersExceeded {
provided,
max_supported,
} => write!(
f,
"the `set_layouts` contain more `DescriptorType::UniformBuffer` descriptors ({}) than the `max_descriptor_set_uniform_buffers` limit ({})",
"the `set_layouts` contain more `DescriptorType::UniformBuffer` descriptors ({}) \
than the `max_descriptor_set_uniform_buffers` limit ({})",
provided, max_supported,
),
Self::MaxDescriptorSetUniformBuffersDynamicExceeded { provided, max_supported } => write!(
Self::MaxDescriptorSetUniformBuffersDynamicExceeded {
provided,
max_supported,
} => write!(
f,
"the `set_layouts` contain more `DescriptorType::UniformBufferDynamic` descriptors ({}) than the `max_descriptor_set_uniform_buffers_dynamic` limit ({})",
"the `set_layouts` contain more `DescriptorType::UniformBufferDynamic` descriptors \
({}) than the `max_descriptor_set_uniform_buffers_dynamic` limit ({})",
provided, max_supported,
),
Self::MaxDescriptorSetStorageBuffersExceeded { provided, max_supported } => write!(
Self::MaxDescriptorSetStorageBuffersExceeded {
provided,
max_supported,
} => write!(
f,
"the `set_layouts` contain more `DescriptorType::StorageBuffer` descriptors ({}) than the `max_descriptor_set_storage_buffers` limit ({})",
"the `set_layouts` contain more `DescriptorType::StorageBuffer` descriptors ({}) \
than the `max_descriptor_set_storage_buffers` limit ({})",
provided, max_supported,
),
Self::MaxDescriptorSetStorageBuffersDynamicExceeded { provided, max_supported } => write!(
Self::MaxDescriptorSetStorageBuffersDynamicExceeded {
provided,
max_supported,
} => write!(
f,
"the `set_layouts` contain more `DescriptorType::StorageBufferDynamic` descriptors ({}) than the `max_descriptor_set_storage_buffers_dynamic` limit ({})",
"the `set_layouts` contain more `DescriptorType::StorageBufferDynamic` descriptors \
({}) than the `max_descriptor_set_storage_buffers_dynamic` limit ({})",
provided, max_supported,
),
Self::MaxDescriptorSetSampledImagesExceeded { provided, max_supported } => write!(
Self::MaxDescriptorSetSampledImagesExceeded {
provided,
max_supported,
} => write!(
f,
"the `set_layouts` contain more `DescriptorType::SampledImage`, `DescriptorType::CombinedImageSampler` and `DescriptorType::UniformTexelBuffer` descriptors ({}) than the `max_descriptor_set_sampled_images` limit ({})",
"the `set_layouts` contain more `DescriptorType::SampledImage`, \
`DescriptorType::CombinedImageSampler` and `DescriptorType::UniformTexelBuffer` \
descriptors ({}) than the `max_descriptor_set_sampled_images` limit ({})",
provided, max_supported,
),
Self::MaxDescriptorSetStorageImagesExceeded { provided, max_supported } => write!(
Self::MaxDescriptorSetStorageImagesExceeded {
provided,
max_supported,
} => write!(
f,
"the `set_layouts` contain more `DescriptorType::StorageImage` and `DescriptorType::StorageTexelBuffer` descriptors ({}) than the `max_descriptor_set_storage_images` limit ({})",
"the `set_layouts` contain more `DescriptorType::StorageImage` and \
`DescriptorType::StorageTexelBuffer` descriptors ({}) than the \
`max_descriptor_set_storage_images` limit ({})",
provided, max_supported,
),
Self::MaxDescriptorSetInputAttachmentsExceeded { provided, max_supported } => write!(
Self::MaxDescriptorSetInputAttachmentsExceeded {
provided,
max_supported,
} => write!(
f,
"the `set_layouts` contain more `DescriptorType::InputAttachment` descriptors ({}) than the `max_descriptor_set_input_attachments` limit ({})",
"the `set_layouts` contain more `DescriptorType::InputAttachment` descriptors ({}) \
than the `max_descriptor_set_input_attachments` limit ({})",
provided, max_supported,
),
Self::MaxPerStageResourcesExceeded { provided, max_supported } => write!(
Self::MaxPerStageResourcesExceeded {
provided,
max_supported,
} => write!(
f,
"the `set_layouts` contain more bound resources ({}) in a single stage than the `max_per_stage_resources` limit ({})",
"the `set_layouts` contain more bound resources ({}) in a single stage than the \
`max_per_stage_resources` limit ({})",
provided, max_supported,
),
Self::MaxPerStageDescriptorSamplersExceeded { provided, max_supported } => write!(
Self::MaxPerStageDescriptorSamplersExceeded {
provided,
max_supported,
} => write!(
f,
"the `set_layouts` contain more `DescriptorType::Sampler` and `DescriptorType::CombinedImageSampler` descriptors ({}) in a single stage than the `max_per_stage_descriptor_set_samplers` limit ({})",
"the `set_layouts` contain more `DescriptorType::Sampler` and \
`DescriptorType::CombinedImageSampler` descriptors ({}) in a single stage than the \
`max_per_stage_descriptor_set_samplers` limit ({})",
provided, max_supported,
),
Self::MaxPerStageDescriptorUniformBuffersExceeded { provided, max_supported } => write!(
Self::MaxPerStageDescriptorUniformBuffersExceeded {
provided,
max_supported,
} => write!(
f,
"the `set_layouts` contain more `DescriptorType::UniformBuffer` and `DescriptorType::UniformBufferDynamic` descriptors ({}) in a single stage than the `max_per_stage_descriptor_set_uniform_buffers` limit ({})",
"the `set_layouts` contain more `DescriptorType::UniformBuffer` and \
`DescriptorType::UniformBufferDynamic` descriptors ({}) in a single stage than the \
`max_per_stage_descriptor_set_uniform_buffers` limit ({})",
provided, max_supported,
),
Self::MaxPerStageDescriptorStorageBuffersExceeded { provided, max_supported } => write!(
Self::MaxPerStageDescriptorStorageBuffersExceeded {
provided,
max_supported,
} => write!(
f,
"the `set_layouts` contain more `DescriptorType::StorageBuffer` and `DescriptorType::StorageBufferDynamic` descriptors ({}) in a single stage than the `max_per_stage_descriptor_set_storage_buffers` limit ({})",
"the `set_layouts` contain more `DescriptorType::StorageBuffer` and \
`DescriptorType::StorageBufferDynamic` descriptors ({}) in a single stage than the \
`max_per_stage_descriptor_set_storage_buffers` limit ({})",
provided, max_supported,
),
Self::MaxPerStageDescriptorSampledImagesExceeded { provided, max_supported } => write!(
Self::MaxPerStageDescriptorSampledImagesExceeded {
provided,
max_supported,
} => write!(
f,
"the `set_layouts` contain more `DescriptorType::SampledImage`, `DescriptorType::CombinedImageSampler` and `DescriptorType::UniformTexelBuffer` descriptors ({}) in a single stage than the `max_per_stage_descriptor_set_sampled_images` limit ({})",
"the `set_layouts` contain more `DescriptorType::SampledImage`, \
`DescriptorType::CombinedImageSampler` and `DescriptorType::UniformTexelBuffer` \
descriptors ({}) in a single stage than the \
`max_per_stage_descriptor_set_sampled_images` limit ({})",
provided, max_supported,
),
Self::MaxPerStageDescriptorStorageImagesExceeded { provided, max_supported } => write!(
Self::MaxPerStageDescriptorStorageImagesExceeded {
provided,
max_supported,
} => write!(
f,
"the `set_layouts` contain more `DescriptorType::StorageImage` and `DescriptorType::StorageTexelBuffer` descriptors ({}) in a single stage than the `max_per_stage_descriptor_set_storage_images` limit ({})",
"the `set_layouts` contain more `DescriptorType::StorageImage` and \
`DescriptorType::StorageTexelBuffer` descriptors ({}) in a single stage than the \
`max_per_stage_descriptor_set_storage_images` limit ({})",
provided, max_supported,
),
Self::MaxPerStageDescriptorInputAttachmentsExceeded { provided, max_supported } => write!(
Self::MaxPerStageDescriptorInputAttachmentsExceeded {
provided,
max_supported,
} => write!(
f,
"the `set_layouts` contain more `DescriptorType::InputAttachment` descriptors ({}) in a single stage than the `max_per_stage_descriptor_set_input_attachments` limit ({})",
"the `set_layouts` contain more `DescriptorType::InputAttachment` descriptors ({}) \
in a single stage than the `max_per_stage_descriptor_set_input_attachments` limit \
({})",
provided, max_supported,
),
Self::MaxPushConstantsSizeExceeded { provided, max_supported } => write!(
Self::MaxPushConstantsSizeExceeded {
provided,
max_supported,
} => write!(
f,
"an element in `push_constant_ranges` has an `offset + size` ({}) greater than the `max_push_constants_size` limit ({})",
"an element in `push_constant_ranges` has an `offset + size` ({}) greater than the \
`max_push_constants_size` limit ({})",
provided, max_supported,
),
Self::PushConstantRangesStageMultiple => write!(
@ -937,21 +1013,19 @@ impl Display for PipelineLayoutCreationError {
),
Self::SetLayoutsPushDescriptorMultiple => write!(
f,
"multiple elements of `set_layouts` have `push_descriptor` enabled"
"multiple elements of `set_layouts` have `push_descriptor` enabled",
),
}
}
}
impl From<OomError> for PipelineLayoutCreationError {
#[inline]
fn from(err: OomError) -> PipelineLayoutCreationError {
PipelineLayoutCreationError::OomError(err)
}
}
impl From<VulkanError> for PipelineLayoutCreationError {
#[inline]
fn from(err: VulkanError) -> PipelineLayoutCreationError {
match err {
err @ VulkanError::OutOfHostMemory => {
@ -966,7 +1040,6 @@ impl From<VulkanError> for PipelineLayoutCreationError {
}
impl From<RequirementNotMet> for PipelineLayoutCreationError {
#[inline]
fn from(err: RequirementNotMet) -> Self {
Self::RequirementNotMet {
required_for: err.required_for,
@ -994,55 +1067,53 @@ pub enum PipelineLayoutSupersetError {
}
impl Error for PipelineLayoutSupersetError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match *self {
PipelineLayoutSupersetError::DescriptorRequirementsNotMet { ref error, .. } => {
Some(error)
}
match self {
PipelineLayoutSupersetError::DescriptorRequirementsNotMet { error, .. } => Some(error),
_ => None,
}
}
}
impl Display for PipelineLayoutSupersetError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match self {
PipelineLayoutSupersetError::DescriptorRequirementsNotMet { set_num, binding_num, .. } => write!(
PipelineLayoutSupersetError::DescriptorRequirementsNotMet {
set_num,
binding_num,
..
} => write!(
f,
"the descriptor at set {} binding {} does not meet the requirements",
set_num, binding_num
set_num, binding_num,
),
PipelineLayoutSupersetError::DescriptorMissing {
set_num,
binding_num,
} => write!(
f,
"a descriptor at set {} binding {} is required by the shaders, but is missing from the pipeline layout",
set_num, binding_num
"a descriptor at set {} binding {} is required by the shaders, but is missing from \
the pipeline layout",
set_num, binding_num,
),
PipelineLayoutSupersetError::PushConstantRange {
first_range,
second_range,
} => {
writeln!(
f,
"our range did not completely encompass the other range"
)?;
writeln!(f, "our range did not completely encompass the other range")?;
writeln!(f, " our stages: {:?}", first_range.stages)?;
writeln!(
f,
" our range: {} - {}",
first_range.offset,
first_range.offset + first_range.size
first_range.offset + first_range.size,
)?;
writeln!(f, " other stages: {:?}", second_range.stages)?;
write!(
f,
" other range: {} - {}",
second_range.offset,
second_range.offset + second_range.size
second_range.offset + second_range.size,
)
}
}

View File

@ -269,7 +269,6 @@ pub enum StateMode<F> {
}
impl<T> From<Option<T>> for StateMode<T> {
#[inline]
fn from(val: Option<T>) -> Self {
match val {
Some(x) => StateMode::Fixed(x),
@ -279,7 +278,6 @@ impl<T> From<Option<T>> for StateMode<T> {
}
impl<T> From<StateMode<T>> for Option<T> {
#[inline]
fn from(val: StateMode<T>) -> Self {
match val {
StateMode::Fixed(x) => Some(x),

View File

@ -110,6 +110,7 @@ impl QueryPool {
///
/// - `handle` must be a valid Vulkan object handle created from `device`.
/// - `create_info` must match the info used to create the object.
#[inline]
pub unsafe fn from_handle(
device: Arc<Device>,
handle: ash::vk::QueryPool,
@ -120,6 +121,7 @@ impl QueryPool {
query_count,
_ne: _,
} = create_info;
Arc::new(QueryPool {
handle,
device,
@ -152,9 +154,9 @@ impl QueryPool {
/// Returns a reference to a range of queries, or `None` if out of range.
///
/// # Panic
/// # Panics
///
/// Panics if the range is empty.
/// - Panics if the range is empty.
#[inline]
pub fn queries_range(&self, range: Range<u32>) -> Option<QueriesRange<'_>> {
assert!(!range.is_empty());
@ -203,7 +205,6 @@ impl PartialEq for QueryPool {
impl Eq for QueryPool {}
impl Hash for QueryPool {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.handle.hash(state);
self.device().hash(state);
@ -248,17 +249,15 @@ pub enum QueryPoolCreationError {
}
impl Error for QueryPoolCreationError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match *self {
QueryPoolCreationError::OomError(ref err) => Some(err),
match self {
QueryPoolCreationError::OomError(err) => Some(err),
_ => None,
}
}
}
impl Display for QueryPoolCreationError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
write!(
f,
@ -267,7 +266,7 @@ impl Display for QueryPoolCreationError {
QueryPoolCreationError::OomError(_) => "not enough memory available",
QueryPoolCreationError::PipelineStatisticsQueryFeatureNotEnabled => {
"a pipeline statistics pool was requested but the corresponding feature \
wasn't enabled"
wasn't enabled"
}
}
)
@ -275,14 +274,12 @@ impl Display for QueryPoolCreationError {
}
impl From<OomError> for QueryPoolCreationError {
#[inline]
fn from(err: OomError) -> QueryPoolCreationError {
QueryPoolCreationError::OomError(err)
}
}
impl From<VulkanError> for QueryPoolCreationError {
#[inline]
fn from(err: VulkanError) -> QueryPoolCreationError {
match err {
err @ VulkanError::OutOfHostMemory => {
@ -352,6 +349,7 @@ impl<'a> QueriesRange<'a> {
/// is returned if some results were not yet available; these will not be written to the buffer.
///
/// See also [`copy_query_pool_results`](crate::command_buffer::AutoCommandBufferBuilder::copy_query_pool_results).
#[inline]
pub fn get_results<T>(
&self,
destination: &mut [T],
@ -461,22 +459,19 @@ pub enum GetResultsError {
}
impl Error for GetResultsError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match *self {
Self::OomError(ref err) => Some(err),
match self {
Self::OomError(err) => Some(err),
_ => None,
}
}
}
impl Display for GetResultsError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match self {
Self::OomError(_) => write!(f, "not enough memory available"),
Self::DeviceLost => write!(f, "the connection to the device has been lost"),
Self::RequirementNotMet {
required_for,
requires_one_of,
@ -485,7 +480,6 @@ impl Display for GetResultsError {
"a requirement was not met for: {}; requires one of: {}",
required_for, requires_one_of,
),
Self::BufferTooSmall { .. } => write!(f, "the buffer is too small for the operation"),
Self::InvalidFlags => write!(
f,
@ -496,7 +490,6 @@ impl Display for GetResultsError {
}
impl From<VulkanError> for GetResultsError {
#[inline]
fn from(err: VulkanError) -> Self {
match err {
VulkanError::OutOfHostMemory | VulkanError::OutOfDeviceMemory => {
@ -509,14 +502,12 @@ impl From<VulkanError> for GetResultsError {
}
impl From<OomError> for GetResultsError {
#[inline]
fn from(err: OomError) -> Self {
Self::OomError(err)
}
}
impl From<RequirementNotMet> for GetResultsError {
#[inline]
fn from(err: RequirementNotMet) -> Self {
Self::RequirementNotMet {
required_for: err.required_for,

View File

@ -37,6 +37,7 @@ where
V: Eq + Clone,
{
/// Makes a new empty `RangeMap`.
#[inline]
pub fn new() -> Self {
RangeMap {
btm: BTreeMap::new(),
@ -45,12 +46,14 @@ where
/// Returns a reference to the value corresponding to the given key,
/// if the key is covered by any range in the map.
#[inline]
pub fn get(&self, key: &K) -> Option<&V> {
self.get_key_value(key).map(|(_range, value)| value)
}
/// Returns the range-value pair (as a pair of references) corresponding
/// to the given key, if the key is covered by any range in the map.
#[inline]
pub fn get_key_value(&self, key: &K) -> Option<(&Range<K>, &V)> {
// The only stored range that could contain the given key is the
// last stored range whose start is less than or equal to this key.
@ -68,6 +71,7 @@ where
}
/// Returns `true` if any range in the map covers the specified key.
#[inline]
pub fn contains_key(&self, key: &K) -> bool {
self.get(key).is_some()
}
@ -88,6 +92,7 @@ where
/// ordered by key range.
///
/// The iterator element type is `(&'a Range<K>, &'a V)`.
#[inline]
pub fn iter(&self) -> Iter<'_, K, V> {
Iter {
inner: self.btm.iter(),
@ -98,6 +103,7 @@ where
/// ordered by key range.
///
/// The iterator element type is `(&'a Range<K>, &'a mut V)`.
#[inline]
pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
IterMut {
inner: self.btm.iter_mut(),
@ -767,6 +773,7 @@ pub struct RangeStartWrapper<T> {
}
impl<T> RangeStartWrapper<T> {
#[inline]
pub fn new(range: Range<T>) -> RangeStartWrapper<T> {
RangeStartWrapper { range }
}

View File

@ -1577,21 +1577,18 @@ pub enum RenderPassCreationError {
}
impl Error for RenderPassCreationError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match *self {
RenderPassCreationError::OomError(ref err) => Some(err),
match self {
RenderPassCreationError::OomError(err) => Some(err),
_ => None,
}
}
}
impl Display for RenderPassCreationError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match *self {
Self::OomError(_) => write!(f, "not enough memory available",),
match self {
Self::OomError(_) => write!(f, "not enough memory available"),
Self::RequirementNotMet {
required_for,
requires_one_of,
@ -1600,63 +1597,88 @@ impl Display for RenderPassCreationError {
"a requirement was not met for: {}; requires one of: {}",
required_for, requires_one_of,
),
Self::AttachmentFirstUseLoadOpInvalid { attachment, first_use_subpass } => write!(
Self::AttachmentFirstUseLoadOpInvalid {
attachment,
first_use_subpass,
} => write!(
f,
"attachment {} is first used in the render pass in subpass {} with a read-only layout or as an input attachment, but its `load_op` or `stencil_load_op` is `LoadOp::Clear`",
"attachment {} is first used in the render pass in subpass {} with a read-only \
layout or as an input attachment, but its `load_op` or `stencil_load_op` is \
`LoadOp::Clear`",
attachment, first_use_subpass,
),
Self::AttachmentLayoutInvalid { attachment } => write!(
f,
"attachment {} has an `initial_layout` or `final_layout` value that is invalid for the provided `format`",
"attachment {} has an `initial_layout` or `final_layout` value that is invalid for \
the provided `format`",
attachment,
),
Self::CorrelatedViewMasksMultiviewNotEnabled => write!(
f,
"correlated view masks were included, but multiview is not enabled on the render pass",
"correlated view masks were included, but multiview is not enabled on the render \
pass",
),
Self::CorrelatedViewMasksOverlapping => write!(
f,
"the provided correlated view masks contain a bit that is set in more than one element",
"the provided correlated view masks contain a bit that is set in more than one \
element",
),
Self::DependencyAccessNotSupportedByStages { dependency } => write!(
f,
"subpass dependency {} specified an access type that was not supported by the given stages",
dependency,
),
Self::DependencySelfDependencyFramebufferStagesWithoutByRegion { dependency } => write!(
f,
"subpass dependency {} specifies a subpass self-dependency and includes framebuffer stages in both `source_stages` and `destination_stages`, but the `by_region` dependency was not enabled",
dependency,
),
Self::DependencySelfDependencySourceStageAfterDestinationStage { dependency } => write!(
f,
"subpass dependency {} specifies a subpass self-dependency and includes non-framebuffer stages, but the latest stage in `source_stages` is after the earliest stage in `destination_stages`",
"subpass dependency {} specified an access type that was not supported by the \
given stages",
dependency,
),
Self::DependencySelfDependencyFramebufferStagesWithoutByRegion { dependency } => {
write!(
f,
"subpass dependency {} specifies a subpass self-dependency and includes \
framebuffer stages in both `source_stages` and `destination_stages`, but the \
`by_region` dependency was not enabled",
dependency,
)
}
Self::DependencySelfDependencySourceStageAfterDestinationStage { dependency } => {
write!(
f,
"subpass dependency {} specifies a subpass self-dependency and includes \
non-framebuffer stages, but the latest stage in `source_stages` is after the \
earliest stage in `destination_stages`",
dependency,
)
}
Self::DependencySelfDependencyViewLocalNonzeroOffset { dependency } => write!(
f,
"subpass dependency {} specifies a subpass self-dependency and has the `view_local` dependency enabled, but the inner offset value was not 0",
"subpass dependency {} specifies a subpass self-dependency and has the \
`view_local` dependency enabled, but the inner offset value was not 0",
dependency,
),
Self::DependencySelfDependencyViewMaskMultiple { dependency, subpass } => write!(
Self::DependencySelfDependencyViewMaskMultiple {
dependency,
subpass,
} => write!(
f,
"subpass dependency {} specifies a subpass self-dependency without the `view_local` dependency, but the referenced subpass {} has more than one bit set in its `view_mask`",
"subpass dependency {} specifies a subpass self-dependency without the \
`view_local` dependency, but the referenced subpass {} has more than one bit set \
in its `view_mask`",
dependency, subpass,
),
Self::DependencySourceSubpassAfterDestinationSubpass { dependency } => write!(
f,
"subpass dependency {} has a `source_subpass` that is later than the `destination_subpass`",
"subpass dependency {} has a `source_subpass` that is later than the \
`destination_subpass`",
dependency,
),
Self::DependencyStageNotSupported { dependency } => write!(
f,
"subpass dependency {} has a bit set in the `source_stages` or `destination_stages` that is not supported for graphics pipelines",
"subpass dependency {} has a bit set in the `source_stages` or \
`destination_stages` that is not supported for graphics pipelines",
dependency,
),
Self::DependencyBothSubpassesExternal { dependency } => write!(
f,
"subpass dependency {} has both `source_subpass` and `destination_subpass` set to `None`",
"subpass dependency {} has both `source_subpass` and `destination_subpass` set to \
`None`",
dependency,
),
Self::DependencySubpassOutOfRange {
@ -1664,25 +1686,35 @@ impl Display for RenderPassCreationError {
subpass,
} => write!(
f,
"the subpass index {} in subpass dependency {} is not less than the number of subpasses in the render pass",
"the subpass index {} in subpass dependency {} is not less than the number of \
subpasses in the render pass",
subpass, dependency,
),
Self::DependencyViewLocalExternalDependency { dependency } => write!(
f,
"subpass dependency {} has the `view_local` dependency enabled, but `source_subpass` or `destination_subpass` were set to `None`",
"subpass dependency {} has the `view_local` dependency enabled, but \
`source_subpass` or `destination_subpass` were set to `None`",
dependency,
),
Self::DependencyViewLocalMultiviewNotEnabled { dependency } => write!(
f,
"subpass dependency {} has the `view_local` dependency enabled, but multiview is not enabled on the render pass",
"subpass dependency {} has the `view_local` dependency enabled, but multiview is \
not enabled on the render pass",
dependency,
),
Self::SubpassAttachmentAspectsNotEmpty { subpass, attachment } => write!(
Self::SubpassAttachmentAspectsNotEmpty {
subpass,
attachment,
} => write!(
f,
"a reference to attachment {} used other than as an input attachment in subpass {} has one or more aspects selected",
"a reference to attachment {} used other than as an input attachment in subpass {} \
has one or more aspects selected",
attachment, subpass,
),
Self::SubpassAttachmentLayoutMismatch { subpass, attachment } => write!(
Self::SubpassAttachmentLayoutMismatch {
subpass,
attachment,
} => write!(
f,
"the layouts of all uses of attachment {} in subpass {} do not match.",
attachment, subpass,
@ -1693,27 +1725,45 @@ impl Display for RenderPassCreationError {
usage,
} => write!(
f,
"attachment {} used as {} attachment in subpass {} has a layout that is not supported for that usage",
"attachment {} used as {} attachment in subpass {} has a layout that is not \
supported for that usage",
attachment, usage, subpass,
),
Self::SubpassAttachmentOutOfRange { subpass, attachment } => write!(
Self::SubpassAttachmentOutOfRange {
subpass,
attachment,
} => write!(
f,
"the attachment index {} in subpass {} is not less than the number of attachments in the render pass",
"the attachment index {} in subpass {} is not less than the number of attachments \
in the render pass",
attachment, subpass,
),
Self::SubpassAttachmentUsageColorDepthStencil { subpass, attachment } => write!(
Self::SubpassAttachmentUsageColorDepthStencil {
subpass,
attachment,
} => write!(
f,
"attachment {} is used as both a color attachment and a depth/stencil attachment in subpass {}",
"attachment {} is used as both a color attachment and a depth/stencil attachment \
in subpass {}",
attachment, subpass,
),
Self::SubpassAttachmentFormatUsageNotSupported { subpass, attachment, usage, } => write!(
Self::SubpassAttachmentFormatUsageNotSupported {
subpass,
attachment,
usage,
} => write!(
f,
"attachment {} used as {} attachment in subpass {} has a format that does not support that usage",
"attachment {} used as {} attachment in subpass {} has a format that does not \
support that usage",
attachment, usage, subpass,
),
Self::SubpassColorAttachmentWithResolveNotMultisampled { subpass, attachment } => write!(
Self::SubpassColorAttachmentWithResolveNotMultisampled {
subpass,
attachment,
} => write!(
f,
"attachment {} used as a color attachment in subpass {} with resolve attachments has a `samples` value of `SampleCount::Sample1`",
"attachment {} used as a color attachment in subpass {} with resolve attachments \
has a `samples` value of `SampleCount::Sample1`",
attachment, subpass,
),
Self::SubpassColorDepthStencilAttachmentSamplesMismatch {
@ -1723,37 +1773,49 @@ impl Display for RenderPassCreationError {
first_samples,
} => write!(
f,
"attachment {} used as a color or depth/stencil attachment in subpass {} has a `samples` value {:?} that is different from the first color attachment ({:?})",
"attachment {} used as a color or depth/stencil attachment in subpass {} has a \
`samples` value {:?} that is different from the first color attachment ({:?})",
attachment, subpass, samples, first_samples,
),
Self::SubpassInputAttachmentAspectsNotCompatible { subpass, attachment } => write!(
Self::SubpassInputAttachmentAspectsNotCompatible {
subpass,
attachment,
} => write!(
f,
"a reference to attachment {} used as an input attachment in subpass {} selects aspects that are not present in the format of the attachment",
"a reference to attachment {} used as an input attachment in subpass {} selects \
aspects that are not present in the format of the attachment",
attachment, subpass,
),
Self::SubpassMaxColorAttachmentsExceeded { .. } => {
write!(f, "the `max_color_attachments` limit has been exceeded",)
write!(f, "the `max_color_attachments` limit has been exceeded")
}
Self::SubpassMaxMultiviewViewCountExceeded { .. } => {
write!(f, "the `max_multiview_view_count` limit has been exceeded for a subpass",)
},
Self::SubpassMaxMultiviewViewCountExceeded { .. } => write!(
f,
"the `max_multiview_view_count` limit has been exceeded for a subpass",
),
Self::SubpassMultiviewMismatch {
subpass,
multiview,
first_subpass_multiview,
} => write!(
f,
"the multiview state (whether `view_mask` is nonzero) of subpass {} is {}, which is different from the first subpass ({})",
"the multiview state (whether `view_mask` is nonzero) of subpass {} is {}, which \
is different from the first subpass ({})",
subpass, multiview, first_subpass_multiview,
),
Self::SubpassPreserveAttachmentUsedElsewhere { subpass, attachment } => write!(
Self::SubpassPreserveAttachmentUsedElsewhere {
subpass,
attachment,
} => write!(
f,
"attachment {} marked as a preserve attachment in subpass {} is also used as an attachment in that subpass",
"attachment {} marked as a preserve attachment in subpass {} is also used as an \
attachment in that subpass",
attachment, subpass,
),
Self::SubpassResolveAttachmentsColorAttachmentsLenMismatch { subpass } => write!(
f,
"the `resolve_attachments` field of subpass {} was not empty, but its length did not match the length of `color_attachments`",
"the `resolve_attachments` field of subpass {} was not empty, but its length did \
not match the length of `color_attachments`",
subpass,
),
Self::SubpassResolveAttachmentFormatMismatch {
@ -1762,17 +1824,23 @@ impl Display for RenderPassCreationError {
color_attachment,
} => write!(
f,
"attachment {} used as a resolve attachment in subpass {} has a `format` value different from the corresponding color attachment {}",
"attachment {} used as a resolve attachment in subpass {} has a `format` value \
different from the corresponding color attachment {}",
subpass, resolve_attachment, color_attachment,
),
Self::SubpassResolveAttachmentMultisampled { subpass, attachment } => write!(
Self::SubpassResolveAttachmentMultisampled {
subpass,
attachment,
} => write!(
f,
"attachment {} used as a resolve attachment in subpass {} has a `samples` value other than `SampleCount::Sample1`",
"attachment {} used as a resolve attachment in subpass {} has a `samples` value \
other than `SampleCount::Sample1`",
attachment, subpass,
),
Self::SubpassResolveAttachmentWithoutColorAttachment { subpass } => write!(
f,
"a resolve attachment in subpass {} is `Some`, but the corresponding color attachment is `None`",
"a resolve attachment in subpass {} is `Some`, but the corresponding color \
attachment is `None`",
subpass,
),
}
@ -1780,14 +1848,12 @@ impl Display for RenderPassCreationError {
}
impl From<OomError> for RenderPassCreationError {
#[inline]
fn from(err: OomError) -> RenderPassCreationError {
RenderPassCreationError::OomError(err)
}
}
impl From<VulkanError> for RenderPassCreationError {
#[inline]
fn from(err: VulkanError) -> RenderPassCreationError {
match err {
err @ VulkanError::OutOfHostMemory => {
@ -1802,7 +1868,6 @@ impl From<VulkanError> for RenderPassCreationError {
}
impl From<RequirementNotMet> for RenderPassCreationError {
#[inline]
fn from(err: RequirementNotMet) -> Self {
Self::RequirementNotMet {
required_for: err.required_for,

View File

@ -336,6 +336,7 @@ impl Framebuffer {
///
/// - `handle` must be a valid Vulkan object handle created from `render_pass`.
/// - `create_info` must match the info used to create the object.
#[inline]
pub unsafe fn from_handle(
render_pass: Arc<RenderPass>,
handle: ash::vk::Framebuffer,
@ -431,7 +432,6 @@ impl PartialEq for Framebuffer {
impl Eq for Framebuffer {}
impl Hash for Framebuffer {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.handle.hash(state);
self.device().hash(state);
@ -588,33 +588,28 @@ pub enum FramebufferCreationError {
}
impl From<OomError> for FramebufferCreationError {
#[inline]
fn from(err: OomError) -> Self {
Self::OomError(err)
}
}
impl Error for FramebufferCreationError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match *self {
Self::OomError(ref err) => Some(err),
match self {
Self::OomError(err) => Some(err),
_ => None,
}
}
}
impl Display for FramebufferCreationError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match *self {
Self::OomError(_) => write!(
f,
"no memory available",
),
match self {
Self::OomError(_) => write!(f, "no memory available",),
Self::Attachment2dArrayCompatibleDepthStencil { attachment } => write!(
f,
"attachment image {} is a 2D image view created from a 3D image, and has a depth/stencil format",
"attachment image {} is a 2D image view created from a 3D image, and has a \
depth/stencil format",
attachment,
),
Self::AttachmentComponentMappingNotIdentity { attachment } => write!(
@ -632,7 +627,8 @@ impl Display for FramebufferCreationError {
min,
} => write!(
f,
"attachment image {} has an extent ({:?}) smaller than the provided `extent` ({:?})",
"attachment image {} has an extent ({:?}) smaller than the provided `extent` \
({:?})",
attachment, provided, min,
),
Self::AttachmentFormatMismatch {
@ -641,24 +637,19 @@ impl Display for FramebufferCreationError {
required,
} => write!(
f,
"attachment image {} has a `format` ({:?}) different from what the render pass requires ({:?})",
"attachment image {} has a `format` ({:?}) different from what the render pass \
requires ({:?})",
attachment, provided, required,
),
Self::AttachmentMissingUsage {
attachment,
usage,
} => write!(
Self::AttachmentMissingUsage { attachment, usage } => write!(
f,
"attachment image {} is missing usage `{}` that the render pass requires it to have",
"attachment image {} is missing usage `{}` that the render pass requires it to \
have",
attachment, usage,
),
Self::AttachmentMultipleMipLevels {
attachment,
} => write!(
f,
"attachment image {} has multiple mip levels",
attachment,
),
Self::AttachmentMultipleMipLevels { attachment } => {
write!(f, "attachment image {} has multiple mip levels", attachment)
}
Self::AttachmentNotEnoughLayers {
attachment,
provided,
@ -674,27 +665,29 @@ impl Display for FramebufferCreationError {
required,
} => write!(
f,
"attachment image {} has a `samples` ({:?}) different from what the render pass requires ({:?})",
"attachment image {} has a `samples` ({:?}) different from what the render pass \
requires ({:?})",
attachment, provided, required,
),
Self::AttachmentViewType3d {
attachment,
} => write!(
Self::AttachmentViewType3d { attachment } => write!(
f,
"attachment image {} has a `ty` of `ImageViewType::Dim3d`",
attachment,
),
Self::AutoExtentAttachmentsEmpty => write!(
f,
"one of the elements of `extent` is zero, but no attachment images were given to calculate the extent from",
"one of the elements of `extent` is zero, but no attachment images were given to \
calculate the extent from",
),
Self::AutoLayersAttachmentsEmpty => write!(
f,
"`layers` is zero, but no attachment images were given to calculate the number of layers from",
"`layers` is zero, but no attachment images were given to calculate the number of \
layers from",
),
Self::MaxFramebufferExtentExceeded { provided, max } => write!(
f,
"the provided `extent` ({:?}) exceeds the `max_framebuffer_width` or `max_framebuffer_height` limits ({:?})",
"the provided `extent` ({:?}) exceeds the `max_framebuffer_width` or \
`max_framebuffer_height` limits ({:?})",
provided, max,
),
Self::MaxFramebufferLayersExceeded { provided, max } => write!(
@ -708,7 +701,8 @@ impl Display for FramebufferCreationError {
min,
} => write!(
f,
"the render pass has multiview enabled, and attachment image {} has less layers ({}) than the number of views in the render pass ({})",
"the render pass has multiview enabled, and attachment image {} has less layers \
({}) than the number of views in the render pass ({})",
attachment, provided, min,
),
Self::MultiviewLayersInvalid => write!(
@ -720,7 +714,6 @@ impl Display for FramebufferCreationError {
}
impl From<VulkanError> for FramebufferCreationError {
#[inline]
fn from(err: VulkanError) -> Self {
Self::from(OomError::from(err))
}

View File

@ -198,6 +198,7 @@ impl RenderPass {
///
/// - `handle` must be a valid Vulkan object handle created from `device`.
/// - `create_info` must match the info used to create the object.
#[inline]
pub unsafe fn from_handle(
device: Arc<Device>,
handle: ash::vk::RenderPass,
@ -399,21 +400,21 @@ impl RenderPass {
if !(subpasses1.iter())
.zip(subpasses2.iter())
.all(|(subpass1, subpass2)| {
let &SubpassDescription {
let SubpassDescription {
view_mask: view_mask1,
input_attachments: ref input_attachments1,
color_attachments: ref color_attachments1,
resolve_attachments: ref resolve_attachments1,
depth_stencil_attachment: ref depth_stencil_attachment1,
input_attachments: input_attachments1,
color_attachments: color_attachments1,
resolve_attachments: resolve_attachments1,
depth_stencil_attachment: depth_stencil_attachment1,
preserve_attachments: _,
_ne: _,
} = subpass1;
let &SubpassDescription {
let SubpassDescription {
view_mask: view_mask2,
input_attachments: ref input_attachments2,
color_attachments: ref color_attachments2,
resolve_attachments: ref resolve_attachments2,
depth_stencil_attachment: ref depth_stencil_attachment2,
input_attachments: input_attachments2,
color_attachments: color_attachments2,
resolve_attachments: resolve_attachments2,
depth_stencil_attachment: depth_stencil_attachment2,
preserve_attachments: _,
_ne: _,
} = subpass2;
@ -546,7 +547,6 @@ impl PartialEq for RenderPass {
impl Eq for RenderPass {}
impl Hash for RenderPass {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.handle.hash(state);
self.device.hash(state);
@ -727,6 +727,7 @@ impl Subpass {
/// Returns `true` if this subpass is compatible with the fragment output definition.
// TODO: return proper error
#[inline]
pub fn is_compatible_with(&self, shader_interface: &ShaderInterface) -> bool {
self.render_pass
.is_compatible_with_shader(self.subpass_id, shader_interface)

View File

@ -448,6 +448,7 @@ impl Sampler {
///
/// - `handle` must be a valid Vulkan object handle created from `device`.
/// - `create_info` must match the info used to create the object.
#[inline]
pub unsafe fn from_handle(
device: Arc<Device>,
handle: ash::vk::Sampler,
@ -752,7 +753,6 @@ impl PartialEq for Sampler {
impl Eq for Sampler {}
impl Hash for Sampler {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.handle.hash(state);
self.device().hash(state);
@ -854,22 +854,19 @@ pub enum SamplerCreationError {
}
impl Error for SamplerCreationError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match *self {
SamplerCreationError::OomError(ref err) => Some(err),
match self {
SamplerCreationError::OomError(err) => Some(err),
_ => None,
}
}
}
impl Display for SamplerCreationError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match *self {
match self {
Self::OomError(_) => write!(f, "not enough memory available"),
Self::TooManyObjects => write!(f, "too many simultaneous sampler objects",),
Self::TooManyObjects => write!(f, "too many simultaneous sampler objects"),
Self::RequirementNotMet {
required_for,
requires_one_of,
@ -878,61 +875,77 @@ impl Display for SamplerCreationError {
"a requirement was not met for: {}; requires one of: {}",
required_for, requires_one_of,
),
Self::AnisotropyInvalidFilter { .. } => write!(f, "anisotropy was enabled with an invalid filter"),
Self::CompareInvalidReductionMode { .. } => write!(f, "depth comparison was enabled with an invalid reduction mode"),
Self::AnisotropyInvalidFilter { .. } => {
write!(f, "anisotropy was enabled with an invalid filter")
}
Self::CompareInvalidReductionMode { .. } => write!(
f,
"depth comparison was enabled with an invalid reduction mode",
),
Self::MaxSamplerAnisotropyExceeded { .. } => {
write!(f, "max_sampler_anisotropy limit exceeded")
}
Self::MaxSamplerLodBiasExceeded { .. } => write!(f, "mip lod bias limit exceeded"),
Self::SamplerYcbcrConversionAnisotropyEnabled => write!(
f,
"sampler YCbCr conversion was enabled together with anisotropy"
"sampler YCbCr conversion was enabled together with anisotropy",
),
Self::SamplerYcbcrConversionChromaFilterMismatch { .. } => write!(
f,
"sampler YCbCr conversion was enabled, and its format does not support
`sampled_image_ycbcr_conversion_separate_reconstruction_filter`, but `mag_filter`
or `min_filter` did not match the conversion's `chroma_filter`",
),
Self::SamplerYcbcrConversionInvalidAddressMode { .. } => write!(
f,
"sampler YCbCr conversion was enabled, but the address mode for u, v or w was
something other than `ClampToEdge`",
),
Self::SamplerYcbcrConversionInvalidReductionMode { .. } => write!(
f,
"sampler YCbCr conversion was enabled, but the reduction mode was something other \
than `WeightedAverage`",
),
Self::SamplerYcbcrConversionChromaFilterMismatch { .. } => write!(f, "sampler YCbCr conversion was enabled, and its format does not support `sampled_image_ycbcr_conversion_separate_reconstruction_filter`, but `mag_filter` or `min_filter` did not match the conversion's `chroma_filter`"),
Self::SamplerYcbcrConversionInvalidAddressMode { .. } => write!(f, "sampler YCbCr conversion was enabled, but the address mode for u, v or w was something other than `ClampToEdge`"),
Self::SamplerYcbcrConversionInvalidReductionMode { .. } => write!(f, "sampler YCbCr conversion was enabled, but the reduction mode was something other than `WeightedAverage`"),
Self::SamplerYcbcrConversionUnnormalizedCoordinatesEnabled => write!(
f,
"sampler YCbCr conversion was enabled together with unnormalized coordinates"
"sampler YCbCr conversion was enabled together with unnormalized coordinates",
),
Self::UnnormalizedCoordinatesAnisotropyEnabled => write!(
f,
"unnormalized coordinates were enabled together with anisotropy"
"unnormalized coordinates were enabled together with anisotropy",
),
Self::UnnormalizedCoordinatesCompareEnabled => write!(
f,
"unnormalized coordinates were enabled together with depth comparison"
"unnormalized coordinates were enabled together with depth comparison",
),
Self::UnnormalizedCoordinatesFiltersNotEqual { .. } => write!(
f,
"unnormalized coordinates were enabled, but the min and mag filters were not equal"
"unnormalized coordinates were enabled, but the min and mag filters were not equal",
),
Self::UnnormalizedCoordinatesInvalidAddressMode { .. } => write!(
f,
"unnormalized coordinates were enabled, but the address mode for u or v was something other than `ClampToEdge` or `ClampToBorder`"
"unnormalized coordinates were enabled, but the address mode for u or v was \
something other than `ClampToEdge` or `ClampToBorder`",
),
Self::UnnormalizedCoordinatesInvalidMipmapMode { .. } => write!(
f,
"unnormalized coordinates were enabled, but the mipmap mode was not `Nearest`"
"unnormalized coordinates were enabled, but the mipmap mode was not `Nearest`",
),
Self::UnnormalizedCoordinatesNonzeroLod { .. } => write!(
f,
"unnormalized coordinates were enabled, but the LOD range was not zero"
"unnormalized coordinates were enabled, but the LOD range was not zero",
),
}
}
}
impl From<OomError> for SamplerCreationError {
#[inline]
fn from(err: OomError) -> Self {
Self::OomError(err)
}
}
impl From<VulkanError> for SamplerCreationError {
#[inline]
fn from(err: VulkanError) -> Self {
match err {
err @ VulkanError::OutOfHostMemory => Self::OomError(OomError::from(err)),
@ -944,7 +957,6 @@ impl From<VulkanError> for SamplerCreationError {
}
impl From<RequirementNotMet> for SamplerCreationError {
#[inline]
fn from(err: RequirementNotMet) -> Self {
Self::RequirementNotMet {
required_for: err.required_for,
@ -1084,6 +1096,7 @@ pub struct SamplerCreateInfo {
}
impl Default for SamplerCreateInfo {
#[inline]
fn default() -> Self {
Self {
mag_filter: Filter::Nearest,
@ -1475,16 +1488,55 @@ impl Error for SamplerImageViewIncompatibleError {}
impl Display for SamplerImageViewIncompatibleError {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match self {
Self::BorderColorFormatNotCompatible => write!(f, "the sampler has a border color with a numeric type different from the image view"),
Self::BorderColorOpaqueBlackNotIdentitySwizzled => write!(f, "the sampler has an opaque black border color, but the image view is not identity swizzled"),
Self::DepthComparisonNotSupported => write!(f, "the sampler has depth comparison enabled, but this is not supported by the image view"),
Self::DepthComparisonWrongAspect => write!(f, "the sampler has depth comparison enabled, but the image view does not select the `depth` aspect"),
Self::FilterLinearNotSupported => write!(f, "the sampler uses a linear filter, but this is not supported by the image view's format features"),
Self::FilterCubicNotSupported => write!(f, "the sampler uses a cubic filter, but this is not supported by the image view's format features"),
Self::FilterCubicMinmaxNotSupported => write!(f, "the sampler uses a cubic filter with a `Min` or `Max` reduction mode, but this is not supported by the image view's format features"),
Self::MipmapModeLinearNotSupported => write!(f, "the sampler uses a linear mipmap mode, but this is not supported by the image view's format features"),
Self::UnnormalizedCoordinatesMultipleMipLevels => write!(f, "the sampler uses unnormalized coordinates, but the image view has multiple mip levels"),
Self::UnnormalizedCoordinatesViewTypeNotCompatible => write!(f, "the sampler uses unnormalized coordinates, but the image view has a type other than `Dim1d` or `Dim2d`"),
Self::BorderColorFormatNotCompatible => write!(
f,
"the sampler has a border color with a numeric type different from the image view",
),
Self::BorderColorOpaqueBlackNotIdentitySwizzled => write!(
f,
"the sampler has an opaque black border color, but the image view is not identity \
swizzled",
),
Self::DepthComparisonNotSupported => write!(
f,
"the sampler has depth comparison enabled, but this is not supported by the image \
view",
),
Self::DepthComparisonWrongAspect => write!(
f,
"the sampler has depth comparison enabled, but the image view does not select the \
`depth` aspect",
),
Self::FilterLinearNotSupported => write!(
f,
"the sampler uses a linear filter, but this is not supported by the image view's \
format features",
),
Self::FilterCubicNotSupported => write!(
f,
"the sampler uses a cubic filter, but this is not supported by the image view's \
format features",
),
Self::FilterCubicMinmaxNotSupported => write!(
f,
"the sampler uses a cubic filter with a `Min` or `Max` reduction mode, but this is \
not supported by the image view's format features",
),
Self::MipmapModeLinearNotSupported => write!(
f,
"the sampler uses a linear mipmap mode, but this is not supported by the image \
view's format features",
),
Self::UnnormalizedCoordinatesMultipleMipLevels => write!(
f,
"the sampler uses unnormalized coordinates, but the image view has multiple mip \
levels",
),
Self::UnnormalizedCoordinatesViewTypeNotCompatible => write!(
f,
"the sampler uses unnormalized coordinates, but the image view has a type other \
than `Dim1d` or `Dim2d`",
),
}
}
}

View File

@ -362,6 +362,7 @@ impl SamplerYcbcrConversion {
/// - `handle` must be a valid Vulkan object handle created from `device`.
/// - `create_info` must match the info used to create the object.
/// - `create_info.format` must be `Some`.
#[inline]
pub unsafe fn from_handle(
device: Arc<Device>,
handle: ash::vk::SamplerYcbcrConversion,
@ -377,6 +378,7 @@ impl SamplerYcbcrConversion {
force_explicit_reconstruction,
_ne: _,
} = create_info;
Arc::new(SamplerYcbcrConversion {
handle,
device,
@ -506,7 +508,6 @@ impl PartialEq for SamplerYcbcrConversion {
impl Eq for SamplerYcbcrConversion {}
impl Hash for SamplerYcbcrConversion {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.handle.hash(state);
self.device().hash(state);
@ -557,21 +558,18 @@ pub enum SamplerYcbcrConversionCreationError {
}
impl Error for SamplerYcbcrConversionCreationError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match *self {
SamplerYcbcrConversionCreationError::OomError(ref err) => Some(err),
match self {
SamplerYcbcrConversionCreationError::OomError(err) => Some(err),
_ => None,
}
}
}
impl Display for SamplerYcbcrConversionCreationError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match *self {
match self {
Self::OomError(_) => write!(f, "not enough memory available"),
Self::RequirementNotMet {
required_for,
requires_one_of,
@ -580,7 +578,6 @@ impl Display for SamplerYcbcrConversionCreationError {
"a requirement was not met for: {}; requires one of: {}",
required_for, requires_one_of,
),
Self::CubicFilterNotSupported => {
write!(f, "the `Cubic` filter was specified")
}
@ -596,43 +593,37 @@ impl Display for SamplerYcbcrConversionCreationError {
Self::FormatChromaOffsetNotSupported => {
write!(f, "the format does not support the chosen chroma offsets")
}
Self::FormatInvalidComponentMapping => {
write!(
f,
"the component mapping was not valid for use with the chosen format"
)
}
Self::FormatForceExplicitReconstructionNotSupported => {
write!(
f,
"the format does not support `force_explicit_reconstruction`"
)
}
Self::FormatInvalidComponentMapping => write!(
f,
"the component mapping was not valid for use with the chosen format",
),
Self::FormatForceExplicitReconstructionNotSupported => write!(
f,
"the format does not support `force_explicit_reconstruction`",
),
Self::FormatLinearFilterNotSupported => {
write!(f, "the format does not support the `Linear` filter")
}
Self::YcbcrModelInvalidComponentMapping => {
write!(
f,
"the component mapping was not valid for use with the chosen YCbCr model"
)
}
Self::YcbcrRangeFormatNotEnoughBits => {
write!(f, "for the chosen `ycbcr_range`, the R, G or B components being read from the `format` do not have the minimum number of required bits")
}
Self::YcbcrModelInvalidComponentMapping => write!(
f,
"the component mapping was not valid for use with the chosen YCbCr model",
),
Self::YcbcrRangeFormatNotEnoughBits => write!(
f,
"for the chosen `ycbcr_range`, the R, G or B components being read from the \
`format` do not have the minimum number of required bits",
),
}
}
}
impl From<OomError> for SamplerYcbcrConversionCreationError {
#[inline]
fn from(err: OomError) -> SamplerYcbcrConversionCreationError {
SamplerYcbcrConversionCreationError::OomError(err)
}
}
impl From<VulkanError> for SamplerYcbcrConversionCreationError {
#[inline]
fn from(err: VulkanError) -> SamplerYcbcrConversionCreationError {
match err {
err @ VulkanError::OutOfHostMemory => {
@ -647,7 +638,6 @@ impl From<VulkanError> for SamplerYcbcrConversionCreationError {
}
impl From<RequirementNotMet> for SamplerYcbcrConversionCreationError {
#[inline]
fn from(err: RequirementNotMet) -> Self {
Self::RequirementNotMet {
required_for: err.required_for,

View File

@ -63,6 +63,7 @@ impl ShaderModule {
/// # Safety
///
/// - The SPIR-V code is not validated beyond the minimum needed to extract the information.
#[inline]
pub unsafe fn from_words(
device: Arc<Device>,
words: &[u32],
@ -84,11 +85,13 @@ impl ShaderModule {
/// # Panics
///
/// - Panics if the length of `bytes` is not a multiple of 4.
#[inline]
pub unsafe fn from_bytes(
device: Arc<Device>,
bytes: &[u8],
) -> Result<Arc<ShaderModule>, ShaderCreationError> {
assert!((bytes.len() % 4) == 0);
Self::from_words(
device,
std::slice::from_raw_parts(
@ -204,6 +207,7 @@ impl ShaderModule {
entry_points: impl IntoIterator<Item = (String, ExecutionModel, EntryPointInfo)>,
) -> Result<Arc<ShaderModule>, ShaderCreationError> {
assert!((bytes.len() % 4) == 0);
Self::from_words_with_data(
device,
std::slice::from_raw_parts(
@ -220,6 +224,7 @@ impl ShaderModule {
/// Returns information about the entry point with the provided name. Returns `None` if no entry
/// point with that name exists in the shader module or if multiple entry points with the same
/// name exist.
#[inline]
pub fn entry_point<'a>(&'a self, name: &str) -> Option<EntryPoint<'a>> {
self.entry_points.get(name).and_then(|infos| {
if infos.len() == 1 {
@ -234,8 +239,9 @@ impl ShaderModule {
})
}
/// Returns information about the entry point with the provided name and execution model. Returns
/// `None` if no entry and execution model exists in the shader module.
/// Returns information about the entry point with the provided name and execution model.
/// Returns `None` if no entry and execution model exists in the shader module.
#[inline]
pub fn entry_point_with_execution<'a>(
&'a self,
name: &str,
@ -294,7 +300,6 @@ pub enum ShaderCreationError {
}
impl Error for ShaderCreationError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
Self::OomError(err) => Some(err),
@ -604,6 +609,7 @@ pub struct DescriptorIdentifier {
impl DescriptorRequirements {
/// Produces the intersection of two descriptor requirements, so that the requirements of both
/// are satisfied. An error is returned if the requirements conflict.
#[inline]
pub fn intersection(&self, other: &Self) -> Result<Self, DescriptorRequirementsIncompatible> {
let descriptor_types: Vec<_> = self
.descriptor_types
@ -731,7 +737,7 @@ pub struct SpecializationConstantRequirements {
///
/// This trait is implemented on `()` for shaders that don't have any specialization constant.
///
/// # Example
/// # Examples
///
/// ```rust
/// use vulkano::shader::SpecializationConstants;
@ -774,7 +780,6 @@ pub struct SpecializationConstantRequirements {
/// - The `SpecializationMapEntry` returned must contain valid offsets and sizes.
/// - The size of each `SpecializationMapEntry` must match the size of the corresponding constant
/// (`4` for booleans).
///
pub unsafe trait SpecializationConstants {
/// Returns descriptors of the struct's layout.
fn descriptors() -> &'static [SpecializationMapEntry];
@ -840,6 +845,7 @@ impl ShaderInterface {
}
/// Creates a description of an empty shader interface.
#[inline]
pub const fn empty() -> ShaderInterface {
ShaderInterface {
elements: Vec::new(),
@ -855,6 +861,7 @@ impl ShaderInterface {
/// Checks whether the interface is potentially compatible with another one.
///
/// Returns `Ok` if the two interfaces are compatible.
#[inline]
pub fn matches(&self, other: &ShaderInterface) -> Result<(), ShaderInterfaceMismatchError> {
if self.elements().len() != other.elements().len() {
return Err(ShaderInterfaceMismatchError::ElementsCountMismatch {
@ -977,6 +984,7 @@ pub enum ShaderScalarType {
// https://registry.khronos.org/vulkan/specs/1.3-extensions/html/chap43.html#formats-numericformat
impl From<NumericType> for ShaderScalarType {
#[inline]
fn from(val: NumericType) -> Self {
match val {
NumericType::SFLOAT => Self::Float,
@ -1023,12 +1031,11 @@ pub enum ShaderInterfaceMismatchError {
impl Error for ShaderInterfaceMismatchError {}
impl Display for ShaderInterfaceMismatchError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
write!(
f,
"{}",
match *self {
match self {
ShaderInterfaceMismatchError::ElementsCountMismatch { .. } => {
"the number of elements mismatches"
}

View File

@ -29,6 +29,7 @@ use ahash::{HashMap, HashSet};
use std::borrow::Cow;
/// Returns an iterator of the capabilities used by `spirv`.
#[inline]
pub fn spirv_capabilities(spirv: &Spirv) -> impl Iterator<Item = &Capability> {
spirv
.iter_capability()
@ -39,6 +40,7 @@ pub fn spirv_capabilities(spirv: &Spirv) -> impl Iterator<Item = &Capability> {
}
/// Returns an iterator of the extensions used by `spirv`.
#[inline]
pub fn spirv_extensions(spirv: &Spirv) -> impl Iterator<Item = &str> {
spirv
.iter_extension()
@ -49,6 +51,7 @@ pub fn spirv_extensions(spirv: &Spirv) -> impl Iterator<Item = &str> {
}
/// Returns an iterator over all entry points in `spirv`, with information about the entry point.
#[inline]
pub fn entry_points(
spirv: &Spirv,
) -> impl Iterator<Item = (String, ExecutionModel, EntryPointInfo)> + '_ {
@ -56,13 +59,13 @@ pub fn entry_points(
spirv.iter_entry_point().filter_map(move |instruction| {
let (execution_model, function_id, entry_point_name, interface) = match instruction {
&Instruction::EntryPoint {
ref execution_model,
Instruction::EntryPoint {
execution_model,
entry_point,
ref name,
ref interface,
name,
interface,
..
} => (execution_model, entry_point, name, interface),
} => (execution_model, *entry_point, name, interface),
_ => return None,
};
@ -210,7 +213,6 @@ fn inspect_entry_point(
spirv: &Spirv,
entry_point: Id,
) -> HashMap<(u32, u32), DescriptorRequirements> {
#[inline]
fn instruction_chain<'a, const N: usize>(
result: &'a mut HashMap<Id, DescriptorVariable>,
global: &HashMap<Id, DescriptorVariable>,
@ -226,8 +228,8 @@ fn inspect_entry_point(
return Some((variable, Some(0)));
}
let (id, indexes) = match spirv.id(id).instruction() {
&Instruction::AccessChain {
let (id, indexes) = match *spirv.id(id).instruction() {
Instruction::AccessChain {
base, ref indexes, ..
} => (base, indexes),
_ => return None,
@ -237,8 +239,8 @@ fn inspect_entry_point(
// Variable was accessed with an access chain.
// Retrieve index from instruction if it's a constant value.
// TODO: handle a `None` index too?
let index = match spirv.id(*indexes.first().unwrap()).instruction() {
&Instruction::Constant { ref value, .. } => Some(value[0]),
let index = match *spirv.id(*indexes.first().unwrap()).instruction() {
Instruction::Constant { ref value, .. } => Some(value[0]),
_ => None,
};
let variable = result.entry(id).or_insert_with(|| variable.clone());
@ -248,26 +250,23 @@ fn inspect_entry_point(
None
}
#[inline]
fn inst_image_texel_pointer(spirv: &Spirv, id: Id) -> Option<Id> {
match spirv.id(id).instruction() {
&Instruction::ImageTexelPointer { image, .. } => Some(image),
match *spirv.id(id).instruction() {
Instruction::ImageTexelPointer { image, .. } => Some(image),
_ => None,
}
}
#[inline]
fn inst_load(spirv: &Spirv, id: Id) -> Option<Id> {
match spirv.id(id).instruction() {
&Instruction::Load { pointer, .. } => Some(pointer),
match *spirv.id(id).instruction() {
Instruction::Load { pointer, .. } => Some(pointer),
_ => None,
}
}
#[inline]
fn inst_sampled_image(spirv: &Spirv, id: Id) -> Option<Id> {
match spirv.id(id).instruction() {
&Instruction::SampledImage { sampler, .. } => Some(sampler),
match *spirv.id(id).instruction() {
Instruction::SampledImage { sampler, .. } => Some(sampler),
_ => Some(id),
}
}
@ -283,15 +282,15 @@ fn inspect_entry_point(
let mut in_function = false;
for instruction in spirv.instructions() {
if !in_function {
match instruction {
Instruction::Function { result_id, .. } if result_id == &function => {
match *instruction {
Instruction::Function { result_id, .. } if result_id == function => {
in_function = true;
}
_ => {}
}
} else {
match instruction {
&Instruction::AtomicLoad { pointer, .. } => {
match *instruction {
Instruction::AtomicLoad { pointer, .. } => {
// Storage buffer
instruction_chain(result, global, spirv, [], pointer);
@ -307,26 +306,26 @@ fn inspect_entry_point(
}
}
&Instruction::AtomicStore { pointer, .. }
| &Instruction::AtomicExchange { pointer, .. }
| &Instruction::AtomicCompareExchange { pointer, .. }
| &Instruction::AtomicCompareExchangeWeak { pointer, .. }
| &Instruction::AtomicIIncrement { pointer, .. }
| &Instruction::AtomicIDecrement { pointer, .. }
| &Instruction::AtomicIAdd { pointer, .. }
| &Instruction::AtomicISub { pointer, .. }
| &Instruction::AtomicSMin { pointer, .. }
| &Instruction::AtomicUMin { pointer, .. }
| &Instruction::AtomicSMax { pointer, .. }
| &Instruction::AtomicUMax { pointer, .. }
| &Instruction::AtomicAnd { pointer, .. }
| &Instruction::AtomicOr { pointer, .. }
| &Instruction::AtomicXor { pointer, .. }
| &Instruction::AtomicFlagTestAndSet { pointer, .. }
| &Instruction::AtomicFlagClear { pointer, .. }
| &Instruction::AtomicFMinEXT { pointer, .. }
| &Instruction::AtomicFMaxEXT { pointer, .. }
| &Instruction::AtomicFAddEXT { pointer, .. } => {
Instruction::AtomicStore { pointer, .. }
| Instruction::AtomicExchange { pointer, .. }
| Instruction::AtomicCompareExchange { pointer, .. }
| Instruction::AtomicCompareExchangeWeak { pointer, .. }
| Instruction::AtomicIIncrement { pointer, .. }
| Instruction::AtomicIDecrement { pointer, .. }
| Instruction::AtomicIAdd { pointer, .. }
| Instruction::AtomicISub { pointer, .. }
| Instruction::AtomicSMin { pointer, .. }
| Instruction::AtomicUMin { pointer, .. }
| Instruction::AtomicSMax { pointer, .. }
| Instruction::AtomicUMax { pointer, .. }
| Instruction::AtomicAnd { pointer, .. }
| Instruction::AtomicOr { pointer, .. }
| Instruction::AtomicXor { pointer, .. }
| Instruction::AtomicFlagTestAndSet { pointer, .. }
| Instruction::AtomicFlagClear { pointer, .. }
| Instruction::AtomicFMinEXT { pointer, .. }
| Instruction::AtomicFMaxEXT { pointer, .. }
| Instruction::AtomicFAddEXT { pointer, .. } => {
// Storage buffer
if let Some((variable, Some(index))) =
instruction_chain(result, global, spirv, [], pointer)
@ -347,16 +346,16 @@ fn inspect_entry_point(
}
}
&Instruction::CopyMemory { target, source, .. } => {
Instruction::CopyMemory { target, source, .. } => {
instruction_chain(result, global, spirv, [], target);
instruction_chain(result, global, spirv, [], source);
}
&Instruction::CopyObject { operand, .. } => {
Instruction::CopyObject { operand, .. } => {
instruction_chain(result, global, spirv, [], operand);
}
&Instruction::ExtInst { ref operands, .. } => {
Instruction::ExtInst { ref operands, .. } => {
// We don't know which extended instructions take pointers,
// so we must interpret every operand as a pointer.
for &operand in operands {
@ -364,7 +363,7 @@ fn inspect_entry_point(
}
}
&Instruction::FunctionCall {
Instruction::FunctionCall {
function,
ref arguments,
..
@ -386,16 +385,16 @@ fn inspect_entry_point(
}
}
&Instruction::FunctionEnd => return,
Instruction::FunctionEnd => return,
&Instruction::ImageGather {
Instruction::ImageGather {
sampled_image,
ref image_operands,
image_operands,
..
}
| &Instruction::ImageSparseGather {
| Instruction::ImageSparseGather {
sampled_image,
ref image_operands,
image_operands,
..
} => {
if let Some((variable, Some(index))) = instruction_chain(
@ -420,8 +419,8 @@ fn inspect_entry_point(
}
}
&Instruction::ImageDrefGather { sampled_image, .. }
| &Instruction::ImageSparseDrefGather { sampled_image, .. } => {
Instruction::ImageDrefGather { sampled_image, .. }
| Instruction::ImageSparseDrefGather { sampled_image, .. } => {
if let Some((variable, Some(index))) = instruction_chain(
result,
global,
@ -437,24 +436,24 @@ fn inspect_entry_point(
}
}
&Instruction::ImageSampleImplicitLod {
Instruction::ImageSampleImplicitLod {
sampled_image,
ref image_operands,
image_operands,
..
}
| &Instruction::ImageSampleProjImplicitLod {
| Instruction::ImageSampleProjImplicitLod {
sampled_image,
ref image_operands,
image_operands,
..
}
| &Instruction::ImageSparseSampleProjImplicitLod {
| Instruction::ImageSparseSampleProjImplicitLod {
sampled_image,
ref image_operands,
image_operands,
..
}
| &Instruction::ImageSparseSampleImplicitLod {
| Instruction::ImageSparseSampleImplicitLod {
sampled_image,
ref image_operands,
image_operands,
..
} => {
if let Some((variable, Some(index))) = instruction_chain(
@ -478,14 +477,14 @@ fn inspect_entry_point(
}
}
&Instruction::ImageSampleProjExplicitLod {
Instruction::ImageSampleProjExplicitLod {
sampled_image,
ref image_operands,
image_operands,
..
}
| &Instruction::ImageSparseSampleProjExplicitLod {
| Instruction::ImageSparseSampleProjExplicitLod {
sampled_image,
ref image_operands,
image_operands,
..
} => {
if let Some((variable, Some(index))) = instruction_chain(
@ -508,24 +507,24 @@ fn inspect_entry_point(
}
}
&Instruction::ImageSampleDrefImplicitLod {
Instruction::ImageSampleDrefImplicitLod {
sampled_image,
ref image_operands,
image_operands,
..
}
| &Instruction::ImageSampleProjDrefImplicitLod {
| Instruction::ImageSampleProjDrefImplicitLod {
sampled_image,
ref image_operands,
image_operands,
..
}
| &Instruction::ImageSparseSampleDrefImplicitLod {
| Instruction::ImageSparseSampleDrefImplicitLod {
sampled_image,
ref image_operands,
image_operands,
..
}
| &Instruction::ImageSparseSampleProjDrefImplicitLod {
| Instruction::ImageSparseSampleProjDrefImplicitLod {
sampled_image,
ref image_operands,
image_operands,
..
} => {
if let Some((variable, Some(index))) = instruction_chain(
@ -550,24 +549,24 @@ fn inspect_entry_point(
}
}
&Instruction::ImageSampleDrefExplicitLod {
Instruction::ImageSampleDrefExplicitLod {
sampled_image,
ref image_operands,
image_operands,
..
}
| &Instruction::ImageSampleProjDrefExplicitLod {
| Instruction::ImageSampleProjDrefExplicitLod {
sampled_image,
ref image_operands,
image_operands,
..
}
| &Instruction::ImageSparseSampleDrefExplicitLod {
| Instruction::ImageSparseSampleDrefExplicitLod {
sampled_image,
ref image_operands,
image_operands,
..
}
| &Instruction::ImageSparseSampleProjDrefExplicitLod {
| Instruction::ImageSparseSampleProjDrefExplicitLod {
sampled_image,
ref image_operands,
image_operands,
..
} => {
if let Some((variable, Some(index))) = instruction_chain(
@ -591,14 +590,14 @@ fn inspect_entry_point(
}
}
&Instruction::ImageSampleExplicitLod {
Instruction::ImageSampleExplicitLod {
sampled_image,
ref image_operands,
image_operands,
..
}
| &Instruction::ImageSparseSampleExplicitLod {
| Instruction::ImageSparseSampleExplicitLod {
sampled_image,
ref image_operands,
image_operands,
..
} => {
if let Some((variable, Some(index))) = instruction_chain(
@ -626,11 +625,11 @@ fn inspect_entry_point(
}
}
&Instruction::ImageTexelPointer { image, .. } => {
Instruction::ImageTexelPointer { image, .. } => {
instruction_chain(result, global, spirv, [], image);
}
&Instruction::ImageRead { image, .. } => {
Instruction::ImageRead { image, .. } => {
if let Some((variable, Some(index))) =
instruction_chain(result, global, spirv, [inst_load], image)
{
@ -638,7 +637,7 @@ fn inspect_entry_point(
}
}
&Instruction::ImageWrite { image, .. } => {
Instruction::ImageWrite { image, .. } => {
if let Some((variable, Some(index))) =
instruction_chain(result, global, spirv, [inst_load], image)
{
@ -646,11 +645,11 @@ fn inspect_entry_point(
}
}
&Instruction::Load { pointer, .. } => {
Instruction::Load { pointer, .. } => {
instruction_chain(result, global, spirv, [], pointer);
}
&Instruction::SampledImage { image, sampler, .. } => {
Instruction::SampledImage { image, sampler, .. } => {
let identifier =
match instruction_chain(result, global, spirv, [inst_load], image) {
Some((variable, Some(index))) => DescriptorIdentifier {
@ -673,7 +672,7 @@ fn inspect_entry_point(
}
}
&Instruction::Store { pointer, .. } => {
Instruction::Store { pointer, .. } => {
if let Some((variable, Some(index))) =
instruction_chain(result, global, spirv, [], pointer)
{
@ -696,6 +695,7 @@ fn inspect_entry_point(
spirv,
entry_point,
);
result
.into_iter()
.map(|(_, variable)| ((variable.set, variable.binding), variable.reqs))
@ -714,15 +714,15 @@ fn descriptor_requirements_of(spirv: &Spirv, variable_id: Id) -> DescriptorVaria
};
let (mut next_type_id, is_storage_buffer) = {
let variable_type_id = match variable_id_info.instruction() {
Instruction::Variable { result_type_id, .. } => *result_type_id,
let variable_type_id = match *variable_id_info.instruction() {
Instruction::Variable { result_type_id, .. } => result_type_id,
_ => panic!("Id {} is not a variable", variable_id),
};
match spirv.id(variable_type_id).instruction() {
match *spirv.id(variable_type_id).instruction() {
Instruction::TypePointer {
ty, storage_class, ..
} => (Some(*ty), *storage_class == StorageClass::StorageBuffer),
} => (Some(ty), storage_class == StorageClass::StorageBuffer),
_ => panic!(
"Variable {} result_type_id does not refer to a TypePointer instruction",
variable_id
@ -733,7 +733,7 @@ fn descriptor_requirements_of(spirv: &Spirv, variable_id: Id) -> DescriptorVaria
while let Some(id) = next_type_id {
let id_info = spirv.id(id);
next_type_id = match id_info.instruction() {
next_type_id = match *id_info.instruction() {
Instruction::TypeStruct { .. } => {
let decoration_block = id_info.iter_decoration().any(|instruction| {
matches!(
@ -757,7 +757,8 @@ fn descriptor_requirements_of(spirv: &Spirv, variable_id: Id) -> DescriptorVaria
assert!(
decoration_block ^ decoration_buffer_block,
"Structs in shader interface are expected to be decorated with one of Block or BufferBlock"
"Structs in shader interface are expected to be decorated with one of Block or \
BufferBlock",
);
if decoration_buffer_block || decoration_block && is_storage_buffer {
@ -775,16 +776,20 @@ fn descriptor_requirements_of(spirv: &Spirv, variable_id: Id) -> DescriptorVaria
None
}
&Instruction::TypeImage {
Instruction::TypeImage {
sampled_type,
ref dim,
dim,
arrayed,
ms,
sampled,
ref image_format,
image_format,
..
} => {
assert!(sampled != 0, "Vulkan requires that variables of type OpTypeImage have a Sampled operand of 1 or 2");
assert!(
sampled != 0,
"Vulkan requires that variables of type OpTypeImage have a Sampled operand of \
1 or 2",
);
reqs.image_format = image_format.clone().into();
reqs.image_multisampled = ms != 0;
reqs.image_scalar_type = Some(match *spirv.id(sampled_type).instruction() {
@ -809,7 +814,7 @@ fn descriptor_requirements_of(spirv: &Spirv, variable_id: Id) -> DescriptorVaria
Dim::SubpassData => {
assert!(
reqs.image_format.is_none(),
"If Dim is SubpassData, Image Format must be Unknown"
"If Dim is SubpassData, Image Format must be Unknown",
);
assert!(sampled == 2, "If Dim is SubpassData, Sampled must be 2");
assert!(arrayed == 0, "If Dim is SubpassData, Arrayed must be 0");
@ -854,23 +859,25 @@ fn descriptor_requirements_of(spirv: &Spirv, variable_id: Id) -> DescriptorVaria
None
}
&Instruction::TypeSampler { .. } => {
Instruction::TypeSampler { .. } => {
reqs.descriptor_types = vec![DescriptorType::Sampler];
None
}
&Instruction::TypeSampledImage { image_type, .. } => {
Instruction::TypeSampledImage { image_type, .. } => {
reqs.descriptor_types = vec![DescriptorType::CombinedImageSampler];
Some(image_type)
}
&Instruction::TypeArray {
Instruction::TypeArray {
element_type,
length,
..
} => {
let len = match spirv.id(length).instruction() {
&Instruction::Constant { ref value, .. } => {
Instruction::Constant { value, .. } => {
value.iter().rev().fold(0, |a, &b| (a << 32) | b as u64)
}
_ => panic!("failed to find array length"),
@ -883,23 +890,28 @@ fn descriptor_requirements_of(spirv: &Spirv, variable_id: Id) -> DescriptorVaria
Some(element_type)
}
&Instruction::TypeRuntimeArray { element_type, .. } => {
Instruction::TypeRuntimeArray { element_type, .. } => {
reqs.descriptor_count = None;
Some(element_type)
}
&Instruction::TypeAccelerationStructureKHR { .. } => None, // FIXME temporary workaround
Instruction::TypeAccelerationStructureKHR { .. } => None, // FIXME temporary workaround
_ => {
let name = variable_id_info
.iter_name()
.find_map(|instruction| match instruction {
Instruction::Name { name, .. } => Some(name.as_str()),
.find_map(|instruction| match *instruction {
Instruction::Name { ref name, .. } => Some(name.as_str()),
_ => None,
})
.unwrap_or("__unnamed");
panic!("Couldn't find relevant type for global variable `{}` (id {}, maybe unimplemented)", name, variable_id);
panic!(
"Couldn't find relevant type for global variable `{}` (id {}, maybe \
unimplemented)",
name, variable_id,
);
}
};
}
@ -907,21 +919,21 @@ fn descriptor_requirements_of(spirv: &Spirv, variable_id: Id) -> DescriptorVaria
DescriptorVariable {
set: variable_id_info
.iter_decoration()
.find_map(|instruction| match instruction {
.find_map(|instruction| match *instruction {
Instruction::Decorate {
decoration: Decoration::DescriptorSet { descriptor_set },
..
} => Some(*descriptor_set),
} => Some(descriptor_set),
_ => None,
})
.unwrap(),
binding: variable_id_info
.iter_decoration()
.find_map(|instruction| match instruction {
.find_map(|instruction| match *instruction {
Instruction::Decorate {
decoration: Decoration::Binding { binding_point },
..
} => Some(*binding_point),
} => Some(binding_point),
_ => None,
})
.unwrap(),
@ -933,8 +945,8 @@ fn descriptor_requirements_of(spirv: &Spirv, variable_id: Id) -> DescriptorVaria
fn push_constant_requirements(spirv: &Spirv, stage: ShaderStage) -> Option<PushConstantRange> {
spirv
.iter_global()
.find_map(|instruction| match instruction {
&Instruction::TypePointer {
.find_map(|instruction| match *instruction {
Instruction::TypePointer {
ty,
storage_class: StorageClass::PushConstant,
..
@ -947,6 +959,7 @@ fn push_constant_requirements(spirv: &Spirv, stage: ShaderStage) -> Option<PushC
let start = offset_of_struct(spirv, ty);
let end =
size_of_type(spirv, ty).expect("Found runtime-sized push constants") as u32;
Some(PushConstantRange {
stages: stage.into(),
offset: start,
@ -964,39 +977,39 @@ fn specialization_constant_requirements(
spirv
.iter_global()
.filter_map(|instruction| {
match instruction {
&Instruction::SpecConstantTrue {
match *instruction {
Instruction::SpecConstantTrue {
result_type_id,
result_id,
}
| &Instruction::SpecConstantFalse {
| Instruction::SpecConstantFalse {
result_type_id,
result_id,
}
| &Instruction::SpecConstant {
| Instruction::SpecConstant {
result_type_id,
result_id,
..
}
| &Instruction::SpecConstantComposite {
| Instruction::SpecConstantComposite {
result_type_id,
result_id,
..
} => spirv
.id(result_id)
.iter_decoration()
.find_map(|instruction| match instruction {
.find_map(|instruction| match *instruction {
Instruction::Decorate {
decoration:
Decoration::SpecId {
specialization_constant_id,
},
..
} => Some(*specialization_constant_id),
} => Some(specialization_constant_id),
_ => None,
})
.map(|constant_id| {
let size = match spirv.id(result_type_id).instruction() {
let size = match *spirv.id(result_type_id).instruction() {
Instruction::TypeBool { .. } => {
// Translate bool to Bool32
std::mem::size_of::<ash::vk::Bool32>() as DeviceSize
@ -1022,13 +1035,13 @@ fn shader_interface(
let elements: Vec<_> = interface
.iter()
.filter_map(|&id| {
let (result_type_id, result_id) = match spirv.id(id).instruction() {
&Instruction::Variable {
let (result_type_id, result_id) = match *spirv.id(id).instruction() {
Instruction::Variable {
result_type_id,
result_id,
ref storage_class,
storage_class,
..
} if storage_class == &filter_storage_class => (result_type_id, result_id),
} if storage_class == filter_storage_class => (result_type_id, result_id),
_ => return None,
};
@ -1040,18 +1053,18 @@ fn shader_interface(
let name = id_info
.iter_name()
.find_map(|instruction| match instruction {
Instruction::Name { name, .. } => Some(Cow::Owned(name.to_owned())),
.find_map(|instruction| match *instruction {
Instruction::Name { ref name, .. } => Some(Cow::Owned(name.clone())),
_ => None,
});
let location = id_info
.iter_decoration()
.find_map(|instruction| match instruction {
.find_map(|instruction| match *instruction {
Instruction::Decorate {
decoration: Decoration::Location { location },
..
} => Some(*location),
} => Some(location),
_ => None,
})
.unwrap_or_else(|| {
@ -1062,17 +1075,18 @@ fn shader_interface(
});
let component = id_info
.iter_decoration()
.find_map(|instruction| match instruction {
.find_map(|instruction| match *instruction {
Instruction::Decorate {
decoration: Decoration::Component { component },
..
} => Some(*component),
} => Some(component),
_ => None,
})
.unwrap_or(0);
let ty = shader_interface_type_of(spirv, result_type_id, ignore_first_array);
assert!(ty.num_elements >= 1);
Some(ShaderInterfaceEntry {
location,
component,
@ -1111,21 +1125,21 @@ fn shader_interface(
fn size_of_type(spirv: &Spirv, id: Id) -> Option<DeviceSize> {
let id_info = spirv.id(id);
match id_info.instruction() {
match *id_info.instruction() {
Instruction::TypeBool { .. } => {
panic!("Can't put booleans in structs")
}
Instruction::TypeInt { width, .. } | Instruction::TypeFloat { width, .. } => {
assert!(width % 8 == 0);
Some(*width as DeviceSize / 8)
Some(width as DeviceSize / 8)
}
&Instruction::TypeVector {
Instruction::TypeVector {
component_type,
component_count,
..
} => size_of_type(spirv, component_type)
.map(|component_size| component_size * component_count as DeviceSize),
&Instruction::TypeMatrix {
Instruction::TypeMatrix {
column_type,
column_count,
..
@ -1134,19 +1148,19 @@ fn size_of_type(spirv: &Spirv, id: Id) -> Option<DeviceSize> {
size_of_type(spirv, column_type)
.map(|column_size| column_size * column_count as DeviceSize)
}
&Instruction::TypeArray { length, .. } => {
Instruction::TypeArray { length, .. } => {
let stride = id_info
.iter_decoration()
.find_map(|instruction| match instruction {
.find_map(|instruction| match *instruction {
Instruction::Decorate {
decoration: Decoration::ArrayStride { array_stride },
..
} => Some(*array_stride),
} => Some(array_stride),
_ => None,
})
.unwrap();
let length = match spirv.id(length).instruction() {
&Instruction::Constant { ref value, .. } => Some(
Instruction::Constant { value, .. } => Some(
value
.iter()
.rev()
@ -1159,7 +1173,9 @@ fn size_of_type(spirv: &Spirv, id: Id) -> Option<DeviceSize> {
Some(stride as DeviceSize * length)
}
Instruction::TypeRuntimeArray { .. } => None,
Instruction::TypeStruct { member_types, .. } => {
Instruction::TypeStruct {
ref member_types, ..
} => {
let mut end_of_struct = 0;
for (&member, member_info) in member_types.iter().zip(id_info.iter_members()) {
@ -1181,11 +1197,11 @@ fn size_of_type(spirv: &Spirv, id: Id) -> Option<DeviceSize> {
let offset =
member_info
.iter_decoration()
.find_map(|instruction| match instruction {
.find_map(|instruction| match *instruction {
Instruction::MemberDecorate {
decoration: Decoration::Offset { byte_offset },
..
} => Some(*byte_offset),
} => Some(byte_offset),
_ => None,
})?;
let size = size_of_type(spirv, member)?;
@ -1206,11 +1222,11 @@ fn offset_of_struct(spirv: &Spirv, id: Id) -> u32 {
.filter_map(|member_info| {
member_info
.iter_decoration()
.find_map(|instruction| match instruction {
.find_map(|instruction| match *instruction {
Instruction::MemberDecorate {
decoration: Decoration::Offset { byte_offset },
..
} => Some(*byte_offset),
} => Some(byte_offset),
_ => None,
})
})
@ -1293,15 +1309,14 @@ fn shader_interface_type_of(
let num_elements = spirv
.instructions()
.iter()
.filter_map(|e| match e {
&Instruction::Constant {
.find_map(|instruction| match *instruction {
Instruction::Constant {
result_id,
ref value,
..
} if result_id == length => Some(value.clone()),
_ => None,
})
.next()
.expect("failed to find array length")
.iter()
.rev()
@ -1351,25 +1366,19 @@ fn is_builtin(spirv: &Spirv, id: Id) -> bool {
}
match id_info.instruction() {
Instruction::Variable { result_type_id, .. } => {
return is_builtin(spirv, *result_type_id);
Instruction::Variable {
result_type_id: ty, ..
}
Instruction::TypeArray { element_type, .. } => {
return is_builtin(spirv, *element_type);
| Instruction::TypeArray {
element_type: ty, ..
}
Instruction::TypeRuntimeArray { element_type, .. } => {
return is_builtin(spirv, *element_type);
| Instruction::TypeRuntimeArray {
element_type: ty, ..
}
| Instruction::TypePointer { ty, .. } => is_builtin(spirv, *ty),
Instruction::TypeStruct { member_types, .. } => {
if member_types.iter().any(|ty| is_builtin(spirv, *ty)) {
return true;
}
member_types.iter().any(|ty| is_builtin(spirv, *ty))
}
Instruction::TypePointer { ty, .. } => {
return is_builtin(spirv, *ty);
}
_ => (),
_ => false,
}
false
}

View File

@ -571,6 +571,7 @@ impl From<Id> for u32 {
}
impl Display for Id {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
write!(f, "%{}", self.0)
}
@ -588,7 +589,6 @@ impl<'a> InstructionReader<'a> {
/// Constructs a new reader from a slice of words for a single instruction, including the opcode
/// word. `instruction` is the number of the instruction currently being read, and is used for
/// error reporting.
#[inline]
fn new(words: &'a [u32], instruction: usize) -> Self {
debug_assert!(!words.is_empty());
Self {
@ -599,13 +599,11 @@ impl<'a> InstructionReader<'a> {
}
/// Returns whether the reader has reached the end of the current instruction.
#[inline]
fn is_empty(&self) -> bool {
self.next_word >= self.words.len()
}
/// Converts the `ParseErrors` enum to the `ParseError` struct, adding contextual information.
#[inline]
fn map_err(&self, error: ParseErrors) -> ParseError {
ParseError {
instruction: self.instruction,
@ -616,7 +614,6 @@ impl<'a> InstructionReader<'a> {
}
/// Returns the next word in the sequence.
#[inline]
fn next_u32(&mut self) -> Result<u32, ParseError> {
let word = *self.words.get(self.next_word).ok_or(ParseError {
instruction: self.instruction,
@ -625,6 +622,7 @@ impl<'a> InstructionReader<'a> {
words: self.words.to_owned(),
})?;
self.next_word += 1;
Ok(word)
}
@ -653,7 +651,6 @@ impl<'a> InstructionReader<'a> {
}
/// Reads all remaining words.
#[inline]
fn remainder(&mut self) -> Vec<u32> {
let vec = self.words[self.next_word..].to_owned();
self.next_word = self.words.len();
@ -686,13 +683,12 @@ pub enum SpirvError {
}
impl Display for SpirvError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match self {
Self::BadLayout { index } => write!(
f,
"the instruction at index {} does not follow the logical layout of a module",
index
index,
),
Self::DuplicateId {
id,
@ -701,10 +697,19 @@ impl Display for SpirvError {
} => write!(
f,
"id {} is assigned more than once, by instructions {} and {}",
id, first_index, second_index
id, first_index, second_index,
),
Self::GroupDecorateNotGroup { index } => write!(
f,
"a GroupDecorate or GroupMemberDecorate instruction at index {} referred to an Id \
that was not a DecorationGroup",
index,
),
Self::IdOutOfBounds { id, bound, index } => write!(
f,
"id {}, assigned at instruction {}, is not below the maximum bound {}",
id, index, bound,
),
Self::GroupDecorateNotGroup { index } => write!(f, "a GroupDecorate or GroupMemberDecorate instruction at index {} referred to an Id that was not a DecorationGroup", index),
Self::IdOutOfBounds { id, bound, index, } => write!(f, "id {}, assigned at instruction {}, is not below the maximum bound {}", id, index, bound),
Self::InvalidHeader => write!(f, "the SPIR-V module header is invalid"),
Self::MemoryModelInvalid => {
write!(f, "the MemoryModel instruction is not present exactly once")
@ -715,7 +720,6 @@ impl Display for SpirvError {
}
impl Error for SpirvError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
Self::ParseError(err) => Some(err),
@ -725,7 +729,6 @@ impl Error for SpirvError {
}
impl From<ParseError> for SpirvError {
#[inline]
fn from(err: ParseError) -> Self {
Self::ParseError(err)
}
@ -745,12 +748,11 @@ pub struct ParseError {
}
impl Display for ParseError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
write!(
f,
"at instruction {}, word {}: {}",
self.instruction, self.word, self.error
self.instruction, self.word, self.error,
)
}
}
@ -770,16 +772,23 @@ pub enum ParseErrors {
}
impl Display for ParseErrors {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match self {
Self::FromUtf8Error(_) => write!(f, "invalid UTF-8 in string literal"),
Self::LeftoverOperands => write!(f, "unparsed operands remaining"),
Self::MissingOperands => write!(f, "the instruction and its operands require more words than are present in the instruction"),
Self::MissingOperands => write!(
f,
"the instruction and its operands require more words than are present in the \
instruction",
),
Self::UnexpectedEOF => write!(f, "encountered unexpected end of file"),
Self::UnknownEnumerant(ty, enumerant) => write!(f, "invalid enumerant {} for enum {}", enumerant, ty),
Self::UnknownEnumerant(ty, enumerant) => {
write!(f, "invalid enumerant {} for enum {}", enumerant, ty)
}
Self::UnknownOpcode(opcode) => write!(f, "invalid instruction opcode {}", opcode),
Self::UnknownSpecConstantOpcode(opcode) => write!(f, "invalid spec constant instruction opcode {}", opcode),
Self::UnknownSpecConstantOpcode(opcode) => {
write!(f, "invalid spec constant instruction opcode {}", opcode)
}
}
}
}

View File

@ -142,10 +142,9 @@ impl DisplayPlane {
/// Enumerates all the display planes that are available on a given physical device.
///
/// # Panic
/// # Panics
///
/// - Panics if the device or host ran out of memory.
///
// TODO: move iterator creation here from raw constructor?
#[inline]
pub fn enumerate(physical_device: Arc<PhysicalDevice>) -> IntoIter<DisplayPlane> {
@ -235,10 +234,9 @@ impl Display {
/// Enumerates all the displays that are available on a given physical device.
///
/// # Panic
/// # Panics
///
/// - Panics if the device or host ran out of memory.
///
// TODO: move iterator creation here from raw constructor?
#[inline]
pub fn enumerate(physical_device: Arc<PhysicalDevice>) -> IntoIter<Display> {
@ -344,10 +342,9 @@ impl Display {
/// Returns a list of all modes available on this display.
///
/// # Panic
/// # Panics
///
/// - Panics if the device or host ran out of memory.
///
// TODO: move iterator creation here from display_modes_raw?
#[inline]
pub fn display_modes(&self) -> IntoIter<DisplayMode> {

View File

@ -51,7 +51,7 @@
//! may be able to do this for you, if you pass it ownership of your Window (or a
//! reference-counting container for it).
//!
//! ### Example
//! ### Examples
//!
//! ```no_run
//! use std::ptr;
@ -88,9 +88,9 @@
//! # }
//! #
//! # fn build_window() -> Arc<Window> { Arc::new(Window(ptr::null())) }
//! let window = build_window(); // Third-party function, not provided by vulkano
//! let window = build_window(); // Third-party function, not provided by vulkano
//! let _surface = unsafe {
//! let hinstance: *const () = ptr::null(); // Windows-specific object
//! let hinstance: *const () = ptr::null(); // Windows-specific object
//! Surface::from_win32(instance.clone(), hinstance, window.hwnd(), Arc::clone(&window)).unwrap()
//! };
//! ```
@ -194,31 +194,31 @@
//!
//! // Create the swapchain and its images.
//! let (swapchain, images) = Swapchain::new(
//! // Create the swapchain in this `device`'s memory.
//! device,
//! // The surface where the images will be presented.
//! surface,
//! // The creation parameters.
//! SwapchainCreateInfo {
//! // How many images to use in the swapchain.
//! min_image_count,
//! // The format of the images.
//! image_format: Some(image_format),
//! // The size of each image.
//! image_extent,
//! // What the images are going to be used for.
//! image_usage,
//! // What transformation to use with the surface.
//! pre_transform,
//! // How to handle the alpha channel.
//! composite_alpha,
//! // How to present images.
//! present_mode,
//! // How to handle full-screen exclusivity
//! full_screen_exclusive,
//! ..Default::default()
//! }
//! )?;
//! // Create the swapchain in this `device`'s memory.
//! device,
//! // The surface where the images will be presented.
//! surface,
//! // The creation parameters.
//! SwapchainCreateInfo {
//! // How many images to use in the swapchain.
//! min_image_count,
//! // The format of the images.
//! image_format: Some(image_format),
//! // The size of each image.
//! image_extent,
//! // What the images are going to be used for.
//! image_usage,
//! // What transformation to use with the surface.
//! pre_transform,
//! // How to handle the alpha channel.
//! composite_alpha,
//! // How to present images.
//! present_mode,
//! // How to handle full-screen exclusivity
//! full_screen_exclusive,
//! ..Default::default()
//! }
//! )?;
//!
//! # Ok(())
//! # }
@ -256,12 +256,14 @@
//! // The command_buffer contains the draw commands that modify the framebuffer
//! // constructed from images[image_index]
//! acquire_future
//! .then_execute(queue.clone(), command_buffer).unwrap()
//! .then_execute(queue.clone(), command_buffer)
//! .unwrap()
//! .then_swapchain_present(
//! queue.clone(),
//! SwapchainPresentInfo::swapchain_image_index(swapchain.clone(), image_index),
//! )
//! .then_signal_fence_and_flush().unwrap();
//! .then_signal_fence_and_flush()
//! .unwrap();
//! }
//! ```
//!
@ -276,7 +278,6 @@
//! rendering, you will need to *recreate* the swapchain by creating a new swapchain and passing
//! as last parameter the old swapchain.
//!
//!
//! ```
//! use vulkano::swapchain;
//! use vulkano::swapchain::{AcquireError, SwapchainCreateInfo, SwapchainPresentInfo};
@ -303,7 +304,7 @@
//! let (image_index, suboptimal, acq_future) = match swapchain::acquire_next_image(swapchain.clone(), None) {
//! Ok(r) => r,
//! Err(AcquireError::OutOfDate) => { recreate_swapchain = true; continue; },
//! Err(err) => panic!("{:?}", err)
//! Err(err) => panic!("{:?}", err),
//! };
//!
//! // ...
@ -314,14 +315,14 @@
//! queue.clone(),
//! SwapchainPresentInfo::swapchain_image_index(swapchain.clone(), image_index),
//! )
//! .then_signal_fence_and_flush().unwrap(); // TODO: PresentError?
//! .then_signal_fence_and_flush()
//! .unwrap(); // TODO: PresentError?
//!
//! if suboptimal {
//! recreate_swapchain = true;
//! }
//! }
//! ```
//!
pub use self::{
surface::{
@ -448,10 +449,12 @@ pub struct RectangleLayer {
impl RectangleLayer {
/// Returns true if this rectangle layer is compatible with swapchain.
#[inline]
pub fn is_compatible_with(&self, swapchain: &dyn SwapchainAbstract) -> bool {
// FIXME negative offset is not disallowed by spec, but semantically should not be possible
debug_assert!(self.offset[0] >= 0);
debug_assert!(self.offset[1] >= 0);
self.offset[0] as u32 + self.extent[0] <= swapchain.image_extent()[0]
&& self.offset[1] as u32 + self.extent[1] <= swapchain.image_extent()[1]
&& self.layer < swapchain.image_array_layers()

View File

@ -67,7 +67,6 @@ impl<W> Surface<W> {
/// - `handle` must have been created from `api`.
/// - The window object that `handle` was created from must outlive the created `Surface`.
/// The `win` parameter can be used to ensure this.
#[inline]
pub unsafe fn from_handle(
instance: Arc<Instance>,
handle: ash::vk::SurfaceKHR,
@ -95,7 +94,6 @@ impl<W> Surface<W> {
///
/// Presenting to a headless surface does nothing, so this is mostly useless in itself. However,
/// it may be useful for testing, and it is available for future extensions to layer on top of.
#[inline]
pub fn headless(instance: Arc<Instance>, win: W) -> Result<Arc<Self>, SurfaceCreationError> {
Self::validate_headless(&instance)?;
@ -159,11 +157,10 @@ impl<W> Surface<W> {
/// Creates a `Surface` from a `DisplayPlane`.
///
/// # Panic
/// # Panics
///
/// - Panics if `display_mode` and `plane` don't belong to the same physical device.
/// - Panics if `plane` doesn't support the display of `display_mode`.
#[inline]
pub fn from_display_plane(
display_mode: &DisplayMode,
plane: &DisplayPlane,
@ -263,7 +260,6 @@ impl<W> Surface<W> {
/// - `window` must be a valid Android `ANativeWindow` handle.
/// - The object referred to by `window` must outlive the created `Surface`.
/// The `win` parameter can be used to ensure this.
#[inline]
pub unsafe fn from_android<T>(
instance: Arc<Instance>,
window: *const T,
@ -345,7 +341,6 @@ impl<W> Surface<W> {
/// - `surface` must be a valid DirectFB `IDirectFBSurface` handle.
/// - The object referred to by `dfb` and `surface` must outlive the created `Surface`.
/// The `win` parameter can be used to ensure this.
#[inline]
pub unsafe fn from_directfb<D, S>(
instance: Arc<Instance>,
dfb: *const D,
@ -433,7 +428,6 @@ impl<W> Surface<W> {
/// - `image_pipe_handle` must be a valid Fuchsia `zx_handle_t` handle.
/// - The object referred to by `image_pipe_handle` must outlive the created `Surface`.
/// The `win` parameter can be used to ensure this.
#[inline]
pub unsafe fn from_fuchsia_image_pipe(
instance: Arc<Instance>,
image_pipe_handle: ash::vk::zx_handle_t,
@ -519,7 +513,6 @@ impl<W> Surface<W> {
/// - `stream_descriptor` must be a valid Google Games Platform `GgpStreamDescriptor` handle.
/// - The object referred to by `stream_descriptor` must outlive the created `Surface`.
/// The `win` parameter can be used to ensure this.
#[inline]
pub unsafe fn from_ggp_stream_descriptor(
instance: Arc<Instance>,
stream_descriptor: ash::vk::GgpStreamDescriptor,
@ -607,7 +600,6 @@ impl<W> Surface<W> {
/// The `win` parameter can be used to ensure this.
/// - The `UIView` must be backed by a `CALayer` instance of type `CAMetalLayer`.
#[cfg(target_os = "ios")]
#[inline]
pub unsafe fn from_ios(
instance: Arc<Instance>,
metal_layer: IOSMetalLayer,
@ -694,7 +686,6 @@ impl<W> Surface<W> {
/// The `win` parameter can be used to ensure this.
/// - The `NSView` must be backed by a `CALayer` instance of type `CAMetalLayer`.
#[cfg(target_os = "macos")]
#[inline]
pub unsafe fn from_mac_os<T>(
instance: Arc<Instance>,
view: *const T,
@ -780,7 +771,6 @@ impl<W> Surface<W> {
/// - `layer` must be a valid Metal `CAMetalLayer` handle.
/// - The object referred to by `layer` must outlive the created `Surface`.
/// The `win` parameter can be used to ensure this.
#[inline]
pub unsafe fn from_metal<T>(
instance: Arc<Instance>,
layer: *const T,
@ -859,7 +849,6 @@ impl<W> Surface<W> {
/// - `window` must be a valid QNX Screen `_screen_window` handle.
/// - The object referred to by `window` must outlive the created `Surface`.
/// The `win` parameter can be used to ensure this.
#[inline]
pub unsafe fn from_qnx_screen<T, U>(
instance: Arc<Instance>,
context: *const T,
@ -949,7 +938,6 @@ impl<W> Surface<W> {
/// - `window` must be a valid `nn::vi::NativeWindowHandle` handle.
/// - The object referred to by `window` must outlive the created `Surface`.
/// The `win` parameter can be used to ensure this.
#[inline]
pub unsafe fn from_vi<T>(
instance: Arc<Instance>,
window: *const T,
@ -1033,7 +1021,6 @@ impl<W> Surface<W> {
/// - `surface` must be a valid Wayland `wl_surface` handle.
/// - The objects referred to by `display` and `surface` must outlive the created `Surface`.
/// The `win` parameter can be used to ensure this.
#[inline]
pub unsafe fn from_wayland<D, S>(
instance: Arc<Instance>,
display: *const D,
@ -1126,7 +1113,6 @@ impl<W> Surface<W> {
/// - `hwnd` must be a valid Win32 `HWND` handle.
/// - The objects referred to by `hwnd` and `hinstance` must outlive the created `Surface`.
/// The `win` parameter can be used to ensure this.
#[inline]
pub unsafe fn from_win32<T, U>(
instance: Arc<Instance>,
hinstance: *const T,
@ -1217,7 +1203,6 @@ impl<W> Surface<W> {
/// - `window` must be a valid X11 `xcb_window_t` handle.
/// - The objects referred to by `connection` and `window` must outlive the created `Surface`.
/// The `win` parameter can be used to ensure this.
#[inline]
pub unsafe fn from_xcb<C>(
instance: Arc<Instance>,
connection: *const C,
@ -1308,7 +1293,6 @@ impl<W> Surface<W> {
/// - `window` must be a valid Xlib `Window` handle.
/// - The objects referred to by `display` and `window` must outlive the created `Surface`.
/// The `win` parameter can be used to ensure this.
#[inline]
pub unsafe fn from_xlib<D>(
instance: Arc<Instance>,
display: *const D,
@ -1390,19 +1374,16 @@ impl<W> Surface<W> {
}
/// Returns the instance this surface was created with.
#[inline]
pub fn instance(&self) -> &Arc<Instance> {
&self.instance
}
/// Returns the windowing API that was used to construct the surface.
#[inline]
pub fn api(&self) -> SurfaceApi {
self.api
}
/// Returns a reference to the `W` type parameter that was passed when creating the surface.
#[inline]
pub fn window(&self) -> &W {
&self.window
}
@ -1415,7 +1396,6 @@ impl<W> Surface<W> {
/// its sublayers are not automatically resized, and we must resize
/// it here.
#[cfg(target_os = "ios")]
#[inline]
pub unsafe fn update_ios_sublayer_on_resize(&self) {
use core_graphics_types::geometry::CGRect;
let class = class!(CAMetalLayer);
@ -1427,7 +1407,6 @@ impl<W> Surface<W> {
}
impl<W> Drop for Surface<W> {
#[inline]
fn drop(&mut self) {
unsafe {
let fns = self.instance.fns();
@ -1443,14 +1422,12 @@ impl<W> Drop for Surface<W> {
unsafe impl<W> VulkanObject for Surface<W> {
type Object = ash::vk::SurfaceKHR;
#[inline]
fn internal_object(&self) -> ash::vk::SurfaceKHR {
self.handle
}
}
impl<W> Debug for Surface<W> {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
let Self {
handle,
@ -1472,7 +1449,6 @@ impl<W> Debug for Surface<W> {
}
impl<W> PartialEq for Surface<W> {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.handle == other.handle && self.instance() == other.instance()
}
@ -1481,7 +1457,6 @@ impl<W> PartialEq for Surface<W> {
impl<W> Eq for Surface<W> {}
impl<W> Hash for Surface<W> {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.handle.hash(state);
self.instance().hash(state);
@ -1489,7 +1464,6 @@ impl<W> Hash for Surface<W> {
}
unsafe impl<W> SurfaceSwapchainLock for Surface<W> {
#[inline]
fn flag(&self) -> &AtomicBool {
&self.has_swapchain
}
@ -1508,7 +1482,6 @@ pub enum SurfaceCreationError {
}
impl Error for SurfaceCreationError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
SurfaceCreationError::OomError(err) => Some(err),
@ -1518,11 +1491,9 @@ impl Error for SurfaceCreationError {
}
impl Display for SurfaceCreationError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match self {
SurfaceCreationError::OomError(_) => write!(f, "not enough memory available"),
Self::OomError(_) => write!(f, "not enough memory available"),
Self::RequirementNotMet {
required_for,
requires_one_of,
@ -1536,14 +1507,12 @@ impl Display for SurfaceCreationError {
}
impl From<OomError> for SurfaceCreationError {
#[inline]
fn from(err: OomError) -> SurfaceCreationError {
SurfaceCreationError::OomError(err)
}
}
impl From<VulkanError> for SurfaceCreationError {
#[inline]
fn from(err: VulkanError) -> SurfaceCreationError {
match err {
err @ VulkanError::OutOfHostMemory => {
@ -1805,83 +1774,87 @@ vulkan_enum! {
///
/// ## What is a color space?
///
/// Each pixel of a monitor is made of three components: one red, one green, and one blue. In the
/// past, computers would simply send to the monitor the intensity of each of the three components.
/// Each pixel of a monitor is made of three components: one red, one green, and one blue. In
/// the past, computers would simply send to the monitor the intensity of each of the three
/// components.
///
/// This proved to be problematic, because depending on the brand of the monitor the colors would
/// not exactly be the same. For example on some monitors, a value of `[1.0, 0.0, 0.0]` would be a
/// This proved to be problematic, because depending on the brand of the monitor the colors
/// would not exactly be the same. For example on some monitors, a value of `[1.0, 0.0, 0.0]`
/// would be a
/// bit more orange than on others.
///
/// In order to standardize this, there exist what are called *color spaces*: sRGB, AdobeRGB,
/// DCI-P3, scRGB, etc. When you manipulate RGB values in a specific color space, these values have
/// a precise absolute meaning in terms of color, that is the same across all systems and monitors.
/// DCI-P3, scRGB, etc. When you manipulate RGB values in a specific color space, these values
/// have a precise absolute meaning in terms of color, that is the same across all systems and
/// monitors.
///
/// > **Note**: Color spaces are orthogonal to concept of RGB. *RGB* only indicates what is the
/// > representation of the data, but not how it is interpreted. You can think of this a bit like
/// > text encoding. An *RGB* value is a like a byte, in other words it is the medium by which
/// > values are communicated, and a *color space* is like a text encoding (eg. UTF-8), in other
/// > words it is the way the value should be interpreted.
/// > representation of the data, but not how it is interpreted. You can think of this a bit
/// > like text encoding. An *RGB* value is a like a byte, in other words it is the medium by
/// > which values are communicated, and a *color space* is like a text encoding (eg. UTF-8),
/// > in other words it is the way the value should be interpreted.
///
/// The most commonly used color space today is sRGB. Most monitors today use this color space,
/// and most images files are encoded in this color space.
///
/// ## Pixel formats and linear vs non-linear
///
/// In Vulkan all images have a specific format in which the data is stored. The data of an image
/// consists of pixels in RGB but contains no information about the color space (or lack thereof)
/// of these pixels. You are free to store them in whatever color space you want.
/// In Vulkan all images have a specific format in which the data is stored. The data of an
/// image consists of pixels in RGB but contains no information about the color space (or lack
/// thereof) of these pixels. You are free to store them in whatever color space you want.
///
/// But one big practical problem with color spaces is that they are sometimes not linear, and in
/// particular the popular sRGB color space is not linear. In a non-linear color space, a value of
/// `[0.6, 0.6, 0.6]` for example is **not** twice as bright as a value of `[0.3, 0.3, 0.3]`. This
/// is problematic, because operations such as taking the average of two colors or calculating the
/// lighting of a texture with a dot product are mathematically incorrect and will produce
/// incorrect colors.
/// But one big practical problem with color spaces is that they are sometimes not linear, and
/// in particular the popular sRGB color space is not linear. In a non-linear color space, a
/// value of `[0.6, 0.6, 0.6]` for example is **not** twice as bright as a value of `[0.3, 0.3,
/// 0.3]`. This is problematic, because operations such as taking the average of two colors or
/// calculating the lighting of a texture with a dot product are mathematically incorrect and
/// will produce incorrect colors.
///
/// > **Note**: If the texture format has an alpha component, it is not affected by the color space
/// > and always behaves linearly.
/// > **Note**: If the texture format has an alpha component, it is not affected by the color
/// > space and always behaves linearly.
///
/// In order to solve this Vulkan also provides image formats with the `Srgb` suffix, which are
/// expected to contain RGB data in the sRGB color space. When you sample an image with such a
/// format from a shader, the implementation will automatically turn the pixel values into a linear
/// color space that is suitable for linear operations (such as additions or multiplications).
/// When you write to a framebuffer attachment with such a format, the implementation will
/// automatically perform the opposite conversion. These conversions are most of the time performed
/// by the hardware and incur no additional cost.
/// format from a shader, the implementation will automatically turn the pixel values into a
/// linear color space that is suitable for linear operations (such as additions or
/// multiplications). When you write to a framebuffer attachment with such a format, the
/// implementation will automatically perform the opposite conversion. These conversions are
/// most of the time performed by the hardware and incur no additional cost.
///
/// ## Color space of the swapchain
///
/// The color space that you specify when you create a swapchain is how the implementation will
/// interpret the raw data inside of the image.
///
/// > **Note**: The implementation can choose to send the data in the swapchain image directly to
/// > the monitor, but it can also choose to write it in an intermediary buffer that is then read
/// > by the operating system or windowing system. Therefore the color space that the
/// > **Note**: The implementation can choose to send the data in the swapchain image directly
/// > to the monitor, but it can also choose to write it in an intermediary buffer that is then
/// > read by the operating system or windowing system. Therefore the color space that the
/// > implementation supports is not necessarily the same as the one supported by the monitor.
///
/// It is *your* job to ensure that the data in the swapchain image is in the color space
/// that is specified here, otherwise colors will be incorrect.
/// The implementation will never perform any additional automatic conversion after the colors have
/// been written to the swapchain image.
/// that is specified here, otherwise colors will be incorrect. The implementation will never
/// perform any additional automatic conversion after the colors have been written to the
/// swapchain image.
///
/// # How do I handle this correctly?
///
/// The easiest way to handle color spaces in a cross-platform program is:
///
/// - Always request the `SrgbNonLinear` color space when creating the swapchain.
/// - Make sure that all your image files use the sRGB color space, and load them in images whose
/// format has the `Srgb` suffix. Only use non-sRGB image formats for intermediary computations
/// or to store non-color data.
/// - Make sure that all your image files use the sRGB color space, and load them in images
/// whose format has the `Srgb` suffix. Only use non-sRGB image formats for intermediary
/// computations or to store non-color data.
/// - Swapchain images should have a format with the `Srgb` suffix.
///
/// > **Note**: Lots of developers are confused by color spaces. You can sometimes find articles
/// > talking about gamma correction and suggestion to put your colors to the power 2.2 for
/// > example. These are all hacks and you should use the sRGB pixel formats instead.
///
/// If you follow these three rules, then everything should render the same way on all platforms.
/// If you follow these three rules, then everything should render the same way on all
/// platforms.
///
/// Additionally you can try detect whether the implementation supports any additional color space
/// and perform a manual conversion to that color space from inside your shader.
/// Additionally you can try detect whether the implementation supports any additional color
/// space and perform a manual conversion to that color space from inside your shader.
#[non_exhaustive]
ColorSpace = ColorSpaceKHR(i32);
@ -1964,10 +1937,10 @@ vulkan_enum! {
},
}
/// Parameters for
/// [`PhysicalDevice::surface_capabilities`](crate::device::physical::PhysicalDevice::surface_capabilities)
/// and
/// [`PhysicalDevice::surface_formats`](crate::device::physical::PhysicalDevice::surface_formats).
/// Parameters for [`PhysicalDevice::surface_capabilities`] and [`PhysicalDevice::surface_formats`].
///
/// [`PhysicalDevice::surface_capabilities`]: crate::device::physical::PhysicalDevice::surface_capabilities
/// [`PhysicalDevice::surface_formats`]: crate::device::physical::PhysicalDevice::surface_formats
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct SurfaceInfo {
pub full_screen_exclusive: FullScreenExclusive,
@ -2004,6 +1977,7 @@ pub struct IOSMetalLayer {
#[cfg(target_os = "ios")]
impl IOSMetalLayer {
#[inline]
pub fn new(main_layer: *mut Object, render_layer: *mut Object) -> Self {
Self {
main_layer: LayerHandle(main_layer),

View File

@ -71,8 +71,9 @@ pub struct Swapchain<W> {
// The images of this swapchain.
images: Vec<ImageEntry>,
// If true, that means we have tried to use this swapchain to recreate a new swapchain. The current
// swapchain can no longer be used for anything except presenting already-acquired images.
// If true, that means we have tried to use this swapchain to recreate a new swapchain. The
// current swapchain can no longer be used for anything except presenting already-acquired
// images.
//
// We use a `Mutex` instead of an `AtomicBool` because we want to keep that locked while
// we acquire the image.
@ -177,7 +178,6 @@ where
/// # Panics
///
/// - Panics if `create_info.usage` is empty.
#[inline]
pub fn recreate(
self: &Arc<Self>,
mut create_info: SwapchainCreateInfo,
@ -726,7 +726,6 @@ where
}
/// Returns the creation parameters of the swapchain.
#[inline]
pub fn create_info(&self) -> SwapchainCreateInfo {
SwapchainCreateInfo {
min_image_count: self.min_image_count,
@ -747,37 +746,31 @@ where
}
/// Returns the saved Surface, from the Swapchain creation.
#[inline]
pub fn surface(&self) -> &Arc<Surface<W>> {
&self.surface
}
/// Returns the pre-transform that was passed when creating the swapchain.
#[inline]
pub fn pre_transform(&self) -> SurfaceTransform {
self.pre_transform
}
/// Returns the alpha mode that was passed when creating the swapchain.
#[inline]
pub fn composite_alpha(&self) -> CompositeAlpha {
self.composite_alpha
}
/// Returns the present mode that was passed when creating the swapchain.
#[inline]
pub fn present_mode(&self) -> PresentMode {
self.present_mode
}
/// Returns the value of `clipped` that was passed when creating the swapchain.
#[inline]
pub fn clipped(&self) -> bool {
self.clipped
}
/// Returns the value of 'full_screen_exclusive` that was passed when creating the swapchain.
#[inline]
pub fn full_screen_exclusive(&self) -> FullScreenExclusive {
self.full_screen_exclusive
}
@ -875,7 +868,6 @@ where
}
impl<W> Drop for Swapchain<W> {
#[inline]
fn drop(&mut self) {
unsafe {
let fns = self.device.fns();
@ -892,7 +884,6 @@ impl<W> Drop for Swapchain<W> {
unsafe impl<W> VulkanObject for Swapchain<W> {
type Object = ash::vk::SwapchainKHR;
#[inline]
fn internal_object(&self) -> ash::vk::SwapchainKHR {
self.handle
}
@ -905,7 +896,6 @@ unsafe impl<W> DeviceOwned for Swapchain<W> {
}
impl<W> PartialEq for Swapchain<W> {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.handle == other.handle && self.device() == other.device()
}
@ -914,7 +904,6 @@ impl<W> PartialEq for Swapchain<W> {
impl<W> Eq for Swapchain<W> {}
impl<W> Hash for Swapchain<W> {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.handle.hash(state);
self.device().hash(state);
@ -922,7 +911,6 @@ impl<W> Hash for Swapchain<W> {
}
impl<W> Debug for Swapchain<W> {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
let Self {
handle,
@ -1005,7 +993,6 @@ unsafe impl<W> SwapchainAbstract for Swapchain<W>
where
W: Send + Sync,
{
#[inline]
fn raw_image(&self, image_index: u32) -> Option<ImageInner<'_>> {
self.images.get(image_index as usize).map(|i| ImageInner {
image: &i.image,
@ -1016,37 +1003,30 @@ where
})
}
#[inline]
fn image_count(&self) -> u32 {
self.images.len() as u32
}
#[inline]
fn image_format(&self) -> Format {
self.image_format
}
#[inline]
fn image_color_space(&self) -> ColorSpace {
self.image_color_space
}
#[inline]
fn image_extent(&self) -> [u32; 2] {
self.image_extent
}
#[inline]
fn image_array_layers(&self) -> u32 {
self.image_array_layers
}
#[inline]
unsafe fn full_screen_exclusive_held(&self) -> &AtomicBool {
&self.full_screen_exclusive_held
}
#[inline]
unsafe fn try_claim_present_id(&self, present_id: NonZeroU64) -> bool {
let present_id = u64::from(present_id);
self.prev_present_id.fetch_max(present_id, Ordering::SeqCst) < present_id
@ -1063,7 +1043,6 @@ impl PartialEq for dyn SwapchainAbstract {
impl Eq for dyn SwapchainAbstract {}
impl Hash for dyn SwapchainAbstract {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.internal_object().hash(state);
self.device().hash(state);
@ -1221,10 +1200,7 @@ pub enum SwapchainCreationError {
/// The provided `image_array_layers` is greater than what is supported by the surface for this
/// device.
ImageArrayLayersNotSupported {
provided: u32,
max_supported: u32,
},
ImageArrayLayersNotSupported { provided: u32, max_supported: u32 },
/// The provided `image_extent` is not within the range supported by the surface for this
/// device.
@ -1276,7 +1252,7 @@ pub enum SwapchainCreationError {
supported: SupportedSurfaceTransforms,
},
// The provided `surface` is not supported by any of the device's queue families.
/// The provided `surface` is not supported by any of the device's queue families.
SurfaceNotSupported,
/// The swapchain has already been used to create a new one.
@ -1287,29 +1263,26 @@ pub enum SwapchainCreationError {
}
impl Error for SwapchainCreationError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match *self {
Self::OomError(ref err) => Some(err),
match self {
Self::OomError(err) => Some(err),
_ => None,
}
}
}
impl Display for SwapchainCreationError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match self {
Self::OomError(_) => write!(f, "not enough memory available",),
Self::DeviceLost => write!(f, "the device was lost",),
Self::SurfaceLost => write!(f, "the surface was lost",),
Self::OomError(_) => write!(f, "not enough memory available"),
Self::DeviceLost => write!(f, "the device was lost"),
Self::SurfaceLost => write!(f, "the surface was lost"),
Self::SurfaceInUse => {
write!(f, "the surface is already used by another swapchain",)
write!(f, "the surface is already used by another swapchain")
}
Self::NativeWindowInUse => {
write!(f, "the window is already in use by another API")
}
Self::RequirementNotMet {
required_for,
requires_one_of,
@ -1318,23 +1291,32 @@ impl Display for SwapchainCreationError {
"a requirement was not met for: {}; requires one of: {}",
required_for, requires_one_of,
),
Self::CompositeAlphaNotSupported { .. } => write!(
f,
"the provided `composite_alpha` is not supported by the surface for this device",
),
Self::FormatColorSpaceNotSupported => write!(
f,
"the provided `format` and `color_space` are not supported by the surface for this device",
"the provided `format` and `color_space` are not supported by the surface for this \
device",
),
Self::ImageArrayLayersNotSupported { provided, max_supported } => write!(
Self::ImageArrayLayersNotSupported {
provided,
max_supported,
} => write!(
f,
"the provided `image_array_layers` ({}) is greater than what is supported ({}) by the surface for this device",
"the provided `image_array_layers` ({}) is greater than what is supported ({}) by \
the surface for this device",
provided, max_supported,
),
Self::ImageExtentNotSupported { provided, min_supported, max_supported } => write!(
Self::ImageExtentNotSupported {
provided,
min_supported,
max_supported,
} => write!(
f,
"the provided `image_extent` ({:?}) is not within the range (min: {:?}, max: {:?}) supported by the surface for this device",
"the provided `image_extent` ({:?}) is not within the range (min: {:?}, max: {:?}) \
supported by the surface for this device",
provided, min_supported, max_supported,
),
Self::ImageExtentZeroLengthDimensions => write!(
@ -1343,20 +1325,31 @@ impl Display for SwapchainCreationError {
),
Self::ImageFormatPropertiesNotSupported => write!(
f,
"the provided image parameters are not supported as queried from `image_format_properties`",
"the provided image parameters are not supported as queried from \
`image_format_properties`",
),
Self::ImageSharingQueueFamilyIndexOutOfRange { queue_family_index, queue_family_count: _ } => write!(
Self::ImageSharingQueueFamilyIndexOutOfRange {
queue_family_index,
queue_family_count: _,
} => write!(
f,
"the provided `image_sharing` was set to `Concurrent`, but one of the specified queue family indices ({}) was out of range",
"the provided `image_sharing` was set to `Concurrent`, but one of the specified \
queue family indices ({}) was out of range",
queue_family_index,
),
Self::ImageUsageNotSupported { .. } => write!(
f,
"the provided `image_usage` has fields set that are not supported by the surface for this device",
"the provided `image_usage` has fields set that are not supported by the surface \
for this device",
),
Self::MinImageCountNotSupported { provided, min_supported, max_supported } => write!(
Self::MinImageCountNotSupported {
provided,
min_supported,
max_supported,
} => write!(
f,
"the provided `min_image_count` ({}) is not within the range (min: {}, max: {:?}) supported by the surface for this device",
"the provided `min_image_count` ({}) is not within the range (min: {}, max: {:?}) \
supported by the surface for this device",
provided, min_supported, max_supported,
),
Self::PresentModeNotSupported => write!(
@ -1371,10 +1364,9 @@ impl Display for SwapchainCreationError {
f,
"the provided `surface` is not supported by any of the device's queue families",
),
Self::SwapchainAlreadyRetired => write!(
f,
"the swapchain has already been used to create a new one",
),
Self::SwapchainAlreadyRetired => {
write!(f, "the swapchain has already been used to create a new one")
}
Self::Win32MonitorInvalid => write!(
f,
"the `win32_monitor` value was `Some` when it must be `None` or vice-versa",
@ -1384,7 +1376,6 @@ impl Display for SwapchainCreationError {
}
impl From<VulkanError> for SwapchainCreationError {
#[inline]
fn from(err: VulkanError) -> SwapchainCreationError {
match err {
err @ VulkanError::OutOfHostMemory => Self::OomError(OomError::from(err)),
@ -1398,14 +1389,12 @@ impl From<VulkanError> for SwapchainCreationError {
}
impl From<OomError> for SwapchainCreationError {
#[inline]
fn from(err: OomError) -> SwapchainCreationError {
Self::OomError(err)
}
}
impl From<RequirementNotMet> for SwapchainCreationError {
#[inline]
fn from(err: RequirementNotMet) -> Self {
Self::RequirementNotMet {
required_for: err.required_for,
@ -1449,7 +1438,6 @@ impl Win32Monitor {
/// # Safety
///
/// - `hmonitor` must be a valid handle as returned by the Win32 API.
#[inline]
pub unsafe fn new<T>(hmonitor: *const T) -> Self {
Self(hmonitor as _)
}
@ -1483,22 +1471,20 @@ pub enum FullScreenExclusiveError {
}
impl Error for FullScreenExclusiveError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match *self {
FullScreenExclusiveError::OomError(ref err) => Some(err),
match self {
FullScreenExclusiveError::OomError(err) => Some(err),
_ => None,
}
}
}
impl Display for FullScreenExclusiveError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
write!(
f,
"{}",
match *self {
match self {
FullScreenExclusiveError::OomError(_) => "not enough memory",
FullScreenExclusiveError::SurfaceLost => {
"the surface of this swapchain is no longer valid"
@ -1519,7 +1505,6 @@ impl Display for FullScreenExclusiveError {
}
impl From<VulkanError> for FullScreenExclusiveError {
#[inline]
fn from(err: VulkanError) -> FullScreenExclusiveError {
match err {
err @ VulkanError::OutOfHostMemory => {
@ -1536,7 +1521,6 @@ impl From<VulkanError> for FullScreenExclusiveError {
}
impl From<OomError> for FullScreenExclusiveError {
#[inline]
fn from(err: OomError) -> FullScreenExclusiveError {
FullScreenExclusiveError::OomError(err)
}
@ -1600,8 +1584,7 @@ pub fn acquire_next_image<W>(
/// Presents an image on the screen.
///
/// The actual behavior depends on the present mode that you passed when creating the
/// swapchain.
/// The actual behavior depends on the present mode that you passed when creating the swapchain.
pub fn present<F>(
before: F,
queue: Arc<Queue>,
@ -1628,10 +1611,12 @@ where
}
}
/// Wait for an image to be presented to the user. Must be used with a `present_id` given to `present_with_id`.
/// Wait for an image to be presented to the user. Must be used with a `present_id` given to
/// `present_with_id`.
///
/// Returns a bool to represent if the presentation was suboptimal. In this case the swapchain is still
/// usable, but the swapchain should be recreated as the Surface's properties no longer match the swapchain.
/// Returns a bool to represent if the presentation was suboptimal. In this case the swapchain is
/// still usable, but the swapchain should be recreated as the Surface's properties no longer match
/// the swapchain.
pub fn wait_for_present<W>(
swapchain: Arc<Swapchain<W>>,
present_id: u64,
@ -1704,13 +1689,11 @@ pub struct SwapchainAcquireFuture<W> {
impl<W> SwapchainAcquireFuture<W> {
/// Returns the index of the image in the list of images returned when creating the swapchain.
#[inline]
pub fn image_index(&self) -> u32 {
self.image_index
}
/// Returns the corresponding swapchain.
#[inline]
pub fn swapchain(&self) -> &Arc<Swapchain<W>> {
&self.swapchain
}
@ -1720,10 +1703,8 @@ unsafe impl<W> GpuFuture for SwapchainAcquireFuture<W>
where
W: Send + Sync,
{
#[inline]
fn cleanup_finished(&mut self) {}
#[inline]
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, FlushError> {
if let Some(ref semaphore) = self.semaphore {
let sem = smallvec![semaphore.clone()];
@ -1733,27 +1714,22 @@ where
}
}
#[inline]
fn flush(&self) -> Result<(), FlushError> {
Ok(())
}
#[inline]
unsafe fn signal_finished(&self) {
self.finished.store(true, Ordering::SeqCst);
}
#[inline]
fn queue_change_allowed(&self) -> bool {
true
}
#[inline]
fn queue(&self) -> Option<Arc<Queue>> {
None
}
#[inline]
fn check_buffer_access(
&self,
_buffer: &UnsafeBuffer,
@ -1764,7 +1740,6 @@ where
Err(AccessCheckError::Unknown)
}
#[inline]
fn check_image_access(
&self,
image: &UnsafeImage,
@ -1833,7 +1808,6 @@ impl<W> Drop for SwapchainAcquireFuture<W> {
}
unsafe impl<W> DeviceOwned for SwapchainAcquireFuture<W> {
#[inline]
fn device(&self) -> &Arc<Device> {
&self.swapchain.device
}
@ -1871,22 +1845,20 @@ pub enum AcquireError {
}
impl Error for AcquireError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match *self {
AcquireError::OomError(ref err) => Some(err),
match self {
AcquireError::OomError(err) => Some(err),
_ => None,
}
}
}
impl Display for AcquireError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
write!(
f,
"{}",
match *self {
match self {
AcquireError::OomError(_) => "not enough memory",
AcquireError::DeviceLost => "the connection to the device has been lost",
AcquireError::Timeout => "no image is available for acquiring yet",
@ -1915,14 +1887,12 @@ impl From<SemaphoreError> for AcquireError {
}
impl From<OomError> for AcquireError {
#[inline]
fn from(err: OomError) -> AcquireError {
AcquireError::OomError(err)
}
}
impl From<VulkanError> for AcquireError {
#[inline]
fn from(err: VulkanError) -> AcquireError {
match err {
err @ VulkanError::OutOfHostMemory => AcquireError::OomError(OomError::from(err)),
@ -1970,19 +1940,17 @@ pub enum PresentWaitError {
}
impl Error for PresentWaitError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match *self {
Self::OomError(ref err) => Some(err),
match self {
Self::OomError(err) => Some(err),
_ => None,
}
}
}
impl Display for PresentWaitError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match *self {
match self {
Self::OomError(e) => write!(f, "{}", e),
Self::DeviceLost => write!(f, "the connection to the device has been lost"),
Self::Timeout => write!(f, "no image is available for acquiring yet"),
@ -2005,14 +1973,12 @@ impl Display for PresentWaitError {
}
impl From<OomError> for PresentWaitError {
#[inline]
fn from(err: OomError) -> PresentWaitError {
Self::OomError(err)
}
}
impl From<RequirementNotMet> for PresentWaitError {
#[inline]
fn from(err: RequirementNotMet) -> Self {
Self::RequirementNotMet {
required_for: err.required_for,
@ -2022,7 +1988,6 @@ impl From<RequirementNotMet> for PresentWaitError {
}
impl From<VulkanError> for PresentWaitError {
#[inline]
fn from(err: VulkanError) -> PresentWaitError {
match err {
err @ VulkanError::OutOfHostMemory => Self::OomError(OomError::from(err)),
@ -2058,13 +2023,11 @@ where
P: GpuFuture,
{
/// Returns the index of the image in the list of images returned when creating the swapchain.
#[inline]
pub fn image_id(&self) -> u32 {
self.swapchain_info.image_index
}
/// Returns the corresponding swapchain.
#[inline]
pub fn swapchain(&self) -> &Arc<dyn SwapchainAbstract> {
&self.swapchain_info.swapchain
}
@ -2074,12 +2037,10 @@ unsafe impl<P> GpuFuture for PresentFuture<P>
where
P: GpuFuture,
{
#[inline]
fn cleanup_finished(&mut self) {
self.previous.cleanup_finished();
}
#[inline]
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, FlushError> {
if self.flushed.load(Ordering::SeqCst) {
return Ok(SubmitAnyBuilder::Empty);
@ -2148,7 +2109,6 @@ where
})
}
#[inline]
fn flush(&self) -> Result<(), FlushError> {
unsafe {
// If `flushed` already contains `true`, then `build_submission` will return `Empty`.
@ -2194,19 +2154,16 @@ where
}
}
#[inline]
unsafe fn signal_finished(&self) {
self.flushed.store(true, Ordering::SeqCst);
self.finished.store(true, Ordering::SeqCst);
self.previous.signal_finished();
}
#[inline]
fn queue_change_allowed(&self) -> bool {
false
}
#[inline]
fn queue(&self) -> Option<Arc<Queue>> {
debug_assert!(match self.previous.queue() {
None => true,
@ -2216,7 +2173,6 @@ where
Some(self.queue.clone())
}
#[inline]
fn check_buffer_access(
&self,
buffer: &UnsafeBuffer,
@ -2228,7 +2184,6 @@ where
.check_buffer_access(buffer, range, exclusive, queue)
}
#[inline]
fn check_image_access(
&self,
image: &UnsafeImage,
@ -2281,7 +2236,6 @@ unsafe impl<P> DeviceOwned for PresentFuture<P>
where
P: GpuFuture,
{
#[inline]
fn device(&self) -> &Arc<Device> {
self.queue.device()
}

View File

@ -33,6 +33,7 @@ pub struct Event {
impl Event {
/// Creates a new `Event`.
#[inline]
pub fn new(device: Arc<Device>, _create_info: EventCreateInfo) -> Result<Event, OomError> {
let create_info = ash::vk::EventCreateInfo {
flags: ash::vk::EventCreateFlags::empty(),
@ -66,6 +67,7 @@ impl Event {
///
/// For most applications, using the event pool should be preferred,
/// in order to avoid creating new events every frame.
#[inline]
pub fn from_pool(device: Arc<Device>) -> Result<Event, OomError> {
let handle = device.event_pool().lock().pop();
let event = match handle {
@ -100,6 +102,7 @@ impl Event {
///
/// - `handle` must be a valid Vulkan object handle created from `device`.
/// - `create_info` must match the info used to create the object.
#[inline]
pub unsafe fn from_handle(
device: Arc<Device>,
handle: ash::vk::Event,
@ -142,10 +145,9 @@ impl Event {
///
/// If a command buffer is waiting on this event, it is then unblocked.
///
/// # Panic
/// # Panics
///
/// - Panics if the device or host ran out of memory.
///
#[inline]
pub fn set(&mut self) {
self.set_raw().unwrap();
@ -165,10 +167,9 @@ impl Event {
/// Changes the `Event` to the unsignaled state.
///
/// # Panic
/// # Panics
///
/// - Panics if the device or host ran out of memory.
///
#[inline]
pub fn reset(&mut self) {
self.reset_raw().unwrap();
@ -216,7 +217,6 @@ impl PartialEq for Event {
impl Eq for Event {}
impl Hash for Event {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.handle.hash(state);
self.device().hash(state);
@ -230,6 +230,7 @@ pub struct EventCreateInfo {
}
impl Default for EventCreateInfo {
#[inline]
fn default() -> Self {
Self {
_ne: crate::NonExhaustive(()),

View File

@ -103,6 +103,7 @@ impl Fence {
}
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
#[inline]
pub unsafe fn new_unchecked(
device: Arc<Device>,
create_info: FenceCreateInfo,
@ -148,6 +149,7 @@ impl Fence {
)
.result()
.map_err(VulkanError::from)?;
output.assume_init()
};
@ -171,6 +173,7 @@ impl Fence {
///
/// For most applications, using the fence pool should be preferred,
/// in order to avoid creating new fences every frame.
#[inline]
pub fn from_pool(device: Arc<Device>) -> Result<Fence, FenceError> {
let handle = device.fence_pool().lock().pop();
let fence = match handle {
@ -210,6 +213,7 @@ impl Fence {
///
/// - `handle` must be a valid Vulkan object handle created from `device`.
/// - `create_info` must match the info used to create the object.
#[inline]
pub unsafe fn from_handle(
device: Arc<Device>,
handle: ash::vk::Fence,
@ -236,6 +240,7 @@ impl Fence {
}
/// Returns true if the fence is signaled.
#[inline]
pub fn is_signaled(&self) -> Result<bool, OomError> {
let queue_to_signal = {
let mut state = self.lock();
@ -322,10 +327,9 @@ impl Fence {
/// Waits for multiple fences at once.
///
/// # Panic
/// # Panics
///
/// Panics if not all fences belong to the same device.
#[inline]
/// - Panics if not all fences belong to the same device.
pub fn multi_wait<'a>(
fences: impl IntoIterator<Item = &'a Fence>,
timeout: Option<Duration>,
@ -442,8 +446,10 @@ impl Fence {
}
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
#[inline]
pub unsafe fn reset_unchecked(&self) -> Result<(), VulkanError> {
let mut state = self.state.lock();
self.reset_unchecked_locked(&mut state)
}
@ -462,10 +468,9 @@ impl Fence {
///
/// The fences must not be in use by a queue operation.
///
/// # Panic
/// # Panics
///
/// - Panics if not all fences belong to the same device.
#[inline]
pub fn multi_reset<'a>(fences: impl IntoIterator<Item = &'a Fence>) -> Result<(), FenceError> {
let (fences, mut states): (SmallVec<[_; 8]>, SmallVec<[_; 8]>) = fences
.into_iter()
@ -503,7 +508,6 @@ impl Fence {
}
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
#[inline]
pub unsafe fn multi_reset_unchecked<'a>(
fences: impl IntoIterator<Item = &'a Fence>,
) -> Result<(), VulkanError> {
@ -514,6 +518,7 @@ impl Fence {
(fence, state)
})
.unzip();
Self::multi_reset_unchecked_locked(&fences, &mut states)
}
@ -544,7 +549,6 @@ impl Fence {
Ok(())
}
#[inline]
pub(crate) fn lock(&self) -> MutexGuard<'_, FenceState> {
self.state.lock()
}
@ -591,7 +595,6 @@ impl PartialEq for Fence {
impl Eq for Fence {}
impl Hash for Fence {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.handle.hash(state);
self.device().hash(state);
@ -607,17 +610,14 @@ pub struct FenceState {
impl FenceState {
/// If the fence is already signaled, or it's unsignaled but there's no queue that
/// could signal it, returns the currently known value.
#[inline]
pub(crate) fn status(&self) -> Option<bool> {
(self.is_signaled || self.in_use_by.is_none()).then_some(self.is_signaled)
}
#[inline]
pub(crate) fn is_in_use(&self) -> bool {
self.in_use_by.is_some()
}
#[inline]
pub(crate) unsafe fn add_to_queue(&mut self, queue: &Arc<Queue>) {
self.is_signaled = false;
self.in_use_by = Some(Arc::downgrade(queue));
@ -625,20 +625,17 @@ impl FenceState {
/// Called when a fence first discovers that it is signaled.
/// Returns the queue that should be informed about it.
#[inline]
pub(crate) unsafe fn set_signaled(&mut self) -> Option<Arc<Queue>> {
self.is_signaled = true;
self.in_use_by.take().and_then(|queue| queue.upgrade())
}
/// Called when a queue is unlocking resources.
#[inline]
pub(crate) unsafe fn set_finished(&mut self) {
self.is_signaled = true;
self.in_use_by = None;
}
#[inline]
pub(crate) unsafe fn reset(&mut self) {
debug_assert!(self.in_use_by.is_none());
self.is_signaled = false;
@ -795,10 +792,9 @@ pub enum FenceError {
}
impl Error for FenceError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match *self {
Self::OomError(ref err) => Some(err),
match self {
Self::OomError(err) => Some(err),
_ => None,
}
}
@ -810,7 +806,6 @@ impl Display for FenceError {
Self::OomError(_) => write!(f, "not enough memory available"),
Self::DeviceLost => write!(f, "the device was lost"),
Self::Timeout => write!(f, "the timeout has been reached"),
Self::RequirementNotMet {
required_for,
requires_one_of,
@ -819,14 +814,12 @@ impl Display for FenceError {
"a requirement was not met for: {}; requires one of: {}",
required_for, requires_one_of,
),
Self::InUse => write!(f, "the fence is currently in use by a queue"),
}
}
}
impl From<VulkanError> for FenceError {
#[inline]
fn from(err: VulkanError) -> Self {
match err {
e @ VulkanError::OutOfHostMemory | e @ VulkanError::OutOfDeviceMemory => {
@ -839,14 +832,12 @@ impl From<VulkanError> for FenceError {
}
impl From<OomError> for FenceError {
#[inline]
fn from(err: OomError) -> Self {
Self::OomError(err)
}
}
impl From<RequirementNotMet> for FenceError {
#[inline]
fn from(err: RequirementNotMet) -> Self {
Self::RequirementNotMet {
required_for: err.required_for,

View File

@ -20,7 +20,6 @@ use parking_lot::{Mutex, MutexGuard};
use std::{mem::replace, ops::Range, sync::Arc, time::Duration};
/// Builds a new fence signal future.
#[inline]
pub fn then_signal_fence<F>(future: F, behavior: FenceSignalFutureBehavior) -> FenceSignalFuture<F>
where
F: GpuFuture,
@ -167,7 +166,6 @@ where
{
// Implementation of `cleanup_finished`, but takes a `&self` instead of a `&mut self`.
// This is an external function so that we can also call it from an `Arc<FenceSignalFuture>`.
#[inline]
fn cleanup_finished_impl(&self) {
let mut state = self.state.lock();
@ -353,12 +351,11 @@ where
}
impl<F> FenceSignalFutureState<F> {
#[inline]
fn get_prev(&self) -> Option<&F> {
match *self {
FenceSignalFutureState::Pending(ref prev, _) => Some(prev),
FenceSignalFutureState::PartiallyFlushed(ref prev, _) => Some(prev),
FenceSignalFutureState::Flushed(ref prev, _) => Some(prev),
match self {
FenceSignalFutureState::Pending(prev, _) => Some(prev),
FenceSignalFutureState::PartiallyFlushed(prev, _) => Some(prev),
FenceSignalFutureState::Flushed(prev, _) => Some(prev),
FenceSignalFutureState::Cleaned => None,
FenceSignalFutureState::Poisoned => None,
}
@ -369,18 +366,16 @@ unsafe impl<F> GpuFuture for FenceSignalFuture<F>
where
F: GpuFuture,
{
#[inline]
fn cleanup_finished(&mut self) {
self.cleanup_finished_impl()
}
#[inline]
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, FlushError> {
let mut state = self.state.lock();
self.flush_impl(&mut state)?;
match *state {
FenceSignalFutureState::Flushed(_, ref fence) => match self.behavior {
match &*state {
FenceSignalFutureState::Flushed(_, fence) => match self.behavior {
FenceSignalFutureBehavior::Block { timeout } => {
fence.wait(timeout)?;
}
@ -394,13 +389,11 @@ where
Ok(SubmitAnyBuilder::Empty)
}
#[inline]
fn flush(&self) -> Result<(), FlushError> {
let mut state = self.state.lock();
self.flush_impl(&mut state)
}
#[inline]
unsafe fn signal_finished(&self) {
let state = self.state.lock();
match *state {
@ -412,7 +405,6 @@ where
}
}
#[inline]
fn queue_change_allowed(&self) -> bool {
match self.behavior {
FenceSignalFutureBehavior::Continue => {
@ -423,7 +415,6 @@ where
}
}
#[inline]
fn queue(&self) -> Option<Arc<Queue>> {
let state = self.state.lock();
if let Some(prev) = state.get_prev() {
@ -433,7 +424,6 @@ where
}
}
#[inline]
fn check_buffer_access(
&self,
buffer: &UnsafeBuffer,
@ -449,7 +439,6 @@ where
}
}
#[inline]
fn check_image_access(
&self,
image: &UnsafeImage,
@ -484,7 +473,6 @@ unsafe impl<F> DeviceOwned for FenceSignalFuture<F>
where
F: GpuFuture,
{
#[inline]
fn device(&self) -> &Arc<Device> {
&self.device
}
@ -528,39 +516,32 @@ unsafe impl<F> GpuFuture for Arc<FenceSignalFuture<F>>
where
F: GpuFuture,
{
#[inline]
fn cleanup_finished(&mut self) {
self.cleanup_finished_impl()
}
#[inline]
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, FlushError> {
// Note that this is sound because we always return `SubmitAnyBuilder::Empty`. See the
// documentation of `build_submission`.
(**self).build_submission()
}
#[inline]
fn flush(&self) -> Result<(), FlushError> {
(**self).flush()
}
#[inline]
unsafe fn signal_finished(&self) {
(**self).signal_finished()
}
#[inline]
fn queue_change_allowed(&self) -> bool {
(**self).queue_change_allowed()
}
#[inline]
fn queue(&self) -> Option<Arc<Queue>> {
(**self).queue()
}
#[inline]
fn check_buffer_access(
&self,
buffer: &UnsafeBuffer,
@ -571,7 +552,6 @@ where
(**self).check_buffer_access(buffer, range, exclusive, queue)
}
#[inline]
fn check_image_access(
&self,
image: &UnsafeImage,

View File

@ -19,7 +19,6 @@ use std::{ops::Range, sync::Arc};
/// Joins two futures together.
// TODO: handle errors
#[inline]
pub fn join<F, S>(first: F, second: S) -> JoinFuture<F, S>
where
F: GpuFuture,
@ -49,7 +48,6 @@ where
A: DeviceOwned,
B: DeviceOwned,
{
#[inline]
fn device(&self) -> &Arc<Device> {
let device = self.first.device();
debug_assert_eq!(
@ -65,22 +63,20 @@ where
A: GpuFuture,
B: GpuFuture,
{
#[inline]
fn cleanup_finished(&mut self) {
self.first.cleanup_finished();
self.second.cleanup_finished();
}
#[inline]
fn flush(&self) -> Result<(), FlushError> {
// Since each future remembers whether it has been flushed, there's no safety issue here
// if we call this function multiple times.
self.first.flush()?;
self.second.flush()?;
Ok(())
}
#[inline]
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, FlushError> {
// TODO: review this function
let first = self.first.build_submission()?;
@ -179,18 +175,15 @@ where
})
}
#[inline]
unsafe fn signal_finished(&self) {
self.first.signal_finished();
self.second.signal_finished();
}
#[inline]
fn queue_change_allowed(&self) -> bool {
self.first.queue_change_allowed() && self.second.queue_change_allowed()
}
#[inline]
fn queue(&self) -> Option<Arc<Queue>> {
match (self.first.queue(), self.second.queue()) {
(Some(q1), Some(q2)) => {
@ -210,7 +203,6 @@ where
}
}
#[inline]
fn check_buffer_access(
&self,
buffer: &UnsafeBuffer,
@ -245,7 +237,6 @@ where
}
}
#[inline]
fn check_image_access(
&self,
image: &UnsafeImage,

View File

@ -145,7 +145,7 @@ pub unsafe trait GpuFuture: DeviceOwned {
/// Checks whether accessing a swapchain image is permitted.
///
/// > **Note**: Setting `before` to `true` should skip checking the current future and always
/// > forward the call to the future before.
/// > forward the call to the future before.
fn check_swapchain_image_acquired(
&self,
image: &UnsafeImage,
@ -166,7 +166,6 @@ pub unsafe trait GpuFuture: DeviceOwned {
///
/// > **Note**: This is just a shortcut function. The actual implementation is in the
/// > `CommandBuffer` trait.
#[inline]
fn then_execute<Cb>(
self,
queue: Arc<Queue>,
@ -183,7 +182,6 @@ pub unsafe trait GpuFuture: DeviceOwned {
///
/// > **Note**: This is just a shortcut function. The actual implementation is in the
/// > `CommandBuffer` trait.
#[inline]
fn then_execute_same_queue<Cb>(
self,
command_buffer: Cb,
@ -228,6 +226,7 @@ pub unsafe trait GpuFuture: DeviceOwned {
{
let f = self.then_signal_semaphore();
f.flush()?;
Ok(f)
}
@ -253,6 +252,7 @@ pub unsafe trait GpuFuture: DeviceOwned {
{
let f = self.then_signal_fence();
f.flush()?;
Ok(f)
}
@ -277,6 +277,7 @@ pub unsafe trait GpuFuture: DeviceOwned {
/// Turn the current future into a `Box<dyn GpuFuture>`.
///
/// This is a helper function that calls `Box::new(yourFuture) as Box<dyn GpuFuture>`.
#[inline]
fn boxed(self) -> Box<dyn GpuFuture>
where
Self: Sized + 'static,
@ -287,6 +288,7 @@ pub unsafe trait GpuFuture: DeviceOwned {
/// Turn the current future into a `Box<dyn GpuFuture + Send>`.
///
/// This is a helper function that calls `Box::new(yourFuture) as Box<dyn GpuFuture + Send>`.
#[inline]
fn boxed_send(self) -> Box<dyn GpuFuture + Send>
where
Self: Sized + Send + 'static,
@ -297,6 +299,7 @@ pub unsafe trait GpuFuture: DeviceOwned {
/// Turn the current future into a `Box<dyn GpuFuture + Sync>`.
///
/// This is a helper function that calls `Box::new(yourFuture) as Box<dyn GpuFuture + Sync>`.
#[inline]
fn boxed_sync(self) -> Box<dyn GpuFuture + Sync>
where
Self: Sized + Sync + 'static,
@ -306,7 +309,9 @@ pub unsafe trait GpuFuture: DeviceOwned {
/// Turn the current future into a `Box<dyn GpuFuture + Send + Sync>`.
///
/// This is a helper function that calls `Box::new(yourFuture) as Box<dyn GpuFuture + Send + Sync>`.
/// This is a helper function that calls `Box::new(yourFuture) as Box<dyn GpuFuture + Send +
/// Sync>`.
#[inline]
fn boxed_send_sync(self) -> Box<dyn GpuFuture + Send + Sync>
where
Self: Sized + Send + Sync + 'static,
@ -319,37 +324,30 @@ unsafe impl<F: ?Sized> GpuFuture for Box<F>
where
F: GpuFuture,
{
#[inline]
fn cleanup_finished(&mut self) {
(**self).cleanup_finished()
}
#[inline]
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, FlushError> {
(**self).build_submission()
}
#[inline]
fn flush(&self) -> Result<(), FlushError> {
(**self).flush()
}
#[inline]
unsafe fn signal_finished(&self) {
(**self).signal_finished()
}
#[inline]
fn queue_change_allowed(&self) -> bool {
(**self).queue_change_allowed()
}
#[inline]
fn queue(&self) -> Option<Arc<Queue>> {
(**self).queue()
}
#[inline]
fn check_buffer_access(
&self,
buffer: &UnsafeBuffer,
@ -360,7 +358,6 @@ where
(**self).check_buffer_access(buffer, range, exclusive, queue)
}
#[inline]
fn check_image_access(
&self,
image: &UnsafeImage,
@ -431,12 +428,11 @@ pub enum AccessError {
impl Error for AccessError {}
impl Display for AccessError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
write!(
f,
"{}",
match *self {
match self {
AccessError::ExclusiveDenied => "only shared access is allowed for this resource",
AccessError::AlreadyInUse => {
"the resource is already in use, and there is no tracking of concurrent usages"
@ -446,14 +442,14 @@ impl Display for AccessError {
}
AccessError::ImageNotInitialized { .. } => {
"trying to use an image without transitioning it from the undefined or \
preinitialized layouts first"
preinitialized layouts first"
}
AccessError::BufferNotInitialized => {
"trying to use a buffer that still contains garbage data"
}
AccessError::SwapchainImageNotAcquired => {
"trying to use a swapchain image without depending on a corresponding acquire \
image future"
image future"
}
}
)
@ -472,12 +468,11 @@ pub enum AccessCheckError {
impl Error for AccessCheckError {}
impl Display for AccessCheckError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
write!(
f,
"{}",
match *self {
match self {
AccessCheckError::Denied(_) => "access to the resource has been denied",
AccessCheckError::Unknown => "the resource is unknown",
}
@ -486,7 +481,6 @@ impl Display for AccessCheckError {
}
impl From<AccessError> for AccessCheckError {
#[inline]
fn from(err: AccessError) -> AccessCheckError {
AccessCheckError::Denied(err)
}
@ -524,23 +518,21 @@ pub enum FlushError {
}
impl Error for FlushError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match *self {
FlushError::AccessError(ref err) => Some(err),
FlushError::OomError(ref err) => Some(err),
match self {
FlushError::AccessError(err) => Some(err),
FlushError::OomError(err) => Some(err),
_ => None,
}
}
}
impl Display for FlushError {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
write!(
f,
"{}",
match *self {
match self {
FlushError::AccessError(_) => "access to a resource has been denied",
FlushError::OomError(_) => "not enough memory",
FlushError::DeviceLost => "the connection to the device has been lost",
@ -550,8 +542,7 @@ impl Display for FlushError {
"the swapchain no longer has full screen exclusivity"
}
FlushError::Timeout => {
"the flush operation needed to block, but the timeout has \
elapsed"
"the flush operation needed to block, but the timeout has elapsed"
}
FlushError::PresentIdLessThanOrEqual => {
"present id is less than or equal to previous"
@ -562,14 +553,12 @@ impl Display for FlushError {
}
impl From<AccessError> for FlushError {
#[inline]
fn from(err: AccessError) -> FlushError {
FlushError::AccessError(err)
}
}
impl From<VulkanError> for FlushError {
#[inline]
fn from(err: VulkanError) -> Self {
match err {
VulkanError::OutOfHostMemory | VulkanError::OutOfDeviceMemory => {
@ -585,7 +574,6 @@ impl From<VulkanError> for FlushError {
}
impl From<FenceError> for FlushError {
#[inline]
fn from(err: FenceError) -> FlushError {
match err {
FenceError::OomError(err) => FlushError::OomError(err),

View File

@ -27,7 +27,6 @@ use std::{
};
/// Builds a new semaphore signal future.
#[inline]
pub fn then_signal_semaphore<F>(future: F) -> SemaphoreSignalFuture<F>
where
F: GpuFuture,
@ -64,17 +63,15 @@ unsafe impl<F> GpuFuture for SemaphoreSignalFuture<F>
where
F: GpuFuture,
{
#[inline]
fn cleanup_finished(&mut self) {
self.previous.cleanup_finished();
}
#[inline]
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, FlushError> {
// Flushing the signaling part, since it must always be submitted before the waiting part.
self.flush()?;
let sem = smallvec![self.semaphore.clone()];
Ok(SubmitAnyBuilder::SemaphoresWait(sem))
}
@ -193,24 +190,20 @@ where
}
}
#[inline]
unsafe fn signal_finished(&self) {
debug_assert!(*self.wait_submitted.lock());
self.finished.store(true, Ordering::SeqCst);
self.previous.signal_finished();
}
#[inline]
fn queue_change_allowed(&self) -> bool {
true
}
#[inline]
fn queue(&self) -> Option<Arc<Queue>> {
self.previous.queue()
}
#[inline]
fn check_buffer_access(
&self,
buffer: &UnsafeBuffer,
@ -223,7 +216,6 @@ where
.map(|_| None)
}
#[inline]
fn check_image_access(
&self,
image: &UnsafeImage,
@ -251,7 +243,6 @@ unsafe impl<F> DeviceOwned for SemaphoreSignalFuture<F>
where
F: GpuFuture,
{
#[inline]
fn device(&self) -> &Arc<Device> {
self.semaphore.device()
}

Some files were not shown because too many files have changed in this diff Show More